aboutsummaryrefslogtreecommitdiffstats
path: root/src/compile.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-12-25 09:24:48 +0000
committerDavid Robillard <d@drobilla.net>2010-12-25 09:24:48 +0000
commit6dec2bd33e6c142664c881405bdc0f9b298e4a11 (patch)
tree8cc17f033c145f2a9467a2c2f56ee7b015fc1a03 /src/compile.cpp
parentc1ee499d0b14be87b5f5664448507026b9b87fd6 (diff)
downloadresp-6dec2bd33e6c142664c881405bdc0f9b298e4a11.tar.gz
resp-6dec2bd33e6c142664c881405bdc0f9b298e4a11.tar.bz2
resp-6dec2bd33e6c142664c881405bdc0f9b298e4a11.zip
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
Diffstat (limited to 'src/compile.cpp')
-rw-r--r--src/compile.cpp40
1 files changed, 14 insertions, 26 deletions
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);
@@ -77,6 +77,16 @@ compile_def(CEnv& cenv, const ATuple* def) throw()
}
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);
@@ -117,28 +127,6 @@ compile_if(CEnv& cenv, const ATuple* aif) throw()
}
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()
{
const AST* lhs = call->list_ref(1);
@@ -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