Search code examples
forthlanguage-implementation

How is Forth LEAVE ... LOOP implemented, since number of LEAVEs is not known beforehand?


The word LOOP is described as "Resolve the destination of all unresolved occurrences of LEAVE". (emphasis mine)

Unlike IF ... ELSE ... THEN, where the number of forward references is always one, LOOP has no constraints on the quantity of LEAVE. How to implement it then?

One approach I thought of is to always keep the number of LEAVEs on top of the stack. Each LEAVE increments this counter and puts itself under it. LOOP reads the counter from the top and resolves that many references. But it seems like a cheap trick.

How do real Forth systems implement this kind of loop? I don't need teh codez (been implementing Forth as a learning experience), just the concepts.


Solution

  • In SP-Forth the loop control parameters comprise the index, limit, and address after LOOP. So, no need to resolve LEAVE at compile time, it knows the address from the loop control parameters at run-time.

    Another approach is to store the control-flow stack depth on DO, place the unresolved forward reference on the control-flow stack under all other already placed values (using the stored depth) on LEAVE, and then resolve all the placed forward references on LOOP.

    See my high-level implementation of DO LOOP on the basis of BEGIN UNTIL and AHEAD THEN (spoiler warning).