changeset 129:ed815b31479b

Added a Symbol
author Anders Halager <halager@gmail.com>
date Sat, 21 Jun 2008 20:41:18 +0200
parents 7264c61088c4
children 6545a8d59596
files ast/Decl.d ast/Exp.d ast/Module.d basic/SmallArray.d gen/CodeGen.d sema/DType.d sema/Operation.d sema/Scope.d sema/ScopeBuilder.d sema/Symbol.d
diffstat 10 files changed, 402 insertions(+), 104 deletions(-) [+]
line wrap: on
line diff
--- a/ast/Decl.d	Sat Jun 21 17:32:27 2008 +0200
+++ b/ast/Decl.d	Sat Jun 21 20:41:18 2008 +0200
@@ -8,6 +8,7 @@
 import tango.io.Stdout;
 
 import sema.Scope,
+       sema.Symbol,
        sema.DType,
        basic.SmallArray,
        basic.Attribute;
@@ -15,6 +16,7 @@
 enum DeclType
 {
     VarDecl,
+    DummyDecl,
     ImportDecl,
     FuncDecl,
     StructDecl,
@@ -31,13 +33,27 @@
     {
     }
 
-    DType type() { return null; }
+    DType type()
+    {
+        if (sym !is null)
+            return sym.type;
+        return null;
+    }
 
     DeclType declType;
     Scope env;
+    Symbol sym;
     Attribute att;
 }
 
+class DummyDecl : Decl
+{
+    this()
+    {
+        super(DeclType.DummyDecl);
+    }
+}
+
 class VarDecl : Decl
 {
     this(Identifier type, Identifier identifier,
@@ -55,7 +71,7 @@
 
     override DType type()
     {
-        return env.find(identifier).type;
+        return env.findType(varType);
     }
 
     Identifier varType, identifier;
@@ -109,7 +125,8 @@
 
     void simplify()
     {
-        if(auto t = cast(DFunction)env.find(identifier).type)
+        /*
+        if(auto t = env.find(identifier).type.asFunction())
         {
             if(auto s = cast(DStruct)t.returnType)
             {
@@ -131,6 +148,7 @@
                 myType = null;
             }
         }
+        */
 
         foreach (funcArg; funcArgs)
             funcArg.simplify();
--- a/ast/Exp.d	Sat Jun 21 17:32:27 2008 +0200
+++ b/ast/Exp.d	Sat Jun 21 20:41:18 2008 +0200
@@ -1,6 +1,7 @@
 module ast.Exp;
 
-import tango.text.Util;
+import tango.text.Util,
+       Integer = tango.text.convert.Integer;
 import tango.io.Stdout;
 
 import ast.Decl,
@@ -9,6 +10,7 @@
 import lexer.Token;
 
 import sema.Scope,
+       sema.Symbol,
        sema.DType;
 
 import basic.LiteralParsing;
@@ -38,6 +40,23 @@
         this.loc = loc;
     }
 
+    /**
+      Get the fully qualified name for the expression (if it can be resolved to
+      one) - otherwise null is returned
+     **/
+    char[] getFQN() { return null; }
+
+    /// The same as getFQN, except that the name is mangled
+    char[] getMangledFQN() { return null; }
+
+    /**
+      Try to get the symbol the expression represents.
+
+      Returns null for most expressions as they don't represent any symbol.
+      Identifiers and member references can have a sensible value.
+     **/
+    Symbol getSymbol() { return null; }
+
     /// Get the type of the expression
     abstract DType type();
 
@@ -47,6 +66,8 @@
     /// The environment of the expression
     Scope env;
 
+    Symbol symbol;
+
     int stmtIndex;
 
     /**
@@ -96,6 +117,7 @@
 
     Exp simplify()
     {
+        /*
         if(auto t = type.asStruct)
         {
             DFunction func_t = cast(DFunction)exp.type();
@@ -134,6 +156,7 @@
 
             return i;
         }
+        */
         return this;
     }
 }
