17.6.2.2141
REPLACES
 
STRING EXT
 
( c-addr1 u1 c-addr2 u2 -- )

Set the string c-addr1 u1 as the text to substitute for the substitution named by c-addr2 u2. If the substitution does not exist it is created. The program may then reuse the buffer c-addr1 u1 without affecting the definition of the substitution.

Ambiguous conditions occur as follows:

  • The substitution cannot be created;
  • The name of a substitution contains the `%' delimiter character.

REPLACES may allot data space and create a definition. This breaks the contiguity of the current region and is not allowed during compilation of a colon definition

Implementation:
DECIMAL

[UNDEFINED] place [IF]
   : place    \ c-addr1 u c-addr2 --
   \ Copy the string described by c-addr1 u as a counted
   \ string at the memory address described by c-addr2.
     2DUP 2>R
     1 CHARS + SWAP MOVE
     2R> C!
   ;
[THEN]

: "/COUNTED-STRING" S" /COUNTED-STRING" ;
"/COUNTED-STRING" ENVIRONMENT? 0= [IF] 256 [THEN]
CHARS CONSTANT string-max

WORDLIST CONSTANT wid-subst
\ Wordlist ID of the wordlist used to hold substitution names and replacement text.

[DEFINED] VFXforth [IF] \ VFX Forth
   : makeSubst \ c-addr len -- c-addr
   \ Given a name string create a substution and storage space.
   \ Return the address of the buffer for the substitution text.
   \ This word requires system specific knowledge of the host Forth.
   \ Some systems may need to perform case conversion here.
     GET-CURRENT >R wid-subst SET-CURRENT
     ($create)                            \ like CREATE but takes c-addr/len
     R> SET-CURRENT
     HERE string-max ALLOT 0 OVER C! \ create buffer space
   ;
[THEN]

[DEFINED] (WID-CREATE) [IF] \ SwiftForth
   : makeSubst \ c-addr len -- c-addr
     wid-subst (WID-CREATE)            \ like CREATE but takes c-addr/len/wid
     LAST @ >CREATE !
     HERE string-max ALLOT 0 OVER C! \ create buffer space
   ;
[THEN]

: findSubst \ c-addr len -- xt flag | 0
\ Given a name string, find the substitution.
\ Return xt and flag if found, or just zero if not found.
\ Some systems may need to perform case conversion here.
   wid-subst SEARCH-WORDLIST
;

: REPLACES \ text tlen name nlen --
\ Define the string text/tlen as the text to substitute for the substitution named name/nlen.
\ If the substitution does not exist it is created.
   2DUP findSubst IF
     NIP NIP EXECUTE    \ get buffer address
   ELSE
     makeSubst
   THEN
   place                  \ copy as counted string
;