Search in sources :

Example 6 with StatementList

use of dyvilx.tools.compiler.ast.statement.StatementList in project Dyvil by Dyvil.

the class ClassMetadata method createDefaultConstructor.

private CodeConstructor createDefaultConstructor() {
    // init(classParams...)
    final SourcePosition position = this.theClass.position();
    final AttributeList attributes = this.theClass.getConstructorAttributes();
    attributes.addFlag(Modifiers.GENERATED);
    final CodeConstructor constructor = new CodeConstructor(this.theClass, attributes);
    constructor.setPosition(position);
    this.copyClassParameters(constructor);
    // : super(superParams...)
    final IType superType = this.theClass.getSuperType();
    if (superType != null) {
        // Generate the constructor body
        ArgumentList arguments = this.theClass.getSuperConstructorArguments();
        if (arguments == null) {
            arguments = ArgumentList.empty();
        }
        final InitializerCall init = new InitializerCall(this.theClass.getPosition(), true, arguments, superType);
        constructor.setInitializer(init);
    }
    // { this.classParams... = classParams... }
    final ParameterList classParams = this.theClass.getParameters();
    final StatementList ctorBody = new StatementList();
    final ParameterList ctorParams = constructor.getParameters();
    // j is the counter for class parameters, as there may be leading synthetic constructor parameters
    for (int i = 0, j = 0, count = ctorParams.size(); i < count; i++) {
        final IParameter ctorParam = ctorParams.get(i);
        if (ctorParam.hasModifier(Modifiers.SYNTHETIC)) {
            continue;
        }
        final IParameter classParam = classParams.get(j++);
        if (classParam.hasModifier(Modifiers.OVERRIDE)) {
            continue;
        }
        final IValue receiver = new ThisExpr(this.theClass);
        final FieldAccess access = new FieldAccess(ctorParam);
        final FieldAssignment assignment = new FieldAssignment(position, receiver, classParam, access);
        ctorBody.add(assignment);
    }
    constructor.setValue(ctorBody);
    return constructor;
}
Also used : IParameter(dyvilx.tools.compiler.ast.parameter.IParameter) AttributeList(dyvilx.tools.compiler.ast.attribute.AttributeList) FieldAssignment(dyvilx.tools.compiler.ast.expression.access.FieldAssignment) ArgumentList(dyvilx.tools.compiler.ast.parameter.ArgumentList) InitializerCall(dyvilx.tools.compiler.ast.expression.access.InitializerCall) IType(dyvilx.tools.compiler.ast.type.IType) IValue(dyvilx.tools.compiler.ast.expression.IValue) CodeConstructor(dyvilx.tools.compiler.ast.constructor.CodeConstructor) SourcePosition(dyvil.source.position.SourcePosition) StatementList(dyvilx.tools.compiler.ast.statement.StatementList) ParameterList(dyvilx.tools.compiler.ast.parameter.ParameterList) FieldAccess(dyvilx.tools.compiler.ast.expression.access.FieldAccess) ThisExpr(dyvilx.tools.compiler.ast.expression.ThisExpr)

Example 7 with StatementList

use of dyvilx.tools.compiler.ast.statement.StatementList in project Dyvil by Dyvil.

the class StatementListParser method parse.

