aboutsummaryrefslogtreecommitdiffstats
path: root/tuplr_llvm.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-03-06 02:57:57 +0000
committerDavid Robillard <d@drobilla.net>2009-03-06 02:57:57 +0000
commit2f1797c685202d88c93a73de8dfbb2c6d6da87b3 (patch)
tree597e07baacadcfe44cacb7ac05c64e9a427a35f0 /tuplr_llvm.cpp
parent7c1ea0948d9b43bfb7a86aa356eea04c1b9649ae (diff)
downloadresp-2f1797c685202d88c93a73de8dfbb2c6d6da87b3.tar.gz
resp-2f1797c685202d88c93a73de8dfbb2c6d6da87b3.tar.bz2
resp-2f1797c685202d88c93a73de8dfbb2c6d6da87b3.zip
More generic parser function mechanism that works for atoms too.
Use atom parser methods to parse literals. Remove the last of the language and backend specific things from core code. git-svn-id: http://svn.drobilla.net/resp/tuplr@56 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'tuplr_llvm.cpp')
-rw-r--r--tuplr_llvm.cpp86
1 files changed, 50 insertions, 36 deletions
diff --git a/tuplr_llvm.cpp b/tuplr_llvm.cpp
index 8d1f1db..3c5ee17 100644
--- a/tuplr_llvm.cpp
+++ b/tuplr_llvm.cpp
@@ -40,6 +40,12 @@ struct CEngine {
llvm::IRBuilder<> builder;
};
+struct CArg {
+ CArg(int o=0, int a=0) : op(o), arg(a) {}
+ int op;
+ int arg;
+};
+
using namespace llvm;
using namespace std;
using boost::format;
@@ -76,13 +82,13 @@ ASTPrimitive::constrain(TEnv& tenv) const
{
FOREACH(const_iterator, p, *this)
(*p)->constrain(tenv);
- if (OP_IS_A(arg.op, Instruction::BinaryOps)) {
+ if (OP_IS_A(arg->op, Instruction::BinaryOps)) {
if (size() <= 2) throw Error((format("`%1%' requires at least 2 arguments")
% at(0)->str()).str(), exp.loc);
AType* tvar = tenv.type(this);
for (size_t i = 1; i < size(); ++i)
tenv.constrain(at(i), tvar);
- } else if (arg.op == Instruction::ICmp) {
+ } else if (arg->op == Instruction::ICmp) {
if (size() != 3) throw Error((format("`%1%' requires exactly 2 arguments")
% at(0)->str()).str(), exp.loc);
tenv.constrain(at(1), tenv.type(at(2)));
@@ -362,30 +368,30 @@ ASTPrimitive::compile(CEnv& cenv)
Value* a = LLVal(cenv.compile(at(1)));
Value* b = LLVal(cenv.compile(at(2)));
- if (OP_IS_A(arg.op, Instruction::BinaryOps)) {
- const Instruction::BinaryOps bo = (Instruction::BinaryOps)arg.op;
+ if (OP_IS_A(arg->op, Instruction::BinaryOps)) {
+ const Instruction::BinaryOps bo = (Instruction::BinaryOps)arg->op;
if (size() == 2)
return cenv.compile(at(1));
Value* val = cenv.engine.builder.CreateBinOp(bo, a, b);
for (size_t i = 3; i < size(); ++i)
val = cenv.engine.builder.CreateBinOp(bo, val, LLVal(cenv.compile(at(i))));
return val;
- } else if (arg.op == Instruction::ICmp) {
+ } else if (arg->op == Instruction::ICmp) {
bool isInt = cenv.tenv.type(at(1))->str() == "Int";
if (isInt) {
- return cenv.engine.builder.CreateICmp((CmpInst::Predicate)arg.arg, a, b);
+ return cenv.engine.builder.CreateICmp((CmpInst::Predicate)arg->arg, a, b);
} else {
// Translate to floating point operation
- switch (arg.arg) {
- case CmpInst::ICMP_EQ: arg.arg = CmpInst::FCMP_OEQ; break;
- case CmpInst::ICMP_NE: arg.arg = CmpInst::FCMP_ONE; break;
- case CmpInst::ICMP_SGT: arg.arg = CmpInst::FCMP_OGT; break;
- case CmpInst::ICMP_SGE: arg.arg = CmpInst::FCMP_OGE; break;
- case CmpInst::ICMP_SLT: arg.arg = CmpInst::FCMP_OLT; break;
- case CmpInst::ICMP_SLE: arg.arg = CmpInst::FCMP_OLE; break;
+ switch (arg->arg) {
+ case CmpInst::ICMP_EQ: arg->arg = CmpInst::FCMP_OEQ; break;
+ case CmpInst::ICMP_NE: arg->arg = CmpInst::FCMP_ONE; break;
+ case CmpInst::ICMP_SGT: arg->arg = CmpInst::FCMP_OGT; break;
+ case CmpInst::ICMP_SGE: arg->arg = CmpInst::FCMP_OGE; break;
+ case CmpInst::ICMP_SLT: arg->arg = CmpInst::FCMP_OLT; break;
+ case CmpInst::ICMP_SLE: arg->arg = CmpInst::FCMP_OLE; break;
default: throw Error("Unknown primitive", exp.loc);
}
- return cenv.engine.builder.CreateFCmp((CmpInst::Predicate)arg.arg, a, b);
+ return cenv.engine.builder.CreateFCmp((CmpInst::Predicate)arg->arg, a, b);
}
}
throw Error("Unknown primitive", exp.loc);
@@ -598,31 +604,39 @@ repl(CEnv& cenv)
int
main(int argc, char** argv)
{
-#define PRIM(O, A) PEnv::Parser(parseAST<ASTPrimitive>, CArg(Instruction:: O, A))
PEnv penv;
- penv.reg("fn", PEnv::Parser(parseFn));
- penv.reg("if", PEnv::Parser(parseAST<ASTIf>));
- penv.reg("def", PEnv::Parser(parseAST<ASTDefinition>));
- penv.reg("cons", PEnv::Parser(parseAST<ASTConsCall>));
- penv.reg("car", PEnv::Parser(parseAST<ASTCarCall>));
- penv.reg("cdr", PEnv::Parser(parseAST<ASTCdrCall>));
- penv.reg("+", PRIM(Add, 0));
- penv.reg("-", PRIM(Sub, 0));
- penv.reg("*", PRIM(Mul, 0));
- penv.reg("/", PRIM(FDiv, 0));
- penv.reg("%", PRIM(FRem, 0));
- penv.reg("&", PRIM(And, 0));
- penv.reg("|", PRIM(Or, 0));
- penv.reg("^", PRIM(Xor, 0));
- penv.reg("=", PRIM(ICmp, CmpInst::ICMP_EQ));
- penv.reg("!=", PRIM(ICmp, CmpInst::ICMP_NE));
- penv.reg(">", PRIM(ICmp, CmpInst::ICMP_SGT));
- penv.reg(">=", PRIM(ICmp, CmpInst::ICMP_SGE));
- penv.reg("<", PRIM(ICmp, CmpInst::ICMP_SLT));
- penv.reg("<=", PRIM(ICmp, CmpInst::ICMP_SLE));
+ 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;
+ 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));
CEngine engine;
- CEnv cenv(penv, engine);
+ CEnv cenv(penv, engine);
cenv.tenv.def(penv.sym("Bool"), new AType(penv.sym("Bool"), Type::Int1Ty));
cenv.tenv.def(penv.sym("Int"), new AType(penv.sym("Int"), Type::Int32Ty));