aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/c.cpp13
-rw-r--r--src/compile.cpp19
-rw-r--r--src/constrain.cpp2
-rw-r--r--src/llvm.cpp28
-rw-r--r--src/repl.cpp4
-rw-r--r--src/resp.hpp26
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);