Documentation
¶
Overview ¶
Package basic tokenises and detokenises Sinclair BASIC programs.
It converts between human-readable BASIC source (one line per text line, each beginning with a line number) and the on-disk tokenised form used by the Spectrum: a sequence of lines, each
[line number: 2 bytes big-endian][length: 2 bytes little-endian][text...][0x0D]
Keyword tokens occupy 0xA3-0xFF; 0xA3 (SPECTRUM) and 0xA4 (PLAY) are 128K-only. Numeric constants appear as their visible ASCII digits followed by a 0x0E marker and a 5-byte binary value.
Scope: this covers what loaders and ordinary hand-written BASIC need - keywords, integer numeric constants in 0..65535, string literals, and REM comments. A leading minus on a number is the subtraction operator (stored as a literal '-' followed by a positive number), matching the ROM; there is no signed single-number form. Floating-point literals, DEF FN calculator slots, and embedded colour-control argument bytes are not produced.
This package depends only on the standard library.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Detokenise ¶
Detokenise converts a tokenised Sinclair BASIC program (the raw program bytes, with no PLUS3DOS header) into readable text. It is the inverse of Tokenise.
Program structure: a sequence of lines, each
[line number: 2 bytes big-endian][length: 2 bytes little-endian][text...][0x0D]
Within the text, keyword tokens (0xA3-0xFF) expand to keywords; a numeric constant appears as its visible ASCII digits followed by a 0x0E marker and a 5-byte binary form, which is skipped (the visible digits are what we print).
This handles the cases a loader needs: keywords, numbers, strings, and the statement separator. It does not reproduce embedded colour/AT/TAB control-code arguments beyond passing printable bytes through; non-printable bytes are shown as a [XX] hex escape so output stays lossless.
func LooksTokenised ¶
LooksTokenised reports whether data appears to be already-tokenised BASIC rather than plain-text source. It parses data as a sequence of tokenised lines ([line# big-endian, 0-9999][length little-endian][length bytes][0x0D]) and returns true only if the whole buffer parses cleanly into one or more such lines with ascending line numbers. This is a structural check, not a guess on a single byte, so it is suitable for an advisory warning: it will not misfire on ordinary text source, which does not have this layout.
func Tokenise ¶
Tokenise converts BASIC source text into the on-disk tokenised byte form. It is the inverse of Detokenise.
Input is one BASIC line per text line, each beginning with a line number, for example:
10 CLEAR 32767: LOAD "game"CODE: RANDOMIZE USR 32768 20 PRINT "DONE"
Keywords are matched longest-first and only outside string literals and REM text. Numeric constants are emitted in the ROM integer form (visible digits, then 0x0E and a 5-byte value); only integer constants in 0..65535 are encoded.
The result is the raw tokenised program with no PLUS3DOS header.
Types ¶
type Option ¶
type Option func(*config)
Option configures tokenisation. Options are applied left to right.
func CaseSensitive ¶
func CaseSensitive() Option
CaseSensitive makes keyword matching case-sensitive (keywords must be upper-case to tokenise). By default matching is case-insensitive, which suits hand-written source.