aboutsummaryrefslogtreecommitdiffstats
path: root/src/compile.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-12-02 08:03:47 +0000
committerDavid Robillard <d@drobilla.net>2010-12-02 08:03:47 +0000
commitcf6c924f9cb10a583edbab2560773f2500a86323 (patch)
tree9073dbe14d904764d4af59141a03228f2e0fbf8e /src/compile.cpp
parent563a807be78bfe12e5bfbb9ff0d6da44242696c4 (diff)
downloadresp-cf6c924f9cb10a583edbab2560773f2500a86323.tar.gz
resp-cf6c924f9cb10a583edbab2560773f2500a86323.tar.bz2
resp-cf6c924f9cb10a583edbab2560773f2500a86323.zip
Work towards removing different classes for each type of expression.
git-svn-id: http://svn.drobilla.net/resp/resp@278 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/compile.cpp')
-rw-r--r--src/compile.cpp197
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;
}