Write down that the left operand decides integer or float arithmetic
No behaviour change, by decision. `A# * 0.45` is 0 and `0.45 * A#` is 1.35, because every operator branches on `self->valuetype` and converts the right operand to match. It is inherited from the Go reference, a C128 promotes to float instead, and this interpreter is at least consistent about it -- so a dialect saying the left operand wins is a defensible position, and changing it to promotion would alter the result of every mixed expression in every existing program. **The defect was that nobody said so.** Chapter 3's "Numbers" did not mention it, Chapter 13 did not list it among the differences, and nothing fails when a program gets it wrong -- it computes something else and carries on. The game in examples/ lost its per-level speed increase to `5.6 + LEVEL# * 0.45` evaluating to a flat 5.6, and bled velocity out of every bounce through `0 - BLVX%(B#)` quantising to whole pixels. Both read correctly. Neither produced a diagnostic. Now said in three places: a section in Chapter 3 with the demonstration and the two rules that keep a program out of it (put the float on the left, put the answer somewhere with a `%` on it), a row in Chapter 13 naming it as the difference from 7.0 most likely to turn a working listing into a quietly wrong one, and the reasoning on value.h where the operators are declared. tests/value_arithmetic.c pins it in both directions across multiply and subtract, with a comment saying it is the documented contract rather than an accident -- so promotion becomes a decision somebody takes deliberately rather than a change that could slip in under a passing suite. TODO.md section 9 item 4, struck as a documentation outcome. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,16 @@
|
||||
* exactly, including the parts that look wrong -- see TODO.md section 12 for the
|
||||
* catalogue and the reason they are not fixed yet.
|
||||
*
|
||||
* **The left operand decides whether an operation is done in integers or in
|
||||
* floats**, and this is deliberate rather than an oversight: every operator
|
||||
* branches on `self->valuetype` and converts the right operand to match, so an
|
||||
* integer on the left truncates a float on the right. `A# * 0.45` is 0 and
|
||||
* `0.45 * A#` is 1.35. It is inherited from the reference
|
||||
* (basicvalue.go:190-193), a C128 promotes to float instead, and nothing fails
|
||||
* when a program gets it wrong -- it computes something else and carries on.
|
||||
* Documented in docs/03-the-language.md and docs/13-differences.md, and pinned
|
||||
* in tests/value_arithmetic.c so that changing it has to be a decision.
|
||||
*
|
||||
* Every binary operator takes a `scratch` value the caller has drawn from an
|
||||
* environment's pool and an out-parameter `dest`. Most operators set `*dest` to
|
||||
* `scratch` and fill it; akbasic_value_math_plus sets `*dest` to `self` when
|
||||
|
||||
Reference in New Issue
Block a user