changeset 53:da551f90e03f new_gen

Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
author Anders Johnsen <skabet@gmail.com>
date Sat, 26 Apr 2008 18:52:27 +0200
parents 6decab6f45c4
children d84fec04d462
files ast/Decl.d dsss.conf gen/CodeGen.d parser/Action.d parser/Parser.d sema/AstAction.d sema/SymbolTable.d sema/SymbolTableBuilder.d test.td
diffstat 9 files changed, 158 insertions(+), 65 deletions(-) [+]
line wrap: on
line diff
--- a/ast/Decl.d	Sat Apr 26 16:12:36 2008 +0200
+++ b/ast/Decl.d	Sat Apr 26 18:52:27 2008 +0200
@@ -66,14 +66,18 @@
 
 class StructDecl : Decl
 {
-    this(Identifier identifier, 
-            VarDecl[] vars)
+    this(Identifier identifier)
     {
         super(DeclType.StructDecl);
         this.identifier = identifier;
         this.vars = vars;
     }
 
+    void addMember(Identifier type, Identifier name, Exp exp)
+    {
+        vars ~= new VarDecl(type, name, exp);
+    }
+
     Identifier identifier;
     VarDecl[] vars;
 }
--- a/dsss.conf	Sat Apr 26 16:12:36 2008 +0200
+++ b/dsss.conf	Sat Apr 26 18:52:27 2008 +0200
@@ -9,7 +9,7 @@
 buildflags = -llllvm-c-ext -llstdc++ \
  -llLLVMCore -llLLVMBitWriter -llLLVMBitReader -llLLVMAnalysis -llLLVMTarget \
  -llLLVMTransformUtils -llLLVMScalarOpts -llLLVMipa -llLLVMipo \
- -llLLVMInstrumentation -llLLVMSystem -llLLVMSupport
+ -llLLVMInstrumentation -llLLVMSystem -llLLVMSupport -lldl
 
 [tests/run.d]
 Target = tests/run
--- a/gen/CodeGen.d	Sat Apr 26 16:12:36 2008 +0200
+++ b/gen/CodeGen.d	Sat Apr 26 18:52:27 2008 +0200
@@ -568,6 +568,17 @@
             type_map[t] = res;
             return res;
         }
+        if (auto s = cast(DStruct)t)
+        {
+            Type[] members;
+            foreach(m; s.members)
+                members ~= llvm(m);
+
+
+            Type res = StructType.Get(members);
+            type_map[t] = res;
+            return res;
+        }
         assert(0, "Only integers are supported");
     }
 
