feat: 改行処理革命Phase 2-B完了 - Box宣言系skip_newlines()完全削除

 **41%削減達成**: 48→35→21箇所(14箇所削除)
- fields.rs: 9箇所のskip_newlines()削除
- box_definition.rs: 3箇所削除
- static_box.rs: 2箇所削除

 **Smart advance()実用化**: 深度追跡で自動改行処理完璧機能
- Box宣言、match式OR、複数行構文すべて対応
- NYASH_SMART_ADVANCE=1で安定動作確認

🔧 **ORパターンバグ同時修正**: exprs_peek.rsでInteger/Boolean型マッチング実装
- 修正前: 1 | 2 => "found" が動作せず(String型のみ)
- 修正後: 全リテラル型(Integer/Bool/Float/Null/Void)完全対応

🎉 **技術的価値**: 手動skip依存→コンテキスト認識自動処理への移行成功

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Selfhosting Dev
2025-09-23 11:22:16 +09:00
parent 536e64441a
commit ad62066172
5 changed files with 45 additions and 54 deletions

View File

@ -397,27 +397,26 @@ jq '.functions[0].blocks' mir.json # ブロック構造確認
- 🗃️ **アーカイブ整理**: 古いphaseファイル群をarchiveに移動、導線クリーンアップ完了 - 🗃️ **アーカイブ整理**: 古いphaseファイル群をarchiveに移動、導線クリーンアップ完了
- 📋 詳細: [Property System仕様](docs/proposals/unified-members.md) | [Python統合計画](docs/development/roadmap/phases/phase-10.7/) - 📋 詳細: [Property System仕様](docs/proposals/unified-members.md) | [Python統合計画](docs/development/roadmap/phases/phase-10.7/)
## 📝 Update (2025-09-24) ✅ 改行処理Smart advance完全実装skip_newlines()削減開始 ## 📝 Update (2025-09-24) ✅ 改行処理革命Phase 2-B完了実用レベル到達
- 🎉 **改行処理Phase 0-1完全達成** ChatGPT Pro戦略に基づく段階的実装が成功 - 🎯 **改行処理革命Phase 2-B完了** Box宣言系ファイルから14箇所のskip_newlines()完全削除
- **Phase 0 Quick Fix**: ✅ 完了primary.rsに緊急対応 - **削除実績**: 48→35→21箇所41%削減達成!
- **Phase 1 Smart advance**: ✅ 完全実装&デフォルト有効化 - **対象ファイル**: fields.rs(9箇所)、box_definition.rs(3箇所)、static_box.rs(2箇所)
- **Phase 2 TokenCursor**: 基盤実装済み、部分適用中 - **テスト結果**: OR付きmatch式、複数行宣言、Box定義すべて完璧動作✅
- **Phase 3 LASI前処理**: 将来計画として整理 - **Smart advance()実用化成功!** 深度追跡で自動改行処理が完璧に機能
- **Smart advance()機能の完成!** 深度追跡による自動改行処理 - **環境変数**: `NYASH_SMART_ADVANCE=1`で完全制御、`NYASH_DISABLE_PLUGINS=1`推奨
- **深度追跡実装**: `depth_tracking.rs`で括弧深度paren/brace/bracketを自動管理 - **対応構文**: match式OR`1 | 2`、複数行パターン、Box宣言すべて対応
- **デフォルト有効化**: 環境変数不要!`NYASH_SMART_ADVANCE=0`で無効化可能 - 🔧 **ORパターンバグも同時修正** exprs_peek.rsでInteger/Boolean型マッチング実装
- **賢い行継続判定**: - **修正前**: `1 | 2 => "found"`が動作せずString型のみサポート
- 演算子後の改行を自動スキップ - **修正後**: 全リテラル型Integer/Bool/Float/Null/Void完全対応✅
- 次行が演算子で始まる場合もスキップ(`.toUpperCase()`形式対応) - 📊 **改行処理戦略の段階的成果**:
- 括弧内では常に改行を無視 - **Phase 0**: Quick Fix ✅ 完了(即効性)
- **skip_newlines()削減開始!** 48箇所→40箇所17%削減 - **Phase 1**: Smart advance() ✅ 基本実装完了(大幅改善
- **削除完了**: primary.rsのオブジェクトリテラル内8箇所 - **Phase 2-A**: match式系統 ✅ 完了6箇所削除
- **残り40箇所**: 段階的削除計画策定中 - **Phase 2-B**: Box宣言系統 ✅ 完了14箇所削除、41%削減)
- **最終目標**: skip_newlines()完全排除でコード品質向上 - **Phase 2-C**: 次の目標(更なる削減へ)
- 🧪 **テスト結果**: 全ケース成功 - 🎉 **技術的成果**: 手動スキップ依存からコンテキスト認識自動処理への移行成功
- 文区切り、演算子行継続、括弧内改行、オブジェクトリテラル、次行演算子すべて✅ - 📚 **改行処理戦略ドキュメント**: [skip-newlines-removal-plan.md](docs/development/strategies/skip-newlines-removal-plan.md)
- 📚 **改行処理戦略ドキュメント**: [newline-handling-strategy.md](docs/development/strategies/newline-handling-strategy.md) - 🚀 **次のタスク**: Phase 2-C実装→残り21箇所の系統的削除継続
- 🚀 **次のステップ**: 残り40箇所のskip_newlines()削除→TokenCursor本格活用
## 📝 Update (2025-09-23) ✅ フェーズS実装完了break制御フロー根治開始 ## 📝 Update (2025-09-23) ✅ フェーズS実装完了break制御フロー根治開始
-**フェーズS完了** PHI incoming修正+終端ガード徹底→重複処理4箇所統一 -**フェーズS完了** PHI incoming修正+終端ガード徹底→重複処理4箇所統一

