diff options
author | David Robillard <d@drobilla.net> | 2011-05-14 10:08:06 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2011-05-14 10:08:06 +0000 |
commit | ea1c80ab4422d2811292cc7be651bd298f66b8cf (patch) | |
tree | 79ea82d53cd8cf56aa4a6f7fcd1c6bf2dcaaf31f /src | |
parent | fedff47ebf4a1c2dd9830d2004735a74ad42ef36 (diff) | |
download | resp-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
Diffstat (limited to 'src')
-rw-r--r-- | src/llvm.cpp | 18 | ||||
-rw-r--r-- | src/repl.cpp | 49 | ||||
-rw-r--r-- | src/resp.hpp | 8 |
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; |