diff options
-rw-r--r-- | src/ChangeLog | 9 | ||||
-rw-r--r-- | src/interp/g-opt.boot | 13 | ||||
-rw-r--r-- | src/interp/lisp-backend.boot | 44 |
3 files changed, 41 insertions, 25 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 126537fa..9a997f7f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,14 @@ 2011-12-16 Gabriel Dos Reis <gdr@cs.tamu.edu> + * interp/g-opt.boot (freeIteratorFirstValues): New. + (cleanLoop!): Use it. + * interp/lisp-backend.boot ($freeVarName): Remove. + (loopVarInit): Do not generate initializer for free iterators. + Adjust callers. + (massageFreeVarInits): Remove. Adjust caller. + +2011-12-16 Gabriel Dos Reis <gdr@cs.tamu.edu> + * interp/compiler.boot (finishListCollect): New. (compRepeatOrCollect): Use it. * interp/g-opt.boot (optCollectVector): Likewise. diff --git a/src/interp/g-opt.boot b/src/interp/g-opt.boot index c93204bc..e529d56f 100644 --- a/src/interp/g-opt.boot +++ b/src/interp/g-opt.boot @@ -345,10 +345,21 @@ removeLeave! x == walkWith!(x,function f) where x is ['%leave,.,y] and y is ['%return,:.] => resetTo(x,y) x +freeIteratorFirstValues iters == + [u for it in iters | u := f it] where + f it == + it is ['STEP,['%free,:id],lo,:.] => ['%LET,id,lo] + it is ['ON,['%free,:id],l] => ['%LET,id,l] + nil + cleanLoop! x == prefixWalk!(x,function f) where f x == x is ['%scope,tag,['%repeat,:itl,body,val]] => - resetTo(x,f ['%repeat,:itl,g(body,tag),g(val,tag)]) + body := g(body,tag) + val := g(val,tag) + firstVals := freeIteratorFirstValues itl => + resetTo(x,mkSeq [:firstVals,f ['%repeat,:itl,body,val]]) + resetTo(x,f ['%repeat,:itl,body,val]) x g(x,tag) == atomic? x => x diff --git a/src/interp/lisp-backend.boot b/src/interp/lisp-backend.boot index f5fcf28f..fb1e012b 100644 --- a/src/interp/lisp-backend.boot +++ b/src/interp/lisp-backend.boot @@ -55,11 +55,8 @@ module lisp_-backend where --% 3. predicate guarding loop body execution --% 4. loop termination predicate -++ Dummy free var name. -$freeVarName == KEYWORD::freeVar - loopVarInit(x,y) == - x is ['%free,:id] => [id,[$freeVarName,['%LET,id,y]]] + x is ['%free,:id] => [id,nil] -- no init form for free iterators. if x is ['%local,:.] then x := x.rest [x,[x,y]] @@ -67,11 +64,13 @@ loopVarInit(x,y) == ++ Generate code that sequentially visits each component of a list. expandIN(x,l,early?) == g := gensym() -- rest of the list yet to be visited - early? => -- give the loop variable a wider scope. + early? or x is ['%free,:.] => -- give the loop variable a wider scope. [x,init] := loopVarInit(x,'%nil) - [[[g,l],init], - nil,[['%store,g,['%tail,g]]], - nil,[['%not,['%pair?,g]],['%seq,['%store,x,['%head,g]],'%nil]]] + init := + init = nil => [[g,l]] + [[g,l],init] + [init,nil,[['%store,g,['%tail,g]]],nil, + [['%not,['%pair?,g]],['%seq,['%store,x,['%head,g]],'%nil]]] [x,init] := loopVarInit(x,['%head,g]) [[[g,l]], [init],[['%store,g,['%tail,g]]], @@ -79,13 +78,17 @@ expandIN(x,l,early?) == expandON(x,l) == [x,init] := loopVarInit(x,l) - [[init],nil,[['%store,x,['%tail,x]]],nil,[['%not,['%pair?,x]]]] + if init ~= nil then + init := [init] + [init,nil,[['%store,x,['%tail,x]]],nil,[['%not,['%pair?,x]]]] ++ Generate code that traverses an interval with lower bound 'lo', ++ arithmetic progression `step, and possible upper bound `final'. expandSTEP(id,lo,step,final)== [id,init] := loopVarInit(id,lo) - loopvar := [init] + loopvar := + init = nil => nil + [init] inc := atomic? step => step g1 := gensym() @@ -143,19 +146,9 @@ expandIterators iters == it is ["%init",var,val] => expandInit(var,val) nil -massageFreeVarInits(body,inits) == - inits = nil => body - inits is [[var,init]] and sameObject?(var,$freeVarName) => - ['%scope,nil,['%seq,init,['%leave,nil,body]]] - for init in inits repeat - sameObject?(init.first,$freeVarName) => - init.first := gensym() - ['LET,inits,body] - - expandRepeat ['%repeat,:iters,body,ret] == itersCode := expandIterators iters - itersCode = "failed" => systemErrorHere ["expandLoop",iters] + itersCode is "failed" => systemErrorHere ["expandLoop",iters] body := middleEndExpand body itersCode := "coagulate"/itersCode where @@ -165,14 +158,17 @@ expandRepeat ['%repeat,:iters,body,ret] == if filters ~= nil then body := mkpf([:filters,body],"AND") -- If there is any body-wide initialization, now is the time. - body := massageFreeVarInits(body,bodyInits) + if bodyInits ~= nil then + body := ['%bind,bodyInits,body] exits := exits = nil => body ['%when,[mkpf(exits,"OR"),["RETURN",expandToVMForm ret]], - [true,body]] + ['%otherwise,body]] body := ['%loop,exits,:cont] -- Finally, set up loop-wide initializations. - expandToVMForm optimize! massageFreeVarInits(body,loopInits) + if loopInits ~= nil then + body := ['LET,loopInits,body] + expandToVMForm optimize! body ++ Generate code for list comprehension. expandCollect ['%collect,:iters,body] == |