A BASIC language interpreter. Does not conform to existing standards. Mostly a toy.

Overview

logo

JW-Basic

LoC

A toy language that is somewhat like QBasic.

Features:

  • Graphics: 160x96 (255 colors & transparent)
  • Text: 32x16 (4x5 font)
  • Character set: ASCII (32-127)
  • Keyboard input
  • Multidimensional arrays

Design:

  • Parses tokens using nom and nom_locate
  • Syntax & expression tree parsed with from tokens
  • Assembly-like instructions emitted from syntax
  • Instructions executed using a register-based virtual machine
  • Graphics & text output using Screen-13
  • Operates as a library or command-line program

Language demonstration:

' This is a comment! Types you may use:
'  ?: Boolean
'  @: Unsigned byte
'  %: Signed 32-bit integer
'  !: Single-precision float
'  $: String

DIM myVar$ = "Variable initialization is optional"
DIM answer% = 42, question? = TRUE
DIM latitude!

' Type specifiers are not required:
latitude = 100.0

IF question THEN
    latitude! = -100.0!
END IF

CLS
PRINT "Hello, there!", myVar

' A diagonal red line
LINE (0, 13) - (159, 21), 4@

' Some colorful boxes
FOR c = 25 TO 95 STEP 3
    RECTANGLE (c - 5, c - 3) - (159, c), CBYTE(c), TRUE
NEXT

See full specification below

Example Programs

This repository contains several example programs. Access the helpfile with --help:

A BASIC language interpreter. Does not conform to existing standards. Mostly a toy.

Usage: jw-basic [OPTIONS] <PATH>

Arguments:
  <PATH>
          File to load and interpret (.bas format)

Options:
  -d, --debug
          Display debugging information
          
          NOTE: Set `RUST_LOG=debug` environment variable to display output

  -h, --help
          Print help (see a summary with '-h')

  -V, --version
          Print version

Hello, world!

examples/hello_world.bas

cargo run examples/hello_world.bas

Preview

Raycast

examples/raycast.bas

cargo run examples/raycast.bas

Preview

Language Specifications

ABS[! | %](expr) | COS[!](expr) | SIN[!](expr)

    Math functions.

    expr: Any expression.

    Examples:

        ABS(-1.0) + COS(4.5) ' Radians of course!


CLS

    CLS clears the screen of text and graphics. Color 0 is used.


COLOR foreground@[, background@]

    COLOR sets text and graphics colors.

    foreground: The color of characters and any lines or rectangles which do not specify a color.
    backround:  The backgroud of text characters or the fill-color of rectangles which do not
                specify a color.

    Examples:

        COLOR 4, 14 ' Red on yellow, danger!


CBOOLEAN[?](expr) | CBYTE[@](expr) | CFLOAT[!](expr) | CINT[%](expr) | CSTR[$](expr)

    Converts an expression to another type.

    expr: Any expression.

    Examples:

        CSTR(1.0)


DIM var[type][(subscripts)] [= value] [, var[type][(subscripts)]] [= value] ...

    DIM declares variables and arrays. Variables may also be simply assigned without DIM.

    var:        The name of a variable.
    type:       Type of data which may be stored:
                    ? (boolean)
                    @ (byte)
                    ! (float)
                    % (integer)
                    $ (string)
    subscripts: [lower% TO] upper% [, [lower% TO] upper%] ...
                lower: Lower bound of the array. The default bound is zero.
                upper: Upper bound of the array. Inclusive.
    value:      Any expression. Not supported with arrays yet.

    Examples:

        DIM name$, myMatrix!(2, -2 TO 2)
        DIM total% = 5
        myMatrix(2, -2) = 10.0


FOR var = start TO end [STEP step]
    [..]
