aboutsummaryrefslogtreecommitdiffstats
path: root/src/compile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/compile.cpp')
-rw-r--r--src/compile.cpp114
1 files changed, 44 insertions, 70 deletions
diff --git a/src/compile.cpp b/src/compile.cpp
index ba8cc5e..1f82a47 100644
--- a/src/compile.cpp
+++ b/src/compile.cpp
@@ -29,6 +29,9 @@ using namespace std;
static CVal
compile_symbol(CEnv& cenv, const ASymbol* sym) throw()
{
+ if (*sym == *cenv.penv.sym("__unreachable"))
+ return NULL;
+
if (cenv.repl && cenv.vals.topLevel(sym) && !is_form(cenv.type(sym), "Fn")) {
return cenv.engine()->compileGlobalGet(cenv, sym->sym(), *cenv.vals.ref(sym));
} else {
@@ -94,14 +97,8 @@ compile_def(CEnv& cenv, const ATuple* def) throw()
{
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); // define stub first for recursion
CVal val = resp_compile(cenv, body);
- if (cenv.repl && cenv.vals.size() == 1 && !is_form(cenv.type(body), "Fn")) {
- val = cenv.engine()->compileGlobalSet(
- cenv, sym->str(), val, cenv.type(body));
- cenv.lock(def);
- }
- cenv.vals.def(sym, val);
+ cenv.def(sym, body, cenv.type(body), val);
return NULL;
}
@@ -125,63 +122,6 @@ compile_def_type(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);
-
- const AST* const type = cenv.type(fn);
- CFunc f = cenv.findImpl(fn, type);
- if (f)
- return f;
-
- // Write function declaration and push stack frame
- f = cenv.engine()->startFn(cenv, cenv.name(fn), fn->prot(), type->as_tuple());
- cenv.engine()->pushFnArgs(cenv, fn->prot(), type->as_tuple(), f);
- cenv.currentFn = f;
-
- // Write function body
- CVal retVal = NULL;
- for (ATuple::const_iterator i = fn->iter_at(2); i != fn->end(); ++i)
- retVal = resp_compile(cenv, *i);
-
- // Write function conclusion and pop stack frame
- cenv.engine()->finishFn(cenv, f, retVal, type->as_tuple()->frrst());
- cenv.pop();
- cenv.currentFn = NULL;
-
- cenv.vals.def(cenv.penv.sym(cenv.name(fn)), f);
- cenv.addImpl(fn, f);
- return f;
-}
-
-static CVal
-compile_if(CEnv& cenv, const ATuple* aif) throw()
-{
- const AST* cond = aif->list_ref(1);
- const AST* then = aif->list_ref(2);
- const AST* aelse = NULL;
- if (*aif->list_last() != *cenv.penv.sym("__unreachable"))
- aelse = aif->list_ref(3);
-
- const AST* type = cenv.type(then);
-
- cenv.engine()->compileIfStart(cenv, cond, type);
- cenv.engine()->compileIfThen(cenv, resp_compile(cenv, then));
- cenv.engine()->compileIfElse(cenv, resp_compile(cenv, aelse));
- return cenv.engine()->compileIfEnd(cenv);
-}
-
-static CVal
compile_quote(CEnv& cenv, const ATuple* quote) throw()
{
switch (quote->list_ref(1)->tag()) {
@@ -218,6 +158,34 @@ compile_call(CEnv& cenv, const ATuple* call) throw()
return cenv.engine()->compileCall(cenv, f, cenv.type(call->fst())->as_tuple(), args);
}
+static CVal
+compile_fn_start(CEnv& cenv, const ATuple* call) throw()
+{
+ const ASymbol* name = call->list_ref(1)->as_symbol();
+ const ATuple* type = cenv.type(name)->as_tuple();
+ const ATuple* args = call->rst()->rst();
+
+ CFunc func = cenv.engine()->startFn(cenv, name->sym(), args, type);
+ cenv.def(name, NULL, type, func);
+
+ cenv.engine()->pushFnArgs(cenv, args, type, func);
+ cenv.currentFn = func;
+
+ return NULL;
+}
+
+static CVal
+compile_fn_end(CEnv& cenv, const ATuple* call) throw()
+{
+ const AST* retT = cenv.type(call->frst())->as_tuple()->frrst();
+ cenv.engine()->finishFn(cenv, cenv.currentFn,
+ resp_compile(cenv, call->frrst()),
+ retT);
+ cenv.pop();
+ cenv.currentFn = NULL;
+ return NULL;
+}
+
CVal
resp_compile(CEnv& cenv, const AST* ast) throw()
{
@@ -255,14 +223,20 @@ resp_compile(CEnv& cenv, const AST* ast) throw()
return compile_def(cenv, call);
else if (form == "def-type")
return compile_def_type(cenv, call);
- 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 == "quote")
return compile_quote(cenv, call);
+ else if (form == "fn-start")
+ return compile_fn_start(cenv, call);
+ else if (form == "fn-end")
+ return compile_fn_end(cenv, call);
+ else if (form == "if-start")
+ return cenv.engine()->compileIfStart(cenv, call->frrst(), cenv.type(call));
+ else if (form == "if-then")
+ return cenv.engine()->compileIfThen(cenv, resp_compile(cenv, call->frrst()));
+ else if (form == "if-else")
+ return cenv.engine()->compileIfElse(cenv, resp_compile(cenv, call->frrst()));
+ else if (form == "if-end")
+ return cenv.engine()->compileIfEnd(cenv);
else
return compile_call(cenv, call);
}