feat(phase285w): Implement weak x unary operator syntax

Phase 285W-Syntax-0: Migrate weak reference syntax from function call
to unary operator for consistency and clarity.

**Changes**:
- Parser: Add UnaryOperator::Weak variant and parse_unary() handling
- MIR: Lower UnaryOp::Weak to emit_weak_new() (reuses existing path)
- AST: Add Weak to UnaryOperator enum + Display/JSON support
- Tests: Migrate 8 files from `weak(x)` to `weak x` syntax
  - 7 .hako test files updated
  - 1 smoke test shell script updated
- Cleanup: Remove obsolete weak(x) parser/MIR special cases
- Docs: Update Phase 285 README

**Syntax Change**:
- Old: `local w = weak(x)`  (function call)
- New: `local w = weak x`   (unary operator)

**Validation**: All migrated phase285* smoke tests pass (4/4 relevant)

**SSOT**: docs/reference/language/lifecycle.md

🤖 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 17:21:21 +09:00
parent 5b2b5528a5
commit 9227673ef7
17 changed files with 73 additions and 44 deletions

View File

@ -313,19 +313,6 @@ impl NyashParser {
span: Span::unknown(),
})
}
// Phase 285A0: weak(expr) → WeakRef creation
// SSOT: docs/reference/language/lifecycle.md:171
TokenType::WEAK => {
self.advance();
self.consume(TokenType::LPAREN)?;
let argument = self.parse_expression()?;
self.consume(TokenType::RPAREN)?;
Ok(ASTNode::FunctionCall {
name: "weak".to_string(),
arguments: vec![argument],
span: Span::unknown(),
})
}
_ => {
let line = self.current_token().line;
Err(ParseError::InvalidExpression { line })

View File

@ -242,6 +242,17 @@ impl NyashParser {
});
}
// Phase 285W-Syntax-0: weak <expr> unary operator
if self.match_token(&TokenType::WEAK) {
self.advance(); // consume 'weak'
let operand = self.parse_unary()?; // 再帰的に単項演算をパース
return Ok(ASTNode::UnaryOp {
operator: UnaryOperator::Weak,
operand: Box::new(operand),
span: Span::unknown(),
});
}
self.parse_call()
}