Search in sources :

Example 1 with Variable

use of dyvilx.tools.compiler.ast.field.Variable in project Dyvil by Dyvil.

the class OptionalChainAware method nullCoalescing.

static IValue nullCoalescing(IValue lhs, IValue rhs) {
    BindingIfStatement bindingIf;
    if (lhs instanceof BindingIfStatement && (bindingIf = (BindingIfStatement) lhs).getElse() == NullValue.NULL) {
        // safe bet that the rhs used to be an optional chain
        // this branch is actually an optimization and technically not necessary, but it is very common
        // to use the null coalescing operator after an optional chain.
        final IValue then = bindingIf.getThen();
        if (NullableType.isNullable(then.getType())) {
            // Perform the following transformation:
            // if let $0 = oldReceiver { $0.oldAccess } else null
            // becomes
            // if (let $0 = oldReceiver, let $1 = $0.oldAccess) { $1 } else { <rhs> }
            final Variable var = newVar(bindingIf.getPosition(), then);
            bindingIf.addVariable(var);
            bindingIf.setThen(new FieldAccess(var));
        }
        // if the then branch of the old binding if is not nullable, we simply set the rhs
        bindingIf.setElse(rhs);
        return bindingIf;
    }
    // the lhs was not an optional chain, so we set up an impromptu null coalescing inline implementation
    final SourcePosition position = lhs.getPosition();
    // let l = <lhs>
    final Variable var = newVar(position, lhs);
    // if let l = <lhs> { l } else { <rhs> }
    bindingIf = new BindingIfStatement(position);
    bindingIf.addVariable(var);
    bindingIf.setThen(new FieldAccess(var));
    bindingIf.setElse(rhs);
    return bindingIf;
}
Also used : BindingIfStatement(dyvilx.tools.compiler.ast.statement.BindingIfStatement) IValue(dyvilx.tools.compiler.ast.expression.IValue) Variable(dyvilx.tools.compiler.ast.field.Variable) SourcePosition(dyvil.source.position.SourcePosition) FieldAccess(dyvilx.tools.compiler.ast.expression.access.FieldAccess)

Example 2 with Variable

use of dyvilx.tools.compiler.ast.field.Variable in project Dyvil by Dyvil.

the class OptionalChainAware method newVar.

/**
 * Creates a new variable for use in binding if statements. The lhs automatically gets wrapped in an optional unwrap
 * operator.
 */
static Variable newVar(SourcePosition position, IValue lhs) {
    final IValue value = new OptionalUnwrapOperator(lhs, true);
    final Variable var = new Variable(position, null, value.getType(), AttributeList.of(Modifiers.FINAL));
    var.setValue(value);
    return var;
}
Also used : IValue(dyvilx.tools.compiler.ast.expression.IValue) Variable(dyvilx.tools.compiler.ast.field.Variable)

Example 3 with Variable

use of dyvilx.tools.compiler.ast.field.Variable in project Dyvil by Dyvil.

the class BraceAccessExpr method resolve.

@Override
public IValue resolve(MarkerList markers, IContext context) {
    if (this.value != null) {
        this.value = this.value.resolve(markers, context);
    } else {
        this.value = context.resolveImplicit(null);
    }
    if (this.value == null) {
        markers.add(Markers.semanticError(this.position, "braceaccess.invalid"));
    } else {
        final IType valueType = this.value.getType();
        final IValue typedValue = this.value.withType(valueType, valueType, markers, context);
        if (typedValue != null) {
            this.value = typedValue;
        }
        this.variable = new Variable(Names.$0, this.value.getType());
        this.implicitAccess = new FieldAccess(this.variable);
    }
    context = context.push(this);
    this.statement = this.statement.resolve(markers, context);
    context.pop();
    return this;
}
Also used : Variable(dyvilx.tools.compiler.ast.field.Variable) IVariable(dyvilx.tools.compiler.ast.field.IVariable) FieldAccess(dyvilx.tools.compiler.ast.expression.access.FieldAccess) IType(dyvilx.tools.compiler.ast.type.IType)

Example 4 with Variable

use of dyvilx.tools.compiler.ast.field.Variable in project Dyvil by Dyvil.

the class SideEffectHelper method processValue.

public IValue processValue(IValue value) {
    if (value == null || !value.hasSideEffects()) {
        return value;
    }
    if (this.statementList == null) {
        this.statementList = new StatementList();
    }
    final Variable variable = new Variable(value.getPosition(), Name.fromRaw("sideEffect$" + this.registered), value.getType());
    variable.setValue(value);
    this.statementList.add(new VariableStatement(variable));
    this.statementList.addVariable(variable);
    this.registered++;
    return new FieldAccess(value.getPosition(), null, variable);
}
Also used : Variable(dyvilx.tools.compiler.ast.field.Variable) VariableStatement(dyvilx.tools.compiler.ast.statement.VariableStatement) StatementList(dyvilx.tools.compiler.ast.statement.StatementList) FieldAccess(dyvilx.tools.compiler.ast.expression.access.FieldAccess)

