diff options
author | David Robillard <d@drobilla.net> | 2009-10-16 14:26:42 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-10-16 14:26:42 +0000 |
commit | 338da7070dfe47fdf041b35a6d84c00fab6d9678 (patch) | |
tree | 118736b14c7160709cee5e916c3adcb0d5bcd4ab | |
parent | bf0d7b7add98f976592c9766273ecc84f8b0b6b9 (diff) | |
download | resp-338da7070dfe47fdf041b35a6d84c00fab6d9678.tar.gz resp-338da7070dfe47fdf041b35a6d84c00fab6d9678.tar.bz2 resp-338da7070dfe47fdf041b35a6d84c00fab6d9678.zip |
Compile top level definitions to globalas.
git-svn-id: http://svn.drobilla.net/resp/tuplr@239 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r-- | src/c.cpp | 14 | ||||
-rw-r--r-- | src/compile.cpp | 8 | ||||
-rw-r--r-- | src/llvm.cpp | 25 | ||||
-rw-r--r-- | src/repl.cpp | 16 | ||||
-rw-r--r-- | src/tuplr.hpp | 8 |
5 files changed, 62 insertions, 9 deletions
@@ -141,6 +141,8 @@ struct CEngine : public Engine { CVal compileLiteral(CEnv& cenv, AST* lit); CVal compilePrimitive(CEnv& cenv, APrimitive* prim); CVal compileIf(CEnv& cenv, AIf* aif); + CVal compileGlobal(CEnv& cenv, AType* type, const string& name, CVal val); + CVal getGlobal(CEnv& cenv, CVal val); void writeModule(CEnv& cenv, std::ostream& os) { os << out; @@ -310,3 +312,15 @@ CEngine::compilePrimitive(CEnv& cenv, APrimitive* prim) out += (format("const %s %s = %s;\n") % *llType(cenv.type(prim)) % *varname % val).str(); return varname; } + +CVal +CEngine::compileGlobal(CEnv& cenv, AType* type, const string& name, CVal val) +{ + return NULL; +} + +CVal +CEngine::getGlobal(CEnv& cenv, CVal val) +{ + return NULL; +} diff --git a/src/compile.cpp b/src/compile.cpp index 2a716c2..605ec40 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -34,7 +34,10 @@ COMPILE_LITERAL(bool); CVal ASymbol::compile(CEnv& cenv) { - return *cenv.vals.ref(this); + if (cenv.vals.topLevel(this) && cenv.type(this)->head()->str() != "Fn") + return cenv.engine()->getGlobal(cenv, *cenv.vals.ref(this)); + else + return *cenv.vals.ref(this); } CVal @@ -72,8 +75,7 @@ ACall::compile(CEnv& cenv) CVal ADef::compile(CEnv& cenv) { - // Define stub first for recursion - cenv.def(sym(), body(), cenv.type(body()), NULL); + cenv.def(sym(), body(), cenv.type(body()), NULL); // define stub first for recursion CVal val = body()->compile(cenv); cenv.vals.def(sym(), val); return val; diff --git a/src/llvm.cpp b/src/llvm.cpp index 26b4bf2..fa4e99e 100644 --- a/src/llvm.cpp +++ b/src/llvm.cpp @@ -56,7 +56,7 @@ llType(const AType* t) } else if (t->kind == AType::EXPR && t->head()->str() == "Fn") { AType::const_iterator i = t->begin(); const ATuple* protT = (*++i)->to<const ATuple*>(); - const AType* retT = (*i)->as<const AType*>(); + const AType* retT = (*++i)->as<const AType*>(); if (!llType(retT)) return NULL; @@ -173,6 +173,8 @@ struct LLVMEngine : public Engine { CVal compileLiteral(CEnv& cenv, AST* lit); CVal compilePrimitive(CEnv& cenv, APrimitive* prim); CVal compileIf(CEnv& cenv, AIf* aif); + CVal compileGlobal(CEnv& cenv, AType* type, const string& name, CVal val); + CVal getGlobal(CEnv& cenv, CVal val); void writeModule(CEnv& cenv, std::ostream& os) { AssemblyAnnotationWriter writer; @@ -194,6 +196,8 @@ struct LLVMEngine : public Engine { ss << (((bool (*)())fp)() ? "#t" : "#f"); else if (t != Type::VoidTy) ss << ((void* (*)())fp)(); + else + ((void (*)())fp)(); return ss.str(); } @@ -433,3 +437,22 @@ LLVMEngine::compilePrimitive(CEnv& cenv, APrimitive* prim) throw Error(prim->loc, "unknown primitive"); } + +CVal +LLVMEngine::compileGlobal(CEnv& cenv, AType* type, const string& name, CVal val) +{ + LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine()); + Constant* init = Constant::getNullValue(llType(type)); + GlobalVariable* global = new GlobalVariable(llType(type), false, + GlobalValue::ExternalLinkage, Constant::getNullValue(llType(type)), name, module); + + engine->builder.CreateStore(llVal(val), global); + return global; +} + +CVal +LLVMEngine::getGlobal(CEnv& cenv, CVal val) +{ + LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine()); + return engine->builder.CreateLoad(llVal(val), "globalPtr"); +} diff --git a/src/repl.cpp b/src/repl.cpp index d66fe36..85b2821 100644 --- a/src/repl.cpp +++ b/src/repl.cpp @@ -60,7 +60,7 @@ readParseTypeCompile(CEnv& cenv, Cursor& cursor, istream& is, AST*& exp, AST*& a static void callPrintCollect(CEnv& cenv, CFunc f, AST* result, AType* resultT, bool execute) { - if (execute && resultT->concrete()) + if (execute) cenv.out << cenv.engine()->call(cenv, f, resultT); // Print type (if applicable) @@ -127,7 +127,6 @@ repl(CEnv& cenv) Cursor cursor("(stdin)"); try { - Subst oldSubst = cenv.tsubst; if (!readParseTypeCompile(cenv, cursor, std::cin, exp, ast, type)) break; @@ -135,15 +134,22 @@ repl(CEnv& cenv) try { // Create function for this repl loop f = cenv.engine()->startFunction(cenv, replFnName, type, ATuple(cursor)); - cenv.engine()->finishFunction(cenv, f, type, ast->compile(cenv)); + + CVal val = ast->compile(cenv); + + // Set global if expression is a top level define + if (ast->to<ADef*>()) { + ADef* def = ast->to<ADef*>(); + cenv.vals.def(def->sym(), cenv.engine()->compileGlobal( + cenv, cenv.type(def->body()), def->sym()->str(), val)); + } + cenv.engine()->finishFunction(cenv, f, type, val); callPrintCollect(cenv, f, ast, type, true); } catch (Error& e) { cenv.out << e.msg << endl; cenv.engine()->eraseFunction(cenv, f); } - cenv.tsubst = oldSubst; - } catch (Error& e) { cenv.err << e.what() << endl; } diff --git a/src/tuplr.hpp b/src/tuplr.hpp index 9a87c37..059a6cf 100644 --- a/src/tuplr.hpp +++ b/src/tuplr.hpp @@ -85,6 +85,12 @@ struct Env : public list< vector< pair<K,V> > > { return &b->second; return NULL; } + bool topLevel(const K& key) { + for (typename Frame::iterator b = this->back().begin(); b != this->back().end(); ++b) + if (b->first == key) + return true; + return false; + } }; @@ -635,6 +641,8 @@ struct Engine { virtual CVal compileCall(CEnv& cenv, CFunc f, const vector<CVal>& args) = 0; virtual CVal compilePrimitive(CEnv& cenv, APrimitive* prim) = 0; virtual CVal compileIf(CEnv& cenv, AIf* aif) = 0; + virtual CVal compileGlobal(CEnv& cenv, AType* t, const string& sym, CVal val) = 0; + virtual CVal getGlobal(CEnv& cenv, CVal val) = 0; virtual void writeModule(CEnv& cenv, std::ostream& os) = 0; virtual const string call(CEnv& cenv, CFunc f, AType* retT) = 0; |