use of dyvilx.tools.compiler.parser.expression.ExpressionParser in project Dyvil by Dyvil.
the class REPLParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
final int type = token.type();
if (type == Tokens.EOF) {
pm.popParser();
return;
}
switch(this.mode) {
case ELEMENT:
this.mode = SEPARATOR;
if (TRY_PARSER.tryParse(pm, new SourceFileParser(this.context).withFlags(ONE_ELEMENT | NO_CLASSES), token, EXIT_ON_ROOT)) {
return;
}
if (TRY_PARSER.tryParse(pm, new MemberParser<>(this.context), token, EXIT_ON_ROOT)) {
return;
}
pm.pushParser(new ExpressionParser(this.context));
return;
case SEPARATOR:
this.mode = ELEMENT;
switch(type) {
case BaseSymbols.SEMICOLON:
case BaseSymbols.COMMA:
return;
}
pm.report(token, "statement_list.semicolon");
}
}
use of dyvilx.tools.compiler.parser.expression.ExpressionParser in project Dyvil by Dyvil.
the class ParameterListParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
final int type = token.type();
switch(this.mode) {
case DECLARATOR:
switch(type) {
case BaseSymbols.SEMICOLON:
if (token.isInferred()) {
return;
}
break;
case DyvilKeywords.LET:
this.attributes.addFlag(Modifiers.FINAL);
// Fallthrough
case DyvilKeywords.VAR:
this.mode = NAME;
return;
case DyvilKeywords.THIS:
if (token.next().type() != BaseSymbols.COLON) {
pm.report(token, "parameter.identifier");
this.mode = SEPARATOR;
return;
}
// this : TYPE
this.mode = TYPE_ASCRIPTION;
// the colon
pm.skip();
pm.pushParser(new TypeParser(t -> this.setThisType(t, token, pm)));
return;
case DyvilSymbols.AT:
final Annotation annotation = new CodeAnnotation(token.raw());
this.attributes.add(annotation);
pm.pushParser(new AnnotationParser(annotation));
return;
}
final Modifier modifier;
if ((modifier = ModifierParser.parseModifier(token, pm)) != null) {
this.attributes.add(modifier);
return;
}
if (BaseSymbols.isCloseBracket(type)) {
pm.popParser(true);
return;
}
// Fallthrough
case NAME:
final Name name;
if (Tokens.isIdentifier(type)) {
name = token.nameValue();
} else if (type == BaseSymbols.UNDERSCORE) {
name = null;
} else if (Tokens.isKeyword(type)) {
name = Name.fromRaw(token.stringValue());
} else {
if (BaseSymbols.isCloseBracket(type)) {
pm.popParser(true);
}
if (type == Tokens.EOF) {
pm.popParser();
}
this.mode = SEPARATOR;
pm.report(token, "parameter.identifier");
return;
}
this.parameter = this.consumer.createParameter(token.raw(), name, this.type, this.attributes);
this.mode = INTERNAL_NAME;
return;
case INTERNAL_NAME:
this.mode = VARARGS_AFTER_NAME;
// overwrite the internal name if necessary
if (Tokens.isIdentifier(type)) {
// IDENTIFIER IDENTIFIER : TYPE
this.parameter.setName(token.nameValue());
return;
} else if (type == BaseSymbols.UNDERSCORE) {
// IDENTIFIER _ : TYPE
this.parameter.setName(null);
return;
}
// Fallthrough
case VARARGS_AFTER_NAME:
if (type == DyvilSymbols.ELLIPSIS) {
this.flags |= VARARGS;
this.mode = TYPE_ASCRIPTION;
return;
}
// Fallthrough
case TYPE_ASCRIPTION:
case VARARGS_AFTER_POST_TYPE:
// continue with the remaining cases (DEFAULT_VALUE, PROPERTY, ...).
if (this.mode == VARARGS_AFTER_POST_TYPE) {
// case (2)
if (type == DyvilSymbols.ELLIPSIS) {
this.setTypeVarargs();
this.mode = DEFAULT_VALUE;
return;
}
} else /* case (1) */
if (type == BaseSymbols.COLON) {
this.mode = VARARGS_AFTER_POST_TYPE;
final TypeParser parser = new TypeParser(this);
if (this.hasFlag(LAMBDA_ARROW_END)) {
parser.withFlags(TypeParser.IGNORE_LAMBDA);
}
pm.pushParser(parser);
return;
}
// Fallthrough
case DEFAULT_VALUE:
if (type == BaseSymbols.EQUALS) {
this.mode = PROPERTY;
pm.pushParser(new ExpressionParser(this.parameter));
return;
}
// Fallthrough
case PROPERTY:
if (type == BaseSymbols.OPEN_CURLY_BRACKET && this.hasFlag(ALLOW_PROPERTIES)) {
final IProperty property = this.parameter.createProperty();
pm.pushParser(new PropertyBodyParser(property), true);
this.mode = SEPARATOR;
return;
}
// Fallthrough
case SEPARATOR:
this.mode = DECLARATOR;
if (this.parameter != null) {
if (this.hasFlag(VARARGS)) {
this.parameter.setVarargs();
}
this.parameter.setType(this.type);
this.consumer.getParameters().add(this.parameter);
}
this.reset();
switch(type) {
case DyvilSymbols.ARROW_RIGHT:
case DyvilSymbols.DOUBLE_ARROW_RIGHT:
if (!this.hasFlag(LAMBDA_ARROW_END)) {
// produce a syntax error
break;
}
// Fallthrough
case BaseSymbols.CLOSE_PARENTHESIS:
case BaseSymbols.CLOSE_CURLY_BRACKET:
case BaseSymbols.CLOSE_SQUARE_BRACKET:
pm.reparse();
// Fallthrough
case Tokens.EOF:
pm.popParser();
return;
case BaseSymbols.COMMA:
case BaseSymbols.SEMICOLON:
return;
}
pm.report(token, "parameter.separator");
}
}
use of dyvilx.tools.compiler.parser.expression.ExpressionParser in project Dyvil by Dyvil.
the class ForStatementParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
final int type = token.type();
switch(this.mode) {
case FOR:
this.mode = FOR_START;
if (type != DyvilKeywords.FOR) {
pm.reparse();
pm.report(token, "for.for_keyword");
}
return;
case FOR_START:
this.mode = VARIABLE;
if (type == BaseSymbols.OPEN_PARENTHESIS) {
this.parenthesis = true;
return;
}
// Fallthrough
case VARIABLE:
if (type == BaseSymbols.SEMICOLON) {
// for (; ...
// => No variable declaration, parse Condition next
pm.pushParser(new ExpressionParser(this));
this.mode = CONDITION_END;
return;
}
// for ( i ...
// for ( var i ...
// for ( let i ...
pm.pushParser(new DataMemberParser<>(this), true);
this.mode = VARIABLE_SEPARATOR;
return;
case VARIABLE_SEPARATOR:
switch(type) {
case DyvilSymbols.ARROW_LEFT:
this.mode = FOR_EACH_END;
final ExpressionParser parser = new ExpressionParser(this.variable);
if (!this.parenthesis) {
parser.addFlags(IGNORE_COLON | IGNORE_CLOSURE);
}
pm.pushParser(parser);
return;
case BaseSymbols.EQUALS:
this.mode = VARIABLE_END;
pm.pushParser(new ExpressionParser(this.variable));
return;
}
this.mode = VARIABLE_END;
pm.reparse();
pm.report(token, "for.variable.separator");
return;
case VARIABLE_END:
this.mode = CONDITION_END;
if (token.next().type() != BaseSymbols.SEMICOLON) {
pm.pushParser(new ExpressionParser(this));
return;
}
if (type != BaseSymbols.SEMICOLON) {
pm.reparse();
pm.report(token, "for.variable.semicolon");
}
return;
case CONDITION_END:
this.mode = FOR_END;
if (type != BaseSymbols.SEMICOLON) {
pm.reparse();
pm.report(token, "for.condition.semicolon");
return;
}
if (token.next().type() != BaseSymbols.SEMICOLON) {
final ExpressionParser parser = new ExpressionParser(this);
if (!this.parenthesis) {
parser.addFlags(IGNORE_COLON | IGNORE_CLOSURE);
}
pm.pushParser(parser);
}
return;
case FOR_END:
this.forStatement = new ForStatement(this.position, this.variable, this.condition, this.update);
this.parseEnd(pm, token, type);
return;
case FOR_EACH_END:
this.forStatement = new ForEachStatement(this.position, this.variable);
this.parseEnd(pm, token, type);
return;
case STATEMENT:
if (BaseSymbols.isTerminator(type) && !token.isInferred()) {
pm.popParser(true);
this.field.setValue(this.forStatement);
return;
}
pm.pushParser(new ExpressionParser(this), true);
this.mode = END;
return;
case END:
pm.popParser(true);
this.field.setValue(this.forStatement);
}
}
use of dyvilx.tools.compiler.parser.expression.ExpressionParser in project Dyvil by Dyvil.
the class IfStatementParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
final int type = token.type();
switch(this.mode) {
case IF:
if (type != DyvilKeywords.IF) {
pm.report(token, "if.if_keyword");
return;
}
this.mode = OPEN_PAREN;
this.statement = new IfStatement(token.raw());
return;
case OPEN_PAREN:
if (type == BaseSymbols.OPEN_PARENTHESIS) {
this.parentheses = true;
this.mode = CONDITION_PART;
return;
}
// Fallthrough
case CONDITION_PART:
if (type == DyvilKeywords.LET) {
pm.pushParser(new DataMemberParser<>(this), true);
this.mode = VARIABLE_VALUE;
return;
}
this.mode = SEPARATOR;
pm.pushParser(this.expressionParser(this.statement::setCondition), true);
return;
case VARIABLE_VALUE:
if (type == BaseSymbols.EQUALS) {
pm.pushParser(this.expressionParser(this.lastVariable));
this.mode = SEPARATOR;
return;
}
pm.report(token, "if.binding.assignment");
// Fallthrough
case SEPARATOR:
switch(type) {
case BaseSymbols.COMMA:
case BaseSymbols.SEMICOLON:
if (this.parentheses && !this.hasCondition()) {
this.mode = CONDITION_PART;
return;
}
// then
break;
case BaseSymbols.CLOSE_PARENTHESIS:
if (this.parentheses) {
this.mode = THEN;
return;
}
// then
break;
}
if (this.parentheses) {
pm.report(token, "if.close_paren");
}
// Fallthrough
case THEN:
switch(type) {
case Tokens.EOF:
case BaseSymbols.SEMICOLON:
this.end(pm);
return;
}
this.mode = ELSE;
pm.pushParser(new ExpressionParser(this.statement::setThen), true);
return;
case ELSE:
if (type == DyvilKeywords.ELSE) {
pm.pushParser(new ExpressionParser(this.statement::setElse));
this.mode = END;
return;
}
if (token.isInferred() && token.next().type() == DyvilKeywords.ELSE) {
// ... inferred_semicolon else
pm.skip();
pm.pushParser(new ExpressionParser(this.statement::setElse));
this.mode = END;
return;
}
// Fallthrough
case END:
this.end(pm);
return;
}
}
use of dyvilx.tools.compiler.parser.expression.ExpressionParser in project Dyvil by Dyvil.
the class RepeatStatementParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
final int type = token.type();
switch(this.mode) {
case REPEAT:
this.mode = ACTION;
if (type != DyvilKeywords.REPEAT) {
pm.reparse();
pm.report(token, "repeat.repeat_keyword");
}
return;
case ACTION:
pm.pushParser(new ExpressionParser(this), true);
this.mode = WHILE;
return;
case WHILE:
if (type == DyvilKeywords.WHILE) {
this.mode = END;
pm.pushParser(new ExpressionParser(this));
return;
}
if (type == BaseSymbols.SEMICOLON && token.isInferred() && token.next().type() == DyvilKeywords.WHILE) {
this.mode = END;
pm.skip(1);
pm.pushParser(new ExpressionParser(this));
return;
}
// fallthrough
case END:
pm.popParser(true);
}
}
Aggregations