use of dyvil.lang.Name in project Dyvil by Dyvil.
the class PatternParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
final int type = token.type();
switch(this.mode) {
case PATTERN:
switch(type) {
case DyvilKeywords.TRUE:
this.pattern = new BooleanPattern(token.raw(), true);
this.mode = END;
return;
case DyvilKeywords.FALSE:
this.pattern = new BooleanPattern(token.raw(), false);
this.mode = END;
return;
case DyvilSymbols.UNDERSCORE:
this.pattern = new WildcardPattern(token.raw());
this.mode = END;
return;
case DyvilKeywords.NULL:
this.pattern = new NullPattern(token.raw());
this.mode = END;
return;
case Tokens.STRING:
this.pattern = new StringPattern(token.raw(), token.stringValue());
this.mode = END;
return;
case Tokens.SINGLE_QUOTED_STRING:
this.pattern = new CharPattern(token.raw(), token.stringValue());
this.mode = END;
return;
case Tokens.VERBATIM_CHAR:
this.pattern = new CharPattern(token.raw(), token.stringValue(), true);
this.mode = END;
return;
case Tokens.INT:
this.pattern = new IntPattern(token.raw(), token.intValue());
this.mode = END;
return;
case Tokens.LONG:
this.pattern = new LongPattern(token.raw(), token.longValue());
this.mode = END;
return;
case Tokens.FLOAT:
this.pattern = new FloatPattern(token.raw(), token.floatValue());
this.mode = END;
return;
case Tokens.DOUBLE:
this.pattern = new DoublePattern(token.raw(), token.doubleValue());
this.mode = END;
return;
case DyvilKeywords.VAR:
case DyvilKeywords.LET:
final BindingPattern pattern = new BindingPattern();
pm.pushParser(new DataMemberParser<>(pattern), true);
this.pattern = pattern;
this.mode = END;
return;
case BaseSymbols.OPEN_PARENTHESIS:
final dyvilx.tools.compiler.ast.pattern.object.TuplePattern tuplePattern = new dyvilx.tools.compiler.ast.pattern.object.TuplePattern(token);
this.pattern = tuplePattern;
this.mode = TUPLE_END;
pm.pushParser(new PatternListParser(tuplePattern));
return;
case BaseSymbols.DOT:
this.mode = ENUM_IDENTIFIER;
return;
}
if (Tokens.isIdentifier(type)) {
if (token.nameValue() == Names.minus) {
this.mode = NEGATIVE_NUMBER;
return;
}
this.mode = TYPE_END;
pm.pushParser(new TypeParser(this).withFlags(TypeParser.NAMED_ONLY), true);
return;
}
if (BaseSymbols.isTerminator(type)) {
pm.popParser(true);
}
pm.report(Markers.syntaxError(token, "pattern.invalid", token.toString()));
return;
case NEGATIVE_NUMBER:
switch(type) {
case Tokens.INT:
this.pattern = new IntPattern(token.prev().to(token), -token.intValue());
this.mode = END;
return;
case Tokens.LONG:
this.pattern = new LongPattern(token.prev().to(token), -token.intValue());
this.mode = END;
return;
case Tokens.FLOAT:
this.pattern = new FloatPattern(token.prev().to(token), -token.intValue());
this.mode = END;
return;
case Tokens.DOUBLE:
this.pattern = new DoublePattern(token.prev().to(token), -token.intValue());
this.mode = END;
return;
default:
pm.report(token, "pattern.number.negative");
this.mode = END;
pm.reparse();
return;
}
case ENUM_IDENTIFIER:
if (Tokens.isIdentifier(type)) {
this.pattern = new dyvilx.tools.compiler.ast.pattern.object.EnumPattern(token.raw(), token.nameValue());
this.mode = END;
return;
}
pm.report(token, "pattern.enum.identifier");
return;
case TYPE_END:
if (type == BaseSymbols.OPEN_PARENTHESIS) {
// TYPE ( ...
// => Unapply pattern
final dyvilx.tools.compiler.ast.pattern.object.UnapplyPattern unapplyPattern = new UnapplyPattern(token, this.type);
pm.pushParser(new PatternListParser(unapplyPattern));
this.pattern = unapplyPattern;
this.mode = CASE_CLASS_END;
return;
}
// TYPE
// => Object Pattern
this.pattern = new dyvilx.tools.compiler.ast.pattern.object.ObjectPattern(this.type.getPosition(), this.type);
this.mode = END;
pm.reparse();
return;
case TUPLE_END:
this.mode = END;
this.pattern.expandPosition(token);
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.report(token, "pattern.tuple.close_paren");
}
return;
case CASE_CLASS_END:
this.mode = END;
this.pattern.expandPosition(token);
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.report(token, "pattern.case_class.close_paren");
}
return;
case END:
if (type == DyvilKeywords.AS) {
final TypeCheckPattern typeCheck = new TypeCheckPattern(token.raw(), this.pattern);
this.pattern = typeCheck;
pm.pushParser(new TypeParser(typeCheck));
return;
}
if (Tokens.isIdentifier(type)) {
final Name name = token.nameValue();
if (name == Names.bar) {
if (this.checkPrecedence(OPERATOR_OR)) {
this.endPattern(pm);
return;
}
final OrPattern orPattern = new OrPattern(this.pattern, token.raw(), null);
this.pattern = orPattern;
pm.pushParser(new PatternParser(orPattern::setRight, OPERATOR_OR));
return;
}
if (name == Names.amp) {
if (this.checkPrecedence(OPERATOR_AND)) {
this.endPattern(pm);
return;
}
final AndPattern andPattern = new AndPattern(this.pattern, token.raw(), null);
this.pattern = andPattern;
pm.pushParser(new PatternParser(andPattern::setRight, OPERATOR_AND));
return;
}
}
this.endPattern(pm);
}
}
use of dyvil.lang.Name in project Dyvil by Dyvil.
the class OperatorParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
final int type = token.type();
switch(this.mode) {
case TYPE:
this.mode = OPERATOR;
switch(type) {
case DyvilKeywords.PREFIX:
if (token.next().type() == DyvilKeywords.POSTFIX) {
pm.skip();
this.type = IOperator.CIRCUMFIX;
return;
}
this.type = IOperator.PREFIX;
return;
case DyvilKeywords.POSTFIX:
this.type = IOperator.POSTFIX;
return;
case DyvilKeywords.INFIX:
this.type = IOperator.INFIX;
return;
}
pm.report(token, "operator.type.invalid");
return;
case OPERATOR:
this.mode = OPERATOR_SYMBOL;
if (type != DyvilKeywords.OPERATOR) {
pm.reparse();
pm.report(token, "operator.operator");
}
return;
case OPERATOR_SYMBOL:
{
Name name = getOperatorName(pm, token);
if (name == null) {
pm.report(token, "operator.identifier");
return;
}
this.operator = new Operator(name, this.type);
// TODO Add 'ternary' keyword?
if (this.type == IOperator.INFIX) {
name = getOperatorName(pm, token.next());
if (name != null) {
this.operator.setType(IOperator.TERNARY);
this.operator.setName2(name);
pm.skip();
}
} else if (this.type == IOperator.CIRCUMFIX || this.type == IOperator.TERNARY) {
name = getOperatorName(pm, token.next());
if (name != null) {
this.operator.setName2(name);
pm.skip();
} else {
pm.report(SourcePosition.between(token, token.next()), "operator.identifier2");
}
}
this.mode = SEPARATOR;
return;
}
case SEPARATOR:
switch(type) {
case BaseSymbols.SEMICOLON:
pm.popParser(true);
this.map.addOperator(this.operator);
return;
case Tokens.EOF:
pm.popParser();
this.map.addOperator(this.operator);
return;
case BaseSymbols.OPEN_CURLY_BRACKET:
this.mode = PROPERTY;
return;
}
pm.popParser(true);
this.map.addOperator(this.operator);
pm.report(token, "operator.separator");
return;
case PROPERTY:
switch(type) {
case Tokens.LETTER_IDENTIFIER:
final Name name = token.nameValue();
if (name == precedence) {
this.mode = PRECEDENCE;
return;
}
if (name == associativity) {
this.mode = ASSOCIATIVITY;
return;
}
if (this.parseAssociativity(pm, token, name)) {
this.mode = COMMA;
return;
}
break;
case BaseSymbols.CLOSE_CURLY_BRACKET:
pm.popParser();
this.map.addOperator(this.operator);
return;
}
if ((type & Tokens.INT) != 0) {
this.setPrecedence(pm, token, token.intValue());
this.mode = COMMA;
return;
}
pm.report(Markers.syntaxError(token, "operator.property.invalid", token));
return;
case COMMA:
if (type == BaseSymbols.CLOSE_CURLY_BRACKET) {
pm.popParser();
this.map.addOperator(this.operator);
return;
}
this.mode = PROPERTY;
if (type != BaseSymbols.COMMA) {
pm.reparse();
pm.report(token, "operator.property.comma");
return;
}
return;
case PRECEDENCE:
this.mode = COMMA;
if ((type & Tokens.INT) == 0) {
pm.reparse();
pm.report(token, "operator.property.precedence");
return;
}
this.setPrecedence(pm, token, token.intValue());
return;
case ASSOCIATIVITY:
this.mode = COMMA;
if (type == Tokens.LETTER_IDENTIFIER) {
final Name name = token.nameValue();
if (this.parseAssociativity(pm, token, name)) {
return;
}
}
pm.reparse();
pm.report(token, "operator.property.associativity");
}
}
use of dyvil.lang.Name in project Dyvil by Dyvil.
the class TypeParameterParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
final int type = token.type();
switch(this.mode) {
case ANNOTATIONS:
switch(type) {
case DyvilSymbols.AT:
final Annotation annotation = new CodeAnnotation(token.raw());
this.attributes.add(annotation);
pm.pushParser(new AnnotationParser(annotation));
return;
case DyvilKeywords.TYPE:
// type IDENTIFIER
// type +IDENTIFIER
// type -IDENTIFIER
this.mode = VARIANCE;
return;
case BaseSymbols.SEMICOLON:
if (token.isInferred()) {
return;
}
}
if (TypeParser.isGenericEnd(token, type)) {
pm.popParser(true);
return;
}
// Fallthrough
case VARIANCE:
{
if (!Tokens.isIdentifier(type)) {
pm.report(token, "type_parameter.identifier");
return;
}
final Name name = token.nameValue();
if (Tokens.isIdentifier(token.next().type())) {
if (name == Names.plus) {
this.mode = NAME;
this.variance = Variance.COVARIANT;
return;
}
if (name == Names.minus) {
this.mode = NAME;
this.variance = Variance.CONTRAVARIANT;
return;
}
}
this.createTypeParameter(token, this.variance);
return;
}
case NAME:
if (Tokens.isIdentifier(type)) {
this.createTypeParameter(token, this.variance);
return;
}
pm.report(token, "type_parameter.identifier");
return;
case TYPE_BOUNDS:
switch(type) {
case DyvilKeywords.EXTENDS:
case BaseSymbols.COLON:
// type T: Super
// type T extends Super
pm.pushParser(this.newTypeParser());
this.setBoundMode(UPPER_BOUND);
return;
case DyvilKeywords.SUPER:
pm.pushParser(this.newTypeParser());
this.setBoundMode(LOWER_BOUND);
return;
}
if (BaseSymbols.isTerminator(type) || TypeParser.isGenericEnd(token, type)) {
if (this.typeParameter != null) {
this.typeParameterized.getTypeParameters().add(this.typeParameter);
}
pm.popParser(true);
return;
}
if (this.typeParameter != null) {
this.typeParameterized.getTypeParameters().add(this.typeParameter);
}
pm.popParser(true);
pm.report(token, "type_parameter.bound.invalid");
}
}
use of dyvil.lang.Name in project Dyvil by Dyvil.
the class FieldAssignment method resolveAsMethod.
@Override
protected IValue resolveAsMethod(IValue receiver, MarkerList markers, IContext context) {
final Name name = Util.addEq(this.name);
final ArgumentList argument = new ArgumentList(this.value);
final MethodAssignment assignment = new MethodAssignment(this.position, receiver, name, argument);
return assignment.resolveCall(markers, context, false);
}
use of dyvil.lang.Name in project Dyvil by Dyvil.
the class CodeTypeParameter method computeReifiedKind.
@Override
protected void computeReifiedKind() {
super.computeReifiedKind();
final IType type;
final Reified.Type reifiedKind = this.getReifiedKind();
if (reifiedKind == Reified.Type.TYPE) {
type = TypeOperator.LazyFields.TYPE;
} else if (reifiedKind != null) {
type = ClassOperator.LazyFields.CLASS;
} else {
return;
}
if (this.getReifiedKind() != null) {
final AttributeList attributes = AttributeList.of(Modifiers.MANDATED | Modifiers.SYNTHETIC | Modifiers.FINAL);
final Name name = Name.apply("reify_" + this.getName().qualified);
final CodeParameter parameter = new CodeParameter(null, this.getPosition(), name, type, attributes);
this.setReifyParameter(parameter);
}
}
Aggregations