The more macros, the merrier

This commit is contained in:
Erin 2024-02-04 03:08:20 +01:00
parent 4aa39f3fbc
commit de723980da

View file

@ -3,73 +3,78 @@ use {
rhai::{Engine, ImmutableString, Module}, rhai::{Engine, ImmutableString, Module},
}; };
macro_rules! shdm_fns {
(
module: $module:expr;
shared: $shared:expr => $shname:ident;
$(
$vis:ident fn $name:ident($($params:tt)*) $(-> $ret:ty)? $blk:block
)*
) => {{
let module = $module;
let shared = $shared;
$({
let $shname = SharedObject::clone(&shared);
let hash = module.set_native_fn(
stringify!($name),
move |$($params)*| $(-> $ret)? {
let mut $shname = $shname.borrow_mut();
$blk
},
);
module.update_fn_namespace(
hash,
paste::paste!(rhai::FnNamespace::[<$vis:camel>])
);
})*
}};
}
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct UnboundLabel(pub usize); pub struct UnboundLabel(pub usize);
pub fn setup(engine: &mut Engine, module: &mut Module, object: SharedObject) { pub fn setup(engine: &mut Engine, module: &mut Module, object: SharedObject) {
{ shdm_fns! {
let object = SharedObject::clone(&object); module: module;
let hash = module.set_native_fn("label", move || { shared: object => obj;
let mut obj = object.borrow_mut();
global fn label() {
let symbol = obj.symbol(crate::object::Section::Text); let symbol = obj.symbol(crate::object::Section::Text);
Ok(symbol) Ok(symbol)
});
module.update_fn_namespace(hash, rhai::FnNamespace::Global);
} }
{ global fn label(label: ImmutableString) {
let object = SharedObject::clone(&object);
let hash = module.set_native_fn("label", move |label: ImmutableString| {
let mut obj = object.borrow_mut();
let symbol = obj.symbol(crate::object::Section::Text); let symbol = obj.symbol(crate::object::Section::Text);
obj.labels.insert(label, symbol.0); obj.labels.insert(label, symbol.0);
Ok(symbol) Ok(symbol)
});
module.update_fn_namespace(hash, rhai::FnNamespace::Global);
} }
{ global fn declabel() {
let object = SharedObject::clone(&object);
let hash = module.set_native_fn("declabel", move || {
let mut obj = object.borrow_mut();
let index = obj.symbols.len(); let index = obj.symbols.len();
obj.symbols.push(None); obj.symbols.push(None);
Ok(UnboundLabel(index)) Ok(UnboundLabel(index))
});
module.update_fn_namespace(hash, rhai::FnNamespace::Global);
} }
{ global fn declabel(label: ImmutableString) {
let object = SharedObject::clone(&object);
let hash = module.set_native_fn("declabel", move |label: ImmutableString| {
let mut obj = object.borrow_mut();
let index = obj.symbols.len(); let index = obj.symbols.len();
obj.symbols.push(None); obj.symbols.push(None);
obj.labels.insert(label, index); obj.labels.insert(label, index);
Ok(UnboundLabel(index)) Ok(UnboundLabel(index))
});
module.update_fn_namespace(hash, rhai::FnNamespace::Global);
} }
{ global fn here(label: UnboundLabel) {
module.set_native_fn("here", move |label: UnboundLabel| {
let mut obj = object.borrow_mut();
obj.symbols[label.0] = Some(crate::object::SymbolEntry { obj.symbols[label.0] = Some(crate::object::SymbolEntry {
location: crate::object::Section::Text, location: crate::object::Section::Text,
offset: obj.sections.text.len(), offset: obj.sections.text.len(),
}); });
Ok(()) Ok(())
}); }
} }
engine.register_type_with_name::<UnboundLabel>("UnboundLabel"); engine.register_type_with_name::<UnboundLabel>("UnboundLabel");