-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlib.rs
213 lines (206 loc) · 8.97 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
//!
//! # num_parser: a math interpreter and evaluator
//!
//! [](https://crates.io/crates/num_parser)
//! [](https://github.com/BearToCode/num_parser/blob/master/LICENSE)
//! [](https://docs.rs/num_parser/1.0.2/num_parser/)
//!
//! **num_parser** allows you to easily **parse** strings into math expressions
//! and **evaluate** them.
//!
//! ## Features
//! * Binary and unary operators
//! * Supports **multiple value types**:
//! * Bool,
//! * Int,
//! * Float,
//! * [Complex](num::complex::Complex64),
//! * Vector
//! * Built-in functions
//! * Built-in constants
//! * **User-defined functions**: `f(x,y) = xsin(y)+ysin(x)`
//! * **User-defined var**: `a = pi/2` or `b = a+2`
//! * Define you own functions with **macros**.
//! * Understands **ambiguous syntax**, like: `g(x) = pisinx`
//! * **Recursion**: `f(x) = branch(x<=2, 1, f(x-1)+f(x-2))`
//! * Serde support
//! * No panicking
//!
//! Much more will be implemented in future releases!
//!
//! ## Use Guide
//!
//! Evaluating **simple static expressions**:
//! ```
//! use num_parser::*;
//!
//! assert_eq!(eval("2+2").unwrap(), Value::from(4));
//! assert_eq!(eval("sin(pi)").unwrap(), Value::from(0));
//! assert_eq!(eval("re(10+3i)").unwrap(), Value::from(10));
//! ```
//!
//! Using **contexts**:
//!
//! ```
//! use num_parser::*;
//!
//! let mut context = Context::default();
//! // Declaring a function
//! let res = eval_with_mutable_context(
//! "f(x) = branch(x<=2, 1, f(x-1) + f(x-2))",
//! &mut context
//! ).unwrap();
//!
//! // Result is None
//! assert_eq!(res, None);
//! // Calling the function. We could just use eval_with_static_context at this point
//! let res = eval_with_mutable_context("f(10)", &mut context).unwrap();
//!
//! assert_eq!(res, Some(Value::from(55)));
//! ```
//!
//! ## Values
//! **Values** are contained inside the [Value enum](Value), which provides useful functions
//! to access the contained data:
//!
//! ```rust
//! use num_parser::Value;
//!
//! let value = Value::Float(1.0);
//!
//! assert_eq!(value.as_bool().unwrap(), true);
//! assert_eq!(value.as_int().unwrap(), 1);
//! assert_eq!(value.as_float().unwrap(), 1.0);
//! assert_eq!(value.as_complex().unwrap(), num::complex::Complex::new(1.0, 0.0));
//! assert_eq!(value.as_vector(), vec![Value::Float(1.0)]);
//!
//! // Assign type implicitly:
//! let implicit = Value::from(1.0);
//!
//! assert_eq!(value, implicit);
//! ```
//!
//! Note that, even thought the initial value was a float, it has been **cast** into ints and bools. This
//! was possible since the value had no decimal part and it was a one. If these conditions were not
//! met, the cast would have failed.
//!
//! ## Operators
//! **Binary** operators:
//!
//! | Operator | Description | Precedence |
//! |----------|-------------|------------|
//! | ^ | Exponentiation | 90 |
//! | / | Division | 70 |
//! | * | Multiplication | 70 |
//! | % | Modulo | 70 |
//! | + | Sum | 60 |
//! | - | Subtraction | 60 |
//! | < | Less than | 50 |
//! | > | Greater than | 50 |
//! | <= | Less or equal to | 50 |
//! | >= | Greater or equal to | 50 |
//! | == | Equal to | 40 |
//! | != | Not equal to | 40 |
//! | && | Logical AND | 30 |
//! | || | Logical OR | 20 |
//! | , | Aggregation. Creates vectors | 10 |
//! | = | Assignment. Used for functions and vars declarations | 0 |
//!
//! **Unary** operators:
//!
//! | Operator | Description | Precedence |
//! |----------|-------------|------------|
//! | ! | Logical NOT | 80 |
//! | - | Negation | 60 |
//!
//! ## Functions
//!
//! | Function | Parameters Amount | Description |
//! |----------|----------------------------|---------------------------------------------------------------|
//! | `min` | >=1 | Returns the minimum value. |
//! | `max` | >=1 | Returns the maximum value. |
//! | `floor` | 1 | Returns the greatest lower integer. |
//! | `ceil` | 1 | Returns the lowest greater integer. |
//! | `round` | 1 | Returns the rounded integer. |
//! | `ln` | 1 | Returns the natural log of the number. |
//! | `log` | 2 (base, arg) | Returns the logarithm of the number with the specified base. |
//! | `exp` | 1 | Returns e^(arg). |
//! | `abs` | 1 | Returns the absolute value of a number. |
//! | `sqrt` | 1 | Returns the square root of a number. |
//! | `rand` | 2 (min, max) | Returns a random float between the two number specified. |
//! | `branch` | 3 (condition, true, false) | Returns the second argument if the condition is true, the third if it is false. |
//! | `sin` | 1 | Returns the sine of the angle. |
//! | `cos` | 1 | Returns the cosine of the angle. |
//! | `tan` | 1 | Returns the tangent of the angle. |
//! | `asin` | 1 | Returns the arcsine of the angle. |
//! | `acos` | 1 | Returns the arccosine of the angle. |
//! | `atan` | 1 | Returns the arctangent of the angle. |
//! | `sinh` | 1 | Returns the hyperbolic sine of the angle. |
//! | `cosh` | 1 | Returns the hyperbolic cosine of the angle. |
//! | `tanh` | 1 | Returns the hyperbolic tangent of the angle. |
//! | `asinh` | 1 | Returns the hyperbolic arcsine of the angle. |
//! | `acosh` | 1 | Returns the hyperbolic arccosine of the angle. |
//! | `atanh` | 1 | Returns the hyperbolic arctangent of the angle. |
//! | `re` | 1 | Returns the natural part of the number. |
//! | `im` | 1 | Returns the imaginary part of the number. |
//! | `polar` | 1 | Returns the polar form (r, theta) of the complex number. |
//! | `arg` | 1 | Returns the principal arg of the number. |
//! | `norm` | 1 | Returns the length of the vector (re, im). |
//!
//! ## Context
//!
//! [Contexts](Context) allows you keep track of **user-defined functions** and **variables**, as well
//! as settings. They can be created as follows:
//!
//! ```rust
//! use num_parser::*;
//!
//! // Generate the default context
//! let mut default = Context::default();
//!
//! // Generate a custom context
//! let mut custom = Context::new(
//! settings::Rounding::NoRounding,
//! settings::AngleUnit::Degree,
//! settings::DepthLimit::NoLimit
//! );
//! ```
//!
//! ### Serde
//!
//! You can use the optional feature `serde_support` to let all the public structs
//! derive [`Serialize`](https://docs.rs/serde/1.0.71/serde/trait.Serializer.html) and
//! [`Deserialize`](https://docs.rs/serde/1.0.71/serde/trait.Serializer.html).
//!
//! ```text
//! [dependencies]
//! num = { version = "<version>", features = [ "serde_support" ] }
//! ```
//!
//! ## License and contribution
//! num_parser is licensed under a **MIT License**.
//!
//! Feel free to open issues and pull requests for any problems or ideas you come up with.
//!
#[cfg(feature = "serde_support")]
extern crate serde;
extern crate num;
pub mod function;
mod api;
mod context;
mod interpreter;
mod objects;
mod operators;
mod out;
mod token;
mod tree;
mod value;
#[cfg(test)]
mod tests;
pub use crate::{
api::*,
context::{settings, Context},
objects::Expression,
out::*,
value::{valuetype::*, Value},
};