From d02fe43f0f6e50f8f22321aa0080283ee2ecc9fc Mon Sep 17 00:00:00 2001
From: David Robillard <d@drobilla.net>
Date: Wed, 8 Dec 2010 19:07:09 +0000
Subject: 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
---
 src/c.cpp         | 13 +++++++------
 src/compile.cpp   | 19 ++++++++-----------
 src/constrain.cpp |  2 +-
 src/llvm.cpp      | 28 +++++++++++++++-------------
 src/repl.cpp      |  4 ++--
 src/resp.hpp      | 26 +++++++++++++++++++-------
 6 files changed, 52 insertions(+), 40 deletions(-)

diff --git a/src/c.cpp b/src/c.cpp
index 51455e3..2373846 100644
--- a/src/c.cpp
+++ b/src/c.cpp
@@ -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);
-- 
cgit v1.2.1