1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
use std::ffi::CStr; use std::mem::transmute; use std::os::raw::{c_char, c_void}; use std::slice; use crate::string_cache::Atom; use crate::throne::Context; use crate::token::Token; #[repr(C)] pub struct CRule { id: i32, } #[no_mangle] pub extern "C" fn throne_context_create_from_text(string_ptr: *const c_char) -> *mut Context { let cstr = unsafe { CStr::from_ptr(string_ptr) }; unsafe { transmute(Box::new(Context::from_text(cstr.to_str().unwrap()))) } } #[no_mangle] pub extern "C" fn throne_context_destroy(context: *mut Context) { let _drop: Box<Context> = unsafe { transmute(context) }; } #[no_mangle] pub extern "C" fn throne_update(context: *mut Context) { let context = unsafe { &mut *context }; context.update(|_: &[Token]| None); } #[no_mangle] pub extern "C" fn throne_context_string_to_atom( context: *mut Context, string_ptr: *const c_char, ) -> Atom { let context = unsafe { &mut *context }; let cstr = unsafe { CStr::from_ptr(string_ptr) }; context.str_to_atom(cstr.to_str().unwrap()) } #[no_mangle] pub extern "C" fn throne_context_find_matching_rules( context: *mut Context, side_input: extern "C" fn(p: *const Atom, p_len: usize, data: *mut c_void) -> bool, side_input_data: *mut c_void, result_ptr: *mut CRule, result_len: usize, ) -> usize { let context = unsafe { &mut *context }; let result = unsafe { slice::from_raw_parts_mut(result_ptr, result_len) }; let mut side_input_p = vec![]; let rules = context.find_matching_rules(|p: &[Token]| { side_input_p.clear(); side_input_p.extend(p.iter().map(|t| t.atom)); if side_input(side_input_p.as_ptr(), side_input_p.len(), side_input_data) { Some(vec![]) } else { None } }); let len = rules.len().min(result_len); for i in 0..len { result[i] = CRule { id: rules[i].id }; } return len; } #[no_mangle] pub extern "C" fn throne_context_find_phrase5( context: *mut Context, atom_ptr1: *const Atom, atom_ptr2: *const Atom, atom_ptr3: *const Atom, atom_ptr4: *const Atom, atom_ptr5: *const Atom, result_ptr: *mut Atom, result_len: usize, ) -> usize { let context = unsafe { &mut *context }; let result = unsafe { slice::from_raw_parts_mut(result_ptr, result_len) }; let ptr_to_atom = |atom_ptr: *const Atom| unsafe { atom_ptr.as_ref() }; if let Some(phrase) = context.find_phrase5( ptr_to_atom(atom_ptr1), ptr_to_atom(atom_ptr2), ptr_to_atom(atom_ptr3), ptr_to_atom(atom_ptr4), ptr_to_atom(atom_ptr5), ) { let len = phrase.len().min(result_len); for i in 0..len { result[i] = phrase[i].atom; } len } else { 0 } }