use of dyvilx.tools.compiler.parser.classes.PropertyBodyParser 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");
}
}
Aggregations