|
|
|
@ -1,20 +1,14 @@
|
|
|
|
|
use crate::data::eval::EvalError;
|
|
|
|
|
use crate::data::op::Op;
|
|
|
|
|
use crate::data::value::Value;
|
|
|
|
|
use crate::data::op::{extract_two_args, Op};
|
|
|
|
|
use crate::data::value::{StaticValue, Value};
|
|
|
|
|
use std::result;
|
|
|
|
|
|
|
|
|
|
type Result<T> = result::Result<T, EvalError>;
|
|
|
|
|
|
|
|
|
|
pub(crate) struct OpAdd;
|
|
|
|
|
|
|
|
|
|
impl Op for OpAdd {
|
|
|
|
|
fn arity(&self) -> Option<usize> {
|
|
|
|
|
Some(2)
|
|
|
|
|
}
|
|
|
|
|
fn name(&self) -> &str {
|
|
|
|
|
"+"
|
|
|
|
|
}
|
|
|
|
|
fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result<Value<'a>> {
|
|
|
|
|
impl OpAdd {
|
|
|
|
|
pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result<Value<'a>> {
|
|
|
|
|
let res: Value = match (left, right) {
|
|
|
|
|
(Value::Int(l), Value::Int(r)) => (l + r).into(),
|
|
|
|
|
(Value::Float(l), Value::Int(r)) => (l + (r as f64)).into(),
|
|
|
|
@ -31,16 +25,32 @@ impl Op for OpAdd {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) struct OpSub;
|
|
|
|
|
|
|
|
|
|
impl Op for OpSub {
|
|
|
|
|
impl Op for OpAdd {
|
|
|
|
|
fn arity(&self) -> Option<usize> {
|
|
|
|
|
Some(2)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn has_side_effect(&self) -> bool {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn name(&self) -> &str {
|
|
|
|
|
"-"
|
|
|
|
|
"+"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn non_null_args(&self) -> bool {
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
fn eval<'a>(&self, args: Vec<Value<'a>>) -> crate::data::op::Result<Value<'a>> {
|
|
|
|
|
let (left, right) = extract_two_args(args);
|
|
|
|
|
self.eval_two_non_null(left, right)
|
|
|
|
|
}
|
|
|
|
|
fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result<Value<'a>> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) struct OpSub;
|
|
|
|
|
|
|
|
|
|
impl OpSub {
|
|
|
|
|
pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result<Value<'a>> {
|
|
|
|
|
let res: Value = match (left, right) {
|
|
|
|
|
(Value::Int(l), Value::Int(r)) => (l - r).into(),
|
|
|
|
|
(Value::Float(l), Value::Int(r)) => (l - (r as f64)).into(),
|
|
|
|
@ -57,16 +67,32 @@ impl Op for OpSub {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) struct OpMul;
|
|
|
|
|
|
|
|
|
|
impl Op for OpMul {
|
|
|
|
|
impl Op for OpSub {
|
|
|
|
|
fn arity(&self) -> Option<usize> {
|
|
|
|
|
Some(2)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn has_side_effect(&self) -> bool {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn name(&self) -> &str {
|
|
|
|
|
"*"
|
|
|
|
|
"-"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn non_null_args(&self) -> bool {
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result<Value<'a>> {
|
|
|
|
|
fn eval<'a>(&self, args: Vec<Value<'a>>) -> crate::data::op::Result<Value<'a>> {
|
|
|
|
|
let (left, right) = extract_two_args(args);
|
|
|
|
|
self.eval_two_non_null(left, right)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) struct OpMul;
|
|
|
|
|
|
|
|
|
|
impl OpMul {
|
|
|
|
|
pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result<Value<'a>> {
|
|
|
|
|
let res: Value = match (left, right) {
|
|
|
|
|
(Value::Int(l), Value::Int(r)) => (l * r).into(),
|
|
|
|
|
(Value::Float(l), Value::Int(r)) => (l * (r as f64)).into(),
|
|
|
|
@ -83,16 +109,33 @@ impl Op for OpMul {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) struct OpDiv;
|
|
|
|
|
|
|
|
|
|
impl Op for OpDiv {
|
|
|
|
|
impl Op for OpMul {
|
|
|
|
|
fn arity(&self) -> Option<usize> {
|
|
|
|
|
Some(2)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn has_side_effect(&self) -> bool {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn name(&self) -> &str {
|
|
|
|
|
"/"
|
|
|
|
|
"*"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn non_null_args(&self) -> bool {
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn eval<'a>(&self, args: Vec<Value<'a>>) -> crate::data::op::Result<Value<'a>> {
|
|
|
|
|
let (left, right) = extract_two_args(args);
|
|
|
|
|
self.eval_two_non_null(left, right)
|
|
|
|
|
}
|
|
|
|
|
fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result<Value<'a>> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) struct OpDiv;
|
|
|
|
|
|
|
|
|
|
impl OpDiv {
|
|
|
|
|
pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result<Value<'a>> {
|
|
|
|
|
let res: Value = match (left, right) {
|
|
|
|
|
(Value::Int(l), Value::Int(r)) => (l as f64 / r as f64).into(),
|
|
|
|
|
(Value::Float(l), Value::Int(r)) => (l / (r as f64)).into(),
|
|
|
|
@ -109,16 +152,33 @@ impl Op for OpDiv {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) struct OpMod;
|
|
|
|
|
|
|
|
|
|
impl Op for OpMod {
|
|
|
|
|
impl Op for OpDiv {
|
|
|
|
|
fn arity(&self) -> Option<usize> {
|
|
|
|
|
Some(2)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn has_side_effect(&self) -> bool {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn name(&self) -> &str {
|
|
|
|
|
"%"
|
|
|
|
|
"/"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn non_null_args(&self) -> bool {
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result<Value<'a>> {
|
|
|
|
|
|
|
|
|
|
fn eval<'a>(&self, args: Vec<Value<'a>>) -> crate::data::op::Result<Value<'a>> {
|
|
|
|
|
let (left, right) = extract_two_args(args);
|
|
|
|
|
self.eval_two_non_null(left, right)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) struct OpMod;
|
|
|
|
|
|
|
|
|
|
impl OpMod {
|
|
|
|
|
pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result<Value<'a>> {
|
|
|
|
|
let res: Value = match (left, right) {
|
|
|
|
|
(Value::Int(l), Value::Int(r)) => (l % r).into(),
|
|
|
|
|
(l, r) => {
|
|
|
|
@ -132,16 +192,33 @@ impl Op for OpMod {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) struct OpPow;
|
|
|
|
|
|
|
|
|
|
impl Op for OpPow {
|
|
|
|
|
impl Op for OpMod {
|
|
|
|
|
fn arity(&self) -> Option<usize> {
|
|
|
|
|
Some(2)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn has_side_effect(&self) -> bool {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn name(&self) -> &str {
|
|
|
|
|
"**"
|
|
|
|
|
"%"
|
|
|
|
|
}
|
|
|
|
|
fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result<Value<'a>> {
|
|
|
|
|
|
|
|
|
|
fn non_null_args(&self) -> bool {
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn eval<'a>(&self, args: Vec<Value<'a>>) -> crate::data::op::Result<Value<'a>> {
|
|
|
|
|
let (left, right) = extract_two_args(args);
|
|
|
|
|
self.eval_two_non_null(left, right)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) struct OpPow;
|
|
|
|
|
|
|
|
|
|
impl OpPow {
|
|
|
|
|
pub(crate) fn eval_two_non_null<'a>(&self, left: Value<'a>, right: Value<'a>) -> Result<Value<'a>> {
|
|
|
|
|
let res: Value = match (left, right) {
|
|
|
|
|
(Value::Int(l), Value::Int(r)) => ((l as f64).powf(r as f64)).into(),
|
|
|
|
|
(Value::Float(l), Value::Int(r)) => ((l.into_inner()).powf(r as f64)).into(),
|
|
|
|
@ -158,13 +235,32 @@ impl Op for OpPow {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) struct OpMinus;
|
|
|
|
|
impl Op for OpPow {
|
|
|
|
|
fn arity(&self) -> Option<usize> {
|
|
|
|
|
Some(2)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn has_side_effect(&self) -> bool {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Op for OpMinus {
|
|
|
|
|
fn name(&self) -> &str {
|
|
|
|
|
"--"
|
|
|
|
|
"**"
|
|
|
|
|
}
|
|
|
|
|
fn eval_one_non_null<'a>(&self, arg: Value<'a>) -> Result<Value<'a>> {
|
|
|
|
|
|
|
|
|
|
fn non_null_args(&self) -> bool {
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
fn eval<'a>(&self, args: Vec<Value<'a>>) -> crate::data::op::Result<Value<'a>> {
|
|
|
|
|
let (left, right) = extract_two_args(args);
|
|
|
|
|
self.eval_two_non_null(left, right)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) struct OpMinus;
|
|
|
|
|
|
|
|
|
|
impl OpMinus {
|
|
|
|
|
pub(crate) fn eval_one_non_null<'a>(&self, arg: Value<'a>) -> Result<Value<'a>> {
|
|
|
|
|
match arg {
|
|
|
|
|
Value::Int(i) => Ok((-i).into()),
|
|
|
|
|
Value::Float(i) => Ok((-i).into()),
|
|
|
|
@ -175,3 +271,21 @@ impl Op for OpMinus {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Op for OpMinus {
|
|
|
|
|
fn arity(&self) -> Option<usize> {
|
|
|
|
|
Some(1)
|
|
|
|
|
}
|
|
|
|
|
fn has_side_effect(&self) -> bool {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
fn non_null_args(&self) -> bool {
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
fn name(&self) -> &str {
|
|
|
|
|
"--"
|
|
|
|
|
}
|
|
|
|
|
fn eval<'a>(&self, args: Vec<Value<'a>>) -> crate::data::op::Result<Value<'a>> {
|
|
|
|
|
self.eval_one_non_null(args.into_iter().next().unwrap())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|