changeset 562:b0533550d64c

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.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Fri, 28 Dec 2007 17:48:47 +0100
parents 302e50e71ec2
children c838ed7f2ac9
files trunk/src/dil/Declarations.d trunk/src/dil/Scope.d trunk/src/dil/SymbolTable.d trunk/src/dil/Symbols.d trunk/src/dil/Types.d
diffstat 5 files changed, 96 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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);
   }
 }
--- 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;
+  }
 }
--- 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
--- 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