diff options
author | David Robillard <d@drobilla.net> | 2012-12-14 06:17:55 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2012-12-14 06:17:55 +0000 |
commit | 7bfe9965f7b3bd980bd0dd788ca7ec50a2d5f6e1 (patch) | |
tree | 53c847025f11c951541723c195dd0310bdd14724 /src | |
parent | 32c1b78fc9bdadd1dd40ed390941b2a6fea39435 (diff) | |
download | resp-7bfe9965f7b3bd980bd0dd788ca7ec50a2d5f6e1.tar.gz resp-7bfe9965f7b3bd980bd0dd788ca7ec50a2d5f6e1.tar.bz2 resp-7bfe9965f7b3bd980bd0dd788ca7ec50a2d5f6e1.zip |
More flexible and unified code pass design.
git-svn-id: http://svn.drobilla.net/resp/trunk@435 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src')
-rw-r--r-- | src/repl.cpp | 76 | ||||
-rw-r--r-- | src/resp.hpp | 8 | ||||
-rw-r--r-- | src/simplify.cpp | 34 |
3 files changed, 66 insertions, 52 deletions
diff --git a/src/repl.cpp b/src/repl.cpp index 1169b3d..2848a53 100644 --- a/src/repl.cpp +++ b/src/repl.cpp @@ -83,45 +83,55 @@ dump(CEnv& cenv, const Code& code) const AST* compile(CEnv& cenv, const Code& parsed, Code& defs, bool& hasMain, const char* mainName) { - const AST* exp = NULL; - - // Simplify all expressions - Code simplified; - for (Code::const_iterator i = parsed.begin(); i != parsed.end(); ++i) - if ((exp = resp_simplify(cenv, *i))) - simplified.push_back(exp); - if (cenv.args.find("-R") != cenv.args.end()) - return dump(cenv, simplified); - - // Convert to CPS - Code cps; - for (Code::const_iterator i = simplified.begin(); i != simplified.end(); ++i) - if ((exp = resp_cps(cenv, *i, cenv.penv.sym("display")))) - cps.push_back(exp); - if (cenv.args.find("-C") != cenv.args.end()) - return dump(cenv, cps); + // Convert to CPS (currently not used in the compilation process) + if (cenv.args.find("-C") != cenv.args.end()) { + Code cps; + for (Code::const_iterator i = parsed.begin(); i != parsed.end(); ++i) { + const AST* exp = resp_cps(cenv, *i, cenv.penv.sym("display")); + if (exp) { + cps.push_back(exp); + } + } +h return dump(cenv, cps); + } - // Lift all expressions - Code lifted; - for (Code::const_iterator i = simplified.begin(); i != simplified.end(); ++i) - if ((exp = resp_lift(cenv, lifted, *i))) - lifted.push_back(exp); - if (cenv.args.find("-L") != cenv.args.end()) - return dump(cenv, lifted); - - // Depoly all expressions - Code concrete; - for (Code::const_iterator i = lifted.begin(); i != lifted.end(); ++i) - if ((exp = resp_depoly(cenv, concrete, *i))) - concrete.push_back(exp); - if (cenv.args.find("-D") != cenv.args.end()) { - return dump(cenv, concrete); + struct Pass { + const RespPass* pass; ///< Pass function + const char* option; ///< Command line option to stop and dump here + }; + + const Pass passes[] = { + { resp_simplify, "-R" }, + { resp_lift, "-L" }, + { resp_depoly, "-D" }, + { NULL, NULL } + }; + + // List of stages of code after each pass + std::list<Code> stages; + stages.push_back(parsed); + + // Apply each pass in turn and append to stages + for (const Pass* p = passes; p->pass; ++p) { + const Code& input = stages.back(); + Code output; + for (Code::const_iterator i = input.begin(); i != input.end(); ++i) { + const AST* exp = (*p->pass)(cenv, output, *i); + if (exp) { + output.push_back(exp); + } + } + stages.push_back(output); + + if (cenv.args.find(p->option) != cenv.args.end()) { + return dump(cenv, output); + } } // Flatten expressions const AST* retT = NULL; Code exprs; - for (Code::const_iterator i = concrete.begin(); i != concrete.end(); ++i) { + for (Code::const_iterator i = stages.back().begin(); i != stages.back().end(); ++i) { const ATuple* call = (*i)->to_tuple(); if (call && (is_form(*i, "def-type") || (is_form(*i, "def") && is_form(call->frrst(), "fn")))) { diff --git a/src/resp.hpp b/src/resp.hpp index 8d37cd3..8cdb75e 100644 --- a/src/resp.hpp +++ b/src/resp.hpp @@ -839,9 +839,13 @@ void initLang(PEnv& penv, TEnv& tenv); int eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute); int repl(CEnv& cenv); -void resp_constrain(TEnv& tenv, Constraints& c, const AST* ast) throw(Error); -const AST* resp_simplify(CEnv& cenv, const AST* ast) throw(); const AST* resp_cps(CEnv& cenv, const AST* ast, const AST* k) throw(); + +void resp_constrain(TEnv& tenv, Constraints& c, const AST* ast) throw(Error); + +typedef const AST* (RespPass)(CEnv& cenv, Code& code, const AST* ast); + +const AST* resp_simplify(CEnv& cenv, Code& code, const AST* ast) throw(); const AST* resp_lift(CEnv& cenv, Code& code, const AST* ast) throw(); const AST* resp_flatten(CEnv& cenv, Code& code, const AST* ast) throw(); const AST* resp_depoly(CEnv& cenv, Code& code, const AST* ast) throw(); diff --git a/src/simplify.cpp b/src/simplify.cpp index e081bf7..921c6e6 100644 --- a/src/simplify.cpp +++ b/src/simplify.cpp @@ -26,7 +26,7 @@ using namespace std; static const AST* -simplify_if(CEnv& cenv, const ATuple* aif) throw() +simplify_if(CEnv& cenv, Code& code, const ATuple* aif) throw() { List copy(aif->loc, cenv.penv.sym("if"), NULL); copy.push_back(aif->list_ref(1)); @@ -54,9 +54,9 @@ simplify_if(CEnv& cenv, const ATuple* aif) throw() } static const AST* -simplify_match(CEnv& cenv, const ATuple* match) throw() +simplify_match(CEnv& cenv, Code& code, const ATuple* match) throw() { - const AST* const obj = resp_simplify(cenv, match->list_ref(1)); + const AST* const obj = resp_simplify(cenv, code, match->list_ref(1)); // Dot expression to get tag. Note index is -1 to compensate for the lift phase // which adds 1 to skip the RTTI, which we don't want here (FIXME: ick...) @@ -108,7 +108,7 @@ simplify_match(CEnv& cenv, const ATuple* match) throw() fn.push_back(def); } - fn.push_back(resp_simplify(cenv, body)); + fn.push_back(resp_simplify(cenv, code, body)); List fnT(Cursor(), cenv.tenv.Fn, protT, cenv.type(match), 0); assert(fnT.head->list_ref(1)); @@ -121,18 +121,18 @@ simplify_match(CEnv& cenv, const ATuple* match) throw() copyIf.push_back(cenv.penv.sym("__unreachable")); cenv.setTypeSameAs(copyIf, match); - List copy(match->loc, cenv.penv.sym("do"), def.head, simplify_if(cenv, copyIf), 0); + List copy(match->loc, cenv.penv.sym("do"), def.head, simplify_if(cenv, code, copyIf), 0); cenv.setTypeSameAs(copy, match); return copy; } static const AST* -simplify_list(CEnv& cenv, const ATuple* call) throw() +simplify_list(CEnv& cenv, Code& code, const ATuple* call) throw() { List copy; for (ATuple::const_iterator i = call->begin(); i != call->end(); ++i) - copy.push_back(resp_simplify(cenv, *i)); + copy.push_back(resp_simplify(cenv, code, *i)); cenv.setTypeSameAs(copy.head, call); @@ -140,7 +140,7 @@ simplify_list(CEnv& cenv, const ATuple* call) throw() } static const AST* -simplify_let(CEnv& cenv, const ATuple* call) throw() +simplify_let(CEnv& cenv, Code& code, const ATuple* call) throw() { const ATuple* vars = call->list_ref(1)->to_tuple(); @@ -153,12 +153,12 @@ simplify_let(CEnv& cenv, const ATuple* call) throw() const ASymbol* sym = (*i++)->to_symbol(); const AST* val = (*i++); fnProt.push_back(sym); - fnArgs.push_back(resp_simplify(cenv, val)); + fnArgs.push_back(resp_simplify(cenv, code, val)); fnProtT.push_back(cenv.type(val)); } fn.push_back(fnProt.head); - fn.push_back(resp_simplify(cenv, call->list_ref(2))); + fn.push_back(resp_simplify(cenv, code, call->list_ref(2))); List fnT; fnT.push_back(cenv.tenv.Fn); @@ -194,7 +194,7 @@ simplify_list_elem(CEnv& cenv, const ATuple* node, const AST* type) } static const AST* -simplify_quote(CEnv& cenv, const ATuple* call) throw() +simplify_quote(CEnv& cenv, Code& code, const ATuple* call) throw() { switch (call->frst()->tag()) { case T_SYMBOL: @@ -214,7 +214,7 @@ simplify_quote(CEnv& cenv, const ATuple* call) throw() } const AST* -resp_simplify(CEnv& cenv, const AST* ast) throw() +resp_simplify(CEnv& cenv, Code& code, const AST* ast) throw() { const ATuple* const list = ast->to_tuple(); if (!list) @@ -224,13 +224,13 @@ resp_simplify(CEnv& cenv, const AST* ast) throw() const std::string form = sym ? sym->sym() : ""; if (form == "match") - return simplify_match(cenv, list); + return simplify_match(cenv, code, list); else if (form == "if") - return simplify_if(cenv, list); + return simplify_if(cenv, code, list); else if (form == "let") - return simplify_let(cenv, list); + return simplify_let(cenv, code, list); else if (form == "quote") - return simplify_quote(cenv, list); + return simplify_quote(cenv, code, list); else - return simplify_list(cenv, list); + return simplify_list(cenv, code, list); } |