aboutsummaryrefslogtreecommitdiffstats
path: root/src/c.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-12-09 01:02:54 +0000
committerDavid Robillard <d@drobilla.net>2010-12-09 01:02:54 +0000
commite78acdecac3611299db12705c36bbc882efd42fe (patch)
tree7d1d964d9c2ba7e6d624782ef5bdc50603a16207 /src/c.cpp
parent82dc3a0291d993b5a1dd803aae8d166f263d7da2 (diff)
downloadresp-e78acdecac3611299db12705c36bbc882efd42fe.tar.gz
resp-e78acdecac3611299db12705c36bbc882efd42fe.tar.bz2
resp-e78acdecac3611299db12705c36bbc882efd42fe.zip
Clean up engine code.
git-svn-id: http://svn.drobilla.net/resp/resp@320 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/c.cpp')
-rw-r--r--src/c.cpp263
1 files changed, 149 insertions, 114 deletions
diff --git a/src/c.cpp b/src/c.cpp
index 0e3596d..b4089bb 100644
--- a/src/c.cpp
+++ b/src/c.cpp
@@ -27,20 +27,57 @@
using namespace std;
using boost::format;
-typedef string Type;
-typedef string Value;
+/** C Engine (Compiler only) */
+struct CEngine : public Engine {
+ CEngine()
+ : out(
+ "#include <stdint.h>\n"
+ "#include <stdbool.h>\n"
+ "void* resp_gc_allocate(unsigned size, uint8_t tag);\n\n")
+ {
+ }
-struct Function {
- string returnType;
- string name;
- string text;
+ CFunc startFn(CEnv& cenv, const string& name, const ATuple* args, const AType* type);
+ void pushFnArgs(CEnv& cenv, const ATuple* prot, const AType* type, CFunc f);
+ void finishFn(CEnv& cenv, CFunc f, CVal ret);
+ void eraseFn(CEnv& cenv, CFunc f);
+
+ CVal compileCall(CEnv& cenv, CFunc f, const AType* funcT, const vector<CVal>& args);
+ CVal compileCons(CEnv& cenv, const AType* type, CVal rtti, const vector<CVal>& fields);
+ CVal compileDot(CEnv& cenv, CVal tup, int32_t index);
+ CVal compileGlobal(CEnv& cenv, const AType* type, const string& sym, CVal val);
+ CVal compileGlobalGet(CEnv& cenv, const string& sym, CVal val);
+ IfState compileIfStart(CEnv& cenv);
+ void compileIfBranch(CEnv& cenv, IfState state, CVal condV, const AST* then);
+ CVal compileIfEnd(CEnv& cenv, IfState state, CVal elseV, const AType* type);
+ CVal compileIsA(CEnv& cenv, CVal rtti, const ASymbol* tag);
+ CVal compileLiteral(CEnv& cenv, const AST* lit);
+ CVal compilePrimitive(CEnv& cenv, const ATuple* prim);
+ CVal compileString(CEnv& cenv, const char* str);
+
+ void writeModule(CEnv& cenv, std::ostream& os);
+
+ const string call(CEnv& cenv, CFunc f, const AType* retT);
+
+private:
+ typedef string Type;
+ typedef string Value;
+
+ struct Function {
+ string returnType;
+ string name;
+ string text;
+ };
+
+ inline Value* llVal(CVal v) { return static_cast<Value*>(v); }
+ inline Function* llFunc(CFunc f) { return static_cast<Function*>(f); }
+ const Type* llType(const AType* t);
+
+ std::string out;
};
-static inline Value* llVal(CVal v) { return static_cast<Value*>(v); }
-static inline Function* llFunc(CFunc f) { return static_cast<Function*>(f); }
-
-static const Type*
-llType(const AType* t)
+const CEngine::Type*
+CEngine::llType(const AType* t)
{
if (t == NULL) {
return NULL;
@@ -85,111 +122,18 @@ llType(const AType* t)
return new Type("void*");
}
-
-/***************************************************************************
- * LLVM Engine *
- ***************************************************************************/
-
-struct CEngine : public Engine {
- CEngine()
- : out(
- "#include <stdint.h>\n"
- "#include <stdbool.h>\n"
- "void* resp_gc_allocate(unsigned size, uint8_t tag);\n\n")
- {
- }
-
- CFunc startFunction(CEnv& cenv,
- const std::string& name, const ATuple* args, const AType* type)
- {
- const AType* argsT = type->prot()->as_type();
- const AType* retT = type->list_ref(2)->as_type();
-
- vector<const Type*> cprot;
- FOREACHP(ATuple::const_iterator, i, argsT) {
- const AType* at = (*i)->as_type();
- THROW_IF(!llType(at), Cursor(), string("non-concrete parameter :: ")
- + at->str())
- cprot.push_back(llType(at));
- }
-
- THROW_IF(!llType(retT), Cursor(),
- (format("return has non-concrete type `%1%'") % retT->str()).str());
-
- Function* f = new Function();
- f->returnType = *llType(retT);
- f->name = name;
- f->text += f->returnType + "\n" + f->name + "(";
- ATuple::const_iterator ai = argsT->begin();
- ATuple::const_iterator ni = args->begin();
- for (; ai != argsT->end(); ++ai, ++ni) {
- if (ai != argsT->begin())
- f->text += ", ";
- f->text += *llType((*ai)->as_type()) + " " + (*ni)->as_symbol()->cppstr;
- }
- f->text += ")\n{\n";
-
- out += f->text;
-
- return f;
- }
-
- void pushFunctionArgs(CEnv& cenv, const ATuple* prot, const AType* type, CFunc f);
-
- void finishFunction(CEnv& cenv, CFunc f, CVal ret) {
- out += "return " + *(Value*)ret + ";\n}\n\n";
- }
-
- void eraseFunction(CEnv& cenv, CFunc f) {
- cenv.err << "C backend does not support JIT (eraseFunction)" << endl;
- }
-
- CVal compileCall(CEnv& cenv, CFunc func, const AType* funcT, const vector<CVal>& args) {
- Value* varname = new string(cenv.penv.gensymstr("x"));
- Function* f = llFunc(func);
- out += (format("const %s %s = %s(") % f->returnType % *varname % f->name).str();
- FOREACH(vector<CVal>::const_iterator, i, args)
- out += *llVal(*i);
- out += ");\n";
- return varname;
- }
-
- CVal compileCons(CEnv& cenv, const AType* type, CVal rtti, const vector<CVal>& fields);
- CVal compileDot(CEnv& cenv, CVal tup, int32_t index);
- CVal compileLiteral(CEnv& cenv, const AST* lit);
- CVal compileString(CEnv& cenv, const char* str);
- CVal compilePrimitive(CEnv& cenv, const ATuple* prim);
- CVal compileIf(CEnv& cenv, const ATuple* aif);
- CVal compileIsA(CEnv& cenv, CVal rtti, const ASymbol* tag) { return NULL; }
- CVal compileGlobal(CEnv& cenv, const AType* type, const string& sym, CVal val);
- CVal compileGlobalGet(CEnv& cenv, const string& sym, CVal val);
-
- IfState compileIfStart(CEnv& cenv) { return NULL; }
- void compileIfBranch(CEnv& cenv, IfState state, CVal condV, const AST* then) {}
- CVal compileIfEnd(CEnv& cenv, IfState state, CVal elseV, const AType* type) { return NULL; }
-
- void writeModule(CEnv& cenv, std::ostream& os) {
- os << out;
- }
-
- const string call(CEnv& cenv, CFunc f, const AType* retT) {
- cenv.err << "C backend does not support JIT (call)" << endl;
- return "";
- }
-
- std::string out;
-};
-
-Engine*
-resp_new_c_engine()
+CVal
+CEngine::compileCall(CEnv& cenv, CFunc func, const AType* funcT, const vector<CVal>& args)
{
- return new CEngine();
+ Value* varname = new string(cenv.penv.gensymstr("x"));
+ Function* f = llFunc(func);
+ out += (format("const %s %s = %s(") % f->returnType % *varname % f->name).str();
+ FOREACH(vector<CVal>::const_iterator, i, args)
+ out += *llVal(*i);
+ out += ");\n";
+ return varname;
}
-/***************************************************************************
- * Code Generation *
- ***************************************************************************/
-
CVal
CEngine::compileCons(CEnv& cenv, const AType* type, CVal rtti, const vector<CVal>& fields)
{
@@ -214,8 +158,43 @@ CEngine::compileString(CEnv& cenv, const char* str)
return new Value(string("\"") + str + "\"");
}
+CFunc
+CEngine::startFn(CEnv& cenv, const std::string& name, const ATuple* args, const AType* type)
+{
+ const AType* argsT = type->prot()->as_type();
+ const AType* retT = type->list_ref(2)->as_type();
+
+ vector<const Type*> cprot;
+ FOREACHP(ATuple::const_iterator, i, argsT) {
+ const AType* at = (*i)->as_type();
+ THROW_IF(!llType(at), Cursor(), string("non-concrete parameter :: ")
+ + at->str())
+ cprot.push_back(llType(at));
+ }
+
+ THROW_IF(!llType(retT), Cursor(),
+ (format("return has non-concrete type `%1%'") % retT->str()).str());
+
+ Function* f = new Function();
+ f->returnType = *llType(retT);
+ f->name = name;
+ f->text += f->returnType + "\n" + f->name + "(";
+ ATuple::const_iterator ai = argsT->begin();
+ ATuple::const_iterator ni = args->begin();
+ for (; ai != argsT->end(); ++ai, ++ni) {
+ if (ai != argsT->begin())
+ f->text += ", ";
+ f->text += *llType((*ai)->as_type()) + " " + (*ni)->as_symbol()->cppstr;
+ }
+ f->text += ")\n{\n";
+
+ out += f->text;
+
+ return f;
+}
+
void
-CEngine::pushFunctionArgs(CEnv& cenv, const ATuple* prot, const AType* type, CFunc f)
+CEngine::pushFnArgs(CEnv& cenv, const ATuple* prot, const AType* type, CFunc f)
{
cenv.push();
@@ -233,6 +212,19 @@ CEngine::pushFunctionArgs(CEnv& cenv, const ATuple* prot, const AType* type, CFu
}
}
+void
+CEngine::finishFn(CEnv& cenv, CFunc f, CVal ret)
+{
+ out += "return " + *(Value*)ret + ";\n}\n\n";
+}
+
+void
+CEngine::eraseFn(CEnv& cenv, CFunc f)
+{
+ cenv.err << "C backend does not support JIT (eraseFn)" << endl;
+}
+
+#if 0
CVal
CEngine::compileIf(CEnv& cenv, const ATuple* aif)
{
@@ -264,6 +256,30 @@ CEngine::compileIf(CEnv& cenv, const ATuple* aif)
return varname;
}
+#endif
+
+IfState
+CEngine::compileIfStart(CEnv& cenv)
+{
+ return NULL;
+}
+
+void
+CEngine::compileIfBranch(CEnv& cenv, IfState s, CVal condV, const AST* then)
+{
+}
+
+CVal
+CEngine::compileIfEnd(CEnv& cenv, IfState s, CVal elseV, const AType* type)
+{
+ return NULL;
+}
+
+CVal
+CEngine::compileIsA(CEnv& cenv, CVal rtti, const ASymbol* tag)
+{
+ return NULL;
+}
CVal
CEngine::compilePrimitive(CEnv& cenv, const ATuple* prim)
@@ -306,3 +322,22 @@ CEngine::compileGlobalGet(CEnv& cenv, const string& sym, CVal val)
{
return NULL;
}
+
+void
+CEngine::writeModule(CEnv& cenv, std::ostream& os)
+{
+ os << out;
+}
+
+const string
+CEngine::call(CEnv& cenv, CFunc f, const AType* retT)
+{
+ cenv.err << "C backend does not support JIT (call)" << endl;
+ return "";
+}
+
+Engine*
+resp_new_c_engine()
+{
+ return new CEngine();
+}