basic-dsl 0.3.0

A Rust procedural macro crate that provides a BASIC interpreter embedded as a domain-specific language
Documentation

BASIC DSL for Rust 🦀

A Rust procedural macro crate that provides a BASIC interpreter embedded as a domain-specific language with direct token parsing for excellent IDE support.

Features

  • Variables: Assignment with LET and arithmetic expressions
  • Input/Output: INPUT for reading user input and PRINT statements with flexible formatting
  • Control Flow: IF...THEN GOTO conditionals and GOTO jumps
  • Loops: FOR...NEXT loops with optional STEP increment
  • Program Structure: Line numbers, labels, and END termination
  • IDE Support: Full syntax highlighting, error reporting, and code completion

Usage

Add this to your Cargo.toml:

[dependencies]
basic-dsl = "0.2.0"

Then use the macro in your Rust code:

use basic_dsl::basic;

fn main() {
    basic! {
        10 LET X = 1
        20 PRINT X
        30 IF X < 5 THEN GOTO 50
        40 PRINT "DONE"
        45 END
        50 LET X = X + 1
        60 GOTO 20
    }
}

Syntax

The DSL supports classic BASIC syntax with modern IDE integration:

Statements

  • LET variable = expression - Variable assignment
  • PRINT [expression, ...] - Output values or strings (comma creates tab stops for columnar formatting, semicolon concatenates, or empty for newline)
  • INPUT [prompt,] variable - Read user input from stdin into variable (auto-detects numbers vs strings)
  • GOTO label - Jump to line number
  • IF condition THEN GOTO label - Conditional jump
  • FOR variable = start TO end [STEP increment] - Loop initialization
  • NEXT [variable] - Loop increment and condition check
  • END - Terminate program

Expressions

  • Arithmetic: +, -, *, / with proper precedence
  • Comparisons: <, <=, =, >=, >
  • Literals: Numbers (42) and strings ("Hello")
  • Variables: Any valid identifier (X, COUNTER, etc.)
  • Parentheses: For grouping expressions

Program Structure

  • Line numbers act as labels for jumps and program flow
  • Statements are written directly without quotes for full IDE support
  • Nested FOR loops and complex expressions are fully supported

Examples

Enhanced PRINT Statement

basic! {
    10 PRINT "Name", "Age", "Score"    // Tab-separated columns
    20 PRINT "Alice", 25, 95           // Comma creates tab stops  
    30 PRINT "Bob", 30, 87             // For columnar output
    40 PRINT "Concat:"; "A"; "B"       // Semicolon concatenates
    50 PRINT                           // Empty PRINT = newline
    60 END
}

Interactive INPUT

basic! {
    10 PRINT "Number Guessing Game"
    20 INPUT "Enter your guess", GUESS
    30 IF GUESS = 42 THEN GOTO 60
    40 PRINT "Wrong! The answer was 42"
    50 GOTO 70
    60 PRINT "Correct! You got it!"
    70 END
}

RustBasic FizzBuzz

basic! {
    10 PRINT "RustBasic FizzBuzz from 1 to 20:"
    20 FOR I = 1 TO 20
    30 LET A = I / 3 * 3
    40 LET B = I / 5 * 5
    50 IF A = I THEN GOTO 100
    60 IF B = I THEN GOTO 170
    70 PRINT I
    80 GOTO 180
    100 IF B = I THEN GOTO 150
    110 PRINT "Rust"
    120 GOTO 180
    150 PRINT "RustBasic"
    160 GOTO 180
    170 PRINT "Basic"
    180 NEXT I
    190 END
}

Running Examples

This repository includes example programs that you can run:

# Run the RustBasic FitzBuzz example
cargo run --bin basic

# Run comprehensive feature tests  
cargo run --bin test-features

# Run enhanced PRINT statement demo
cargo run --bin print-demo

# Test INPUT functionality with various scenarios
cargo run --bin input-test

# Play the interactive number guessing game
cargo run --bin number-guessing-game

License

Licensed under the European Union Public Licence 1.2 (EUPL-1.2).