-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(builder): add stuff needed for fib
- Loading branch information
Showing
8 changed files
with
350 additions
and
89 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#[no_mangle] | ||
pub fn fib(a: u32, b: u32, n: u32) -> u32 { | ||
if n == 0 { a } else { fib(b, a + b, n - 1) } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
use inkwell::values::{FunctionValue, InstructionValue}; | ||
|
||
use super::{CairoFunctionBuilder, CairoFunctionSignature, CairoParameter}; | ||
use crate::builder::get_name; | ||
|
||
impl<'ctx> CairoFunctionBuilder<'ctx> { | ||
/// Translate the LLVM function signature into a Cairo function signature. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `function` - The function we want to translate the signature of. | ||
/// * `fn_id` - Is the index of the function in our file but it can be any number it's just in | ||
/// case the llvm function name is empty. | ||
/// | ||
/// # Returns | ||
/// | ||
/// * `String` - The cairo function signature in the form | ||
/// `pub fn <name>(<param1>: <type1>,<param2>: <type2>,) -> <return_type>` | ||
pub fn process_function_signature( | ||
&mut self, | ||
function: &FunctionValue<'ctx>, | ||
fn_id: usize, | ||
) -> CairoFunctionSignature { | ||
// Get the function name and if it's empty call it "function{fn_id}" | ||
let name = get_name(function.get_name()).unwrap_or(format!("function{fn_id}")); | ||
let mut parameters = Vec::<CairoParameter>::with_capacity(function.count_params() as usize); | ||
// Extract each parameter and its type. | ||
function.get_param_iter().enumerate().for_each(|(index, param)| { | ||
let param_name = get_name(param.get_name()).unwrap_or(index.to_string()); | ||
let param_type = param.get_type().print_to_string().to_string(); | ||
self.variables.insert(param, param_name.clone()); | ||
parameters.push(CairoParameter { name: param_name, ty: param_type }); | ||
}); | ||
// Get the return type of the function. If it's Some it means that the function returns a value else | ||
// it returns void. | ||
let return_type = if let Some(ty) = function.get_type().get_return_type() { | ||
ty.print_to_string().to_string() | ||
} else { | ||
"()".to_string() | ||
}; | ||
CairoFunctionSignature::new(name, parameters, return_type) | ||
} | ||
|
||
/// Translate an LLVM Return instruction in cairo. | ||
pub fn process_return(&mut self, instruction: &InstructionValue) -> String { | ||
format!( | ||
"return {};", | ||
self.variables | ||
.get( | ||
&instruction | ||
.get_operand(0) | ||
.expect("Return opcode should have exactly 1 operand") | ||
.left() | ||
.expect("Return can only return a value hence left") | ||
) | ||
// TODO handle const | ||
.expect("Return a variable") | ||
) | ||
} | ||
} |
Oops, something went wrong.