Search in sources :

Example 1 with ForEachDirective

use of dyvilx.tools.gensrc.ast.directive.ForEachDirective 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)1 StatementList (dyvilx.tools.compiler.ast.statement.StatementList)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