diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 70 |
1 files changed, 55 insertions, 15 deletions
diff --git a/src/main.rs b/src/main.rs index a979e20..f137417 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -17,34 +17,39 @@ | |||
17 | 17 | ||
18 | */ | 18 | */ |
19 | 19 | ||
20 | // std | ||
20 | use std::f64; | 21 | use std::f64; |
21 | use std::env; | ||
22 | 22 | ||
23 | // modules | ||
23 | mod lex; | 24 | mod lex; |
24 | use crate::lex::*; | 25 | use crate::lex::*; |
25 | |||
26 | mod parse; | 26 | mod parse; |
27 | use crate::parse::*; | 27 | use crate::parse::*; |
28 | |||
29 | mod error; | 28 | mod error; |
30 | use crate::error::{ CalcError, handler }; | 29 | use crate::error::{ CalcError, handler }; |
31 | 30 | ||
31 | // extern crates | ||
32 | use rustyline::error::ReadlineError; | 32 | use rustyline::error::ReadlineError; |
33 | use rustyline::Editor; | 33 | use rustyline::Editor; |
34 | use rustyline::config::{ Builder, ColorMode, EditMode }; | 34 | use rustyline::config::{ Builder, ColorMode, EditMode }; |
35 | use clap::{Arg, App}; | ||
36 | use lazy_static::lazy_static; | ||
35 | 37 | ||
38 | struct Configuration { | ||
39 | radian_mode: bool, | ||
40 | fix: usize, | ||
41 | input: String | ||
42 | } | ||
36 | 43 | ||
37 | fn main() { | 44 | lazy_static! { |
45 | static ref CONFIGURATION: Configuration = parse_arguments(); | ||
46 | } | ||
38 | 47 | ||
39 | let args: Vec<String> = env::args().collect(); | 48 | fn main() { |
40 | if args.len() > 1 { | 49 | if CONFIGURATION.input.len() > 0 { |
41 | let mut expr = String::new(); | 50 | let evaled = eval_math_expression(&CONFIGURATION.input[..]); |
42 | for arg in args[1..].iter() { | ||
43 | expr.push_str(&arg[..]); | ||
44 | } | ||
45 | let evaled = eval_math_expression(&expr[..]); | ||
46 | match evaled { | 51 | match evaled { |
47 | Ok(ans) => println!("{}", ans), | 52 | Ok(ans) => println!("{:.*}", CONFIGURATION.fix, ans), |
48 | Err(e) => { | 53 | Err(e) => { |
49 | eprintln!("{}", handler(e)); | 54 | eprintln!("{}", handler(e)); |
50 | std::process::exit(1); | 55 | std::process::exit(1); |
@@ -69,7 +74,7 @@ fn main() { | |||
69 | rl.add_history_entry(line.as_ref()); | 74 | rl.add_history_entry(line.as_ref()); |
70 | let evaled = eval_math_expression(&line[..]); | 75 | let evaled = eval_math_expression(&line[..]); |
71 | match evaled { | 76 | match evaled { |
72 | Ok(ans) => println!("{}", ans), | 77 | Ok(ans) => println!("{:.*}", CONFIGURATION.fix, ans), |
73 | Err(e) => println!("{}", handler(e)), | 78 | Err(e) => println!("{}", handler(e)), |
74 | }; | 79 | }; |
75 | }, | 80 | }, |
@@ -91,6 +96,40 @@ fn main() { | |||
91 | } | 96 | } |
92 | } | 97 | } |
93 | 98 | ||
99 | fn parse_arguments() -> Configuration { | ||
100 | let config = App::new(env!("CARGO_PKG_NAME")) | ||
101 | .version(env!("CARGO_PKG_VERSION")) | ||
102 | .author(env!("CARGO_PKG_AUTHORS")) | ||
103 | .about(env!("CARGO_PKG_DESCRIPTION")) | ||
104 | .arg(Arg::with_name("fix") | ||
105 | .short("f") | ||
106 | .long("fix") | ||
107 | .takes_value(true) | ||
108 | .value_name("FIX") | ||
109 | .help("set number of decimal places in the output")) | ||
110 | .arg(Arg::with_name("INPUT") | ||
111 | .help("optional expression string to run eva in command mode") | ||
112 | .index(1)) | ||
113 | .arg(Arg::with_name("radian") | ||
114 | .short("r") | ||
115 | .long("radian") | ||
116 | .help("set eva to radian mode")) | ||
117 | .get_matches(); | ||
118 | |||
119 | let mut input = String::new(); | ||
120 | if let Some(i) = config.value_of("input") { | ||
121 | input.push_str(i); | ||
122 | }; | ||
123 | Configuration { | ||
124 | radian_mode: config.is_present("radian"), | ||
125 | fix: config.value_of("fix") | ||
126 | .unwrap_or("10") | ||
127 | .parse() | ||
128 | .unwrap(), | ||
129 | input, | ||
130 | } | ||
131 | } | ||
132 | |||
94 | fn autobalance_parens(input: &str) -> Result<String, CalcError> { | 133 | fn autobalance_parens(input: &str) -> Result<String, CalcError> { |
95 | let mut balanced = String::from(input); | 134 | let mut balanced = String::from(input); |
96 | let mut left_parens = 0; | 135 | let mut left_parens = 0; |
@@ -115,6 +154,8 @@ fn autobalance_parens(input: &str) -> Result<String, CalcError> { | |||
115 | } | 154 | } |
116 | 155 | ||
117 | fn eval_math_expression(input: &str) -> Result<f64, CalcError> { | 156 | fn eval_math_expression(input: &str) -> Result<f64, CalcError> { |
157 | let input = input.trim(); | ||
158 | let input = input.replace(" ", ""); | ||
118 | if input.len() == 0 { | 159 | if input.len() == 0 { |
119 | return Ok(0.) | 160 | return Ok(0.) |
120 | } | 161 | } |
@@ -122,10 +163,9 @@ fn eval_math_expression(input: &str) -> Result<f64, CalcError> { | |||
122 | let lexed = lexer(&input[..])?; | 163 | let lexed = lexer(&input[..])?; |
123 | let postfixed = to_postfix(lexed)?; | 164 | let postfixed = to_postfix(lexed)?; |
124 | let evaled = eval_postfix(postfixed)?; | 165 | let evaled = eval_postfix(postfixed)?; |
125 | Ok(format!("{:.*}", 5, evaled).parse::<f64>().unwrap()) | 166 | Ok(evaled) |
126 | } | 167 | } |
127 | 168 | ||
128 | |||
129 | #[cfg(test)] | 169 | #[cfg(test)] |
130 | mod tests { | 170 | mod tests { |
131 | use super::*; | 171 | use super::*; |