Refactor: Introduce system library
- Add `rtl/system.myc` as the system library, containing core utilities like `while` and `cache`. - Remove the duplicate `prelude.myc` from `src/ast/rtl/`. - Modify `Environment::collect_dependencies` to implicitly add `#use system` when necessary. - Update `Environment::with_cwd` to also add the `rtl` subdirectory to search paths. - Add `target/` to `.geminiignore` to exclude build artifacts. - Adjust example `sma.myc` to use the new `cache` macro and reduce sample data size. - Update `rtl/sma.myc` to correctly initialize the `history` series with its `length`. - Add `preload_dependencies` calls to `dump_ast` and `run_script` for proper module loading.
This commit is contained in:
+19
-13
@@ -177,7 +177,12 @@ impl Environment {
|
||||
/// This is a builder method to easily initialize an environment for file-based usage.
|
||||
pub fn with_cwd(self) -> Self {
|
||||
if let Ok(cwd) = std::env::current_dir() {
|
||||
self.add_search_path(cwd);
|
||||
self.add_search_path(&cwd);
|
||||
// Also add the rtl subdirectory if it exists
|
||||
let rtl_path = cwd.join("rtl");
|
||||
if rtl_path.exists() {
|
||||
self.add_search_path(rtl_path);
|
||||
}
|
||||
}
|
||||
self
|
||||
}
|
||||
@@ -213,15 +218,6 @@ impl Environment {
|
||||
MacroExpander::new(self.macro_registry.borrow().clone(), evaluator)
|
||||
}
|
||||
|
||||
fn eval_prelude(&self, source: &str) {
|
||||
let mut parser = crate::ast::parser::Parser::new(source);
|
||||
let untyped_ast = parser.parse_expression();
|
||||
let mut expander = self.get_expander();
|
||||
let _ = expander
|
||||
.expand(untyped_ast)
|
||||
.expect("Failed to expand prelude");
|
||||
*self.macro_registry.borrow_mut() = expander.into_registry();
|
||||
}
|
||||
|
||||
/// Resolves a #use module path relative to a base path, then falls back to search paths.
|
||||
/// Returns a list of all matching .myc files (single file, or all files in a directory).
|
||||
@@ -274,14 +270,22 @@ impl Environment {
|
||||
Err(format!("Could not find module or directory '{}'", module_path))
|
||||
}
|
||||
|
||||
/// Recursively collects all dependencies starting from a given source string.
|
||||
fn collect_dependencies(
|
||||
&self,
|
||||
source: &str,
|
||||
base_path: &Path,
|
||||
all_files: &mut Vec<(PathBuf, Node<UntypedKind>)>,
|
||||
) -> Result<(), String> {
|
||||
let directives = self.extract_use_directives(source);
|
||||
let mut directives = self.extract_use_directives(source);
|
||||
|
||||
// Implicitly add #use system if it's not already there and we can resolve it.
|
||||
// This is only done for the root script (when loaded_modules is empty) to avoid redundancy.
|
||||
if !directives.contains(&"system".to_string())
|
||||
&& self.loaded_modules.borrow().is_empty()
|
||||
&& self.resolve_module_paths("system", base_path).is_ok()
|
||||
{
|
||||
directives.insert(0, "system".to_string());
|
||||
}
|
||||
|
||||
for module_path in directives {
|
||||
let abs_paths = self.resolve_module_paths(&module_path, base_path)?;
|
||||
@@ -528,10 +532,10 @@ impl Environment {
|
||||
|
||||
fn register_stdlib(&self) {
|
||||
rtl::register(self);
|
||||
self.eval_prelude(include_str!("rtl/prelude.myc"));
|
||||
}
|
||||
|
||||
pub fn dump_ast(&self, source: &str) -> Result<String, String> {
|
||||
self.preload_dependencies(source, None)?;
|
||||
let compiled = self.compile(source).into_result()?;
|
||||
let linked = self.link(compiled);
|
||||
Ok(Dumper::dump(&linked))
|
||||
@@ -717,6 +721,7 @@ impl Environment {
|
||||
}
|
||||
|
||||
pub fn run_script(&self, source: &str) -> Result<Value, String> {
|
||||
self.preload_dependencies(source, None)?;
|
||||
if self.debug_mode {
|
||||
let (res, logs) = self.run_debug(source)?;
|
||||
for line in logs {
|
||||
@@ -739,6 +744,7 @@ impl Environment {
|
||||
}
|
||||
|
||||
pub fn run_debug(&self, source: &str) -> Result<(Result<Value, String>, Vec<String>), String> {
|
||||
self.preload_dependencies(source, None)?;
|
||||
let compiled = self.compile(source).into_result()?;
|
||||
let linked = self.link(compiled);
|
||||
let mut vm = VM::new(self.global_values.clone());
|
||||
|
||||
Reference in New Issue
Block a user