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:
2026-04-15 19:28:26 +02:00
parent 280f09c60d
commit ec950551fd
2 changed files with 46 additions and 0 deletions
+30
View File
@@ -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
// ===================================================================