aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-06-27 01:12:25 +0000
committerDavid Robillard <d@drobilla.net>2009-06-27 01:12:25 +0000
commitf81807ae192fa9b54320da69b59c063e505e94e1 (patch)
treeeb12822d7f4687c6d26b513b43d334320ce4f805
parent9ba1ca23fb217c747117c5bbff3fcaac98f5f261 (diff)
downloadresp-f81807ae192fa9b54320da69b59c063e505e94e1.tar.gz
resp-f81807ae192fa9b54320da69b59c063e505e94e1.tar.bz2
resp-f81807ae192fa9b54320da69b59c063e505e94e1.zip
Add nothing type.
Only actually compile down to LLVM if main program is typed. git-svn-id: http://svn.drobilla.net/resp/tuplr@152 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r--cps.cpp6
-rw-r--r--llvm.cpp21
-rw-r--r--tuplr.cpp30
-rw-r--r--tuplr.hpp8
4 files changed, 37 insertions, 28 deletions
diff --git a/cps.cpp b/cps.cpp
index 3d79b9d..8df11c2 100644
--- a/cps.cpp
+++ b/cps.cpp
@@ -63,7 +63,6 @@ ACall::cps(TEnv& tenv, AST* cont)
// Each makes a tail call to the next, and the last makes a tail
// call to the continuation of this call
ssize_t firstFn = -1;
- ssize_t lastFn = -1;
for (size_t i = 0; i < size(); ++i) {
if (!at(i)->to<ATuple*>()) {
funcs.push_back(make_pair((AFn*)NULL, at(i)));
@@ -77,12 +76,11 @@ ACall::cps(TEnv& tenv, AST* cont)
tup<ATuple>(at(i)->loc, arg, 0),
0);
- if (lastFn != -1)
- fn->push_back(at(lastFn)->cps(tenv, thisFn));
+ if (fn)
+ fn->push_back(at(i)->cps(tenv, thisFn));
funcs.push_back(make_pair(thisFn, arg));
fn = thisFn;
- lastFn = i;
}
}
diff --git a/llvm.cpp b/llvm.cpp
index fc369b8..e963336 100644
--- a/llvm.cpp
+++ b/llvm.cpp
@@ -42,9 +42,10 @@ static const Type*
llType(const AType* t)
{
if (t->kind == AType::PRIM) {
- if (t->at(0)->str() == "Bool") return Type::Int1Ty;
- if (t->at(0)->str() == "Int") return Type::Int32Ty;
- if (t->at(0)->str() == "Float") return Type::FloatTy;
+ if (t->at(0)->str() == "Nothing") return Type::VoidTy;
+ if (t->at(0)->str() == "Bool") return Type::Int1Ty;
+ if (t->at(0)->str() == "Int") return Type::Int32Ty;
+ if (t->at(0)->str() == "Float") return Type::FloatTy;
throw Error(t->loc, string("Unknown primitive type `") + t->str() + "'");
}
return NULL; // non-primitive type
@@ -113,9 +114,13 @@ struct LLVMEngine : public Engine {
return f;
}
- void finishFunction(CEnv& cenv, CFunction f, CValue ret) {
- Value* retVal = llVal(ret);
- builder.CreateRet(retVal);
+ void finishFunction(CEnv& cenv, CFunction f, const AType* retT, CValue ret) {
+ if (retT->concrete()) {
+ Value* retVal = llVal(ret);
+ builder.CreateRet(retVal);
+ } else {
+ builder.CreateRetVoid();
+ }
verifyFunction(*static_cast<Function*>(f));
if (cenv.args.find("-g") == cenv.args.end())
@@ -240,7 +245,7 @@ AFn::liftCall(CEnv& cenv, const AType& argsT)
thisType = argsSubst.apply(thisType)->as<AType*>();
if (!thisType->concrete())
throw Error(loc, string("unable to resolve concrete type for function :: ")
- + thisType->str());
+ + thisType->str() + "\n" + this->str());
}
Object::pool.addRoot(thisType);
@@ -326,7 +331,7 @@ AFn::liftCall(CEnv& cenv, const AType& argsT)
CValue retVal = NULL;
for (size_t i = 2; i < size(); ++i)
retVal = cenv.compile(at(i));
- cenv.engine()->finishFunction(cenv, f, retVal);
+ cenv.engine()->finishFunction(cenv, f, cenv.type(at(size()-1)), retVal);
} catch (Error& e) {
f->eraseFromParent(); // Error reading body, remove function
cenv.pop();
diff --git a/tuplr.cpp b/tuplr.cpp
index c49cdf8..dd4681f 100644
--- a/tuplr.cpp
+++ b/tuplr.cpp
@@ -191,9 +191,10 @@ void
initLang(PEnv& penv, TEnv& tenv)
{
// Types
- tenv.def(penv.sym("Bool"), make_pair((AST*)NULL, new AType(penv.sym("Bool"))));
- tenv.def(penv.sym("Int"), make_pair((AST*)NULL, new AType(penv.sym("Int"))));
- tenv.def(penv.sym("Float"), make_pair((AST*)NULL, new AType(penv.sym("Float"))));
+ tenv.def(penv.sym("Nothing"), make_pair((AST*)0, new AType(penv.sym("Nothing"))));
+ tenv.def(penv.sym("Bool"), make_pair((AST*)0, new AType(penv.sym("Bool"))));
+ tenv.def(penv.sym("Int"), make_pair((AST*)0, new AType(penv.sym("Int"))));
+ tenv.def(penv.sym("Float"), make_pair((AST*)0, new AType(penv.sym("Float"))));
// Literals
static bool trueVal = true;
@@ -263,9 +264,6 @@ eval(CEnv& cenv, const string& name, istream& is)
}
}
- // Create function for top-level of program
- CFunction f = cenv.engine()->startFunction(cenv, "main", resultType, ATuple(cursor));
-
// Print CPS form
CValue val = NULL;
/*for (list< pair<SExp, AST*> >::const_iterator i = exprs.begin(); i != exprs.end(); ++i) {
@@ -273,13 +271,21 @@ eval(CEnv& cenv, const string& name, istream& is)
pprint(cout, i->second->cps(cenv.tenv, cenv.penv.sym("cont")));
}*/
- // Compile all expressions into it
- for (list< pair<SExp, AST*> >::const_iterator i = exprs.begin(); i != exprs.end(); ++i)
- val = cenv.compile(i->second);
+ if (resultType->concrete()) {
+ // Create function for top-level of program
+ CFunction f = cenv.engine()->startFunction(cenv, "main", resultType, ATuple(cursor));
- cenv.engine()->finishFunction(cenv, f, val);
+ // Compile all expressions into it
+ for (list< pair<SExp, AST*> >::const_iterator i = exprs.begin(); i != exprs.end(); ++i)
+ val = cenv.compile(i->second);
- cenv.out << cenv.engine()->call(cenv, f, resultType) << " : " << resultType << endl;
+ // Finish and call it
+ cenv.engine()->finishFunction(cenv, f, resultType, val);
+ cenv.out << cenv.engine()->call(cenv, f, resultType) << " : " << resultType << endl;
+ } else {
+ // Non-concrete body type, just report type
+ cenv.out << " : " << resultType << endl;
+ }
Object::pool.collect(Object::pool.roots());
@@ -323,7 +329,7 @@ repl(CEnv& cenv)
// Create anonymous function to insert code into
f = cenv.engine()->startFunction(cenv, cenv.penv.gensymstr("_repl"), bodyT, ATuple(cursor));
CValue retVal = cenv.compile(body);
- cenv.engine()->finishFunction(cenv, f, retVal);
+ cenv.engine()->finishFunction(cenv, f, bodyT, retVal);
cenv.out << cenv.engine()->call(cenv, f, bodyT);
} catch (Error& e) {
ADef* def = body->to<ADef*>();
diff --git a/tuplr.hpp b/tuplr.hpp
index 37a09db..69f6bfd 100644
--- a/tuplr.hpp
+++ b/tuplr.hpp
@@ -297,7 +297,7 @@ struct AType : public ATuple {
bool concrete() const {
switch (kind) {
case VAR: return false;
- case PRIM: return true;
+ case PRIM: return at(0)->str() != "Nothing";
case EXPR:
FOREACH(const_iterator, t, *this) {
AType* kid = (*t)->to<AType*>();
@@ -576,9 +576,9 @@ struct Engine {
const AType* retT, const ATuple& argsT,
const vector<string> argNames=vector<string>()) = 0;
- virtual void finishFunction(CEnv& cenv, CFunction f, CValue ret) = 0;
- virtual void eraseFunction(CEnv& cenv, CFunction f) = 0;
- virtual void writeModule(CEnv& cenv, std::ostream& os) = 0;
+ virtual void finishFunction(CEnv& cenv, CFunction f, const AType* retT, CValue ret) = 0;
+ virtual void eraseFunction(CEnv& cenv, CFunction f) = 0;
+ virtual void writeModule(CEnv& cenv, std::ostream& os) = 0;
virtual const string call(CEnv& cenv, CFunction f, AType* retT) = 0;
};