diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 83 |
1 files changed, 3 insertions, 80 deletions
diff --git a/src/main.rs b/src/main.rs index 28af074..5846a87 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -14,6 +14,8 @@ mod parse; | |||
14 | use crate::parse::*; | 14 | use crate::parse::*; |
15 | mod error; | 15 | mod error; |
16 | use crate::error::{ CalcError, handler }; | 16 | use crate::error::{ CalcError, handler }; |
17 | mod format; | ||
18 | use crate::format::*; | ||
17 | 19 | ||
18 | // extern crates | 20 | // extern crates |
19 | use rustyline::error::ReadlineError; | 21 | use rustyline::error::ReadlineError; |
@@ -84,63 +86,6 @@ fn main() { | |||
84 | } | 86 | } |
85 | } | 87 | } |
86 | 88 | ||
87 | fn pprint(ans: f64) { | ||
88 | let ans_string = radix_fmt(ans, CONFIGURATION.base).unwrap(); | ||
89 | let ans_vector: Vec<&str> = ans_string.split(".").collect(); | ||
90 | match ans_vector.len() { | ||
91 | 1 => println!("{:>10}", thousand_sep(ans_vector[0])), | ||
92 | 2 => println!("{:>10}.{}", thousand_sep(ans_vector[0]),ans_vector[1]), | ||
93 | _ => () | ||
94 | } | ||
95 | } | ||
96 | |||
97 | fn radix_fmt(number: f64, obase: usize) -> Result<String, CalcError> { | ||
98 | if obase > 36 { | ||
99 | return Err(CalcError::Syntax("Unknown base".into())); | ||
100 | } | ||
101 | |||
102 | let table: Vec<char> = "0123456789abcdefghijklmnopqrstuvwxyz".chars().collect(); | ||
103 | |||
104 | // format integral part of float | ||
105 | let mut integral = number.trunc() as i64; | ||
106 | let mut obase_int = String::new(); | ||
107 | while integral >= obase as i64 { | ||
108 | obase_int.push(table[(integral % obase as i64) as usize]); | ||
109 | integral /= obase as i64; | ||
110 | } | ||
111 | obase_int.push(table[integral as usize]); | ||
112 | if number.is_sign_negative() { | ||
113 | obase_int.push('-'); | ||
114 | } | ||
115 | let obase_int = obase_int.chars().rev().collect::<String>(); | ||
116 | |||
117 | // format fractional part of float | ||
118 | let mut fract = number.abs().fract(); | ||
119 | let mut obase_fract = String::new(); | ||
120 | let mut i = 0; | ||
121 | loop { | ||
122 | fract *= obase as f64; | ||
123 | obase_fract.push(table[fract.trunc() as usize]); | ||
124 | i += 1; | ||
125 | if fract.fract() == 0. || i > 10 { | ||
126 | break; | ||
127 | } | ||
128 | fract = fract.fract(); | ||
129 | } | ||
130 | Ok(format!("{}.{}", obase_int, obase_fract)) | ||
131 | } | ||
132 | |||
133 | fn thousand_sep(inp: &str) -> String { | ||
134 | let mut result_string = String::new(); | ||
135 | for (i,c) in inp.to_string().chars().rev().enumerate() { | ||
136 | if i % 3 == 0 && i != 0 && c.to_string() != "-" { | ||
137 | result_string.push(','); | ||
138 | } | ||
139 | result_string.push(c) | ||
140 | } | ||
141 | result_string.chars().rev().collect::<String>() | ||
142 | } | ||
143 | |||
144 | fn parse_arguments() -> Configuration { | 89 | fn parse_arguments() -> Configuration { |
145 | let config = App::new(env!("CARGO_PKG_NAME")) | 90 | let config = App::new(env!("CARGO_PKG_NAME")) |
146 | .version(env!("CARGO_PKG_VERSION")) | 91 | .version(env!("CARGO_PKG_VERSION")) |
@@ -185,28 +130,6 @@ fn parse_arguments() -> Configuration { | |||
185 | } | 130 | } |
186 | } | 131 | } |
187 | 132 | ||
188 | fn autobalance_parens(input: &str) -> Result<String, CalcError> { | ||
189 | let mut balanced = String::from(input); | ||
190 | let mut left_parens = 0; | ||
191 | let mut right_parens = 0; | ||
192 | for letter in input.chars() { | ||
193 | if letter == '(' { | ||
194 | left_parens += 1; | ||
195 | } else if letter == ')' { | ||
196 | right_parens += 1; | ||
197 | } | ||
198 | } | ||
199 | |||
200 | if left_parens > right_parens { | ||
201 | let extras = ")".repeat(left_parens - right_parens); | ||
202 | balanced.push_str(&extras[..]); | ||
203 | Ok(balanced) | ||
204 | } else if left_parens < right_parens { | ||
205 | return Err(CalcError::Syntax("Mismatched parentheses!".into())) | ||
206 | } else { | ||
207 | Ok(balanced) | ||
208 | } | ||
209 | } | ||
210 | 133 | ||
211 | fn eval_math_expression(input: &str) -> Result<f64, CalcError> { | 134 | fn eval_math_expression(input: &str) -> Result<f64, CalcError> { |
212 | let input = input.trim(); | 135 | let input = input.trim(); |
@@ -214,7 +137,7 @@ fn eval_math_expression(input: &str) -> Result<f64, CalcError> { | |||
214 | if input.len() == 0 { | 137 | if input.len() == 0 { |
215 | return Ok(0.) | 138 | return Ok(0.) |
216 | } | 139 | } |
217 | let input = autobalance_parens(&input[..])?; | 140 | let input = format::autobalance_parens(&input[..])?; |
218 | let lexed = lexer(&input[..])?; | 141 | let lexed = lexer(&input[..])?; |
219 | let postfixed = to_postfix(lexed)?; | 142 | let postfixed = to_postfix(lexed)?; |
220 | let evaled = eval_postfix(postfixed)?; | 143 | let evaled = eval_postfix(postfixed)?; |