changeset 820:1d06b4aed7cf

Revised code in the first pass. Added code to handle anonymous unions and structs. Hope the idea will work. Added type to class Aggregate and isAnonymous to some other Symbol classes.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Fri, 14 Mar 2008 15:42:08 +0100
parents 438ed3a72c9d
children fd52beaaa94a
files src/cmd/Compile.d src/dil/lexer/IdTable.d src/dil/semantic/Pass1.d src/dil/semantic/Pass2.d src/dil/semantic/Symbols.d src/dil/semantic/Types.d
diffstat 6 files changed, 122 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/src/cmd/Compile.d	Thu Mar 13 18:59:54 2008 +0100
+++ b/src/cmd/Compile.d	Fri Mar 14 15:42:08 2008 +0100
@@ -52,10 +52,10 @@
   void printMTree(Package pckg, string indent)
   {
     Stdout(indent)(pckg.pckgName)("/").newline;
-    foreach (p; pckg.packages)
+    foreach (p; pckg.packages) // TODO: sort packages alphabetically by name?
       printMTree(p, indent ~ "  ");
-    foreach (m; pckg.modules)
-      Stdout(indent ~ "  ")(m.moduleName)(".d").newline;
+    foreach (m; pckg.modules) // TODO: sort modules alphabetically by name?
+      Stdout(indent ~ "  ")(m.moduleName)(".")(m.fileExtension()).newline;
   }
 
   /// Runs the first pass on modul.
--- a/src/dil/lexer/IdTable.d	Thu Mar 13 18:59:54 2008 +0100
+++ b/src/dil/lexer/IdTable.d	Fri Mar 14 15:42:08 2008 +0100
@@ -148,6 +148,24 @@
     return genAnonymousID("__anonenum");
   }
 
+  /// Generates an identifier for an anonymous class.
+  Identifier* genAnonClassID()
+  {
+    return genAnonymousID("__anonclass");
+  }
+
+  /// Generates an identifier for an anonymous struct.
+  Identifier* genAnonStructID()
+  {
+    return genAnonymousID("__anonstruct");
+  }
+
+  /// Generates an identifier for an anonymous union.
+  Identifier* genAnonUnionID()
+  {
+    return genAnonymousID("__anonunion");
+  }
+
   /// Generates an identifier for a module which has got no valid name.
   Identifier* genModuleID()
   {
--- a/src/dil/semantic/Pass1.d	Thu Mar 13 18:59:54 2008 +0100
+++ b/src/dil/semantic/Pass1.d	Fri Mar 14 15:42:08 2008 +0100
@@ -87,6 +87,12 @@
   }
 
   /// Inserts a symbol into the current scope.
+  void insert(Symbol symbol)
+  {
+    insert(symbol, symbol.name);
+  }
+
+  /// Inserts a symbol into the current scope.
   void insert(Symbol symbol, Identifier* name)
   {
     auto symX = scop.symbol.lookup(name);
@@ -111,8 +117,9 @@
   }
 
   /// Inserts a symbol, overloading on the name, into the current scope.
