Mercurial > projects > dang
changeset 101:fea8d61a2451 new_gen
First step(the other first was a bad one) toward imports. You can now compile two files that use eachother - given that they both are in the command line. Right now it's only root sturcts and methods you can use(i guess...?)
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Wed, 07 May 2008 19:58:13 +0200 |
parents | 5f258eaf9517 |
children | cd066f3b539a |
files | ast/Decl.d dang/compiler.d gen/CodeGen.d sema/LoadModule.d sema/Scope.d sema/ScopeBuilder.d sema/Visitor.d tools/AstPrinter.d |
diffstat | 8 files changed, 217 insertions(+), 129 deletions(-) [+] |
line wrap: on
line diff
--- a/ast/Decl.d Tue May 06 22:49:43 2008 +0200 +++ b/ast/Decl.d Wed May 07 19:58:13 2008 +0200 @@ -67,6 +67,15 @@ super(DeclType.ImportDecl); } + char[] get() + { + char[] res; + foreach(i ; packages) + res ~= i.get ~ "."; + res ~= name.get; + return res; + } + bool isStatic = false; Identifier[] packages;
--- a/dang/compiler.d Tue May 06 22:49:43 2008 +0200 +++ b/dang/compiler.d Wed May 07 19:58:13 2008 +0200 @@ -23,7 +23,6 @@ import gen.CodeGen; import sema.Visitor, - sema.LoadModule, sema.AstAction, sema.ScopeBuilder, sema.ScopeCheck, @@ -85,7 +84,7 @@ Signal!(Lexer) postLex; Signal!(Lexer) preParse; - Signal!(Module, SourceManager) postParse; + Signal!(Module[], SourceManager) postParse; preStart.attach(&checkFiles); @@ -143,50 +142,62 @@ auto what = options["what-to-do"]; if (what == "" || what == "gen-llvm") postParse.attach( - (Module m, SourceManager sm) { - StopWatch w; w.start; - auto llvmGen = new CodeGen(); - auto file = new FileConduit("out.bc", FileConduit.WriteCreate); - llvmGen.gen(m, file.fileHandle, optimize, inline); - timings ~= Measurement("Generating LLVM bytecode", w.stop); + (Module[] modules, SourceManager sm) { + foreach(m ; modules) + { + StopWatch w; w.start; + auto llvmGen = new CodeGen(); + auto file = new FileConduit(m.moduleName~".bc", FileConduit.WriteCreate); + llvmGen.gen(m, file.fileHandle, optimize, inline); + timings ~= Measurement("Generating LLVM bytecode", w.stop); + } }); else if (what == "compile") postParse.attach( - (Module m, SourceManager sm) { - StopWatch w; w.start; - auto llvmGen = new CodeGen(); - auto llc = new Process("llc","-o=-"); - auto gcc = new Process("gcc","-c","-o","out.o","-x","assembler","-"); - llc.execute(); - int i = dup(llc.stdin.fileHandle); - llc.stdin.detach; - llvmGen.gen(m, i, optimize, inline); - llc.wait(); - gcc.execute(); - gcc.stdin.copy(llc.stdout); - gcc.stdin.detach; - gcc.wait(); + (Module[] modules, SourceManager sm) { + foreach(m ; modules) + { + StopWatch w; w.start; + auto llvmGen = new CodeGen(); + auto llc = new Process("llc","-o=-"); + auto gcc = new Process("gcc","-c","-o","out.o","-x","assembler","-"); + llc.execute(); + int i = dup(llc.stdin.fileHandle); + llc.stdin.detach; + llvmGen.gen(m, i, optimize, inline); + llc.wait(); + gcc.execute(); + gcc.stdin.copy(llc.stdout); + gcc.stdin.detach; + gcc.wait(); + timings ~= Measurement("Generating assemble bytecode", w.stop); + } - timings ~= Measurement("Generating assemble bytecode", w.stop); }); else if (what == "dot") postParse.attach( - (Module m, SourceManager sm) { + (Module[] m, SourceManager sm) { StopWatch w; w.start; - auto print = new DotPrinter(); - print.print(m); + // auto print = new DotPrinter(); +// print.print(m); timings ~= Measurement("Generating dot output", w.stop); }); else if (what == "code") postParse.attach( - (Module m, SourceManager sm) { + (Module[] modules, SourceManager sm) { StopWatch w; w.start; auto print = new AstPrinter(sm); - print.print(m); + foreach ( m ; modules ) + print.print(m); timings ~= Measurement("Converting AST to text", w.stop); }); StopWatch total; total.start; + + Module[] modules; + + StopWatch watch; + watch.start; foreach (file; filesToHandle) { preLex(file); @@ -197,14 +208,12 @@ preParse(lexer); - StopWatch watch; - watch.start; auto parser = new Parser(messages); auto action = new AstAction(src_mgr); - auto m = cast(Module)parser.parse(src_mgr, lexer, action); - timings ~= Measurement("Lex + Parse", watch.stop); + modules ~= cast(Module)parser.parse(src_mgr, lexer, action); + timings ~= Measurement("Lex + Parse of '"~file~"'", watch.stop); messages.checkErrors(ExitLevel.Parser); - +/* StopWatch watch2; watch.start; watch2.start; @@ -228,9 +237,26 @@ timings ~= Measurement(" - Checking scopes", scope_check); timings ~= Measurement(" - Checking types", type_check); - postParse(m, src_mgr); + postParse(m, src_mgr);*/ } + + (new ScopeBuilder).visit(modules); + StopWatch watch2; + watch.start; + watch2.start; + (new ScopeCheck).visit(modules); + auto scope_check = watch2.stop; + watch2.start; + (new TypeCheck).visit(modules); + auto type_check = watch2.stop; + watch2.start; + + foreach (m; modules) + foreach (decl; m.decls) + decl.simplify(); + timings ~= Measurement("Total", total.stop); + postParse(modules, src_mgr); if (options.flag("time")) foreach (m; timings)
--- a/gen/CodeGen.d Tue May 06 22:49:43 2008 +0200 +++ b/gen/CodeGen.d Wed May 07 19:58:13 2008 +0200 @@ -77,11 +77,12 @@ ~this() { - b.dispose(); +// b.dispose(); } void gen(Module mod, uint handle, bool optimize, bool inline) { + this.mod = mod; // create module m = new LLVM.Module("main_module"); scope(exit) m.dispose(); @@ -139,7 +140,7 @@ } }; auto visitor = new VisitFuncDecls(registerFunc); - visitor.visit(mod); + visitor.visit([mod]); // Before beginning we move all top level var-decls to the start // and then we generate the var-decls first // partition is NOT required to be stable, but that should not create @@ -319,6 +320,7 @@ args ~= v; } + llvm(id.type); // BUG: doesn't do implicit type-conversion if(callExp.sret) return b.buildCall(m.getNamedFunction(id.getMangled), args, ""); @@ -705,18 +707,24 @@ Type res = FunctionType.Get(ret_t, params.unsafe()); type_map[t] = res; -/* auto llfunc = m.addFunction(res, f.name); - - foreach (i, param; f.params) - if (param.isStruct) - llfunc.addParamAttr(i, ParamAttr.ByVal); + auto id = new Identifier(f.name); + id.setType(f); + + auto f_t = m.getNamedFunction(id.getMangled); + if(f_t is null) + { + auto llfunc = m.addFunction(res, id.getMangled); - if (f.firstParamIsReturnValue) - { - llfunc.removeParamAttr(0, ParamAttr.ByVal); - llfunc.addParamAttr(0, ParamAttr.StructRet); + foreach (i, param; f.params) + if (param.isStruct) + llfunc.addParamAttr(i, ParamAttr.ByVal); + + if (f.firstParamIsReturnValue) + { + llfunc.removeParamAttr(0, ParamAttr.ByVal); + llfunc.addParamAttr(0, ParamAttr.StructRet); + } } -*/ return res; } else if (auto f = t.asPointer) @@ -753,6 +761,7 @@ private: // llvm stuff + Module mod; LLVM.Module m; LLVM.Builder b; Function llvm_memcpy;
--- a/sema/LoadModule.d Tue May 06 22:49:43 2008 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -module sema.LoadModule; - -import sema.Visitor, - sema.AstAction, - sema.ScopeBuilder, - sema.ScopeCheck, - sema.TypeCheck; - -import lexer.Lexer; -import parser.Parser; - -import basic.SourceManager, - basic.Message; - -import tango.io.Stdout, - tango.io.FilePath; - - -class LoadModule : Visitor!(Module[], void) -{ - Module[] visit(Module m, SourceManager sc, MessageHandler messages) - { - this.messages = messages; - this.sc = sc; - - visitModule(m); - - return res; - } - - void visitImportDecl(ImportDecl i) - { - char[] dir; - - foreach(p ; i.packages) - dir ~= p.get ~ "/"; - - dir ~= i.name.name ~".d"; - - if(!FilePath(dir).exists) - messages.report(CannotFindModule, i.name.loc) - .arg(dir) - .fatal(ExitLevel.Semantic); - - auto start = sc.addFile(dir); - auto lexer = new Lexer(start, sc, messages); - auto parser = new Parser(messages); - auto action = new AstAction(sc); - auto m = cast(Module)parser.parse(sc, lexer, action); - messages.checkErrors(ExitLevel.Parser); - - Module[] mods = (new LoadModule).visit(m, sc, messages); - (new ScopeBuilder).visit(m); - (new ScopeCheck).visit(m); - (new TypeCheck).visit(m); - - res ~= m; - } - - MessageHandler messages; - Module[] res; - SourceManager sc; -}
--- a/sema/Scope.d Tue May 06 22:49:43 2008 +0200 +++ b/sema/Scope.d Wed May 07 19:58:13 2008 +0200 @@ -18,11 +18,16 @@ this.enclosing = enclosing; this.func = enclosing.func; this.inModule = enclosing.inModule; + this.mHandle = enclosing.mHandle; } Scope enclosing; + ModuleHandler mHandle; Module inModule; + ImportDecl[] imports; + + void add(Identifier id) { symbols[id] = id; @@ -35,16 +40,33 @@ if (auto sym = id in symbols) return *sym; if (enclosing !is null) - return enclosing.find(id); + { + auto type = enclosing.find(id); + if(type is null) + return mHandle.find(getImports, id); + return type; + } return null; } + ImportDecl[] getImports() + { + if(enclosing) + return enclosing.getImports ~ imports; + return imports; + } + DType findType(Identifier id) { if (auto type = id.get in types) return *type; if (enclosing !is null) - return enclosing.findType(id); + { + auto type = enclosing.findType(id); + if(type is null) + return mHandle.findType(getImports, id); + return type; + } return null; } @@ -104,3 +126,43 @@ FuncDecl func; } +class ModuleHandler +{ + void add(Module m) + { + modules[m.moduleName] = m; + } + void add(Module m, char[] file) + { + fileToModule[file] = m.moduleName; + add(m); + } + + DType findType(ImportDecl[] imports, Identifier type) + { + foreach(i ; imports) + if(i.get in modules) + { + auto t = modules[i.get].env.findType(type); + if(t !is null) + return t; + } + return null; + } + + Identifier find(ImportDecl[] imports, Identifier id) + { + foreach(i ; imports) + if(i.get in modules) + { + auto t = modules[i.get].env.find(id); + if(t !is null) + return t; + } + return null; + } + + char[][char[]] fileToModule; + Module[char[]] modules; +} +
--- a/sema/ScopeBuilder.d Tue May 06 22:49:43 2008 +0200 +++ b/sema/ScopeBuilder.d Wed May 07 19:58:13 2008 +0200 @@ -11,6 +11,12 @@ class ForwardReference : Visitor!(void) { + override void visit(Module[] modules) + { + this.modules = modules; + super.visit(modules); + } + override void visitFuncDecl(FuncDecl d) { visitExp(d.returnType); @@ -53,31 +59,52 @@ return typeOf(i.arrayOf, sc).getAsArray(i.size); return sc.findType(id); } + + Module[] modules; } class ScopeBuilder : Visitor!(void) { + static ModuleHandler mHandle; + + static this() + { + mHandle = new ModuleHandler; + } + this() { + } + + override void visit(Module[] modules) + { + foreach(m ; modules) + visitModule(m); + + auto fr = new ForwardReference(); + + fr.visit(modules); + } + + override void visitModule(Module m) + { table ~= new Scope; - table[0].types["void"] = DType.Void; - table[0].types["bool"] = DType.Bool; - table[0].types["byte"] = DType.Byte; - table[0].types["ubyte"] = DType.UByte; - table[0].types["short"] = DType.Short; - table[0].types["ushort"] = DType.UShort; - table[0].types["int"] = DType.Int; - table[0].types["uint"] = DType.UInt; - table[0].types["long"] = DType.Long; - table[0].types["ulong"] = DType.ULong; - } + 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; - override void visit(Module m) - { current().inModule = m; - visitModule(m); - auto fr = new ForwardReference(); - fr.visit(m); + current().mHandle = mHandle; + mHandle.add(m); + m.env = current(); + super.visitModule(m); } override void visitDecl(Decl d) @@ -86,6 +113,12 @@ super.visitDecl(d); } + override void visitImportDecl(ImportDecl i) + { + i.env.imports ~= i; + super.visitImportDecl(i); + } + override void visitStmt(Stmt s) { s.env = current();
--- a/sema/Visitor.d Tue May 06 22:49:43 2008 +0200 +++ b/sema/Visitor.d Wed May 07 19:58:13 2008 +0200 @@ -13,9 +13,10 @@ class Visitor(FinalT = int, ModuleT = FinalT, DeclT = ModuleT, StmtT = DeclT, ExpT = StmtT) { public: - FinalT visit(Module m) + FinalT visit(Module[] modules) { - visitModule(m); + foreach(m ; modules) + visitModule(m); static if (is(FinalT == void)) return; else
--- a/tools/AstPrinter.d Tue May 06 22:49:43 2008 +0200 +++ b/tools/AstPrinter.d Wed May 07 19:58:13 2008 +0200 @@ -21,10 +21,14 @@ void print(Module m) { + printBeginLine("module "); + printEndLine(m.moduleName); + printEndLine(); foreach(decl ; m.decls) { printDecl(decl); } + printEndLine(); } void printDecl(Decl decl) @@ -68,7 +72,14 @@ printDecl(var); printCloseBrace; break; + + case DeclType.ImportDecl: + auto i = cast(ImportDecl)decl; + printBeginLine("import "); + printEndLine(i.get); + break; } + printEndLine(); } void printStatement(Stmt stmt)