A Microsoft QBasic-compatible BASIC compiler implemented in Go. Compiles BASIC source code to native executables via LLVM IR emission.
Source (.bas) -> Lexer -> Parser -> AST -> Semantic Analyzer -> LLVM IR -> Object -> Link -> Executable
# Build
go build -o finn-basic ./cmd/finn-basic
# Compile a BASIC program
./finn-basic compile program.bas -o program
# Run the compiled program
./programfinn-basic compile <file.bas> # Compile to native executable
finn-basic compile --emit-ir <file.bas> # Emit LLVM IR (.ll file)
finn-basic compile --dump-ast <file.bas> # Print AST and exit
finn-basic lint <files...> # Lint BASIC source files
finn-basic lsp --stdio # Start language server
finn-basic version # Print compiler version
finn-basic help # Show usage| Flag | Description |
|---|---|
-o <name> |
Output executable name (default: a.out) |
--emit-ir |
Write .ll file instead of compiling |
--dump-ast |
Print AST and exit |
--trace |
Enable trace output |
finn-basic/
├── cmd/finn-basic/
│ ├── main.go # CLI entry point
│ └── compile.go # compile subcommand
├── internal/
│ ├── lexer/ # Tokenizer
│ ├── parser/ # Recursive descent parser
│ ├── ast/ # AST node definitions
│ ├── analyzer/ # Semantic analysis
│ ├── types/ # Type system
│ ├── lsp/ # Language server protocol
│ └── lint/ # Linter rules
└── testdata/ # Example programs and golden files
- Line numbers (optional)
- PRINT, INPUT, READ/DATA/RESTORE
- LET (implicit and explicit)
- IF/THEN/ELSE (single and multi-line)
- FOR/NEXT, WHILE/WEND, DO/LOOP
- GOTO, GOSUB/RETURN
- ON...GOTO / ON...GOSUB
- SELECT CASE
- DIM, REDIM, REDIM PRESERVE
- SUB/FUNCTION declarations
- DEF FN (single-line functions)
- DEFINT/DEFDBL/DEFSTR type declarations
- SWAP, POKE/PEEK
- CLS, SCREEN, COLOR, LINE, CIRCLE, LOCATE
- REM comments and nested
(* ... *)comments - String functions: LEN, LEFT$, RIGHT$, MID$, STR$, VAL, CHR$, ASC, etc.
- Math functions: ABS, SIN, COS, TAN, SQR, INT, RND, etc.
- Conversion functions: CDBL, CSNG, CINT, CLNG, CSTR
- ON ERROR GOTO / RESUME NEXT
| ID | Description | Severity |
|---|---|---|
| W001 | Variable assigned but never used | warning |
| W002 | Line number declared but never referenced | warning |
| W004 | GOTO jumps to the next line (no-op) | warning |
| W005 | IF statement has empty body | warning |
| S003 | Line numbers have gaps | style |
| S004 | No REM header at top of file | style |
# Run all tests
go test ./...
# Run tests with verbose output
go test ./... -v
# Build and test manually
go build -o finn-basic ./cmd/finn-basic/
./finn-basic compile testdata/hello.bas -o /tmp/hello
/tmp/helloThe LSP server provides IDE features for BASIC source files:
- Diagnostics: Real-time error and warning reporting
- Completion: Keywords, built-in functions, and variables
- Hover: Type and declaration info
- Definition: Jump to variable/subroutine declarations
# Start the server (for editor integration)
./finn-basic lsp --stdio{
"basic.languageServer.command": "finn-basic",
"basic.languageServer.args": ["lsp", "--stdio"],
"files.associations": {
"*.bas": "basic",
"*.BAS": "basic"
}
}# Lint and vet (required between development steps)
go vet ./...
go fix ./...
# Run linter
golangci-lint run
# Run tests
go test ./...10 REM Fibonacci sequence
20 a = 0
30 b = 1
40 FOR i = 1 TO 10
50 PRINT a
60 c = a + b
70 a = b
80 b = c
90 NEXT i
100 ENDSee LICENSE file for details.