187 lines
4.7 KiB
Markdown
187 lines
4.7 KiB
Markdown
# 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:
|
|
|
|
1. Runtime authority (`docs/specs/hardware/topics/chapter-2.md`, `chapter-3.md`, `chapter-9.md`, `chapter-12.md`, `chapter-16.md`)
|
|
2. Bytecode authority (`docs/specs/bytecode/ISA_CORE.md`)
|
|
3. `PBS - Language Syntax Specification v0.md`
|
|
4. This document
|
|
5. 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
|
|
|
|
- `host`
|
|
- `while`
|
|
- `break`
|
|
- `continue`
|
|
|
|
### 4.2 Still reserved in this draft
|
|
|
|
- `alloc`, `borrow`, `mutate`, `peek`, `take`, `weak`
|
|
- `spawn`, `yield`, `sleep`
|
|
- `handle`
|
|
|
|
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.
|
|
|
|
```ebnf
|
|
TopDecl ::= TypeDecl | ServiceDecl | FunctionDecl | HostFnDecl
|
|
|
|
HostFnDecl ::= 'host' 'fn' Identifier ParamList ReturnType? ';'
|
|
```
|
|
|
|
Rules:
|
|
|
|
- `host fn` declares a host-provided call surface only (no body).
|
|
- Calling `host fn` lowers 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:
|
|
|
|
```pbs
|
|
host fn input_state(): (int, int, int);
|
|
host fn gfx_present();
|
|
```
|
|
|
|
## 6. Statement grammar delta
|
|
|
|
Game Profile adds imperative loop/control and assignment statements.
|
|
|
|
```ebnf
|
|
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:
|
|
|
|
- `break` and `continue` are valid only inside `for`/`while`.
|
|
- Assignment is a statement, not an expression.
|
|
- `LValue` cannot 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.
|
|
|
|
```ebnf
|
|
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:
|
|
|
|
```pbs
|
|
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:
|
|
|
|
- `host` call sites map to resolved syscall identities.
|
|
- `while`/`break`/`continue` lower 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`/`continue` outside loops,
|
|
- invalid `LValue` targets,
|
|
- 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
|
|
|
|
```pbs
|
|
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
|
|
|
|
```pbs
|
|
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/mutate` in surface syntax.
|
|
- Defining coroutine syntax (`spawn/yield/sleep`) before bytecode/runtime profile activation.
|