exp-rs

Crates.ioexp-rs
lib.rsexp-rs
version0.2.0
created_at2025-04-21 02:41:58.724861+00
updated_at2025-12-16 20:44:02.550674+00
descriptionno_std expression parser, compiler, and evaluation engine for math expressions designed for embedded, with qemu examples
homepagehttps://github.com/cosmikwolf/exp-rs
repositoryhttps://github.com/cosmikwolf/exp-rs
max_upload_size
id1642215
size4,552,674
Tenkai Kariya (cosmikwolf)

documentation

https://docs.rs/exp-rs

README

exp-rs

Crates.io Documentation CI Coverage Status no_std

A tiny, no_std Pratt expression parser and evaluator for embedded systems.

Key Features

  • Pratt parser for minimal stack depth—handles deep nesting on embedded stacks
  • Arena allocation for bounded memory and zero-allocation evaluation after setup
  • no_std compatible with configurable f32/f64 precision
  • Variables, constants, arrays, attributes, and custom functions
  • C FFI with auto-generated headers via cbindgen

Installation

[dependencies]
exp-rs = "0.2"

Floating-Point Precision

By default, exp-rs uses 64-bit floating point (double precision) for calculations. You can configure the precision using feature flags:

# Use default 64-bit precision (double)
exp-rs = "0.2"

# Use 32-bit precision (float)
exp-rs = { version = "0.2", features = ["f32"] }

The f64 mode is the default when f32 is not specified.

Custom Math Implementations

For embedded systems, you can disable the libm dependency to reduce binary size and provide your own math function implementations:

# Disable libm dependency
exp-rs = { version = "0.2", default-features = false }

Quick Example

use exp_rs::Expression;
use bumpalo::Bump;

let arena = Bump::new();
let result = Expression::eval_simple("2 + 3 * 4", &arena).unwrap();
assert_eq!(result, 14.0);

For the full API including parameters, batch evaluation, custom functions, and more, see the documentation.

C FFI

A C header is automatically generated during build via cbindgen:

#include "exp_rs.h"

int main() {
    double result = exp_rs_eval("2+2*2");
    printf("%f\n", result); // prints "6.000000"
    return 0;
}

The header is generated at include/exp_rs.h after running cargo build.

Build Instructions

cargo build
cargo test

Meson Build

meson setup build
meson compile -C build

QEMU Tests (ARM Cortex-M)

# Run QEMU embedded tests
./run_tests.sh --qemu -v

# Run with allocation tracking
./run_tests.sh --qemu -a system --track-allocs -v -c

# Run native C tests
./run_tests.sh --native -v

# See all options
./run_tests.sh --help

Code Coverage

cargo install cargo-tarpaulin
cargo tarpaulin --workspace

Project History

exp-rs began as a fork of tinyexpr-rs by Krzysztof Kondrak, which was a port of TinyExpr by Lewis Van Winkle. The grammar is based on tinyexpr-plusplus by Blake Madden.

Key differences from tinyexpr:

  • Pratt parser (vs recursive descent) for shallower call stacks
  • Arena allocation for predictable memory usage
  • Extended operator set and short-circuit logical operators

License

Licensed under either of

Commit count: 16

cargo fmt