Show HN: Pilang – A scripting language and VM written in C
摘要
Pilang 是一个紧凑、可嵌入的通用编程语言,采用字节码虚拟机实现。它融合了类似 Python 的易读性与闭包、类、推导式等特性,并原生内置了用于数值计算的张量(Tensor)支持及 SDL 绘图模块(支持 2D/3D 绘图)。该项目代码结构简洁,适合语言实现学习,支持编译为原生程序或通过 WebAssembly 在浏览器运行。
荐读理由
针对 AI 工程中的轻量化部署或边缘计算需求,你可以参考该项目在 C 语言虚拟机中原生集成 Tensor 算子与 WASM 支持的架构实现,作为开发可嵌入式 AI 脚本引擎或高性能数值实验工具的直接参考。
原文
Pilang
A lightweight, embeddable, general-purpose programming language written in C.
Overview
Pilang is a small, expressive scripting language with a compact C implementation, a bytecode virtual machine, modules, objects, tensors, and a practical standard library. It aims to feel light enough for quick scripts, but capable enough for experiments, teaching tools, numerical code, and embeddable application logic.
The language mixes familiar Python-like readability with features that are fun to compose: list comprehensions, slices, ranges, spread syntax, tuples, sets, closures, classes, callable objects, operator hooks, and native tensor helpers. The repository includes a native interpreter, a WebAssembly/browser build, documentation, editor assets, built-in modules, reusable libraries, and a growing test suite. here is two examples show case the capability of the language with data visualization:
Why Pilang
Readable scripts with sharp edges where they help:
let,const,fun,class, ranges, slices,#length,in, ternaries, spread syntax, destructuring, and comprehensions.Collections are first-class: lists, maps, tuples, and sets have literal syntax and work naturally with loops, membership checks, copying, slicing, and collection helpers.
Functions are flexible: named functions, anonymous functions, arrow functions, closures, recursion, defaults, named arguments, and higher-order helpers are all part of the language.
Objects are dynamic but structured: classes, constructors, inheritance, methods, callable objects, bracket access, static behavior, and operator/magic methods let you choose between plain maps and richer objects.
Numerical work is built in: tensor constructors, indexing, _transforms, reductions, broadcasting-style helpers, statistics, and linear algebra functions live in the standard modules.
Made to travel: the same language can run as a native executable or as a WebAssembly/browser build.
Small enough to study: the compiler, VM, object model, module system, and garbage collector live in C source files that are approachable for language/runtime hacking.
Quick Taste
import math:m
fun area(radius) {
return m.PI * radius ** 2
}
radii = [2, 4, 8]
for r in radii {
println("radius = " + r + ", area = " + area(r))
}
Language Tour
Expressive Collections
scores = [91, 72, 88, 91, 64, 72]
unique = {91, 72, 88, 64}
curved = [min(score + 5, 100) : score in scores]
honors = []
for score in curved
if score >= 90
honors += score
println("unique scores: " + unique)
println("honors: " + honors)
println("top three-ish: " + curved[0:3])
Functions and Closures
fun make_counter(start = 0) {
let value = start
return () -> {
value += 1
return value
}
}
next_id = make_counter(100)
println(next_id()) // 101
println(next_id()) // 102
Classes, Inheritance, and Callable Objects
class Model {
parameters() {
return []
}
}
class Linear: Model {
constructor(w, b) {
this.w = w
this.b = b
}
call(x) {
return this.w * x + this.b
}
parameters() {
return [this.w, this.b]
}
format() {
return "Linear(w=" + this.w + ", b=" + this.b + ")"
}
}
model = Linear(2, 1)
println(model(10)) // callable object
println(model.parameters())
Operator Hooks
Objects can participate in operators by defining compute methods, which makes domain objects feel native without changing the VM for every new type.
import lang
class Vec2 {
constructor(x, y) {
this.x = x
this.y = y
}
compute(op, other) {
if op == lang.OP_ADD
return Vec2(this.x + other.x, this.y + other.y)
}
format() {
return "Vec2(" + this.x + ", " + this.y + ")"
}
}
println(Vec2(2, 3) + Vec2(4, 1))
Tensors for Numerical Code
import tensor:t
x = t.from([[1, 2], [3, 4]])
w = t.eye(2, 2)
println(t.shape(x))
println(t.matmult(x, w))
println(t.mean(x))
Plotting and Visualization
Pilang includes native SDL-backed drawing and plotting modules for quick visual feedback while experimenting with numerical code, simulations, and machine-learning examples. The plot module covers 2D charts such as loss curves, while plot3d supports interactive 3D surface, mesh, and wireframe plots.
import draw
import plot
let ctx = draw.canvas(480, 480, "Training Loss")
let chart = plot.chart(ctx)
plot.line(chart, steps, losses, draw.COLOR_RED)
plot.title(chart, "Training Loss")
plot.xlabel(chart, "step")
plot.ylabel(chart, "loss")
plot.grid(chart, true)
plot.show(chart)
draw.run(ctx)
Run Pilang
From the repository root on Windows:
pilang run test.pi
You can also use the shorthand form:
pilang test.pi
Show available commands:
pilang help
Developer helpers:
pilang dis test.pi
pilang dis -o bytecode.txt test.pi
pilang fmt test.pi
pilang min test.pi
fmt and min rewrite the target file in place and use the JavaScript utilities in utils/, so Node.js and the formatter/minifier modules must be available.
Build From Source
The repository includes a Makefile for native and browser builds. On Windows with MinGW available, use make from the repository root. Some MinGW installs expose this as mingw32-make.
make release
Common targets:
make release: build the optimized native executable,release/pilang.exe.make debug: build a debug native executable withDEBUG_BUILDenabled atrelease/pilang.exe.make web: build the Emscripten/WebAssembly output inrelease/.make run: build and run the native executable.make test: build the native executable and runpython tools/run_tests.py.make clean: remove generated build outputs.
The native build expects MinGW GCC and the SDL2 development libraries used by the project. The browser build expects Emscripten's emcc.
Project Layout
pi_*.c,pi_*.h: core compiler, parser, VM, values, objects, modules, and runtime internals.builtin/: built-in native modules.libs/: Pilang libraries written in.pi.ML/: numerical and machine-learning experiments written in Pilang.release/: local build outputs.docs/: language documentation and reference material.tests/: examples and regression tests grouped by language area.
Documentation
Start with the documentation index, then explore:
Testing
Run the test suite with:
python tools/run_tests.py
Tests cover core language behavior, tensors, modules, object/class behavior, runtime types, built-ins, and larger example programs.
Website
The language website and playground are available at:
Use it to read docs, browse examples, and try Pilang in the browser.
License
This project is licensed under the terms in LICENSE.
这条对你有帮助吗?


