# HG changeset patch # User Aziz K?ksal # Date 1198860527 -3600 # Node ID b0533550d64c38affd26ac4fc8c444e18dfa00d3 # Parent 302e50e71ec2d31e3d15b7dcb0f593c738a83491 Added semantic() to VariableDeclaration. Renamed member type to typeNode in VariableDeclaration. Added insert() and error() to class Scope. Made class SymbolTable a struct. Added insert() and lookup() to ScopeSymbol. Added insert() to Aggregate. Added semantic() to TypeNode. diff -r 302e50e71ec2 -r b0533550d64c trunk/src/dil/Declarations.d --- a/trunk/src/dil/Declarations.d Wed Dec 26 23:38:16 2007 +0100 +++ b/trunk/src/dil/Declarations.d Fri Dec 28 17:48:47 2007 +0100 @@ -3,6 +3,7 @@ License: GPL3 +/ module dil.Declarations; + import dil.SyntaxTree; import dil.Expressions; import dil.Types; @@ -12,6 +13,8 @@ import dil.Scope; import dil.IdTable; import dil.Semantics; +import dil.Symbols; +import dil.TypeSystem; abstract class Declaration : Node { @@ -413,18 +416,22 @@ class VariableDeclaration : Declaration { - TypeNode type; + TypeNode typeNode; Identifier*[] idents; Expression[] values; LinkageType linkageType; - this(TypeNode type, Identifier*[] idents, Expression[] values) + this(TypeNode typeNode, Identifier*[] idents, Expression[] values) { + // No empty arrays allowed. Both arrays must be of same size. + assert(idents.length != 0 && idents.length == values.length); + // If no type (in case of AutoDeclaration), first value mustn't be null. + assert(typeNode ? 1 : values[0] !is null); mixin(set_kind); - addOptChild(type); + addOptChild(typeNode); foreach(value; values) addOptChild(value); - this.type = type; + this.typeNode = typeNode; this.idents = idents; this.values = values; } @@ -433,6 +440,36 @@ { this.linkageType = linkageType; } + + Variable[] variables; + + void semantic(Scope scop) + { + Type type; + + if (typeNode) + // Get type from typeNode. + type = typeNode.semantic(scop); + else + { // Infer type from first initializer. + auto firstValue = values[0]; + firstValue = firstValue.semantic(scop); + type = firstValue.type; + } + assert(type !is null); + + // Iterate over variable identifiers in this declaration. + foreach (i, ident; idents) + { + // Perform semantic analysis on value. + values[i] = values[i].semantic(scop); + // Create a new variable symbol. + auto variable = new Variable(stc, linkageType, type, ident, this); + variables ~= variable; + // Add to scope. + scop.insert(variable); + } + } } class InvariantDeclaration : Declaration diff -r 302e50e71ec2 -r b0533550d64c trunk/src/dil/Scope.d --- a/trunk/src/dil/Scope.d Wed Dec 26 23:38:16 2007 +0100 +++ b/trunk/src/dil/Scope.d Fri Dec 28 17:48:47 2007 +0100 @@ -38,6 +38,16 @@ } + /// Insert a new variable symbol into this scope. + void insert(Variable var) + { + auto sym = symbol.lookup(var.ident); + if (sym) + error("variable '"~var.ident.str~"' conflicts with another definition in its scope"); + else + symbol.insert(var, var.ident); + } + /++ Create a new inner scope. +/ @@ -87,7 +97,12 @@ void error(Token* token, MID mid) { auto location = token.getLocation(); - auto error = new SemanticError(location, GetMsg(mid)); -// infoMan.add(error); + infoMan ~= new SemanticError(location, GetMsg(mid)); + } + + void error(char[] msg) + { + auto location = new Location("", 0); + infoMan ~= new SemanticError(location, msg); } } diff -r 302e50e71ec2 -r b0533550d64c trunk/src/dil/SymbolTable.d --- a/trunk/src/dil/SymbolTable.d Wed Dec 26 23:38:16 2007 +0100 +++ b/trunk/src/dil/SymbolTable.d Fri Dec 28 17:48:47 2007 +0100 @@ -11,7 +11,7 @@ /++ Maps an identifier string to a Symbol. +/ -class SymbolTable +struct SymbolTable { protected Symbol[char[]] table; @@ -22,4 +22,9 @@ auto psym = ident.str in table; return psym ? *psym : null; } + + void insert(Symbol s, Identifier* ident) + { + table[ident.str] = s; + } } diff -r 302e50e71ec2 -r b0533550d64c trunk/src/dil/Symbols.d --- a/trunk/src/dil/Symbols.d Wed Dec 26 23:38:16 2007 +0100 +++ b/trunk/src/dil/Symbols.d Fri Dec 28 17:48:47 2007 +0100 @@ -15,11 +15,22 @@ /// A symbol that has its own scope with a symbol table. class ScopeSymbol : Symbol { - SymbolTable symbolTable; /// The symbol table. + protected SymbolTable symbolTable; /// The symbol table. this() { - symbolTable = new SymbolTable; + } + + /// Look up ident in the table. + Symbol lookup(Identifier* ident) + { + return symbolTable.lookup(ident); + } + + /// Insert a symbol into the table. + void insert(Symbol s, Identifier* ident) + { + symbolTable.insert(s, ident); } } @@ -28,6 +39,17 @@ { Function[] funcs; Variable[] fields; + + override void insert(Symbol s, Identifier* ident) + { + if (s.sid == SYM.Variable) + // Append variable to fields. + fields ~= cast(Variable)cast(void*)s; + else if (s.sid == SYM.Function) + // Append function to funcs. + funcs ~= cast(Function)cast(void*)s; + super.insert(s, ident); + } } class Class : Aggregate diff -r 302e50e71ec2 -r b0533550d64c trunk/src/dil/Types.d --- a/trunk/src/dil/Types.d Wed Dec 26 23:38:16 2007 +0100 +++ b/trunk/src/dil/Types.d Fri Dec 28 17:48:47 2007 +0100 @@ -3,11 +3,14 @@ License: GPL3 +/ module dil.Types; + import dil.SyntaxTree; import dil.Token; import dil.Expressions; import dil.Enums; import dil.Identifier; +import dil.Scope; +import dil.TypeSystem; class Parameter : Node { @@ -261,6 +264,11 @@ this.tid = tid; this.next = next; } + + Type semantic(Scope scop) + { + return Types.Error; + } } class IntegralType : TypeNode