Add structure and inductive examples

This commit is contained in:
Leni Aniva 2024-03-07 21:37:37 -08:00
parent 1f8807a809
commit 01a51b4e08
Signed by: aniva
GPG Key ID: 4D9B1C8D10EA4C50
2 changed files with 99 additions and 8 deletions

View File

@ -1,3 +1,19 @@
@[export my_function] @[export my_function]
def my_function (s: String): String := def my_function (s: String): String :=
s ++ s!"abc" s ++ s!" at callee"
-- Formats a string in 3 different forms
@[export stylize]
def stylize (s: String): (String × String × String) :=
(s.capitalize, s.decapitalize, s.toUpper)
inductive Think where
| Success (s: String)
| Failure (i: Nat)
@[export think]
def think (s: String): Think :=
if s.front == 'S' then
Think.Success (s.drop 1)
else
Think.Failure s.length

View File

@ -19,11 +19,14 @@ mod callee {
#[link(name = "Callee")] #[link(name = "Callee")]
extern "C" { extern "C" {
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn initialize_Callee(builtin: u8, world: *mut lean_object) -> *mut lean_object; pub fn initialize_Callee(builtin: u8, world: lean_obj_arg) -> lean_obj_res;
pub fn my_function(s: lean_obj_arg) -> lean_obj_arg; pub fn my_function(s: lean_obj_arg) -> lean_obj_res;
pub fn stylize(s: lean_obj_arg) -> lean_obj_res;
pub fn think(s: lean_obj_arg) -> lean_obj_res;
} }
} }
fn main() {
fn initialize() {
unsafe { unsafe {
lean::lean_initialize_runtime_module(); lean::lean_initialize_runtime_module();
lean::lean_initialize(); lean::lean_initialize();
@ -38,9 +41,10 @@ fn main() {
} }
lean::lean_io_mark_end_initialization(); lean::lean_io_mark_end_initialization();
} }
println!("Lean initialization complete!"); }
let c_str = std::ffi::CString::new("hello ").unwrap(); fn call_my_function() {
let c_str = std::ffi::CString::new("hello").unwrap();
let result = unsafe { let result = unsafe {
let native_str = lean::lean_mk_string(c_str.as_ptr()); let native_str = lean::lean_mk_string(c_str.as_ptr());
let result_obj = callee::my_function(native_str); let result_obj = callee::my_function(native_str);
@ -50,6 +54,77 @@ fn main() {
lean::lean_dec(result_obj); lean::lean_dec(result_obj);
str str
}; };
assert_eq!(result, "hello at callee");
println!("result: {result}"); }
fn unbox_lean_string(str: lean::b_lean_obj_arg) -> String {
unsafe { std::ffi::CStr::from_ptr(lean::lean_string_cstr(str)) }
.to_str()
.expect("Failed to convert C-string to string")
.to_string()
}
fn call_stylize() {
let input = std::ffi::CString::new("aBcDe").unwrap();
let (s1, s2, s3) = unsafe {
let result_obj = callee::stylize(lean::lean_mk_string(input.as_ptr()));
assert!(lean::lean_is_ctor(result_obj), "Tuple must be a ctor");
// Remember Lean tuples are nested!
assert_eq!(
lean::lean_ctor_num_objs(result_obj),
2,
"Tuple ctor has 3 elements"
);
let s1 = unbox_lean_string(lean::lean_ctor_get(result_obj, 0));
let result_obj2 = lean::lean_ctor_get(result_obj, 1);
let s2 = unbox_lean_string(lean::lean_ctor_get(result_obj2, 0));
let s3 = unbox_lean_string(lean::lean_ctor_get(result_obj2, 1));
lean::lean_dec(result_obj);
(s1, s2, s3)
};
assert_eq!(s1, "ABcDe");
assert_eq!(s2, "aBcDe");
assert_eq!(s3, "ABCDE");
}
fn call_think(s: &str) -> Result<String, usize> {
let input = std::ffi::CString::new(s).expect("Failed to convert to C-string");
unsafe {
let result_obj = callee::think(lean::lean_mk_string(input.as_ptr()));
let tag = lean::lean_ptr_tag(result_obj);
let result = if tag == 0 {
assert!(lean::lean_is_ctor(result_obj), "Think must be a ctor");
assert_eq!(
lean::lean_ctor_num_objs(result_obj),
1,
"Ctor must have 1 field"
);
let s = unbox_lean_string(lean::lean_ctor_get(result_obj, 0));
Ok(s)
} else if tag == 1 {
assert_eq!(
lean::lean_ctor_num_objs(result_obj),
1,
"Ctor must have 1 field"
);
let field = lean::lean_ctor_get(result_obj, 0);
let n = lean::lean_uint64_of_nat(field) as usize;
Err(n)
} else {
unreachable!("Object tag > constructor")
};
lean::lean_dec(result_obj);
result
}
}
fn main() {
initialize();
println!("Lean initialization complete!");
call_my_function();
call_stylize();
assert_eq!(call_think("Stanford"), Ok("tanford".to_string()));
assert_eq!(call_think("Else"), Err(4));
} }