]> rethought.computer Git - sorel-lang.git/commitdiff
make imports actually work keep/7a8075bd221c17ae24fabc0462659b3bedbb7be5
authorBryan English <bryan@rethought.computer>
Thu, 8 Jan 2026 04:15:53 +0000 (23:15 -0500)
committerBryan English <bryan@rethought.computer>
Tue, 10 Feb 2026 04:08:54 +0000 (04:08 +0000)
hylo-lang/examples/fib.hylo
hylo-lang/examples/put2.hylo [new file with mode: 0644]
hylo-lang/hyloc/src/ir.rs
hylo-lang/hyloc/src/parser.rs
hylo-lang/hyloc/src/tokenizer.rs

index e59b34e2aafcd959ceb815c70b478232a4c8c648..9057c6def4cdfbba0199fce2f6a193beb48e5a85 100644 (file)
@@ -1,3 +1,4 @@
+import "examples/put2.hylo"
 
 : fib 
     dup 1 > if
@@ -18,3 +19,5 @@
 8 fib putn
 9 fib putn
 10 fib putn
+
+5 fib 6 fib put2
diff --git a/hylo-lang/examples/put2.hylo b/hylo-lang/examples/put2.hylo
new file mode 100644 (file)
index 0000000..440f50f
--- /dev/null
@@ -0,0 +1 @@
+: put2 putn putn ; 
index e3d23e7c645369935516dd6618d899cac772c55d..db95898f6260743c91ee3ec4414a625839577caa 100644 (file)
@@ -9,7 +9,7 @@ macro_rules! push_num {
     ($num:ident) => { IR::StackPush(*$num as u64) }
 }
 
-fn import(specifier: &str, imported: &mut HashSet<PathBuf>) -> Option<ModuleWithImports> {
+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();    
     if imported.contains(&path) {
@@ -18,7 +18,7 @@ fn import(specifier: &str, imported: &mut HashSet<PathBuf>) -> Option<ModuleWith
 
     let contents = std::fs::read_to_string(&path).unwrap();
 
-    Some(generate_internal(&Module::parse(tokenize(&contents)), imported))
+    Some(generate_internal(&Module::parse(tokenize(&contents), is_entrypoint), imported))
 }
 
 fn collapse_module(mut module_w: ModuleWithImports) -> IRModule {
@@ -44,7 +44,7 @@ fn collapse_module(mut module_w: ModuleWithImports) -> IRModule {
 
         prev_data_len += mod_data_len;
     });
-
+    
     IRModule {
         data,
         text,
@@ -53,10 +53,11 @@ 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).unwrap();
+    let module = import(path, &mut imported, true).unwrap();
     collapse_module(module) // TODO remove unused words 
 }
 
+#[derive(Debug)]
 struct ModuleWithImports {
     module: Option<IRModule>,
     imports: Option<Vec<ModuleWithImports>>
@@ -99,7 +100,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) {
+                        if let Some(module) = import(text, imported, false) {
                             imports.push(module);
                         }
                         IR::ImportString // This will be elided later
@@ -124,6 +125,13 @@ fn generate_internal(module: &Module, imported: &mut HashSet<PathBuf>) -> Module
                 _ => false,
             };
             mapped_ir
+        }).filter(|ir| {
+            // Elide IRs that shouldn't actually be in the output IR.
+            match ir {
+                IR::Import => false,
+                IR::ImportString => false,
+                _ => true,
+            }
         }).collect::<Vec<_>>();
 
         let mut result = vec![IR::Label(def.name.to_string())];
@@ -138,6 +146,6 @@ fn generate_internal(module: &Module, imported: &mut HashSet<PathBuf>) -> Module
             text: text.into_iter().flatten().collect::<Vec<_>>(),
             data,
         }),
-        imports: Some(Vec::new()) // TODO
+        imports: Some(imports)
     }
 }
index e678e1462370b727d7e6473931295492270482f2..040a03fc2c93de758a403551cb4cab0d278a2725 100644 (file)
@@ -12,7 +12,7 @@ pub struct Module<'a> {
 }
 
 impl<'a> Module<'a> {
-    pub fn parse(input: Vec<Token<'a>>) -> Self {
+    pub fn parse(input: Vec<Token<'a>>, is_entrypoint: bool) -> Self {
         let mut result = vec![];
         let mut main = vec![];
         let mut current_word: Option<WordDefinition> = None;
@@ -55,10 +55,12 @@ impl<'a> Module<'a> {
             panic!("unfinished word definition!");
         }
 
-        result.push(WordDefinition {
-            name: "main",
-            instructions: main,
-        });
+        if is_entrypoint {
+            result.push(WordDefinition {
+                name: "main",
+                instructions: main,
+            });
+        }
 
         Module { words: result }
     }
@@ -87,7 +89,7 @@ mod tests {
 : soup chicken 4.5 hello ;
 
 hello soup
-"));
+"), true);
         result.debug_print();
     }
 }
index b2e79b0adcb899d86cd28d7ec55ed44935fb16df..dbc764a41844db52ee9517f7a0bd010aff6f607f 100644 (file)
@@ -61,7 +61,7 @@ pub fn tokenize<'a>(input: &'a str) -> Vec<Token<'a>> {
     let mut string_start: Option<usize> = None;
     let mut word_or_num_start: Option<usize> = None;
     let mut last_is_escape = false;
-    let mut last_is_whitespace = false;
+    let mut last_is_whitespace = true;
     let mut in_comment = false;
     let mut index = 0;
     let mut first_char = true;