From 8675beae4f7a8415fc2e88451da95dc068719194 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 13 Apr 2010 02:28:56 +0000 Subject: Restructure as a source translation based compiler. Implement support for closures (via lambda lifting phase). git-svn-id: http://svn.drobilla.net/resp/resp@254 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- src/repl.cpp | 109 +++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 76 insertions(+), 33 deletions(-) (limited to 'src/repl.cpp') diff --git a/src/repl.cpp b/src/repl.cpp index 9fa5781..92fb621 100644 --- a/src/repl.cpp +++ b/src/repl.cpp @@ -27,17 +27,18 @@ using namespace std; static bool -readParseTypeLift(CEnv& cenv, Cursor& cursor, istream& is, AST*& exp, AST*& ast, AType*& type) +readParseType(CEnv& cenv, Cursor& cursor, istream& is, AST*& exp, AST*& ast) { exp = readExpression(cursor, is); if (exp->to() && exp->to()->empty()) return false; ast = cenv.penv.parse(exp); // Parse input - Constraints c; + + Constraints c(cenv.tsubst); ast->constrain(cenv.tenv, c); // Constrain types - cenv.tsubst = Subst::compose(cenv.tsubst, unify(c)); // Solve type constraints + cenv.tsubst = unify(c); // Solve type constraints // Add types in type substition as GC roots for (Subst::iterator i = cenv.tsubst.begin(); i != cenv.tsubst.end(); ++i) { @@ -45,16 +46,11 @@ readParseTypeLift(CEnv& cenv, Cursor& cursor, istream& is, AST*& exp, AST*& ast, Object::pool.addRoot(i->second); } - type = cenv.type(ast); - THROW_IF(!type, cursor, "call to untyped body"); - - ast->lift(cenv); // Lift functions - return true; } static void -callPrintCollect(CEnv& cenv, CFunc f, AST* result, AType* resultT, bool execute) +callPrintCollect(CEnv& cenv, CFunc f, AST* result, const AType* resultT, bool execute) { if (execute) cenv.out << cenv.engine()->call(cenv, f, resultT); @@ -64,43 +60,86 @@ callPrintCollect(CEnv& cenv, CFunc f, AST* result, AType* resultT, bool execute) cenv.out << " : " << resultT << endl; Object::pool.collect(Object::pool.roots()); - - if (cenv.args.find("-d") != cenv.args.end()) - cenv.engine()->writeModule(cenv, cenv.out); } /// Compile and evaluate code from @a is int eval(CEnv& cenv, const string& name, istream& is, bool execute) { - AST* exp = NULL; - AST* ast = NULL; - AType* type = NULL; - list< pair > exprs; + AST* exp = NULL; + AST* ast = NULL; + list parsed; Cursor cursor(name); try { - while (readParseTypeLift(cenv, cursor, is, exp, ast, type)) - exprs.push_back(make_pair(exp, ast)); + while (readParseType(cenv, cursor, is, exp, ast)) + parsed.push_back(ast); - //for (list< pair >::const_iterator i = exprs.begin(); i != exprs.end(); ++i) + //for (list< pair >::const_iterator i = parsed.begin(); i != parsed.end(); ++i) // pprint(cout, i->second->cps(cenv.tenv, cenv.penv.sym("cont"))); CVal val = NULL; CFunc f = NULL; - if (type->concrete()) { - // Create function for top-level of program - f = cenv.engine()->startFunction(cenv, "main", type, ATuple(cursor)); - // Compile all expressions into it - for (list< pair >::const_iterator i = exprs.begin(); i != exprs.end(); ++i) - val = i->second->compile(cenv); + /* + // De-poly all expressions + Code concrete; + for (list::iterator i = parsed.begin(); i != parsed.end(); ++i) { + AST* c = (*i)->depoly(cenv, concrete); + if (c) + concrete.push_back(c); + } - // Finish compilation - cenv.engine()->finishFunction(cenv, f, type, val); + cout << endl << ";;;; CONCRETE {" << endl << endl; + for (Code::iterator i = concrete.begin(); i != concrete.end(); ++i) + cout << *i << endl << endl; + cout << ";;;; } CONCRETE" << endl << endl;*/ + + // Lift all expressions + Code lifted; + for (list::iterator i = parsed.begin(); i != parsed.end(); ++i) { + AST* l = (*i)->lift(cenv, lifted); + if (l) + lifted.push_back(l); + } + + if (cenv.args.find("-d") != cenv.args.end()) { + cout << endl << ";;;; LIFTED {" << endl << endl; + for (Code::iterator i = lifted.begin(); i != lifted.end(); ++i) { + cout << *i << endl; + ADef* def = (*i)->to(); + if (def) + std::cout << " :: " << cenv.type(def->body()) << std::endl; + cout << endl; + } + cout << ";;;; } LIFTED" << endl << endl; } + // Compile top-level (lifted) functions + Code exprs; + for (Code::iterator i = lifted.begin(); i != lifted.end(); ++i) { + ADef* def = (*i)->to(); + if (def && (*(def->begin() + 2))->to()) { + val = def->compile(cenv); + } else { + exprs.push_back(*i); + } + } + + const AType* type = cenv.type(exprs.back()); + + // Create function for top-level of program + f = cenv.engine()->startFunction(cenv, "main", type, ATuple(cursor)); + + // Compile expressions (other than function definitions) into it + for (list::const_iterator i = exprs.begin(); i != exprs.end(); ++i) + val = (*i)->compile(cenv); + + // Finish compilation + cenv.engine()->finishFunction(cenv, f, val); + // Call and print ast - callPrintCollect(cenv, f, ast, type, execute); + if (cenv.args.find("-S") == cenv.args.end()) + callPrintCollect(cenv, f, ast, type, execute); } catch (Error& e) { cenv.err << e.what() << endl; @@ -113,9 +152,8 @@ eval(CEnv& cenv, const string& name, istream& is, bool execute) int repl(CEnv& cenv) { - AST* exp = NULL; - AST* ast = NULL; - AType* type = NULL; + AST* exp = NULL; + AST* ast = NULL; const string replFnName = cenv.penv.gensymstr("_repl"); while (1) { cenv.out << "() "; @@ -123,15 +161,20 @@ repl(CEnv& cenv) Cursor cursor("(stdin)"); try { - if (!readParseTypeLift(cenv, cursor, std::cin, exp, ast, type)) + if (!readParseType(cenv, cursor, std::cin, exp, ast)) break; + Code lifted; + ast = ast->lift(cenv, lifted); + const AType* type = cenv.type(ast); CFunc f = NULL; try { // Create function for this repl loop f = cenv.engine()->startFunction(cenv, replFnName, type, ATuple(cursor)); - cenv.engine()->finishFunction(cenv, f, type, ast->compile(cenv)); + cenv.engine()->finishFunction(cenv, f, ast->compile(cenv)); callPrintCollect(cenv, f, ast, type, true); + if (cenv.args.find("-d") != cenv.args.end()) + cenv.engine()->writeModule(cenv, cenv.out); } catch (Error& e) { cenv.out << e.msg << endl; cenv.engine()->eraseFunction(cenv, f); -- cgit v1.2.1