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:
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`, `.`, `+`, `-`,
+`*`, `/`, `^`, `!`, `|`, `(`, `)`, `@`, `=`, <space>, <line feed>, 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.