aboutsummaryrefslogtreecommitdiffstats
path: root/src/repl.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-10-13 20:44:16 +0000
committerDavid Robillard <d@drobilla.net>2009-10-13 20:44:16 +0000
commit67165233421d658a901ebf4eba7c14cda85f34d3 (patch)
tree8f505db693dfc58399f9c9675562008d682e4304 /src/repl.cpp
parent644b17ee0b248da739736fc4bf3e065ebb705ed5 (diff)
downloadresp-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
Diffstat (limited to 'src/repl.cpp')
-rw-r--r--src/repl.cpp148
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;