diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lex/mod.rs | 7 | ||||
-rw-r--r-- | src/readline/mod.rs | 33 |
2 files changed, 34 insertions, 6 deletions
diff --git a/src/lex/mod.rs b/src/lex/mod.rs index 48e07be..fe9c421 100644 --- a/src/lex/mod.rs +++ b/src/lex/mod.rs | |||
@@ -123,7 +123,7 @@ fn factorial(n: f64) -> f64 { | |||
123 | n.signum() * (1..=n.abs() as u64).fold(1, |p, n| p * n) as f64 | 123 | n.signum() * (1..=n.abs() as u64).fold(1, |p, n| p * n) as f64 |
124 | } | 124 | } |
125 | 125 | ||
126 | pub fn lexer(input: &str, prev_ans: f64) -> Result<Vec<Token>, CalcError> { | 126 | pub fn lexer(input: &str, prev_ans: Option<f64>) -> Result<Vec<Token>, CalcError> { |
127 | let mut num_vec: String = String::new(); | 127 | let mut num_vec: String = String::new(); |
128 | let mut char_vec: String = String::new(); | 128 | let mut char_vec: String = String::new(); |
129 | let mut result: Vec<Token> = vec![]; | 129 | let mut result: Vec<Token> = vec![]; |
@@ -149,6 +149,9 @@ pub fn lexer(input: &str, prev_ans: f64) -> Result<Vec<Token>, CalcError> { | |||
149 | last_char_is_op = false; | 149 | last_char_is_op = false; |
150 | } | 150 | } |
151 | '_' => { | 151 | '_' => { |
152 | if prev_ans.is_none() { | ||
153 | return Err(CalcError::Syntax("No previous answer!".into())); | ||
154 | } | ||
152 | if !char_vec.is_empty() { | 155 | if !char_vec.is_empty() { |
153 | if FUNCTIONS.get(&char_vec[..]).is_some() { | 156 | if FUNCTIONS.get(&char_vec[..]).is_some() { |
154 | return Err(CalcError::Syntax(format!( | 157 | return Err(CalcError::Syntax(format!( |
@@ -169,7 +172,7 @@ pub fn lexer(input: &str, prev_ans: f64) -> Result<Vec<Token>, CalcError> { | |||
169 | num_vec.clear(); | 172 | num_vec.clear(); |
170 | } | 173 | } |
171 | last_char_is_op = false; | 174 | last_char_is_op = false; |
172 | result.push(Token::Num(prev_ans)); | 175 | result.push(Token::Num(prev_ans.unwrap())); |
173 | } | 176 | } |
174 | 'a'...'z' | 'A'...'Z' => { | 177 | 'a'...'z' | 'A'...'Z' => { |
175 | let parse_num = num_vec.parse::<f64>().ok(); | 178 | let parse_num = num_vec.parse::<f64>().ok(); |
diff --git a/src/readline/mod.rs b/src/readline/mod.rs index 41cd742..8eedbfa 100644 --- a/src/readline/mod.rs +++ b/src/readline/mod.rs | |||
@@ -1,4 +1,5 @@ | |||
1 | use std::borrow::Cow::{self, Owned}; | 1 | use std::borrow::Cow::{self, Owned}; |
2 | use std::path::PathBuf; | ||
2 | 3 | ||
3 | use rustyline::completion::{Completer, FilenameCompleter, Pair}; | 4 | use rustyline::completion::{Completer, FilenameCompleter, Pair}; |
4 | use rustyline::config::{Builder, ColorMode, CompletionType, EditMode}; | 5 | use rustyline::config::{Builder, ColorMode, CompletionType, EditMode}; |
@@ -7,6 +8,8 @@ use rustyline::highlight::Highlighter; | |||
7 | use rustyline::hint::{Hinter, HistoryHinter}; | 8 | use rustyline::hint::{Hinter, HistoryHinter}; |
8 | use rustyline::{Context, Editor, Helper}; | 9 | use rustyline::{Context, Editor, Helper}; |
9 | 10 | ||
11 | use directories::ProjectDirs; | ||
12 | |||
10 | use regex::Regex; | 13 | use regex::Regex; |
11 | 14 | ||
12 | use crate::eval_math_expression; | 15 | use crate::eval_math_expression; |
@@ -17,13 +20,35 @@ pub struct RLHelper { | |||
17 | hinter: HistoryHinter, | 20 | hinter: HistoryHinter, |
18 | } | 21 | } |
19 | 22 | ||
20 | struct LineHighlighter {} | 23 | struct LineHighlighter { } |
21 | impl Highlighter for LineHighlighter { | 24 | impl Highlighter for LineHighlighter { |
22 | fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> { | 25 | fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> { |
23 | Owned(format!("\x1b[90m{}\x1b[0m", hint)) | 26 | Owned(format!("\x1b[90m{}\x1b[0m", hint)) |
24 | } | 27 | } |
25 | fn highlight<'l>(&self, line: &'l str, _: usize) -> Cow<'l, str> { | 28 | fn highlight<'l>(&self, line: &'l str, _: usize) -> Cow<'l, str> { |
26 | let op = eval_math_expression(line, 0f64); | 29 | use std::io::{ BufReader, BufRead }; |
30 | use std::fs::OpenOptions; | ||
31 | |||
32 | let eva_dirs = ProjectDirs::from("com", "NerdyPepper", "eva").unwrap(); | ||
33 | let eva_data_dir = eva_dirs.data_dir(); | ||
34 | let mut previous_ans_path= PathBuf::from(eva_data_dir); | ||
35 | previous_ans_path.push("previous_ans.txt"); | ||
36 | |||
37 | let file = OpenOptions::new() | ||
38 | .create(true) | ||
39 | .read(true) | ||
40 | .append(true) | ||
41 | .open(&previous_ans_path) | ||
42 | .unwrap(); | ||
43 | |||
44 | let rdr = BufReader::new(file); | ||
45 | let lines = rdr.lines().map(|l| l.unwrap()); | ||
46 | let prev_ans = lines | ||
47 | .last() | ||
48 | .unwrap() | ||
49 | .parse::<f64>() | ||
50 | .ok(); | ||
51 | let op = eval_math_expression(line, prev_ans); | ||
27 | match op { | 52 | match op { |
28 | Ok(_) => { | 53 | Ok(_) => { |
29 | let constants = ["e", "pi"]; | 54 | let constants = ["e", "pi"]; |
@@ -33,7 +58,7 @@ impl Highlighter for LineHighlighter { | |||
33 | "asec", "acot", | 58 | "asec", "acot", |
34 | ]; | 59 | ]; |
35 | let ops = Regex::new(r"(?P<o>[\+-/\*%\^!])").unwrap(); | 60 | let ops = Regex::new(r"(?P<o>[\+-/\*%\^!])").unwrap(); |
36 | let mut coloured: String = ops.replace_all(line, "\x1b[33m$o\x1b[0m").into(); | 61 | let mut coloured: String = ops.replace_all(line, "\x1b[35m$o\x1b[0m").into(); |
37 | 62 | ||
38 | for c in &constants { | 63 | for c in &constants { |
39 | coloured = coloured.replace(c, &format!("\x1b[33m{}\x1b[0m", c)); | 64 | coloured = coloured.replace(c, &format!("\x1b[33m{}\x1b[0m", c)); |
@@ -89,7 +114,7 @@ pub fn create_readline() -> Editor<RLHelper> { | |||
89 | let mut rl = Editor::with_config(config); | 114 | let mut rl = Editor::with_config(config); |
90 | let h = RLHelper { | 115 | let h = RLHelper { |
91 | completer: FilenameCompleter::new(), | 116 | completer: FilenameCompleter::new(), |
92 | highlighter: LineHighlighter {}, | 117 | highlighter: LineHighlighter { }, |
93 | hinter: HistoryHinter {}, | 118 | hinter: HistoryHinter {}, |
94 | }; | 119 | }; |
95 | rl.set_helper(Some(h)); | 120 | rl.set_helper(Some(h)); |