Pi BASIC Interpreter
A modern, lightweight BASIC interpreter written in C, designed to run on any Linux system — from a standard PC down to a Raspberry Pi. It follows classic BASIC syntax closely while adding capabilities that make it genuinely useful for scripting, education, data processing, and embedded hardware projects.
Features at a Glance
| Category | Highlights |
|---|---|
| Language | Dynamic and strict typing, full expression engine, all loop types, recursion, BYREF |
| Data Structures | Arrays (47-function library), Dictionaries, 2D Matrices |
| String Processing | 40+ string functions, full Regex library (PCRE2) |
| Cryptography | MD5, SHA-1, SHA-256, HMAC, AES-128/192/256 (ECB/CBC/CTR), Base64, CRC32 |
| Networking | HTTP/HTTPS client (GET/POST/PUT/PATCH/DELETE), WebSocket client/server |
| Data Formats | JSON parser/generator, CSV parser/writer with auto-delimiter detection |
| File System | 30+ file and directory functions |
| Concurrency | Threads, mutexes, semaphores, condition variables, lock-free atomics |
| Hardware | GPIO, PWM, I2C, SPI (Raspberry Pi) |
| System | Shell execution, system info, process control, user/group management |
| FFI | Load and call functions from any .so shared library at runtime |
| Developer UX | Interactive REPL with history, library import system |
Language
Syntax and Types
- Traditional BASIC syntax —
LETis optional, identifiers are case-insensitive, comments with'orREM - Six data types —
NUMBER(double-precision float),INTEGER(64-bit signed),BOOLEAN,STRING, arrays, dictionaries - Optional strict typing —
DIM name AS TYPEenforces a type at runtime; omit for fully dynamic variables - Type keywords —
NUMBER=DOUBLE=FLOAT;INTEGER=INT;BOOLEAN=BOOL - Single-quote strings —
'text'as an alternative to"text"
Control Flow
IF / ELSE IF / ELSE / END IF—ELSEIFandENDIFalso acceptedFOR / NEXTwith optionalSTEPWHILE / WENDDO / LOOP WHILE|UNTILSELECT CASE— withTOranges, multiple values perCASE, andCASE ELSEBREAKandCONTINUE— work in every loop type
Functions
- User-defined functions with local scoping and the
GLOBALkeyword - Pass-by-value (default) and pass-by-reference (
BYREF) for scalars, arrays, and dictionaries - Recursion up to 50 levels deep
- Functions can return arrays and dictionaries
Library System
IMPORT "file.bas" / INCLUDE "file.bas" — execute a BASIC file in-place, making all its functions and variables available to the importing program.
Data Structures
Arrays
Declared with DIM name[size] or DIM name[size] AS TYPE. A 47-function built-in library covers:
- Manipulation —
ARR_PUSH,ARR_POP,ARR_SHIFT,ARR_UNSHIFT,ARR_INSERT,ARR_REMOVE,ARR_REVERSE,ARR_SWAP - Sorting —
ARR_SORT_ASC,ARR_SORT_DESC,ARR_SORT_NUM_ASC,ARR_SORT_NUM_DESC - Search —
ARR_FIND,ARR_FIND_LAST,ARR_BINARY_SEARCH,ARR_CONTAINS - Statistics —
ARR_SUM,ARR_AVG,ARR_MIN,ARR_MAX,ARR_MEDIAN,ARR_STDEV,ARR_PERCENTILE - Set operations —
ARR_UNION,ARR_INTERSECT,ARR_DIFF,ARR_UNIQUE - Generation —
ARR_RANGE,ARR_FILL,ARR_LINSPACE - Transformation —
ARR_SLICE,ARR_COPY,ARR_CONCAT,ARR_FLATTEN,ARR_MAP,ARR_FILTER
Dictionaries
Declared with DIM name AS NEW DICTIONARY. Key-value store with string keys, supporting optional typed values and a full DICT_* function set.
Matrices
2-D arrays declared with DIM name[rows][cols], with a dedicated MAT_* library:
- Creation —
MAT_ZEROS,MAT_ONES,MAT_IDENTITY,MAT_FILL,MAT_COPY - Arithmetic —
MAT_ADD,MAT_SUB,MAT_MUL,MAT_HADAMARD,MAT_SCALE,MAT_DOT - Linear algebra —
MAT_DET,MAT_TRANSPOSE,MAT_TRACE,MAT_FROBENIUS - Aggregation —
MAT_SUM,MAT_MIN,MAT_MAX - Utilities —
MAT_RESHAPE,MAT_ROW,MAT_COL,MAT_PRINT,MAT_EQUAL
Built-in Libraries
String Library (40+ functions)
SUBSTR, REPLACE, REPLACE_FIRST, REMOVE, SPLIT / SPLIT_COUNT / SPLIT_GET, JOIN, TRIM, LTRIM, RTRIM, TRIM_CHARS, UPPER, LOWER, TITLE, SWAPCASE, PADLEFT, PADRIGHT, PADCENTER, FIND, FIND_FROM, LAST_INSTR, COUNT_STR, REPEAT, REVERSE, FORMAT (printf-style), STR_CMP, STR_ICMP, HEX_ENCODE, HEX_DECODE, BASE64_ENCODE, BASE64_DECODE, STR_HASH
Predicates: ISNUMERIC, ISALPHA, ISALNUM, ISSPACE, ISUPPER, ISLOWER, ISDIGIT
Math Library
Full trigonometry (SIN, COS, TAN, ASIN, ACOS, ATAN, ATAN2, COT, CSC, SEC), hyperbolic functions, logarithms (LOG, LOG2, LOG10, LOG_BASE, LOG1P), rounding (FLOOR, CEIL, ROUND, TRUNC), ABS, SIGN, CLAMP, HYPOT, DEG, RAD, PI, E, MAP_RANGE, LERP, IS_EVEN, IS_ODD, IS_PRIME, GCD, LCM, FACTORIAL, GAMMA, BETA, ERF
Date/Time Library
DATE(), TIME(), TIMESTAMP(), TIMER(), MICROS(), FORMAT_TIME(), FORMAT_TS(), DATETIME_STR(), TIME_AGO(), SLEEP(), SLEEP_MS(), SLEEP_US(), timestamp arithmetic (TIME_ADD_DAY, TIME_ADD_HOUR, TIME_DIFF, …), calendar helpers (IS_LEAP_YEAR, DAYS_IN_MONTH, MONTH_NAME, WEEKDAY_NAME, ISO_WEEK), UTC functions (UTC_DATETIME, UTC_TIMESTAMP, UTC_HOUR, UTC_OFFSET)
Regular Expressions (PCRE2)
Full Perl-compatible regex engine:
REGEX_MATCH, REGEX_MATCH_FULL, REGEX_FIND, REGEX_FIND_ALL, REGEX_REPLACE, REGEX_REPLACE_ALL, REGEX_SPLIT, REGEX_GROUP, REGEX_NAMED_GROUP, REGEX_COUNT
JSON
Built-in parser and generator. Parsed JSON is flattened into a Dictionary using dot-notation for objects (user.name) and bracket-notation for arrays (tags[0]).
JSON_PARSE, JSON_GET, JSON_VALID, JSON_STRINGIFY
CSV
Auto-detects delimiter (, ; tab). Handles quoted fields, embedded delimiters, and escaped quotes. Data stored in a Dictionary for fast row/column access by name.
CSV_PARSE, CSV_LOAD, CSV_STRINGIFY, CSV_SAVE, CSV_ROWS, CSV_COLS, CSV_GET, CSV_SET, CSV_HEADER, CSV_ADDROW
Cryptography
Pure-C implementation with no external dependencies:
- Hashing —
CRYPTO_MD5,CRYPTO_SHA1,CRYPTO_SHA256,CRYPTO_HMAC_SHA256,CRYPTO_CRC32 - Encoding —
CRYPTO_BASE64_ENC,CRYPTO_BASE64_DEC,CRYPTO_HEX_ENC,CRYPTO_HEX_DEC - Symmetric encryption — AES-128/192/256 in ECB, CBC, and CTR modes
- Key generation —
CRYPTO_AES_KEYGEN(bits),CRYPTO_AES_IV() - Utilities —
CRYPTO_XOR,CRYPTO_ROT13,CRYPTO_RAND_BYTES,CRYPTO_RAND_INT
Networking
HTTP Client
Full HTTP/HTTPS client backed by libcurl (libcurl.so.4), loaded at runtime — present by default on Raspberry Pi OS, Debian, and Ubuntu. No libcurl headers are required to compile.
- Methods —
NET_GET,NET_POST,NET_PUT,NET_PATCH,NET_DELETE - Status and headers —
NET_STATUS,NET_HEADER,NET_HEADERS_CLEAR,NET_RESPONSE_HEADER - Convenience —
NET_SET_BEARER,NET_SET_CONTENT_TYPE,NET_SET_TIMEOUT - Encoding —
NET_ESCAPE,NET_UNESCAPE
WebSocket
Built-in client and server with unlimited concurrent connections (fully dynamic allocation):
WS_CONNECT, WS_LISTEN, WS_SEND, WS_RECV, WS_POLL, WS_CLOSE, WS_BROADCAST, WS_CLIENT_COUNT, WS_SERVER_RUNNING, WS_CLIENT_IP, WS_PING, WS_KICK_ALL
Concurrency
Full POSIX-based multithreading. All internal tables are dynamically sized — there is no fixed upper limit on the number of threads, mutexes, semaphores, or condition variables. Each thread receives a private copy of the interpreter state; shared state is coordinated through the primitives below.
- Threads —
THREAD_CREATE,THREAD_JOIN,THREAD_DETACH,THREAD_RUNNING,THREAD_SELF - Mutexes —
MUTEX_CREATE,MUTEX_LOCK,MUTEX_UNLOCK,MUTEX_TRYLOCK,MUTEX_DESTROY - Semaphores —
SEM_CREATE,SEM_WAIT,SEM_POST,SEM_TRYWAIT,SEM_DESTROY - Condition variables —
COND_CREATE,COND_WAIT,COND_SIGNAL,COND_BROADCAST,COND_TIMEDWAIT,COND_DESTROY - Lock-free atomics —
ATOMIC_INC,ATOMIC_DEC,ATOMIC_ADD,ATOMIC_GET,ATOMIC_SET,ATOMIC_CAS
Hardware (Raspberry Pi)
Requires appropriate kernel modules and device permissions (typically root or membership in the gpio / spi / i2c groups).
- GPIO —
GPIO_SETUP,GPIO_WRITE,GPIO_READ - PWM —
PWM_SETUP,PWM_WRITE - I2C —
I2C_SETUP,I2C_WRITE,I2C_READ - SPI —
SPI_SETUP,SPI_READ,SPI_WRITE,SPI_TRANSFER,SPI_CLOSE - Timing —
DELAY(ms),DELAY_MICRO(µs)
System and Unix
- Shell execution —
EXEC,EXEC_OUT,EXEC_ERR,EXEC_FULL - System info —
UNAME,HOSTNAME,UPTIME,UPTIME_STR,LOADAVG,CPU_COUNT,MEM_TOTAL,MEM_FREE - Process control —
KILL,KILL_NAME,GETPID,GETENV,SETENV,UNSETENV - User management —
USER_ADD,USER_ADD_FULL,USER_DEL,USER_DEL_FULL,USER_MOD,USER_EXISTS,USER_LIST,USER_INFO,PASSWD,WHOAMI - Group management —
GROUP_ADD,GROUP_DEL,GROUP_MOD,GROUP_EXISTS,GROUP_LIST,GROUP_ADD_USER,GROUP_DEL_USER,GROUP_MEMBERS
FFI — C Library Integration
Load any .so shared library at runtime and call its functions directly from BASIC — no recompilation required.
LIBLOAD "libname.so"— load a shared libraryLIBCALL("lib.so", "func", arg, …)— call a function returning a numberLIBCALL_STR("lib.so", "func", arg, …)— call a function returning a stringLIBFREE "libname.so"— unload a libraryLIBLOADED("libname.so")— check if a library is currently loadedLIBLIST— list all loaded libraries
Introspection
ISDEF(name),ISARRAY(name),ISDICT(name),ISFUNCTION(name)— test what a name refers toTYPEOF(expr)— returns"NUMBER","INTEGER","STRING", or"BOOLEAN"ISDYNAMIC(name)/ISSTATIC(name)— test whether a variable has a type constraint
Building
Requirements: GCC or any C99-compatible compiler, make, standard C library. For regex: libpcre2-dev. For HTTP: libcurl at runtime (no headers needed to build).
git clone https://codeberg.org/alimiracle/pibasic
cd pibasic
make
Produces a single executable: pibasic.
make debug # build with full warnings and debug symbols
make clean # remove build artifacts
Usage
./pibasic program.bas # run a program file
./pibasic # start the interactive REPL
Makefile shortcuts:
make run # start the REPL
make run-file FILE=prog.bas # run a specific file
Interactive REPL
Start the interpreter with no arguments. The REPL supports:
- Command history with arrow keys
- Multi-line buffering — the REPL waits for a closing keyword (
END FUNCTION,NEXT,WEND,END IF, etc.) before executing Ctrl+Cto cancel the current input bufferCtrl+Dto exit
Documentation
The full language reference — covering every function, every error message, and 48 worked examples — is in guide.md.
Privileges
GPIO / PWM / I2C / SPI require appropriate kernel modules and device permissions on Raspberry Pi.
User and group management — write operations (USER_ADD, USER_DEL, USER_MOD, PASSWD, GROUP_* write functions) require root. Read-only queries (USER_EXISTS, USER_LIST, USER_INFO, WHOAMI, GROUP_EXISTS, GROUP_LIST, GROUP_MEMBERS) work as any user.
Shell execution — EXEC, EXEC_OUT, EXEC_ERR, and EXEC_FULL pass commands to /bin/sh. Sanitize any user-supplied input before passing it to these functions.
Contributing
Contributions are welcome. Please open an issue before submitting a large pull request so the change can be discussed first. For bug reports, include:
- The
.basprogram that reproduces the issue - Compiler version (
gcc --version) - Platform (OS + architecture)
License
Licensed under the GNU General Public License v3.0. See LICENSE for the full text, or visit https://www.gnu.org/licenses/gpl-3.0.html.
You are free to use, study, modify, and distribute this software under the terms of the GPL v3. Any derivative work must also be distributed under the same license.