Skip to content

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 fn stubs + OP_NATIVE_CALL)
  • star.mod dependency management with require <path> <version>
  • Export-based visibility control (export fn for public API)
  • Package system (package main vs package 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_try flag 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_CALL carries an image-local native_req_id resolved to a slot at load (see NREQ)
  • Event loop — timer-based with every, timer, schedule constructs
  • Error handlingraise/try with 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:

module star-lang.com/myproject
star 0.1

require ../dev-libs/math v0.1

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              |
    +-------------------+