You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An experimental QBASIC compiler written in Rust that targets the ESP32-C3 (RISC-V) microcontroller. Write embedded programs in familiar BASIC syntax instead of C/C++.
' Hello World for RustyBASIC (QBASIC dialect)DIM msg AS STRING
msg ="Hello from RustyBASIC!"PRINT msg
PRINT"Running on ESP32-C3"DIM answer AS INTEGER
answer =42PRINT"The answer is:"; answer
END
FizzBuzz
DIM i AS INTEGER
FOR i =1TO100SELECTCASE0CASE i MOD15PRINT"FizzBuzz"CASE i MOD3PRINT"Fizz"CASE i MOD5PRINT"Buzz"CASEELSEPRINT i
ENDSELECTNEXT i
END
' Reads a push button and toggles an LEDCONST BUTTON_PIN =9CONST LED_PIN =2CONST INPUT_MODE =0CONST OUTPUT_MODE =1DIM state AS INTEGER
DIM ledOn AS INTEGER
GPIO.MODE BUTTON_PIN, INPUT_MODE
GPIO.MODE LED_PIN, OUTPUT_MODE
ledOn =0
GPIO.SET LED_PIN, 0PRINT"Press the button to toggle LED..."DO
GPIO.READ BUTTON_PIN, state
IF state =0THEN ' Button pressed (active low)IF ledOn =0THEN
ledOn =1
GPIO.SET LED_PIN, 1PRINT"LED ON"ELSE
ledOn =0
GPIO.SET LED_PIN, 0PRINT"LED OFF"ENDIF ' Simple debounce
DELAY 300ENDIF
DELAY 50LOOP
SUB and FUNCTION Procedures
DECLARESUB ShowResult (label AS STRING, value AS SINGLE)
DECLAREFUNCTION Add! (a AS SINGLE, b AS SINGLE)
DIM a AS SINGLE
DIM b AS SINGLE
INPUT"First number: "; a
INPUT"Second number: "; b
CALL ShowResult("A + B", Add!(a, b))
CALL ShowResult("A * B", a * b)
ENDSUB ShowResult (label AS STRING, value AS SINGLE)
PRINT label; " = "; value
ENDSUBFUNCTION Add! (a AS SINGLE, b AS SINGLE)
Add! = a + b
ENDFUNCTION
User-Defined Types (Structs)
TYPEPoint
x AS SINGLE
y AS SINGLE
ENDTYPETYPE Rect
left AS SINGLE
top AS SINGLE
widthAS SINGLE
heightAS SINGLE
ENDTYPEDECLAREFUNCTION RectArea! (r AS Rect)
DECLARESUB PrintPoint (p ASPoint)
DIM origin ASPoint
origin.x =0.0
origin.y =0.0DIM cursor ASPoint
cursor.x =10.5
cursor.y =20.3CALL PrintPoint(origin)
CALL PrintPoint(cursor)
DIM r AS Rect
r.left =0
r.top =0
r.width=100
r.height=50PRINT"Rectangle area:"; RectArea!(r)
ENDSUB PrintPoint (p ASPoint)
PRINT"Point("; p.x; ","; p.y; ")"ENDSUBFUNCTION RectArea! (r AS Rect)
RectArea! = r.width* r.heightENDFUNCTION
Arrays
' 1D array (indices 0..5)DIM arr(5) AS INTEGER
arr(0) =10
arr(1) =20
arr(2) =30PRINT arr(0); arr(1); arr(2)
' 2D array (indices 0..2 x 0..3)DIM matrix(2, 3) AS SINGLE
matrix(1, 2) =99.5PRINT"Matrix(1,2) ="; matrix(1, 2)
I2C Communication
' Reads temperature from a BMP280 sensor over I2CCONST I2C_BUS =0CONST SDA_PIN =4CONST SCL_PIN =5CONST I2C_FREQ =100000CONST BMP280_ADDR =118CONST REG_CHIP_ID =208CONST REG_TEMP_MSB =250DIM chipId AS INTEGER
DIM rawTemp AS INTEGER
PRINT"Initializing I2C bus..."
I2C.SETUP I2C_BUS, SDA_PIN, SCL_PIN, I2C_FREQ
' Write register address, then read chip ID
I2C.WRITE BMP280_ADDR, REG_CHIP_ID
I2C.READ BMP280_ADDR, 1, chipId
PRINT"Chip ID:"; chipId
IF chipId =88THENPRINT"BMP280 detected!" ' Read raw temperature MSB
I2C.WRITE BMP280_ADDR, REG_TEMP_MSB
I2C.READ BMP280_ADDR, 1, rawTemp
PRINT"Raw temp MSB:"; rawTemp
ELSEPRINT"Unknown device"ENDIFEND
' Demonstrates the full WiFi lifecycleDIM ssid AS STRING
DIM pass AS STRING
DIM status AS INTEGER
ssid ="MyNetwork"
pass ="MyPassword"PRINT"Connecting to WiFi..."
WIFI.CONNECT ssid, pass
DELAY 3000
WIFI.STATUS status
IF status =1THENPRINT"Connected!"PRINT"Doing some work..."
DELAY 2000PRINT"Disconnecting..."
WIFI.DISCONNECT
DELAY 1000
WIFI.STATUS status
IF status =0THENPRINT"Disconnected successfully."ELSEPRINT"Still connected."ENDIFELSEPRINT"Failed to connect."ENDIFEND
DIM response$ AS STRING
WIFI.CONNECT "MyNetwork", "MyPassword"
DELAY 3000
HTTP.GET"http://httpbin.org/get", response$
PRINT response$
END
INCLUDE Directive
Split code across multiple files with INCLUDE:
include_lib.bas
CONST PI =3.14159CONST GREETING ="Hello from the library!"DECLARESUB PrintBanner (title AS STRING)
DECLAREFUNCTION CircleArea! (radius AS SINGLE)
SUB PrintBanner (title AS STRING)
PRINT"==========================="PRINT" "; title
PRINT"==========================="ENDSUBFUNCTION CircleArea! (radius AS SINGLE)
CircleArea! = PI * radius * radius
ENDFUNCTION
include_main.bas
INCLUDE "include_lib.bas"DIM r AS SINGLE
r =5.0CALL PrintBanner(GREETING)
PRINT"Radius:"; r
PRINT"Area:"; CircleArea!(r)
END
Paths are resolved relative to the including file's directory. Circular includes are detected and reported as errors.
ENUM Types
ENUM Color
Red =1
Green =2
Blue =3END ENUM
DIM c AS INTEGER
c =Color.Green
PRINT"Color:"; c ' prints 2
FOR EACH (Array Iteration)
DIM scores(4) AS INTEGER
scores(0) =90
scores(1) =85
scores(2) =92
scores(3) =78
scores(4) =95FOR EACH s AS INTEGER IN scores
PRINT"Score:"; s
NEXTEND
String Interpolation
DIMnameAS STRING
DIM age AS INTEGER
name="Alice"
age =30PRINT $"Hello, {name}! You are {age} years old."
TRY/CATCH Error Handling
PRINT"Before try"
TRY
PRINT"Inside try block"PRINT"This should work fine"
CATCH errPRINT"Caught error: "; errEND TRY
PRINT"After try/catch"END
LAMBDA Expressions
DIM square ASFUNCTION
square = LAMBDA(x AS INTEGER) => x * x
DIM result AS INTEGER
result = square(5)
PRINT"5 squared = "; result
END
ASSERT
DIM x AS INTEGER
x =42
ASSERT x >0, "x must be positive"
ASSERT x =42PRINT"All assertions passed!"END
DIM count AS INTEGER
count =0ONTIMER1000GOSUB tick
PRINT"Timer event registered"
DELAY 5000PRINT"Count: "; count
END
tick:
count = count +1PRINT"Tick!"RETURN
State Machine DSL
MACHINE TrafficLight
STATE RED
ONTIMERGOTO GREEN
END STATE
STATE GREEN
ONTIMERGOTO YELLOW
END STATE
STATE YELLOW
ONTIMERGOTO RED
END STATE
END MACHINE
PRINT"Traffic light created"
TrafficLight.EVENT "TIMER"PRINT"After first event"END
MODULE Namespaces
MODULE Math
FUNCTION Square(x AS INTEGER) AS INTEGER
Square = x * x
ENDFUNCTIONFUNCTION Cube(x AS INTEGER) AS INTEGER
Cube = x * x * x
ENDFUNCTIONEND MODULE
DIM a AS INTEGER
a = Math.Square(4)
PRINT"4 squared = "; a
a = Math.Cube(3)
PRINT"3 cubed = "; a
END
DO...LOOP Variations
DIM count AS INTEGER
DIM sum AS INTEGER
' Pre-condition: DO WHILE...LOOP
count =1
sum =0DOWHILE count <=10
sum = sum + count
count = count +1LOOPPRINT"Sum 1..10 ="; sum
' Post-condition: DO...LOOP UNTIL
count =10DOPRINT count;
count = count -1LOOP UNTIL count <1PRINT' EXIT DO
count =0DO
count = count +1IF count =5THENEXITDOLOOPPRINT"Exited at count ="; count
END