Skip to content

fix(interpreter): return runtime errors for division by zero and integer overflow - #328

Merged
gengjiawen merged 1 commit into
mainfrom
fix/interpreter-checked-arithmetic
Aug 11, 2026
Merged

fix(interpreter): return runtime errors for division by zero and integer overflow#328
gengjiawen merged 1 commit into
mainfrom
fix/interpreter-checked-arithmetic

Conversation

@gengjiawen

Copy link
Copy Markdown
Owner

Problem

The tree-walking interpreter still did raw i64 arithmetic in eval_integer_infix and eval_prefix_minus:

  • 1 / 0;panicked at interpreter/lib.rs:425: attempt to divide by zero — in release builds too (Rust always checks division), killing the REPL/process.
  • let m = -9223372036854775807 - 1; m / -1; → panic (divide with overflow), all profiles.
  • 9223372036854775807 + 1; → panic in debug builds, silent wrap in release builds — evaluation semantics depended on the build profile.

The bytecode VM was already hardened (compiler/vm.rs uses checked_* and returns classified runtime errors); the interpreter was the un-hardened outlier.

Fix

Use checked_add/sub/mul/div/neg and return EvalError with the exact wording the bytecode VM uses (division by zero, integer overflow in addition/subtraction/multiplication/division/negation), so both engines report these cases identically. Boundary values that fit in i64 (e.g. -9223372036854775807 - 1) still evaluate normally.

Before/after on the REPL:

>> 1 / 0;
thread 'main' panicked at interpreter/lib.rs:425:45: attempt to divide by zero   # before
division by zero                                                                 # after, REPL keeps running

Testing

  • New test_integer_arithmetic_errors pins all six error cases; test_integer_arithmetic_boundaries_still_evaluate pins that i64::MIN-adjacent values still work.
  • cargo test --workspace: 396 passed, 0 failed. Clippy and cargo fmt --check clean.
  • Verified the REPL binary now prints the errors and keeps running.

Affected crates: interpreter only. (The GC VM's wrapping_* add/sub/mul drift vs the compiler VM is a separate known issue, not touched here.)

🤖 Generated with Claude Code

…ger overflow

eval_integer_infix and eval_prefix_minus used raw i64 arithmetic, so
`1 / 0` and `i64::MIN / -1` panicked in every build profile, while
`+ - *` and unary minus panicked in debug builds and silently wrapped
in release builds - evaluation semantics depended on the build profile.

Switch to checked_add/sub/mul/div/neg and surface failures as EvalError
with the same wording the bytecode VM uses ("division by zero",
"integer overflow in addition" etc., compiler/vm.rs), so the two
engines report these cases identically. Boundary values that do fit in
i64 still evaluate; regression tests pin both the errors and the
boundaries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
monkey-playground Ready Ready Preview Aug 11, 2026 3:25am

@gengjiawen
gengjiawen merged commit 8ea8996 into main Aug 11, 2026
11 checks passed
@gengjiawen
gengjiawen deleted the fix/interpreter-checked-arithmetic branch August 11, 2026 04:25
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