Skip to content

Commit

Permalink
feat: builtin functions imported by default
Browse files Browse the repository at this point in the history
  • Loading branch information
vishruth-thimmaiah committed Nov 29, 2024
1 parent 6fad360 commit fc15b3f
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 14 deletions.
4 changes: 2 additions & 2 deletions examples/ex6.slpe
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import std:builtin

func main() u32 {
let u32[] a = [1, 2, 3]
let u32 b = builtin:len(a)
let u32[] a = [1, 2, 3, 2]
let u32 b = len(a)
return b
}
57 changes: 51 additions & 6 deletions src/llvm/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ use crate::{
parser::nodes::{ExpressionParserNode, FunctionCallParserNode, FunctionParserNode, ReturnNode},
};

use super::codegen::{CodeGen, FunctionStore};
use super::{
codegen::{CodeGen, FunctionStore},
stdlib_defs::get_builtin_function,
};

impl<'ctx> CodeGen<'ctx> {
pub fn add_function(&self, node: &FunctionParserNode) {
Expand Down Expand Up @@ -72,10 +75,7 @@ impl<'ctx> CodeGen<'ctx> {
if let Some(func) = get_stdlib_function(&internal_func_name) {
func
} else {
errors::compiler_error(&format!(
"Function '{}' not found in stdlib",
func_name
));
errors::compiler_error(&format!("Function '{}' not found in stdlib", func_name));
}
} else {
todo!("user defined functions are not supported yet");
Expand Down Expand Up @@ -108,15 +108,60 @@ impl<'ctx> CodeGen<'ctx> {
func
}

pub fn def_builtin(&self, func_name: &str) -> Option<FunctionValue<'ctx>> {
if let Some(func) = self.module.get_function(func_name) {
if func.get_linkage() == inkwell::module::Linkage::External {
return Some(func);
}
}
let internal_func_name = format!("__builtin__{}", func_name);

let func_def = if let Some(func_def) = get_builtin_function(&internal_func_name) {
func_def
} else {
return None;
};
let params = self.def_func_args(
&func_def
.args
.to_vec()
.iter()
.map(|p| (p.0.to_string(), p.1.clone()))
.collect::<Vec<_>>(),
);

let fn_type = if let Some(expr) = self.def_expr(&func_def.return_type) {
expr.fn_type(&params, false)
} else {
self.context.void_type().fn_type(&params, false)
};

let func = self.module.add_function(
&internal_func_name,
fn_type,
Some(inkwell::module::Linkage::External),
);

if let Some(exec_engine) = self.execution_engine.as_ref() {
exec_engine.add_global_mapping(&func, func_def.ptr);
}

Some(func)
}

pub fn add_func_call(
&self,
func_node: &FunctionCallParserNode,
func_name: &str,
) -> BasicValueEnum<'ctx> {
let function = if let Some(imported) = &func_node.imported {
self.def_extern(&func_node.func_name, imported)
} else if let Some(func) = self.module.get_function(&func_node.func_name) {
func
} else if let Some(func) = self.def_builtin(&func_node.func_name) {
func
} else {
self.module.get_function(&func_node.func_name).unwrap()
panic!("Function {} not found", func_node.func_name)
};
let mut args = Vec::new();
let params = function.get_params();
Expand Down
11 changes: 9 additions & 2 deletions src/llvm/stdlib_defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,16 @@ pub fn get_stdlib_function(name: &str) -> Option<StdLibFunc> {
return_type: &DATATYPE::NONE,
ptr: stdlib::io::__std__io__printflt as usize,
},
"__std__builtin__len" => StdLibFunc {
_ => return None,
};
Some(func)
}

pub fn get_builtin_function(name: &str) -> Option<StdLibFunc> {
let func = match name {
"__builtin__len" => StdLibFunc {
args: &[("arr", &DATATYPE::U32)],
ptr: stdlib::builtin::arrays::__std__builtin__len as usize,
ptr: stdlib::builtin::arrays::__builtin__len as usize,
return_type: &DATATYPE::U64,
},
_ => return None,
Expand Down
8 changes: 4 additions & 4 deletions stdlib/src/builtin/arrays.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#[repr(C)]
pub struct Array {
pub len: u64,
pub data: *const u32,
pub data: *const u32,
}

#[no_mangle]
pub extern "C" fn __std__builtin__len(arr: Array) -> u64 {
let len = unsafe { &*(arr.len as *const u64) };
return *len;
pub extern "C" fn __builtin__len(arr: *const Array) -> u64 {
let deref_arr = unsafe { &*(arr) };
return deref_arr.len;
}

0 comments on commit fc15b3f

Please sign in to comment.