Show equation variable in result, #140

This commit is contained in:
PaddiM8 2024-04-03 01:16:45 +02:00
parent b6d22903fc
commit 8ffc0e1e9d
2 changed files with 93 additions and 21 deletions

View File

@ -7,17 +7,19 @@ pub struct CalculationResult {
value: KalkValue, value: KalkValue,
radix: u8, radix: u8,
is_approximation: bool, is_approximation: bool,
equation_variable: Option<String>,
} }
// Wraps around KalkValue since enums don't work // Wraps around KalkValue since enums don't work
// with the javascript bindings. // with the javascript bindings.
#[wasm_bindgen] #[wasm_bindgen]
impl CalculationResult { impl CalculationResult {
pub(crate) fn new(value: KalkValue, radix: u8, is_approximation: bool) -> Self { pub(crate) fn new(value: KalkValue, radix: u8, is_approximation: bool, equation_variable: Option<String>) -> Self {
CalculationResult { CalculationResult {
value, value,
radix, radix,
is_approximation, is_approximation,
equation_variable,
} }
} }
@ -56,10 +58,16 @@ impl CalculationResult {
0 0
}; };
if self.is_approximation || decimal_count == 10 { let equation_variable = if let Some(name) = &self.equation_variable {
format!("{}", value) format!("{} ", name)
} else { } else {
format!("= {}", value) String::new()
};
if self.is_approximation || decimal_count == 10 {
format!("{}{}", equation_variable, value)
} else {
format!("{}= {}", equation_variable, value)
} }
} }

View File

