initial commit

This commit is contained in:
rus07tam 2025-11-03 12:43:30 +00:00
commit 4a08b87af4
20 changed files with 967 additions and 0 deletions

127
README.md Normal file
View file

@ -0,0 +1,127 @@
# Owa
A small experimental virtual machine and interpreter for an interpreted language, written in Zig.
Owa provides a minimal bytecode format, a stack-based VM, and an object model with prototype inheritance and "magic" hooks. It is designed as a playground for building a compact interpreter, adding opcodes, and experimenting with native/built-in functions.
## Features
- **Stack-based VM**: executes a custom bytecode (`OwaInstruction`).
- **Interpreter/threads**: `OwaInterpreter` manages `OwaThread` instances that run frames and bytecode.
- **Frames and locals**: each call executes in an `OwaFrame` with its own instruction pointer and locals map.
- **Object model**: `OwaObject` supports attributes, prototype chain, and a callable function slot.
- **Magic hooks**: predefined magic names (`__call`, `__str`, etc.) enable dynamic behavior.
- **Builtins module**: includes basic objects such as `OWA_NULL` and a native `print` function.
## Getting Started
### Prerequisites
- Zig (0.12+ recommended)
### Build and Run
```bash
zig build
zig build run
```
This builds the `Owa` executable and runs the demo program from `src/main.zig`.
## How It Works
### Bytecode and Instructions
Instructions are defined in `src/vm/instruction.zig` as a tagged union `OwaInstruction` with an underlying `enum(u8)` opcode. Examples include `Nop`, `LoadConst`, `Call`, `Return`, and simple stack/rotation ops. Programs are encoded to bytes and then decoded during execution.
```zig
const encoded = try OwaInstruction.encode_program(&.{
OwaInstruction{ .LoadConst = 0 }, // push builtins.print
OwaInstruction{ .LoadConst = 1 }, // push OWA_NULL
OwaInstruction{ .Call = 1 }, // call print with 1 arg
OwaInstruction{ .Return = {} },
}, allocator);
```
### Interpreter and Threads
- `OwaInterpreter` initializes memory, holds thread and module lists, and can `spawn()` new `OwaThread`s.
- `OwaThread` manages a value stack and a current `OwaFrame`; it repeatedly decodes bytecode and dispatches instructions.
- `OwaFrame` tracks the function being executed, the instruction pointer (`ip`), a link to the previous frame, and a locals map.
### Object Model
`OwaObject` holds:
- `attrs`: attribute map (`StringHashMapUnmanaged`)
- `prototype`: optional prototype link
- `call_fn`: optional function (either bytecode-backed or native)
The VM resolves attribute access via `getAttr` and prototype chaining. Callability is resolved through `call_fn` or the `__call` magic attribute.
### Builtins
The `modules/builtins` module defines core objects and natives:
- `OWA_NULL`: the null value
- `print`: a native function printing its arguments
## Example
`src/main.zig` demonstrates creating an interpreter and running a tiny program that calls the builtin `print` with `OWA_NULL`:
```zig
const std = @import("std");
const owa = @import("Owa");
const modules = @import("modules");
pub fn main() !void {
const allocator = std.heap.page_allocator;
var interpreter = try owa.OwaInterpreter.init(allocator);
var thread1 = try interpreter.spawn();
var func = owa.OwaFunction{
.owa = .{
.code = try owa.OwaInstruction.encode_program(&.{
owa.OwaInstruction{ .LoadConst = 0 }, // builtins.print
owa.OwaInstruction{ .LoadConst = 1 }, // OWA_NULL
owa.OwaInstruction{ .Call = 1 },
owa.OwaInstruction{ .Return = {} },
}, allocator),
.var_const = &.{
&modules.builtins.print,
&modules.builtins.OWA_NULL,
},
},
};
try thread1.execute(&func);
interpreter.deinit();
}
```
## Project Structure
- `src/mod.zig`: re-exports core VM types (instructions, objects, interpreter, etc.).
- `src/main.zig`: demo entry point.
- `src/vm/instruction.zig`: opcodes and encode/decode utilities.
- `src/core/object.zig`: object model and attribute logic.
- `src/core/function.zig`: function union (bytecode vs native) and flags.
- `src/core/frame.zig`: call frame and locals.
- `src/core/thread.zig`: thread state, dispatch loop, and call mechanics.
- `src/core/interpreter.zig`: interpreter lifecycle and thread management.
- `src/core/magic.zig`: magic names like `__call`, `__str`, etc.
- `src/modules/builtins/`: built-in objects and native functions.
- `build.zig`: Zig build configuration (modules, executable, run step).
## Roadmap
- More opcodes (arithmetic, control flow, comparisons, etc.).
- Exception handling and error objects.
- Strings, numbers, and collections as first-class runtime objects.
- Module system and loader.
- Basic standard library.
## License
See `LICENSE` for details.