diff options
Diffstat (limited to 'src/interp')
-rw-r--r-- | src/interp/compiler.boot | 51 | ||||
-rw-r--r-- | src/interp/g-opt.boot | 47 |
2 files changed, 51 insertions, 47 deletions
diff --git a/src/interp/compiler.boot b/src/interp/compiler.boot index c4428079..64715539 100644 --- a/src/interp/compiler.boot +++ b/src/interp/compiler.boot @@ -2392,6 +2392,8 @@ processInlineRequest(t,e) == --% ITERATORS --% +++ Generate code for collecting values generated by the expression `body' +++ controlled by iterators in `iters' into a list. finishListCollect(iters,body) == val := gensym() -- result of the list comprehension -- Transform the body to build the list as we go. @@ -2399,6 +2401,53 @@ finishListCollect(iters,body) == -- Don't forget we built the result in reverse order. ['%repeat,:iters,['%init,val,'%nil],body,['%lreverse!,val]] +++ Generate code for collecting values generated by the expression `body' +++ controlled by iterators in `iters' into a vector with element +++ type indicated by `eltType'. +finishVectorCollect(eltType,iters,body) == + fromList := false -- are we drawing from a list? + vecSize := nil -- size of vector + index := nil -- loop/vector index. + for iter in iters while not fromList repeat + [op,:.] := iter + op in '(_| SUCHTHAT WHILE UNTIL) => fromList := true + op in '(IN ON) => vecSize := [['%llength,third iter],:vecSize] + op in '(STEP ISTEP) => + -- pick a loop variable that we can use as the loop index. + [.,var,lo,inc,:etc] := iter + if lo = 0 and inc = 1 then + index := + var is [.,:var'] => var' + var + if [hi] := etc then + sz := + inc = 1 => + lo = 1 => hi + lo = 0 => ['%iinc,hi] + ['%iinc,['%isub,hi,lo]] + lo = 1 => ['%idiv,hi,inc] + lo = 0 => ['%idiv,['%iinc,hi],inc] + ['%idiv,['%isub,['%iinc,hi], lo],inc] + vecSize := [sz, :vecSize] + systemErrorHere ['finishVectorCollect, iter] + -- if we draw from a list, then just build a list and convert to vector. + fromList => + ['homogeneousListToVector,['getVMType,eltType], + finishListCollect(iters,body)] + vecSize = nil => systemErrorHere ['finishVectorCollect,eltType,iters,body] + -- get the actual size of the vector. + vecSize := + vecSize is [hi] => hi + ['%imin,:reverse! vecSize] + -- if no suitable loop index was found, introduce one. + if index = nil then + index := gensym() + iters := [:iters,['STEP,index,0,1]] + vec := gensym() + ['%bind,[[vec,['makeSimpleArray,['getVMType,eltType],vecSize]]], + ['%repeat,:iters,['setSimpleArrayEntry,vec,index,body],vec]] + + compReduce(form,m,e) == compReduce1(form,m,e,$formalArgList) @@ -2500,7 +2549,7 @@ compRepeatOrCollect(form,m,e) == itl':= substitute(["UNTIL",untilCode],'$until,itl') form':= $loopKind = "%CollectV" => - ["%CollectV",localReferenceIfThere(m',e'),:itl',body'] + finishVectorCollect(localReferenceIfThere(m',e'),itl',body') -- We are phasing out use of LISP macros COLLECT and REPEAT. $loopKind = "COLLECT" => finishListCollect(itl',body') ['%repeat,:itl',body','%nil] diff --git a/src/interp/g-opt.boot b/src/interp/g-opt.boot index e529d56f..7816eafb 100644 --- a/src/interp/g-opt.boot +++ b/src/interp/g-opt.boot @@ -772,50 +772,6 @@ optList form == literalElts is "failed" => form quote literalElts -optCollectVector form == - [.,eltType,:iters,body] := form - fromList := false -- are we drawing from a list? - vecSize := nil -- size of vector - index := nil -- loop/vector index. - for iter in iters while not fromList repeat - [op,:.] := iter - op in '(| SUCHTHAT WHILE UNTIL) => fromList := true - op in '(IN ON) => vecSize := [['%llength,third iter],:vecSize] - op in '(STEP ISTEP) => - -- pick a loop variable that we can use as the loop index. - [.,var,lo,inc,:etc] := iter - if lo = 0 and inc = 1 then - index := - var is [.,:var'] => var' - var - if [hi] := etc then - sz := - inc = 1 => - lo = 1 => hi - lo = 0 => ['%iinc,hi] - ['%iinc,['%isub,hi,lo]] - lo = 1 => ['%idiv,hi,inc] - lo = 0 => ['%idiv,['%iinc,hi],inc] - ['%idiv,['%isub,['%iinc,hi], lo],inc] - vecSize := [sz, :vecSize] - systemErrorHere ["optCollectVector", iter] - -- if we draw from a list, then just build a list and convert to vector. - fromList => - ["homogeneousListToVector",["getVMType",eltType], - finishListCollect(iters,body)] - vecSize = nil => systemErrorHere ["optCollectVector",form] - -- get the actual size of the vector. - vecSize := - vecSize is [hi] => hi - ['%imin,:reverse! vecSize] - -- if no suitable loop index was found, introduce one. - if index = nil then - index := gensym() - iters := [:iters,['STEP,index,0,1]] - vec := gensym() - ['%bind,[[vec,["makeSimpleArray",["getVMType",eltType],vecSize]]], - ['%repeat,:iters,["setSimpleArrayEntry",vec,index,body],vec]] - ++ Translate retraction of a value denoted by `e' to sub-domain `m' ++ defined by predicate `pred', optRetract ["%retract",e,m,pred] == @@ -1029,8 +985,7 @@ for x in '((%call optCall) _ (%scope optScope)_ (%when optCond)_ (%retract optRetract)_ - (%pullback optPullback)_ - (%CollectV optCollectVector)) _ + (%pullback optPullback)) _ repeat property(first x,'OPTIMIZE) := second x --much quicker to call functions if they have an SBC |