Phase 10.7/10.5c: include cycle detection (VM/Interpreter), minimal pyc IR→Nyash, String unification bridge (VM partial), add core plugins: RegexBox/EncodingBox/TOMLBox/PathBox + examples; wire nyash.toml; begin String interop for internal vs plugin boxes; update CURRENT_TASK.md
This commit is contained in:
@ -57,9 +57,24 @@ impl NyashInterpreter {
|
||||
} else if std::path::Path::new(&canonical_path).extension().is_none() {
|
||||
canonical_path.push_str(".nyash");
|
||||
}
|
||||
|
||||
// 循環検出(ロード中スタック)
|
||||
{
|
||||
let mut stack = self.shared.include_stack.lock().unwrap();
|
||||
if let Some(pos) = stack.iter().position(|p| p == &canonical_path) {
|
||||
// 検出: A -> ... -> B -> A
|
||||
let mut chain: Vec<String> = stack[pos..].to_vec();
|
||||
chain.push(canonical_path.clone());
|
||||
let msg = format!("include cycle detected: {}",
|
||||
chain.join(" -> "));
|
||||
return Err(RuntimeError::InvalidOperation { message: msg });
|
||||
}
|
||||
stack.push(canonical_path.clone());
|
||||
}
|
||||
|
||||
// 重複読み込みチェック
|
||||
if self.shared.included_files.lock().unwrap().contains(&canonical_path) {
|
||||
// スタックから外して早期終了
|
||||
self.shared.include_stack.lock().unwrap().pop();
|
||||
return Ok(()); // 既に読み込み済み
|
||||
}
|
||||
|
||||
@ -76,10 +91,14 @@ impl NyashInterpreter {
|
||||
})?;
|
||||
|
||||
// 重複防止リストに追加
|
||||
self.shared.included_files.lock().unwrap().insert(canonical_path);
|
||||
self.shared.included_files.lock().unwrap().insert(canonical_path.clone());
|
||||
|
||||
// 現在の環境で実行
|
||||
self.execute(ast)?;
|
||||
let exec_res = self.execute(ast);
|
||||
// スタックを外す
|
||||
self.shared.include_stack.lock().unwrap().pop();
|
||||
// 実行結果を伝播
|
||||
exec_res?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -96,6 +115,18 @@ impl NyashInterpreter {
|
||||
canonical_path.push_str(".nyash");
|
||||
}
|
||||
|
||||
// 循環検出(ロード中スタック)
|
||||
{
|
||||
let mut stack = self.shared.include_stack.lock().unwrap();
|
||||
if let Some(pos) = stack.iter().position(|p| p == &canonical_path) {
|
||||
let mut chain: Vec<String> = stack[pos..].to_vec();
|
||||
chain.push(canonical_path.clone());
|
||||
let msg = format!("include cycle detected: {}", chain.join(" -> "));
|
||||
return Err(RuntimeError::InvalidOperation { message: msg });
|
||||
}
|
||||
stack.push(canonical_path.clone());
|
||||
}
|
||||
|
||||
// ファイル読み込み(static box名検出用)
|
||||
let content = std::fs::read_to_string(&canonical_path)
|
||||
.map_err(|e| RuntimeError::InvalidOperation {
|
||||
@ -131,8 +162,14 @@ impl NyashInterpreter {
|
||||
set.contains(&canonical_path)
|
||||
};
|
||||
if !already {
|
||||
self.shared.included_files.lock().unwrap().insert(canonical_path);
|
||||
self.execute(ast)?;
|
||||
self.shared.included_files.lock().unwrap().insert(canonical_path.clone());
|
||||
let exec_res = self.execute(ast);
|
||||
// スタックを外す
|
||||
self.shared.include_stack.lock().unwrap().pop();
|
||||
exec_res?;
|
||||
} else {
|
||||
// スタックを外す(既に読み込み済みのため)
|
||||
self.shared.include_stack.lock().unwrap().pop();
|
||||
}
|
||||
|
||||
// static boxを初期化・取得して返す
|
||||
|
||||
@ -20,6 +20,9 @@ pub struct SharedState {
|
||||
|
||||
/// 読み込み済みファイル(重複防止)
|
||||
pub included_files: Arc<Mutex<HashSet<String>>>,
|
||||
|
||||
/// includeロード中スタック(循環検出用: A -> B -> A を検出)
|
||||
pub include_stack: Arc<Mutex<Vec<String>>>,
|
||||
}
|
||||
|
||||
impl SharedState {
|
||||
@ -37,6 +40,7 @@ impl SharedState {
|
||||
static_functions: Arc::new(RwLock::new(HashMap::new())),
|
||||
static_box_definitions: Arc::new(RwLock::new(HashMap::new())),
|
||||
included_files: Arc::new(Mutex::new(HashSet::new())),
|
||||
include_stack: Arc::new(Mutex::new(Vec::new())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user