EMPTY$
( $: -- empty$ )
=> [FORTH]
Push the MSA of a fixed, external representation of the empty
string onto the string stack. "empty-string"
primitive code = [p4_empty_str]
\n$
( $: -- newline$ )
=> [FORTH]
Push the MSA of a fixed, external string whose body is the
Unix newline character onto the string stack.
"newline-string"
primitive code = [p4_newline_str]
(M!)
=> [FORTH]
(no description)
primitive code = [p4_parens_m_store]
PARSE>S
( [ccc<char>] char -- addr len )
=> [FORTH]
Parse the input stream up to the first occurrence of char,
which is parsed away. If executing in compilation mode,
append run-time semantics to the current definition that
leaves the ANS Forth string representation on the stack. In
interpretation mode, leave the ANS Forth string
representation for a stored copy, which may be transient in
the style of S
". In either mode, the format of the
stored string is implementation dependent.
"parse-to-s"
NOTE: The interpreted copy is a nontransient in this
implementation, and both copies are mstrings.
primitive code = [p4_parse_to_s]
S`
( [ccc<`>] -- addr len )
=> [FORTH]
An immediate version of parse>s where the delimiter is `. In
particular, the stored string in interpret mode is not
transient. "s-back-tick"
compiling word = [p4_s_back_tick]
M,S
( addr len -- addr' len )
=> [FORTH]
ALLOT room and store the ANS Forth string into aligned data
space as an mstring, leaving data space zero-filled to
alignment; and leave the length and new body address. It is
assumed that len is unsigned. An error is thrown if len is
larger than the system parameter MAX_DATA_STR
.
"m-comma-s"
NOTE: MAX_DATA_STR
is returned by
S" /SCOPY" ENVIRONMENT?
NOTE: M,S
differs from STRING,
in Wil Baden's Tool
Belt in that it stores an aligned, measured string with
zero-filled alignment instead of a counted string, and it
leaves the ANS Forth string representation of the stored
string.
primitive code = [p4_m_comma_s]
MCOUNT@
( msa -- count )
=> [FORTH]
Fetch the count of the mstring at msa.
"m-count-fetch"
primitive code = [p4_m_count_fetch]
MCOUNT!
( count msa -- )
=> [FORTH]
Store the count in the measured string count field at msa,
without checking that it fits.
"m-count-store"
primitive code = [p4_m_count_store]
MCOUNT
( msa -- body.addr count )
=> [FORTH]
Convert the mstring MSA to its ANS Forth string
representation. "m-count"
primitive code = [p4_m_count]
-MCOUNT
( addr len -- msa )
=> [FORTH]
Convert the ANS Forth representation of an mstring to its
MSA. "minus-m-count"
primitive code = [p4_minus_m_count]
($:
=> [FORTH]
(no description)
immediate code = [p4_paren]
0STRINGS
( -- )
=> [FORTH]
Set all string variables holding bound string values in string
space to the empty string, and clear string space, including
the string buffer, string stack, and string stack frames.
"zero-strings"
NOTE: If used for under the hood development, this word must
be executed only when string space is in a valid state.
primitive code = [p4_zero_strings]
$GARBAGE?
( -- flag )
=> [FORTH]
Leave true if there is garbage in the current string space.
Not normally used, since garbage collection is transparent.
"string-garbage-question"
primitive code = [p4_str_garbage_Q]
$GC-OFF
( -- )
=> [FORTH]
Disable garbage collection in the current string space. An
error will be thrown if garbage collection is attempted.
"string-g-c-off"
primitive code = [p4_str_gc_off]
$GC-ON
( -- )
=> [FORTH]
Enable garbage collection in the current string space. This
is the default. "string-g-c-on"
primitive code = [p4_str_gc_on]
$GC-LOCK@
( -- flag )
=> [FORTH]
Fetch the dstring garbage collection "off" state. Intended
for saving the off state for later restoration after a usage
of $GC-ON
or $GC-OFF
.
"string-g-c-lock-fetch"
primitive code = [p4_str_gc_lock_fetch]
$GC-LOCK!
( flag -- )
=> [FORTH]
Set the dstring garbage collection "off" state according to
flag. Intended for restoring the off state previously
fetched by $GC-LOCK@
.
"string-g-c-lock-fetch"
primitive code = [p4_str_gc_lock_store]
$UNUSED
( -- u )
=> [FORTH]
Leave the number of bytes available for dynamic strings and
string stack entries in the string buffer.
"string-unused"
primitive code = [p4_str_unused]
COLLECT-$GARBAGE
( -- collected-flag )
=> [FORTH]
If string space is not marked as containing garbage, return
false. If there is garbage, throw an error when garbage
collection is disabled. Otherwise remove the garbage and
return true. Garbage collection is "transparent", so the
user would not normally use this word.
"collect-string-garbage"
primitive code = [p4_collect_str_garbage]
MAKE-$SPACE
( size #frames -- addr )
=> [FORTH]
Allocate and initialize a string space with size bytes
available for the string buffer including the string stack,
and with a string frame stack for frame description entries
holding up to #frames. The size is rounded up to cell
alignment, and the buffer begins and ends with cell alignment.
Return addr, the address of the string space. The standard
word FREE
with addr as input can be used to release the space.
"make-string-space"
primitive code = [p4_make_str_space]
/$BUF
( -- u )
=> [FORTH]
Leave the size in address units allocated for the current
string buffer. "slash-string-buf"
primitive code = [p4_slash_str_buf]
MAX-#$FRAMES
( -- u )
=> [FORTH]
Leave the number of string frames allowed on the string frame
stack for the current string space.
"max-number-string-frames"
primitive code = [p4_max_num_str_frames]
$!
( $var.dfa $: a$ -- )
=> [FORTH]
Store the string MSA on the string stack in the variable
whose DFA is on the parameter stack.
"string-store"
NOTES: The only situation in which $!
copies the string
value is when it is a bound string already stored in another
variable. In that case, the new copy is the one that is
stored in the variable. In particular, external strings are
not copied.
If the string value held by the string variable on entry is a
bound string that is also referenced deeper on the string
stack, its back link is reset to point to the deepest string
stack reference. If it is a bound string not deeper on the
string stack and not identical to the input string, its back
link is set to zero, making it garbage. If it is an external
string, its MSA in the variable is simply written over by
that popped from the string stack.
primitive code = [p4_str_store]
$@
( $var.pfa -- $: a$ )
=> [FORTH]
Leave the MSA of the string held by the string variable.
"string-fetch"
primitive code = [p4_str_fetch]
(M$:)
=> [FORTH]
(no description)
compiling word = [p4_marg_execution]
$"
( [ccc<">] -- $: str )
=> [FORTH]
Parse ccc delimited by " (double quote) and store it in data
space as an mstring. If interpreting, leave the MSA on the
string stack. If compiling, append run-time semantics to the
current definition that leaves the MSA on the string stack.
A program should not alter the stored string. An error is
thrown if the quoted string length is larger than the system
parameter MAX_DATA_STR
(see SM,
).
"string-quote"
NOTE: In contrast to S"
, the string stored by $"
when
interpreting is not transient.
The implementation is based on PFE code for S"
.
compiling word = [p4_str_quote]
$`
( [ccc<`>] -- $: str )
=> [FORTH]
Parse ccc delimited by ` (back-tick). This is "$""
with
back tick instead of double quote as the delimiter.
"string-back-tick"
compiling word = [p4_str_back_tick]
$VARIABLE
( "name" -- )
=> [FORTH]
"name" execution: ( -- dfa )
Create an ordinary Forth variable and initialize it to the
address of a fixed, external, measured representation of the
empty string, such as that pushed onto the string stack by
EMPTY$
. "string-variable""
primitive code = [p4_str_variable]
PARSE>$
( [ccc<char>] char -- $: ccc$ )
=> [FORTH]
Parse the input stream up to the first occurrence of char,
which is parsed away, and store the string as an external
measured string. If executing in compilation mode, append
run-time semantics to the current definition that leaves the
MSA on the string stack. In interpretation mode, leave the
MSA on the string stack, where the stored copy, unlike
PARSE>S
, is required to be nontransient.
primitive code = [p4_parse_to_str]
$.
( $: a$ -- )
=> [FORTH]
Display the string on the terminal. If the system
implementation of TYPE has its output vectored, $. uses the
same vector. "string-dot"
primitive code = [p4_str_dot]
$2DROP
( $: a$ b$ -- )
=> [FORTH]
Drop the two topmost string stack entries, marking them as
garbage if appropriate. "string-two-drop"
primitive code = [p4_str_two_drop]
$2DUP
( $: a$ b$ -- a$ b$ a$ b$ )
=> [FORTH]
Leave copies of the two topmost string stack entries. The string
values are not copied. "string-two-dupe"
primitive code = [p4_str_two_dup]
$DEPTH
( -- n )
=> [FORTH]
Leave the number of items on the string stack.
"string-depth"
primitive code = [p4_str_depth]
$DROP
( $: a$ -- )
=> [FORTH]
Drop the topmost string stack entry, marking it as garbage if
it is initially bound to the top of the string stack.
"string-drop"
primitive code = [p4_str_drop]
$DUP
( $: a$ -- a$ a$ )
=> [FORTH]
Leave a copy of the topmost string stack entry. The string
value is not copied. "string-dupe"
primitive code = [p4_str_dup]
$NIP
($: a$ b$ -- b$ )
=> [FORTH]
Drop the next to top item from the string stack.
"string-nip"
NOTE: Because of essential string space bookkeeping, the
system level implementation can be little more efficient than
the high-level definition:
: $NIP $SWAP $DROP ;
primitive code = [p4_str_nip]
$OVER
( $: a$ b$ -- a$ b$ a$ )
=> [FORTH]
Leave a copy of the next most accessible string stack entry
on top of the string stack. The string value is not copied.
"string-over"
primitive code = [p4_str_over]
$PICK
( u $: au$ ... a0$ -- au$ ... a0$ au$ )
=> [FORTH]
Copy the u-th string stack entry to the top of the string
stack. The string value is not copied. Throw an error if
the input string stack does not have at least u+1 items.
"string-pick"
primitive code = [p4_str_pick]
$SWAP
( $: a$ b$ -- b$ a$ )
=> [FORTH]
Exchange the two most accessible strings on the string stack.
Throw an error if there are less than two strings on the
stack. Neither string value is copied.
"string-swap"
primitive code = [p4_str_swap]
$EXCHANGE
( i j -- )
=> [FORTH]
($: maxth$ ... minth$ ... -- minth$ ... maxth$ ... )
Exchange the ith and jth strings on the string stack, where
the top is the 0th. Throw an error if there are not at least
max[i,j] + 1 strings on the stack. Neither string value is
copied.
"string-exchange"
primitive code = [p4_str_exchange]
$S>
( $: a$ -- S: a.s )
=> [FORTH]
Drop a$ from the string stack and leave it as a ANS Forth
string a.s, without copying.
"string-s-from"
WARNING: If a$ is a bound string, it may move or disappear
at the next garbage collection, making a.s invalid. This can
be avoided by sandwiching sections of code where this could
occur between $GC-OFF and $GC-ON.
primitive code = [p4_str_s_from]
$,S
( $: a$ -- S: a.s )
=> [FORTH]
Drop a$ from the string stack, copy it into data space as a
measured string, and leave it as an ANS Forth string a.s.
An error is thrown if the string length is larger than the
system parameter MAX_DATA_STR
(see M,S
).
"string-comma-s"
primitive code = [p4_str_comma_s]
$S@
( $: a$ -- a$ S: a.s )
=> [FORTH]
Leave the string stack unchanged, and leave the string body
address and length on the data stack.
"string-s-fetch"
WARNING: If a$ is a bound string, it may move at the next
garbage collection, making a.s invalid. This can be avoided
by sandwiching sections of code where this could occur
between $GC-OFF and $GC-ON.
primitive code = [p4_str_s_fetch]
$TUCK
($: a$ b$ -- b$ a$ b$ )
=> [FORTH]
Copy the top string stack item just below the second item. The
string value is not copied. "string-tuck"
NOTE: Because of essential string space bookkeeping, the
system level implementation can be little more efficient than
the high-level definition:
: $TUCK $SWAP $OVER ;
primitive code = [p4_str_tuck]
$TYPE
($: a$ -- )
=> [FORTH]
Display the string on the terminal. A deprecated $.
synonym. "string-type"
primitive code = [p4_str_dot]
>$S-COPY
( a.s -- $: a$ )
=> [FORTH]
Copy the external string value whose body address and count
are on the parameter stack into the string buffer and push it
onto the string stack. Errors are thrown if the count is
larger than MAX_MCOUNT
, if there is not enough room in string
space, even after garbage collection, or if there is an
unterminated string concatenation. The input external string
need not exist as a measured string.
"to-string-s-copy"
NOTE: MAX_MCOUNT
is the largest size the count field of a
measured string can hold, e.g., 255, 64K-1, or 4,096M-1. It
is returned by:
S" /DYNAMIC-STRING" ENVIRONMENT?
WARNING: This word should not be used when the input string
is a bound string because the copy operation may generate a
garbage collection which invalidates its MSA.
primitive code = [p4_to_str_s_copy]
>$S
( a.s -- $: a$ )
=> [FORTH]
Push the external ANS Forth string a.s onto the string
stack, without copying the string value into the string
buffer. It is an unchecked error if the Forth string a.s
is not stored as an external measured string.
"to-string-s"
WARNING: If the string value of a.s is actually in the
string buffer and not external, the push operation may
generate a garbage collection that invalidates its MSA.
primitive code = [p4_to_str_s]
$+
($: a$ -- )
=> [FORTH]
If a$ is the empty string, drop it and do nothing else.
In particular, do not start a new concatenation, which would
lock string space against new nonconcatenating copies.
Otherwise append the string body to the end of the string
currently being concatenated as the last string in the string
buffer, and update its count field. If there is no
concatenating string, start one. An error is thrown if the
size of the combined string would be larger than
MAX_MCOUNT
or if there is not enough room in string space
even after a garbage collection.
If garbage collection occurs, a$ remains valid even when
it is in the string buffer.
When there is a concatenating string, concatenation is the
only basic string operation that can copy a string into the
string buffer. "string-plus"
primitive code = [p4_str_plus]
S+
( a.s -- )
=> [FORTH]
If a.s is the empty string, drop it and do nothing else.
Append the ANS Forth string body to the end of the string
currently being concatenated as the last string in the string
buffer, and update its count field. If there is no
concatenating string, start one. An error is thrown if the
size of the combined string would be larger than MAX_MCOUNT
or if there is not enough room in string space even after a
garbage collection.
S+
is most commonly used on external strings, not
assumed to exist as mstrings. In contrast to $+
,
garbage collection could invalidate a.s if it is a dynamic
string in the string buffer. S+
can be used in that
situation if garbage collection is turned off with
$GC-OFF
.
When there is a concatenating string, concatenation is the
only basic string operation that can copy a string into the
string buffer. "s-plus"
primitive code = [p4_s_plus]
PARSE-S+
( [ccc<char>] char -- )
=> [FORTH]
Parse the input stream up to the first occurrence of char,
which is parsed away. If executing in compilation mode,
append run-time semantics to the current definition that
concatenates the characters parsed from the string.
Otherwise concatenate the characters.
"parse-s-plus"
primitive code = [p4_parse_s_plus]
ENDCAT
( -- $: cat$ | empty$ )
=> [FORTH]
If there is no concatenating string, do nothing but leave the
empty string. If there is, leave it as a string bound to the
top of the string stack, and terminate concatenation,
permitting normal copies into the string buffer.
"end-cat"
primitive code = [p4_endcat]
$+"
( [ccc<quote>] -- )
=> [FORTH]
This word is immediate. In compilation mode it appends
run-time semantics to the current definition that
concatenates the quoted string according to the specification
for $+
. In interpretation mode it concatenates the
string. An error is thrown if the length of the quoted
string is longer than the system parameter MAX_DATA_STR
(see M,S
). "string-plus-quote"
compiling word = [p4_str_plus_quote]
$+`
( [ccc<backtick>] -- )
=> [FORTH]
The same as $+"
but with back tick instead of double
quote as delimiter. "string-plus-back-tick"
compiling word = [p4_str_plus_back_tick]
#$ARGS
( -- u )
=> [FORTH]
Leave the number of entries in the topmost string frame.
Throw an error if the frame stack is empty.
"number-string-args"
primitive code = [p4_num_str_args]
$ARGS{
( arg1'$ ... argN'$ "arg1 ... argN <}>" -- )
=> [FORTH]
compilation: ( -- $: arg1$ ... argN$ )
Immediate and compilation-only.
Copy the argument strings across lines to the string buffer,
push them onto the string stack with "argN" the most
accessible, and make them into the top compile-time string
stack frame. Compile the run-time code to make an argument
frame out of the N most accessible run-time string stack
entries. Inform the system text interpreter that it should
compile run-time code for any white-space delimited argument
encountered in the text of the definition, that concatenates
the corresponding string in the run-time frame. At the
semicolon terminating the definition, drop the compile-time
argument frame and compile code to drop the run-time argument
frame.
The code between $ARGS{
... }
and the terminating
semicolon is not allowed to make a net change in the string
stack depth, because that would interfere with the automatic
dropping of the string argument frame at the semicolon.
"string-args-brace"
Syntax for defining a string macro GEORGE:
: george ($: a$ b$ c$ -- cat$ )
$ARGS{ arg1 arg2 arg3 }
cat" This is arg1: " arg1 cat" ." ENDCAT $. ;
The blank following the last argument is required. For a
macro with no arguments, $ARGS{ }
does nothing but add
useless overhead and should be omitted. Two of the
arguments in this example are ignored and could have been
left out. Note that ENDCAT
would not be legal in this
word without something like $.
to remove the concatenated
string from the string stack before the terminating
semicolon. It is normal to use an $ARGS{ }
word as a step
in a concatenation that is terminated elsewhere.
Sample syntax using the string macro george
:
$" bill" $" sue" $" marie" george $.
The resulting display is:
This is arg1: bill.
NOTE: Macro argument labels must be distinct from each other
and from any local labels that appear in the same definition,
and there is no check for that.
NOTE: At the moment the semantics of $ARGS{
is undefined
before DOES>
.
immediate code = [p4_str_args_brace]
$FRAME
( u -- )
=> [FORTH]
Push the description of a string stack frame starting at the
top of the string stack and containing u entries onto the
string frame stack. Errors are thrown if the frame stack
would overflow or if the depth of the string stack above the
top frame, if there is one, is less than u. The value u = 0
is allowed. "string-frame"
NOTE: This implementation pushes u and the string stack
pointer onto the frame stack.
primitive code = [p4_str_frame]
$FRAME-DEPTH
( -- u )
=> [FORTH]
Leave the number of string frames currently on the string
frame stack. "string-frame-depth"
primitive code = [p4_str_frame_depth]
DROP-$FRAME
($: frame*$ i*$ -- i*s )
=> [FORTH]
Drop the topmost string frame from the string frame stack,
and the corresponding strings, frame*$, from the string
stack. An error is thrown if either stack would underflow.
The cases where the frame has zero entries on the string
stack and/or there are zero or more items on the string stack
above the top frame item are handled properly.
"drop-string-frame"
primitive code = [p4_drop_str_frame]
FIND-$ARG
( s -- u true | false )
=> [FORTH]
Leave true and its index u in the top string frame if the
ANS Forth string matches an element of the frame, else leave
false. The index of the top frame element is zero.
"find-string-arg"
primitive code = [p4_find_str_arg]
TH-$ARG
( u -- $: arg$ )
=> [FORTH]
Leave the u-th string in the topmost string frame, where the
index u of the top element is zero. Throw an error if the
frame stack is empty or if the top frame contains less than
u+1 strings. "th-string-arg"
primitive code = [p4_th_str_arg]
(DROP-$FRAME)
=> [FORTH]
(no description)
compiling word = [p4_do_drop_str_frame]
$POP
( $: a$ -- s: a$)
=> [FORTH]
Abort if the string stack would underflow when popped.
Otherwise pop the top of the string stack and push it onto
the data stack.
If the string is in the current string space and initially
bound to the top of the string stack, mark it as garbage by
setting its back link to NULL
and set the garbage flag.
This word violates the rule that only ANS Forth strings
should appear on the data stack, and so is under the hood.
"string-pop"
primitive code = [p4_str_pop]
$PUSH-EXT
( a$ -- $: a$ )
=> [FORTH]
Pop an external mstring address from the data stack and push
it onto the string stack after checking for room, invoking
garbage collection if necessary. Not to be used with a
dynamic string because a garbage collection can invalidate
its address.
This word violates the normal rule that only ANS Forth
strings should appear on the data stack, and so is under the
hood.
"string-push-ext"
primitive code = [p4_str_push_ext]
$BREAKP@
( -- $stack.break.addr )
=> [FORTH]
"string-break-p-fetch"
primitive code = [p4_str_breakp_fetch]
$BUFP@
( -- $buffer.addr )
=> [FORTH]
"string-buf-p-fetch"
primitive code = [p4_str_bufp_fetch]
$FBREAKP@
( -- frame.stack.break.addr )
=> [FORTH]
"string-f-break-p-fetch"
primitive code = [p4_str_fbreakp_fetch]
$FSP@
( -- frame.stack.top.addr )
=> [FORTH]
"string-f-s-p-fetch"
primitive code = [p4_str_fsp_fetch]
$FSP0@
( -- initial.frame.stack.top.addr )
=> [FORTH]
"string-f-s-p-zero-fetch"
primitive code = [p4_str_fsp0_fetch]
$SP@
( -- string.stack.top.addr )
=> [FORTH]
"string-s-p-fetch"
primitive code = [p4_str_sp_fetch]
$SP0@
( -- initial.string.stack.top.addr )
=> [FORTH]
"string-s-p-zero-fetch"
primitive code = [p4_str_sp0_fetch]
/$FRAME-ITEM
=> [FORTH]
(no description)
primitive code = [p4_slash_str_frame_item]
/$FRAME-STACK
=> [FORTH]
(no description)
primitive code = [p4_slash_str_frame_stack]
/$SPACE-HEADER
( -- $space.header.size )
=> [FORTH]
"slash-string-space-header"
primitive code = [p4_slash_str_space_header]
0$SPACE
( $space.addr -- )
=> [FORTH]
Clear the string buffer, string stack, and string frame stack
in the string space starting at space.addr. Any string
variables holding strings in the string buffer are left
pointing into limbo. This may be executed with the string
space in an invalid state, as long as the /$BUF
and
MAX-#$FRAMES
fields of its string space structure are
intact. "zero-string-space"
NOTE: This word does not zero fill the string buffer.
primitive code = [p4_zero_str_space]
CAT$P@
( -- cat$.msa | 0 )
=> [FORTH]
"cat-string-fetch"
primitive code = [p4_cat_str_p_fetch]
IN-$BUFFER?
( msa -- flag )
=> [FORTH]
Leave true if the mstring is in the string buffer.
"in-string-buffer-question"
primitive code = [p4_in_str_buffer_Q]