diff --git a/Cargo.lock b/Cargo.lock index 0a3da2e..33f56b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -138,7 +138,7 @@ dependencies = [ [[package]] name = "kalk" -version = "0.1.11" +version = "0.2.0" dependencies = [ "lazy_static", "phf", @@ -149,7 +149,7 @@ dependencies = [ [[package]] name = "kalk_cli" -version = "0.1.10" +version = "0.2.0" dependencies = [ "ansi_term", "kalk", diff --git a/README.md b/README.md index e71dbe0..995285d 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ![Build status](https://img.shields.io/travis/PaddiM8/kalk/master?label=build%20%26%20test) -Kalk is a calculator (both program and library) that supports user-defined variables and functions. +Kalk is a calculator (both program and library) that supports user-defined variables, functions, and units (experimental). [Project kanban board (Kolan)](https://kolan.smrk.me/Board/4RAdMjLDz) ![](example.png) @@ -15,6 +15,7 @@ Kalk is a calculator (both program and library) that supports user-defined varia * Groups: (), ⌈⌉, ⌋⌊ * [Pre-defined functions and constants](https://github.com/PaddiM8/kalk/blob/master/kalk/src/prelude.rs) * User-defined functions and variables. `f(x, y) = xy`, `x = 5` +* User-defined units (experimental). `unit m = cm/100`, `2m/50cm`, `50cm to m` * Understands fairly ambiguous syntax. Eg. `2sin50 + 2xy` * Syntax highlighting * Special-symbol completion on tab. Eg. write `sqrt` and press tab. It will be turned into `√`. @@ -33,3 +34,30 @@ Run `cargo install kalk_cli` 1. Go into the `kalk_cli` directory. 2. Run `cargo build --release` 3. Grab the binary from `targets/release` + +## Syntax + +### Functions +__Defining:__ name(parameter1, parameter2, ...) = expression +**Example:** `f(x) = 2x+3` + +__Using:__ name(argument1, argument2) +**Example:** `f(2)` + +### Variables +__Defining:__ name = expression +**Example:** `x = 3` + +__Using:__ name +**Example:** `x` + +### Units +*Note: You only need to define the relationship between two units once. You will be able to convert between both of them.* +__Defining:__ `unit` name = expression +**Example:** `unit deg = (rad*180)/π` + +__Using:__ Use them freely in expressions. +**Example:** `2m/50cm` + +__Converting:__ expression `to` unit +**Example:** `2 m to cm` diff --git a/kalk/Cargo.toml b/kalk/Cargo.toml index 71577e8..e331d8c 100644 --- a/kalk/Cargo.toml +++ b/kalk/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "kalk" -version = "0.1.11" +version = "0.2.0" authors = ["PaddiM8"] edition = "2018" readme = "README.md" -description = "A math evaluator library that supports user-defined functions and variables and can handle fairly ambiguous syntax." +description = "A math evaluator library that supports user-defined functions, variables and units, and can handle fairly ambiguous syntax." repository = "https://github.com/PaddiM8/kalk/tree/master/kalk" license = "MIT" keywords = ["math", "calculator", "evaluator"] diff --git a/kalk/src/interpreter.rs b/kalk/src/interpreter.rs index f08b050..f238e8b 100644 --- a/kalk/src/interpreter.rs +++ b/kalk/src/interpreter.rs @@ -27,20 +27,27 @@ impl<'a> Context<'a> { statements: Vec, ) -> Result, CalcError> { for (i, stmt) in statements.iter().enumerate() { - let value = eval_stmt(self, stmt); + let (value, unit) = eval_stmt(self, stmt)?; // Insert the last value into the `ans` variable. - self.symbol_table.set( - "ans", + self.symbol_table.set(if (&unit).len() > 0 { Stmt::VarDecl( String::from("ans"), - Box::new(Expr::Literal(value.clone()?.to_string())), - ), - ); + Box::new(Expr::Unit( + unit.clone(), + Box::new(Expr::Literal(value.clone().to_string())), + )), + ) + } else { + Stmt::VarDecl( + String::from("ans"), + Box::new(Expr::Literal(value.clone().to_string())), + ) + }); if i == statements.len() - 1 { if let Stmt::Expr(_) = stmt { - return Ok(Some(value?)); + return Ok(Some((value, unit))); } } } diff --git a/kalk_cli/Cargo.toml b/kalk_cli/Cargo.toml index 81bcf3c..950b395 100644 --- a/kalk_cli/Cargo.toml +++ b/kalk_cli/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "kalk_cli" -version = "0.1.10" +version = "0.2.0" authors = ["PaddiM8"] edition = "2018" readme = "../README.md" -description = "A calculator that supports user-defined functions and variables and can handle fairly ambiguous syntax." +description = "A calculator that supports user-defined functions, variables and units, and can handle fairly ambiguous syntax." repository = "https://github.com/PaddiM8/kalk" license = "MIT" keywords = ["math", "calculator", "cli", "command-line"] @@ -15,7 +15,7 @@ path = "src/main.rs" name = "kalk" [dependencies] -kalk = { path = "../kalk", version = "^0.1.11" } +kalk = { path = "../kalk", version = "^0.2.0" } rustyline = "6.1.2" ansi_term = "0.12" regex = "1"