aboutsummaryrefslogtreecommitdiffstats
path: root/src/compile.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-12-29 22:50:20 +0000
committerDavid Robillard <d@drobilla.net>2010-12-29 22:50:20 +0000
commit2eda11ca28589991471ff3251cccc2471424770e (patch)
treea763edd57dcdcabba3f5eccf5af23f52d90b1eca /src/compile.cpp
parent0076c050fb12c92a35b673d63fca82d5cff63bdb (diff)
downloadresp-2eda11ca28589991471ff3251cccc2471424770e.tar.gz
resp-2eda11ca28589991471ff3251cccc2471424770e.tar.bz2
resp-2eda11ca28589991471ff3251cccc2471424770e.zip
Destructuring (i.e. working `match').
git-svn-id: http://svn.drobilla.net/resp/resp@374 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/compile.cpp')
-rw-r--r--src/compile.cpp25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/compile.cpp b/src/compile.cpp
index d2f0530..90e31ba 100644
--- a/src/compile.cpp
+++ b/src/compile.cpp
@@ -51,6 +51,14 @@ compile_literal_symbol(CEnv& cenv, const ASymbol* sym) throw()
}
static CVal
+compile_cast(CEnv& cenv, const ATuple* cast) throw()
+{
+ return cenv.engine()->compileCast(cenv,
+ resp_compile(cenv, cast->frst()),
+ cenv.type(cast));
+}
+
+static CVal
compile_type(CEnv& cenv, const AST* type) throw()
{
return compile_literal_symbol(cenv, type->as_tuple()->fst()->as_symbol());
@@ -78,6 +86,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);
+ assert((unsigned)index->val < cenv.type(dot->frst())->as_tuple()->list_len());
return cenv.engine()->compileDot(cenv, tupVal, index->val);
}
@@ -175,14 +184,24 @@ compile_quote(CEnv& cenv, const ATuple* quote) throw()
static CVal
compile_call(CEnv& cenv, const ATuple* call) throw()
{
+ const ATuple* protT = cenv.type(call->fst())->as_tuple()->prot();
CFunc f = resp_compile(cenv, call->fst());
if (!f)
f = cenv.currentFn; // Recursive call (callee defined as a stub)
vector<CVal> args;
- for (ATuple::const_iterator e = call->iter_at(1); e != call->end(); ++e)
- args.push_back(resp_compile(cenv, *e));
+ ATuple::const_iterator t = protT->iter_at(0);
+ for (ATuple::const_iterator e = call->iter_at(1); e != call->end(); ++e, ++t) {
+ CVal arg = resp_compile(cenv, *e);
+ if ((*e)->to_symbol()) {
+ if (cenv.type(*e) != cenv.type(*t)) {
+ args.push_back(cenv.engine()->compileCast(cenv, arg, *t));
+ continue;
+ }
+ }
+ args.push_back(arg);
+ }
return cenv.engine()->compileCall(cenv, f, cenv.type(call->fst())->as_tuple(), args);
}
@@ -211,6 +230,8 @@ resp_compile(CEnv& cenv, const AST* ast) throw()
const std::string form = sym ? sym->sym() : "";
if (is_primitive(cenv.penv, call))
return cenv.engine()->compilePrimitive(cenv, ast->as_tuple());
+ else if (form == "cast")
+ return compile_cast(cenv, call);
else if (form == "cons" || isupper(form[0]))
return compile_cons(cenv, call);
else if (form == ".")