You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Compound assignment is the general case of which `++`/`--` is the degenerate
`x op= 1` form. `x op= e` lowers to `x := x op e` and yields the new value,
usable as a statement (`x += 2;`) or in expression position (`int y := (x += 2)`).
* AST: new `StmtExpr.CompoundAssign (op : Operation) (target) (rhs)` ctor. The
`op` is invariably one of Add/Sub/Mul/Div/Mod/StrConcat (enforced by the
concrete-to-abstract translator); downstream sites treat any other as a bug.
* Grammar: `+= -= *= /= %= ^=` at prec(10), rightassoc. Mixed `:=`/`op=`
chaining is unsupported paren-free, matching `:=`'s existing behavior (plain
`x := y := z` also does not parse); `a += b += c` groups right.
* Lowering: `EliminateIncrDecr.lowerToAssign` is generalized to `lowerOpAssign`
(arbitrary `Operation` + RHS), shared with the `++`/`--` path (rhs = 1). The
`.PrimitiveOp` keeps `skipProof := false`, so `/=`/`%=` carry the same
division-by-zero proof obligation as a hand-written `x := x / e`. Runs first in
the pipeline, so no later pass observes `.CompoundAssign`.
* Type checking is construct-keyed, by design: `++`/`--` reject `real` (the
synthesized int `1` cannot type-check against a real under strict numeric
typing), but `+= -= *= /=` accept `real` because the RHS is user-written;
`%=` is int-only (`.Mod` has no real lowering); `^=` is string-only. The
shared `compoundAssignAccepts` predicate drives both the resolution-time
target check and the model-based RHS-type check (`compoundAssignRhsErrors`,
run in the post-resolution validation phase). The RHS check is suppressed
when the target type is already invalid, so one mistake yields one error.
* All exhaustive `StmtExpr` matches updated (MapStmtExpr traverses the rhs even
for Local/Declare targets, FilterPrelude, computeExprType, both grammar
translators, the Core-translator defensive arm, the lift `contains*` helpers,
resolution `collectStmtExpr` and the diamond-field walker).
Tests:
* T24_CompoundAssign: each operator on int; real for `+= -= *= /=`; string for
`^=`; constrained-int (`nat`); expression position; nested side-effecting RHS;
right-associative `a += b += c`.
* T24b_CompoundAssignField: field target `c#n += e` and chained `o#inner#count
+= e`, both statement and expression position.
* CompoundAssignTypeRejectionTest: per-operator target rejections; RHS-type
mismatches; the intended `r += 1.0` accepts / `r++` rejects asymmetry; and a
`/= 0` verification failure pinning `skipProof := false`.
* CompoundAssignLiftTest: golden lowering for statement, expression, and
nested-RHS forms.
0 commit comments