From 45a5a2fb253b07906540ee6a5fb723a640bd2576 Mon Sep 17 00:00:00 2001 From: Bryan English Date: Thu, 12 Feb 2026 09:19:06 -0500 Subject: [PATCH] function pointers --- sorel-ir/src/lib.rs | 2 ++ sorelc/src/ir.rs | 13 ++++++++++++- sorelc/src/riscv_asm_codegen.rs | 11 +++++++++++ tests/test1.sorel | 6 ++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/sorel-ir/src/lib.rs b/sorel-ir/src/lib.rs index d4e8e8f..35970e9 100644 --- a/sorel-ir/src/lib.rs +++ b/sorel-ir/src/lib.rs @@ -5,6 +5,8 @@ use serde_derive::{Serialize, Deserialize}; pub enum IR { Label(String), Call(String), + WordPointer(String), + CallPtr, Ret, StackPush(u64), StackPushString(String), // refers to string label, not the string itself diff --git a/sorelc/src/ir.rs b/sorelc/src/ir.rs index 7324af7..7b931c4 100644 --- a/sorelc/src/ir.rs +++ b/sorelc/src/ir.rs @@ -181,6 +181,7 @@ impl ImportTree { "endif" => IR::EndIf, "loop" => IR::Loop, "endloop" => IR::EndLoop, + "call" => IR::CallPtr, "=" => IR::Equals, ">" => IR::GreaterThan, "<" => IR::LessThan, @@ -198,7 +199,14 @@ impl ImportTree { "sys5" => IR::Sys5, "sys6" => IR::Sys6, // TODO num type specfic math like `+:i32`, etc. - _ => IR::Call(String::from(*word)) + _ => { + if word.starts_with("'") { + let actual_word = &word[1..]; + IR::WordPointer(String::from(actual_word)) + } else { + IR::Call(String::from(*word)) + } + } } }, Token::String(text) => { @@ -284,6 +292,9 @@ impl ImportTree { IR::Call(name) => { IR::Call(module.get_label_for_call(name)) }, + IR::WordPointer(name) => { + IR::WordPointer(module.get_label_for_call(name)) + }, _ => instruction.clone() }; self.text.push(new_instruction); diff --git a/sorelc/src/riscv_asm_codegen.rs b/sorelc/src/riscv_asm_codegen.rs index 23fba90..e9b0e86 100644 --- a/sorelc/src/riscv_asm_codegen.rs +++ b/sorelc/src/riscv_asm_codegen.rs @@ -161,6 +161,17 @@ impl<'a> CodeGen<'a> { self.label(format!("# call {}", mangled)); self.line(format!("call {}", mangled)); }, + IR::WordPointer(name) => { + let mangled = mangle(name); + self.label(format!("# '{} (word pointer)", mangled)); + self.line(format!("la t0, {}", mangled)); + self.push_from("t0"); + }, + IR::CallPtr => { + self.label("# callptr"); + self.pop_to("t0"); + self.line("jalr t0"); + }, IR::Ret => { if last_label == "main" { self.label("# exit 0 syscall"); diff --git a/tests/test1.sorel b/tests/test1.sorel index ca868a4..dd01bd7 100644 --- a/tests/test1.sorel +++ b/tests/test1.sorel @@ -32,3 +32,9 @@ puts \ ( ptr ) free \ ( ) 42 43 44 "soup" putstack + +: hello_world_again + "Hello World, Again!\n" puts drop +; + +'hello_world_again call -- 2.43.0