likebike / fasteval Goto Github PK
View Code? Open in Web Editor NEWFast and safe evaluation of algebraic expressions
Home Page: https://crates.io/crates/fasteval/
License: MIT License
Fast and safe evaluation of algebraic expressions
Home Page: https://crates.io/crates/fasteval/
License: MIT License
It would be great if you could provide a binary target which is a REPL to quickly perform calculations in the command line.
I would work on this issue if you accpet it
From a brief look over the code (and judging from the explanations around slabs in the docs), fasteval should be easily usable on platforms without dynamic memory allocation. Some features around the "easy use" parts might be unavailable, but that wouldn't hurt too much.
A typical way this can be done in recent (2018) Rust versions is to convert what can be done to from std::
to core::
(eg. core::mem
), and cfg-gate everything that does need real standard library features (implementing std::error, file I/O) behind a new and default std
feature. Thus, regular users see no change, but embedded users will set default-features to false.
One use case where this would come in handy is embedded devices, which could then be configurable with custom expressions rather than only static parameters (think configuring the intensity of a floor light as ((t < 300) && 1) || max(0, (t - 305) / 5, (t - 310) / 20)
instead of configuring a runtime of 5 minutes and a fade-out time of 10 seconds with no hopes to customize the fading).
Please consider supporting no_std for this crate.
Hi, I am porting Debian package to riscv64 arch.
Here is basic buildd info of rust-fastval in Debian:
https://buildd.debian.org/status/package.php?p=rust-fasteval
Now the buildd log on riscv64:
https://buildd.debian.org/status/fetch.php?pkg=rust-fasteval&arch=riscv64&ver=0.2.4-1&stamp=1650289636&raw=0
And the log is same with my local build on riscv64 hardware:
c-unknown-linux-gnu/debug/deps/libfasteval-da6ed3a61e1082c9.rlib -C debuginfo=2 --cap-lints warn -C linker=riscv64-linux-gnu-gcc -C link-arg=-Wl,-z,relro --remap-path-prefix /<<PKGBUILDDIR>>=/usr/share/cargo/registry/fasteval-0.2.4`
Finished test [unoptimized + debuginfo] target(s) in 1m 54s
Running `/<<PKGBUILDDIR>>/target/riscv64gc-unknown-linux-gnu/debug/deps/fasteval-4b9cf3c38633e3ef`
running 3 tests
test parser::internal_tests::priv_tests ... ok
test parser::internal_tests::util ... ok
test parser::internal_tests::rem_no_panic ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running `/<<PKGBUILDDIR>>/target/riscv64gc-unknown-linux-gnu/debug/deps/compile-f8df2945b86f1b68`
running 6 tests
test basics ... ok
test eval_macro ... ok
test custom_func ... ok
test slab_overflow ... ok
test double_neg ... ok
test all_instrs ... FAILED
failures:
---- all_instrs stdout ----
thread 'all_instrs' panicked at 'assertion failed: `(left == right)`
left: `"CompileSlab{ instrs:{ 0:IUnsafeVar { name: \"x\", ptr: 0x?????????? }, 1:IUnsafeVar { name: \"y\", ptr: 0x?????????? } } }"`,
right: `"CompileSlab{ instrs:{ 0:IUnsafeVar { name: \"x\", ptr: 0x???????????? }, 1:IUnsafeVar { name: \"y\", ptr: 0x???????????? } } }"`', tests/compile.rs:131:5
stack backtrace:
0: rust_begin_unwind
at /usr/src/rustc-1.58.1/library/std/src/panicking.rs:498:5
1: core::panicking::panic_fmt
at /usr/src/rustc-1.58.1/library/core/src/panicking.rs:107:14
2: core::panicking::assert_failed_inner
3: core::panicking::assert_failed
at /usr/src/rustc-1.58.1/library/core/src/panicking.rs:145:5
4: compile::unsafe_comp_chk
at /usr/share/cargo/registry/fasteval-0.2.4/tests/compile.rs:131:5
5: compile::all_instrs
at /usr/share/cargo/registry/fasteval-0.2.4/tests/compile.rs:389:9
6: compile::all_instrs::{{closure}}
at /usr/share/cargo/registry/fasteval-0.2.4/tests/compile.rs:213:1
7: core::ops::function::FnOnce::call_once
at /usr/src/rustc-1.58.1/library/core/src/ops/function.rs:227:5
8: core::ops::function::FnOnce::call_once
at /usr/src/rustc-1.58.1/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
failures:
all_instrs
test result: FAILED. 5 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.12s
error: test failed, to rerun pass '--test compile'
dh_auto_test: error: /usr/share/cargo/bin/cargo test --all --features unsafe-vars returned exit code 101
make[1]: *** [debian/rules:6: override_dh_auto_test] Error 25
make[1]: Leaving directory '/<<PKGBUILDDIR>>'
So, I think the the test case : assert_eq!(replace_addrs(format!("{:?}",slab.cs)), expect_fmt) is not support on riscv64 now.
This is just I guess.
Could you tell me how to debug this issue in order to support rust-fasteval run on riscv64. and if you need me to run more test case, please feel free let me kown, thanks.
Hi, thanks for the great crate!
I want to return a Result
with my error type in the lookup
function in the EvalNamespace
object. For example, there can be recursion where a
is dependent on value a
, and I can tell this only when the lookup
function is called. And I want to show in an error message that problem exactly in the recursion of user-defined formulas.
I believe this can be done by adding an Error
associated type to EmptyNamespace
and return something like Result<f64, Either<Self::Error, fasteval::Error>>
from the lookup
function.
Right now, fasteval
only supports f64. I'd also like to support these other modes:
Any others?
First of all, congrats and thanks for the crate !
I'm currently using fasteval
in a computer graphics project, and in that world, f64
or double-precision numbers are very rarely used: not only is the precision often unnecessary but it makes GPU
s much slower (often by 2x) as GPUs are big SIMD/T machines and can pack 2 times more f32
instructions than f64
per cycle, and I suppose this is the same for SIMD in CPUs.
This could be an easier step towards full SIMD use within the crate, though I haven't implemented it as a PoC.
Currently I'm converting the f64
to f32
before sending it to the GPU but I think this inefficiency may be a nice optimization, and a good step towards the milestone of supporting arbitrary-precision numbers.
Hi,
thanks for the fast eval crate.
is there a way to use numbers and strings as variables? Something like this:
Evaluate: x > 1 && y == 'Y' ? where x will be a number and y a string.
For some use cases it may be useful to be able to serialize and deserialize compiled Instruction
s, along with Slab
s. Perhaps this could become an optional feature?
At the moment supported evaluation results is Result<f64,Error>
, will be enhanced with Advanced Number Types (Complex Numbers, Rational Numbers, Arbitrary Precision Numbers, Big Integers + Crypto), but is it even possible to have something like Result<Vec<T>,Error>
? I imagine to have custom functions that can perform map or iteration operations over some data not just reduction.
I'm trying to build the crate, and one of the tests fail:
---- aaa_test_b0 stdout ----
thread 'aaa_test_b0' panicked at 'assertion failed: `(left == right)`
left: `Ok(ExpressionI(0))`,
right: `Err(ParseF64("4.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"))`', tests/from_go.rs:65:5
The host system is Fedora 35 with rust-1.55.0-1.fc35.x86_64.
/cc @nabijaczleweli
Now:
2 * pi()
Desired:
2 * pi
Is there any reason for the first? Would it make sense/be easy to implement the second? The second is what I see and prefer with most other evaluators, and forcing the first is actually a big blocker for our customers (other than that fasteval looks great to me). The first form could still be available to maintain backwards compatibility.
Thank you.
It would be very helpful if you can specify numbers in other bases, e.g. hexadecimal (0xFF) or binary (0b1001), and convert them via functions like in Python. (hex(255) -> 0xFF, bin(2) -> 10)
Title says it all... I'd like to read in an arbitrary expression and find out what variables need binding (so I can look them up).
It might not be good to allow anybody who can eval expressions to print to console. I would like a way to do this in fasteval rather than checking for "print(" in the input or something.
It would be very nice if this crate can support these types along with their specific operations like bitwise operations (for int) or logic and/or (for bool), and equal/greater/less (for float + int โ bool). And bool and float combination in rust-style: if my_bool { 1.0 } else { 0.0 } + sin(x)
.
Hello!
I have two problems with expressions.
ez_eval()
returns an incorrect value.@lnicola @likebike Can you help me?
use fasteval::{EmptyNamespace, ez_eval};
let mut ns = EmptyNamespace;
// OK
let value = ez_eval("1 == 1", &mut ns).unwrap();
println!("1 == 1 -> fast_eval: {:?}", value);
assert_eq!(value, 1.0);
// 1.
// PROBLEM
let value = ez_eval("true == true", &mut ns).unwrap();
println!("true == true -> fast_eval: {:?}", value);
assert_eq!(value, 1.0);
// 2.
// PROBLEM, result = 3 ??
let bitand_text = format!("{} && {}", b_value, b_mask);
let value = ez_eval(bitand_text.as_str(), &mut ns).unwrap();
println!("bitand_text {} -> fast_eval: {:?}", bitand_text, value);
assert_eq!(value, 2.0);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.