# brusic

A GW-BASIC interpreter written in Rust. Loads and executes original `.BAS` programs from the MS-DOS era on any modern platform (macOS, FreeBSD, Linux, Windows).

This is neither an emulator (DOSBox already does that) nor a modernised BASIC (FreeBASIC does that). It is a compatible interpreter: take a vintage `.BAS` file, run `brusic program.bas`, and see the same output the original user would have seen.

## Building

Requires Rust (1.70+). Install with:

```sh
cargo install --path .
```

This places the `brusic` binary in `~/.cargo/bin/`.

## Usage

```sh
brusic program.bas
```

Both ASCII-format `.BAS` files (saved with the `,A` option in GW-BASIC) and tokenised binary `.BAS` files (the default save format) are supported. The binary loader detokenises the file back to text before parsing, so both formats pass through the same interpreter.

### Example

```basic
10 REM Hello World
20 FOR I = 1 TO 5
30   PRINT "Hello, World! #"; I
40 NEXT I
50 END
```

```sh
$ brusic hello.bas
Hello, World! # 1
Hello, World! # 2
Hello, World! # 3
Hello, World! # 4
Hello, World! # 5
```

## Current Status

See [SPECIFICATION.md](SPECIFICATION.md) for detailed architecture and technical decisions.

### What works today

- **Core language**: `PRINT`, `LET`, `REM`, `END`, `STOP`
- **Control flow**: `GOTO`, `GOSUB`/`RETURN`, `FOR`/`NEXT` (with `STEP`), `WHILE`/`WEND`, `IF`/`THEN`/`ELSE`, `ON...GOTO`/`GOSUB`
- **Expressions**: Full operator precedence (13 levels), arithmetic, string concatenation, relational and logical operators
- **Variables**: Scalar variables with type suffixes (`%`, `!`, `#`, `$`), arrays with `DIM`, `OPTION BASE`, `ERASE`, `SWAP`
- **Type defaults**: `DEFINT`, `DEFSNG`, `DEFDBL`, `DEFSTR`
- **User-defined functions**: `DEF FN` with parameters
- **Built-in functions**: All math (`ABS`, `SQR`, `SIN`, `COS`, `TAN`, `ATN`, `LOG`, `EXP`, `INT`, `FIX`, `SGN`, `RND`), all string (`LEFT$`, `RIGHT$`, `MID$`, `LEN`, `CHR$`, `ASC`, `INSTR`, `STR$`, `VAL`, `HEX$`, `OCT$`, `SPACE$`, `STRING$`), type conversion (`CINT`, `CSNG`, `CDBL`)
- **Data I/O**: `DATA`, `READ`, `RESTORE`
- **Error handling**: `ON ERROR GOTO`, `RESUME`, `RESUME NEXT`, `RESUME` line, `ERR`, `ERL`, `ERROR`
- **Formatted output**: `PRINT USING` with all numeric and string format fields (`#`, `.`, `+`, `-`, `**`, `$$`, `**$`, commas, `^^^^`, `!`, `\`, `&`, `_` escape), mid-statement `USING` after semicolons, `PRINT#` with `USING`/`TAB`/`SPC`
- **Terminal control**: `CLS`, `LOCATE`, `COLOR` (CGA palette), `WIDTH`, `CSRLIN`, `POS`, `INKEY$`, `VIEW PRINT` (with lazy raw mode via crossterm)
- **File I/O**: Sequential (`OPEN FOR INPUT`/`OUTPUT`/`APPEND`, `PRINT#`, `WRITE#`, `INPUT#`, `LINE INPUT#`), random-access (`OPEN...AS #n LEN=n`, `GET#`, `PUT#`, `LOF`, `LOC`), `FIELD`/`LSET`/`RSET`, `MKI$`/`MKS$`/`MKD$`/`CVI`/`CVS`/`CVD`, `INPUT$(n,#f)`
- **File management**: `KILL`, `FILES` (with wildcard expressions), `NAME...AS`
- **User input**: `INPUT` (with prompt, `INPUT;` to suppress CR), `LINE INPUT` (with `LINE INPUT;`)
- **System**: `DATE$`, `TIME$`, `ENVIRON$`, `SHELL`, `TIMER`, `CLEAR`, `TRON`/`TROFF`
- **Graphics**: `SCREEN 1`/`2`/`7` (CGA/EGA modes via `winit`+`softbuffer` window), `LINE` (with `B`/`BF`), `CIRCLE` (arcs, ellipses), `DRAW` (turtle graphics), `PAINT` (flood fill), `PSET`/`PRESET`/`POINT`, `GET`/`PUT` sprites (XOR/PSET/OR/AND), `VIEW`/`WINDOW` (viewport and world coordinates), CGA 8x8 bitmap font rendering, multi-page display with `PCOPY`
- **Virtual memory**: `PEEK`, `POKE`, `DEF SEG` with emulated CGA video memory at `&HB800`
- **Sound**: `BEEP`, `SOUND` (frequency + duration), `PLAY` (music macro language with notes, octaves, tempo, dotted notes, sharps/flats)
- **Event trapping**: `ON KEY(n) GOSUB`, `KEY(n) ON/OFF/STOP`, user-defined keys 15-20 for interrupt-driven keyboard input
- **Editor**: Full-screen TUI (`ratatui`) with `LIST`, `RUN`, `SAVE`, `LOAD`, `DELETE`, `NEW`, `RENUM`, syntax highlighting
- **Binary file loading**: Tokenised `.BAS` files with full token table (single-byte, `0xFD`/`0xFE`/`0xFF` prefix tables), MBF-to-IEEE float conversion, `VARPTR(#n)` stub
- **Literals**: Integer, single-precision, double-precision, string, hex (&H), octal (&O)

All 10 implementation phases and Milestones A–D are complete.

### Out of scope

The following are deliberately excluded — they are tied to IBM PC hardware or have no meaningful equivalent on modern systems:

- **Hardware I/O**: `INP`, `OUT`, `WAIT`, `USR`, `CALL`, `BLOAD`, `BSAVE`. These manipulate raw I/O ports and memory blocks.
- **Serial and device I/O**: `COM`, `LPRINT`, `PEN`, `STICK`, `STRIG`, `MOTOR`.
- **Higher EGA/VGA modes**: `SCREEN 8`–`SCREEN 13`. Only `SCREEN 0`/`1`/`2`/`7` are implemented.
- **Protected files**: Encrypted `.BAS` files (saved with `,P`) are not supported.

See [SPECIFICATION.md](SPECIFICATION.md) for the full list with rationale.

## Licence

MIT
