Skip to content

Commit

Permalink
Enable right side to override binary ops
Browse files Browse the repository at this point in the history
  • Loading branch information
voltrevo committed Jul 17, 2024
1 parent 731e34c commit 27115c3
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 27 deletions.
2 changes: 1 addition & 1 deletion valuescript_vm/src/binary_op.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[derive(Clone, Debug)]
#[derive(Copy, Clone, Debug)]
pub enum BinaryOp {
Plus,
Minus,
Expand Down
56 changes: 34 additions & 22 deletions valuescript_vm/src/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,20 @@ use crate::vs_value::Val;
use crate::vs_value::ValTrait;
use crate::vs_value::VsType;

fn try_binary_override(op: BinaryOp, left: &Val, right: &Val) -> Option<Result<Val, Val>> {
if let Some(res) = left.override_binary_op(op, left, right) {
return Some(res);
}

if let Some(res) = right.override_binary_op(op, left, right) {
return Some(res);
}

None
}

pub fn op_plus(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::Plus, right) {
if let Some(res) = try_binary_override(BinaryOp::Plus, left, right) {
return res;
}

Expand Down Expand Up @@ -66,7 +78,7 @@ pub fn op_unary_plus(input: &Val) -> Result<Val, Val> {
}

pub fn op_minus(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::Minus, right) {
if let Some(res) = try_binary_override(BinaryOp::Minus, left, right) {
return res;
}

Expand All @@ -89,7 +101,7 @@ pub fn op_unary_minus(input: &Val) -> Result<Val, Val> {
}

pub fn op_mul(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::Mul, right) {
if let Some(res) = try_binary_override(BinaryOp::Mul, left, right) {
return res;
}

Expand All @@ -101,7 +113,7 @@ pub fn op_mul(left: &Val, right: &Val) -> Result<Val, Val> {
}

pub fn op_div(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::Div, right) {
if let Some(res) = try_binary_override(BinaryOp::Div, left, right) {
return res;
}

Expand All @@ -113,7 +125,7 @@ pub fn op_div(left: &Val, right: &Val) -> Result<Val, Val> {
}

pub fn op_mod(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::Mod, right) {
if let Some(res) = try_binary_override(BinaryOp::Mod, left, right) {
return res;
}

Expand All @@ -125,7 +137,7 @@ pub fn op_mod(left: &Val, right: &Val) -> Result<Val, Val> {
}

pub fn op_exp(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::Exp, right) {
if let Some(res) = try_binary_override(BinaryOp::Exp, left, right) {
return res;
}

Expand Down Expand Up @@ -281,15 +293,15 @@ where
}

pub fn op_eq(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::LooseEq, right) {
if let Some(res) = try_binary_override(BinaryOp::LooseEq, left, right) {
return res;
}

Ok(Val::Bool(op_eq_impl(left, right)?))
}

pub fn op_ne(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::LooseNe, right) {
if let Some(res) = try_binary_override(BinaryOp::LooseNe, left, right) {
return res;
}

Expand Down Expand Up @@ -400,7 +412,7 @@ pub fn op_triple_eq_impl(left: &Val, right: &Val) -> Result<bool, Val> {
}

pub fn op_triple_eq(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::Eq, right) {
if let Some(res) = try_binary_override(BinaryOp::Eq, left, right) {
return res;
}

Expand All @@ -409,7 +421,7 @@ pub fn op_triple_eq(left: &Val, right: &Val) -> Result<Val, Val> {
}

pub fn op_triple_ne(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::Ne, right) {
if let Some(res) = try_binary_override(BinaryOp::Ne, left, right) {
return res;
}

Expand All @@ -418,7 +430,7 @@ pub fn op_triple_ne(left: &Val, right: &Val) -> Result<Val, Val> {
}

pub fn op_and(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::And, right) {
if let Some(res) = try_binary_override(BinaryOp::And, left, right) {
return res;
}

Expand All @@ -428,7 +440,7 @@ pub fn op_and(left: &Val, right: &Val) -> Result<Val, Val> {
}

pub fn op_or(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::Or, right) {
if let Some(res) = try_binary_override(BinaryOp::Or, left, right) {
return res;
}

Expand All @@ -446,7 +458,7 @@ pub fn op_not(input: &Val) -> Result<Val, Val> {
}

pub fn op_less(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::Less, right) {
if let Some(res) = try_binary_override(BinaryOp::Less, left, right) {
return res;
}

Expand All @@ -462,7 +474,7 @@ pub fn op_less(left: &Val, right: &Val) -> Result<Val, Val> {
}

pub fn op_less_eq(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::LessEq, right) {
if let Some(res) = try_binary_override(BinaryOp::LessEq, left, right) {
return res;
}

Expand All @@ -481,7 +493,7 @@ pub fn op_less_eq(left: &Val, right: &Val) -> Result<Val, Val> {
}

pub fn op_greater(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::Greater, right) {
if let Some(res) = try_binary_override(BinaryOp::Greater, left, right) {
return res;
}

Expand All @@ -497,7 +509,7 @@ pub fn op_greater(left: &Val, right: &Val) -> Result<Val, Val> {
}

pub fn op_greater_eq(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::GreaterEq, right) {
if let Some(res) = try_binary_override(BinaryOp::GreaterEq, left, right) {
return res;
}

Expand Down Expand Up @@ -550,7 +562,7 @@ pub fn to_u32(x: f64) -> u32 {
}

pub fn op_bit_and(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::BitAnd, right) {
if let Some(res) = try_binary_override(BinaryOp::BitAnd, left, right) {
return res;
}

Expand All @@ -565,7 +577,7 @@ pub fn op_bit_and(left: &Val, right: &Val) -> Result<Val, Val> {
}

pub fn op_bit_or(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::BitOr, right) {
if let Some(res) = try_binary_override(BinaryOp::BitOr, left, right) {
return res;
}

Expand Down Expand Up @@ -594,7 +606,7 @@ pub fn op_bit_not(input: &Val) -> Result<Val, Val> {
}

pub fn op_bit_xor(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::BitXor, right) {
if let Some(res) = try_binary_override(BinaryOp::BitXor, left, right) {
return res;
}

Expand All @@ -609,7 +621,7 @@ pub fn op_bit_xor(left: &Val, right: &Val) -> Result<Val, Val> {
}

pub fn op_left_shift(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::LeftShift, right) {
if let Some(res) = try_binary_override(BinaryOp::LeftShift, left, right) {
return res;
}

Expand All @@ -626,7 +638,7 @@ pub fn op_left_shift(left: &Val, right: &Val) -> Result<Val, Val> {
}

pub fn op_right_shift(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::RightShift, right) {
if let Some(res) = try_binary_override(BinaryOp::RightShift, left, right) {
return res;
}

Expand All @@ -646,7 +658,7 @@ pub fn op_right_shift(left: &Val, right: &Val) -> Result<Val, Val> {
}

pub fn op_right_shift_unsigned(left: &Val, right: &Val) -> Result<Val, Val> {
if let Some(res) = left.override_binary_op(BinaryOp::RightShiftUnsigned, right) {
if let Some(res) = try_binary_override(BinaryOp::RightShiftUnsigned, left, right) {
return res;
}

Expand Down
13 changes: 9 additions & 4 deletions valuescript_vm/src/vs_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,12 @@ pub trait ValTrait: fmt::Display {
fn has(&self, key: &Val) -> Option<bool>;
fn submov(&mut self, key: &Val, value: Val) -> Result<(), Val>;

fn override_binary_op(&self, _op: BinaryOp, _right: &Val) -> Option<Result<Val, Val>> {
fn override_binary_op(
&self,
_op: BinaryOp,
_left: &Val,
_right: &Val,
) -> Option<Result<Val, Val>> {
None
}

Expand Down Expand Up @@ -569,7 +574,7 @@ impl ValTrait for Val {
op_submov(self, key, value)
}

fn override_binary_op(&self, op: BinaryOp, right: &Val) -> Option<Result<Val, Val>> {
fn override_binary_op(&self, op: BinaryOp, left: &Val, right: &Val) -> Option<Result<Val, Val>> {
match self {
Val::Void
| Val::Undefined
Expand All @@ -585,8 +590,8 @@ impl ValTrait for Val {
| Val::Class(_)
| Val::CopyCounter(_)
| Val::StoragePtr(_) => None,
Val::Static(static_) => static_.override_binary_op(op, right),
Val::Dynamic(dynamic) => dynamic.override_binary_op(op, right),
Val::Static(static_) => static_.override_binary_op(op, left, right),
Val::Dynamic(dynamic) => dynamic.override_binary_op(op, left, right),
}
}

Expand Down

0 comments on commit 27115c3

Please sign in to comment.