Mercurial > projects > dil
changeset 707:efa5fcb9aa14
Added semantic code related to enums.
Added member symbol to EnumMemberDeclaration.
Added genAnonEnumID() to IdTable.
Added class EnumMember.
Wrote code for SemanticPass2.visit(EnumDeclaration).
Revised code in SemanticPass1.visit(EnumDeclaration).
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Tue, 29 Jan 2008 01:07:39 +0100 |
parents | 684ec5932b2e |
children | 3a4c7d444467 |
files | trunk/src/dil/ast/Declarations.d trunk/src/dil/lexer/IdTable.d trunk/src/dil/semantic/Pass1.d trunk/src/dil/semantic/Pass2.d trunk/src/dil/semantic/Symbol.d trunk/src/dil/semantic/Symbols.d |
diffstat | 6 files changed, 106 insertions(+), 35 deletions(-) [+] |
line wrap: on
line diff
--- a/trunk/src/dil/ast/Declarations.d Mon Jan 28 21:39:08 2008 +0100 +++ b/trunk/src/dil/ast/Declarations.d Tue Jan 29 01:07:39 2008 +0100 @@ -192,6 +192,8 @@ this.name = name; this.value = value; } + + EnumMember symbol; } class TemplateDeclaration : Declaration
--- a/trunk/src/dil/lexer/IdTable.d Mon Jan 28 21:39:08 2008 +0100 +++ b/trunk/src/dil/lexer/IdTable.d Tue Jan 29 01:07:39 2008 +0100 @@ -139,6 +139,11 @@ while (x /= 10) return Identifier(str, TOK.Identifier); } + + Identifier* genAnonEnumID() + { + return genAnonymousID("__anonenum"); + } } unittest
--- a/trunk/src/dil/semantic/Pass1.d Mon Jan 28 21:39:08 2008 +0100 +++ b/trunk/src/dil/semantic/Pass1.d Tue Jan 29 01:07:39 2008 +0100 @@ -72,41 +72,53 @@ } /// Insert a symbol into the current scope. - void insert(Symbol sym, Identifier* ident) + void insert(Symbol sym, Identifier* name) { - auto sym2 = scop.symbol.lookup(ident); + auto sym2 = scop.symbol.lookup(name); if (sym2) - reportSymbolConflict(sym, sym2, ident); + reportSymbolConflict(sym, sym2, name); else - scop.symbol.insert(sym, ident); + scop.symbol.insert(sym, name); // Set the current scope symbol as the parent. sym.parent = scop.symbol; } + /// Insert a symbol into scopeSym. + void insert(Symbol symbol, ScopeSymbol scopeSym) + { + auto symX = scopeSym.lookup(symbol.name); + if (symX) + reportSymbolConflict(symbol, symX, symbol.name); + else + scopeSym.insert(symbol, symbol.name); + // Set the current scope symbol as the parent. + symbol.parent = scopeSym; + } + /// Insert a symbol, overloading on the name, into the current scope. - void insertOverload(Symbol sym, Identifier* ident) + void insertOverload(Symbol sym, Identifier* name) { - auto sym2 = scop.symbol.lookup(ident); + auto sym2 = scop.symbol.lookup(name); if (sym2) { if (sym2.isOverloadSet) (cast(OverloadSet)cast(void*)sym2).add(sym); else - reportSymbolConflict(sym, sym2, ident); + reportSymbolConflict(sym, sym2, name); } else // Create a new overload set. - scop.symbol.insert(new OverloadSet(ident, sym.node), ident); + scop.symbol.insert(new OverloadSet(name, sym.node), name); // 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) + void reportSymbolConflict(Symbol s1, Symbol s2, Identifier* name) { auto loc = s2.node.begin.getErrorLocation(); auto locString = Format("{}({},{})", loc.filePath, loc.lineNum, loc.colNum); - error(s1.node.begin, MSG.DeclConflictsWithDecl, ident.str, locString); + error(s1.node.begin, MSG.DeclConflictsWithDecl, name.str, locString); } void error(Token* token, char[] formatMsg, ...) @@ -186,24 +198,30 @@ { // Create the symbol. d.symbol = new Enum(d.name, d); - if (d.name) - { // Declare named enum. - insert(d.symbol, d.name); - enterScope(d.symbol); - } + auto isAnonymous = d.name is null; + if (isAnonymous) + d.symbol.name = IdTable.genAnonEnumID(); + insert(d.symbol, d.name); + auto parentScopeSymbol = scop.symbol; + enterScope(d.symbol); // Declare members. foreach (member; d.members) { - auto variable = new Variable(member.name, protection, storageClass, linkageType, member); - insert(variable, variable.name); + visitD(member); + if (isAnonymous) // Also insert into parent scope if enum is anonymous. + insert(member.symbol, parentScopeSymbol); + member.symbol.parent = d.symbol; } - if (d.name) - exitScope(); + exitScope(); return d; } - D visit(EnumMemberDeclaration) - { return null; } + D visit(EnumMemberDeclaration d) + { + d.symbol = new EnumMember(d.name, protection, storageClass, linkageType, d); + insert(d.symbol, d.symbol.name); + return d; + } D visit(ClassDeclaration d) {
--- a/trunk/src/dil/semantic/Pass2.d Mon Jan 28 21:39:08 2008 +0100 +++ b/trunk/src/dil/semantic/Pass2.d Tue Jan 29 01:07:39 2008 +0100 @@ -68,6 +68,11 @@ private alias Statement S; private alias TypeNode T; + /// The scope symbol to use in identifier or template instance expressions. + /// E.g.: object.method(); // After 'object' has been visited, dotIdScope is + /// // set, and 'method' will be looked up there. + ScopeSymbol dotIdScope; + override { D visit(CompoundDeclaration d) @@ -75,6 +80,31 @@ return super.visit(d); } + D visit(EnumDeclaration d) + { + Type type = Types.Int; // Default to int. + if (d.baseType) + type = visitT(d.baseType).type; + d.symbol.type = new TypeEnum(d.symbol, type); + enterScope(d.symbol); + foreach (member; d.members) + { + Expression finalValue; + if (member.value) + { + member.value = visitE(member.value); + finalValue = Interpreter.interpret(member.value, modul.infoMan, scop); + if (finalValue is Interpreter.NAR) + continue; + } + //else + // TODO: increment a number variable and assign that to value. + member.symbol.value = finalValue; + } + exitScope(); + return d; + } + D visit(MixinDeclaration md) { if (md.decls)
--- a/trunk/src/dil/semantic/Symbol.d Mon Jan 28 21:39:08 2008 +0100 +++ b/trunk/src/dil/semantic/Symbol.d Tue Jan 29 01:07:39 2008 +0100 @@ -17,6 +17,7 @@ Struct, Union, Enum, + EnumMember, Template, Variable, Function, @@ -45,20 +46,21 @@ } // A template macro for building isXYZ() methods. - private template is_(char[] kind) + private template isX(char[] kind) { - const char[] is_ = `bool is`~kind~`(){ return sid == SYM.`~kind~`; }`; + const char[] isX = `bool is`~kind~`(){ return sid == SYM.`~kind~`; }`; } - mixin(is_!("Module")); - mixin(is_!("Class")); - mixin(is_!("Interface")); - mixin(is_!("Struct")); - mixin(is_!("Union")); - mixin(is_!("Enum")); - mixin(is_!("Template")); - mixin(is_!("Variable")); - mixin(is_!("Function")); - mixin(is_!("Alias")); - mixin(is_!("OverloadSet")); -// mixin(is_!("Type")); + mixin(isX!("Module")); + mixin(isX!("Class")); + mixin(isX!("Interface")); + mixin(isX!("Struct")); + mixin(isX!("Union")); + mixin(isX!("Enum")); + mixin(isX!("EnumMember")); + mixin(isX!("Template")); + mixin(isX!("Variable")); + mixin(isX!("Function")); + mixin(isX!("Alias")); + mixin(isX!("OverloadSet")); +// mixin(isX!("Type")); }
--- a/trunk/src/dil/semantic/Symbols.d Mon Jan 28 21:39:08 2008 +0100 +++ b/trunk/src/dil/semantic/Symbols.d Tue Jan 29 01:07:39 2008 +0100 @@ -4,6 +4,7 @@ +/ module dil.semantic.Symbols; +import dil.ast.Expression; import dil.semantic.Symbol; import dil.semantic.SymbolTable; import dil.semantic.Types; @@ -136,6 +137,7 @@ LinkageType linkType; /// The linkage type. Type type; /// The type of this variable. + Expression value; /// The value of this variable. this(Identifier* name, Protection prot, StorageClass stc, LinkageType linkType, @@ -143,11 +145,23 @@ { super(SYM.Variable, name, variableNode); + this.prot = prot; this.stc = stc; this.linkType = linkType; } } +class EnumMember : Variable +{ + this(Identifier* name, + Protection prot, StorageClass stc, LinkageType linkType, + Node enumMemberNode) + { + super(name, prot, stc, linkType, enumMemberNode); + this.sid = SYM.EnumMember; + } +} + class Alias : Symbol { this(Identifier* name, Node aliasNode)