use super::{CodeGen, CodegenResult};
use inkwell::values::PointerValue;
impl<'ctx> CodeGen<'ctx> {
pub fn compile_builtin(
&mut self,
name: &str,
stack: PointerValue<'ctx>,
) -> CodegenResult<Option<PointerValue<'ctx>>> {
match name {
"dup" => self.compile_runtime_call("dup", stack),
"drop" => self.compile_runtime_call("drop", stack),
"swap" => self.compile_runtime_call("swap", stack),
"over" => self.compile_runtime_call("over", stack),
"rot" => self.compile_runtime_call("rot", stack),
"+" => self.compile_runtime_call("add", stack),
"-" => self.compile_runtime_call("subtract", stack),
"*" => self.compile_runtime_call("multiply", stack),
"/" => self.compile_runtime_call("divide", stack),
"<" => self.compile_runtime_call("less_than", stack),
">" => self.compile_runtime_call("greater_than", stack),
"=" => self.compile_runtime_call("equal", stack),
"call" => self.compile_runtime_call("call_quotation", stack),
"if" => self.compile_runtime_call("if_then_else", stack),
_ => Ok(None),
}
}
fn compile_runtime_call(
&mut self,
fn_name: &str,
stack: PointerValue<'ctx>,
) -> CodegenResult<Option<PointerValue<'ctx>>> {
let result = self.call_runtime(fn_name, &[stack.into()])?;
Ok(Some(result))
}
}
pub const PRIMITIVES: &[&str] = &[
"dup", "drop", "swap", "over", "rot",
"+", "-", "*", "/",
"<", ">", "=",
"call", "if",
];
pub fn is_primitive(name: &str) -> bool {
PRIMITIVES.contains(&name)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_primitive() {
assert!(is_primitive("dup"));
assert!(is_primitive("+"));
assert!(is_primitive("<"));
assert!(!is_primitive("custom_word"));
}
}