State where a scalar lives in the three chapters that describe the pool

Chapter 13's limits table said 4096 array elements "in total", Chapter 16 said
an instance's fields come out of the same pool and nothing is reclaimed, and
Chapter 14's pool table listed `AKBASIC_MAX_ARRAY_VALUES` with no note about
what does and does not draw from it. All three were written when a scalar drew
from that pool, and all three now understate what a program may do.

Each gains the same two facts in the register it is written in. Chapter 13: a
scalar does not come out of the 4096, so creating one inside a `GOSUB` or a
`FOR` -- the loop counter included -- costs nothing, while a `DIM` inside a
scope does and is not given back. Chapter 16: scalars are the exception, and
"nothing is reclaimed" is what lets a pointer into a record stay sound after its
scope has gone -- which is the reason arrays and structures still spend.
Chapter 14: a row for the variable's own storage, and a paragraph on why the
value pool is the one budget that needs a second sentence.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-02 00:32:20 -04:00
parent 91fadf032b
commit ad76889292
3 changed files with 21 additions and 2 deletions

View File

@@ -366,12 +366,21 @@ error naming the pool, not a crash and not a slow leak.
| `AKBASIC_MAX_VARIABLES` | 128 | runtime | `Maximum runtime variables reached` |
| `AKBASIC_MAX_FUNCTIONS` | 64 | runtime | `Maximum function definitions reached` |
| `AKBASIC_MAX_ARRAY_VALUES` | 4096 | runtime (`valuepool`) | `Array of N elements does not fit in the M remaining value slots` |
| — a scalar is not in that pool | 1 | **the variable** (`inlinevalue`) | — |
| `AKBASIC_MAX_TOKENS` | 32 | **environment** | `Line N has more than 32 tokens` |
| `AKBASIC_MAX_LEAVES` | 32 | **environment** | `No more leaves available` |
| `AKBASIC_MAX_VALUES` | 64 | **environment** | `Maximum values per line reached` |
The numbers are in `include/akbasic/types.h`, transcribed from the reference's `main.go`
plus three the Go version did not need because it called `make()`.
**The value pool is the one that needs a second sentence.** It is a bump allocator with
no free, so anything drawn from it is spent for the life of the run — and scope exit
returns a variable's *slot* without returning its storage. A scalar therefore does not
draw from it at all: `akbasic_variable_init()` points a one-element non-`@` variable at
its own `inlinevalue`, which is what makes a local, a `FOR` counter and a `DEF` parameter
free. Arrays and structures still spend, deliberately, because a pointer into a record is
allowed to outlive the scope that DIMmed it.
[Chapter 13](13-differences.md) states the same budget from a BASIC programmer's side.
The per-environment three are reset at the top of every line, which is what makes