aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNerdyPepper <[email protected]>2019-08-06 16:29:25 +0100
committerNerdyPepper <[email protected]>2019-08-06 16:29:25 +0100
commitac352e26b6b0ff9b90004208abf4644f0b2c2f4e (patch)
tree3e20b6387ca957752ae5db6207681123ef6a1c14
parentae36284d60b828869ede5a77343ccb307046b69a (diff)
improve highlight for `_`, store program state
-rw-r--r--src/lex/mod.rs7
-rw-r--r--src/readline/mod.rs33
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
126pub fn lexer(input: &str, prev_ans: f64) -> Result<Vec<Token>, CalcError> { 126pub 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 @@
1use std::borrow::Cow::{self, Owned}; 1use std::borrow::Cow::{self, Owned};
2use std::path::PathBuf;
2 3
3use rustyline::completion::{Completer, FilenameCompleter, Pair}; 4use rustyline::completion::{Completer, FilenameCompleter, Pair};
4use rustyline::config::{Builder, ColorMode, CompletionType, EditMode}; 5use rustyline::config::{Builder, ColorMode, CompletionType, EditMode};
@@ -7,6 +8,8 @@ use rustyline::highlight::Highlighter;
7use rustyline::hint::{Hinter, HistoryHinter}; 8use rustyline::hint::{Hinter, HistoryHinter};
8use rustyline::{Context, Editor, Helper}; 9use rustyline::{Context, Editor, Helper};
9 10
11use directories::ProjectDirs;
12
10use regex::Regex; 13use regex::Regex;
11 14
12use crate::eval_math_expression; 15use crate::eval_math_expression;
@@ -17,13 +20,35 @@ pub struct RLHelper {
17 hinter: HistoryHinter, 20 hinter: HistoryHinter,
18} 21}
19 22
20struct LineHighlighter {} 23struct LineHighlighter { }
21impl Highlighter for LineHighlighter { 24impl 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));