2.5 Simple parsing

We have already discussed 'REFILL' a bit. We've seen that it is closely related to 'ACCEPT'. 'REFILL' returns a true flag if all is well. When you use the keyboard it usually is, so we can safely drop it, but we will encounter a situation where this flag comes in handy.

If you want to get a string from the keyboard, you only have to type:

     refill drop                   \ get string from keyboard

Every next call to 'REFILL' will overwrite any previously entered string. So if you want to do something with that string you've got to get it out of there, usually to one of your own strings.

But if accessing the TIB directly is not the proper way, what is? The use of 'REFILL' is closely linked to the word 'WORD', which is a parser. 'WORD' looks for the delimiter, whose ASCII code is on the stack.

If the string starts with the delimiter, it will skip this and all subsequent occurences until it finds a string. Then it will look for the delimiter again and slice the string right there. It then copies the sliced string to PAD and returns its address.

This extremely handy when you want to obtain filtered input. E.g. when you want to split somebodies name into first name, initials and lastname:

     Hans L. Bezemer

Just use this program:

     ." Give first name, initials, lastname: "
     refill drop                   \ get string from keyboard
     bl word                       \ parse first name
     ." First name: "              \ write message
     count type cr                 \ type first name
     bl word                       \ parse initials
     ." Initials  : "              \ write message
     count type cr                 \ type initials
     bl word                       \ parse last name
     ." Last name : "              \ write message
     count type cr                 \ write last name

You don't have to parse the entire string with the same character. This program will split up an MS-DOS filename into its components:

     ." DOS filename: " refill          \ input a DOS filename
     drop cr                       \ get rid of the flag

     char : word                   \ parse drive
     ." Drive: " count type ." :" cr
                                   \ print drive
     begin
          char \ word              \ parse path
          count 0<>                \ if not a NULL string
     while                         \ print path
          ." Path : " count type cr
     repeat                        \ parse again
     drop                          \ discard address

If 'WORD' reaches the end of the string and the delimiter is still not found, it returns the remainder of that string. If you try to parse beyond the end of the string, it returns a NULL string. That is an empty string or, in other words, a string with length zero.

Therefore, we checked whether the string had zero length. If it had, we had reached the end of the string and further parsing was deemed useless.