Search in sources :

Example 1 with TypeListParser

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;
    }
}
Also used : StatementListParser(dyvilx.tools.compiler.parser.statement.StatementListParser) ParameterListParser(dyvilx.tools.compiler.parser.method.ParameterListParser) TypeListParser(dyvilx.tools.compiler.parser.type.TypeListParser) ExpressionParser(dyvilx.tools.compiler.parser.expression.ExpressionParser) ArgumentListParser(dyvilx.tools.compiler.parser.expression.ArgumentListParser) InitializerCall(dyvilx.tools.compiler.ast.expression.access.InitializerCall)

Example 2 with TypeListParser

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();
    }
}
Also used : CodeAnnotation(dyvilx.tools.compiler.ast.attribute.annotation.CodeAnnotation) AnnotationParser(dyvilx.tools.compiler.parser.annotation.AnnotationParser) TypeParser(dyvilx.tools.compiler.parser.type.TypeParser) ParameterListParser(dyvilx.tools.compiler.parser.method.ParameterListParser) TypeParameterListParser(dyvilx.tools.compiler.parser.type.TypeParameterListParser) TypeListParser(dyvilx.tools.compiler.parser.type.TypeListParser) Modifier(dyvilx.tools.compiler.ast.attribute.modifiers.Modifier) TypeParameterListParser(dyvilx.tools.compiler.parser.type.TypeParameterListParser) Annotation(dyvilx.tools.compiler.ast.attribute.annotation.Annotation) CodeAnnotation(dyvilx.tools.compiler.ast.attribute.annotation.CodeAnnotation) Name(dyvil.lang.Name) ClassBody(dyvilx.tools.compiler.ast.classes.ClassBody)

Example 3 with TypeListParser

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);
}
Also used : InfixCallChain(dyvilx.tools.compiler.ast.expression.operator.InfixCallChain) TypeListParser(dyvilx.tools.compiler.parser.type.TypeListParser) PostfixCall(dyvilx.tools.compiler.ast.expression.operator.PostfixCall) IToken(dyvilx.tools.parsing.token.IToken) PrefixCall(dyvilx.tools.compiler.ast.expression.operator.PrefixCall)

Example 4 with TypeListParser

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;
    }
}
Also used : StatementListParser(dyvilx.tools.compiler.parser.statement.StatementListParser) TypeParser(dyvilx.tools.compiler.parser.type.TypeParser) TypeParameterListParser(dyvilx.tools.compiler.parser.type.TypeParameterListParser) ParameterListParser(dyvilx.tools.compiler.parser.method.ParameterListParser) TypeListParser(dyvilx.tools.compiler.parser.type.TypeListParser) ExpressionParser(dyvilx.tools.compiler.parser.expression.ExpressionParser) TypeParameterListParser(dyvilx.tools.compiler.parser.type.TypeParameterListParser)

Aggregations

TypeListParser (dyvilx.tools.compiler.parser.type.TypeListParser)4 ParameterListParser (dyvilx.tools.compiler.parser.method.ParameterListParser)3 ExpressionParser (dyvilx.tools.compiler.parser.expression.ExpressionParser)2 StatementListParser (dyvilx.tools.compiler.parser.statement.StatementListParser)2 TypeParameterListParser (dyvilx.tools.compiler.parser.type.TypeParameterListParser)2 TypeParser (dyvilx.tools.compiler.parser.type.TypeParser)2 Name (dyvil.lang.Name)1 Annotation (dyvilx.tools.compiler.ast.attribute.annotation.Annotation)1 CodeAnnotation (dyvilx.tools.compiler.ast.attribute.annotation.CodeAnnotation)1 Modifier (dyvilx.tools.compiler.ast.attribute.modifiers.Modifier)1 ClassBody (dyvilx.tools.compiler.ast.classes.ClassBody)1 InitializerCall (dyvilx.tools.compiler.ast.expression.access.InitializerCall)1 InfixCallChain (dyvilx.tools.compiler.ast.expression.operator.InfixCallChain)1 PostfixCall (dyvilx.tools.compiler.ast.expression.operator.PostfixCall)1 PrefixCall (dyvilx.tools.compiler.ast.expression.operator.PrefixCall)1 AnnotationParser (dyvilx.tools.compiler.parser.annotation.AnnotationParser)1 ArgumentListParser (dyvilx.tools.compiler.parser.expression.ArgumentListParser)1 IToken (dyvilx.tools.parsing.token.IToken)1