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
//! `rcalc` is a glorified calculator with a lexer, parser, and interpreter written in Rust. This
//! documentation covers the library form of `rcalc`; creating an application from the library is
//! trivial, as will [be shown](#examples) later on.
//!
//! `rcalc` parses mathematical expressions, observing accepted operand precedence and computing
//! the results of the expressions. Its operation is fairly simple:
//!
//! 1. The Lexer reads in tokens from the program, one at a time.
//! 2. The Parser attempts to identify the significance and type of each token, observing
//! mathematical orders of operations during this analysis.
//! 3. The Parser places each token in an Abstract Syntax Tree, in a position relative to the
//! relationships the current token has with adjacent tokens.
//! 4. The Interpreter traverses the AST node-by-node, building up the result of the program.
//!
//! Each component of `rcalc` has been split into individual components for purposes of
//! readibility, fast access, and easy refactoring. The Lexer, Parser, and Interpreter should be
//! fairly easy to understand and extend in other applications or libraries.
//!
//! # Examples
//!
//! A mathematical expression can quickly be evaluated in `rcalc`:
//!
//! ```
//! # use rcalc::Interpreter;
//! let expr = "2 + 3 * 5";
//! let mut program = Interpreter::from(expr);
//! let result = program.interpret().unwrap(); // => 17
//! # assert_eq!(result, 17.);
//! ```
//!
//! The Lexer and Parser can also be implemented indendependently. However, the only public APIs
//! avaliable are to generate the next token of the program, and to create an AST from the Parser.
//!
//! ```
//! # use rcalc::{ASTNode, Lexer, Parser, Token};
//! # let expr = "2 + 3 * 5";
//! let mut lexer = Lexer::from(expr);
//! let next_token: Token = lexer.next_token().unwrap();
//!
//! let mut parser = Parser::from(lexer);
//! let tree: ASTNode = parser.parse().unwrap();
//! ```
//!
//! An Interpereter can currently only be created from a String representing a program. Attempts
//! to create an Interpreter from a Parser or AST are currently impossible, but may be supported
//! later.
//!
//! ```compile_fail
//! # use rcalc::{Interpreter, Lexer, Parser};
//! # let expr = "2 + 3 * 5";
//! let lexer = Lexer::from(expr);
//! let parser = Parser::from(lexer);
//! let program = Interpreter::from(parser); // will fail!
//! ```

mod rcalc;

pub use rcalc::*;