Matheval
A modern, high-performance mathematical expression evaluator built with Pratt Parsing and Stack-based VM
Install / Use
/learn @gocronx/MathevalREADME
matheval
A high-performance mathematical expression evaluator implementing a Pratt parser with bytecode compilation and a stack-based virtual machine.
Design Philosophy
Traditional expression evaluators rely on the Shunting-yard algorithm and tree-walking interpretation. This implementation adopts a compiler-VM architecture for superior performance:
- Pratt Parsing: Top-down operator precedence parsing with O(n) complexity
- Bytecode Compilation: AST flattening into compact, cache-friendly instruction sequences
- Stack-based VM: Zero-overhead execution with tight instruction dispatch loop
Performance Characteristics
| Component | Optimization | Complexity | |-----------|-------------|------------| | Variable Resolution | Index-based interning | O(1) | | Constant Pool | HashMap deduplication | O(1) | | Function Dispatch | Direct pointer table | O(1) | | Batch Evaluation | Shared VM instance | O(n·m) |
Key Optimizations:
- Constant Folding: Compile-time evaluation of constant expressions
- Algebraic Simplification: Identity elimination (x·1 → x, x+0 → x)
- Zero-copy Execution: Direct stack manipulation without heap allocation
- Function Validation: Compile-time arity checking with metadata
Architecture
┌─────────────┐
│ Source │
└──────┬──────┘
│ Lexical Analysis
▼
┌─────────────┐
│ Tokens │
└──────┬──────┘
│ Pratt Parsing
▼
┌─────────────┐
│ AST │
└──────┬──────┘
│ Optimization & Compilation
▼
┌─────────────┐ ┌──────────────┐
│ Bytecode │────▶│ Symbol Table │
└──────┬──────┘ └──────────────┘
│
│ VM Execution
▼
┌─────────────┐
│ Result │
└─────────────┘
Quick Start
Rust
use matheval_core::Compiler;
let compiler = Compiler::new();
let program = compiler.compile("x^2 + 2*x + 1").unwrap();
let mut context = program.create_context();
context.set_by_index(0, 3.0); // x = 3
let result = program.eval(&context).unwrap();
assert_eq!(result, 16.0); // 3² + 2·3 + 1 = 16
Python
import matheval
compiler = matheval.Compiler()
program = compiler.compile("x^2 + 2*x + 1")
context = matheval.Context()
context.set("x", 3.0)
result = program.eval(context)
assert result == 16.0
Advanced Features
Batch Evaluation
Optimized for Monte Carlo simulations and parameter sweeps:
let program = compiler.compile("S * exp(r*T) - K").unwrap();
// Vectorized evaluation: reuses VM instance
let var_sets = vec![
&[100.0, 0.05, 1.0, 105.0][..], // S, r, T, K
&[110.0, 0.05, 1.0, 105.0][..],
&[120.0, 0.05, 1.0, 105.0][..],
];
let results = program.eval_batch(&var_sets).unwrap();
Performance: 6-7× faster than loop-based evaluation for large datasets.
Error Handling
Comprehensive error reporting with position tracking:
use matheval_core::{Error, ErrorKind, Position};
let err = Error::wrong_arg_count("sin", 1, 2)
.with_position(Position::new(1, 5, 4))
.with_source("x + sin(1, 2)".to_string());
// Output:
// Error: Function 'sin' expects 1 argument, but got 2 at line 1, column 5
//
// 1 | x + sin(1, 2)
// ^
//
// Hint: Check the function documentation for the correct number of arguments
Supported Operations
Arithmetic: +, -, *, /, ^ (right-associative)
Functions: sin, cos, tan, sqrt, abs, floor, ceil, round, exp, ln, log10, max, min
Precedence: Standard mathematical order with parentheses support
Implementation Details
Compiler Pipeline
- Lexical Analysis: Tokenization with position tracking
- Syntax Analysis: Pratt parsing with binding power resolution
- Optimization: Constant folding and algebraic simplification
- Code Generation: Bytecode emission with symbol table construction
Virtual Machine
- Instruction Set: 9 opcodes (LoadConst, LoadVar, Add, Sub, Mul, Div, Pow, Neg, Call)
- Stack Model: f64 operand stack with bounds checking
- Function Table: Direct function pointer dispatch
- Metadata: Compile-time arity validation
Memory Layout
Program {
instructions: Vec<u8>, // Compact bytecode
constants: Vec<f64>, // Deduplicated constant pool
var_names: Vec<String>, // Variable name table
func_table: Vec<BuiltinFn>, // Function pointer table
func_metadata: Vec<Metadata>, // Arity information
}
Benchmarks
Expression: x * 2 + sin(y) (10,000 iterations)
| Method | Time | Throughput | |--------|------|------------| | Loop eval() | 34.5 ms | 290k ops/s | | Batch eval_batch() | 5.0 ms | 2M ops/s |
Speedup: 6.9× for batch evaluation
Safety & Correctness
- 100% Safe Rust: No
unsafeblocks - Comprehensive Testing: 97 unit tests, 9 Python integration tests
- Validation: Compile-time function arity checking
- Error Recovery: Graceful handling of division by zero, stack underflow
Related Skills
himalaya
341.8kCLI to manage emails via IMAP/SMTP. Use `himalaya` to list, read, write, reply, forward, search, and organize emails from the terminal. Supports multiple accounts and message composition with MML (MIME Meta Language).
node-connect
341.8kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
claude-opus-4-5-migration
84.6kMigrate prompts and code from Claude Sonnet 4.0, Sonnet 4.5, or Opus 4.1 to Opus 4.5
frontend-design
84.6kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
