Skip to main content

oaknut-basic

oaknut-basic

PyPI version CI Python versions License: MIT Documentation

Read the documentation — getting started, the command reference, and the API.

Work with the persistent artefacts a BBC BASIC program leaves behind — both the code and the data:

  • Programs. Convert a program between its compact on-disc tokenised form and a plain-text listing — the two directions a real BBC Micro performs when you LOAD and LIST it — plus line numbering for source typed without numbers.
  • Data files. Read and write the channel-based files a program creates with OPENOUT and writes with PRINT# and BPUT#, translating their tagged records to and from native Python values.

The problem

Both formats are bytecode, not text, and idiosyncratic to the BBC.

A tokenised program packs keywords like PRINT and GOTO into single bytes, folds line numbers into each line's header, and scrambles a reference such as GOTO 100 into a three-byte form that can never be mistaken for a line terminator. A text codec decoding one produces garbage.

A PRINT# data file is just as surprising: PRINT#channel, 42 writes a type tag and the number's bytes in reverse, not the characters 4 2; strings go out length-prefixed and backwards, and reals use the BBC's packed 5-byte floating-point format. The file is meant to be read back only by INPUT#.

oaknut-basic reproduces the BBC BASIC II ROM's behaviour exactly — every token value and flag, the line-number encoding, the record tags and the 5-byte REAL format — so a program round-trips between bytes and text byte-for-byte, and a data file round-trips through Python values byte-for-byte.

Installation

Install with the [cli] extra for the oaknut-basic command, or bare for the library only:

uv tool install "oaknut-basic[cli]"     # the command-line tool
uv add oaknut-basic                       # the importable library

pip works identically with the same names. oaknut-basic requires Python 3.11 or newer.

Command-line usage

$ oaknut-basic --help
Usage: oaknut-basic [OPTIONS] COMMAND [ARGS]...

  Tools for BBC BASIC programs and data files.

Options:
  --version  Show the version and exit.
  --help     Show this message and exit.

Commands:
  data        Read and write BBC BASIC data files.
  detokenise  De-tokenise a stored BBC BASIC program into source text.
  number      Prepend ascending line numbers to an unnumbered BBC BASIC...
  tokenise    Tokenise BBC BASIC source text into a stored program.

The program commands read from a file or standard input and write to a file or standard output, so each works file-to-file and as a pipe stage. That makes them compose with oaknut-disc to edit a program in place on a disc image:

disc get game.ssd MENU - | oaknut-basic detokenise > menu.bas
oaknut-basic tokenise menu.bas | disc put game.ssd MENU -

Tokenising and de-tokenising are exact inverses, so a program survives a there-and-back trip unchanged. The tokenise command can also number unnumbered source on the way in (--start / --step), exactly as typing it under AUTO would.

The data subcommands turn a PRINT# data file into something host tools can read. The inspect command shows its records as a table; decode and encode are a lossless JSON round-trip pair for editing or generating a file:

oaknut-basic data inspect scores.dat
oaknut-basic data decode scores.dat | jq '.[0]'
echo '[42, "HELLO", 3.5]' | oaknut-basic data encode - scores.dat

Library usage

Programs are handled by the functions tokenise, detokenise, and number_lines, all importable from oaknut.basic:

from oaknut.basic import tokenise, detokenise

program = tokenise('10 PRINT "HELLO"\n20 GOTO 10\n')   # str -> bytes
listing = detokenise(program)                          # bytes -> str
assert tokenise(detokenise(program)) == program        # byte-exact

When the program lives in a disc image, prefer the path-object wrappers DFSPath.read_basic / write_basic (and the ADFS equivalents), which compose the codec with the disc's character encoding and the correct load address.

Data files are handled by a context-managed, file-like object. The module-level open mirrors the built-in one: a mode string selects a reader, a writer, or a combined object, and accepts a path or a binary stream. The polymorphic write picks the record type from the Python value; typed read_int / read_float / read_str read it back without coercion:

