diff options
author | David Robillard <d@drobilla.net> | 2009-06-27 01:12:25 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-06-27 01:12:25 +0000 |
commit | f81807ae192fa9b54320da69b59c063e505e94e1 (patch) | |
tree | eb12822d7f4687c6d26b513b43d334320ce4f805 | |
parent | 9ba1ca23fb217c747117c5bbff3fcaac98f5f261 (diff) | |
download | resp-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.cpp | 6 | ||||
-rw-r--r-- | llvm.cpp | 21 | ||||
-rw-r--r-- | tuplr.cpp | 30 | ||||
-rw-r--r-- | tuplr.hpp | 8 |
4 files changed, 37 insertions, 28 deletions
@@ -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; } } @@ -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(); @@ -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*>(); @@ -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; }; |