Implement #use directive for dependency management

Introduces the `#use` preprocessor directive, allowing Myc scripts to
explicitly declare dependencies on other Myc libraries. This change
moves dependency management from a command-line argument to an in-script
declaration, ensuring scripts are self-contained and can correctly
resolve macros and other symbols.

Key features include:
- Declarations at the beginning of a file, evaluated before parsing.
- Support for relative paths and a new `->` separator.
- Automatic resolution of dependencies from specified search paths.
- Idempotent loading to prevent duplicate parsing and evaluation.
- No AST pollution; dependency management is a compile-time concern.

The compiler's lexer has been updated to recognize `#` as a comment
character, and the environment now manages search paths and loaded
modules. This lays the groundwork for more complex library structures
and improved code organization.
This commit is contained in:
Michael Schimmel
2026-03-06 20:43:45 +01:00
parent d4ca9c4620
commit a59367ba61
7 changed files with 221 additions and 38 deletions
+12 -5
View File
@@ -45,12 +45,9 @@ fn main() {
let mut env = Environment::new();
env.optimization = !cli.no_opt;
// Load libraries
// Load libraries (Now just search paths)
for lib_path in &cli.lib {
if let Err(e) = env.load_library(lib_path) {
eprintln!("❌ Error loading library {:?}: {}", lib_path, e);
std::process::exit(1);
}
env.add_search_path(lib_path);
}
if cli.bench || cli.update_bench {
@@ -77,6 +74,11 @@ fn main() {
}
if let Some(script_str) = cli.eval {
if let Err(e) = env.preload_dependencies(&script_str, None) {
eprintln!("❌ Error resolving dependencies: {}", e);
std::process::exit(1);
}
if cli.dump {
match env.dump_ast(&script_str) {
Ok(dump) => println!("{}", dump),
@@ -90,6 +92,11 @@ fn main() {
} else if let Some(file_path) = cli.file {
match fs::read_to_string(&file_path) {
Ok(content) => {
if let Err(e) = env.preload_dependencies(&content, Some(&file_path)) {
eprintln!("❌ Error resolving dependencies for {:?}:\n{}", file_path, e);
std::process::exit(1);
}
if cli.dump {
match env.dump_ast(&content) {
Ok(dump) => println!("{}", dump),