from oaknut.basic import datafile

with datafile.open("scores.dat", "w") as f:
    f.write("ALICE")     # str   -> string record
    f.write(42)          # int   -> integer record
    f.write(3.5)         # float -> real record

with datafile.open("scores.dat", "r") as f:
    for value in f:      # yields "ALICE", 42, 3.5
        print(value)

Strings use the BBC acorn character set by default, and reals convert through the packed 5-byte REAL format exposed as pack_float5 / unpack_float5.

References

  • BBC BASIC — Wikipedia overview of the language and its versions.
  • BBC BASIC program format — BeebWiki reference for the on-disc tokenised format and the token table.
  • Format of a random access file — BeebWiki background on the disc filing system that holds these files; the PRINT# record tags and 5-byte REAL format are documented in this package's own API reference.

Part of oaknut

oaknut-basic is one package in the oaknut monorepo of tools for Acorn computer filesystems, files, and formats. It backs the read_basic / write_basic methods of the oaknut-dfs and oaknut-adfs packages, and is usable on its own for the .bas / .bbc programs and the data files BBC BASIC leaves on a disc.

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

oaknut_basic-12.14.0.tar.gz (63.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

oaknut_basic-12.14.0-py3-none-any.whl (43.6 kB view details)

Uploaded Python 3

File details

Details for the file oaknut_basic-12.14.0.tar.gz.

File metadata

  • Download URL: oaknut_basic-12.14.0.tar.gz
  • Upload date:
  • Size: 63.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for oaknut_basic-12.14.0.tar.gz
Algorithm Hash digest
SHA256 acd51f99d78030e89fa35ca408b06388f6a0aee02ef88dc97226af5107cea0ef
MD5 abfc3e66bf0f907643cf368cc8069bcd
BLAKE2b-256 1aa308a654aa93c769c95d8a6d49a8d89f50f41e21b24ffc20ae52bd0d574f36

See more details on using hashes here.

File details

Details for the file oaknut_basic-12.14.0-py3-none-any.whl.

File metadata

  • Download URL: oaknut_basic-12.14.0-py3-none-any.whl
  • Upload date:
  • Size: 43.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for oaknut_basic-12.14.0-py3-none-any.whl
Algorithm Hash digest
SHA256 01a28fde132460ef13cfc61c1532299b6394e1ce98b680e070c501ddb68e0f6d
MD5 0648f02dbada7abfa32f66258f1b16b4
BLAKE2b-256 70d321640ce4462268db803efcbcd32621ae69ef2aadd9cbb1767bcc159e0c4d

See more details on using hashes here.

Release history Release notifications | RSS feed

12.15.1

2 files

12.15.0

2 files

12.14.1

2 files

This release

12.14.0 This release

2 files

12.13.1

2 files

12.12.0

2 files

12.11.0

2 files

12.10.1

2 files

12.10.0

2 files

12.9.0

2 files

12.8.2

2 files

12.8.1

2 files

12.8.0

2 files

12.7.2

2 files

12.7.1

2 files

12.7.0

2 files

12.6.2

2 files

12.6.1

2 files

12.6.0

2 files

12.5.3

2 files

12.5.2

2 files

12.5.1

2 files

12.5.0

2 files

12.4.1

2 files

12.4.0

2 files

12.3.0

2 files

12.2.0

2 files

12.1.0

2 files

12.0.1

2 files

12.0.0

2 files

11.2.0

2 files

11.1.0

2 files

11.0.2

2 files

11.0.1

2 files

11.0.0

2 files

10.7.0

2 files

10.6.0

2 files

10.5.0

2 files

10.4.0

2 files

10.3.0

2 files

10.2.0

2 files

10.1.0

2 files

10.0.5

2 files

10.0.4

2 files

10.0.3

2 files

10.0.2

2 files

10.0.1

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page