From d4a9dad1539e2128fd86aaed1269374ffa0c4c4e Mon Sep 17 00:00:00 2001 From: bakk Date: Sun, 23 Jan 2022 00:18:49 +0100 Subject: [PATCH] Error message when trying to index by imaginary number --- kalk/src/interpreter.rs | 51 ++++++++++++++++++++++++++++------------- kalk/src/parser.rs | 2 ++ 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/kalk/src/interpreter.rs b/kalk/src/interpreter.rs index 672d950..3152200 100644 --- a/kalk/src/interpreter.rs +++ b/kalk/src/interpreter.rs @@ -620,30 +620,30 @@ fn eval_matrix(context: &mut Context, rows: &[Vec]) -> Result Result { let var_value = eval_expr(context, var, unit)?; match var_value { KalkValue::Vector(values) => { - if indexes.len() != 1 { - return Err(CalcError::IncorrectAmountOfIndexes(indexes.len(), 1)); + if index_expressions.len() != 1 { + return Err(CalcError::IncorrectAmountOfIndexes( + index_expressions.len(), + 1, + )); } - let index_value = eval_expr(context, &indexes[0], unit)?.to_f64() as usize; - if index_value == 0 { - return Err(CalcError::ItemOfIndexDoesNotExist(vec![index_value])); - } - - if let Some(value) = values.get(index_value - 1) { + let index = as_indices(context, index_expressions)?[0]; + if let Some(value) = values.get(index - 1) { Ok(value.clone()) } else { - Err(CalcError::ItemOfIndexDoesNotExist(vec![index_value])) + Err(CalcError::ItemOfIndexDoesNotExist(vec![index])) } } KalkValue::Matrix(rows) => { - if indexes.len() == 1 { - let row_index = eval_expr(context, &indexes[0], unit)?.to_f64() as usize; + let indices = as_indices(context, index_expressions)?; + if indices.len() == 1 { + let row_index = indices[0]; return if let Some(row) = rows.get(row_index - 1) { Ok(KalkValue::Vector(row.clone())) } else { @@ -651,12 +651,12 @@ fn eval_indexer( }; } - if indexes.len() != 2 { - return Err(CalcError::IncorrectAmountOfIndexes(indexes.len(), 2)); + if indices.len() != 2 { + return Err(CalcError::IncorrectAmountOfIndexes(indices.len(), 2)); } - let row_index = eval_expr(context, &indexes[0], unit)?.to_f64() as usize; - let column_index = eval_expr(context, &indexes[1], unit)?.to_f64() as usize; + let row_index = indices[0]; + let column_index = indices[1]; if row_index == 0 || column_index == 0 { return Err(CalcError::ItemOfIndexDoesNotExist(vec![ row_index, @@ -679,6 +679,25 @@ fn eval_indexer( } } +fn as_indices(context: &mut Context, expressions: &[Expr]) -> Result, CalcError> { + let mut indices = Vec::new(); + for expr in expressions { + let value = eval_expr(context, expr, "")?; + if value.has_imaginary() { + return Err(CalcError::CannotIndexByImaginary); + } + + let index = value.to_f64() as usize; + if index == 0 { + return Err(CalcError::ItemOfIndexDoesNotExist(vec![index])); + } + + indices.push(index); + } + + Ok(indices) +} + fn eval_comprehension( context: &mut Context, left: &Expr, diff --git a/kalk/src/parser.rs b/kalk/src/parser.rs index c97518b..54414bd 100644 --- a/kalk/src/parser.rs +++ b/kalk/src/parser.rs @@ -89,6 +89,7 @@ impl Default for Context { /// Error that occured during parsing or evaluation. #[derive(Debug, Clone, PartialEq)] pub enum CalcError { + CannotIndexByImaginary, CanOnlyIndexX, Expected(String), ExpectedDx, @@ -118,6 +119,7 @@ pub enum CalcError { impl ToString for CalcError { fn to_string(&self) -> String { match self { + CalcError::CannotIndexByImaginary => String::from("Cannot index by imaginary numbers."), CalcError::CanOnlyIndexX => String::from("Indexing (getting an item with a specific index) is only possible on vectors and matrices."), CalcError::Expected(description) => format!("Expected: {}", description), CalcError::ExpectedDx => String::from("Expected eg. dx, to specify for which variable the operation is being done to. Example with integration: ∫(0, 1, x dx) or ∫(0, 1, x, dx). You may need to put parenthesis around the expression before dx/dy/du/etc."),