Files
hakorune/src/mir/builder/calls/extern_calls.rs
nyash-codex f9d100ce01 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>
2025-11-21 06:25:17 +09:00

178 lines
4.9 KiB
Rust

/*!
* External Call Handling
*
* Manages env.* methods and external interface calls
* Provides bridge to host environment functionality
*/
use crate::mir::{Effect, EffectMask};
/// Table-like spec for env.* methods
/// Returns (iface_name, method_name, effects, returns_value)
pub fn get_env_method_spec(
iface: &str,
method: &str,
) -> Option<(String, String, EffectMask, bool)> {
match (iface, method) {
// Future/async operations
("future", "delay") => Some((
"env.future".to_string(),
"delay".to_string(),
EffectMask::READ.add(Effect::Io),
true,
)),
("future", "spawn") => Some((
"env.future".to_string(),
"spawn".to_string(),
EffectMask::IO,
true,
)),
// Task management
("task", "currentToken") => Some((
"env.task".to_string(),
"currentToken".to_string(),
EffectMask::READ,
true,
)),
("task", "cancelCurrent") => Some((
"env.task".to_string(),
"cancelCurrent".to_string(),
EffectMask::IO,
false,
)),
// Console I/O
("console", "log") => Some((
"env.console".to_string(),
"log".to_string(),
EffectMask::IO,
false,
)),
("console", "readLine") => Some((
"env.console".to_string(),
"readLine".to_string(),
EffectMask::IO,
true,
)),
("console", "error") => Some((
"env.console".to_string(),
"error".to_string(),
EffectMask::IO,
false,
)),
// Canvas operations
("canvas", m) if matches!(m, "fillRect" | "fillText" | "clear") => Some((
"env.canvas".to_string(),
method.to_string(),
EffectMask::IO,
false,
)),
// File system
("fs", "readFile") => Some((
"env.fs".to_string(),
"readFile".to_string(),
EffectMask::IO,
true,
)),
("fs", "writeFile") => Some((
"env.fs".to_string(),
"writeFile".to_string(),
EffectMask::IO,
false,
)),
("fs", "exists") => Some((
"env.fs".to_string(),
"exists".to_string(),
EffectMask::READ,
true,
)),
// Network
("net", "fetch") => Some((
"env.net".to_string(),
"fetch".to_string(),
EffectMask::IO,
true,
)),
("net", "listen") => Some((
"env.net".to_string(),
"listen".to_string(),
EffectMask::IO,
true,
)),
// Process/system
("process", "exit") => Some((
"env.process".to_string(),
"exit".to_string(),
EffectMask::IO.add(Effect::Control),
false,
)),
("process", "argv") => Some((
"env.process".to_string(),
"argv".to_string(),
EffectMask::READ,
true,
)),
("process", "env") => Some((
"env.process".to_string(),
"env".to_string(),
EffectMask::READ,
true,
)),
// Direct env access
("env", "get") => Some(("env".to_string(), "get".to_string(), EffectMask::READ, true)),
("env", "set") => Some(("env".to_string(), "set".to_string(), EffectMask::IO, false)),
// Unknown
_ => None,
}
}
/// Parse external call name into interface and method
/// E.g., "nyash.builtin.print" -> ("nyash.builtin", "print")
pub fn parse_extern_name(name: &str) -> (String, String) {
let parts: Vec<&str> = name.rsplitn(2, '.').collect();
if parts.len() == 2 {
(parts[1].to_string(), parts[0].to_string())
} else {
("nyash".to_string(), name.to_string())
}
}
/// Check if a name refers to an environment interface
#[allow(dead_code)]
pub fn is_env_interface(name: &str) -> bool {
matches!(
name,
"env"
| "env.console"
| "env.fs"
| "env.net"
| "env.canvas"
| "env.task"
| "env.future"
| "env.process"
)
}
/// Determine effects for an external call
pub fn compute_extern_effects(iface: &str, method: &str) -> EffectMask {
match (iface, method) {
// Pure reads
(_, m) if m.starts_with("get") || m == "argv" || m == "env" => EffectMask::READ,
// Control flow changes
(_, "exit") | (_, "panic") | (_, "throw") => EffectMask::IO.add(Effect::Control),
// Memory allocation
(_, m) if m.starts_with("new") || m.starts_with("create") => {
EffectMask::IO.add(Effect::Alloc)
}
// Default to I/O
_ => EffectMask::IO,
}
}