Search in sources :

Example 1 with IfDirective

use of dyvilx.tools.gensrc.ast.directive.IfDirective 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)1 ExpressionParser (dyvilx.tools.compiler.parser.expression.ExpressionParser)1 IfDirective (dyvilx.tools.gensrc.ast.directive.IfDirective)1