Move more packages to plugins.

This commit is contained in:
Stephen Chung
2020-08-14 18:58:34 +08:00
parent c0dc47c9db
commit ceb1a26733
5 changed files with 167 additions and 135 deletions

View File

@@ -1,11 +1,12 @@
#![cfg(not(feature = "no_index"))]
#![allow(non_snake_case)]
use crate::any::{Dynamic, Variant};
use crate::def_package;
use crate::engine::{Array, Engine};
use crate::fn_native::FnPtr;
use crate::module::{FuncReturn, Module};
use crate::parser::{ImmutableString, INT};
use crate::plugin::*;
#[cfg(not(feature = "unchecked"))]
use crate::{result::EvalAltResult, token::Position};
@@ -15,26 +16,148 @@ use crate::stdlib::{any::TypeId, boxed::Box};
#[cfg(not(feature = "unchecked"))]
use crate::stdlib::string::ToString;
// Register array utility functions
fn push<T: Variant + Clone>(list: &mut Array, item: T) -> FuncReturn<()> {
list.push(Dynamic::from(item));
Ok(())
pub type Unit = ();
macro_rules! gen_array_functions {
($root:ident => $($arg_type:ident),+ ) => {
pub mod $root { $(
pub mod $arg_type {
use super::super::*;
#[export_fn]
pub fn push_func(list: &mut Array, item: $arg_type) {
super::super::push(list, item);
}
#[export_fn]
pub fn insert_func(list: &mut Array, len: INT, item: $arg_type) {
super::super::insert(list, len, item);
}
}
)* }
}
}
fn ins<T: Variant + Clone>(list: &mut Array, position: INT, item: T) -> FuncReturn<()> {
macro_rules! reg_functions {
($mod_name:ident += $root:ident ; $($arg_type:ident),+) => {
$(set_exported_fn!($mod_name, "push", $root::$arg_type::push_func);)*
$(set_exported_fn!($mod_name, "insert", $root::$arg_type::insert_func);)*
}
}
macro_rules! reg_pad {
($lib:expr, $($par:ty),*) => {
$({
$lib.set_raw_fn("pad",
&[TypeId::of::<Array>(), TypeId::of::<INT>(), TypeId::of::<$par>()],
pad::<$par>
);
})*
};
}
def_package!(crate:BasicArrayPackage:"Basic array utilities.", lib, {
lib.merge(&exported_module!(array_functions));
set_exported_fn!(lib, "+", append);
set_exported_fn!(lib, "+", concat);
reg_functions!(lib += basic; INT, bool, char, ImmutableString, FnPtr, Array, Unit);
reg_pad!(lib, INT, bool, char, ImmutableString, FnPtr, Array, Unit);
#[cfg(not(feature = "only_i32"))]
#[cfg(not(feature = "only_i64"))]
{
reg_functions!(lib += numbers; i8, u8, i16, u16, i32, i64, u32, u64);
reg_pad!(lib, u8, i16, u16, i32, u32, i64, u64);
#[cfg(not(target_arch = "wasm32"))]
{
reg_functions!(lib += num_128; i128, u128);
reg_pad!(lib, i128, u128);
}
}
#[cfg(not(feature = "no_float"))]
{
reg_functions!(lib += float; f32, f64);
reg_pad!(lib, f32, f64);
}
#[cfg(not(feature = "no_object"))]
lib.set_getter_fn("len", |list: &mut Array| Ok(list.len() as INT));
// Register array iterator
lib.set_iter(
TypeId::of::<Array>(),
|arr| Box::new(arr.cast::<Array>().into_iter()) as Box<dyn Iterator<Item = Dynamic>>,
);
});
#[export_fn]
fn append(x: &mut Array, y: Array) {
x.extend(y);
}
#[export_fn]
fn concat(mut x: Array, y: Array) -> Array {
x.extend(y);
x
}
#[export_module]
mod array_functions {
pub fn len(list: &mut Array) -> INT {
list.len() as INT
}
pub fn append(x: &mut Array, y: Array) {
x.extend(y);
}
pub fn pop(list: &mut Array) -> Dynamic {
list.pop().unwrap_or_else(|| ().into())
}
pub fn shift(list: &mut Array) -> Dynamic {
if list.is_empty() {
().into()
} else {
list.remove(0)
}
}
pub fn remove(list: &mut Array, len: INT) -> Dynamic {
if len < 0 || (len as usize) >= list.len() {
().into()
} else {
list.remove(len as usize)
}
}
pub fn clear(list: &mut Array) {
list.clear();
}
pub fn truncate(list: &mut Array, len: INT) {
if len >= 0 {
list.truncate(len as usize);
} else {
list.clear();
}
}
}
// Register array utility functions
fn push<T: Variant + Clone>(list: &mut Array, item: T) {
list.push(Dynamic::from(item));
}
fn insert<T: Variant + Clone>(list: &mut Array, position: INT, item: T) {
if position <= 0 {
list.insert(0, Dynamic::from(item));
} else if (position as usize) >= list.len() - 1 {
push(list, item)?;
push(list, item);
} else {
list.insert(position as usize, Dynamic::from(item));
}
Ok(())
}
fn pad<T: Variant + Clone>(
_engine: &Engine,
_: &Module,
args: &mut [&mut Dynamic],
) -> FuncReturn<()> {
) -> Result<(), Box<EvalAltResult>> {
let len = *args[1].read_lock::<INT>().unwrap();
// Check if array will be over max size limit
@@ -63,115 +186,16 @@ fn pad<T: Variant + Clone>(
Ok(())
}
macro_rules! reg_op {
($lib:expr, $op:expr, $func:ident, $($par:ty),*) => {
$( $lib.set_fn_2_mut($op, $func::<$par>); )*
};
}
macro_rules! reg_tri {
($lib:expr, $op:expr, $func:ident, $($par:ty),*) => {
$( $lib.set_fn_3_mut($op, $func::<$par>); )*
};
}
macro_rules! reg_pad {
($lib:expr, $op:expr, $func:ident, $($par:ty),*) => {
$({
$lib.set_raw_fn($op,
&[TypeId::of::<Array>(), TypeId::of::<INT>(), TypeId::of::<$par>()],
$func::<$par>
);
})*
};
}
gen_array_functions!(basic => INT, bool, char, ImmutableString, FnPtr, Array, Unit);
def_package!(crate:BasicArrayPackage:"Basic array utilities.", lib, {
reg_op!(lib, "push", push, INT, bool, char, ImmutableString, FnPtr, Array, ());
reg_pad!(lib, "pad", pad, INT, bool, char, ImmutableString, FnPtr, Array, ());
reg_tri!(lib, "insert", ins, INT, bool, char, ImmutableString, FnPtr, Array, ());
#[cfg(not(feature = "only_i32"))]
#[cfg(not(feature = "only_i64"))]
gen_array_functions!(numbers => i8, u8, i16, u16, i32, i64, u32, u64);
lib.set_fn_2_mut("append", |x: &mut Array, y: Array| {
x.extend(y);
Ok(())
});
lib.set_fn_2_mut("+=", |x: &mut Array, y: Array| {
x.extend(y);
Ok(())
});
lib.set_fn_2(
"+",
|mut x: Array, y: Array| {
x.extend(y);
Ok(x)
},
);
#[cfg(not(feature = "only_i32"))]
#[cfg(not(feature = "only_i64"))]
#[cfg(not(target_arch = "wasm32"))]
gen_array_functions!(num_128 => i128, u128);
if cfg!(not(feature = "only_i32")) && cfg!(not(feature = "only_i64")) {
reg_op!(lib, "push", push, i8, u8, i16, u16, i32, i64, u32, u64);
reg_pad!(lib, "pad", pad, i8, u8, i16, u16, i32, u32, i64, u64);
reg_tri!(lib, "insert", ins, i8, u8, i16, u16, i32, i64, u32, u64);
if cfg!(not(target_arch = "wasm32")) {
reg_op!(lib, "push", push, i128, u128);
reg_pad!(lib, "pad", pad, i128, u128);
reg_tri!(lib, "insert", ins, i128, u128);
}
}
#[cfg(not(feature = "no_float"))]
{
reg_op!(lib, "push", push, f32, f64);
reg_pad!(lib, "pad", pad, f32, f64);
reg_tri!(lib, "insert", ins, f32, f64);
}
lib.set_fn_1_mut(
"pop",
|list: &mut Array| Ok(list.pop().unwrap_or_else(|| ().into())),
);
lib.set_fn_1_mut(
"shift",
|list: &mut Array| {
Ok(if list.is_empty() {
().into()
} else {
list.remove(0)
})
},
);
lib.set_fn_2_mut(
"remove",
|list: &mut Array, len: INT| {
Ok(if len < 0 || (len as usize) >= list.len() {
().into()
} else {
list.remove(len as usize)
})
},
);
lib.set_fn_1_mut("len", |list: &mut Array| Ok(list.len() as INT));
#[cfg(not(feature = "no_object"))]
lib.set_getter_fn("len", |list: &mut Array| Ok(list.len() as INT));
lib.set_fn_1_mut("clear", |list: &mut Array| {
list.clear();
Ok(())
});
lib.set_fn_2_mut(
"truncate",
|list: &mut Array, len: INT| {
if len >= 0 {
list.truncate(len as usize);
} else {
list.clear();
}
Ok(())
},
);
// Register array iterator
lib.set_iter(
TypeId::of::<Array>(),
|arr| Box::new(arr.cast::<Array>().into_iter()) as Box<dyn Iterator<Item = Dynamic>>,
);
});
#[cfg(not(feature = "no_float"))]
gen_array_functions!(float => f32, f64);