From 82eeba6aca368aa04a6650b6ee7cefe4b28804b8 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 14 May 2011 05:35:11 +0000 Subject: Add flatten stage to generate flat s-expression IR for the (now simpler) compilation stage. git-svn-id: http://svn.drobilla.net/resp/trunk@417 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- src/compile.cpp | 114 ++++++++++++++++++++++---------------------------------- 1 file changed, 44 insertions(+), 70 deletions(-) (limited to 'src/compile.cpp') diff --git a/src/compile.cpp b/src/compile.cpp index ba8cc5e..1f82a47 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -29,6 +29,9 @@ using namespace std; static CVal compile_symbol(CEnv& cenv, const ASymbol* sym) throw() { + if (*sym == *cenv.penv.sym("__unreachable")) + 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)); } else { @@ -94,14 +97,8 @@ compile_def(CEnv& cenv, const ATuple* def) throw() { const ASymbol* const sym = def->list_ref(1)->as_symbol(); const AST* const body = def->list_ref(2); - cenv.def(sym, body, cenv.type(body), NULL); // define stub first for recursion CVal val = resp_compile(cenv, body); - if (cenv.repl && cenv.vals.size() == 1 && !is_form(cenv.type(body), "Fn")) { - val = cenv.engine()->compileGlobalSet( - cenv, sym->str(), val, cenv.type(body)); - cenv.lock(def); - } - cenv.vals.def(sym, val); + cenv.def(sym, body, cenv.type(body), val); return NULL; } @@ -124,63 +121,6 @@ compile_def_type(CEnv& cenv, const ATuple* def) throw() return NULL; } -static CVal -compile_do(CEnv& cenv, const ATuple* ado) throw() -{ - CVal retVal = NULL; - for (ATuple::const_iterator i = ado->iter_at(1); i != ado->end(); ++i) - retVal = resp_compile(cenv, *i); - - return retVal; -} - -static CVal -compile_fn(CEnv& cenv, const ATuple* fn) throw() -{ - assert(!cenv.currentFn); - - const AST* const type = cenv.type(fn); - CFunc f = cenv.findImpl(fn, type); - if (f) - return f; - - // Write function declaration and push stack frame - f = cenv.engine()->startFn(cenv, cenv.name(fn), fn->prot(), type->as_tuple()); - cenv.engine()->pushFnArgs(cenv, fn->prot(), type->as_tuple(), f); - cenv.currentFn = f; - - // Write function body - CVal retVal = NULL; - for (ATuple::const_iterator i = fn->iter_at(2); i != fn->end(); ++i) - retVal = resp_compile(cenv, *i); - - // Write function conclusion and pop stack frame - cenv.engine()->finishFn(cenv, f, retVal, type->as_tuple()->frrst()); - cenv.pop(); - cenv.currentFn = NULL; - - cenv.vals.def(cenv.penv.sym(cenv.name(fn)), f); - cenv.addImpl(fn, f); - return f; -} - -static CVal -compile_if(CEnv& cenv, const ATuple* aif) throw() -{ - const AST* cond = aif->list_ref(1); - const AST* then = aif->list_ref(2); - const AST* aelse = NULL; - if (*aif->list_last() != *cenv.penv.sym("__unreachable")) - aelse = aif->list_ref(3); - - const AST* type = cenv.type(then); - - cenv.engine()->compileIfStart(cenv, cond, type); - cenv.engine()->compileIfThen(cenv, resp_compile(cenv, then)); - cenv.engine()->compileIfElse(cenv, resp_compile(cenv, aelse)); - return cenv.engine()->compileIfEnd(cenv); -} - static CVal compile_quote(CEnv& cenv, const ATuple* quote) throw() { @@ -218,6 +158,34 @@ compile_call(CEnv& cenv, const ATuple* call) throw() return cenv.engine()->compileCall(cenv, f, cenv.type(call->fst())->as_tuple(), args); } +static CVal +compile_fn_start(CEnv& cenv, const ATuple* call) throw() +{ + const ASymbol* name = call->list_ref(1)->as_symbol(); + 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.currentFn = func; + + return NULL; +} + +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, cenv.currentFn, + resp_compile(cenv, call->frrst()), + retT); + cenv.pop(); + cenv.currentFn = NULL; + return NULL; +} + CVal resp_compile(CEnv& cenv, const AST* ast) throw() { @@ -255,14 +223,20 @@ resp_compile(CEnv& cenv, const AST* ast) throw() return compile_def(cenv, call); else if (form == "def-type") return compile_def_type(cenv, call); - else if (form == "do") - return compile_do(cenv, call); - else if (form == "fn") - return compile_fn(cenv, call); - else if (form == "if") - return compile_if(cenv, call); else if (form == "quote") return compile_quote(cenv, call); + else if (form == "fn-start") + return compile_fn_start(cenv, call); + else if (form == "fn-end") + return compile_fn_end(cenv, call); + else if (form == "if-start") + return cenv.engine()->compileIfStart(cenv, call->frrst(), cenv.type(call)); + else if (form == "if-then") + return cenv.engine()->compileIfThen(cenv, resp_compile(cenv, call->frrst())); + else if (form == "if-else") + return cenv.engine()->compileIfElse(cenv, resp_compile(cenv, call->frrst())); + else if (form == "if-end") + return cenv.engine()->compileIfEnd(cenv); else return compile_call(cenv, call); } -- cgit v1.2.1