@ -24,6 +24,7 @@ pub struct Context<'a> {
is_approximation: bool, is_approximation: bool,
recursion_depth: u32, recursion_depth: u32,
max_recursion_depth: u32, max_recursion_depth: u32,
equation_variable: Option<String>,
} }
impl<'a> Context<'a> { impl<'a> Context<'a> {
@ -46,6 +47,7 @@ impl<'a> Context<'a> {
is_approximation: false, is_approximation: false,
recursion_depth: 0, recursion_depth: 0,
max_recursion_depth: DEFAULT_MAX_RECURSION_DEPTH, max_recursion_depth: DEFAULT_MAX_RECURSION_DEPTH,
equation_variable: None,
} }
} }
@ -60,6 +62,9 @@ impl<'a> Context<'a> {
statements: Vec<Stmt>, statements: Vec<Stmt>,
) -> Result<Option<CalculationResult>, KalkError> { ) -> Result<Option<CalculationResult>, KalkError> {
for (i, stmt) in statements.iter().enumerate() { for (i, stmt) in statements.iter().enumerate() {
self.is_approximation = false;
self.equation_variable = None;
let num = eval_stmt(self, stmt)?; let num = eval_stmt(self, stmt)?;
// Insert the last value into the `ans` variable. // Insert the last value into the `ans` variable.
@ -80,7 +85,12 @@ impl<'a> Context<'a> {
if i == statements.len() - 1 { if i == statements.len() - 1 {
if let Stmt::Expr(_) = stmt { if let Stmt::Expr(_) = stmt {
return Ok(Some(CalculationResult::new(num, 10, self.is_approximation))); return Ok(Some(CalculationResult::new(
num,
10,
self.is_approximation,
self.equation_variable.clone(),
)));
} }
} }
} }
@ -829,6 +839,7 @@ fn eval_equation(
unknown_var: &Identifier, unknown_var: &Identifier,
) -> Result<KalkValue, KalkError> { ) -> Result<KalkValue, KalkError> {
context.is_approximation = true; context.is_approximation = true;
context.equation_variable = Some(unknown_var.full_name.clone());
let expr = Expr::Binary( let expr = Expr::Binary(
Box::new(left.clone()), Box::new(left.clone()),
@ -918,18 +929,61 @@ mod tests {
#[test] #[test]
fn test_binary() { fn test_binary() {
let add = Stmt::Expr(binary(f64_to_float_literal(2f64), Plus, f64_to_float_literal(3f64))); let add = Stmt::Expr(binary(
let sub = Stmt::Expr(binary(f64_to_float_literal(2f64), Minus, f64_to_float_literal(3f64))); f64_to_float_literal(2f64),
let mul = Stmt::Expr(binary(f64_to_float_literal(2f64), Star, f64_to_float_literal(3f64))); Plus,
let div = Stmt::Expr(binary(f64_to_float_literal(2f64), Slash, f64_to_float_literal(4f64))); f64_to_float_literal(3f64),
let pow = Stmt::Expr(binary(f64_to_float_literal(2f64), Power, f64_to_float_literal(3f64))); ));
let equals = Stmt::Expr(binary(f64_to_float_literal(2f64), Equals, f64_to_float_literal(3f64))); let sub = Stmt::Expr(binary(
let not_equals = Stmt::Expr(binary(f64_to_float_literal(2f64), NotEquals, f64_to_float_literal(3f64))); f64_to_float_literal(2f64),
let greater_than = Stmt::Expr(binary(f64_to_float_literal(2f64), GreaterThan, f64_to_float_literal(3f64))); Minus,
let less_than = Stmt::Expr(binary(f64_to_float_literal(2f64), LessThan, f64_to_float_literal(3f64))); f64_to_float_literal(3f64),
let greater_or_equals = ));
Stmt::Expr(binary(f64_to_float_literal(2f64), GreaterOrEquals, f64_to_float_literal(3f64))); let mul = Stmt::Expr(binary(
let less_or_equals = Stmt::Expr(binary(f64_to_float_literal(2f64), LessOrEquals, f64_to_float_literal(3f64))); f64_to_float_literal(2f64),
Star,
f64_to_float_literal(3f64),
));
let div = Stmt::Expr(binary(
f64_to_float_literal(2f64),
Slash,
f64_to_float_literal(4f64),
));
let pow = Stmt::Expr(binary(
f64_to_float_literal(2f64),
Power,
f64_to_float_literal(3f64),
));
let equals = Stmt::Expr(binary(
f64_to_float_literal(2f64),
Equals,
f64_to_float_literal(3f64),
));
let not_equals = Stmt::Expr(binary(
f64_to_float_literal(2f64),
NotEquals,
f64_to_float_literal(3f64),
));
let greater_than = Stmt::Expr(binary(
f64_to_float_literal(2f64),
GreaterThan,
f64_to_float_literal(3f64),
));
let less_than = Stmt::Expr(binary(
f64_to_float_literal(2f64),
LessThan,
f64_to_float_literal(3f64),
));
let greater_or_equals = Stmt::Expr(binary(
f64_to_float_literal(2f64),
GreaterOrEquals,
f64_to_float_literal(3f64),
));
let less_or_equals = Stmt::Expr(binary(
f64_to_float_literal(2f64),
LessOrEquals,
f64_to_float_literal(3f64),
));
assert_eq!(interpret(add).unwrap().unwrap().to_f64(), 5f64); assert_eq!(interpret(add).unwrap().unwrap().to_f64(), 5f64);
assert_eq!(interpret(sub).unwrap().unwrap().to_f64(), -1f64); assert_eq!(interpret(sub).unwrap().unwrap().to_f64(), -1f64);
@ -967,7 +1021,11 @@ mod tests {
let stmt = Stmt::Expr(binary( let stmt = Stmt::Expr(binary(
f64_to_float_literal(5f64), f64_to_float_literal(5f64),
Percent, Percent,
group(binary(f64_to_float_literal(3f64), Plus, unary(Percent, f64_to_float_literal(2f64)))), group(binary(
f64_to_float_literal(3f64),
Plus,
unary(Percent, f64_to_float_literal(2f64)),
)),
)); ));
assert!(cmp(interpret(stmt).unwrap().unwrap(), 1.94f64)); assert!(cmp(interpret(stmt).unwrap().unwrap(), 1.94f64));
@ -984,8 +1042,14 @@ mod tests {
#[test] #[test]
fn test_angle_units() { fn test_angle_units() {
let rad_explicit = Stmt::Expr(fn_call("sin", vec![*unit("rad", f64_to_float_literal(1f64))])); let rad_explicit = Stmt::Expr(fn_call(
let deg_explicit = Stmt::Expr(fn_call("sin", vec![*unit("deg", f64_to_float_literal(1f64))])); "sin",
vec![*unit("rad", f64_to_float_literal(1f64))],
));
let deg_explicit = Stmt::Expr(fn_call(
"sin",
vec![*unit("deg", f64_to_float_literal(1f64))],
));
let implicit = Stmt::Expr(fn_call("sin", vec![*f64_to_float_literal(1f64)])); let implicit = Stmt::Expr(fn_call("sin", vec![*f64_to_float_literal(1f64)]));
assert!(cmp(interpret(rad_explicit).unwrap().unwrap(), 0.84147098)); assert!(cmp(interpret(rad_explicit).unwrap().unwrap(), 0.84147098));
@ -1093,7 +1157,7 @@ mod tests {
vec![ vec![
*binary(var("n"), TokenKind::Equals, f64_to_float_literal(start)), *binary(var("n"), TokenKind::Equals, f64_to_float_literal(start)),
*f64_to_float_literal(to), *f64_to_float_literal(to),
*binary(var("n"), TokenKind::Plus,f64_to_float_literal(3f64)), *binary(var("n"), TokenKind::Plus, f64_to_float_literal(3f64)),
], ],
)); ));