diff options
author | David Robillard <d@drobilla.net> | 2010-12-08 19:07:09 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-12-08 19:07:09 +0000 |
commit | d02fe43f0f6e50f8f22321aa0080283ee2ecc9fc (patch) | |
tree | 2a2007137d19221a541e97764dc3adef054f6581 /src | |
parent | 583a2d9d2397ff174b16d7df377f16c1df6fe875 (diff) | |
download | resp-d02fe43f0f6e50f8f22321aa0080283ee2ecc9fc.tar.gz resp-d02fe43f0f6e50f8f22321aa0080283ee2ecc9fc.tar.bz2 resp-d02fe43f0f6e50f8f22321aa0080283ee2ecc9fc.zip |
Clean up function compilation stuff.
Add some utilities to for using named types.
git-svn-id: http://svn.drobilla.net/resp/resp@313 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src')
-rw-r--r-- | src/c.cpp | 13 | ||||
-rw-r--r-- | src/compile.cpp | 19 | ||||
-rw-r--r-- | src/constrain.cpp | 2 | ||||
-rw-r--r-- | src/llvm.cpp | 28 | ||||
-rw-r--r-- | src/repl.cpp | 4 | ||||
-rw-r--r-- | src/resp.hpp | 26 |
6 files changed, 52 insertions, 40 deletions
@@ -100,7 +100,7 @@ struct CEngine : public Engine { } CFunc startFunction(CEnv& cenv, - const std::string& name, const ATuple* args, const AType* type) + const std::string& name, const ATuple* args, const AType* type) { const AType* argsT = type->prot()->as_type(); const AType* retT = type->list_ref(2)->as_type(); @@ -130,10 +130,11 @@ struct CEngine : public Engine { f->text += ")\n{\n"; out += f->text; + return f; } - void pushFunctionArgs(CEnv& cenv, const ATuple* fn, const AType* type, CFunc f); + void pushFunctionArgs(CEnv& cenv, const ATuple* prot, const AType* type, CFunc f); void finishFunction(CEnv& cenv, CFunc f, CVal ret) { out += "return " + *(Value*)ret + ";\n}\n\n"; @@ -210,7 +211,7 @@ CEngine::compileString(CEnv& cenv, const char* str) } void -CEngine::pushFunctionArgs(CEnv& cenv, const ATuple* fn, const AType* type, CFunc f) +CEngine::pushFunctionArgs(CEnv& cenv, const ATuple* prot, const AType* type, CFunc f) { cenv.push(); @@ -218,12 +219,12 @@ CEngine::pushFunctionArgs(CEnv& cenv, const ATuple* fn, const AType* type, CFunc // Bind argument values in CEnv vector<Value*> args; - ATuple::const_iterator p = fn->prot()->begin(); + ATuple::const_iterator p = prot->begin(); ATuple::const_iterator pT = argsT->begin(); - for (; p != fn->prot()->end(); ++p, ++pT) { + for (; p != prot->end(); ++p, ++pT) { const AType* t = (*pT)->as_type(); const Type* lt = llType(t); - THROW_IF(!lt, fn->loc, "untyped parameter\n"); + THROW_IF(!lt, (*p)->loc, "untyped parameter\n"); cenv.def((*p)->as_symbol(), *p, t, new string((*p)->str())); } } diff --git a/src/compile.cpp b/src/compile.cpp index 282a7f0..647c7d5 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -36,17 +36,16 @@ compile_symbol(CEnv& cenv, const ASymbol* sym) throw() static CVal compile_fn(CEnv& cenv, const ATuple* fn) throw() { + assert(!cenv.currentFn); + const AType* type = cenv.type(fn); CFunc f = cenv.findImpl(fn, type); if (f) return f; - - // Write function declaration - f = cenv.engine()->startFunction(cenv, cenv.name(fn), fn->prot(), type); - // Create a new environment frame and bind argument values - cenv.engine()->pushFunctionArgs(cenv, fn, type, f); - assert(!cenv.currentFn); + // Write function declaration and push stack frame + f = cenv.engine()->startFunction(cenv, cenv.name(fn), fn->prot(), type); + cenv.engine()->pushFunctionArgs(cenv, fn->prot(), type, f); cenv.currentFn = f; // Write function body @@ -54,11 +53,9 @@ compile_fn(CEnv& cenv, const ATuple* fn) throw() for (ATuple::const_iterator i = fn->iter_at(2); i != fn->end(); ++i) retVal = resp_compile(cenv, *i); - // Write function conclusion + // Write function conclusion and pop stack frame cenv.engine()->finishFunction(cenv, f, retVal); - - // Pop environment frame - cenv.pop(); + cenv.pop(); cenv.currentFn = NULL; cenv.vals.def(cenv.penv.sym(cenv.name(fn)), f); @@ -84,7 +81,7 @@ compile_type(CEnv& cenv, const AType* type) throw() static CVal compile_call(CEnv& cenv, const ATuple* call) throw() { - CFunc f = resp_compile(cenv, *call->begin()); + CFunc f = resp_compile(cenv, call->head()); if (!f) f = cenv.currentFn; // Recursive call (callee defined as a stub) diff --git a/src/constrain.cpp b/src/constrain.cpp index 3aee45a..e97bcc3 100644 --- a/src/constrain.cpp +++ b/src/constrain.cpp @@ -225,7 +225,7 @@ constrain_dot(TEnv& tenv, Constraints& c, const ATuple* call) throw(Error) for (int i = 0; i < idx->val; ++i) objT.push_back(tenv.var()); objT.push_back(retT); - objT.push_back(new AType(obj->loc, AType::DOTS)); + objT.push_back(tenv.Dots); c.constrain(tenv, obj, objT); } diff --git a/src/llvm.cpp b/src/llvm.cpp index 0dfbc69..32aedf7 100644 --- a/src/llvm.cpp +++ b/src/llvm.cpp @@ -124,12 +124,15 @@ struct LLVMEngine : public Engine { } return PointerType::get(StructType::get(context, ctypes, false), 0); + } else if (t->kind == AType::NAME) { + assert(false); } + assert(false); return PointerType::get(Type::getInt8Ty(context), NULL); } - CFunc startFunction(CEnv& cenv, - const std::string& name, const ATuple* args, const AType* type) + CFunc startFunction( + CEnv& cenv, const std::string& name, const ATuple* args, const AType* type) { const AType* argsT = type->prot()->as_type(); const AType* retT = type->list_last()->as_type(); @@ -166,7 +169,7 @@ struct LLVMEngine : public Engine { return f; } - void pushFunctionArgs(CEnv& cenv, const ATuple* fn, const AType* type, CFunc f); + void pushFunctionArgs(CEnv& cenv, const ATuple* prot, const AType* type, CFunc f); void appendBlock(LLVMEngine* engine, Function* function, BasicBlock* block) { function->getBasicBlockList().push_back(block); @@ -349,22 +352,21 @@ LLVMEngine::compileString(CEnv& cenv, const char* str) } void -LLVMEngine::pushFunctionArgs(CEnv& cenv, const ATuple* fn, const AType* type, CFunc f) +LLVMEngine::pushFunctionArgs(CEnv& cenv, const ATuple* prot, const AType* type, CFunc cfunc) { cenv.push(); const AType* argsT = type->prot()->as_type(); - + Function* f = llFunc(cfunc); + // Bind argument values in CEnv - vector<Value*> args; - ATuple::const_iterator p = fn->prot()->begin(); + ATuple::const_iterator p = prot->begin(); ATuple::const_iterator pT = argsT->begin(); - assert(fn->prot()->size() == argsT->size()); - assert(fn->prot()->size() == f->num_args()); - for (Function::arg_iterator a = llFunc(f)->arg_begin(); a != llFunc(f)->arg_end(); ++a, ++p, ++pT) { - const AType* t = (*pT)->as_type(); - const Type* lt = llType(t); - THROW_IF(!lt, fn->loc, "untyped parameter\n"); + assert(prot->size() == argsT->size()); + assert(prot->size() == f->num_args()); + for (Function::arg_iterator a = f->arg_begin(); a != f->arg_end(); ++a, ++p, ++pT) { + const AType* t = cenv.resolveType((*pT)->as_type()); + THROW_IF(!llType(t), (*p)->loc, "untyped parameter\n"); cenv.def((*p)->as_symbol(), *p, t, &*a); } } diff --git a/src/repl.cpp b/src/repl.cpp index 965e202..247799b 100644 --- a/src/repl.cpp +++ b/src/repl.cpp @@ -57,7 +57,7 @@ readParseType(CEnv& cenv, Cursor& cursor, istream& is, AST*& exp, const AST*& as //cout << "(SUBST " << endl << subst << ")" << endl; //cout << "(TSUBST " << endl << cenv.tsubst << ")" << endl; - //cenv.tsubst = Subst::compose(cenv.tsubst, subst); + cenv.tsubst = Subst::compose(cenv.tsubst, subst); // FIXME: breaks polymorphism + repl Object::pool.addRoot(ast); // Make parsed expression a GC root so it is not deleted @@ -133,7 +133,7 @@ eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute) // Create function for top-level of program f = cenv.engine()->startFunction(cenv, "main", new ATuple(cursor), fnT); - + // Compile expressions (other than function definitions) into it for (Code::const_iterator i = exprs.begin(); i != exprs.end(); ++i) val = resp_compile(cenv, *i); diff --git a/src/resp.hpp b/src/resp.hpp index 3cccd30..7c88be4 100644 --- a/src/resp.hpp +++ b/src/resp.hpp @@ -647,6 +647,8 @@ struct TEnv : public Env<const ASymbol*, const AType*> { TEnv(PEnv& p) : penv(p) , varID(1) + , Closure(new AType(penv.sym("Closure"), AType::NAME)) + , Dots(new AType(Cursor(), AType::DOTS)) , Fn(new AType(penv.sym("Fn"), AType::PRIM)) , Tup(new AType(penv.sym("Tup"), AType::NAME)) , U(new AType(penv.sym("U"), AType::PRIM)) @@ -678,6 +680,8 @@ struct TEnv : public Env<const ASymbol*, const AType*> { PEnv& penv; unsigned varID; + AType* Closure; + AType* Dots; AType* Fn; AType* Tup; AType* U; @@ -701,9 +705,9 @@ struct Engine { const std::string& name, const ATuple* args, const AType* type) = 0; - - virtual void pushFunctionArgs(CEnv& cenv, const ATuple* fn, const AType* type, CFunc f) = 0; - + + virtual void pushFunctionArgs(CEnv& cenv, const ATuple* prot, const AType* type, CFunc f) = 0; + virtual void finishFunction(CEnv& cenv, CFunc f, CVal ret) = 0; virtual void eraseFunction(CEnv& cenv, CFunc f) = 0; virtual CVal compileCons(CEnv& cenv, const AType* t, CVal rtti, ValVec& f) = 0; @@ -742,7 +746,12 @@ struct CEnv { if (type(ast)) Object::pool.addRoot(type(ast)); } - const AType* type(const AST* ast, const Subst& subst = Subst()) const { + const AType* resolveType(const AType* type) const { + if (type->kind == AType::NAME) + return tenv.named(type->head()->to_symbol()->cppstr); + return type; + } + const AType* type(const AST* ast, const Subst& subst = Subst(), bool resolve=true) const { const AType* ret = NULL; const ASymbol* sym = ast->to_symbol(); if (sym) { @@ -753,8 +762,10 @@ struct CEnv { if (!ret) ret = tenv.vars[ast]; if (ret) - return tsubst.apply(subst.apply(ret))->to_type(); - return NULL; + ret = tsubst.apply(subst.apply(ret))->to_type(); + if (resolve && ret) + ret = this->resolveType(ret); + return ret; } void def(const ASymbol* sym, const AST* c, const AType* t, CVal v) { code.def(sym, c); @@ -766,7 +777,8 @@ struct CEnv { const AST** rec = code.ref(sym); return rec ? *rec : ast; } - void setType(AST* ast, const AType* type) { + void setType(const AST* ast, const AType* type) { + assert(!ast->to_symbol()); const AType* tvar = tenv.var(); tenv.vars.insert(make_pair(ast, tvar)); tsubst.add(tvar, type); |