Example 5 with Variable

use of dyvilx.tools.compiler.ast.field.Variable in project Dyvil by Dyvil.

the class ForDirectiveParser method parse.

@Override
public void parse(IParserManager pm, IToken token) {
    // #for (IDENTIFIER <- EXPRESSION) {BLOCK}
    final int type = token.type();
    switch(this.mode) {
        case FOR:
            assert type == GenSrcSymbols.FOR;
            this.mode = OPEN_PAREN;
            this.directive = new ForEachDirective(token.raw(), null);
            return;
        case OPEN_PAREN:
            if (type != BaseSymbols.OPEN_PARENTHESIS) {
                pm.report(token, "for.open_paren");
                this.list.add(this.directive);
                pm.popParser(true);
                return;
            }
            this.mode = VAR_NAME;
            return;
        case VAR_NAME:
            if (type == Tokens.LETTER_IDENTIFIER) {
                this.directive.setVariable(new Variable(token.raw(), token.nameValue(), Types.UNKNOWN));
                this.mode = TYPE_ASCRIPTION;
                return;
            }
            pm.report(token, "for.identifier");
            if (type == BaseSymbols.CLOSE_PARENTHESIS) {
                this.mode = BODY;
            }
            return;
        case TYPE_ASCRIPTION:
            if (type == BaseSymbols.COLON) {
                pm.pushParser(new TypeParser(this.directive.getVariable()));
                this.mode = ARROW;
                return;
            }
        // Fallthrough
        case ARROW:
            if (type != GenSrcSymbols.ARROW_LEFT) {
                pm.reparse();
                pm.report(token, "for.arrow_left");
            }
            pm.pushParser(new ExpressionParser(this.directive.getVariable()));
            this.mode = CLOSE_PAREN;
            return;
        case CLOSE_PAREN:
            if (type != BaseSymbols.CLOSE_PARENTHESIS) {
                pm.report(token, "for.close_paren");
                return;
            }
            this.mode = BODY;
            return;
        case BODY:
            if (type != BaseSymbols.OPEN_CURLY_BRACKET) {
                pm.report(token, "for.open_brace");
                this.list.add(this.directive);
                pm.popParser(true);
                return;
            }
            final StatementList body = new StatementList();
            pm.pushParser(new BlockParser(body));
            this.directive.setAction(body);
            this.mode = BODY_END;
            return;
        case BODY_END:
            if (type != BaseSymbols.CLOSE_CURLY_BRACKET) {
                pm.report(token, "for.close_brace");
            }
            this.list.add(this.directive);
            pm.popParser();
    }
}
Also used : Variable(dyvilx.tools.compiler.ast.field.Variable) TypeParser(dyvilx.tools.compiler.parser.type.TypeParser) ForEachDirective(dyvilx.tools.gensrc.ast.directive.ForEachDirective) StatementList(dyvilx.tools.compiler.ast.statement.StatementList) ExpressionParser(dyvilx.tools.compiler.parser.expression.ExpressionParser)

Aggregations

Variable (dyvilx.tools.compiler.ast.field.Variable)8 FieldAccess (dyvilx.tools.compiler.ast.expression.access.FieldAccess)5 IValue (dyvilx.tools.compiler.ast.expression.IValue)4 StatementList (dyvilx.tools.compiler.ast.statement.StatementList)3 SourcePosition (dyvil.source.position.SourcePosition)2 BindingIfStatement (dyvilx.tools.compiler.ast.statement.BindingIfStatement)2 VariableStatement (dyvilx.tools.compiler.ast.statement.VariableStatement)2 ConstructorCall (dyvilx.tools.compiler.ast.expression.access.ConstructorCall)1 MethodCall (dyvilx.tools.compiler.ast.expression.access.MethodCall)1 IVariable (dyvilx.tools.compiler.ast.field.IVariable)1 ArgumentList (dyvilx.tools.compiler.ast.parameter.ArgumentList)1 IType (dyvilx.tools.compiler.ast.type.IType)1 ExpressionParser (dyvilx.tools.compiler.parser.expression.ExpressionParser)1 TypeParser (dyvilx.tools.compiler.parser.type.TypeParser)1 ForEachDirective (dyvilx.tools.gensrc.ast.directive.ForEachDirective)1