Skip to main content

umka_sys/
lib.rs

1#![allow(non_camel_case_types)]
2#![allow(non_snake_case)]
3#![allow(non_upper_case_globals)]
4#![allow(clippy::pub_underscore_fields)]
5#![allow(clippy::unreadable_literal)]
6include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
7
8#[cfg(test)]
9mod tests {
10    use std::{
11        ffi::CStr,
12        mem::zeroed,
13        ptr::{null, null_mut},
14    };
15
16    use super::*;
17
18    fn error_msg(umka: *mut tagUmka) -> String {
19        unsafe {
20            let err = *umkaGetError(umka);
21            if err.msg.is_null() {
22                return "(no umka error)".to_string();
23            }
24            let fname = CStr::from_ptr(err.fileName).to_string_lossy();
25            let msg = CStr::from_ptr(err.msg).to_string_lossy();
26            format!("{}:{} {}", fname, err.line, msg)
27        }
28    }
29
30    #[test]
31    fn compile_and_run() {
32        unsafe {
33            let umka = umkaAlloc();
34            let ok = umkaInit(
35                umka,
36                c"compile_and_run.um".as_ptr(),
37                c"fn main() { printf(\"hello world!\") }".as_ptr(),
38                4096,
39                null_mut(),
40                0,
41                null_mut(),
42                false,
43                false,
44                None,
45            );
46            assert!(ok, "umkaInit failed: {}", error_msg(umka));
47
48            let ok = umkaCompile(umka);
49            assert!(ok, "umkaCompile failed: {}", error_msg(umka));
50
51            let code = umkaRun(umka);
52            assert_eq!(
53                code,
54                0,
55                "umkaRun exited with code {code}: {}",
56                error_msg(umka)
57            );
58
59            umkaFree(umka);
60        }
61    }
62
63    #[test]
64    fn compile_and_call_function() {
65        let src = c"
66            fn add(a: int, b: int): int {
67                return a + b
68            }
69        ";
70        unsafe {
71            let umka = umkaAlloc();
72            let ok = umkaInit(
73                umka,
74                c"compile_and_call_function.um".as_ptr(),
75                src.as_ptr(),
76                4096,
77                null_mut(),
78                0,
79                null_mut(),
80                false,
81                false,
82                None,
83            );
84            assert!(ok, "umkaInit failed: {}", error_msg(umka));
85
86            let ok = umkaCompile(umka);
87            assert!(ok, "umkaCompile failed: {}", error_msg(umka));
88
89            let mut add_fn: UmkaFuncContext = zeroed();
90            let ok = umkaGetFunc(umka, null(), c"add".as_ptr(), &mut add_fn);
91            assert!(ok, "umkaGetFunc(add) failed: {}", error_msg(umka));
92
93            (*umkaGetParam(add_fn.params, 0)).intVal = 3;
94            (*umkaGetParam(add_fn.params, 1)).intVal = 7;
95            let ok = umkaCall(umka, &mut add_fn);
96            assert_eq!(ok, 0, "umkaCall failed: {}", error_msg(umka));
97            let ret = (*add_fn.result).intVal;
98            assert_eq!(ret, 10, "add(3, 7)");
99
100            umkaFree(umka);
101        }
102    }
103}