diff options
Diffstat (limited to 'src/compile.cpp')
-rw-r--r-- | src/compile.cpp | 25 |
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 == ".") |