add struct with visibility

This commit is contained in:
bQUARKz 2026-03-02 17:04:42 +00:00
parent feb82c5bfa
commit 267e28fab9
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
3 changed files with 35 additions and 13 deletions

View File

@ -16,9 +16,9 @@ The question is whether the current contract is already stable enough to unblock
Decision: sufficient for the next phase.
The current Host ABI contract is explicit enough to unblock the next stage even if the specification remains marked `Temporary` for now.
The current Host ABI contract is explicit enough to unblock the next stage.
`Temporary` should be interpreted here as "final binary-format and integration details may still be hardened", not as "core contract still missing".
the final binary-format and integration details may still be hardened, not as "core contract still missing".
## 3. Why This Is Sufficient

View File

@ -78,6 +78,7 @@ Active keywords in `.pbs`:
- `import`, `from`, `as`
- `service`, `host`, `fn`, `apply`, `bind`, `new`, `implements`, `using`, `ctor`
- `declare`, `struct`, `contract`, `error`, `enum`, `callback`, `Self`, `this`
- `pub`, `mut`
- `let`, `const`
- `if`, `else`, `switch`, `default`, `for`, `from`, `until`, `step`, `while`, `break`, `continue`, `return`
- `void`, `optional`, `result`
@ -87,7 +88,7 @@ Active keywords in `.pbs`:
Barrel-only keywords:
- `pub`, `mod`
- `mod`
- `type`
Reserved (not active syntax in v1 core):
@ -139,7 +140,8 @@ Visibility levels:
- `pub`: visible to importing modules.
Top-level declarations not listed in `mod.barrel` are file-private.
Using `mod`/`pub` as top-level modifiers inside `.pbs` files is a syntax error.
Using `mod` or a top-level standalone `pub` modifier inside `.pbs` files is a syntax error.
Inside ordinary `.pbs` source, `pub` and `mut` are reserved for struct field declarations, with `mut` valid only immediately after `pub`.
For overloaded functions, visibility is per-signature; each exported overload must appear explicitly in `mod.barrel`.
### 5.3 Barrel grammar
@ -269,7 +271,9 @@ HostDecl ::= 'declare' 'host' Identifier HostBody
ErrorDecl ::= 'declare' 'error' Identifier ErrorBody
EnumDecl ::= 'declare' 'enum' Identifier '(' EnumCaseDecl (',' EnumCaseDecl)* ','? ')' ';'
StructFieldList ::= StructFieldDecl (',' StructFieldDecl)* ','?
StructFieldDecl ::= Identifier ':' TypeRef
StructFieldDecl ::= StructFieldAccess? Identifier ':' TypeRef
StructFieldAccess ::= 'pub' MutOpt
MutOpt ::= 'mut'?
StructMethodBody ::= '{' StructMemberDecl* '}'
StructMemberDecl ::= StructMethodDecl | StructCtorDecl
StructMethodDecl ::= 'fn' Identifier ParamList ReturnAnn? Block
@ -290,7 +294,12 @@ Rules:
- `declare struct Name(...);` declares a heap-backed nominal user type with fields only.
- `declare struct Name(...) { ... }` declares a heap-backed nominal user type with fields and methods.
- Struct fields are declared positionally in the header and are mutable and accessible by default in v1 core.
- Struct fields are declared positionally in the header.
- A struct field with no access modifier is private to the enclosing struct body and its `ctor` declarations.
- `pub field: T` permits read access from outside the enclosing struct, but external writes remain invalid.
- `pub mut field: T` permits both read and write access from outside the enclosing struct.
- `mut` is valid in a struct field declaration only immediately after `pub`.
- Methods and `ctor` bodies of the enclosing struct may read and write all of that struct's fields regardless of field access modifier.
- The enclosing struct name is in scope within its own field types, so self-referential headers such as `declare struct Node(next: optional Node);` are valid.
- Struct method and `ctor` declarations belong only in the optional struct body.
- Struct methods have an implicit `this` receiver and do not declare `this: Self` explicitly.
@ -632,6 +641,7 @@ At minimum, deterministic diagnostics are required for:
- invalid callback declaration shape,
- invalid `Self` type usage,
- invalid `this` usage,
- invalid struct field access modifier surface,
- invalid struct method declaration shape,
- invalid service method declaration shape,
- invalid `ctor` declaration shape,
@ -988,7 +998,7 @@ fn demo_callback() -> void {
```pbs
declare callback UpdateCb(dt: int) -> void;
declare struct Enemy(hp: int);
declare struct Enemy(pub hp: int);
fn enemy_tick(self: Enemy, dt: int) -> void {
let _ = self.hp;
@ -1014,8 +1024,8 @@ declare contract StasisProcess {
declare struct Struct(
a: int,
b: str,
c: float,
pub b: str,
pub mut c: float,
) {
fn compute_something() -> int {
return this.a;
@ -1040,10 +1050,13 @@ fn demo_contract() -> int {
let s2 = new Struct.createWithSomethingSpecial(1, 2);
let sp: StasisProcess = s;
let sp2 = s as StasisProcess;
let visible = s.b;
s.c = 4.0;
let direct = s.compute_something();
let via_contract = sp.stasis();
let _ = s2.compute_something();
let _ = sp2.stasis();
let _ = visible;
return direct + via_contract;
}
```

View File

@ -222,7 +222,11 @@ Rules:
- Struct construction arguments are matched positionally to the declared struct field order.
- Assigning a struct value copies the reference, not the underlying field storage.
- Assigning a service value copies the same canonical singleton identity; it does not create a new instance.
- Struct fields are mutable and accessible by default in v1 core.
- A struct field with no access modifier is readable and writable only from methods and `ctor` bodies of its enclosing struct.
- A `pub` struct field is externally readable but remains externally non-assignable.
- A `pub mut` struct field is externally readable and externally assignable.
- An assignment target `expr.name` to a struct field is valid only when the access site is permitted to write that field.
- Writes to a private struct field are valid only through `this.name` inside methods and `ctor` bodies of the enclosing struct.
- A struct method declared in a struct body has an implicit receiver binding `this` of type `Self`.
- A service method declared in a service body has an implicit receiver binding `this` of type `Self`.
- `this` is valid only inside struct method, service method, and `ctor` bodies.
@ -266,7 +270,7 @@ declare contract StasisProcess {
fn stasis() -> int;
}
declare struct Struct(a: int) {
declare struct Struct(pub a: int) {
fn compute() -> int {
return this.a;
}
@ -287,7 +291,7 @@ fn demo() -> int {
let s2 = new Struct.createWithSomethingSpecial(2);
let sp: StasisProcess = s;
let sp2 = s as StasisProcess;
let a = s.compute();
let a = s.a;
let _ = s2.compute();
let b = sp.stasis();
let c = sp2.stasis();
@ -483,8 +487,9 @@ Rules:
- `TypeName.case` is valid when `TypeName` resolves to a declared enum type and `case` resolves to one of its declared enum cases.
- `TypeName.case` has static type `TypeName`.
- `expr.name` is valid when the static type of `expr` is a declared `struct` containing field `name`.
- `expr.name` is valid when the static type of `expr` is a declared `struct` containing field `name` and the access site is permitted to read that field.
- For `struct` field access, the projected member type is the declared field type.
- Reads of a private struct field are valid only through `this.name` inside methods and `ctor` bodies of the enclosing struct.
- `expr.method` is a valid method-call target when the static type of `expr` is a concrete struct type declaring method `method`.
- `expr.method` over a concrete struct receiver does not search visible contract implementations.
- `expr.method` is a valid method-call target when the static type of `expr` is a concrete service type declaring method `method`.
@ -503,6 +508,8 @@ Rules:
- `expr.key()` has static type `int`.
- Access to a missing output label is a compile-time error.
- Access to a missing struct field is a compile-time error.
- Read access to an inaccessible private struct field is a compile-time error.
- Write access to an inaccessible or non-`pub mut` struct field is a compile-time error.
- Access to a missing struct method is a compile-time error.
- Access to a missing service method is a compile-time error.
- Access to a missing host method is a compile-time error.
@ -680,6 +687,8 @@ At minimum, deterministic static diagnostics are required for:
- invalid mapped error label in `handle`,
- attempted use of a single-slot tuple literal where no such surface form exists,
- member access on a missing struct field,
- read access to an inaccessible private struct field,
- write access to an inaccessible or non-`pub mut` struct field,
- member access on a missing struct method,
- member access on a missing service method,
- member access on a missing host method,