aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog5
-rw-r--r--src/interp/g-opt.boot23
2 files changed, 22 insertions, 6 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 2217b103..39ec289b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,10 @@
2011-12-27 Gabriel Dos Reis <gdr@cs.tamu.edu>
+ * interp/g-opt.boot (exitScope?): Now return an expression or nil.
+ (cancelScopeLeave!): Tidy.
+
+2011-12-27 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
* algebra/prs.spad.pamphlet (PseudoRemainderSequence): Tidy.
2011-12-27 Gabriel Dos Reis <gdr@cs.tamu.edu>
diff --git a/src/interp/g-opt.boot b/src/interp/g-opt.boot
index eb3c3e86..a4b4f549 100644
--- a/src/interp/g-opt.boot
+++ b/src/interp/g-opt.boot
@@ -289,11 +289,14 @@ coagulateWhenSeries(x,tag) ==
nil
nil
-++ Return true if the expression `x' exist the scope with tag `g'
+++ Return non-nil if the expression `x' exist the scope with tag `g'
++ by normal local transfer or by exiting the enclosing function
-++ with a `return' statement.
+++ with a `return' statement. If non-nil, the return value is the
+++ expression operand to the normal exit.
exitScope?(x,g) ==
- x is ['%leave,=g,:.] or x is ['%return,:.]
+ x is ['%leave,=g,y] and hasNoLeave?(y,g) => y
+ x is ['%return,:.] => x
+ nil
unnestWhen! x == f x where
f x ==
@@ -348,15 +351,23 @@ spliceSeq! x == walkWith!(x,function f) where
x.args := spliceSeqArgs x.args
x
+++ Return the list of reduced clauses if every branch is a simple
+++ normal exiting expression. Otherwise, return nil.
+exitClauses(l,g) ==
+ [[p,x] for cl in l | cl is [p,u] and (x := exitScope?(u,g)) or leave nil]
+
++ Remove superfluous cancel/scope pairs exposed by running
++ removeJunk!.
cancelScopeLeave! x == walkWith!(x,function f) where
f x ==
- x is ['%scope,g,['%leave,=g,y]] and hasNoLeave?(y,g) =>
- resetTo(x,f y)
- x is ['%scope,g,u:=['%return,.,y]] => resetTo(x,u)
+ x is ['%scope,g,u] =>
+ u is ['%when,:.] and (v := exitClauses(u.args,g)) =>
+ resetTo(x,['%when,:v])
+ y := exitScope?(u,g) => resetTo(x,f y)
+ x
x
+++ Remove redundant %leave opode around %return forms.
removeLeave! x == walkWith!(x,function f) where
f x ==
x is ['%leave,.,y] and y is ['%return,:.] => resetTo(x,y)