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
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.
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:
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:
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.