aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-05-14 10:08:06 +0000
committerDavid Robillard <d@drobilla.net>2011-05-14 10:08:06 +0000
commitea1c80ab4422d2811292cc7be651bd298f66b8cf (patch)
tree79ea82d53cd8cf56aa4a6f7fcd1c6bf2dcaaf31f
parentfedff47ebf4a1c2dd9830d2004735a74ad42ef36 (diff)
downloadresp-ea1c80ab4422d2811292cc7be651bd298f66b8cf.tar.gz
resp-ea1c80ab4422d2811292cc7be651bd298f66b8cf.tar.bz2
resp-ea1c80ab4422d2811292cc7be651bd298f66b8cf.zip
Create 'main' in IR and compile it like any other function.
git-svn-id: http://svn.drobilla.net/resp/trunk@423 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r--src/llvm.cpp18
-rw-r--r--src/repl.cpp49
-rw-r--r--src/resp.hpp8
3 files changed, 52 insertions, 23 deletions
diff --git a/src/llvm.cpp b/src/llvm.cpp
index 532051e..3391cb7 100644
--- a/src/llvm.cpp
+++ b/src/llvm.cpp
@@ -80,6 +80,7 @@ struct LLVMEngine : 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, CVal ret, const AST* retT);
+ CFunc getFn(CEnv& cenv, const std::string& name);
void eraseFn(CEnv& cenv, CFunc f);
CVal compileCall(CEnv& cenv, CFunc f, const ATuple* funcT, const vector<CVal>& args);
@@ -392,9 +393,11 @@ LLVMEngine::startFn(
// however LLVM chooses to mangle is fine, we keep a pointer
// Set argument names in generated code
- Function::arg_iterator a = f->arg_begin();
- for (ATuple::const_iterator i = args->begin(); i != args->end(); ++a, ++i)
- a->setName((*i)->as_symbol()->sym());
+ if (args) {
+ Function::arg_iterator a = f->arg_begin();
+ for (ATuple::const_iterator i = args->begin(); i != args->end(); ++a, ++i)
+ a->setName((*i)->as_symbol()->sym());
+ }
BasicBlock* bb = BasicBlock::Create(context, "entry", f);
builder.SetInsertPoint(bb);
@@ -408,6 +411,9 @@ LLVMEngine::pushFnArgs(CEnv& cenv, const ATuple* prot, const ATuple* type, CFunc
{
cenv.push();
+ if (!prot)
+ return;
+
const ATuple* argsT = type->prot();
Function* f = llFunc(cfunc);
@@ -443,6 +449,12 @@ LLVMEngine::finishFn(CEnv& cenv, CVal ret, const AST* retT)
currentFn = NULL;
}
+CFunc
+LLVMEngine::getFn(CEnv& cenv, const std::string& name)
+{
+ return module->getFunction(name);
+}
+
void
LLVMEngine::eraseFn(CEnv& cenv, CFunc f)
{
diff --git a/src/repl.cpp b/src/repl.cpp
index 83324f2..25ae163 100644
--- a/src/repl.cpp
+++ b/src/repl.cpp
@@ -122,6 +122,7 @@ eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute)
// Flatten expressions
Code flattened; // Type and function definitions
Code exprs; // Other top-level expressions (main code)
+ const AST* retT = NULL;
for (Code::const_iterator i = lifted.begin(); i != lifted.end(); ++i) {
const ATuple* call = (*i)->to_tuple();
if (call && (is_form(*i, "def-type")
@@ -131,31 +132,35 @@ eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute)
const ATuple* tup = (*i)->to_tuple();
if (!tup || !tup->empty()) {
exprs.push_back(*i);
+ retT = cenv.type(*i);
}
}
}
- if (cenv.args.find("-F") != cenv.args.end())
- return dump(cenv, flattened);
-
- // Compile type and function definitions
- for (Code::const_iterator i = flattened.begin(); i != flattened.end(); ++i) {
- resp_compile(cenv, *i);
- }
- // Compile other top-level expressions into "main" function
+ // Flatten main code into flattened
if (!exprs.empty()) {
- const AST* type = cenv.type(exprs.back());
- const ATuple* fnT = tup(cursor, cenv.tenv.Fn, new ATuple(cursor), type, 0);
-
- CFunc f = cenv.engine()->startFn(cenv, "main", new ATuple(cursor), fnT);
- CVal val = NULL;
+ 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);
+
+ flattened.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)
- val = resp_compile(cenv, *i);
- cenv.engine()->finishFn(cenv, val, type);
+ mainRet = resp_flatten(cenv, flattened, *i);
+
+ flattened.push_back(
+ tup(Cursor(), cenv.penv.sym("fn-end"), main, mainRet, NULL));
+ }
- // Call main and print result
- if (cenv.args.find("-S") == cenv.args.end())
- callPrintCollect(cenv, f, ast, type, execute);
+ if (cenv.args.find("-F") != cenv.args.end()) {
+ return dump(cenv, flattened);
+ }
+
+ // Compile flattened code
+ for (Code::const_iterator i = flattened.begin(); i != flattened.end(); ++i) {
+ resp_compile(cenv, *i);
}
if (cenv.args.find("-S") != cenv.args.end()) {
@@ -163,6 +168,13 @@ eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute)
return 0;
}
+ // Call main and print result
+ if (!exprs.empty()) {
+ CFunc f = cenv.engine()->getFn(cenv, "main");
+ if (cenv.args.find("-S") == cenv.args.end())
+ callPrintCollect(cenv, f, ast, retT, execute);
+ }
+
} catch (Error& e) {
cenv.err << e.what() << endl;
return 1;
@@ -190,6 +202,7 @@ repl(CEnv& cenv)
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;
diff --git a/src/resp.hpp b/src/resp.hpp
index 94ea43a..f12c4c9 100644
--- a/src/resp.hpp
+++ b/src/resp.hpp
@@ -213,7 +213,7 @@ struct ATuple : public AST {
inline const AST* rrst() const { return _rst->_rst; }
inline const AST* frrst() const { return _rst->_rst->_fst; }
- bool empty() const { return _fst == 0 && _rst ==0; }
+ bool empty() const { return _fst == 0 && _rst == 0; }
size_t list_len() const {
size_t ret = 0;
@@ -358,6 +358,7 @@ struct List {
va_end(args);
}
void push_back(const AST* ast) {
+ assert(ast);
if (!head) {
head = new ATuple(ast, NULL, Cursor());
} else if (!tail) {
@@ -545,9 +546,11 @@ struct Subst : public list<Constraint> {
}
const AST* apply(const AST* in) const {
if (AType::is_expr(in)) {
+ if (in->as_tuple()->empty())
+ return in;
List out;
for (ATuple::const_iterator i = in->as_tuple()->begin(); i != in->as_tuple()->end(); ++i)
- out.push_back(apply((*i)));
+ out.push_back(apply(*i));
if (out.head)
out.head->loc = in->loc;
return out.head;
@@ -674,6 +677,7 @@ struct Engine {
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;
virtual CVal compileCall(CEnv& cenv, CFunc f, const ATuple* fT, CVals& args) = 0;