Remove unused system library and simplify environment initialization

The `system.myc` file, containing macros and core utilities, has been
removed as its functionality is now handled by an embedded string. This
simplifies the build process and eliminates a file that was no longer
strictly necessary.

Additionally, the `with_cwd()` method on the `Environment` has been
removed. The environment now automatically adds the current working
directory and its `rtl` subdirectory to the search paths during
initialization. This streamlines the setup for file-based usage and
ensures standard search paths are always considered.
This commit is contained in:
Michael Schimmel
2026-03-08 13:09:53 +01:00
parent 4dfdc75545
commit b622f7f8bd
6 changed files with 42 additions and 98 deletions
+32 -26
View File
@@ -19,7 +19,6 @@ use crate::ast::compiler::macros::{MacroEvaluator, MacroExpander, MacroRegistry}
use crate::ast::compiler::optimizer::Optimizer;
use crate::ast::compiler::specializer::{FunctionRegistry, MonoCache, Specializer};
use crate::ast::compiler::tco::{ExecNode, TCO};
use crate::ast::rtl;
use crate::ast::rtl::intrinsics;
use crate::ast::types::{
Identity, NodeIdentity, Object, Purity, SourceLocation, StaticType, Value,
@@ -28,6 +27,9 @@ use crate::ast::types::{
use crate::ast::diagnostics::{DiagnosticLevel, Diagnostics};
pub type PipelineGenerator = Box<dyn FnMut() -> bool>;
const SYSTEM_LIB_SOURCE: &str = include_str!("system.myc");
const SYSTEM_LIB_PATH: &str = "<embedded>/system.myc";
pub struct CompilationResult {
pub ast: Option<TypedNode>,
pub diagnostics: Diagnostics,
@@ -169,22 +171,18 @@ impl Environment {
search_paths: Rc::new(RefCell::new(Vec::new())),
loaded_modules: Rc::new(RefCell::new(HashSet::new())),
};
env.register_stdlib();
env
}
crate::ast::rtl::register(&env);
/// Adds the current working directory to the global search paths.
/// This is a builder method to easily initialize an environment for file-based usage.
pub fn with_cwd(self) -> Self {
// Automatically add standard search paths (CWD and CWD/rtl)
if let Ok(cwd) = std::env::current_dir() {
self.add_search_path(&cwd);
// Also add the rtl subdirectory if it exists
env.add_search_path(&cwd);
let rtl_path = cwd.join("rtl");
if rtl_path.exists() {
self.add_search_path(rtl_path);
env.add_search_path(rtl_path);
}
}
self
env
}
pub fn add_search_path(&self, path: impl AsRef<Path>) {
@@ -276,16 +274,7 @@ impl Environment {
base_path: &Path,
all_files: &mut Vec<(PathBuf, Node<UntypedKind>)>,
) -> Result<(), String> {
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());
}
let directives = self.extract_use_directives(source);
for module_path in directives {
let abs_paths = self.resolve_module_paths(&module_path, base_path)?;
@@ -352,7 +341,23 @@ impl Environment {
pub fn preload_dependencies(&self, source: &str, file_path: Option<&Path>) -> Result<(), String> {
let base_path = file_path.and_then(|p| p.parent()).unwrap_or_else(|| Path::new("."));
let mut files = Vec::new();
// 1. Always load the embedded system library first as a virtual module
let system_path = PathBuf::from(SYSTEM_LIB_PATH);
if !self.loaded_modules.borrow().contains(&system_path) {
self.loaded_modules.borrow_mut().insert(system_path.clone());
let mut parser = Parser::new(SYSTEM_LIB_SOURCE);
let untyped_ast = parser.parse_expression();
if parser.diagnostics.has_errors() {
return Err(format!(
"Failed to parse embedded system library:\n{}",
parser.diagnostics.items[0].message
));
}
files.push((system_path, untyped_ast));
}
// 2. Collect dependencies from the main source
self.collect_dependencies(source, base_path, &mut files)?;
// Pass 1: Discovery (Globals and Macros)
@@ -463,7 +468,7 @@ impl Environment {
Some(checker.check(&wrapped_ast, &[], diagnostics))
}
pub fn compile_untyped(&self, untyped_ast: Node<UntypedKind>) -> Result<TypedNode, String> {
fn compile_untyped(&self, untyped_ast: Node<UntypedKind>) -> Result<TypedNode, String> {
let mut diagnostics = Diagnostics::new();
let typed_ast_opt = self.compile_pipeline(untyped_ast, &mut diagnostics);
@@ -530,9 +535,6 @@ impl Environment {
values.push(val);
}
fn register_stdlib(&self) {
rtl::register(self);
}
pub fn dump_ast(&self, source: &str) -> Result<String, String> {
self.preload_dependencies(source, None)?;
@@ -542,6 +544,10 @@ impl Environment {
}
pub fn compile(&self, source: &str) -> CompilationResult {
if let Err(e) = self.preload_dependencies(source, None) {
return CompilationResult::error(format!("Dependency Error: {}", e));
}
let mut parser = Parser::new(source);
let untyped_ast = parser.parse_expression();