5.3 KiB
PR-003 Runtime First Builtins: Color, Vec2, Pixel
Goal
Implement the first concrete builtin types, constants, and intrinsic behaviors so the frontend can target a stable MVP builtin line.
This PR should be the first runtime feature slice that a PBS frontend can map to directly.
Why
After PR-001 and PR-002, the runtime has the machinery but not the domain set. This PR makes the model real by installing the first builtin registry entries and execution implementations.
The initial scope should match the current agenda and spec direction:
- scalar builtin
color - aggregate builtin
vec2 - aggregate builtin
pixel - intrinsic methods for
vec2 - builtin constant for
vec2.zero
Scope
Add runtime registry entries and implementations for:
- builtin type
color - builtin type
vec2 - builtin type
pixel - builtin constant
("vec2", "zero", 1) - intrinsic
("vec2", "dot", 1) - intrinsic
("vec2", "length", 1)
("vec2", "distance", 1) may be included if the numeric contract is already
clear enough for portable behavior.
If not, leave it for a follow-up PR.
Builtin Type Contracts
1. color
Canonical identity:
("color", 1)
Expected properties:
- scalar builtin
- flat slot width
1 - runtime semantic distinctness from plain
int
Suggested field model:
rawcarrier field if the runtime benefits from explicit internal naming
2. vec2
Canonical identity:
("vec2", 1)
Expected properties:
- aggregate builtin
- flattened layout
[float, float] - field
xat slot0 - field
yat slot1 - flat slot width
2
3. pixel
Canonical identity:
("pixel", 1)
Expected properties:
- aggregate builtin
- semantic layout
[int, int, color] - flattened width
3 - field
xat slot0 - field
yat slot1 - field
colorat slot2
Builtin Constant Contract
vec2.zero
Canonical identity:
("vec2", "zero", 1)
Expected materialized value:
[0.0, 0.0]
This constant must be runtime-owned and materialized without touching the host.
Intrinsic Contracts
1. vec2.dot
Canonical identity:
("vec2", "dot", 1)
Stack contract:
args: [float, float, float, float]
ret: [float]
Semantic behavior:
(x1 * x2) + (y1 * y2)
2. vec2.length
Canonical identity:
("vec2", "length", 1)
Stack contract:
args: [float, float]
ret: [float]
Semantic behavior:
sqrt((x * x) + (y * y))
3. Optional: vec2.distance
Canonical identity:
("vec2", "distance", 1)
Stack contract:
args: [float, float, float, float]
ret: [float]
Semantic behavior:
sqrt(((x1 - x2)^2) + ((y1 - y2)^2))
Only include this if the runtime already has a clear portable numeric contract
for sqrt.
Representation Guidance
color
Choose one of:
- dedicated scalar runtime variant with builtin nominal tag
- 1-slot scalar carrier plus explicit builtin registry identity
The critical rule is:
colormust remain semantically a builtin color type,- even if its carrier width matches
int.
vec2 and pixel
Do not allocate heap objects for these in the MVP.
Represent them as:
- canonical stack-shaped flattened values,
- with runtime metadata describing field offsets and nominal builtin identity.
Numeric Contract Note
vec2.dot is straightforward and should land in this PR.
vec2.length and vec2.distance depend on the runtime's floating-point
portability story. If that story is not already stable, implement:
vec2.dotvec2.zero- builtin type descriptors for
color,vec2,pixel
and either:
- gate
length/distancebehind the current platform float rules, - or defer them into a follow-up PR.
Acceptance Criteria
- Runtime registry contains builtin entries for
color,vec2, andpixel. - Runtime registry contains builtin constant entry for
("vec2", "zero", 1). - Runtime registry contains intrinsic entries for at least
vec2.dotandvec2.length. vec2layout is width2andpixellayout is width3.pixelcomposescolorthrough builtin layout metadata rather than by special-case host code.- Executing
vec2.dotandvec2.lengththroughINTRINSIC <id>produces correct runtime results. - No part of the implementation routes through
SYSC,HOSTCALL, orSYSCALL.
Test Cases
Builtin metadata
colorwidth is1vec2width is2pixelwidth is3
Constant materialization
- materializing
("vec2", "zero", 1)yields[0.0, 0.0]
Intrinsic execution
dot([1, 2], [3, 4]) == 11length([3, 4]) == 5
Composition
pixel(x=1, y=2, color=<red>)uses builtin metadata width3pixel.colorpoints at slot2
Frontend Alignment
This PR should be implemented so the following frontend surfaces map naturally:
[BuiltinType(name="vec2", version=1)]
declare builtin type Vec2(
[Slot(0)] pub x: float,
[Slot(1)] pub y: float,
) {
[IntrinsicCall(name="dot")]
fn dot(other: Vec2) -> float;
[IntrinsicCall(name="length")]
fn length() -> float;
}
[BuiltinConst(target="vec2", name="zero", version=1)]
declare const ZERO: Vec2;
The runtime should not care whether the source-visible type name is Vec2,
vec2, or something else.
It should care only about canonical identities and flattened layout.