uLisp is a programming language for microcontrollers and embedded devices. This project ulisp-wasm
is a port of uLisp to WebAssembly that runs in the browser and on server side.
See the Playground page and introduction post on the forum.
Status: Draft - It can parse and evaluate a Lisp expression. The runtime on Wasm has its own process thread with 64K of memory, and an event loop to yield control to the host on every instruction.
Based on uLisp builder, uLisp ESP32, BL602 RISC-V fork
- Rewrite and upgrade from uLisp 3.6 to 4.6b, 4.7, 4.8d
- Load code and step through each instruction
- Replace devices with host events for emulation
- Analog port read/write
- Digital port read/write
- Serial interface
- Graphics
- Audio
- LittleFS
- EPROM read/write
- Load/save/autorun image
- I2C interface - See function
with-i2c
- SD card
- Extended RAM - Define
BOARD_HAS_PSRAM
- REPL (read-eval-print loop) in web interface
- REPL on server side
- REPL and line editor in uLisp using serial interface
- CLI on server side to run uLisp programs
- Run in the browser
- Run on JavaScript runtimes: Node, Bun, Deno
- Run on WASM runtimes with WASI support
- Standalone executable
- WebAssembly Standalone
- Or maybe
wasm-micro-runtime
- Documentation
- Web interface
- Code editor with syntax highlight
- Console output
- Canvas
- SVG
- Web Audio
Prerequisites:
- Docker to run Emscripten in a container; or directly use
emcc
from Emscripten SDK (install options) - Bun
git clone https://github.com/eliot-akira/ulisp-wasm
cd ulisp-wasm
bun install
Build frontend app as static site, watch files for changes, rebuild and reload page.
bun run start
Build for production with minified assets.
bun run build
From documentation of uLisp builder
preface.lisp
- the C macros and constant definitionsutilities.lisp
- the C typedefs, global variables, and utility functionssaveload.lisp
- the definitions for save-image, load-image, and autorunassembler.lisp
- the assembler for the ARM and RISC-V platformsprettyprint.lisp
- the prettyprinterpostscript.lisp
- the definitions for the function table lookup, eval, read, print, and the REPL
- The source file preamble
- The platform-specific settings: WORKSPACESIZE, etc.
- The stream definitions: I2C, SPI, serial, etc.
- The analogread and analogwrite I/O pin definitions
- Definitions for note, sleep, and keywords
From ulisp-builder/build.lisp
- Header
- Workspace
- Macros
- Constants
- Typedefs
- Enum declarations
- Global variables
- Error handling
- Setup workspace
- Make objects
- Utilities
- Feature list
- Garbage collection
- Compact image
- Make filename
- Save image
- Tracing
- Helper functions
- Association lists
- Array utilities
- String utilities
- Closures
- In place
- I2C interface
- Stream interface
- Note
- Sleep
- Pretty print
- Assembler
- Interrupts
- Function definitions
- Symbol names
- Documentation strings
- Built-in symbol lookup table
- Eval
- Print functions
- Read functions
- Setup 1 & 2
- REPL
- Loop
uLisp has graphics methods that use the Adafruit GFX Library with TFT LCD displays.
// Color definitions
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
drawBitmap(x, y, canvas.getBuffer(), 128, 32, foreground, background)
(draw-char x y char [colour background size]) Draws the character char with its top left corner at (x,y). The character is drawn in a 5 x 7 pixel font in colour against background, which default to white and black respectively. The character can optionally be scaled by size.
void drawPixel(uint16_t x, uint16_t y, uint16_t color);
getTextBounds(string, x, y, &x1, &y1, &w, &h)
Sets the display orientation for subsequent graphics commands; values are 0, 1, 2, or 3.
- I2Cinit
- I2Cread
- I2Cwrite
- I2Cstart
- I2Crestart
- I2Cstop