NEXT [var]

    Loop where `var` is incremented (or decremented) from `start` to `end` in `step` increments.

    var:   A byte, float, or integer variable defined for the body of the FOR..NEXT statement.
    start: Any expression evaluated to become the initial value of `var`.
    end:   Any expression evaluated to become the inclusive final value of `var`.
    step:  Any expression evaluated to be added to `var` for each iteration.

    Examples:

        FOR temperature = 96.0 to 104.5 STEP 0.1
            PRINT temperature
        NEXT


GOTO [label | line number]

    Jumps directly to a given labelled or numbered line. Fun at parties.

    Examples:

        Again:
        PRINT "Dance!"
        GOTO Again


IF expr THEN
    [..]
[ELSE IF expr THEN]
    [..]
[ELSE THEN]
    [..]
END IF

    Branching logic tree.

    expr: Any expression which evaluates to a boolean.


KEYDOWN[@](expr)

    Returns TRUE when a given key is pressed.

    expr: Any expression which evaluates to a byte, see source code for the keys which have
          been setup.


LINE [(x0, y0) -] (x1, y1), color

    Draws a line between two points.

    x0, y0, x1, y1: Any expression which evaluates to an integer.
    color:          Any expression which evaluates to a byte.


LOCATE row[, col]

    Moves the text output location of the following PRINT statements.


PALETTE color, r, g, b

    Changes the currently active palette allowing for colorful animation without re-drawing the
    screen.

    color:   Any expression which evaluates to a byte in the 0-254 range. 255 (&hFF@) is
             transparent.
    r, g, b: Any expression which evaluates to a byte.


PRINT [expr][; expr][, expr]

    PRINT displays text using the current foreground and background colors at the current cursor
    location.

    expr:       Any expression.
    semicolon:  Prints the following expression with zero additional spaces.
    comma:      Prints the following expression with one additional space.

    Examples:

        PRINT "Hello " + name$ + ". Nice to meet you!", "Welcome to day ", dayOfWeek%; "!"


RECTANGLE [(x0, y0) -] (x1, y1), color[, filled]

    Draws a rectangle between two points.

    x0, y0, x1, y1: Any expression which evaluates to an integer.
    color:          Any expression which evaluates to a byte.
    filled:         Any expression which evaluates to a boolean.


TIMER[%]()

    Returns the number of microseconds since the program began execution.


WHILE expr
    [..]
WEND

    Loop which begins if `expr` is TRUE and continues until it is FALSE.

    expr: Any expression which evaluates to a boolean.


YIELD

    Pause execution of a program until the next update of the interpreter. Without calling this
    execution will continue until the final statement is executed.

Tests

In addition to the test programs, there are unit and integration tests of the language. When something goes wrong you should receive an error indicating the line and column number which caused the issue.

Running the tests:

cargo test

Credits

This project was designed completely for fun and to learn how a language might be developed. I hope you find something useful that you can bring to your projects, just like I was able to find sources of inspiration for JW-Basic.

Feel free to submit PRs if you would like to enhance this code or fill out remaining features.

You might also like...
A pastebin that does just enough to be really useful.

Rocket Powered Pastebin (rktpb | paste.rs) A pastebin that does just enough to be really useful. Really fast, really lightweight. Renders markdown lik

🐢 Atuin replaces your existing shell history with a SQLite database, and records additional context for your commands
🐢 Atuin replaces your existing shell history with a SQLite database, and records additional context for your commands

Atuin replaces your existing shell history with a SQLite database, and records additional context for your commands. Additionally, it provides optional and fully encrypted synchronisation of your history between machines, via an Atuin server.

A curated list of replacements for existing software written in Rust

Awesome Alternatives in Rust A curated list of replacements for existing software written in Rust. If you want to contribute, please read CONTRIBUTING

Rust TUI library - Clipping region is a set of min/max x/y values applied to the existing region

TinyBit Clipping region is a set of min/max x/y values applied to the existing region A TUI lib This is not yet production ready T O D O TODO: bugs: T

A user-friendly re-implementation of existing hex tools in Rust
A user-friendly re-implementation of existing hex tools in Rust

