Getting started¶
The library is function-shaped: there is no program object to construct.
Three functions, importable straight from the oaknut.basic
namespace, do the work.
from oaknut.basic import tokenise, detokenise, number_lines
Tokenising and de-tokenising¶
tokenise takes a numbered source listing as a str and
returns the tokenised program as bytes; detokenise does the
reverse:
program = tokenise("10 PRINT \"HELLO\"\n20 GOTO 10\n")
# program is bytes: 0x0D 0x00 0x0A ... 0x0D 0xFF
listing = detokenise(program)
# listing is "10 PRINT \"HELLO\"\n20 GOTO 10\n"
The two are exact inverses at the byte level — see Round-tripping and code points for what that guarantees, and for the character-encoding contract the strings follow.
Numbering¶
number_lines prepends ascending line numbers to unnumbered source,
the AUTO equivalent:
number_lines("PRINT\nGOTO 10", start=10, step=10)
# "10 PRINT\n20 GOTO 10"
tokenise accepts the same start and step keywords directly,
to number and tokenise unnumbered source in one call:
tokenise("PRINT\nEND", start=10, step=10)
On a disc image¶
When the program lives in a disc image, prefer the path-object wrappers
over calling the codec by hand. oaknut.dfs.DFSPath.write_basic()
and read_basic() (and the ADFS equivalents)
compose the codec with the correct load-address default and the disc’s
character encoding:
from oaknut.dfs import DFS
with DFS.from_file("game.ssd") as disc:
(disc.root / "$" / "MENU").write_basic("10 PRINT\n20 END")
print((disc.root / "$" / "MENU").read_basic())
Never move a BASIC program through read_text / write_text: a
tokenised program is bytecode, and a text codec would mangle it.