Skip to content

rhetro/emlex

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Emlex

A mathematical S-expression Domain Specific Language (DSL) compiler embedded in Rust macros.

emlex provides two compile-time evaluation environments:

  • eml!: A single-form DSL for real number evaluations.
  • ceml!: A comprehensive DSL for complex number operations.

The library evaluates S-expressions into native Rust operations at compile-time while preserving the Abstract Syntax Tree (AST) for structural optimization and Reverse DSL transformations.

Architecture & Performance

The macros generate purely native Rust code. To handle AST preservation (EExpr / CExpr) without runtime allocation overhead, the library utilizes lazy evaluation via static function pointers (LazyEExpr / LazyCExpr). If the AST is not explicitly consumed at runtime, LLVM's Dead Code Elimination (DCE) removes the allocation instructions, resulting in zero-overhead execution matching handwritten native operations.

Recursion Limit

emlex performs full S-expression parsing using macro_rules!, which relies on recursive macro expansion. For deeply nested expressions, the default Rust recursion limit (#[recursion_limit = "128"]) may be insufficient.

If you encounter a compilation error such as:

recursion limit reached while expanding the macro

add the following attribute to your crate root (lib.rs or main.rs):

#![recursion_limit = "512"]

Most projects will not require this, but complex or deeply nested DSL inputs may.

Features

  • Dual Evaluation Engines:
  • eml!: Evaluates (eml x y) as exp(x) - ln(y).
  • ceml!: Evaluates standard operations backed by num_complex::Complex<f64>.
  • Reverse DSL (AST Reconstruction): Parses inputs into ASTs that can be reconstructed back into their original S-expression strings using .to_eml() and .to_ceml().
  • AST Optimization: Automatically reduces redundant mathematical structures (e.g., simplifying exp(ln(x)) to x) through structural pattern matching.

Usage

Real Number DSL (eml!)

use emlex::prelude::*;

fn main() {
    let x: f64 = 2.0;
    let y: f64 = 3.0;
    
    // Returns (LazyEExpr, f64)
    let (ast, val) = eml!((eml x y));
    
    assert_eq!(val, x.exp() - y.ln());
    assert_eq!(ast.to_eml(), "(eml x y)");
    
    // AST Optimization
    let z: f64 = 5.0;
    let (opt_ast, _) = eml!((eml (eml 1.0 (eml (eml 1.0 z) 1.0)) 1.0));
    assert_eq!(opt_ast.optimize().to_eml(), "z");
}

Complex Number DSL (ceml!)

use emlex::prelude::*;

fn main() {
    let z1 = Complex::new(1.0, 2.0);
    
    // Returns (LazyCExpr, Complex<f64>)
    let (ast, val) = ceml!((add z1 (i)));
    
    assert_eq!(val, z1 + Complex::new(0.0, 1.0));
    assert_eq!(ast.to_ceml(), "(add z1 (i))");
}

License

This project is licensed under either of

at your option.

About

A zero-cost S-expression mathematical DSL engine for Rust. Provides compile-time evaluation, AST preservation, optimization, and reverse DSL reconstruction.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages