+ 'S double-quote' (not 'S backslash double-quote').]
+
+ S\" string\" is used in FORTH to define strings. It leaves the address of the string and
+ its length on the stack with the address at the top.
+
+ In compile mode we append
+ LITSTRING <string length> <string rounded up 4 bytes>
+ to the current word. The primitive LITSTRING does the right thing when the current
+ word is executed.
+
+ In immediate mode there isn't a particularly good place to put the string, but in this
+ case we put the string at HERE (but we _don't_ change HERE). This is meant as a temporary
+ location, likely to be overwritten soon after.
+)
+: S\" IMMEDIATE ( -- len addr )
+ STATE @ IF ( compiling? )
+ ' LITSTRING , ( compile LITSTRING )
+ HERE @ ( save the address of the length word on the stack )
+ 0 , ( dummy length - we don't know what it is yet )
+ BEGIN
+ KEY ( get next character of the string )
+ DUP '\"' <>
+ WHILE
+ HERE @ !b ( store the character in the compiled image )
+ 1 HERE +! ( increment HERE pointer by 1 byte )
+ REPEAT
+ DROP ( drop the double quote character at the end )
+ DUP ( get the saved address of the length word )
+ HERE @ SWAP - ( calculate the length )
+ 4- ( subtract 4 (because we measured from the start of the length word) )
+ SWAP ! ( and back-fill the length location )
+ HERE @ ( round up to next multiple of 4 bytes for the remaining code )
+ 3 +
+ 3 INVERT AND
+ HERE !
+ ELSE ( immediate mode )
+ HERE @ ( get the start address of the temporary space )
+ BEGIN
+ KEY
+ DUP '\"' <>
+ WHILE
+ OVER !b ( save next character )
+ 1+ ( increment address )
+ REPEAT
+ HERE @ - ( calculate the length )
+ HERE @ ( push the start address )
+ THEN
+;