aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile22
-rw-r--r--src/compile.cpp8
-rw-r--r--src/tuplr.cpp43
-rw-r--r--src/tuplr.hpp8
-rw-r--r--src/tuplr_llvm.cpp45
5 files changed, 70 insertions, 56 deletions
diff --git a/Makefile b/Makefile
index 66ae353..f25b489 100644
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,14 @@
LLVM_CXXFLAGS=`llvm-config --cppflags core jit native`
LLVM_LDFLAGS=`llvm-config --ldflags --libs core jit native`
-COMMON_FLAGS=-Wextra -Wno-unused-parameter
+COMMON_FLAGS=-fPIC
+COMMON_FLAGS+=-Wextra -Wno-unused-parameter
COMMON_FLAGS+=-O0 -g
#COMMON_FLAGS+=-O2 -march=nocona -fomit-frame-pointer
CFLAGS=$(COMMON_FLAGS) -std=c99
-CXXFLAGS=$(COMMON_FLAGS) $(LLVM_CXXFLAGS)
-LDFLAGS=$(LLVM_LDFLAGS) -lm
+CXXFLAGS=$(COMMON_FLAGS) -ansi
+LDFLAGS=-rdynamic -lm -ldl
all: builddir build/tuplr
mkdir -p build
@@ -20,18 +21,20 @@ OBJECTS = \
build/constrain.o \
build/cps.o \
build/gc.o \
- build/tuplr_gc.so \
build/lex.o \
- build/tuplr_llvm.so \
build/parse.o \
build/pprint.o \
build/repl.o \
build/tlsf.o \
build/tuplr.o \
+ build/tuplr_llvm.o \
build/unify.o
-build/tuplr: $(OBJECTS)
- g++ -o $@ $^ $(LDFLAGS)
+LIBS = \
+ build/tuplr_gc.so
+
+build/tuplr: $(OBJECTS) $(LIBS)
+ g++ -o $@ $(OBJECTS) $(LDFLAGS) $(LLVM_LDFLAGS)
build/%.o: src/%.cpp src/tuplr.hpp
g++ $(CXXFLAGS) -o $@ -c $<
@@ -39,8 +42,11 @@ build/%.o: src/%.cpp src/tuplr.hpp
build/tlsf.o: src/tlsf.c src/tlsf.h
gcc $(CFLAGS) -o $@ -c $<
+build/tuplr_llvm.o: src/tuplr_llvm.cpp src/tuplr.hpp
+ g++ -c $(CXXFLAGS) $(LLVM_CXXFLAGS) -o $@ src/tuplr_llvm.cpp
+
build/%.so: src/%.cpp src/tuplr.hpp
- g++ -fPIC -dPIC -shared $(CXXFLAGS) -o $@ $<
+ g++ -shared $(CXXFLAGS) -o $@ $^
clean:
rm -rf build
diff --git a/src/compile.cpp b/src/compile.cpp
index 8c83e15..addad2b 100644
--- a/src/compile.cpp
+++ b/src/compile.cpp
@@ -27,6 +27,14 @@
using namespace std;
+#define COMPILE_LITERAL(CT) \
+template<> CValue ALiteral<CT>::compile(CEnv& cenv) { \
+ return cenv.engine()->compileLiteral(cenv, this); \
+}
+COMPILE_LITERAL(int32_t);
+COMPILE_LITERAL(float);
+COMPILE_LITERAL(bool);
+
CValue
ASymbol::compile(CEnv& cenv)
{
diff --git a/src/tuplr.cpp b/src/tuplr.cpp
index f8cc246..481885c 100644
--- a/src/tuplr.cpp
+++ b/src/tuplr.cpp
@@ -48,16 +48,7 @@ print_usage(char* name, bool error)
int
main(int argc, char** argv)
{
- PEnv penv;
- TEnv tenv(penv);
- initLang(penv, tenv);
-
- Engine* engine = tuplr_new_engine();
- CEnv* cenv = new CEnv(penv, tenv, engine);
-
- cenv->push();
- Object::pool.lock();
-
+ // Read command line arguments
map<string,string> args;
list<string> files;
for (int i = 1; i < argc; ++i) {
@@ -78,17 +69,35 @@ main(int argc, char** argv)
}
}
+ PEnv penv;
+ TEnv tenv(penv);
+ initLang(penv, tenv);
+
+ Engine* engine = NULL;
+
+ map<string,string>::const_iterator a = args.find("-b");
+ const string backend_name = (a != args.end() ? a->second : "llvm");
+
+ if (backend_name == "llvm")
+ engine = tuplr_new_llvm_engine();
+
+ if (!engine) {
+ std::cerr << "Unable to open backend " << backend_name << std::endl;
+ return 1;
+ }
+
+ CEnv* cenv = new CEnv(penv, tenv, engine);
cenv->args = args;
+ cenv->push();
+
+ Object::pool.lock();
int ret = 0;
- string output;
- map<string,string>::const_iterator a = args.find("-o");
- if (a != args.end())
- output = a->second;
+ a = args.find("-o");
+ const string output = (a != args.end()) ? a->second : "";
- a = args.find("-p");
- if (a != args.end()) {
+ if (args.find("-p") != args.end()) {
ifstream is(files.front().c_str());
if (is.good()) {
Cursor loc;
@@ -131,7 +140,7 @@ main(int argc, char** argv)
}
delete cenv;
- tuplr_free_engine(engine);
+ delete engine;
return ret;
}
diff --git a/src/tuplr.hpp b/src/tuplr.hpp
index 925deec..c3c30c4 100644
--- a/src/tuplr.hpp
+++ b/src/tuplr.hpp
@@ -621,7 +621,7 @@ Subst unify(const Constraints& c);
* Code Generation *
***************************************************************************/
-/// Compiler back-end
+/// Compiler backend
struct Engine {
virtual CFunction startFunction(CEnv& cenv, const std::string& name,
const AType* retT, const ATuple& argsT,
@@ -630,6 +630,7 @@ struct Engine {
virtual void finishFunction(CEnv& cenv, CFunction f, const AType* retT, CValue ret) = 0;
virtual void eraseFunction(CEnv& cenv, CFunction f) = 0;
virtual void liftCall(CEnv& cenv, AFn* fn, const AType& argsT) = 0;
+ virtual CValue compileLiteral(CEnv& cenv, AST* lit) = 0;
virtual CValue compileCall(CEnv& cenv, CFunction f, const vector<CValue>& args) = 0;
virtual CValue compilePrimitive(CEnv& cenv, APrimitive* prim) = 0;
virtual CValue compileIf(CEnv& cenv, AIf* aif) = 0;
@@ -638,10 +639,7 @@ struct Engine {
virtual const string call(CEnv& cenv, CFunction f, AType* retT) = 0;
};
-extern "C" {
- Engine* tuplr_new_engine();
- void tuplr_free_engine(Engine* engine);
-}
+Engine* tuplr_new_llvm_engine();
/// Compile-Time Environment
struct CEnv {
diff --git a/src/tuplr_llvm.cpp b/src/tuplr_llvm.cpp
index dfd4c9d..e2f7f1a 100644
--- a/src/tuplr_llvm.cpp
+++ b/src/tuplr_llvm.cpp
@@ -43,12 +43,6 @@ using namespace llvm;
using namespace std;
using boost::format;
-// Backend shared library interface
-extern "C" {
- Engine* tuplr_new_engine();
- void tuplr_free_engine(Engine* engine);
-}
-
static inline Value* llVal(CValue v) { return static_cast<Value*>(v); }
static inline Function* llFunc(CFunction f) { return static_cast<Function*>(f); }
@@ -166,6 +160,8 @@ struct LLVMEngine : public Engine {
}
void liftCall(CEnv& cenv, AFn* fn, const AType& argsT);
+
+ CValue compileLiteral(CEnv& cenv, AST* lit);
CValue compilePrimitive(CEnv& cenv, APrimitive* prim);
CValue compileIf(CEnv& cenv, AIf* aif);
@@ -200,36 +196,33 @@ struct LLVMEngine : public Engine {
FunctionPassManager opt;
};
-extern "C" {
-
-/// Create a new Engine (shared library entry point)
Engine*
-tuplr_new_engine()
+tuplr_new_llvm_engine()
{
return new LLVMEngine();
}
-/// Free an Engine (shared library entry point)
-void
-tuplr_free_engine(Engine* engine)
-{
- delete (LLVMEngine*)engine;
-}
-
-}
-
-
/***************************************************************************
* Code Generation *
***************************************************************************/
-#define COMPILE_LITERAL(CT, COMPILED) \
-template<> CValue ALiteral<CT>::compile(CEnv& cenv) { return (COMPILED); }
+CValue
+LLVMEngine::compileLiteral(CEnv& cenv, AST* lit)
+{
+ ALiteral<int32_t>* ilit = dynamic_cast<ALiteral<int32_t>*>(lit);
+ if (ilit)
+ return ConstantInt::get(Type::Int32Ty, ilit->val, true);
+
+ ALiteral<float>* flit = dynamic_cast<ALiteral<float>*>(lit);
+ if (flit)
+ return ConstantFP::get(Type::FloatTy, flit->val);
-// Literal template instantiations
-COMPILE_LITERAL(int32_t, ConstantInt::get(Type::Int32Ty, val, true))
-COMPILE_LITERAL(float, ConstantFP::get(Type::FloatTy, val))
-COMPILE_LITERAL(bool, ConstantInt::get(Type::Int1Ty, val, false))
+ ALiteral<bool>* blit = dynamic_cast<ALiteral<bool>*>(lit);
+ if (blit)
+ return ConstantFP::get(Type::FloatTy, blit->val);
+
+ throw Error(lit->loc, "Unknown literal type");
+}
void
LLVMEngine::liftCall(CEnv& cenv, AFn* fn, const AType& argsT)