aboutsummaryrefslogtreecommitdiff
path: root/src/interp/compiler.boot
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2011-08-14 21:23:34 +0000
committerdos-reis <gdr@axiomatics.org>2011-08-14 21:23:34 +0000
commit7dff09b8cac803d6936887fdfa286a2a25073ac2 (patch)
tree1f82b9c5f57145f6f2234617bb35503666f0b2dc /src/interp/compiler.boot
parent775f2c3cca11ab64df713afb7f35363afe5d4ce0 (diff)
downloadopen-axiom-7dff09b8cac803d6936887fdfa286a2a25073ac2.tar.gz
* interp/lisp-backend.boot ($freeVarName): New global constant.
(loopVarInit): New. (expandIN): Use it. (expandON): Likewise. (expandSTEP): Likewise. (massageFreeVarInits): New. (expandLoop): Use it. * interp/fnewmeta.lisp (PARSE-QuantifiedVariable): Tidy. (PARSE-AnyId): Likewise. (PARSE-Variable): New. Allow scope-of-type specification for loop variable. (PARSE-Iterator): Use it. * interp/compiler.boot (massage_llop): Don't check $mayHaveFreeIteratorVariables. (compRepeatOrCollect): Don't bind it. (classifyIteratorVariable): New. (complainIfShadowing): Remove as no longer needed. (compStepIterator): Use it. Tidy. (compONIterator, compINIterator): New. Split out of compIterator. (compIterator): Refactor. * interp/functor.boot (optFunctorBody): Fix thinko. * interp/g-opt.boot (optCollectVector): A STEP iterator may have a storage class. * algebra/clip.spad.pamphlet: Fix loop variable scope. * algebra/ffpoly.spad.pamphlet: Likewise. * algebra/fparfrac.spad.pamphlet: Likewise. * algebra/gdpoly.spad.pamphlet: Likewise. * algebra/ghensel.spad.pamphlet: Likewise. * algebra/groebsol.spad.pamphlet: Likewise. * algebra/intfact.spad.pamphlet: Likewise. * algebra/matfuns.spad.pamphlet: Likewise. * algebra/moddfact.spad.pamphlet: Likewise. * algebra/numtheor.spad.pamphlet: Likewise. * algebra/permgrps.spad.pamphlet: Likewise. * algebra/pfbr.spad.pamphlet: Likewise. * algebra/pgcd.spad.pamphlet: Likewise. * algebra/pleqn.spad.pamphlet: Likewise. * algebra/pseudolin.spad.pamphlet: Likewise. * algebra/radeigen.spad.pamphlet: Likewise. * algebra/radix.spad.pamphlet: Likewise. * algebra/regset.spad.pamphlet: Likewise. * algebra/rep2.spad.pamphlet: Likewise. * algebra/sgcf.spad.pamphlet: Likewise. * algebra/smith.spad.pamphlet: Likewise. * algebra/sregset.spad.pamphlet: Likewise. * algebra/syssolp.spad.pamphlet: Likewise. * algebra/zerodim.spad.pamphlet: Likewise. * algebra/crfp.spad.pamphlet: Remove capsule-level declaration of local variables. * algebra/galfact.spad.pamphlet: Likewise. * algebra/mathml.spad.pamphlet: Likewise. * algebra/numode.spad.pamphlet: Likewise. * algebra/tex.spad.pamphlet: Likewise. * algebra/updecomp.spad.pamphlet: Likewise.
Diffstat (limited to 'src/interp/compiler.boot')
-rw-r--r--src/interp/compiler.boot101
1 files changed, 59 insertions, 42 deletions
diff --git a/src/interp/compiler.boot b/src/interp/compiler.boot
index c85d1e9f..1dc074ce 100644
--- a/src/interp/compiler.boot
+++ b/src/interp/compiler.boot
@@ -2306,7 +2306,7 @@ localReferenceIfThere m ==
massageLoop x == main x where
main x ==
x isnt ['CATCH,tag,['REPEAT,:iters,body]] => x
- $mayHaveFreeIteratorVariables or CONTAINED('TAGGEDexit,x) => x
+ CONTAINED('TAGGEDexit,x) => x
replaceThrowWithLeave(body,tag)
containsNonLocalControl?(body,nil) => systemErrorHere ['massageLoop,x]
['CATCH,tag,['%loop,:iters,body,'%nil]]
@@ -2339,7 +2339,6 @@ compRepeatOrCollect(form,m,e) ==
$iterateCount: local := 0
$loopBodyTag: local := nil
$breakCount: local := 0
- $mayHaveFreeIteratorVariables: local := false
oldEnv := e
aggr := nil
[$loopKind,:itl,body]:= form
@@ -2399,6 +2398,28 @@ joinIntegerModes(x,y,e) ==
isSubset(y,x,e) => x
$Integer
+++ Given a for-loop iterator `x', return
+++ a. its storage class
+++ b. its name
+++ c. an environment containing its declaration in case a type
+++ was specified.
+classifyIteratorVariable(x,e) == check(main(x,e),x) where
+ main(x,e) ==
+ x is [":",var,t] =>
+ not ident? var => nil
+ checkVariableName var
+ t is 'local => ['%local,var,e]
+ t is 'free => ['%free,var,e]
+ [.,.,e] := compMakeDeclaration(var,t,e) => ['%local,var,e]
+ nil
+ ident? x =>
+ checkVariableName x
+ ['%local,x,e]
+ nil
+ check(x,y) ==
+ x ~= nil => x
+ stackAndThrow('"invalid loop variable %1bp",[y])
+
++ Subroutine of compStepIterator.
++ We are elaborating the STEP form of a for-iterator, where all
++ bounds and increment are expected to be integer-valued expressions.
@@ -2427,21 +2448,13 @@ compIntegerValue(x,e) ==
comp(x,$NonNegativeInteger,e) or
compOrCroak(x,$Integer,e)
-++ Issue a diagnostic if `x' names a loop variable with a matching
-++ declaration or definition in the enclosing scope.
-complainIfShadowing(x,e) ==
- $loopKind = 'COLLECT => nil -- collect loop variables always shadow
- if getmode(x,e) ~= nil then
- $mayHaveFreeIteratorVariables := true -- bound in compRepeatOrCollect
- stackWarning('"loop variable %1b shadows variable from enclosing scope",[x])
-
++ Attempt to compile a `for' iterator of the form
++ for index in start..final by inc
++ where the bound `final' may be missing.
compStepIterator(index,start,final,inc,e) ==
- checkVariableName index
- complainIfShadowing(index,e)
- $formalArgList := [index,:$formalArgList]
+ [sc,index,e] := classifyIteratorVariable(index,e)
+ if sc = '%local then
+ $formalArgList := [index,:$formalArgList]
[start,startMode,e] := compIntegerValue(start,e) or return
stackMessage('"start value of index: %1b must be an integer",[start])
[inc,incMode,e] := compIntegerValue(inc,e) or return
@@ -2456,38 +2469,42 @@ compStepIterator(index,start,final,inc,e) ==
if get(index,"mode",e) = nil then
[.,.,e] := compMakeDeclaration(index,indexMode,e) or return nil
e := giveVariableSomeValue(index,indexMode,e)
- [["STEP",index,start,inc,:final],e]
+ [["STEP",[sc,:index],start,inc,:final],e]
+compINIterator(x,y,e) ==
+ [sc,x,e] := classifyIteratorVariable(x,e)
+ --these two lines must be in this order, to get "for f in list f"
+ --to give an error message if f is undefined
+ [y',m,e]:= comp(y,$EmptyMode,e) or return nil
+ if sc = '%local then
+ $formalArgList := [x,:$formalArgList]
+ [mOver,mUnder]:=
+ modeIsAggregateOf("List",m,e) or return
+ stackMessage('"mode: %1pb must be a list of some mode",[m])
+ if null get(x,"mode",e) then [.,.,e]:=
+ compMakeDeclaration(x,mUnder,e) or return nil
+ e:= giveVariableSomeValue(x,mUnder,e)
+ [y'',m'',e] := coerce([y',m,e], mOver) or return nil
+ [["IN",[sc,:x],y''],e]
+
+compONIterator(x,y,e) ==
+ [sc,x,e] := classifyIteratorVariable(x,e)
+ if sc = '%local then
+ $formalArgList := [x,:$formalArgList]
+ [y',m,e]:= comp(y,$EmptyMode,e) or return nil
+ [mOver,mUnder]:=
+ modeIsAggregateOf("List",m,e) or return
+ stackMessage('"mode: %1pb must be a list of other modes",[m])
+ if null get(x,"mode",e) then [.,.,e]:=
+ compMakeDeclaration(x,m,e) or return nil
+ e:= giveVariableSomeValue(x,m,e)
+ [y'',m'',e] := coerce([y',m,e], mOver) or return nil
+ [["ON",[sc,:x],y''],e]
+
compIterator(it,e) ==
-- ??? Allow for declared iterator variable.
- it is ["IN",x,y] =>
- checkVariableName x
- complainIfShadowing(x,e)
- --these two lines must be in this order, to get "for f in list f"
- --to give an error message if f is undefined
- [y',m,e]:= comp(y,$EmptyMode,e) or return nil
- $formalArgList:= [x,:$formalArgList]
- [mOver,mUnder]:=
- modeIsAggregateOf("List",m,e) or return
- stackMessage('"mode: %1pb must be a list of some mode",[m])
- if null get(x,"mode",e) then [.,.,e]:=
- compMakeDeclaration(x,mUnder,e) or return nil
- e:= giveVariableSomeValue(x,mUnder,e)
- [y'',m'',e] := coerce([y',m,e], mOver) or return nil
- [["IN",x,y''],e]
- it is ["ON",x,y] =>
- checkVariableName x
- complainIfShadowing(x,e)
- $formalArgList:= [x,:$formalArgList]
- [y',m,e]:= comp(y,$EmptyMode,e) or return nil
- [mOver,mUnder]:=
- modeIsAggregateOf("List",m,e) or return
- stackMessage('"mode: %1pb must be a list of other modes",[m])
- if null get(x,"mode",e) then [.,.,e]:=
- compMakeDeclaration(x,m,e) or return nil
- e:= giveVariableSomeValue(x,m,e)
- [y'',m'',e] := coerce([y',m,e], mOver) or return nil
- [["ON",x,y''],e]
+ it is ["IN",x,y] => compINIterator(x,y,e)
+ it is ["ON",x,y] => compONIterator(x,y,e)
it is ["STEP",index,start,inc,:optFinal] =>
compStepIterator(index,start,optFinal,inc,e)
it is ["WHILE",p] =>