aboutsummaryrefslogtreecommitdiffstats
path: root/tuplr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tuplr.cpp')
-rw-r--r--tuplr.cpp121
1 files changed, 120 insertions, 1 deletions
diff --git a/tuplr.cpp b/tuplr.cpp
index ae9caf7..de7d8a1 100644
--- a/tuplr.cpp
+++ b/tuplr.cpp
@@ -226,9 +226,128 @@ initLang(PEnv& penv, TEnv& tenv)
}
+/***************************************************************************
+ * EVAL/REPL *
+ ***************************************************************************/
+
+int
+eval(CEnv& cenv, const string& name, istream& is)
+{
+ AST* result = NULL;
+ AType* resultType = NULL;
+ list< pair<SExp, AST*> > exprs;
+ Cursor cursor(name);
+ try {
+ while (true) {
+ SExp exp = readExpression(cursor, is);
+ if (exp.type == SExp::LIST && exp.empty())
+ break;
+
+ result = cenv.penv.parse(exp); // Parse input
+ Constraints c;
+ result->constrain(cenv.tenv, c); // Constrain types
+ cenv.tsubst = Subst::compose(cenv.tsubst, TEnv::unify(c)); // Solve type constraints
+ resultType = cenv.type(result);
+ result->lift(cenv); // Lift functions
+ exprs.push_back(make_pair(exp, result));
+
+ // Add definitions as GC roots
+ if (result->to<ADefinition*>())
+ 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);
+ }
+ }
+
+ // Create function for top-level of program
+ CFunction f = startFunction(cenv, "main", resultType, ATuple(cursor));
+
+ // Compile all expressions into it
+ CValue val = NULL;
+ for (list< pair<SExp, AST*> >::const_iterator i = exprs.begin(); i != exprs.end(); ++i)
+ val = cenv.compile(i->second);
+
+ finishFunction(cenv, f, val);
+
+ cenv.out << call(cenv, f, resultType) << " : " << resultType << endl;
+
+ Object::pool.collect(Object::pool.roots());
+
+ if (cenv.args.find("-d") != cenv.args.end())
+ cenv.write(cenv.out);
+
+ } catch (Error& e) {
+ cenv.err << e.what() << endl;
+ return 1;
+ }
+ return 0;
+}
+
+int
+repl(CEnv& cenv)
+{
+ while (1) {
+ cenv.out << "() ";
+ cenv.out.flush();
+ Cursor cursor("(stdin)");
+
+ try {
+ SExp exp = readExpression(cursor, std::cin);
+ if (exp.type == SExp::LIST && exp.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, TEnv::unify(c)); // Solve type constraints
+
+ AType* bodyT = cenv.type(body);
+ THROW_IF(!bodyT, cursor, "call to untyped body")
+
+ body->lift(cenv);
+
+ CFunction f = NULL;
+ try {
+ // Create anonymous function to insert code into
+ f = startFunction(cenv, cenv.gensym("_repl"), bodyT, ATuple(cursor));
+ CValue retVal = cenv.compile(body);
+ finishFunction(cenv, f, retVal);
+ cenv.out << call(cenv, f, bodyT);
+ } catch (Error& e) {
+ ADefinition* def = body->to<ADefinition*>();
+ if (def)
+ cenv.out << def->sym();
+ else
+ cenv.out << "?";
+ eraseFunction(cenv, f);
+ }
+ cenv.out << " : " << cenv.type(body) << endl;
+
+ // Add definitions as GC roots
+ if (body->to<ADefinition*>())
+ cenv.lock(body);
+
+ Object::pool.collect(Object::pool.roots());
+
+ cenv.tsubst = oldSubst;
+ if (cenv.args.find("-d") != cenv.args.end())
+ cenv.write(cenv.out);
+
+ } catch (Error& e) {
+ cenv.err << e.what() << endl;
+ }
+ }
+ return 0;
+}
+
/***************************************************************************
- * EVAL/REPL/MAIN *
+ * MAIN *
***************************************************************************/
int