aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-10-16 14:26:42 +0000
committerDavid Robillard <d@drobilla.net>2009-10-16 14:26:42 +0000
commit338da7070dfe47fdf041b35a6d84c00fab6d9678 (patch)
tree118736b14c7160709cee5e916c3adcb0d5bcd4ab
parentbf0d7b7add98f976592c9766273ecc84f8b0b6b9 (diff)
downloadresp-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.cpp14
-rw-r--r--src/compile.cpp8
-rw-r--r--src/llvm.cpp25
-rw-r--r--src/repl.cpp16
-rw-r--r--src/tuplr.hpp8
5 files changed, 62 insertions, 9 deletions
diff --git a/src/c.cpp b/src/c.cpp
index 4e9a49f..563c2ba 100644
--- a/src/c.cpp
+++ b/src/c.cpp
@@ -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;