Skip to content

LAL: unify arithmetic operators (+ - * /) with JLS-style type promotion#13858

Open
wu-sheng wants to merge 1 commit intomasterfrom
feature/lal-arithmetic-ops
Open

LAL: unify arithmetic operators (+ - * /) with JLS-style type promotion#13858
wu-sheng wants to merge 1 commit intomasterfrom
feature/lal-arithmetic-ops

Conversation

@wu-sheng
Copy link
Copy Markdown
Member

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 with
proper precedence (* / / bind tighter than + / -), and the compiler
emits 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. JLS
binary numeric promotion picks the wider primitive when sides differ.

  • (x as Integer) + (y as Integer)int + int (was long + long).
  • (x as Integer) + (y as Long)(long) ... + ... widened to long.
  • (x as Double) - 1double - (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 — 1000L for long,
1.5f for float, 1e3 for double — with L valid only on integer
literals (no decimal, no exponent), matching Java. The existing typeCast
clause accepts Double and Float in addition to String / Long /
Integer / Boolean, including in def variable declarations.

Numeric comparisons now honour declared casts on both sides — previously the
compiler routed 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.

  • Add a unit test to verify that the fix works.
  • Explain briefly why the bug exists and how to fix it.
  • Update the `CHANGES` log.

…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.
@wu-sheng wu-sheng added backend OAP backend related. enhancement Enhancement on performance or codes logging Log collecting and analysis labels Apr 30, 2026
@wu-sheng wu-sheng added this to the 10.5.0 milestone Apr 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend OAP backend related. enhancement Enhancement on performance or codes logging Log collecting and analysis

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant