Search in sources :

Example 21 with Name

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);
    }
}
Also used : TypeParser(dyvilx.tools.compiler.parser.type.TypeParser) dyvilx.tools.compiler.ast.pattern(dyvilx.tools.compiler.ast.pattern) AndPattern(dyvilx.tools.compiler.ast.pattern.operator.AndPattern) Name(dyvil.lang.Name) UnapplyPattern(dyvilx.tools.compiler.ast.pattern.object.UnapplyPattern) UnapplyPattern(dyvilx.tools.compiler.ast.pattern.object.UnapplyPattern) OrPattern(dyvilx.tools.compiler.ast.pattern.operator.OrPattern)

Example 22 with Name

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");
    }
}
Also used : IOperator(dyvilx.tools.compiler.ast.expression.operator.IOperator) Operator(dyvilx.tools.compiler.ast.expression.operator.Operator) Name(dyvil.lang.Name)

Example 23 with Name

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");
    }
}
Also used : CodeAnnotation(dyvilx.tools.compiler.ast.attribute.annotation.CodeAnnotation) AnnotationParser(dyvilx.tools.compiler.parser.annotation.AnnotationParser) CodeAnnotation(dyvilx.tools.compiler.ast.attribute.annotation.CodeAnnotation) Annotation(dyvilx.tools.compiler.ast.attribute.annotation.Annotation) Name(dyvil.lang.Name)

Example 24 with Name

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);
}
Also used : ArgumentList(dyvilx.tools.compiler.ast.parameter.ArgumentList) Name(dyvil.lang.Name)

Example 25 with Name

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);
    }
}
Also used : AttributeList(dyvilx.tools.compiler.ast.attribute.AttributeList) Reified(dyvil.annotation.Reified) CodeParameter(dyvilx.tools.compiler.ast.parameter.CodeParameter) IType(dyvilx.tools.compiler.ast.type.IType) Name(dyvil.lang.Name)

Aggregations

Name (dyvil.lang.Name)33 Annotation (dyvilx.tools.compiler.ast.attribute.annotation.Annotation)4 CodeAnnotation (dyvilx.tools.compiler.ast.attribute.annotation.CodeAnnotation)4 AnnotationParser (dyvilx.tools.compiler.parser.annotation.AnnotationParser)4 TypeParser (dyvilx.tools.compiler.parser.type.TypeParser)4 IClass (dyvilx.tools.compiler.ast.classes.IClass)3 IField (dyvilx.tools.compiler.ast.field.IField)3 IParameter (dyvilx.tools.compiler.ast.parameter.IParameter)3 IType (dyvilx.tools.compiler.ast.type.IType)3 AttributeList (dyvilx.tools.compiler.ast.attribute.AttributeList)2 Modifier (dyvilx.tools.compiler.ast.attribute.modifiers.Modifier)2 IValue (dyvilx.tools.compiler.ast.expression.IValue)2 IOperator (dyvilx.tools.compiler.ast.expression.operator.IOperator)2 IDataMember (dyvilx.tools.compiler.ast.field.IDataMember)2 IProperty (dyvilx.tools.compiler.ast.field.IProperty)2 IMethod (dyvilx.tools.compiler.ast.method.IMethod)2 ArgumentList (dyvilx.tools.compiler.ast.parameter.ArgumentList)2 CodeParameter (dyvilx.tools.compiler.ast.parameter.CodeParameter)2 NamedType (dyvilx.tools.compiler.ast.type.raw.NamedType)2 ExpressionParser (dyvilx.tools.compiler.parser.expression.ExpressionParser)2