From 27c5539c0aa8e7df2947d9addbab90b2df8c3a3d Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sun, 26 Dec 2021 13:53:22 +0100 Subject: Add `exp(x)` function which evaluates to `e^x` Quite useful when doing analysis at University, also preferable over `e^x` because it's way nicer to write `exp(arbitrary expr)` rather than `e^(arbitrary expr)`. --- src/lex.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lex.rs b/src/lex.rs index 76f61a0..4bdd7b6 100644 --- a/src/lex.rs +++ b/src/lex.rs @@ -101,6 +101,7 @@ lazy_static! { m.insert("acsc", Function::token_from_fn("acsc".into(), |x| (1./x).asin())); m.insert("asec", Function::token_from_fn("asec".into(), |x| (1./x).acos())); m.insert("acot", Function::token_from_fn("acot".into(), |x| (1./x).atan())); + m.insert("exp", Function::token_from_fn("exp".into(), |x| x.exp())); // single arg function s can be added here m }; -- cgit v1.2.3 From 66790c32e9cc80eed512d67fe3630bbe124c6c61 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sun, 26 Dec 2021 14:02:19 +0100 Subject: Add `exp2` function and ensure it's correctly lexed --- src/lex.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/lex.rs b/src/lex.rs index 4bdd7b6..1c686a1 100644 --- a/src/lex.rs +++ b/src/lex.rs @@ -102,6 +102,7 @@ lazy_static! { m.insert("asec", Function::token_from_fn("asec".into(), |x| (1./x).acos())); m.insert("acot", Function::token_from_fn("acot".into(), |x| (1./x).atan())); m.insert("exp", Function::token_from_fn("exp".into(), |x| x.exp())); + m.insert("exp2", Function::token_from_fn("exp2".into(), |x| x.exp2())); // single arg function s can be added here m }; @@ -135,19 +136,23 @@ pub fn lexer(input: &str, prev_ans: Option) -> Result, CalcError '0'..='9' | '.' => { if !char_vec.is_empty() { if FUNCTIONS.get(&char_vec[..]).is_some() { - return Err(CalcError::Syntax(format!( - "Function '{}' expected parentheses", - char_vec - ))); + char_vec.push(letter); + if !FUNCTIONS.get(&char_vec[..]).is_some() { + return Err(CalcError::Syntax(format!( + "Function '{}' expected parentheses", + &char_vec[..char_vec.chars().count()-1] + ))); + } } else { return Err(CalcError::Syntax(format!( "Unexpected character '{}'", char_vec ))); } + } else { + num_vec.push(letter); + last_char_is_op = false; } - num_vec.push(letter); - last_char_is_op = false; } '_' => { if prev_ans.is_none() { -- cgit v1.2.3 From cb3e69df8b17ffc0cab721e2dcc285731a1c5bc9 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sun, 26 Dec 2021 14:09:27 +0100 Subject: Add functions to highlighting list --- src/readline.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/readline.rs b/src/readline.rs index d689f95..2939ee1 100644 --- a/src/readline.rs +++ b/src/readline.rs @@ -55,7 +55,7 @@ impl Highlighter for LineHighlighter { let functions = [ "sin", "cos", "tan", "csc", "sec", "cot", "sinh", "cosh", "tanh", "ln", "log", "sqrt", "ceil", "floor", "rad", "deg", "abs", "asin", "acos", "atan", "acsc", - "asec", "acot", + "asec", "acot", "exp2", "exp" ]; let ops = Regex::new(r"(?P[\+-/\*%\^!])").unwrap(); let mut coloured: String = ops.replace_all(line, "\x1b[35m$o\x1b[0m").into(); -- cgit v1.2.3 From 4fd3ec330a89e4177099c21277d3c12e97ca0c21 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sun, 26 Dec 2021 15:22:57 +0100 Subject: Update rustyline to v9 Also refresh line always. This isn't a big deal for the small expressions we have here and also fixes a few annoying issues I had with the highlighter. --- Cargo.lock | 248 ++++++++++++++++++++++++++++++++++++++++++++++++-------- Cargo.toml | 2 +- src/readline.rs | 7 +- 3 files changed, 222 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de51705..48a5246 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aho-corasick" version = "0.7.10" @@ -55,9 +57,9 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "blake2b_simd" @@ -82,6 +84,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "clap" version = "2.33.0" @@ -97,6 +105,17 @@ dependencies = [ "vec_map", ] +[[package]] +name = "clipboard-win" +version = "4.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8340083d28acb43451166543b98c838299b7e0863621be53a338adceea0ed" +dependencies = [ + "error-code", + "str-buf", + "winapi", +] + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -110,7 +129,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" dependencies = [ "autocfg", - "cfg-if", + "cfg-if 0.1.10", "lazy_static", ] @@ -120,19 +139,18 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "dirs-sys", ] [[package]] -name = "dirs" -version = "1.0.5" +name = "dirs-next" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ - "libc", - "redox_users", - "winapi", + "cfg-if 1.0.0", + "dirs-sys-next", ] [[package]] @@ -141,12 +159,39 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", + "libc", + "redox_users 0.3.4", + "winapi", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ "libc", - "redox_users", + "redox_users 0.4.0", "winapi", ] +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "error-code" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5115567ac25674e0043e472be13d14e537f37ea8aa4bdc4aef0c89add1db1ff" +dependencies = [ + "libc", + "str-buf", +] + [[package]] name = "eva" version = "0.2.7" @@ -161,15 +206,37 @@ dependencies = [ "term_size", ] +[[package]] +name = "fd-lock" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a16910e685088843d53132b04e0f10a571fdb193224fc589685b3ba1ce4cb03d" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "windows-sys", +] + [[package]] name = "getrandom" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", "libc", - "wasi", + "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] @@ -189,9 +256,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.68" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "log" @@ -199,7 +266,7 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] @@ -208,17 +275,35 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + [[package]] name = "nix" -version = "0.13.1" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b" +checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" dependencies = [ "bitflags", "cc", - "cfg-if", + "cfg-if 1.0.0", "libc", - "void", + "memoffset", ] [[package]] @@ -304,23 +389,52 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce082a9940a7ace2ad4a8b7d0b1eac6aa378895f18be598230c5f2284ac05426" +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + [[package]] name = "redox_syscall" version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" dependencies = [ - "getrandom", - "redox_syscall", + "getrandom 0.1.14", + "redox_syscall 0.1.56", "rust-argon2", ] +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom 0.2.3", + "redox_syscall 0.2.10", +] + [[package]] name = "regex" version = "1.3.6" @@ -353,21 +467,46 @@ dependencies = [ [[package]] name = "rustyline" -version = "4.1.0" +version = "9.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f47ea1ceb347d2deae482d655dc8eef4bd82363d3329baffa3818bd76fea48b" +checksum = "6c38cfbd0a4d7df7aab7cf53732d5d43449d0300358fd15cd4e8c8468a956aca" dependencies = [ - "dirs", + "bitflags", + "cfg-if 1.0.0", + "clipboard-win", + "dirs-next", + "fd-lock", "libc", "log", "memchr", "nix", + "radix_trie", + "scopeguard", + "smallvec", "unicode-segmentation", "unicode-width", "utf8parse", "winapi", ] +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "smallvec" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" + +[[package]] +name = "str-buf" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d44a3643b4ff9caf57abcee9c2c621d6c03d9135e0d8b589bd9afb5992cb176a" + [[package]] name = "strsim" version = "0.8.0" @@ -416,9 +555,9 @@ checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" [[package]] name = "utf8parse" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d" +checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" [[package]] name = "vec_map" @@ -427,16 +566,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" [[package]] -name = "void" -version = "1.0.2" +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" +version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "winapi" @@ -459,3 +598,46 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82ca39602d5cbfa692c4b67e3bcbb2751477355141c1ed434c94da4186836ff6" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52695a41e536859d5308cc613b4a022261a274390b25bd29dfff4bf08505f3c2" + +[[package]] +name = "windows_i686_gnu" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f54725ac23affef038fecb177de6c9bf065787c2f432f79e3c373da92f3e1d8a" + +[[package]] +name = "windows_i686_msvc" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d5158a43cc43623c0729d1ad6647e62fa384a3d135fd15108d37c683461f64" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc31f409f565611535130cfe7ee8e6655d3fa99c1c61013981e491921b5ce954" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f" diff --git a/Cargo.toml b/Cargo.toml index 4527862..6ae2e05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ categories = ["command-line-interface", "science", "parser-implementations"] license = "MIT" [dependencies] -rustyline = "4.1.0" +rustyline = "9.1.1" clap = "2.32.0" radix_fmt = "1.0.0" lazy_static = "1.3.0" diff --git a/src/readline.rs b/src/readline.rs index 2939ee1..f59cd22 100644 --- a/src/readline.rs +++ b/src/readline.rs @@ -7,6 +7,7 @@ use rustyline::error::ReadlineError; use rustyline::highlight::Highlighter; use rustyline::hint::{Hinter, HistoryHinter}; use rustyline::{Context, Editor, Helper}; +use rustyline::validate::Validator; use directories::ProjectDirs; @@ -75,6 +76,7 @@ impl Highlighter for LineHighlighter { } impl Highlighter for RLHelper { + fn highlight_char(&self, _: &str, _: usize) -> bool { true } fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> { self.highlighter.highlight_hint(hint) } @@ -96,11 +98,14 @@ impl Completer for RLHelper { } impl Hinter for RLHelper { - fn hint(&self, line: &str, a: usize, b: &Context) -> Option { + type Hint = String; + fn hint(&self, line: &str, a: usize, b: &Context) -> Option { self.hinter.hint(line, a, b) } } +impl Validator for RLHelper {} + impl Helper for RLHelper {} pub fn create_readline() -> Editor { -- cgit v1.2.3 From acf947b608db99ff2e46a8020b6e70466c233088 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sun, 26 Dec 2021 15:27:41 +0100 Subject: Fix highlighting of `e` vs `exp` --- src/readline.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/readline.rs b/src/readline.rs index f59cd22..9912af6 100644 --- a/src/readline.rs +++ b/src/readline.rs @@ -62,10 +62,12 @@ impl Highlighter for LineHighlighter { let mut coloured: String = ops.replace_all(line, "\x1b[35m$o\x1b[0m").into(); for c in &constants { - coloured = coloured.replace(c, &format!("\x1b[33m{}\x1b[0m", c)); + let re = Regex::new(format!("(?P{})(?P(\x1b\\[35m)?([\\+-/\\*%\\^! ]|$))", c).as_str()).unwrap(); + coloured = re.replace_all(&coloured, "\x1b[33m$o\x1b[0m$r").into(); } for f in &functions { - coloured = coloured.replace(f, &format!("\x1b[34m{}\x1b[0m", f)); + let re = Regex::new(format!("(?P{})(?P(\\(|$))", f).as_str()).unwrap(); + coloured = re.replace_all(&coloured, "\x1b[34m$o\x1b[0m$r").into(); } Owned(coloured) } -- cgit v1.2.3 From 7d1db014ebc6bf0a8fd3e5a25abdc81aa2270a1d Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sun, 26 Dec 2021 15:31:13 +0100 Subject: Deduplicate references to functions & constants --- src/readline.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/readline.rs b/src/readline.rs index 9912af6..6734674 100644 --- a/src/readline.rs +++ b/src/readline.rs @@ -15,6 +15,7 @@ use regex::Regex; use crate::error::CalcError; use crate::eval_math_expression; +use crate::lex::{CONSTANTS, FUNCTIONS}; pub struct RLHelper { completer: FilenameCompleter, @@ -52,20 +53,16 @@ impl Highlighter for LineHighlighter { let op = eval_math_expression(line, prev_ans); match op { Ok(_) => { - let constants = ["e", "pi"]; - let functions = [ - "sin", "cos", "tan", "csc", "sec", "cot", "sinh", "cosh", "tanh", "ln", "log", - "sqrt", "ceil", "floor", "rad", "deg", "abs", "asin", "acos", "atan", "acsc", - "asec", "acot", "exp2", "exp" - ]; + let constants = CONSTANTS.keys(); + let functions = FUNCTIONS.keys(); let ops = Regex::new(r"(?P[\+-/\*%\^!])").unwrap(); let mut coloured: String = ops.replace_all(line, "\x1b[35m$o\x1b[0m").into(); - for c in &constants { + for c in constants { let re = Regex::new(format!("(?P{})(?P(\x1b\\[35m)?([\\+-/\\*%\\^! ]|$))", c).as_str()).unwrap(); coloured = re.replace_all(&coloured, "\x1b[33m$o\x1b[0m$r").into(); } - for f in &functions { + for f in functions { let re = Regex::new(format!("(?P{})(?P(\\(|$))", f).as_str()).unwrap(); coloured = re.replace_all(&coloured, "\x1b[34m$o\x1b[0m$r").into(); } -- cgit v1.2.3 From 18a1ce8f0343f7865f8a01741fb96f98945645d0 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sun, 26 Dec 2021 15:41:47 +0100 Subject: Allow expressions such as `e2` as multiplication of `e * 2` --- src/lex.rs | 6 ++++++ src/main.rs | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/lex.rs b/src/lex.rs index 1c686a1..da542d5 100644 --- a/src/lex.rs +++ b/src/lex.rs @@ -143,6 +143,12 @@ pub fn lexer(input: &str, prev_ans: Option) -> Result, CalcError &char_vec[..char_vec.chars().count()-1] ))); } + } else if CONSTANTS.get(&char_vec[..]).is_some() { + result.push(CONSTANTS.get(&char_vec[..]).unwrap().clone()); + result.push(OPERATORS.get(&'*').unwrap().clone()); + char_vec.clear(); + num_vec.push(letter); + last_char_is_op = false; } else { return Err(CalcError::Syntax(format!( "Unexpected character '{}'", diff --git a/src/main.rs b/src/main.rs index 75c33bb..f5e5c59 100644 --- a/src/main.rs +++ b/src/main.rs @@ -259,4 +259,9 @@ mod tests { let evaled = eval_math_expression("9 + _ ", Some(0f64)).unwrap(); assert_eq!(9., evaled); } + #[test] + fn eval_const_multiplication() { + let evaled = eval_math_expression("e2", None).unwrap(); + assert_eq!(5.4365636569, evaled); + } } -- cgit v1.2.3 From a18e994ae5fc95761d4d3569a99d98dd4a99660b Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sun, 26 Dec 2021 16:01:25 +0100 Subject: Add `round()` function --- src/lex.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lex.rs b/src/lex.rs index da542d5..1220a1f 100644 --- a/src/lex.rs +++ b/src/lex.rs @@ -103,6 +103,7 @@ lazy_static! { m.insert("acot", Function::token_from_fn("acot".into(), |x| (1./x).atan())); m.insert("exp", Function::token_from_fn("exp".into(), |x| x.exp())); m.insert("exp2", Function::token_from_fn("exp2".into(), |x| x.exp2())); + m.insert("round", Function::token_from_fn("round".into(), |x| x.round())); // single arg function s can be added here m }; -- cgit v1.2.3 From 794a795f525ee3587ce317e65b24935aeb9ba5cf Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Thu, 30 Dec 2021 18:16:46 +0100 Subject: Implement a few more testcases --- src/main.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/main.rs b/src/main.rs index f5e5c59..e6a865e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -264,4 +264,30 @@ mod tests { let evaled = eval_math_expression("e2", None).unwrap(); assert_eq!(5.4365636569, evaled); } + #[test] + fn eval_round() { + let evaled = eval_math_expression("round(0.5)+round(2.4)", None).unwrap(); + assert_eq!(3., evaled); + } + #[test] + fn eval_exp2() { + assert_eq!( + 256., + eval_math_expression("exp2(8)", None).unwrap() + ); + } + #[test] + fn eval_exp() { + assert_eq!( + 20.0855369232 as f64, + eval_math_expression("exp(3)", None).unwrap() + ); + } + #[test] + fn eval_e_times_n() { + assert_eq!( + 0. as f64, + eval_math_expression("e0", None).unwrap() + ); + } } -- cgit v1.2.3 From 7e673fc429df46f1792f5586965245b59d92990e Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Tue, 4 Jan 2022 17:38:09 +0100 Subject: rustyline: disable default features --- Cargo.lock | 66 ++++---------------------------------------------------------- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 48a5246..287db82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -143,16 +143,6 @@ dependencies = [ "dirs-sys", ] -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if 1.0.0", - "dirs-sys-next", -] - [[package]] name = "dirs-sys" version = "0.3.4" @@ -161,18 +151,7 @@ checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" dependencies = [ "cfg-if 0.1.10", "libc", - "redox_users 0.3.4", - "winapi", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users 0.4.0", + "redox_users", "winapi", ] @@ -225,18 +204,7 @@ checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" dependencies = [ "cfg-if 0.1.10", "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -405,36 +373,17 @@ version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -[[package]] -name = "redox_syscall" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" -dependencies = [ - "bitflags", -] - [[package]] name = "redox_users" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" dependencies = [ - "getrandom 0.1.14", - "redox_syscall 0.1.56", + "getrandom", + "redox_syscall", "rust-argon2", ] -[[package]] -name = "redox_users" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" -dependencies = [ - "getrandom 0.2.3", - "redox_syscall 0.2.10", -] - [[package]] name = "regex" version = "1.3.6" @@ -474,7 +423,6 @@ dependencies = [ "bitflags", "cfg-if 1.0.0", "clipboard-win", - "dirs-next", "fd-lock", "libc", "log", @@ -571,12 +519,6 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - [[package]] name = "winapi" version = "0.3.8" diff --git a/Cargo.toml b/Cargo.toml index 6ae2e05..4be652d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ categories = ["command-line-interface", "science", "parser-implementations"] license = "MIT" [dependencies] -rustyline = "9.1.1" +rustyline = { version = "9.1.1", default-features = false } clap = "2.32.0" radix_fmt = "1.0.0" lazy_static = "1.3.0" -- cgit v1.2.3 From 3f0f8d9f0f910b4c9477297049d4a508eacc3734 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Tue, 4 Jan 2022 17:46:33 +0100 Subject: readline: explain constant highlighting regex --- src/readline.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/readline.rs b/src/readline.rs index 6734674..8906a4f 100644 --- a/src/readline.rs +++ b/src/readline.rs @@ -59,6 +59,22 @@ impl Highlighter for LineHighlighter { let mut coloured: String = ops.replace_all(line, "\x1b[35m$o\x1b[0m").into(); for c in constants { + // This regex consists of the following pieces: + // * the constant (`o`) to highlight (to be substituted as `{}` via `format!`), + // e.g. `e` or `pi`. + // * (optionally) an ANSI escape-code (`\x1b\[35m`) that is used to highlight + // a binary operator (e.g. `+`/`-`/...). With this one it is ensured that + // binary operators are always correctly detected after a constant + // (see the next bullet-point for why that's needed). + // * the following operator (e.g. `+`/`-`/...), a space or the end + // of the expression (to highlight e.g. `1+e` correctly). This is + // required to distinguish a constant in an expression from a function-call, + // e.g. `e+1` from `exp(1)`, without this matching logic, the `e` from + // `exp` would be improperly interpreted as constant. + // + // To make sure none of existing highlighting (i.e. highlighting + // of binary operators that happens before) breaks, the escape-codes & operator + // (called `r`) are appended after the highlighted constant. let re = Regex::new(format!("(?P{})(?P(\x1b\\[35m)?([\\+-/\\*%\\^! ]|$))", c).as_str()).unwrap(); coloured = re.replace_all(&coloured, "\x1b[33m$o\x1b[0m$r").into(); } -- cgit v1.2.3