diff options
Diffstat (limited to 'src/lift.cpp')
-rw-r--r-- | src/lift.cpp | 80 |
1 files changed, 41 insertions, 39 deletions
diff --git a/src/lift.cpp b/src/lift.cpp index 5ac3816..4e2159b 100644 --- a/src/lift.cpp +++ b/src/lift.cpp @@ -47,6 +47,35 @@ lift_symbol(CEnv& cenv, Code& code, const ASymbol* sym) throw() } static const AST* +lift_def(CEnv& cenv, Code& code, const ATuple* def) throw() +{ + // Define stub first for recursion + 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); + if (is_form(body, "fn")) + cenv.setName(body->as_tuple(), sym->str()); + + assert(def->list_ref(1)->to_symbol()); + List<ATuple, const AST> copy; + copy.push_back(def->head()); + copy.push_back(resp_lift(cenv, code, def->list_ref(1))); + for (ATuple::const_iterator t = def->iter_at(2); t != def->end(); ++t) + copy.push_back(resp_lift(cenv, code, *t)); + + cenv.setTypeSameAs(copy.head, def); + + if (copy.head->list_ref(1) == copy.head->list_ref(2)) + return NULL; // Definition created by lift_fn when body was lifted + + cenv.def(copy.head->list_ref(1)->as_symbol(), + copy.head->list_ref(2), + cenv.type(copy.head->list_ref(2)), + NULL); + return copy; +} + +static const AST* lift_fn(CEnv& cenv, Code& code, const ATuple* fn) throw() { List<ATuple, const AST> impl; @@ -180,36 +209,7 @@ lift_call(CEnv& cenv, Code& code, const ATuple* call) throw() } static const AST* -lift_def(CEnv& cenv, Code& code, const ATuple* def) throw() -{ - // Define stub first for recursion - 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); - if (is_form(body, "fn")) - cenv.setName(body->as_tuple(), sym->str()); - - assert(def->list_ref(1)->to_symbol()); - List<ATuple, const AST> copy; - copy.push_back(def->head()); - copy.push_back(resp_lift(cenv, code, def->list_ref(1))); - for (ATuple::const_iterator t = def->iter_at(2); t != def->end(); ++t) - copy.push_back(resp_lift(cenv, code, *t)); - - cenv.setTypeSameAs(copy.head, def); - - if (copy.head->list_ref(1) == copy.head->list_ref(2)) - return NULL; // Definition created by lift_fn when body was lifted - - cenv.def(copy.head->list_ref(1)->as_symbol(), - copy.head->list_ref(2), - cenv.type(copy.head->list_ref(2)), - NULL); - return copy; -} - -static const AST* -lift_builtin_call(CEnv& cenv, Code& code, const ATuple* call) throw() +lift_args(CEnv& cenv, Code& code, const ATuple* call) throw() { List<ATuple, const AST> copy; copy.push_back(call->head()); @@ -235,18 +235,20 @@ resp_lift(CEnv& cenv, Code& code, const AST* ast) throw() const ASymbol* const sym = call->head()->to_symbol(); const std::string form = sym ? sym->sym() : ""; if (is_primitive(cenv.penv, call)) - return lift_builtin_call(cenv, code, call); - else if (form == "fn") - return lift_fn(cenv, code, call); + return lift_args(cenv, code, call); + else if (form == "cons" || isupper(form[0])) + return lift_args(cenv, code, call); + else if (form == ".") + return lift_args(cenv, code, call); else if (form == "def") return lift_def(cenv, code, call); + else if (form == "def-type") + return call; // FIXME + else if (form == "fn") + return lift_fn(cenv, code, call); else if (form == "if") - return lift_builtin_call(cenv, code, call); - else if (form == "cons" || isupper(form[0])) - return lift_builtin_call(cenv, code, call); - else if (form == ".") - return lift_builtin_call(cenv, code, call); - else if (form == "match" || form == "def-type") + return lift_args(cenv, code, call); + else if (form == "match") return call; // FIXME else return lift_call(cenv, code, call); |