aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-05-15 20:15:27 +0000
committerDavid Robillard <d@drobilla.net>2011-05-15 20:15:27 +0000
commit8cbb1c710d6c8877dfc2871dc3f068b52598a884 (patch)
treee1a7b157be12dbaafc8baee861407242595d0e4f
parentec6bd7cded43bfd3ba1491c8ec08eb1975334e4e (diff)
downloadresp-8cbb1c710d6c8877dfc2871dc3f068b52598a884.tar.gz
resp-8cbb1c710d6c8877dfc2871dc3f068b52598a884.tar.bz2
resp-8cbb1c710d6c8877dfc2871dc3f068b52598a884.zip
Generate code entirely via emitting flat IR (don't special case main/repl).
git-svn-id: http://svn.drobilla.net/resp/trunk@427 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r--src/c.cpp3
-rw-r--r--src/compile.cpp18
-rw-r--r--src/llvm.cpp6
-rw-r--r--src/repl.cpp98
-rw-r--r--src/resp.hpp7
5 files changed, 73 insertions, 59 deletions
diff --git a/src/c.cpp b/src/c.cpp
index d83ff95..f172b65 100644
--- a/src/c.cpp
+++ b/src/c.cpp
@@ -42,7 +42,6 @@ struct CEngine : public Engine {
}
CFunc startFn(CEnv& cenv, const string& name, const ATuple* args, const ATuple* type);
- void pushFnArgs(CEnv& cenv, const ATuple* prot, const ATuple* type, CFunc f);
void finishFn(CEnv& cenv, CFunc f, CVal ret, const AST* retT);
void eraseFn(CEnv& cenv, CFunc f);
@@ -63,6 +62,8 @@ struct CEngine : public Engine {
const string call(CEnv& cenv, CFunc f, const AST* retT);
private:
+ void pushFnArgs(CEnv& cenv, const ATuple* prot, const ATuple* type, CFunc f);
+
typedef string Type;
typedef string Value;
diff --git a/src/compile.cpp b/src/compile.cpp
index e8baed3..f84d789 100644
--- a/src/compile.cpp
+++ b/src/compile.cpp
@@ -33,7 +33,8 @@ compile_symbol(CEnv& cenv, const ASymbol* sym) throw()
return NULL;
if (cenv.repl && cenv.vals.topLevel(sym) && !is_form(cenv.type(sym), "Fn")) {
- return cenv.engine()->compileGlobalGet(cenv, sym->sym(), *cenv.vals.ref(sym));
+ CVal val = cenv.globals[sym->sym()];
+ return cenv.engine()->compileGlobalGet(cenv, sym->sym(), val);
} else {
return *cenv.vals.ref(sym);
}
@@ -93,6 +94,7 @@ compile_def(CEnv& cenv, const ATuple* def) throw()
if (cenv.repl && cenv.vals.topLevel(sym) && !is_form(cenv.type(sym), "Fn")) {
CVal global = cenv.engine()->compileGlobalSet(
cenv, sym->sym(), val, cenv.type(body));
+ cenv.globals.insert(make_pair(sym->sym(), global));
cenv.def(sym, body, cenv.type(body), global);
} else {
cenv.def(sym, body, cenv.type(body), val);
@@ -159,10 +161,7 @@ compile_fn_start(CEnv& cenv, const ATuple* call) throw()
const ATuple* type = cenv.type(name)->as_tuple();
const ATuple* args = call->rst()->rst();
- CFunc func = cenv.engine()->startFn(cenv, name->sym(), args, type);
- cenv.def(name, NULL, type, func);
-
- cenv.engine()->pushFnArgs(cenv, args, type, func);
+ cenv.engine()->startFn(cenv, name->sym(), args, type);
return NULL;
}
@@ -170,8 +169,13 @@ compile_fn_start(CEnv& cenv, const ATuple* call) throw()
static CVal
compile_fn_end(CEnv& cenv, const ATuple* call) throw()
{
- const AST* retT = cenv.type(call->frst())->as_tuple()->frrst();
- cenv.engine()->finishFn(cenv, resp_compile(cenv, call->frrst()), retT);
+ const AST* ret = (call->list_len() > 2) ? call->frrst() : NULL;
+ const AST* retT = (ret)
+ ? cenv.type(call->frst())->as_tuple()->frrst()
+ : cenv.penv.sym("Nothing");
+
+ cenv.engine()->finishFn(cenv, resp_compile(cenv, ret), retT);
+
cenv.pop();
return NULL;
}
diff --git a/src/llvm.cpp b/src/llvm.cpp
index 3391cb7..c4744c3 100644
--- a/src/llvm.cpp
+++ b/src/llvm.cpp
@@ -78,7 +78,6 @@ struct LLVMEngine : public Engine {
virtual ~LLVMEngine();
CFunc startFn(CEnv& cenv, const string& name, const ATuple* args, const ATuple* type);
- void pushFnArgs(CEnv& cenv, const ATuple* prot, const ATuple* type, CFunc f);
void finishFn(CEnv& cenv, CVal ret, const AST* retT);
CFunc getFn(CEnv& cenv, const std::string& name);
void eraseFn(CEnv& cenv, CFunc f);
@@ -103,6 +102,8 @@ struct LLVMEngine : public Engine {
const string call(CEnv& cenv, CFunc f, const AST* retT);
private:
+ void pushFnArgs(CEnv& cenv, const ATuple* prot, const ATuple* type, CFunc f);
+
void appendBlock(LLVMEngine* engine, Function* function, BasicBlock* block) {
function->getBasicBlockList().push_back(block);
engine->builder.SetInsertPoint(block);
@@ -403,6 +404,9 @@ LLVMEngine::startFn(
builder.SetInsertPoint(bb);
currentFn = f;
+ cenv.def(cenv.penv.sym(name), NULL, type, f);
+ pushFnArgs(cenv, args, type, f);
+
return f;
}
diff --git a/src/repl.cpp b/src/repl.cpp
index edaa003..b457e06 100644
--- a/src/repl.cpp
+++ b/src/repl.cpp
@@ -81,7 +81,7 @@ dump(CEnv& cenv, const Code& code)
}
const AST*
-compile(CEnv& cenv, const Code& parsed, Code& defs, Code& exprs)
+compile(CEnv& cenv, const Code& parsed, Code& defs, bool& hasMain, const char* mainName)
{
const AST* exp = NULL;
@@ -111,6 +111,7 @@ compile(CEnv& cenv, const Code& parsed, Code& defs, Code& exprs)
// Flatten expressions
const AST* retT = NULL;
+ Code exprs;
for (Code::const_iterator i = lifted.begin(); i != lifted.end(); ++i) {
const ATuple* call = (*i)->to_tuple();
if (call && (is_form(*i, "def-type")
@@ -125,6 +126,25 @@ compile(CEnv& cenv, const Code& parsed, Code& defs, Code& exprs)
}
}
+ // Flatten top-level code into main function
+ if (!exprs.empty()) {
+ const ASymbol* main = cenv.penv.sym(mainName);
+
+ List mainT(Cursor(), cenv.penv.sym("Fn"), new ATuple(Cursor()), retT, NULL);
+ cenv.def(main, NULL, mainT, NULL);
+
+ defs.push_back(
+ tup(Cursor(), cenv.penv.sym("fn-start"), main, NULL));
+
+ const AST* mainRet = NULL;
+ for (Code::const_iterator i = exprs.begin(); i != exprs.end(); ++i)
+ mainRet = resp_flatten(cenv, defs, *i);
+
+ defs.push_back(
+ tup(Cursor(), cenv.penv.sym("fn-end"), main, mainRet, NULL));
+ }
+
+ hasMain = !exprs.empty();
return retT;
}
@@ -145,27 +165,9 @@ eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute)
return 0;
}
- Code defs;
- Code exprs;
- const AST* retT = compile(cenv, parsed, defs, exprs);
-
- // Flatten main code into `defs'
- if (!exprs.empty()) {
- const ASymbol* main = cenv.penv.sym("main");
- List mainT(Cursor(), cenv.penv.sym("Fn"), new ATuple(Cursor()), retT, NULL);
- cenv.def(main, NULL, mainT, NULL);
-
- defs.push_back(
- tup(Cursor(), cenv.penv.sym("fn-start"), main, NULL));
-
- const AST* mainRet = NULL;
- for (Code::const_iterator i = exprs.begin(); i != exprs.end(); ++i)
- mainRet = resp_flatten(cenv, defs, *i);
-
- defs.push_back(
- tup(Cursor(), cenv.penv.sym("fn-end"), main, mainRet, NULL));
- }
-
+ Code defs;
+ bool hasMain;
+ const AST* retT = compile(cenv, parsed, defs, hasMain, "main");
if (cenv.args.find("-F") != cenv.args.end()) {
dump(cenv, defs);
return 0;
@@ -174,15 +176,15 @@ eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute)
// Compile flattened code
for (Code::const_iterator i = defs.begin(); i != defs.end(); ++i) {
resp_compile(cenv, *i);
+ Object::pool.addRoot(*i);
}
-
if (cenv.args.find("-S") != cenv.args.end()) {
cenv.engine()->writeModule(cenv, cenv.out);
return 0;
}
// Call main and print result
- if (!exprs.empty())
+ if (hasMain)
callPrintCollect(cenv, cenv.engine()->getFn(cenv, "main"),
ast, retT, execute);
@@ -199,9 +201,8 @@ repl(CEnv& cenv)
{
cenv.repl = true;
- const AST* exp = NULL;
- const AST* ast = NULL;
- const string replFnName = cenv.penv.gensymstr("_repl");
+ const AST* exp = NULL;
+ const AST* ast = NULL;
while (1) {
cenv.out << "() ";
cenv.out.flush();
@@ -211,24 +212,31 @@ repl(CEnv& cenv)
if (!readParseType(cenv, cursor, std::cin, exp, ast))
break;
- Code lifted;
- ast = resp_lift(cenv, lifted, ast);
-
- const AST* type = cenv.type(ast);
- const ATuple* fnT = tup(cursor, cenv.tenv.Fn, new ATuple(cursor), type, 0);
- CFunc f = NULL;
- try {
- // Create function for this repl loop
- f = cenv.engine()->startFn(cenv, replFnName, new ATuple(cursor), fnT);
- cenv.engine()->finishFn(cenv, resp_compile(cenv, ast), type);
-
- if (cenv.args.find("-S") != cenv.args.end())
- cenv.engine()->writeModule(cenv, cenv.out);
- else
- callPrintCollect(cenv, f, ast, type, true);
- } catch (Error& e) {
- cenv.out << e.msg << endl;
- cenv.engine()->eraseFn(cenv, f);
+ Code parsed;
+ parsed.push_back(ast);
+
+ Code defs;
+ bool hasMain;
+ const std::string replName = cenv.penv.gensymstr("_repl");
+ const AST* retT = compile(cenv, parsed, defs, hasMain, replName.c_str());
+ if (cenv.args.find("-F") != cenv.args.end()) {
+ dump(cenv, defs);
+ continue;
+ }
+
+ // Compile flattened code
+ for (Code::const_iterator i = defs.begin(); i != defs.end(); ++i) {
+ resp_compile(cenv, *i);
+ }
+ if (cenv.args.find("-S") != cenv.args.end()) {
+ cenv.engine()->writeModule(cenv, cenv.out);
+ continue;
+ }
+
+ // Call main and print result
+ if (hasMain) {
+ callPrintCollect(cenv, cenv.engine()->getFn(cenv, replName),
+ ast, retT, true);
}
} catch (Error& e) {
diff --git a/src/resp.hpp b/src/resp.hpp
index f12c4c9..f952c40 100644
--- a/src/resp.hpp
+++ b/src/resp.hpp
@@ -671,11 +671,6 @@ struct Engine {
const ATuple* args,
const ATuple* type) = 0;
- virtual void pushFnArgs(CEnv& cenv,
- const ATuple* prot,
- const ATuple* type,
- CFunc f) = 0;
-
virtual void finishFn(CEnv& cenv, CVal ret, const AST* retT) = 0;
virtual CFunc getFn(CEnv& cenv, const std::string& name) = 0;
virtual void eraseFn(CEnv& cenv, CFunc f) = 0;
@@ -784,6 +779,8 @@ struct CEnv {
map<string,string> args;
+ map<string, CVal> globals;
+
typedef map<const char*, CVal> CSyms;
CSyms cSyms;