diff options
author | David Robillard <d@drobilla.net> | 2010-12-09 17:58:43 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-12-09 17:58:43 +0000 |
commit | acf13b1df559c6187d270ef7e31890201c191b12 (patch) | |
tree | 4a3d07f257efac1cd5ef51b21af2e55d4fd798b5 /src/lift.cpp | |
parent | d92de14f7d8354004edb14ed5658d5f434ce1e31 (diff) | |
download | resp-acf13b1df559c6187d270ef7e31890201c191b12.tar.gz resp-acf13b1df559c6187d270ef7e31890201c191b12.tar.bz2 resp-acf13b1df559c6187d270ef7e31890201c191b12.zip |
Add let form.
git-svn-id: http://svn.drobilla.net/resp/resp@328 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/lift.cpp')
-rw-r--r-- | src/lift.cpp | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/lift.cpp b/src/lift.cpp index ad377d7..e3a741b 100644 --- a/src/lift.cpp +++ b/src/lift.cpp @@ -32,7 +32,7 @@ lift_symbol(CEnv& cenv, Code& code, const ASymbol* sym) throw() { if (!cenv.liftStack.empty() && cenv.name(cenv.liftStack.top().fn) == sym->sym()) { return cenv.penv.sym("_me"); // Reference to innermost function - } else if (!cenv.code.innermost(sym)) { + } else if (!cenv.liftStack.empty() && !cenv.code.innermost(sym)) { // Replace symbol with code to access free variable from closure const int32_t index = cenv.liftStack.top().index(sym); return tup<ATuple>(sym->loc, cenv.penv.sym("."), @@ -158,6 +158,36 @@ lift_fn(CEnv& cenv, Code& code, const ATuple* fn) throw() } static const AST* +lift_let(CEnv& cenv, Code& code, const ATuple* let) throw() +{ + const ATuple* vars = let->list_ref(1)->to_tuple(); + + List<ATuple, const AST> copy(let->loc, let->head(), NULL); + List<ATuple, const AST> copyVars; + + 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), NULL); + copyVars.push_back(sym); + copyVars.push_back(val); + resp_lift(cenv, code, val); + } + copy.push_back(copyVars); + + for (ATuple::const_iterator i = let->iter_at(2); i != let->end(); ++i) + copy.push_back(resp_lift(cenv, code, *i)); + + cenv.pop(); + + cenv.setTypeSameAs(copy, let); + + return copy; +} + +static const AST* lift_call(CEnv& cenv, Code& code, const ATuple* call) throw() { List<ATuple, const AST> copy; @@ -246,6 +276,8 @@ resp_lift(CEnv& cenv, Code& code, const AST* ast) throw() return lift_fn(cenv, code, call); else if (form == "if") return lift_args(cenv, code, call); + else if (form == "let") + return lift_let(cenv, code, call); else if (form == "match") return call; // FIXME else |