From 7f831d8d37a8365781e87957339e2f86044ea730 Mon Sep 17 00:00:00 2001 From: Nilton Constantino Date: Mon, 2 Feb 2026 11:41:26 +0000 Subject: [PATCH] added specs for linkage model --- .../pbs/PBS - Module and Linking Model.md | 346 +++++++++++++----- docs/specs/pbs/PBS - prometeu.json specs.ms | 268 ++++++++++++++ ...ipting - Prometeu Bytecode Script (PBS).md | 2 + docs/specs/pbs/files/PRs para Junie Global.md | 27 +- docs/specs/pbs/files/PRs para Junie.md | 343 ++++++++++++++++- test-cartridges/sdk/prometeu.json | 5 + .../sdk/src/main/modules/gfx/gfx.pbs | 12 + .../sdk/src/main/modules/input/input.pbs | 29 ++ test-cartridges/test01/prometeu.json | 7 +- test-cartridges/test01/src/main.pbs | 66 ---- .../test01/src/main/modules/main.pbs | 22 ++ 11 files changed, 923 insertions(+), 204 deletions(-) create mode 100644 docs/specs/pbs/PBS - prometeu.json specs.ms create mode 100644 test-cartridges/sdk/prometeu.json create mode 100644 test-cartridges/sdk/src/main/modules/gfx/gfx.pbs create mode 100644 test-cartridges/sdk/src/main/modules/input/input.pbs delete mode 100644 test-cartridges/test01/src/main.pbs create mode 100644 test-cartridges/test01/src/main/modules/main.pbs diff --git a/docs/specs/pbs/PBS - Module and Linking Model.md b/docs/specs/pbs/PBS - Module and Linking Model.md index a0a424df..f6aaa886 100644 --- a/docs/specs/pbs/PBS - Module and Linking Model.md +++ b/docs/specs/pbs/PBS - Module and Linking Model.md @@ -1,167 +1,321 @@ -# PBS v0 — Module & Linking Model (Self‑Contained Blob) +# Prometeu PBS v0 — Unified Project, Module, Linking & Execution Specification -## Status - -**Accepted (v0)** — This specification defines the authoritative execution and linking model for PBS v0. +> **Status:** Canonical / Replaces all previous module & linking specs +> +> This document **fully replaces**: +> +> * "PBS – Module and Linking Model" +> * Any partial or implicit module/linking descriptions in earlier PBS documents +> +> After this document, there must be **no parallel or competing spec** describing project structure, modules, imports, or linking for PBS v0. --- -## 1. Motivation +## 1. Purpose -PBS is designed to be executed by a small, deterministic virtual machine embedded in PrometeuOS. To keep the VM **simple, secure, and optimizable**, all *semantic linking* must happen **before runtime**, in the compiler/tooling layer. +This specification defines the **single authoritative model** for how a Prometeu PBS v0 program is: -The VM is **not a linker**. It is an executor with validation guarantees. +1. Organized as a project +2. Structured into modules +3. Resolved and linked at compile time +4. Emitted as one executable bytecode blob +5. Loaded and executed by the Prometeu Virtual Machine + +The primary objective is to **eliminate ambiguity** by enforcing a strict separation of responsibilities: + +* **Compiler / Tooling**: all symbolic, structural, and linking work +* **Runtime / VM**: verification and execution only --- -## 2. Core Principle +## 2. Core Principles -> **A PBS module must be fully self‑contained and executable as a single blob.** +### 2.1 Compiler Finality Principle -There is **no runtime linking** in PBS v0. +All operations involving **names, symbols, structure, or intent** must be completed at compile time. -The VM only performs: +The VM **never**: -``` -load → verify → execute +* Resolves symbols or names +* Loads or links multiple modules +* Applies relocations or fixups +* Interprets imports or dependencies + +### 2.2 Single-Blob Execution Principle + +A PBS v0 program is executed as **one fully linked, self-contained bytecode blob**. + +At runtime there is no concept of: + +* Projects +* Modules +* Imports +* Dependencies + +These concepts exist **only in the compiler**. + +--- + +## 3. Project Model + +### 3.1 Project Root + +A Prometeu project is defined by a directory containing: + +* `prometeu.json` — project manifest (required) +* One or more module directories + +### 3.2 `prometeu.json` Manifest + +The project manifest is mandatory and must define: + +```json +{ + "name": "example_project", + "version": "0.1.0", + "dependencies": { + "core": "../core", + "input": "../input" + } +} ``` ---- +#### Fields -## 3. What “Linking” Means in PBS +* `name` (string, required) -In PBS, *linking* refers to resolving all symbolic or relative references into a **final, index‑based layout**. + * Canonical project identifier +* `version` (string, required) +* `dependencies` (map, optional) -This includes: + * Key: dependency project name + * Value: filesystem path or resolver hint -* Function call resolution -* Control‑flow targets (JMP / conditional branches) -* Constant pool indexing -* Syscall signature binding - -All of this must be **fully resolved by the compiler/toolchain**. +Dependency resolution is **purely a compiler concern**. --- -## 4. PBS v0 Module Structure +## 4. Module Model (Compile-Time Only) -A PBS v0 module consists of: +### 4.1 Module Definition -* `code: [u8]` — final bytecode stream -* `functions: [FunctionMeta]` — function table -* `const_pool: [Const]` — constant pool -* (optional) metadata (build id, debug info, hashes) +* A module is a directory inside a project +* Each module contains one or more `.pbs` source files -The module is **self‑contained**: no external symbols, imports, or relocations. +### 4.2 Visibility Rules + +Visibility is enforced **exclusively at compile time**: + +* `file`: visible only within the same source file +* `mod`: visible within the same module +* `pub`: visible to importing modules or projects + +The VM has **zero awareness** of visibility. --- -## 5. Function Table and CALL Semantics +## 5. Imports & Dependency Resolution -### 5.1 Function Identification +### 5.1 Import Syntax -Functions are identified **by index** in the function table. +Imports reference **projects and modules**, never files: + +``` +import @core:math +import @input:pad +``` + +### 5.2 Resolution Pipeline + +The compiler performs the following phases: + +1. Project dependency graph resolution (via `prometeu.json`) +2. Module discovery +3. Symbol table construction +4. Name and visibility resolution +5. Type checking + +Any failure aborts compilation and **never reaches the VM**. + +--- + +## 6. Linking Model (Compiler Responsibility) + +### 6.1 Link Stage + +After semantic validation, the compiler executes a **mandatory link stage**. + +The linker: + +* Assigns final `func_id` indices +* Assigns constant pool indices +* Computes final `code_offset` and `code_len` +* Resolves all jumps and calls +* Merges all module bytecode into one contiguous code segment + +### 6.2 Link Output Format + +The output of linking is a **Linked PBS Program** with the following layout: ```text -CALL +[ Header ] +[ Constant Pool ] +[ Function Table ] +[ Code Segment ] ``` -There are **no address‑based calls** in PBS v0. +All references are: -### 5.2 FunctionMeta +* Absolute +* Final +* Fully resolved -Each function is described by `FunctionMeta`: - -* `code_offset` -* `code_len` -* `param_slots` -* `local_slots` -* `return_slots` -* (optional) `max_stack_slots` (precomputed) - -The compiler is responsible for emitting **correct metadata**. +No relocations or fixups remain. --- -## 6. Control Flow (JMP / Branches) +## 7. Runtime Execution Contract -* All jump targets are **relative to the start of the current function**. -* Targets must land on **valid instruction boundaries**. +### 7.1 VM Input Requirements -This eliminates the need for global relocations. +The Prometeu VM accepts **only linked PBS blobs**. + +It assumes: + +* All function references are valid +* All jumps target instruction boundaries +* No unresolved imports exist + +### 7.2 VM Responsibilities + +The VM is responsible for: + +1. Loading the bytecode blob +2. Structural and control-flow verification +3. Stack discipline verification +4. Deterministic execution + +The VM **must not**: + +* Perform linking +* Resolve symbols +* Modify code offsets +* Load multiple modules --- -## 7. Role of the Compiler / Tooling +## 8. Errors and Runtime Traps -The compiler (or offline tooling) is responsible for: +### 8.1 Compile-Time Errors -* Resolving all calls to `func_id` -* Emitting the final function table -* Laying out code contiguously -* Emitting valid jump targets -* Computing stack effects (optionally embedding `max_stack_slots`) -* Ensuring ABI‑correct syscall usage +Handled exclusively by the compiler: -The output must be a **ready‑to‑run PBS module**. +* Unresolved imports +* Visibility violations +* Type errors +* Circular dependencies + +These errors **never produce bytecode**. + +### 8.2 Runtime Traps + +Runtime traps represent **deterministic execution faults**, such as: + +* Stack underflow +* Invalid local access +* Invalid syscall invocation +* Explicit `TRAP` opcode + +Traps are part of the **execution model**, not debugging. --- -## 8. Role of the VM +## 9. Versioning and Scope -The VM **does not perform linking**. +### 9.1 PBS v0 Guarantees -It is responsible for: +PBS v0 guarantees: -* Parsing the module -* Verifying structural and semantic correctness -* Executing bytecode deterministically +* Single-blob execution +* No runtime linking +* Deterministic behavior -### 8.1 Mandatory Runtime Verification +### 9.2 Out of Scope for v0 -The VM must always verify: +The following are explicitly excluded from PBS v0: -* Bytecode truncation / corruption -* Stack underflow / overflow -* Invalid `func_id` -* Invalid jump targets -* Syscall signature mismatches - -These checks exist for **safety and determinism**, not for late binding. +* Dynamic module loading +* Runtime imports +* Hot reloading +* Partial linking --- -## 9. Legacy and Compatibility Policies +## 10. Canonical Ownership Summary -Legacy formats (e.g. PPBC) may be supported behind explicit policies. +| Concern | Owner | +| ----------------- | ------------- | +| Project structure | Compiler | +| Dependencies | Compiler | +| Modules & imports | Compiler | +| Linking | Compiler | +| Bytecode format | Bytecode spec | +| Verification | VM | +| Execution | VM | -Example: - -* Legacy `CALL addr` encodings are **rejected** under Policy (A) -* Only `CALL func_id` is valid in PBS v0 - -Compatibility handling is **orthogonal** to the linking model. +> **Rule of thumb:** +> If it requires names, symbols, or intent → compiler. +> If it requires bytes, slots, or PCs → VM. --- -## 10. Future Evolution (Non‑Goals for v0) +## 11. Final Note -PBS v0 explicitly does **not** define: +After adoption of this document: -* Multi‑module linking -* Dynamic imports -* Runtime symbol resolution -* Relocation tables - -These may appear in future versions (v1+), but **v0 is closed and static by design**. +* Any existing or future document describing PBS modules or linking **must defer to this spec** +* Any behavior conflicting with this spec is considered **non-compliant** +* The Prometeu VM is formally defined as a **pure executor**, not a linker --- -## 11. Summary +## Addendum — `prometeu.json` and Dependency Management -* PBS modules are **single, self‑contained blobs** -* All linking happens **before runtime** -* The VM is a **verifying executor**, not a linker -* This model enables aggressive optimization, predictability, and simplicity +This specification intentionally **does not standardize the full dependency resolution algorithm** for `prometeu.json`. -This specification is **normative** for PBS v0. +### Scope Clarification + +* `prometeu.json` **defines project identity and declared dependencies only**. +* **Dependency resolution, fetching, version selection, and conflict handling are responsibilities of the Prometeu Compiler**, not the VM and not the runtime bytecode format. +* The Virtual Machine **never reads or interprets `prometeu.json`**. + +### Compiler Responsibility + +The compiler is responsible for: + +* Resolving dependency sources (`path`, `git`, registry, etc.) +* Selecting versions (exact, range, or `latest`) +* Applying aliasing / renaming rules +* Detecting conflicts and incompatibilities +* Producing a **fully linked, closed-world Program Image** + +After compilation and linking: + +* All symbols are resolved +* All function indices are fixed +* All imports are flattened into the final bytecode image + +The VM consumes **only the resulting bytecode blob** and associated metadata. + +### Separate Specification + +A **dedicated specification** will define: + +* The complete schema of `prometeu.json` +* Dependency version semantics +* Resolution order and override rules +* Tooling expectations (compiler, build system, CI) + +This addendum exists to explicitly state the boundary: + +> **`prometeu.json` is a compiler concern; dependency management is not part of the VM or bytecode execution model.** diff --git a/docs/specs/pbs/PBS - prometeu.json specs.ms b/docs/specs/pbs/PBS - prometeu.json specs.ms new file mode 100644 index 00000000..0288b370 --- /dev/null +++ b/docs/specs/pbs/PBS - prometeu.json specs.ms @@ -0,0 +1,268 @@ +# Prometeu.json — Project Manifest Specification + +## Status + +Draft · Complementary specification to the PBS Linking & Module Model + +## Purpose + +`prometeu.json` is the **project manifest** for Prometeu-based software. + +Its role is to: + +* Identify a Prometeu project +* Declare its dependencies +* Provide **input metadata to the compiler and linker** + +It is **not** consumed by the Virtual Machine. + +--- + +## Design Principles + +1. **Compiler-owned** + + * Only the Prometeu Compiler reads `prometeu.json`. + * The VM and runtime never see this file. + +2. **Declarative, not procedural** + + * The manifest declares *what* the project depends on, not *how* to resolve it. + +3. **Closed-world output** + + * Compilation + linking produce a single, fully resolved bytecode blob. + +4. **Stable identity** + + * Project identity is explicit and versioned. + +--- + +## File Location + +`prometeu.json` must be located at the **root of the project**. + +--- + +## Top-level Structure + +```json +{ + "name": "my_project", + "version": "0.1.0", + "kind": "app", + "dependencies": { + "std": { + "git": "https://github.com/prometeu/std", + "version": ">=0.2.0" + } + } +} +``` + +--- + +## Fields + +### `name` + +**Required** + +* Logical name of the project +* Used as the **default module namespace** + +Rules: + +* ASCII lowercase recommended +* Must be unique within the dependency graph + +Example: + +```json +"name": "sector_crawl" +``` + +--- + +### `version` + +**Required** + +* Semantic version of the project +* Used by the compiler for compatibility checks + +Format: + +``` +MAJOR.MINOR.PATCH +``` + +--- + +### `kind` + +**Optional** (default: `app`) + +Defines how the project is treated by tooling. + +Allowed values: + +* `app` — executable program +* `lib` — reusable module/library +* `system` — firmware / system component + +--- + +### `dependencies` + +**Optional** + +A map of **dependency aliases** to dependency specifications. + +```json +"dependencies": { + "alias": { /* spec */ } +} +``` + +#### Alias semantics + +* The **key** is the name by which the dependency is referenced **inside this project**. +* It acts as a **rename / namespace alias**. + +Example: + +```json +"dependencies": { + "gfx": { + "path": "../prometeu-gfx" + } +} +``` + +Internally, the dependency will be referenced as `gfx`, regardless of its original project name. + +--- + +## Dependency Specification + +Each dependency entry supports the following fields. + +### `path` + +Local filesystem dependency. + +```json +{ + "path": "../std" +} +``` + +Rules: + +* Relative paths are resolved from the current `prometeu.json` +* Absolute paths are allowed but discouraged + +--- + +### `git` + +Git-based dependency. + +```json +{ + "git": "https://github.com/prometeu/std", + "version": "^0.3.0" +} +``` + +The compiler is responsible for: + +* Cloning / fetching +* Version selection +* Caching + +--- + +### `version` + +Optional version constraint. + +Examples: + +* Exact: + + ```json + "version": "0.3.1" + ``` + +* Range: + + ```json + "version": ">=0.2.0 <1.0.0" + ``` + +* Latest: + + ```json + "version": "latest" + ``` + +Semantics are defined by the compiler. + +--- + +## Resolution Model (Compiler-side) + +The compiler must: + +1. Load root `prometeu.json` +2. Resolve all dependencies recursively +3. Apply aliasing rules +4. Detect: + + * Cycles + * Version conflicts + * Name collisions +5. Produce a **flat module graph** +6. Invoke the linker to generate a **single Program Image** + +--- + +## Interaction with the Linker + +* `prometeu.json` feeds the **module graph** +* The linker: + + * Assigns final function indices + * Fixes imports/exports + * Emits a closed bytecode image + +After linking: + +> No module boundaries or dependency information remain at runtime. + +--- + +## Explicit Non-Goals + +This specification does **not** define: + +* Lockfiles +* Registry formats +* Caching strategies +* Build profiles +* Conditional dependencies + +These may be added in future specs. + +--- + +## Summary + +* `prometeu.json` is the **single source of truth for project identity and dependencies** +* Dependency management is **compiler-owned** +* The VM executes **only fully linked bytecode** + +This file completes the boundary between **project structure** and **runtime execution**. diff --git a/docs/specs/pbs/Prometeu Scripting - Prometeu Bytecode Script (PBS).md b/docs/specs/pbs/Prometeu Scripting - Prometeu Bytecode Script (PBS).md index bcb6d999..7f505b72 100644 --- a/docs/specs/pbs/Prometeu Scripting - Prometeu Bytecode Script (PBS).md +++ b/docs/specs/pbs/Prometeu Scripting - Prometeu Bytecode Script (PBS).md @@ -59,6 +59,8 @@ Import resolution: * The import prefix `@project:` is resolved relative to `{root}/src/main/modules`. * Any path after `@project:` is interpreted as a **module path**, not a file path. +* `project` is declared into `prometeu.json` as the project name. and int the case of +missing it we should use `{root}` as project name. If `{root}/src/main/modules` does not exist, compilation fails. diff --git a/docs/specs/pbs/files/PRs para Junie Global.md b/docs/specs/pbs/files/PRs para Junie Global.md index 2ac0ae0d..7fa467a7 100644 --- a/docs/specs/pbs/files/PRs para Junie Global.md +++ b/docs/specs/pbs/files/PRs para Junie Global.md @@ -1,23 +1,10 @@ -# VM PR Plan — PBS v0 Executable (Industrial Baseline) +# PRs for Junie — Compiler Dependency Resolution & Linking Pipeline -> **Goal:** make *all PBS v0 functionality* executable on the VM with **deterministic semantics**, **closed stack/locals contract**, **stable ABI**, and **integration-grade tests**. -> -> **Non-goal:** new language features. If something must be reworked to achieve industrial quality, it *must* be reworked. +> Goal: Move dependency resolution + linking orchestration into **prometeu_compiler** so that the compiler produces a **single fully-linked bytecode blob**, and the VM/runtime only **loads + executes**. ---- +## Non-goals (for this PR set) -## Guiding invariants (apply to every PR) - -### VM invariants - -1. **Every opcode has an explicit stack effect**: `pop_n → push_m` (in *slots*, not “values”). -2. **Frames are explicit**: params/locals/operand stack are separate or formally delimited. -3. **No implicit behavior**: if it isn’t encoded in bytecode or runtime state, it doesn’t exist. -4. **Deterministic traps** only (no UB): trap includes `trap_code`, `pc`, `opcode`, and (if present) `span`. -5. **Bytecode stability**: versioned format; opcodes are immutable once marked v0. - -### Compiler/VM boundary invariants - -1. **Types map to slot counts** deterministically (including flattened SAFE structs and multi-slot returns). -2. **Calling convention is frozen**: param order, return slots, caller/callee responsibilities. -3. **Imports are compile/link-time only**; VM runs a fully-linked program image. \ No newline at end of file +* No lockfile format (yet) +* No registry (yet) +* No advanced SAT solver: first iteration is deterministic and pragmatic +* No incremental compilation (yet) \ No newline at end of file diff --git a/docs/specs/pbs/files/PRs para Junie.md b/docs/specs/pbs/files/PRs para Junie.md index 42c52c0c..56332f05 100644 --- a/docs/specs/pbs/files/PRs para Junie.md +++ b/docs/specs/pbs/files/PRs para Junie.md @@ -1,34 +1,337 @@ -## PR-12 — VM test harness: stepper, trace, and property tests +## PR-09 — Add `prometeu.json` manifest parser + schema validation -**Why:** Industrial quality means test tooling, not just “it runs”. +**Why:** Dependency resolution cannot exist without a stable project manifest. ### Scope -* Add `VmRunner` test harness: +* Implement `prometeu_compiler::manifest` module: - * step limit - * deterministic trace of stack deltas - * snapshot of locals -* Add property tests (lightweight): + * `Manifest` struct mirroring the spec fields: - * stack never underflows in verified programs - * verified programs never jump out of bounds + * `name`, `version`, `kind` + * `dependencies: HashMap` +* Support `DependencySpec` variants: + + * `path` + * `git` (+ optional `version`) +* Validate: + + * required fields present + * dependency entry must specify exactly one source (`path` or `git`) + * dependency aliases must be unique + * basic name rules (non-empty, no whitespace) + +### Deliverables + +* `load_manifest(project_root) -> Result` +* Diagnostic errors with file path + JSON pointer (or best-effort context) + +### Tests + +* parse minimal manifest +* missing name/version errors +* invalid dependency shape errors ### Acceptance -* Debugging is fast, and regressions are caught. +* Compiler can reliably load + validate `prometeu.json`. --- -## Definition of Done (DoD) for PBS v0 “minimum executable” +## PR-10 — Dependency Resolver v0: build a resolved project graph -A single canonical cartridge runs end-to-end: +**Why:** We need a deterministic **module graph** from manifest(s) before compiling. -* `let` declarations (locals) -* arithmetic (+, -, *, /, %, comparisons) -* `if/else` control flow -* `when` expression (if present in lowering) -* function calls with params + returns (including `void`) -* multiple return slots (flattened structs / hardware value types) -* host syscalls (e.g., `GfxClear565`, `InputPadSnapshot`, `InputTouchSnapshot`) -* deterministic traps (OOB bounded, invalid local, invalid call target, stack underflow) \ No newline at end of file +### Scope + +* Implement `prometeu_compiler::deps::resolver`: + + * Input: root project dir + * Output: `ResolvedGraph` +* Graph nodes: + + * project identity: `{name, version}` + * local alias name (the key used by the parent) + * root path in filesystem (after fetch/resolve) + * manifest loaded for each node +* Resolution rules (v0): + + * DFS/stack walk from root + * cycle detection + * collision handling: + + * If the same (project name) appears with incompatible versions, error + * aliasing: + + * alias is local to the edge, but graph also stores the underlying project identity + +### Deliverables + +* `resolve_graph(root_dir) -> Result` +* `ResolveError` variants: + + * cycle detected (show chain) + * missing dependency (path not found / git not fetchable) + * version conflict (same project name, incompatible constraints) + * name collision (two distinct projects claiming same name) + +### Tests + +* simple root -> dep path graph +* cycle detection +* alias rename does not change project identity + +### Acceptance + +* Compiler can produce a stable, deterministic dependency graph. + +--- + +## PR-11 — Dependency Fetching v0: local cache layout + git/path fetch + +**Why:** Graph resolution needs a concrete directory for each dependency. + +### Scope + +* Implement `prometeu_compiler::deps::fetch`: + + * `fetch_path(dep, base_dir) -> ProjectDir` + * `fetch_git(dep, cache_dir) -> ProjectDir` +* Define a cache layout: + + * `~/.prometeu/cache/git//...` (or configurable) + * the dependency is *materialized* as a directory containing `prometeu.json` +* For git deps (v0): + + * accept `git` URL + optional `version` + * support `version: "latest"` as default + * implementation can pin to HEAD for now (but must expose in diagnostics) + +### Deliverables + +* Config option: `PROMETEU_CACHE_DIR` override +* Errors: + + * clone failed + * missing manifest in fetched project + +### Tests + +* path fetch resolves relative paths +* cache path generation deterministic + +### Acceptance + +* Resolver can rely on fetcher to produce directories. + +--- + +## PR-12 — Module Discovery v0: find PBS sources per project + +**Why:** Once deps are resolved, the compiler must discover compilation units. + +### Scope + +* Define a convention (v0): + + * `src/**/*.pbs` are source files + * `src/main.pbs` for `kind=app` (entry) +* Implement `prometeu_compiler::sources::discover(project_dir)`: + + * returns ordered list of source files +* Enforce: + + * `kind=app` must have `src/main.pbs` + * `kind=lib` must not require `main` + +### Deliverables + +* `ProjectSources { main: Option, files: Vec }` + +### Tests + +* app requires main +* lib without main accepted + +### Acceptance + +* Compiler can list sources for every node in the graph. + +--- + +## PR-13 — Build Plan v0: deterministic compilation order + +**Why:** We need a stable pipeline: compile deps first, then root. + +### Scope + +* Implement `prometeu_compiler::build::plan`: + + * Input: `ResolvedGraph` + * Output: topologically sorted build steps +* Each step contains: + + * project identity + * project dir + * sources list + * dependency edge map (alias -> resolved project) + +### Deliverables + +* `BuildPlan { steps: Vec }` + +### Tests + +* topo ordering stable across runs + +### Acceptance + +* BuildPlan is deterministic and includes all info needed to compile. + +--- + +## PR-14 — Compiler Output Format v0: emit per-project object module (intermediate) + +**Why:** Linking needs an intermediate representation (IR/object) per project. + +### Scope + +* Define `CompiledModule` (compiler output) containing: + + * `module_name` (project name) + * `exports` (functions/symbols) + * `imports` (symbol refs by (dep-alias, symbol)) + * `const_pool` fragment + * `code` fragment + * `function_metas` fragment +* This is **not** the final VM blob. + +### Deliverables + +* `compile_project(step) -> Result` + +### Tests + +* compile root-only project to `CompiledModule` + +### Acceptance + +* Compiler can produce a linkable unit per project. + +--- + +## PR-15 — Link Orchestration v0 inside `prometeu_compiler` + +**Why:** The compiler must produce the final closed-world blob. + +### Scope + +* Move “link pipeline” responsibility to `prometeu_compiler`: + + * Input: `Vec` in build order + * Output: `ProgramImage` (single bytecode blob) +* Define linker responsibilities (v0): + + * resolve imports to exports across modules + * assign final `FunctionTable` indices + * patch CALL targets to `func_id` + * merge const pools deterministically + * emit the final PBS v0 module image + +### Deliverables + +* `link(modules) -> Result` +* `LinkError`: + + * unresolved import + * duplicate export + * incompatible symbol signatures (if available) + +### Tests + +* `archive-pbs/test01` becomes an integration test: + + * root depends on a lib + * root calls into lib + * output blob runs in VM + +### Acceptance + +* Compiler emits a single executable blob; VM only loads it. + +--- + +## PR-16 — VM Boundary Cleanup: remove linker behavior from runtime + +**Why:** Runtime should be dumb: no dependency resolution, no linking. + +### Scope + +* Audit `prometeu_core` + `prometeu_bytecode`: + + * VM loads PBS v0 module + * VM verifies (optional) and executes +* Remove/disable any linker-like logic in runtime: + + * no search for func idx by address beyond function table + * no module graph assumptions + +### Deliverables + +* VM init uses: + + * `BytecodeLoader::load()` => `(code, const_pool, functions)` + * verifier as a gate + +### Tests + +* runtime loads compiler-produced blob + +### Acceptance + +* Linking is fully compiler-owned. + +--- + +## PR-17 — Diagnostics UX: show dependency graph + resolution trace + +**Why:** When deps fail, we need actionable feedback. + +### Scope + +* Add CLI output (or compiler API output) showing: + + * resolved graph + * alias mapping + * where a conflict occurred +* Add `--explain-deps` mode (or equivalent) + +### Deliverables + +* human-readable resolution trace + +### Tests + +* snapshot tests for error messages (best-effort) + +### Acceptance + +* Users can debug dependency issues without guessing. + +--- + +## Suggested execution order + +1. PR-09 → PR-10 → PR-11 +2. PR-12 → PR-13 +3. PR-14 → PR-15 +4. PR-16 → PR-17 + +--- + +## Notes for Junie + +* Keep all “v0” decisions simple and deterministic. +* Favor explicit errors over silent fallback. +* Treat `archive-pbs/test01` as the north-star integration scenario. +* No background tasks: every PR must include tests proving the behavior. diff --git a/test-cartridges/sdk/prometeu.json b/test-cartridges/sdk/prometeu.json new file mode 100644 index 00000000..660136cb --- /dev/null +++ b/test-cartridges/sdk/prometeu.json @@ -0,0 +1,5 @@ +{ + "project": "sdk", + "script_fe": "pbs", + "produces": "lib" +} \ No newline at end of file diff --git a/test-cartridges/sdk/src/main/modules/gfx/gfx.pbs b/test-cartridges/sdk/src/main/modules/gfx/gfx.pbs new file mode 100644 index 00000000..5a364219 --- /dev/null +++ b/test-cartridges/sdk/src/main/modules/gfx/gfx.pbs @@ -0,0 +1,12 @@ +declare struct Color(raw: bounded) +[[ + BLACK: Color(0b), + WHITE: Color(65535b), + RED: Color(63488b), + GREEN: Color(2016b), + BLUE: Color(31b) +]] + +declare contract Gfx host { + fn clear(color: Color): void; +} \ No newline at end of file diff --git a/test-cartridges/sdk/src/main/modules/input/input.pbs b/test-cartridges/sdk/src/main/modules/input/input.pbs new file mode 100644 index 00000000..286e8103 --- /dev/null +++ b/test-cartridges/sdk/src/main/modules/input/input.pbs @@ -0,0 +1,29 @@ +declare struct ButtonState( + pressed: bool, + released: bool, + down: bool, + hold_frames: bounded +) + +declare struct Pad( + up: ButtonState, + down: ButtonState, + left: ButtonState, + right: ButtonState, + a: ButtonState, + b: ButtonState, + x: ButtonState, + y: ButtonState, + l: ButtonState, + r: ButtonState, + start: ButtonState, + select: ButtonState +) + +declare contract Input host { + fn pad(): Pad; +} + +fn add(a: int, b: int): int { + return a + b; +} \ No newline at end of file diff --git a/test-cartridges/test01/prometeu.json b/test-cartridges/test01/prometeu.json index ce0b30dc..56254530 100644 --- a/test-cartridges/test01/prometeu.json +++ b/test-cartridges/test01/prometeu.json @@ -1,7 +1,10 @@ { + "project": "test01", "script_fe": "pbs", + "produces": "app", "entry": "src/main.pbs", "out": "build/program.pbc", - "emit_disasm": true, - "emit_symbols": true + "dependencies": { + "sdk": "../sdk" + } } diff --git a/test-cartridges/test01/src/main.pbs b/test-cartridges/test01/src/main.pbs deleted file mode 100644 index 74486e18..00000000 --- a/test-cartridges/test01/src/main.pbs +++ /dev/null @@ -1,66 +0,0 @@ -// CartridgeCanonical.pbs -// Purpose: VM Heartbeat Test (Industrial Baseline) - -declare struct Color(raw: bounded) -[[ - BLACK: Color(0b), - WHITE: Color(65535b), - RED: Color(63488b), - GREEN: Color(2016b), - BLUE: Color(31b) -]] - -declare struct ButtonState( - pressed: bool, - released: bool, - down: bool, - hold_frames: bounded -) - -declare struct Pad( - up: ButtonState, - down: ButtonState, - left: ButtonState, - right: ButtonState, - a: ButtonState, - b: ButtonState, - x: ButtonState, - y: ButtonState, - l: ButtonState, - r: ButtonState, - start: ButtonState, - select: ButtonState -) - -declare contract Gfx host { - fn clear(color: Color): void; -} - -declare contract Input host { - fn pad(): Pad; -} - -fn add(a: int, b: int): int { - return a + b; -} - -fn frame(): void { - // 1. Locals & Arithmetic - let x = 10; - let y = 20; - let z = add(x, y); - - // 2. Control Flow (if) - if z == 30 { - // 3. Syscall Clear - Gfx.clear(Color.GREEN); - } else { - Gfx.clear(Color.RED); - } - - // 4. Input Snapshot & Nested Member Access - let p = Input.pad(); - if p.a.down { - Gfx.clear(Color.BLUE); - } -} diff --git a/test-cartridges/test01/src/main/modules/main.pbs b/test-cartridges/test01/src/main/modules/main.pbs new file mode 100644 index 00000000..e8504d4c --- /dev/null +++ b/test-cartridges/test01/src/main/modules/main.pbs @@ -0,0 +1,22 @@ +import { Color, Gfx, Input } from "@test01:sdk"; + +fn frame(): void { + // 1. Locals & Arithmetic + let x = 10; + let y = 20; + let z = add(x, y); + + // 2. Control Flow (if) + if z == 30 { + // 3. Syscall Clear + Gfx.clear(Color.GREEN); + } else { + Gfx.clear(Color.RED); + } + + // 4. Input Snapshot & Nested Member Access + let p = Input.pad(); + if p.a.down { + Gfx.clear(Color.BLUE); + } +}