home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.forth      Forth programmers eat a lot of Bratwurst      117,927 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 117,681 of 117,927   
   Gerry Jackson to All   
   Iterator using [ELSE]   
   04 Nov 25 21:36:40   
   
   From: do-not-use@swldwa.uk   
      
   HunptyDumpty introduced his Y Combinator in this post:   
   https://groups.google.com/g/comp.lang.forth/c/ea59-OtiLvE/m/TH_8t9c7BgAJ   
   with the definition   
   : yc  ( .. xt xt |0 -- .. ) begin while execute repeat  ;   
      
   An example from HD's post:   
   : downcount dup . 1- dup 0 >= IF xt dup ELSE 0 THEN ;   
   where xt is the execution token of downcount.   
      
   Having experimented with iterators to avoid having to get the xt of a   
   word I tried using a quotation:   
      
   : foo  [:  ;] yc  ;   
      
   and developed a word ITERATOR-YC to generate the boiler-plate code   
   around a word such as DOWNCOUNT. This was rather complicated.   
      
   After that I realised that moving the BEGIN from YC to precede the   
   quotation led to a more flexible iterator in that the code inside the   
   quotation can exit in three ways   
   1. naturally at the end of the quotation with TRUE on the stack   
   2. EXIT with 0 on the stack to exit the iterator   
   3. EXIT with TRUE on the stack to prematurely start another iteration.   
      
   Much like a multi-WHILE loop but better.   
      
   Last week in the Conditional Compilation discussion, having shown how   
   [ELSE] could be used as a general purpose word to skip over lines of   
   text or code e.g. for a multi-line comment, I realised that this could   
   greatly simplify ITERATOR-YC so that a definition for DOWNCOUNT could be   
   defined as:   
      
   iterator: downcount dup 0< if drop 0 exit then dup . 1- true  ;iterator   
      
   where  iterator: ... ;iterator compiles the following code   
      
   : downcount true begin [: dup 0< if drop 0 exit then dup . 1- true :]   
                     swap while execute repeat drop   
      
      
   The implementation follows   
   \ ------------------------   
      
   : ]]        \ Single line postponer, avoids POSTPONE clutter   
       begin   
          >in @ parse-name s" [[" compare   
       while   
          >in ! postpone postpone   
       repeat drop   
    immediate   
      
   \ Ruvim's reference code for [IF] [THEN] [ELSE]   
   wordlist dup constant bracket-flow-wl  get-current swap set-current   
      
   : [if]   ( level1 -- level2 ) 1+ ;   
   : [else] ( level1 -- level2 ) dup 1 = if 1- then ;   
   : [then] ( level1 -- level2 ) 1- ;   
      
   : ;iterator 1- ;   
   : \  postpone \  ;   
      
   set-current   
      
   : [else] ( -- )   
       1 begin begin parse-name   
       dup while   
          bracket-flow-wl search-wordlist if   
             execute dup 0= if drop exit then   
          then   
       repeat 2drop refill 0= until drop   
      
   : [then] ( -- ) ; immediate   
      
   : [if] ( flag -- ) 0= if postpone [else] then ; immediate   
      
   \ The iterator compiler   
      
   synonym scan-words [else]   
      
   : iterator:  ( "name" -- xt ) \ xt of quotation   
       : ]] true begin [: [[   
       save-input ]] scan-words [[ restore-input   
       abort" Error: RESTORE-INPUT failed"   
      
      
   : ;iterator  ( xt -- ) ]] ;] swap while execute repeat drop ; [[  ;   
   immediate   
      
   \ Example   
   iterator: downcount dup 0< if drop 0 exit then dup . 1- true  ;iterator   
      
   cr 10 downcount \ displays 10 9 8 7 6 5 4 3 2 1 0   
      
   \ ------------------------   
      
   Note this code will only work from a file as SAVE-INPUT is not   
   guaranteed to work from a keyboard.   
      
   ITERATOR: starts the definition and quotation, then SAVE-INPUT   
   and SCAN-WORDS scan past the quotation code until the first definition   
   of ;ITERATOR stops the scanning.   
   RESTORE-INPUT returns control to the start of the downcount code which   
   compiles the downcound code until the second definition of ;ITERATOR   
   compiles the rest of the boiler-plate code.   
      
   A definition of [ELSE] that took an xt as an input to define an action   
   if the SEARCH-WORDLIST fails would be a better scanner. This is simple   
   to add.   
      
      
      
   --   
   Gerry   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca