Cookbook¶
Worked examples that use oaknut.basic directly. Each is a small,
complete program.
Tokenise a listing to a file¶
from pathlib import Path
from oaknut.basic import tokenise
source = Path("menu.bas").read_text(encoding="utf-8")
Path("MENU").write_bytes(tokenise(source))
The source string is the program’s logical text; if it contains
non-ASCII characters, encode them to the Acorn character set before
tokenising (or let the CLI’s --encoding do it). See
Round-tripping and code points for the code-point contract.
De-tokenise a stored program¶
from pathlib import Path
from oaknut.basic import detokenise
listing = detokenise(Path("MENU").read_bytes())
print(listing)
Number unnumbered source, then tokenise¶
from oaknut.basic import number_lines, tokenise
draft = "PRINT \"HELLO\"\nGOTO 10"
# Two steps...
numbered = number_lines(draft, start=10, step=10)
program = tokenise(numbered)
# ...or one, with auto-numbering inside tokenise.
program = tokenise(draft, start=10, step=10)
Validate a program defensively¶
Because every codec failure is a BASICError, a
batch tool can convert what it can and collect the rest:
from oaknut.basic import detokenise, BASICError
def to_listing(program: bytes) -> str | None:
try:
return detokenise(program)
except BASICError as exc:
log.warning("skipping malformed program: %s", exc)
return None
Round-trip through a disc image¶
When the program lives on a disc, the path-object wrappers compose the
codec with the disc’s encoding and the right load address — prefer them
to calling tokenise() / detokenise() by hand:
from oaknut.dfs import DFS
with DFS.from_file("game.ssd") as disc:
menu = disc.root / "$" / "MENU"
listing = menu.read_basic()
menu.write_basic(listing.replace("GOTO 10", "GOTO 20"))