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:
27
TODO.md
27
TODO.md
@@ -2667,7 +2667,19 @@ reduced against `build/basic`, the stdio build, unless it says otherwise.
|
||||
|
||||
The tee half is three lines and is worth doing whatever is decided about the rest.
|
||||
|
||||
4. **Mixed-type arithmetic is decided by the left operand alone, and nothing says so.**
|
||||
4. ~~**Mixed-type arithmetic is decided by the left operand alone, and nothing says so.**~~
|
||||
**Done, as documentation, by decision.** The behaviour is unchanged: a dialect is
|
||||
allowed to say the left operand wins and this one is consistent about it, and promotion
|
||||
would change the result of every mixed expression in every existing program. What was
|
||||
missing was anybody saying so. Now: a section in `docs/03-the-language.md` with the
|
||||
two-line demonstration and the two rules that keep a program out of it, a row in
|
||||
`docs/13-differences.md` naming it as the difference from 7.0 most likely to turn a
|
||||
working listing into a quietly wrong one, and the reasoning on `include/akbasic/value.h`
|
||||
where the operators are declared.
|
||||
|
||||
`tests/value_arithmetic.c` pins it in both directions, so **promotion is now a decision
|
||||
somebody has to take deliberately** rather than a change that could slip in. The
|
||||
original report:
|
||||
|
||||
```basic
|
||||
A# = 3
|
||||
@@ -2700,7 +2712,18 @@ reduced against `build/basic`, the stdio build, unless it says otherwise.
|
||||
The cheap fix is documentation: a paragraph in chapter 3 and a row in chapter 13. The other
|
||||
fix is promotion, which would be a real change of semantics and wants its own decision.
|
||||
|
||||
5. **A drawing that spans a 256-line batch boundary is torn, not merely transient.** §5 and
|
||||
5. ~~**A drawing that spans a 256-line batch boundary is torn, not merely transient.**~~
|
||||
**Done, as documentation.** No fix is possible without changing what a host owns -- the
|
||||
budget is the host's and the present is the host's -- so what was needed was for the
|
||||
consequence to be written down beside the advice it qualifies. `docs/13-differences.md`
|
||||
now says that "redraw it every frame" is not sufficient on its own and carries the
|
||||
measured numbers, `docs/06-graphics.md` says it where `SSHAPE` is introduced, and
|
||||
`docs/14-architecture.md` explains the mechanism from the step loop's side and points at
|
||||
the `TI#` synchronisation a program has to build.
|
||||
|
||||
**Untested, and deliberately:** it needs the real frontend, a clock and a timing
|
||||
window, and a test that reproduced it would be reproducing a race. Said here rather than
|
||||
left looking like an oversight. The original report: §5 and
|
||||
chapter 13 record that drawing does not persist across frames. What neither says is that a
|
||||
single uninterrupted sequence of drawing verbs longer than one `akbasic_runtime_run()` budget
|
||||
comes back **half drawn**, because the present in the middle of it discards the buffer — so
|
||||
|
||||
Reference in New Issue
Block a user