aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compile.cpp40
-rw-r--r--src/lift.cpp34
-rw-r--r--src/repl.cpp2
-rw-r--r--src/resp.hpp4
-rw-r--r--src/simplify.cpp54
5 files changed, 66 insertions, 68 deletions
diff --git a/src/compile.cpp b/src/compile.cpp
index 4c7980e..eed481a 100644
--- a/src/compile.cpp
+++ b/src/compile.cpp
@@ -29,7 +29,7 @@ using namespace std;
static CVal
compile_symbol(CEnv& cenv, const ASymbol* sym) throw()
{
- if (cenv.vals.topLevel(sym) && cenv.type(sym)->head()->str() != "Fn") {
+ if (cenv.repl && cenv.vals.topLevel(sym) && cenv.type(sym)->head()->str() != "Fn") {
return cenv.engine()->compileGlobalGet(cenv, sym->sym(), *cenv.vals.ref(sym));
} else {
return *cenv.vals.ref(sym);
@@ -67,7 +67,7 @@ compile_def(CEnv& cenv, const ATuple* def) throw()
const AST* const body = def->list_ref(2);
cenv.def(sym, body, cenv.type(body), NULL); // define stub first for recursion
CVal val = resp_compile(cenv, body);
- if (cenv.vals.size() == 1 && cenv.type(body)->head()->str() != "Fn") {
+ if (cenv.repl && cenv.vals.size() == 1 && cenv.type(body)->head()->str() != "Fn") {
val = cenv.engine()->compileGlobalSet(
cenv, sym->str(), val, cenv.type(body));
cenv.lock(def);
@@ -77,6 +77,16 @@ compile_def(CEnv& cenv, const ATuple* def) throw()
}
static CVal
+compile_do(CEnv& cenv, const ATuple* ado) throw()
+{
+ CVal retVal = NULL;
+ for (ATuple::const_iterator i = ado->iter_at(1); i != ado->end(); ++i)
+ retVal = resp_compile(cenv, *i);
+
+ return retVal;
+}
+
+static CVal
compile_fn(CEnv& cenv, const ATuple* fn) throw()
{
assert(!cenv.currentFn);
@@ -117,28 +127,6 @@ compile_if(CEnv& cenv, const ATuple* aif) throw()
}
static CVal
-compile_let(CEnv& cenv, const ATuple* let) throw()
-{
- const ATuple* vars = let->list_ref(1)->to_tuple();
-
- 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), resp_compile(cenv, val));
- }
-
- CVal ret = NULL;
- for (ATuple::const_iterator i = let->iter_at(2); i != let->end(); ++i)
- ret = resp_compile(cenv, *i);
-
- cenv.pop();
-
- return ret;
-}
-
-static CVal
compile_tag_is(CEnv& cenv, const ATuple* call) throw()
{
const AST* lhs = call->list_ref(1);
@@ -207,12 +195,12 @@ resp_compile(CEnv& cenv, const AST* ast) throw()
return compile_def(cenv, call);
else if (form == "def-type")
return NULL; // FIXME
+ else if (form == "do")
+ return compile_do(cenv, call);
else if (form == "fn")
return compile_fn(cenv, call);
else if (form == "if")
return compile_if(cenv, call);
- else if (form == "let")
- return compile_let(cenv, call);
else if (form == "__tag_is")
return compile_tag_is(cenv, call);
else
diff --git a/src/lift.cpp b/src/lift.cpp
index 71843b5..1e115cf 100644
--- a/src/lift.cpp
+++ b/src/lift.cpp
@@ -183,36 +183,6 @@ lift_fn(CEnv& cenv, Code& code, const ATuple* fn) throw()
}
static const AST*
-lift_let(CEnv& cenv, Code& code, const ATuple* let) throw()
-{
- const ATuple* vars = let->list_ref(1)->to_tuple();
-
- List<ATuple, const AST> copy(let->loc, let->head(), NULL);
- List<ATuple, const AST> 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()
{
List<ATuple, const AST> copy;
@@ -295,12 +265,12 @@ resp_lift(CEnv& cenv, Code& code, const AST* ast) throw()
return lift_def(cenv, code, call);
else if (form == "def-type")
return call;
+ else if (form == "do")
+ return lift_args(cenv, code, call);
else if (form == "fn")
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 == "__tag_is")
return call;
else
diff --git a/src/repl.cpp b/src/repl.cpp
index 063f1e7..d5d78a6 100644
--- a/src/repl.cpp
+++ b/src/repl.cpp
@@ -177,6 +177,8 @@ eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute)
int
repl(CEnv& cenv)
{
+ cenv.repl = true;
+
const AST* exp = NULL;
const AST* ast = NULL;
const string replFnName = cenv.penv.gensymstr("_repl");
diff --git a/src/resp.hpp b/src/resp.hpp
index 439d00b..9bc34e8 100644
--- a/src/resp.hpp
+++ b/src/resp.hpp
@@ -748,7 +748,7 @@ Engine* resp_new_c_engine();
/// Compile-Time Environment
struct CEnv {
CEnv(PEnv& p, TEnv& t, Engine* e, ostream& os=std::cout, ostream& es=std::cerr)
- : out(os), err(es), penv(p), tenv(t), currentFn(NULL), _engine(e)
+ : out(os), err(es), penv(p), tenv(t), currentFn(NULL), repl(false), _engine(e)
{}
~CEnv() { Object::pool.collect(GC::Roots()); }
@@ -829,6 +829,8 @@ struct CEnv {
CFunc currentFn; ///< Currently compiling function
+ bool repl;
+
struct FreeVars : public std::vector<const ASymbol*> {
FreeVars(const ATuple* f, const std::string& n) : fn(f), implName(n) {}
const ATuple* const fn;
diff --git a/src/simplify.cpp b/src/simplify.cpp
index 35178ac..b797057 100644
--- a/src/simplify.cpp
+++ b/src/simplify.cpp
@@ -56,19 +56,16 @@ simplify_if(CEnv& cenv, const ATuple* aif) throw()
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");
-
+ // 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...)
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()));
+ tval.push_back(new ALiteral<int32_t>(T_INT32, -1, Cursor()));
+
+ const ASymbol* tsym = cenv.penv.gensym("_matchT");
- copyVars.push_back(tsym);
- copyVars.push_back(tval);
- copy.push_back(copyVars);
+ List<ATuple, const AST> def(match->loc, cenv.penv.sym("def"), tsym, tval.head, NULL);
List<ATuple, const AST> copyIf;
copyIf.push_back(cenv.penv.sym("if"));
@@ -86,6 +83,10 @@ simplify_match(CEnv& cenv, const ATuple* match) throw()
}
copyIf.push_back(cenv.penv.sym("__unreachable"));
cenv.setTypeSameAs(copyIf, match);
+
+ List<ATuple, const AST> copy;
+ copy.push_back(cenv.penv.sym("do"));
+ copy.push_back(def);
copy.push_back(simplify_if(cenv, copyIf));
cenv.setTypeSameAs(copy, match);
@@ -104,6 +105,39 @@ simplify_list(CEnv& cenv, const ATuple* call) throw()
return copy;
}
+static const AST*
+simplify_let(CEnv& cenv, const ATuple* call) throw()
+{
+ const ATuple* vars = call->list_ref(1)->to_tuple();
+
+ List<ATuple, const AST> fn(Cursor(), cenv.penv.sym("fn"), NULL);
+
+ List<ATuple, const AST> fnProt;
+ List<ATuple, const AST> fnArgs;
+ List<AType, const AType> fnProtT;
+ for (ATuple::const_iterator i = vars->begin(); i != vars->end();) {
+ const ASymbol* sym = (*i++)->to_symbol();
+ const AST* val = (*i++);
+ fnProt.push_back(sym);
+ fnArgs.push_back(resp_simplify(cenv, val));
+ fnProtT.push_back(cenv.type(val));
+ }
+
+ fn.push_back(fnProt.head);
+ fn.push_back(resp_simplify(cenv, call->list_ref(2)));
+
+ List<AType, const AType> fnT;
+ fnT.push_back(cenv.tenv.Fn);
+ fnT.push_back(fnProtT);
+ fnT.push_back(cenv.type(call->list_ref(2)));
+ cenv.setType(fn, fnT);
+
+ ATuple* copy = new ATuple(fn, fnArgs, call->loc);
+ cenv.setTypeSameAs(copy, call);
+
+ return copy;
+}
+
const AST*
resp_simplify(CEnv& cenv, const AST* ast) throw()
{
@@ -118,6 +152,8 @@ resp_simplify(CEnv& cenv, const AST* ast) throw()
return simplify_match(cenv, list);
else if (form == "if")
return simplify_if(cenv, list);
+ else if (form == "let")
+ return simplify_let(cenv, list);
else
return simplify_list(cenv, list);
}