From e78acdecac3611299db12705c36bbc882efd42fe Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 9 Dec 2010 01:02:54 +0000 Subject: Clean up engine code. git-svn-id: http://svn.drobilla.net/resp/resp@320 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- src/c.cpp | 263 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 149 insertions(+), 114 deletions(-) (limited to 'src/c.cpp') 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 \n" + "#include \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& args); + CVal compileCons(CEnv& cenv, const AType* type, CVal rtti, const vector& 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(v); } + inline Function* llFunc(CFunc f) { return static_cast(f); } + const Type* llType(const AType* t); + + std::string out; }; -static inline Value* llVal(CVal v) { return static_cast(v); } -static inline Function* llFunc(CFunc f) { return static_cast(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 \n" - "#include \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 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& 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::const_iterator, i, args) - out += *llVal(*i); - out += ");\n"; - return varname; - } - - CVal compileCons(CEnv& cenv, const AType* type, CVal rtti, const vector& 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& 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::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& 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 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(); +} -- cgit v1.2.1