LAL: unify arithmetic operators (+ - * /) with JLS-style type promotion#13858
Open
LAL: unify arithmetic operators (+ - * /) with JLS-style type promotion#13858
Conversation
…otion
Extend LAL value-access grammar to support full arithmetic — `+`, `-`, `*`, `/`
with proper precedence. Operand types are inferred from explicit casts (`as Integer`
/ `as Long` / `as Float` / `as Double`), typed proto fields, or numeric literal
shape. The compiler honours JLS-style binary numeric promotion and emits Java
arithmetic in the declared primitive type instead of forcing all integer
arithmetic through `long`.
`(x as Integer) + (y as Integer)` now compiles to `int + int` rather than being
widened defensively. `+` with any String operand falls back to string
concatenation; `-` / `*` / `/` against non-numeric operands produces a
compile-time error.
Numeric literals support Java-style suffixes — `1000L` (long), `1.5f` (float),
`1e3` (double) — with `L` valid only on integer literals (no decimal, no
exponent). The existing `typeCast` clause now accepts `Double` and `Float` in
addition to `String` / `Long` / `Integer` / `Boolean`, including in `def`
variable declarations.
Numeric comparisons honour declared casts on both sides instead of routing
everything through `h.toLong()`. `tag("a") as Double < 1.5` compiles to
`h.toDouble(...) < 1.5`; `tag("a") as Integer < 1.5` compiles to
`(double) h.toInt(...) < 1.5`. Typed proto chains (`parsed?.x.y as Integer`)
keep their direct unboxed comparison path.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
LAL arithmetic operators (+, -, *, /) with JLS-style type promotion
Builds on #13857. Generalises the LAL value-access expression grammar so all
four arithmetic operators (
+,-,*,/) work on numeric operands withproper precedence (
*//bind tighter than+/-), and the compileremits Java arithmetic in the user-declared primitive type instead of forcing
all integer arithmetic through
long.Operand types are inferred from explicit casts (
as Integer/as Long/as Float/as Double), typed proto fields, or numeric-literal shape. JLSbinary numeric promotion picks the wider primitive when sides differ.
(x as Integer) + (y as Integer)→int + int(waslong + long).(x as Integer) + (y as Long)→(long) ... + ...widened tolong.(x as Double) - 1→double - (double) 1.+with any String operand falls back to string concatenation;-/*//against non-numeric operands produces a compile-time error.Numeric literals now support Java-style suffixes —
1000Lfor long,1.5ffor float,1e3for double — withLvalid only on integerliterals (no decimal, no exponent), matching Java. The existing
typeCastclause accepts
DoubleandFloatin addition toString/Long/Integer/Boolean, including indefvariable declarations.Numeric comparisons now honour declared casts on both sides — previously the
compiler routed everything through
h.toLong().tag(\"a\") as Double < 1.5compiles to
h.toDouble(...) < 1.5;tag(\"a\") as Integer < 1.5compilesto
(double) h.toInt(...) < 1.5. Typed proto chains(
parsed?.x.y as Integer) keep their direct unboxed comparison path.