Add structure and inductive examples
This commit is contained in:
parent
1f8807a809
commit
01a51b4e08
|
@ -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
|
||||||
|
|
87
src/main.rs
87
src/main.rs
|
@ -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,8 +41,9 @@ fn main() {
|
||||||
}
|
}
|
||||||
lean::lean_io_mark_end_initialization();
|
lean::lean_io_mark_end_initialization();
|
||||||
}
|
}
|
||||||
println!("Lean initialization complete!");
|
}
|
||||||
|
|
||||||
|
fn call_my_function() {
|
||||||
let c_str = std::ffi::CString::new("hello").unwrap();
|
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());
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue