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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
//! `xxcalc` is a crate which provides an embeddable floating-point
//! polynomial calculator and linear solver.
//!
//! You can use `xxcalc` to embed mathematical expression evaluator
//! in your own programs. By default the calculator provides addition `+`,
//! subtraction `-`, multiplication `*`, division `/` and exponentation `^`
//! operators. Some functions such as `log` and `log10` are implemented,
//! as well as `pi` and `e` constants. This is a polynomial calculator, so
//! you can perform arithmetic operations on polynomials (using `x` symbol
//! by default) - a simple floating-point number is just a special case of
//! a polynomial (the constant polynomial, polynomial of degree zero).
//!
//! Furthermore the crate is well structurized and documented - you can use
//! pieces it provides to create your own custom solutions (you can use or change
//! a tokenizer, parser and evaluator however you want). Look at implementations
//! of PolynomialParser, LinearSolverParser, PolynomialEvaluator or
//! LinearSolverEvaluator to see how to extend default implementations.
//!
//! With the crate a `xxcalc` binary is provided which can be used as a
//! standalone CLI calculator (which can be replacement for `bc` command).
//! If the crate is installed with a feature "interactive" enabled, a history
//! of commands is enabled.
//!
//! Whole library is meticulously tested, use `cargo test` to run unit tests
//! (including doc examples), `cargo bench` will run simple benchmarks, while
//! `cargo bench -- --ignored` will run more computation-heavy benchmarks.
//!
//! # Examples
//!
//! You can easily take a LinearSolver or PolynomialCalculator to embed
//! mathematical engine inside your programs.
//!
//! ```
//! use xxcalc::linear_solver::LinearSolver;
//! use xxcalc::calculator::Calculator;
//! use xxcalc::polynomial::Polynomial;
//!
//! assert_eq!(LinearSolver.process("2x + 1 = 2(1-x)"), Ok(Polynomial::constant(0.25)));
//! assert_eq!(LinearSolver.process("0.1*-2+4"), Ok(Polynomial::constant(3.8)));
//! ```
//!
//! Please see documentation for [PolynomialCalculator] for more examples.
//!
//! [PolynomialCalculator]: polynomial_calculator/index.html
use Index;
use BTreeMap;
/// Token is a basic unit returned after tokenization using
/// a StringProcessor.
///
/// Token can be than rearranged with a TokensProcessor and
/// interpreted (evaluated) to a Polynomial using a TokensReducer.
///
/// Tokens are used to conveniently store expressions in partially
/// parsed and computer readable form.
/// List of tokens with their position.
///
/// Tokens are represented as space-efficient continous vector
/// of tuples consisting of position in a input string and a
/// corresponding Token.
pub type TokenList = ;
/// Vector of unique identifiers.
///
/// Token::Identifier stores just a location in this vector,
/// this keeps size of individual tokens minimal.
pub type Identifiers = ;
/// Tokens is a compound storage for list of tokens with
/// their identifiers.
///
/// A TokenList is invalid without Identifiers, therefore
/// this struct keeps them always together. Furthermore
/// a lookup table is kept, so creating new identifier is
/// a relatively quick task.
/// Transforms text expression into list of tokens.
///
/// A StringProcessor can be implemented for a tokenizer (lexer)
/// which converts some text expression into a list of tokens.
/// Transforms list of tokens into another list of tokens.
///
/// A TokensProcessor can be implemented for a parser which
/// takes a list of tokens in some order and transform them
/// into list of tokens in the other form (like infix to
/// RPN notation). Furthermore a TokensProcessor can be used
/// to extend tokenizer with knowledge of new tokens, as it
/// can transform unknown tokens to known ones.
/// Evaluates list of tokens into a single Polynomial value.
///
/// A TokensReducer takes a list of tokens in some expected
/// arrangement and evaluates them into a single Polynomial
/// value. It can be used for implementation of various
/// computational languages (such as the scientific calcualtor).
/// Returns position and token with given index.
///
/// One should note that token position is indepentent
/// from its index.
///
/// # Panics
///
/// It will panic when the index is greater than number of
/// tokens stored in the list.
///
/// # Examples
///
/// ```
/// # use xxcalc::{Tokens, Token};
/// let mut tokens = Tokens::new(None);
///
/// tokens.push(0, Token::Number(1.0));
/// tokens.push(8, Token::Number(2.0));
///
/// assert_eq!(tokens[0], (0, Token::Number(1.0)));
/// assert_eq!(tokens[1], (8, Token::Number(2.0)));
/// ```
/// An error that occurs during token processing,
/// usually by a parser.
/// An error that occurs during token reduction,
/// usually by an evaluator.