use of dyvilx.tools.compiler.parser.type.TypeListParser in project Dyvil by Dyvil.
the class ConstructorParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
final int type = token.type();
switch(this.mode) {
case DECLARATOR:
switch(type) {
case DyvilSymbols.AT:
this.parseAnnotation(pm, token);
return;
case DyvilKeywords.INIT:
this.member = this.consumer.createConstructor(token.raw(), this.attributes);
this.mode = PARAMETERS;
return;
}
if (this.parseModifier(pm, token)) {
return;
}
// Fallthrough
case PARAMETERS:
this.mode = PARAMETERS_END;
if (type == BaseSymbols.OPEN_PARENTHESIS) {
pm.pushParser(new ParameterListParser(this.member));
return;
}
pm.reparse();
pm.report(token, "constructor.parameters.open_paren");
return;
case PARAMETERS_END:
this.mode = INITIALIZER;
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.reparse();
pm.report(token, "constructor.parameters.close_paren");
}
return;
case INITIALIZER:
if (type == BaseSymbols.COLON) {
this.mode = INIT_TYPE;
return;
}
// Fallthrough
case EXCEPTIONS:
if (type == DyvilKeywords.THROWS) {
pm.pushParser(new TypeListParser(this.member.getExceptions()));
this.mode = BODY;
return;
}
// Fallthrough
case BODY:
switch(type) {
case BaseSymbols.OPEN_CURLY_BRACKET:
pm.pushParser(new StatementListParser(this.member), true);
this.mode = END;
return;
case BaseSymbols.EQUALS:
pm.pushParser(new ExpressionParser(this.member));
this.mode = END;
return;
}
// Fallthrough
case END:
this.consumer.addConstructor(this.member);
pm.popParser(type != Tokens.EOF);
return;
case INIT_TYPE:
boolean isSuper = false;
switch(type) {
case DyvilKeywords.SUPER:
isSuper = true;
// Fallthrough
case DyvilKeywords.THIS:
final InitializerCall init = new InitializerCall(token.raw(), isSuper);
this.member.setInitializer(init);
this.mode = INIT_ARGUMENTS;
return;
}
pm.report(token, "initializer.call.type");
return;
case INIT_ARGUMENTS:
if (type == BaseSymbols.OPEN_PARENTHESIS) {
pm.pushParser(new ArgumentListParser(this.member.getInitializer()));
this.mode = INIT_END;
return;
}
pm.report(token, "initializer.call.open_paren");
this.mode = EXCEPTIONS;
return;
case INIT_END:
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.report(token, "initializer.call.close_paren");
return;
}
this.mode = EXCEPTIONS;
return;
}
}
use of dyvilx.tools.compiler.parser.type.TypeListParser in project Dyvil by Dyvil.
the class ClassDeclarationParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
int type = token.type();
switch(this.mode) {
case NAME:
if (!Tokens.isIdentifier(type)) {
pm.report(token, "class.identifier");
return;
}
final Name name = token.nameValue();
if (name.qualified.indexOf('$') >= 0) {
pm.report(Markers.syntaxError(token, "class.identifier.invalid", name, name.qualified));
}
this.theClass = this.consumer.createClass(token.raw(), name, this.classAttributes);
this.mode = GENERICS;
return;
case GENERICS:
if (type == BaseSymbols.SEMICOLON && token.isInferred() && TypeParser.isGenericStart(token.next())) {
// allow an implicit semicolon / line break between name and generic argument list
return;
}
if (TypeParser.isGenericStart(token, type)) {
pm.splitJump(token, 1);
pm.pushParser(new TypeParameterListParser(this.theClass));
this.mode = GENERICS_END;
return;
}
// Fallthrough
case PARAMETERS:
final Modifier modifier = ModifierParser.parseModifier(token, pm);
if (modifier != null) {
this.theClass.getConstructorAttributes().add(modifier);
return;
}
if (type == DyvilSymbols.AT) {
final Annotation annotation = new CodeAnnotation(token.raw());
this.theClass.getConstructorAttributes().add(annotation);
pm.pushParser(new AnnotationParser(annotation));
return;
}
if (type == BaseSymbols.OPEN_PARENTHESIS) {
pm.pushParser(new ParameterListParser(this.theClass).withFlags(ParameterListParser.ALLOW_PROPERTIES));
this.mode = PARAMETERS_END;
return;
}
// Fallthrough
case EXTENDS:
if (type == DyvilKeywords.EXTENDS) {
if (this.theClass.isInterface()) {
pm.pushParser(new TypeListParser(this));
this.mode = BODY;
return;
}
pm.pushParser(new TypeParser(this));
this.mode = EXTENDS_PARAMETERS;
return;
}
// Fallthrough
case IMPLEMENTS:
if (type == DyvilKeywords.IMPLEMENTS) {
pm.pushParser(new TypeListParser(this));
this.mode = BODY;
if (this.theClass.isInterface()) {
pm.report(token, "class.interface.implements");
return;
}
return;
}
// Fallthrough
case BODY:
if (type == BaseSymbols.OPEN_CURLY_BRACKET) {
ClassBody body = new ClassBody(this.theClass);
this.theClass.setBody(body);
pm.pushParser(new ClassBodyParser(body), true);
this.mode = BODY_END;
return;
}
if (BaseSymbols.isTerminator(type)) {
if (token.isInferred()) {
switch(token.next().type()) {
case DyvilKeywords.EXTENDS:
this.mode = EXTENDS;
return;
case DyvilKeywords.IMPLEMENTS:
this.mode = IMPLEMENTS;
return;
case BaseSymbols.OPEN_SQUARE_BRACKET:
this.mode = GENERICS;
return;
case BaseSymbols.OPEN_PARENTHESIS:
this.mode = PARAMETERS;
return;
}
}
pm.popParser(true);
this.consumer.addClass(this.theClass);
return;
}
this.mode = BODY_END;
pm.report(token, "class.body.separator");
return;
case GENERICS_END:
this.mode = PARAMETERS;
if (TypeParser.isGenericEnd(token, type)) {
pm.splitJump(token, 1);
return;
}
pm.reparse();
pm.report(token, "generic.close_angle");
return;
case PARAMETERS_END:
this.mode = EXTENDS;
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.reparse();
pm.report(token, "class.parameters.close_paren");
}
return;
case BODY_END:
pm.popParser();
this.consumer.addClass(this.theClass);
if (type != BaseSymbols.CLOSE_CURLY_BRACKET) {
pm.reparse();
pm.report(token, "class.body.close_brace");
}
return;
case EXTENDS_PARAMETERS_END:
this.mode = IMPLEMENTS;
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.reparse();
pm.report(token, "class.extends.close_paren");
}
return;
case EXTENDS_PARAMETERS:
if (type == BaseSymbols.OPEN_PARENTHESIS) {
ArgumentListParser.parseArguments(pm, token.next(), this.theClass::setSuperConstructorArguments);
this.mode = EXTENDS_PARAMETERS_END;
return;
}
this.mode = IMPLEMENTS;
pm.reparse();
}
}
use of dyvilx.tools.compiler.parser.type.TypeListParser in project Dyvil by Dyvil.
the class ExpressionParser method parseInfixAccess.
private void parseInfixAccess(IParserManager pm, IToken token, Name name, boolean forceInfix) {
final int type = token.type();
final IToken next = token.next();
final int nextType = next.type();
if (isSymbolic(type)) {
// Identifier is an operator
final IToken prev = token.prev();
final boolean leftNeighbor = prev.isNeighboring(token);
final boolean rightNeighbor = token.isNeighboring(next);
if (// prefix
this.value == null) {
if (// only true iff this.value == null
forceInfix) {
pm.report(SourcePosition.before(token), "expression.infix.before");
}
// OPERATOR EXPRESSION
// token next
this.mode = ACCESS;
if (this.isOperatorEnd(nextType)) {
this.value = new FieldAccess(token.raw(), null, name);
return;
}
final PrefixCall call = new PrefixCall(token.raw(), name);
this.value = call;
this.parseApply(pm, next, call);
return;
} else if (!forceInfix && !leftNeighbor && rightNeighbor) {
// Revert to Juxtaposition
this.parseApply(pm, token);
return;
}
if (this.isOperatorEnd(nextType) || !forceInfix && leftNeighbor && !rightNeighbor) {
if (// only true iff this.isOperatorEnd(nextType)
forceInfix) {
pm.report(SourcePosition.after(token), "expression.infix.after");
}
// EXPRESSION_OPERATOR EXPRESSION
// EXPRESSION OPERATOR EOF
// token next
this.value = new PostfixCall(token.raw(), this.value, name);
this.mode = ACCESS;
return;
}
if (this.hasFlag(IGNORE_OPERATOR)) {
this.valueConsumer.setValue(this.value);
pm.popParser(true);
return;
}
// EXPRESSION OPERATOR EXPRESSION
// token next
final InfixCallChain chain;
if (this.value.valueTag() == IValue.OPERATOR_CHAIN) {
chain = (InfixCallChain) this.value;
} else {
chain = new InfixCallChain();
chain.addOperand(this.value);
this.value = chain;
}
chain.addOperator(name, token.raw());
pm.pushParser(new ExpressionParser(chain::addOperand).withFlags(this.flags | IGNORE_OPERATOR));
return;
}
switch(nextType) {
case BaseSymbols.OPEN_PARENTHESIS:
{
// IDENTIFIER (
final MethodCall call = new MethodCall(token.raw(), this.value, name);
ArgumentListParser.parseArguments(pm, next.next(), call);
this.value = call;
this.mode = PARAMETERS_END;
pm.skip();
return;
}
case BaseSymbols.OPEN_SQUARE_BRACKET:
{
// IDENTIFIER [
final FieldAccess fieldAccess = new FieldAccess(token.raw(), this.value, name);
final SubscriptAccess subscriptAccess = new SubscriptAccess(next.raw(), fieldAccess);
ArgumentListParser.parseArguments(pm, next.next(), subscriptAccess);
this.value = subscriptAccess;
this.mode = SUBSCRIPT_END;
pm.skip();
return;
}
case DyvilSymbols.ARROW_RIGHT:
case DyvilSymbols.DOUBLE_ARROW_RIGHT:
if (this.hasFlag(IGNORE_LAMBDA)) {
break;
}
// IDENTIFIER => ...
// token next
// Lambda Expression with one untyped parameter
pm.pushParser(new LambdaOrTupleParser(this, LambdaOrTupleParser.SINGLE_PARAMETER), true);
this.mode = END;
return;
}
if (isGenericCall(next, nextType)) {
final MethodCall call = new MethodCall(token.raw(), this.value, name, ArgumentList.EMPTY);
this.value = call;
pm.splitJump(next, 1);
pm.pushParser(new TypeListParser(call.getGenericData().getTypes(), true));
this.mode = TYPE_ARGUMENTS_END;
return;
}
if (this.isFieldAccess(token, next, nextType)) {
this.value = new FieldAccess(token.raw(), this.value, name);
this.mode = ACCESS;
return;
}
// IDENTIFIER EXPRESSION
// token next
// Parse a single-argument call
// e.g. println "abc"
// println -1
// println i
final MethodCall call = new MethodCall(token.raw(), this.value, name, ArgumentList.empty());
this.value = call;
this.mode = ACCESS;
this.parseApply(pm, token.next(), call);
}
use of dyvilx.tools.compiler.parser.type.TypeListParser in project Dyvil by Dyvil.
the class MethodParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
final int type = token.type();
switch(this.mode) {
case DECLARATOR:
switch(type) {
case DyvilSymbols.AT:
this.parseAnnotation(pm, token);
return;
case DyvilKeywords.FUNC:
case DyvilKeywords.OPERATOR:
this.mode = METHOD_NAME;
return;
}
if (this.parseModifier(pm, token)) {
return;
}
// Fallthrough
case METHOD_NAME:
if (!Tokens.isIdentifier(type)) {
pm.report(token, "method.identifier");
return;
}
this.method = this.consumer.createMethod(token.raw(), token.nameValue(), Types.UNKNOWN, this.attributes);
this.mode = GENERICS;
return;
// Fallthrough
case GENERICS:
if (TypeParser.isGenericStart(token, type)) {
pm.splitJump(token, 1);
this.mode = GENERICS_END;
pm.pushParser(new TypeParameterListParser(this.method));
return;
}
// Fallthrough
case PARAMETERS:
if (type == BaseSymbols.OPEN_PARENTHESIS) {
this.mode = PARAMETERS_END;
pm.pushParser(new ParameterListParser(this.method));
return;
}
// Fallthrough
case TYPE:
switch(type) {
case BaseSymbols.COLON:
pm.report(Markers.syntaxWarning(token, "method.type.colon.deprecated"));
// Fallthrough
case DyvilSymbols.ARROW_RIGHT:
pm.pushParser(new TypeParser(this.method));
this.mode = EXCEPTIONS;
return;
}
// Fallthrough
case EXCEPTIONS:
if (type == DyvilKeywords.THROWS) {
pm.pushParser(new TypeListParser(this.method.getExceptions()));
this.mode = BODY;
return;
}
// Fallthrough
case BODY:
switch(type) {
case BaseSymbols.OPEN_CURLY_BRACKET:
pm.pushParser(new StatementListParser(this.method), true);
this.mode = END;
return;
case BaseSymbols.EQUALS:
pm.pushParser(new ExpressionParser(this.method));
this.mode = END;
return;
}
// Fallthrough
case END:
this.consumer.addMethod(this.method);
pm.popParser(type != Tokens.EOF);
return;
case GENERICS_END:
this.mode = PARAMETERS;
if (TypeParser.isGenericEnd(token, type)) {
pm.splitJump(token, 1);
return;
}
pm.reparse();
pm.report(token, "generic.close_angle");
return;
case PARAMETERS_END:
this.mode = TYPE;
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.reparse();
pm.report(token, "method.parameters.close_paren");
}
return;
}
}
Aggregations