aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-12-09 22:43:56 +0000
committerDavid Robillard <d@drobilla.net>2010-12-09 22:43:56 +0000
commit7f30acc2d088d3d57ad2c8922eb1927c24fc72a7 (patch)
treeda1a32eb5c69ff1cf6f8113bbb5ef87d3dbbd8b4 /src
parentb078303aa8fa31728a8351587a0796e76301d575 (diff)
downloadresp-7f30acc2d088d3d57ad2c8922eb1927c24fc72a7.tar.gz
resp-7f30acc2d088d3d57ad2c8922eb1927c24fc72a7.tar.bz2
resp-7f30acc2d088d3d57ad2c8922eb1927c24fc72a7.zip
Document the free variable implementation (mostly in lift_symbol) better.
git-svn-id: http://svn.drobilla.net/resp/resp@335 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src')
-rw-r--r--src/lift.cpp30
-rw-r--r--src/resp.hpp2
2 files changed, 20 insertions, 12 deletions
diff --git a/src/lift.cpp b/src/lift.cpp
index 6bd991b..67ae580 100644
--- a/src/lift.cpp
+++ b/src/lift.cpp
@@ -33,18 +33,26 @@ using namespace std;
static const AST*
lift_symbol(CEnv& cenv, Code& code, const ASymbol* sym) throw()
{
- if (!cenv.liftStack.empty() && cenv.name(cenv.liftStack.top().fn) == sym->sym()) {
- return cenv.penv.sym("_me"); // Reference to innermost function
- } else if (!cenv.liftStack.empty() && !cenv.code.innermost(sym)) {
- // Replace symbol with code to access free variable from closure
- const int32_t index = cenv.liftStack.top().index(sym);
- return tup<ATuple>(sym->loc, cenv.penv.sym("."),
- cenv.penv.sym("_me"),
- new ALiteral<int32_t>(T_INT32, index, Cursor()),
- NULL);
- } else {
- return sym;
+ if (!cenv.liftStack.empty()) {
+ CEnv::FreeVars& vars = cenv.liftStack.top();
+ if (cenv.name(vars.fn) == sym->sym()) {
+ // Reference to innermost function, replace with "_me"
+ return cenv.penv.sym("_me");
+
+ } else if (!cenv.code.innermost(sym)) {
+ /* Free variable, replace with "(. _me i)" where i is the index
+ * of the free variable in the closure.
+ * If this free variable hasn't been encountered yet, it is appended
+ * to the closure (the calling lift_fn will use cenv.liftStack.top()
+ * to construct the closure after the fn body has been lifted).
+ */
+ return tup<ATuple>(sym->loc, cenv.penv.sym("."),
+ cenv.penv.sym("_me"),
+ new ALiteral<int32_t>(T_INT32, vars.index(sym), Cursor()),
+ NULL);
+ }
}
+ return sym;
}
static const AST*
diff --git a/src/resp.hpp b/src/resp.hpp
index 24e79ff..7767d33 100644
--- a/src/resp.hpp
+++ b/src/resp.hpp
@@ -833,7 +833,7 @@ struct CEnv {
for (; i != end(); ++i)
if ((*i)->sym() == sym->sym())
break;
-
+
if (i != end()) {
return i - begin() + 1;
} else {