feat(core): SwiftForth input number conversion, DPL and NH
Punctuation (`,` `.` `+` `/` `:` and an embedded `-`) after the leftmost digit now forces double-cell conversion, so `12.34`, `1,234`, `12:30:45` and `2026-08-06` convert as doubles. Only a trailing `.` worked before, and `1.5` was an "unknown word" error. The punctuation is a double-cell marker, not a fractional point, so the scale has to travel separately: DPL carries the digit count right of the rightmost punctuation character (negative when there was none), which is what lets `<# #>` place the point back on output. NH carries the high cell a single-cell conversion drops, so a token that overflows a cell is still recoverable as a double. parse_number and parse_double_number duplicated the prefix and sign handling and could not share a DPL counter, so they collapse into one parse_numeric_literal that reports which kind it converted. Verified token-for-token against sf64. One deliberate divergence: WAFER keeps accepting a sign before a base prefix (`-$FF`), which sf64 rejects.
This commit is contained in:
@@ -108,6 +108,23 @@ pub const SYSVAR_HLD: u32 = SYSVAR_BASE + 28;
|
||||
pub const SYSVAR_LEAVE_FLAG: u32 = SYSVAR_BASE + 32;
|
||||
/// Throw code left by a compiled stack-guard fault for `_STACK_FAULT_`.
|
||||
pub const SYSVAR_FAULT_CODE: u32 = SYSVAR_BASE + 36;
|
||||
/// DPL: digits right of the rightmost punctuation in the last converted
|
||||
/// number; negative when the token carried no punctuation.
|
||||
pub const SYSVAR_DPL: u32 = SYSVAR_BASE + 40;
|
||||
/// NH: high-order cell of the last single-cell conversion, so an
|
||||
/// out-of-range token can be recovered as a double.
|
||||
pub const SYSVAR_NH: u32 = SYSVAR_BASE + 44;
|
||||
|
||||
/// Seed for [`SYSVAR_DPL`] before conversion starts.
|
||||
///
|
||||
/// `SwiftForth` seeds DPL with a negative value and bumps it once per digit,
|
||||
/// so an unpunctuated token still ends up negative. Punctuation resets the
|
||||
/// counter to zero, which makes the final value the digit count right of the
|
||||
/// rightmost punctuation character.
|
||||
///
|
||||
/// The exact seed is observable: `sf64` reports DPL as -1020 after `1234`
|
||||
/// and -1023 after `-1`, both of which pin it to -1024.
|
||||
pub const DPL_INIT: i32 = -1024;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
@@ -149,6 +166,9 @@ mod tests {
|
||||
SYSVAR_NUM_TIB,
|
||||
SYSVAR_HLD,
|
||||
SYSVAR_LEAVE_FLAG,
|
||||
SYSVAR_FAULT_CODE,
|
||||
SYSVAR_DPL,
|
||||
SYSVAR_NH,
|
||||
];
|
||||
for offset in all_offsets {
|
||||
assert!(offset + CELL_SIZE <= SYSVAR_BASE + SYSVAR_SIZE);
|
||||
|
||||
Reference in New Issue
Block a user