Skip to content

finnh-dev/anita

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

anita

Anita is a JIT compiler that allows runtime compilation of math expressions.

Usage

Anita compiles a given expression and returns a structure with a function that follows a given signature. This can be achieved by using the compile_expression! macro.

let expression: String = "x+1".to_owned(); // This can be anything implementing AsRef<str>
let function: CompiledFunction<fn(f32) -> f32> = compile_expression!(expression, (x) -> f32).unwrap();
assert_eq!(function(4_f32), 5_f32);

Supported features

This is the current state of features in anita

Types

Anita can support any type implementing the AnitaType trait but only can support one type at a time which is speccified by the return type in the compile_expression! macro.

Inbuilt type support

Type Status
f32 supported
f64 untested

Operators

Operator Description
^ Exponentiation
* Product
/ Division
% Modulo
+ Sum
- Difference
< Lower than
> Greater than
<= Lower than or equal
>= Greater than or equal
== Equal
!= Not equal
&& Logical and
|| Logical or
= Assignment
; Expression Chaining
- (unary) Negation
! Logical not

Functions

Anita ships with a set of default functions for the f32 type. If these are not used the no-default-functions feature can be enabled to reduce compiler overhead.

Identifier Argument Amount Description
min 2 see core::f32::min
max 2 see core::f32::max
floor 1 see std::f32::floor
round 1 see std::f32::round
ceil 1 see std::f32::ceil
if 3 If the first argument is normal and not equal to 0.0, returns the second argument, otherwise, returns the third
is_nan 1 see core::f32::is_nan.
The return value is mapped to 1.0 if true and 0.0 if false
is_finite 1 see core::f32::is_finite.
The return value is mapped to 1.0 if true and 0.0 if false
is_infinite 1 see core::f32::is_infinite.
The return value is mapped to 1.0 if true and 0.0 if false
is_normal 1 see core::f32::is_normal.
The return value is mapped to 1.0 if true and 0.0 if false
mod 2 see core::f32::rem
ln 1 see std::f32::ln
log 2 see std::f32::log
log2 1 see std::f32::log2
log10 1 see std::f32::log10
exp 1 see std::f32::exp
exp2 1 see std::f32::exp2
pow 2 see std::f32::powf
cos 1 see std::f32::cos
acos 1 see std::f32::acos
cosh 1 see std::f32::cosh
acosh 1 see std::f32::acosh
sin 1 see std::f32::sin
asin 1 see std::f32::asin
sinh 1 see std::f32::sinh
asinh 1 see std::f32::asinh
tan 1 see std::f32::tan
atan 1 see std::f32::atan
atan2 2 see std::f32::atan2
tanh 1 see std::f32::tanh
atanh 1 see std::f32::atanh
sqrt 1 see std::f32::sqrt
cbrt 1 see std::f32::cbrt
hypot 2 see std::f32::hypot
abs 1 see core::f32::abs

Custom Functions

If different functions are needed, they can be introduced using the FunctionManager trait. To construct a function Manager it is advised to use the #[function_manager] macro attribute. By default using the custom functions will have the same name as they are declared with. This can be overwritten using the #[name = "other_name"] attribute.

struct CustomFunctions {}

#[function_manager]
impl CustomFunctions {
    fn custom(x: f32) -> f32 {
        x + 1.0
    }

    #[name = "not_zero"]
    fn custom_if_not_zero(x: f32) -> f32 {
        (x != 0.0) as u8 as f32
    }
}

#[cfg(tests)]
mod test {
    #[test]
    fn it_works() {
        let function: CompiledFunction<fn(f32) -> f32> = compile_expression!("not_zero(custom(x))", (x) -> f32, CustomFunctions).unwrap();
        assert_eq(function(-1.0), 0.0);
        assert_eq(function(42.0), 1.0);
    }
}

SIMD

TODO!

Frontend

Anita uses a custom language frontend inspired by the evalexpr crate.

Naming

The name anita is inspired by the first all-electronic desktop calculator ANITA

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages