diff options
Diffstat (limited to 'llvm.cpp')
-rw-r--r-- | llvm.cpp | 73 |
1 files changed, 34 insertions, 39 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 |