diff options
Diffstat (limited to 'src/compile.cpp')
-rw-r--r-- | src/compile.cpp | 33 |
1 files changed, 11 insertions, 22 deletions
diff --git a/src/compile.cpp b/src/compile.cpp index b5d7222..123b403 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -57,7 +57,7 @@ compile_dot(CEnv& cenv, const ATuple* dot) throw() const ALiteral<int32_t>* index = (ALiteral<int32_t>*)(*++i); assert(index->tag() == T_INT32); CVal tupVal = resp_compile(cenv, tup); - return cenv.engine()->compileDot(cenv, tupVal, index->val + 1); // + 1 to skip RTTI + return cenv.engine()->compileDot(cenv, tupVal, index->val); } static CVal @@ -120,7 +120,10 @@ compile_if(CEnv& cenv, const ATuple* aif) throw() i = next; // jump 2 each iteration (to the next predicate) } - CVal elseV = resp_compile(cenv, aif->list_last()); + CVal elseV = NULL; + if (*aif->list_last() != *cenv.penv.sym("__unreachable")) + elseV = resp_compile(cenv, aif->list_last()); + return cenv.engine()->compileIfEnd(cenv, state, elseV, cenv.type(aif)); } @@ -147,25 +150,11 @@ compile_let(CEnv& cenv, const ATuple* let) throw() } static CVal -compile_match(CEnv& cenv, const ATuple* match) throw() +compile_tag_is(CEnv& cenv, const ATuple* call) throw() { - IfState state = cenv.engine()->compileIfStart(cenv); - CVal matchee = resp_compile(cenv, match->list_ref(1)); - CVal rtti = cenv.engine()->compileDot(cenv, matchee, 0); - - size_t idx = 1; - for (ATuple::const_iterator i = match->iter_at(2); i != match->end(); ++idx) { - const AST* pat = *i++; - const AST* body = *i++; - const ASymbol* sym = pat->as_tuple()->head()->as_symbol(); - - CVal condV = cenv.engine()->compileIsA(cenv, rtti, sym); - - cenv.engine()->compileIfBranch(cenv, state, condV, body); - } - - const AType* type = cenv.type(match); - return cenv.engine()->compileIfEnd(cenv, state, NULL, type); + const AST* lhs = call->list_ref(1); + const ASymbol* rhs = call->list_ref(2)->as_symbol(); + return cenv.engine()->compileIsA(cenv, resp_compile(cenv, lhs), rhs); } static CVal @@ -235,8 +224,8 @@ resp_compile(CEnv& cenv, const AST* ast) throw() return compile_if(cenv, call); else if (form == "let") return compile_let(cenv, call); - else if (form == "match") - return compile_match(cenv, call); + else if (form == "__tag_is") + return compile_tag_is(cenv, call); else return compile_call(cenv, call); } |