Hints for Implementing repeat

A repeat statement,

(repeat <num expr> <stmt 1> <stmt 2>...<stmt N>)

is interpreted as follows:

Detailed Example

In actuality, repeat is a macro in LOBO. Remember how macros in Scheme worked? Scheme evaluates the following program

(let ((x 2)) (+ x x)) by expanding it into an equivalent program ((lambda (x) (+ x x)) 2) and then evaluating the equivalent program. Well repeat works the same way in LOBO. Let's look at an example in detail. The program stack is initialized to the program to be interpreted and the graphic accumulator is initialized to the null graphic object:

program stack graphic accumulator
((repeat 4 (pendown) (forward 5) (penup) (forward 5) ) )

LOBO recognizes the repeat keyword, so it calls itself on a program stack which has been expanded to look like this:

program stack graphic accumulator
((pendown) (forward 5) (penup) (forward 5) (repeat 3 (pendown) (forward 5) (penup) (forward 5) ) )

After the first four statements on the top of the program stack have been interpreted, i.e., ((pendown)(forward 5)(penup)(forward 5)), the program stack and graphic accumulator look like this:

program stack graphic accumulator
((repeat 3 (pendown) (forward 5) (penup) (forward 5) ) )

LOBO recognizes the repeat keyword, so it calls itself on a program stack which has been expanded to look like this:

program stack graphic accumulator
((pendown) (forward 5) (penup) (forward 5) (repeat 2 (pendown) (forward 5) (penup) (forward 5) ) )

After the first four statements on the top of the program stack are interpreted, i.e., ((pendown)(forward 5)(penup)(forward 5)), the program stack and graphic accumulator look like this:

program stack graphic accumulator
((repeat 2 (pendown) (forward 5) (penup) (forward 5) ) )

LOBO recognizes the repeat keyword, so it calls itself on a program stack which has been expanded to look like this:

program stack graphic accumulator
((pendown) (forward 5) (penup) (forward 5) (repeat 1 (pendown) (forward 5) (penup) (forward 5) ) )

After the first four statements on the top of the program stack are interpreted, i.e., ((pendown)(forward 5)(penup)(forward 5)), the program stack and graphic accumulator look like this:

program stack graphic accumulator
((repeat 1 (pendown) (forward 5) (penup) (forward 5) ) )

LOBO recognizes the repeat keyword, so it calls itself on a program stack which has been expanded to look like this:

program stack graphic accumulator
((pendown) (forward 5) (penup) (forward 5) (repeat 0 (pendown) (forward 5) (penup) (forward 5) ) )

After the first four statements on the top of the program stack are interpreted, i.e., ((pendown)(forward 5)(penup)(forward 5)), the program stack and graphic accumulator look like this:

program stack graphic accumulator
((repeat 0 (pendown) (forward 5) (penup) (forward 5) ) )

LOBO recognizes the repeat keyword. But repeat's argument is zero, so it calls itself on the cdr of the program stack:

program stack graphic accumulator
()

which is just the empty list. Consequently, LOBO is done, and it returns the value of the graphic accumulator.