aboutsummaryrefslogtreecommitdiffstats
path: root/src/compile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/compile.cpp')
-rw-r--r--src/compile.cpp24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/compile.cpp b/src/compile.cpp
index 554fab6..48c2b0a 100644
--- a/src/compile.cpp
+++ b/src/compile.cpp
@@ -151,6 +151,28 @@ compile_if(CEnv& cenv, const ATuple* aif) throw()
return cenv.engine()->compileIfEnd(cenv, state, elseV, cenv.type(aif));
}
+static CVal
+compile_match(CEnv& cenv, const ATuple* match) 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);
+}
+
CVal
resp_compile(CEnv& cenv, const AST* ast) throw()
{
@@ -185,7 +207,7 @@ resp_compile(CEnv& cenv, const AST* ast) throw()
else if (form == ".")
return compile_dot(cenv, call);
else if (form == "match")
- return cenv.engine()->compileMatch(cenv, call);
+ return compile_match(cenv, call);
else if (form == "def-type")
return NULL;
else