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