@Override
public void parse(IParserManager pm, IToken token) {
    final int type = token.type();
    if (type == BaseSymbols.CLOSE_CURLY_BRACKET) {
        this.end(pm);
        return;
    }
    if (type == Tokens.EOF) {
        this.end(pm);
        pm.report(token, "statement_list.close_brace");
        return;
    }
    switch(this.mode) {
        case OPEN_BRACKET:
            {
                final IToken next = token.next();
                final IToken lambdaArrow = this.findLambdaArrow(next);
                if (lambdaArrow != null) {
                    this.lambdaExpr = new LambdaExpr(lambdaArrow.raw());
                    this.lambdaExpr.setValue(this.statementList = new StatementList(token));
                    if (next == lambdaArrow) {
                        // { ->
                        // { =>
                        this.mode = LAMBDA_TYPE_ARROW;
                        return;
                    }
                    if (next.type() == BaseSymbols.OPEN_PARENTHESIS) {
                        // { ( ... ) =>
                        // { ( ... ) ->
                        pm.skip();
                        pm.pushParser(new ParameterListParser(this.lambdaExpr));
                        this.mode = LAMBDA_PARAMETERS_END;
                        return;
                    }
                    // { ... ->
                    // { ... =>
                    pm.pushParser(new ParameterListParser(this.lambdaExpr).withFlags(LAMBDA_ARROW_END));
                    this.mode = LAMBDA_TYPE_ARROW;
                    return;
                }
                // { ...
                this.statementList = this.closure ? new Closure(token) : new StatementList(token);
                this.mode = EXPRESSION;
                if (type != BaseSymbols.OPEN_CURLY_BRACKET) {
                    pm.report(token, "statement_list.open_brace");
                    pm.reparse();
                }
                return;
            }
        case LAMBDA_PARAMETERS_END:
            this.mode = LAMBDA_TYPE_ARROW;
            if (type != BaseSymbols.CLOSE_PARENTHESIS) {
                pm.report(token, "statement_list.lambda.close_paren");
            }
            return;
        case LAMBDA_TYPE_ARROW:
            if (type == DyvilSymbols.ARROW_RIGHT) {
                pm.pushParser(LambdaOrTupleParser.returnTypeParser(this.lambdaExpr));
                this.mode = LAMBDA_RETURN_ARROW;
                return;
            }
        // Fallthrough
        case LAMBDA_RETURN_ARROW:
            if (type != DyvilSymbols.DOUBLE_ARROW_RIGHT) {
                pm.report(token, "statement_list.lambda.arrow");
                return;
            }
            this.mode = EXPRESSION;
            return;
        case EXPRESSION:
            switch(type) {
                case BaseSymbols.SEMICOLON:
                case BaseSymbols.COMMA:
                    return;
                case DyvilKeywords.LABEL:
                    this.mode = LABEL_NAME;
                    return;
            }
            this.mode = SEPARATOR;
            final MemberParser<IVariable> parser = new MemberParser<>(this).withFlags(MemberParser.NO_FIELD_PROPERTIES);
            if (this.tryParserManager.tryParse(pm, parser, token, EXIT_ON_ROOT)) {
                return;
            }
            pm.pushParser(new ExpressionParser(this));
            return;
        case LABEL_NAME:
            if (Tokens.isIdentifier(type)) {
                this.label = token.nameValue();
                this.mode = LABEL_END;
                return;
            }
            this.mode = EXPRESSION;
            if (type != BaseSymbols.COLON) {
                pm.reparse();
            }
            pm.report(token, "statement_list.label.name");
            return;
        case LABEL_END:
            switch(type) {
                case BaseSymbols.COLON:
                case BaseSymbols.SEMICOLON:
                    this.mode = EXPRESSION;
                    return;
            }
            this.mode = EXPRESSION;
            pm.reparse();
            pm.report(SourcePosition.between(token, token.next()), "statement_list.label.separator");
            return;
        case SEPARATOR:
            this.mode = EXPRESSION;
            switch(type) {
                case BaseSymbols.SEMICOLON:
                case BaseSymbols.COMMA:
                    return;
            }
            pm.report(token, "statement_list.semicolon");
    }
}
Also used : ParameterListParser(dyvilx.tools.compiler.parser.method.ParameterListParser) Closure(dyvilx.tools.compiler.ast.statement.Closure) IToken(dyvilx.tools.parsing.token.IToken) LambdaExpr(dyvilx.tools.compiler.ast.expression.LambdaExpr) StatementList(dyvilx.tools.compiler.ast.statement.StatementList) IVariable(dyvilx.tools.compiler.ast.field.IVariable) ExpressionParser(dyvilx.tools.compiler.parser.expression.ExpressionParser)

Example 8 with StatementList

use of dyvilx.tools.compiler.ast.statement.StatementList 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 9 with StatementList

use of dyvilx.tools.compiler.ast.statement.StatementList 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)

Example 10 with StatementList

use of dyvilx.tools.compiler.ast.statement.StatementList in project Dyvil by Dyvil.

the class IfDirectiveParser method parse.

@Override
public void parse(IParserManager pm, IToken token) {
    // #if (EXPRESSION) {BLOCK}
    // #if (EXPRESSION) {BLOCK} #else {BLOCK}
    final int type = token.type();
    switch(this.mode) {
        case IF:
            assert type == GenSrcSymbols.IF;
            this.directive = new IfDirective(token.raw());
            this.mode = OPEN_PAREN;
            return;
        case OPEN_PAREN:
            if (type != BaseSymbols.OPEN_PARENTHESIS) {
                pm.report(token, "if.open_paren");
                this.list.add(this.directive);
                pm.popParser(true);
                return;
            }
            pm.pushParser(new ExpressionParser(this.directive::setCondition));
            this.mode = CLOSE_PAREN;
            return;
        case CLOSE_PAREN:
            if (type != BaseSymbols.CLOSE_PARENTHESIS) {
                pm.report(token, "if.close_paren");
                return;
            }
            this.mode = THEN_BODY;
            return;
        case THEN_BODY:
            if (type != BaseSymbols.OPEN_CURLY_BRACKET) {
                pm.report(token, "if.open_brace");
                this.list.add(this.directive);
                pm.popParser(true);
                return;
            }
            final StatementList thenBlock = new StatementList();
            pm.pushParser(new BlockParser(thenBlock));
            this.directive.setThen(thenBlock);
            this.mode = THEN_BODY_END;
            return;
        case THEN_BODY_END:
            if (type != BaseSymbols.CLOSE_CURLY_BRACKET) {
                pm.report(token, "if.close_brace");
                this.list.add(this.directive);
                pm.popParser();
                return;
            }
            this.mode = ELSE;
            return;
        case ELSE:
            if (type == Tokens.STRING && isBlank(token.stringValue()) && isHashElse(token.next())) {
                // ignore empty whitespace between } and #else
                // skip the '#' and 'else'
                pm.skip(2);
                this.mode = ELSE_BODY;
                return;
            }
            if (isHashElse(token)) {
                // skip the 'else'
                pm.skip();
                this.mode = ELSE_BODY;
                return;
            }
            this.list.add(this.directive);
            pm.popParser(true);
            return;
        case ELSE_BODY:
            if (type != BaseSymbols.OPEN_CURLY_BRACKET) {
                pm.report(token, "if.else.open_brace");
                this.list.add(this.directive);
                pm.popParser(true);
                return;
            }
            final StatementList elseBlock = new StatementList();
            pm.pushParser(new BlockParser(elseBlock));
            this.directive.setElse(elseBlock);
            this.mode = ELSE_BODY_END;
            return;
        case ELSE_BODY_END:
            if (type != BaseSymbols.CLOSE_CURLY_BRACKET) {
                pm.report(token, "if.else.close_brace");
            }
            this.list.add(this.directive);
            pm.popParser();
    }
}
Also used : StatementList(dyvilx.tools.compiler.ast.statement.StatementList) ExpressionParser(dyvilx.tools.compiler.parser.expression.ExpressionParser) IfDirective(dyvilx.tools.gensrc.ast.directive.IfDirective)

Aggregations

StatementList (dyvilx.tools.compiler.ast.statement.StatementList)12 ExpressionParser (dyvilx.tools.compiler.parser.expression.ExpressionParser)4 FieldAccess (dyvilx.tools.compiler.ast.expression.access.FieldAccess)3 Variable (dyvilx.tools.compiler.ast.field.Variable)3 AttributeList (dyvilx.tools.compiler.ast.attribute.AttributeList)2 IValue (dyvilx.tools.compiler.ast.expression.IValue)2 VariableStatement (dyvilx.tools.compiler.ast.statement.VariableStatement)2 SourcePosition (dyvil.source.position.SourcePosition)1 ClassBody (dyvilx.tools.compiler.ast.classes.ClassBody)1 CodeClass (dyvilx.tools.compiler.ast.classes.CodeClass)1 CodeConstructor (dyvilx.tools.compiler.ast.constructor.CodeConstructor)1 LambdaExpr (dyvilx.tools.compiler.ast.expression.LambdaExpr)1 ThisExpr (dyvilx.tools.compiler.ast.expression.ThisExpr)1 ConstructorCall (dyvilx.tools.compiler.ast.expression.access.ConstructorCall)1 FieldAssignment (dyvilx.tools.compiler.ast.expression.access.FieldAssignment)1 InitializerCall (dyvilx.tools.compiler.ast.expression.access.InitializerCall)1 MethodCall (dyvilx.tools.compiler.ast.expression.access.MethodCall)1 IVariable (dyvilx.tools.compiler.ast.field.IVariable)1 CodeMethod (dyvilx.tools.compiler.ast.method.CodeMethod)1 ArgumentList (dyvilx.tools.compiler.ast.parameter.ArgumentList)1