From 7dff09b8cac803d6936887fdfa286a2a25073ac2 Mon Sep 17 00:00:00 2001 From: dos-reis Date: Sun, 14 Aug 2011 21:23:34 +0000 Subject: * 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. --- src/interp/compiler.boot | 101 +++++++++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 42 deletions(-) (limited to 'src/interp/compiler.boot') 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] => -- cgit v1.2.3