boot: add S — state-smart parse-next-token-as-string
`S name` is the string analogue of `[CHAR] x` and `['] name`: parses the
next whitespace-delimited token, state-smart.
Interpret: leaves ( c-addr u ) pointing into the input buffer.
Compile: appends run-time push of the copied bytes (identical code
to writing S" name" inline).
One line in boot.fth, leverages the existing PARSE-NAME + SLITERAL.
Zero runtime overhead inside : definitions.
This commit is contained in:
@@ -305,3 +305,19 @@
|
||||
: DFALIGN FALIGN ;
|
||||
|
||||
\ .S keeps its Rust host function (complex stack introspection).
|
||||
|
||||
\ ---------------------------------------------------------------
|
||||
\ Phase 8: Parse-ahead sugar
|
||||
\ ---------------------------------------------------------------
|
||||
|
||||
\ S ( "<spaces>name<space>" -- ) ( -- c-addr u at run time )
|
||||
\
|
||||
\ State-smart "quote the next whitespace-delimited token as a string".
|
||||
\ Interpret-mode: leave ( c-addr u ) pointing into the input buffer.
|
||||
\ Compile-mode: append run-time semantics that push the copied string
|
||||
\ (identical to writing S" name" inline).
|
||||
\
|
||||
\ This is the string analogue of [CHAR] (for chars) and ['] (for xts).
|
||||
\ Comparable to Lisp's quote: S foo is to a string what ' foo is to an xt.
|
||||
\ Inside a : definition the compiled code is bit-identical to S" foo".
|
||||
: S PARSE-NAME STATE @ IF SLITERAL THEN ; IMMEDIATE
|
||||
|
||||
@@ -7550,6 +7550,36 @@ mod tests {
|
||||
assert_eq!(eval_output(": TEST S\" World\" TYPE ; TEST"), "World");
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// New words: S (state-smart parse-next-token-as-string)
|
||||
// ===================================================================
|
||||
|
||||
#[test]
|
||||
fn test_s_interpret_type() {
|
||||
assert_eq!(eval_output("S hello TYPE"), "hello");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_s_interpret_length() {
|
||||
// S pushes ( c-addr u ); NIP leaves the length on top.
|
||||
assert_eq!(eval_stack("S foo NIP"), vec![3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_s_compile_mode() {
|
||||
assert_eq!(eval_output(": GREET S world TYPE ; GREET"), "world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_s_compile_stored_literal() {
|
||||
// The string compiled into a colon def must still be readable after
|
||||
// the enclosing input line is gone.
|
||||
let mut vm = ForthVM::<NativeRuntime>::new().unwrap();
|
||||
vm.evaluate(": NAME S kelvar ;").unwrap();
|
||||
vm.evaluate("NAME TYPE").unwrap();
|
||||
assert_eq!(vm.take_output(), "kelvar");
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// New words: COUNT
|
||||
// ===================================================================
|
||||
|
||||
Reference in New Issue
Block a user