closer, but the function isnt getting the tuple
This commit is contained in:
@@ -241,8 +241,6 @@ impl Grid {
|
|||||||
/// Only evaluates equations, such as `=10` or `=A1/C2`, not
|
/// Only evaluates equations, such as `=10` or `=A1/C2`, not
|
||||||
/// strings or numbers.
|
/// strings or numbers.
|
||||||
pub fn evaluate(&self, mut eq: &str) -> Result<f64, String> {
|
pub fn evaluate(&self, mut eq: &str) -> Result<f64, String> {
|
||||||
let original_equation = eq;
|
|
||||||
|
|
||||||
if eq.starts_with('=') {
|
if eq.starts_with('=') {
|
||||||
eq = &eq[1..];
|
eq = &eq[1..];
|
||||||
} else {
|
} else {
|
||||||
@@ -271,49 +269,6 @@ impl Grid {
|
|||||||
}
|
}
|
||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
EvalexprError::VariableIdentifierNotFound(var_not_found) => {
|
EvalexprError::VariableIdentifierNotFound(var_not_found) => {
|
||||||
// the identifier might be a range: A:A
|
|
||||||
let v = var_not_found.split(':').collect::<Vec<&str>>();
|
|
||||||
if v.len() == 2 {
|
|
||||||
let start_col = v[0];
|
|
||||||
let end_col = v[1];
|
|
||||||
|
|
||||||
let as_index = |s: &str| {
|
|
||||||
s.char_indices().map(|(a, b)| Grid::char_to_idx((a, &b))).fold(0, |a, b| a + b)
|
|
||||||
};
|
|
||||||
|
|
||||||
let start_idx = as_index(start_col);
|
|
||||||
let end_idx = as_index(end_col);
|
|
||||||
|
|
||||||
let mut buf = Vec::new();
|
|
||||||
|
|
||||||
for x in start_idx..=end_idx {
|
|
||||||
for y in 0..=self.max_y_at_x(x) {
|
|
||||||
if let Some(s) = self.get_cell_raw(x, y) {
|
|
||||||
match s {
|
|
||||||
super::calc::CellType::Number(n) => buf.push(n.to_string()),
|
|
||||||
super::calc::CellType::String(_) => (),
|
|
||||||
super::calc::CellType::Equation(e) => buf.push(e.to_string()),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let start = original_equation.find(&var_not_found).expect("It should be here");
|
|
||||||
let end = start + var_not_found.len();
|
|
||||||
|
|
||||||
let res = buf.iter().enumerate().map(|(i,b )| {
|
|
||||||
if i == buf.len()-1 {
|
|
||||||
// last cell
|
|
||||||
b.to_owned()
|
|
||||||
} else {
|
|
||||||
format!("{b},")
|
|
||||||
}
|
|
||||||
}).collect::<String>();
|
|
||||||
|
|
||||||
let new_eq = format!("{}{}{}", &original_equation[..start], res, &original_equation[end..]);
|
|
||||||
|
|
||||||
// FIXME this might be a dangerous recursion, as I don't think its bounded right now
|
|
||||||
return self.evaluate(&new_eq)
|
|
||||||
}
|
|
||||||
return Err(format!("\"{var_not_found}\" is not a variable"));
|
return Err(format!("\"{var_not_found}\" is not a variable"));
|
||||||
}
|
}
|
||||||
EvalexprError::TypeError {
|
EvalexprError::TypeError {
|
||||||
|
|||||||
@@ -14,6 +14,35 @@ pub struct CallbackContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CallbackContext<'a> {
|
impl<'a> CallbackContext<'a> {
|
||||||
|
fn expand_range(&self, range: &str) -> Option<Vec<String>> {
|
||||||
|
let v = range.split(':').collect::<Vec<&str>>();
|
||||||
|
if v.len() == 2 {
|
||||||
|
let start_col = v[0];
|
||||||
|
let end_col = v[1];
|
||||||
|
|
||||||
|
let as_index = |s: &str| s.char_indices().map(|(a, b)| Grid::char_to_idx((a, &b))).fold(0, |a, b| a + b);
|
||||||
|
|
||||||
|
let start_idx = as_index(start_col);
|
||||||
|
let end_idx = as_index(end_col);
|
||||||
|
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
|
||||||
|
for x in start_idx..=end_idx {
|
||||||
|
for y in 0..=self.variables.max_y_at_x(x) {
|
||||||
|
if let Some(s) = self.variables.get_cell_raw(x, y) {
|
||||||
|
match s {
|
||||||
|
super::calc::CellType::Number(n) => buf.push(n.to_string()),
|
||||||
|
super::calc::CellType::String(_) => (),
|
||||||
|
super::calc::CellType::Equation(e) => buf.push(e.to_string()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Some(buf);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn get_functions() -> HashMap<String, Function<DefaultNumericTypes>> {
|
fn get_functions() -> HashMap<String, Function<DefaultNumericTypes>> {
|
||||||
let mut functions = HashMap::new();
|
let mut functions = HashMap::new();
|
||||||
|
|
||||||
@@ -75,21 +104,6 @@ impl<'a> CallbackContext<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn clear_variables(&mut self) {
|
|
||||||
()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn clear_functions(&mut self) {
|
|
||||||
()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn clear(&mut self) {
|
|
||||||
self.clear_variables();
|
|
||||||
self.clear_functions();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Context for CallbackContext<'a> {
|
impl<'a> Context for CallbackContext<'a> {
|
||||||
@@ -113,6 +127,8 @@ impl<'a> Context for CallbackContext<'a> {
|
|||||||
// deep we've gone.
|
// deep we've gone.
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
// remove the equals sign from the beginning, as that
|
||||||
|
// tries to set variables with our evaluation lib
|
||||||
match eval_with_context(&eq[1..], self) {
|
match eval_with_context(&eq[1..], self) {
|
||||||
Ok(e) => return Some(e),
|
Ok(e) => return Some(e),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -130,6 +146,18 @@ impl<'a> Context for CallbackContext<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// identifier not found in cells, might be range
|
||||||
|
if let Some(v) = self.expand_range(identifier) {
|
||||||
|
dbg!(&v);
|
||||||
|
let mut vals = Vec::new();
|
||||||
|
for v in v {
|
||||||
|
if let Some(value) = self.get_value(&v) {
|
||||||
|
vals.push(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Some(Value::Tuple(vals));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user