aboutsummaryrefslogtreecommitdiffstats
path: root/src/repl.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-04-13 02:28:56 +0000
committerDavid Robillard <d@drobilla.net>2010-04-13 02:28:56 +0000
commit8675beae4f7a8415fc2e88451da95dc068719194 (patch)
tree599de9b6730a14035a25f7d9e0467f96866185ed /src/repl.cpp
parent1f988f420ba3827941886962680f3e2ad6f01740 (diff)
downloadresp-8675beae4f7a8415fc2e88451da95dc068719194.tar.gz
resp-8675beae4f7a8415fc2e88451da95dc068719194.tar.bz2
resp-8675beae4f7a8415fc2e88451da95dc068719194.zip
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
Diffstat (limited to 'src/repl.cpp')
-rw-r--r--src/repl.cpp109
1 files changed, 76 insertions, 33 deletions
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<ATuple*>() && exp->to<ATuple*>()->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<AST*, AST*> > exprs;
+ AST* exp = NULL;
+ AST* ast = NULL;
+ list<AST*> 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<SExp, AST*> >::const_iterator i = exprs.begin(); i != exprs.end(); ++i)
+ //for (list< pair<SExp, AST*> >::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<AST*, AST*> >::const_iterator i = exprs.begin(); i != exprs.end(); ++i)
- val = i->second->compile(cenv);
+ /*
+ // De-poly all expressions
+ Code concrete;
+ for (list<AST*>::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<AST*>::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<ADef*>();
+ 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<ADef*>();
+ if (def && (*(def->begin() + 2))->to<AFn*>()) {
+ 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<AST*>::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);