aboutsummaryrefslogtreecommitdiff
path: root/src/interp
diff options
context:
space:
mode:
Diffstat (limited to 'src/interp')
-rw-r--r--src/interp/compiler.boot51
-rw-r--r--src/interp/g-opt.boot47
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