Skip to content

3583Bytes/Arcade-BASIC

Repository files navigation

Arcade BASIC

CI Release .NET Spec: ISO 10279

Replace OWNER/REPO in the badges above with your GitHub owner/repo once the project is pushed.

Arcade BASIC is an interpreter and compiler for the Full BASIC language (ISO/IEC 10279:1991, ANSI X3.113-1987), written in C#.

Documentation

  • Architecture — the pipeline, project graph, key data structures, target-framework strategy.
  • Contributing — build/test loop and concrete recipes for adding builtins, statements, opcodes.
  • Conformance — known deviations from ISO 10279:1991 and implementation-defined choices.
  • Examples — sample programs with a feature matrix across tree-walker and bytecode VM.

Targets

Library assemblies (lexer through VM) multi-target net9.0 and netstandard2.1, so they're embeddable in Unity (Mono/IL2CPP), Xamarin, .NET Framework, and any other netstandard2.1 host. The CLI stays single-target net9.0 for AOT publishing and host-specific APIs.

Unity

The unity/ folder is a ready-to-use UPM (Unity Package Manager) package — package.json, ArcadeBasic.asmdef, and an InGameConsole sample with a one-click scene builder that drops an in-game REPL (TMP input + scrollable transcript + Run button) into your project. Once installed, embedding a BASIC program is one call:

using ArcadeBasic;

var result = BasicEngine.Run("PRINT 6 * 7", out string output);
Debug.Log(output);   // " 42 "

See unity/README.md for install instructions (UPM via git URL, or extract the release ZIP into Packages/). The release CI builds the netstandard2.1 DLLs and bundles them into a arcade-basic-unity-<version>.zip artifact attached to every tagged release.

Status

Three execution paths land an Arcade BASIC program in different forms:

  • arcade-basic run <file> — tree-walking interpreter. The most complete front end: arrays, MAT, file I/O, exception handling, modules, PRINT USING, INPUT.
  • arcade-basic vm <file> — compile to stack bytecode and run on the VM. Currently a subset of the tree-walker (no arrays/MAT, no file I/O, no exceptions, no modules, no PRINT USING, no INPUT).
  • arcade-basic build <file> [-o out] — bundle the VM and the compiled program into a single self-contained native binary (Phase 10, Path E). Same feature subset as vm.

Pipeline phases 0–10 are all merged. Optional Phase 8 modules are partial: PRINT USING (8a) is done; graphics + picture (SVG backend) and fixed-decimal are not.

See examples/README.md for a feature matrix across the sample programs.

Build

Requires .NET 9 SDK.

dotnet build                                       # debug build
dotnet test                                        # all unit + integration tests
dotnet run --project src/ArcadeBasic.Cli -- run <f>  # invoke the CLI

# AOT-publish a standalone CLI for the current platform
dotnet publish src/ArcadeBasic.Cli -c Release /p:PublishAot=true
# → ./publish/aot/ArcadeBasic.Cli

CLI

arcade-basic <command> [args]

  lex <file>              tokenize and print the token stream
  parse <file>            lex + parse, pretty-print the AST
  analyze <file>          lex + parse + sema, print symbol/DATA summary
  run <file> [mod ...]    tree-walking interpreter (most complete)
  vm <file>               compile to bytecode and run on the VM (subset)
  build <file> [-o out]   produce a self-contained native binary
  repl                    interactive Arcade BASIC session
  --version
  --bigdecimal-spike      BigDecimal AOT smoke test

Try the REPL

dotnet run --project src/ArcadeBasic.Cli -- repl
Arcade BASIC REPL — type .help for commands, .exit to quit.
> LET X = 42
> PRINT X * 2
 84
> FOR I = 1 TO 4
...   PRINT I, I * I
... NEXT I
 1               1
 2               4
 3               9
 4               16
> PRINT SIN(PI / 2)
 1
> .exit
bye.

