Impl returns closures.

This commit is contained in:
Stephen Chung 2021-06-20 21:42:13 +08:00
parent 4093727dcb
commit 3b345acebf

View File

@ -76,75 +76,55 @@ pub fn get_builtin_binary_op_fn(
let types_pair = (type1, type2); let types_pair = (type1, type2);
macro_rules! impl_op { macro_rules! impl_op {
($xx:ident $op:tt $yy:ident) => { ($xx:ident $op:tt $yy:ident) => { |_, args| {
Some(|_, args| {
let x = &*args[0].read_lock::<$xx>().expect(BUILTIN); let x = &*args[0].read_lock::<$xx>().expect(BUILTIN);
let y = &*args[1].read_lock::<$yy>().expect(BUILTIN); let y = &*args[1].read_lock::<$yy>().expect(BUILTIN);
Ok((x $op y).into()) Ok((x $op y).into())
}) } };
}; ($xx:ident . $func:ident ( $yy:ty )) => { |_, args| {
($xx:ident . $func:ident ( $yy:ty )) => {
Some(|_, args| {
let x = &*args[0].read_lock::<$xx>().expect(BUILTIN); let x = &*args[0].read_lock::<$xx>().expect(BUILTIN);
let y = &*args[1].read_lock::<$yy>().expect(BUILTIN); let y = &*args[1].read_lock::<$yy>().expect(BUILTIN);
Ok(x.$func(y).into()) Ok(x.$func(y).into())
}) } };
}; ($xx:ident . $func:ident ( $yy:ident . $yyy:ident () )) => { |_, args| {
($xx:ident . $func:ident ( $yy:ident . $yyy:ident () )) => {
Some(|_, args| {
let x = &*args[0].read_lock::<$xx>().expect(BUILTIN); let x = &*args[0].read_lock::<$xx>().expect(BUILTIN);
let y = &*args[1].read_lock::<$yy>().expect(BUILTIN); let y = &*args[1].read_lock::<$yy>().expect(BUILTIN);
Ok(x.$func(y.$yyy()).into()) Ok(x.$func(y.$yyy()).into())
}) } };
}; ($func:ident ( $op:tt )) => { |_, args| {
($func:ident ( $op:tt )) => {
Some(|_, args| {
let (x, y) = $func(args); let (x, y) = $func(args);
Ok((x $op y).into()) Ok((x $op y).into())
}) } };
}; ($base:ty => $xx:ident $op:tt $yy:ident) => { |_, args| {
($base:ty => $xx:ident $op:tt $yy:ident) => {
Some(|_, args| {
let x = args[0].$xx().expect(BUILTIN) as $base; let x = args[0].$xx().expect(BUILTIN) as $base;
let y = args[1].$yy().expect(BUILTIN) as $base; let y = args[1].$yy().expect(BUILTIN) as $base;
Ok((x $op y).into()) Ok((x $op y).into())
}) } };
}; ($base:ty => $xx:ident . $func:ident ( $yy:ident as $yyy:ty)) => { |_, args| {
($base:ty => $xx:ident . $func:ident ( $yy:ident as $yyy:ty)) => {
Some(|_, args| {
let x = args[0].$xx().expect(BUILTIN) as $base; let x = args[0].$xx().expect(BUILTIN) as $base;
let y = args[1].$yy().expect(BUILTIN) as $base; let y = args[1].$yy().expect(BUILTIN) as $base;
Ok(x.$func(y as $yyy).into()) Ok(x.$func(y as $yyy).into())
}) } };
}; ($base:ty => $func:ident ( $xx:ident, $yy:ident )) => { |_, args| {
($base:ty => $func:ident ( $xx:ident, $yy:ident )) => {
Some(|_, args| {
let x = args[0].$xx().expect(BUILTIN) as $base; let x = args[0].$xx().expect(BUILTIN) as $base;
let y = args[1].$yy().expect(BUILTIN) as $base; let y = args[1].$yy().expect(BUILTIN) as $base;
$func(x, y).map(Into::<Dynamic>::into) $func(x, y).map(Into::<Dynamic>::into)
}) } };
}; (from $base:ty => $xx:ident $op:tt $yy:ident) => { |_, args| {
(from $base:ty => $xx:ident $op:tt $yy:ident) => {
Some(|_, args| {
let x = <$base>::from(args[0].$xx().expect(BUILTIN)); let x = <$base>::from(args[0].$xx().expect(BUILTIN));
let y = <$base>::from(args[1].$yy().expect(BUILTIN)); let y = <$base>::from(args[1].$yy().expect(BUILTIN));
Ok((x $op y).into()) Ok((x $op y).into())
}) } };
}; (from $base:ty => $xx:ident . $func:ident ( $yy:ident )) => { |_, args| {
(from $base:ty => $xx:ident . $func:ident ( $yy:ident )) => {
Some(|_, args| {
let x = <$base>::from(args[0].$xx().expect(BUILTIN)); let x = <$base>::from(args[0].$xx().expect(BUILTIN));
let y = <$base>::from(args[1].$yy().expect(BUILTIN)); let y = <$base>::from(args[1].$yy().expect(BUILTIN));
Ok(x.$func(y).into()) Ok(x.$func(y).into())
}) } };
}; (from $base:ty => $func:ident ( $xx:ident, $yy:ident )) => { |_, args| {
(from $base:ty => $func:ident ( $xx:ident, $yy:ident )) => {
Some(|_, args| {
let x = <$base>::from(args[0].$xx().expect(BUILTIN)); let x = <$base>::from(args[0].$xx().expect(BUILTIN));
let y = <$base>::from(args[1].$yy().expect(BUILTIN)); let y = <$base>::from(args[1].$yy().expect(BUILTIN));
$func(x, y).map(Into::<Dynamic>::into) $func(x, y).map(Into::<Dynamic>::into)
}) } };
};
} }
macro_rules! impl_float { macro_rules! impl_float {
@ -152,18 +132,18 @@ pub fn get_builtin_binary_op_fn(
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) { if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
return match op { return match op {
"+" => impl_op!(FLOAT => $xx + $yy), "+" => Some(impl_op!(FLOAT => $xx + $yy)),
"-" => impl_op!(FLOAT => $xx - $yy), "-" => Some(impl_op!(FLOAT => $xx - $yy)),
"*" => impl_op!(FLOAT => $xx * $yy), "*" => Some(impl_op!(FLOAT => $xx * $yy)),
"/" => impl_op!(FLOAT => $xx / $yy), "/" => Some(impl_op!(FLOAT => $xx / $yy)),
"%" => impl_op!(FLOAT => $xx % $yy), "%" => Some(impl_op!(FLOAT => $xx % $yy)),
"**" => impl_op!(FLOAT => $xx.powf($yy as FLOAT)), "**" => Some(impl_op!(FLOAT => $xx.powf($yy as FLOAT))),
"==" => impl_op!(FLOAT => $xx == $yy), "==" => Some(impl_op!(FLOAT => $xx == $yy)),
"!=" => impl_op!(FLOAT => $xx != $yy), "!=" => Some(impl_op!(FLOAT => $xx != $yy)),
">" => impl_op!(FLOAT => $xx > $yy), ">" => Some(impl_op!(FLOAT => $xx > $yy)),
">=" => impl_op!(FLOAT => $xx >= $yy), ">=" => Some(impl_op!(FLOAT => $xx >= $yy)),
"<" => impl_op!(FLOAT => $xx < $yy), "<" => Some(impl_op!(FLOAT => $xx < $yy)),
"<=" => impl_op!(FLOAT => $xx <= $yy), "<=" => Some(impl_op!(FLOAT => $xx <= $yy)),
_ => None, _ => None,
}; };
} }
@ -183,12 +163,12 @@ pub fn get_builtin_binary_op_fn(
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
match op { match op {
"+" => return impl_op!(from Decimal => add($xx, $yy)), "+" => return Some(impl_op!(from Decimal => add($xx, $yy))),
"-" => return impl_op!(from Decimal => subtract($xx, $yy)), "-" => return Some(impl_op!(from Decimal => subtract($xx, $yy))),
"*" => return impl_op!(from Decimal => multiply($xx, $yy)), "*" => return Some(impl_op!(from Decimal => multiply($xx, $yy))),
"/" => return impl_op!(from Decimal => divide($xx, $yy)), "/" => return Some(impl_op!(from Decimal => divide($xx, $yy))),
"%" => return impl_op!(from Decimal => modulo($xx, $yy)), "%" => return Some(impl_op!(from Decimal => modulo($xx, $yy))),
"**" => return impl_op!(from Decimal => power($xx, $yy)), "**" => return Some(impl_op!(from Decimal => power($xx, $yy))),
_ => () _ => ()
} }
@ -197,22 +177,22 @@ pub fn get_builtin_binary_op_fn(
#[cfg(feature = "unchecked")] #[cfg(feature = "unchecked")]
match op { match op {
"+" => return impl_op!(from Decimal => $xx + $yy), "+" => return Some(impl_op!(from Decimal => $xx + $yy)),
"-" => return impl_op!(from Decimal => $xx - $yy), "-" => return Some(impl_op!(from Decimal => $xx - $yy)),
"*" => return impl_op!(from Decimal => $xx * $yy), "*" => return Some(impl_op!(from Decimal => $xx * $yy)),
"/" => return impl_op!(from Decimal => $xx / $yy), "/" => return Some(impl_op!(from Decimal => $xx / $yy)),
"%" => return impl_op!(from Decimal => $xx % $yy), "%" => return Some(impl_op!(from Decimal => $xx % $yy)),
"**" => return impl_op!(from Decimal => $xx.powd($yy)), "**" => return Some(impl_op!(from Decimal => $xx.powd($yy))),
_ => () _ => ()
} }
return match op { return match op {
"==" => impl_op!(from Decimal => $xx == $yy), "==" => Some(impl_op!(from Decimal => $xx == $yy)),
"!=" => impl_op!(from Decimal => $xx != $yy), "!=" => Some(impl_op!(from Decimal => $xx != $yy)),
">" => impl_op!(from Decimal => $xx > $yy), ">" => Some(impl_op!(from Decimal => $xx > $yy)),
">=" => impl_op!(from Decimal => $xx >= $yy), ">=" => Some(impl_op!(from Decimal => $xx >= $yy)),
"<" => impl_op!(from Decimal => $xx < $yy), "<" => Some(impl_op!(from Decimal => $xx < $yy)),
"<=" => impl_op!(from Decimal => $xx <= $yy), "<=" => Some(impl_op!(from Decimal => $xx <= $yy)),
_ => None _ => None
}; };
} }
@ -241,12 +221,12 @@ pub fn get_builtin_binary_op_fn(
let y = &*args[1].read_lock::<ImmutableString>().expect(BUILTIN); let y = &*args[1].read_lock::<ImmutableString>().expect(BUILTIN);
Ok(format!("{}{}", x, y).into()) Ok(format!("{}{}", x, y).into())
}), }),
"==" => impl_op!(get_s1s2(==)), "==" => Some(impl_op!(get_s1s2(==))),
"!=" => impl_op!(get_s1s2(!=)), "!=" => Some(impl_op!(get_s1s2(!=))),
">" => impl_op!(get_s1s2(>)), ">" => Some(impl_op!(get_s1s2(>))),
">=" => impl_op!(get_s1s2(>=)), ">=" => Some(impl_op!(get_s1s2(>=))),
"<" => impl_op!(get_s1s2(<)), "<" => Some(impl_op!(get_s1s2(<))),
"<=" => impl_op!(get_s1s2(<=)), "<=" => Some(impl_op!(get_s1s2(<=))),
_ => None, _ => None,
}; };
} }
@ -273,12 +253,12 @@ pub fn get_builtin_binary_op_fn(
let y = args[1].as_char().expect(BUILTIN); let y = args[1].as_char().expect(BUILTIN);
Ok((x - y).into()) Ok((x - y).into())
}), }),
"==" => impl_op!(get_s1s2(==)), "==" => Some(impl_op!(get_s1s2(==))),
"!=" => impl_op!(get_s1s2(!=)), "!=" => Some(impl_op!(get_s1s2(!=))),
">" => impl_op!(get_s1s2(>)), ">" => Some(impl_op!(get_s1s2(>))),
">=" => impl_op!(get_s1s2(>=)), ">=" => Some(impl_op!(get_s1s2(>=))),
"<" => impl_op!(get_s1s2(<)), "<" => Some(impl_op!(get_s1s2(<))),
"<=" => impl_op!(get_s1s2(<=)), "<=" => Some(impl_op!(get_s1s2(<=))),
OP_CONTAINS => Some(|_, args| { OP_CONTAINS => Some(|_, args| {
let s = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN); let s = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
let c = args[1].as_char().expect(BUILTIN); let c = args[1].as_char().expect(BUILTIN);
@ -294,7 +274,7 @@ pub fn get_builtin_binary_op_fn(
use crate::Map; use crate::Map;
return match op { return match op {
OP_CONTAINS => impl_op!(Map.contains_key(ImmutableString.as_str())), OP_CONTAINS => Some(impl_op!(Map.contains_key(ImmutableString.as_str()))),
_ => None, _ => None,
}; };
} }
@ -316,69 +296,69 @@ pub fn get_builtin_binary_op_fn(
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
match op { match op {
"+" => return impl_op!(INT => add(as_int, as_int)), "+" => return Some(impl_op!(INT => add(as_int, as_int))),
"-" => return impl_op!(INT => subtract(as_int, as_int)), "-" => return Some(impl_op!(INT => subtract(as_int, as_int))),
"*" => return impl_op!(INT => multiply(as_int, as_int)), "*" => return Some(impl_op!(INT => multiply(as_int, as_int))),
"/" => return impl_op!(INT => divide(as_int, as_int)), "/" => return Some(impl_op!(INT => divide(as_int, as_int))),
"%" => return impl_op!(INT => modulo(as_int, as_int)), "%" => return Some(impl_op!(INT => modulo(as_int, as_int))),
"**" => return impl_op!(INT => power(as_int, as_int)), "**" => return Some(impl_op!(INT => power(as_int, as_int))),
">>" => return impl_op!(INT => shift_right(as_int, as_int)), ">>" => return Some(impl_op!(INT => shift_right(as_int, as_int))),
"<<" => return impl_op!(INT => shift_left(as_int, as_int)), "<<" => return Some(impl_op!(INT => shift_left(as_int, as_int))),
_ => (), _ => (),
} }
#[cfg(feature = "unchecked")] #[cfg(feature = "unchecked")]
match op { match op {
"+" => return impl_op!(INT => as_int + as_int), "+" => return Some(impl_op!(INT => as_int + as_int)),
"-" => return impl_op!(INT => as_int - as_int), "-" => return Some(impl_op!(INT => as_int - as_int)),
"*" => return impl_op!(INT => as_int * as_int), "*" => return Some(impl_op!(INT => as_int * as_int)),
"/" => return impl_op!(INT => as_int / as_int), "/" => return Some(impl_op!(INT => as_int / as_int)),
"%" => return impl_op!(INT => as_int % as_int), "%" => return Some(impl_op!(INT => as_int % as_int)),
"**" => return impl_op!(INT => as_int.pow(as_int as u32)), "**" => return Some(impl_op!(INT => as_int.pow(as_int as u32))),
">>" => return impl_op!(INT => as_int >> as_int), ">>" => return Some(impl_op!(INT => as_int >> as_int)),
"<<" => return impl_op!(INT => as_int << as_int), "<<" => return Some(impl_op!(INT => as_int << as_int)),
_ => (), _ => (),
} }
return match op { return match op {
"==" => impl_op!(INT => as_int == as_int), "==" => Some(impl_op!(INT => as_int == as_int)),
"!=" => impl_op!(INT => as_int != as_int), "!=" => Some(impl_op!(INT => as_int != as_int)),
">" => impl_op!(INT => as_int > as_int), ">" => Some(impl_op!(INT => as_int > as_int)),
">=" => impl_op!(INT => as_int >= as_int), ">=" => Some(impl_op!(INT => as_int >= as_int)),
"<" => impl_op!(INT => as_int < as_int), "<" => Some(impl_op!(INT => as_int < as_int)),
"<=" => impl_op!(INT => as_int <= as_int), "<=" => Some(impl_op!(INT => as_int <= as_int)),
"&" => impl_op!(INT => as_int & as_int), "&" => Some(impl_op!(INT => as_int & as_int)),
"|" => impl_op!(INT => as_int | as_int), "|" => Some(impl_op!(INT => as_int | as_int)),
"^" => impl_op!(INT => as_int ^ as_int), "^" => Some(impl_op!(INT => as_int ^ as_int)),
_ => None, _ => None,
}; };
} }
if type1 == TypeId::of::<bool>() { if type1 == TypeId::of::<bool>() {
return match op { return match op {
"==" => impl_op!(bool => as_bool == as_bool), "==" => Some(impl_op!(bool => as_bool == as_bool)),
"!=" => impl_op!(bool => as_bool != as_bool), "!=" => Some(impl_op!(bool => as_bool != as_bool)),
">" => impl_op!(bool => as_bool > as_bool), ">" => Some(impl_op!(bool => as_bool > as_bool)),
">=" => impl_op!(bool => as_bool >= as_bool), ">=" => Some(impl_op!(bool => as_bool >= as_bool)),
"<" => impl_op!(bool => as_bool < as_bool), "<" => Some(impl_op!(bool => as_bool < as_bool)),
"<=" => impl_op!(bool => as_bool <= as_bool), "<=" => Some(impl_op!(bool => as_bool <= as_bool)),
"&" => impl_op!(bool => as_bool & as_bool), "&" => Some(impl_op!(bool => as_bool & as_bool)),
"|" => impl_op!(bool => as_bool | as_bool), "|" => Some(impl_op!(bool => as_bool | as_bool)),
"^" => impl_op!(bool => as_bool ^ as_bool), "^" => Some(impl_op!(bool => as_bool ^ as_bool)),
_ => None, _ => None,
}; };
} }
if type1 == TypeId::of::<ImmutableString>() { if type1 == TypeId::of::<ImmutableString>() {
return match op { return match op {
"+" => impl_op!(ImmutableString + ImmutableString), "+" => Some(impl_op!(ImmutableString + ImmutableString)),
"-" => impl_op!(ImmutableString - ImmutableString), "-" => Some(impl_op!(ImmutableString - ImmutableString)),
"==" => impl_op!(ImmutableString == ImmutableString), "==" => Some(impl_op!(ImmutableString == ImmutableString)),
"!=" => impl_op!(ImmutableString != ImmutableString), "!=" => Some(impl_op!(ImmutableString != ImmutableString)),
">" => impl_op!(ImmutableString > ImmutableString), ">" => Some(impl_op!(ImmutableString > ImmutableString)),
">=" => impl_op!(ImmutableString >= ImmutableString), ">=" => Some(impl_op!(ImmutableString >= ImmutableString)),
"<" => impl_op!(ImmutableString < ImmutableString), "<" => Some(impl_op!(ImmutableString < ImmutableString)),
"<=" => impl_op!(ImmutableString <= ImmutableString), "<=" => Some(impl_op!(ImmutableString <= ImmutableString)),
OP_CONTAINS => Some(|_, args| { OP_CONTAINS => Some(|_, args| {
let s1 = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN); let s1 = &*args[0].read_lock::<ImmutableString>().expect(BUILTIN);
let s2 = &*args[1].read_lock::<ImmutableString>().expect(BUILTIN); let s2 = &*args[1].read_lock::<ImmutableString>().expect(BUILTIN);
@ -395,12 +375,12 @@ pub fn get_builtin_binary_op_fn(
let y = args[1].as_char().expect(BUILTIN); let y = args[1].as_char().expect(BUILTIN);
Ok(format!("{}{}", x, y).into()) Ok(format!("{}{}", x, y).into())
}), }),
"==" => impl_op!(char => as_char == as_char), "==" => Some(impl_op!(char => as_char == as_char)),
"!=" => impl_op!(char => as_char != as_char), "!=" => Some(impl_op!(char => as_char != as_char)),
">" => impl_op!(char => as_char > as_char), ">" => Some(impl_op!(char => as_char > as_char)),
">=" => impl_op!(char => as_char >= as_char), ">=" => Some(impl_op!(char => as_char >= as_char)),
"<" => impl_op!(char => as_char < as_char), "<" => Some(impl_op!(char => as_char < as_char)),
"<=" => impl_op!(char => as_char <= as_char), "<=" => Some(impl_op!(char => as_char <= as_char)),
_ => None, _ => None,
}; };
} }
@ -433,59 +413,43 @@ pub fn get_builtin_op_assignment_fn(
let types_pair = (type1, type2); let types_pair = (type1, type2);
macro_rules! impl_op { macro_rules! impl_op {
($x:ty = x $op:tt $yy:ident) => { ($x:ty = x $op:tt $yy:ident) => { |_, args| {
Some(|_, args| {
let x = args[0].$yy().expect(BUILTIN); let x = args[0].$yy().expect(BUILTIN);
let y = args[1].$yy().expect(BUILTIN) as $x; let y = args[1].$yy().expect(BUILTIN) as $x;
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x $op y).into()) Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x $op y).into())
}) } };
}; ($x:ident $op:tt $yy:ident) => { |_, args| {
($x:ident $op:tt $yy:ident) => {
Some(|_, args| {
let y = args[1].$yy().expect(BUILTIN) as $x; let y = args[1].$yy().expect(BUILTIN) as $x;
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into()) Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into())
}) } };
}; ($x:ident $op:tt $yy:ident as $yyy:ty) => { |_, args| {
($x:ident $op:tt $yy:ident as $yyy:ty) => {
Some(|_, args| {
let y = args[1].$yy().expect(BUILTIN) as $yyy; let y = args[1].$yy().expect(BUILTIN) as $yyy;
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into()) Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into())
}) } };
}; ($x:ty => $xx:ident . $func:ident ( $yy:ident as $yyy:ty )) => { |_, args| {
($x:ty => $xx:ident . $func:ident ( $yy:ident as $yyy:ty )) => {
Some(|_, args| {
let x = args[0].$xx().expect(BUILTIN); let x = args[0].$xx().expect(BUILTIN);
let y = args[1].$yy().expect(BUILTIN) as $x; let y = args[1].$yy().expect(BUILTIN) as $x;
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x.$func(y as $yyy)).into()) Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x.$func(y as $yyy)).into())
}) } };
}; ($x:ty => $func:ident ( $xx:ident, $yy:ident )) => { |_, args| {
($x:ty => $func:ident ( $xx:ident, $yy:ident )) => {
Some(|_, args| {
let x = args[0].$xx().expect(BUILTIN); let x = args[0].$xx().expect(BUILTIN);
let y = args[1].$yy().expect(BUILTIN) as $x; let y = args[1].$yy().expect(BUILTIN) as $x;
Ok((*args[0].write_lock().expect(BUILTIN) = $func(x, y)?).into()) Ok((*args[0].write_lock().expect(BUILTIN) = $func(x, y)?).into())
}) } };
}; (from $x:ident $op:tt $yy:ident) => { |_, args| {
(from $x:ident $op:tt $yy:ident) => {
Some(|_, args| {
let y = <$x>::from(args[1].$yy().expect(BUILTIN)); let y = <$x>::from(args[1].$yy().expect(BUILTIN));
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into()) Ok((*args[0].write_lock::<$x>().expect(BUILTIN) $op y).into())
}) } };
}; (from $x:ty => $xx:ident . $func:ident ( $yy:ident )) => { |_, args| {
(from $x:ty => $xx:ident . $func:ident ( $yy:ident )) => {
Some(|_, args| {
let x = args[0].$xx().expect(BUILTIN); let x = args[0].$xx().expect(BUILTIN);
let y = <$x>::from(args[1].$yy().expect(BUILTIN)); let y = <$x>::from(args[1].$yy().expect(BUILTIN));
Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x.$func(y)).into()) Ok((*args[0].write_lock::<$x>().expect(BUILTIN) = x.$func(y)).into())
}) } };
}; (from $x:ty => $func:ident ( $xx:ident, $yy:ident )) => { |_, args| {
(from $x:ty => $func:ident ( $xx:ident, $yy:ident )) => {
Some(|_, args| {
let x = args[0].$xx().expect(BUILTIN); let x = args[0].$xx().expect(BUILTIN);
let y = <$x>::from(args[1].$yy().expect(BUILTIN)); let y = <$x>::from(args[1].$yy().expect(BUILTIN));
Ok((*args[0].write_lock().expect(BUILTIN) = $func(x, y)?).into()) Ok((*args[0].write_lock().expect(BUILTIN) = $func(x, y)?).into())
}) } };
};
} }
macro_rules! impl_float { macro_rules! impl_float {
@ -493,12 +457,12 @@ pub fn get_builtin_op_assignment_fn(
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) { if types_pair == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
return match op { return match op {
"+=" => impl_op!($x += $yy), "+=" => Some(impl_op!($x += $yy)),
"-=" => impl_op!($x -= $yy), "-=" => Some(impl_op!($x -= $yy)),
"*=" => impl_op!($x *= $yy), "*=" => Some(impl_op!($x *= $yy)),
"/=" => impl_op!($x /= $yy), "/=" => Some(impl_op!($x /= $yy)),
"%=" => impl_op!($x %= $yy), "%=" => Some(impl_op!($x %= $yy)),
"**=" => impl_op!($x => $xx.powf($yy as $x)), "**=" => Some(impl_op!($x => $xx.powf($yy as $x))),
_ => None, _ => None,
}; };
} }
@ -517,12 +481,12 @@ pub fn get_builtin_op_assignment_fn(
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
return match op { return match op {
"+=" => impl_op!(from $x => add($xx, $yy)), "+=" => Some(impl_op!(from $x => add($xx, $yy))),
"-=" => impl_op!(from $x => subtract($xx, $yy)), "-=" => Some(impl_op!(from $x => subtract($xx, $yy))),
"*=" => impl_op!(from $x => multiply($xx, $yy)), "*=" => Some(impl_op!(from $x => multiply($xx, $yy))),
"/=" => impl_op!(from $x => divide($xx, $yy)), "/=" => Some(impl_op!(from $x => divide($xx, $yy))),
"%=" => impl_op!(from $x => modulo($xx, $yy)), "%=" => Some(impl_op!(from $x => modulo($xx, $yy))),
"**=" => impl_op!(from $x => power($xx, $yy)), "**=" => Some(impl_op!(from $x => power($xx, $yy))),
_ => None, _ => None,
}; };
@ -531,12 +495,12 @@ pub fn get_builtin_op_assignment_fn(
#[cfg(feature = "unchecked")] #[cfg(feature = "unchecked")]
return match op { return match op {
"+=" => impl_op!(from $x += $yy), "+=" => Some(impl_op!(from $x += $yy)),
"-=" => impl_op!(from $x -= $yy), "-=" => Some(impl_op!(from $x -= $yy)),
"*=" => impl_op!(from $x *= $yy), "*=" => Some(impl_op!(from $x *= $yy)),
"/=" => impl_op!(from $x /= $yy), "/=" => Some(impl_op!(from $x /= $yy)),
"%=" => impl_op!(from $x %= $yy), "%=" => Some(impl_op!(from $x %= $yy)),
"**=" => impl_op!(from $x => $xx.powd($yy)), "**=" => Some(impl_op!(from $x => $xx.powd($yy))),
_ => None, _ => None,
}; };
} }
@ -549,8 +513,8 @@ pub fn get_builtin_op_assignment_fn(
// string op= char // string op= char
if types_pair == (TypeId::of::<ImmutableString>(), TypeId::of::<char>()) { if types_pair == (TypeId::of::<ImmutableString>(), TypeId::of::<char>()) {
return match op { return match op {
"+=" => impl_op!(ImmutableString += as_char as char), "+=" => Some(impl_op!(ImmutableString += as_char as char)),
"-=" => impl_op!(ImmutableString -= as_char as char), "-=" => Some(impl_op!(ImmutableString -= as_char as char)),
_ => None, _ => None,
}; };
} }
@ -585,42 +549,42 @@ pub fn get_builtin_op_assignment_fn(
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
match op { match op {
"+=" => return impl_op!(INT => add(as_int, as_int)), "+=" => return Some(impl_op!(INT => add(as_int, as_int))),
"-=" => return impl_op!(INT => subtract(as_int, as_int)), "-=" => return Some(impl_op!(INT => subtract(as_int, as_int))),
"*=" => return impl_op!(INT => multiply(as_int, as_int)), "*=" => return Some(impl_op!(INT => multiply(as_int, as_int))),
"/=" => return impl_op!(INT => divide(as_int, as_int)), "/=" => return Some(impl_op!(INT => divide(as_int, as_int))),
"%=" => return impl_op!(INT => modulo(as_int, as_int)), "%=" => return Some(impl_op!(INT => modulo(as_int, as_int))),
"**=" => return impl_op!(INT => power(as_int, as_int)), "**=" => return Some(impl_op!(INT => power(as_int, as_int))),
">>=" => return impl_op!(INT => shift_right(as_int, as_int)), ">>=" => return Some(impl_op!(INT => shift_right(as_int, as_int))),
"<<=" => return impl_op!(INT => shift_left(as_int, as_int)), "<<=" => return Some(impl_op!(INT => shift_left(as_int, as_int))),
_ => (), _ => (),
} }
#[cfg(feature = "unchecked")] #[cfg(feature = "unchecked")]
match op { match op {
"+=" => return impl_op!(INT += as_int), "+=" => return Some(impl_op!(INT += as_int)),
"-=" => return impl_op!(INT -= as_int), "-=" => return Some(impl_op!(INT -= as_int)),
"*=" => return impl_op!(INT *= as_int), "*=" => return Some(impl_op!(INT *= as_int)),
"/=" => return impl_op!(INT /= as_int), "/=" => return Some(impl_op!(INT /= as_int)),
"%=" => return impl_op!(INT %= as_int), "%=" => return Some(impl_op!(INT %= as_int)),
"**=" => return impl_op!(INT => as_int.pow(as_int as u32)), "**=" => return Some(impl_op!(INT => as_int.pow(as_int as u32))),
">>=" => return impl_op!(INT >>= as_int), ">>=" => return Some(impl_op!(INT >>= as_int)),
"<<=" => return impl_op!(INT <<= as_int), "<<=" => return Some(impl_op!(INT <<= as_int)),
_ => (), _ => (),
} }
return match op { return match op {
"&=" => impl_op!(INT &= as_int), "&=" => Some(impl_op!(INT &= as_int)),
"|=" => impl_op!(INT |= as_int), "|=" => Some(impl_op!(INT |= as_int)),
"^=" => impl_op!(INT ^= as_int), "^=" => Some(impl_op!(INT ^= as_int)),
_ => None, _ => None,
}; };
} }
if type1 == TypeId::of::<bool>() { if type1 == TypeId::of::<bool>() {
return match op { return match op {
"&=" => impl_op!(bool = x && as_bool), "&=" => Some(impl_op!(bool = x && as_bool)),
"|=" => impl_op!(bool = x || as_bool), "|=" => Some(impl_op!(bool = x || as_bool)),
_ => None, _ => None,
}; };
} }