-  void insertOverload(Symbol sym, Identifier* name)
+  void insertOverload(Symbol sym)
   {
+    auto name = sym.name;
     auto sym2 = scop.symbol.lookup(name);
     if (sym2)
     {
@@ -224,21 +231,30 @@
 
   D visit(EnumDeclaration d)
   {
+    if (d.symbol)
+      return d;
+
     // Create the symbol.
     d.symbol = new Enum(d.name, d);
-    auto isAnonymous = d.name is null;
+
+    bool isAnonymous = d.symbol.isAnonymous;
     if (isAnonymous)
       d.symbol.name = IdTable.genAnonEnumID();
-    insert(d.symbol, d.symbol.name);
+
+    insert(d.symbol);
+
     auto parentScopeSymbol = scop.symbol;
+    auto enumSymbol = d.symbol;
     enterScope(d.symbol);
     // Declare members.
     foreach (member; d.members)
     {
       visitD(member);
+
       if (isAnonymous) // Also insert into parent scope if enum is anonymous.
         insert(member.symbol, parentScopeSymbol);
-      member.symbol.parent = d.symbol;
+
+      member.symbol.type = enumSymbol.type; // Assign TypeEnum.
     }
     exitScope();
     return d;
@@ -247,7 +263,7 @@
   D visit(EnumMemberDeclaration d)
   {
     d.symbol = new EnumMember(d.name, protection, storageClass, linkageType, d);
-    insert(d.symbol, d.symbol.name);
+    insert(d.symbol);
     return d;
   }
 
@@ -255,9 +271,10 @@
   {
     if (d.symbol)
       return d;
+    // Create the symbol.
     d.symbol = new Class(d.name, d);
     // Insert into current scope.
-    insert(d.symbol, d.name);
+    insert(d.symbol);
     enterScope(d.symbol);
     // Continue semantic analysis.
     d.decls && visitD(d.decls);
@@ -269,12 +286,13 @@
   {
     if (d.symbol)
       return d;
+    // Create the symbol.
     d.symbol = new dil.semantic.Symbols.Interface(d.name, d);
     // Insert into current scope.
-    insert(d.symbol, d.name);
+    insert(d.symbol);
     enterScope(d.symbol);
-    // Continue semantic analysis.
-    d.decls && visitD(d.decls);
+      // Continue semantic analysis.
+      d.decls && visitD(d.decls);
     exitScope();
     return d;
   }
@@ -283,14 +301,23 @@
   {
     if (d.symbol)
       return d;
+    // Create the symbol.
     d.symbol = new Struct(d.name, d);
+
+    if (d.symbol.isAnonymous)
+      d.symbol.name = IdTable.genAnonStructID();
     // Insert into current scope.
-    if (d.name)
-      insert(d.symbol, d.name);
+    insert(d.symbol);
+
     enterScope(d.symbol);
-    // Continue semantic analysis.
-    d.decls && visitD(d.decls);
+      // Continue semantic analysis.
+      d.decls && visitD(d.decls);
     exitScope();
+
+    if (d.symbol.isAnonymous)
+      // Insert members into parent scope as well.
+      foreach (member; d.symbol.members)
+        insert(member);
     return d;
   }
 
@@ -298,49 +325,59 @@
   {
     if (d.symbol)
       return d;
+    // Create the symbol.
     d.symbol = new Union(d.name, d);
+
+    if (d.symbol.isAnonymous)
+      d.symbol.name = IdTable.genAnonUnionID();
+
     // Insert into current scope.
-    if (d.name)
-      insert(d.symbol, d.name);
+    insert(d.symbol);
+
     enterScope(d.symbol);
-    // Continue semantic analysis.
-    d.decls && visitD(d.decls);
+      // Continue semantic analysis.
+      d.decls && visitD(d.decls);
     exitScope();
+
+    if (d.symbol.isAnonymous)
+      // Insert members into parent scope as well.
+      foreach (member; d.symbol.members)
+        insert(member);
     return d;
   }
 
   D visit(ConstructorDeclaration d)
   {
     auto func = new Function(Ident.__ctor, d);
-    insertOverload(func, func.name);
+    insertOverload(func);
     return d;
   }
 
   D visit(StaticConstructorDeclaration d)
   {
     auto func = new Function(Ident.__ctor, d);
-    insertOverload(func, func.name);
+    insertOverload(func);
     return d;
   }
 
   D visit(DestructorDeclaration d)
   {
     auto func = new Function(Ident.__dtor, d);
-    insertOverload(func, func.name);
+    insertOverload(func);
     return d;
   }
 
   D visit(StaticDestructorDeclaration d)
   {
     auto func = new Function(Ident.__dtor, d);
-    insertOverload(func, func.name);
+    insertOverload(func);
     return d;
   }
 
   D visit(FunctionDeclaration d)
   {
     auto func = new Function(d.name, d);
-    insertOverload(func, func.name);
+    insertOverload(func);
     return d;
   }
 
@@ -356,7 +393,7 @@
       auto variable = new Variable(name, protection, storageClass, linkageType, vd);
       variable.value = vd.inits[i];
       vd.variables ~= variable;
-      insert(variable, name);
+      insert(variable);
     }
     return vd;
   }
@@ -364,21 +401,21 @@
   D visit(InvariantDeclaration d)
   {
     auto func = new Function(Ident.__invariant, d);
-    insert(func, func.name);
+    insert(func);
     return d;
   }
 
   D visit(UnittestDeclaration d)
   {
     auto func = new Function(Ident.__unittest, d);
-    insertOverload(func, func.name);
+    insertOverload(func);
     return d;
   }
 
   D visit(DebugDeclaration d)
   {
     if (d.isSpecification)
-    {
+    { // debug = Id|Int
       if (!isModuleScope())
         error(d.begin, MSG.DebugSpecModuleLevel, d.spec.srcText);
       else if (d.spec.kind == TOK.Identifier)
@@ -400,7 +437,7 @@
   D visit(VersionDeclaration d)
   {
     if (d.isSpecification)
-    {
+    { // version = Id|Int
       if (!isModuleScope())
         error(d.begin, MSG.VersionSpecModuleLevel, d.spec.srcText);
       else if (d.spec.kind == TOK.Identifier)
@@ -423,27 +460,24 @@
   {
     if (d.symbol)
       return d;
+    // Create the symbol.
     d.symbol = new Template(d.name, d);
     // Insert into current scope.
-    insertOverload(d.symbol, d.name);
-    enterScope(d.symbol);
-    // Continue semantic analysis.
-    visitD(d.decls);
-    exitScope();
+    insertOverload(d.symbol);
     return d;
   }
 
   D visit(NewDeclaration d)
   {
     auto func = new Function(Ident.__new, d);
-    insert(func, func.name);
+    insert(func);
     return d;
   }
 
   D visit(DeleteDeclaration d)
   {
     auto func = new Function(Ident.__delete, d);
-    insert(func, func.name);
+    insert(func);
     return d;
   }
 
--- a/src/dil/semantic/Pass2.d	Thu Mar 13 18:59:54 2008 +0100
+++ b/src/dil/semantic/Pass2.d	Fri Mar 14 15:42:08 2008 +0100
@@ -134,7 +134,10 @@
     Type type = Types.Int; // Default to int.
     if (d.baseType)
       type = visitT(d.baseType).type;
-    d.symbol.type = new TypeEnum(d.symbol, type);
+    // Set the enum's base type.
+    d.symbol.type.baseType = type;
+
+    // TODO: check base type. must be basic type or another enum.
 
     enterScope(d.symbol);
 
@@ -151,7 +154,6 @@
       }
       //else
         // TODO: increment a number variable and assign that to value.
-      member.symbol.type = d.symbol.type; // Assign TypeEnum.
       member.symbol.value = finalValue;
       member.symbol.setComplete();
     }
--- a/src/dil/semantic/Symbols.d	Thu Mar 13 18:59:54 2008 +0100
+++ b/src/dil/semantic/Symbols.d	Fri Mar 14 15:42:08 2008 +0100
@@ -48,6 +48,7 @@
 /// Aggregates have function and field members.
 abstract class Aggregate : ScopeSymbol
 {
+  Type type;
   Function[] funcs;
   Variable[] fields;
 
@@ -74,6 +75,7 @@
   this(Identifier* name, Node classNode)
   {
     super(SYM.Class, name, classNode);
+    this.type = new TypeClass(this);
   }
 }
 
@@ -83,24 +85,31 @@
   this(Identifier* name, Node interfaceNode)
   {
     super(SYM.Interface, name, interfaceNode);
+    this.type = new TypeClass(this);
+  }
+}
+
+/// A struct symbol.
+class Struct : Aggregate
+{
+  bool isAnonymous;
+  this(Identifier* name, Node structNode)
+  {
+    super(SYM.Struct, name, structNode);
+    this.type = new TypeStruct(this);
+    this.isAnonymous = name is null;
   }
 }
 
 /// A union symbol.
 class Union : Aggregate
 {
+  bool isAnonymous;
   this(Identifier* name, Node unionNode)
   {
     super(SYM.Union, name, unionNode);
-  }
-}
-
-/// A struct symbol.
-class Struct : Aggregate
-{
-  this(Identifier* name, Node structNode)
-  {
-    super(SYM.Struct, name, structNode);
+    this.type = new TypeStruct(this);
+    this.isAnonymous = name is null;
   }
 }
 
@@ -108,9 +117,12 @@
 class Enum : ScopeSymbol
 {
   TypeEnum type;
+  bool isAnonymous;
   this(Identifier* name, Node enumNode)
   {
     super(SYM.Enum, name, enumNode);
+    this.type = new TypeEnum(this);
+    this.isAnonymous = name is null;
   }
 
   void setType(TypeEnum type)
--- a/src/dil/semantic/Types.d	Thu Mar 13 18:59:54 2008 +0100
+++ b/src/dil/semantic/Types.d	Fri Mar 14 15:42:08 2008 +0100
@@ -130,12 +130,19 @@
 /// Enum type.
 class TypeEnum : Type
 {
-  this(Symbol symbol, Type baseType)
+  this(Symbol symbol)
   {
     super(baseType, TYP.Enum);
     this.symbol = symbol;
   }
 
+  /// Setter for the base type.
+  void baseType(Type type)
+  {
+    next = type;
+  }
+
+  /// Getter for the base type.
   Type baseType()
   {
     return next;