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)