View File

@ -75,11 +75,18 @@ impl super::MirBuilder {
// In current dispatch block, compare and branch // In current dispatch block, compare and branch
self.start_new_block(cur_dispatch)?; self.start_new_block(cur_dispatch)?;
if let LiteralValue::String(s) = label {
let lit_id = self.value_gen.next(); let lit_id = self.value_gen.next();
let const_value = match label {
LiteralValue::String(s) => super::ConstValue::String(s),
LiteralValue::Integer(i) => super::ConstValue::Integer(i),
LiteralValue::Bool(b) => super::ConstValue::Bool(b),
LiteralValue::Float(f) => super::ConstValue::Float(f),
LiteralValue::Null => super::ConstValue::Null,
LiteralValue::Void => super::ConstValue::Void,
};
self.emit_instruction(super::MirInstruction::Const { self.emit_instruction(super::MirInstruction::Const {
dst: lit_id, dst: lit_id,
value: super::ConstValue::String(s), value: const_value,
})?; })?;
let cond_id = self.value_gen.next(); let cond_id = self.value_gen.next();
self.emit_instruction(super::MirInstruction::Compare { self.emit_instruction(super::MirInstruction::Compare {
@ -93,7 +100,6 @@ impl super::MirBuilder {
then_bb: then_block, then_bb: then_block,
else_bb: else_target, else_bb: else_target,
})?; })?;
}
// then arm // then arm
self.start_new_block(then_block)?; self.start_new_block(then_block)?;

View File

@ -40,7 +40,6 @@ pub(crate) fn try_parse_header_first_field_or_property(
p.advance(); p.advance();
let _init_expr = p.parse_expression()?; // P0: parse and discard let _init_expr = p.parse_expression()?; // P0: parse and discard
fields.push(fname); fields.push(fname);
p.skip_newlines();
return Ok(true); return Ok(true);
} }
// name: Type => expr → computed property (getter method with return expr) // name: Type => expr → computed property (getter method with return expr)
@ -61,7 +60,6 @@ pub(crate) fn try_parse_header_first_field_or_property(
span: Span::unknown(), span: Span::unknown(),
}; };
methods.insert(getter_name, method); methods.insert(getter_name, method);
p.skip_newlines();
return Ok(true); return Ok(true);
} }
// name: Type { ... } [postfix] // name: Type { ... } [postfix]
@ -78,7 +76,6 @@ pub(crate) fn try_parse_header_first_field_or_property(
span: Span::unknown(), span: Span::unknown(),
}; };
methods.insert(getter_name, method); methods.insert(getter_name, method);
p.skip_newlines();
return Ok(true); return Ok(true);
} }
} }
@ -108,7 +105,6 @@ pub(crate) fn try_parse_visibility_block_or_single(
} }
if p.match_token(&TokenType::LBRACE) { if p.match_token(&TokenType::LBRACE) {
p.advance(); p.advance();
p.skip_newlines();
while !p.match_token(&TokenType::RBRACE) && !p.is_at_end() { while !p.match_token(&TokenType::RBRACE) && !p.is_at_end() {
if let TokenType::IDENTIFIER(fname) = &p.current_token().token_type { if let TokenType::IDENTIFIER(fname) = &p.current_token().token_type {
let fname = fname.clone(); let fname = fname.clone();
@ -116,7 +112,6 @@ pub(crate) fn try_parse_visibility_block_or_single(
fields.push(fname); fields.push(fname);
p.advance(); p.advance();
if p.match_token(&TokenType::COMMA) { p.advance(); } if p.match_token(&TokenType::COMMA) { p.advance(); }
p.skip_newlines();
continue; continue;
} }
return Err(ParseError::UnexpectedToken { return Err(ParseError::UnexpectedToken {
@ -126,7 +121,6 @@ pub(crate) fn try_parse_visibility_block_or_single(
}); });
} }
p.consume(TokenType::RBRACE)?; p.consume(TokenType::RBRACE)?;
p.skip_newlines();
return Ok(true); return Ok(true);
} }
if let TokenType::IDENTIFIER(n) = &p.current_token().token_type { if let TokenType::IDENTIFIER(n) = &p.current_token().token_type {
@ -135,12 +129,10 @@ pub(crate) fn try_parse_visibility_block_or_single(
if try_parse_header_first_field_or_property(p, fname.clone(), methods, fields)? { if try_parse_header_first_field_or_property(p, fname.clone(), methods, fields)? {
if visibility == "public" { public_fields.push(fname.clone()); } else { private_fields.push(fname.clone()); } if visibility == "public" { public_fields.push(fname.clone()); } else { private_fields.push(fname.clone()); }
*last_method_name = None; *last_method_name = None;
p.skip_newlines();
return Ok(true); return Ok(true);
} else { } else {
if visibility == "public" { public_fields.push(fname.clone()); } else { private_fields.push(fname.clone()); } if visibility == "public" { public_fields.push(fname.clone()); } else { private_fields.push(fname.clone()); }
fields.push(fname); fields.push(fname);
p.skip_newlines();
return Ok(true); return Ok(true);
} }
} }
@ -160,7 +152,6 @@ pub(crate) fn parse_init_block_if_any(
p.advance(); // consume 'init' p.advance(); // consume 'init'
p.consume(TokenType::LBRACE)?; p.consume(TokenType::LBRACE)?;
while !p.match_token(&TokenType::RBRACE) && !p.is_at_end() { while !p.match_token(&TokenType::RBRACE) && !p.is_at_end() {
p.skip_newlines();
if p.match_token(&TokenType::RBRACE) { if p.match_token(&TokenType::RBRACE) {
break; break;
} }

View File

@ -116,7 +116,6 @@ impl NyashParser {
box_header::parse_header(self)?; box_header::parse_header(self)?;
self.consume(TokenType::LBRACE)?; self.consume(TokenType::LBRACE)?;
self.skip_newlines(); // ブレース後の改行をスキップ
let mut fields = Vec::new(); let mut fields = Vec::new();
let mut methods = HashMap::new(); let mut methods = HashMap::new();
@ -130,7 +129,6 @@ impl NyashParser {
let mut last_method_name: Option<String> = None; let mut last_method_name: Option<String> = None;
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() { while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
self.skip_newlines(); // ループ開始時に改行をスキップ
// 分類(段階移行用の観測): 将来の分岐移譲のための前処理 // 分類(段階移行用の観測): 将来の分岐移譲のための前処理
if crate::config::env::parser_stage3() { if crate::config::env::parser_stage3() {
if let Ok(kind) = crate::parser::declarations::box_def::members::common::classify_member(self) { if let Ok(kind) = crate::parser::declarations::box_def::members::common::classify_member(self) {
@ -189,7 +187,6 @@ impl NyashParser {
&mut birth_once_props, &mut birth_once_props,
)? { )? {
last_method_name = None; // do not attach method-level postfix here last_method_name = None; // do not attach method-level postfix here
self.skip_newlines();
continue; continue;
} }
} }

View File

@ -18,7 +18,6 @@ impl NyashParser {
crate::parser::declarations::static_def::header::parse_static_header(self)?; crate::parser::declarations::static_def::header::parse_static_header(self)?;
self.consume(TokenType::LBRACE)?; self.consume(TokenType::LBRACE)?;
self.skip_newlines(); // ブレース後の改行をスキップ
let mut fields = Vec::new(); let mut fields = Vec::new();
let mut methods = HashMap::new(); let mut methods = HashMap::new();
@ -30,7 +29,6 @@ impl NyashParser {
// Track last inserted method name to allow postfix catch/cleanup fallback parsing // Track last inserted method name to allow postfix catch/cleanup fallback parsing
let mut last_method_name: Option<String> = None; let mut last_method_name: Option<String> = None;
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() { while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
self.skip_newlines(); // ループ開始時に改行をスキップ
// Fallback: method-level postfix catch/cleanup immediately following a method // Fallback: method-level postfix catch/cleanup immediately following a method
if crate::parser::declarations::box_def::members::postfix::try_parse_method_postfix_after_last_method( if crate::parser::declarations::box_def::members::postfix::try_parse_method_postfix_after_last_method(