Mercurial > projects > dil
diff trunk/src/dil/semantic/Pass1.d @ 683:1ae72234db26
Implemented some methods in SemanticPass1.
Renamed Symbol.ident to name.
Added a constructor to Symbol.
Adapted constructors of classes that inherit from Symbol.
Added Alias and OverloadSet Symbol classes.
Renamed idents and values to names and inits in VariablesDeclaration.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Mon, 21 Jan 2008 17:10:12 +0100 |
parents | 6b3e397229c5 |
children | e8c09d13f2a5 |
line wrap: on
line diff
--- a/trunk/src/dil/semantic/Pass1.d Sat Jan 19 20:35:45 2008 +0100 +++ b/trunk/src/dil/semantic/Pass1.d Mon Jan 21 17:10:12 2008 +0100 @@ -11,6 +11,7 @@ dil.ast.Statements, dil.ast.Types, dil.ast.Parameters; +import dil.lexer.Identifier; import dil.semantic.Symbol, dil.semantic.Symbols, dil.semantic.Types, @@ -20,6 +21,8 @@ import dil.Location; import dil.Information; import dil.Messages; +import dil.Enums; +import dil.CompilerInfo; import common; class SemanticPass1 : Visitor @@ -27,6 +30,12 @@ Scope scop; /// The current scope. Module modul; /// The module to be semantically checked. + // Attributes: + LinkageType linkageType; + Protection protection; + StorageClass storageClass; + uint alignSize = DEFAULT_ALIGN_SIZE; + this(Module modul) { this.modul = modul; @@ -40,7 +49,7 @@ scop = new Scope(); scop.symbol = modul; // Set this module as the scope's symbol. scop.infoMan = modul.infoMan; - visitN(modul.root); + visit(modul.root); } void enterScope(ScopeSymbol s) @@ -53,6 +62,44 @@ scop = scop.exit(); } + /// Insert a symbol into the current scope. + void insert(Symbol sym, Identifier* ident) + { + auto sym2 = scop.symbol.lookup(ident); + if (sym2) + reportSymbolConflict(sym, sym2, ident); + else + scop.symbol.insert(sym, ident); + // Set the current scope symbol as the parent. + sym.parent = scop.symbol; + } + + /// Insert a symbol, overloading on the name, into the current scope. + void insertOverload(Symbol sym, Identifier* ident) + { + auto sym2 = scop.symbol.lookup(ident); + if (sym2) + { + if (sym2.isOverloadSet) + (cast(OverloadSet)cast(void*)sym2).add(sym); + else + reportSymbolConflict(sym, sym2, ident); + } + else + // Create a new overload set. + scop.symbol.insert(new OverloadSet(ident, sym.node), ident); + // Set the current scope symbol as the parent. + sym.parent = scop.symbol; + } + + /// Report error: new symbol s1 conflicts with existing symbol s2. + void reportSymbolConflict(Symbol s1, Symbol s2, Identifier* ident) + { + auto loc = s2.node.begin.getErrorLocation(); + auto locString = Format("{}({},{})", loc.filePath, loc.lineNum, loc.colNum); + error(s1.node.begin, MSG.DeclConflictsWithDecl, ident.str, locString); + } + void error(Token* token, char[] formatMsg, ...) { auto location = token.getErrorLocation(); @@ -60,9 +107,11 @@ modul.infoMan ~= new SemanticError(location, msg); } + private alias Declaration D; + override { - Declaration visit(CompoundDeclaration d) + D visit(CompoundDeclaration d) { foreach (node; d.children) { @@ -72,18 +121,18 @@ return d; } - Declaration visit(IllegalDeclaration) + D visit(IllegalDeclaration) { assert(0, "semantic pass on invalid AST"); return null; } - Declaration visit(EmptyDeclaration ed) + D visit(EmptyDeclaration ed) { return ed; } - Declaration visit(ModuleDeclaration) + D visit(ModuleDeclaration) { return null; } - Declaration visit(ImportDeclaration) + D visit(ImportDeclaration) { return null; } - Declaration visit(AliasDeclaration ad) + D visit(AliasDeclaration ad) { /+ decl.semantic(scop); // call semantic() or do SA in if statements? @@ -99,7 +148,7 @@ return ad; } - Declaration visit(TypedefDeclaration td) + D visit(TypedefDeclaration td) { /+ decl.semantic(scop); // call semantic() or do SA in if statements? @@ -115,52 +164,39 @@ return td; } - Declaration visit(EnumDeclaration ed) + D visit(EnumDeclaration d) { - /+ // Create the symbol. - symbol = new Enum(name, this); - // Type semantics. - Type type = Types.Int; // Default to integer. - if (baseType) - type = baseType.semantic(scop); - auto enumType = new EnumType(symbol, type); - // Set the base type of the enum symbol. - symbol.setType(enumType); - if (name) - { // Insert named enum into scope. - scop.insert(symbol, symbol.ident); - // Create new scope. - scop = scop.push(symbol); + d.symbol = new Enum(d.name, d); + if (d.name) + { // Declare named enum. + insert(d.symbol, d.name); + enterScope(d.symbol); } - // Semantic on members. - foreach (member; members) + // Declare members. + foreach (member; d.members) { - auto value = member.value; - if (value) - { - // value = value.semantic(scop); - // value = value.evaluate(); - } - auto variable = new Variable(StorageClass.Const, LinkageType.None, type, member.name, member); - scop.insert(variable, variable.ident); + auto variable = new Variable(member.name, protection, storageClass, linkageType, member); + insert(variable, variable.name); } - if (name) - scop.pop(); - +/ - return ed; + if (d.name) + exitScope(); + return d; } - Declaration visit(EnumMemberDeclaration) + D visit(EnumMemberDeclaration) { return null; } - Declaration visit(ClassDeclaration d) + D visit(ClassDeclaration d) { if (d.symbol) return d; d.symbol = new Class(d.name, d); // Insert into current scope. - scop.insert(d.symbol, d.name); + if (d.tparams) + insertOverload(d.symbol, d.name); + else + insert(d.symbol, d.name); enterScope(d.symbol); // Continue semantic analysis. d.decls && visitD(d.decls); @@ -168,13 +204,16 @@ return d; } - Declaration visit(InterfaceDeclaration d) + D visit(InterfaceDeclaration d) { if (d.symbol) return d; d.symbol = new dil.semantic.Symbols.Interface(d.name, d); // Insert into current scope. - scop.insert(d.symbol, d.name); + if (d.tparams) + insertOverload(d.symbol, d.name); + else + insert(d.symbol, d.name); enterScope(d.symbol); // Continue semantic analysis. d.decls && visitD(d.decls); @@ -182,14 +221,39 @@ return d; } - Declaration visit(StructDeclaration d) + D visit(StructDeclaration d) { if (d.symbol) return d; d.symbol = new Struct(d.name, d); // Insert into current scope. if (d.name) - scop.insert(d.symbol, d.name); + { + if (d.tparams) + insertOverload(d.symbol, d.name); + else + insert(d.symbol, d.name); + } + enterScope(d.symbol); + // Continue semantic analysis. + d.decls && visitD(d.decls); + exitScope(); + return d; + } + + D visit(UnionDeclaration d) + { + if (d.symbol) + return d; + d.symbol = new Union(d.name, d); + // Insert into current scope. + if (d.name) + { + if (d.tparams) + insertOverload(d.symbol, d.name); + else + insert(d.symbol, d.name); + } enterScope(d.symbol); // Continue semantic analysis. d.decls && visitD(d.decls); @@ -197,96 +261,109 @@ return d; } - Declaration visit(UnionDeclaration d) + D visit(ConstructorDeclaration) + { return null; } + D visit(StaticConstructorDeclaration) + { return null; } + D visit(DestructorDeclaration) + { return null; } + D visit(StaticDestructorDeclaration) + { return null; } + D visit(FunctionDeclaration) + { return null; } + + D visit(VariablesDeclaration vd) + { + // Error if we are in an interface. + if (scop.isInterface) + return error(vd.begin, MSG.InterfaceCantHaveVariables), vd; + + // Insert variable symbols in this declaration into the symbol table. + foreach (name; vd.names) + { + auto variable = new Variable(name, protection, storageClass, linkageType, vd); + vd.variables ~= variable; + insert(variable, name); + } + return vd; + } + + D visit(InvariantDeclaration) + { return null; } + D visit(UnittestDeclaration) + { return null; } + D visit(DebugDeclaration) + { return null; } + D visit(VersionDeclaration) + { return null; } + + D visit(StaticIfDeclaration d) + { + visitE(d.condition); + visitD(d.ifDecls); + d.elseDecls && visitD(d.elseDecls); + return null; + } + + D visit(StaticAssertDeclaration d) + { return d; } // SP2 + + D visit(TemplateDeclaration d) { if (d.symbol) return d; - d.symbol = new Union(d.name, d); + d.symbol = new Template(d.name, d); // Insert into current scope. - if (d.name) - scop.insert(d.symbol, d.name); + insertOverload(d.symbol, d.name); enterScope(d.symbol); // Continue semantic analysis. - d.decls && visitD(d.decls); + visitD(d.decls); exitScope(); return d; } - Declaration visit(ConstructorDeclaration) - { return null; } - Declaration visit(StaticConstructorDeclaration) - { return null; } - Declaration visit(DestructorDeclaration) - { return null; } - Declaration visit(StaticDestructorDeclaration) - { return null; } - Declaration visit(FunctionDeclaration) - { return null; } - - Declaration visit(VariablesDeclaration vd) - { - Type type = Types.Undefined; + D visit(NewDeclaration) + { /*add id to env*/return null; } + D visit(DeleteDeclaration) + { /*add id to env*/return null; } - if (vd.typeNode) - // Get type from typeNode. - type = visitT(vd.typeNode).type; - else - { // Infer type from first initializer. - auto firstInit = vd.values[0]; - firstInit = visitE(firstInit); - type = firstInit.type; - } - //assert(type !is null); - - // Check if we are in an interface. - if (scop.isInterface) - return error(vd.begin, MSG.InterfaceCantHaveVariables), vd; - - // Iterate over variable identifiers in this declaration. - foreach (i, ident; vd.idents) - { - // Perform semantic analysis on value. - if (vd.values[i]) - vd.values[i] = visitE(vd.values[i]); - // Create a new variable symbol. - // TODO: pass 'prot' to constructor. - auto variable = new Variable(vd.stc, vd.linkageType, type, ident, vd); - vd.variables ~= variable; - // Add to scope. - scop.insert(variable); - } - return vd; + D visit(ProtectionDeclaration d) + { + auto saved = protection; // Save. + protection = d.prot; // Set. + visitD(d.decls); + protection = saved; // Restore. + return d; } - Declaration visit(InvariantDeclaration) - { return null; } - Declaration visit(UnittestDeclaration) - { return null; } - Declaration visit(DebugDeclaration) - { return null; } - Declaration visit(VersionDeclaration) - { return null; } - Declaration visit(StaticIfDeclaration) - { return null; } - Declaration visit(StaticAssertDeclaration) - { return null; } - Declaration visit(TemplateDeclaration) - { return null; } - Declaration visit(NewDeclaration) - { return null; } - Declaration visit(DeleteDeclaration) - { return null; } + D visit(StorageClassDeclaration d) + { + auto saved = storageClass; // Save. + storageClass = d.storageClass; // Set. + visitD(d.decls); + storageClass = saved; // Restore. + return d; + } - Declaration visit(ProtectionDeclaration d) - { visitD(d.decls); return d; } - Declaration visit(StorageClassDeclaration d) - { visitD(d.decls); return d; } - Declaration visit(LinkageDeclaration d) - { visitD(d.decls); return d; } - Declaration visit(AlignDeclaration d) - { visitD(d.decls); return d; } + D visit(LinkageDeclaration d) + { + auto saved = linkageType; // Save. + linkageType = d.linkageType; // Set. + visitD(d.decls); + linkageType = saved; // Restore. + return d; + } - Declaration visit(PragmaDeclaration d) + D visit(AlignDeclaration d) + { + auto saved = alignSize; // Save. + alignSize = d.size; // Set. + visitD(d.decls); + alignSize = saved; // Restore. + return d; + } + + D visit(PragmaDeclaration d) { pragmaSemantic(scop, d.begin, d.ident, d.args); visitD(d.decls); @@ -300,155 +377,13 @@ return s; } - Declaration visit(MixinDeclaration) - { return null; } - - Expression visit(ParenExpression e) - { - if (!e.type) - { - e.next = visitE(e.next); - e.type = e.next.type; - } - return e; - } - - Expression visit(CommaExpression e) - { - if (!e.type) - { - e.left = visitE(e.left); - e.right = visitE(e.right); - e.type = e.right.type; - } - return e; - } - - Expression visit(OrOrExpression) - { return null; } - - Expression visit(AndAndExpression) - { return null; } - - Expression visit(SpecialTokenExpression e) - { - if (e.type) - return e.value; - switch (e.specialToken.kind) - { - case TOK.LINE, TOK.VERSION: - e.value = new IntExpression(e.specialToken.uint_, Types.Uint); - break; - case TOK.FILE, TOK.DATE, TOK.TIME, TOK.TIMESTAMP, TOK.VENDOR: - e.value = new StringExpression(e.specialToken.str); - break; - default: - assert(0); - } - e.type = e.value.type; - return e.value; - } - - Expression visit(DollarExpression e) - { - if (e.type) - return e; - e.type = Types.Size_t; - // if (!inArraySubscript) - // error("$ can only be in an array subscript."); - return e; - } - - Expression visit(NullExpression e) - { - if (!e.type) - e.type = Types.Void_ptr; - return e; - } - - Expression visit(BoolExpression e) + D visit(MixinDeclaration md) { - if (e.type) - return e; - e.value = new IntExpression(e.toBool(), Types.Bool); - e.type = Types.Bool; - return e; - } - - Expression visit(IntExpression e) - { - if (e.type) - return e; - - if (e.number & 0x8000_0000_0000_0000) - e.type = Types.Ulong; // 0xFFFF_FFFF_FFFF_FFFF - else if (e.number & 0xFFFF_FFFF_0000_0000) - e.type = Types.Long; // 0x7FFF_FFFF_FFFF_FFFF - else if (e.number & 0x8000_0000) - e.type = Types.Uint; // 0xFFFF_FFFF - else - e.type = Types.Int; // 0x7FFF_FFFF - return e; - } - - Expression visit(RealExpression e) - { - if (e.type) - e.type = Types.Double; - return e; - } - - Expression visit(ComplexExpression e) - { - if (!e.type) - e.type = Types.Cdouble; - return e; - } - - Expression visit(CharExpression e) - { - if (e.type) - return e; - if (e.character <= 0xFF) - e.type = Types.Char; - else if (e.character <= 0xFFFF) - e.type = Types.Wchar; - else - e.type = Types.Dchar; - return e; - } - - Expression visit(StringExpression e) - { - return e; - } - - Expression visit(MixinExpression me) - { - /+ - if (type) - return this.expr; - // TODO: - auto expr = this.expr.semantic(scop); - expr = expr.evaluate(); - if (expr is null) - return this; - auto strExpr = TryCast!(StringExpression)(expr); - if (strExpr is null) - error(scop, MSG.MixinArgumentMustBeString); - else - { - auto loc = this.begin.getErrorLocation(); - auto filePath = loc.filePath; - auto parser = new_ExpressionParser(strExpr.getString(), filePath, scop.infoMan); - expr = parser.parse(); - expr = expr.semantic(scop); - } - this.expr = expr; - this.type = expr.type; - return expr; - +/ - return null; + // Add md to vector of (Scope, MixinDeclaration) + // and evaluate them in 2nd pass? + // TODO: store all attributes in md; they have to be applied + // to the content that is mixed in. + return md; } } // override }