aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-12-14 06:17:55 +0000
committerDavid Robillard <d@drobilla.net>2012-12-14 06:17:55 +0000
commit7bfe9965f7b3bd980bd0dd788ca7ec50a2d5f6e1 (patch)
tree53c847025f11c951541723c195dd0310bdd14724 /src
parent32c1b78fc9bdadd1dd40ed390941b2a6fea39435 (diff)
downloadresp-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.cpp76
-rw-r--r--src/resp.hpp8
-rw-r--r--src/simplify.cpp34
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);
}