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");
}
}
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();
}
}
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();
}
}
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();
}
}
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());
}
}));
}
Aggregations