--- a/parser/Action.d	Sat Apr 26 16:12:36 2008 +0200
+++ b/parser/Action.d	Sat Apr 26 18:52:27 2008 +0200
@@ -68,6 +68,14 @@
     }
 
     /**
+      Add a struct member to a struct.
+     */
+    void actOnStructMember(DeclT decl, ref Id type, ref Id name, ExprT init)
+    {
+        return null;
+    }
+
+    /**
       Add an initialization expression to a previously created decl.
 
       Used for default values on function params and for values to local
--- a/parser/Parser.d	Sat Apr 26 16:12:36 2008 +0200
+++ b/parser/Parser.d	Sat Apr 26 18:52:27 2008 +0200
@@ -63,12 +63,52 @@
         }
         else if (t.type == Tok.Struct)
         {
+            Id type = Id(lexer.next);
+            Id iden = Id(require(Tok.Identifier));
+            
+            return parseStruct(type, iden);
         }
         char[] c = t.getType;
         throw error(__LINE__, PE.UnexpectedTok).tok(t).arg(c);
     }
 
     /**
+      Parse struct
+     */
+    Decl parseStruct(Id type, Id iden)
+    {
+        auto decl = action.actOnDeclarator(type, iden, null);
+
+        require(Tok.OpenBrace);
+
+        while(lexer.peek.isBasicType || lexer.peek.isIdentifier)
+        {
+            Id var_type = Id(lexer.next);
+            Id var_iden = Id(require(Tok.Identifier));
+            Token next = lexer.peek();
+            if (next.type == Tok.Seperator)
+            {
+                Token sep = lexer.next();
+                action.actOnStructMember(decl, var_type, var_iden, null);
+                continue;
+            }
+            else if (next.type == Tok.Assign)
+            {
+                Token assign = lexer.next();
+                Exp exp = parseExpression();
+                require(Tok.Seperator);
+                action.actOnStructMember(decl, var_type, var_iden, exp);
+                continue;
+            }
+            throw error(__LINE__, PE.UnexpectedTok)
+                .tok(next).arg(next.getType);
+        }
+
+        require(Tok.CloseBrace);
+        
+        return decl;
+    }
+    /**
       Parse statements.
 
       This is the place to attack!
--- a/sema/AstAction.d	Sat Apr 26 16:12:36 2008 +0200
+++ b/sema/AstAction.d	Sat Apr 26 18:52:27 2008 +0200
@@ -23,7 +23,20 @@
     override DeclT actOnDeclarator(ref Id type, ref Id id, ExprT init)
     {
         Exp exp = cast(Exp)init;
-        return new VarDecl(new Identifier(type.tok), new Identifier(id.tok), exp);
+        if(type.tok.type == Tok.Struct)
+            return new StructDecl(new Identifier(id.tok));
+        else
+            return new VarDecl(new Identifier(type.tok), new Identifier(id.tok), exp);
+    }
+    
+    override void actOnStructMember(DeclT decl, ref Id type, ref Id name, ExprT init)
+    {
+        Exp exp = cast(Exp)init;
+        StructDecl st = cast(StructDecl)decl;
+        st.addMember(
+                new Identifier(type.tok), 
+                new Identifier(name.tok), 
+                exp);
     }
 
     override DeclT actOnStartOfFunctionDef(ref Id type, ref Id name)
--- a/sema/SymbolTable.d	Sat Apr 26 16:12:36 2008 +0200
+++ b/sema/SymbolTable.d	Sat Apr 26 18:52:27 2008 +0200
@@ -76,7 +76,7 @@
     {
         if (func)
             return Stdout.layout.convert("{}: {}", func.id.get, symbols.length);
-        return "root";
+        return Stdout.layout.convert("root: {}", symbols.length);
     }
 
     Symbol parentFunction(Symbol f)
--- a/sema/SymbolTableBuilder.d	Sat Apr 26 16:12:36 2008 +0200
+++ b/sema/SymbolTableBuilder.d	Sat Apr 26 18:52:27 2008 +0200
@@ -10,6 +10,62 @@
 
 class SymbolTableBuilder : Visitor!(void)
 {
+    override void visit(Decl[] decls)
+    {
+        auto sb = new ScopeBuilder();
+        sb.visit(decls);
+        foreach (decl; decls)
+            visitDecl(decl);
+    }
+
+    override void visitFuncDecl(FuncDecl d)
+    {
+        d.env.find(d.identifier).type = typeOf(d.type, d.env);
+        visitExp(d.type);
+        visitExp(d.identifier);
+        foreach (arg; d.funcArgs)
+            visitDecl(arg);
+        foreach (stmt; d.statements)
+            visitStmt(stmt);
+    }
+
+    override void visitVarDecl(VarDecl d)
+    {
+        if (d.init)
+            visitExp(d.init);
+
+        d.env.find(d.identifier).type = typeOf(d.type, d.env);
+        visitExp(d.type);
+        visitExp(d.identifier);
+    }
+
+    override void visitStructDecl(StructDecl s)
+    {
+        DType[char[]] types;
+        foreach(varDecl ; s.vars)
+        {
+            types[varDecl.identifier.get] = typeOf(varDecl.type, s.env);
+        }
+
+        (cast(DStruct)s.env.types[s.identifier.get]).setMembers(types);
+        super.visitStructDecl(s);
+    }
+
+    DType typeOf(Identifier id, Scope sc)
+    {
+        return sc.findType(id);
+
+        /*
+        if (auto type = id.get in types)
+            return *type;
+        DType res = new DType(id);
+        types[id.get] = res;
+        return res;*/
+    }
+}
+
+class ScopeBuilder : Visitor!(void)
+{
     this()
     {
         table ~= new Scope;
@@ -53,7 +109,7 @@
     {
         auto sym = current().add(d.identifier);
         auto sc = push();
-        sym.type = typeOf(d.type, sc);
+
         visitExp(d.type);
         visitExp(d.identifier);
         d.env = current();
@@ -70,14 +126,13 @@
         if (d.init)
             visitExp(d.init);
 
-        if (need_push > 0) {
+        if (need_push > 0 && current().parentFunction !is null) {
             push();
             --need_push;
         }
 
         auto sc = current();
         auto sym = sc.add(d.identifier);
-        sym.type = typeOf(d.type, sc);
         d.env = sc;
         visitExp(d.type);
         visitExp(d.identifier);
@@ -87,18 +142,10 @@
     {
         auto sc = current();
         auto sym = sc.add(s.identifier);
-        DType[char[]] types;
-        foreach(varDecl ; s.vars)
-        {
-            types[varDecl.identifier.get] = typeOf(varDecl.type, sc);
-        }
 
         auto type = new DStruct(s.identifier);
         
-        type.setMembers(types);
-
         sc.types[s.identifier.get] = type;
-        sym.type = type;
         s.env = sc;
         super.visitStructDecl(s);
     }
@@ -169,18 +216,5 @@
     {
         return table[$ - 1];
     }
-
-    DType typeOf(Identifier id, Scope sc)
-    {
-        return sc.findType(id);
-
-        /*
-        if (auto type = id.get in types)
-            return *type;
-        DType res = new DType(id);
-        types[id.get] = res;
-        return res;*/
-    }
-    DType[char[]] types;
 }
 
--- a/test.td	Sat Apr 26 16:12:36 2008 +0200
+++ b/test.td	Sat Apr 26 18:52:27 2008 +0200
@@ -1,48 +1,31 @@
+
+
+
+int main()
+{
+    int y = 4;
+
+    karina k;
+
+
+    while (y > 0)
+        y = y - 1;
+
+    return x;
+}
 
 int x = 4;
 
+
 struct karina
 {
+    anders a;
     int age;
     int width;
     int height;
     int lovers;
 }
-
-int main()
+struct anders
 {
-    int y = 4;
-    switch (y)
-    {
-        case 2:
-            y = 3;
-        case 3:
-        default:
-            y = 5;
-        case 5, 6, 7:
-            return 1;
-    }
-
-    karina k;
-
-    k.age = 21;
-    k.width = 120000;
-    k.height = 50;
-    k.lovers = 76;
-    
-
-    while (y > 0)
-        y = y - 1;
-
-    getLovers(k, k.age);
-
-    return k.age;
+    int hej;
 }
-
-int getLovers(karina k, int offset)
-{
-    k.age = 42;
-    k.lovers = offset + k.age * k.height;
-    return k.lovers + 72 + offset;
-}
-