Architecture
Overview
+--------------+
| VSCode |
| (LSP/DAP) |
+------+------+
| JSON-RPC (stdio)
+------v------+
| LangServer |
| LSP + DAP |
+------+------+
|
+------------v------------+
| Compiler |
| Lexer > Parser > Codegen|
| .star > bytecode |
+------------+------------+
|
+------------v------------+
| VM |
| Stack-based execution |
+------------+------------+
|
+------------v------------+
| HAL |
| PC | ESP32 |
+-------------------------+
Compiler
Single-pass compiler. The lexer produces tokens while the parser consumes them and emits bytecode simultaneously.
Features:
- Static type checking (compile-time) with generic types (
array<T>,dict<K,V>) - User-defined struct types with nested field access and defaults
- Integer types (
i32,u8) with dedicated arithmetic opcodes - Block scope
- Module loading via import (inline compilation for source modules)
- Native module system (
export fnstubs +OP_NATIVE_CALL) star.moddependency management withrequire <path> <version>- Export-based visibility control (
export fnfor public API) - Package system (
package mainvspackage lib) - Per-function debug info (Lua-style)
VM
Stack-based virtual machine with mark-and-sweep garbage collector.
- Stack — 256 slots, all values pass through the stack
- Call frames — 64 levels of function calls, with
is_tryflag for error handling - Globals — 256 global variables
- Constants — 256 constants (from constant pool)
- Native functions — up to 128 registered C functions, each identified by a content-addressed contract hash;
OP_NATIVE_CALLcarries an image-localnative_req_idresolved to a slot at load (see NREQ) - Event loop — timer-based with
every,timer,scheduleconstructs - Error handling —
raise/trywith frame-based propagation, no setjmp/longjmp - GC — mark-and-sweep, automatic trigger at 1MB threshold
Debug features:
- Breakpoint support (source file + line based, with conditions)
- Step over / step into / step out
- Per-function source mapping
Language Server
Single executable (star-lsp) runs in two modes:
- LSP mode — Editor integration (diagnostics, context-aware completion, hover with type info, signature help, go-to-definition, find references, rename, document symbols, formatting)
- DAP mode — Debug integration (breakpoints with conditions, step over/into/out, variable inspection with array/dict/struct expansion, watch expressions)
HAL
Hardware abstraction layer. The same StarLang code can run on different platforms:
| Platform | I/O |
|---|---|
| PC | stdio, file I/O |
| ESP32 | UART, GPIO, SPI, CAN |
Module System
Two types of modules:
| Type | Stub | Compilation | Dispatch |
|---|---|---|---|
Source (.star) |
Full function bodies | Compiled inline into bytecode | OP_CALL |
| Native (C) | export fn without body |
No bytecode emitted | OP_NATIVE_CALL |
Dependencies are declared in star.mod:
The CLI reads star.mod, sets up module paths for the compiler, and registers native C functions on the VM. See the star.mod reference for the full manifest format.
Compilation Flow
star.mod
require ../dev-libs/math v0.1
hello.star (package main)
|
+-- import "utils" (source module)
| |
| +-- utils.star → inline bytecode (OP_CALL)
|
+-- import "math" (native module, from star.mod)
| |
| +-- math.star → stubs only (OP_NATIVE_CALL)
|
+-- fn main():void { ... }
|
v
+-------------------+
| Bytecode (.starbc)|
| +-fn double------+| (from utils.star)
| | addr=3 ||
| +----------------+|
| +-fn main--------+|
| | addr=23 ||
| | NATIVE_CALL 0,1| ← math.sqrt(x)
| | CALL 0 | ← utils.double(x)
| +----------------+|
| LOAD_GLOBAL main |
| CALL 0 |
| HALT |
+-------------------+