Hex A project to create alternate (and more user friendly) versions of existing hex tools. The project can be installed as a extension to the github-c

📦 Distribute Roblox games as standalone executables -- No existing client necessary. 🚧
📦 Distribute Roblox games as standalone executables -- No existing client necessary. 🚧

📦 Packer Distribute Roblox games as standalone executables. 🚧 Packer is still being worked on. Among many other things, Windows is not currently sup

Rust-based interpreter for the Dreamberd (https://github.com/TodePond/DreamBerd) language

Dreamberd.rs Rust-based interpreter for the Dreamberd language. The full specification for Dreamberd is available at https://github.com/TodePond/Dream

An interpreter and compiler for the Brainfuck language.

Brainrust 🧠 An interpreter and compiler for the Brainfuck language. Prerequisites You need a LLVM 16.0.* installation on your system. On Windows, you

Turbine is a toy CLI app for converting Rails schema declarations into equivalent type declarations in other languages.

Turbine Turbine is a toy CLI app for converting Rails schema declarations into equivalent type declarations in other languages. It’s described as a to

Owner
John Wells
John Wells
Use your computer as a cosmic ray detector! One of the memory errors Rust does not protect against.

Your computer can double up as a cosmic ray detector. Yes, really! Cosmic rays hit your computer all the time. If they hit the RAM, this can sometimes

Johanna Sörngård 110 Jun 16, 2023
An Interpreter for Brainfuck programming language implemented in the Rust programming language with zero dependencies.

Brainfuck Hello, Visitor! Hey there, welcome to my project showcase website! It's great to have you here. I hope you're ready to check out some awesom

Syed Vilayat Ali Rizvi 7 Mar 31, 2023
JA4+ is a suite of network fingerprinting standards

JA4+ Network Fingerprinting JA4+ is a suite of network fingerprinting methods that are easy to use and easy to share. These methods are both human and

FoxIO 94 Oct 5, 2023
My solutions to Advent of Code 2021 (mostly in rust)

Advent of Code 2021 Small code to solve problems at https://adventofcode.com/2021. Most of the code are written in Rust. How to run solutions For exam

“Plane” Abhabongse  Janthong 3 Apr 22, 2022
A rust binary that will flip one or more bits of a file (mostly for messing with images for fun).

file-bitflipper A rust binary that will flip one or more bits of a file (mostly for messing with images for fun). Example (bitflipped bentley) Usage $

null 1 Aug 31, 2022
A Rust-based shell script to create a folder structure to use for a single class every semester. Mostly an excuse to use Rust.

A Rust Course Folder Shell Script PROJECT IN PROGRESS (Spring 2022) When completed, script will create a folder structure of the following schema: [ro

Sebastián Romero Cruz 1 Apr 10, 2022
A crate that allows you to mostly-safely cast one type into another type.

A crate that allows you to mostly-safely cast one type into another type. This is mostly useful for generic functions, e.g. pub fn foo<S>(s: S) {

Bincode 3 Sep 23, 2023
ddi is a wrapper for dd. It takes all the same arguments, and all it really does is call dd in the background

ddi A safer dd Introduction If you ever used dd, the GNU coreutil that lets you copy data from one file to another, then you may have encountered a ty

Tomás Ralph 80 Sep 8, 2022
Human numeric sorting program — does what `sort -h` is supposed to do!

hns — Human Numeric Sort v0.1.0 (⏫︎2022-09-20) © 2022 Fredrick R. Brennan and hns Authors Apache 2.0 licensed, see LICENSE. man page Packages hns_0.1.

Fredrick Brennan 7 Sep 25, 2022
Parallel iteration of FASTA/FASTQ files, for when sequence order doesn't matter but speed does

Rust-parallelfastx A truly parallel parser for FASTA/FASTQ files. Principle The input file is memory-mapped then virtually split into N chunks. Each c

Rayan Chikhi 8 Oct 24, 2022