diff options
author | dos-reis <gdr@axiomatics.org> | 2010-06-09 02:04:08 +0000 |
---|---|---|
committer | dos-reis <gdr@axiomatics.org> | 2010-06-09 02:04:08 +0000 |
commit | ddd0d01eed235ef965e622c982667eeb2eb528c8 (patch) | |
tree | 934290623d267f317669a29ea0f7254b49c464b8 /src/interp/g-util.boot | |
parent | 6aca99e6211a8fe97a8bb84d2bc85f9900f35315 (diff) | |
download | open-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.boot | 21 |
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 |