adjustments on docs
This commit is contained in:
parent
f77b9f762f
commit
1b0e290e1d
17
README.md
17
README.md
@ -1,8 +1,8 @@
|
||||
# PROMETEU
|
||||
|
||||
PROMETEU is an **educational and experimental ecosystem** inspired by classic consoles, focusing on **teaching programming, system architecture, and hardware concepts through software**.
|
||||
PROMETEU is an **educational and experimental fantasy handheld / fantasy console ecosystem** inspired by classic consoles, focusing on **teaching programming, system architecture, and hardware concepts through software**.
|
||||
|
||||
> PROMETEU is a simple, explicit, and educational virtual machine.
|
||||
> PROMETEU is a fantasy console with a simple, explicit, and educational VM/runtime inside it.
|
||||
|
||||
---
|
||||
|
||||
@ -12,6 +12,7 @@ PROMETEU is an **educational and experimental ecosystem** inspired by classic co
|
||||
- **Deterministic Loop**: Ensure the same code produces the same result on any platform.
|
||||
- **Total Portability**: The core does not depend on an operating system, allowing it to run from modern computers to dedicated hardware.
|
||||
- **First-Class Tools**: Offer deep debugging and inspection as a central part of the experience.
|
||||
- **DIY hardware affinity**: Keep the machine model close enough to handheld/console-era hardware that it can inform real embedded and homebrew-style implementations.
|
||||
|
||||
---
|
||||
|
||||
@ -22,6 +23,17 @@ PROMETEU is an **educational and experimental ecosystem** inspired by classic co
|
||||
- **Deterministic**: same input → same result.
|
||||
- **Hardware-first**: APIs model peripherals, not modern frameworks.
|
||||
- **Portable by definition**: if it doesn't work on all platforms, it doesn't exist.
|
||||
- **Console-era sensibility**: PROMETEU carries intentional influence from NES, SNES, Mega Drive, Game Boy, GBA, CPS-2, and adjacent DIY-friendly hardware thinking.
|
||||
|
||||
## 🧭 Canonical Architecture
|
||||
|
||||
PROMETEU is the machine. The VM/runtime is one subsystem inside that machine.
|
||||
|
||||
Authoritative documents:
|
||||
|
||||
- [`docs/runtime/virtual-machine/ARCHITECTURE.md`](docs/runtime/virtual-machine/ARCHITECTURE.md) is normative for VM/runtime invariants.
|
||||
- [`docs/runtime/specs/README.md`](docs/runtime/specs/README.md) describes the broader PROMETEU machine, hardware model, and fantasy console context.
|
||||
- Supporting material under `docs/` may expand, explain, or propose changes, but it must not silently collapse the whole machine into the VM layer.
|
||||
|
||||
---
|
||||
|
||||
@ -81,4 +93,3 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
||||
## ✨ Final Note
|
||||
|
||||
PROMETEU is both a technical and pedagogical project. The idea is not to hide complexity, but to **expose the right complexity**, at the right level, so it can be understood, studied, and explored.
|
||||
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
//! Core ISA profile (bytecode-only, minimal and stable).
|
||||
//! Core ISA profile (bytecode-level, stable, canonical).
|
||||
//!
|
||||
//! This profile is the canonical surface used by decoder/disasm. It intentionally
|
||||
//! avoids higher-level constructs (e.g., closures/coroutines) at this stage.
|
||||
//! This profile is the canonical opcode surface used by decoder/disasm and
|
||||
//! mirrors the runtime-visible instruction set implemented today, including
|
||||
//! closures, coroutines, intrinsics, and hostcall patching semantics.
|
||||
|
||||
// For PR-1.4 we define the core profile as the current `OpCode` set. We re-export
|
||||
// the opcode type and spec so downstream tools can import from a stable path:
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
# Prometeu Runtime — Architecture (Reset Invariants)
|
||||
|
||||
This document captures the high-level invariants for the reset cycle. It is a stub and will
|
||||
evolve as we formalize the new ISA/VM specs. The goal is to define non-negotiable properties
|
||||
that guide refactors without forcing legacy compatibility.
|
||||
|
||||
Core invariants
|
||||
---------------
|
||||
- Stack-based VM with heap-allocated objects.
|
||||
- Garbage Collection happens at safepoints, primarily at `FRAME_SYNC`.
|
||||
- Closures are first-class (user functions). Syscalls are callable but not first-class values.
|
||||
- Coroutines are the only concurrency model.
|
||||
- No backward compatibility: old bytecode formats, shims, or legacy bridges are out of scope.
|
||||
|
||||
Scope of this stage
|
||||
-------------------
|
||||
- Establish tooling baselines (fmt, clippy, CI) and minimal smoke tests.
|
||||
- Avoid encoding legacy ISA semantics in tests; keep tests focused on build confidence.
|
||||
- Production code must remain free from test-only hooks; use dev-only utilities for determinism.
|
||||
|
||||
Out of scope (for now)
|
||||
----------------------
|
||||
- Detailed ISA definition and instruction semantics beyond what is needed to compile and run
|
||||
smoke-level validations.
|
||||
- Performance tuning or GC algorithm selection.
|
||||
@ -1,183 +0,0 @@
|
||||
PR-1.1 — Bytecode Legacy Inventory & Deletion Map
|
||||
|
||||
Goal
|
||||
- Provide an explicit, reviewable inventory of all RC/HIP-era artifacts (opcodes, traps, types, helpers, docs, tests) and a deletion map for the ISA reset.
|
||||
- No code changes in this PR — documentation only. Follow-up PRs will execute the deletions/edits.
|
||||
|
||||
Repository root
|
||||
- runtime (this file lives at docs/bytecode/RESET_LEGACY_MAP.md)
|
||||
|
||||
Quick grep guide (reviewers)
|
||||
- Use these commands from the project root. They avoid target/ and other generated dirs.
|
||||
|
||||
```
|
||||
# Core RC/HIP signal words
|
||||
grep -RIn --exclude-dir target --exclude-dir dist-staging --exclude-dir dist-workspace \
|
||||
-e '\bHIP\b' -e '\bgate\b' -e 'GATE_' -e '\bretain\b' -e '\brelease\b' -e '\bscope\b' .
|
||||
|
||||
# Legacy opcodes (bytecode + VM handlers)
|
||||
grep -RIn --exclude-dir target \
|
||||
-e 'GateLoad' -e 'GateStore' -e 'GateBeginPeek' -e 'GateEndPeek' \
|
||||
-e 'GateBeginBorrow' -e 'GateEndBorrow' -e 'GateBeginMutate' -e 'GateEndMutate' \
|
||||
-e 'GateRetain' -e 'GateRelease' -e 'Alloc' \
|
||||
crates/console/prometeu-bytecode crates/console/prometeu-vm
|
||||
|
||||
# Scope-related (inventory only; not necessarily to delete)
|
||||
grep -RIn --exclude-dir target -e 'PushScope' -e 'PopScope' crates/console
|
||||
|
||||
# Trap codes inventory (post-reset, check for any lingering gate-specific traps)
|
||||
grep -RIn --exclude-dir target \
|
||||
-e '\bTRAP_\w\+' \
|
||||
crates/console/prometeu-bytecode crates/console/prometeu-vm | grep -Ei 'gate|heap|hip' -n || true
|
||||
|
||||
# Value::Gate usages
|
||||
grep -RIn --exclude-dir target -e 'Value::Gate' crates/console
|
||||
|
||||
# Docs that describe HIP/RC model
|
||||
grep -RIn --exclude-dir target --include '*.md' -e '\bHIP\b' docs files
|
||||
```
|
||||
|
||||
Legend for the deletion map
|
||||
- Remove: file or symbol slated for deletion in follow-up PRs.
|
||||
- Edit: file will survive but needs edits to remove/rename legacy parts.
|
||||
- Keep: file or symbol remains under the GC stack+heap model (not part of RC/HIP removal) — listed here when helpful for context.
|
||||
|
||||
|
||||
1) Legacy opcodes (RC/HIP)
|
||||
|
||||
Remove — OpCode variants (definitions and all references)
|
||||
- prometeu-bytecode
|
||||
- crates/console/prometeu-bytecode/src/opcode.rs
|
||||
- OpCode::Alloc
|
||||
- OpCode::GateLoad
|
||||
- OpCode::GateStore
|
||||
- OpCode::GateBeginPeek, OpCode::GateEndPeek
|
||||
- OpCode::GateBeginBorrow, OpCode::GateEndBorrow
|
||||
- OpCode::GateBeginMutate, OpCode::GateEndMutate
|
||||
- OpCode::GateRetain, OpCode::GateRelease
|
||||
- Notes: also appears in TryFrom<u16> mapping and in cycles() table inside same file.
|
||||
- crates/console/prometeu-bytecode/src/opcode_spec.rs
|
||||
- Spec entries for each of the above (names: GATE_LOAD, GATE_STORE, GATE_BEGIN_PEEK, ... GATE_RELEASE; ALLOC).
|
||||
- crates/console/prometeu-bytecode/src/decoder.rs
|
||||
- Keep file. No direct legacy handling beyond general decoding; remains after removing legacy opcodes.
|
||||
- crates/console/prometeu-bytecode/src/model.rs
|
||||
- Keep file. No opcode definitions here; only payload helpers like imm_u32x2 are generic. No deletion but re-check comments if they reference ALLOC semantics.
|
||||
- crates/console/prometeu-bytecode/src/value.rs
|
||||
- Edit: enum Value includes Gate(usize). This is HIP-only; plan to remove variant and downstream usages when ISA reset lands.
|
||||
- crates/console/prometeu-bytecode/src/program_image.rs
|
||||
- Edit: maps Value to ConstantPoolEntry; has a Value::Gate arm that turns into Null. Will be adjusted once Value::Gate is removed.
|
||||
|
||||
- prometeu-vm (execution semantics for legacy opcodes)
|
||||
- crates/console/prometeu-vm/src/virtual_machine.rs
|
||||
- Match arms for: Alloc, GateLoad/Store, GateBegin*/End* (Peek/Borrow/Mutate), GateRetain/Release.
|
||||
- Gate pool and heap structures (GateEntry, GateId), resolve_gate() helper, and related fields in VM state.
|
||||
- Unit tests tied to HIP/RC model, e.g.:
|
||||
- fn test_hip_traps_oob()
|
||||
- fn test_hip_traps_type()
|
||||
- fn test_invalid_gate_traps()
|
||||
- fn test_gate_ids_distinct_and_round_trip()
|
||||
- crates/console/prometeu-vm/src/scope_frame.rs
|
||||
- Inventory only (scope handling). Scope is not inherently HIP, keep or revise later under GC if needed.
|
||||
|
||||
- prometeu-hal / prometeu-system (touch points)
|
||||
- crates/console/prometeu-hal/src/host_return.rs
|
||||
- Pushes Value::Gate in some host return paths. Will require edits once Value::Gate is removed.
|
||||
- crates/console/prometeu-system/*
|
||||
- No direct HIP opcode handling expected, but grep for Value::Gate and GATE_ in formatting/printing if any.
|
||||
|
||||
|
||||
2) Trap codes (RC/HIP)
|
||||
|
||||
Remove — gate-specific traps (delete constants and all usages)
|
||||
- crates/console/prometeu-bytecode/src/abi.rs
|
||||
- Remove identifiers tied to HIP/gate semantics
|
||||
|
||||
Keep — still meaningful under GC model (names may be revised later, but remain functionally)
|
||||
- crates/console/prometeu-bytecode/src/abi.rs
|
||||
- TRAP_OOB (0x03) — out-of-bounds (generic)
|
||||
- TRAP_INVALID_SYSCALL (0x0000_0007)
|
||||
- TRAP_STACK_UNDERFLOW (0x0000_0008)
|
||||
- TRAP_INVALID_LOCAL (0x0000_0009)
|
||||
- TRAP_DIV_ZERO (0x0000_000A)
|
||||
- TRAP_INVALID_FUNC (0x0000_000B)
|
||||
- TRAP_BAD_RET_SLOTS (0x0000_000C)
|
||||
- TRAP_TYPE — retained; semantics generalized to non-HIP type mismatches
|
||||
|
||||
Usages to edit alongside removal
|
||||
- crates/console/prometeu-vm/src/virtual_machine.rs
|
||||
- Imports: remove any gate-specific trap imports
|
||||
- resolve_gate() and gate handlers construct TrapInfo with those codes
|
||||
- Tests asserting these trap codes
|
||||
|
||||
|
||||
3) Legacy terminology occurrences (inventory)
|
||||
|
||||
Gate/GATE_
|
||||
- Files containing gate-centric logic or names:
|
||||
- crates/console/prometeu-bytecode/src/opcode.rs — Gate* opcodes
|
||||
- crates/console/prometeu-bytecode/src/opcode_spec.rs — GATE_* names
|
||||
- crates/console/prometeu-bytecode/src/value.rs — Value::Gate
|
||||
- crates/console/prometeu-vm/src/virtual_machine.rs — GateEntry, GateId, handlers, tests
|
||||
- docs/specs/pbs/Prometeu VM Memory model.md — extensive HIP/gate sections
|
||||
- docs/specs/pbs/Prometeu Scripting - Prometeu Bytecode Script (PBS).md — HIP/gate model and APIs
|
||||
|
||||
Retain/Release (RC semantics)
|
||||
- Opcode names: GateRetain, GateRelease — bytecode + VM
|
||||
- Docs: reference counting sections in PBS and VM Memory model docs
|
||||
|
||||
Scope
|
||||
- Opcode names: PushScope, PopScope — present in opcode.rs/opcode_spec.rs and executed in VM
|
||||
- VM scope_frame.rs and scope_stack usage — not inherently HIP, but inventoried here per task wording
|
||||
|
||||
HIP (Heap Interface Protocol)
|
||||
- Labelled sections/comments:
|
||||
- crates/console/prometeu-bytecode/src/opcode.rs — comment header “HIP (Heap Interface Protocol)” above Gate* opcodes
|
||||
- docs/specs/pbs/Prometeu VM Memory model.md — HIP-specific architecture
|
||||
- docs/specs/pbs/Prometeu Scripting - Prometeu Bytecode Script (PBS).md — HIP world, borrow/mutate/peek, RC
|
||||
- files/Borrow Mutate - Compiler GC.md — discusses removing RC/HIP in favor of GC; keep as design context but will need text updates after reset
|
||||
|
||||
|
||||
4) Deletion map (by module)
|
||||
|
||||
Will be removed outright (symbols or blocks)
|
||||
- prometeu-bytecode
|
||||
- opcode.rs: all Gate* variants and Alloc variant; TryFrom/encoding IDs and cycles for those
|
||||
- opcode_spec.rs: corresponding spec arms (GATE_*, ALLOC)
|
||||
- abi.rs: gate-specific trap constants
|
||||
- prometeu-vm
|
||||
- virtual_machine.rs: handlers for Alloc and all Gate* opcodes; GateEntry/GateId data structures; resolve_gate(); HIP-focused unit tests listed above
|
||||
|
||||
Will be edited (kept but changed)
|
||||
- prometeu-bytecode
|
||||
- value.rs: remove Value::Gate and update Display/eq code paths
|
||||
- program_image.rs: remove/adjust Value::Gate mapping in constant pool materialization
|
||||
- decoder.rs: no semantic change; ensure UnknownOpcode remains deterministic (already the case)
|
||||
- prometeu-vm
|
||||
- virtual_machine.rs: remove trap imports for legacy codes; update match to exclude removed opcodes; prune gate/heap fields
|
||||
- scope_frame.rs: keep unless later ISA changes require scope model changes (not part of HIP removal)
|
||||
- prometeu-hal
|
||||
- host_return.rs: stop producing Value::Gate once Value enum loses Gate
|
||||
|
||||
Docs to remove or rewrite (architecture reset)
|
||||
- docs/specs/pbs/Prometeu VM Memory model.md — replace HIP/RC model with GC stack+heap model
|
||||
- docs/specs/pbs/Prometeu Scripting - Prometeu Bytecode Script (PBS).md — remove HIP world/RC sections; update storage semantics
|
||||
- Any disasm examples or golden outputs referring to GATE_* or ALLOC — update after opcode removal
|
||||
|
||||
Tests/fixtures affected
|
||||
- Unit tests in prometeu-vm referencing HIP traps or Gate behavior:
|
||||
- test_hip_traps_oob, test_hip_traps_type, test_invalid_gate_traps, test_gate_ids_distinct_and_round_trip
|
||||
- Golden disassemblies under test-cartridges/*/build/program.disasm.txt may include GATE_* lines — grep and update in follow-up PRs
|
||||
|
||||
|
||||
5) Reviewer checklist for follow-up PRs
|
||||
- Bytecode enum/spec cleaned: no Gate*/Alloc variants remain
|
||||
- VM execution has no references to Gate/GateEntry/resolve_gate
|
||||
- Value enum no longer has Gate; all Display/eq/serde paths fixed
|
||||
- Trap ABI contains only GC-era traps (OOB, stack underflow, invalid func/local/syscall, div by zero, bad ret slots, etc.)
|
||||
- Disassembler/printers do not print legacy names (GATE_*, ALLOC)
|
||||
- Docs no longer mention HIP/RC; updated to GC model
|
||||
- All tests green (`cargo test`) after deletions and necessary test updates
|
||||
|
||||
|
||||
6) Notes
|
||||
- This document inventories occurrences proactively, but exact refactors in the reset may slightly shift responsibilities (e.g., how storage allocation appears under GC). Use the grep guide to double-check any stragglers during code deletion PRs.
|
||||
@ -1,113 +0,0 @@
|
||||
# Specification — Prometeu Development Cycle
|
||||
**Version:** 0.1
|
||||
**Status:** Conceptual / Philosophical
|
||||
|
||||
---
|
||||
|
||||
## 1. Central Principle
|
||||
|
||||
Prometeu is a didactic platform for interactive software development.
|
||||
Its development cycle is designed to clearly separate:
|
||||
|
||||
- Code creation
|
||||
- Compilation
|
||||
- Execution
|
||||
- Observation and explanation
|
||||
|
||||
Each stage has its own specialized, non-overlapping tool.
|
||||
|
||||
---
|
||||
|
||||
## 2. Cycle Tools
|
||||
|
||||
The cycle uses four pillars:
|
||||
|
||||
1. **Code Editor**
|
||||
Free environment (e.g., WebStorm) where the developer writes in TypeScript.
|
||||
|
||||
2. **Prometeu Compiler**
|
||||
Converts source code into executable bytecode for the Prometeu runtime.
|
||||
|
||||
3. **Prometeu Runtime**
|
||||
Executes games and applications in its own graphical environment.
|
||||
|
||||
4. **Prometeu Debugger**
|
||||
A didactic tool for observation, analysis, and explanation of the system's internal behavior.
|
||||
|
||||
None of these tools try to replace each other.
|
||||
They cooperate through clear contracts.
|
||||
|
||||
---
|
||||
|
||||
## 3. General Flow
|
||||
|
||||
The cycle always follows the same conceptual sequence:
|
||||
|
||||
1. The developer writes code in TypeScript.
|
||||
2. The code is compiled to Prometeu bytecode.
|
||||
3. The bytecode is packaged as a cartridge.
|
||||
4. The cartridge is executed by the runtime.
|
||||
5. Internal behavior can be observed by the Prometeu Debugger.
|
||||
|
||||
---
|
||||
|
||||
## 4. Execution Modes
|
||||
|
||||
Prometeu has two conceptual execution modes:
|
||||
|
||||
### Normal Execution (Run)
|
||||
|
||||
- The cartridge is packaged and executed.
|
||||
- The runtime operates autonomously.
|
||||
- The Debugger acts only as an observer.
|
||||
|
||||
### Assisted Execution (Debug)
|
||||
|
||||
- The cartridge is packaged and executed.
|
||||
- The runtime waits for a connection from the Prometeu Debugger.
|
||||
- The Debugger begins to control and observe the execution.
|
||||
|
||||
---
|
||||
|
||||
## 5. Separation of Roles
|
||||
|
||||
Each part of the cycle has a unique responsibility:
|
||||
|
||||
| Stage | Main Role |
|
||||
|------------|------------------------------------|
|
||||
| Editor | Create code |
|
||||
| Compiler | Transform code into bytecode |
|
||||
| Runtime | Execute |
|
||||
| Debugger | Observe, explain, and teach |
|
||||
|
||||
This separation is intentional and part of the Prometeu philosophy.
|
||||
|
||||
---
|
||||
|
||||
## 6. Didactic Philosophy
|
||||
|
||||
Prometeu is not just an engine.
|
||||
It is a platform for learning how interactive software works from the inside.
|
||||
|
||||
The development cycle is designed to:
|
||||
|
||||
- Make execution visible
|
||||
- Make technical decisions observable
|
||||
- Make errors explainable
|
||||
- Make performance measurable
|
||||
|
||||
The Debugger is not just a fix tool, but a pedagogical instrument.
|
||||
|
||||
---
|
||||
|
||||
## 7. Synthesis
|
||||
|
||||
The Prometeu Development Cycle is:
|
||||
|
||||
- Modular
|
||||
- Observable
|
||||
- Didactic
|
||||
- Not coupled to a specific IDE
|
||||
- Oriented towards learning and deep understanding
|
||||
|
||||
It exists so that the developer does not just write programs, but understands how they live inside the machine.
|
||||
@ -1,537 +0,0 @@
|
||||
# PR — lsp-base (LSP MVP)
|
||||
|
||||
**Branch:** `pr-08-lsp-mvp`
|
||||
|
||||
## Briefing
|
||||
|
||||
Queremos um **LSP mínimo funcional** que já permita trabalhar PBS no VSCode com:
|
||||
|
||||
* erros aparecendo (diagnostics)
|
||||
* navegação básica (goto definition)
|
||||
* visão estrutural (document/workspace symbols)
|
||||
|
||||
Regras-chave (MVP):
|
||||
|
||||
* `didChange` será **full-text**
|
||||
* rebuild será **coarse** (recompila o projeto inteiro) sempre que qualquer arquivo muda
|
||||
* sem incremental analysis ainda
|
||||
* comentários extensivos com exemplos se necessário e em inglês sempre
|
||||
|
||||
Este PR não inclui semantic tokens nem completion (virão nos PRs seguintes).
|
||||
|
||||
---
|
||||
|
||||
## Alvo (Features)
|
||||
|
||||
### LSP endpoints
|
||||
|
||||
* ✅ `initialize`
|
||||
* ✅ `textDocument/didOpen`
|
||||
* ✅ `textDocument/didChange` (FULL)
|
||||
* ✅ `textDocument/didClose`
|
||||
* ✅ `textDocument/documentSymbol`
|
||||
* ✅ `workspace/symbol`
|
||||
* ✅ `textDocument/definition`
|
||||
* ✅ `textDocument/publishDiagnostics`
|
||||
|
||||
### Modelo de build
|
||||
|
||||
* `AnalysisDb` em memória
|
||||
* `FileDb` (uri → texto)
|
||||
* `rebuild()` recompila **workspace inteiro** e produz um snapshot
|
||||
|
||||
---
|
||||
|
||||
## Design (como deve funcionar)
|
||||
|
||||
### 1) AnalysisDb: estado e snapshot
|
||||
|
||||
**Objetivo:** separar “estado de arquivos” de “resultado de análise”.
|
||||
|
||||
Estruturas recomendadas:
|
||||
|
||||
```rust
|
||||
pub struct AnalysisDb {
|
||||
pub file_db: FileDb,
|
||||
pub revision: u64,
|
||||
pub active_rebuild: Option<RebuildHandle>,
|
||||
pub last_good: Option<AnalysisSnapshot>,
|
||||
}
|
||||
|
||||
pub struct AnalysisSnapshot {
|
||||
pub diagnostics: Vec<Diagnostic>,
|
||||
pub symbols: SymbolIndex, // index por Project/Module (coarse)
|
||||
pub node_to_symbol: NodeToSymbol, // para definition
|
||||
pub def_index: DefIndex, // opcional se você já tiver
|
||||
pub ast: AstArena, // opcional (mas útil para nodes)
|
||||
}
|
||||
```
|
||||
|
||||
> Observação: use os tipos reais do seu compiler. O importante é ter um “snapshot” único que o LSP consulta.
|
||||
|
||||
### 2) Fluxo de rebuild
|
||||
|
||||
* `didOpen/didChange`:
|
||||
|
||||
* atualizar `file_db` com texto atual
|
||||
* incrementar `revision`
|
||||
* disparar `request_rebuild()` (coalescing)
|
||||
|
||||
* `request_rebuild()`:
|
||||
|
||||
* cancela rebuild anterior se houver
|
||||
* agenda um rebuild assíncrono (tokio task)
|
||||
* no fim, se não estiver cancelado e se `revision` não mudou, grava `last_good` e publica diagnostics
|
||||
|
||||
### 3) Diagnostics
|
||||
|
||||
* O compiler já deve produzir diagnostics com `Span { file, start, end }` em bytes.
|
||||
* Para publicar, converter:
|
||||
|
||||
* `Span` → `lsp_types::Range` via `TextIndex` (já existe do refactor)
|
||||
|
||||
Regra:
|
||||
|
||||
* Diagnóstico sem `Span` (ou span inválido) deve ser **ignorado** ou degradado para range 0..0.
|
||||
|
||||
### 4) Definition
|
||||
|
||||
Ao receber `textDocument/definition`:
|
||||
|
||||
1. converter `Position` → byte offset (com `TextIndex`)
|
||||
2. encontrar `NodeId` no ponto
|
||||
3. resolver `NodeId -> SymbolId` via `node_to_symbol`
|
||||
4. pegar `Symbol.decl_span`
|
||||
5. converter `decl_span` → `Location`
|
||||
|
||||
> Se `NodeId` não existir ou não resolver símbolo: retornar `None`.
|
||||
|
||||
### 5) documentSymbol / workspaceSymbol
|
||||
|
||||
* `documentSymbol`: filtrar símbolos cujo `decl_span.file` == arquivo da request.
|
||||
* `workspaceSymbol`: busca textual simples (contains/case-insensitive) nos nomes de símbolos (coarse) e retorna top N.
|
||||
|
||||
---
|
||||
|
||||
## Tarefas de implementação (checklist técnico)
|
||||
|
||||
### Capabilities em `initialize`
|
||||
|
||||
Declarar no server:
|
||||
|
||||
* `textDocumentSync: Full`
|
||||
* `definitionProvider: true`
|
||||
* `documentSymbolProvider: true`
|
||||
* `workspaceSymbolProvider: true`
|
||||
* `diagnosticProvider`: use publishDiagnostics (push)
|
||||
|
||||
### didOpen
|
||||
|
||||
* upsert texto
|
||||
* request_rebuild
|
||||
|
||||
### didChange (Full)
|
||||
|
||||
* receber texto completo do doc
|
||||
* upsert texto
|
||||
* request_rebuild
|
||||
|
||||
### didClose
|
||||
|
||||
* remover do file_db (ou marcar fechado)
|
||||
* publicar diagnostics vazios para o arquivo fechado
|
||||
|
||||
### Conversions
|
||||
|
||||
* `uri <-> FileId`: FileDb precisa mapear URI para FileId estável.
|
||||
* `Span -> Range`: usar `TextIndex` do texto atual do arquivo.
|
||||
* `Position -> byte`: usar `TextIndex`.
|
||||
|
||||
### Node lookup
|
||||
|
||||
Você precisa de uma função no snapshot (ou util) tipo:
|
||||
|
||||
* `fn node_at(file: FileId, byte: u32) -> Option<NodeId>`
|
||||
|
||||
MVP aceitável:
|
||||
|
||||
* se você ainda não tiver um índice de nodes por span, pode:
|
||||
|
||||
* usar AST arena e fazer busca linear na árvore (aceitável no coarse MVP)
|
||||
|
||||
---
|
||||
|
||||
## Test Harness (mínimo, mas real)
|
||||
|
||||
### Opção A (preferida): tests com `tower-lsp` client in-process
|
||||
|
||||
Criar um teste `tests/lsp_mvp.rs`:
|
||||
|
||||
* sobe o backend LSP em memória
|
||||
* envia:
|
||||
|
||||
* `initialize`
|
||||
* `didOpen` com um fixture PBS (2 arquivos)
|
||||
* espera `publishDiagnostics` (pode interceptar via `Client` mock)
|
||||
* chama `definition` em uma posição de uso e verifica que retorna `Location` do `decl_span`
|
||||
|
||||
**Aceite:**
|
||||
|
||||
* definition retorna arquivo correto
|
||||
* range bate com span convertido
|
||||
|
||||
### Opção B (mais simples): unit tests nos adaptadores
|
||||
|
||||
Se o harness LSP demorar, pelo menos criar:
|
||||
|
||||
* `span_to_range_uses_utf16()`
|
||||
* `position_to_byte_roundtrip()`
|
||||
* `definition_resolves_to_decl_span()` usando snapshot fake.
|
||||
|
||||
---
|
||||
|
||||
## Checklist de aceite (obrigatório)
|
||||
|
||||
* [ ] `cargo test -q` passa no workspace
|
||||
* [ ] VSCode: abrir arquivo `.pbs` mostra diagnostics (pelo menos 1 erro sintático)
|
||||
* [ ] VSCode: `Go to Definition` funciona para símbolo resolvido
|
||||
* [ ] VSCode: Outline mostra `documentSymbol`
|
||||
* [ ] Mudanças em um arquivo disparam rebuild e atualizam diagnostics
|
||||
* [ ] Unicode: diagnostics não ficam “desalinhados” (teste manual com `ação`/emoji)
|
||||
|
||||
---
|
||||
|
||||
## Fora de escopo (explicitamente)
|
||||
|
||||
* semantic tokens
|
||||
* completion
|
||||
* references/rename
|
||||
* hover/signatureHelp
|
||||
* incremental analysis e cancelation avançada
|
||||
|
||||
---
|
||||
|
||||
# PR — lsp-hightlight-base (Semantic Tokens — lexer-first)
|
||||
|
||||
**Branch:** `pr-12a-lsp-semantic-lexer`
|
||||
|
||||
## Briefing
|
||||
|
||||
Queremos **highlight no VSCode via LSP**, sem depender de resolver e sem TextMate.
|
||||
|
||||
Estratégia:
|
||||
|
||||
* Implementar `textDocument/semanticTokens/full`.
|
||||
* Gerar tokens **lexer-first**: comments/strings/numbers/keywords/identifiers.
|
||||
* Converter spans (bytes) para LSP positions (UTF-16) usando `TextIndex`.
|
||||
* comentários extensivos com exemplos se necessário e em inglês sempre
|
||||
|
||||
Isso entrega um highlight “bom o suficiente” e muito estável, mesmo com arquivo com erro de parse.
|
||||
|
||||
---
|
||||
|
||||
## Alvo (Features)
|
||||
|
||||
* ✅ `textDocument/semanticTokens/full`
|
||||
* ✅ `SemanticTokensLegend` consistente
|
||||
* ✅ tokens derivados do lexer
|
||||
|
||||
Opcional (não obrigatório neste PR):
|
||||
|
||||
* `semanticTokens/range`
|
||||
* `semanticTokens/full/delta`
|
||||
|
||||
---
|
||||
|
||||
## Design
|
||||
|
||||
### 1) Legend fixa
|
||||
|
||||
Escolher um conjunto pequeno de token types:
|
||||
|
||||
* `comment`
|
||||
* `string`
|
||||
* `number`
|
||||
* `keyword`
|
||||
* `operator` (opcional)
|
||||
* `variable` (para identifiers genéricos)
|
||||
|
||||
> Não inventar muitos tipos agora; fácil expandir depois.
|
||||
|
||||
### 2) Fonte de tokens
|
||||
|
||||
Implementar uma função no analysis/compiler layer (ou no lsp crate) que, dado:
|
||||
|
||||
* `FileId`
|
||||
* `text: &str`
|
||||
retorna `Vec<(Span, TokenType, TokenModifiers)>`.
|
||||
|
||||
**Importante:**
|
||||
|
||||
* Spans são em bytes.
|
||||
* Devem ser **não sobrepostos** e preferencialmente em ordem.
|
||||
|
||||
### 3) Conversão para formato LSP (deltas)
|
||||
|
||||
LSP semantic tokens usa encoding em deltas:
|
||||
|
||||
* `deltaLine`, `deltaStartChar`, `length`, `tokenType`, `tokenModifiers`
|
||||
|
||||
Algoritmo:
|
||||
|
||||
1. Converter `Span.start` e `Span.end` em `(line, utf16_col)`.
|
||||
2. Calcular `length` em UTF-16 units para o trecho (start..end).
|
||||
3. Ordenar por `(line, col)`.
|
||||
4. Emitir deltas.
|
||||
|
||||
Regra:
|
||||
|
||||
* Se `Span` cruza linhas, **quebrar** em múltiplos tokens por linha (MVP seguro).
|
||||
|
||||
### 4) Robustez
|
||||
|
||||
* Token inválido (end < start, ou fora do texto) deve ser ignorado.
|
||||
* Se o arquivo não estiver no `FileDb`, retornar tokens vazios.
|
||||
|
||||
---
|
||||
|
||||
## Tarefas de implementação
|
||||
|
||||
### Server capabilities
|
||||
|
||||
No `initialize`, anunciar:
|
||||
|
||||
* `semanticTokensProvider` com:
|
||||
|
||||
* `legend`
|
||||
* `full: true`
|
||||
* `range: false` (por enquanto)
|
||||
|
||||
### Handler
|
||||
|
||||
Implementar `semantic_tokens_full(params)`:
|
||||
|
||||
* pegar `uri`
|
||||
* buscar texto no `file_db`
|
||||
* gerar tokens do lexer
|
||||
* converter com `TextIndex`
|
||||
* retornar `SemanticTokensResult::Tokens`
|
||||
|
||||
### Lexer tokens
|
||||
|
||||
Se você já tem lexer com spans:
|
||||
|
||||
* mapear tokens para os tipos (keyword/string/comment/number/identifier)
|
||||
* keywords: pode ser por enum do token ou por tabela
|
||||
|
||||
Se o lexer não marca keyword vs ident:
|
||||
|
||||
* fallback: parse por string e classifica keywords via `HashSet<&'static str>`.
|
||||
|
||||
---
|
||||
|
||||
## Testes
|
||||
|
||||
### Unit tests (obrigatórios)
|
||||
|
||||
1. `semantic_tokens_legend_is_stable()`
|
||||
|
||||
* garante que legend não muda sem intenção.
|
||||
|
||||
2. `semantic_tokens_are_sorted_and_non_negative()`
|
||||
|
||||
* gera tokens em um fixture com 2 linhas
|
||||
* valida que deltas nunca ficam negativos e que ordem é válida.
|
||||
|
||||
3. `semantic_tokens_unicode_length_utf16()`
|
||||
|
||||
* texto com `ação🙂`
|
||||
* valida que `length` corresponde a UTF-16 (emoji conta como 2).
|
||||
|
||||
### Teste manual (aceite)
|
||||
|
||||
* Abrir `.pbs` no VSCode
|
||||
* Verificar:
|
||||
|
||||
* strings e comentários coloridos
|
||||
* keywords coloridas
|
||||
* números coloridos
|
||||
* identifiers coloridos (mesmo que genérico)
|
||||
|
||||
---
|
||||
|
||||
## Checklist de aceite
|
||||
|
||||
* [ ] `cargo test -q` passa
|
||||
* [ ] VSCode: arquivos PBS ficam coloridos via LSP (sem TextMate)
|
||||
* [ ] Unicode não quebra offsets
|
||||
* [ ] Arquivo com erro de parse ainda tem highlight (lexer-first)
|
||||
|
||||
---
|
||||
|
||||
## Fora de escopo
|
||||
|
||||
* semantic tokens semântico (type vs fn vs var) — virá em `PR-12b`
|
||||
* `range`/`delta`
|
||||
* completion
|
||||
|
||||
---
|
||||
|
||||
# PR — lsp-completion-base (Completion mínimo)
|
||||
|
||||
**Branch:** `pr-11a-lsp-completion-min`
|
||||
|
||||
## Briefing
|
||||
|
||||
Queremos autocomplete **mínimo mas útil** para conseguir escrever SDK/ECS em PBS sem fricção.
|
||||
|
||||
Princípio:
|
||||
|
||||
* Não depende de scope facts, nem type facts.
|
||||
* Usa somente:
|
||||
|
||||
* keywords/builtins
|
||||
* símbolos top-level do módulo atual
|
||||
* exports/imports visíveis no projeto (coarse)
|
||||
|
||||
Isso é suficiente para começar a programar e evoluir o LSP depois.
|
||||
|
||||
* comentários extensivos com exemplos se necessário e em inglês sempre
|
||||
|
||||
---
|
||||
|
||||
## Alvo (Features)
|
||||
|
||||
* ✅ `textDocument/completion`
|
||||
* ✅ `completionItem/resolve` (opcional; pode retornar item já completo)
|
||||
|
||||
---
|
||||
|
||||
## Design
|
||||
|
||||
### 1) Buckets e ordenação
|
||||
|
||||
Retornar `CompletionList` com itens nesta prioridade:
|
||||
|
||||
1. Keywords (`fn`, `let`, `mutate`, `declare`, `struct`, `storage`, `if`, `else`, `for`, `return`, etc.)
|
||||
2. Builtins/funções globais (ex.: `alloc`, `box`, `unbox`, `range`, etc. — conforme spec do PBS)
|
||||
3. Símbolos do módulo atual (top-level)
|
||||
4. Símbolos “workspace visible” (exports/imports), limitado (ex.: top 200)
|
||||
|
||||
**Regra de ranking simples:**
|
||||
|
||||
* locals (não teremos) > módulo atual > workspace
|
||||
|
||||
### 2) Contexto
|
||||
|
||||
Para completion mínimo, só precisamos:
|
||||
|
||||
* `uri` do documento
|
||||
* `position` (para pegar prefixo)
|
||||
|
||||
Prefixo:
|
||||
|
||||
* converter `Position` -> byte
|
||||
* extrair texto até o cursor e identificar o “token parcial” (regex simples `[A-Za-z_][A-Za-z0-9_]*$`)
|
||||
|
||||
### 3) Fonte dos símbolos
|
||||
|
||||
Usar o `AnalysisSnapshot` (produzido na PR-08) para expor:
|
||||
|
||||
* `fn symbols_in_file(file: FileId) -> Vec<SymbolId>`
|
||||
* `fn symbols_in_module(project: ProjectId, module: ModuleId) -> Vec<SymbolId>`
|
||||
* `fn workspace_symbols() -> impl Iterator<Item = (name, kind, decl_span)>`
|
||||
|
||||
MVP aceitável:
|
||||
|
||||
* `workspace_symbols()` pode ser um vetor “flatten” pré-calculado no snapshot.
|
||||
|
||||
### 4) CompletionItem
|
||||
|
||||
Mapeamento para `CompletionItemKind`:
|
||||
|
||||
* functions -> `FUNCTION`
|
||||
* types -> `CLASS` (ou `STRUCT` se quiser)
|
||||
* modules -> `MODULE`
|
||||
* variables/constants -> `VARIABLE` / `CONSTANT`
|
||||
|
||||
Campos:
|
||||
|
||||
* `label`: nome
|
||||
* `detail`: (opcional) `"fn"/"type"/"module"`
|
||||
* `sortText`: prefixado para impor bucket (ex.: `"1_"`, `"2_"`)
|
||||
* `filterText`: label
|
||||
|
||||
---
|
||||
|
||||
## Tarefas de implementação
|
||||
|
||||
### Capabilities
|
||||
|
||||
No `initialize`:
|
||||
|
||||
* `completionProvider: { resolveProvider: false, triggerCharacters: [".", ":"]? }`
|
||||
|
||||
> Para completion mínimo, nem precisa trigger chars. Pode deixar default.
|
||||
|
||||
### Handler `completion`
|
||||
|
||||
* buscar texto e `TextIndex`
|
||||
* calcular prefixo
|
||||
* montar lista de candidatos por bucket
|
||||
* filtrar por prefixo (case-sensitive ou insensitive; escolha e documente)
|
||||
* limitar tamanho
|
||||
* retornar `CompletionResponse::List`
|
||||
|
||||
### Builtins/keywords
|
||||
|
||||
Criar tabelas estáticas em `prometeu-lsp`:
|
||||
|
||||
* `static KEYWORDS: &[&str] = ...`
|
||||
* `static BUILTINS: &[&str] = ...`
|
||||
|
||||
---
|
||||
|
||||
## Testes
|
||||
|
||||
### Unit tests (obrigatórios)
|
||||
|
||||
1. `completion_extracts_prefix()`
|
||||
|
||||
* valida regex de prefixo
|
||||
|
||||
2. `completion_includes_keywords()`
|
||||
|
||||
* chama handler com texto vazio e posição 0
|
||||
* garante que `fn` aparece
|
||||
|
||||
3. `completion_filters_by_prefix()`
|
||||
|
||||
* prefixo `"ra"` deve sugerir `range` (se builtin)
|
||||
|
||||
4. (se possível) `completion_includes_module_symbols()`
|
||||
|
||||
* usando snapshot fake ou fixture compilado pela infra da PR-08
|
||||
|
||||
### Teste manual (aceite)
|
||||
|
||||
* Abrir arquivo PBS e digitar `ra` -> aparece `range`
|
||||
* Digitar nome de tipo/fn do SDK -> aparece suggestion
|
||||
|
||||
---
|
||||
|
||||
## Checklist de aceite
|
||||
|
||||
* [ ] `cargo test -q` passa
|
||||
* [ ] VSCode: autocomplete sugere keywords e builtins
|
||||
* [ ] VSCode: autocomplete sugere símbolos do módulo atual
|
||||
* [ ] Não trava com rebuild coarse
|
||||
|
||||
---
|
||||
|
||||
## Fora de escopo
|
||||
|
||||
* locals em scope
|
||||
* members (`obj.`)
|
||||
* signatureHelp
|
||||
* hover
|
||||
@ -1,219 +0,0 @@
|
||||
# LSP Roadmap — do “base usable” até “LSP completo”
|
||||
|
||||
> Este documento é o mapa incremental pós `lsp-base`, `lsp-hightlight-base`, `lsp-completion-base`.
|
||||
> A ideia é manter o LSP evoluindo sem rework, enquanto SDK/ECS/Packer avançam em paralelo.
|
||||
|
||||
---
|
||||
|
||||
## Estado atual (após os 3 PRs base)
|
||||
|
||||
### ✅ Já temos
|
||||
|
||||
* Diagnostics (publishDiagnostics)
|
||||
* Definition (goto definition)
|
||||
* DocumentSymbol / WorkspaceSymbol
|
||||
* Semantic tokens (lexer-first)
|
||||
* Completion mínimo (keywords/builtins/top-level/module/workspace)
|
||||
|
||||
### ❌ Ainda não temos
|
||||
|
||||
* references / rename
|
||||
* hover / signatureHelp
|
||||
* completion com locals em scope
|
||||
* semantic tokens semântico (type vs fn vs var)
|
||||
* incremental analysis real (por arquivo / cancelation)
|
||||
* debug map pc→span integrado com traps
|
||||
* code actions / formatting
|
||||
|
||||
---
|
||||
|
||||
## Próximos PRs recomendados (ordem sugerida)
|
||||
|
||||
## PR-09 — References + Rename (seguro)
|
||||
|
||||
### Objetivo
|
||||
|
||||
Habilitar `references`, `prepareRename`, `rename` com regras de segurança.
|
||||
|
||||
### Pré-requisitos
|
||||
|
||||
* `RefIndex` completo (SymbolId -> usos em spans)
|
||||
* `NodeToSymbol` estável
|
||||
* `TriviaIndex` (comments/strings) para não renomear spans proibidos
|
||||
|
||||
### Regras de segurança
|
||||
|
||||
* Não renomear símbolo não-resolvido
|
||||
* Não renomear em comentário/string
|
||||
* Renomear deve gerar `WorkspaceEdit` apenas para spans válidos
|
||||
|
||||
### Testes
|
||||
|
||||
* Fixture com 2 arquivos: rename atualiza todas as refs
|
||||
* Fixture: rename em comentário não altera nada
|
||||
|
||||
---
|
||||
|
||||
## PR-10 — Hover + SignatureHelp
|
||||
|
||||
### Objetivo
|
||||
|
||||
* `hover`: mostrar tipo + docstring (docstring opcional)
|
||||
* `signatureHelp`: para call nodes
|
||||
|
||||
### Pré-requisitos
|
||||
|
||||
* Type facts básicos: `NodeId -> TypeId`
|
||||
* Modelo de assinatura: para functions (params, retorno)
|
||||
|
||||
### Testes
|
||||
|
||||
* Hover em símbolo mostra tipo
|
||||
* SignatureHelp em chamada mostra params
|
||||
|
||||
---
|
||||
|
||||
## PR-11b — Completion com locals em scope
|
||||
|
||||
### Objetivo
|
||||
|
||||
Autocomplete útil para código real:
|
||||
|
||||
* locals/params
|
||||
* shadowing correto
|
||||
|
||||
### Pré-requisitos
|
||||
|
||||
* Binder/Scope facts:
|
||||
|
||||
* `Position -> ScopeId`
|
||||
* `ScopeId -> bindings (name -> SymbolId/TypeId)`
|
||||
|
||||
### Testes
|
||||
|
||||
* Dentro de bloco, sugere variável local
|
||||
* Shadowing: sugere a mais interna
|
||||
|
||||
---
|
||||
|
||||
## PR-12b — Semantic tokens resolver-backed (semântico)
|
||||
|
||||
### Objetivo
|
||||
|
||||
Melhorar highlight:
|
||||
|
||||
* diferenciar `type` vs `function` vs `variable` vs `parameter` vs `module`
|
||||
|
||||
### Pré-requisitos
|
||||
|
||||
* `NodeAtPosition` confiável
|
||||
* `NodeToSymbol` confiável
|
||||
* `SymbolKind` consistente
|
||||
|
||||
### Testes
|
||||
|
||||
* Identificador de tipo recebe token `type`
|
||||
* Função recebe token `function`
|
||||
|
||||
---
|
||||
|
||||
## PR-13 — Formatting + Code Actions (opcional)
|
||||
|
||||
### Objetivo
|
||||
|
||||
* `textDocument/formatting` (nem que seja formatter simples/estável)
|
||||
* code actions básicas:
|
||||
|
||||
* organizar imports
|
||||
* criar stub de função/struct
|
||||
|
||||
### Pré-requisitos
|
||||
|
||||
* AST pretty printer (ou formatter incremental)
|
||||
|
||||
---
|
||||
|
||||
## PR-14 — Incremental analysis + cancelation (de verdade)
|
||||
|
||||
### Objetivo
|
||||
|
||||
Sair do rebuild coarse:
|
||||
|
||||
* recompilar somente arquivo/módulo afetado
|
||||
* cancelamento real de builds longos
|
||||
* snapshots por versão
|
||||
|
||||
### Pré-requisitos
|
||||
|
||||
* Graph de dependências por módulo
|
||||
* Cache de parse/resolve por arquivo
|
||||
* `revision` por doc
|
||||
|
||||
### Testes
|
||||
|
||||
* Editar arquivo A não recompila projeto inteiro
|
||||
* Cancel: digitar rápido não aplica resultados velhos
|
||||
|
||||
---
|
||||
|
||||
## PR-15 — Debug map (pc→span) + integração com traps
|
||||
|
||||
### Objetivo
|
||||
|
||||
Quando a VM gerar trap/runtime error:
|
||||
|
||||
* mapear `pc` para `Span`
|
||||
* mostrar erro com localização exata
|
||||
|
||||
### Pré-requisitos
|
||||
|
||||
* SourceMap gerado no backend bytecode
|
||||
* runtime expõe `pc`/contexto
|
||||
|
||||
### Testes
|
||||
|
||||
* programa que gera trap aponta para linha/col corretos
|
||||
|
||||
---
|
||||
|
||||
# Backlog adicional (nice to have)
|
||||
|
||||
* `workspace/didChangeWatchedFiles` (reagir a mudanças fora do editor)
|
||||
* `textDocument/codeLens` (ex.: run test / run main)
|
||||
* `textDocument/inlayHint`
|
||||
* `workspace/diagnostic` pull-mode (se quiser)
|
||||
* semanticTokens `range` e `delta` para performance
|
||||
|
||||
---
|
||||
|
||||
## Interação com SDK/ECS/Packer
|
||||
|
||||
### Com os 3 PRs base, você já consegue:
|
||||
|
||||
* escrever SDK/ECS em PBS com feedback imediato
|
||||
* navegar rapidamente pelo código
|
||||
* manter arquivos grandes com highlight
|
||||
* usar completion para nomes de APIs
|
||||
|
||||
### Enquanto isso, em paralelo:
|
||||
|
||||
* packer pode evoluir (não depende do LSP)
|
||||
* quando packer estabilizar, podemos adicionar code actions/codelens para “build/pack/run” direto no VSCode
|
||||
|
||||
---
|
||||
|
||||
## Definição de “LSP completo” (para Prometeu view-ready)
|
||||
|
||||
Para chamar de "completo" (na sua visão de produto):
|
||||
|
||||
* ✅ diagnostics
|
||||
* ✅ definition
|
||||
* ✅ symbols
|
||||
* ✅ highlight semântico
|
||||
* ✅ completion com scope + members
|
||||
* ✅ hover + signatureHelp
|
||||
* ✅ references + rename
|
||||
* ✅ incremental + cancel
|
||||
* ✅ debug map integrado com traps
|
||||
|
||||
> A ordem acima é incremental por valor percebido e por dependências.
|
||||
@ -1,564 +0,0 @@
|
||||
# Prometeu Packer (prometeu-packer) — Specification (Draft)
|
||||
|
||||
> **Status:** Draft / Community-facing
|
||||
>
|
||||
> This document specifies the **Prometeu Packer**, the tooling responsible for **asset management** and producing two build artifacts:
|
||||
>
|
||||
> * `build/assets.pa` — the ROM payload containing packed asset bytes
|
||||
> * `build/asset_table.json` — a machine-readable descriptor of the packed assets
|
||||
>
|
||||
> The Packer is deliberately **agnostic of cartridge building**. A separate **Cartridge Builder** (outside the Packer) consumes `build/asset_table.json` to generate the final `cartridge/manifest.json`, copy `assets.pa` to the cartridge directory, and zip the cartridge into a distributable format.
|
||||
|
||||
---
|
||||
|
||||
## 1. Goals and Non-Goals
|
||||
|
||||
### 1.1 Goals
|
||||
|
||||
1. **Be the guardian of sanity** in a constantly mutating `assets/` workspace.
|
||||
|
||||
* Users may be disorganized.
|
||||
* The directory may contain WIP, junk, unused files, duplicates, outdated exports.
|
||||
* The Packer must help users identify and fix mistakes.
|
||||
|
||||
2. Provide a robust, deterministic, **tooling-grade** asset pipeline.
|
||||
|
||||
* Stable asset identity.
|
||||
* Deterministic packing order.
|
||||
* Reproducible output bytes.
|
||||
|
||||
3. Support both **raw (direct) assets** and **virtual assets**.
|
||||
|
||||
* Raw assets: the payload in ROM is exactly the source bytes.
|
||||
* Virtual assets: the payload is derived from multiple inputs via a build pipeline (e.g., PNG + palettes → `TILES` payload).
|
||||
|
||||
4. Produce an output descriptor (`build/asset_table.json`) suitable for:
|
||||
|
||||
* a Cartridge Builder to generate the runtime manifest
|
||||
* CI checks
|
||||
* a future IDE / GUI tooling
|
||||
|
||||
5. Provide an extensive **diagnostics chain** (doctor) with structured error codes and suggested fixes.
|
||||
|
||||
### 1.2 Non-Goals
|
||||
|
||||
* The Packer **does not**:
|
||||
|
||||
* generate `cartridge/manifest.json`
|
||||
* decide preload slots
|
||||
* copy files into `cartridge/`
|
||||
* compile PBS bytecode
|
||||
* zip cartridges
|
||||
|
||||
These responsibilities belong to a separate **Cartridge Builder**.
|
||||
|
||||
---
|
||||
|
||||
## 2. Repository / Project Layout (Golden Pipeline)
|
||||
|
||||
The Prometeu project uses the following canonical structure:
|
||||
|
||||
* `src/` — PBS scripts
|
||||
* `assets/` — mutable asset workspace (WIP allowed)
|
||||
* `build/` — generated artifacts and caches
|
||||
* `cartridge/` — final cartridge directory (produced by Cartridge Builder)
|
||||
* `prometeu.json` — project description (dependencies, version, etc.)
|
||||
* `sdk/` — SDK/tooling and libraries
|
||||
|
||||
The Packer owns the asset workspace metadata under:
|
||||
|
||||
* `assets/.prometeu/` — Packer control directory (registry, cache, quarantine)
|
||||
|
||||
---
|
||||
|
||||
## 3. Crate Topology
|
||||
|
||||
### 3.1 Crates
|
||||
|
||||
* **`prometeu-packer`**
|
||||
|
||||
* **lib**: `prometeu_packer_core`
|
||||
* **bin**: `prometeu-packer`
|
||||
|
||||
* a thin CLI wrapper delegating to `prometeu_packer_core::run()`
|
||||
|
||||
* **`prometeu` dispatcher**
|
||||
|
||||
* provides a wrapper command **`prometeup`** (or integrated subcommand)
|
||||
* delegates to `prometeu-packer` for packer operations
|
||||
|
||||
### 3.2 Design Principle
|
||||
|
||||
Treat the Packer like the compiler: core library + CLI wrapper.
|
||||
|
||||
* The core library enables future integrations (IDE, GUI, watch mode) without shelling out.
|
||||
* CLI is a stable interface for users and CI.
|
||||
|
||||
---
|
||||
|
||||
## 4. Mental Model: A “Git-like” Asset Workspace
|
||||
|
||||
The Packer treats `assets/` like a **dirty working tree**.
|
||||
|
||||
* `assets/` can contain *anything*.
|
||||
* Only the assets registered in the Packer registry are considered part of the build.
|
||||
|
||||
This is analogous to Git:
|
||||
|
||||
* working tree (chaos) vs index (truth)
|
||||
|
||||
The **source of truth** for “what counts” is the registry:
|
||||
|
||||
* `assets/.prometeu/index.json`
|
||||
|
||||
---
|
||||
|
||||
## 5. Core Concepts
|
||||
|
||||
### 5.1 Managed Asset
|
||||
|
||||
A **managed asset** is an entry in `assets/.prometeu/index.json` pointing to an **asset root directory** that contains an anchor file:
|
||||
|
||||
* `asset.json` (the asset specification)
|
||||
|
||||
Everything else is free-form.
|
||||
|
||||
### 5.2 Asset Identity
|
||||
|
||||
Each asset has stable identity:
|
||||
|
||||
* `asset_id: u32` — stable within the project (used by runtime/tooling)
|
||||
* `asset_uuid: string` — globally unique stable identifier (useful for IDE and future migrations)
|
||||
|
||||
Names and paths may change, but identity remains.
|
||||
|
||||
### 5.3 Asset Types (Bank Targets)
|
||||
|
||||
Assets ultimately target a **bank type** in the runtime:
|
||||
|
||||
* `TILES`
|
||||
* `SOUNDS`
|
||||
* (future) `SPRITESHEET`, `MAP`, `FONT`, `RAW_BLOB`, etc.
|
||||
|
||||
The Packer does **not** define bank memory semantics. It defines the *ROM payload* and its metadata.
|
||||
|
||||
### 5.4 Raw vs Virtual Assets
|
||||
|
||||
* **Raw assets**: ROM payload equals the source bytes.
|
||||
* **Virtual assets**: ROM payload is derived from input(s) via deterministic build steps.
|
||||
|
||||
Examples:
|
||||
|
||||
* PNG + palette files → `TILES` payload (indexed pixels + packed palettes)
|
||||
* WAV → PCM16LE payload
|
||||
* Multiple PNGs → atlas spritesheet
|
||||
|
||||
---
|
||||
|
||||
## 6. Directory Structure and Control Files
|
||||
|
||||
### 6.1 Workspace
|
||||
|
||||
`assets/` is a mutable workspace:
|
||||
|
||||
* users may create nested organization trees
|
||||
* junk files are allowed
|
||||
|
||||
### 6.2 Control Directory
|
||||
|
||||
The Packer stores its truth + tools state in:
|
||||
|
||||
```
|
||||
assets/
|
||||
.prometeu/
|
||||
index.json
|
||||
cache/
|
||||
fingerprints.json
|
||||
build-cache.json
|
||||
quarantine/
|
||||
...
|
||||
```
|
||||
|
||||
* `index.json` — registry of managed assets
|
||||
* `cache/` — fingerprints and incremental build cache
|
||||
* `quarantine/` — optional area to move detected junk (only by explicit user action)
|
||||
|
||||
---
|
||||
|
||||
## 7. Asset Specification: `asset.json`
|
||||
|
||||
`asset.json` describes:
|
||||
|
||||
1. **the output ROM payload** expected by runtime
|
||||
2. **the build pipeline** (for virtual assets)
|
||||
3. **metadata** needed by runtime/builder
|
||||
|
||||
This spec is modular: **each asset format** (e.g. `TILES/indexed_v1`) has its own dedicated specification document.
|
||||
|
||||
### 7.1 Common Fields (All Assets)
|
||||
|
||||
* `schema_version`
|
||||
* `name`
|
||||
* `type` (bank type)
|
||||
* `codec` (e.g. `RAW`; future: compression)
|
||||
* `inputs` (for virtual assets)
|
||||
* `output` (format + required metadata)
|
||||
* `build` (optional pipeline configuration)
|
||||
|
||||
### 7.2 Virtual Asset Pipeline Declaration
|
||||
|
||||
Virtual assets must be declared in a way that is:
|
||||
|
||||
* deterministic
|
||||
* fully materialized (no silent inference)
|
||||
* explicit about defaults (defaults may exist, but must be written into `asset.json` or build outputs)
|
||||
|
||||
---
|
||||
|
||||
## 8. Build Artifacts Produced by the Packer
|
||||
|
||||
### 8.1 `build/assets.pa`
|
||||
|
||||
**`assets.pa`** is the ROM asset payload used by the runtime.
|
||||
|
||||
**Definition:** a contiguous binary blob where each managed asset contributes a payload region.
|
||||
|
||||
#### Key Properties
|
||||
|
||||
* Deterministic asset order (by `asset_id`)
|
||||
* Offsets are recorded in `build/asset_table.json`
|
||||
* Alignment rules (configurable by packer, default: no alignment unless required by a format)
|
||||
|
||||
**Note:** `assets.pa` is intentionally simple.
|
||||
|
||||
* No internal header is required.
|
||||
* The authoritative structure comes from the descriptor (`asset_table.json`).
|
||||
|
||||
Future versions may introduce chunk tables, but v1 keeps ROM simple.
|
||||
|
||||
### 8.2 `build/asset_table.json`
|
||||
|
||||
**`asset_table.json`** is the canonical descriptor output of the Packer.
|
||||
|
||||
It contains:
|
||||
|
||||
* `assets_pa` file info (size, hash)
|
||||
* `asset_table[]` entries describing each payload slice
|
||||
* optional diagnostics/warnings
|
||||
|
||||
#### Asset Table Entry
|
||||
|
||||
An entry describes a ROM slice and its runtime meaning:
|
||||
|
||||
* `asset_id` — stable u32
|
||||
* `asset_uuid` — stable UUID string
|
||||
* `asset_name` — stable user-facing name
|
||||
* `bank_type` — e.g. `TILES`, `SOUNDS`
|
||||
* `offset` — byte offset in `assets.pa`
|
||||
* `size` — bytes stored in ROM
|
||||
* `decoded_size` — bytes after decode (equal to `size` when `codec=RAW`)
|
||||
* `codec` — `RAW` (future: compression)
|
||||
* `metadata` — format-specific metadata needed by runtime/builder
|
||||
|
||||
Additional tooling fields:
|
||||
|
||||
* `source_root` — path to asset dir
|
||||
* `inputs` — resolved input paths
|
||||
* `source_hashes` — stable fingerprints of inputs
|
||||
|
||||
`asset_table.json` is machine-readable and designed for:
|
||||
|
||||
* cartridge builder consumption
|
||||
* IDE visualization
|
||||
* debugging
|
||||
|
||||
---
|
||||
|
||||
## 9. Determinism Rules
|
||||
|
||||
1. Asset packing order MUST be deterministic.
|
||||
|
||||
* Default: increasing `asset_id`
|
||||
|
||||
2. All derived outputs MUST be deterministic.
|
||||
|
||||
* No random seeds unless explicitly declared
|
||||
* Any seed must be written to output metadata
|
||||
|
||||
3. Default values MUST be materialized.
|
||||
|
||||
* If the packer infers something, it must be written into `asset.json` (via `--fix`) or recorded in build outputs.
|
||||
|
||||
---
|
||||
|
||||
## 10. Diagnostics and the “Sanity Guardian” Chain
|
||||
|
||||
The Packer provides structured diagnostics:
|
||||
|
||||
* `code` — stable diagnostic code
|
||||
* `severity` — `error | warning | info`
|
||||
* `path` — affected file
|
||||
* `message` — human friendly
|
||||
* `help` — extended context
|
||||
* `fixes[]` — suggested automated or manual fixes
|
||||
|
||||
### 10.1 Diagnostic Classes
|
||||
|
||||
1. **Registered Errors** (break build)
|
||||
|
||||
* registry entry missing anchor file
|
||||
* `asset.json` invalid
|
||||
* missing inputs
|
||||
* format/metadata mismatch
|
||||
|
||||
2. **Workspace Warnings** (does not break build)
|
||||
|
||||
* orphaned `asset.json` (not registered)
|
||||
* unused large files
|
||||
* duplicate inputs by hash
|
||||
|
||||
3. **Policy Hints** (optional)
|
||||
|
||||
* naming conventions
|
||||
* missing preview
|
||||
|
||||
### 10.2 `doctor` Modes
|
||||
|
||||
* `doctor` (default) — validate registry only (fast)
|
||||
* `doctor --workspace` — deep scan workspace (slow)
|
||||
|
||||
---
|
||||
|
||||
## 11. Incremental Build, Cache, and Fingerprints
|
||||
|
||||
The Packer maintains fingerprints of inputs:
|
||||
|
||||
* size
|
||||
* mtime
|
||||
* strong hash (sha256)
|
||||
|
||||
Stored in:
|
||||
|
||||
* `assets/.prometeu/cache/fingerprints.json`
|
||||
|
||||
This enables:
|
||||
|
||||
* detecting changes
|
||||
* rebuild only what changed
|
||||
* producing stable reports
|
||||
|
||||
The cache must never compromise determinism.
|
||||
|
||||
---
|
||||
|
||||
## 12. Quarantine and Garbage Collection
|
||||
|
||||
### 12.1 Quarantine
|
||||
|
||||
The Packer can optionally move suspected junk to:
|
||||
|
||||
* `assets/.prometeu/quarantine/`
|
||||
|
||||
Rules:
|
||||
|
||||
* Quarantine is **never automatic** without user consent.
|
||||
* Packer must explain exactly what will be moved.
|
||||
|
||||
### 12.2 Garbage Collection (`gc`)
|
||||
|
||||
The Packer can report unused files:
|
||||
|
||||
* files not referenced by any registered asset
|
||||
* orphaned asset dirs
|
||||
|
||||
Actions:
|
||||
|
||||
* list candidates
|
||||
* optionally move to quarantine
|
||||
* never delete without explicit user request
|
||||
|
||||
---
|
||||
|
||||
## 13. CLI Commands (Comprehensive)
|
||||
|
||||
> The CLI is a stable interface; all commands are implemented by calling `prometeu_packer_core`.
|
||||
|
||||
### 13.1 `prometeu packer init`
|
||||
|
||||
Creates the control directory and initial registry:
|
||||
|
||||
* creates `assets/.prometeu/index.json`
|
||||
* creates caches directory
|
||||
|
||||
### 13.2 `prometeu packer add <path> [--name <name>] [--type <TILES|SOUNDS|...>]`
|
||||
|
||||
Registers a new managed asset.
|
||||
|
||||
* does not require moving files
|
||||
* can create an asset root directory if desired
|
||||
* generates `asset.json` with explicit defaults
|
||||
* allocates `asset_id` and `asset_uuid`
|
||||
|
||||
Variants:
|
||||
|
||||
* `add --dir` creates a dedicated asset root dir
|
||||
* `add --in-place` anchors next to the file
|
||||
|
||||
### 13.3 `prometeu packer adopt`
|
||||
|
||||
Scans workspace for unregistered `asset.json` anchors and offers to register them.
|
||||
|
||||
* default: dry-run list
|
||||
* `--apply` registers them
|
||||
|
||||
### 13.4 `prometeu packer forget <name|id|uuid>`
|
||||
|
||||
Removes an asset from the registry without deleting files.
|
||||
|
||||
Useful for WIP and cleanup.
|
||||
|
||||
### 13.5 `prometeu packer rm <name|id|uuid> [--delete]`
|
||||
|
||||
Removes the asset from the registry.
|
||||
|
||||
* default: no deletion
|
||||
* `--delete` can remove the asset root dir (dangerous; must confirm in UI tooling, or require a force flag in CLI)
|
||||
|
||||
### 13.6 `prometeu packer list`
|
||||
|
||||
Lists managed assets:
|
||||
|
||||
* id, uuid, name
|
||||
* type
|
||||
* status (ok/error)
|
||||
|
||||
### 13.7 `prometeu packer show <name|id|uuid>`
|
||||
|
||||
Shows detailed information:
|
||||
|
||||
* resolved inputs
|
||||
* metadata
|
||||
* fingerprints
|
||||
* last build summary
|
||||
|
||||
### 13.8 `prometeu packer doctor [--workspace] [--strict] [--fix]`
|
||||
|
||||
Runs diagnostics:
|
||||
|
||||
* `--workspace` deep scan
|
||||
* `--strict` warnings become errors
|
||||
* `--fix` applies safe automatic fixes (materialize defaults, normalize paths)
|
||||
|
||||
### 13.9 `prometeu packer build [--out build/assets.pa] [--table build/asset_table.json]`
|
||||
|
||||
Builds:
|
||||
|
||||
* `build/assets.pa`
|
||||
* `build/asset_table.json`
|
||||
|
||||
Key behaviors:
|
||||
|
||||
* validates registry before packing
|
||||
* packs assets deterministically
|
||||
* for virtual assets, runs build pipelines
|
||||
* records all offsets and metadata
|
||||
|
||||
### 13.10 `prometeu packer watch`
|
||||
|
||||
Watches registered inputs and registry changes.
|
||||
|
||||
* emits events (future)
|
||||
* rebuilds incrementally
|
||||
|
||||
`watch` is optional in v0 but recommended.
|
||||
|
||||
### 13.11 `prometeu packer gc [--workspace] [--quarantine]`
|
||||
|
||||
Reports unused files.
|
||||
|
||||
* default: report only
|
||||
* `--quarantine` moves candidates to quarantine
|
||||
|
||||
### 13.12 `prometeu packer quarantine <path> [--restore]`
|
||||
|
||||
Moves or restores files into/from quarantine.
|
||||
|
||||
---
|
||||
|
||||
## 14. Virtual Assets (Deep Explanation)
|
||||
|
||||
Virtual assets are a major capability.
|
||||
|
||||
### 14.1 Why Virtual Assets
|
||||
|
||||
* Most runtime formats should be derived from human-friendly authoring formats.
|
||||
* Example:
|
||||
|
||||
* author uses `source.png` and palette files
|
||||
* runtime expects indexed pixels + packed RGB565 palettes
|
||||
|
||||
### 14.2 Virtual Asset Contract
|
||||
|
||||
* Inputs are explicit.
|
||||
* Build steps are deterministic.
|
||||
* Outputs match a well-defined runtime payload format.
|
||||
|
||||
### 14.3 Examples of Future Virtual Assets
|
||||
|
||||
* `TILES/indexed_v1`: PNG + palette files → indexed pixels + packed palettes
|
||||
* `SOUNDS/pcm16le_v1`: WAV → PCM16LE
|
||||
* `SPRITESHEET/atlas_v1`: multiple PNG frames → atlas + metadata
|
||||
|
||||
Each `output.format` must have its own dedicated spec.
|
||||
|
||||
---
|
||||
|
||||
## 15. Integration with Cartridge Builder
|
||||
|
||||
The Cartridge Builder should:
|
||||
|
||||
1. Compile PBS into bytecode (e.g. `program.pbc` / `program.pbx`)
|
||||
2. Call `prometeu packer build`
|
||||
3. Consume `build/asset_table.json` and produce `cartridge/manifest.json`
|
||||
4. Copy artifacts into `cartridge/`
|
||||
5. Zip the cartridge into a distributable format (`.crt` / `.rom` / `.pro`)
|
||||
|
||||
The packer never touches `cartridge/`.
|
||||
|
||||
---
|
||||
|
||||
## 16. Compatibility and Versioning
|
||||
|
||||
* `assets/.prometeu/index.json` has `schema_version`
|
||||
* `asset.json` has `schema_version`
|
||||
* `build/asset_table.json` has `schema_version`
|
||||
|
||||
The Packer must be able to migrate older schema versions or emit actionable diagnostics.
|
||||
|
||||
---
|
||||
|
||||
## 17. Security and Trust Model
|
||||
|
||||
* The Packer is offline tooling.
|
||||
* It must never execute untrusted scripts.
|
||||
* It should treat external inputs as untrusted data.
|
||||
|
||||
---
|
||||
|
||||
## 18. Implementation Notes (Non-Normative)
|
||||
|
||||
* Rust implementation with a core crate + CLI wrapper.
|
||||
* Prefer structured JSON serde models.
|
||||
* Use stable diagnostic codes.
|
||||
* Keep the build deterministic.
|
||||
|
||||
---
|
||||
|
||||
## Appendix A — Glossary
|
||||
|
||||
* **ROM (`assets.pa`)**: packed asset payload used by runtime
|
||||
* **Descriptor (`asset_table.json`)**: mapping from logical assets to ROM slices
|
||||
* **Managed asset**: registered asset with stable identity and anchor file
|
||||
* **Virtual asset**: derived asset built from multiple inputs
|
||||
* **Quarantine**: safe area for suspected junk
|
||||
* **Doctor**: diagnostic command to keep sanity
|
||||
@ -1,6 +1,26 @@
|
||||
Prometeu Runtime — Architecture (Baseline)
|
||||
Prometeu VM Runtime — Canonical Architecture
|
||||
|
||||
This document is the concise, authoritative description of the current Prometeu VM baseline after the architectural reset. It reflects the implementation as it exists today — no legacy, no transitional wording.
|
||||
Status: canonical
|
||||
|
||||
This document is the authoritative architectural reference for the Prometeu VM runtime. It reflects the implementation as it exists today and defines the invariants that govern architectural changes in the VM layer.
|
||||
|
||||
Scope boundary:
|
||||
|
||||
- PROMETEU itself is a fantasy handheld / fantasy console with a broader machine model, firmware model, cartridge model, and virtual hardware surface.
|
||||
- This document does not define the whole PROMETEU machine.
|
||||
- This document defines the VM/runtime subsystem that executes bytecode inside that machine.
|
||||
- For broader machine-level framing, see [`../specs/README.md`](../specs/README.md).
|
||||
|
||||
Document roles:
|
||||
|
||||
- This file is normative for VM/runtime architecture.
|
||||
- Detailed domain specifications may live under `docs/runtime/specs/`, but they must not contradict this document where VM/runtime invariants are concerned.
|
||||
- Roadmaps, agendas, and PR proposals may discuss future changes, but they are not authoritative until this document is updated.
|
||||
- The machine-wide fantasy console framing lives in the runtime specs manual and related domain specs; those documents are complementary, not competing VM architecture sources.
|
||||
|
||||
Maintenance rule:
|
||||
|
||||
- Any PR that changes VM/runtime architectural invariants must update this document in the same change.
|
||||
|
||||
|
||||
1. Overview
|
||||
@ -161,4 +181,4 @@ The verifier statically checks bytecode for structural safety and stack‑shape
|
||||
- Keep the public surface minimal and metadata‑driven (e.g., syscalls via `SyscallMeta`).
|
||||
- Do not assume implicit safepoints; schedule and GC only at `FRAME_SYNC`.
|
||||
- When adding new opcodes or object kinds, extend the verifier and GC traversal accordingly (children enumeration, environment scanning, root sets).
|
||||
- This document is the canonical reference; update it alongside any architectural change.
|
||||
- Update this document alongside any architectural change that affects runtime invariants.
|
||||
@ -1,6 +1,19 @@
|
||||
### Prometeu Bytecode — Core ISA (Minimal, Bytecode‑Only)
|
||||
### Prometeu Bytecode — Core ISA
|
||||
|
||||
This document defines the minimal, stable Core ISA surface for the Prometeu Virtual Machine at the bytecode level. It specifies instruction encoding, the stack evaluation model, and the instruction set currently available. Higher‑level constructs (closures, coroutines) are intentionally out of scope at this stage.
|
||||
Status: bytecode-level normative
|
||||
|
||||
This document defines the stable Core ISA surface for the Prometeu Virtual Machine at the bytecode level. It specifies instruction encoding, the stack evaluation model, and the instruction set currently available in the canonical opcode surface used by encoder, decoder, disassembler, assembler, verifier, and VM execution.
|
||||
|
||||
Machine boundary:
|
||||
|
||||
- PROMETEU is not "just the VM". It is the broader fantasy console/handheld machine.
|
||||
- This document covers only the bytecode ISA of the VM subsystem embedded in that machine.
|
||||
|
||||
Authority rule:
|
||||
|
||||
- This document is normative for bytecode-level encoding and opcode surface.
|
||||
- Runtime-wide invariants still live in [`../../ARCHITECTURE.md`](../../ARCHITECTURE.md).
|
||||
- If a bytecode-level rule here conflicts with runtime architecture, the conflict must be resolved explicitly in both documents; neither should drift silently.
|
||||
|
||||
#### Encoding Rules
|
||||
|
||||
@ -51,14 +64,21 @@ This document defines the minimal, stable Core ISA surface for the Prometeu Virt
|
||||
- Functions and scopes:
|
||||
- `CALL u32` — call by function index; argument/result arity per function metadata.
|
||||
- `RET` — return from current function (block terminator).
|
||||
- `PUSH_SCOPE`, `POP_SCOPE` — begin/end lexical scope.
|
||||
- `MAKE_CLOSURE u32,u32` — create closure from `(fn_id, capture_count)`.
|
||||
- `CALL_CLOSURE u32` — invoke closure with `arg_count` user arguments.
|
||||
|
||||
- Concurrency:
|
||||
- `SPAWN u32,u32` — create coroutine for `(fn_id, arg_count)`.
|
||||
- `YIELD` — request cooperative yield at the next safepoint.
|
||||
- `SLEEP u32` — request suspension for a logical tick duration.
|
||||
|
||||
- System/Timing:
|
||||
- `HOSTCALL u32` — PBX pre-load host binding call by `SYSC` table index; the loader must resolve and rewrite it before verification or execution.
|
||||
- `SYSCALL u32` — final numeric platform call in the executable image; raw `SYSCALL` in PBX pre-load artifacts is rejected by the loader.
|
||||
- `INTRINSIC u32` — final numeric VM-owned intrinsic call.
|
||||
- `FRAME_SYNC` — yield until the next frame boundary (e.g., vblank); explicit safepoint.
|
||||
|
||||
For exact immediates and stack effects, see `CoreOpCode::spec()` which is the single source of truth used by the decoder, disassembler, and (later) verifier.
|
||||
For exact immediates and stack effects, see `CoreOpCode::spec()` which is the single source of truth used by the decoder, disassembler, and verifier.
|
||||
|
||||
#### Canonical Decoder Contract
|
||||
|
||||
@ -73,12 +93,18 @@ For exact immediates and stack effects, see `CoreOpCode::spec()` which is the si
|
||||
- `CoreOpcodeSpec` and `CoreOpCodeSpecExt` — spec with `imm_bytes`, stack effects, and flags.
|
||||
- Consumers (encoder/decoder/disasm/verifier) should import from this module to avoid depending on internal layout.
|
||||
|
||||
#### Scope Notes
|
||||
|
||||
- "Core ISA" in the current repository means the canonical opcode surface implemented by the runtime today.
|
||||
- It includes closures, coroutines, `HOSTCALL` patching semantics, `INTRINSIC`, and `FRAME_SYNC`.
|
||||
- It does not, by itself, define higher-level runtime policy such as crash taxonomy, firmware behavior, cartridge lifecycle, or host service organization. Those belong to the canonical runtime architecture and related specs.
|
||||
|
||||
#### FRAME_SYNC — Semantics and Placement (Bytecode Level)
|
||||
|
||||
- Semantics:
|
||||
- `FRAME_SYNC` is a zero-operand instruction and does not modify the operand stack.
|
||||
- It marks a VM safepoint for GC and the cooperative scheduler. In `CoreOpcodeSpec` this is exposed as `spec.is_safepoint == true`.
|
||||
- On execution, the VM may suspend the current fiber/coroutine until the next frame boundary (e.g., vsync) and/or perform GC. After resuming, execution continues at the next instruction.
|
||||
- On execution, the VM may suspend the current coroutine until the next frame boundary and/or perform GC. After resuming, execution continues at the next instruction.
|
||||
|
||||
- Placement rules (representable and checkable):
|
||||
- `FRAME_SYNC` may appear anywhere inside a function body where normal instructions can appear. It is NOT a block terminator (`spec.is_terminator == false`).
|
||||
Loading…
x
Reference in New Issue
Block a user