diff options
author | David Robillard <d@drobilla.net> | 2009-03-06 22:33:58 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-03-06 22:33:58 +0000 |
commit | 77162da0f773b8e79939491aca4e0232c62c255c (patch) | |
tree | c9618c6b9b52a20a9bf9830d9da69bd6ff732fbc | |
parent | ecef8f697c66e15b85beb934d2b617b915a97aab (diff) | |
download | resp-77162da0f773b8e79939491aca4e0232c62c255c.tar.gz resp-77162da0f773b8e79939491aca4e0232c62c255c.tar.bz2 resp-77162da0f773b8e79939491aca4e0232c62c255c.zip |
Remove low level type stuff completely from core code (let the backend deal with conversion of abstract types to compiled types).
git-svn-id: http://svn.drobilla.net/resp/tuplr@65 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r-- | llvm.cpp | 73 | ||||
-rw-r--r-- | tuplr.cpp | 6 | ||||
-rw-r--r-- | tuplr.hpp | 32 |
3 files changed, 58 insertions, 53 deletions
@@ -35,9 +35,8 @@ using namespace llvm; using namespace std; using boost::format; -inline Value* LLVal(CValue v) { return static_cast<Value*>(v); } -inline const Type* LLType(CType t) { return static_cast<const Type*>(t); } -inline Function* LLFunc(CFunction f) { return static_cast<Function*>(f); } +inline Value* LLVal(CValue v) { return static_cast<Value*>(v); } +inline Function* LLFunc(CFunction f) { return static_cast<Function*>(f); } struct CEngine { CEngine(); @@ -51,19 +50,28 @@ struct CEngine { * Typing * ***************************************************************************/ -CType -AType::ctype() +const Type* +lltype(AType* t) { - if (at(0)->str() == "Pair") { - vector<const Type*> types; - for (size_t i = 1; i < size(); ++i) { - assert(dynamic_cast<AType*>(at(i))); - types.push_back(LLType(((AType*)at(i))->ctype())); + switch (t->kind) { + case AType::VAR: + return NULL; + case AType::PRIM: + if (t->at(0)->str() == "Bool") return Type::Int1Ty; + if (t->at(0)->str() == "Int") return Type::Int32Ty; + if (t->at(0)->str() == "Float") return Type::FloatTy; + throw Error(string("Unknown primitive type `") + t->str() + "'"); + case AType::EXPR: + if (t->at(0)->str() == "Pair") { + vector<const Type*> types; + for (size_t i = 1; i < t->size(); ++i) + types.push_back(lltype(dynamic_cast<AType*>(t->at(i)))); + return PointerType::get(StructType::get(types, false), 0); + } else { + throw Error(string("Unknown composite type `") + t->str() + "'"); } - return PointerType::get(StructType::get(types, false), 0); - } else { - return _ctype; } + return NULL; // not reached } @@ -141,7 +149,7 @@ LITERAL(float, "Float", ConstantFP::get(Type::FloatTy, val)) LITERAL(bool, "Bool", ConstantInt::get(Type::Int1Ty, val, false)) static Function* -compileFunction(CEnv& cenv, const std::string& name, CType retT, const ASTTuple& prot, +compileFunction(CEnv& cenv, const std::string& name, const Type* retT, const ASTTuple& prot, const vector<string> argNames=vector<string>()) { Function::LinkageTypes linkage = Function::ExternalLinkage; @@ -149,8 +157,8 @@ compileFunction(CEnv& cenv, const std::string& name, CType retT, const ASTTuple& vector<const Type*> cprot; for (size_t i = 0; i < prot.size(); ++i) { AType* at = cenv.tenv.type(prot.at(i)); - if (!at->ctype() || at->var()) throw Error("function parameter is untyped"); - cprot.push_back(LLType(at->ctype())); + if (!lltype(at)) throw Error("function parameter is untyped"); + cprot.push_back(lltype(at)); } if (!retT) throw Error("function return is untyped"); @@ -201,7 +209,7 @@ ASTClosure::lift(CEnv& cenv) // Write function declaration string name = this->name == "" ? cenv.gensym("_fn") : this->name; - Function* f = compileFunction(cenv, name, cenv.tenv.type(at(2))->ctype(), *prot()); + Function* f = compileFunction(cenv, name, lltype(cenv.tenv.type(at(2))), *prot()); // Bind argument values in CEnv vector<Value*> args; @@ -330,7 +338,7 @@ ASTIf::compile(CEnv& cenv) // Emit merge block (Phi node) parent->getBasicBlockList().push_back(mergeBB); cenv.engine.builder.SetInsertPoint(mergeBB); - PHINode* pn = cenv.engine.builder.CreatePHI(LLType(cenv.tenv.type(this)->ctype()), "ifval"); + PHINode* pn = cenv.engine.builder.CreatePHI(lltype(cenv.tenv.type(this)), "ifval"); FOREACH(Branches::iterator, i, branches) pn->addIncoming(i->first, i->second); @@ -404,7 +412,7 @@ ASTConsCall::lift(CEnv& cenv) vector<const Type*> types; size_t sz = 0; for (size_t i = 1; i < size(); ++i) { - const Type* t = LLType(cenv.tenv.type(at(i))->ctype()); + const Type* t = lltype(cenv.tenv.type(at(i))); types.push_back(t); sz += t->getPrimitiveSizeInBits(); } @@ -471,19 +479,6 @@ ASTCdrCall::compile(CEnv& cenv) /*************************************************************************** - * Standard Definitions * - ***************************************************************************/ - -void -initTypes(PEnv& penv, TEnv& tenv) -{ - tenv.def(penv.sym("Bool"), new AType(penv.sym("Bool"), Type::Int1Ty)); - tenv.def(penv.sym("Int"), new AType(penv.sym("Int"), Type::Int32Ty)); - tenv.def(penv.sym("Float"), new AType(penv.sym("Float"), Type::FloatTy)); -} - - -/*************************************************************************** * EVAL/REPL * ***************************************************************************/ @@ -491,11 +486,11 @@ const string call(AType* retT, void* fp) { std::stringstream ss; - if (retT->ctype() == Type::Int32Ty) + if (lltype(retT) == Type::Int32Ty) ss << ((int32_t (*)())fp)(); - else if (retT->ctype() == Type::FloatTy) + else if (lltype(retT) == Type::FloatTy) ss << ((float (*)())fp)(); - else if (retT->ctype() == Type::Int1Ty) + else if (lltype(retT) == Type::Int1Ty) ss << ((bool (*)())fp)(); else ss << ((void* (*)())fp)(); @@ -525,8 +520,8 @@ eval(CEnv& cenv, const string& name, istream& is) if (!resultType || resultType->var()) throw Error("body is undefined/untyped", cursor); - CType ctype = resultType->ctype(); - if (!ctype) throw Error("body has no system type", cursor); + const Type* ctype = lltype(resultType); + if (!ctype) throw Error("body has non-compilable type", cursor); // Create function for top-level of program Function* f = compileFunction(cenv, "main", ctype, ASTTuple()); @@ -570,9 +565,9 @@ repl(CEnv& cenv) body->lift(cenv); - if (bodyT->ctype()) { + if (lltype(bodyT)) { // Create anonymous function to insert code into - Function* f = compileFunction(cenv, cenv.gensym("_repl"), bodyT->ctype(), ASTTuple()); + Function* f = compileFunction(cenv, cenv.gensym("_repl"), lltype(bodyT), ASTTuple()); try { Value* retVal = LLVal(cenv.compile(body)); cenv.engine.builder.CreateRet(retVal); // Finish function @@ -100,6 +100,11 @@ readExpression(Cursor& cur, std::istream& in) void initLang(PEnv& penv, TEnv& tenv) { + // Types + tenv.def(penv.sym("Bool"), new AType(penv.sym("Bool"))); + tenv.def(penv.sym("Int"), new AType(penv.sym("Int"))); + tenv.def(penv.sym("Float"), new AType(penv.sym("Float"))); + // Literals static bool trueVal = true; static bool falseVal = false; @@ -155,7 +160,6 @@ main(int argc, char** argv) { PEnv penv; TEnv tenv(penv); - initTypes(penv, tenv); initLang(penv, tenv); CEnv* cenv = newCenv(penv, tenv); @@ -26,17 +26,26 @@ #include <vector> #include <boost/format.hpp> -typedef void* CValue; ///< Compiled value (opaque) -typedef const void* CType; ///< Compiled type (opaque) -typedef void* CFunction; ///< Compiled function (opaque) - -struct CEngine; ///< Backend data (opaque) - #define FOREACH(IT, i, c) for (IT i = (c).begin(); i != (c).end(); ++i) using namespace std; using boost::format; + +/*************************************************************************** + * Backend * + ***************************************************************************/ + +typedef void* CValue; ///< Compiled value (opaque) +typedef void* CFunction; ///< Compiled function (opaque) + +struct CEngine; ///< Backend data (opaque) + + +/*************************************************************************** + * Basic Utility Classes * + ***************************************************************************/ + extern std::ostream& err; extern std::ostream& out; @@ -56,7 +65,7 @@ struct Error { }; template<typename Atom> -struct Exp { // ::= Atom | (Exp*) +struct Exp { Exp(Cursor c) : type(LIST), loc(c) {} Exp(Cursor c, const Atom& a) : type(ATOM), loc(c), atom(a) {} typedef std::vector< Exp<Atom> > List; @@ -164,9 +173,9 @@ struct ASTTuple : public AST, public vector<AST*> { /// Type Expression, e.g. "Int", "(Fn (Int Int) Float)" struct AType : public ASTTuple { - AType(const ASTTuple& t) : ASTTuple(t), kind(EXPR), _ctype(0) {} - AType(unsigned i) : kind(VAR), id(i), _ctype(0) {} - AType(ASTSymbol* n, CType t) : kind(PRIM), _ctype(t) { push_back(n); } + AType(unsigned i) : kind(VAR), id(i) {} + AType(ASTSymbol* s) : kind(PRIM), id(0) { push_back(s); } + AType(const ASTTuple& t) : ASTTuple(t), kind(EXPR), id(0) {} string str() const { switch (kind) { case VAR: return (format("?%1%") % id).str(); @@ -203,11 +212,8 @@ struct AType : public ASTTuple { } return false; // never reached } - CType ctype(); enum { VAR, PRIM, EXPR } kind; unsigned id; -private: - const CType _ctype; }; /// Lifted system functions (of various types) for a single Tuplr function |