diff options
Diffstat (limited to 'tuplr_llvm.cpp')
-rw-r--r-- | tuplr_llvm.cpp | 91 |
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; } |