From b59d3e1f5182cb438f832a00c60bef56476f880a Mon Sep 17 00:00:00 2001 From: PaddiM8 Date: Thu, 31 Dec 2020 00:15:16 +0100 Subject: [PATCH] JavaScript bindings to KalkNum and ScientificNotation --- kalk/src/kalk_num/regular.rs | 39 +++++++++++++++++++++++++++--------- kalk/src/parser.rs | 8 ++++---- kalk/src/prelude/regular.rs | 6 ++---- kalk_cli/src/output.rs | 2 +- kalk_web/index.js | 2 +- 5 files changed, 38 insertions(+), 19 deletions(-) diff --git a/kalk/src/kalk_num/regular.rs b/kalk/src/kalk_num/regular.rs index a4f8ab3..1f042b0 100644 --- a/kalk/src/kalk_num/regular.rs +++ b/kalk/src/kalk_num/regular.rs @@ -1,18 +1,24 @@ use crate::ast::Expr; +use wasm_bindgen::prelude::*; +#[wasm_bindgen] #[derive(PartialEq, Debug, Clone, Default)] pub struct KalkNum { pub(crate) value: f64, pub(crate) unit: String, } +#[wasm_bindgen] +#[derive(Clone)] pub struct ScientificNotation { pub negative: bool, - pub digits: String, + pub(crate) digits: String, pub exponent: i32, } +#[wasm_bindgen] impl ScientificNotation { + #[wasm_bindgen(js_name = toString)] pub fn to_string(&self) -> String { let sign = if self.negative { "-" } else { "" }; let mut digits_and_mul = if self.digits == "1" { @@ -29,6 +35,7 @@ impl ScientificNotation { } } +#[wasm_bindgen] impl KalkNum { pub fn new(value: f64, unit: &str) -> Self { Self { @@ -37,43 +44,57 @@ impl KalkNum { } } + #[wasm_bindgen(js_name = getValue)] pub fn to_f64(&self) -> f64 { self.value } + #[wasm_bindgen(js_name = toString)] pub fn to_string(&self) -> String { self.value.to_string() } + #[wasm_bindgen(js_name = toStringBig)] pub fn to_string_big(&self) -> String { self.value.to_string() } + #[wasm_bindgen(js_name = isTooBig)] pub fn is_too_big(&self) -> bool { self.value.is_infinite() } + #[wasm_bindgen(js_name = toStringWithUnit)] pub fn to_string_with_unit(&self) -> String { format!("{} {}", self.to_string(), self.unit) } + #[cfg(not(target_arch = "wasm32"))] pub fn get_unit(&self) -> &str { &self.unit } + #[cfg(target_arch = "wasm32")] + #[wasm_bindgen(js_name = getUnit)] + pub fn get_unit(&self) -> String { + self.unit.clone().into() + } + + #[wasm_bindgen(js_name = hasUnit)] pub fn has_unit(&self) -> bool { self.unit.len() > 0 } + #[wasm_bindgen(js_name = toScientificNotation)] pub fn to_scientific_notation(&self) -> ScientificNotation { ScientificNotation { negative: self.value < 0f64, digits: self.value.to_string().replace(".", ""), - exponent: self.value.log(10f64) as i32, + exponent: self.value.log(10f64) as i32 + 1, } } - pub fn convert_to_unit( + pub(crate) fn convert_to_unit( &self, context: &mut crate::interpreter::Context, to_unit: &str, @@ -92,32 +113,32 @@ impl KalkNum { } } - pub fn add(self, context: &mut crate::interpreter::Context, rhs: KalkNum) -> KalkNum { + pub(crate) fn add(self, context: &mut crate::interpreter::Context, rhs: KalkNum) -> KalkNum { let right = calculate_unit(context, &self, rhs.clone()).unwrap_or(rhs); KalkNum::new(self.value + right.value, &right.unit) } - pub fn sub(self, context: &mut crate::interpreter::Context, rhs: KalkNum) -> KalkNum { + pub(crate) fn sub(self, context: &mut crate::interpreter::Context, rhs: KalkNum) -> KalkNum { let right = calculate_unit(context, &self, rhs.clone()).unwrap_or(rhs); KalkNum::new(self.value - right.value, &right.unit) } - pub fn mul(self, context: &mut crate::interpreter::Context, rhs: KalkNum) -> KalkNum { + pub(crate) fn mul(self, context: &mut crate::interpreter::Context, rhs: KalkNum) -> KalkNum { let right = calculate_unit(context, &self, rhs.clone()).unwrap_or(rhs); KalkNum::new(self.value * right.value, &right.unit) } - pub fn div(self, context: &mut crate::interpreter::Context, rhs: KalkNum) -> KalkNum { + pub(crate) fn div(self, context: &mut crate::interpreter::Context, rhs: KalkNum) -> KalkNum { let right = calculate_unit(context, &self, rhs.clone()).unwrap_or(rhs); KalkNum::new(self.value / right.value, &right.unit) } - pub fn rem(self, context: &mut crate::interpreter::Context, rhs: KalkNum) -> KalkNum { + pub(crate) fn rem(self, context: &mut crate::interpreter::Context, rhs: KalkNum) -> KalkNum { let right = calculate_unit(context, &self, rhs.clone()).unwrap_or(rhs); KalkNum::new(self.value % right.value, &right.unit) } - pub fn pow(self, context: &mut crate::interpreter::Context, rhs: KalkNum) -> KalkNum { + pub(crate) fn pow(self, context: &mut crate::interpreter::Context, rhs: KalkNum) -> KalkNum { let right = calculate_unit(context, &self, rhs.clone()).unwrap_or(rhs); KalkNum::new(self.value.powf(right.value), &right.unit) } diff --git a/kalk/src/parser.rs b/kalk/src/parser.rs index f78b072..52d4caf 100644 --- a/kalk/src/parser.rs +++ b/kalk/src/parser.rs @@ -137,15 +137,15 @@ pub fn eval( interpreter.interpret(statements) } -#[wasm_bindgen] +#[wasm_bindgen(js_name = evaluate)] #[cfg(not(feature = "rug"))] -pub fn simple_eval(input: &str) -> Result { +pub fn js_eval(input: &str) -> Result { let mut context = Context::new(); let result = eval(&mut context, input); match result { - Ok(Some(value)) => Ok(value.to_f64().into()), - Ok(None) => Ok(JsValue::NULL), + Ok(Some(value)) => Ok(value), + Ok(None) => Ok(KalkNum::default()), Err(err) => Err(err.to_string().into()), } } diff --git a/kalk/src/prelude/regular.rs b/kalk/src/prelude/regular.rs index b66b3a6..708d5e6 100644 --- a/kalk/src/prelude/regular.rs +++ b/kalk/src/prelude/regular.rs @@ -96,8 +96,7 @@ fn from_angle_unit(context: &mut interpreter::Context, x: f64, angle_unit: &str) pub mod special_funcs { pub fn factorial(x: f64) -> f64 { - //special::Gamma::gamma(x + 1f64) - x + unimplemented!() } } @@ -199,8 +198,7 @@ pub(super) mod funcs { } pub fn gamma(x: f64) -> f64 { - //special::Gamma::gamma(x) - x + unimplemented!() } pub fn hyp(x: f64, y: f64) -> f64 { diff --git a/kalk_cli/src/output.rs b/kalk_cli/src/output.rs index f338dbd..c75beb7 100644 --- a/kalk_cli/src/output.rs +++ b/kalk_cli/src/output.rs @@ -1,6 +1,6 @@ use crate::DEFAULT_PRECISION; use ansi_term::Colour::Red; -use kalk::parser::{self, CalcError, CalcError::*}; +use kalk::parser; pub fn eval(parser: &mut parser::Context, input: &str, precision: u32) { match parser::eval(parser, input, precision) { diff --git a/kalk_web/index.js b/kalk_web/index.js index d08fd64..2f164ad 100644 --- a/kalk_web/index.js +++ b/kalk_web/index.js @@ -4,7 +4,7 @@ async function main() { const kalk = await import("kalk-rs"); try { - console.log(kalk.simple_eval("5+")); + console.log(kalk.evaluate("5^3").toScientificNotation().toString()); } catch(err) { console.log(err); }