From acf13b1df559c6187d270ef7e31890201c191b12 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 9 Dec 2010 17:58:43 +0000 Subject: Add let form. git-svn-id: http://svn.drobilla.net/resp/resp@328 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- src/lift.cpp | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'src/lift.cpp') 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(sym->loc, cenv.penv.sym("."), @@ -157,6 +157,36 @@ lift_fn(CEnv& cenv, Code& code, const ATuple* fn) throw() return cons; } +static const AST* +lift_let(CEnv& cenv, Code& code, const ATuple* let) throw() +{ + const ATuple* vars = let->list_ref(1)->to_tuple(); + + List copy(let->loc, let->head(), NULL); + List 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() { @@ -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 -- cgit v1.2.1