@@ -303,7 +326,7 @@
 
     override DType type() 
     {
-        return exp.type().asPointer.pointerOf; 
+        return exp.type().asPointer().pointerOf; 
     }
 
     override SourceRange sourceRange()
@@ -370,6 +393,24 @@
         this.child = child;
     }
 
+    override char[] getFQN()
+    {
+        return getSymbol().getFQN();
+    }
+
+    override char[] getMangledFQN()
+    {
+        return target.type.mangle() ~ child.getMangledFQN();
+    }
+
+    override Symbol getSymbol()
+    {
+        auto s = target.getSymbol();
+        if (s !is null)
+            return s.findMember(child.get);
+        return null;
+    }
+
     Exp simplify()
     {
         target = target.simplify;
@@ -535,15 +576,33 @@
         super(t, loc);
     }
 
+    override char[] getFQN()
+    {
+        return name;
+    }
+
+    override char[] getMangledFQN()
+    {
+        return Integer.toString(name.length) ~ name;
+    }
+
+    override Symbol getSymbol()
+    {
+        if (auto decl = env.find(this))
+            return decl.sym;
+        else
+            return null;
+    }
+
     override DType type()
     {
         if (myType !is null)
             return myType;
-        if(auto s = env.find(this))
-            if(s.type)
-                myType = s.type;
+        else if (auto sym = getSymbol)
+            myType = sym.type;
         else
             myType = DType.Int;
+
         return myType;
     }
 
@@ -557,16 +616,6 @@
     {
         return name;
     }
-    
-    char[] getMangled()
-    {
-        DType t = type;
-
-        if(name == "main")
-            return "main";
-
-        return "_D"~name~t.mangle;
-    }
 
     hash_t toHash()
     {
--- a/ast/Module.d	Sat Jun 21 17:32:27 2008 +0200
+++ b/ast/Module.d	Sat Jun 21 20:41:18 2008 +0200
@@ -1,6 +1,7 @@
 module ast.Module;
 
-import sema.Scope;
+import sema.Scope,
+       sema.Symbol;
 
 import ast.Decl;
 
@@ -19,4 +20,6 @@
     Decl[] decls;
     char[] moduleName;
     Scope env;
+    Symbol symbol;
 }
+
--- a/basic/SmallArray.d	Sat Jun 21 17:32:27 2008 +0200
+++ b/basic/SmallArray.d	Sat Jun 21 20:41:18 2008 +0200
@@ -84,6 +84,19 @@
         else
             ptr = array.ptr;
     }
+    alias opCatAssign push;
+
+    T pop()
+    {
+        assert(len > 0, "Can't remove from an empty array");
+        return ptr[--len];
+    }
+
+    T peek()
+    {
+        assert(len > 0, "Array is empty");
+        return ptr[len - 1];
+    }
 
     size_t length() { return len; }
 
