mirror of
https://github.com/PaddiM8/kalker.git
synced 2024-11-07 08:24:33 +01:00
Renamed CalcError to KalkError
This commit is contained in:
parent
1630a8282e
commit
136036f3f0
@ -3,11 +3,10 @@ Overview of features
|
||||
Groups: (), ⌈⌉, ⌊⌋, []
|
||||
Pre-defined functions and constants
|
||||
User-defined functions and variables
|
||||
User-defined units (experimental and limited)
|
||||
Understands fairly ambiguous syntax. Eg. 2sinx + 2xy
|
||||
Syntax highlighting
|
||||
Completion for special symbols on tab
|
||||
Sum functions
|
||||
Sum/prod functions
|
||||
|
||||
Operators
|
||||
+, -, *, /
|
||||
|
@ -2,7 +2,7 @@ use crate::{
|
||||
ast::{ConditionalPiece, Expr, Identifier, RangedVar, Stmt},
|
||||
inverter,
|
||||
lexer::TokenKind,
|
||||
parser::{self, CalcError},
|
||||
parser::{self, KalkError},
|
||||
prelude,
|
||||
symbol_table::SymbolTable,
|
||||
};
|
||||
@ -25,7 +25,7 @@ pub(crate) struct Context<'a> {
|
||||
pub(crate) fn analyse_stmt(
|
||||
symbol_table: &mut SymbolTable,
|
||||
statement: Stmt,
|
||||
) -> Result<Stmt, CalcError> {
|
||||
) -> Result<Stmt, KalkError> {
|
||||
let mut context = Context {
|
||||
symbol_table,
|
||||
current_function_name: None,
|
||||
@ -77,7 +77,7 @@ pub(crate) fn analyse_stmt(
|
||||
})
|
||||
}
|
||||
|
||||
fn analyse_stmt_expr(context: &mut Context, value: Expr) -> Result<Stmt, CalcError> {
|
||||
fn analyse_stmt_expr(context: &mut Context, value: Expr) -> Result<Stmt, KalkError> {
|
||||
Ok(
|
||||
if let Expr::Binary(left, TokenKind::Equals, right) = value {
|
||||
match *left {
|
||||
@ -125,11 +125,11 @@ fn analyse_stmt_expr(context: &mut Context, value: Expr) -> Result<Stmt, CalcErr
|
||||
}
|
||||
Expr::Var(identifier) if !context.in_conditional => {
|
||||
if inverter::contains_var(context.symbol_table, &right, &identifier.full_name) {
|
||||
return Err(CalcError::VariableReferencesItself);
|
||||
return Err(KalkError::VariableReferencesItself);
|
||||
}
|
||||
|
||||
if prelude::is_constant(&identifier.full_name) {
|
||||
return Err(CalcError::UnableToOverrideConstant(identifier.pure_name));
|
||||
return Err(KalkError::UnableToOverrideConstant(identifier.pure_name));
|
||||
}
|
||||
|
||||
let result =
|
||||
@ -155,7 +155,7 @@ fn build_fn_decl_from_scratch(
|
||||
identifier_expr: Expr,
|
||||
parameter_expr: Expr,
|
||||
right: Expr,
|
||||
) -> Result<Stmt, CalcError> {
|
||||
) -> Result<Stmt, KalkError> {
|
||||
Ok(match identifier_expr {
|
||||
Expr::Var(identifier) if !prelude::is_prelude_func(&identifier.full_name) => {
|
||||
// Check if all the expressions in the parameter_expr are
|
||||
@ -229,7 +229,7 @@ fn build_fn_decl_from_scratch(
|
||||
})
|
||||
}
|
||||
|
||||
fn analyse_expr(context: &mut Context, expr: Expr) -> Result<Expr, CalcError> {
|
||||
fn analyse_expr(context: &mut Context, expr: Expr) -> Result<Expr, KalkError> {
|
||||
Ok(match expr {
|
||||
Expr::Binary(left, op, right) => analyse_binary(context, *left, op, *right)?,
|
||||
Expr::Unary(op, value) => Expr::Unary(op, Box::new(analyse_expr(context, *value)?)),
|
||||
@ -291,7 +291,7 @@ fn analyse_binary(
|
||||
left: Expr,
|
||||
op: TokenKind,
|
||||
right: Expr,
|
||||
) -> Result<Expr, CalcError> {
|
||||
) -> Result<Expr, KalkError> {
|
||||
let previous_in_conditional = context.in_conditional;
|
||||
if op == TokenKind::And || op == TokenKind::Or {
|
||||
context.in_conditional = true;
|
||||
@ -335,7 +335,7 @@ fn analyse_binary(
|
||||
// If the inverted expression still contains the variable,
|
||||
// the equation solving failed.
|
||||
if inverter::contains_var(context.symbol_table, &inverted, var_name) {
|
||||
return Err(CalcError::UnableToSolveEquation);
|
||||
return Err(KalkError::UnableToSolveEquation);
|
||||
}
|
||||
|
||||
context.symbol_table.insert(Stmt::VarDecl(
|
||||
@ -440,7 +440,7 @@ fn analyse_comparison_with_var(
|
||||
var: Expr,
|
||||
op: TokenKind,
|
||||
right: Expr,
|
||||
) -> Result<Expr, CalcError> {
|
||||
) -> Result<Expr, KalkError> {
|
||||
let right = analyse_expr(context, right)?;
|
||||
|
||||
if context.comprehension_vars.is_none() {
|
||||
@ -503,7 +503,7 @@ fn analyse_var(
|
||||
identifier: Identifier,
|
||||
adjacent_factor: Option<Expr>,
|
||||
adjacent_exponent: Option<Expr>,
|
||||
) -> Result<Expr, CalcError> {
|
||||
) -> Result<Expr, KalkError> {
|
||||
let adjacent_factor = if let Some(adjacent_factor) = adjacent_factor {
|
||||
Some(analyse_expr(context, adjacent_factor)?)
|
||||
} else {
|
||||
@ -582,7 +582,7 @@ fn with_adjacent(
|
||||
expr: Expr,
|
||||
factor: Option<Expr>,
|
||||
exponent: Option<Expr>,
|
||||
) -> Result<Expr, CalcError> {
|
||||
) -> Result<Expr, KalkError> {
|
||||
if let Some(factor) = factor {
|
||||
Ok(Expr::Binary(
|
||||
Box::new(expr),
|
||||
@ -600,7 +600,7 @@ fn with_adjacent(
|
||||
}
|
||||
}
|
||||
|
||||
fn build_indexed_var(context: &mut Context, identifier: Identifier) -> Result<Expr, CalcError> {
|
||||
fn build_indexed_var(context: &mut Context, identifier: Identifier) -> Result<Expr, KalkError> {
|
||||
let underscore_pos = identifier.pure_name.find('_').unwrap();
|
||||
let var_name = &identifier.pure_name[0..underscore_pos];
|
||||
let lowered = &identifier.pure_name[underscore_pos + 1..];
|
||||
@ -621,7 +621,7 @@ fn build_dx(
|
||||
context: &mut Context,
|
||||
name_without_dx: &str,
|
||||
char_after_d: char,
|
||||
) -> Result<Expr, CalcError> {
|
||||
) -> Result<Expr, KalkError> {
|
||||
if name_without_dx.is_empty() {
|
||||
Ok(Expr::Var(Identifier::from_full_name(&format!(
|
||||
"d{}",
|
||||
@ -649,7 +649,7 @@ fn build_split_up_vars(
|
||||
identifier: Identifier,
|
||||
adjacent_factor: Option<Expr>,
|
||||
adjacent_exponent: Option<Expr>,
|
||||
) -> Result<Expr, CalcError> {
|
||||
) -> Result<Expr, KalkError> {
|
||||
let mut chars: Vec<char> = identifier.pure_name.chars().collect();
|
||||
let last_char = chars.pop().unwrap_or_default();
|
||||
let identifier_without_last: String = chars.iter().collect();
|
||||
@ -737,7 +737,7 @@ fn analyse_fn(
|
||||
context: &mut Context,
|
||||
identifier: Identifier,
|
||||
arguments: Vec<Expr>,
|
||||
) -> Result<Expr, CalcError> {
|
||||
) -> Result<Expr, KalkError> {
|
||||
let is_integral = identifier.pure_name == "integrate";
|
||||
let prev_in_integral = context.in_integral;
|
||||
if is_integral {
|
||||
|
@ -7,13 +7,13 @@ use crate::float;
|
||||
use crate::interpreter;
|
||||
use crate::kalk_value::KalkValue;
|
||||
use crate::lexer::TokenKind;
|
||||
use crate::parser::CalcError;
|
||||
use crate::parser::KalkError;
|
||||
|
||||
pub fn derive_func(
|
||||
context: &mut interpreter::Context,
|
||||
name: &Identifier,
|
||||
argument: KalkValue,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
const H: f64 = 0.000001;
|
||||
|
||||
let unit = argument.get_unit().cloned();
|
||||
@ -45,7 +45,7 @@ pub fn integrate_with_unknown_variable(
|
||||
a: &Expr,
|
||||
b: &Expr,
|
||||
expr: &Expr,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
let mut integration_variable: Option<&str> = None;
|
||||
|
||||
// integral(a, b, expr dx)
|
||||
@ -59,7 +59,7 @@ pub fn integrate_with_unknown_variable(
|
||||
}
|
||||
|
||||
if integration_variable.is_none() {
|
||||
return Err(CalcError::ExpectedDx);
|
||||
return Err(KalkError::ExpectedDx);
|
||||
}
|
||||
|
||||
// "dx" is still in the expression. Set dx = 1, so that it doesn't affect the expression value.
|
||||
@ -77,7 +77,7 @@ pub fn integrate(
|
||||
b: &Expr,
|
||||
expr: &Expr,
|
||||
integration_variable: &str,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
Ok(simpsons_rule(context, a, b, expr, integration_variable)?.round_if_needed())
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ fn simpsons_rule(
|
||||
b_expr: &Expr,
|
||||
expr: &Expr,
|
||||
integration_variable: &str,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
let mut result_real = float!(0);
|
||||
let mut result_imaginary = float!(0);
|
||||
let original_variable_value = context
|
||||
|
@ -3,7 +3,7 @@ use crate::ast::{Identifier, RangedVar};
|
||||
use crate::calculation_result::CalculationResult;
|
||||
use crate::kalk_value::KalkValue;
|
||||
use crate::lexer::TokenKind;
|
||||
use crate::parser::CalcError;
|
||||
use crate::parser::KalkError;
|
||||
use crate::parser::DECL_UNIT;
|
||||
use crate::symbol_table::SymbolTable;
|
||||
use crate::{as_number_or_zero, calculus};
|
||||
@ -44,7 +44,7 @@ impl<'a> Context<'a> {
|
||||
pub fn interpret(
|
||||
&mut self,
|
||||
statements: Vec<Stmt>,
|
||||
) -> Result<Option<CalculationResult>, CalcError> {
|
||||
) -> Result<Option<CalculationResult>, KalkError> {
|
||||
for (i, stmt) in statements.iter().enumerate() {
|
||||
let num = eval_stmt(self, stmt)?;
|
||||
|
||||
@ -80,7 +80,7 @@ struct SumVar {
|
||||
value: i128,
|
||||
}
|
||||
|
||||
fn eval_stmt(context: &mut Context, stmt: &Stmt) -> Result<KalkValue, CalcError> {
|
||||
fn eval_stmt(context: &mut Context, stmt: &Stmt) -> Result<KalkValue, KalkError> {
|
||||
match stmt {
|
||||
Stmt::VarDecl(_, _) => eval_var_decl_stmt(context, stmt),
|
||||
Stmt::FnDecl(_, _, _) => eval_fn_decl_stmt(),
|
||||
@ -89,20 +89,20 @@ fn eval_stmt(context: &mut Context, stmt: &Stmt) -> Result<KalkValue, CalcError>
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_var_decl_stmt(context: &mut Context, stmt: &Stmt) -> Result<KalkValue, CalcError> {
|
||||
fn eval_var_decl_stmt(context: &mut Context, stmt: &Stmt) -> Result<KalkValue, KalkError> {
|
||||
context.symbol_table.insert(stmt.clone());
|
||||
Ok(KalkValue::from(1))
|
||||
}
|
||||
|
||||
fn eval_fn_decl_stmt() -> Result<KalkValue, CalcError> {
|
||||
fn eval_fn_decl_stmt() -> Result<KalkValue, KalkError> {
|
||||
Ok(KalkValue::from(1)) // Nothing needs to happen here, since the parser will already have added the FnDecl's to the symbol table.
|
||||
}
|
||||
|
||||
fn eval_unit_decl_stmt() -> Result<KalkValue, CalcError> {
|
||||
fn eval_unit_decl_stmt() -> Result<KalkValue, KalkError> {
|
||||
Ok(KalkValue::from(1))
|
||||
}
|
||||
|
||||
fn eval_expr_stmt(context: &mut Context, expr: &Expr) -> Result<KalkValue, CalcError> {
|
||||
fn eval_expr_stmt(context: &mut Context, expr: &Expr) -> Result<KalkValue, KalkError> {
|
||||
eval_expr(context, expr, None)
|
||||
}
|
||||
|
||||
@ -110,11 +110,11 @@ pub(crate) fn eval_expr(
|
||||
context: &mut Context,
|
||||
expr: &Expr,
|
||||
unit: Option<&String>,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
if let (Ok(elapsed), Some(timeout)) = (context.start_time.elapsed(), context.timeout) {
|
||||
if elapsed.as_millis() >= timeout {
|
||||
return Err(CalcError::TimedOut);
|
||||
return Err(KalkError::TimedOut);
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ fn eval_binary_expr(
|
||||
op: &TokenKind,
|
||||
right_expr: &Expr,
|
||||
unit: Option<&String>,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
if let TokenKind::ToKeyword = op {
|
||||
// TODO: When the unit conversion function takes a Float instead of Expr,
|
||||
// move this to the match statement further down.
|
||||
@ -201,14 +201,14 @@ fn eval_unary_expr(
|
||||
op: &TokenKind,
|
||||
expr: &Expr,
|
||||
unit: Option<&String>,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
let num = eval_expr(context, expr, unit)?;
|
||||
|
||||
match op {
|
||||
TokenKind::Minus => Ok(num.mul(context, KalkValue::from(-1f64))),
|
||||
TokenKind::Percent => Ok(num.mul(context, KalkValue::from(0.01f64))),
|
||||
TokenKind::Exclamation => Ok(prelude::special_funcs::factorial(num)),
|
||||
_ => Err(CalcError::InvalidOperator),
|
||||
_ => Err(KalkError::InvalidOperator),
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,7 +216,7 @@ fn eval_unit_expr(
|
||||
context: &mut Context,
|
||||
identifier: &str,
|
||||
expr: &Expr,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
let angle_unit = &context.angle_unit.clone();
|
||||
if (identifier == "rad" || identifier == "deg") && angle_unit != identifier {
|
||||
return convert_unit(
|
||||
@ -235,11 +235,11 @@ pub fn convert_unit(
|
||||
expr: &Expr,
|
||||
from_unit: Option<&String>,
|
||||
to_unit: Option<&String>,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
let (from_unit, to_unit) = if let (Some(from_unit), Some(to_unit)) = (from_unit, to_unit) {
|
||||
(from_unit, to_unit)
|
||||
} else {
|
||||
return Err(CalcError::InvalidUnit);
|
||||
return Err(KalkError::InvalidUnit);
|
||||
};
|
||||
|
||||
if let Some(Stmt::UnitDecl(_, _, unit_def)) =
|
||||
@ -253,7 +253,7 @@ pub fn convert_unit(
|
||||
let (real, imaginary, _) = as_number_or_zero!(eval_expr(context, &unit_def, None)?);
|
||||
Ok(KalkValue::Number(real, imaginary, Some(to_unit.clone())))
|
||||
} else {
|
||||
Err(CalcError::InvalidUnit)
|
||||
Err(KalkError::InvalidUnit)
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,7 +261,7 @@ fn eval_var_expr(
|
||||
context: &mut Context,
|
||||
identifier: &Identifier,
|
||||
unit: Option<&String>,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
// If there is a constant with this name, return a literal expression with its value
|
||||
if let Some(value) = prelude::CONSTANTS.get(identifier.full_name.as_ref() as &str) {
|
||||
return eval_expr(context, &Expr::Literal(*value), unit);
|
||||
@ -284,7 +284,7 @@ fn eval_var_expr(
|
||||
if let Some(Stmt::VarDecl(_, expr)) = var_decl {
|
||||
eval_expr(context, &expr, unit)
|
||||
} else {
|
||||
Err(CalcError::UndefinedVar(identifier.full_name.clone()))
|
||||
Err(KalkError::UndefinedVar(identifier.full_name.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,7 +294,7 @@ fn eval_literal_expr(
|
||||
context: &mut Context,
|
||||
value: f64,
|
||||
unit: Option<&String>,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
let mut float = float!(value);
|
||||
float.set_prec(context.precision);
|
||||
|
||||
@ -307,7 +307,7 @@ fn eval_literal_expr(
|
||||
context: &mut Context,
|
||||
value: f64,
|
||||
unit: Option<&String>,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
Ok(KalkValue::Number(float!(value), float!(0), unit.cloned()))
|
||||
}
|
||||
|
||||
@ -315,7 +315,7 @@ fn eval_group_expr(
|
||||
context: &mut Context,
|
||||
expr: &Expr,
|
||||
unit: Option<&String>,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
eval_expr(context, expr, unit)
|
||||
}
|
||||
|
||||
@ -324,7 +324,7 @@ pub(crate) fn eval_fn_call_expr(
|
||||
identifier: &Identifier,
|
||||
expressions: &[Expr],
|
||||
unit: Option<&String>,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
// Special functions
|
||||
match identifier.full_name.as_ref() {
|
||||
"sum" | "prod" => {
|
||||
@ -333,7 +333,7 @@ pub(crate) fn eval_fn_call_expr(
|
||||
if let Expr::Var(var_identifier) = &**left {
|
||||
// Make sure exactly 3 arguments were supplied.
|
||||
if expressions.len() != 3 {
|
||||
return Err(CalcError::IncorrectAmountOfArguments(
|
||||
return Err(KalkError::IncorrectAmountOfArguments(
|
||||
3,
|
||||
"sum/prod".into(),
|
||||
expressions.len(),
|
||||
@ -369,10 +369,10 @@ pub(crate) fn eval_fn_call_expr(
|
||||
if let Expr::Var(integration_variable) = &expressions[3] {
|
||||
&integration_variable.full_name[1..]
|
||||
} else {
|
||||
return Err(CalcError::ExpectedDx);
|
||||
return Err(KalkError::ExpectedDx);
|
||||
},
|
||||
),
|
||||
_ => Err(CalcError::IncorrectAmountOfArguments(
|
||||
_ => Err(KalkError::IncorrectAmountOfArguments(
|
||||
3,
|
||||
"integrate".into(),
|
||||
expressions.len(),
|
||||
@ -496,7 +496,7 @@ pub(crate) fn eval_fn_call_expr(
|
||||
match stmt_definition {
|
||||
Some(Stmt::FnDecl(_, arguments, fn_body)) => {
|
||||
if arguments.len() != expressions.len() {
|
||||
return Err(CalcError::IncorrectAmountOfArguments(
|
||||
return Err(KalkError::IncorrectAmountOfArguments(
|
||||
arguments.len(),
|
||||
identifier.full_name.clone(),
|
||||
expressions.len(),
|
||||
@ -549,7 +549,7 @@ pub(crate) fn eval_fn_call_expr(
|
||||
|
||||
fn_value
|
||||
}
|
||||
_ => Err(CalcError::UndefinedFn(identifier.full_name.clone())),
|
||||
_ => Err(KalkError::UndefinedFn(identifier.full_name.clone())),
|
||||
}
|
||||
}
|
||||
|
||||
@ -561,7 +561,7 @@ fn eval_loop(
|
||||
end_expr: &Expr,
|
||||
expression: &Expr,
|
||||
unit: Option<String>,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
if context.sum_variables.is_none() {
|
||||
context.sum_variables = Some(Vec::new());
|
||||
}
|
||||
@ -611,7 +611,7 @@ fn eval_piecewise(
|
||||
context: &mut Context,
|
||||
pieces: &[crate::ast::ConditionalPiece],
|
||||
unit: Option<&String>,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
for piece in pieces {
|
||||
if let KalkValue::Boolean(condition_is_true) = eval_expr(context, &piece.condition, unit)? {
|
||||
if condition_is_true {
|
||||
@ -620,10 +620,10 @@ fn eval_piecewise(
|
||||
}
|
||||
}
|
||||
|
||||
Err(CalcError::PiecewiseConditionsAreFalse)
|
||||
Err(KalkError::PiecewiseConditionsAreFalse)
|
||||
}
|
||||
|
||||
fn eval_vector(context: &mut Context, values: &[Expr]) -> Result<KalkValue, CalcError> {
|
||||
fn eval_vector(context: &mut Context, values: &[Expr]) -> Result<KalkValue, KalkError> {
|
||||
let mut eval_values = Vec::new();
|
||||
for value in values {
|
||||
eval_values.push(eval_expr(context, value, None)?);
|
||||
@ -632,7 +632,7 @@ fn eval_vector(context: &mut Context, values: &[Expr]) -> Result<KalkValue, Calc
|
||||
Ok(KalkValue::Vector(eval_values))
|
||||
}
|
||||
|
||||
fn eval_matrix(context: &mut Context, rows: &[Vec<Expr>]) -> Result<KalkValue, CalcError> {
|
||||
fn eval_matrix(context: &mut Context, rows: &[Vec<Expr>]) -> Result<KalkValue, KalkError> {
|
||||
let mut eval_rows = Vec::new();
|
||||
for row in rows {
|
||||
let mut eval_row = Vec::new();
|
||||
@ -651,12 +651,12 @@ fn eval_indexer(
|
||||
var: &Expr,
|
||||
index_expressions: &[Expr],
|
||||
unit: Option<&String>,
|
||||
) -> Result<KalkValue, CalcError> {
|
||||
) -> Result<KalkValue, KalkError> {
|
||||
let var_value = eval_expr(context, var, unit)?;
|
||||
match var_value {
|
||||
KalkValue::Vector(values) => {
|
||||
if index_expressions.len() != 1 {
|
||||
return Err(CalcError::IncorrectAmountOfIndexes(
|
||||
return Err(KalkError::IncorrectAmountOfIndexes(
|
||||
index_expressions.len(),
|
||||
1,
|
||||
));
|
||||
@ -666,7 +666,7 @@ fn eval_indexer(
|
||||
if let Some(value) = values.get(index - 1) {
|
||||
Ok(value.clone())
|
||||
} else {
|
||||
Err(CalcError::ItemOfIndexDoesNotExist(vec![index]))
|
||||
Err(KalkError::ItemOfIndexDoesNotExist(vec![index]))
|
||||
}
|
||||
}
|
||||
KalkValue::Matrix(rows) => {
|
||||
@ -676,18 +676,18 @@ fn eval_indexer(
|
||||
return if let Some(row) = rows.get(row_index - 1) {
|
||||
Ok(KalkValue::Vector(row.clone()))
|
||||
} else {
|
||||
Err(CalcError::ItemOfIndexDoesNotExist(vec![row_index]))
|
||||
Err(KalkError::ItemOfIndexDoesNotExist(vec![row_index]))
|
||||
};
|
||||
}
|
||||
|
||||
if indices.len() != 2 {
|
||||
return Err(CalcError::IncorrectAmountOfIndexes(indices.len(), 2));
|
||||
return Err(KalkError::IncorrectAmountOfIndexes(indices.len(), 2));
|
||||
}
|
||||
|
||||
let row_index = indices[0];
|
||||
let column_index = indices[1];
|
||||
if row_index == 0 || column_index == 0 {
|
||||
return Err(CalcError::ItemOfIndexDoesNotExist(vec![
|
||||
return Err(KalkError::ItemOfIndexDoesNotExist(vec![
|
||||
row_index,
|
||||
column_index,
|
||||
]));
|
||||
@ -699,26 +699,26 @@ fn eval_indexer(
|
||||
}
|
||||
}
|
||||
|
||||
Err(CalcError::ItemOfIndexDoesNotExist(vec![
|
||||
Err(KalkError::ItemOfIndexDoesNotExist(vec![
|
||||
row_index,
|
||||
column_index,
|
||||
]))
|
||||
}
|
||||
_ => Err(CalcError::CanOnlyIndexX),
|
||||
_ => Err(KalkError::CanOnlyIndexX),
|
||||
}
|
||||
}
|
||||
|
||||
fn as_indices(context: &mut Context, expressions: &[Expr]) -> Result<Vec<usize>, CalcError> {
|
||||
fn as_indices(context: &mut Context, expressions: &[Expr]) -> Result<Vec<usize>, KalkError> {
|
||||
let mut indices = Vec::new();
|
||||
for expr in expressions {
|
||||
let value = eval_expr(context, expr, None)?;
|
||||
if value.has_imaginary() {
|
||||
return Err(CalcError::CannotIndexByImaginary);
|
||||
return Err(KalkError::CannotIndexByImaginary);
|
||||
}
|
||||
|
||||
let index = value.to_f64() as usize;
|
||||
if index == 0 {
|
||||
return Err(CalcError::ItemOfIndexDoesNotExist(vec![index]));
|
||||
return Err(KalkError::ItemOfIndexDoesNotExist(vec![index]));
|
||||
}
|
||||
|
||||
indices.push(index);
|
||||
@ -732,9 +732,9 @@ fn eval_comprehension(
|
||||
left: &Expr,
|
||||
conditions: &[Expr],
|
||||
vars: &[RangedVar],
|
||||
) -> Result<Vec<KalkValue>, CalcError> {
|
||||
) -> Result<Vec<KalkValue>, KalkError> {
|
||||
if vars.len() != conditions.len() {
|
||||
return Err(CalcError::InvalidComprehension(String::from("Expected a new variable to be introduced for every condition (conditions are comma separated).")));
|
||||
return Err(KalkError::InvalidComprehension(String::from("Expected a new variable to be introduced for every condition (conditions are comma separated).")));
|
||||
}
|
||||
|
||||
let condition = conditions.first().unwrap();
|
||||
@ -806,7 +806,7 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
fn interpret_with_unit(stmt: Stmt) -> Result<Option<CalculationResult>, CalcError> {
|
||||
fn interpret_with_unit(stmt: Stmt) -> Result<Option<CalculationResult>, KalkError> {
|
||||
let mut symbol_table = SymbolTable::new();
|
||||
symbol_table
|
||||
.insert(DEG_RAD_UNIT.clone())
|
||||
@ -815,7 +815,7 @@ mod tests {
|
||||
context(&mut symbol_table, "rad").interpret(vec![stmt])
|
||||
}
|
||||
|
||||
fn interpret(stmt: Stmt) -> Result<Option<KalkValue>, CalcError> {
|
||||
fn interpret(stmt: Stmt) -> Result<Option<KalkValue>, KalkError> {
|
||||
if let Some(result) = interpret_with_unit(stmt)? {
|
||||
Ok(Some(result.get_value()))
|
||||
} else {
|
||||
@ -976,7 +976,7 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
interpret(stmt),
|
||||
Err(CalcError::UndefinedVar(String::from("x")))
|
||||
Err(KalkError::UndefinedVar(String::from("x")))
|
||||
);
|
||||
}
|
||||
|
||||
@ -1016,7 +1016,7 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
interpret(stmt),
|
||||
Err(CalcError::UndefinedFn(String::from("f")))
|
||||
Err(KalkError::UndefinedFn(String::from("f")))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::ast::Identifier;
|
||||
use crate::ast::{Expr, Stmt};
|
||||
use crate::lexer::TokenKind;
|
||||
use crate::parser::CalcError;
|
||||
use crate::parser::KalkError;
|
||||
use crate::prelude;
|
||||
use crate::symbol_table::SymbolTable;
|
||||
use lazy_static::lazy_static;
|
||||
@ -44,7 +44,7 @@ impl Expr {
|
||||
&self,
|
||||
symbol_table: &mut SymbolTable,
|
||||
unknown_var: &str,
|
||||
) -> Result<Self, CalcError> {
|
||||
) -> Result<Self, KalkError> {
|
||||
let target_expr = Expr::Var(Identifier::from_full_name(unknown_var));
|
||||
let result = invert(target_expr, symbol_table, self, unknown_var);
|
||||
|
||||
@ -56,7 +56,7 @@ impl Expr {
|
||||
symbol_table: &mut SymbolTable,
|
||||
target_expr: Expr,
|
||||
unknown_var: &str,
|
||||
) -> Result<Self, CalcError> {
|
||||
) -> Result<Self, KalkError> {
|
||||
let x = invert(target_expr, symbol_table, self, unknown_var)?;
|
||||
Ok(x.0)
|
||||
}
|
||||
@ -67,7 +67,7 @@ fn invert(
|
||||
symbol_table: &mut SymbolTable,
|
||||
expr: &Expr,
|
||||
unknown_var: &str,
|
||||
) -> Result<(Expr, Expr), CalcError> {
|
||||
) -> Result<(Expr, Expr), KalkError> {
|
||||
match expr {
|
||||
Expr::Binary(left, op, right) => {
|
||||
invert_binary(target_expr, symbol_table, left, op, right, unknown_var)
|
||||
@ -86,12 +86,12 @@ fn invert(
|
||||
unknown_var,
|
||||
),
|
||||
Expr::Literal(_) => Ok((target_expr, expr.clone())),
|
||||
Expr::Piecewise(_) => Err(CalcError::UnableToInvert(String::from("Piecewise"))),
|
||||
Expr::Vector(_) => Err(CalcError::UnableToInvert(String::from("Vector"))),
|
||||
Expr::Matrix(_) => Err(CalcError::UnableToInvert(String::from("Matrix"))),
|
||||
Expr::Indexer(_, _) => Err(CalcError::UnableToInvert(String::from("Inverter"))),
|
||||
Expr::Piecewise(_) => Err(KalkError::UnableToInvert(String::from("Piecewise"))),
|
||||
Expr::Vector(_) => Err(KalkError::UnableToInvert(String::from("Vector"))),
|
||||
Expr::Matrix(_) => Err(KalkError::UnableToInvert(String::from("Matrix"))),
|
||||
Expr::Indexer(_, _) => Err(KalkError::UnableToInvert(String::from("Inverter"))),
|
||||
Expr::Comprehension(_, _, _) => {
|
||||
Err(CalcError::UnableToInvert(String::from("Comprehension")))
|
||||
Err(KalkError::UnableToInvert(String::from("Comprehension")))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -103,7 +103,7 @@ fn invert_binary(
|
||||
op: &TokenKind,
|
||||
right: &Expr,
|
||||
unknown_var: &str,
|
||||
) -> Result<(Expr, Expr), CalcError> {
|
||||
) -> Result<(Expr, Expr), KalkError> {
|
||||
let op_inv = match op {
|
||||
TokenKind::Plus => TokenKind::Minus,
|
||||
TokenKind::Minus => {
|
||||
@ -194,7 +194,7 @@ fn invert_binary(
|
||||
)
|
||||
};
|
||||
}
|
||||
_ => return Err(CalcError::UnableToInvert(String::new())),
|
||||
_ => return Err(KalkError::UnableToInvert(String::new())),
|
||||
};
|
||||
|
||||
// If the left expression contains the unit, invert the right one instead,
|
||||
@ -203,7 +203,7 @@ fn invert_binary(
|
||||
// But if the right expression *also* contains the unit,
|
||||
// throw an error, since it can't handle this yet.
|
||||
if contains_var(symbol_table, right, unknown_var) {
|
||||
return Err(CalcError::UnableToInvert(String::from(
|
||||
return Err(KalkError::UnableToInvert(String::from(
|
||||
"Expressions with several instances of an unknown variable (this might be supported in the future). Try simplifying the expression.",
|
||||
)));
|
||||
}
|
||||
@ -233,14 +233,14 @@ fn invert_binary(
|
||||
)
|
||||
}
|
||||
|
||||
fn invert_unary(target_expr: Expr, op: &TokenKind, expr: &Expr) -> Result<(Expr, Expr), CalcError> {
|
||||
fn invert_unary(target_expr: Expr, op: &TokenKind, expr: &Expr) -> Result<(Expr, Expr), KalkError> {
|
||||
match op {
|
||||
TokenKind::Minus => Ok((
|
||||
// Make the target expression negative
|
||||
Expr::Unary(TokenKind::Minus, Box::new(target_expr)),
|
||||
expr.clone(), // And then continue inverting the inner-expression.
|
||||
)),
|
||||
_ => Err(CalcError::UnableToInvert(String::new())),
|
||||
_ => Err(KalkError::UnableToInvert(String::new())),
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,7 +250,7 @@ fn invert_unit(
|
||||
identifier: &str,
|
||||
expr: &Expr,
|
||||
unknown_var: &str,
|
||||
) -> Result<(Expr, Expr), CalcError> {
|
||||
) -> Result<(Expr, Expr), KalkError> {
|
||||
let x = Expr::Binary(
|
||||
Box::new(target_expr),
|
||||
TokenKind::ToKeyword,
|
||||
@ -264,7 +264,7 @@ fn invert_var(
|
||||
symbol_table: &mut SymbolTable,
|
||||
identifier: &Identifier,
|
||||
unknown_var: &str,
|
||||
) -> Result<(Expr, Expr), CalcError> {
|
||||
) -> Result<(Expr, Expr), KalkError> {
|
||||
if identifier.full_name == unknown_var {
|
||||
Ok((target_expr, Expr::Var(identifier.clone())))
|
||||
} else if let Some(Stmt::VarDecl(_, var_expr)) =
|
||||
@ -282,7 +282,7 @@ fn invert_fn_call(
|
||||
identifier: &Identifier,
|
||||
arguments: &[Expr],
|
||||
unknown_var: &str,
|
||||
) -> Result<(Expr, Expr), CalcError> {
|
||||
) -> Result<(Expr, Expr), KalkError> {
|
||||
// If prelude function
|
||||
match arguments.len() {
|
||||
1 => {
|
||||
@ -310,7 +310,7 @@ fn invert_fn_call(
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
return Err(CalcError::UnableToInvert(format!(
|
||||
return Err(KalkError::UnableToInvert(format!(
|
||||
"Function '{}'",
|
||||
identifier.full_name
|
||||
)));
|
||||
@ -321,7 +321,7 @@ fn invert_fn_call(
|
||||
}
|
||||
2 => {
|
||||
if prelude::BINARY_FUNCS.contains_key(identifier.full_name.as_ref() as &str) {
|
||||
return Err(CalcError::UnableToInvert(format!(
|
||||
return Err(KalkError::UnableToInvert(format!(
|
||||
"Function '{}'",
|
||||
identifier.full_name
|
||||
)));
|
||||
@ -336,12 +336,12 @@ fn invert_fn_call(
|
||||
{
|
||||
(parameters, body)
|
||||
} else {
|
||||
return Err(CalcError::UndefinedFn(identifier.full_name.clone()));
|
||||
return Err(KalkError::UndefinedFn(identifier.full_name.clone()));
|
||||
};
|
||||
|
||||
// Make sure the input is valid.
|
||||
if parameters.len() != arguments.len() {
|
||||
return Err(CalcError::IncorrectAmountOfArguments(
|
||||
return Err(KalkError::IncorrectAmountOfArguments(
|
||||
parameters.len(),
|
||||
identifier.full_name.clone(),
|
||||
arguments.len(),
|
||||
@ -404,7 +404,7 @@ pub fn contains_var(symbol_table: &SymbolTable, expr: &Expr, var_name: &str) ->
|
||||
}
|
||||
|
||||
/// Multiply an expression into a group.
|
||||
fn multiply_into(expr: &Expr, base_expr: &Expr) -> Result<Expr, CalcError> {
|
||||
fn multiply_into(expr: &Expr, base_expr: &Expr) -> Result<Expr, KalkError> {
|
||||
match base_expr {
|
||||
Expr::Binary(left, op, right) => match op {
|
||||
// If + or -, multiply the expression with each term.
|
||||
@ -419,7 +419,7 @@ fn multiply_into(expr: &Expr, base_expr: &Expr) -> Result<Expr, CalcError> {
|
||||
*op,
|
||||
right.clone(),
|
||||
)),
|
||||
_ => Err(CalcError::UnableToInvert(String::new())),
|
||||
_ => Err(KalkError::UnableToInvert(String::new())),
|
||||
},
|
||||
// If it's a literal, just multiply them together.
|
||||
Expr::Literal(_) | Expr::Var(_) => Ok(Expr::Binary(
|
||||
@ -427,10 +427,10 @@ fn multiply_into(expr: &Expr, base_expr: &Expr) -> Result<Expr, CalcError> {
|
||||
TokenKind::Star,
|
||||
Box::new(base_expr.clone()),
|
||||
)),
|
||||
Expr::Group(_) => Err(CalcError::UnableToInvert(String::from(
|
||||
Expr::Group(_) => Err(KalkError::UnableToInvert(String::from(
|
||||
"Parenthesis multiplied with parenthesis (this should be possible in the future).",
|
||||
))),
|
||||
_ => Err(CalcError::UnableToInvert(String::new())),
|
||||
_ => Err(KalkError::UnableToInvert(String::new())),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ impl Default for Context {
|
||||
|
||||
/// Error that occured during parsing or evaluation.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum CalcError {
|
||||
pub enum KalkError {
|
||||
CannotIndexByImaginary,
|
||||
CanOnlyIndexX,
|
||||
Expected(String),
|
||||
@ -116,42 +116,42 @@ pub enum CalcError {
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl ToString for CalcError {
|
||||
impl ToString for KalkError {
|
||||
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."),
|
||||
CalcError::ExpectedIf => String::from("Expected 'if', with a condition after it."),
|
||||
CalcError::IncorrectAmountOfArguments(expected, func, got) => format!(
|
||||
KalkError::CannotIndexByImaginary => String::from("Cannot index by imaginary numbers."),
|
||||
KalkError::CanOnlyIndexX => String::from("Indexing (getting an item with a specific index) is only possible on vectors and matrices."),
|
||||
KalkError::Expected(description) => format!("Expected: {}", description),
|
||||
KalkError::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."),
|
||||
KalkError::ExpectedIf => String::from("Expected 'if', with a condition after it."),
|
||||
KalkError::IncorrectAmountOfArguments(expected, func, got) => format!(
|
||||
"Expected {} arguments for function {}, but got {}.",
|
||||
expected, func, got
|
||||
),
|
||||
CalcError::IncorrectAmountOfIndexes(expected, got) => format!(
|
||||
KalkError::IncorrectAmountOfIndexes(expected, got) => format!(
|
||||
"Expected {} indexes but got {}.",
|
||||
expected, got
|
||||
),
|
||||
CalcError::ItemOfIndexDoesNotExist(indexes) => format!("Item of index ⟦{}⟧ does not exist.", indexes.iter().map(|x| x.to_string()).collect::<Vec<String>>().join(", ")),
|
||||
CalcError::InconsistentColumnWidths => String::from("Inconsistent column widths. Matrix columns must be the same size."),
|
||||
CalcError::InvalidComprehension(x) => format!("Invalid comprehension: {}", x),
|
||||
CalcError::InvalidNumberLiteral(x) => format!("Invalid number literal: '{}'.", x),
|
||||
CalcError::InvalidOperator => String::from("Invalid operator."),
|
||||
CalcError::InvalidUnit => String::from("Invalid unit."),
|
||||
CalcError::TimedOut => String::from("Operation took too long."),
|
||||
CalcError::VariableReferencesItself => String::from("Variable references itself."),
|
||||
CalcError::PiecewiseConditionsAreFalse => String::from("All the conditions in the piecewise are false."),
|
||||
CalcError::UnexpectedToken(got, expected) => {
|
||||
KalkError::ItemOfIndexDoesNotExist(indexes) => format!("Item of index ⟦{}⟧ does not exist.", indexes.iter().map(|x| x.to_string()).collect::<Vec<String>>().join(", ")),
|
||||
KalkError::InconsistentColumnWidths => String::from("Inconsistent column widths. Matrix columns must be the same size."),
|
||||
KalkError::InvalidComprehension(x) => format!("Invalid comprehension: {}", x),
|
||||
KalkError::InvalidNumberLiteral(x) => format!("Invalid number literal: '{}'.", x),
|
||||
KalkError::InvalidOperator => String::from("Invalid operator."),
|
||||
KalkError::InvalidUnit => String::from("Invalid unit."),
|
||||
KalkError::TimedOut => String::from("Operation took too long."),
|
||||
KalkError::VariableReferencesItself => String::from("Variable references itself."),
|
||||
KalkError::PiecewiseConditionsAreFalse => String::from("All the conditions in the piecewise are false."),
|
||||
KalkError::UnexpectedToken(got, expected) => {
|
||||
format!("Unexpected token: '{:?}', expected '{:?}'.", got, expected)
|
||||
}
|
||||
CalcError::UnableToInvert(msg) => format!("Unable to invert: {}", msg),
|
||||
CalcError::UndefinedFn(name) => format!("Undefined function: '{}'.", name),
|
||||
CalcError::UndefinedVar(name) => format!("Undefined variable: '{}'.", name),
|
||||
CalcError::UnableToParseExpression => String::from("Unable to parse expression."),
|
||||
CalcError::UnableToSolveEquation => String::from("Unable to solve equation."),
|
||||
CalcError::UnableToOverrideConstant(name) => format!("Unable to override constant: '{}'.", name),
|
||||
CalcError::UnrecognizedBase => String::from("Unrecognized base."),
|
||||
CalcError::Unknown => String::from("Unknown error."),
|
||||
KalkError::UnableToInvert(msg) => format!("Unable to invert: {}", msg),
|
||||
KalkError::UndefinedFn(name) => format!("Undefined function: '{}'.", name),
|
||||
KalkError::UndefinedVar(name) => format!("Undefined variable: '{}'.", name),
|
||||
KalkError::UnableToParseExpression => String::from("Unable to parse expression."),
|
||||
KalkError::UnableToSolveEquation => String::from("Unable to solve equation."),
|
||||
KalkError::UnableToOverrideConstant(name) => format!("Unable to override constant: '{}'.", name),
|
||||
KalkError::UnrecognizedBase => String::from("Unrecognized base."),
|
||||
KalkError::Unknown => String::from("Unknown error."),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -163,7 +163,7 @@ pub fn eval(
|
||||
context: &mut Context,
|
||||
input: &str,
|
||||
#[cfg(feature = "rug")] precision: u32,
|
||||
) -> Result<Option<CalculationResult>, CalcError> {
|
||||
) -> Result<Option<CalculationResult>, KalkError> {
|
||||
let statements = parse(context, input)?;
|
||||
|
||||
let symbol_table = context.symbol_table.get_mut();
|
||||
@ -186,7 +186,7 @@ pub fn eval(
|
||||
/// Parse expressions/declarations and return a syntax tree.
|
||||
///
|
||||
/// `None` will be returned if the last statement is a declaration.
|
||||
pub fn parse(context: &mut Context, input: &str) -> Result<Vec<Stmt>, CalcError> {
|
||||
pub fn parse(context: &mut Context, input: &str) -> Result<Vec<Stmt>, KalkError> {
|
||||
let mut lexer = Lexer::new(input);
|
||||
context.tokens = lexer.lex();
|
||||
context.pos = 0;
|
||||
@ -211,7 +211,7 @@ pub fn parse(context: &mut Context, input: &str) -> Result<Vec<Stmt>, CalcError>
|
||||
Ok(statements)
|
||||
}
|
||||
|
||||
fn parse_stmt(context: &mut Context) -> Result<Stmt, CalcError> {
|
||||
fn parse_stmt(context: &mut Context) -> Result<Stmt, KalkError> {
|
||||
if match_token(context, TokenKind::UnitKeyword) {
|
||||
parse_unit_decl_stmt(context)
|
||||
} else {
|
||||
@ -219,7 +219,7 @@ fn parse_stmt(context: &mut Context) -> Result<Stmt, CalcError> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_piecewise(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_piecewise(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
advance(context);
|
||||
skip_newlines(context);
|
||||
|
||||
@ -250,7 +250,7 @@ fn parse_piecewise(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
|
||||
reached_otherwise = true;
|
||||
} else {
|
||||
return Err(CalcError::ExpectedIf);
|
||||
return Err(KalkError::ExpectedIf);
|
||||
}
|
||||
|
||||
if match_token(context, TokenKind::Semicolon) {
|
||||
@ -269,7 +269,7 @@ fn parse_piecewise(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
Ok(Expr::Piecewise(pieces))
|
||||
}
|
||||
|
||||
fn parse_unit_decl_stmt(context: &mut Context) -> Result<Stmt, CalcError> {
|
||||
fn parse_unit_decl_stmt(context: &mut Context) -> Result<Stmt, KalkError> {
|
||||
advance(context); // Unit keyword
|
||||
let identifier = advance(context).clone();
|
||||
consume(context, TokenKind::Equals)?;
|
||||
@ -283,7 +283,7 @@ fn parse_unit_decl_stmt(context: &mut Context) -> Result<Stmt, CalcError> {
|
||||
let base_unit = if let Some(base_unit) = &context.unit_decl_base_unit {
|
||||
base_unit.clone()
|
||||
} else {
|
||||
return Err(CalcError::InvalidUnit);
|
||||
return Err(KalkError::InvalidUnit);
|
||||
};
|
||||
|
||||
// Automatically create a second unit decl with the expression inverted.
|
||||
@ -302,11 +302,11 @@ fn parse_unit_decl_stmt(context: &mut Context) -> Result<Stmt, CalcError> {
|
||||
Ok(stmt)
|
||||
}
|
||||
|
||||
fn parse_expr(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_expr(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
parse_or(context)
|
||||
}
|
||||
|
||||
fn parse_comprehension(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_comprehension(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let left = parse_or(context)?;
|
||||
|
||||
if match_token(context, TokenKind::Colon) {
|
||||
@ -319,7 +319,7 @@ fn parse_comprehension(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_comprehension_comma(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_comprehension_comma(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let left = parse_or(context)?;
|
||||
|
||||
if match_token(context, TokenKind::Comma) {
|
||||
@ -332,7 +332,7 @@ fn parse_comprehension_comma(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_or(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_or(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let left = parse_and(context)?;
|
||||
|
||||
if match_token(context, TokenKind::Or) {
|
||||
@ -345,7 +345,7 @@ fn parse_or(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_and(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_and(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let left = parse_comparison(context)?;
|
||||
|
||||
if match_token(context, TokenKind::And) {
|
||||
@ -358,7 +358,7 @@ fn parse_and(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_comparison(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_comparison(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let mut left = parse_to(context)?;
|
||||
|
||||
// Equality check
|
||||
@ -460,7 +460,7 @@ fn parse_comparison(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_to(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_to(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let left = parse_term(context)?;
|
||||
|
||||
if match_token(context, TokenKind::ToKeyword) {
|
||||
@ -477,7 +477,7 @@ fn parse_to(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_term(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_term(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let mut left = parse_factor(context)?;
|
||||
|
||||
while match_token(context, TokenKind::Plus) || match_token(context, TokenKind::Minus) {
|
||||
@ -491,7 +491,7 @@ fn parse_term(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_factor(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_factor(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let mut left = parse_unit(context)?;
|
||||
|
||||
if let Expr::Unary(TokenKind::Percent, percent_left) = left.clone() {
|
||||
@ -531,7 +531,7 @@ fn parse_factor(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_unit(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_unit(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let expr = parse_exponent(context)?;
|
||||
|
||||
if match_token(context, TokenKind::Identifier) {
|
||||
@ -547,7 +547,7 @@ fn parse_unit(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
fn parse_exponent(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_exponent(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let left = parse_unary(context)?;
|
||||
|
||||
if match_token(context, TokenKind::Power) {
|
||||
@ -559,7 +559,7 @@ fn parse_exponent(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_unary(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_unary(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
if match_token(context, TokenKind::Minus) {
|
||||
let op = advance(context).kind;
|
||||
let expr = Box::new(parse_unary(context)?);
|
||||
@ -574,7 +574,7 @@ fn parse_unary(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_indexer(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_indexer(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let left = parse_factorial(context)?;
|
||||
|
||||
if match_token(context, TokenKind::OpenDoubleBracket) {
|
||||
@ -593,7 +593,7 @@ fn parse_indexer(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_factorial(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_factorial(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let expr = parse_primary(context)?;
|
||||
|
||||
Ok(if match_token(context, TokenKind::Exclamation) {
|
||||
@ -604,19 +604,19 @@ fn parse_factorial(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_primary(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_primary(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let expr = match peek(context).kind {
|
||||
TokenKind::OpenParenthesis | TokenKind::OpenBracket => parse_vector(context)?,
|
||||
TokenKind::Pipe | TokenKind::OpenCeil | TokenKind::OpenFloor => parse_group_fn(context)?,
|
||||
TokenKind::Identifier => parse_identifier(context)?,
|
||||
TokenKind::Literal => Expr::Literal(string_to_num(&advance(context).value)?),
|
||||
_ => return Err(CalcError::UnableToParseExpression),
|
||||
_ => return Err(KalkError::UnableToParseExpression),
|
||||
};
|
||||
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
fn parse_group_fn(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_group_fn(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let name = match &peek(context).kind {
|
||||
TokenKind::Pipe => "abs",
|
||||
TokenKind::OpenCeil => "ceil",
|
||||
@ -634,7 +634,7 @@ fn parse_group_fn(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_vector(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_vector(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let kind = advance(context).kind;
|
||||
|
||||
if kind == TokenKind::OpenBracket {
|
||||
@ -660,7 +660,7 @@ fn parse_vector(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
{
|
||||
if let Some(columns) = column_count {
|
||||
if columns != items_in_row {
|
||||
return Err(CalcError::InconsistentColumnWidths);
|
||||
return Err(KalkError::InconsistentColumnWidths);
|
||||
}
|
||||
} else {
|
||||
column_count = Some(items_in_row);
|
||||
@ -676,7 +676,7 @@ fn parse_vector(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
}
|
||||
|
||||
if peek(context).kind == TokenKind::Eof {
|
||||
return Err(CalcError::Expected(String::from(
|
||||
return Err(KalkError::Expected(String::from(
|
||||
"Closing group symbol, eg. )",
|
||||
)));
|
||||
}
|
||||
@ -699,7 +699,7 @@ fn parse_vector(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_identifier(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
fn parse_identifier(context: &mut Context) -> Result<Expr, KalkError> {
|
||||
let identifier = Identifier::from_full_name(&advance(context).value);
|
||||
|
||||
let mut log_base = None;
|
||||
@ -775,12 +775,12 @@ fn advance(context: &mut Context) -> &Token {
|
||||
previous(context)
|
||||
}
|
||||
|
||||
fn consume(context: &mut Context, kind: TokenKind) -> Result<&Token, CalcError> {
|
||||
fn consume(context: &mut Context, kind: TokenKind) -> Result<&Token, KalkError> {
|
||||
if match_token(context, kind) {
|
||||
return Ok(advance(context));
|
||||
}
|
||||
|
||||
Err(CalcError::UnexpectedToken(peek(context).kind, kind))
|
||||
Err(KalkError::UnexpectedToken(peek(context).kind, kind))
|
||||
}
|
||||
|
||||
fn is_at_end(context: &Context) -> bool {
|
||||
@ -793,16 +793,16 @@ fn skip_newlines(context: &mut Context) {
|
||||
}
|
||||
}
|
||||
|
||||
fn string_to_num(value: &str) -> Result<f64, CalcError> {
|
||||
fn string_to_num(value: &str) -> Result<f64, KalkError> {
|
||||
let base = get_base(value)?;
|
||||
if let Some(result) = crate::radix::parse_float_radix(&value.replace(" ", ""), base) {
|
||||
Ok(result)
|
||||
} else {
|
||||
Err(CalcError::InvalidNumberLiteral(value.into()))
|
||||
Err(KalkError::InvalidNumberLiteral(value.into()))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_base(value: &str) -> Result<u8, CalcError> {
|
||||
fn get_base(value: &str) -> Result<u8, KalkError> {
|
||||
let underscore_pos = if let Some(i) = value.find('_') {
|
||||
i
|
||||
} else {
|
||||
@ -813,7 +813,7 @@ fn get_base(value: &str) -> Result<u8, CalcError> {
|
||||
if let Some(base) = crate::text_utils::parse_subscript(subscript) {
|
||||
Ok(base)
|
||||
} else {
|
||||
Err(CalcError::UnrecognizedBase)
|
||||
Err(KalkError::UnrecognizedBase)
|
||||
}
|
||||
}
|
||||
|
||||
@ -825,7 +825,7 @@ mod tests {
|
||||
use crate::test_helpers::*;
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
fn parse_with_context(context: &mut Context, tokens: Vec<Token>) -> Result<Stmt, CalcError> {
|
||||
fn parse_with_context(context: &mut Context, tokens: Vec<Token>) -> Result<Stmt, KalkError> {
|
||||
context.tokens = tokens;
|
||||
context.pos = 0;
|
||||
|
||||
@ -834,7 +834,7 @@ mod tests {
|
||||
analysis::analyse_stmt(symbol_table, parsed)
|
||||
}
|
||||
|
||||
fn parse(tokens: Vec<Token>) -> Result<Stmt, CalcError> {
|
||||
fn parse(tokens: Vec<Token>) -> Result<Stmt, KalkError> {
|
||||
let mut context = Context::new();
|
||||
context.tokens = tokens;
|
||||
context.pos = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user