Search in sources :

Example 16 with ExpressionParser

use of dyvilx.tools.compiler.parser.expression.ExpressionParser in project Dyvil by Dyvil.

the class TryStatementParser method parse.

@Override
public void parse(IParserManager pm, IToken token) {
    final int type = token.type();
    switch(this.mode) {
        case END:
            pm.popParser(true);
            return;
        case ACTION:
            pm.pushParser(new ExpressionParser(this), true);
            this.mode = CATCH;
            return;
        case CATCH:
            if (type == DyvilKeywords.CATCH) {
                this.statement.addCatchBlock(this.catchBlock = new CatchBlock());
                this.mode = CATCH_OPEN;
                return;
            }
            if (type == DyvilKeywords.FINALLY) {
                pm.pushParser(new ExpressionParser(this));
                this.mode = END;
                return;
            }
            if (BaseSymbols.isTerminator(type)) {
                int nextType = token.next().type();
                if (nextType == Tokens.EOF) {
                    pm.popParser(true);
                    return;
                }
                if (nextType == DyvilKeywords.CATCH || nextType == DyvilKeywords.FINALLY) {
                    return;
                }
            }
            pm.popParser(true);
            return;
        case CATCH_OPEN:
            if (type == BaseSymbols.OPEN_PARENTHESIS) {
                this.mode = CATCH_CLOSE;
                pm.pushParser(new DataMemberParser<>(this));
            } else {
                this.mode = CATCH_SEPARATOR;
                pm.pushParser(new DataMemberParser<>(this), true);
            }
            return;
        case CATCH_CLOSE:
            this.mode = CATCH;
            pm.pushParser(new ExpressionParser(this.catchBlock));
            if (type != BaseSymbols.CLOSE_PARENTHESIS) {
                pm.reparse();
                pm.report(token, "try.catch.close_paren");
            }
            return;
        case CATCH_SEPARATOR:
            switch(type) {
                case Tokens.EOF:
                    pm.popParser();
                    return;
                case BaseSymbols.SEMICOLON:
                    this.mode = CATCH;
                    return;
                case BaseSymbols.OPEN_CURLY_BRACKET:
                    this.mode = CATCH;
                    pm.pushParser(new StatementListParser(this.catchBlock), true);
                    return;
            }
            pm.report(token, "try.catch.separator");
    }
}
Also used : CatchBlock(dyvilx.tools.compiler.ast.statement.exception.CatchBlock) ExpressionParser(dyvilx.tools.compiler.parser.expression.ExpressionParser)

Example 17 with ExpressionParser

use of dyvilx.tools.compiler.parser.expression.ExpressionParser 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 18 with ExpressionParser

use of dyvilx.tools.compiler.parser.expression.ExpressionParser 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)

Example 19 with ExpressionParser

use of dyvilx.tools.compiler.parser.expression.ExpressionParser in project Dyvil by Dyvil.

the class ScopeDirectiveParser method parse.

@Override
public void parse(IParserManager pm, IToken token) {
    final int type = token.type();
    switch(this.mode) {
        case OPEN_PAREN:
            if (type == BaseSymbols.OPEN_PARENTHESIS) {
                this.directive = new ScopeDirective();
                pm.pushParser(new ExpressionParser(this.directive::setValue));
                this.mode = CLOSE_PAREN;
                return;
            }
        // Fallthrough
        case BODY:
            if (type == BaseSymbols.OPEN_CURLY_BRACKET) {
                final StatementList body = new StatementList();
                pm.pushParser(new BlockParser(body));
                this.directive.setBlock(body);
                this.mode = BODY_END;
                return;
            }
            this.list.add(this.directive);
            pm.popParser(true);
            return;
        case CLOSE_PAREN:
            if (type == BaseSymbols.CLOSE_PARENTHESIS) {
                this.mode = BODY;
                return;
            }
            pm.report(token, "directive.close_paren");
            return;
        case BODY_END:
            assert type == BaseSymbols.CLOSE_CURLY_BRACKET;
            this.list.add(this.directive);
            pm.popParser();
    }
}
Also used : StatementList(dyvilx.tools.compiler.ast.statement.StatementList) ExpressionParser(dyvilx.tools.compiler.parser.expression.ExpressionParser) ScopeDirective(dyvilx.tools.gensrc.ast.directive.ScopeDirective)

