expr-solver
A mathematical expression evaluator library written in Rust with support for custom functions, constants, and bytecode compilation.
Features
- Mathematical expressions - Arithmetic, comparisons, and built-in functions
- 128-bit decimal precision - No floating-point errors using
rust_decimal - Custom symbols - Register your own constants and functions
- Rich error messages - Syntax errors with source location highlighting
- Bytecode compilation - Compile expressions to portable binary format
- Stack-based VM - Efficient execution on a virtual machine
How It Works
The library implements a classic compiler pipeline:
Source → Lexer → Parser → AST → Semantic Analysis → IR → Bytecode → VM
- Lexer - Tokenizes the input string into operators, numbers, and identifiers
- Parser - Uses operator precedence climbing to build an Abstract Syntax Tree (AST)
- Semantic Analysis - Resolves symbols and validates function arities
- IR Builder - Converts the AST into stack-based bytecode instructions
- Virtual Machine - Executes the bytecode on a stack-based VM
This architecture allows for:
- Separating parsing from execution
- Compiling expressions once and running them multiple times
- Serializing compiled bytecode to disk for later use
Usage
As a Library
Add this to your Cargo.toml:
[]
= "1.0.3"
As a binary
Add this to your Cargo.toml:
[]
= "1.0.3"
Basic Example
use Eval;
Advanced Example
use ;
use dec;
Compile and Execute
use Eval;
use PathBuf;
Viewing Assembly
You can inspect the generated bytecode as human-readable assembly:
use Eval;
Output:
; VERSION 1.0.2
0000 PUSH 2
0001 PUSH 3
0002 PUSH 4
0003 MUL
0004 ADD
The assembly shows the stack-based bytecode instructions that will be executed by the VM.
Precision and Data Types
All calculations are performed using 128-bit Decimal type from the rust_decimal crate, providing exact decimal arithmetic without floating-point errors.
Note: Some trigonometric and hyperbolic functions (
asin,acos,atan,atan2,sinh,cosh,tanh,cbrt,exp2,log2,hypot) internally convert to/fromf64for computation, which may introduce minor precision differences. All constants (pi,e,tau,ln2,ln10,sqrt2) are computed using nativeDecimaloperations for maximum precision.
Built-in Functions
| Function | Arguments | Description | Notes |
|---|---|---|---|
| Arithmetic | |||
abs(x) |
1 | Absolute value | |
sign(x) |
1 | Sign (-1, 0, or 1) | |
floor(x) |
1 | Round down to integer | |
ceil(x) |
1 | Round up to integer | |
round(x) |
1 | Round to nearest integer | |
trunc(x) |
1 | Truncate to integer | |
fract(x) |
1 | Fractional part | |
mod(x, y) |
2 | Remainder of x/y | |
clamp(x, min, max) |
3 | Constrain value between bounds | |
| Trigonometry | |||
sin(x) |
1 | Sine | |
cos(x) |
1 | Cosine | |
tan(x) |
1 | Tangent | |
asin(x) |
1 | Arcsine | Uses f64 internally |
acos(x) |
1 | Arccosine | Uses f64 internally |
atan(x) |
1 | Arctangent | Uses f64 internally |
atan2(y, x) |
2 | Two-argument arctangent | Uses f64 internally |
| Hyperbolic | |||
sinh(x) |
1 | Hyperbolic sine | Uses f64 internally |
cosh(x) |
1 | Hyperbolic cosine | Uses f64 internally |
tanh(x) |
1 | Hyperbolic tangent | Uses f64 internally |
| Exponential/Logarithmic | |||
sqrt(x) |
1 | Square root | |
cbrt(x) |
1 | Cube root | Uses f64 internally |
pow(x, y) |
2 | x raised to power y | |
exp(x) |
1 | e raised to power x | |
exp2(x) |
1 | 2 raised to power x | Uses f64 internally |
log(x) |
1 | Natural logarithm | |
log2(x) |
1 | Base-2 logarithm | Uses f64 internally |
log10(x) |
1 | Base-10 logarithm | |
hypot(x, y) |
2 | Euclidean distance √(x²+y²) | Uses f64 internally |
| Variadic | |||
min(x, ...) |
1+ | Minimum value | Accepts any number of arguments |
max(x, ...) |
1+ | Maximum value | Accepts any number of arguments |
sum(x, ...) |
1+ | Sum of values | Accepts any number of arguments |
avg(x, ...) |
1+ | Average of values | Accepts any number of arguments |
| Special | |||
if(cond, t, f) |
3 | Conditional: returns t if cond≠0, else f |
Built-in Constants
| Constant | Value | Description |
|---|---|---|
pi |
3.14159... | π (pi) |
e |
2.71828... | Euler's number |
tau |
6.28318... | 2π (tau) |
ln2 |
0.69314... | Natural logarithm of 2 |
ln10 |
2.30258... | Natural logarithm of 10 |
sqrt2 |
1.41421... | Square root of 2 |
Note: All function and constant names are case-insensitive.
Supported Operators
| Operator | Type | Associativity | Precedence | Description |
|---|---|---|---|---|
! |
Postfix Unary | Left | 6 | Factorial |
^ |
Binary | Right | 5 | Exponentiation |
- |
Prefix Unary | Right | 4 | Negation |
*, / |
Binary | Left | 3 | Multiplication, Division |
+, - |
Binary | Left | 2 | Addition, Subtraction |
==, !=, <, <=, >, >= |
Binary | Left | 1 | Comparisons (return 1 or 0) |
() |
Grouping | - | - | Parentheses for grouping |
Command Line Usage
# Evaluate an expression
# Use the -e flag
# Define custom constants
# Compile to binary
# Execute compiled binary
# View assembly
# List available functions and constants
Testing
Run the test suite:
# Run all tests
License
This project is licensed under the MIT License.