From 8cbb1c710d6c8877dfc2871dc3f068b52598a884 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 15 May 2011 20:15:27 +0000 Subject: 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 --- src/c.cpp | 3 +- src/compile.cpp | 18 ++++++----- src/llvm.cpp | 6 +++- src/repl.cpp | 98 +++++++++++++++++++++++++++++++-------------------------- src/resp.hpp | 7 ++--- 5 files changed, 73 insertions(+), 59 deletions(-) (limited to 'src') 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 args; + map globals; + typedef map CSyms; CSyms cSyms; -- cgit v1.2.1