[comp.lang.modula2] Need Help With 'BY'

BJ020000@NDSUVM1.BITNET (Dave Mueller) (01/04/91)

I'm trying to write a FOR loop that needs a 'nonconstant' BY, for example:

IF Case = 1 THEN
   Begin := 0;
   End := Length(Line)-1;
   By := 1;
ELSE
   Begin := Length(Line)-1;
   End := 0;
   By := -1;
END;

FOR Loop := Begin TO End BY By DO
etc..


Any suggestions as to how I go about doing this in a FOR Loop???  Or am I gonna
end up doing it some other way??

Thanx much!

Dave Mueller

josef@nixpbe.nixdorf.de (josef Moellers) (01/07/91)

In <91003.102704BJ020000@NDSUVM1.BITNET> BJ020000@NDSUVM1.BITNET (Dave Mueller) writes:


>I'm trying to write a FOR loop that needs a 'nonconstant' BY, for example:

>IF Case = 1 THEN
>   Begin := 0;
>   End := Length(Line)-1;
>   By := 1;
>ELSE
>   Begin := Length(Line)-1;
>   End := 0;
>   By := -1;
>END;

>FOR Loop := Begin TO End BY By DO
>etc..


>Any suggestions as to how I go about doing this in a FOR Loop???  Or am I gonna
>end up doing it some other way??

My version of PIM (3rd corrected ed.) states:

(Page 158, "Report on The Programming Language Modula-2":)
9.8 For Statements
... Its [the variable's] value should not be changed by the statement
sequence.
... C [the increment/decrement] must be a constant of type INTEGER or
CARDINAL.

(Page 172, "Appendix 1, The Syntax of Modula-2":)
ForStatement = FOR ident ":=" expression TO expression
	[BY ConstExpression] DO StatementSequence END.
	    ^^^^^

So, Your pretty much out of luck. I see two possibilities:
1 You make it two FOR-statements with an IF-statement selecting between
  both (You could put it into the CASE)
2 Use a WHILE-statement:

	replace

  FOR Loop := Begin TO End BY By DO

	by

  Loop := Begin;
  WHILE Loop <= End DO
     <statements>
     INC(Loop, By);
  END;

>Thanx much!

>Dave Mueller

Josef Moellers
--
| Josef Moellers		| c/o Siemens Nixdorf Informationssysteme AG |
|  USA: mollers.pad@nixdorf.com	| Abt. STO-XS 113			     |
| !USA: mollers.pad@nixdorf.de	| Heinz-Nixdorf-Ring			     |
| Phone: (+49) 5251 104662	| D-4790 Paderborn			     |

schoebel@bs3.informatik.uni-stuttgart.de (Thomas Schoebel) (01/14/91)

In article <josef.663236830@ugum01> josef@nixpbe.nixdorf.de (josef Moellers) writes:
>
>	replace
>
>  FOR Loop := Begin TO End BY By DO
>
>	by
>
>  Loop := Begin;
>  WHILE Loop <= End DO
>     <statements>
>     INC(Loop, By);
>  END;

Danger!

This will not work! If By is negative, the loop is intended to
count backward and normally Begin > End. The above code
will never execute the loop in this case!

So the WHILE condition should read Loop>=End if By is negative,
and Loop<=End otherwise. There are once again two possibilities:

1) Use two different WHILE loops with different conditions. But
   then you have to repeat the <statements> inside the WHILE body twice.
   Also, there is no advantage against using the FOR version.

2) Replace the While condition by Loop <> End. To get correct results,
   the End variable has to be modified one step before the WHILE loop
   begins. Also, the special case of never executing the FOR loop
   has to be treated separately. This code is:

  IF ((By>0) AND (Begin<=End)) OR ((By<0) AND (Begin>=End)) THEN
    INC (End, By);
    Loop:=Begin;
    WHILE Loop <> End DO
      <statements>
      INC (Loop, By);
    END;
  END;

This version avoids to copy the <statements> twice and will give
relative good performance.

Thomas

Thomas Sch"obel, Institut f"ur Informatik, Universit"at Stuttgart
Internet: schoebel@ifi.informatik.uni-stuttgart.de
Phone: +49 711 121-1409