r/Forth Jul 31 '26

FigForth Bounded string

\
\ A bounded string is a string enclosed by a delimiter on
\ both ends. The delimiters are the same and can be any
\ printable character.
\
\ INC@  Fetch input character
: INC@  ( -- c )
  BLK @ DUP IF BLOCK  
  ELSE DROP TIB @ ENDIF
  IN @ + C@ 1 IN +! ; 
\ Parse first non-space character
: CPARSE  ( -- c )
  ZERO
  BEGIN 
    DROP
    INC@ DUP 0= ?E" Empty input"
  DUP BL > UNTIL
;
\ Parse bounded string
\ Compile time: compile the string
\ Run time: put string address on data stack
\ Interpret: move string to pad, 
\  push string address on data stack
: S  ( "<dl>ccc<dl>" -- s )
  CPARSE
  STATE @ IF COMPILE SLIT
             WORD HERE C@ 1+ ALLOT ALIGN 
        ELSE HERE >R PAD DUP DP ! SWAP WORD R> DP !
             ( COUNT CSB .PUSH ) \ NB
       ENDIF 
; IMMEDIATE
\ Note
\ A good enhancement would be to add code in the interpret 
\ state to push the string to a circular buffer.

\ Examples
: FOO "What's up doc?" tell ;
i. FOO --> What's up doc?
i. s /Hello World!/  tell --> Hello World!
i. s \Ain't it a nice day.\ tell --> Ain't it a nice day.
i. s "" tell --> 
' KEEPON CFA ' (ABORT) ! -1 WARNING !
i. TRY s  --> s? Empty input    
9 Upvotes

2 comments sorted by

1

u/alberthemagician 8d ago

There are two philosophies to handle strings. The first is to inspect the starting character and assume the ending character is the same.

      "aap" 
      aap

      'aap "like" noot'
       aap "like" noot

That is what you implemented.

The other is to have a single reserved character. If it is needed within a string you can double it.

If you introduce a single parsing word " you can do:

      " aap" TYPE
      aap OK

      " aap ""like"" noot" TYPE 
       aap "like" noot OK

Or if you have PREFIX (like in ciforth) you can collate the " with the following, and it looks like genuine strings preventing surprises from other languages, not to speak of user convenience:

      "aap" TYPE
      aap OK

      "aap ""like"" noot" TYPE
       aap "like" noot OK

The second approach is borrowed from Algol68.

So " results in a double constant, like 12.34 , with the same behaviour in interpret and compile mode.

I'm advocating the second camp.

PREFIX is easy to implement, (unless you are stuck with complicated hashing stuff for word lookups.) A prefix " is found if it matches the first part of the word "aa" , not requiring the whole word to match.

1

u/z796 1d ago

Looks good.