Search in sources :

Example 1 with HeaderDeclaration

use of dyvilx.tools.compiler.ast.header.HeaderDeclaration in project Dyvil by Dyvil.

the class SourceFileParser method parse.

@Override
public void parse(IParserManager pm, IToken token) {
    final int type = token.type();
    switch(this.mode) {
        case SEPARATOR:
            if (this.unit.classCount() > 0) {
                // any classes -> only allow classes from here
                this.mode = CLASS;
            } else if (this.unit.importCount() > 0 || this.unit.typeAliasCount() > 0 || this.unit.operatorCount() > 0 || this.unit.getHeaderDeclaration() != null) {
                // any imports, type aliases, operators or header declarations -> don't allow any package declarations
                this.mode = IMPORT;
            } else {
                // nothing defined yet -> allow a package declaration
                this.mode = PACKAGE;
            }
            if (!checkEnd(pm, type)) {
                pm.report(token, "header.separator");
                pm.reparse();
            }
            return;
        case PACKAGE:
            if (type == DyvilKeywords.PACKAGE) {
                PackageDeclaration pack = new PackageDeclaration(token.raw());
                this.unit.setPackageDeclaration(pack);
                pm.pushParser(new PackageParser(pack));
                this.mode = SEPARATOR;
                return;
            }
        // Fallthrough
        case IMPORT:
            switch(type) {
                case DyvilKeywords.IMPORT:
                    pm.pushParser(new ImportParser(this.importConsumer(token)));
                    this.mode = SEPARATOR;
                    return;
                case DyvilKeywords.USING:
                    pm.pushParser(new ImportParser(this.importConsumer(token), KindedImport.USING_DECLARATION));
                    this.mode = SEPARATOR;
                    return;
                case DyvilKeywords.OPERATOR:
                    pm.pushParser(new OperatorParser(this.unit, Operator.INFIX), true);
                    this.mode = SEPARATOR;
                    return;
                case DyvilKeywords.PREFIX:
                case DyvilKeywords.POSTFIX:
                case DyvilKeywords.INFIX:
                    if (// 
                    token.next().type() == DyvilKeywords.OPERATOR || token.next().type() == DyvilKeywords.POSTFIX && token.next().next().type() == DyvilKeywords.OPERATOR) {
                        pm.pushParser(new OperatorParser(this.unit), true);
                        this.mode = SEPARATOR;
                        return;
                    }
                    // parse as modifier (in 'case CLASS' via fallthrough)
                    break;
                case DyvilKeywords.TYPE:
                    pm.pushParser(new TypeAliasParser(this.unit, new TypeAlias()));
                    this.mode = SEPARATOR;
                    return;
                case DyvilKeywords.HEADER:
                    final IToken next = token.next();
                    if (!Tokens.isIdentifier(next.type())) {
                        this.attributes = new AttributeList();
                        pm.report(next, "header.declaration.identifier");
                        return;
                    }
                    pm.skip();
                    if (this.unit.getHeaderDeclaration() != null) {
                        this.attributes = new AttributeList();
                        pm.report(token, "header.declaration.duplicate");
                        this.mode = SEPARATOR;
                        return;
                    }
                    final HeaderDeclaration declaration = new HeaderDeclaration(this.unit, next.raw(), next.nameValue(), this.attributes);
                    this.unit.setHeaderDeclaration(declaration);
                    // reset
                    this.attributes = new AttributeList();
                    this.mode = SEPARATOR;
                    return;
            }
        // Fallthrough
        case CLASS:
            if (this.parseAttribute(pm, token)) {
                return;
            }
            final int classType;
            if ((classType = ModifierParser.parseClassTypeModifier(token, pm)) >= 0) {
                if ((this.flags & NO_CLASSES) != 0) {
                    pm.report(token, "header.class");
                }
                this.attributes.addFlag(classType);
                pm.pushParser(new ClassDeclarationParser(this.unit, this.attributes));
                // reset
                this.attributes = new AttributeList();
                this.mode = SEPARATOR;
                return;
            }
    }
    if (!checkEnd(pm, type)) {
        pm.report(Markers.syntaxError(token, "header.element.invalid", token.toString()));
    }
}
Also used : IToken(dyvilx.tools.parsing.token.IToken) ClassDeclarationParser(dyvilx.tools.compiler.parser.classes.ClassDeclarationParser) AttributeList(dyvilx.tools.compiler.ast.attribute.AttributeList) TypeAlias(dyvilx.tools.compiler.ast.type.alias.TypeAlias) HeaderDeclaration(dyvilx.tools.compiler.ast.header.HeaderDeclaration) PackageDeclaration(dyvilx.tools.compiler.ast.header.PackageDeclaration)

Example 2 with HeaderDeclaration

use of dyvilx.tools.compiler.ast.header.HeaderDeclaration in project Dyvil by Dyvil.

the class SingleImport method checkInline.

private boolean checkInline(MarkerList markers, IContext context, IHeaderUnit header) {
    // Check if the Header has a Header Declaration
    final HeaderDeclaration headerDeclaration = header.getHeaderDeclaration();
    if (headerDeclaration == null) {
        return header.isHeader();
    }
    // Header Access Check
    int accessLevel = headerDeclaration.getAttributes().flags() & Modifiers.ACCESS_MODIFIERS;
    if ((accessLevel & Modifiers.INTERNAL) != 0) {
        if (header instanceof ExternalHeader) {
            markers.add(Markers.semanticError(this.position, "import.inline_header.internal", header.getName()));
            return false;
        }
        accessLevel &= 0b1111;
    }
    switch(accessLevel) {
        case Modifiers.PACKAGE:
        case Modifiers.PROTECTED:
            if (header.getPackage() == context.getHeader().getPackage()) {
                return true;
            }
        // Fallthrough
        case Modifiers.PRIVATE:
            markers.add(Markers.semanticError(this.position, "import.inline_header.invisible", header.getName()));
            return false;
    }
    // All checks passed
    return true;
}
Also used : HeaderDeclaration(dyvilx.tools.compiler.ast.header.HeaderDeclaration) ExternalHeader(dyvilx.tools.compiler.ast.external.ExternalHeader)

Aggregations

HeaderDeclaration (dyvilx.tools.compiler.ast.header.HeaderDeclaration)2 AttributeList (dyvilx.tools.compiler.ast.attribute.AttributeList)1 ExternalHeader (dyvilx.tools.compiler.ast.external.ExternalHeader)1 PackageDeclaration (dyvilx.tools.compiler.ast.header.PackageDeclaration)1 TypeAlias (dyvilx.tools.compiler.ast.type.alias.TypeAlias)1 ClassDeclarationParser (dyvilx.tools.compiler.parser.classes.ClassDeclarationParser)1 IToken (dyvilx.tools.parsing.token.IToken)1