aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs70
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
20use std::f64; 21use std::f64;
21use std::env;
22 22
23// modules
23mod lex; 24mod lex;
24use crate::lex::*; 25use crate::lex::*;
25
26mod parse; 26mod parse;
27use crate::parse::*; 27use crate::parse::*;
28
29mod error; 28mod error;
30use crate::error::{ CalcError, handler }; 29use crate::error::{ CalcError, handler };
31 30
31// extern crates
32use rustyline::error::ReadlineError; 32use rustyline::error::ReadlineError;
33use rustyline::Editor; 33use rustyline::Editor;
34use rustyline::config::{ Builder, ColorMode, EditMode }; 34use rustyline::config::{ Builder, ColorMode, EditMode };
35use clap::{Arg, App};
36use lazy_static::lazy_static;
35 37
38struct Configuration {
39 radian_mode: bool,
40 fix: usize,
41 input: String
42}
36 43
37fn main() { 44lazy_static! {
45 static ref CONFIGURATION: Configuration = parse_arguments();
46}
38 47
39 let args: Vec<String> = env::args().collect(); 48fn 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
99fn 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
94fn autobalance_parens(input: &str) -> Result<String, CalcError> { 133fn 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
117fn eval_math_expression(input: &str) -> Result<f64, CalcError> { 156fn 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)]
130mod tests { 170mod tests {
131 use super::*; 171 use super::*;