--- a/gen/CodeGen.d	Sat Jun 21 17:32:27 2008 +0200
+++ b/gen/CodeGen.d	Sat Jun 21 20:41:18 2008 +0200
@@ -96,7 +96,7 @@
                 Type[] param_types;
                 foreach (i, p; fd.funcArgs)
                 {
-                    DType t = p.env.find(p.identifier).type;
+                    DType t = p.identifier.type;
                     if (auto st = t.asStruct())
                     {
                         Type pointer = PointerType.Get(llvm(st));
@@ -110,20 +110,20 @@
                     else
                         param_types ~= llvm(t);
                 }
-                auto ret_t = fd.env.find(fd.identifier).type;
+                auto ret_t = fd.identifier.type;
                 if(auto st = cast(DStruct)ret_t)
                     ret_t = DType.Void;
                 else if(auto f = cast(DFunction)ret_t)
                     ret_t = f.returnType;
                 auto func_t = FunctionType.Get(llvm(ret_t), param_types);
-                auto llfunc = m.addFunction(func_t, fd.identifier.getMangled);
+                auto llfunc = m.addFunction(func_t, fd.sym.getMangledFQN());
 
                 foreach (i, p; fd.funcArgs)
                 {
                     if(i == 0 && fd.sret)
                         llfunc.addParamAttr(0, ParamAttr.StructRet);
 
-                    DType t = p.env.find(p.identifier).type;
+                    DType t = p.identifier.type;
                     if (auto st = t.asStruct)
                     {
                         if (i == 0 && fd.sret)
@@ -173,7 +173,7 @@
                     return;
 
                 llvm(funcDecl.type);
-                auto llfunc = m.getNamedFunction(funcDecl.identifier.getMangled);
+                auto llfunc = m.getNamedFunction(funcDecl.sym.getMangledFQN());
                 auto func_tp = cast(PointerType)llfunc.type;
                 auto func_t = cast(FunctionType)func_tp.elementType();
                 auto ret_t = func_t.returnType();
@@ -214,7 +214,7 @@
 
             case DeclType.VarDecl:
                 auto varDecl = cast(VarDecl)decl;
-                auto id = varDecl.env.find(varDecl.identifier);
+                auto id = varDecl.identifier;
                 Type t = llvm(id.type);
                 GlobalVariable g = m.addGlobal(t, id.get);
                 g.initializer = ConstantInt.GetS(t, 0);
@@ -241,17 +241,21 @@
         {
             case DeclType.VarDecl:
                 auto varDecl = cast(VarDecl)decl;
-                auto name = varDecl.identifier.get;
-                auto sym = varDecl.env.find(varDecl.identifier);
-                auto AI = b.buildAlloca(llvm(sym.type), name);
+                auto id = varDecl.identifier;
+                auto name = id.get;
+                auto AI = b.buildAlloca(llvm(id.type), name);
                 table[name] = AI;
                 if (varDecl.init)
                 {
                     LValue dst = genLValue(varDecl.identifier);
                     RValue src = genExpression(varDecl.init);
-                    storeThroughLValue(dst, src, sym.type);
+                    storeThroughLValue(dst, src, id.type);
                 }
                 break;
+
+            case DeclType.FuncDecl:
+                genRootDecl(decl);
+                break;
         
             default:
         }
@@ -344,13 +348,20 @@
                 auto callExp = cast(CallExp)exp;
                 // BUG: Might not be a simple identifier, a.foo(x) is also a
                 // valid call - or foo(x)(y) for that matter.
-                auto id = exp.env.find(cast(Identifier)callExp.exp);
+
+                // if type of exp is DFunction - safe to call getSymbol and FQN
+                // if function ptr: do something else
+                // if delegate do a third thing
+                // if struct/class check for opCall
+                DType type = callExp.exp.type;
+                assert (type.isFunction(), "Can only call functions");
+                auto sym = callExp.exp.getSymbol();
                 scope args = new Value[callExp.args.length];
                 foreach (i, arg; callExp.args)
                     args[i] = genExpression(arg).value;
-                llvm(id.type);
-                auto f = m.getNamedFunction(id.getMangled);
-                DFunction f_type = cast(DFunction)id.type;
+                llvm(type);
+                auto f = m.getNamedFunction(sym.getMangledFQN());
+                DFunction f_type = type.asFunction();
                 bool isVoid = f_type.returnType is DType.Void;
                 // BUG: doesn't do implicit type-conversion on args
                 auto r = b.buildCall(f, args, isVoid? "" : "call");
@@ -366,8 +377,7 @@
                 return genTypeCast(value, exp.type, castExp.type);
 
             case ExpType.Identifier:
-                auto identifier = cast(Identifier)exp;
-                auto id = exp.env.find(identifier);
+                auto id = cast(Identifier)exp;
                 if(id.type.isStruct() || id.type.isArray())
                     return RValue(table.find(id.get));
                 else
@@ -518,7 +528,7 @@
                     Value False = ConstantInt.GetS(cond.type, 0);
                     cond = b.buildICmp(IntPredicate.NE, cond, False, ".cond");
                 }
-                auto func_name = stmt.env.parentFunction().identifier.getMangled;
+                auto func_name = symbolName(stmt.env.parentFunction());
                 Function func = m.getNamedFunction(func_name);
                 bool has_else = (ifStmt.else_body !is null);
 
@@ -546,8 +556,8 @@
                 break;
             case StmtType.While:
                 auto wStmt = cast(WhileStmt)stmt;
-                auto func_name = stmt.env.parentFunction().identifier.get;
-                Function func = m.getNamedFunction(func_name);
+                auto fd = stmt.env.parentFunction();
+                Function func = m.getNamedFunction(symbolName(fd));
 
                 auto condBB = func.appendBasicBlock("cond");
                 auto bodyBB = func.appendBasicBlock("body");
@@ -632,8 +642,7 @@
         switch(exp.expType)
         {
             case ExpType.Identifier:
-                auto identifier = cast(Identifier)exp;
-                auto id = exp.env.find(identifier);
+                auto id = cast(Identifier)exp;
                 return LValue(table.find(id.get));
             case ExpType.Deref:
                 // LValue(*x): load(x)
@@ -663,9 +672,8 @@
                 switch (mem.target.expType)
                 {
                     case ExpType.Identifier:
-                        auto identifier = cast(Identifier)mem.target;
+                        auto id = cast(Identifier)mem.target;
                         auto child = mem.child;
-                        auto id = exp.env.find(identifier);
                         Value v = table.find(id.get);
                         DType t = id.type;
                         auto st = t.asStruct;
@@ -682,11 +690,9 @@
                     case ExpType.MemberReference:
                         auto addr = genLValue(mem.target).getAddress();
                         auto child = mem.child;
-                        auto symChild = child.env.find(child);
-                        DType t = mem.target.type;
-                        auto st = t.asStruct;
+                        DStruct t = mem.target.type.asStruct();
 
-                        int i = st.indexOf(child.get);
+                        int i = t.indexOf(child.get);
 
                         Value[2] vals;   
                         vals[0] = ZeroIndex;
@@ -785,6 +791,12 @@
         return RValue(res);
     }
 
+    /// Get the mangled name of a function
+    char[] symbolName(FuncDecl f)
+    {
+        return f.sym.getMangledFQN();
+    }
+
     /**
       Get the LLVM Type corresponding to a DType.
 
@@ -846,13 +858,17 @@
 
             Type res = FunctionType.Get(ret_t, params.unsafe());
             type_map[t] = res;
+            /*
+            //TODO: create own DType -> FunctionType mapping without names
             auto id = new Identifier(f.name);
             id.setType(f);
 
-            auto f_t = m.getNamedFunction(id.getMangled);
+            auto f_name = symbolName(id);
+            auto f_t = m.getNamedFunction(f_name);
             if(f_t is null)
             {
-                auto llfunc = m.addFunction(res, id.getMangled);
+                Stdout("oh noes").newline;
+                auto llfunc = m.addFunction(res, f_name);
 
                 foreach (i, param; f.params)
                     if (param.isStruct)
@@ -864,6 +880,7 @@
                     llfunc.addParamAttr(0, ParamAttr.StructRet);
                 }
             }
+            */
             return res;
         }
         else if (auto f = t.asPointer)
@@ -901,8 +918,8 @@
         type_map[DType.Real]   = Type.X86_FP80;
 
         type_map[DType.Char]   = Type.Int8;
-        type_map[DType.WChar]   = Type.Int16;
-        type_map[DType.DChar]   = Type.Int32;
+        type_map[DType.WChar]  = Type.Int16;
+        type_map[DType.DChar]  = Type.Int32;
     }
 
 private:
@@ -916,8 +933,6 @@
     Type BytePtr;
     Type[DType] type_map;
 
-    FuncDecl[char[]] functions;
-
     SimpleSymbolTable table;
 }
 
