]> rethought.computer Git - sorel-lang.git/commitdiff
relative imports, properly keep/51ad71ca38c5c7a3c536326a3cc1aa40ae91a428
authorBryan English <bryan@rethought.computer>
Thu, 8 Jan 2026 04:17:08 +0000 (23:17 -0500)
committerBryan English <bryan@rethought.computer>
Tue, 10 Feb 2026 04:08:54 +0000 (04:08 +0000)
hylo-lang/examples/fib.hylo
hylo-lang/hyloc/src/ir.rs

index 9057c6def4cdfbba0199fce2f6a193beb48e5a85..25f42056a51df74396c61e623ad6802c3b3bfb05 100644 (file)
@@ -1,4 +1,4 @@
-import "examples/put2.hylo"
+import "./put2.hylo"
 
 : fib 
     dup 1 > if
index db95898f6260743c91ee3ec4414a625839577caa..f1f5edf604094cf5b2b46729195191710ab9faba 100644 (file)
@@ -9,16 +9,20 @@ macro_rules! push_num {
     ($num:ident) => { IR::StackPush(*$num as u64) }
 }
 
-fn import(specifier: &str, imported: &mut HashSet<PathBuf>, is_entrypoint: bool) -> Option<ModuleWithImports> {
-    // TODO paths relative to the files, not just the invocation
-    let path = PathBuf::from(specifier).canonicalize().unwrap();    
+fn import(importer_dir: &PathBuf, specifier: &str, imported: &mut HashSet<PathBuf>, is_entrypoint: bool) -> Option<ModuleWithImports> {
+    let mut path = PathBuf::from(specifier);
+    if path.is_relative() {
+        let mut new_path = importer_dir.clone();
+        new_path.push(path);
+        path = new_path.canonicalize().unwrap();
+    }
     if imported.contains(&path) {
         return None;
     }
 
     let contents = std::fs::read_to_string(&path).unwrap();
 
-    Some(generate_internal(&Module::parse(tokenize(&contents), is_entrypoint), imported))
+    Some(generate_internal(path, &Module::parse(tokenize(&contents), is_entrypoint), imported))
 }
 
 fn collapse_module(mut module_w: ModuleWithImports) -> IRModule {
@@ -53,17 +57,17 @@ fn collapse_module(mut module_w: ModuleWithImports) -> IRModule {
 
 pub fn compile(path: &str) -> IRModule {
     let mut imported = HashSet::new();
-    let module = import(path, &mut imported, true).unwrap();
+    let module = import(&std::env::current_dir().unwrap(), path, &mut imported, true).unwrap();
     collapse_module(module) // TODO remove unused words 
 }
 
 #[derive(Debug)]
 struct ModuleWithImports {
     module: Option<IRModule>,
-    imports: Option<Vec<ModuleWithImports>>
+    imports: Option<Vec<ModuleWithImports>>,
 }
 
-fn generate_internal(module: &Module, imported: &mut HashSet<PathBuf>) -> ModuleWithImports {
+fn generate_internal(path: PathBuf, module: &Module, imported: &mut HashSet<PathBuf>) -> ModuleWithImports {
     // Eventually these will end up being sections in assembly
     let mut text = vec![];
     let mut data = vec![];
@@ -100,7 +104,7 @@ fn generate_internal(module: &Module, imported: &mut HashSet<PathBuf>) -> Module
                 },
                 Token::String(text) => {
                     if last_was_import {
-                        if let Some(module) = import(text, imported, false) {
+                        if let Some(module) = import(&path.parent().unwrap().to_path_buf(), text, imported, false) {
                             imports.push(module);
                         }
                         IR::ImportString // This will be elided later
@@ -146,6 +150,6 @@ fn generate_internal(module: &Module, imported: &mut HashSet<PathBuf>) -> Module
             text: text.into_iter().flatten().collect::<Vec<_>>(),
             data,
         }),
-        imports: Some(imports)
+        imports: Some(imports),
     }
 }