Example 20 with ExpressionParser

use of dyvilx.tools.compiler.parser.expression.ExpressionParser in project Dyvil by Dyvil.

the class CompleteCommand method execute.

@Override
public void execute(DyvilREPL repl, String argument) {
    final IContext context = repl.getContext().getContext();
    if (argument == null) {
        // REPL Variables
        this.printREPLMembers(repl, "");
        return;
    }
    final int dotIndex = argument.lastIndexOf('.');
    if (dotIndex <= 0) {
        // REPL Variable Completions
        this.printREPLMembers(repl, Qualifier.qualify(argument));
        return;
    }
    final String expression = argument.substring(0, dotIndex);
    final String memberStart = Qualifier.qualify(argument.substring(dotIndex + 1));
    final MarkerList markers = new MarkerList(Markers.INSTANCE);
    final TokenList tokens = new DyvilLexer(markers, DyvilSymbols.INSTANCE).tokenize(expression);
    new ParserManager(DyvilSymbols.INSTANCE, tokens.iterator(), markers).parse(new ExpressionParser((IValue value) -> {
        value.resolveTypes(markers, context);
        value = value.resolve(markers, context);
        value.checkTypes(markers, context);
        if (!markers.isEmpty()) {
            // Print Errors, if any
            final boolean colors = repl.getCompiler().config.useAnsiColors();
            final StringBuilder buffer = new StringBuilder();
            markers.log(new LineSource(expression), buffer, colors);
            repl.getOutput().println(buffer);
        }
        try {
            this.printCompletions(repl, memberStart, value);
        } catch (Throwable throwable) {
            throwable.printStackTrace(repl.getErrorOutput());
        }
    }));
}
Also used : ParserManager(dyvilx.tools.parsing.ParserManager) MarkerList(dyvilx.tools.parsing.marker.MarkerList) IContext(dyvilx.tools.compiler.ast.context.IContext) IValue(dyvilx.tools.compiler.ast.expression.IValue) LineSource(dyvil.source.LineSource) DyvilLexer(dyvilx.tools.parsing.lexer.DyvilLexer) TokenList(dyvilx.tools.parsing.TokenList) ExpressionParser(dyvilx.tools.compiler.parser.expression.ExpressionParser)

Aggregations

ExpressionParser (dyvilx.tools.compiler.parser.expression.ExpressionParser)20 TypeParser (dyvilx.tools.compiler.parser.type.TypeParser)5 StatementList (dyvilx.tools.compiler.ast.statement.StatementList)4 StatementListParser (dyvilx.tools.compiler.parser.statement.StatementListParser)4 ParameterListParser (dyvilx.tools.compiler.parser.method.ParameterListParser)3 Name (dyvil.lang.Name)2 TypeListParser (dyvilx.tools.compiler.parser.type.TypeListParser)2 IToken (dyvilx.tools.parsing.token.IToken)2 Modifiers (dyvil.reflect.Modifiers)1 LineSource (dyvil.source.LineSource)1 AttributeList (dyvilx.tools.compiler.ast.attribute.AttributeList)1 Annotation (dyvilx.tools.compiler.ast.attribute.annotation.Annotation)1 CodeAnnotation (dyvilx.tools.compiler.ast.attribute.annotation.CodeAnnotation)1 Modifier (dyvilx.tools.compiler.ast.attribute.modifiers.Modifier)1 ITypeConsumer (dyvilx.tools.compiler.ast.consumer.ITypeConsumer)1 IContext (dyvilx.tools.compiler.ast.context.IContext)1 IValue (dyvilx.tools.compiler.ast.expression.IValue)1 LambdaExpr (dyvilx.tools.compiler.ast.expression.LambdaExpr)1 MatchCase (dyvilx.tools.compiler.ast.expression.MatchCase)1 InitializerCall (dyvilx.tools.compiler.ast.expression.access.InitializerCall)1