diff options
author | David Robillard <d@drobilla.net> | 2010-12-10 04:24:20 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-12-10 04:24:20 +0000 |
commit | 22e329617866a6580ccff5636f148d72603fa8fc (patch) | |
tree | 4038bdc902a7726da493850e71e81b1b01102622 /src | |
parent | 4b2af37d24d864db463d004930f924b5adfebc28 (diff) | |
download | resp-22e329617866a6580ccff5636f148d72603fa8fc.tar.gz resp-22e329617866a6580ccff5636f148d72603fa8fc.tar.bz2 resp-22e329617866a6580ccff5636f148d72603fa8fc.zip |
Move simplification from lift stage to a new (post-typing) simplify stage.
git-svn-id: http://svn.drobilla.net/resp/resp@344 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src')
-rw-r--r-- | src/lift.cpp | 46 | ||||
-rw-r--r-- | src/repl.cpp | 17 | ||||
-rw-r--r-- | src/resp.cpp | 2 | ||||
-rw-r--r-- | src/resp.hpp | 1 | ||||
-rw-r--r-- | src/simplify.cpp | 94 |
5 files changed, 114 insertions, 46 deletions
diff --git a/src/lift.cpp b/src/lift.cpp index 239b02e..5791e41 100644 --- a/src/lift.cpp +++ b/src/lift.cpp @@ -213,48 +213,6 @@ lift_let(CEnv& cenv, Code& code, const ATuple* let) throw() } static const AST* -lift_match(CEnv& cenv, Code& code, const ATuple* match) throw() -{ - List<ATuple, const AST> copy(match->loc, cenv.penv.sym("let"), NULL); - List<ATuple, const AST> copyVars; - - const ASymbol* tsym = cenv.penv.gensym("_matchT"); - - List<ATuple, const AST> tval; - tval.push_back(cenv.penv.sym(".")); - tval.push_back(resp_lift(cenv, code, match->list_ref(1))); - tval.push_back(new ALiteral<int32_t>(T_INT32, 0, Cursor())); - - copyVars.push_back(tsym); - copyVars.push_back(tval); - copy.push_back(copyVars); - - List<ATuple, const AST> copyIf; - copyIf.push_back(cenv.penv.sym("if")); - for (ATuple::const_iterator i = match->iter_at(2); i != match->end();) { - const ATuple* pat = (*i++)->as_tuple(); - const AST* body = *i++; - - List<ATuple, const AST> cond; - cond.push_back(cenv.penv.sym("__tag_is")); - cond.push_back(tsym); - cond.push_back(pat->head()); - - copyIf.push_back(cond); - const AST* liftedBody = resp_lift(cenv, code, body); - assert(liftedBody); - copyIf.push_back(liftedBody); - } - copyIf.push_back(cenv.penv.sym("__unreachable")); - copy.push_back(copyIf); - - cenv.setTypeSameAs(copyIf, match); - cenv.setTypeSameAs(copy, match); - - return copy; -} - -static const AST* lift_call(CEnv& cenv, Code& code, const ATuple* call) throw() { List<ATuple, const AST> copy; @@ -345,8 +303,8 @@ resp_lift(CEnv& cenv, Code& code, const AST* ast) throw() return lift_args(cenv, code, call); else if (form == "let") return lift_let(cenv, code, call); - else if (form == "match") - return lift_match(cenv, code, call); + else if (form == "__tag_is") + return call; else return lift_call(cenv, code, call); } diff --git a/src/repl.cpp b/src/repl.cpp index 52d35c5..063f1e7 100644 --- a/src/repl.cpp +++ b/src/repl.cpp @@ -100,12 +100,26 @@ eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute) return 0; } + // Simplify all expressions + Code simplified; + for (Parsed::const_iterator i = parsed.begin(); i != parsed.end(); ++i) { + const AST* l = resp_simplify(cenv, *i); + if (l) + simplified.push_back(l); + } + + if (cenv.args.find("-R") != cenv.args.end()) { + for (Code::const_iterator i = simplified.begin(); i != simplified.end(); ++i) + pprint(cout, *i, &cenv, (cenv.args.find("-a") != cenv.args.end())); + return 0; + } + CVal val = NULL; CFunc f = NULL; // Lift all expressions Code lifted; - for (Parsed::const_iterator i = parsed.begin(); i != parsed.end(); ++i) { + for (Parsed::const_iterator i = simplified.begin(); i != simplified.end(); ++i) { const AST* l = resp_lift(cenv, lifted, *i); if (l) lifted.push_back(l); @@ -114,7 +128,6 @@ eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute) if (cenv.args.find("-L") != cenv.args.end()) { for (Code::const_iterator i = lifted.begin(); i != lifted.end(); ++i) pprint(cout, *i, &cenv, (cenv.args.find("-a") != cenv.args.end())); - return 0; } diff --git a/src/resp.cpp b/src/resp.cpp index 765939c..5f45bdd 100644 --- a/src/resp.cpp +++ b/src/resp.cpp @@ -77,6 +77,7 @@ print_usage(char* name, bool error) os << " -r Enter REPL after evaluating files" << endl; os << " -P Parse only" << endl; os << " -T Type check only" << endl; + os << " -R Reduce to simpler forms only" << endl; os << " -L Lambda lift only" << endl; os << " -S Compile to assembly only (do not execute)" << endl; @@ -96,6 +97,7 @@ main(int argc, char** argv) files.push_back(argv[i]); } else if (!strncmp(argv[i], "-L", 3) || !strncmp(argv[i], "-P", 3) + || !strncmp(argv[i], "-R", 3) || !strncmp(argv[i], "-S", 3) || !strncmp(argv[i], "-T", 3) || !strncmp(argv[i], "-a", 3) diff --git a/src/resp.hpp b/src/resp.hpp index 266387c..a2b5cf8 100644 --- a/src/resp.hpp +++ b/src/resp.hpp @@ -877,6 +877,7 @@ 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_lift(CEnv& cenv, Code& code, const AST* ast) throw(); CVal resp_compile(CEnv& cenv, const AST* ast) throw(); diff --git a/src/simplify.cpp b/src/simplify.cpp new file mode 100644 index 0000000..31eb83a --- /dev/null +++ b/src/simplify.cpp @@ -0,0 +1,94 @@ +/* Resp: A programming language + * Copyright (C) 2008-2009 David Robillard <dave@drobilla.net> + * + * Resp is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Resp is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Resp. If not, see <http://www.gnu.org/licenses/>. + */ + +/** @file + * @brief Simplify (reduce to simpler forms, e.g. match => if) + */ + +#include <string> + +#include "resp.hpp" + +using namespace std; + +static const AST* +simplify_match(CEnv& cenv, const ATuple* match) throw() +{ + List<ATuple, const AST> copy(match->loc, cenv.penv.sym("let"), NULL); + List<ATuple, const AST> copyVars; + + const ASymbol* tsym = cenv.penv.gensym("_matchT"); + + List<ATuple, const AST> tval; + tval.push_back(cenv.penv.sym(".")); + tval.push_back(resp_simplify(cenv, match->list_ref(1))); + tval.push_back(new ALiteral<int32_t>(T_INT32, 0, Cursor())); + + copyVars.push_back(tsym); + copyVars.push_back(tval); + copy.push_back(copyVars); + + List<ATuple, const AST> copyIf; + copyIf.push_back(cenv.penv.sym("if")); + for (ATuple::const_iterator i = match->iter_at(2); i != match->end();) { + const ATuple* pat = (*i++)->as_tuple(); + const AST* body = *i++; + + List<ATuple, const AST> cond; + cond.push_back(cenv.penv.sym("__tag_is")); + cond.push_back(tsym); + cond.push_back(pat->head()); + + copyIf.push_back(cond); + copyIf.push_back(resp_simplify(cenv, body)); + } + copyIf.push_back(cenv.penv.sym("__unreachable")); + copy.push_back(copyIf); + + cenv.setTypeSameAs(copyIf, match); + cenv.setTypeSameAs(copy, match); + + return copy; +} + +static const AST* +simplify_list(CEnv& cenv, const ATuple* call) throw() +{ + List<ATuple, const AST> copy; + for (ATuple::const_iterator i = call->begin(); i != call->end(); ++i) + copy.push_back(resp_simplify(cenv, *i)); + + cenv.setTypeSameAs(copy.head, call); + + return copy; +} + +const AST* +resp_simplify(CEnv& cenv, const AST* ast) throw() +{ + const ATuple* const list = ast->to_tuple(); + if (!list) + return ast; + + const ASymbol* const sym = list->head()->to_symbol(); + const std::string form = sym ? sym->sym() : ""; + + if (form == "match") + return simplify_match(cenv, list); + else + return simplify_list(cenv, list); +} |