A simple and lightweight arithmetic expression interpreter written in Rust. Mate parses string expressions using a lexer that generates a token tree, then calculates results using an X/O/Y algorithm. Supports basic arithmetic, parentheses, absolute values, powers, percentages, and mathematical functions.
Both binary and library are provided. The binary offers an interactive REPL and direct expression evaluation. The library enables programmatic calculation with full access to the lexer and calculator components.
Install the binary globally:
cargo install mate-rsFor the latest git version:
cargo install --git https://github.com/theiskaa/mateAdd to your project:
cargo add mate-rsOr add to your Cargo.toml:
mate-rs = "0.3.0"Evaluate expressions directly:
mate 2 + 2
mate "(5 + 3) * 2"
mate "sqrt(16) + sin(3.14159 / 2)"Start interactive REPL:
mateShow parsed tokens with -t flag:
mate -t "10 / 2"Using the Mate wrapper for simple calculations:
use mate_rs::mate::Mate;
let result = Mate::calculate("6 * 7");
match result {
Ok(v) => assert_eq!(v, 42.0),
Err(e) => println!("Error: {}", e),
};Using Lexer and Calculator separately:
use mate_rs::{calculator::Calculator, lexer::Lexer};
let input = "[ (2 + 5) * (5 - 9 + (8 - 5)) ] + 35";
let tokens = Lexer::lex(input).unwrap();
let result = Calculator::calculate(tokens, input);| Operator | Description | Example |
|---|---|---|
+ |
Addition | 2 + 3 |
- |
Subtraction | 5 - 2 |
* |
Multiplication | 4 * 3 |
/ |
Division | 10 / 2 |
% |
Percentage | 50 % 10 (10% of 50 = 5) |
^ |
Power | 2 ^ 3 (= 8) |
! |
Factorial | 5! (= 120) |
() |
Parentheses | (2 + 3) * 4 |
[] |
Absolute value | [-5] (= 5) |
| Function | Description | Example |
|---|---|---|
sqrt(x) |
Square root | sqrt(16) (= 4) |
sin(x) |
Sine (radians) | sin(3.14159 / 2) |
cos(x) |
Cosine (radians) | cos(0) (= 1) |
tan(x) |
Tangent (radians) | tan(0.785) |
log(x) |
Base-10 logarithm | log(100) (= 2) |
ln(x) |
Natural logarithm | ln(2.718) |
exp(x) |
Exponential (e^x) | exp(1) |
floor(x) |
Round down | floor(3.7) (= 3) |
ceil(x) |
Round up | ceil(3.2) (= 4) |
round(x) |
Round to nearest | round(3.5) (= 4) |
Functions can be nested: sqrt(floor(17)), sin(cos(0)), 2 * sqrt(16) + 1
Variables can be assigned and used in expressions (REPL mode only):
>>> x = 5
5
>>> x + 10
15
>>> y = x * 2
10
>>> radius = 7
7
>>> 3.14159 * radius ^ 2
153.938Variable names can contain letters, numbers, and underscores (must start with a letter).
REPL commands for variables:
vars- Show all defined variablesreset- Clear all variables
The Lexer iterates through the input string, converting each character into tokens. It groups tokens related to multiplication or division operations into a single sub-expression to maintain correct operation priority. It also nests parentheses, absolute values, and powers using a level-to-expression algorithm.
The level-to-expression algorithm maps each expression to its nesting level. For example, given the token list (2 + 5) * (5 - 9 / (8 - 5)):
This approach ensures correct operation priority is maintained.
The Calculator uses an X/O/Y algorithm where X and Y are numbers and O is an operation:
╭────────╮ ╭───────────╮ ╭────────╮
│ NUMBER │ │ OPERATION │ │ NUMBER │
╰────────╯ ╰───────────╯ ╰────────╯
╰───╮ │ ╭───╯
▼ ▼ ▼
X [+, -, *, /] Y
Sub-expressions are recursively evaluated before the main calculation.
For information regarding contributions, please refer to CONTRIBUTING.md file.
