Update README.org
This commit is contained in:
parent
252c9614c0
commit
2fb3fa08d1
423
README.org
423
README.org
|
@ -1,154 +1,363 @@
|
|||
#+OPTIONS: toc:nil
|
||||
#+TITLE: Zirûl: A Language for Enduring Realities
|
||||
#+SUBTITLE: "Shape realities that outlast their makers."
|
||||
#+AUTHOR: Zongor
|
||||
#+EMAIL: archive@zirul-lang.org
|
||||
#+DATE: [2025-04-05]
|
||||
#+LANGUAGE: en
|
||||
#+OPTIONS: H:4 num:t toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
|
||||
#+STARTUP: align fold nodlcheck hidestars oddeven lognotestate
|
||||
#+TAGS: { TODO(t) NEXT(n) DONE(d) | HOLD(h) WAITING(w) CANCELLED(c) }
|
||||
#+PROPERTY: header-args :tangle-mode (identity #o0644)
|
||||
|
||||
* Reality Engine
|
||||
#+DESCRIPTION: A sustainable, portable virtual machine and programming language for constrained systems and game preservation.
|
||||
* Zirûl: A Language for Enduring Realities
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: zongors-universe-machine
|
||||
:header:
|
||||
:⎡ ᛉ · · · ⎤
|
||||
:⎢ · ᚱ · · ⎥
|
||||
:⎢ · · ᛇ · ⎥
|
||||
:⎣ · · · ᛚ ⎦
|
||||
:END:
|
||||
|
||||
#+begin_src
|
||||
[ ᛉ . . .
|
||||
. ᚱ . .
|
||||
. . ᛇ .
|
||||
. . . ᛚ]
|
||||
#+end_src
|
||||
Zirûl (pronounced /'zi.rul/) is a permacomputing oriented, statically-typed, zero-allocation programming language and virtual machine system designed for:
|
||||
|
||||
* Overview
|
||||
- =Constrained systems=: microcontrollers, retro consoles (PS1, N64, Mac Classic)
|
||||
- =Portable environments=: Web (Emscripten), embedded, CLI
|
||||
- =Permacomputing=: long-term survivability, sustainability, minimalism
|
||||
- =3D world-building=: built-in primitives for PS1/N64-style rendering
|
||||
- =Live development=: hot reloading, REPL, shadowing, symbol versioning
|
||||
|
||||
Reality Engine Language (ZREL) and the Reality Engine Virtual Machine (VM) are designed for:
|
||||
It runs on the =Reality Engine=, a minimal C89 VM inspired by Uxn, Plan 9, and Forth - but built for =spatial software=, =deterministic execution=, and =software that lasts=.
|
||||
|
||||
- Constrained systems (e.g., microcontrollers, retro consoles)
|
||||
- Portable environments (e.g., Emscripten/Web)
|
||||
- Permacomputing principles (e.g., long-term survivability, sustainability, zero dynamic allocation)
|
||||
* The Reality Engine
|
||||
|
||||
* Key Design Goals
|
||||
The =Reality Engine= is a register-based virtual machine designed to render not just graphics, but *realities* - persistent, inspectable, reproducible computational worlds.
|
||||
|
||||
- Written in portable **C89**
|
||||
- No dynamic memory: **no malloc/free**
|
||||
- Designed for **cross-platform** reproducibility
|
||||
- Inspired by **Uxn**, but for 3D
|
||||
- Built-in **3D primitive support** for game developers
|
||||
It is:
|
||||
- Written in **C89** for maximum portability
|
||||
- **No dynamic allocation** - memory is static, frame-managed, zero-initialized
|
||||
- **Deterministic by design** - identical input -> identical output, forever
|
||||
- **Self-inspectable** - symbol table, memory, and state are always accessible
|
||||
- Inspired by Uxn, Dis VM, Dusk OS, and Plan 9
|
||||
|
||||
* VM Architecture
|
||||
**VM Architecture**
|
||||
|
||||
**CISC-like instruction format:**
|
||||
| Feature | Specification |
|
||||
|-----------------------|----------------------------------------------------|
|
||||
| Instruction Format | 1-byte opcode, 3-byte operand (CISC-like) |
|
||||
| Register Set | 32 general-purpose registers (R0-R31) |
|
||||
| Initialization | **ZII**: Zero Is Initialization |
|
||||
| Memory Model | Frame-based arenas (function scope = frame) |
|
||||
| Heap Behavior | Copy-on-write; allocations append to frame |
|
||||
| Frame Exit | Pointer resets on return (stack-GC style) |
|
||||
| Error Handling | Returns stub pointers to zeroed memory |
|
||||
|
||||
- 1-byte opcode
|
||||
- 3-byte operand
|
||||
- **Register-based** rather than stack-based
|
||||
This ensures:
|
||||
- No =malloc=, no =free=, no GC
|
||||
- Predictable memory use
|
||||
- Perfect reproducibility
|
||||
- Safe failure modes
|
||||
|
||||
**Register Set:**
|
||||
* Zirûl Language (ZREL)
|
||||
|
||||
- Default: 32 general-purpose registers (may vary depending on L1/L2/L3 cache sizes)
|
||||
- Always-initialized: Zero is a valid value; zero-initialized objects are always valid.
|
||||
- Concept: *ZII* → Zero Is Initialization
|
||||
Zirûl is a statically-typed language with **first-class arrays**, **immediate-mode semantics**, and **symbolic clarity** - designed for game developers, artists, and preservationists.
|
||||
|
||||
**Memory Model:**
|
||||
**Core Types**
|
||||
|
||||
- Static memory
|
||||
- Memory is managed via *frame-based arenas*:
|
||||
- function scopes defines a memory *frame*
|
||||
- "Heap" allocations push pointers within this frame
|
||||
- When a frame exits, the pointer is reset (like stack-based GC)
|
||||
- Values passed to functions must be explicitly returned to propagate
|
||||
- Heap values are **copy-on-write**
|
||||
| Type | Description |
|
||||
|--------|-----------------------------------------------|
|
||||
| =int= | 32-bit signed integer |
|
||||
| =nat= | 32-bit natural number (also used for pointers)|
|
||||
| =real= | Q16.16 fixed-point real number |
|
||||
| =str= | 4-byte packed string or fat pointer |
|
||||
| =bool= | Compile-time flag |
|
||||
| =ref<T>= | Reference type for passing by reference |
|
||||
|
||||
**Error Handling:**
|
||||
**Array Semantics (Fortran-Style)**
|
||||
|
||||
- Stub values: Blocks of zeroed memory
|
||||
- On failure, return a pointer to the zeroed stub
|
||||
- Stubs are automatically cleared at the end of the frame
|
||||
Arrays are **first-class values**:
|
||||
|
||||
* Language Features (ZREL)
|
||||
#+BEGIN_SRC zrl
|
||||
real[3] pos = [1.0r, 2.0r, 3.0r];
|
||||
real[4][4] mat = identity();
|
||||
real[3] result = mat * pos; ! compiler generates matrix-vector multiply
|
||||
#+END_SRC
|
||||
|
||||
**Core Types:**
|
||||
- Row-major order
|
||||
- Fat pointers for slices and strings
|
||||
- No =vec3=/=mat4x4= structs needed - math is generated
|
||||
- Supports composition, slicing, element-wise ops
|
||||
|
||||
- `int` (integer numbers)
|
||||
- `nat` (natural numbers, also used for pointers)
|
||||
- `real` (Q16.16 fixed-point real numbers)
|
||||
- `str` (Fat pointers of 4-byte char packed or slices)
|
||||
**Boolean/Enum Strategy**
|
||||
|
||||
**Array Semantics:**
|
||||
Flags are compiled into **parallel arrays** (like =MultiArrayList=):
|
||||
|
||||
- Row-major, Fortran-style; replaces need for vec2/vec3/mat4x4
|
||||
- Arrays are first-class values
|
||||
- The compiler generates *array multiplication code*
|
||||
- Supports array composition and manipulation without needing OOP or polymorphism
|
||||
#+BEGIN_SRC zrl
|
||||
bool[] player_alive;
|
||||
real[3][] player_pos;
|
||||
str[] player_name;
|
||||
#+END_SRC
|
||||
|
||||
**Boolean/Enum Strategy:**
|
||||
This enables:
|
||||
- Cache-friendly data layout
|
||||
- No polymorphism tax
|
||||
- High-performance iteration
|
||||
|
||||
- Compile-time transformation of flags into parallel arrays
|
||||
- Example: `monster_alive`, `monster_dead` → `MultiArrayList`
|
||||
* Plex: The Form of Being
|
||||
|
||||
A =plex= is a **Platonic form** - a structured definition of a kind of being in your program.
|
||||
|
||||
#+BEGIN_SRC zrl
|
||||
plex Player {
|
||||
version 1;
|
||||
str name;
|
||||
real[3] pos;
|
||||
|
||||
init(str name, real[3] pos) {
|
||||
this.name = name;
|
||||
this.pos = pos;
|
||||
}
|
||||
update() {}
|
||||
logout() {}
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
- Not a class: no inheritance, no vtables
|
||||
- Methods are functions with implicit =this= argument
|
||||
- Instances are **atoms** - persistent, versioned, serializable
|
||||
- Stored in the internal graph
|
||||
|
||||
> *"A plex defines what a thing is. An atom is its incarnation in a reality."*
|
||||
|
||||
* Versioning & Shadowing (Forth-Inspired)
|
||||
|
||||
When you redefine a =plex=, the old version is **shadowed but preserved** - unless explicitly discarded.
|
||||
|
||||
#+BEGIN_SRC zrl
|
||||
plex Counter { version 1; nat value; inc() { value += 1; } }
|
||||
plex Counter { version 2; nat value; inc() { value += 2; } } ! shadows v1
|
||||
|
||||
Counter c1 = Counter(); ! uses v2 (latest)
|
||||
Counter c2 = Counter.v1(); ! uses v1 - still available
|
||||
|
||||
discard Counter.v1; ! optional: free memory
|
||||
#+END_SRC
|
||||
|
||||
Internally, plex versions form a **linked version chain**:
|
||||
- =head= -> latest version
|
||||
- =tail= -> oldest retained version
|
||||
- =migrate(obj, Counter)= -> converts data layout
|
||||
- =versions(Counter)= -> list available versions
|
||||
|
||||
This enables:
|
||||
- Non-destructive evolution
|
||||
- Safe refactoring
|
||||
- Historical reproducibility
|
||||
- Code archaeology
|
||||
|
||||
* Graphics & Devices
|
||||
|
||||
**Graphics:**
|
||||
**Memory-Mapped I/O**
|
||||
|
||||
- Memory-mapped devices (e.g., SDL surface points into memory)
|
||||
- All rendering is done by manipulating the memory directly
|
||||
- **Texture system**:
|
||||
- RGB8888 format default
|
||||
- Tile sizes: 8×8 to 32×32
|
||||
- Built-in automatic mipmapping (default for 128px), optional manual override
|
||||
Devices are memory-mapped:
|
||||
- SDL surface -> direct memory access
|
||||
- GPU registers -> memory addresses
|
||||
- All rendering done by writing to memory
|
||||
|
||||
**3D Primitives:**
|
||||
**Texture System**
|
||||
- Default format: RGB332 (1 byte per pixel)
|
||||
- Tile sizes: 8x8 to 32x32
|
||||
- Automatic mipmapping for textures >128px
|
||||
- Manual override available
|
||||
|
||||
- Built-in support for simple 3D shapes
|
||||
- Aimed at enabling PS1/N64-style rendering with minimal code
|
||||
**Immediate Mode GUI**
|
||||
- Function calls are equivelent to redraws
|
||||
- Child calls define spacial location in code as well as the UI
|
||||
|
||||
**3D Primitives**
|
||||
Built-in support for:
|
||||
- =Cube(pos, size)=
|
||||
- =Plane(pos, radius)=
|
||||
- =Model(mesh, texture)=
|
||||
- Simple PS1/N64-style rendering pipeline
|
||||
|
||||
No shaders, no pipelines - just direct manipulation of memory and math.
|
||||
|
||||
* Tunnels: Unified I/O (Plan 9 / 9P-Inspired)
|
||||
|
||||
A =Tunnel= unifies:
|
||||
- Files
|
||||
- Sockets
|
||||
- Web APIs
|
||||
- Devices
|
||||
- Databases
|
||||
|
||||
#+BEGIN_SRC zrl
|
||||
Tunnel server = Tunnel("tcp://localhost:25565");
|
||||
if (server.attach(auth)) {
|
||||
Player[] players = server.read("players");
|
||||
server.write("me", me.update());
|
||||
server.clunk();
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
**Tunnel Operations**
|
||||
|
||||
| Op | Meaning |
|
||||
|------------|--------------------------------------|
|
||||
| =.attach()= | Authenticate and open |
|
||||
| =.open()= / =.create()= | Access/create resource |
|
||||
| =.read()= / =.write()= | Transfer data |
|
||||
| =.walk()= | Navigate hierarchy |
|
||||
| =.flush()= | Cancel long operation |
|
||||
| =.clunk()= | Close connection |
|
||||
| =.stat()= | Get metadata |
|
||||
| =.version()=| Get protocol version |
|
||||
|
||||
Tunnels make I/O **uniform, composable, and archival**.
|
||||
|
||||
* Development Environment
|
||||
|
||||
**Goals:**
|
||||
Zirûl supports **live coding** and **temporal development**:
|
||||
|
||||
- Live coding: Compile and inject code while VM is running
|
||||
- Hot module reloading
|
||||
- Shadowing + symbol versioning (inspired by Forth word tables)
|
||||
- REPL-style interactivity (inspired by Lisp environments)
|
||||
**Live Coding Features**
|
||||
- Hot module reloading: inject code while VM runs
|
||||
- REPL-style interaction: inspect memory, call functions, test logic
|
||||
- Shadowing: redefine =plex=es without restarting
|
||||
- Symbol table manipulation: runtime introspection and patching
|
||||
|
||||
**Symbol Table & Module System:**
|
||||
|
||||
- Objects embed *load-code* for reconstruction
|
||||
- Runtime symbol manipulation and memory inspection
|
||||
- Final binaries are snapshots of the memory + symbol table
|
||||
**Final Binaries**
|
||||
- Are **snapshots** of:
|
||||
- Memory state
|
||||
- Symbol table
|
||||
- Version chains
|
||||
- Can be saved, restored, or archived as =.zbin= files
|
||||
- Are fully deterministic and reproducible
|
||||
|
||||
* Sustainability & Permacomputing
|
||||
|
||||
The entire system adheres to the ethos of *Permacomputing*:
|
||||
Zirûl embodies **permacomputing principles**:
|
||||
|
||||
- Minimal resource usage
|
||||
- Transparent, inspectable code and memory layouts
|
||||
- Deterministic execution
|
||||
- No garbage collector, no dynamic allocation
|
||||
- Emphasis on long-term legibility and preservation
|
||||
| Principle | How Zirûl Supports It |
|
||||
|-------------------------------|------------------------------------------------|
|
||||
| Long-Term Survivability | C89 base, no deps, text-based source |
|
||||
| Zero Dynamic Allocation | Frame arenas, copy-on-write, ZII |
|
||||
| Energy Efficiency | Fixed-point math, no GC, minimal ops |
|
||||
| Maintenance Over Obsolescence | Versioned plexes, refactorable code |
|
||||
| Use Existing Hardware | Runs on microcontrollers, old consoles |
|
||||
| Sustainability | No bloat, no planned obsolescence |
|
||||
| Compute to Strengthen | Designed for art, education, preservation |
|
||||
|
||||
* Implementation Status & Roadmap
|
||||
* Getting Started
|
||||
|
||||
- [X] Implement frame-based memory management
|
||||
- [ ] Add SDL device layer
|
||||
- [ ] Write compiler front-end for ZREL
|
||||
- [ ] Add array multiplication code generation
|
||||
- [ ] Develop 3D primitive library
|
||||
- [ ] Design module and hot reload system
|
||||
**Build the Reality Engine**
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
git clone https://git.alfrescocavern.com/zongor/reality-engine.git
|
||||
cd reality-engine
|
||||
make
|
||||
./zre client.zrl
|
||||
#+END_SRC
|
||||
|
||||
**Sample Program: =hello.zrl=**
|
||||
|
||||
#+BEGIN_SRC zrl
|
||||
function main(nat argc, str[] argv) {
|
||||
str name = argc > 1 ? argv[1] : "World";
|
||||
print("Hello, {name}!");
|
||||
exits("Done");
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
Run it:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
./zre hello.zrl Alice
|
||||
# Output: Hello, Alice!
|
||||
#+END_SRC
|
||||
|
||||
* Example: 3D Client (=client.zrl=)
|
||||
|
||||
#+BEGIN_SRC zrl
|
||||
use "common.zrl";
|
||||
|
||||
function main(int argc, str[] argv) {
|
||||
nat w = 800, h = 450;
|
||||
Player me(argv[1], [0.0, 1.0, 2.0], PURPLE);
|
||||
|
||||
bool running = true;
|
||||
while (running) {
|
||||
window("Zirûl Client", w, h) {
|
||||
splitbox(parent.size, 0.25) {
|
||||
canvas() {
|
||||
if (button("Logout")) {
|
||||
me.logout();
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
splitbox(parent.size, 0.75) {
|
||||
canvas() {
|
||||
model(Floor([0,0,0], 30));
|
||||
me.update();
|
||||
model(Cube(me.pos, [0.5r,0.5r,0.5r], me.color));
|
||||
if (Player[] others = me.server.read("players")) {
|
||||
for (p in others) {
|
||||
model(Cube(p.pos, [0.5r,0.5r,0.5r], p.color));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exits("Client Closed Successfully");
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
* Future & Preservation
|
||||
|
||||
**Goals**
|
||||
- Run on hardware from **1980 to 2080+**
|
||||
- Be **hand-readable in 3024**
|
||||
- Preserve digital art and games **forever**
|
||||
|
||||
**Preservation Plan**
|
||||
- Text-based source: no binary blobs
|
||||
- Versioned plexes: forward/backward compatibility
|
||||
- Self-documenting syntax: just enough magic
|
||||
- Open standard: no vendor lock-in
|
||||
- Archive formats: =.zrl=, =.zbin=, =.zatom=
|
||||
|
||||
* License
|
||||
|
||||
To be determined. Preferably a permissive license (e.g., MIT, 0BSD) for long-term survivability.
|
||||
**MIT-0** - No restrictions, no warranty.
|
||||
|
||||
With an ethical understanding:
|
||||
|
||||
> This software should not be used to accelerate obsolescence, exploit users, or harm ecosystems. Compute only to strengthen what lasts.
|
||||
|
||||
* Inspirations
|
||||
- [[https://wiki.xxiivv.com/site/uxn.html][Uxn VM]]
|
||||
- [[https://plan9.io/][Plan 9]]
|
||||
- [[https://www.permacomputing.net][Permacomputing wiki]]
|
||||
- [[https://handmade.network][Handmade Network]]
|
||||
- [[http://duskos.org/][Dusk OS]]
|
||||
- [[https://doc.cat-v.org/inferno/4th_edition/dis_VM_specification][Dis VM]]
|
||||
- [[https://www.craftinginterpreters.com/the-lox-language.html][Lox]]
|
||||
- [[https://lua.org][Lua]]
|
||||
- [[https://en.wikipedia.org/wiki/Lisp_(programming_language)][Lisp]]
|
||||
- [[https://en.wikipedia.org/wiki/C_(programming_language)][C]]
|
||||
- [[https://fortran-lang.org/][Fortran]]
|
||||
- [[https://ziglang.org/][Zig]]
|
||||
- Retro systems like:
|
||||
- N64
|
||||
- PlayStation 1
|
||||
- Macintosh Classic (System 7)
|
||||
- Windows 95
|
||||
|
||||
- Uxn - Minimalism, elegance
|
||||
- Plan 9 / 9P - Unified I/O, Tunnels
|
||||
- Forth - Shadowing, interactivity, immediacy
|
||||
- Lisp - Live coding, REPL, introspection
|
||||
- Fortran - Array semantics, scientific clarity
|
||||
- C / Zig - Control, minimalism
|
||||
- Permacomputing Wiki - Sustainability, longevity
|
||||
- Retro Systems - N64, PS1, Mac Classic, Windows 95, Plan9 - proof that beauty needs no bloat
|
||||
|
||||
* Join the Effort
|
||||
|
||||
Zirûl is a community project. We welcome:
|
||||
- Compiler contributors
|
||||
- Port developers (Web, Game Boy, etc.)
|
||||
- Artists and game designers
|
||||
- Archivists and historians
|
||||
|
||||
> *"We are not making programs. We are writing Ages."*
|
||||
|
||||
* Contact
|
||||
|
||||
- Website: https://zirul-lang.org
|
||||
- Email: archive@zirul-lang.org
|
||||
- Repository: https://git.alfrescocavern.com/zongor/reality-engine.git
|
||||
|
|
Loading…
Reference in New Issue