Skip to content

feat(parse): accept explicit + sign in e-notation exponent#248

Open
thedavidmeister wants to merge 2 commits into
mainfrom
feat/issue-214-positive-exponent-sign
Open

feat(parse): accept explicit + sign in e-notation exponent#248
thedavidmeister wants to merge 2 commits into
mainfrom
feat/issue-214-positive-exponent-sign

Conversation

@thedavidmeister

@thedavidmeister thedavidmeister commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • LibParseDecimalFloat.parseDecimalFloatInline now accepts an optional explicit + sign after e/E (e.g. 1e+2, 1.0e+2), treating it identically to the implicit positive case (1e2)
  • + with no following digits still rejects with MalformedExponentDigits (same as 1e-)
  • Adds CMASK_PLUS_SIGN import from rain-string

Addresses rainlanguage/rainlang#214.

Deploy required: source change moves the decimal-float bytecode → testDeployAddress, testExpectedCodeHashDecimalFloat, and testArtifactsCommitted are red pending a manual-sol-artifacts.yaml run on this branch with suite=decimal-float.

Test plan

  • New testParseLiteralDecimalFloatPositiveExponentSign — 9 positive cases
  • New testParseLiteralDecimalFloatPositiveENoDigits1e+ and 0.0e+ still reject
  • Existing testParseLiteralDecimalFloatExponents — 505 total tests pass (8 expected failures: 5 fork/RPC, 3 bytecode-pin pre-deploy)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Decimal float parsing now accepts an explicit + sign in exponents, so values like 1e+2 are handled correctly.
    • Inputs with a + but no exponent digits still fail with the expected error.
  • Tests
    • Added coverage for positive exponent signs and malformed exponent cases, including cursor-position checks.

`1e+2`, `1.0e+2`, `1E+2` etc. now parse identically to `1e2`.
`1e+` with no digits still rejects with MalformedExponentDigits.

Fixes rainlanguage/rainlang#214.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@thedavidmeister thedavidmeister self-assigned this Jul 3, 2026
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

💤 Files selected but had no reviewable changes (1)
  • crates/float/abi/DecimalFloat.json
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 62255cc9-8943-420a-9578-e49c770cb456

📥 Commits

Reviewing files that changed from the base of the PR and between 6429749 and 393956e.

📒 Files selected for processing (1)
  • crates/float/abi/DecimalFloat.json

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR extends LibParseDecimalFloat to accept an optional explicit + sign immediately after the exponent marker (e/E) in decimal float literals, mirroring existing support for -. Tests are added covering acceptance of e+ variants and the MalformedExponentDigits failure when no digits follow.

Changes

Positive Exponent Sign Support

Layer / File(s) Summary
Exponent sign parsing
src/lib/parse/LibParseDecimalFloat.sol
Imports CMASK_PLUS_SIGN and updates exponent parsing to detect and skip an optional + after e/E, adjusting eStart so digit parsing starts correctly.
Exponent sign tests
test/src/lib/parse/LibParseDecimalFloat.t.sol
Adds tests confirming e+ parses equivalently to e across several inputs, and that + without following digits reverts with MalformedExponentDigits.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Related PRs: None identified.

Suggested labels: enhancement, tests

Suggested reviewers: None identified.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: accepting an explicit plus sign in exponent notation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/issue-214-positive-exponent-sign

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/parse/LibParseDecimalFloat.sol (1)

141-151: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Mixed -/+ exponent signs silently mis-parsed instead of rejected.

The new + check runs unconditionally after the - skip, without verifying that no negative sign was already consumed. For input like "1e-+2":

  • Line 145 skips the -, advancing cursor to point at +.
  • Line 148 then matches + at that position, advances cursor past it, and overwrites eStart to point at 2 — discarding the previously consumed - entirely.
  • The exponent parses as +2 instead of being rejected, silently dropping the sign that was present in the input.

Previously (before this PR) "1e-+2" failed with MalformedExponentDigits because + is not a digit. Now it succeeds with an incorrect (wrong-sign) exponent value. This is a real regression for a decimal-float parser that presumably feeds downstream numeric/financial logic.

🐛 Proposed fix: only accept `+` when no `-` was already consumed
                 uint256 eStart = cursor;
-                cursor = LibParseChar.skipMask(cursor, end, CMASK_NEGATIVE_SIGN);
-                // Skip an optional explicit positive sign (e.g. 1e+2). Advance
-                // eStart past it so the int parser only sees the digit string.
-                if (LibParseChar.isMask(cursor, end, CMASK_PLUS_SIGN) == 1) {
-                    cursor++;
-                    eStart = cursor;
-                }
+                uint256 cursorBeforeSign = cursor;
+                cursor = LibParseChar.skipMask(cursor, end, CMASK_NEGATIVE_SIGN);
+                // Skip an optional explicit positive sign (e.g. 1e+2), but only
+                // if a negative sign was not already consumed above. Advance
+                // eStart past it so the int parser only sees the digit string.
+                if (cursor == cursorBeforeSign && LibParseChar.isMask(cursor, end, CMASK_PLUS_SIGN) == 1) {
+                    cursor++;
+                    eStart = cursor;
+                }

Please add test cases for "1e-+2" and "0.0e-+1" asserting MalformedExponentDigits (or another rejection), to lock in the correct behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/parse/LibParseDecimalFloat.sol` around lines 141 - 151, The
exponent-sign handling in LibParseDecimalFloat.parseDecimalFloat currently
accepts a plus sign even after a minus has already been consumed, which lets
mixed signs like 1e-+2 slip through. Update the exponent parsing logic around
the eValue/cursor/eStart block so the optional CMASK_PLUS_SIGN is only
recognized when no CMASK_NEGATIVE_SIGN was skipped, and otherwise leave the
parser to fail with MalformedExponentDigits. Add regression tests covering 1e-+2
and 0.0e-+1 to ensure mixed signs are rejected.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/lib/parse/LibParseDecimalFloat.sol`:
- Around line 141-151: The exponent-sign handling in
LibParseDecimalFloat.parseDecimalFloat currently accepts a plus sign even after
a minus has already been consumed, which lets mixed signs like 1e-+2 slip
through. Update the exponent parsing logic around the eValue/cursor/eStart block
so the optional CMASK_PLUS_SIGN is only recognized when no CMASK_NEGATIVE_SIGN
was skipped, and otherwise leave the parser to fail with
MalformedExponentDigits. Add regression tests covering 1e-+2 and 0.0e-+1 to
ensure mixed signs are rejected.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 12c3e737-fa22-481d-a6a1-9aceddbfddd3

📥 Commits

Reviewing files that changed from the base of the PR and between 774ed07 and 6429749.

📒 Files selected for processing (2)
  • src/lib/parse/LibParseDecimalFloat.sol
  • test/src/lib/parse/LibParseDecimalFloat.t.sol

Regenerate DecimalFloat.json artifact after adding explicit + sign
support in e-notation exponent parsing.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant