🙃
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::cell::CellRef;
|
||||
use crate::common::LeadErr;
|
||||
use crate::common::LeadErrCode;
|
||||
use crate::common::Literal;
|
||||
use crate::grid::Grid;
|
||||
use crate::parser::*;
|
||||
use std::collections::HashSet;
|
||||
use std::f64;
|
||||
use std::fmt;
|
||||
use crate::{
|
||||
cell::CellRef,
|
||||
common::{LeadErr, LeadErrCode, Literal},
|
||||
evaluator::utils::*,
|
||||
grid::Grid,
|
||||
parser::*,
|
||||
};
|
||||
|
||||
use std::{collections::HashSet, f64, fmt};
|
||||
|
||||
mod utils;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
@@ -266,37 +268,6 @@ fn eval_avg(
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_single_arg_numeric(
|
||||
args: &Vec<Expr>,
|
||||
precs: &mut HashSet<CellRef>,
|
||||
grid: Option<&Grid>,
|
||||
func: fn(f64) -> f64,
|
||||
func_name: String,
|
||||
) -> Result<Eval, LeadErr> {
|
||||
if args.len() != 1 {
|
||||
return Err(LeadErr {
|
||||
title: "Evaluation error.".into(),
|
||||
desc: format!("{func_name} function requires a single argument."),
|
||||
code: LeadErrCode::Invalid,
|
||||
});
|
||||
}
|
||||
|
||||
let err = LeadErr {
|
||||
title: "Evaluation error.".into(),
|
||||
desc: format!("{func_name} function requires a numeric argument."),
|
||||
code: LeadErrCode::TypeErr,
|
||||
};
|
||||
|
||||
match evaluate_expr(&args[0], precs, grid)? {
|
||||
Eval::Literal(Literal::Number(num)) => Ok(Eval::Literal(Literal::Number(func(num)))),
|
||||
Eval::CellRef { eval, .. } => match *eval {
|
||||
Eval::Literal(Literal::Number(n)) => Ok(Eval::Literal(Literal::Number(func(n)))),
|
||||
_ => Err(err),
|
||||
},
|
||||
_ => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_const(args: &Vec<Expr>, value: Eval) -> Result<Eval, LeadErr> {
|
||||
if args.len() != 0 {
|
||||
return Err(LeadErr {
|
||||
76
backend/src/evaluator/utils.rs
Normal file
76
backend/src/evaluator/utils.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use crate::{
|
||||
cell::CellRef,
|
||||
common::{LeadErr, LeadErrCode, Literal},
|
||||
evaluator::{Eval, evaluate_expr},
|
||||
grid::Grid,
|
||||
parser::Expr,
|
||||
};
|
||||
|
||||
pub fn eval_single_arg_numeric(
|
||||
args: &Vec<Expr>,
|
||||
precs: &mut HashSet<CellRef>,
|
||||
grid: Option<&Grid>,
|
||||
func: fn(f64) -> f64,
|
||||
func_name: String,
|
||||
) -> Result<Eval, LeadErr> {
|
||||
if args.len() != 1 {
|
||||
return Err(LeadErr {
|
||||
title: "Evaluation error.".into(),
|
||||
desc: format!("{func_name} function requires a single argument."),
|
||||
code: LeadErrCode::Invalid,
|
||||
});
|
||||
}
|
||||
let err = LeadErr {
|
||||
title: "Evaluation error.".into(),
|
||||
desc: format!("{func_name} function requires a numeric argument."),
|
||||
code: LeadErrCode::TypeErr,
|
||||
};
|
||||
match evaluate_expr(&args[0], precs, grid)? {
|
||||
Eval::Literal(Literal::Number(num)) => Ok(Eval::Literal(Literal::Number(func(num)))),
|
||||
Eval::CellRef { eval, .. } => match *eval {
|
||||
Eval::Literal(Literal::Number(n)) => Ok(Eval::Literal(Literal::Number(func(n)))),
|
||||
_ => Err(err),
|
||||
},
|
||||
_ => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eval_n_arg_numeric(
|
||||
n: usize,
|
||||
args: &Vec<Expr>,
|
||||
precs: &mut HashSet<CellRef>,
|
||||
grid: Option<&Grid>,
|
||||
func: fn(Vec<f64>) -> f64,
|
||||
func_name: String,
|
||||
) -> Result<Eval, LeadErr> {
|
||||
if args.len() != n {
|
||||
return Err(LeadErr {
|
||||
title: "Evaluation error.".into(),
|
||||
desc: format!("{func_name} function requires {n} argument(s)."),
|
||||
code: LeadErrCode::Invalid,
|
||||
});
|
||||
}
|
||||
|
||||
let err = LeadErr {
|
||||
title: "Evaluation error.".into(),
|
||||
desc: format!("{func_name} function requires numeric argument(s)."),
|
||||
code: LeadErrCode::TypeErr,
|
||||
};
|
||||
|
||||
let mut numbers = Vec::with_capacity(n);
|
||||
|
||||
for arg in args {
|
||||
match evaluate_expr(arg, precs, grid)? {
|
||||
Eval::Literal(Literal::Number(num)) => numbers.push(num),
|
||||
Eval::CellRef { eval, .. } => match *eval {
|
||||
Eval::Literal(Literal::Number(num)) => numbers.push(num),
|
||||
_ => return Err(err.clone()),
|
||||
},
|
||||
_ => return Err(err.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Eval::Literal(Literal::Number(func(numbers))))
|
||||
}
|
||||
Reference in New Issue
Block a user