feat(parser): Phase 285A1.4 & A1.5 - Weak field sugar + Parser hang fix

A1.4: Add sugar syntax `public weak parent` ≡ `public { weak parent }`
A1.5: Fix parser hang on unsupported `param: Type` syntax

Key changes:
- A1.4: Extend visibility parser to handle weak modifier (fields.rs)
- A1.5: Shared helper `parse_param_name_list()` with progress-zero detection
- A1.5: Fix 6 vulnerable parameter parsing loops (methods, constructors, functions)
- Tests: Sugar syntax (OK/NG), parser hang (timeout-based)
- Docs: lifecycle.md, EBNF.md, phase-285a1-boxification.md

Additional changes:
- weak() builtin implementation (handlers/weak.rs)
- Leak tracking improvements (leak_tracker.rs)
- Documentation updates (lifecycle, types, memory-finalization, etc.)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-24 07:44:50 +09:00
parent a47f850d02
commit ab76e39036
60 changed files with 2099 additions and 454 deletions

View File

@ -72,13 +72,25 @@ This section adds a minimal grammar for Box members (a unified member model) wit
```
box_decl := 'box' IDENT '{' member* '}'
member := stored
member := visibility_block
| weak_stored
| stored
| computed
| once_decl
| birth_once_decl
| method_decl
| block_as_role ; nyash-mode (block-first) equivalent
visibility_block := ( 'public' | 'private' ) '{' member* '}'
; member visibility grouping (Phase 285A1.3). `weak` is allowed inside.
weak_stored := 'weak' IDENT ( ':' TYPE )?
; weak field declaration (Phase 285A1.2). Enforces WeakRef type at compile-time.
visibility_weak_sugar := ('public'|'private') 'weak' IDENT ( ':' TYPE )?
; sugar syntax (Phase 285A1.4). Equivalent to visibility block form.
; e.g., `public weak parent` ≡ `public { weak parent }`
stored := IDENT ':' TYPE ( '=' expr )?
; stored property (read/write). No handlers supported.
@ -93,6 +105,10 @@ birth_once_decl:= 'birth_once' IDENT ':' TYPE ( '=>' expr | block ) handler_tail
method_decl := IDENT '(' params? ')' ( ':' TYPE )? block handler_tail?
params := IDENT (',' IDENT)*
; parameter name list (Phase 285A1.5)
; Note: Parameter type annotations (e.g., `name: Type`) are not supported.
; nyash-mode (block-first) variant — gated with NYASH_ENABLE_UNIFIED_MEMBERS=1
block_as_role := block 'as' ( 'once' | 'birth_once' )? IDENT ':' TYPE
@ -101,7 +117,7 @@ catch_block := 'catch' ( '(' ( IDENT IDENT | IDENT )? ')' )? block
cleanup_block := 'cleanup' block
; Stage3 (Phase 1 via normalization gate NYASH_CATCH_NEW=1)
; Postfix handlers for expressions and calls
; Postfix handlers for expressions and calls (cleanup may appear without catch)
postfix_catch := primary_expr 'catch' ( '(' ( IDENT IDENT | IDENT )? ')' )? block
postfix_cleanup := primary_expr 'cleanup' block
```
@ -120,12 +136,23 @@ Lowering (no JSON v0 change)
- birth_once → add `__name: T` and insert initialization just before user `birth` in declaration order; handlers apply to each initializer
- method → existing method forms; optional postfix handlers lower to try/catch/finally
## Legacy: `init { ... }` field list (compatibility)
Some docs and older code use an `init { a, b, c }` list inside a `box` body. This is a legacy compatibility form to declare stored slots.
Semantics (SSOT):
- `init { a, b, c }` declares **untyped stored slots** named `a`, `b`, `c` (equivalent to writing `a` / `b` / `c` as stored members without type).
- `init { weak x, weak y }` declares **weak fields** (equivalent to writing `weak x` / `weak y` as members).
- It does not execute code. Initialization logic belongs in `birth(...) { ... }` and assignments.
- **New code** should prefer the direct syntax: `weak field_name` (Phase 285A1.2) or the unified member model (`stored/computed/once/birth_once`).
- Legacy `init { weak field }` syntax still works for backward compatibility but is superseded by `weak field`.
## Stage3 (Gated) Additions
Enabled when `NYASH_PARSER_STAGE3=1` for the Rust parser (and via `--stage3`/`NYASH_NY_COMPILER_STAGE3=1` for the selfhost parser):
- try/catch/cleanup
- `try_stmt := 'try' block ('catch' '(' (IDENT IDENT | IDENT | ε) ')' block) ('cleanup' block)?`
- `try_stmt := 'try' block ('catch' '(' (IDENT IDENT | IDENT | ε) ')' block)? ('cleanup' block)?`
- MVP policy: single `catch` per `try`
- `(Type var)` or `(var)` or `()` are accepted for the catch parameter。