Error message when trying to index by imaginary number

This commit is contained in:
bakk 2022-01-23 00:18:49 +01:00 committed by PaddiM8
parent 39cbbb607d
commit d4a9dad153
2 changed files with 37 additions and 16 deletions

View File

@ -620,30 +620,30 @@ fn eval_matrix(context: &mut Context, rows: &[Vec<Expr>]) -> Result<KalkValue, C
fn eval_indexer(
context: &mut Context,
var: &Expr,
indexes: &[Expr],
index_expressions: &[Expr],
unit: &str,
) -> Result<KalkValue, CalcError> {
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<Vec<usize>, 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,

View File

@ -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."),