Skip to content

Commit

Permalink
Add support for variadic functions
Browse files Browse the repository at this point in the history
Signed-off-by: Filippo Costa <filippo@neysofu.me>
  • Loading branch information
neysofu authored and garritfra committed Dec 23, 2024
1 parent 37e31c7 commit becbc9a
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 12 deletions.
3 changes: 2 additions & 1 deletion examples/hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,16 @@ fn generate_main_func(module: &mut Module) {
Instr::Call(
"add".into(),
vec![(Type::Word, Value::Const(1)), (Type::Word, Value::Const(1))],
None,
),
);
// TODO: The example shows a variadic call. We don't have those yet
func.add_instr(Instr::Call(
"printf".into(),
vec![
(Type::Long, Value::Global("fmt".into())),
(Type::Word, Value::Temporary("r".into())),
],
Some(1),
));
func.add_instr(Instr::Ret(Some(Value::Const(0))));

Expand Down
22 changes: 11 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub enum Instr<'a> {
/// Unconditionally jumps to a label
Jmp(String),
/// Calls a function
Call(String, Vec<(Type<'a>, Value)>),
Call(String, Vec<(Type<'a>, Value)>, Option<u64>),
/// Allocates a 4-byte aligned area on the stack
Alloc4(u32),
/// Allocates a 8-byte aligned area on the stack
Expand Down Expand Up @@ -122,16 +122,16 @@ impl<'a> fmt::Display for Instr<'a> {
write!(f, "jnz {}, @{}, @{}", val, if_nonzero, if_zero)
}
Self::Jmp(label) => write!(f, "jmp @{}", label),
Self::Call(name, args) => {
write!(
f,
"call ${}({})",
name,
args.iter()
.map(|(ty, temp)| format!("{} {}", ty, temp))
.collect::<Vec<String>>()
.join(", "),
)
Self::Call(name, args, opt_variadic_i) => {
let mut args_fmt = args
.iter()
.map(|(ty, temp)| format!("{} {}", ty, temp))
.collect::<Vec<String>>();
if let Some(i) = *opt_variadic_i {
args_fmt.insert(i as usize, "...".to_string());
}

write!(f, "call ${}({})", name, args_fmt.join(", "),)
}
Self::Alloc4(size) => write!(f, "alloc4 {}", size),
Self::Alloc8(size) => write!(f, "alloc8 {}", size),
Expand Down
14 changes: 14 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,3 +266,17 @@ fn add_function_to_module() {

assert_eq!(module.functions.into_iter().next().unwrap(), function);
}

#[test]
fn variadic_call() {
let instr = Instr::Call(
"printf".into(),
vec![
(Type::Long, Value::Global("fmt".into())),
(Type::Word, Value::Const(0)),
],
Some(1),
);

assert_eq!(instr.to_string(), "call $printf(l $fmt, ..., w 0)");
}

0 comments on commit becbc9a

Please sign in to comment.