A BASIC-to-x86_64 native code compiler.
xbasic64 compiles 1980s-era BASIC dialects (Tandy Color BASIC, GW-BASIC, QuickBASIC) directly to native x86-64 executables. No interpreter, no bytecode—just fast native binaries.
Why xbasic64?
- Nostalgia: Write and run classic BASIC programs on modern hardware
- Education: Learn compiler design with a simple, readable Rust codebase
- Simplicity: Direct AST-to-assembly compilation with no intermediate representation
- Classic BASIC syntax with line numbers, named labels, or structured code
- Numeric types: Integer, Long, Single, Double (with type suffixes)
- Strings with the standard function set (
LEFT$,MID$,UCASE$,INSTR, ...), includingMID$as an assignment target - Control flow:
IF/THEN/ELSE,FOR/NEXT,WHILE/WEND,DO/LOOP,SELECT CASEwith ranges, lists andIScomparisons, andEXIT - Procedures:
SUBandFUNCTIONwith recursion;DEF FNfor one-liners - Arrays with
REDIM,REDIM PRESERVE,OPTION BASE, andLBOUND/UBOUND - User-defined record types with
TYPE, including nesting and arrays of records - File I/O: sequential reading and writing, with
EOFandLOF; random-access records withFIELD,LSET/RSET,GET/PUT,LOCKand theMKI$/CVIconversion family DATA/READ/RESTOREfor inline data- Formatted output with
PRINT USING - Runtime checks for out-of-range subscripts and division by zero, with
--unsafeto remove them - Diagnostics that name the file, line and problem rather than failing at link time, including a reason for every GW-BASIC keyword the compiler does not provide, so a program using one is refused rather than quietly misbehaving
cargo build --release# Compile a BASIC program to executable
xbasic64 program.bas
# Specify output file
xbasic64 program.bas -o myprogram
# Emit assembly only (no linking)
xbasic64 -S program.bas
# Omit the runtime safety checks
xbasic64 --unsafe program.bas' Fibonacci sequence
A = 0
B = 1
FOR I = 1 TO 10
PRINT A
C = A + B
A = B
B = C
NEXT ISave as fib.bas, compile with xbasic64 fib.bas, and run ./fib.
- Language Reference - Complete guide to the supported BASIC dialect
The compiler is a four-stage pipeline:
Source → Lexer → Parser → Semantic Analysis → Code Generator → Assembly → Executable
(tokens) (AST) (symbols) (x86-64)
- Lexer - Tokenizes BASIC source (case-insensitive keywords, line numbers, type suffixes)
- Parser - Recursive descent parser producing an AST
- Semantic analysis - Resolves names, checks types and argument counts, and reports problems with a source line
- Code Generator - Direct AST-to-x86-64 assembly translation
The runtime library provides I/O, string operations, and math functions as hand-written x86-64 assembly using libc for portability.
Key design choices:
- No IR—direct AST to assembly for simplicity
- System V AMD64 ABI for libc interoperability
- GW-BASIC type semantics (division always returns Double)
- Rust toolchain
- Linux: system assembler (
as) and C compiler/linker (cc) with libc - Windows: Clang (used to assemble) and the MSVC linker (
link.exe)
- Linux (x86-64)
- Windows (x86-64)