//! 模块系统:require() 加载器 //! //! `require("path/to/module.ast")` 加载并执行指定的 Aster 文件, //! 返回一个包含模块所有顶层定义的 `Value::Object`。 //! 模块在自己的作用域中执行,只能访问内置函数,无法访问调用者的变量。 //! 第二次 require 同一文件会返回缓存的对象。 use crate::error::RuntimeError; use crate::lexer::Lexer; use crate::parser::Parser; use super::{Interpreter, Env, Value, Signal, Runtime}; use std::cell::RefCell; use std::collections::HashMap; use std::path::Path; use std::rc::Rc; impl Runtime for Interpreter { fn require(&mut self, path: &str) -> Result { require_impl(self, path) } } /// require() 的内置函数实现 — 薄包装,委托给 Runtime::require pub fn require_fn(runtime: &mut dyn Runtime, args: Vec) -> Result { let path_str = match args.first() { Some(Value::String(s)) => s.clone(), Some(other) => return Err(runtime_error(format!( "require() expects a string argument, got {}", other))), None => return Err(runtime_error( "require() expects 1 argument (string path)")), }; runtime.require(&path_str) } /// require() 的内部实现 (供 Interpreter::require 使用) fn require_impl(interp: &mut Interpreter, path_str: &str) -> Result { // 1. 路径解析 let resolved = resolve_path(&interp.current_dir, path_str)?; // 2. 缓存查找 if let Some(cached) = interp.module_cache.borrow().get(&resolved) { return Ok(cached.clone()); } // 3. 读取文件 let src = std::fs::read_to_string(&resolved) .map_err(|e| runtime_error(format!( "Module '{}' not found: {}", path_str, e)))?; // 4. 词法分析 let (tokens, lex_errors) = Lexer::new(&src).tokenize(); if !lex_errors.is_empty() { return Err(runtime_error(format!( "Lex error in module '{}': {}", path_str, lex_errors[0]))); } // 5. 语法分析 let mut parser = Parser::new(tokens); let (stmts, parse_errors) = parser.parse(); if !parse_errors.is_empty() { return Err(runtime_error(format!( "Parse error in module '{}': {}", path_str, parse_errors[0]))); } // 6. 创建隔离的模块 env(父级 = builtins_env,看不到调用者的变量) let module_env = Rc::new(RefCell::new(Env::new(Some(Rc::clone(&interp.builtins_env))))); // 7. 在缓存中插入占位符(支持循环 require) let exports_map = Rc::new(RefCell::new(HashMap::new())); let exports = Value::Object(Rc::clone(&exports_map)); interp.module_cache.borrow_mut().insert(resolved.clone(), exports.clone()); // 8. 保存调用者状态 let previous_env = Rc::clone(&interp.env); let previous_dir = interp.current_dir.clone(); // 9. 切换到模块上下文 interp.env = module_env.clone(); interp.current_dir = module_dir(&resolved); // 10. 执行模块 for stmt in &stmts { match interp.execute(stmt.clone()) { Ok(Signal::Break) | Ok(Signal::Continue) => { interp.env = previous_env; interp.current_dir = previous_dir; interp.module_cache.borrow_mut().remove(&resolved); return Err(runtime_error( "break/continue outside of loop in module")); } Err(e) => { interp.env = previous_env; interp.current_dir = previous_dir; interp.module_cache.borrow_mut().remove(&resolved); return Err(e); } Ok(Signal::None) | Ok(Signal::Return(_)) => {} } } // 11. 恢复调用者状态 interp.env = previous_env; interp.current_dir = previous_dir; // 12. 收集 exports(模块 env 中的所有直接绑定) for (name, (val, _mutable)) in module_env.borrow().values.clone() { exports_map.borrow_mut().insert(name, val); } Ok(exports) } // ============================================================================ // Helpers // ============================================================================ fn resolve_path(current_dir: &str, path_str: &str) -> Result { let path = Path::new(path_str); let resolved = if path.is_absolute() { path.to_path_buf() } else { Path::new(current_dir).join(path) }; std::fs::canonicalize(&resolved) .map(|p| p.to_string_lossy().to_string()) .map_err(|_| runtime_error(format!( "Module '{}' not found (resolved to '{}')", path_str, resolved.display()))) } fn module_dir(resolved: &str) -> String { Path::new(resolved) .parent() .map(|p| p.to_string_lossy().to_string()) .unwrap_or_else(|| ".".to_string()) } fn runtime_error(msg: impl Into) -> RuntimeError { RuntimeError::RuntimeError { message: msg.into(), token: None, } }