aboutsummaryrefslogtreecommitdiffstats
path: root/tuplr_llvm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tuplr_llvm.cpp')
-rw-r--r--tuplr_llvm.cpp91
1 files changed, 44 insertions, 47 deletions
diff --git a/tuplr_llvm.cpp b/tuplr_llvm.cpp
index 3c5ee17..b236bbd 100644
--- a/tuplr_llvm.cpp
+++ b/tuplr_llvm.cpp
@@ -15,10 +15,11 @@
* along with Tuplr. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <fstream>
+#include <map>
#include <sstream>
-#include "tuplr.hpp"
+#include <boost/format.hpp>
#include "llvm/Analysis/Verifier.h"
+#include "llvm/Assembly/AsmAnnotationWriter.h"
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/Instructions.h"
@@ -28,6 +29,7 @@
#include "llvm/Support/IRBuilder.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/Scalar.h"
+#include "tuplr.hpp"
llvm::Value* LLVal(CValue v) { return static_cast<llvm::Value*>(v); }
const llvm::Type* LLType(CType t) { return static_cast<const llvm::Type*>(t); }
@@ -130,8 +132,8 @@ struct CEnvPimpl {
Function* alloc;
};
-CEnv::CEnv(PEnv& p, CEngine& eng)
- : engine(eng), penv(p), tenv(p), symID(0), _pimpl(new CEnvPimpl(eng))
+CEnv::CEnv(PEnv& p, TEnv& t, CEngine& eng)
+ : engine(eng), penv(p), tenv(t), symID(0), _pimpl(new CEnvPimpl(eng))
{
}
@@ -154,6 +156,13 @@ CEnv::optimise(CFunction f)
_pimpl->opt.run(*static_cast<Function*>(f));
}
+void
+CEnv::write(std::ostream& os)
+{
+ AssemblyAnnotationWriter writer;
+ engine.module->print(os, &writer);
+}
+
#define LITERAL(CT, NAME, COMPILED) \
template<> CValue \
ASTLiteral<CT>::compile(CEnv& cenv) { return (COMPILED); } \
@@ -289,7 +298,7 @@ ASTCall::compile(CEnv& cenv)
}
assert(c);
- Function* f = dynamic_cast<Function*>(LLVal(c->compile(cenv)));
+ Function* f = dynamic_cast<Function*>(LLVal(cenv.compile(c)));
if (!f) throw Error("callee failed to compile", exp.loc);
vector<Value*> params(size() - 1);
@@ -601,10 +610,9 @@ repl(CEnv& cenv)
return 0;
}
-int
-main(int argc, char** argv)
+void
+initLang(PEnv& penv, TEnv& tenv)
{
- PEnv penv;
penv.reg(true, "fn", PEnv::Handler(parseFn));
penv.reg(true, "if", PEnv::Handler(parseCall<ASTIf>));
penv.reg(true, "def", PEnv::Handler(parseCall<ASTDefinition>));
@@ -617,51 +625,40 @@ main(int argc, char** argv)
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)
+ 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));
+}
- CEngine 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));
- cenv.tenv.def(penv.sym("Float"), new AType(penv.sym("Float"), Type::FloatTy));
+CEnv*
+newCenv(PEnv& penv, TEnv& tenv)
+{
+ CEngine* engine = new CEngine();
+ CEnv* cenv = new CEnv(penv, tenv, *engine);
// Host provided allocation primitive prototypes
std::vector<const Type*> argsT(1, Type::Int32Ty);
FunctionType* funcT = FunctionType::get(PointerType::get(Type::Int8Ty, 0), argsT, false);
- cenv.alloc = Function::Create(funcT, Function::ExternalLinkage, "malloc", engine.module);
-
- int ret;
- if (argc > 2 && !strncmp(argv[1], "-e", 3)) {
- std::istringstream is(argv[2]);
- ret = eval(cenv, "(command line)", is);
- } else if (argc > 2 && !strncmp(argv[1], "-f", 3)) {
- std::ifstream is(argv[2]);
- ret = eval(cenv, argv[2], is);
- is.close();
- } else {
- ret = repl(cenv);
- }
-
- //out << endl << "*** Generated Code ***" << endl;
- //cenv.module->dump();
+ cenv->alloc = Function::Create(funcT, Function::ExternalLinkage, "malloc", engine->module);
- return ret;
+ return cenv;
}