floats iter 2.1 fixup: drop task-tags + refresh stale prose + uppercase-E + leading-dot tests
This commit is contained in:
@@ -10,7 +10,9 @@
|
||||
//! 3. After tokenisation, classify by first character:
|
||||
//! - `"` ⇒ string literal (consume until closing `"`; `\"` and
|
||||
//! `\n` escapes supported).
|
||||
//! - digit, or `-` followed by digit ⇒ integer literal.
|
||||
//! - digit, or `-` followed by digit ⇒ integer or float literal
|
||||
//! (float if the token contains `.`, `e`, or `E`; integer
|
||||
//! otherwise).
|
||||
//! - otherwise ⇒ ident.
|
||||
//!
|
||||
//! Operators (`+`, `==`, `<=`, `**`), qualified names like
|
||||
@@ -40,7 +42,7 @@ pub enum Tok {
|
||||
/// Integer literal. Original textual form preserved for error messages;
|
||||
/// parsed `i64` value carried for direct use.
|
||||
Int(i64),
|
||||
/// IEEE-754 binary64 literal (Floats milestone iter 2). The
|
||||
/// IEEE-754 binary64 literal. The
|
||||
/// payload is the bit pattern produced by `f64::to_bits`. The
|
||||
/// surface forms recognised by the lexer are
|
||||
/// `<digits>.<digits>(e[+-]?<digits>)?` and
|
||||
@@ -49,7 +51,7 @@ pub enum Tok {
|
||||
Float(u64),
|
||||
/// String literal contents (after escape processing).
|
||||
Str(String),
|
||||
/// Identifier. Anything that isn't a paren, integer, or string.
|
||||
/// Identifier. Anything that isn't a paren, integer, float, or string.
|
||||
Ident(String),
|
||||
}
|
||||
|
||||
@@ -347,7 +349,7 @@ mod tests {
|
||||
assert!(matches!(&toks[0].tok, Tok::Str(s) if s == "em — dash and naïve"));
|
||||
}
|
||||
|
||||
/// Iter 22-floats.2 RED: a `<digits>.<digits>` token lexes as
|
||||
/// A `<digits>.<digits>` token lexes as
|
||||
/// `Tok::Float` carrying the IEEE-754 binary64 bit pattern of
|
||||
/// `f64::from_str(raw).unwrap().to_bits()`. Pinned literal:
|
||||
/// `1.5_f64` → bit pattern `0x3FF8000000000000`.
|
||||
@@ -475,4 +477,34 @@ mod tests {
|
||||
"expected InvalidFloat for `1..5`, got {err:?}"
|
||||
);
|
||||
}
|
||||
|
||||
/// Spec A2 grammar accepts both `e` and `E` for the exponent
|
||||
/// marker. The `looks_like_float` validator handles both bytes;
|
||||
/// pin the uppercase form explicitly.
|
||||
#[test]
|
||||
fn float_uppercase_exponent() {
|
||||
let toks = tokenize("1.5E3 2E-5").unwrap();
|
||||
assert_eq!(toks.len(), 2);
|
||||
match toks[0].tok {
|
||||
Tok::Float(b) => assert_eq!(b, 1.5e3_f64.to_bits()),
|
||||
ref other => panic!("expected Tok::Float, got {other:?}"),
|
||||
}
|
||||
match toks[1].tok {
|
||||
Tok::Float(b) => assert_eq!(b, 2e-5_f64.to_bits()),
|
||||
ref other => panic!("expected Tok::Float, got {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Spec A2 rejects bare leading dot at the *float* level — `.5` is
|
||||
/// not a float literal. The lexer's digit-lead rule does not fire
|
||||
/// (first byte `.` is not a digit and not `-`-followed-by-digit),
|
||||
/// so `.5` falls through to the maximal-non-paren-non-whitespace
|
||||
/// run and lexes as `Tok::Ident(".5")`. Downstream parser /
|
||||
/// typecheck stages produce the appropriate diagnostic.
|
||||
#[test]
|
||||
fn float_leading_dot_lexes_as_ident() {
|
||||
let toks = tokenize(".5").unwrap();
|
||||
assert_eq!(toks.len(), 1);
|
||||
assert!(matches!(&toks[0].tok, Tok::Ident(s) if s == ".5"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user