aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Perry <avaglir@gmail.com>2019-03-29 15:20:27 -0400
committerNathan Perry <avaglir@gmail.com>2019-03-29 15:20:27 -0400
commit5f63ea4a1991159348c2e7d7f519c3ac6cd46454 (patch)
tree4af4ba0814287dd4ce6e7144c614f7def495c162
parent2685e6028dd775bcd618a3d8d2b22e32730454a3 (diff)
switch over to pest
-rw-r--r--Cargo.lock132
-rw-r--r--Cargo.toml3
-rw-r--r--src/commands/calc.pest79
-rw-r--r--src/commands/mod.rs5
-rw-r--r--src/commands/roll.rs422
-rw-r--r--src/main.rs3
6 files changed, 333 insertions, 311 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ff96643..8c54df1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -43,6 +43,11 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "arrayref"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "arrayvec"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -138,11 +143,25 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "block-buffer"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "build_const"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "byte-tools"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "byteorder"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -330,6 +349,14 @@ dependencies = [
]
[[package]]
+name = "digest"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "dotenv"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -437,6 +464,11 @@ dependencies = [
]
[[package]]
+name = "fake-simd"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "fern"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -508,6 +540,14 @@ dependencies = [
]
[[package]]
+name = "generic-array"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "glob"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -749,6 +789,11 @@ dependencies = [
]
[[package]]
+name = "maplit"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "matches"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -941,15 +986,6 @@ dependencies = [
]
[[package]]
-name = "nom"
-version = "4.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
name = "num-integer"
version = "0.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1086,6 +1122,45 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "pest"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "pest_derive"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pest_generator 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "pest_generator"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pest_meta 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "pest_meta"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "phf"
version = "0.7.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1574,6 +1649,17 @@ dependencies = [
]
[[package]]
+name = "sha-1"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "sha1"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1766,7 +1852,8 @@ dependencies = [
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "nom 4.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1936,6 +2023,16 @@ dependencies = [
]
[[package]]
+name = "typenum"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "ucd-trie"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "ucd-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2131,6 +2228,7 @@ dependencies = [
"checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
+"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
@@ -2141,7 +2239,9 @@ dependencies = [
"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
"checksum bindgen 0.37.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1b25ab82877ea8fe6ce1ce1f8ac54361f0218bad900af9eb11803994bf67c221"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
+"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
+"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
"checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa"
"checksum cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)" = "d01c69d08ff207f231f07196e30f84c70f1c815b04f980f8b7b01ff01f05eb92"
@@ -2163,6 +2263,7 @@ dependencies = [
"checksum ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "630391922b1b893692c6334369ff528dcc3a9d8061ccf4c803aa8f83cb13db5e"
"checksum diesel 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a2469cbcf1dfb9446e491cac4c493c2554133f87f7d041e892ac82e5cd36e863"
"checksum diesel_derives 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "62a27666098617d52c487a41f70de23d44a1dc1f3aa5877ceba2790fb1f1cab4"
+"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
"checksum dotenv 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d0a1279c96732bc6800ce6337b6a614697b0e74ae058dc03c62ebeb78b4d86"
"checksum dotenv 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eea1395d2df3b5344dc577809296d9578303296e8d105c408aa80ed67d598ef1"
"checksum dotenv_codegen 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "106db107983c2d0c10a9601cdd0c88514df87515e18d24df87e7ae0e2a50c3fa"
@@ -2174,6 +2275,7 @@ dependencies = [
"checksum evzht9h3nznqzwl 0.0.2 (git+https://github.com/mammothbane/rust-websocket)" = "<none>"
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
+"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum fern 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b48af88aaf938b11baef948a5599e66e709cf92854aa2b87c71f1bcf20f80a01"
"checksum flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2291c165c8e703ee54ef3055ad6188e3d51108e2ded18e9f2476e774fc5ad3d4"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
@@ -2184,6 +2286,7 @@ dependencies = [
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b"
"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
+"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum h2 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "ddb2b25a33e231484694267af28fec74ac63b5ccf51ee2065a5e313b834d836e"
"checksum http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fe67e3678f2827030e89cc4b9e7ecd16d52f132c0b940ab5005f88e821500f6a"
@@ -2210,6 +2313,7 @@ dependencies = [
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
+"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
@@ -2230,7 +2334,6 @@ dependencies = [
"checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17"
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
"checksum nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b"
-"checksum nom 4.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4836e9d6036552017e107edc598c97b2dee245161ff1b1ad4af215004774b354"
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
@@ -2247,6 +2350,10 @@ dependencies = [
"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
+"checksum pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "54f0c72a98d8ab3c99560bfd16df8059cc10e1f9a8e83e6e3b97718dd766e9c3"
+"checksum pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
+"checksum pest_generator 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "63120576c4efd69615b5537d3d052257328a4ca82876771d6944424ccfd9f646"
+"checksum pest_meta 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5a3492a4ed208ffc247adcdcc7ba2a95be3104f58877d0d02f0df39bf3efb5e"
"checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18"
"checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e"
"checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662"
@@ -2301,6 +2408,7 @@ dependencies = [
"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d"
"checksum serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d48f9f99cd749a2de71d29da5f948de7f2764cc5a9d7f3c97e3514d4ee6eabf2"
"checksum serenity 0.5.11 (git+https://github.com/mammothbane/serenity)" = "<none>"
+"checksum sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded"
"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"
"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
@@ -2339,6 +2447,8 @@ dependencies = [
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
"checksum typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6"
+"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
+"checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77"
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
"checksum unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3218ea14b4edcaccfa0df0a64a3792a2c32cc706f1b336e48867f9d3147f90"
diff --git a/Cargo.toml b/Cargo.toml
index d7f2c1d..19924ef 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -29,9 +29,10 @@ itertools = "^0.8"
serde = { version = "~1.0", features = ["derive"] }
serde_json = "~1.0"
timeago = "^0.1"
-nom = { version = "~4.2", features = ["verbose-errors"] }
statrs = "^0.10"
fnv = "~1.0"
+pest = "~2.1"
+pest_derive = "~2.1"
[dependencies.serenity]
default-features = false
diff --git a/src/commands/calc.pest b/src/commands/calc.pest
new file mode 100644
index 0000000..07eeddb
--- /dev/null
+++ b/src/commands/calc.pest
@@ -0,0 +1,79 @@
+num = {
+ hex
+ | oct
+ | binary
+ | float
+}
+
+float = @{ int ~ ( "." ~ ASCII_DIGIT*)? ~ (^"e" ~ int)? }
+ int = { "-"? ~ ASCII_DIGIT+ }
+
+hex = @{ "0x" ~ ASCII_HEX_DIGIT+ }
+oct = @{ "0o" ~ ASCII_OCT_DIGIT+ }
+binary = @{ "0b" ~ ASCII_BIN_DIGIT+ }
+
+infix = _{ add | sub | mul | div | modulo }
+ add = { "+" }
+ sub = { "-" }
+ modulo = { "%" | "mod" }
+ mul = { "*" }
+ div = { "/" }
+
+tight_infix = _{ dice | pow }
+ dice = { "d" }
+ pow = { "^" }
+
+trig = _{ sin | cos | tan | asin | acos | atan }
+ sin = { "sin" }
+ cos = { "cos" }
+ tan = { "tan" }
+ asin = { "asin" }
+ acos = { "acos" }
+ atan = { "atan" }
+
+htrig = _{ sinh | cosh | tanh | asinh | acosh | atanh }
+ sinh = { "sinh" }
+ cosh = { "cosh" }
+ tanh = { "tanh" }
+ asinh = { "asinh" }
+ acosh = { "acosh" }
+ atanh = { "atanh" }
+
+unary_prefix = _{ log | sqrt | sgn | htrig | trig | exp | abs | ceil | floor | round }
+ log = { "log" | "ln" }
+ sqrt = { "sqrt" }
+ sgn = { "sgn" }
+ exp = { "exp" }
+ abs = { "abs" }
+ ceil = { "ceil" }
+ floor = { "floor" }
+ round = { "round" }
+
+binary_prefix = _{ min | max | atan2 }
+ min = { "min" }
+ max = { "max" }
+ atan2 = { "atan2" }
+
+suffix = _{ factorial }
+ factorial = { "!" }
+
+term = _{ num | "(" ~ expr ~ ")" }
+
+suffix_expr = { term ~ suffix }
+unary_expr = ${ unary_prefix ~ ws+ ~ outfix_expr }
+binary_expr = ${ binary_prefix ~ ws+ ~ outfix_expr ~ ws+ ~ outfix_expr }
+
+tight = _{ (suffix_expr | term) ~ (tight_infix ~ tight)* }
+
+expr = { outfix_expr ~ (infix ~ outfix_expr)* }
+
+outfix_expr = _{
+ tight |
+ binary_expr |
+ unary_expr
+}
+
+calc = _{ SOI ~ expr ~ EOI }
+
+ws = _{ " " | "\t" | "\n" }
+WHITESPACE = _{ ws }
diff --git a/src/commands/mod.rs b/src/commands/mod.rs
index 1582977..6596a32 100644
--- a/src/commands/mod.rs
+++ b/src/commands/mod.rs
@@ -60,11 +60,6 @@ pub fn register_commands(f: StandardFramework) -> StandardFramework {
.desc("simulate rolling dice")
.guild_only(true)
.exec(roll::roll))
- .command("debug_expr", |c| c
- .desc("debug calculator expression")
- .owners_only(true)
- .exec(roll::debug_expr)
- )
.unrecognised_command(|ctx, msg, unrec| {
let url = match msg.content.split_whitespace().skip(1).next() {
Some(x) if x.starts_with("http") => x,
diff --git a/src/commands/roll.rs b/src/commands/roll.rs
index bdb729e..b447692 100644
--- a/src/commands/roll.rs
+++ b/src/commands/roll.rs
@@ -1,10 +1,3 @@
-use failure::Error;
-use itertools::Itertools;
-use nom::{
- self,
- double,
- types::CompleteStr,
-};
use rand::prelude::*;
use serenity::{
framework::standard::Args,
@@ -18,334 +11,177 @@ use crate::{
Result,
};
-#[derive(Clone, Debug, PartialEq)]
-enum CalcExpr {
- Binary(BinOp, Box<CalcExpr>, Box<CalcExpr>),
- Unary(UnaryOp, Box<CalcExpr>),
- Term(f64),
-}
-
-#[derive(Clone, Debug, PartialEq, Fail)]
-enum CalcParseError {
- #[fail(display = "couldn't consume entire expression. parsed: {:?}, remaining: '{}'.", parsed, remaining)]
- NotReadToEnd {
- parsed: Box<CalcExpr>,
- remaining: String,
- },
- #[fail(display = "nom error: {}", _0)]
- Nom(String),
-}
+#[derive(Parser)]
+#[grammar = "commands/calc.pest"]
+struct Calc;
-impl CalcExpr {
- pub fn parse<S: AsRef<str>>(input: S) -> Result<Box<Self>> {
- parse_expr(CompleteStr(input.as_ref()))
- .map_err(|e| CalcParseError::Nom(format!("{}", e)))
- .and_then(|(s, res)| {
- if s.len() != 0 {
- Err(CalcParseError::NotReadToEnd {
- parsed: res,
- remaining: s.as_ref().to_owned(),
- })
- } else {
- Ok(res)
- }
- })
- .map_err(Error::from)
- }
+impl Calc {
+ fn eval<S: AsRef<str>>(s: S) -> Result<f64> {
+ use pest::{
+ Parser,
+ prec_climber::PrecClimber,
+ iterators::{Pair, Pairs},
+ };
- pub fn pretty(&self) -> String {
- format!("```\n{}\n```", self.pretty_helper(0))
- }
+ use self::Rule::*;
- fn pretty_helper(&self, depth: usize) -> String {
- match self {
- CalcExpr::Binary(op, e1, e2) => {
- let lines = vec! {
- format!("{}{:?} ({}) {{", "\t".repeat(depth), op, self.compute()),
- e1.pretty_helper(depth + 1),
- e2.pretty_helper(depth + 1),
- "\t".repeat(depth) + "}",
+ lazy_static! {
+ static ref CLIMBER: PrecClimber<self::Rule> = {
+ use pest::prec_climber::{
+ Operator,
+ Assoc::*,
};
- lines.into_iter().join("\n")
- },
- CalcExpr::Unary(op, e) => {
- let lines = vec! {
- format!("{}{:?} ({}) {{", "\t".repeat(depth), op, self.compute()),
- e.pretty_helper(depth + 1),
- "\t".repeat(depth) + "}",
- };
-
- lines.into_iter().join("\n")
- },
- CalcExpr::Term(val) => {
- format!("{}{}", "\t".repeat(depth), val)
- }
+ PrecClimber::new(vec![
+ Operator::new(add, Left) | Operator::new(sub, Left) | Operator::new(modulo, Left),
+ Operator::new(mul, Left) | Operator::new(div, Left),
+ Operator::new(dice, Left),
+ Operator::new(pow, Right),
+ ])
+ };
}
- }
- pub fn compute(&self) -> f64 {
- use self::CalcExpr::*;
- use self::BinOp::*;
- use self::UnaryOp::*;
+ let result = Calc::parse(calc, s.as_ref())?;
- match self {
- Binary(bop, e1, e2) => {
- let r1 = e1.compute();
- let r2 = e2.compute();
- match bop {
- Add => r1 + r2,
- Sub => r1 - r2,
- Mul => r1 * r2,
- Div => r1 / r2,
- Mod => r1 % r2,
- Pow => r1.powf(r2),
- Min => r1.min(r2),
- Max => r1.max(r2),
- DiceRoll => {
- let dice_count = r1 as usize;
- let dice_faces = r2 as usize;
+ fn eval_single_pair(pair: Pair<self::Rule>) -> f64 {
+ match pair.as_rule() {
+ oct | hex | binary => {
+ let base = match pair.as_rule() {
+ hex => 16,
+ oct => 8,
+ binary => 2,
+ _ => unreachable!(),
+ };
- let mut rng = thread_rng();
- (0..dice_count).map(|_| rng.gen_range(1, dice_faces + 1)).sum::<usize>() as f64
- }
- }
- },
- Unary(uop, e) => {
- let r = e.compute();
+ u64::from_str_radix(&pair.as_str()[2..], base).unwrap() as f64
+ },
+ float => pair.as_str().parse::<f64>().unwrap(),
+ expr | num => eval_expr(pair.into_inner()),
+ unary_expr => {
+ let mut p = pair.into_inner();
- match uop {
- Neg => -r,
- Log => r.ln(),
- Sqrt => r.sqrt(),
- Sgn => r.signum(),
- Sin => r.sin(),
- Cos => r.cos(),
- Tan => r.tan(),
- Factorial => statrs::function::gamma::gamma(r),
- Exp => r.exp(),
- Abs => r.abs(),
- Ceil => r.ceil(),
- Floor => r.floor(),
- Round => r.round(),
- }
- },
- Term(v) => *v,
- }
- }
-}
+ let op = p.next().unwrap();
+ let arg = eval_expr(p);
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-enum BinOp {
- Add,
- Sub,
- Mul,
- Div,
- Mod,
- Pow,
- Min,
- Max,
- DiceRoll,
-}
+ match op.as_rule() {
+ log => arg.ln(),
+ sqrt => arg.sqrt(),
+ sgn => arg.signum(),
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-enum UnaryOp {
- Log,
- Sqrt,
- Sgn,
- Exp,
- Sin,
- Cos,
- Tan,
- Factorial,
- Neg,
- Ceil,
- Floor,
- Abs,
- Round,
-}
+ sin => arg.sin(),
+ cos => arg.cos(),
+ tan => arg.tan(),
+ asin => arg.asin(),
+ acos => arg.acos(),
+ atan => arg.atan(),
-fn parse_expr(input: CompleteStr) -> nom::IResult<CompleteStr, Box<CalcExpr>> {
- ws!(input, up_to_add_sub_mod)
-}
+ sinh => arg.sinh(),
+ cosh => arg.cosh(),
+ tanh => arg.tanh(),
+ asinh => arg.asinh(),
+ acosh => arg.acosh(),
+ atanh => arg.atanh(),
-fn parse_add_sub_mod(input: CompleteStr) -> nom::IResult<CompleteStr, Box<CalcExpr>> {
- ws!(input, do_parse!(
- tpl: tuple!(up_to_div_mul, ws!(one_of!("+-%")), parse_expr) >>
- ({
- let (expr1, op, expr2) = tpl;
- let op = match op {
- '+' => BinOp::Add,
- '-' => BinOp::Sub,
- '%' => BinOp::Mod,
- _ => unreachable!(),
- };
- Box::new(CalcExpr::Binary(op, expr1, expr2))
- })
- ))
-}
+ exp => arg.exp(),
+ abs => arg.abs(),
+ ceil => arg.ceil(),
+ floor => arg.floor(),
+ round => arg.round(),
+ _ => unreachable!(),
+ }
+ },
+ binary_expr => {
+ let mut p = pair.into_inner();
-fn parse_div_mul(input: CompleteStr) -> nom::IResult<CompleteStr, Box<CalcExpr>> {
- ws!(input, do_parse!(
- tpl: tuple!(up_to_binary_prefix, ws!(one_of!("/*")), parse_expr) >>
- ({
- let (expr1, op, expr2) = tpl;
- let op = match op {
- '*' => BinOp::Mul,
- '/' => BinOp::Div,
- '^' => BinOp::Pow,
- _ => unreachable!(),
- };
- Box::new(CalcExpr::Binary(op, expr1, expr2))
- })
- ))
-}
+ let op = p.next().unwrap();
-fn parse_binary_prefix(input: CompleteStr) -> nom::IResult<CompleteStr, Box<CalcExpr>> {
- ws!(input, do_parse!(
- op: ws!(alt_complete!(
- tag!("min") => { |_| BinOp::Min } |
- tag!("max") => { |_| BinOp::Max }
- )) >>
- expr1: up_to_unary_prefix >>
- expr2: up_to_unary_prefix >>
- (Box::new(CalcExpr::Binary(op, expr1, expr2)))
- ))
-}
+ let arg1 = eval_single_pair(p.next().unwrap());
+ let arg2 = eval_single_pair(p.next().unwrap());
-fn parse_unary_prefix(input: CompleteStr) -> nom::IResult<CompleteStr, Box<CalcExpr>> {
- ws!(input, do_parse!(
- op: ws!(alt_complete!(
- tag!("log") => { |_| UnaryOp::Log }
- | tag!("sqrt") => { |_| UnaryOp::Sqrt }
- | tag!("sin") => { |_| UnaryOp::Sin }
- | tag!("cos") => { |_| UnaryOp::Cos }
- | tag!("tan") => { |_| UnaryOp::Tan }
- | tag!("sgn") => { |_| UnaryOp::Sgn }
- | tag!("exp") => { |_| UnaryOp::Exp }
- | tag!("ceil") => { |_| UnaryOp::Ceil }
- | tag!("floor") => { |_| UnaryOp::Floor }
- | tag!("abs") => { |_| UnaryOp::Abs }
- | tag!("round") => { |_| UnaryOp::Round }
- )) >>
- expr: up_to_dice >>
- (Box::new(CalcExpr::Unary(op, expr)))
- ))
-}
+ assert!(p.next().is_none());
-fn parse_dice(input: CompleteStr) -> nom::IResult<CompleteStr, Box<CalcExpr>> {
- ws!(input, do_parse!(
- tpl: separated_pair!(up_to_pow, ws!(char!('d')), up_to_pow) >>
- ({
- let (expr1, expr2) = tpl;
- Box::new(CalcExpr::Binary(BinOp::DiceRoll, expr1, expr2))
- })
- ))
-}
+ match op.as_rule() {
+ min => arg1.min(arg2),
+ max => arg1.max(arg2),
+ atan2 => arg1.atan2(arg2),
+ _ => unreachable!(),
+ }
+ },
+ suffix_expr => {
+ let mut p = pair.into_inner();
-fn parse_pow(input: CompleteStr) -> nom::IResult<CompleteStr, Box<CalcExpr>> {
- ws!(input, do_parse!(
- tpl: separated_pair!(up_to_neg, ws!(char!('^')), up_to_neg) >>
- ({
- let (expr1, expr2) = tpl;
- Box::new(CalcExpr::Binary(BinOp::Pow, expr1, expr2))
- })
- ))
-}
+ let arg = eval_expr(p.next().unwrap().into_inner());
+ let op = p.next().unwrap();
-fn parse_neg(input: CompleteStr) -> nom::IResult<CompleteStr, Box<CalcExpr>> {
- ws!(input, do_parse!(
- expr: ws!(preceded!(char!('-'), up_to_suffix)) >>
- (Box::new(CalcExpr::Unary(UnaryOp::Neg, expr)))
- ))
-}
+ assert!(p.next().is_none());
-fn parse_suffix(input: CompleteStr) -> nom::IResult<CompleteStr, Box<CalcExpr>> {
- ws!(input, do_parse!(
- expr: terminated!(parse_term_or_paren, ws!(tag!("!"))) >>
- (Box::new(CalcExpr::Unary(UnaryOp::Factorial, expr)))
- ))
-}
+ match op.as_rule() {
+ factorial => statrs::function::gamma::gamma(arg + 1.),
+ _ => unreachable!(),
+ }
+ },
+ _ => unreachable!(),
+ }
+ }
-fn parse_term_or_paren(input: CompleteStr) -> nom::IResult<CompleteStr, Box<CalcExpr>> {
- ws!(input, alt_complete!(
- delimited!(char!('('), parse_expr, char!(')')) |
- do_parse!(
- dat: double >>
- (Box::new(CalcExpr::Term(dat)))
- )
- ))
-}
+ fn eval_expr(p: Pairs<self::Rule>) -> f64 {
+ CLIMBER.climb(
+ p,
+ eval_single_pair,
+ |lhs: f64, op, rhs: f64| match op.as_rule() {
+ add => lhs + rhs,
+ sub => lhs - rhs,
+ mul => lhs * rhs,
+ div => lhs / rhs,
+ pow => lhs.powf(rhs),
+ dice => {
+ let dice_count = lhs as usize;
+ let dice_faces = rhs as usize;
-macro_rules! up_to {
- ($up_to_name:ident, $fn_name:ident, $prev:ident) => (
- fn $up_to_name(input: CompleteStr) -> nom::IResult<CompleteStr, Box<CalcExpr>> {
- alt_complete!(input, $fn_name | $prev)
+ let mut rng = thread_rng();
+ (0..dice_count).map(|_| rng.gen_range(1, dice_faces + 1)).sum::<usize>() as f64
+ },
+ _ => unreachable!(),
+ }
+ )
}
- )
-}
-up_to! { up_to_add_sub_mod, parse_add_sub_mod, up_to_div_mul }
-up_to! { up_to_div_mul, parse_div_mul, up_to_binary_prefix }
-up_to! { up_to_binary_prefix, parse_binary_prefix, up_to_unary_prefix }
-up_to! { up_to_unary_prefix, parse_unary_prefix, up_to_dice }
-up_to! { up_to_dice, parse_dice, up_to_pow }
-up_to! { up_to_pow, parse_pow, up_to_neg }
-up_to! { up_to_neg, parse_neg, up_to_suffix }
-up_to! { up_to_suffix, parse_suffix, parse_term_or_paren }
+ Ok(eval_expr(result))
+ }
+}
#[cfg(test)]
mod test {
use super::*;
#[test]
- fn test_parse_usize() {
- let (s, expr) = parse_expr("123".into()).unwrap();
- assert_eq!(s.0, "");
- assert_eq!(expr, box CalcExpr::Term(123.));
+ fn test_calc_basics() {
+ assert_eq!(3., Calc::eval("1 + 2").unwrap());
+ assert_eq!(3.0f64.ln(), Calc::eval("log 3").unwrap());
+ assert!(6. - Calc::eval("3!").unwrap() < 0.0001);
+ assert_eq!(3., Calc::eval("max 3 2").unwrap());
}
#[test]
- fn test_parens() {
- let (s, expr) = parse_expr("(123)".into()).unwrap();
- assert_eq!(s.0, "");
- assert_eq!(expr, box CalcExpr::Term(123.));
+ fn test_binary_unary() {
+ assert_eq!(3.0f64.ln(), Calc::eval("max log 3 log 2").unwrap());
}
#[test]
- fn test_infix() {
- let (s, expr) = parse_expr("1 + 2".into()).unwrap();
- assert_eq!(s.0, "");
- assert_eq!(expr, box CalcExpr::Binary(BinOp::Add, box CalcExpr::Term(1.), box CalcExpr::Term(2.)))
+ fn test_prefix_suffix() {
+ assert!(6. - Calc::eval("abs 3!").unwrap() < 0.0001);
}
-
}
pub fn roll(_ctx: &mut Context, msg: &Message, args: Args) -> Result<()> {
- match CalcExpr::parse(args.rest()) {
- Ok(expr) => send(msg.channel_id, &format!("{}", expr.compute()), msg.tts),
- Err(e) => {
- let parse_err = e.downcast::<CalcParseError>().unwrap();
- if let CalcParseError::NotReadToEnd { remaining, .. } = parse_err {
- error!("parsing '{}': failed to consume '{}'", args.rest(), remaining);
- send(msg.channel_id, "I COULDN'T READ THAT YOU FUCK", msg.tts)
- } else {
- Err(parse_err.into())
- }
+ match Calc::eval(args.rest()) {
+ Ok(result) => {
+ debug!("got calc result '{}'", result);
+ send(msg.channel_id, &format!("{}", result), msg.tts)
},
- }
-}
-
-pub fn debug_expr(_ctx: &mut Context, msg: &Message, args: Args) -> Result<()> {
- match CalcExpr::parse(args.rest()) {
- Ok(expr) => send(msg.channel_id, &expr.pretty(), false),
Err(e) => {
- let parse_err = e.downcast::<CalcParseError>().unwrap();
- if let CalcParseError::NotReadToEnd { remaining, parsed } = parse_err {
- send(msg.channel_id, &format!("parsed this expr: {}\nwith remaining text: '{}'", parsed.pretty(), remaining), false)
- } else {
- Err(parse_err.into())
- }
- }
+ error!("error encountered reading calc '{}': {}", args.rest(), e);
+ send(msg.channel_id, "I COULDN'T READ THAT YOU FUCK", msg.tts)
+ },
}
}
diff --git a/src/main.rs b/src/main.rs
index 177f726..1d1c6dd 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -18,7 +18,8 @@ extern crate fnv;
#[cfg_attr(test, macro_use)] extern crate itertools;
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate log;
-#[macro_use] extern crate nom;
+extern crate pest;
+#[macro_use] extern crate pest_derive;
extern crate rand;
extern crate regex;
extern crate reqwest;