diff options
Diffstat (limited to 'src/compile.cpp')
-rw-r--r-- | src/compile.cpp | 197 |
1 files changed, 109 insertions, 88 deletions
diff --git a/src/compile.cpp b/src/compile.cpp index da9683e..ccde2ca 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -23,62 +23,36 @@ using namespace std; -#define COMPILE_LITERAL(CT) \ -template<> CVal ALiteral<CT>::compile(CEnv& cenv) const throw() { \ - return cenv.engine()->compileLiteral(cenv, this); \ -} -COMPILE_LITERAL(int32_t); -COMPILE_LITERAL(float); -COMPILE_LITERAL(bool); - -CVal -AString::compile(CEnv& cenv) const throw() -{ - return cenv.engine()->compileString(cenv, c_str()); -} - -CVal -AQuote::compile(CEnv& cenv) const throw() -{ - return list_ref(1)->compile(cenv); -} - -CVal -ALexeme::compile(CEnv& cenv) const throw() +static CVal +compile_symbol(CEnv& cenv, const ASymbol* sym) throw() { - return cenv.engine()->compileString(cenv, c_str()); -} - -CVal -ASymbol::compile(CEnv& cenv) const throw() -{ - if (cenv.vals.topLevel(this) && cenv.type(this)->head()->str() != "Fn") { - return cenv.engine()->getGlobal(cenv, cppstr, *cenv.vals.ref(this)); + if (cenv.vals.topLevel(sym) && cenv.type(sym)->head()->str() != "Fn") { + return cenv.engine()->getGlobal(cenv, sym->cppstr, *cenv.vals.ref(sym)); } else { - return *cenv.vals.ref(this); + return *cenv.vals.ref(sym); } } -CVal -AFn::compile(CEnv& cenv) const throw() +static CVal +compile_fn(CEnv& cenv, const AFn* fn) throw() { - const AType* type = cenv.type(this); - CFunc f = cenv.findImpl(this, type); + const AType* type = cenv.type(fn); + CFunc f = cenv.findImpl(fn, type); if (f) return f; // Write function declaration - f = cenv.engine()->startFunction(cenv, name, prot(), type); + f = cenv.engine()->startFunction(cenv, fn->name, fn->prot(), type); // Create a new environment frame and bind argument values - cenv.engine()->pushFunctionArgs(cenv, this, type, f); + cenv.engine()->pushFunctionArgs(cenv, fn, type, f); assert(!cenv.currentFn); cenv.currentFn = f; // Write function body CVal retVal = NULL; - for (AFn::const_iterator i = iter_at(2); i != end(); ++i) - retVal = (*i)->compile(cenv); + for (AFn::const_iterator i = fn->iter_at(2); i != fn->end(); ++i) + retVal = resp_compile(cenv, *i); // Write function conclusion cenv.engine()->finishFunction(cenv, f, retVal); @@ -87,97 +61,144 @@ AFn::compile(CEnv& cenv) const throw() cenv.pop(); cenv.currentFn = NULL; - cenv.vals.def(cenv.penv.sym(name), f); - cenv.addImpl(this, f); + cenv.vals.def(cenv.penv.sym(fn->name), f); + cenv.addImpl(fn, f); return f; } -CVal -ACall::compile(CEnv& cenv) const throw() +static CVal +compile_call(CEnv& cenv, const ACall* call) throw() { - CFunc f = (*begin())->compile(cenv); + CFunc f = resp_compile(cenv, *call->begin()); if (!f) f = cenv.currentFn; // Recursive call (callee defined as a stub) vector<CVal> args; - for (const_iterator e = iter_at(1); e != end(); ++e) - args.push_back((*e)->compile(cenv)); + for (ACall::const_iterator e = call->iter_at(1); e != call->end(); ++e) + args.push_back(resp_compile(cenv, *e)); - return cenv.engine()->compileCall(cenv, f, cenv.type(head()), args); + return cenv.engine()->compileCall(cenv, f, cenv.type(call->head()), args); } -CVal -ADef::compile(CEnv& cenv) const throw() +static CVal +compile_def(CEnv& cenv, const ADef* def) throw() { - cenv.def(sym(), body(), cenv.type(body()), NULL); // define stub first for recursion - CVal val = body()->compile(cenv); - if (cenv.vals.size() == 1 && cenv.type(body())->head()->str() != "Fn") { + const ASymbol* const sym = def->list_ref(1)->as<const ASymbol*>(); + cenv.def(sym, def->body(), cenv.type(def->body()), NULL); // define stub first for recursion + CVal val = resp_compile(cenv, def->body()); + if (cenv.vals.size() == 1 && cenv.type(def->body())->head()->str() != "Fn") { val = cenv.engine()->compileGlobal( - cenv, cenv.type(body()), sym()->str(), val); - cenv.lock(this); + cenv, cenv.type(def->body()), sym->str(), val); + cenv.lock(def); } - cenv.vals.def(sym(), val); + cenv.vals.def(sym, val); return NULL; } -CVal -AIf::compile(CEnv& cenv) const throw() +static CVal +compile_cons(CEnv& cenv, const ACons* cons) throw() { - return cenv.engine()->compileIf(cenv, this); -} - -CVal -ACons::compile(CEnv& cenv) const throw() -{ - return ATuple::compile(cenv); -} - -CVal -ATuple::compile(CEnv& cenv) const throw() -{ - AType* type = new AType(const_cast<ASymbol*>(head()->as<const ASymbol*>()), NULL, Cursor()); + AType* type = new AType(const_cast<ASymbol*>(cons->head()->as<const ASymbol*>()), NULL, Cursor()); TList tlist(type); vector<CVal> fields; - for (const_iterator i = iter_at(1); i != end(); ++i) { + for (ACons::const_iterator i = cons->iter_at(1); i != cons->end(); ++i) { tlist.push_back(const_cast<AType*>(cenv.type(*i))); - fields.push_back((*i)->compile(cenv)); + fields.push_back(resp_compile(cenv, *i)); } - return cenv.engine()->compileTup(cenv, type, type->compile(cenv), fields); + return cenv.engine()->compileTup(cenv, type, resp_compile(cenv, type), fields); } -CVal -AType::compile(CEnv& cenv) const throw() +static CVal +compile_type(CEnv& cenv, const AType* type) throw() { - const ASymbol* sym = head()->as<const ASymbol*>(); + const ASymbol* sym = type->head()->as<const ASymbol*>(); CVal* existing = cenv.vals.ref(sym); if (existing) { return *existing; } else { - CVal compiled = cenv.engine()->compileString(cenv, (string("__T_") + head()->str()).c_str()); + CVal compiled = cenv.engine()->compileString( + cenv, (string("__T_") + type->head()->str()).c_str()); cenv.vals.def(sym, compiled); return compiled; } } -CVal -ADot::compile(CEnv& cenv) const throw() +static CVal +compile_dot(CEnv& cenv, const ADot* dot) throw() { - const_iterator i = begin(); + ATuple::const_iterator i = dot->begin(); const AST* tup = *++i; const ALiteral<int32_t>* index = (*++i)->as<const ALiteral<int32_t>*>(); - CVal tupVal = tup->compile(cenv); + CVal tupVal = resp_compile(cenv, tup); return cenv.engine()->compileDot(cenv, tupVal, index->val); } CVal -APrimitive::compile(CEnv& cenv) const throw() +resp_compile(CEnv& cenv, const AST* ast) throw() { - return cenv.engine()->compilePrimitive(cenv, this); -} + if (ast->to<const ALiteral<int32_t>*>() + || ast->to<const ALiteral<float>*>() + || ast->to<const ALiteral<bool>*>()) + return cenv.engine()->compileLiteral(cenv, ast); + + const AString* str = ast->to<const AString*>(); + if (str) + return cenv.engine()->compileString(cenv, str->c_str()); + + const AQuote* quote = ast->to<const AQuote*>(); + if (quote) + return resp_compile(cenv, quote->list_ref(1)); + + const ALexeme* lexeme = ast->to<const ALexeme*>(); + if (lexeme) + return cenv.engine()->compileString(cenv, lexeme->c_str()); + + const ASymbol* sym = ast->to<const ASymbol*>(); + if (sym) + return compile_symbol(cenv, sym); + + const AFn* fn = ast->to<const AFn*>(); + if (fn) + return compile_fn(cenv, fn); + + const ADef* def = ast->to<const ADef*>(); + if (def) + return compile_def(cenv, def); -CVal -AMatch::compile(CEnv& cenv) const throw() -{ - return cenv.engine()->compileMatch(cenv, this); + const AIf* aif = ast->to<const AIf*>(); + if (aif) + return cenv.engine()->compileIf(cenv, aif); + + const ACons* cons = ast->to<const ACons*>(); + if (cons) + return compile_cons(cenv, cons); + + const APrimitive* prim = ast->to<const APrimitive*>(); + if (prim) + return cenv.engine()->compilePrimitive(cenv, prim); + + const AMatch* match = ast->to<const AMatch*>(); + if (match) + return cenv.engine()->compileMatch(cenv, match); + + const AType* type = ast->to<const AType*>(); + if (type) + return compile_type(cenv, type); + + const ADot* dot = ast->to<const ADot*>(); + if (dot) + return compile_dot(cenv, dot); + + const ADefType* deftype = ast->to<const ADefType*>(); + if (deftype) + return NULL; + + const ACall* call = ast->to<const ACall*>(); + if (call) + return compile_call(cenv, call); + + cenv.err << "Attempt to compile unknown type" << endl; + assert(false); + return NULL; } |