calc_rational

CLI calculator for rational numbers.
git clone https://git.philomathiclife.com/repos/calc_rational
Log | Files | Refs | README

commit 6d9f4ad39dc96730d1b474a9e45e9610c3b87101
parent 5be9d112bcb3810a2ffd1b661695440ad5f737fd
Author: Zack Newman <zack@philomathiclife.com>
Date:   Fri, 14 Apr 2023 12:09:16 -0600

removed lang.pdf from being tracked. improved readme

Diffstat:
M.gitignore | 1+
MCargo.toml | 4++--
MREADME.md | 154++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Dlang.pdf | 0
Msrc/main.rs | 2+-
5 files changed, 149 insertions(+), 12 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -2,3 +2,4 @@ Cargo.lock target/** lang.aux lang.log +lang.pdf diff --git a/Cargo.toml b/Cargo.toml @@ -2,14 +2,14 @@ authors = ["Zack Newman <zack@philomathiclife.com>"] categories = ["algorithms", "mathematics", "science", "command-line-utilities"] description = "CLI calculator for rational numbers." -documentation = "https://docs.rs/calc_rational" +documentation = "https://crates.io/crates/calc_rational" edition = "2021" keywords = ["calculator", "mathematics", "numerics"] license = "MIT OR Apache-2.0" name = "calc_rational" readme = "README.md" repository = "https://git.philomathiclife.com/repos/calc_rational/" -version = "0.1.0" +version = "0.1.1" [lib] name = "calc_lib" diff --git a/README.md b/README.md @@ -1,9 +1,145 @@ -calc_rational ----------------- -calc_rational consists of a binary crate calc and a library crate -calc_lib. calc is a CLI calculator that only deals with arithmetic -defined on the rational numbers. Internally it is based on -[`Ratio<T>`](https://docs.rs/num/latest/num/rational/struct.Ratio.html) -and [`BigInt`](https://docs.rs/num-bigint/latest/num_bigint/struct.BigInt.html). -For a formal specification of the calc language, one can read -[lang.pdf](https://git.philomathiclife.com/calc_rational/lang.pdf). +# calc_rational + +calc_rational consists of a binary crate `calc` and a library crate +`calc_lib`. `calc` is a CLI calculator for basic rational number arithmetic +using standard operator precedence and associativity. Additionally, it +stores the previous eight evaluated expressions as well as provides a +way to display previous results in decimal form. Internally, it is +based on [`Ratio<T>`](https://docs.rs/num/latest/num/rational/struct.Ratio.html) +and [`BigInt`](https://docs.rs/num-bigint/latest/num_bigint/struct.BigInt.html). + +## Calc in action + +```bash +2.71828^0^3.14159 + -1! +> 0 +@^0 +> 1 +@/3 * 3 +> 1 +|@2 - 9|^(1 - 2*3) +> 1/32768 +=3@ +> 0.000 +=6@ +> 0.000031 +=@7 +There are only 4 previous results. +@6 +There are only 4 previous results. +=2 @2 +Invalid recall statement. A recall statement must be of the extended regex form: ^ *= *[0-9]?@[1-8]? *$. +q a +Invalid quit statement. A quit statement must be of the extended regex form: ^ *q *$. +a +Missing terminal expression at position 0. A terminal expression is a decimal literal expression, +recall expression, or addition expression enclosed in vertical bars or parentheses. +|1 +Invalid absolute value expression ending at position 2. An absolute value expression is an +addition expression enclosed in '||'. +(2 +Invalid parenthetical expression ending at position 2. A parenthetical expression is an addition +expression enclosed in '()'. +1/(2-2) +Division by zero ending at position 7. +2^(1/2) +Non-integer exponent with a base that was not 0 or 1 ending at position 7. +0^-1 +Non-negative exponent with a base of 0 ending at position 4. +(-1)! +Factorial of a rational number that was not a non-negative integer ending at position 5. +(1/2)! +Factorial of a rational number that was not a non-negative integer ending at position 6. +4. +Invalid decimal literal expression ending at position 2. A decimal literal expression must be of the +extended regex form: *[0-9]+(\.[0-9]+)?. +1+2 a +Trailing symbols starting at position 4. +q +``` + +## Operators + +The following are the list of operators in descending order of precedence: + 1. `()`, `||` + 2. `!` + 3. `^` + 4. `-` (unary negation operator) + 5. `*`, `/` + 6. `+`, `-` + +All binary operators are left-associative sans `^` which is right-associative. + +Any expression is allowed to be enclosed in `()`. Note that parentheses are purely for grouping expressions; +in particular, you cannot use them to represent multiplication (e.g., `4(2)` is grammatically incorrect and +will result in an error message). + +Any expression is allowed to be enclosed in `||`. This unary operator represents absolute value. + +`!` is the factorial operator. Due to its high precedence, something like *-i!^j!* for *i, j ∈ ℕ* is +the same thing as *-((i!)^(j!))*. If the expression preceding it does not evaluate to a non-negative integer, +then an error will be displayed. Spaces are *not* ignored; so `1 !` is grammatically incorrect and +will result in an error message. + +`^` is the exponentiation operator. The expression left of the operator can evaluate to any rational number; +however the expression right of the operator must evaluate to an integer unless the expression on the left +evaluates to `0` or `1`. In the event of the former, the expression right of the operator must evaluate to a +non-negative rational number. In the event of the latter, the expression right of the operator can evaluate to +any rational number. Note that `0^0` is defined to be 1. + +The unary operator `-` represents negation. + +The operators `*` and `/` represent multiplication and division respectively. Expressions right of `/` +must evaluate to any non-zero rational number; otherwise an error will be displayed. + +The binary operators `+` and `-` represent addition and subtraction respectively. + +With the aforementioned exception of `!`, all spaces before and after operators are ignored. + +## Numbers + +A number literal is a non-empty sequence of digits or a non-empty sequence of digits immediately followed by `.` +which is immediately followed by a non-empty sequence of digits (e.g., `134.901`). This means that number +literals represent precisely all possible ratios of non-negative integers to non-negative integers who sole +prime factors are 2 or 5. To represent all other rational numbers, the unary operator `-` and binary +operator `/` must be used. + +## Recall expressions + +`@` is used to recall previously evaluated expressions. It can be followed by any *digit* from `1` to `8`. +If such a digit does not immediately follow it, then it will be interpreted as if there were a `1`. +`@i` returns the *i*-th most-previous result where *i ∈ {1, 2, 3, 4, 5, 6, 7, 8}*. +Note that spaces are *not* ignored so `@ 2` is grammatically incorrect and will result in an error message. +As emphasized, it does not work on expressions; so both `@@` and `@(1)` are grammatically incorrect. + +## Displaying results in decimal form + +All calculations are done using exact rational number arithmetic; however if one wants to display a previous +result in decimal form, one can use `=<digit>@<1-8>`. For example `=2@` will display the previous result +rounded to two decimal places following normal rounding rules. Note that this is not an expression and so does +not influence previous results as can be recalled by `@`. + +## Character encoding + +All inputs must only contain the UTF-8 encoding of the following Unicode scalar values: `0`-`9`, `.`, `+`, `-`, +`*`, `/`, `^`, `!`, `|`, `(`, `)`, `@`, `=`, &lt;space&gt;, &lt;line feed&gt;, and `q`. Any other byte +sequences are grammatically incorrect and will lead to an error message. + +## Errors + +Errors due to a language violation (e.g., dividing by `0`) manifest into an error message. `panic!`s, +[`io::Error`](https://doc.rust-lang.org/std/io/struct.Error.html)s that are not of the [`ErrorKind::Interrupted`](https://doc.rust-lang.org/std/io/enum.ErrorKind.html) +variant, and [`fmt::Error`](https://doc.rust-lang.org/beta/core/fmt/struct.Error.html)s all lead to program abortion. + +## Exiting + +`q` with any number of spaces before and after will cause the program to terminate. + +## Installing + +`cargo install calc_rational`. The executable is called `calc`. + +### Formal language specification + +For a more precise specification of the "calc language", one can read the +[calc language specification](https://git.philomathiclife.com/calc_rational/lang.pdf). diff --git a/lang.pdf b/lang.pdf Binary files differ. diff --git a/src/main.rs b/src/main.rs @@ -46,7 +46,7 @@ //! non-negative rational number. In the event of the latter, the expression right of the operator can evaluate to //! any rational number. Note that `0^0` is defined to be 1. //! -//! The unary operator, `-`, represents negation. +//! The unary operator `-` represents negation. //! //! The operators `*` and `/` represent multiplication and division respectively. Expressions right of `/` //! must evaluate to any non-zero rational number; otherwise an error will be displayed.