diff options
author | Ivan Tham <[email protected]> | 2022-01-05 04:01:48 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2022-01-05 04:01:48 +0000 |
commit | 9fa2823b3916184dbfbb9c704ab34ae79c0c1038 (patch) | |
tree | 597a3ac1bad860fa62737faa58aeb71184c249be | |
parent | 3f52f6f2ce8408350fcdc180d416e63dd627d93f (diff) | |
parent | 3f0f8d9f0f910b4c9477297049d4a508eacc3734 (diff) |
Merge pull request #51 from Ma27/exp-and-round
Add functions `exp()`, `exp2()` & `round()`; fix minor readline issues
-rw-r--r-- | Cargo.lock | 188 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/lex.rs | 25 | ||||
-rw-r--r-- | src/main.rs | 31 | ||||
-rw-r--r-- | src/readline.rs | 42 |
5 files changed, 238 insertions, 50 deletions
@@ -1,5 +1,7 @@ | |||
1 | # This file is automatically @generated by Cargo. | 1 | # This file is automatically @generated by Cargo. |
2 | # It is not intended for manual editing. | 2 | # It is not intended for manual editing. |
3 | version = 3 | ||
4 | |||
3 | [[package]] | 5 | [[package]] |
4 | name = "aho-corasick" | 6 | name = "aho-corasick" |
5 | version = "0.7.10" | 7 | version = "0.7.10" |
@@ -55,9 +57,9 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" | |||
55 | 57 | ||
56 | [[package]] | 58 | [[package]] |
57 | name = "bitflags" | 59 | name = "bitflags" |
58 | version = "1.2.1" | 60 | version = "1.3.2" |
59 | source = "registry+https://github.com/rust-lang/crates.io-index" | 61 | source = "registry+https://github.com/rust-lang/crates.io-index" |
60 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" | 62 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" |
61 | 63 | ||
62 | [[package]] | 64 | [[package]] |
63 | name = "blake2b_simd" | 65 | name = "blake2b_simd" |
@@ -83,6 +85,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
83 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" | 85 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" |
84 | 86 | ||
85 | [[package]] | 87 | [[package]] |
88 | name = "cfg-if" | ||
89 | version = "1.0.0" | ||
90 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
91 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" | ||
92 | |||
93 | [[package]] | ||
86 | name = "clap" | 94 | name = "clap" |
87 | version = "2.33.0" | 95 | version = "2.33.0" |
88 | source = "registry+https://github.com/rust-lang/crates.io-index" | 96 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -98,6 +106,17 @@ dependencies = [ | |||
98 | ] | 106 | ] |
99 | 107 | ||
100 | [[package]] | 108 | [[package]] |
109 | name = "clipboard-win" | ||
110 | version = "4.2.2" | ||
111 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
112 | checksum = "3db8340083d28acb43451166543b98c838299b7e0863621be53a338adceea0ed" | ||
113 | dependencies = [ | ||
114 | "error-code", | ||
115 | "str-buf", | ||
116 | "winapi", | ||
117 | ] | ||
118 | |||
119 | [[package]] | ||
101 | name = "constant_time_eq" | 120 | name = "constant_time_eq" |
102 | version = "0.1.5" | 121 | version = "0.1.5" |
103 | source = "registry+https://github.com/rust-lang/crates.io-index" | 122 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -110,7 +129,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
110 | checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" | 129 | checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" |
111 | dependencies = [ | 130 | dependencies = [ |
112 | "autocfg", | 131 | "autocfg", |
113 | "cfg-if", | 132 | "cfg-if 0.1.10", |
114 | "lazy_static", | 133 | "lazy_static", |
115 | ] | 134 | ] |
116 | 135 | ||
@@ -120,31 +139,36 @@ version = "2.0.2" | |||
120 | source = "registry+https://github.com/rust-lang/crates.io-index" | 139 | source = "registry+https://github.com/rust-lang/crates.io-index" |
121 | checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" | 140 | checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" |
122 | dependencies = [ | 141 | dependencies = [ |
123 | "cfg-if", | 142 | "cfg-if 0.1.10", |
124 | "dirs-sys", | 143 | "dirs-sys", |
125 | ] | 144 | ] |
126 | 145 | ||
127 | [[package]] | 146 | [[package]] |
128 | name = "dirs" | 147 | name = "dirs-sys" |
129 | version = "1.0.5" | 148 | version = "0.3.4" |
130 | source = "registry+https://github.com/rust-lang/crates.io-index" | 149 | source = "registry+https://github.com/rust-lang/crates.io-index" |
131 | checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" | 150 | checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" |
132 | dependencies = [ | 151 | dependencies = [ |
152 | "cfg-if 0.1.10", | ||
133 | "libc", | 153 | "libc", |
134 | "redox_users", | 154 | "redox_users", |
135 | "winapi", | 155 | "winapi", |
136 | ] | 156 | ] |
137 | 157 | ||
138 | [[package]] | 158 | [[package]] |
139 | name = "dirs-sys" | 159 | name = "endian-type" |
140 | version = "0.3.4" | 160 | version = "0.1.2" |
141 | source = "registry+https://github.com/rust-lang/crates.io-index" | 161 | source = "registry+https://github.com/rust-lang/crates.io-index" |
142 | checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" | 162 | checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" |
163 | |||
164 | [[package]] | ||
165 | name = "error-code" | ||
166 | version = "2.3.0" | ||
167 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
168 | checksum = "b5115567ac25674e0043e472be13d14e537f37ea8aa4bdc4aef0c89add1db1ff" | ||
143 | dependencies = [ | 169 | dependencies = [ |
144 | "cfg-if", | ||
145 | "libc", | 170 | "libc", |
146 | "redox_users", | 171 | "str-buf", |
147 | "winapi", | ||
148 | ] | 172 | ] |
149 | 173 | ||
150 | [[package]] | 174 | [[package]] |
@@ -162,12 +186,23 @@ dependencies = [ | |||
162 | ] | 186 | ] |
163 | 187 | ||
164 | [[package]] | 188 | [[package]] |
189 | name = "fd-lock" | ||
190 | version = "3.0.2" | ||
191 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
192 | checksum = "a16910e685088843d53132b04e0f10a571fdb193224fc589685b3ba1ce4cb03d" | ||
193 | dependencies = [ | ||
194 | "cfg-if 1.0.0", | ||
195 | "libc", | ||
196 | "windows-sys", | ||
197 | ] | ||
198 | |||
199 | [[package]] | ||
165 | name = "getrandom" | 200 | name = "getrandom" |
166 | version = "0.1.14" | 201 | version = "0.1.14" |
167 | source = "registry+https://github.com/rust-lang/crates.io-index" | 202 | source = "registry+https://github.com/rust-lang/crates.io-index" |
168 | checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" | 203 | checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" |
169 | dependencies = [ | 204 | dependencies = [ |
170 | "cfg-if", | 205 | "cfg-if 0.1.10", |
171 | "libc", | 206 | "libc", |
172 | "wasi", | 207 | "wasi", |
173 | ] | 208 | ] |
@@ -189,9 +224,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" | |||
189 | 224 | ||
190 | [[package]] | 225 | [[package]] |
191 | name = "libc" | 226 | name = "libc" |
192 | version = "0.2.68" | 227 | version = "0.2.112" |
193 | source = "registry+https://github.com/rust-lang/crates.io-index" | 228 | source = "registry+https://github.com/rust-lang/crates.io-index" |
194 | checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" | 229 | checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" |
195 | 230 | ||
196 | [[package]] | 231 | [[package]] |
197 | name = "log" | 232 | name = "log" |
@@ -199,7 +234,7 @@ version = "0.4.8" | |||
199 | source = "registry+https://github.com/rust-lang/crates.io-index" | 234 | source = "registry+https://github.com/rust-lang/crates.io-index" |
200 | checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" | 235 | checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" |
201 | dependencies = [ | 236 | dependencies = [ |
202 | "cfg-if", | 237 | "cfg-if 0.1.10", |
203 | ] | 238 | ] |
204 | 239 | ||
205 | [[package]] | 240 | [[package]] |
@@ -209,16 +244,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
209 | checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" | 244 | checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" |
210 | 245 | ||
211 | [[package]] | 246 | [[package]] |
247 | name = "memoffset" | ||
248 | version = "0.6.5" | ||
249 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
250 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" | ||
251 | dependencies = [ | ||
252 | "autocfg", | ||
253 | ] | ||
254 | |||
255 | [[package]] | ||
256 | name = "nibble_vec" | ||
257 | version = "0.1.0" | ||
258 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
259 | checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" | ||
260 | dependencies = [ | ||
261 | "smallvec", | ||
262 | ] | ||
263 | |||
264 | [[package]] | ||
212 | name = "nix" | 265 | name = "nix" |
213 | version = "0.13.1" | 266 | version = "0.23.1" |
214 | source = "registry+https://github.com/rust-lang/crates.io-index" | 267 | source = "registry+https://github.com/rust-lang/crates.io-index" |
215 | checksum = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b" | 268 | checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" |
216 | dependencies = [ | 269 | dependencies = [ |
217 | "bitflags", | 270 | "bitflags", |
218 | "cc", | 271 | "cc", |
219 | "cfg-if", | 272 | "cfg-if 1.0.0", |
220 | "libc", | 273 | "libc", |
221 | "void", | 274 | "memoffset", |
222 | ] | 275 | ] |
223 | 276 | ||
224 | [[package]] | 277 | [[package]] |
@@ -305,6 +358,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
305 | checksum = "ce082a9940a7ace2ad4a8b7d0b1eac6aa378895f18be598230c5f2284ac05426" | 358 | checksum = "ce082a9940a7ace2ad4a8b7d0b1eac6aa378895f18be598230c5f2284ac05426" |
306 | 359 | ||
307 | [[package]] | 360 | [[package]] |
361 | name = "radix_trie" | ||
362 | version = "0.2.1" | ||
363 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
364 | checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" | ||
365 | dependencies = [ | ||
366 | "endian-type", | ||
367 | "nibble_vec", | ||
368 | ] | ||
369 | |||
370 | [[package]] | ||
308 | name = "redox_syscall" | 371 | name = "redox_syscall" |
309 | version = "0.1.56" | 372 | version = "0.1.56" |
310 | source = "registry+https://github.com/rust-lang/crates.io-index" | 373 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -353,15 +416,21 @@ dependencies = [ | |||
353 | 416 | ||
354 | [[package]] | 417 | [[package]] |
355 | name = "rustyline" | 418 | name = "rustyline" |
356 | version = "4.1.0" | 419 | version = "9.1.1" |
357 | source = "registry+https://github.com/rust-lang/crates.io-index" | 420 | source = "registry+https://github.com/rust-lang/crates.io-index" |
358 | checksum = "0f47ea1ceb347d2deae482d655dc8eef4bd82363d3329baffa3818bd76fea48b" | 421 | checksum = "6c38cfbd0a4d7df7aab7cf53732d5d43449d0300358fd15cd4e8c8468a956aca" |
359 | dependencies = [ | 422 | dependencies = [ |
360 | "dirs", | 423 | "bitflags", |
424 | "cfg-if 1.0.0", | ||
425 | "clipboard-win", | ||
426 | "fd-lock", | ||
361 | "libc", | 427 | "libc", |
362 | "log", | 428 | "log", |
363 | "memchr", | 429 | "memchr", |
364 | "nix", | 430 | "nix", |
431 | "radix_trie", | ||
432 | "scopeguard", | ||
433 | "smallvec", | ||
365 | "unicode-segmentation", | 434 | "unicode-segmentation", |
366 | "unicode-width", | 435 | "unicode-width", |
367 | "utf8parse", | 436 | "utf8parse", |
@@ -369,6 +438,24 @@ dependencies = [ | |||
369 | ] | 438 | ] |
370 | 439 | ||
371 | [[package]] | 440 | [[package]] |
441 | name = "scopeguard" | ||
442 | version = "1.1.0" | ||
443 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
444 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" | ||
445 | |||
446 | [[package]] | ||
447 | name = "smallvec" | ||
448 | version = "1.7.0" | ||
449 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
450 | checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" | ||
451 | |||
452 | [[package]] | ||
453 | name = "str-buf" | ||
454 | version = "1.0.5" | ||
455 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
456 | checksum = "d44a3643b4ff9caf57abcee9c2c621d6c03d9135e0d8b589bd9afb5992cb176a" | ||
457 | |||
458 | [[package]] | ||
372 | name = "strsim" | 459 | name = "strsim" |
373 | version = "0.8.0" | 460 | version = "0.8.0" |
374 | source = "registry+https://github.com/rust-lang/crates.io-index" | 461 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -416,9 +503,9 @@ checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" | |||
416 | 503 | ||
417 | [[package]] | 504 | [[package]] |
418 | name = "utf8parse" | 505 | name = "utf8parse" |
419 | version = "0.1.1" | 506 | version = "0.2.0" |
420 | source = "registry+https://github.com/rust-lang/crates.io-index" | 507 | source = "registry+https://github.com/rust-lang/crates.io-index" |
421 | checksum = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d" | 508 | checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" |
422 | 509 | ||
423 | [[package]] | 510 | [[package]] |
424 | name = "vec_map" | 511 | name = "vec_map" |
@@ -427,12 +514,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
427 | checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" | 514 | checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" |
428 | 515 | ||
429 | [[package]] | 516 | [[package]] |
430 | name = "void" | ||
431 | version = "1.0.2" | ||
432 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
433 | checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" | ||
434 | |||
435 | [[package]] | ||
436 | name = "wasi" | 517 | name = "wasi" |
437 | version = "0.9.0+wasi-snapshot-preview1" | 518 | version = "0.9.0+wasi-snapshot-preview1" |
438 | source = "registry+https://github.com/rust-lang/crates.io-index" | 519 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -459,3 +540,46 @@ name = "winapi-x86_64-pc-windows-gnu" | |||
459 | version = "0.4.0" | 540 | version = "0.4.0" |
460 | source = "registry+https://github.com/rust-lang/crates.io-index" | 541 | source = "registry+https://github.com/rust-lang/crates.io-index" |
461 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" | 542 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" |
543 | |||
544 | [[package]] | ||
545 | name = "windows-sys" | ||
546 | version = "0.28.0" | ||
547 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
548 | checksum = "82ca39602d5cbfa692c4b67e3bcbb2751477355141c1ed434c94da4186836ff6" | ||
549 | dependencies = [ | ||
550 | "windows_aarch64_msvc", | ||
551 | "windows_i686_gnu", | ||
552 | "windows_i686_msvc", | ||
553 | "windows_x86_64_gnu", | ||
554 | "windows_x86_64_msvc", | ||
555 | ] | ||
556 | |||
557 | [[package]] | ||
558 | name = "windows_aarch64_msvc" | ||
559 | version = "0.28.0" | ||
560 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
561 | checksum = "52695a41e536859d5308cc613b4a022261a274390b25bd29dfff4bf08505f3c2" | ||
562 | |||
563 | [[package]] | ||
564 | name = "windows_i686_gnu" | ||
565 | version = "0.28.0" | ||
566 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
567 | checksum = "f54725ac23affef038fecb177de6c9bf065787c2f432f79e3c373da92f3e1d8a" | ||
568 | |||
569 | [[package]] | ||
570 | name = "windows_i686_msvc" | ||
571 | version = "0.28.0" | ||
572 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
573 | checksum = "51d5158a43cc43623c0729d1ad6647e62fa384a3d135fd15108d37c683461f64" | ||
574 | |||
575 | [[package]] | ||
576 | name = "windows_x86_64_gnu" | ||
577 | version = "0.28.0" | ||
578 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
579 | checksum = "bc31f409f565611535130cfe7ee8e6655d3fa99c1c61013981e491921b5ce954" | ||
580 | |||
581 | [[package]] | ||
582 | name = "windows_x86_64_msvc" | ||
583 | version = "0.28.0" | ||
584 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
585 | checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f" | ||
@@ -12,7 +12,7 @@ categories = ["command-line-interface", "science", "parser-implementations"] | |||
12 | license = "MIT" | 12 | license = "MIT" |
13 | 13 | ||
14 | [dependencies] | 14 | [dependencies] |
15 | rustyline = "4.1.0" | 15 | rustyline = { version = "9.1.1", default-features = false } |
16 | clap = "2.32.0" | 16 | clap = "2.32.0" |
17 | radix_fmt = "1.0.0" | 17 | radix_fmt = "1.0.0" |
18 | lazy_static = "1.3.0" | 18 | lazy_static = "1.3.0" |
@@ -101,6 +101,9 @@ lazy_static! { | |||
101 | m.insert("acsc", Function::token_from_fn("acsc".into(), |x| (1./x).asin())); | 101 | m.insert("acsc", Function::token_from_fn("acsc".into(), |x| (1./x).asin())); |
102 | m.insert("asec", Function::token_from_fn("asec".into(), |x| (1./x).acos())); | 102 | m.insert("asec", Function::token_from_fn("asec".into(), |x| (1./x).acos())); |
103 | m.insert("acot", Function::token_from_fn("acot".into(), |x| (1./x).atan())); | 103 | m.insert("acot", Function::token_from_fn("acot".into(), |x| (1./x).atan())); |
104 | m.insert("exp", Function::token_from_fn("exp".into(), |x| x.exp())); | ||
105 | m.insert("exp2", Function::token_from_fn("exp2".into(), |x| x.exp2())); | ||
106 | m.insert("round", Function::token_from_fn("round".into(), |x| x.round())); | ||
104 | // single arg function s can be added here | 107 | // single arg function s can be added here |
105 | m | 108 | m |
106 | }; | 109 | }; |
@@ -134,19 +137,29 @@ pub fn lexer(input: &str, prev_ans: Option<f64>) -> Result<Vec<Token>, CalcError | |||
134 | '0'..='9' | '.' => { | 137 | '0'..='9' | '.' => { |
135 | if !char_vec.is_empty() { | 138 | if !char_vec.is_empty() { |
136 | if FUNCTIONS.get(&char_vec[..]).is_some() { | 139 | if FUNCTIONS.get(&char_vec[..]).is_some() { |
137 | return Err(CalcError::Syntax(format!( | 140 | char_vec.push(letter); |
138 | "Function '{}' expected parentheses", | 141 | if !FUNCTIONS.get(&char_vec[..]).is_some() { |
139 | char_vec | 142 | return Err(CalcError::Syntax(format!( |
140 | ))); | 143 | "Function '{}' expected parentheses", |
144 | &char_vec[..char_vec.chars().count()-1] | ||
145 | ))); | ||
146 | } | ||
147 | } else if CONSTANTS.get(&char_vec[..]).is_some() { | ||
148 | result.push(CONSTANTS.get(&char_vec[..]).unwrap().clone()); | ||
149 | result.push(OPERATORS.get(&'*').unwrap().clone()); | ||
150 | char_vec.clear(); | ||
151 | num_vec.push(letter); | ||
152 | last_char_is_op = false; | ||
141 | } else { | 153 | } else { |
142 | return Err(CalcError::Syntax(format!( | 154 | return Err(CalcError::Syntax(format!( |
143 | "Unexpected character '{}'", | 155 | "Unexpected character '{}'", |
144 | char_vec | 156 | char_vec |
145 | ))); | 157 | ))); |
146 | } | 158 | } |
159 | } else { | ||
160 | num_vec.push(letter); | ||
161 | last_char_is_op = false; | ||
147 | } | 162 | } |
148 | num_vec.push(letter); | ||
149 | last_char_is_op = false; | ||
150 | } | 163 | } |
151 | '_' => { | 164 | '_' => { |
152 | if prev_ans.is_none() { | 165 | if prev_ans.is_none() { |
diff --git a/src/main.rs b/src/main.rs index 75c33bb..e6a865e 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -259,4 +259,35 @@ mod tests { | |||
259 | let evaled = eval_math_expression("9 + _ ", Some(0f64)).unwrap(); | 259 | let evaled = eval_math_expression("9 + _ ", Some(0f64)).unwrap(); |
260 | assert_eq!(9., evaled); | 260 | assert_eq!(9., evaled); |
261 | } | 261 | } |
262 | #[test] | ||
263 | fn eval_const_multiplication() { | ||
264 | let evaled = eval_math_expression("e2", None).unwrap(); | ||
265 | assert_eq!(5.4365636569, evaled); | ||
266 | } | ||
267 | #[test] | ||
268 | fn eval_round() { | ||
269 | let evaled = eval_math_expression("round(0.5)+round(2.4)", None).unwrap(); | ||
270 | assert_eq!(3., evaled); | ||
271 | } | ||
272 | #[test] | ||
273 | fn eval_exp2() { | ||
274 | assert_eq!( | ||
275 | 256., | ||
276 | eval_math_expression("exp2(8)", None).unwrap() | ||
277 | ); | ||
278 | } | ||
279 | #[test] | ||
280 | fn eval_exp() { | ||
281 | assert_eq!( | ||
282 | 20.0855369232 as f64, | ||
283 | eval_math_expression("exp(3)", None).unwrap() | ||
284 | ); | ||
285 | } | ||
286 | #[test] | ||
287 | fn eval_e_times_n() { | ||
288 | assert_eq!( | ||
289 | 0. as f64, | ||
290 | eval_math_expression("e0", None).unwrap() | ||
291 | ); | ||
292 | } | ||
262 | } | 293 | } |
diff --git a/src/readline.rs b/src/readline.rs index d689f95..8906a4f 100644 --- a/src/readline.rs +++ b/src/readline.rs | |||
@@ -7,6 +7,7 @@ use rustyline::error::ReadlineError; | |||
7 | use rustyline::highlight::Highlighter; | 7 | use rustyline::highlight::Highlighter; |
8 | use rustyline::hint::{Hinter, HistoryHinter}; | 8 | use rustyline::hint::{Hinter, HistoryHinter}; |
9 | use rustyline::{Context, Editor, Helper}; | 9 | use rustyline::{Context, Editor, Helper}; |
10 | use rustyline::validate::Validator; | ||
10 | 11 | ||
11 | use directories::ProjectDirs; | 12 | use directories::ProjectDirs; |
12 | 13 | ||
@@ -14,6 +15,7 @@ use regex::Regex; | |||
14 | 15 | ||
15 | use crate::error::CalcError; | 16 | use crate::error::CalcError; |
16 | use crate::eval_math_expression; | 17 | use crate::eval_math_expression; |
18 | use crate::lex::{CONSTANTS, FUNCTIONS}; | ||
17 | 19 | ||
18 | pub struct RLHelper { | 20 | pub struct RLHelper { |
19 | completer: FilenameCompleter, | 21 | completer: FilenameCompleter, |
@@ -51,20 +53,34 @@ impl Highlighter for LineHighlighter { | |||
51 | let op = eval_math_expression(line, prev_ans); | 53 | let op = eval_math_expression(line, prev_ans); |
52 | match op { | 54 | match op { |
53 | Ok(_) => { | 55 | Ok(_) => { |
54 | let constants = ["e", "pi"]; | 56 | let constants = CONSTANTS.keys(); |
55 | let functions = [ | 57 | let functions = FUNCTIONS.keys(); |
56 | "sin", "cos", "tan", "csc", "sec", "cot", "sinh", "cosh", "tanh", "ln", "log", | ||
57 | "sqrt", "ceil", "floor", "rad", "deg", "abs", "asin", "acos", "atan", "acsc", | ||
58 | "asec", "acot", | ||
59 | ]; | ||
60 | let ops = Regex::new(r"(?P<o>[\+-/\*%\^!])").unwrap(); | 58 | let ops = Regex::new(r"(?P<o>[\+-/\*%\^!])").unwrap(); |
61 | let mut coloured: String = ops.replace_all(line, "\x1b[35m$o\x1b[0m").into(); | 59 | let mut coloured: String = ops.replace_all(line, "\x1b[35m$o\x1b[0m").into(); |
62 | 60 | ||
63 | for c in &constants { | 61 | for c in constants { |
64 | coloured = coloured.replace(c, &format!("\x1b[33m{}\x1b[0m", c)); | 62 | // This regex consists of the following pieces: |
63 | // * the constant (`o`) to highlight (to be substituted as `{}` via `format!`), | ||
64 | // e.g. `e` or `pi`. | ||
65 | // * (optionally) an ANSI escape-code (`\x1b\[35m`) that is used to highlight | ||
66 | // a binary operator (e.g. `+`/`-`/...). With this one it is ensured that | ||
67 | // binary operators are always correctly detected after a constant | ||
68 | // (see the next bullet-point for why that's needed). | ||
69 | // * the following operator (e.g. `+`/`-`/...), a space or the end | ||
70 | // of the expression (to highlight e.g. `1+e` correctly). This is | ||
71 | // required to distinguish a constant in an expression from a function-call, | ||
72 | // e.g. `e+1` from `exp(1)`, without this matching logic, the `e` from | ||
73 | // `exp` would be improperly interpreted as constant. | ||
74 | // | ||
75 | // To make sure none of existing highlighting (i.e. highlighting | ||
76 | // of binary operators that happens before) breaks, the escape-codes & operator | ||
77 | // (called `r`) are appended after the highlighted constant. | ||
78 | let re = Regex::new(format!("(?P<o>{})(?P<r>(\x1b\\[35m)?([\\+-/\\*%\\^! ]|$))", c).as_str()).unwrap(); | ||
79 | coloured = re.replace_all(&coloured, "\x1b[33m$o\x1b[0m$r").into(); | ||
65 | } | 80 | } |
66 | for f in &functions { | 81 | for f in functions { |
67 | coloured = coloured.replace(f, &format!("\x1b[34m{}\x1b[0m", f)); | 82 | let re = Regex::new(format!("(?P<o>{})(?P<r>(\\(|$))", f).as_str()).unwrap(); |
83 | coloured = re.replace_all(&coloured, "\x1b[34m$o\x1b[0m$r").into(); | ||
68 | } | 84 | } |
69 | Owned(coloured) | 85 | Owned(coloured) |
70 | } | 86 | } |
@@ -75,6 +91,7 @@ impl Highlighter for LineHighlighter { | |||
75 | } | 91 | } |
76 | 92 | ||
77 | impl Highlighter for RLHelper { | 93 | impl Highlighter for RLHelper { |
94 | fn highlight_char(&self, _: &str, _: usize) -> bool { true } | ||
78 | fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> { | 95 | fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> { |
79 | self.highlighter.highlight_hint(hint) | 96 | self.highlighter.highlight_hint(hint) |
80 | } | 97 | } |
@@ -96,11 +113,14 @@ impl Completer for RLHelper { | |||
96 | } | 113 | } |
97 | 114 | ||
98 | impl Hinter for RLHelper { | 115 | impl Hinter for RLHelper { |
99 | fn hint(&self, line: &str, a: usize, b: &Context) -> Option<String> { | 116 | type Hint = String; |
117 | fn hint(&self, line: &str, a: usize, b: &Context) -> Option<Self::Hint> { | ||
100 | self.hinter.hint(line, a, b) | 118 | self.hinter.hint(line, a, b) |
101 | } | 119 | } |
102 | } | 120 | } |
103 | 121 | ||
122 | impl Validator for RLHelper {} | ||
123 | |||
104 | impl Helper for RLHelper {} | 124 | impl Helper for RLHelper {} |
105 | 125 | ||
106 | pub fn create_readline() -> Editor<RLHelper> { | 126 | pub fn create_readline() -> Editor<RLHelper> { |