aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-05-14 22:41:13 +0000
committerDavid Robillard <d@drobilla.net>2011-05-14 22:41:13 +0000
commitccc0e2c718ac0562bbc2273cde5c853249f94ab2 (patch)
tree84369ee8b39099eb3e145708e2db6a236c549895
parent6ca900cd7409cfea90294d274bf0a6c48a13a8dc (diff)
downloadresp-ccc0e2c718ac0562bbc2273cde5c853249f94ab2.tar.gz
resp-ccc0e2c718ac0562bbc2273cde5c853249f94ab2.tar.bz2
resp-ccc0e2c718ac0562bbc2273cde5c853249f94ab2.zip
Fix global set/get (top level variable definitions in the REPL).
git-svn-id: http://svn.drobilla.net/resp/trunk@425 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r--src/compile.cpp8
-rw-r--r--src/repl.cpp119
2 files changed, 74 insertions, 53 deletions
diff --git a/src/compile.cpp b/src/compile.cpp
index 1534263..e8baed3 100644
--- a/src/compile.cpp
+++ b/src/compile.cpp
@@ -90,7 +90,13 @@ compile_def(CEnv& cenv, const ATuple* def) throw()
const ASymbol* const sym = def->list_ref(1)->as_symbol();
const AST* const body = def->list_ref(2);
CVal val = resp_compile(cenv, body);
- cenv.def(sym, body, cenv.type(body), val);
+ if (cenv.repl && cenv.vals.topLevel(sym) && !is_form(cenv.type(sym), "Fn")) {
+ CVal global = cenv.engine()->compileGlobalSet(
+ cenv, sym->sym(), val, cenv.type(body));
+ cenv.def(sym, body, cenv.type(body), global);
+ } else {
+ cenv.def(sym, body, cenv.type(body), val);
+ }
return NULL;
}
diff --git a/src/repl.cpp b/src/repl.cpp
index dd61f9f..edaa003 100644
--- a/src/repl.cpp
+++ b/src/repl.cpp
@@ -72,7 +72,7 @@ callPrintCollect(CEnv& cenv, CFunc f, const AST* result, const AST* resultT, boo
Object::pool.collect(Object::pool.roots());
}
-static inline int
+static inline const AST*
dump(CEnv& cenv, const Code& code)
{
for (Code::const_iterator i = code.begin(); i != code.end(); ++i)
@@ -80,6 +80,54 @@ dump(CEnv& cenv, const Code& code)
return 0;
}
+const AST*
+compile(CEnv& cenv, const Code& parsed, Code& defs, Code& exprs)
+{
+ const AST* exp = NULL;
+
+ // Simplify all expressions
+ Code simplified;
+ for (Code::const_iterator i = parsed.begin(); i != parsed.end(); ++i)
+ if ((exp = resp_simplify(cenv, *i)))
+ simplified.push_back(exp);
+ if (cenv.args.find("-R") != cenv.args.end())
+ return dump(cenv, simplified);
+
+ // Convert to CPS
+ Code cps;
+ for (Code::const_iterator i = simplified.begin(); i != simplified.end(); ++i)
+ if ((exp = resp_cps(cenv, *i, cenv.penv.sym("display"))))
+ cps.push_back(exp);
+ if (cenv.args.find("-C") != cenv.args.end())
+ return dump(cenv, cps);
+
+ // Lift all expressions
+ Code lifted;
+ for (Code::const_iterator i = simplified.begin(); i != simplified.end(); ++i)
+ if ((exp = resp_lift(cenv, lifted, *i)))
+ lifted.push_back(exp);
+ if (cenv.args.find("-L") != cenv.args.end())
+ return dump(cenv, lifted);
+
+ // Flatten expressions
+ const AST* retT = NULL;
+ for (Code::const_iterator i = lifted.begin(); i != lifted.end(); ++i) {
+ const ATuple* call = (*i)->to_tuple();
+ if (call && (is_form(*i, "def-type")
+ || (is_form(*i, "def") && is_form(call->frrst(), "fn")))) {
+ resp_flatten(cenv, defs, call);
+ } else {
+ const ATuple* tup = (*i)->to_tuple();
+ if (!tup || !tup->empty()) {
+ exprs.push_back(*i);
+ retT = cenv.type(*i);
+ }
+ }
+ }
+
+ return retT;
+}
+
/// Compile and evaluate code from @a is
int
eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute)
@@ -92,74 +140,39 @@ eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute)
Code parsed;
while (readParseType(cenv, cursor, is, exp, ast))
parsed.push_back(ast);
- if (cenv.args.find("-T") != cenv.args.end())
- return dump(cenv, parsed);
-
- // Simplify all expressions
- Code simplified;
- for (Code::const_iterator i = parsed.begin(); i != parsed.end(); ++i)
- if ((exp = resp_simplify(cenv, *i)))
- simplified.push_back(exp);
- if (cenv.args.find("-R") != cenv.args.end())
- return dump(cenv, simplified);
-
- // Convert to CPS
- Code cps;
- for (Code::const_iterator i = simplified.begin(); i != simplified.end(); ++i)
- if ((exp = resp_cps(cenv, *i, cenv.penv.sym("display"))))
- cps.push_back(exp);
- if (cenv.args.find("-C") != cenv.args.end())
- return dump(cenv, cps);
-
- // Lift all expressions
- Code lifted;
- for (Code::const_iterator i = simplified.begin(); i != simplified.end(); ++i)
- if ((exp = resp_lift(cenv, lifted, *i)))
- lifted.push_back(exp);
- if (cenv.args.find("-L") != cenv.args.end())
- return dump(cenv, lifted);
-
- // Flatten expressions
- Code flattened; // Type and function definitions
- Code exprs; // Other top-level expressions (main code)
- const AST* retT = NULL;
- for (Code::const_iterator i = lifted.begin(); i != lifted.end(); ++i) {
- const ATuple* call = (*i)->to_tuple();
- if (call && (is_form(*i, "def-type")
- || (is_form(*i, "def") && is_form(call->frrst(), "fn")))) {
- resp_flatten(cenv, flattened, call);
- } else {
- const ATuple* tup = (*i)->to_tuple();
- if (!tup || !tup->empty()) {
- exprs.push_back(*i);
- retT = cenv.type(*i);
- }
- }
+ if (cenv.args.find("-T") != cenv.args.end()) {
+ dump(cenv, parsed);
+ return 0;
}
- // Flatten main code into flattened
+ Code defs;
+ Code exprs;
+ const AST* retT = compile(cenv, parsed, defs, exprs);
+
+ // Flatten main code into `defs'
if (!exprs.empty()) {
const ASymbol* main = cenv.penv.sym("main");
List mainT(Cursor(), cenv.penv.sym("Fn"), new ATuple(Cursor()), retT, NULL);
cenv.def(main, NULL, mainT, NULL);
- flattened.push_back(
+ defs.push_back(
tup(Cursor(), cenv.penv.sym("fn-start"), main, NULL));
const AST* mainRet = NULL;
for (Code::const_iterator i = exprs.begin(); i != exprs.end(); ++i)
- mainRet = resp_flatten(cenv, flattened, *i);
+ mainRet = resp_flatten(cenv, defs, *i);
- flattened.push_back(
+ defs.push_back(
tup(Cursor(), cenv.penv.sym("fn-end"), main, mainRet, NULL));
}
if (cenv.args.find("-F") != cenv.args.end()) {
- return dump(cenv, flattened);
+ dump(cenv, defs);
+ return 0;
}
// Compile flattened code
- for (Code::const_iterator i = flattened.begin(); i != flattened.end(); ++i) {
+ for (Code::const_iterator i = defs.begin(); i != defs.end(); ++i) {
resp_compile(cenv, *i);
}
@@ -208,9 +221,11 @@ repl(CEnv& cenv)
// Create function for this repl loop
f = cenv.engine()->startFn(cenv, replFnName, new ATuple(cursor), fnT);
cenv.engine()->finishFn(cenv, resp_compile(cenv, ast), type);
- callPrintCollect(cenv, f, ast, type, true);
- if (cenv.args.find("-d") != cenv.args.end())
+
+ if (cenv.args.find("-S") != cenv.args.end())
cenv.engine()->writeModule(cenv, cenv.out);
+ else
+ callPrintCollect(cenv, f, ast, type, true);
} catch (Error& e) {
cenv.out << e.msg << endl;
cenv.engine()->eraseFn(cenv, f);