Re-sequence the language queue now that libakgl closed the gaps
The bump in 7f16337 updated sections 3, 7 and 8 but left the section 4 work
queue still marking groups G and I "file it", which is no longer true.
Groups G and I are unblocked outright. Group E splits: GET, GETKEY and SCNCLR
need nothing further, while WINDOW, KEY, SLEEP, WAIT and TI still want the sink
or a clock. LOCATE was listed in both E and G; it belongs to G alone, because in
BASIC 7.0 it moves the graphics pixel cursor DRAW starts from and the text
cursor verb is CHAR, already in group D.
One gap is genuinely outstanding and upstream named it in the same commit that
added the audio API: FILTER has no SDL3 primitive behind it. It is recorded in
section 7 with the behaviour to apply until an akgl_audio_filter() exists --
refuse at execution rather than silently ignore, since a program that asks for a
low-pass and gets an unfiltered square wave has been lied to.
Also records why the libakgl requirement is pinned by commit rather than by
version: 42b60f7 added 22 public symbols across four headers and left both
VERSION 0.1.0 and the libakgl.so.0.1 soname alone, so AKGL_VERSION_AT_LEAST
cannot tell the two trees apart and a binary built against the new headers
resolves against an old .so without complaint.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -410,7 +410,9 @@ Plus six more the original already carried: a leading `0` selects base 8, so `PR
|
|||||||
* `USING`, `VERIFY`, `VOL`, `WAIT`, `WIDTH`, `WINDOW`
|
* `USING`, `VERIFY`, `VOL`, `WAIT`, `WIDTH`, `WINDOW`
|
||||||
* The I/O-channel variants (`GETIO`, `INPUTIO`, `OPENIO`, `PRINTIO`, `RECORDIO`)
|
* The I/O-channel variants (`GETIO`, `INPUTIO`, `OPENIO`, `PRINTIO`, `RECORDIO`)
|
||||||
|
|
||||||
None of those is blocked on a missing `libakgl` capability any more. Four were — text measurement, immediate-mode drawing, audio, and a non-blocking keystroke read — and rather than work around them here they were filed in [`deps/libakgl/TODO.md`](deps/libakgl/TODO.md) under "API gaps blocking akbasic". All four have since landed upstream (`akgl_text_measure`, the `akgl_draw_*` family, `akgl_audio_*`, and `akgl_controller_poll_key`), so what is left is akbasic-side work.
|
One of those is still blocked on a missing `libakgl` capability, and it is only one. Four were — text measurement, immediate-mode drawing, audio, and a non-blocking keystroke read — and rather than work around them here they were filed in [`deps/libakgl/TODO.md`](deps/libakgl/TODO.md) under "API gaps blocking akbasic". All four have since landed upstream (`akgl_text_measure`, the `akgl_draw_*` family, `akgl_audio_*`, and `akgl_controller_poll_key`), so what is left is akbasic-side work.
|
||||||
|
|
||||||
|
The exception is `FILTER`, which sets the SID's filter cutoff, band switches and resonance. `akgl_audio_*` synthesises raw waveforms and mixes them; there is no filter stage to configure, and SDL3 supplies no primitive to build one from. Until an `akgl_audio_filter()` exists, `FILTER` parses and then refuses at execution rather than being silently ignored — a program that asks for a low-pass and gets an unfiltered square wave has been lied to.
|
||||||
|
|
||||||
## Deliberately out of scope
|
## Deliberately out of scope
|
||||||
|
|
||||||
@@ -422,7 +424,7 @@ None of those is blocked on a missing `libakgl` capability any more. Four were
|
|||||||
|
|
||||||
* [libakerror](https://source.starfort.tech/andrew/libakerror) 1.0.0 — TRY/CATCH-style error contexts. Every function that can fail returns one.
|
* [libakerror](https://source.starfort.tech/andrew/libakerror) 1.0.0 — TRY/CATCH-style error contexts. Every function that can fail returns one.
|
||||||
* [libakstdlib](https://source.starfort.tech/andrew/libakstdlib) 0.1.0 — libc wrappers that report through `libakerror`.
|
* [libakstdlib](https://source.starfort.tech/andrew/libakstdlib) 0.1.0 — libc wrappers that report through `libakerror`.
|
||||||
* [libakgl](https://source.starfort.tech/andrew/libakgl) 0.1.0 — **optional**, only for `-DAKBASIC_WITH_AKGL=ON`. Pulls in SDL3.
|
* [libakgl](https://source.starfort.tech/andrew/libakgl) 0.1.0 at commit `42b60f7` or later — **optional**, only for `-DAKBASIC_WITH_AKGL=ON`. Pulls in SDL3. The requirement is pinned by submodule commit rather than by version on purpose: 42b60f7 added 22 public symbols and left the version and the `libakgl.so.0.1` soname alone, so `AKGL_VERSION_AT_LEAST(0, 1, 0)` cannot tell the two trees apart. Filed upstream; `TODO.md` section 8 has the detail.
|
||||||
* [basicinterpret](https://source.starfort.tech/andrew/basicinterpret) — the Go original, vendored as the behavioural spec and the acceptance corpus. Not linked, not built.
|
* [basicinterpret](https://source.starfort.tech/andrew/basicinterpret) — the Go original, vendored as the behavioural spec and the acceptance corpus. Not linked, not built.
|
||||||
|
|
||||||
Everything is a submodule; `git submodule update --init --recursive` gets all of it. There is nothing to install first.
|
Everything is a submodule; `git submodule update --init --recursive` gets all of it. There is nothing to install first.
|
||||||
|
|||||||
46
TODO.md
46
TODO.md
@@ -424,13 +424,18 @@ Order by what unblocks the most, and by what does not need `libakgl` to grow fir
|
|||||||
| B. Housekeeping | `NEW`, `CLR`, `CONT`, `RESTORE`, `RENUMBER`, `SWAP`, `TRON`, `TROFF`, `HELP` | nothing |
|
| B. Housekeeping | `NEW`, `CLR`, `CONT`, `RESTORE`, `RENUMBER`, `SWAP`, `TRON`, `TROFF`, `HELP` | nothing |
|
||||||
| C. Errors | `TRAP`, `RESUME`, `ER`, `ERR` | needs a BASIC-visible error object |
|
| C. Errors | `TRAP`, `RESUME`, `ER`, `ERR` | needs a BASIC-visible error object |
|
||||||
| D. Strings/format | `USING`, `PUDEF`, `WIDTH`, `CHAR` | nothing |
|
| D. Strings/format | `USING`, `PUDEF`, `WIDTH`, `CHAR` | nothing |
|
||||||
| E. Console | `GET`, `GETKEY`, `SCNCLR`, `LOCATE`, `WINDOW`, `KEY`, `SLEEP`, `WAIT`, `TI` | sink + `libakgl` input |
|
| E. Console | `GET`, `GETKEY`, `SCNCLR`, `WINDOW`, `KEY`, `SLEEP`, `WAIT`, `TI` | `GET`/`GETKEY`/`SCNCLR` nothing; the rest want the sink or a clock |
|
||||||
| F. Disk | `DOPEN`, `DCLOSE`, `APPEND`, `RECORD`, `HEADER`, `COLLECT`, `BACKUP`, `COPY`, `CONCAT`, `RENAME`, `SCRATCH`, `DIRECTORY`, `CATALOG`, `DCLEAR`, `DVERIFY`, `SAVE`, `LOAD`, `VERIFY`, `BLOAD`, `BSAVE`, `BOOT` | `aksl_f*` only; no new akgl |
|
| F. Disk | `DOPEN`, `DCLOSE`, `APPEND`, `RECORD`, `HEADER`, `COLLECT`, `BACKUP`, `COPY`, `CONCAT`, `RENAME`, `SCRATCH`, `DIRECTORY`, `CATALOG`, `DCLEAR`, `DVERIFY`, `SAVE`, `LOAD`, `VERIFY`, `BLOAD`, `BSAVE`, `BOOT` | `aksl_f*` only; no new akgl |
|
||||||
| G. Graphics | `GRAPHIC`, `DRAW`, `BOX`, `CIRCLE`, `PAINT`, `COLOR`, `SCALE`, `SSHAPE`, `GSHAPE`, `LOCATE` | **`libakgl` immediate-mode draw API — file it** |
|
| G. Graphics | `GRAPHIC`, `DRAW`, `BOX`, `CIRCLE`, `PAINT`, `COLOR`, `SCALE`, `SSHAPE`, `GSHAPE`, `LOCATE` | nothing — `akgl_draw_*` landed at 42b60f7 |
|
||||||
| H. Sprites | `SPRITE`, `MOVSPR`, `SPRCOLOR`, `SPRDEF`, `SPRSAV`, `COLLISION` | `libakgl` sprite/actor API — check before filing |
|
| H. Sprites | `SPRITE`, `MOVSPR`, `SPRCOLOR`, `SPRDEF`, `SPRSAV`, `COLLISION` | `libakgl` sprite/actor API — check before filing |
|
||||||
| I. Audio | `PLAY`, `SOUND`, `ENVELOPE`, `FILTER`, `VOL`, `TEMPO` | **`libakgl` has no mixer-backed audio API — file it** |
|
| I. Audio | `PLAY`, `SOUND`, `ENVELOPE`, `VOL`, `TEMPO` | nothing — `akgl_audio_*` landed at 42b60f7 |
|
||||||
|
| I′. Audio, still gapped | `FILTER`, `SOUND`'s sweep arguments | `libakgl` has neither; see §7 |
|
||||||
| J. Machine | `SYS`, `FETCH`, `STASH`, `POKE`/`PEEK` variants | nothing |
|
| J. Machine | `SYS`, `FETCH`, `STASH`, `POKE`/`PEEK` variants | nothing |
|
||||||
|
|
||||||
|
`LOCATE` used to appear in both E and G. It belongs to G alone: in BASIC 7.0 `LOCATE` moves the
|
||||||
|
*graphics* pixel cursor that `DRAW` starts from, and the text cursor verb is `CHAR`, which is
|
||||||
|
already in group D.
|
||||||
|
|
||||||
**Out of scope, and staying that way** — the reference marks these as incompatible with a
|
**Out of scope, and staying that way** — the reference marks these as incompatible with a
|
||||||
modern PC and that reasoning stands: `BANK` (no bank switching), `FAST` (irrelevant CPU speed
|
modern PC and that reasoning stands: `BANK` (no bank switching), `FAST` (irrelevant CPU speed
|
||||||
control), `MONITOR` (no machine-language monitor).
|
control), `MONITOR` (no machine-language monitor).
|
||||||
@@ -627,8 +632,21 @@ Building against any of it needs `-DAKBASIC_WITH_AKGL=ON`, which pulls in `libak
|
|||||||
submodules (SDL and friends). Those are not initialized in a default clone; `git submodule
|
submodules (SDL and friends). Those are not initialized in a default clone; `git submodule
|
||||||
update --init --recursive` gets them.
|
update --init --recursive` gets them.
|
||||||
|
|
||||||
No gaps are currently outstanding. When the next one turns up, file it there rather than
|
**One gap is outstanding, and upstream named it itself.** The commit that added the audio API
|
||||||
working around it here.
|
says plainly what it does not cover: *"Still missing for a complete BASIC sound vocabulary:
|
||||||
|
`FILTER` (SDL3 has no filter primitive; this would need writing), `TEMPO` and the `PLAY`
|
||||||
|
note-string parser, both of which belong in the interpreter rather than here."*
|
||||||
|
|
||||||
|
- **`TEMPO` and the `PLAY` parser are ours**, not a gap. They are group I work in this
|
||||||
|
repository and nothing upstream is waiting on.
|
||||||
|
- **`FILTER` is a real gap.** BASIC 7.0's `FILTER freq, lp, bp, hp, res` sets the SID's
|
||||||
|
filter cutoff, the three band-pass switches and the resonance. `akgl_audio_*` synthesises
|
||||||
|
raw waveforms and mixes them; there is no filter stage to configure and SDL3 supplies no
|
||||||
|
primitive to build one from. Until an `akgl_audio_filter()` exists, `FILTER` is accepted by
|
||||||
|
the parser and refused at execution with `AKBASIC_ERR_DEVICE` rather than silently ignored —
|
||||||
|
a program that asks for a low-pass and gets an unfiltered square wave has been lied to.
|
||||||
|
|
||||||
|
When the next gap turns up, file it there rather than working around it here.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -659,7 +677,23 @@ Dependency baseline:
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `deps/libakerror` | 1.0.0 | Private ownership-enforced status registry. akbasic reserves 512–767 in `akbasic_error_register()`. Does not namespace its `coverage` target when embedded — worked around in our `CMakeLists.txt`. |
|
| `deps/libakerror` | 1.0.0 | Private ownership-enforced status registry. akbasic reserves 512–767 in `akbasic_error_register()`. Does not namespace its `coverage` target when embedded — worked around in our `CMakeLists.txt`. |
|
||||||
| `deps/libakstdlib` | 0.1.0 | soname `libakstdlib.so.0.1`. `AKSL_VERSION_CHECK()` asserted in `tests/version_check.c`. Its `aksl_ato*` family is banned here — see §1.9. |
|
| `deps/libakstdlib` | 0.1.0 | soname `libakstdlib.so.0.1`. `AKSL_VERSION_CHECK()` asserted in `tests/version_check.c`. Its `aksl_ato*` family is banned here — see §1.9. |
|
||||||
| `deps/libakgl` | 0.1.0 | Migrated to the 1.0.0 registry and owns 256–260. Not yet linked: `AKBASIC_WITH_AKGL` defaults OFF and `src/sink_akgl.c` does not exist. |
|
| `deps/libakgl` | 0.1.0, **pinned at commit 42b60f7** | Migrated to the 1.0.0 registry and owns 256–260. Not yet linked: `AKBASIC_WITH_AKGL` defaults OFF and `src/sink_akgl.c` does not exist. The version number cannot carry this requirement — see below. |
|
||||||
|
|
||||||
|
**The `libakgl` requirement is pinned by commit, not by version, and that is a defect
|
||||||
|
upstream.** 42b60f7 added 22 public symbols across four headers — `akgl_draw_*` (8),
|
||||||
|
`akgl_audio_*` (10), `akgl_controller_poll_key`/`_flush_keys`, and `akgl_text_measure`/
|
||||||
|
`_measure_wrapped` — and left `project(akgl VERSION 0.1.0)` and the `libakgl.so.0.1` soname
|
||||||
|
unchanged. By that repository's own stated rule, *"0.1 and 0.2 are different ABIs"*, this
|
||||||
|
should have been 0.2.0. Two consequences land here:
|
||||||
|
|
||||||
|
- A binary compiled against the new headers links happily against an installed
|
||||||
|
`libakgl.so.0.1` built from the old tree, and fails at symbol resolution rather than at
|
||||||
|
configure time.
|
||||||
|
- `AKGL_VERSION_AT_LEAST(0, 1, 0)` is true for both trees, so nothing here can feature-test
|
||||||
|
for the new API. The submodule pointer is the only thing that expresses the requirement.
|
||||||
|
|
||||||
|
Filed in `deps/libakgl/TODO.md`. When it is fixed, add the floor to the `find_package` call
|
||||||
|
and say so here.
|
||||||
|
|
||||||
CI is split in two. `.gitea/workflows/ci.yaml` runs on push -- the suite, ASan+UBSan, coverage
|
CI is split in two. `.gitea/workflows/ci.yaml` runs on push -- the suite, ASan+UBSan, coverage
|
||||||
and a two-file mutation run -- and `.gitea/workflows/release.yaml` is manual
|
and a two-file mutation run -- and `.gitea/workflows/release.yaml` is manual
|
||||||
|
|||||||
Reference in New Issue
Block a user