aboutsummaryrefslogtreecommitdiff
path: root/src/interp/g-util.boot
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2010-06-09 02:04:08 +0000
committerdos-reis <gdr@axiomatics.org>2010-06-09 02:04:08 +0000
commitddd0d01eed235ef965e622c982667eeb2eb528c8 (patch)
tree934290623d267f317669a29ea0f7254b49c464b8 /src/interp/g-util.boot
parent6aca99e6211a8fe97a8bb84d2bc85f9900f35315 (diff)
downloadopen-axiom-ddd0d01eed235ef965e622c982667eeb2eb528c8.tar.gz
Widen scope of iterator variables in presence of terminating
predicate iterators. There is exactly one instance in the entire OpenAxio library. * interp/g-util.boot (expandIN): Take one more parameter to determine early binding. (expandIterators): Determine if wider scope is needed for iterator variables.
Diffstat (limited to 'src/interp/g-util.boot')
-rw-r--r--src/interp/g-util.boot21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/interp/g-util.boot b/src/interp/g-util.boot
index 0d786928..ac31d47e 100644
--- a/src/interp/g-util.boot
+++ b/src/interp/g-util.boot
@@ -108,11 +108,15 @@ mkVMForm(op,args) ==
--% 4. loop termination predicate
++ Generate code that sequentially visits each component of a list.
-expandIN(x,l) ==
+expandIN(x,l,early?) ==
g := gensym() -- rest of the list yet to be visited
+ early? => -- give the loop variable a wider scope.
+ [[[g,middleEndExpand l],[x,'NIL]],
+ nil,[['SETQ,g,['CDR,g]]],
+ nil,[['ATOM,g],['PROGN,['SETQ,x,['CAR,g]],'NIL]]]
[[[g,middleEndExpand l]],
- [[x,["CAR",g]]],[["SETQ",g,["CDR",g]]],
- nil,[["ATOM",g]]]
+ [[x,['CAR,g]]],[['SETQ,g,['CDR,g]]],
+ nil,[['ATOM,g]]]
expandON(x,l) ==
[[[x,middleEndExpand l]],nil,[["SETQ",x,["CDR",x]]],nil,[["ATOM",x]]]
@@ -165,10 +169,15 @@ expandInit(var,val) ==
[[[var,middleEndExpand val]],nil,nil,nil,nil]
expandIterators iters ==
- [toLisp it or leave "failed" for it in iters] where
- toLisp it ==
+ -- Exit predicates may reference iterator variables. In that case,
+ -- the scope the variables must cover the generated loop body. The
+ -- following is much more coarse approximation than we may want,
+ -- but it will do. For now.
+ early? := or/[ it.op in '(WHILE UNTIL) for it in iters]
+ [toLisp(it,early?) or leave "failed" for it in iters] where
+ toLisp(it,early?) ==
it is ["STEP",var,lo,inc,:hi] => expandSTEP(var,lo,inc,hi)
- it is ["IN",var,seq] => expandIN(var,seq)
+ it is ["IN",var,seq] => expandIN(var,seq,early?)
it is ["ON",var,seq] => expandON(var,seq)
it is ["WHILE",pred] => expandWHILE pred
it is [op,pred] and op in '(SUCHTHAT _|) => expandSUCHTHAT pred