4.7 KiB
PBS - Game Profile Syntax Specification v1 (Draft)
Status: Draft (Normative for Game Profile parser/lowering work)
Scope: Syntax delta over PBS - Language Syntax Specification v0.md
Language: English
1. Purpose
This document defines the parser-facing syntax additions for the PBS Game Profile.
Goals:
- keep beginner usage fluid for 2D game construction,
- preserve deterministic/frame-oriented execution,
- remain compatible with closed VM + bytecode/runtime authority,
- avoid introducing hidden runtime behavior in language syntax.
2. Authority and precedence
Normative precedence order:
- Runtime authority (
docs/specs/hardware/topics/chapter-2.md,chapter-3.md,chapter-9.md,chapter-12.md,chapter-16.md) - Bytecode authority (
docs/specs/bytecode/ISA_CORE.md) PBS - Language Syntax Specification v0.md- This document
- Legacy references (
docs/specs/pbs_old/*)
If a rule here conflicts with higher authority, the rule is invalid.
3. Profile activation
Game Profile syntax is enabled by toolchain profile selection (game profile).
Without this profile, v0 Core syntax rules remain in effect.
4. Lexical delta (keywords)
4.1 Newly active keywords in Game Profile
hostwhilebreakcontinue
4.2 Still reserved in this draft
alloc,borrow,mutate,peek,take,weakspawn,yield,sleephandle
This draft does not activate heap-specialized syntax or coroutine syntax.
5. Top-level grammar delta
Game Profile extends top-level declarations with host function declarations.
TopDecl ::= TypeDecl | ServiceDecl | FunctionDecl | HostFnDecl
HostFnDecl ::= 'host' 'fn' Identifier ParamList ReturnType? ';'
Rules:
host fndeclares a host-provided call surface only (no body).- Calling
host fnlowers to syscall-linked call sites. - Host functions are callable entities, never first-class function values.
- Service-shaped facades over host functions belong to stdlib design, not to host syntax.
Examples:
host fn input_state(): (int, int, int);
host fn gfx_present();
6. Statement grammar delta
Game Profile adds imperative loop/control and assignment statements.
Stmt ::= LetStmt
| AssignStmt
| ReturnStmt
| IfStmt
| ForStmt
| WhileStmt
| BreakStmt
| ContinueStmt
| ExprStmt
WhileStmt ::= 'while' Expr Block
BreakStmt ::= 'break' ';'
ContinueStmt ::= 'continue' ';'
AssignStmt ::= LValue AssignOp Expr ';'
AssignOp ::= '=' | '+=' | '-=' | '*=' | '/=' | '%='
LValue ::= Identifier LValueSuffix*
LValueSuffix ::= '.' Identifier | '[' Expr ']'
Rules:
breakandcontinueare valid only insidefor/while.- Assignment is a statement, not an expression.
LValuecannot contain function calls.- Compound assignments are semantic sugar over read/compute/write.
7. Expression grammar delta
Game Profile adds postfix member/index access chains for fluent gameplay code.
UnaryExpr ::= ('!' | '-') UnaryExpr | PostfixExpr
PostfixExpr ::= PrimaryExpr PostfixSuffix*
PostfixSuffix ::= CallSuffix | MemberSuffix | IndexSuffix
CallSuffix ::= '(' ArgList? ')'
MemberSuffix ::= '.' Identifier
IndexSuffix ::= '[' Expr ']'
This replaces the v0 Core CallExpr chain and enables expressions such as:
gfx_present();
player.transform.position.x;
tiles[i].id;
8. Determinism and lowering constraints
Game Profile syntax additions MUST preserve:
- deterministic control flow,
- verifier-friendly stack effects,
- explicit host call boundaries.
Lowering requirements:
hostcall sites map to resolved syscall identities.while/break/continuelower to structured jumps compatible with verifier rules.- Member/index read-write operations must lower to deterministic, type-checked access paths.
9. Diagnostics requirements (parser + early semantic phase)
Implementations MUST produce deterministic diagnostics for:
break/continueoutside loops,- invalid
LValuetargets, - duplicate host signatures in the same scope,
- unresolved host declarations at link/resolve stage,
- use of still-reserved keywords as active syntax.
10. Minimal canonical examples
10.1 Frame loop style with while
host fn gfx_present();
fn run(): int {
let running = true;
while running {
update_world();
render_world();
gfx_present();
}
return 0;
}
10.2 Assignment and member/index access
fn integrate(p: Vec2, v: Vec2): Vec2 {
let out = p;
out.x += v.x;
out.y += v.y;
return out;
}
11. Non-goals of this syntax draft
- Defining pool/arena memory syntax.
- Enabling
alloc/borrow/mutatein surface syntax. - Defining coroutine syntax (
spawn/yield/sleep) before bytecode/runtime profile activation.