forth

Semantic of double WHILE


According to Forth Standard, you can implement PARSE-NAME using a combination of words that include this xt-skip:

: xt-skip ( addr1 n1 xt -- addr2 n2 )
   \ skip all characters satisfying xt ( c -- f )
   >R
   BEGIN
     DUP
   WHILE
     OVER C@ R@ EXECUTE
   WHILE
     1 /STRING
   REPEAT THEN
   R> DROP ; 

I can't understand what the double WHILE do. Can someone explain it to me?


Solution

  • The section A.3.2.3.2 Control-flow stack describes in length how control-flow words work.

    Let's add stack diagrams of compile time to the xt-skip definition:

    : xt-skip   ( C:                                -- colon-sys )
       >R
       BEGIN    ( C: colon-sys                      -- colon-sys dest )
         DUP
       WHILE    ( C: colon-sys dest                 -- colon-sys orig.1 dest )
         OVER C@ R@ EXECUTE
       WHILE    ( C: colon-sys orig.1 dest          -- colon-sys orig.1 orig.2 dest )
         1 /STRING
       REPEAT   ( C: colon-sys orig.1 orig.2 dest   -- colon-sys orig.1 )
       THEN     ( C: colon-sys orig.1               -- colon-sys )
       R> DROP
    ;           ( C: colon-sys                      -- )
    

    In stack diagrams, "C:" is a stack-id of the control-flow stack. The symbols colon-sys, orig, dest are data type symbols, and an optional index (delimited by a dot) is used to unambiguously refer a stack parameter in the corresponding stack position.

    The compilation semantics for WHILE just place an orig under the top parameter (that shall be a dest). So, after the second WHILE we have two parameters of the orig type (in the positions orig.1 and orig.2).

    The compilation semantics for REPEAT consumes a pair ( orig dest ) from the top of the stack. So one orig parameter remains on the stack. THEN consumes this orig parameter.