From 6dec2bd33e6c142664c881405bdc0f9b298e4a11 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 25 Dec 2010 09:24:48 +0000 Subject: Simplify let to fn, rather than deal with it through to compilation. The previous implementation of let was a premature optimization intended to make let cheap/free, but screws up closure creation and variable indexing because a new scope is created by something other than fn. Only compile top level expressions to globals (with associated store/retrieve overhead) in a REPL when it is necessary. Add `do' form (ala scheme `begin') to backend (used by `match' simplify). git-svn-id: http://svn.drobilla.net/resp/resp@348 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- src/compile.cpp | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) (limited to 'src/compile.cpp') diff --git a/src/compile.cpp b/src/compile.cpp index 4c7980e..eed481a 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -29,7 +29,7 @@ using namespace std; static CVal compile_symbol(CEnv& cenv, const ASymbol* sym) throw() { - if (cenv.vals.topLevel(sym) && cenv.type(sym)->head()->str() != "Fn") { + if (cenv.repl && cenv.vals.topLevel(sym) && cenv.type(sym)->head()->str() != "Fn") { return cenv.engine()->compileGlobalGet(cenv, sym->sym(), *cenv.vals.ref(sym)); } else { return *cenv.vals.ref(sym); @@ -67,7 +67,7 @@ compile_def(CEnv& cenv, const ATuple* def) throw() 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.vals.size() == 1 && cenv.type(body)->head()->str() != "Fn") { + if (cenv.repl && cenv.vals.size() == 1 && cenv.type(body)->head()->str() != "Fn") { val = cenv.engine()->compileGlobalSet( cenv, sym->str(), val, cenv.type(body)); cenv.lock(def); @@ -76,6 +76,16 @@ compile_def(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() { @@ -116,28 +126,6 @@ compile_if(CEnv& cenv, const ATuple* aif) throw() return cenv.engine()->compileIf(cenv, aif->list_ref(1), aif->list_ref(2), aelse); } -static CVal -compile_let(CEnv& cenv, const ATuple* let) throw() -{ - const ATuple* vars = let->list_ref(1)->to_tuple(); - - cenv.push(); - - for (ATuple::const_iterator i = vars->begin(); i != vars->end();) { - const ASymbol* sym = (*i++)->to_symbol(); - const AST* val = (*i++); - cenv.def(sym, val, cenv.type(val), resp_compile(cenv, val)); - } - - CVal ret = NULL; - for (ATuple::const_iterator i = let->iter_at(2); i != let->end(); ++i) - ret = resp_compile(cenv, *i); - - cenv.pop(); - - return ret; -} - static CVal compile_tag_is(CEnv& cenv, const ATuple* call) throw() { @@ -207,12 +195,12 @@ resp_compile(CEnv& cenv, const AST* ast) throw() return compile_def(cenv, call); else if (form == "def-type") return NULL; // FIXME + 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 == "let") - return compile_let(cenv, call); else if (form == "__tag_is") return compile_tag_is(cenv, call); else -- cgit v1.2.1