aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm.cpp119
-rw-r--r--tuplr.hpp15
2 files changed, 66 insertions, 68 deletions
diff --git a/llvm.cpp b/llvm.cpp
index 0b32656..2e53b7f 100644
--- a/llvm.cpp
+++ b/llvm.cpp
@@ -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)
{
diff --git a/tuplr.hpp b/tuplr.hpp
index a1bae51..87cc743 100644
--- a/tuplr.hpp
+++ b/tuplr.hpp
@@ -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