From 3f1b9a5e2e6a383652641bf918417e47743b00b7 Mon Sep 17 00:00:00 2001 From: Luyu Cheng Date: Mon, 1 Jan 2024 21:08:32 +0800 Subject: [PATCH] Fix minor issues mentioned in the PR --- shared/src/main/scala/mlscript/NewLexer.scala | 8 ++++---- shared/src/test/diff/nu/DecLit.mls | 13 +++++++++++-- shared/src/test/diff/nu/IntLit.mls | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/shared/src/main/scala/mlscript/NewLexer.scala b/shared/src/main/scala/mlscript/NewLexer.scala index a0dab65938..4985c2fcea 100644 --- a/shared/src/main/scala/mlscript/NewLexer.scala +++ b/shared/src/main/scala/mlscript/NewLexer.scala @@ -66,6 +66,7 @@ class NewLexer(origin: Origin, raise: Diagnostic => Unit, dbg: Bool) { else (cur.reverseIterator.mkString, i) final def num(i: Int): (Lit, Int) = { + def test(i: Int, p: Char => Bool): Bool = i < length && p(bytes(i)) def zero: IntLit = IntLit(BigInt(0)) /** Take a sequence of digits interleaved with underscores. */ def takeDigits(i: Int, pred: Char => Bool): (Opt[Str], Int) = { @@ -101,7 +102,7 @@ class NewLexer(origin: Origin, raise: Diagnostic => Unit, dbg: Bool) { def isDecimalStart(ch: Char) = ch === '.' || ch === 'e' || ch === 'E' /** Take a fraction part with an optional exponent part. Call at periods. */ def decimal(i: Int, integral: Str): (DecLit, Int) = { - val (fraction, j) = if (i < length && bytes(i) === '.') { + val (fraction, j) = if (test(i, _ === '.')) { takeDigits(i + 1, isDigit) match { case (N, j) => raise(ErrorReport(msg"Expect at least one digit after the decimal point" -> S(loc(i + 1, i + 2)) :: Nil, @@ -110,8 +111,8 @@ class NewLexer(origin: Origin, raise: Diagnostic => Unit, dbg: Bool) { case (S(digits), j) => ("." + digits, j) } } else ("", i) - val (exponent, k) = if (j < length && (bytes(j) === 'e' || bytes(j) === 'E')) { - val (sign, k) = if (j + 1 < length && (bytes(j + 1) === '+' || bytes(j + 1) === '-')) { + val (exponent, k) = if (test(j, ch => ch === 'e' || ch === 'E')) { + val (sign, k) = if (test(j + 1, ch => ch === '+' || ch === '-')) { (bytes(j + 1), j + 2) } else { ('+', j + 1) @@ -138,7 +139,6 @@ class NewLexer(origin: Origin, raise: Diagnostic => Unit, dbg: Bool) { case _ => integer(i, 10, "decimal", isDigit) } case '0' => (zero, i + 1) - // case '.' => decimal(i, "0") case _ => takeDigits(i, isDigit) match { case (N, j) => raise(ErrorReport(msg"Expect a numeric literal" -> S(loc(i, i + 1)) :: Nil, diff --git a/shared/src/test/diff/nu/DecLit.mls b/shared/src/test/diff/nu/DecLit.mls index 2d61a57497..1714d7b7d3 100644 --- a/shared/src/test/diff/nu/DecLit.mls +++ b/shared/src/test/diff/nu/DecLit.mls @@ -117,13 +117,22 @@ //│ res //│ = 4378 +:pe +5. +//│ ╔══[LEXICAL ERROR] Expect at least one digit after the decimal point +//│ ║ l.121: 5. +//│ ╙── ^ +//│ 5 +//│ res +//│ = 5 + :pe 789.E //│ ╔══[LEXICAL ERROR] Expect at least one digit after the decimal point -//│ ║ l.121: 789.E +//│ ║ l.130: 789.E //│ ╙── ^ //│ ╔══[LEXICAL ERROR] Expect at least one digit after the exponent sign -//│ ║ l.121: 789.E +//│ ║ l.130: 789.E //│ ╙── ^ //│ 789 //│ res diff --git a/shared/src/test/diff/nu/IntLit.mls b/shared/src/test/diff/nu/IntLit.mls index 3b830644f6..b140609aaf 100644 --- a/shared/src/test/diff/nu/IntLit.mls +++ b/shared/src/test/diff/nu/IntLit.mls @@ -122,3 +122,18 @@ //│ = 2 //│ res //│ = 51966 + +// Extra leading zeros are discarded. +0123 +023456 +00 +0 +//│ 0 +//│ res +//│ = 123 +//│ res +//│ = 23456 +//│ res +//│ = 0 +//│ res +//│ = 0