aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/c.cpp4
-rw-r--r--src/compile.cpp20
-rw-r--r--src/llvm.cpp50
-rw-r--r--src/resp.hpp9
4 files changed, 47 insertions, 36 deletions
diff --git a/src/c.cpp b/src/c.cpp
index 4e71eae..afe1132 100644
--- a/src/c.cpp
+++ b/src/c.cpp
@@ -164,6 +164,10 @@ struct CEngine : public Engine {
CVal compileGlobal(CEnv& cenv, const AType* type, const string& sym, CVal val);
CVal compileGlobalGet(CEnv& cenv, const string& sym, CVal val);
+ IfState compileIfStart(CEnv& cenv) { return NULL; }
+ void compileIfBranch(CEnv& cenv, IfState state, CVal condV, const AST* then) {}
+ CVal compileIfEnd(CEnv& cenv, IfState state, CVal elseV, const AType* type) { return NULL; }
+
void writeModule(CEnv& cenv, std::ostream& os) {
os << out;
}
diff --git a/src/compile.cpp b/src/compile.cpp
index 65721fc..4d8e98d 100644
--- a/src/compile.cpp
+++ b/src/compile.cpp
@@ -133,6 +133,24 @@ compile_dot(CEnv& cenv, const ATuple* dot) throw()
return cenv.engine()->compileDot(cenv, tupVal, index->val);
}
+static CVal
+compile_if(CEnv& cenv, const ATuple* aif) throw()
+{
+ IfState state = cenv.engine()->compileIfStart(cenv);
+ for (ATuple::const_iterator i = aif->iter_at(1); ; ++i) {
+ ATuple::const_iterator next = i;
+ if (++next == aif->end())
+ break;
+
+ cenv.engine()->compileIfBranch(cenv, state, resp_compile(cenv, *i), *next);
+
+ i = next; // jump 2 each iteration (to the next predicate)
+ }
+
+ CVal elseV = resp_compile(cenv, aif->list_last());
+ return cenv.engine()->compileIfEnd(cenv, state, elseV, cenv.type(aif));
+}
+
CVal
resp_compile(CEnv& cenv, const AST* ast) throw()
{
@@ -161,7 +179,7 @@ resp_compile(CEnv& cenv, const AST* ast) throw()
else if (form == "def")
return compile_def(cenv, call);
else if (form == "if")
- return cenv.engine()->compileIf(cenv, call);
+ return compile_if(cenv, call);
else if (form == "cons" || isupper(form[0]))
return compile_cons(cenv, call);
else if (form == ".")
diff --git a/src/llvm.cpp b/src/llvm.cpp
index e7c8524..c7d03a8 100644
--- a/src/llvm.cpp
+++ b/src/llvm.cpp
@@ -213,21 +213,21 @@ struct LLVMEngine : public Engine {
typedef pair<Value*, BasicBlock*> IfBranch;
typedef vector<IfBranch> IfBranches;
- struct IfState {
- IfState(BasicBlock* m, Function* p) : mergeBB(m), parent(p) {}
+ struct LLVMIfState {
+ LLVMIfState(BasicBlock* m, Function* p) : mergeBB(m), parent(p) {}
BasicBlock* mergeBB;
Function* parent;
IfBranches branches;
};
- IfState*
+ IfState
compileIfStart(CEnv& cenv);
void
- compileIfBranch(CEnv& cenv, IfState* state, CVal condV, const AST* then);
+ compileIfBranch(CEnv& cenv, IfState state, CVal condV, const AST* then);
CVal
- compileIfEnd(CEnv& cenv, IfState* state, CVal elseV, const AType* type);
+ compileIfEnd(CEnv& cenv, IfState state, CVal elseV, const AType* type);
void writeModule(CEnv& cenv, std::ostream& os) {
AssemblyAnnotationWriter writer;
@@ -371,20 +371,21 @@ LLVMEngine::pushFunctionArgs(CEnv& cenv, const ATuple* prot, const AType* type,
}
}
-LLVMEngine::IfState*
+IfState
LLVMEngine::compileIfStart(CEnv& cenv)
{
LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine());
- return new IfState(BasicBlock::Create(context, "endif"),
- engine->builder.GetInsertBlock()->getParent());
+ return new LLVMIfState(BasicBlock::Create(context, "endif"),
+ engine->builder.GetInsertBlock()->getParent());
}
void
-LLVMEngine::compileIfBranch(CEnv& cenv, IfState* state, CVal condV, const AST* then)
+LLVMEngine::compileIfBranch(CEnv& cenv, IfState s, CVal condV, const AST* then)
{
- LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine());
- BasicBlock* thenBB = BasicBlock::Create(context, (format("then%1%") % labelIndex).str());
- BasicBlock* nextBB = BasicBlock::Create(context, (format("else%1%") % labelIndex).str());
+ LLVMIfState* state = (LLVMIfState*)s;
+ LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine());
+ BasicBlock* thenBB = BasicBlock::Create(context, (format("then%1%") % labelIndex).str());
+ BasicBlock* nextBB = BasicBlock::Create(context, (format("else%1%") % labelIndex).str());
++labelIndex;
@@ -400,9 +401,10 @@ LLVMEngine::compileIfBranch(CEnv& cenv, IfState* state, CVal condV, const AST* t
}
CVal
-LLVMEngine::compileIfEnd(CEnv& cenv, IfState* state, CVal elseV, const AType* type)
+LLVMEngine::compileIfEnd(CEnv& cenv, IfState s, CVal elseV, const AType* type)
{
- LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine());
+ LLVMIfState* state = (LLVMIfState*)s;
+ LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine());
// Emit end of final else block
engine->builder.CreateBr(state->mergeBB);
@@ -418,28 +420,10 @@ LLVMEngine::compileIfEnd(CEnv& cenv, IfState* state, CVal elseV, const AType* ty
}
CVal
-LLVMEngine::compileIf(CEnv& cenv, const ATuple* aif)
-{
- IfState* state = compileIfStart(cenv);
- for (ATuple::const_iterator i = aif->iter_at(1); ; ++i) {
- ATuple::const_iterator next = i;
- if (++next == aif->end())
- break;
-
- compileIfBranch(cenv, state, resp_compile(cenv, *i), *next);
-
- i = next; // jump 2 each iteration (to the next predicate)
- }
-
- CVal elseV = resp_compile(cenv, aif->list_last());
- return compileIfEnd(cenv, state, elseV, cenv.type(aif));
-}
-
-CVal
LLVMEngine::compileMatch(CEnv& cenv, const ATuple* match)
{
LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine());
- IfState* state = compileIfStart(cenv);
+ IfState state = compileIfStart(cenv);
Value* matchee = llVal(resp_compile(cenv, match->list_ref(1)));
Value* rttiPtr = builder.CreateStructGEP(matchee, 0, "matchRTTIPtr");
Value* rtti = builder.CreateLoad(rttiPtr, 0, "matchRTTI");
diff --git a/src/resp.hpp b/src/resp.hpp
index 593205d..7dc9f16 100644
--- a/src/resp.hpp
+++ b/src/resp.hpp
@@ -694,6 +694,8 @@ Subst unify(const Constraints& c);
* Code Generation *
***************************************************************************/
+typedef void* IfState;
+
/// Compiler backend
struct Engine {
virtual ~Engine() {}
@@ -719,11 +721,14 @@ struct Engine {
virtual CVal compileString(CEnv& cenv, const char* str) = 0;
virtual CVal compileCall(CEnv& cenv, CFunc f, const AType* fT, ValVec& args) = 0;
virtual CVal compilePrimitive(CEnv& cenv, const ATuple* prim) = 0;
- virtual CVal compileIf(CEnv& cenv, const ATuple* aif) = 0;
virtual CVal compileMatch(CEnv& cenv, const ATuple* match) = 0;
virtual CVal compileGlobal(CEnv& cenv, const AType* t, const string& sym, CVal val) = 0;
virtual CVal compileGlobalGet(CEnv& cenv, const string& sym, CVal val) = 0;
-
+
+ virtual IfState compileIfStart(CEnv& cenv) = 0;
+ virtual void compileIfBranch(CEnv& cenv, IfState state, CVal condV, const AST* then) = 0;
+ virtual CVal compileIfEnd(CEnv& cenv, IfState state, CVal elseV, const AType* type) = 0;
+
virtual void writeModule(CEnv& cenv, std::ostream& os) = 0;
virtual const string call(CEnv& cenv, CFunc f, const AType* retT) = 0;