gt ge lt le

main
Ziyang Hu 2 years ago
parent a9417bdd8f
commit 9ed4e5174b

@ -250,11 +250,11 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
value::OP_NE => self.ne_values(args)?,
value::OP_OR => self.or_values(args)?,
value::OP_AND => self.and_values(args)?,
value::OP_MOD => { todo!() }
value::OP_GT => { todo!() }
value::OP_GE => { todo!() }
value::OP_LT => { todo!() }
value::OP_LE => { todo!() }
value::OP_MOD => self.mod_values(args)?,
value::OP_GT => self.gt_values(args)?,
value::OP_GE => self.ge_values(args)?,
value::OP_LT => self.lt_values(args)?,
value::OP_LE => self.le_values(args)?,
value::OP_POW => { todo!() }
value::OP_COALESCE => { todo!() }
value::OP_NEGATE => { todo!() }
@ -291,7 +291,7 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_ADD.into(), vec![left, right])));
return Ok((false, Apply(value::OP_SUB.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l - r).into()),
@ -300,6 +300,89 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
(_, _) => return Err(CozoError::InvalidArgument)
})
}
fn gt_values<'a>(&self, args: Vec<Value<'a>>) -> Result<(bool, Value<'a>)> {
let mut args = args.into_iter();
let (le, left) = self.partial_eval(args.next().unwrap())?;
let (re, right) = self.partial_eval(args.next().unwrap())?;
if left == Value::Null || right == Value::Null {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_GT.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l > r).into()),
(Value::Float(l), Value::Int(r)) => (true, (l > (r as f64).into()).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) > r.into_inner()).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
fn lt_values<'a>(&self, args: Vec<Value<'a>>) -> Result<(bool, Value<'a>)> {
let mut args = args.into_iter();
let (le, left) = self.partial_eval(args.next().unwrap())?;
let (re, right) = self.partial_eval(args.next().unwrap())?;
if left == Value::Null || right == Value::Null {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_LT.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l < r).into()),
(Value::Float(l), Value::Int(r)) => (true, (l < (r as f64).into()).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) < r.into_inner()).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
fn ge_values<'a>(&self, args: Vec<Value<'a>>) -> Result<(bool, Value<'a>)> {
let mut args = args.into_iter();
let (le, left) = self.partial_eval(args.next().unwrap())?;
let (re, right) = self.partial_eval(args.next().unwrap())?;
if left == Value::Null || right == Value::Null {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_GE.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l >= r).into()),
(Value::Float(l), Value::Int(r)) => (true, (l >= (r as f64).into()).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) >= r.into_inner()).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
fn le_values<'a>(&self, args: Vec<Value<'a>>) -> Result<(bool, Value<'a>)> {
let mut args = args.into_iter();
let (le, left) = self.partial_eval(args.next().unwrap())?;
let (re, right) = self.partial_eval(args.next().unwrap())?;
if left == Value::Null || right == Value::Null {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_GE.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l <= r).into()),
(Value::Float(l), Value::Int(r)) => (true, (l <= (r as f64).into()).into()),
(Value::Int(l), Value::Float(r)) => (true, ((l as f64) <= r.into_inner()).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
fn mod_values<'a>(&self, args: Vec<Value<'a>>) -> Result<(bool, Value<'a>)> {
let mut args = args.into_iter();
let (le, left) = self.partial_eval(args.next().unwrap())?;
let (re, right) = self.partial_eval(args.next().unwrap())?;
if left == Value::Null || right == Value::Null {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_MOD.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l % r).into()),
(_, _) => return Err(CozoError::InvalidArgument)
})
}
fn mul_values<'a>(&self, args: Vec<Value<'a>>) -> Result<(bool, Value<'a>)> {
let mut args = args.into_iter();
let (le, left) = self.partial_eval(args.next().unwrap())?;
@ -308,7 +391,7 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_ADD.into(), vec![left, right])));
return Ok((false, Apply(value::OP_MUL.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l * r).into()),
@ -325,7 +408,7 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
return Ok((true, Value::Null));
}
if !le || !re {
return Ok((false, Apply(value::OP_ADD.into(), vec![left, right])));
return Ok((false, Apply(value::OP_DIV.into(), vec![left, right])));
}
Ok(match (left, right) {
(Value::Int(l), Value::Int(r)) => (true, (l as f64 / r as f64).into()),

Loading…
Cancel
Save