diff options
-rw-r--r-- | llvm.cpp | 119 | ||||
-rw-r--r-- | tuplr.hpp | 15 |
2 files changed, 66 insertions, 68 deletions
@@ -53,31 +53,25 @@ struct CArg { }; - /*************************************************************************** - * Abstract Syntax Tree * + * Typing * ***************************************************************************/ CType -AType::type() +AType::ctype() { 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))->type())); + types.push_back(LLType(((AType*)at(i))->ctype())); } return PointerType::get(StructType::get(types, false), 0); } else { - return ctype; + return _ctype; } } - -/*************************************************************************** - * Typing * - ***************************************************************************/ - #define OP_IS_A(o, t) ((o) >= t ## Begin && (o) < t ## End) void @@ -184,8 +178,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->type() || at->var()) throw Error("function parameter is untyped"); - cprot.push_back(LLType(at->type())); + if (!at->ctype() || at->var()) throw Error("function parameter is untyped"); + cprot.push_back(LLType(at->ctype())); } if (!retT) throw Error("function return is untyped"); @@ -236,7 +230,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))->type(), *prot()); + Function* f = compileFunction(cenv, name, cenv.tenv.type(at(2))->ctype(), *prot()); // Bind argument values in CEnv vector<Value*> args; @@ -365,7 +359,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)->type()), "ifval"); + PHINode* pn = cenv.engine.builder.CreatePHI(LLType(cenv.tenv.type(this)->ctype()), "ifval"); FOREACH(Branches::iterator, i, branches) pn->addIncoming(i->first, i->second); @@ -431,7 +425,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))->type()); + const Type* t = LLType(cenv.tenv.type(at(i))->ctype()); types.push_back(t); sz += t->getPrimitiveSizeInBits(); } @@ -498,18 +492,61 @@ ASTCdrCall::compile(CEnv& cenv) /*************************************************************************** - * EVAL/REPL/MAIN * + * Standard Definitions * + ***************************************************************************/ + +void +initLang(PEnv& penv, TEnv& tenv) +{ + penv.reg(true, "fn", PEnv::Handler(parseFn)); + penv.reg(true, "if", PEnv::Handler(parseCall<ASTIf>)); + penv.reg(true, "def", PEnv::Handler(parseCall<ASTDefinition>)); + penv.reg(true, "cons", PEnv::Handler(parseCall<ASTConsCall>)); + penv.reg(true, "car", PEnv::Handler(parseCall<ASTCarCall>)); + penv.reg(true, "cdr", PEnv::Handler(parseCall<ASTCdrCall>)); + + bool trueVal = true; + bool falseVal = false; + penv.reg(false, "true", PEnv::Handler(parseLiteral<bool>, (CArg*)&trueVal)); + penv.reg(false, "false", PEnv::Handler(parseLiteral<bool>, (CArg*)&falseVal)); + + map<string, CArg>* prims = new map<string, CArg>(); + prims->insert(make_pair("+", CArg(Instruction::Add))); + prims->insert(make_pair("-", CArg(Instruction::Sub))); + prims->insert(make_pair("*", CArg(Instruction::Mul))); + prims->insert(make_pair("/", CArg(Instruction::FDiv))); + prims->insert(make_pair("%", CArg(Instruction::FRem))); + prims->insert(make_pair("&", CArg(Instruction::And))); + prims->insert(make_pair("|", CArg(Instruction::Or))); + prims->insert(make_pair("^", CArg(Instruction::Xor))); + prims->insert(make_pair("=", CArg(Instruction::ICmp, CmpInst::ICMP_EQ))); + prims->insert(make_pair("!=", CArg(Instruction::ICmp, CmpInst::ICMP_NE))); + prims->insert(make_pair(">", CArg(Instruction::ICmp, CmpInst::ICMP_SGT))); + prims->insert(make_pair(">=", CArg(Instruction::ICmp, CmpInst::ICMP_SGE))); + prims->insert(make_pair("<", CArg(Instruction::ICmp, CmpInst::ICMP_SLT))); + prims->insert(make_pair("<=", CArg(Instruction::ICmp, CmpInst::ICMP_SLE))); + for (map<string,CArg>::iterator p = prims->begin(); p != prims->end(); ++p) + penv.reg(true, p->first, PEnv::Handler(parseCall<ASTPrimitive>, &p->second)); + + 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 * ***************************************************************************/ const string call(AType* retT, void* fp) { std::stringstream ss; - if (retT->type() == Type::Int32Ty) + if (retT->ctype() == Type::Int32Ty) ss << ((int32_t (*)())fp)(); - else if (retT->type() == Type::FloatTy) + else if (retT->ctype() == Type::FloatTy) ss << ((float (*)())fp)(); - else if (retT->type() == Type::Int1Ty) + else if (retT->ctype() == Type::Int1Ty) ss << ((bool (*)())fp)(); else ss << ((void* (*)())fp)(); @@ -539,7 +576,7 @@ eval(CEnv& cenv, const string& name, istream& is) if (!resultType || resultType->var()) throw Error("body is undefined/untyped", cursor); - CType ctype = resultType->type(); + CType ctype = resultType->ctype(); if (!ctype) throw Error("body has no system type", cursor); // Create function for top-level of program @@ -584,9 +621,9 @@ repl(CEnv& cenv) body->lift(cenv); - if (bodyT->type()) { + if (bodyT->ctype()) { // Create anonymous function to insert code into - Function* f = compileFunction(cenv, cenv.gensym("_repl"), bodyT->type(), ASTTuple()); + Function* f = compileFunction(cenv, cenv.gensym("_repl"), bodyT->ctype(), ASTTuple()); try { Value* retVal = LLVal(cenv.compile(body)); cenv.engine.builder.CreateRet(retVal); // Finish function @@ -607,44 +644,6 @@ repl(CEnv& cenv) return 0; } -void -initLang(PEnv& penv, TEnv& tenv) -{ - penv.reg(true, "fn", PEnv::Handler(parseFn)); - penv.reg(true, "if", PEnv::Handler(parseCall<ASTIf>)); - penv.reg(true, "def", PEnv::Handler(parseCall<ASTDefinition>)); - penv.reg(true, "cons", PEnv::Handler(parseCall<ASTConsCall>)); - penv.reg(true, "car", PEnv::Handler(parseCall<ASTCarCall>)); - penv.reg(true, "cdr", PEnv::Handler(parseCall<ASTCdrCall>)); - - bool trueVal = true; - bool falseVal = false; - penv.reg(false, "true", PEnv::Handler(parseLiteral<bool>, (CArg*)&trueVal)); - penv.reg(false, "false", PEnv::Handler(parseLiteral<bool>, (CArg*)&falseVal)); - - map<string, CArg>* prims = new map<string, CArg>(); - prims->insert(make_pair("+", CArg(Instruction::Add))); - prims->insert(make_pair("-", CArg(Instruction::Sub))); - prims->insert(make_pair("*", CArg(Instruction::Mul))); - prims->insert(make_pair("/", CArg(Instruction::FDiv))); - prims->insert(make_pair("%", CArg(Instruction::FRem))); - prims->insert(make_pair("&", CArg(Instruction::And))); - prims->insert(make_pair("|", CArg(Instruction::Or))); - prims->insert(make_pair("^", CArg(Instruction::Xor))); - prims->insert(make_pair("=", CArg(Instruction::ICmp, CmpInst::ICMP_EQ))); - prims->insert(make_pair("!=", CArg(Instruction::ICmp, CmpInst::ICMP_NE))); - prims->insert(make_pair(">", CArg(Instruction::ICmp, CmpInst::ICMP_SGT))); - prims->insert(make_pair(">=", CArg(Instruction::ICmp, CmpInst::ICMP_SGE))); - prims->insert(make_pair("<", CArg(Instruction::ICmp, CmpInst::ICMP_SLT))); - prims->insert(make_pair("<=", CArg(Instruction::ICmp, CmpInst::ICMP_SLE))); - for (map<string,CArg>::iterator p = prims->begin(); p != prims->end(); ++p) - penv.reg(true, p->first, PEnv::Handler(parseCall<ASTPrimitive>, &p->second)); - - 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)); -} - CEnv* newCenv(PEnv& penv, TEnv& tenv) { @@ -164,9 +164,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(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); } string str() const { switch (kind) { case VAR: return (format("?%1%") % id).str(); @@ -203,12 +203,11 @@ struct AType : public ASTTuple { } return false; // never reached } - CType type(); - enum Kind { VAR, PRIM, EXPR }; - Kind kind; - unsigned id; + CType ctype(); + enum { VAR, PRIM, EXPR } kind; + unsigned id; private: - const CType ctype; + const CType _ctype; }; /// Lifted system functions (of various types) for a single Tuplr function |