]> rethought.computer Git - sorel-lang.git/commitdiff
support variables
authorBryan English <bryan@rethought.computer>
Thu, 19 Feb 2026 06:03:51 +0000 (01:03 -0500)
committerBryan English <bryan@rethought.computer>
Thu, 19 Feb 2026 06:04:30 +0000 (01:04 -0500)
sorel-codegen/src/riscv64_asm.rs
sorel-ir/src/ir.rs
sorelc/src/import_tree.rs
tests/test1.sorel

index de724352e5aec877d826385bd77f903dfb0a4cbc..692eca0154dc2f6cb88563fde9911617a9590cdf 100644 (file)
@@ -122,13 +122,6 @@ impl<'a> CodeGen<'a> {
             }
         }
 
-        // Data stack
-        self.label(".data\n");
-        self.label(".align 3\n");
-        self.label("data_stack:");
-        self.line(format!(".space {}", self.data_stack_size));
-        self.label(".globl data_stack_end\ndata_stack_end:\n");
-
         // Code
         self.label(".text\n");
         self.label(".align 3\n");
@@ -139,6 +132,7 @@ impl<'a> CodeGen<'a> {
         let mut loop_stack = vec![];
         let mut seen_else = HashSet::new();
         let mut last_label = "";
+        let mut var_decls = vec![];
 
         for ir in &self.module.text {
             match ir {
@@ -184,6 +178,14 @@ impl<'a> CodeGen<'a> {
                         self.line("ret");
                     }
                 },
+                IR::VarDecl(name) => {
+                    var_decls.push(name);
+                },
+                IR::StackPushVar(name) => {
+                    self.label(format!("# stackpushvar {}", name));
+                    self.line(format!("la t0, {}", name));
+                    self.push_from("t0");
+                },
                 IR::Load8 => {
                     self.label("# load 8");
                     self.copy_top_stack_value_to("t0");
@@ -380,6 +382,17 @@ impl<'a> CodeGen<'a> {
             }
         }
 
+        // Data stack
+        self.label(".bss\n");
+        self.label(".align 3\n");
+        self.label("data_stack:");
+        self.line(format!(".space {}", self.data_stack_size));
+        self.label(".globl data_stack_end\ndata_stack_end:\n");
+        for decl in var_decls {
+            self.label(format!("{}:", decl));
+            self.line(".space 8");
+        }
+
         Ok(self.lines.join("\n"))
     }
 }
index 15cbde073747be28dc27a792ce830eef0120952a..aa2dde053e52e595e8d2591b89be68f8a534fd52 100644 (file)
@@ -5,6 +5,8 @@ pub enum IR {
     Label(String),
     Call(String),
     WordPointer(String),
+    VarDecl(String),
+    StackPushVar(String),
     CallPtr,
     Ret,
     StackPush(u64),
index 9c6896ba508f0693ea017015c3efaa995d2fda17..6ac87d1c271d7eefe44f44223448bda845923a17 100644 (file)
@@ -95,16 +95,44 @@ impl ImportTree {
 
         let externs = module.externs.iter().map(|s| s.to_string()).collect();
 
-        text.push(module.words.iter().flat_map(|def| {
-            let mut body = def.instructions.iter().map(|inst| {
-                IR::from_token(inst, &mut data)
-            }).collect::<Vec<_>>();
+        module.words.iter().try_for_each(|def| -> Result<(), anyhow::Error> {
+            let mut body = vec![];
+            let mut last_call_was_var = false;
+            let mut vars = vec![];
+            def.instructions.iter().try_for_each(|inst| {
+                let new_token = IR::from_token(inst, &mut data);
+                if let IR::Call(thing) = new_token {
+                    if thing == "var" {
+                        last_call_was_var = true;
+                    } else {
+                        if last_call_was_var {
+                            body.push(IR::VarDecl(thing.clone()));
+                            vars.push(thing);
+                            last_call_was_var = false;
+                        } else {
+                            if vars.contains(&thing) {
+                                body.push(IR::StackPushVar(thing));
+                            } else {
+                                body.push(IR::Call(thing));
+                            }
+                        }
+                    }
+                } else {
+                    if last_call_was_var {
+                        bail!("word must come after var!")
+                    } else {
+                        body.push(new_token);
+                    }
+                }
+                Ok(())
+            })?;
 
             let mut result = vec![IR::Label(def.name.to_string())];
             result.append(&mut body);
             result.push(IR::Ret);
-            result
-        }).collect::<Vec<_>>());
+            text.push(result);
+            Ok(())
+        })?;
 
         let number = self.module_count;
         self.module_count += 1;
@@ -142,6 +170,7 @@ impl ImportTree {
             }
         }
 
+        let mut last_label_name = String::from("");
         for instruction in &module.text {
             let new_instruction = match instruction {
                 IR::StackPushString(name) => {
@@ -150,11 +179,20 @@ impl ImportTree {
                 },
                 IR::Label(name) => {
                     if is_entrypoint && name == "main" {
+                        last_label_name = String::from("main");
                         instruction.clone()
                     } else {
+                        let label_name = module.get_label(name);
+                        last_label_name = label_name.clone();
                         IR::Label(module.get_label(name))
                     }
                 },
+                IR::VarDecl(name) => {
+                    IR::VarDecl(format!("_var_{}_{}", last_label_name, name))
+                },
+                IR::StackPushVar(name) => {
+                    IR::StackPushVar(format!("_var_{}_{}", last_label_name, name))
+                },
                 IR::Call(name) => {
                     IR::Call(module.get_label_for_call(name))
                 },
index dd01bd7478e6e2982dd73d3ec7e47e75c1088424..ccd1f9315bca3702d53cbd616ecccdb906ecf967 100644 (file)
@@ -38,3 +38,22 @@ free \ ( )
 ;
 
 'hello_world_again call
+
+: get_my_var
+  var my_var
+  my_var
+;
+
+: test_variables
+  get_my_var
+  dup
+  @
+  1 +
+  swap
+  !
+; 
+
+test_variables test_variables
+get_my_var @ putn
+test_variables
+get_my_var @ putn