The REPL accumulates each accepted line into the session; variables persist, multi-line blocks (FOR/DO/IF/SELECT/SUB/FUNCTION/DEF/MODULE/WHEN) are detected and the prompt switches to ... until the block closes. Bad input doesn't pollute the session. .list shows the accumulated source, .clear resets it.

INPUT and RANDOMIZE don't round-trip cleanly through the REPL's re-execute-each-turn model — for those, run a .bas file with arcade-basic run.

Running the example programs

The 13 sample programs in examples/ exercise different parts of the language. Pick one and run it through any of the three execution paths:

# Tree-walking interpreter — supports every example
dotnet run --project src/ArcadeBasic.Cli -- run examples/hello.bas
dotnet run --project src/ArcadeBasic.Cli -- run examples/factorial.bas
dotnet run --project src/ArcadeBasic.Cli -- run examples/matrix.bas
dotnet run --project src/ArcadeBasic.Cli -- run examples/exception.bas
dotnet run --project src/ArcadeBasic.Cli -- run examples/modules.bas
dotnet run --project src/ArcadeBasic.Cli -- run examples/guess.bas    # reads from stdin
dotnet run --project src/ArcadeBasic.Cli -- run examples/startrek.bas # Super Star Trek (Ahl 1978)
dotnet run --project src/ArcadeBasic.Cli -- run examples/lunar.bas    # Lunar Lander (Storer 1969)

# Bytecode VM — only the examples marked ✓ in examples/README.md
dotnet run --project src/ArcadeBasic.Cli -- vm examples/hello.bas
dotnet run --project src/ArcadeBasic.Cli -- vm examples/factorial.bas
dotnet run --project src/ArcadeBasic.Cli -- vm examples/strings.bas
dotnet run --project src/ArcadeBasic.Cli -- vm examples/pi.bas

Inspect intermediate stages of any program:

dotnet run --project src/ArcadeBasic.Cli -- lex     examples/factorial.bas
dotnet run --project src/ArcadeBasic.Cli -- parse   examples/factorial.bas
dotnet run --project src/ArcadeBasic.Cli -- analyze examples/factorial.bas

After an AOT publish, use the native CLI directly (much faster startup) and produce a standalone binary for any VM-compatible example:

dotnet publish src/ArcadeBasic.Cli -c Release /p:PublishAot=true

./publish/aot/ArcadeBasic.Cli run examples/primes.bas
./publish/aot/ArcadeBasic.Cli vm  examples/pi.bas

./publish/aot/ArcadeBasic.Cli build examples/factorial.bas -o factorial
./factorial

Architecture

Project Purpose
ArcadeBasic.Core source files, positions, diagnostics
ArcadeBasic.Lexer tokenizer
ArcadeBasic.Parser recursive-descent parser → immutable AST (abstract record class)
ArcadeBasic.Sema two-pass analyzer; symbol/scope resolution attached as a side table
ArcadeBasic.Runtime numeric/string/array values (Singulink BigDecimal), builtins, picture-string formatter, file I/O
ArcadeBasic.Interpreter tree-walking interpreter with explicit handler stack and FlowControl returns
ArcadeBasic.Bytecode opcode enum, chunk format, serializer
ArcadeBasic.Compiler AST → bytecode lowering
ArcadeBasic.Vm stack-based VM
ArcadeBasic.Cli command dispatcher + Phase-10 self-extracting stub

Locked architectural decisions (decimal library, value hierarchy, handler-stack design, MAT semantics, etc.) live alongside the code; behavioural deviations from the spec will be tracked in docs/conformance.md.

Conformance

Tested against spec-derived programs written from ISO 10279 section numbers. The NBS Minimal BASIC Test Programs corpus (NBSIR 78-1420) was originally planned as the oracle but is deferred — the archive.org OCR is too column-shredded for clean programmatic extraction. Revisiting it requires re-OCRing the PDFs or transcribing by hand.

License

TBD.

About

No description, website, or topics provided.

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages