diff options
author | David Robillard <d@drobilla.net> | 2009-10-13 20:44:16 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-10-13 20:44:16 +0000 |
commit | 67165233421d658a901ebf4eba7c14cda85f34d3 (patch) | |
tree | 8f505db693dfc58399f9c9675562008d682e4304 | |
parent | 644b17ee0b248da739736fc4bf3e065ebb705ed5 (diff) | |
download | resp-67165233421d658a901ebf4eba7c14cda85f34d3.tar.gz resp-67165233421d658a901ebf4eba7c14cda85f34d3.tar.bz2 resp-67165233421d658a901ebf4eba7c14cda85f34d3.zip |
Factor out common code in eval and repl.
git-svn-id: http://svn.drobilla.net/resp/tuplr@207 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r-- | src/repl.cpp | 148 |
1 files changed, 71 insertions, 77 deletions
diff --git a/src/repl.cpp b/src/repl.cpp index 24b0acf..5c4d459 100644 --- a/src/repl.cpp +++ b/src/repl.cpp @@ -26,68 +26,85 @@ using namespace std; +static bool +readParseTypeCompile(CEnv& cenv, Cursor& cursor, istream& is, AST** exp, AST** result, AType** resultT) +{ + *exp = readExpression(cursor, is); + if ((*exp)->to<ATuple*>() && (*exp)->to<ATuple*>()->empty()) + return false; + + *result = cenv.penv.parse(*exp); // Parse input + Constraints c; + (*result)->constrain(cenv.tenv, c); // Constrain types + + cenv.tsubst = Subst::compose(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) { + Object::pool.addRoot(i->first); + Object::pool.addRoot(i->second); + } + + (*resultT) = cenv.type(*result); + THROW_IF(!*resultT, cursor, "call to untyped body"); + + (*result)->lift(cenv); // Lift functions + + // Add definitions as GC roots + if ((*result)->to<ADef*>()) + cenv.lock(*result); + + return true; +} + +static void +callPrintCollect(CEnv& cenv, CFunction f, AST* result, AType* resultT, bool execute) +{ + if (execute && resultT->concrete()) + cenv.out << cenv.engine()->call(cenv, f, resultT); + + // Print type (if applicable) + if (resultT->at(0)->to<const ASymbol*>()->cppstr != "Nothing") + 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* result = NULL; - AType* resultType = NULL; + AST* exp = NULL; + AST* result = NULL; + AType* resultT = NULL; list< pair<AST*, AST*> > exprs; Cursor cursor(name); try { - while (true) { - AST* exp = readExpression(cursor, is); - if (exp->to<ATuple*>() && exp->to<ATuple*>()->empty()) - break; - - result = cenv.penv.parse(exp); // Parse input - Constraints c; - result->constrain(cenv.tenv, c); // Constrain types - cenv.tsubst = Subst::compose(cenv.tsubst, unify(c)); // Solve type constraints - resultType = cenv.type(result); - result->lift(cenv); // Lift functions + while (readParseTypeCompile(cenv, cursor, is, &exp, &result, &resultT)) exprs.push_back(make_pair(exp, result)); - // Add definitions as GC roots - if (result->to<ADef*>()) - cenv.lock(result); - - // Add types in type substition as GC roots - for (Subst::iterator i = cenv.tsubst.begin(); i != cenv.tsubst.end(); ++i) { - Object::pool.addRoot(i->first); - Object::pool.addRoot(i->second); - } - } - - // Print CPS form - CValue val = NULL; - /*for (list< pair<SExp, AST*> >::const_iterator i = exprs.begin(); i != exprs.end(); ++i) { - cout << "; CPS" << endl; - pprint(cout, i->second->cps(cenv.tenv, cenv.penv.sym("cont"))); - }*/ + //for (list< pair<SExp, AST*> >::const_iterator i = exprs.begin(); i != exprs.end(); ++i) + // pprint(cout, i->second->cps(cenv.tenv, cenv.penv.sym("cont"))); - if (resultType->concrete()) { + CValue val = NULL; + CFunction f = NULL; + if (resultT->concrete()) { // Create function for top-level of program - CFunction f = cenv.engine()->startFunction(cenv, "main", resultType, ATuple(cursor)); + f = cenv.engine()->startFunction(cenv, "main", resultT, ATuple(cursor)); // Compile all expressions into it for (list< pair<AST*, AST*> >::const_iterator i = exprs.begin(); i != exprs.end(); ++i) val = cenv.compile(i->second); // Finish compilation - cenv.engine()->finishFunction(cenv, f, resultType, val); - - // Call it - if (execute) - cenv.out << cenv.engine()->call(cenv, f, resultType); + cenv.engine()->finishFunction(cenv, f, resultT, val); } - if (execute) - cenv.out << " : " << resultType << endl; - - Object::pool.collect(Object::pool.roots()); - if (cenv.args.find("-d") != cenv.args.end()) - cenv.engine()->writeModule(cenv, cenv.out); + // Call and print result + callPrintCollect(cenv, f, result, resultT, execute); } catch (Error& e) { cenv.err << e.what() << endl; @@ -100,55 +117,32 @@ eval(CEnv& cenv, const string& name, istream& is, bool execute) int repl(CEnv& cenv) { + AST* exp = NULL; + AST* result = NULL; + AType* resultT = NULL; + const string replFnName = cenv.penv.gensymstr("_repl"); while (1) { cenv.out << "() "; cenv.out.flush(); Cursor cursor("(stdin)"); try { - AST* exp = readExpression(cursor, std::cin); - if (exp->to<ATuple*>() && exp->to<ATuple*>()->empty()) - break; - - AST* body = cenv.penv.parse(exp); // Parse input - Constraints c; - body->constrain(cenv.tenv, c); // Constrain types - Subst oldSubst = cenv.tsubst; - cenv.tsubst = Subst::compose(cenv.tsubst, unify(c)); // Solve type constraints - - AType* bodyT = cenv.type(body); - THROW_IF(!bodyT, cursor, "call to untyped body") - - body->lift(cenv); + if (!readParseTypeCompile(cenv, cursor, std::cin, &exp, &result, &resultT)) + break; CFunction f = NULL; try { - // 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, bodyT, retVal); - cenv.out << cenv.engine()->call(cenv, f, bodyT); + // Create function for this repl loop + f = cenv.engine()->startFunction(cenv, replFnName, resultT, ATuple(cursor)); + cenv.engine()->finishFunction(cenv, f, resultT, cenv.compile(result)); + callPrintCollect(cenv, f, result, resultT, true); } catch (Error& e) { - ADef* def = body->to<ADef*>(); - if (def) - cenv.out << def->sym(); - else - cenv.out << "?"; + cenv.out << e.msg << endl; cenv.engine()->eraseFunction(cenv, f); } - if (bodyT->at(0)->to<const ASymbol*>()->cppstr != "Nothing") - cenv.out << " : " << cenv.type(body) << endl; - - // Add definitions as GC roots - if (body->to<ADef*>()) - cenv.lock(body); - - Object::pool.collect(Object::pool.roots()); cenv.tsubst = oldSubst; - if (cenv.args.find("-d") != cenv.args.end()) - cenv.engine()->writeModule(cenv, cenv.out); } catch (Error& e) { cenv.err << e.what() << endl; |