Nicer formatting/less indentation of module plugin blocks.

This commit is contained in:
Stephen Chung 2020-08-28 23:13:38 +08:00
parent b72a6355fd
commit 75ca495199
6 changed files with 280 additions and 312 deletions

View File

@ -17,250 +17,246 @@ use crate::stdlib::format;
macro_rules! gen_arithmetic_functions { macro_rules! gen_arithmetic_functions {
($root:ident => $($arg_type:ident),+) => { ($root:ident => $($arg_type:ident),+) => {
pub mod $root { $( pub mod $root { $(pub mod $arg_type {
pub mod $arg_type { use super::super::*;
use super::super::*;
#[export_module] #[export_module]
pub mod functions { pub mod functions {
#[rhai_fn(name = "+", return_raw)] #[rhai_fn(name = "+", return_raw)]
#[inline] #[inline]
pub fn add(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> { pub fn add(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
x.checked_add(y).ok_or_else(|| { x.checked_add(y).ok_or_else(|| {
EvalAltResult::ErrorArithmetic(
format!("Addition overflow: {} + {}", x, y),
Position::none(),
)
.into()
}).map(Dynamic::from)
} else {
Ok(Dynamic::from(x + y))
}
}
#[rhai_fn(name = "-", return_raw)]
#[inline]
pub fn subtract(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) {
x.checked_sub(y).ok_or_else(|| {
EvalAltResult::ErrorArithmetic(
format!("Subtraction overflow: {} - {}", x, y),
Position::none(),
)
.into()
}).map(Dynamic::from)
} else {
Ok(Dynamic::from(x - y))
}
}
#[rhai_fn(name = "*", return_raw)]
#[inline]
pub fn multiply(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) {
x.checked_mul(y).ok_or_else(|| {
EvalAltResult::ErrorArithmetic(
format!("Multiplication overflow: {} * {}", x, y),
Position::none(),
)
.into()
}).map(Dynamic::from)
} else {
Ok(Dynamic::from(x * y))
}
}
#[rhai_fn(name = "/", return_raw)]
#[inline]
pub fn divide(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) {
// Detect division by zero
if y == 0 {
EvalAltResult::ErrorArithmetic(
format!("Division by zero: {} / {}", x, y),
Position::none(),
)
.into()
} else {
x.checked_div(y).ok_or_else(|| {
EvalAltResult::ErrorArithmetic( EvalAltResult::ErrorArithmetic(
format!("Addition overflow: {} + {}", x, y), format!("Division overflow: {} / {}", x, y),
Position::none(), Position::none(),
) )
.into() .into()
}).map(Dynamic::from) }).map(Dynamic::from)
} else {
Ok(Dynamic::from(x + y))
} }
} else {
Ok(Dynamic::from(x / y))
} }
#[rhai_fn(name = "-", return_raw)] }
#[inline] #[rhai_fn(name = "%", return_raw)]
pub fn subtract(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> { #[inline]
if cfg!(not(feature = "unchecked")) { pub fn modulo(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
x.checked_sub(y).ok_or_else(|| { if cfg!(not(feature = "unchecked")) {
x.checked_rem(y).ok_or_else(|| {
EvalAltResult::ErrorArithmetic(
format!("Modulo division by zero or overflow: {} % {}", x, y),
Position::none(),
)
.into()
}).map(Dynamic::from)
} else {
Ok(Dynamic::from(x % y))
}
}
#[rhai_fn(name = "~", return_raw)]
#[inline]
pub fn power(x: INT, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) {
EvalAltResult::ErrorArithmetic(
format!("Integer raised to too large an index: {} ~ {}", x, y),
Position::none(),
)
.into()
} else if y < 0 {
EvalAltResult::ErrorArithmetic(
format!("Integer raised to a negative index: {} ~ {}", x, y),
Position::none(),
)
.into()
} else {
x.checked_pow(y as u32).ok_or_else(|| {
EvalAltResult::ErrorArithmetic( EvalAltResult::ErrorArithmetic(
format!("Subtraction overflow: {} - {}", x, y), format!("Power overflow: {} ~ {}", x, y),
Position::none(), Position::none(),
) )
.into() .into()
}).map(Dynamic::from) }).map(Dynamic::from)
} else {
Ok(Dynamic::from(x - y))
}
}
#[rhai_fn(name = "*", return_raw)]
#[inline]
pub fn multiply(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) {
x.checked_mul(y).ok_or_else(|| {
EvalAltResult::ErrorArithmetic(
format!("Multiplication overflow: {} * {}", x, y),
Position::none(),
)
.into()
}).map(Dynamic::from)
} else {
Ok(Dynamic::from(x * y))
}
}
#[rhai_fn(name = "/", return_raw)]
#[inline]
pub fn divide(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) {
// Detect division by zero
if y == 0 {
EvalAltResult::ErrorArithmetic(
format!("Division by zero: {} / {}", x, y),
Position::none(),
)
.into()
} else {
x.checked_div(y).ok_or_else(|| {
EvalAltResult::ErrorArithmetic(
format!("Division overflow: {} / {}", x, y),
Position::none(),
)
.into()
}).map(Dynamic::from)
}
} else {
Ok(Dynamic::from(x / y))
}
}
#[rhai_fn(name = "%", return_raw)]
#[inline]
pub fn modulo(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) {
x.checked_rem(y).ok_or_else(|| {
EvalAltResult::ErrorArithmetic(
format!("Modulo division by zero or overflow: {} % {}", x, y),
Position::none(),
)
.into()
}).map(Dynamic::from)
} else {
Ok(Dynamic::from(x % y))
}
}
#[rhai_fn(name = "~", return_raw)]
#[inline]
pub fn power(x: INT, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) {
EvalAltResult::ErrorArithmetic(
format!("Integer raised to too large an index: {} ~ {}", x, y),
Position::none(),
)
.into()
} else if y < 0 {
EvalAltResult::ErrorArithmetic(
format!("Integer raised to a negative index: {} ~ {}", x, y),
Position::none(),
)
.into()
} else {
x.checked_pow(y as u32).ok_or_else(|| {
EvalAltResult::ErrorArithmetic(
format!("Power overflow: {} ~ {}", x, y),
Position::none(),
)
.into()
}).map(Dynamic::from)
}
} else {
Ok(Dynamic::from(x.pow(y as u32)))
} }
} else {
Ok(Dynamic::from(x.pow(y as u32)))
} }
}
#[rhai_fn(name = "<<", return_raw)] #[rhai_fn(name = "<<", return_raw)]
#[inline] #[inline]
pub fn shift_left(x: $arg_type, y: INT) -> Result<Dynamic, Box<EvalAltResult>> { pub fn shift_left(x: $arg_type, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) { if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) {
EvalAltResult::ErrorArithmetic(
format!("Left-shift by too many bits: {} << {}", x, y),
Position::none(),
)
.into()
} else if y < 0 {
EvalAltResult::ErrorArithmetic(
format!("Left-shift by a negative number: {} << {}", x, y),
Position::none(),
)
.into()
} else {
x.checked_shl(y as u32).ok_or_else(|| {
EvalAltResult::ErrorArithmetic( EvalAltResult::ErrorArithmetic(
format!("Left-shift by too many bits: {} << {}", x, y), format!("Left-shift by too many bits: {} << {}", x, y),
Position::none(), Position::none(),
) )
.into() .into()
} else if y < 0 { }).map(Dynamic::from)
EvalAltResult::ErrorArithmetic(
format!("Left-shift by a negative number: {} << {}", x, y),
Position::none(),
)
.into()
} else {
x.checked_shl(y as u32).ok_or_else(|| {
EvalAltResult::ErrorArithmetic(
format!("Left-shift by too many bits: {} << {}", x, y),
Position::none(),
)
.into()
}).map(Dynamic::from)
}
} else {
Ok(Dynamic::from(x << y))
} }
} else {
Ok(Dynamic::from(x << y))
} }
#[rhai_fn(name = ">>", return_raw)] }
#[inline] #[rhai_fn(name = ">>", return_raw)]
pub fn shift_right(x: $arg_type, y: INT) -> Result<Dynamic, Box<EvalAltResult>> { #[inline]
if cfg!(not(feature = "unchecked")) { pub fn shift_right(x: $arg_type, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) { if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) {
EvalAltResult::ErrorArithmetic(
format!("Right-shift by too many bits: {} >> {}", x, y),
Position::none(),
)
.into()
} else if y < 0 {
EvalAltResult::ErrorArithmetic(
format!("Right-shift by a negative number: {} >> {}", x, y),
Position::none(),
)
.into()
} else {
x.checked_shr(y as u32).ok_or_else(|| {
EvalAltResult::ErrorArithmetic( EvalAltResult::ErrorArithmetic(
format!("Right-shift by too many bits: {} >> {}", x, y), format!("Right-shift by too many bits: {} >> {}", x, y),
Position::none(), Position::none(),
) )
.into() .into()
} else if y < 0 { }).map(Dynamic::from)
EvalAltResult::ErrorArithmetic(
format!("Right-shift by a negative number: {} >> {}", x, y),
Position::none(),
)
.into()
} else {
x.checked_shr(y as u32).ok_or_else(|| {
EvalAltResult::ErrorArithmetic(
format!("Right-shift by too many bits: {} >> {}", x, y),
Position::none(),
)
.into()
}).map(Dynamic::from)
}
} else {
Ok(Dynamic::from(x >> y))
} }
} } else {
#[rhai_fn(name = "&")] Ok(Dynamic::from(x >> y))
#[inline(always)]
pub fn binary_and(x: $arg_type, y: $arg_type) -> $arg_type {
x & y
}
#[rhai_fn(name = "|")]
#[inline(always)]
pub fn binary_or(x: $arg_type, y: $arg_type) -> $arg_type {
x | y
}
#[rhai_fn(name = "^")]
#[inline(always)]
pub fn binary_xor(x: $arg_type, y: $arg_type) -> $arg_type {
x ^ y
} }
} }
#[rhai_fn(name = "&")]
#[inline(always)]
pub fn binary_and(x: $arg_type, y: $arg_type) -> $arg_type {
x & y
}
#[rhai_fn(name = "|")]
#[inline(always)]
pub fn binary_or(x: $arg_type, y: $arg_type) -> $arg_type {
x | y
}
#[rhai_fn(name = "^")]
#[inline(always)]
pub fn binary_xor(x: $arg_type, y: $arg_type) -> $arg_type {
x ^ y
}
} }
)* } })* }
} }
} }
macro_rules! gen_signed_functions { macro_rules! gen_signed_functions {
($root:ident => $($arg_type:ident),+) => { ($root:ident => $($arg_type:ident),+) => {
pub mod $root { $( pub mod $root { $(pub mod $arg_type {
pub mod $arg_type { use super::super::*;
use super::super::*;
#[export_module] #[export_module]
pub mod functions { pub mod functions {
#[rhai_fn(name = "-", return_raw)] #[rhai_fn(name = "-", return_raw)]
#[inline] #[inline]
pub fn neg(x: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> { pub fn neg(x: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
x.checked_neg().ok_or_else(|| { x.checked_neg().ok_or_else(|| {
EvalAltResult::ErrorArithmetic(format!("Negation overflow: -{}", x), Position::none()) EvalAltResult::ErrorArithmetic(format!("Negation overflow: -{}", x), Position::none())
.into() .into()
}).map(Dynamic::from) }).map(Dynamic::from)
} else { } else {
Ok(Dynamic::from(-x)) Ok(Dynamic::from(-x))
}
} }
#[rhai_fn(return_raw)] }
#[inline] #[rhai_fn(return_raw)]
pub fn abs(x: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> { #[inline]
if cfg!(not(feature = "unchecked")) { pub fn abs(x: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
x.checked_abs().ok_or_else(|| { if cfg!(not(feature = "unchecked")) {
EvalAltResult::ErrorArithmetic(format!("Negation overflow: -{}", x), Position::none()) x.checked_abs().ok_or_else(|| {
.into() EvalAltResult::ErrorArithmetic(format!("Negation overflow: -{}", x), Position::none())
}).map(Dynamic::from) .into()
} else { }).map(Dynamic::from)
Ok(Dynamic::from(x.abs())) } else {
} Ok(Dynamic::from(x.abs()))
} }
#[inline] }
pub fn sign(x: $arg_type) -> INT { #[inline]
if x == 0 { pub fn sign(x: $arg_type) -> INT {
0 if x == 0 {
} else if x < 0 { 0
-1 } else if x < 0 {
} else { -1
1 } else {
} 1
} }
} }
} }
)* } })* }
} }
} }

View File

@ -23,30 +23,33 @@ pub type Unit = ();
macro_rules! gen_array_functions { macro_rules! gen_array_functions {
($root:ident => $($arg_type:ident),+ ) => { ($root:ident => $($arg_type:ident),+ ) => {
pub mod $root { $( pub mod $root { $(pub mod $arg_type {
pub mod $arg_type { use super::super::*;
use super::super::*;
#[export_fn] #[export_fn]
#[inline(always)] #[inline(always)]
pub fn push_func(list: &mut Array, item: $arg_type) { pub fn push(list: &mut Array, item: $arg_type) {
super::super::push(list, item); list.push(Dynamic::from(item));
} }
#[export_fn] #[export_fn]
#[inline(always)] pub fn insert(list: &mut Array, position: INT, item: $arg_type) {
pub fn insert_func(list: &mut Array, len: INT, item: $arg_type) { if position <= 0 {
super::super::insert(list, len, item); list.insert(0, Dynamic::from(item));
} else if (position as usize) >= list.len() - 1 {
push(list, item);
} else {
list.insert(position as usize, Dynamic::from(item));
} }
} }
)* } })* }
} }
} }
macro_rules! reg_functions { macro_rules! reg_functions {
($mod_name:ident += $root:ident ; $($arg_type:ident),+) => { $( ($mod_name:ident += $root:ident ; $($arg_type:ident),+) => { $(
set_exported_fn!($mod_name, "push", $root::$arg_type::push_func); set_exported_fn!($mod_name, "push", $root::$arg_type::push);
set_exported_fn!($mod_name, "insert", $root::$arg_type::insert_func); set_exported_fn!($mod_name, "insert", $root::$arg_type::insert);
$mod_name.set_raw_fn("pad", $mod_name.set_raw_fn("pad",
&[TypeId::of::<Array>(), TypeId::of::<INT>(), TypeId::of::<$arg_type>()], &[TypeId::of::<Array>(), TypeId::of::<INT>(), TypeId::of::<$arg_type>()],
@ -138,20 +141,6 @@ mod array_functions {
} }
} }
// Register array utility functions
#[inline(always)]
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);
} else {
list.insert(position as usize, Dynamic::from(item));
}
}
fn pad<T: Variant + Clone>( fn pad<T: Variant + Clone>(
_engine: &Engine, _engine: &Engine,
_: &Module, _: &Module,

View File

@ -3,45 +3,43 @@ use crate::plugin::*;
macro_rules! gen_cmp_functions { macro_rules! gen_cmp_functions {
($root:ident => $($arg_type:ident),+) => { ($root:ident => $($arg_type:ident),+) => {
mod $root { $( mod $root { $(pub mod $arg_type {
pub mod $arg_type { use super::super::*;
use crate::plugin::*;
#[export_module] #[export_module]
pub mod functions { pub mod functions {
#[rhai_fn(name = "<")] #[rhai_fn(name = "<")]
#[inline(always)] #[inline(always)]
pub fn lt(x: $arg_type, y: $arg_type) -> bool { pub fn lt(x: $arg_type, y: $arg_type) -> bool {
x < y x < y
} }
#[rhai_fn(name = "<=")] #[rhai_fn(name = "<=")]
#[inline(always)] #[inline(always)]
pub fn lte(x: $arg_type, y: $arg_type) -> bool { pub fn lte(x: $arg_type, y: $arg_type) -> bool {
x <= y x <= y
} }
#[rhai_fn(name = ">")] #[rhai_fn(name = ">")]
#[inline(always)] #[inline(always)]
pub fn gt(x: $arg_type, y: $arg_type) -> bool { pub fn gt(x: $arg_type, y: $arg_type) -> bool {
x > y x > y
} }
#[rhai_fn(name = ">=")] #[rhai_fn(name = ">=")]
#[inline(always)] #[inline(always)]
pub fn gte(x: $arg_type, y: $arg_type) -> bool { pub fn gte(x: $arg_type, y: $arg_type) -> bool {
x >= y x >= y
} }
#[rhai_fn(name = "==")] #[rhai_fn(name = "==")]
#[inline(always)] #[inline(always)]
pub fn eq(x: $arg_type, y: $arg_type) -> bool { pub fn eq(x: $arg_type, y: $arg_type) -> bool {
x == y x == y
} }
#[rhai_fn(name = "!=")] #[rhai_fn(name = "!=")]
#[inline(always)] #[inline(always)]
pub fn ne(x: $arg_type, y: $arg_type) -> bool { pub fn ne(x: $arg_type, y: $arg_type) -> bool {
x != y x != y
}
} }
} }
)* } })* }
}; };
} }

View File

@ -26,17 +26,15 @@ pub const MAX_INT: INT = i64::MAX;
macro_rules! gen_conversion_functions { macro_rules! gen_conversion_functions {
($root:ident => $func_name:ident ( $($arg_type:ident),+ ) -> $result_type:ty) => { ($root:ident => $func_name:ident ( $($arg_type:ident),+ ) -> $result_type:ty) => {
pub mod $root { $( pub mod $root { $(pub mod $arg_type {
pub mod $arg_type { use super::super::*;
use super::super::*;
#[export_fn] #[export_fn]
#[inline(always)] #[inline(always)]
pub fn $func_name(x: $arg_type) -> $result_type { pub fn $func_name(x: $arg_type) -> $result_type {
x as $result_type x as $result_type
}
} }
)* } })* }
} }
} }

View File

@ -22,17 +22,15 @@ type Unit = ();
macro_rules! gen_functions { macro_rules! gen_functions {
($root:ident => $fn_name:ident ( $($arg_type:ident),+ )) => { ($root:ident => $fn_name:ident ( $($arg_type:ident),+ )) => {
pub mod $root { $( pub mod $root { $(pub mod $arg_type {
pub mod $arg_type { use super::super::*;
use super::super::*;
#[export_fn] #[export_fn]
#[inline(always)] #[inline(always)]
pub fn to_string_func(x: &mut $arg_type) -> ImmutableString { pub fn to_string_func(x: &mut $arg_type) -> ImmutableString {
super::super::$fn_name(x) super::super::$fn_name(x)
}
} }
)* } })* }
} }
} }
@ -128,12 +126,12 @@ gen_functions!(print_array => to_debug(Array));
#[export_fn] #[export_fn]
#[inline(always)] #[inline(always)]
fn print_empty_string() -> ImmutableString { fn print_empty_string() -> ImmutableString {
"".to_string().into() String::new().into()
} }
#[export_fn] #[export_fn]
#[inline(always)] #[inline(always)]
fn print_unit(_x: ()) -> ImmutableString { fn print_unit(_x: ()) -> ImmutableString {
"".to_string().into() String::new().into()
} }
#[export_fn] #[export_fn]
#[inline(always)] #[inline(always)]
@ -143,7 +141,7 @@ fn print_string(s: ImmutableString) -> ImmutableString {
#[export_fn] #[export_fn]
#[inline(always)] #[inline(always)]
fn debug_fn_ptr(f: &mut FnPtr) -> ImmutableString { fn debug_fn_ptr(f: &mut FnPtr) -> ImmutableString {
f.to_string().into() to_string(f)
} }
#[inline(always)] #[inline(always)]
fn to_string<T: Display>(x: &mut T) -> ImmutableString { fn to_string<T: Display>(x: &mut T) -> ImmutableString {

View File

@ -12,28 +12,26 @@ use crate::utils::StaticVec;
use crate::{result::EvalAltResult, token::Position}; use crate::{result::EvalAltResult, token::Position};
use crate::stdlib::{ use crate::stdlib::{
any::TypeId, boxed::Box, fmt::Display, format, mem, string::String, string::ToString, vec::Vec, any::TypeId, boxed::Box, format, mem, string::String, string::ToString, vec::Vec,
}; };
macro_rules! gen_concat_functions { macro_rules! gen_concat_functions {
($root:ident => $($arg_type:ident),+ ) => { ($root:ident => $($arg_type:ident),+ ) => {
pub mod $root { $( pub mod $root { $(pub mod $arg_type {
pub mod $arg_type { use super::super::*;
use super::super::*;
#[export_fn] #[export_fn]
#[inline(always)] #[inline]
pub fn append_func(x: &mut ImmutableString, y: $arg_type) -> String { pub fn append_func(x: &mut ImmutableString, y: $arg_type) -> String {
super::super::add_append(x, y) format!("{}{}", x, y)
}
#[export_fn]
#[inline(always)]
pub fn prepend_func(x: &mut $arg_type, y: ImmutableString) -> String {
super::super::add_prepend(x, y)
}
} }
)* }
#[export_fn]
#[inline]
pub fn prepend_func(x: &mut $arg_type, y: ImmutableString) -> String {
format!("{}{}", x, y)
}
})* }
} }
} }
@ -116,15 +114,6 @@ def_package!(crate:MoreStringPackage:"Additional string utilities, including str
); );
}); });
#[inline]
fn add_prepend<T: Display>(x: &mut T, y: ImmutableString) -> String {
format!("{}{}", x, y)
}
#[inline]
fn add_append<T: Display>(x: &mut ImmutableString, y: T) -> String {
format!("{}{}", x, y)
}
gen_concat_functions!(basic => INT, bool, char, FnPtr); gen_concat_functions!(basic => INT, bool, char, FnPtr);
#[cfg(not(feature = "only_i32"))] #[cfg(not(feature = "only_i32"))]