[pure-lang-svn] SF.net SVN: pure-lang:[555] pure/trunk
Status: Beta
Brought to you by:
agraef
|
From: <ag...@us...> - 2008-08-21 11:31:01
|
Revision: 555
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=555&view=rev
Author: agraef
Date: 2008-08-21 11:31:10 +0000 (Thu, 21 Aug 2008)
Log Message:
-----------
Fix const name capture in expression preprocessing.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/interpreter.cc
pure/trunk/interpreter.hh
Added Paths:
-----------
pure/trunk/test/test019.log
pure/trunk/test/test019.pure
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-20 21:08:37 UTC (rev 554)
+++ pure/trunk/ChangeLog 2008-08-21 11:31:10 UTC (rev 555)
@@ -1,7 +1,14 @@
-2008-08-20 Albert Graef <Dr....@t-...>
+2008-08-21 Albert Graef <Dr....@t-...>
* 0.5 release.
+ * interpreter.cc (subst): Defer const substitutions (and
+ propagation of type tags) until all variable bindings have been
+ processed, to prevent name capture in const substitutions.
+ Reported by Eddie Rucker.
+
+2008-08-20 Albert Graef <Dr....@t-...>
+
* expr.cc (env::operator=): Bugfix: Only set temporary level of a
constant or free variable if it wasn't defined previously at a
lower level.
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-08-20 21:08:37 UTC (rev 554)
+++ pure/trunk/interpreter.cc 2008-08-21 11:31:10 UTC (rev 555)
@@ -740,7 +740,7 @@
save_globals(g);
compile();
// promote type tags and substitute constants:
- env vars; expr u = subst(vars, x);
+ env vars; expr u = csubst(subst(vars, x));
compile(u);
x = u;
pure_expr *res = doeval(u, e);
@@ -767,7 +767,7 @@
compile();
env vars;
// promote type tags and substitute constants:
- expr rhs = subst(vars, x);
+ expr rhs = csubst(subst(vars, x));
expr lhs = bind(vars, pat);
build_env(vars, lhs);
for (env::const_iterator it = vars.begin(); it != vars.end(); ++it) {
@@ -864,7 +864,7 @@
compile();
env vars;
// promote type tags and substitute constants:
- expr rhs = subst(vars, x);
+ expr rhs = csubst(subst(vars, x));
expr lhs = bind(vars, pat);
build_env(vars, lhs);
for (env::const_iterator it = vars.begin(); it != vars.end(); ++it) {
@@ -1368,6 +1368,11 @@
assert(!r.lhs.is_null());
closure(r, false);
if (toplevel) {
+ // substitute constants:
+ expr u = expr(r.lhs),
+ v = expr(csubst(r.rhs)),
+ w = expr(csubst(r.qual));
+ r = rule(u, v, w);
compile(r.rhs);
compile(r.qual);
}
@@ -1625,14 +1630,7 @@
} else {
expr u = subst(vars, x.xval1(), idx),
v = subst(vars, x.xval2(), idx);
- expr w = expr(u, v);
- // promote type tags
- expr f; uint32_t n = count_args(w, f);
- if (n == 1)
- promote_ttags(f, w, w.xval2());
- else if (n == 2)
- promote_ttags(f, w, w.xval1().xval2(), w.xval2());
- return w;
+ return expr(u, v);
}
// conditionals:
case EXPR::COND: {
@@ -1705,18 +1703,108 @@
// not a bound variable
if (x.ttag() != 0)
throw err("error in expression (misplaced type tag)");
- it = globenv.find(sym.f);
- if (it != globenv.end() && it->second.t == env_info::cvar)
- // substitute constant value
- return *it->second.cval;
- else
- return x;
+ return x;
}
const env_info& info = it->second;
return expr(EXPR::VAR, sym.f, idx, info.ttag, *info.p);
}
}
+expr interpreter::csubst(expr x)
+{
+ if (x.is_null()) return x;
+ switch (x.tag()) {
+ // constants:
+ case EXPR::VAR:
+ case EXPR::FVAR:
+ case EXPR::INT:
+ case EXPR::BIGINT:
+ case EXPR::DBL:
+ case EXPR::STR:
+ case EXPR::PTR:
+ return x;
+ // application:
+ case EXPR::APP:
+ if (x.xval1().tag() == EXPR::APP &&
+ x.xval1().xval1().tag() == symtab.catch_sym().f) {
+ expr u = csubst(x.xval1().xval2()),
+ v = csubst(x.xval2());
+ return expr(symtab.catch_sym().x, u, v);
+ } else {
+ expr u = csubst(x.xval1()),
+ v = csubst(x.xval2());
+ expr w = expr(u, v);
+ // promote type tags
+ expr f; uint32_t n = count_args(w, f);
+ if (n == 1)
+ promote_ttags(f, w, w.xval2());
+ else if (n == 2)
+ promote_ttags(f, w, w.xval1().xval2(), w.xval2());
+ return w;
+ }
+ // conditionals:
+ case EXPR::COND: {
+ expr u = csubst(x.xval1()),
+ v = csubst(x.xval2()),
+ w = csubst(x.xval3());
+ return expr::cond(u, v, w);
+ }
+ // nested closures:
+ case EXPR::LAMBDA: {
+ expr u = x.xval1(), v = csubst(x.xval2());
+ return expr::lambda(u, v);
+ }
+ case EXPR::CASE: {
+ expr u = csubst(x.xval());
+ const rulel *r = x.rules();
+ rulel *s = new rulel;
+ for (rulel::const_iterator it = r->begin(); it != r->end(); ++it) {
+ expr u = it->lhs, v = csubst(it->rhs),
+ w = csubst(it->qual);
+ s->push_back(rule(u, v, w));
+ }
+ return expr::cases(u, s);
+ }
+ case EXPR::WHEN: {
+ const rulel *r = x.rules();
+ rulel *s = new rulel;
+ for (rulel::const_iterator it = r->begin(); it != r->end(); ++it) {
+ expr u = it->lhs, v = csubst(it->rhs);
+ s->push_back(rule(u, v));
+ }
+ expr u = csubst(x.xval());
+ return expr::when(u, s);
+ }
+ case EXPR::WITH: {
+ expr u = csubst(x.xval());
+ const env *e = x.fenv();
+ env *f = new env;
+ for (env::const_iterator it = e->begin(); it != e->end(); ++it) {
+ int32_t g = it->first;
+ const env_info& info = it->second;
+ const rulel *r = info.rules;
+ rulel s;
+ for (rulel::const_iterator jt = r->begin(); jt != r->end(); ++jt) {
+ expr u = jt->lhs, v = csubst(jt->rhs),
+ w = csubst(jt->qual);
+ s.push_back(rule(u, v, w));
+ }
+ (*f)[g] = env_info(info.argc, s, info.temp);
+ }
+ return expr::with(u, f);
+ }
+ default:
+ assert(x.tag() > 0);
+ const symbol& sym = symtab.sym(x.tag());
+ env::const_iterator it = globenv.find(sym.f);
+ if (it != globenv.end() && it->second.t == env_info::cvar)
+ // substitute constant value
+ return *it->second.cval;
+ else
+ return x;
+ }
+}
+
expr interpreter::fsubst(const env& funs, expr x, uint8_t idx)
{
if (x.is_null()) return x;
Modified: pure/trunk/interpreter.hh
===================================================================
--- pure/trunk/interpreter.hh 2008-08-20 21:08:37 UTC (rev 554)
+++ pure/trunk/interpreter.hh 2008-08-21 11:31:10 UTC (rev 555)
@@ -448,6 +448,7 @@
void promote_ttags(expr f, expr x, expr u, expr v);
expr bind(env& vars, expr x, bool b = true, path p = path());
expr subst(const env& vars, expr x, uint8_t idx = 0);
+ expr csubst(expr x);
expr fsubst(const env& funs, expr x, uint8_t idx = 0);
void closure(expr& l, expr& r, bool b = true);
void closure(rule& r, bool b = true);
Added: pure/trunk/test/test019.log
===================================================================
--- pure/trunk/test/test019.log (rev 0)
+++ pure/trunk/test/test019.log 2008-08-21 11:31:10 UTC (rev 555)
@@ -0,0 +1,13 @@
+const i = -1;
+catmap (\i/*0:*/ -> catmap (\j/*0:*/ -> [(i/*1:*/,j/*0:*/)] {
+ rule #0: j = [(i,j)]
+ state 0: #0
+ <var> state 1
+ state 1: #0
+}) (3..4) {
+ rule #0: i = catmap (\j -> [(i,j)]) (3..4)
+ state 0: #0
+ <var> state 1
+ state 1: #0
+}) (1..2);
+[(1,3),(1,4),(2,3),(2,4)]
Added: pure/trunk/test/test019.pure
===================================================================
--- pure/trunk/test/test019.pure (rev 0)
+++ pure/trunk/test/test019.pure 2008-08-21 11:31:10 UTC (rev 555)
@@ -0,0 +1,3 @@
+// const name capture regression, reported by Eddie Rucker
+const i = -1;
+[(i,j); i=1..2; j=3..4];
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|