Repository navigation
The PWE Language
The PWE language is the textual front end of pwe-reference (grammar src/lang.pest). A source program declares a world model and systems; it compiles to typed EIR and runs cross-backend — the interpreter and the CPU JIT must produce byte-identical writes on every step.
PWE source ──parse──▶ WorldModel + system decls ──lower──▶ EIR ──interpret/JIT──▶ writes
The full reference — lexical rules, every keyword, EBNF, operator precedence, and a complete intrinsic function table — lives in docs/lang-usage.md (中文).
world {
# world items (required section)
}
funcs {
# optional: user-defined pure functions
}
systems {
# optional: systems that act on the world
}
Comments run from # or // to end of line and are skipped as whitespace anywhere. Whitespace is otherwise insignificant; ; between statements is optional. A .pwe file is also a module.
| Statement | Meaning |
|---|---|
gravity = (x, y, z) |
Global uniform gravity vector. |
params { G = 1.0; k = 3.0 } |
Runtime-settable parameters, overridable with --param G=2 on the same artifact. |
title = "..." |
Human-readable run title, shown by pwe present. |
entity <name> { … } |
A body. |
shape <name> { part … } |
A user-defined custom shape (presentation only). |
chan <name> { value = v } |
A channel entity; holds its latest value in state[0]. |
field <name> { width; height; dx } |
A deterministic scalar grid field — the PDE substrate. |
pool <name>[n] { … } |
A block of pre-allocated, initially inactive entity slots. |
import "pkg/mod" |
Python-style module import. |
Entity ids are 1-based in declaration order; channels follow the bodies.
| Field | Meaning |
|---|---|
position = (x, y, z) / velocity = (x, y, z)
|
Initial position / velocity. |
state = (v0, …) |
Positional state slots (max 16: s0…s15). |
state = (x = 0, y = 0, …) |
Named slots; read via @self.x. Mixable with positional. |
state = (vec3 pos, …) |
A vector element reserves N consecutive slots. |
mass, dynamic = false, nbody = false
|
Mass; static body; opt out of mutual nbody. |
restitution, friction
|
Contact bounciness / tangential friction. |
box = (dx,dy,dz) / sphere = r / hull = [(x,y,z), …]
|
Collider. |
camera = true |
The viewer camera (excluded from simulation). |
Presentation-only (color, shape, size, opacity, glow, label) never affect simulation state, determinism, or the state hash.
field heat { width = 32; height = 32; depth = 32; dx = 1.0 } declares a 3-D grid. Cells are deterministic world state (snapshot/replayable). Space is 3D — with the simulation clock, fields are the 4D substrate.
-
fget(f, i, j[, k])— read a cell (sees same-step writes). -
fset(f, i, j[, k], v)— write a cell (bare call statement). -
flap(f, i, j[, k])— zero-flux discrete Laplacian scaled by1/dx²(5-point 2D, 7-point 3D).
Primitives, convex hulls, explicit-face polyhedra, and extruded SVG paths:
shape gem {
part poly = [(0,0.9,0), (0.7,0,0.7), …] faces = [[0,1,2],[0,2,3], …];
}
shape star {
part svg = "M 0,-1 L 0.224,-0.309 …" depth 0.22 scale 0.8;
}
slot = expr means slot += dt·expr (explicit Euler); rk4 integrates the same rules at 4th order. Rules are equations, not scripts.
| System | Purpose |
|---|---|
gravity, integrate, damping, force, linear
|
The everyday mechanics kernels. |
ground_contact, wall
|
Contact and bounded domains with restitution. |
nbody { G, dt } |
Mutual inverse-square force (G>0 gravity, G<0 Coulomb). |
update / rk4
|
User-defined ODE rules (Euler / Runge–Kutta 4). |
diffuse, poisson, wave
|
PDE sweeps on grid fields. |
send / recv
|
Go-style channel send/receive. |
invariant |
Per-step assertion. |
watch |
Zero-crossing detection. |
spawn / despawn
|
Activate / recycle pool slots. |
- Cross-entity reads:
@other.state.x, properties@other.mass. - Spatial queries:
neighbor_count,nearest_dist,neighbor_mean. - Constants:
t(clock, s),pi,e. - Stochastic:
random(),noise(),emit()— seeded and replay-stable.
at(T), periodic(P), schedule(gate, delay, …), emit / last_event — exact-once, deterministic, on the step grid.
repeat / for / break / continue unroll to straight-line EIR; Newton iteration inside a step is a one-liner.
Python-style: import "std/forces", import "m" as x, from "m" import f. Packages are directories; circular imports resolve.
Opt-in [m/s^2] annotations with gradual dimensional analysis — unannotated stays a wildcard. Base units: m kg s A K mol cd.
Compile failures print the detail code and the offending line with a caret, javac-style.
let compiled = pwe_reference::lang::compile(SOURCE)?; // parse → lower → EIR
let mut rt = pwe_reference::lang::LangRuntime::compile(SOURCE)?;
rt.step_cross()?; // interpreter == JIT, asserted
rt.step_cross_n(30)?;PWE Wiki
- Home
- Getting Started
- The PWE Language
- Standard Library
- Examples
- Determinism
- Architecture
- The Frozen Contract
- FAQ
Repository
The world is the single source of truth. Program it. Prove it. Watch it move.