@@ -1009,11 +1024,9 @@
         this.dg = dg;
     }
 
-    override void visitModule(DModule m)
+    override void visitFuncDecl(FuncDecl fd)
     {
-        foreach (decl; m.decls)
-            if (auto f = cast(FuncDecl)decl)
-                dg(f);
+        dg(fd);
     }
 }
 
--- a/sema/DType.d	Sat Jun 21 17:32:27 2008 +0200
+++ b/sema/DType.d	Sat Jun 21 20:41:18 2008 +0200
@@ -6,6 +6,7 @@
 public
 import sema.Operation;
 
+///
 class DType
 {
     private char[] id;
@@ -154,7 +155,7 @@
     {
         Void   = new DType("void");
 
-        Bool   = new DInteger("bool",    1, false);
+        Bool   = new DInteger("bool",    1, true);
         Byte   = new DInteger("byte",    8, false);
         UByte  = new DInteger("ubyte",   8, true);
         Short  = new DInteger("short",  16, false);
@@ -386,12 +387,14 @@
     override char[] mangle()
     {
         char[] res;
+
         res ~= "F";
 
         foreach(param ; params)
-            res ~= "J" ~ param.mangle;
+            res ~= param.mangle;
 
-        res ~= "Z" ~ returnType.mangle;
+        res ~= "Z";
+        res ~= returnType.mangle;
 
         return res;
     }
--- a/sema/Operation.d	Sat Jun 21 17:32:27 2008 +0200
+++ b/sema/Operation.d	Sat Jun 21 20:41:18 2008 +0200
@@ -21,7 +21,8 @@
 {
     Add, Sub, Mul, SDiv, UDiv, FDiv, SRem, URem, FRem,
 
-    Shl, LShr, AShr,
+    // FShr is a dummy element to avoid special case for signed >> unsigned
+    Shl, LShr, AShr, FShr,
     And, Or, Xor,
 
     Eq, Ne,
--- a/sema/Scope.d	Sat Jun 21 17:32:27 2008 +0200
+++ b/sema/Scope.d	Sat Jun 21 20:41:18 2008 +0200
@@ -8,7 +8,8 @@
        ast.Exp;
 
 public 
-import sema.DType;
+import sema.DType,
+       sema.Symbol;
 
 class Scope
 {
@@ -28,24 +29,23 @@
 
     ImportDecl[] imports;
 
-
-    void add(Identifier id)
+    void put(Identifier id, Decl d)
     {
-        symbols[id] = id;
+        symbols[id] = d;
     }
 
-    Identifier find(Identifier id)
+    Decl find(Identifier id)
     {
         if(id is null)
             return null;
-        if (auto sym = id in symbols)
+        else if (auto sym = id in symbols)
             return *sym;
-        if (enclosing !is null)
+        else if (enclosing !is null)
         {
-            auto type = enclosing.find(id);
-            if(type is null)
+            auto res = enclosing.find(id);
+            if (res is null)
                 return mHandle.find(getImports, id);
-            return type;
+            return res;
         }
         return null;
     }
@@ -60,7 +60,7 @@
     DType findType(Identifier id)
     {
         if (auto type = id.get in types)
-                return *type;
+            return *type;
         if (enclosing !is null)
         {
             auto type = enclosing.findType(id);
@@ -71,6 +71,7 @@
         return null;
     }
 
+    /*
     char[][] names()
     {
         char[][] res;
@@ -82,6 +83,7 @@
             res ~= sym.name ~ " : " ~ (sym.type is null? "?" : sym.type.name);
         return res;
     }
+    */
 
     FuncDecl parentFunction()
     {
@@ -123,7 +125,7 @@
     DType[char[]] types;
     int currentStmtIndex = -1;
 private:
-    Identifier[Identifier] symbols;
+    Decl[Identifier] symbols;
     FuncDecl func;
 }
 
@@ -151,7 +153,7 @@
         return null;
     }
 
-    Identifier find(ImportDecl[] imports, Identifier id)
+    Decl find(ImportDecl[] imports, Identifier id)
     {
         foreach(i ; imports)
             if(i.get in modules)
--- a/sema/ScopeBuilder.d	Sat Jun 21 17:32:27 2008 +0200
+++ b/sema/ScopeBuilder.d	Sat Jun 21 20:41:18 2008 +0200
@@ -4,7 +4,8 @@
        tango.core.Array : find;
 
 public
-import sema.Scope;
+import sema.Scope,
+       sema.Symbol;
 
 import sema.Visitor,
        basic.SmallArray;
@@ -14,19 +15,31 @@
     override void visit(Module[] modules)
     {
         this.modules = modules;
-        super.visit(modules);
+        inFunctionBodyStack.push(false);
+        foreach (mod; modules)
+        {
+            current = mod;
+            foreach (decl; mod.decls)
+                visitDecl(decl);
+        }
     }
 
     override void visitFuncDecl(FuncDecl d)
     {
+
         visitExp(d.returnType);
         visitExp(d.identifier);
         foreach (arg; d.funcArgs)
             visitDecl(arg);
+
+        inFunctionBodyStack.push(true);
+
         foreach (stmt; d.statements)
             visitStmt(stmt);
 
-        d.env.find(d.identifier).setType(d.type);
+        inFunctionBodyStack.pop();
+
+        d.sym = current.symbol.createMember(d.identifier.get, d.type);
     }
 
     override void visitVarDecl(VarDecl d)
@@ -37,35 +50,68 @@
         if (d.init)
             visitExp(d.init);
 
-        d.env.find(d.identifier).setType( typeOf(d.varType, d.env) );
+        DType t = typeOf(d.varType, d.env);
+        /*
+        if (inFunctionBodyStack.peek())
+        {
+            Stdout.formatln("?? {}, {}, {}", d.varType.get, d.identifier.get, t);
+            auto find = d.env.find(d.varType);
+            d.sym = d.env.find(d.varType).sym;
+        }
+        else
+        */
+            d.sym = current.symbol.createMember(d.identifier.get, t);
     }
 
     override void visitStructDecl(StructDecl s)
     {
-        super.visitStructDecl(s);
+        auto st = s.env.findType(s.identifier).asStruct;
+        s.sym = current.symbol.createMember(s.identifier.get, st);
+        //s.env.set(s.identifier, s);
 
-        DType[char[]] types;
+        auto old = current.symbol;
+        current.symbol = s.sym;
+        inFunctionBodyStack.push(false);
+        super.visitStructDecl(s);
+        inFunctionBodyStack.pop();
+        current.symbol = old;
 
-        auto st = s.env.types[s.identifier.get].asStruct;
         foreach (decl; s.decls)
+        {
+            DType type;
+            char[] name;
             if (auto varDecl = cast(VarDecl)decl)
-                st.addMember(typeOf(varDecl.varType, varDecl.env), varDecl.identifier.get);
+            {
+                type = typeOf(varDecl.varType, varDecl.env);
+                name = varDecl.identifier.get;
+            }
             else if (auto fd = cast(FuncDecl)decl)
-                st.addMember(fd.type, fd.identifier.get);
+            {
+                type = fd.type;
+                name = fd.identifier.get;
+            }
+            st.addMember(type, name);
+        }
     }
 
     DType typeOf(Identifier id, Scope sc)
     {
         if(auto i = cast(PointerIdentifier)id)
             return (typeOf(i.pointerOf, sc)).getPointerTo();
-        if(auto i = cast(ArrayIdentifier)id)
+        else if(auto i = cast(ArrayIdentifier)id)
             return typeOf(i.arrayOf, sc).getAsArray(i.size);
         return sc.findType(id);
     }
 
     Module[] modules;
+    Module current;
+    SmallArray!(bool) inFunctionBodyStack;
 }
 
+/**
+  Add scopes to everything, and add all identifiers that correspond to types.
+  Types/Symbols are added by ForwardReference.
+ **/
 class ScopeBuilder : Visitor!(void)
 {
     static ModuleHandler mHandle;
@@ -89,26 +135,43 @@
         fr.visit(modules);
     }
 
+    private void registerBasicTypeTo(char[] n, DType t, Scope sc, Module m)
+    {
+        sc.types[n] = t;
+        auto sym = m.symbol.createMember(n, t);
+        auto id = new Identifier(n);
+        id.env = sc;
+        auto decl = new DummyDecl();
+        decl.sym = sym;
+        decl.env = sc;
+        sc.put(id, decl);
+    }
+
     override void visitModule(Module m)
     {
-        table ~= new Scope;
-        table[table.length-1].types["void"]    = DType.Void;
-        table[table.length-1].types["bool"]    = DType.Bool;
-        table[table.length-1].types["byte"]    = DType.Byte;
-        table[table.length-1].types["ubyte"]   = DType.UByte;
-        table[table.length-1].types["short"]   = DType.Short;
-        table[table.length-1].types["ushort"]  = DType.UShort;
-        table[table.length-1].types["int"]     = DType.Int;
-        table[table.length-1].types["uint"]    = DType.UInt;
-        table[table.length-1].types["long"]    = DType.Long;
-        table[table.length-1].types["ulong"]   = DType.ULong;
-        table[table.length-1].types["char"]    = DType.Char;
-        table[table.length-1].types["wchar"]   = DType.WChar;
-        table[table.length-1].types["dchar"]   = DType.DChar;
+        auto root = new Scope;
+        table ~= root;
+
+        m.symbol = new Symbol;
 
-        table[table.length-1].types["float"]   = DType.Float;
-        table[table.length-1].types["double"]  = DType.Double;
-        table[table.length-1].types["real"]    = DType.Real;
+        registerBasicTypeTo("void",     DType.Void, root, m);
+        registerBasicTypeTo("bool",     DType.Bool, root, m);
+        registerBasicTypeTo("byte",     DType.Byte, root, m);
+        registerBasicTypeTo("ubyte",    DType.UByte, root, m);
+        registerBasicTypeTo("short",    DType.Short, root, m);
+        registerBasicTypeTo("ushort",   DType.UShort, root, m);
+        registerBasicTypeTo("int",      DType.Int, root, m);
+        registerBasicTypeTo("uint",     DType.UInt, root, m);
+        registerBasicTypeTo("long",     DType.Long, root, m);
+        registerBasicTypeTo("ulong",    DType.ULong, root, m);
+
+        registerBasicTypeTo("char",     DType.Char, root, m);
+        registerBasicTypeTo("wchar",    DType.WChar, root, m);
+        registerBasicTypeTo("dchar",    DType.DChar, root, m);
+
+        registerBasicTypeTo("float",    DType.Float, root, m);
+        registerBasicTypeTo("double",   DType.Double, root, m);
+        registerBasicTypeTo("real",     DType.Real, root, m);
 
         current().inModule = m;
         current().mHandle = mHandle;
@@ -145,7 +208,7 @@
 
     override void visitFuncDecl(FuncDecl d)
     {
-        current().add(d.identifier);
+        current().put(d.identifier, d);
         auto sc = push();
 
         visitExp(d.returnType);
@@ -173,7 +236,7 @@
         }
 
         auto sc = current();
-        sc.add(d.identifier);
+        sc.put(d.identifier, d);
         d.env = sc;
         visitExp(d.varType);
         visitExp(d.identifier);
@@ -182,10 +245,10 @@
     override void visitStructDecl(StructDecl s)
     {
         auto sc = current();
-        sc.add(s.identifier);
+        sc.put(s.identifier, s);
         s.env = sc;
         auto type = new DStruct(s.identifier);
-        
+
         sc.types[s.identifier.get] = type;
 
         sc = push();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sema/Symbol.d	Sat Jun 21 20:41:18 2008 +0200
@@ -0,0 +1,133 @@
+module sema.Symbol;
+
+import tango.text.convert.Integer : format;
+import tango.io.Stdout;
+
+import sema.DType;
+
+///
+class Symbol
+{
+    /// Create a root symbol - representing a module
+    this() { actual = this; }
+
+    /// Get a simple human readable name (bar)
+    char[] getName() { return name; }
+
+    /// Get a human readable name (foo.bar)
+    char[] getFQN()
+    {
+        char[] prefix;
+        if (parent !is null && parent.name !is null)
+            prefix ~= parent.getFQN() ~ ".";
+        return prefix ~ name;
+    }
+
+    /// Get a machine readable name (_D3foo3barFZi)
+    char[] getMangledFQN()
+    {
+        char[] n = `_D`;
+        Symbol p = parent;
+        while (p !is null) {
+            n ~= p.internalFQN();
+            p = p.parent;
+        }
+        n ~= internalFQN();
+        n ~= type.mangle();
+        return n;
+    }
+
+    /**
+      Try to find a contained symbol with the given name - returns null if not
+      found
+     **/
+    Symbol findMember(char[] member)
+    {
+        Stdout.formatln("Trying to find {} in {}", member, name);
+        foreach (possible; contained)
+            if (possible.name == member)
+            {
+        Stdout.formatln("  - found it: {} ({})", possible.getFQN(), possible.getMangledFQN());
+                return possible;
+            }
+        return null;
+    }
+
+    void dump()
+    {
+        Stdout("Symbol: ");
+        Symbol p = parent;
+        while (p !is null) {
+            Stdout.format("{}.", p.name);
+            p = p.parent;
+        }
+        Stdout.formatln("{}", name);
+    }
+
+    /// Create a member with the given name and type
+    Symbol createMember(char[] member, DType type)
+    {
+        //Stdout.formatln("Creating {} of type {} in {}", member, type.mangle, name);
+        auto res = new Symbol(member, type, this);
+        contained ~= res;
+        return res;
+    }
+
+    /**
+      Create an alias of another symbol with the given name.
+
+      The target symbol can be a member of another symbol
+     **/
+    Symbol createAlias(char[] aliasedName, Symbol target)
+    {
+        auto res = new Symbol(aliasedName, target, this);
+        contained ~= res;
+        return res;
+    }
+
+    // The type of this symbol
+    DType type;
+
+private:
+    // Helper for getMangledFQN - gets the FQN without _D and the type
+    char[] internalFQN()
+    {
+        if (actual.name !is null && actual.name.length > 0)
+        {
+            char[32] len;
+            return format(len, actual.name.length) ~ actual.name;
+        }
+        return "";
+    }
+
+    this(char[] name, Symbol actual, Symbol parent)
+    {
+        this.name = name;
+        this.actual = actual;
+        this.parent = parent;
+        this.type = actual.type;
+    }
+
+    this(char[] name, DType type, Symbol parent)
+    {
+        this.name = name;
+        this.actual = this;
+        this.parent = parent;
+        this.type = type;
+    }
+
+private:
+    char[] name;
+
+    // If the symbol is an alias, this will point to the actual symbol
+    Symbol actual;
+    // If this symbol is contained within a struct or similar this will point
+    // to that symbol
+    Symbol parent;
+    // All the symbols contained within this symbol
+    Symbol[] contained;
+
+    // The module that contains this symbol (root of the parent-chain)
+    // DModule mod;
+}
+