chore: Phase 25.1 完了 - LoopForm v2/Stage1 CLI/環境変数削減 + Phase 26-D からの変更
Phase 25.1 完了成果: - ✅ LoopForm v2 テスト・ドキュメント・コメント完備 - 4ケース(A/B/C/D)完全テストカバレッジ - 最小再現ケース作成(SSAバグ調査用) - SSOT文書作成(loopform_ssot.md) - 全ソースに [LoopForm] コメントタグ追加 - ✅ Stage-1 CLI デバッグ環境構築 - stage1_cli.hako 実装 - stage1_bridge.rs ブリッジ実装 - デバッグツール作成(stage1_debug.sh/stage1_minimal.sh) - アーキテクチャ改善提案文書 - ✅ 環境変数削減計画策定 - 25変数の完全調査・分類 - 6段階削減ロードマップ(25→5、80%削減) - 即時削除可能変数特定(NYASH_CONFIG/NYASH_DEBUG) Phase 26-D からの累積変更: - PHI実装改善(ExitPhiBuilder/HeaderPhiBuilder等) - MIRビルダーリファクタリング - 型伝播・最適化パス改善 - その他約300ファイルの累積変更 🎯 技術的成果: - SSAバグ根本原因特定(条件分岐内loop変数変更) - Region+next_iパターン適用完了(UsingCollectorBox等) - LoopFormパターン文書化・テスト化完了 - セルフホスティング基盤強化 Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: ChatGPT <noreply@openai.com> Co-Authored-By: Task Assistant <task@anthropic.com>
This commit is contained in:
@ -182,31 +182,76 @@ impl NyashParser {
|
||||
while let Some(c) = it.next() {
|
||||
if in_line {
|
||||
out.push(c);
|
||||
if c == '\n' { in_line = false; }
|
||||
if c == '\n' {
|
||||
in_line = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if in_block {
|
||||
out.push(c);
|
||||
if c == '*' && matches!(it.peek(), Some('/')) { out.push('/'); it.next(); in_block = false; }
|
||||
if c == '*' && matches!(it.peek(), Some('/')) {
|
||||
out.push('/');
|
||||
it.next();
|
||||
in_block = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if in_str {
|
||||
out.push(c);
|
||||
if c == '\\' { if let Some(nc) = it.next() { out.push(nc); } continue; }
|
||||
if c == '"' { in_str = false; }
|
||||
if c == '\\' {
|
||||
if let Some(nc) = it.next() {
|
||||
out.push(nc);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if c == '"' {
|
||||
in_str = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
match c {
|
||||
'"' => { in_str = true; out.push(c); }
|
||||
'/' => {
|
||||
match it.peek() { Some('/') => { out.push('/'); out.push('/'); it.next(); in_line = true; }, Some('*') => { out.push('/'); out.push('*'); it.next(); in_block = true; }, _ => out.push('/') }
|
||||
'"' => {
|
||||
in_str = true;
|
||||
out.push(c);
|
||||
}
|
||||
'/' => match it.peek() {
|
||||
Some('/') => {
|
||||
out.push('/');
|
||||
out.push('/');
|
||||
it.next();
|
||||
in_line = true;
|
||||
}
|
||||
Some('*') => {
|
||||
out.push('/');
|
||||
out.push('*');
|
||||
it.next();
|
||||
in_block = true;
|
||||
}
|
||||
_ => out.push('/'),
|
||||
},
|
||||
'#' => {
|
||||
in_line = true;
|
||||
out.push('#');
|
||||
}
|
||||
'#' => { in_line = true; out.push('#'); }
|
||||
'|' => {
|
||||
if matches!(it.peek(), Some('|')) { out.push_str(" or "); it.next(); } else if matches!(it.peek(), Some('>')) { out.push('|'); out.push('>'); it.next(); } else { out.push('|'); }
|
||||
if matches!(it.peek(), Some('|')) {
|
||||
out.push_str(" or ");
|
||||
it.next();
|
||||
} else if matches!(it.peek(), Some('>')) {
|
||||
out.push('|');
|
||||
out.push('>');
|
||||
it.next();
|
||||
} else {
|
||||
out.push('|');
|
||||
}
|
||||
}
|
||||
'&' => {
|
||||
if matches!(it.peek(), Some('&')) { out.push_str(" and "); it.next(); } else { out.push('&'); }
|
||||
if matches!(it.peek(), Some('&')) {
|
||||
out.push_str(" and ");
|
||||
it.next();
|
||||
} else {
|
||||
out.push('&');
|
||||
}
|
||||
}
|
||||
_ => out.push(c),
|
||||
}
|
||||
@ -247,10 +292,13 @@ impl NyashParser {
|
||||
let mut statements = Vec::new();
|
||||
let mut _statement_count = 0;
|
||||
|
||||
let allow_sc = std::env::var("NYASH_PARSER_ALLOW_SEMICOLON").ok().map(|v| {
|
||||
let lv = v.to_ascii_lowercase();
|
||||
!(lv == "0" || lv == "false" || lv == "off")
|
||||
}).unwrap_or(true);
|
||||
let allow_sc = std::env::var("NYASH_PARSER_ALLOW_SEMICOLON")
|
||||
.ok()
|
||||
.map(|v| {
|
||||
let lv = v.to_ascii_lowercase();
|
||||
!(lv == "0" || lv == "false" || lv == "off")
|
||||
})
|
||||
.unwrap_or(true);
|
||||
|
||||
while !self.is_at_end() {
|
||||
// EOF tokenはスキップ
|
||||
@ -293,13 +341,13 @@ impl NyashParser {
|
||||
|
||||
// 左辺が代入可能な形式かチェック
|
||||
match &expr {
|
||||
ASTNode::Variable { .. }
|
||||
| ASTNode::FieldAccess { .. }
|
||||
| ASTNode::Index { .. } => Ok(ASTNode::Assignment {
|
||||
target: Box::new(expr),
|
||||
value,
|
||||
span: Span::unknown(),
|
||||
}),
|
||||
ASTNode::Variable { .. } | ASTNode::FieldAccess { .. } | ASTNode::Index { .. } => {
|
||||
Ok(ASTNode::Assignment {
|
||||
target: Box::new(expr),
|
||||
value,
|
||||
span: Span::unknown(),
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
let line = self.current_token().line;
|
||||
Err(ParseError::InvalidStatement { line })
|
||||
@ -365,9 +413,17 @@ impl NyashParser {
|
||||
|
||||
// ---- Minimal ParserUtils impl (depth-less; TokenCursor handles newline policy) ----
|
||||
impl common::ParserUtils for NyashParser {
|
||||
fn tokens(&self) -> &Vec<Token> { &self.tokens }
|
||||
fn current(&self) -> usize { self.current }
|
||||
fn current_mut(&mut self) -> &mut usize { &mut self.current }
|
||||
fn update_depth_before_advance(&mut self) { /* no-op (legacy removed) */ }
|
||||
fn update_depth_after_advance(&mut self) { /* no-op (legacy removed) */ }
|
||||
fn tokens(&self) -> &Vec<Token> {
|
||||
&self.tokens
|
||||
}
|
||||
fn current(&self) -> usize {
|
||||
self.current
|
||||
}
|
||||
fn current_mut(&mut self) -> &mut usize {
|
||||
&mut self.current
|
||||
}
|
||||
fn update_depth_before_advance(&mut self) { /* no-op (legacy removed) */
|
||||
}
|
||||
fn update_depth_after_advance(&mut self) { /* no-op (legacy removed) */
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user