275 lines
8.8 KiB
Markdown
275 lines
8.8 KiB
Markdown
# PBS Stdlib Environment Packaging and Loading Specification
|
|
|
|
Status: Draft v1 (Temporary)
|
|
Applies to: Studio PBS frontend stdlib packaging, stdlib environment discovery, reserved stdlib project spaces, and compiler-side stdlib loading abstractions
|
|
|
|
## 1. Purpose
|
|
|
|
This document defines a practical packaging and loading model for the PBS stdlib environment inside the Studio compiler frontend.
|
|
|
|
Its purpose is to make the stdlib:
|
|
|
|
- available to the compiler without hardcoded symbol tables,
|
|
- structured as real PBS interface modules,
|
|
- versioned by stdlib major line,
|
|
- and loadable through explicit compiler abstractions.
|
|
|
|
This document complements the normative language-level model in:
|
|
|
|
- [5. Manifest, Stdlib, and SDK Resolution Specification.md](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/docs/specs/pbs/5.%20Manifest,%20Stdlib,%20and%20SDK%20Resolution%20Specification.md)
|
|
|
|
## 2. Scope
|
|
|
|
This document defines:
|
|
|
|
- the recommended Studio packaging layout for stdlib interface modules,
|
|
- the logical mapping between stdlib line, reserved project space, and module path,
|
|
- the minimum compiler abstractions required to load stdlib modules,
|
|
- the relationship between `resources` packaging and the logical stdlib environment.
|
|
|
|
This document does not define:
|
|
|
|
- runtime loader behavior,
|
|
- PBX emission,
|
|
- registry publication of stdlib packs,
|
|
- final external distribution of stdlib outside Studio.
|
|
|
|
## 3. Core Model
|
|
|
|
The compiler must load stdlib modules as real interface modules, not as hardcoded built-ins.
|
|
|
|
Rules:
|
|
|
|
- the stdlib is selected by the root project's `stdlib` major,
|
|
- each stdlib line defines one stdlib environment,
|
|
- a stdlib environment exposes reserved project spaces such as `@sdk:*` and `@core:*`,
|
|
- each reserved project space contains one or more modules,
|
|
- each module is represented as PBS source plus `mod.barrel`.
|
|
|
|
## 4. Recommended Studio Packaging Layout
|
|
|
|
The recommended Studio layout is:
|
|
|
|
```text
|
|
prometeu-compiler/frontends/prometeu-frontend-pbs/
|
|
src/main/resources/
|
|
stdlib/
|
|
1/
|
|
sdk/
|
|
gfx/
|
|
main.pbs
|
|
mod.barrel
|
|
asset/
|
|
main.pbs
|
|
mod.barrel
|
|
audio/
|
|
main.pbs
|
|
mod.barrel
|
|
core/
|
|
math/
|
|
main.pbs
|
|
mod.barrel
|
|
```
|
|
|
|
Interpretation:
|
|
|
|
- `stdlib/1` selects stdlib major line `1`,
|
|
- `sdk` and `core` are reserved project spaces,
|
|
- `gfx`, `audio`, `math` are module paths within those reserved spaces,
|
|
- `main.pbs` and `mod.barrel` form the interface module contents.
|
|
|
|
## 5. Logical Mapping
|
|
|
|
The compiler must treat the physical layout as a logical stdlib environment.
|
|
|
|
Required mapping:
|
|
|
|
- `stdlib/<N>/sdk/gfx` -> `@sdk:gfx`
|
|
- `stdlib/<N>/sdk/asset` -> `@sdk:asset`
|
|
- `stdlib/<N>/sdk/audio` -> `@sdk:audio`
|
|
- `stdlib/<N>/core/math` -> `@core:math`
|
|
- `stdlib/<N>/core/math/vector` -> `@core:math/vector`
|
|
|
|
Rules:
|
|
|
|
- physical storage is an implementation detail,
|
|
- logical module identity is authoritative,
|
|
- callers of the resolver should work with logical addresses such as `@sdk:gfx`, not resource paths.
|
|
|
|
## 6. Module File Convention
|
|
|
|
For the Studio implementation, each stdlib module should follow the same structural convention as ordinary PBS modules:
|
|
|
|
- one or more `.pbs` files,
|
|
- exactly one `mod.barrel`.
|
|
|
|
Recommended minimum convention:
|
|
|
|
- `main.pbs`
|
|
- `mod.barrel`
|
|
|
|
Rules:
|
|
|
|
- `main.pbs` is a convention, not a language-level requirement,
|
|
- the module remains an ordinary PBS module from the parser's perspective,
|
|
- it is interpreted under interface-module semantics because it lives in a reserved stdlib project space.
|
|
|
|
## 7. Required Compiler Abstractions
|
|
|
|
The compiler should not reach directly into `resources` paths throughout the frontend.
|
|
|
|
At minimum, the PBS frontend should define abstractions equivalent to:
|
|
|
|
### 7.1 `StdlibEnvironment`
|
|
|
|
Responsibility:
|
|
|
|
- represent the selected stdlib line for one compilation,
|
|
- expose reserved project spaces,
|
|
- provide access to interface modules by logical module address.
|
|
|
|
Minimum operations:
|
|
|
|
- select stdlib major line,
|
|
- answer whether a reserved project space exists,
|
|
- open a module by logical address.
|
|
|
|
### 7.2 `StdlibModuleResolver`
|
|
|
|
Responsibility:
|
|
|
|
- resolve logical imports in reserved project spaces,
|
|
- map `@sdk:*` and `@core:*` imports to concrete interface module sources,
|
|
- reject unknown stdlib modules deterministically.
|
|
|
|
Minimum operations:
|
|
|
|
- `resolve(@sdk:gfx)`
|
|
- `resolve(@core:math/vector)`
|
|
|
|
### 7.3 `StdlibModuleSource`
|
|
|
|
Responsibility:
|
|
|
|
- represent the source files of one stdlib module,
|
|
- provide access to the module's `.pbs` files and `mod.barrel`,
|
|
- hide whether content came from disk, `resources`, or another source.
|
|
|
|
Minimum contents:
|
|
|
|
- module address
|
|
- list of `.pbs` source texts or streams
|
|
- `mod.barrel` source text or stream
|
|
|
|
### 7.4 `InterfaceModuleLoader`
|
|
|
|
Responsibility:
|
|
|
|
- parse a stdlib module source using the normal PBS parser,
|
|
- validate it in interface-module mode,
|
|
- return compiler-facing symbols and metadata.
|
|
|
|
Minimum outputs:
|
|
|
|
- exported symbols
|
|
- declared types
|
|
- host owners
|
|
- host method signatures
|
|
- reserved attribute metadata such as `[Host(...)]`
|
|
|
|
## 8. Loading Algorithm
|
|
|
|
The recommended Studio compiler flow is:
|
|
|
|
1. read the root `prometeu.json`,
|
|
2. parse and normalize `stdlib`,
|
|
3. construct `StdlibEnvironment` for that stdlib major,
|
|
4. create a `StdlibModuleResolver`,
|
|
5. when an import targets a reserved project space, resolve it through the stdlib resolver,
|
|
6. obtain a `StdlibModuleSource`,
|
|
7. parse the module with the standard PBS parser,
|
|
8. validate it under interface-module semantic rules,
|
|
9. cache the resulting interface module graph for the duration of the compilation.
|
|
|
|
Rules:
|
|
|
|
- reserved stdlib modules must not be handled through ordinary dependency resolution,
|
|
- ordinary dependency modules must not be handled through the stdlib resolver,
|
|
- a failed stdlib import is a deterministic compile-time error.
|
|
|
|
## 9. Attributes and Interface Metadata
|
|
|
|
Stdlib interface modules may contain reserved compile-time attributes such as:
|
|
|
|
```pbs
|
|
declare host Gfx {
|
|
[Host(module = "gfx", name = "draw_pixel", version = 1)]
|
|
fn draw_pixel(x: int, y: int, c: color);
|
|
}
|
|
```
|
|
|
|
or:
|
|
|
|
```pbs
|
|
declare host LowAssets {
|
|
[Host(module = "asset", name = "load", version = 1)]
|
|
[Capability(name = "asset")]
|
|
[AssetLowering(param = 0)]
|
|
fn load(addressable: Addressable, slot: int) -> (status: int, loading_handle: int);
|
|
}
|
|
```
|
|
|
|
Rules:
|
|
|
|
- the parser reads the attribute as part of the interface module source,
|
|
- the interface-module loader validates that the attribute is legal in that position,
|
|
- the compiler stores the extracted metadata in its interface graph,
|
|
- the raw attribute surface is not treated as a runtime object,
|
|
- later lowering stages may consume the extracted metadata to produce PBX host-binding declarations.
|
|
- stdlib line `1` MUST expose the low-level asset interface module at `@sdk:asset`,
|
|
- that module MUST declare `LowAssets`,
|
|
- that module MUST use runtime module `asset` and capability `asset`,
|
|
- that module MUST use the runtime-aligned signatures and reserved lowering metadata:
|
|
- `load(addressable: Addressable, slot: int) -> (status: int, loading_handle: int)` together with `[AssetLowering(param = 0)]`
|
|
- `status(loading_handle: int) -> int`
|
|
- `commit(loading_handle: int) -> int`
|
|
- `cancel(loading_handle: int) -> int`
|
|
|
|
## 10. Resources as an Implementation Strategy
|
|
|
|
For the Studio PBS frontend, packaging stdlib interface modules in frontend `resources` is a valid implementation strategy.
|
|
|
|
Rules:
|
|
|
|
- `resources` packaging is implementation-level, not language-level,
|
|
- the compiler should still access stdlib modules through `StdlibEnvironment` and related abstractions,
|
|
- code outside the stdlib loader should not depend on resource path layout directly.
|
|
|
|
Rationale:
|
|
|
|
- `resources` gives a simple bootstrap path,
|
|
- stdlib evolves as real source artifacts,
|
|
- the frontend avoids hardcoded built-ins,
|
|
- the implementation remains replaceable later.
|
|
|
|
## 11. Caching and Reuse
|
|
|
|
The compiler may cache stdlib interface modules within one compilation or across compilations.
|
|
|
|
Rules:
|
|
|
|
- caching must not change observable semantics,
|
|
- cache keys should include at least the stdlib major line and logical module address,
|
|
- cached modules must preserve the same parsed declarations and attribute metadata as uncached loads.
|
|
|
|
## 12. Current Decision Summary
|
|
|
|
The current Studio direction is:
|
|
|
|
1. the stdlib environment is loaded as real PBS interface modules,
|
|
2. the initial implementation may live under frontend `resources`,
|
|
3. the logical model remains `stdlib line -> reserved project space -> module path`,
|
|
4. the compiler should use explicit abstractions such as `StdlibEnvironment` and `StdlibModuleResolver`,
|
|
5. stdlib interface modules are parsed with the normal PBS parser and validated in interface-module mode,
|
|
6. reserved attributes such as `[Host(...)]` are extracted as compile-time metadata for later lowering.
|