# HG changeset patch # User Anders Johnsen # Date 1209228747 -7200 # Node ID da551f90e03f255e6bfd6f645d08b7a27933c287 # Parent 6decab6f45c4cc86fbe2b73e2b375cf188635d52 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 diff -r 6decab6f45c4 -r da551f90e03f ast/Decl.d --- 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; } diff -r 6decab6f45c4 -r da551f90e03f dsss.conf --- 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 diff -r 6decab6f45c4 -r da551f90e03f gen/CodeGen.d --- 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"); } diff -r 6decab6f45c4 -r da551f90e03f parser/Action.d --- 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 diff -r 6decab6f45c4 -r da551f90e03f parser/Parser.d --- 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! diff -r 6decab6f45c4 -r da551f90e03f sema/AstAction.d --- 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) diff -r 6decab6f45c4 -r da551f90e03f sema/SymbolTable.d --- 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) diff -r 6decab6f45c4 -r da551f90e03f sema/SymbolTableBuilder.d --- 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; } diff -r 6decab6f45c4 -r da551f90e03f test.td --- 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; -} -