Revise built-in macros.
This commit is contained in:
parent
52d23522e6
commit
d47bfa431a
@ -140,14 +140,14 @@ impl Engine {
|
|||||||
let args = &mut [&mut *lock_guard, &mut new_val];
|
let args = &mut [&mut *lock_guard, &mut new_val];
|
||||||
|
|
||||||
if self.fast_operators() {
|
if self.fast_operators() {
|
||||||
if let Some((func, ctx)) =
|
if let Some((func, need_context)) =
|
||||||
get_builtin_op_assignment_fn(op_assign_token.clone(), args[0], args[1])
|
get_builtin_op_assignment_fn(op_assign_token.clone(), args[0], args[1])
|
||||||
{
|
{
|
||||||
// Built-in found
|
// Built-in found
|
||||||
let op = op_assign_token.literal_syntax();
|
let op = op_assign_token.literal_syntax();
|
||||||
auto_restore! { let orig_level = global.level; global.level += 1 }
|
auto_restore! { let orig_level = global.level; global.level += 1 }
|
||||||
|
|
||||||
let context = if ctx {
|
let context = if need_context {
|
||||||
Some((self, op, None, &*global, *op_pos).into())
|
Some((self, op, None, &*global, *op_pos).into())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -91,65 +91,65 @@ pub fn get_builtin_binary_op_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Option<F
|
|||||||
let type2 = y.type_id();
|
let type2 = y.type_id();
|
||||||
|
|
||||||
macro_rules! impl_op {
|
macro_rules! impl_op {
|
||||||
($xx:ident $op:tt $yy:ident) => { (|_, args| {
|
($xx:ident $op:tt $yy:ident) => { Some((|_, args| {
|
||||||
let x = &*args[0].read_lock::<$xx>().unwrap();
|
let x = &*args[0].read_lock::<$xx>().unwrap();
|
||||||
let y = &*args[1].read_lock::<$yy>().unwrap();
|
let y = &*args[1].read_lock::<$yy>().unwrap();
|
||||||
Ok((x $op y).into())
|
Ok((x $op y).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
($xx:ident . $func:ident ( $yy:ty )) => { (|_, args| {
|
($xx:ident . $func:ident ( $yy:ty )) => { Some((|_, args| {
|
||||||
let x = &*args[0].read_lock::<$xx>().unwrap();
|
let x = &*args[0].read_lock::<$xx>().unwrap();
|
||||||
let y = &*args[1].read_lock::<$yy>().unwrap();
|
let y = &*args[1].read_lock::<$yy>().unwrap();
|
||||||
Ok(x.$func(y).into())
|
Ok(x.$func(y).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
($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>().unwrap();
|
let x = &*args[0].read_lock::<$xx>().unwrap();
|
||||||
let y = &*args[1].read_lock::<$yy>().unwrap();
|
let y = &*args[1].read_lock::<$yy>().unwrap();
|
||||||
Ok(x.$func(y.$yyy()).into())
|
Ok(x.$func(y.$yyy()).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
($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())
|
||||||
}, false) };
|
}, false)) };
|
||||||
($base:ty => $xx:ident $op:tt $yy:ident) => { (|_, args| {
|
($base:ty => $xx:ident $op:tt $yy:ident) => { Some((|_, args| {
|
||||||
let x = args[0].$xx().unwrap() as $base;
|
let x = args[0].$xx().unwrap() as $base;
|
||||||
let y = args[1].$yy().unwrap() as $base;
|
let y = args[1].$yy().unwrap() as $base;
|
||||||
Ok((x $op y).into())
|
Ok((x $op y).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
($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().unwrap() as $base;
|
let x = args[0].$xx().unwrap() as $base;
|
||||||
let y = args[1].$yy().unwrap() as $base;
|
let y = args[1].$yy().unwrap() as $base;
|
||||||
Ok(x.$func(y as $yyy).into())
|
Ok(x.$func(y as $yyy).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
($base:ty => Ok($func:ident ( $xx:ident, $yy:ident ))) => { (|_, args| {
|
($base:ty => Ok($func:ident ( $xx:ident, $yy:ident ))) => { Some((|_, args| {
|
||||||
let x = args[0].$xx().unwrap() as $base;
|
let x = args[0].$xx().unwrap() as $base;
|
||||||
let y = args[1].$yy().unwrap() as $base;
|
let y = args[1].$yy().unwrap() as $base;
|
||||||
Ok($func(x, y).into())
|
Ok($func(x, y).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
($base:ty => $func:ident ( $xx:ident, $yy:ident )) => { (|_, args| {
|
($base:ty => $func:ident ( $xx:ident, $yy:ident )) => { Some((|_, args| {
|
||||||
let x = args[0].$xx().unwrap() as $base;
|
let x = args[0].$xx().unwrap() as $base;
|
||||||
let y = args[1].$yy().unwrap() as $base;
|
let y = args[1].$yy().unwrap() as $base;
|
||||||
$func(x, y).map(Into::into)
|
$func(x, y).map(Into::into)
|
||||||
}, false) };
|
}, false)) };
|
||||||
(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().unwrap());
|
let x = <$base>::from(args[0].$xx().unwrap());
|
||||||
let y = <$base>::from(args[1].$yy().unwrap());
|
let y = <$base>::from(args[1].$yy().unwrap());
|
||||||
Ok((x $op y).into())
|
Ok((x $op y).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
(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().unwrap());
|
let x = <$base>::from(args[0].$xx().unwrap());
|
||||||
let y = <$base>::from(args[1].$yy().unwrap());
|
let y = <$base>::from(args[1].$yy().unwrap());
|
||||||
Ok(x.$func(y).into())
|
Ok(x.$func(y).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
(from $base:ty => Ok($func:ident ( $xx:ident, $yy:ident ))) => { (|_, args| {
|
(from $base:ty => Ok($func:ident ( $xx:ident, $yy:ident ))) => { Some((|_, args| {
|
||||||
let x = <$base>::from(args[0].$xx().unwrap());
|
let x = <$base>::from(args[0].$xx().unwrap());
|
||||||
let y = <$base>::from(args[1].$yy().unwrap());
|
let y = <$base>::from(args[1].$yy().unwrap());
|
||||||
Ok($func(x, y).into())
|
Ok($func(x, y).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
(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().unwrap());
|
let x = <$base>::from(args[0].$xx().unwrap());
|
||||||
let y = <$base>::from(args[1].$yy().unwrap());
|
let y = <$base>::from(args[1].$yy().unwrap());
|
||||||
$func(x, y).map(Into::into)
|
$func(x, y).map(Into::into)
|
||||||
}, false) };
|
}, false)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for common patterns
|
// Check for common patterns
|
||||||
@ -161,25 +161,25 @@ pub fn get_builtin_binary_op_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Option<F
|
|||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
match op {
|
match op {
|
||||||
Plus => return Some(impl_op!(INT => add(as_int, as_int))),
|
Plus => return impl_op!(INT => add(as_int, as_int)),
|
||||||
Minus => return Some(impl_op!(INT => subtract(as_int, as_int))),
|
Minus => return impl_op!(INT => subtract(as_int, as_int)),
|
||||||
Multiply => return Some(impl_op!(INT => multiply(as_int, as_int))),
|
Multiply => return impl_op!(INT => multiply(as_int, as_int)),
|
||||||
Divide => return Some(impl_op!(INT => divide(as_int, as_int))),
|
Divide => return impl_op!(INT => divide(as_int, as_int)),
|
||||||
Modulo => return Some(impl_op!(INT => modulo(as_int, as_int))),
|
Modulo => return impl_op!(INT => modulo(as_int, as_int)),
|
||||||
PowerOf => return Some(impl_op!(INT => power(as_int, as_int))),
|
PowerOf => return impl_op!(INT => power(as_int, as_int)),
|
||||||
RightShift => return Some(impl_op!(INT => Ok(shift_right(as_int, as_int)))),
|
RightShift => return impl_op!(INT => Ok(shift_right(as_int, as_int))),
|
||||||
LeftShift => return Some(impl_op!(INT => Ok(shift_left(as_int, as_int)))),
|
LeftShift => return impl_op!(INT => Ok(shift_left(as_int, as_int))),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "unchecked")]
|
#[cfg(feature = "unchecked")]
|
||||||
match op {
|
match op {
|
||||||
Plus => return Some(impl_op!(INT => as_int + as_int)),
|
Plus => return impl_op!(INT => as_int + as_int),
|
||||||
Minus => return Some(impl_op!(INT => as_int - as_int)),
|
Minus => return impl_op!(INT => as_int - as_int),
|
||||||
Multiply => return Some(impl_op!(INT => as_int * as_int)),
|
Multiply => return impl_op!(INT => as_int * as_int),
|
||||||
Divide => return Some(impl_op!(INT => as_int / as_int)),
|
Divide => return impl_op!(INT => as_int / as_int),
|
||||||
Modulo => return Some(impl_op!(INT => as_int % as_int)),
|
Modulo => return impl_op!(INT => as_int % as_int),
|
||||||
PowerOf => return Some(impl_op!(INT => as_int.pow(as_int as u32))),
|
PowerOf => return impl_op!(INT => as_int.pow(as_int as u32)),
|
||||||
RightShift => {
|
RightShift => {
|
||||||
return Some((
|
return Some((
|
||||||
|_, args| {
|
|_, args| {
|
||||||
@ -204,32 +204,32 @@ pub fn get_builtin_binary_op_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Option<F
|
|||||||
}
|
}
|
||||||
|
|
||||||
return match op {
|
return match op {
|
||||||
EqualsTo => Some(impl_op!(INT => as_int == as_int)),
|
EqualsTo => impl_op!(INT => as_int == as_int),
|
||||||
NotEqualsTo => Some(impl_op!(INT => as_int != as_int)),
|
NotEqualsTo => impl_op!(INT => as_int != as_int),
|
||||||
GreaterThan => Some(impl_op!(INT => as_int > as_int)),
|
GreaterThan => impl_op!(INT => as_int > as_int),
|
||||||
GreaterThanEqualsTo => Some(impl_op!(INT => as_int >= as_int)),
|
GreaterThanEqualsTo => impl_op!(INT => as_int >= as_int),
|
||||||
LessThan => Some(impl_op!(INT => as_int < as_int)),
|
LessThan => impl_op!(INT => as_int < as_int),
|
||||||
LessThanEqualsTo => Some(impl_op!(INT => as_int <= as_int)),
|
LessThanEqualsTo => impl_op!(INT => as_int <= as_int),
|
||||||
Ampersand => Some(impl_op!(INT => as_int & as_int)),
|
Ampersand => impl_op!(INT => as_int & as_int),
|
||||||
Pipe => Some(impl_op!(INT => as_int | as_int)),
|
Pipe => impl_op!(INT => as_int | as_int),
|
||||||
XOr => Some(impl_op!(INT => as_int ^ as_int)),
|
XOr => impl_op!(INT => as_int ^ as_int),
|
||||||
ExclusiveRange => Some(impl_op!(INT => as_int .. as_int)),
|
ExclusiveRange => impl_op!(INT => as_int .. as_int),
|
||||||
InclusiveRange => Some(impl_op!(INT => as_int ..= as_int)),
|
InclusiveRange => 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 {
|
||||||
EqualsTo => Some(impl_op!(bool => as_bool == as_bool)),
|
EqualsTo => impl_op!(bool => as_bool == as_bool),
|
||||||
NotEqualsTo => Some(impl_op!(bool => as_bool != as_bool)),
|
NotEqualsTo => impl_op!(bool => as_bool != as_bool),
|
||||||
GreaterThan => Some(impl_op!(bool => as_bool > as_bool)),
|
GreaterThan => impl_op!(bool => as_bool > as_bool),
|
||||||
GreaterThanEqualsTo => Some(impl_op!(bool => as_bool >= as_bool)),
|
GreaterThanEqualsTo => impl_op!(bool => as_bool >= as_bool),
|
||||||
LessThan => Some(impl_op!(bool => as_bool < as_bool)),
|
LessThan => impl_op!(bool => as_bool < as_bool),
|
||||||
LessThanEqualsTo => Some(impl_op!(bool => as_bool <= as_bool)),
|
LessThanEqualsTo => impl_op!(bool => as_bool <= as_bool),
|
||||||
Ampersand => Some(impl_op!(bool => as_bool & as_bool)),
|
Ampersand => impl_op!(bool => as_bool & as_bool),
|
||||||
Pipe => Some(impl_op!(bool => as_bool | as_bool)),
|
Pipe => impl_op!(bool => as_bool | as_bool),
|
||||||
XOr => Some(impl_op!(bool => as_bool ^ as_bool)),
|
XOr => impl_op!(bool => as_bool ^ as_bool),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -250,13 +250,13 @@ pub fn get_builtin_binary_op_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Option<F
|
|||||||
},
|
},
|
||||||
CHECKED_BUILD,
|
CHECKED_BUILD,
|
||||||
)),
|
)),
|
||||||
Minus => Some(impl_op!(ImmutableString - ImmutableString)),
|
Minus => impl_op!(ImmutableString - ImmutableString),
|
||||||
EqualsTo => Some(impl_op!(ImmutableString == ImmutableString)),
|
EqualsTo => impl_op!(ImmutableString == ImmutableString),
|
||||||
NotEqualsTo => Some(impl_op!(ImmutableString != ImmutableString)),
|
NotEqualsTo => impl_op!(ImmutableString != ImmutableString),
|
||||||
GreaterThan => Some(impl_op!(ImmutableString > ImmutableString)),
|
GreaterThan => impl_op!(ImmutableString > ImmutableString),
|
||||||
GreaterThanEqualsTo => Some(impl_op!(ImmutableString >= ImmutableString)),
|
GreaterThanEqualsTo => impl_op!(ImmutableString >= ImmutableString),
|
||||||
LessThan => Some(impl_op!(ImmutableString < ImmutableString)),
|
LessThan => impl_op!(ImmutableString < ImmutableString),
|
||||||
LessThanEqualsTo => Some(impl_op!(ImmutableString <= ImmutableString)),
|
LessThanEqualsTo => impl_op!(ImmutableString <= ImmutableString),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -279,12 +279,12 @@ pub fn get_builtin_binary_op_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Option<F
|
|||||||
},
|
},
|
||||||
CHECKED_BUILD,
|
CHECKED_BUILD,
|
||||||
)),
|
)),
|
||||||
EqualsTo => Some(impl_op!(char => as_char == as_char)),
|
EqualsTo => impl_op!(char => as_char == as_char),
|
||||||
NotEqualsTo => Some(impl_op!(char => as_char != as_char)),
|
NotEqualsTo => impl_op!(char => as_char != as_char),
|
||||||
GreaterThan => Some(impl_op!(char => as_char > as_char)),
|
GreaterThan => impl_op!(char => as_char > as_char),
|
||||||
GreaterThanEqualsTo => Some(impl_op!(char => as_char >= as_char)),
|
GreaterThanEqualsTo => impl_op!(char => as_char >= as_char),
|
||||||
LessThan => Some(impl_op!(char => as_char < as_char)),
|
LessThan => impl_op!(char => as_char < as_char),
|
||||||
LessThanEqualsTo => Some(impl_op!(char => as_char <= as_char)),
|
LessThanEqualsTo => impl_op!(char => as_char <= as_char),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -316,8 +316,8 @@ pub fn get_builtin_binary_op_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Option<F
|
|||||||
},
|
},
|
||||||
CHECKED_BUILD,
|
CHECKED_BUILD,
|
||||||
)),
|
)),
|
||||||
EqualsTo => Some(impl_op!(Blob == Blob)),
|
EqualsTo => impl_op!(Blob == Blob),
|
||||||
NotEqualsTo => Some(impl_op!(Blob != Blob)),
|
NotEqualsTo => impl_op!(Blob != Blob),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -338,18 +338,18 @@ pub fn get_builtin_binary_op_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Option<F
|
|||||||
($x:ty, $xx:ident, $y:ty, $yy:ident) => {
|
($x:ty, $xx:ident, $y:ty, $yy:ident) => {
|
||||||
if (type1, type2) == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
if (type1, type2) == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
||||||
return match op {
|
return match op {
|
||||||
Plus => Some(impl_op!(FLOAT => $xx + $yy)),
|
Plus => impl_op!(FLOAT => $xx + $yy),
|
||||||
Minus => Some(impl_op!(FLOAT => $xx - $yy)),
|
Minus => impl_op!(FLOAT => $xx - $yy),
|
||||||
Multiply => Some(impl_op!(FLOAT => $xx * $yy)),
|
Multiply => impl_op!(FLOAT => $xx * $yy),
|
||||||
Divide => Some(impl_op!(FLOAT => $xx / $yy)),
|
Divide => impl_op!(FLOAT => $xx / $yy),
|
||||||
Modulo => Some(impl_op!(FLOAT => $xx % $yy)),
|
Modulo => impl_op!(FLOAT => $xx % $yy),
|
||||||
PowerOf => Some(impl_op!(FLOAT => $xx.powf($yy as FLOAT))),
|
PowerOf => impl_op!(FLOAT => $xx.powf($yy as FLOAT)),
|
||||||
EqualsTo => Some(impl_op!(FLOAT => $xx == $yy)),
|
EqualsTo => impl_op!(FLOAT => $xx == $yy),
|
||||||
NotEqualsTo => Some(impl_op!(FLOAT => $xx != $yy)),
|
NotEqualsTo => impl_op!(FLOAT => $xx != $yy),
|
||||||
GreaterThan => Some(impl_op!(FLOAT => $xx > $yy)),
|
GreaterThan => impl_op!(FLOAT => $xx > $yy),
|
||||||
GreaterThanEqualsTo => Some(impl_op!(FLOAT => $xx >= $yy)),
|
GreaterThanEqualsTo => impl_op!(FLOAT => $xx >= $yy),
|
||||||
LessThan => Some(impl_op!(FLOAT => $xx < $yy)),
|
LessThan => impl_op!(FLOAT => $xx < $yy),
|
||||||
LessThanEqualsTo => Some(impl_op!(FLOAT => $xx <= $yy)),
|
LessThanEqualsTo => impl_op!(FLOAT => $xx <= $yy),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -373,12 +373,12 @@ pub fn get_builtin_binary_op_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Option<F
|
|||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
match op {
|
match op {
|
||||||
Plus => return Some(impl_op!(from Decimal => add($xx, $yy))),
|
Plus => return impl_op!(from Decimal => add($xx, $yy)),
|
||||||
Minus => return Some(impl_op!(from Decimal => subtract($xx, $yy))),
|
Minus => return impl_op!(from Decimal => subtract($xx, $yy)),
|
||||||
Multiply => return Some(impl_op!(from Decimal => multiply($xx, $yy))),
|
Multiply => return impl_op!(from Decimal => multiply($xx, $yy)),
|
||||||
Divide => return Some(impl_op!(from Decimal => divide($xx, $yy))),
|
Divide => return impl_op!(from Decimal => divide($xx, $yy)),
|
||||||
Modulo => return Some(impl_op!(from Decimal => modulo($xx, $yy))),
|
Modulo => return impl_op!(from Decimal => modulo($xx, $yy)),
|
||||||
PowerOf => return Some(impl_op!(from Decimal => power($xx, $yy))),
|
PowerOf => return impl_op!(from Decimal => power($xx, $yy)),
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,22 +387,22 @@ pub fn get_builtin_binary_op_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Option<F
|
|||||||
|
|
||||||
#[cfg(feature = "unchecked")]
|
#[cfg(feature = "unchecked")]
|
||||||
match op {
|
match op {
|
||||||
Plus => return Some(impl_op!(from Decimal => $xx + $yy)),
|
Plus => return impl_op!(from Decimal => $xx + $yy),
|
||||||
Minus => return Some(impl_op!(from Decimal => $xx - $yy)),
|
Minus => return impl_op!(from Decimal => $xx - $yy),
|
||||||
Multiply => return Some(impl_op!(from Decimal => $xx * $yy)),
|
Multiply => return impl_op!(from Decimal => $xx * $yy),
|
||||||
Divide => return Some(impl_op!(from Decimal => $xx / $yy)),
|
Divide => return impl_op!(from Decimal => $xx / $yy),
|
||||||
Modulo => return Some(impl_op!(from Decimal => $xx % $yy)),
|
Modulo => return impl_op!(from Decimal => $xx % $yy),
|
||||||
PowerOf => return Some(impl_op!(from Decimal => $xx.powd($yy))),
|
PowerOf => return impl_op!(from Decimal => $xx.powd($yy)),
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
return match op {
|
return match op {
|
||||||
EqualsTo => Some(impl_op!(from Decimal => $xx == $yy)),
|
EqualsTo => impl_op!(from Decimal => $xx == $yy),
|
||||||
NotEqualsTo => Some(impl_op!(from Decimal => $xx != $yy)),
|
NotEqualsTo => impl_op!(from Decimal => $xx != $yy),
|
||||||
GreaterThan => Some(impl_op!(from Decimal => $xx > $yy)),
|
GreaterThan => impl_op!(from Decimal => $xx > $yy),
|
||||||
GreaterThanEqualsTo => Some(impl_op!(from Decimal => $xx >= $yy)),
|
GreaterThanEqualsTo => impl_op!(from Decimal => $xx >= $yy),
|
||||||
LessThan => Some(impl_op!(from Decimal => $xx < $yy)),
|
LessThan => impl_op!(from Decimal => $xx < $yy),
|
||||||
LessThanEqualsTo => Some(impl_op!(from Decimal => $xx <= $yy)),
|
LessThanEqualsTo => impl_op!(from Decimal => $xx <= $yy),
|
||||||
_ => None
|
_ => None
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -444,12 +444,12 @@ pub fn get_builtin_binary_op_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Option<F
|
|||||||
},
|
},
|
||||||
CHECKED_BUILD,
|
CHECKED_BUILD,
|
||||||
)),
|
)),
|
||||||
EqualsTo => Some(impl_op!(get_s1s2(==))),
|
EqualsTo => impl_op!(get_s1s2(==)),
|
||||||
NotEqualsTo => Some(impl_op!(get_s1s2(!=))),
|
NotEqualsTo => impl_op!(get_s1s2(!=)),
|
||||||
GreaterThan => Some(impl_op!(get_s1s2(>))),
|
GreaterThan => impl_op!(get_s1s2(>)),
|
||||||
GreaterThanEqualsTo => Some(impl_op!(get_s1s2(>=))),
|
GreaterThanEqualsTo => impl_op!(get_s1s2(>=)),
|
||||||
LessThan => Some(impl_op!(get_s1s2(<))),
|
LessThan => impl_op!(get_s1s2(<)),
|
||||||
LessThanEqualsTo => Some(impl_op!(get_s1s2(<=))),
|
LessThanEqualsTo => impl_op!(get_s1s2(<=)),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -486,12 +486,12 @@ pub fn get_builtin_binary_op_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Option<F
|
|||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
)),
|
)),
|
||||||
EqualsTo => Some(impl_op!(get_s1s2(==))),
|
EqualsTo => impl_op!(get_s1s2(==)),
|
||||||
NotEqualsTo => Some(impl_op!(get_s1s2(!=))),
|
NotEqualsTo => impl_op!(get_s1s2(!=)),
|
||||||
GreaterThan => Some(impl_op!(get_s1s2(>))),
|
GreaterThan => impl_op!(get_s1s2(>)),
|
||||||
GreaterThanEqualsTo => Some(impl_op!(get_s1s2(>=))),
|
GreaterThanEqualsTo => impl_op!(get_s1s2(>=)),
|
||||||
LessThan => Some(impl_op!(get_s1s2(<))),
|
LessThan => impl_op!(get_s1s2(<)),
|
||||||
LessThanEqualsTo => Some(impl_op!(get_s1s2(<=))),
|
LessThanEqualsTo => impl_op!(get_s1s2(<=)),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -568,16 +568,16 @@ pub fn get_builtin_binary_op_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Option<F
|
|||||||
// Handle ranges here because ranges are implemented as custom type
|
// Handle ranges here because ranges are implemented as custom type
|
||||||
if type1 == TypeId::of::<ExclusiveRange>() && type1 == type2 {
|
if type1 == TypeId::of::<ExclusiveRange>() && type1 == type2 {
|
||||||
return match op {
|
return match op {
|
||||||
EqualsTo => Some(impl_op!(ExclusiveRange == ExclusiveRange)),
|
EqualsTo => impl_op!(ExclusiveRange == ExclusiveRange),
|
||||||
NotEqualsTo => Some(impl_op!(ExclusiveRange != ExclusiveRange)),
|
NotEqualsTo => impl_op!(ExclusiveRange != ExclusiveRange),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if type1 == TypeId::of::<InclusiveRange>() && type1 == type2 {
|
if type1 == TypeId::of::<InclusiveRange>() && type1 == type2 {
|
||||||
return match op {
|
return match op {
|
||||||
EqualsTo => Some(impl_op!(InclusiveRange == InclusiveRange)),
|
EqualsTo => impl_op!(InclusiveRange == InclusiveRange),
|
||||||
NotEqualsTo => Some(impl_op!(InclusiveRange != InclusiveRange)),
|
NotEqualsTo => impl_op!(InclusiveRange != InclusiveRange),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -626,54 +626,54 @@ pub fn get_builtin_op_assignment_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Opti
|
|||||||
let type2 = y.type_id();
|
let type2 = y.type_id();
|
||||||
|
|
||||||
macro_rules! impl_op {
|
macro_rules! impl_op {
|
||||||
($x:ty = x $op:tt $yy:ident) => { (|_, args| {
|
($x:ty = x $op:tt $yy:ident) => { Some((|_, args| {
|
||||||
let x = args[0].$yy().unwrap();
|
let x = args[0].$yy().unwrap();
|
||||||
let y = args[1].$yy().unwrap() as $x;
|
let y = args[1].$yy().unwrap() as $x;
|
||||||
Ok((*args[0].write_lock::<$x>().unwrap() = x $op y).into())
|
Ok((*args[0].write_lock::<$x>().unwrap() = x $op y).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
($x:ident $op:tt $yy:ident) => { (|_, args| {
|
($x:ident $op:tt $yy:ident) => { Some((|_, args| {
|
||||||
let y = args[1].$yy().unwrap() as $x;
|
let y = args[1].$yy().unwrap() as $x;
|
||||||
Ok((*args[0].write_lock::<$x>().unwrap() $op y).into())
|
Ok((*args[0].write_lock::<$x>().unwrap() $op y).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
($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().unwrap() as $yyy;
|
let y = args[1].$yy().unwrap() as $yyy;
|
||||||
Ok((*args[0].write_lock::<$x>().unwrap() $op y).into())
|
Ok((*args[0].write_lock::<$x>().unwrap() $op y).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
($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().unwrap();
|
let x = args[0].$xx().unwrap();
|
||||||
let y = args[1].$yy().unwrap() as $x;
|
let y = args[1].$yy().unwrap() as $x;
|
||||||
Ok((*args[0].write_lock::<$x>().unwrap() = x.$func(y as $yyy)).into())
|
Ok((*args[0].write_lock::<$x>().unwrap() = x.$func(y as $yyy)).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
($x:ty => Ok($func:ident ( $xx:ident, $yy:ident ))) => { (|_, args| {
|
($x:ty => Ok($func:ident ( $xx:ident, $yy:ident ))) => { Some((|_, args| {
|
||||||
let x = args[0].$xx().unwrap();
|
let x = args[0].$xx().unwrap();
|
||||||
let y = args[1].$yy().unwrap() as $x;
|
let y = args[1].$yy().unwrap() as $x;
|
||||||
let v: Dynamic = $func(x, y).into();
|
let v: Dynamic = $func(x, y).into();
|
||||||
Ok((*args[0].write_lock().unwrap() = v).into())
|
Ok((*args[0].write_lock().unwrap() = v).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
($x:ty => $func:ident ( $xx:ident, $yy:ident )) => { (|_, args| {
|
($x:ty => $func:ident ( $xx:ident, $yy:ident )) => { Some((|_, args| {
|
||||||
let x = args[0].$xx().unwrap();
|
let x = args[0].$xx().unwrap();
|
||||||
let y = args[1].$yy().unwrap() as $x;
|
let y = args[1].$yy().unwrap() as $x;
|
||||||
Ok((*args[0].write_lock().unwrap() = $func(x, y)?).into())
|
Ok((*args[0].write_lock().unwrap() = $func(x, y)?).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
(from $x:ident $op:tt $yy:ident) => { (|_, args| {
|
(from $x:ident $op:tt $yy:ident) => { Some((|_, args| {
|
||||||
let y = <$x>::from(args[1].$yy().unwrap());
|
let y = <$x>::from(args[1].$yy().unwrap());
|
||||||
Ok((*args[0].write_lock::<$x>().unwrap() $op y).into())
|
Ok((*args[0].write_lock::<$x>().unwrap() $op y).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
(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().unwrap();
|
let x = args[0].$xx().unwrap();
|
||||||
let y = <$x>::from(args[1].$yy().unwrap());
|
let y = <$x>::from(args[1].$yy().unwrap());
|
||||||
Ok((*args[0].write_lock::<$x>().unwrap() = x.$func(y)).into())
|
Ok((*args[0].write_lock::<$x>().unwrap() = x.$func(y)).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
(from $x:ty => Ok($func:ident ( $xx:ident, $yy:ident ))) => { (|_, args| {
|
(from $x:ty => Ok($func:ident ( $xx:ident, $yy:ident ))) => { Some((|_, args| {
|
||||||
let x = args[0].$xx().unwrap();
|
let x = args[0].$xx().unwrap();
|
||||||
let y = <$x>::from(args[1].$yy().unwrap());
|
let y = <$x>::from(args[1].$yy().unwrap());
|
||||||
Ok((*args[0].write_lock().unwrap() = $func(x, y).into()).into())
|
Ok((*args[0].write_lock().unwrap() = $func(x, y).into()).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
(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().unwrap();
|
let x = args[0].$xx().unwrap();
|
||||||
let y = <$x>::from(args[1].$yy().unwrap());
|
let y = <$x>::from(args[1].$yy().unwrap());
|
||||||
Ok((*args[0].write_lock().unwrap() = $func(x, y)?).into())
|
Ok((*args[0].write_lock().unwrap() = $func(x, y)?).into())
|
||||||
}, false) };
|
}, false)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for common patterns
|
// Check for common patterns
|
||||||
@ -685,25 +685,25 @@ pub fn get_builtin_op_assignment_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Opti
|
|||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
match op {
|
match op {
|
||||||
PlusAssign => return Some(impl_op!(INT => add(as_int, as_int))),
|
PlusAssign => return impl_op!(INT => add(as_int, as_int)),
|
||||||
MinusAssign => return Some(impl_op!(INT => subtract(as_int, as_int))),
|
MinusAssign => return impl_op!(INT => subtract(as_int, as_int)),
|
||||||
MultiplyAssign => return Some(impl_op!(INT => multiply(as_int, as_int))),
|
MultiplyAssign => return impl_op!(INT => multiply(as_int, as_int)),
|
||||||
DivideAssign => return Some(impl_op!(INT => divide(as_int, as_int))),
|
DivideAssign => return impl_op!(INT => divide(as_int, as_int)),
|
||||||
ModuloAssign => return Some(impl_op!(INT => modulo(as_int, as_int))),
|
ModuloAssign => return impl_op!(INT => modulo(as_int, as_int)),
|
||||||
PowerOfAssign => return Some(impl_op!(INT => power(as_int, as_int))),
|
PowerOfAssign => return impl_op!(INT => power(as_int, as_int)),
|
||||||
RightShiftAssign => return Some(impl_op!(INT => Ok(shift_right(as_int, as_int)))),
|
RightShiftAssign => return impl_op!(INT => Ok(shift_right(as_int, as_int))),
|
||||||
LeftShiftAssign => return Some(impl_op!(INT => Ok(shift_left(as_int, as_int)))),
|
LeftShiftAssign => return impl_op!(INT => Ok(shift_left(as_int, as_int))),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "unchecked")]
|
#[cfg(feature = "unchecked")]
|
||||||
match op {
|
match op {
|
||||||
PlusAssign => return Some(impl_op!(INT += as_int)),
|
PlusAssign => return impl_op!(INT += as_int),
|
||||||
MinusAssign => return Some(impl_op!(INT -= as_int)),
|
MinusAssign => return impl_op!(INT -= as_int),
|
||||||
MultiplyAssign => return Some(impl_op!(INT *= as_int)),
|
MultiplyAssign => return impl_op!(INT *= as_int),
|
||||||
DivideAssign => return Some(impl_op!(INT /= as_int)),
|
DivideAssign => return impl_op!(INT /= as_int),
|
||||||
ModuloAssign => return Some(impl_op!(INT %= as_int)),
|
ModuloAssign => return impl_op!(INT %= as_int),
|
||||||
PowerOfAssign => return Some(impl_op!(INT => as_int.pow(as_int as u32))),
|
PowerOfAssign => return impl_op!(INT => as_int.pow(as_int as u32)),
|
||||||
RightShiftAssign => {
|
RightShiftAssign => {
|
||||||
return Some((
|
return Some((
|
||||||
|_, args| {
|
|_, args| {
|
||||||
@ -730,17 +730,17 @@ pub fn get_builtin_op_assignment_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Opti
|
|||||||
}
|
}
|
||||||
|
|
||||||
return match op {
|
return match op {
|
||||||
AndAssign => Some(impl_op!(INT &= as_int)),
|
AndAssign => impl_op!(INT &= as_int),
|
||||||
OrAssign => Some(impl_op!(INT |= as_int)),
|
OrAssign => impl_op!(INT |= as_int),
|
||||||
XOrAssign => Some(impl_op!(INT ^= as_int)),
|
XOrAssign => impl_op!(INT ^= as_int),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if type1 == TypeId::of::<bool>() {
|
if type1 == TypeId::of::<bool>() {
|
||||||
return match op {
|
return match op {
|
||||||
AndAssign => Some(impl_op!(bool = x && as_bool)),
|
AndAssign => impl_op!(bool = x && as_bool),
|
||||||
OrAssign => Some(impl_op!(bool = x || as_bool)),
|
OrAssign => impl_op!(bool = x || as_bool),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -861,12 +861,12 @@ pub fn get_builtin_op_assignment_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Opti
|
|||||||
($x:ident, $xx:ident, $y:ty, $yy:ident) => {
|
($x:ident, $xx:ident, $y:ty, $yy:ident) => {
|
||||||
if (type1, type2) == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
if (type1, type2) == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
||||||
return match op {
|
return match op {
|
||||||
PlusAssign => Some(impl_op!($x += $yy)),
|
PlusAssign => impl_op!($x += $yy),
|
||||||
MinusAssign => Some(impl_op!($x -= $yy)),
|
MinusAssign => impl_op!($x -= $yy),
|
||||||
MultiplyAssign => Some(impl_op!($x *= $yy)),
|
MultiplyAssign => impl_op!($x *= $yy),
|
||||||
DivideAssign => Some(impl_op!($x /= $yy)),
|
DivideAssign => impl_op!($x /= $yy),
|
||||||
ModuloAssign => Some(impl_op!($x %= $yy)),
|
ModuloAssign => impl_op!($x %= $yy),
|
||||||
PowerOfAssign => Some(impl_op!($x => $xx.powf($yy as $x))),
|
PowerOfAssign => impl_op!($x => $xx.powf($yy as $x)),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -889,12 +889,12 @@ pub fn get_builtin_op_assignment_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Opti
|
|||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
return match op {
|
return match op {
|
||||||
PlusAssign => Some(impl_op!(from $x => add($xx, $yy))),
|
PlusAssign => impl_op!(from $x => add($xx, $yy)),
|
||||||
MinusAssign => Some(impl_op!(from $x => subtract($xx, $yy))),
|
MinusAssign => impl_op!(from $x => subtract($xx, $yy)),
|
||||||
MultiplyAssign => Some(impl_op!(from $x => multiply($xx, $yy))),
|
MultiplyAssign => impl_op!(from $x => multiply($xx, $yy)),
|
||||||
DivideAssign => Some(impl_op!(from $x => divide($xx, $yy))),
|
DivideAssign => impl_op!(from $x => divide($xx, $yy)),
|
||||||
ModuloAssign => Some(impl_op!(from $x => modulo($xx, $yy))),
|
ModuloAssign => impl_op!(from $x => modulo($xx, $yy)),
|
||||||
PowerOfAssign => Some(impl_op!(from $x => power($xx, $yy))),
|
PowerOfAssign => impl_op!(from $x => power($xx, $yy)),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -903,12 +903,12 @@ pub fn get_builtin_op_assignment_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Opti
|
|||||||
|
|
||||||
#[cfg(feature = "unchecked")]
|
#[cfg(feature = "unchecked")]
|
||||||
return match op {
|
return match op {
|
||||||
PlusAssign => Some(impl_op!(from $x += $yy)),
|
PlusAssign => impl_op!(from $x += $yy),
|
||||||
MinusAssign => Some(impl_op!(from $x -= $yy)),
|
MinusAssign => impl_op!(from $x -= $yy),
|
||||||
MultiplyAssign => Some(impl_op!(from $x *= $yy)),
|
MultiplyAssign => impl_op!(from $x *= $yy),
|
||||||
DivideAssign => Some(impl_op!(from $x /= $yy)),
|
DivideAssign => impl_op!(from $x /= $yy),
|
||||||
ModuloAssign => Some(impl_op!(from $x %= $yy)),
|
ModuloAssign => impl_op!(from $x %= $yy),
|
||||||
PowerOfAssign => Some(impl_op!(from $x => $xx.powd($yy))),
|
PowerOfAssign => impl_op!(from $x => $xx.powd($yy)),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -939,7 +939,7 @@ pub fn get_builtin_op_assignment_fn(op: Token, x: &Dynamic, y: &Dynamic) -> Opti
|
|||||||
},
|
},
|
||||||
CHECKED_BUILD,
|
CHECKED_BUILD,
|
||||||
)),
|
)),
|
||||||
MinusAssign => Some(impl_op!(ImmutableString -= as_char as char)),
|
MinusAssign => impl_op!(ImmutableString -= as_char as char),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1611,13 +1611,13 @@ impl Engine {
|
|||||||
|
|
||||||
let operands = &mut [&mut lhs, &mut rhs];
|
let operands = &mut [&mut lhs, &mut rhs];
|
||||||
|
|
||||||
if let Some((func, ctx)) =
|
if let Some((func, need_context)) =
|
||||||
get_builtin_binary_op_fn(op_token.clone(), operands[0], operands[1])
|
get_builtin_binary_op_fn(op_token.clone(), operands[0], operands[1])
|
||||||
{
|
{
|
||||||
// Built-in found
|
// Built-in found
|
||||||
auto_restore! { let orig_level = global.level; global.level += 1 }
|
auto_restore! { let orig_level = global.level; global.level += 1 }
|
||||||
|
|
||||||
let context = if ctx {
|
let context = if need_context {
|
||||||
Some((self, name.as_str(), None, &*global, pos).into())
|
Some((self, name.as_str(), None, &*global, pos).into())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
Loading…
Reference in New Issue
Block a user