From e6e58047f605b4317a507803bbdf6573f72199ba Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Mon, 10 Jul 2023 18:21:51 -0400 Subject: [PATCH] Refactor operation emitter to distinguish filters/sorters/itemops from standalone functions --- Cargo.lock | 592 ++++++++++-------- interpreter/src/faye.rs | 1 + interpreter/src/interpretor.rs | 44 +- interpreter/src/lang/dictionary.rs | 62 +- interpreter/src/lang/filter.rs | 410 +++--------- interpreter/src/lang/filter_replace.rs | 127 +--- interpreter/src/lang/function.rs | 5 +- interpreter/src/lang/iter_block.rs | 95 +-- interpreter/src/lang/mod.rs | 2 +- interpreter/src/lang/operation.rs | 33 +- interpreter/src/lang/sorter.rs | 109 +--- interpreter/src/lang/utility.rs | 23 - interpreter/src/lang/vocabulary/files.rs | 6 +- .../lang/vocabulary/filters/empty_filter.rs | 2 +- .../filters/field/field_match_filter.rs | 2 +- .../lang/vocabulary/filters/index_filter.rs | 4 +- .../lang/vocabulary/filters/range_filter.rs | 8 +- .../src/lang/vocabulary/filters/unique.rs | 6 +- .../src/lang/vocabulary/item_ops/add.rs | 9 +- .../src/lang/vocabulary/item_ops/brackets.rs | 10 +- .../src/lang/vocabulary/item_ops/branch.rs | 6 +- .../src/lang/vocabulary/item_ops/compare.rs | 3 + .../src/lang/vocabulary/item_ops/constant.rs | 2 +- .../lang/vocabulary/item_ops/constructor.rs | 11 +- .../src/lang/vocabulary/item_ops/empty.rs | 4 +- .../lang/vocabulary/item_ops/field_assign.rs | 4 +- .../lang/vocabulary/item_ops/logical_and.rs | 11 +- .../lang/vocabulary/item_ops/logical_or.rs | 11 +- .../src/lang/vocabulary/item_ops/mod.rs | 2 + .../src/lang/vocabulary/item_ops/negate.rs | 2 +- .../src/lang/vocabulary/item_ops/not.rs | 2 +- .../vocabulary/item_ops/remove_variable.rs | 4 +- .../vocabulary/item_ops/retrieve_field.rs | 49 ++ .../vocabulary/item_ops/retrieve_variable.rs | 27 +- .../src/lang/vocabulary/item_ops/subtract.rs | 9 +- .../vocabulary/item_ops/variable_declare.rs | 2 +- interpreter/src/lang/vocabulary/mod.rs | 2 + interpreter/src/lang/vocabulary/repeat.rs | 39 +- .../lang/vocabulary/sorters/empty_sorter.rs | 2 +- interpreter/src/lang/vocabulary/union.rs | 13 +- .../src/lang/vocabulary/variable_iter.rs | 177 ++++++ interpreter/tests/single_line.rs | 23 +- player/Cargo.toml | 1 + 43 files changed, 932 insertions(+), 1024 deletions(-) create mode 100644 interpreter/src/lang/vocabulary/item_ops/retrieve_field.rs create mode 100644 interpreter/src/lang/vocabulary/variable_iter.rs diff --git a/Cargo.lock b/Cargo.lock index d31410a..902a467 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr 2.5.0", ] @@ -70,15 +70,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.69" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "atty" @@ -111,9 +111,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "bindgen" -version = "0.61.0" +version = "0.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a022e58a142a46fea340d68012b9201c094e93ec3d033a944a24f8fd4a4f09a" +checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" dependencies = [ "bitflags", "cexpr", @@ -123,10 +123,10 @@ dependencies = [ "peeking_take_while", "proc-macro2", "quote", - "regex 1.7.1", + "regex 1.9.1", "rustc-hash", "shlex", - "syn", + "syn 1.0.109", ] [[package]] @@ -137,18 +137,18 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bliss-audio-aubio-rs" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe01698d293ee91e334339d6436f17eac30d94bebaa668c5799c8206384dfeb1" +checksum = "fb6b0b33b16bdb7489951c56294f4f9c321d91047ae29aebb91dfcd84a09086f" dependencies = [ "bliss-audio-aubio-sys", ] [[package]] name = "bliss-audio-aubio-sys" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ef9fab7b922bdd057bb06fa2a2fa79d2a93bec3dd576320511cb3dfe21e78a9" +checksum = "bd4d47e7b82164c30a806717cf5562f87e5b136b79b3d942c9ad789134116f2f" dependencies = [ "cc", "fftw-sys", @@ -217,9 +217,9 @@ checksum = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8" [[package]] name = "bumpalo" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "bytemuck" @@ -308,9 +308,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ed9a53e5d4d9c573ae844bfac6872b159cb1d1585a83b29e7a64b7eef7332a" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" dependencies = [ "glob", "libc", @@ -334,15 +334,15 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.23" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "atty", "bitflags", "clap_derive", "clap_lex", - "indexmap", + "indexmap 1.9.3", "once_cell", "strsim 0.10.0", "termcolor", @@ -351,15 +351,15 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.2.18" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" dependencies = [ "heck 0.4.1", "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -383,22 +383,22 @@ dependencies = [ [[package]] name = "console" -version = "0.15.5" +version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" dependencies = [ "encode_unicode", "lazy_static 1.4.0", "libc", "unicode-width", - "windows-sys 0.42.0", + "windows-sys", ] [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "coreaudio-rs" @@ -412,9 +412,9 @@ dependencies = [ [[package]] name = "coreaudio-sys" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9444b94b8024feecc29e01a9706c69c1e26bfee480221c90764200cfd778fb" +checksum = "f034b2258e6c4ade2f73bf87b21047567fb913ee9550837c2316d139b0262b24" dependencies = [ "bindgen", ] @@ -445,9 +445,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] @@ -478,7 +478,7 @@ dependencies = [ "oorandom", "plotters", "rayon", - "regex 1.7.1", + "regex 1.9.1", "serde", "serde_cbor", "serde_derive", @@ -513,9 +513,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ "cfg-if", "crossbeam-utils", @@ -534,14 +534,14 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.8.0", + "memoffset 0.9.0", "scopeguard", ] @@ -557,9 +557,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if", ] @@ -576,9 +576,9 @@ dependencies = [ [[package]] name = "csv" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b015497079b9a9d69c02ad25de6c0a6edef051ea6360a327d0bd05802ef64ad" +checksum = "626ae34994d3d8d668f4269922248239db4ae42d538b14c398b74a52208e8086" dependencies = [ "csv-core", "itoa", @@ -595,16 +595,6 @@ dependencies = [ "memchr 2.5.0", ] -[[package]] -name = "ctor" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" -dependencies = [ - "quote", - "syn", -] - [[package]] name = "dbus" version = "0.6.5" @@ -632,9 +622,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", "crypto-common", @@ -696,10 +686,16 @@ dependencies = [ "atty", "humantime", "log", - "regex 1.7.1", + "regex 1.9.1", "termcolor", ] +[[package]] +name = "equivalent" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -738,9 +734,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", "miniz_oxide", @@ -771,9 +767,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -781,9 +777,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -817,6 +813,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "hashlink" version = "0.7.0" @@ -852,12 +854,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "humantime" @@ -867,26 +866,46 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "indexmap" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", ] [[package]] -name = "indicatif" -version = "0.17.3" +name = "indexmap" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef509aa9bc73864d6756f0d34d35504af3cf0844373afe9b8669a5b8005a729" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + +[[package]] +name = "indicatif" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" dependencies = [ "console", + "instant", "number_prefix", "portable-atomic", "unicode-width", ] +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + [[package]] name = "itertools" version = "0.10.5" @@ -898,9 +917,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" [[package]] name = "jni" @@ -933,9 +952,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -970,15 +989,15 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.140" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libdbus-sys" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f8d7ae751e1cb825c840ae5e682f59b098cdfd213c350ac268b61449a5f58a0" +checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72" dependencies = [ "pkg-config", ] @@ -1006,9 +1025,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", @@ -1016,12 +1035,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "m3u8-rs" @@ -1043,10 +1059,11 @@ dependencies = [ [[package]] name = "matrixmultiply" -version = "0.3.2" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add85d4dd35074e6fedc608f8c8f513a3548619a9024b751949ef0e8e45a4d84" +checksum = "090126dc04f95dc0d1c1c91f61bdd474b3930ca064c1edc8a849da2c6cbe1e77" dependencies = [ + "autocfg", "rawpointer", ] @@ -1076,18 +1093,18 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" @@ -1107,9 +1124,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -1136,7 +1153,7 @@ dependencies = [ name = "muss" version = "0.9.0" dependencies = [ - "clap 3.2.23", + "clap 3.2.25", "console", "lazy_static 1.4.0", "muss-interpreter", @@ -1154,7 +1171,7 @@ dependencies = [ "m3u8-rs", "mpd", "rand 0.8.5", - "regex 1.7.1", + "regex 1.9.1", "rusqlite", "shellexpand", "sqlparser", @@ -1166,7 +1183,7 @@ dependencies = [ name = "muss-m3u8" version = "0.9.0" dependencies = [ - "clap 3.2.23", + "clap 3.2.25", "m3u8-rs", "muss-interpreter", ] @@ -1217,7 +1234,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af5a8477ac96877b5bd1fd67e0c28736c12943aba24eda92b127e036b0c8f400" dependencies = [ - "indexmap", + "indexmap 1.9.3", "itertools", "ndarray", "noisy_float", @@ -1357,7 +1374,7 @@ checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1392,11 +1409,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi 0.3.2", "libc", ] @@ -1418,7 +1435,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1452,9 +1469,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "oorandom" @@ -1470,18 +1487,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "os_str_bytes" -version = "6.4.1" +version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" - -[[package]] -name = "output_vt100" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66" -dependencies = [ - "winapi 0.3.9", -] +checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" [[package]] name = "parking_lot" @@ -1495,15 +1503,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.3.5", "smallvec", - "windows-sys 0.45.0", + "windows-targets 0.48.1", ] [[package]] @@ -1514,9 +1522,9 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "pest" -version = "2.5.6" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cbd939b234e95d72bc393d51788aec68aeeb5d51e748ca08ff3aad58cb722f7" +checksum = "f73935e4d55e2abf7f130186537b19e7a4abc886a0252380b59248af473a3fc9" dependencies = [ "thiserror", "ucd-trie", @@ -1524,9 +1532,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.5.6" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a81186863f3d0a27340815be8f2078dd8050b14cd71913db9fbda795e5f707d7" +checksum = "aef623c9bbfa0eedf5a0efba11a5ee83209c326653ca31ff019bec3a95bfff2b" dependencies = [ "pest", "pest_generator", @@ -1534,22 +1542,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.5.6" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75a1ef20bf3193c15ac345acb32e26b3dc3223aff4d77ae4fc5359567683796b" +checksum = "b3e8cba4ec22bada7fc55ffe51e2deb6a0e0db2d0b7ab0b103acc80d2510c190" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn", + "syn 2.0.25", ] [[package]] name = "pest_meta" -version = "2.5.6" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e3b284b1f13a20dc5ebc90aff59a51b8d7137c221131b52a7260c08cbc1cc80" +checksum = "a01f71cb40bd8bb94232df14b946909e14660e33fc05db3e50ae2a82d7ea0ca0" dependencies = [ "once_cell", "pest", @@ -1558,15 +1566,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "plotters" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" dependencies = [ "num-traits", "plotters-backend", @@ -1577,24 +1585,24 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" [[package]] name = "plotters-svg" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" dependencies = [ "plotters-backend", ] [[package]] name = "portable-atomic" -version = "0.3.19" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b" +checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" [[package]] name = "ppv-lite86" @@ -1604,13 +1612,11 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "pretty_assertions" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" dependencies = [ - "ctor", "diff", - "output_vt100", "yansi", ] @@ -1642,7 +1648,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -1659,9 +1665,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.52" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" +checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" dependencies = [ "unicode-ident", ] @@ -1681,9 +1687,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.26" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] @@ -1748,9 +1754,9 @@ dependencies = [ [[package]] name = "raw-window-handle" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f851a03551ceefd30132e447f07f96cb7011d6b658374f3aed847333adb5559" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" [[package]] name = "rawpointer" @@ -1797,9 +1803,9 @@ dependencies = [ [[package]] name = "realfft" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6b8e8f0c6d2234aa58048d7290c60bf92cd36fd2888cd8331c66ad4f2e1d2" +checksum = "953d9f7e5cdd80963547b456251296efc2626ed4e3cbf36c869d9564e0220571" dependencies = [ "rustfft 6.1.0", ] @@ -1813,6 +1819,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" version = "0.4.3" @@ -1820,7 +1835,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", - "redox_syscall", + "redox_syscall 0.2.16", "thiserror", ] @@ -1839,13 +1854,25 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.1" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ - "aho-corasick 0.7.20", + "aho-corasick 1.0.2", "memchr 2.5.0", - "regex-syntax 0.6.28", + "regex-automata", + "regex-syntax 0.7.3", +] + +[[package]] +name = "regex-automata" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf" +dependencies = [ + "aho-corasick 1.0.2", + "memchr 2.5.0", + "regex-syntax 0.7.3", ] [[package]] @@ -1856,9 +1883,9 @@ checksum = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" [[package]] name = "remove_dir_all" @@ -1975,9 +2002,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" [[package]] name = "same-file" @@ -2011,9 +2038,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.156" +version = "1.0.170" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "314b5b092c0ade17c00142951e50ced110ec27cea304b1037c6969246c2469a4" +checksum = "a56657f512baabca8f840542f9ca8152aecf182c473c26e46e58d6aab4f6e439" dependencies = [ "serde_derive", ] @@ -2030,13 +2057,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.156" +version = "1.0.170" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7e29c4601e36bcec74a223228dce795f4cd3616341a4af93520ca1a837c087d" +checksum = "77d477848e6b23adba0db397777d5aad864555bc17fd9c89abb3b8009788b7b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.25", ] [[package]] @@ -2052,9 +2079,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.94" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" +checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" dependencies = [ "itoa", "ryu", @@ -2078,13 +2105,13 @@ checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -2104,9 +2131,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "sqlparser" @@ -2141,7 +2168,7 @@ dependencies = [ "quote", "serde", "serde_derive", - "syn", + "syn 1.0.109", ] [[package]] @@ -2157,7 +2184,7 @@ dependencies = [ "serde_derive", "serde_json", "sha1", - "syn", + "syn 1.0.109", ] [[package]] @@ -2199,14 +2226,14 @@ dependencies = [ "heck 0.3.3", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "symphonia" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3671dd6f64f4f9d5c87179525054cfc1f60de23ba1f193bd6ceab812737403f1" +checksum = "62e48dba70095f265fdb269b99619b95d04c89e619538138383e63310b14d941" dependencies = [ "lazy_static 1.4.0", "symphonia-bundle-flac", @@ -2226,9 +2253,9 @@ dependencies = [ [[package]] name = "symphonia-bundle-flac" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dc2deed3204967871ba60f913378f95820cb47a2fe9b2eef5a9eedb417dfdc8" +checksum = "7f23b0482a7cb18fcdf9981ab0b78df800ef0080187d294650023c462439058d" dependencies = [ "log", "symphonia-core", @@ -2238,9 +2265,9 @@ dependencies = [ [[package]] name = "symphonia-bundle-mp3" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55a0846e7a2c9a8081ff799fc83a975170417ad2a143f644a77ec2e3e82a2b73" +checksum = "0f31d7fece546f1e6973011a9eceae948133bbd18fd3d52f6073b1e38ae6368a" dependencies = [ "bitflags", "lazy_static 1.4.0", @@ -2251,9 +2278,9 @@ dependencies = [ [[package]] name = "symphonia-codec-aac" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fcdd4a10695ca0528572360ec020586320357350eb62791693667e7de8c871a" +checksum = "68bdd75b25ce4b84b12a4bd20bfea2460c2dbd7fc1d227ef5533504d3168109d" dependencies = [ "lazy_static 1.4.0", "log", @@ -2262,9 +2289,9 @@ dependencies = [ [[package]] name = "symphonia-codec-adpcm" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5cfb8d4405e26eb9593157dc45b05e102b8d774b38ed2a95946d6bb9e26e3e" +checksum = "870e7dc1865d818c7b6318879d060553a73a3b2a3b8443dff90910f10ac41150" dependencies = [ "log", "symphonia-core", @@ -2272,9 +2299,9 @@ dependencies = [ [[package]] name = "symphonia-codec-alac" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c49e1b209318bcefa7ff452bd85f1f593210943a7d9786b7d4250e8991a7449c" +checksum = "3a27e8763d1c9eff666faf903e73a99d4de2f7a93fca4e3c214c1d68432903b9" dependencies = [ "log", "symphonia-core", @@ -2282,9 +2309,9 @@ dependencies = [ [[package]] name = "symphonia-codec-pcm" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb9a9f0b9991cccf3217b74644af412d5d082a4815e5e2943f26e0ecabdf3c9" +checksum = "47f1fbd220a06a641c8ce2ddad10f5ef6ee5cc0c54d9044d25d43b0d3119deaa" dependencies = [ "log", "symphonia-core", @@ -2292,9 +2319,9 @@ dependencies = [ [[package]] name = "symphonia-codec-vorbis" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfed6f7b6bfa21d7cef1acefc8eae5db80df1608a1aca91871b07cbd28d7b74" +checksum = "3953397e3506aa01350c4205817e4f95b58d476877a42f0458d07b665749e203" dependencies = [ "log", "symphonia-core", @@ -2303,9 +2330,9 @@ dependencies = [ [[package]] name = "symphonia-core" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9567e2d8a5f866b2f94f5d366d811e0c6826babcff6d37de9e1a6690d38869" +checksum = "f7c73eb88fee79705268cc7b742c7bc93a7b76e092ab751d0833866970754142" dependencies = [ "arrayvec", "bitflags", @@ -2316,9 +2343,9 @@ dependencies = [ [[package]] name = "symphonia-format-isomp4" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1818f6f54b4eaba5ec004a8dbcca637c57e617eb1ff4c9addbd3fc065eba437" +checksum = "ffdf14bae5cf352032416bc64151e5d6242d29d33cbf3238513b44d4427a1efb" dependencies = [ "encoding_rs", "log", @@ -2329,9 +2356,9 @@ dependencies = [ [[package]] name = "symphonia-format-mkv" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bd22f2def8c8f078495ad66111648bfc7d5222ee33774f2077cb665588f3119" +checksum = "f5c61dfc851ad25d4043d8c231d8617e8f7cd02a6cc0edad21ade21848d58895" dependencies = [ "lazy_static 1.4.0", "log", @@ -2342,9 +2369,9 @@ dependencies = [ [[package]] name = "symphonia-format-ogg" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "474df6e86b871dcb56913130bada1440245f483057c4a2d8a2981455494c4439" +checksum = "9bf1a00ccd11452d44048a0368828040f778ae650418dbd9d8765b7ee2574c8d" dependencies = [ "log", "symphonia-core", @@ -2354,9 +2381,9 @@ dependencies = [ [[package]] name = "symphonia-format-wav" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06679bd5646b3037300f88891dfc8a6e1cc4e1133206cc17a98e5d7c22f88296" +checksum = "da76614728fa27c003bdcdfbac51396bd8fcbf94c95fe8e62f1d2bac58ef03a4" dependencies = [ "log", "symphonia-core", @@ -2365,9 +2392,9 @@ dependencies = [ [[package]] name = "symphonia-metadata" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd35c263223ef6161000be79b124a75de3e065eea563bf3ef169b3e94c7bb2e" +checksum = "89c3e1937e31d0e068bbe829f66b2f2bfaa28d056365279e0ef897172c3320c0" dependencies = [ "encoding_rs", "lazy_static 1.4.0", @@ -2377,9 +2404,9 @@ dependencies = [ [[package]] name = "symphonia-utils-xiph" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce340a6c33ac06cb42de01220308ec056e8a2a3d5cc664aaf34567392557136b" +checksum = "a450ca645b80d69aff8b35576cbfdc7f20940b29998202aab910045714c951f8" dependencies = [ "symphonia-core", "symphonia-metadata", @@ -2396,6 +2423,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tempdir" version = "0.3.7" @@ -2432,22 +2470,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.39" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c" +checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.39" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e" +checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.25", ] [[package]] @@ -2492,17 +2530,17 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" [[package]] name = "toml_edit" -version = "0.19.7" +version = "0.19.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc18466501acd8ac6a3f615dd29a3438f8ca6bb3b19537138b3106e575621274" +checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" dependencies = [ - "indexmap", + "indexmap 2.0.0", "toml_datetime", "winnow", ] @@ -2525,9 +2563,9 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-trie" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "unicase" @@ -2540,9 +2578,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" [[package]] name = "unicode-segmentation" @@ -2616,9 +2654,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2626,24 +2664,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.25", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2651,28 +2689,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.25", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", @@ -2734,28 +2772,13 @@ dependencies = [ "windows_x86_64_msvc 0.37.0", ] -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-sys" version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.2", ] [[package]] @@ -2764,21 +2787,42 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm", + "windows_aarch64_gnullvm 0.42.2", "windows_aarch64_msvc 0.42.2", "windows_i686_gnu 0.42.2", "windows_i686_msvc 0.42.2", "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm", + "windows_x86_64_gnullvm 0.42.2", "windows_x86_64_msvc 0.42.2", ] +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.37.0" @@ -2791,6 +2835,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.37.0" @@ -2803,6 +2853,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.37.0" @@ -2815,6 +2871,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.37.0" @@ -2827,12 +2889,24 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.37.0" @@ -2846,10 +2920,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] -name = "winnow" -version = "0.3.6" +name = "windows_x86_64_msvc" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d020b441f92996c80d94ae9166e8501e59c7bb56121189dc9eab3bd8216966" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winnow" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" dependencies = [ "memchr 2.5.0", ] diff --git a/interpreter/src/faye.rs b/interpreter/src/faye.rs index e632bf4..72c10a3 100644 --- a/interpreter/src/faye.rs +++ b/interpreter/src/faye.rs @@ -134,6 +134,7 @@ where Ok(stmt) => stmt, Err(e) => return Some(Err(error_with_ctx(e, self.tokenizer.current_line()))), }; + //println!("Final parsed op: {}", stmt); #[cfg(debug_assertions)] if !self.buffer.is_empty() { panic!("Token buffer was not emptied! (rem: {:?})", self.buffer) diff --git a/interpreter/src/interpretor.rs b/interpreter/src/interpretor.rs index 958be65..669214f 100644 --- a/interpreter/src/interpretor.rs +++ b/interpreter/src/interpretor.rs @@ -4,10 +4,9 @@ use super::lang::LanguageDictionary; pub(crate) fn standard_vocab(vocabulary: &mut LanguageDictionary) { vocabulary // filters - .add(crate::lang::vocabulary::filters::empty_filter()) - .add(crate::lang::vocabulary::filters::unique_filter()) // accepts .(unique) - .add(crate::lang::vocabulary::filters::range_filter()) - .add( // accepts any .(.something) + .add_transform(crate::lang::vocabulary::filters::empty_filter()) + .add_transform(crate::lang::vocabulary::filters::range_filter()) + .add_transform( // accepts any .(.something) crate::lang::vocabulary::filters::field::FieldFilterBlockFactory::new() .push(crate::lang::vocabulary::filters::field::FieldFilterComparisonFactory) .push(crate::lang::vocabulary::filters::field::FieldFilterMaybeFactory) @@ -15,39 +14,41 @@ pub(crate) fn standard_vocab(vocabulary: &mut LanguageDictionary) { .push(crate::lang::vocabulary::filters::field::FieldRegexFilterFactory) .to_statement_factory() ) - .add(crate::lang::vocabulary::filters::index_filter()) - .add(crate::lang::vocabulary::filters::unique_field_filter()) - .add(crate::lang::vocabulary::filters::nonempty_filter()) + .add_transform(crate::lang::vocabulary::filters::unique_field_filter()) + .add_transform(crate::lang::vocabulary::filters::unique_filter()) + .add_transform(crate::lang::vocabulary::filters::nonempty_filter()) + .add_transform(crate::lang::vocabulary::filters::index_filter()) // sorters - .add(crate::lang::vocabulary::sorters::empty_sort()) - .add(crate::lang::vocabulary::sorters::shuffle_sort()) // accepts ~(~shuffle) - .add(crate::lang::vocabulary::sorters::bliss_sort()) - .add(crate::lang::vocabulary::sorters::bliss_next_sort()) - .add(crate::lang::vocabulary::sorters::radio_sort()) - .add(crate::lang::vocabulary::sorters::field_sort()) // accepts any ~(.name) + .add_transform(crate::lang::vocabulary::sorters::empty_sort()) + .add_transform(crate::lang::vocabulary::sorters::shuffle_sort()) // accepts ~(~shuffle) + .add_transform(crate::lang::vocabulary::sorters::bliss_sort()) + .add_transform(crate::lang::vocabulary::sorters::bliss_next_sort()) + .add_transform(crate::lang::vocabulary::sorters::radio_sort()) + .add_transform(crate::lang::vocabulary::sorters::field_sort()) // accepts any ~(.name) // iter blocks - .add( + .add_transform( crate::lang::ItemBlockFactory::new() - .push(crate::lang::vocabulary::item_ops::ConstantItemOpFactory) - .push(crate::lang::vocabulary::item_ops::VariableAssignItemOpFactory) .push(crate::lang::vocabulary::item_ops::FieldAssignItemOpFactory) - .push(crate::lang::vocabulary::item_ops::FileItemOpFactory) + .push(crate::lang::vocabulary::item_ops::VariableAssignItemOpFactory) .push(crate::lang::vocabulary::item_ops::VariableDeclareItemOpFactory) + .push(crate::lang::vocabulary::item_ops::FileItemOpFactory) .push(crate::lang::vocabulary::item_ops::InterpolateStringItemOpFactory) .push(crate::lang::vocabulary::item_ops::BranchItemOpFactory) .push(crate::lang::vocabulary::item_ops::IterItemOpFactory) .push(crate::lang::vocabulary::item_ops::ConstructorItemOpFactory) .push(crate::lang::vocabulary::item_ops::EmptyItemOpFactory) .push(crate::lang::vocabulary::item_ops::RemoveItemOpFactory) - .push(crate::lang::vocabulary::item_ops::VariableRetrieveItemOpFactory) - .push(crate::lang::vocabulary::item_ops::NegateItemOpFactory) .push(crate::lang::vocabulary::item_ops::NotItemOpFactory) .push(crate::lang::vocabulary::item_ops::CompareItemOpFactory) + .push(crate::lang::vocabulary::item_ops::NegateItemOpFactory) .push(crate::lang::vocabulary::item_ops::AddItemOpFactory) .push(crate::lang::vocabulary::item_ops::SubtractItemOpFactory) .push(crate::lang::vocabulary::item_ops::OrItemOpFactory) .push(crate::lang::vocabulary::item_ops::AndItemOpFactory) - .push(crate::lang::vocabulary::item_ops::BracketsItemOpFactory), + .push(crate::lang::vocabulary::item_ops::BracketsItemOpFactory) + .push(crate::lang::vocabulary::item_ops::FieldRetrieveItemOpFactory) + .push(crate::lang::vocabulary::item_ops::ConstantItemOpFactory) + .push(crate::lang::vocabulary::item_ops::VariableRetrieveItemOpFactory) ) // functions and misc // functions don't enforce bracket coherence @@ -64,5 +65,6 @@ pub(crate) fn standard_vocab(vocabulary: &mut LanguageDictionary) { .add(crate::lang::vocabulary::empties_function_factory()) .add(crate::lang::vocabulary::reset_function_factory()) .add(crate::lang::vocabulary::union_function_factory()) - .add(crate::lang::vocabulary::intersection_function_factory()); + .add(crate::lang::vocabulary::intersection_function_factory()) + .add(crate::lang::vocabulary::VariableRetrieveStatementFactory); } diff --git a/interpreter/src/lang/dictionary.rs b/interpreter/src/lang/dictionary.rs index 2b83280..23a2b44 100644 --- a/interpreter/src/lang/dictionary.rs +++ b/interpreter/src/lang/dictionary.rs @@ -1,26 +1,33 @@ use std::collections::VecDeque; use super::SyntaxError; -use super::{BoxedOpFactory, Op}; +use super::{BoxedOpFactory, Op, BoxedTransformOpFactory}; use crate::tokens::Token; pub struct LanguageDictionary { - vocabulary: Vec>, + root_vocabulary: Vec>, + transform_vocabulary: Vec>, } impl LanguageDictionary { pub fn add(&mut self, factory: T) -> &mut Self { - self.vocabulary + self.root_vocabulary .push(Box::new(factory) as Box); self } - pub fn try_build_statement( + pub fn add_transform(&mut self, factory: T) -> &mut Self { + self.transform_vocabulary + .push(Box::new(factory) as Box); + self + } + + fn try_build_root_statement( &self, tokens: &mut VecDeque, ) -> Result, SyntaxError> { - //println!("try_build_statement with tokens {:?}", tokens); - for factory in &self.vocabulary { + //println!("building root op with tokens {:?}", tokens); + for factory in &self.root_vocabulary { if factory.is_op_boxed(tokens) { return factory.build_op_boxed(tokens, self); } @@ -40,9 +47,47 @@ impl LanguageDictionary { }) } + fn try_build_transformed_statement( + &self, + mut op: Box, + tokens: &mut VecDeque, + ) -> Result, SyntaxError> { + //println!("building transformer for op {} with tokens {:?}", op, tokens); + let mut op_found = true; + while op_found && !tokens.is_empty() { + (op, op_found) = self.try_build_one_transform(op, tokens)?; + } + //println!("built transformed op {}, remaining tokens {:?}", op, tokens); + Ok(op) + } + + pub fn try_build_one_transform( + &self, + mut op: Box, + tokens: &mut VecDeque, + ) -> Result<(Box, bool), SyntaxError> { + for factory in &self.transform_vocabulary { + if factory.is_transform_op(tokens) { + op = factory.build_transform_op(tokens, self, op)?; + return Ok((op, true)) + } + } + Ok((op, false)) + } + + pub fn try_build_statement( + &self, + tokens: &mut VecDeque, + ) -> Result, SyntaxError> { + let root = self.try_build_root_statement(tokens)?; + //println!("built root op {}, remaining tokens {:?}", root, tokens); + self.try_build_transformed_statement(root, tokens) + } + pub fn new() -> Self { Self { - vocabulary: Vec::new(), + root_vocabulary: Vec::new(), + transform_vocabulary: Vec::new(), } } @@ -57,7 +102,8 @@ impl LanguageDictionary { impl Default for LanguageDictionary { fn default() -> Self { Self { - vocabulary: Vec::new(), + root_vocabulary: Vec::new(), + transform_vocabulary: Vec::new(), } } } diff --git a/interpreter/src/lang/filter.rs b/interpreter/src/lang/filter.rs index 40ec3ba..972bd0d 100644 --- a/interpreter/src/lang/filter.rs +++ b/interpreter/src/lang/filter.rs @@ -3,11 +3,11 @@ use std::fmt::{Debug, Display, Error, Formatter}; use std::iter::Iterator; use std::marker::PhantomData; -use crate::lang::utility::{assert_name, assert_token, assert_token_raw, check_name}; +use crate::lang::utility::{assert_name, assert_token_raw, check_name}; use crate::lang::FilterReplaceStatement; use crate::lang::LanguageDictionary; use crate::lang::SingleItem; -use crate::lang::{BoxedOpFactory, IteratorItem, Op, PseudoOp}; +use crate::lang::{BoxedTransformOpFactory, IteratorItem, Op, PseudoOp}; use crate::lang::{RuntimeError, RuntimeMsg, RuntimeOp, SyntaxError}; use crate::processing::general::Type; use crate::tokens::Token; @@ -34,25 +34,10 @@ pub trait FilterFactory: Send + Sync { ) -> Result; } -#[derive(Debug, Clone)] -pub(super) enum VariableOrOp { - Variable(String), - Op(PseudoOp), -} - -impl Display for VariableOrOp { - fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { - match self { - Self::Variable(s) => write!(f, "{}", s), - Self::Op(op) => write!(f, "{}", op), - } - } -} - #[derive(Debug)] pub struct FilterStatement { predicate: P, - iterable: VariableOrOp, + iterable: PseudoOp, context: Option, other_filters: Option, is_failing: bool, @@ -75,7 +60,7 @@ impl Display for FilterStatement

{ if let Some(other_filters) = &self.other_filters { write!( f, - "{}.({} || (like) {})", + "{}.({} || (retconned) {})", self.iterable, self.predicate, other_filters ) } else { @@ -95,20 +80,8 @@ impl Op for FilterStatement

{ fn is_resetable(&self) -> bool { let is_iterable_resetable = match &self.iterable { - VariableOrOp::Variable(s) => { - if self.context.is_some() { - let var = self.context.as_ref().unwrap().variables.get_opt(s); - if let Some(Type::Op(var)) = var { - var.is_resetable() - } else { - false - } - } else { - true - } // ASSUMPTION - } - VariableOrOp::Op(PseudoOp::Real(op)) => op.is_resetable(), - VariableOrOp::Op(PseudoOp::Fake(_)) => false, + PseudoOp::Real(op) => op.is_resetable(), + PseudoOp::Fake(_) => false, }; let is_other_filter_resetable = if let Some(PseudoOp::Real(other_filter)) = &self.other_filters { @@ -126,45 +99,13 @@ impl Op for FilterStatement

{ .reset() .map_err(|x| x.with(RuntimeOp(fake.clone())))?; match &mut self.iterable { - VariableOrOp::Variable(s) => { - if self.context.as_mut().unwrap().variables.exists(s) { - let mut var = self - .context - .as_mut() - .unwrap() - .variables - .remove(s) - .map_err(|e| e.with(RuntimeOp(fake.clone())))?; - let result = if let Type::Op(var) = &mut var { - var.enter(self.context.take().unwrap()); - let result = var.reset(); - self.context = Some(var.escape()); - result - } else { - Err(RuntimeError { - line: 0, - op: fake.clone(), - msg: "Cannot reset non-iterable filter variable".to_string(), - }) - }; - self.context - .as_mut() - .unwrap() - .variables - .declare(s, var) - .map_err(|e| e.with(RuntimeOp(fake)))?; - result - } else { - Ok(()) - } - } - VariableOrOp::Op(PseudoOp::Real(op)) => { + PseudoOp::Real(op) => { op.enter(self.context.take().unwrap()); let result = op.reset(); self.context = Some(op.escape()); result } - VariableOrOp::Op(PseudoOp::Fake(_)) => Err(RuntimeError { + PseudoOp::Fake(_) => Err(RuntimeError { line: 0, op: fake, msg: "Cannot reset PseudoOp::Fake filter".to_string(), @@ -183,10 +124,7 @@ impl Op for FilterStatement

{ fn dup(&self) -> Box { Box::new(Self { predicate: self.predicate.clone(), - iterable: match &self.iterable { - VariableOrOp::Variable(s) => VariableOrOp::Variable(s.clone()), - VariableOrOp::Op(op) => VariableOrOp::Op(op.try_real_ref().unwrap().dup().into()), - }, + iterable: self.iterable.try_real_ref().unwrap().dup().into(), context: None, other_filters: self .other_filters @@ -199,57 +137,15 @@ impl Op for FilterStatement

{ impl FilterStatement

{ fn next_item(&mut self) -> Option { - let fake_op = PseudoOp::from_printable(self); - match &mut self.iterable { - VariableOrOp::Op(op) => match op.try_real() { - Ok(real_op) => { - let ctx = self.context.take().unwrap(); - real_op.enter(ctx); - let item = real_op.next(); - self.context = Some(real_op.escape()); - item - } - Err(e) => return Some(Err(e)), - }, - VariableOrOp::Variable(variable_name) => { - let mut variable = match self - .context - .as_mut() - .unwrap() - .variables - .remove(variable_name) - { - Ok(Type::Op(op)) => op, - Ok(x) => { - return Some(Err(RuntimeError { - line: 0, - op: fake_op, - msg: format!( - "Expected operation/iterable type in variable {}, got {}", - &variable_name, x - ), - })) - } - Err(e) => { - self.is_failing = true; - return Some(Err(e.with(RuntimeOp(PseudoOp::from_printable(self))))); - }, - }; - - variable.enter(self.context.take().unwrap()); - let item = variable.next(); - self.context = Some(variable.escape()); - if let Err(e) = self - .context - .as_mut() - .unwrap() - .variables - .declare(variable_name, Type::Op(variable)) - { - return Some(Err(e.with(RuntimeOp(PseudoOp::from_printable(self))))); - } + match self.iterable.try_real() { + Ok(real_op) => { + let ctx = self.context.take().unwrap(); + real_op.enter(ctx); + let item = real_op.next(); + self.context = Some(real_op.escape()); item } + Err(e) => return Some(Err(e)), } } } @@ -258,6 +154,7 @@ impl Iterator for FilterStatement

{ type Item = IteratorItem; fn next(&mut self) -> Option { + //println!("In FilterStatement {}", self.predicate); if (self.predicate.is_complete() && self.other_filters.is_none()) || self.is_failing { return None; } @@ -278,6 +175,7 @@ impl Iterator for FilterStatement

{ if let Some(inner) = &mut self.other_filters { // handle other filters // make fake inner item + //println!("Making fake inner variable `{}`", INNER_VARIABLE_NAME); let single_op = SingleItem::new_ok(item.clone()); let preexisting_var = self.context.as_mut().unwrap() .variables @@ -310,18 +208,7 @@ impl Iterator for FilterStatement

{ } fn size_hint(&self) -> (usize, Option) { - match &self.iterable { - VariableOrOp::Variable(s) => self - .context - .as_ref() - .and_then(|x| x.variables.get_opt(s)) - .and_then(|x| match x { - Type::Op(op) => Some(op.size_hint()), - _ => None, - }), - VariableOrOp::Op(op) => op.try_real_ref().map(|x| x.size_hint()).ok(), - } - .unwrap_or((0, None)) + self.iterable.try_real_ref().map(|x| x.size_hint()).ok().unwrap_or((0, None)) } } @@ -339,130 +226,64 @@ impl + 'static> FilterStatemen } } -impl + 'static> BoxedOpFactory - for FilterStatementFactory -{ - #[allow(clippy::unnecessary_unwrap)] - fn is_op_boxed(&self, tokens: &VecDeque) -> bool { - let tokens_len = tokens.len(); - if is_correct_format(tokens) { - let start_of_predicate = last_dot_before_open_bracket(tokens) + 2; // .(predicate) - if start_of_predicate > tokens_len - 1 { - false - } else { - let pipe_location_opt = first_double_pipe(tokens, 1); - if pipe_location_opt.is_some() && pipe_location_opt.unwrap() > start_of_predicate { - let pipe_location = pipe_location_opt.unwrap(); - // filters combined by OR operations - let tokens2: VecDeque<&Token> = - VecDeque::from_iter(tokens.range(start_of_predicate..pipe_location)); - self.filter_factory.is_filter(&tokens2) - } else { - // single filter - let tokens2: VecDeque<&Token> = - VecDeque::from_iter(tokens.range(start_of_predicate..tokens_len - 1)); - if !tokens2.is_empty() && check_name("if", tokens2[0]) { - // replacement filter - if let Some(colon_location) = first_colon2(&tokens2) { - let tokens3 = VecDeque::from_iter(tokens.range( - start_of_predicate + 1..start_of_predicate + colon_location, - )); - self.filter_factory.is_filter(&tokens3) - } else { - false - } - } else { - // regular filter - self.filter_factory.is_filter(&tokens2) - } - } - } - } else { - false - } - } - - fn build_op_boxed( +impl + 'static> BoxedTransformOpFactory + for FilterStatementFactory { + fn build_transform_op( &self, tokens: &mut VecDeque, dict: &LanguageDictionary, + op: Box, ) -> Result, SyntaxError> { - let start_of_op = last_dot_before_open_bracket(tokens); - let op = if start_of_op == 1 && tokens[0].is_name() { - // variable_name.(predicate) - let variable_name = assert_token( - |t| match t { - Token::Name(s) => Some(s), - _ => None, - }, - Token::Name("variable_name".into()), - tokens, - )?; - VariableOrOp::Variable(variable_name) - } else { - // .(predicate) - //let mut new_tokens = tokens.range(0..start_of_op).map(|x| x.to_owned()).collect(); - let end_tokens = tokens.split_off(start_of_op); // don't parse filter in inner statement - let inner_op = dict.try_build_statement(tokens)?; - tokens.extend(end_tokens); - VariableOrOp::Op(inner_op.into()) - }; assert_token_raw(Token::Dot, tokens)?; assert_token_raw(Token::OpenBracket, tokens)?; if !tokens.is_empty() && check_name("if", &tokens[0]) { - return { - // replacement filter - //println!("Building replacement filter from tokens {:?}", tokens); - assert_name("if", tokens)?; - if let Some(colon_location) = first_colon(tokens) { - let end_tokens = tokens.split_off(colon_location); - let filter = self.filter_factory.build_filter(tokens, dict)?; - tokens.extend(end_tokens); - assert_token_raw(Token::Colon, tokens)?; - let mut else_op: Option = None; - let if_op: PseudoOp; - if let Some(else_location) = first_else_not_in_bracket(tokens) { - let end_tokens = tokens.split_off(else_location); - // build replacement system - if_op = dict.try_build_statement(tokens)?.into(); - tokens.extend(end_tokens); - assert_name("else", tokens)?; - let end_tokens = tokens.split_off(tokens.len() - 1); // up to ending close bracket - // build replacement system - else_op = Some(dict.try_build_statement(tokens)?.into()); - tokens.extend(end_tokens); - } else { - let end_tokens = tokens.split_off(tokens.len() - 1); - // build replacement system - if_op = dict.try_build_statement(tokens)?.into(); - tokens.extend(end_tokens); - } - assert_token_raw(Token::CloseBracket, tokens)?; - Ok(Box::new(FilterReplaceStatement { - predicate: filter, - iterable: op, - context: None, - op_if: if_op, - op_else: else_op, - item_cache: super::filter_replace::item_cache_deque(), - })) - } else { - Err(SyntaxError { - line: 0, - token: Token::Colon, - got: None, - }) - } - }; + // replacement filter + assert_name("if", tokens)?; + let filter = self.filter_factory.build_filter(tokens, dict)?; + assert_token_raw(Token::Colon, tokens)?; + let mut else_op: Option = None; + let if_op: PseudoOp = dict.try_build_statement(tokens)?.into(); + if check_name("else", &tokens[0]) { + assert_name("else", tokens)?; + else_op = Some(dict.try_build_statement(tokens)?.into()); + } + /*if let Some(else_location) = first_else_not_in_bracket(tokens) { + //println!("First else found at {}; {:?}", else_location, tokens); + //let end_tokens = tokens.split_off(else_location); + // build replacement system + if_op = dict.try_build_statement(tokens)?.into(); + //tokens.extend(end_tokens); + assert_name("else", tokens)?; + //let end_tokens = tokens.split_off(tokens.len() - 1); // up to ending close bracket + // build replacement system + else_op = Some(dict.try_build_statement(tokens)?.into()); + //tokens.extend(end_tokens); + } else { + //let end_tokens = tokens.split_off(tokens.len() - 1); + // build replacement system + if_op = dict.try_build_statement(tokens)?.into(); + //tokens.extend(end_tokens); + }*/ + assert_token_raw(Token::CloseBracket, tokens)?; + Ok(Box::new(FilterReplaceStatement { + predicate: filter, + iterable: op.into(), + context: None, + op_if: if_op, + op_else: else_op, + item_cache: super::filter_replace::item_cache_deque(), + })) } else { + // regular filter let mut another_filter = None; - let (has_or, end_tokens) = if let Some(pipe_location) = first_double_pipe(tokens, 0) { + let has_or = first_double_pipe(tokens, 0).is_some(); + /*let (has_or, end_tokens) = if let Some(pipe_location) = first_double_pipe(tokens, 0) { (true, tokens.split_off(pipe_location)) // parse up to OR operator } else { (false, tokens.split_off(tokens.len() - 1)) // don't parse closing bracket in filter - }; + };*/ let filter = self.filter_factory.build_filter(tokens, dict)?; - tokens.extend(end_tokens); + //tokens.extend(end_tokens); if has_or { // recursively build other filters for OR operation assert_token_raw(Token::Pipe, tokens)?; @@ -470,66 +291,57 @@ impl + 'static> BoxedOpFactory // emit fake filter syntax tokens.push_front(Token::OpenBracket); tokens.push_front(Token::Dot); - tokens.push_front(Token::Name(INNER_VARIABLE_NAME.into())); // impossible to obtain through parsing on purpose - another_filter = Some(dict.try_build_statement(tokens)?.into()); + //tokens.push_front(Token::Name(INNER_VARIABLE_NAME.into())); // impossible to obtain through parsing on purpose + /*let inner_op = Box::new(crate::lang::vocabulary::VariableRetrieveStatement { + variable_name: INNER_VARIABLE_NAME.into(), + context: None, + is_tried: false, + });*/ + let mut inner_tokens = VecDeque::with_capacity(1); + inner_tokens.push_front(Token::Name(INNER_VARIABLE_NAME.into())); + let inner_op = dict.try_build_statement(&mut inner_tokens)?; + let (inner_op, op_transformed) = dict.try_build_one_transform(inner_op, tokens)?; + if !op_transformed { + return Err( + SyntaxError { + token: Token::Name(INNER_VARIABLE_NAME.into()), + got: Some(Token::Name(INNER_VARIABLE_NAME.into())), + line: 0, + } + ) + } + //println!("Built 2nd filter: {}", inner_op); + another_filter = Some(inner_op.into()); } else { + //println!("filter tokens before final bracket: {:?}", tokens); assert_token_raw(Token::CloseBracket, tokens)?; // remove closing bracket } Ok(Box::new(FilterStatement { predicate: filter, - iterable: op, + iterable: op.into(), context: None, other_filters: another_filter, is_failing: false, })) } } -} -fn is_correct_format(tokens: &VecDeque) -> bool { - let mut inside_brackets = 0; - let mut open_bracket_found = false; - let mut close_bracket = 0; - for i in (0..tokens.len()).rev() { - if tokens[i].is_close_bracket() { - if inside_brackets == 0 { - close_bracket = i; - } - inside_brackets += 1; - } else if tokens[i].is_open_bracket() { - if inside_brackets == 1 { - open_bracket_found = true; - } else if inside_brackets != 0 { - inside_brackets -= 1; - } - } else if open_bracket_found { - return tokens[i].is_dot() && (close_bracket == 0 || close_bracket == tokens.len() - 1); - } - } - false -} - -fn last_dot_before_open_bracket(tokens: &VecDeque) -> usize { - let mut inside_brackets = 0; - let mut open_bracket_found = false; - for i in (0..tokens.len()).rev() { - if tokens[i].is_close_bracket() { - inside_brackets += 1; - } else if tokens[i].is_open_bracket() { - if inside_brackets == 1 { - open_bracket_found = true; - } else if inside_brackets != 0 { - inside_brackets -= 1; - } - } else if open_bracket_found { - if tokens[i].is_dot() { - return i; + fn is_transform_op(&self, tokens: &VecDeque) -> bool { + let result = if tokens.len() > 2 && tokens[0].is_dot() && tokens[1].is_open_bracket() { + if check_name("if", &tokens[2]) { + let tokens2: VecDeque<&Token> = + VecDeque::from_iter(tokens.range(3..)); + self.filter_factory.is_filter(&tokens2) } else { - return 0; + let tokens2: VecDeque<&Token> = + VecDeque::from_iter(tokens.range(2..)); + self.filter_factory.is_filter(&tokens2) } - } + } else { + false + }; + result } - 0 } fn first_double_pipe(tokens: &VecDeque, in_brackets: usize) -> Option { @@ -554,25 +366,7 @@ fn first_double_pipe(tokens: &VecDeque, in_brackets: usize) -> Option) -> Option { - for i in 0..tokens.len() { - if tokens[i].is_colon() { - return Some(i); - } - } - None -} - -fn first_colon2(tokens: &VecDeque<&Token>) -> Option { - for i in 0..tokens.len() { - if tokens[i].is_colon() { - return Some(i); - } - } - None -} - -fn first_else_not_in_bracket(tokens: &VecDeque) -> Option { +/*fn first_else_not_in_bracket(tokens: &VecDeque) -> Option { let mut inside_brackets = 0; for i in 0..tokens.len() { if check_name("else", &tokens[i]) && inside_brackets == 0 { @@ -584,4 +378,4 @@ fn first_else_not_in_bracket(tokens: &VecDeque) -> Option { } } None -} +}*/ diff --git a/interpreter/src/lang/filter_replace.rs b/interpreter/src/lang/filter_replace.rs index 59b41e0..2d95821 100644 --- a/interpreter/src/lang/filter_replace.rs +++ b/interpreter/src/lang/filter_replace.rs @@ -3,7 +3,7 @@ use std::fmt::{Debug, Display, Error, Formatter}; use std::iter::Iterator; use crate::lang::SingleItem; -use crate::lang::{filter::VariableOrOp, FilterPredicate}; +use crate::lang::FilterPredicate; use crate::lang::{IteratorItem, Op, PseudoOp}; use crate::lang::{RuntimeError, RuntimeMsg, RuntimeOp}; use crate::processing::general::Type; @@ -21,7 +21,7 @@ pub(super) fn item_cache_deque() -> VecDeque> { #[derive(Debug)] pub struct FilterReplaceStatement { pub(super) predicate: P, - pub(super) iterable: VariableOrOp, + pub(super) iterable: PseudoOp, pub(super) context: Option, pub(super) op_if: PseudoOp, pub(super) op_else: Option, @@ -70,20 +70,8 @@ impl Op for FilterReplaceStatement

{ fn is_resetable(&self) -> bool { match &self.iterable { - VariableOrOp::Variable(s) => { - if self.context.is_some() { - let var = self.context.as_ref().unwrap().variables.get_opt(s); - if let Some(Type::Op(var)) = var { - var.is_resetable() - } else { - false - } - } else { - true - } // ASSUMPTION - } - VariableOrOp::Op(PseudoOp::Real(op)) => op.is_resetable(), - VariableOrOp::Op(PseudoOp::Fake(_)) => false, + PseudoOp::Real(op) => op.is_resetable(), + PseudoOp::Fake(_) => false, } } @@ -94,45 +82,13 @@ impl Op for FilterReplaceStatement

{ .reset() .map_err(|x| x.with(RuntimeOp(fake.clone())))?; match &mut self.iterable { - VariableOrOp::Variable(s) => { - if self.context.as_mut().unwrap().variables.exists(s) { - let mut var = self - .context - .as_mut() - .unwrap() - .variables - .remove(s) - .map_err(|e| e.with(RuntimeOp(fake.clone())))?; - let result = if let Type::Op(var) = &mut var { - var.enter(self.context.take().unwrap()); - let result = var.reset(); - self.context = Some(var.escape()); - result - } else { - Err(RuntimeError { - line: 0, - op: fake.clone(), - msg: "Cannot reset non-iterable filter variable".to_string(), - }) - }; - self.context - .as_mut() - .unwrap() - .variables - .declare(s, var) - .map_err(|e| e.with(RuntimeOp(fake)))?; - result - } else { - Ok(()) - } - } - VariableOrOp::Op(PseudoOp::Real(op)) => { + PseudoOp::Real(op) => { op.enter(self.context.take().unwrap()); let result = op.reset(); self.context = Some(op.escape()); result } - VariableOrOp::Op(PseudoOp::Fake(_)) => Err(RuntimeError { + PseudoOp::Fake(_) => Err(RuntimeError { line: 0, op: fake, msg: "Cannot reset PseudoOp::Fake filter".to_string(), @@ -143,10 +99,7 @@ impl Op for FilterReplaceStatement

{ fn dup(&self) -> Box { Box::new(Self { predicate: self.predicate.clone(), - iterable: match &self.iterable { - VariableOrOp::Variable(s) => VariableOrOp::Variable(s.clone()), - VariableOrOp::Op(op) => VariableOrOp::Op(op.try_real_ref().unwrap().dup().into()), - }, + iterable: self.iterable.try_real_ref().unwrap().dup().into(), context: None, op_if: PseudoOp::from(self.op_if.try_real_ref().unwrap().dup()), op_else: self @@ -167,53 +120,15 @@ impl Iterator for FilterReplaceStatement

{ } let fake = PseudoOp::Fake(format!("{}", self)); // get next item in iterator - let next_item = match &mut self.iterable { - VariableOrOp::Op(op) => match op.try_real() { - Ok(real_op) => { - let ctx = self.context.take().unwrap(); - real_op.enter(ctx); - let item = real_op.next(); - self.context = Some(real_op.escape()); - item - } - Err(e) => return Some(Err(e)), - }, - VariableOrOp::Variable(variable_name) => { - let mut variable = match self - .context - .as_mut() - .unwrap() - .variables - .remove(variable_name) - { - Ok(Type::Op(op)) => op, - Ok(x) => { - return Some(Err(RuntimeError { - line: 0, - op: fake, - msg: format!( - "Expected operation/iterable type in variable {}, got {}", - &variable_name, x - ), - })) - } - Err(e) => return Some(Err(e.with(RuntimeOp(fake)))), - }; + let next_item = match self.iterable.try_real() { + Ok(real_op) => { let ctx = self.context.take().unwrap(); - variable.enter(ctx); - let item = variable.next(); - self.context = Some(variable.escape()); - if let Err(e) = self - .context - .as_mut() - .unwrap() - .variables - .declare(variable_name, Type::Op(variable)) - { - return Some(Err(e.with(RuntimeOp(fake)))); - } + real_op.enter(ctx); + let item = real_op.next(); + self.context = Some(real_op.escape()); item } + Err(e) => return Some(Err(e)), }; // process item match next_item { @@ -242,6 +157,7 @@ impl Iterator for FilterReplaceStatement

{ real_op.enter(self.context.take().unwrap()); if real_op.is_resetable() { if let Err(e) = real_op.reset() { + self.context = Some(real_op.escape()); return Some(Err(e)); } } @@ -269,6 +185,7 @@ impl Iterator for FilterReplaceStatement

{ replacement } } else if let Some(op_else) = &mut self.op_else { + println!("op_else {}\n{:?}", op_else, op_else); // unwrap inner operation match op_else.try_real() { Ok(real_op) => { @@ -286,6 +203,7 @@ impl Iterator for FilterReplaceStatement

{ real_op.enter(self.context.take().unwrap()); if real_op.is_resetable() { if let Err(e) = real_op.reset() { + self.context = Some(real_op.escape()); return Some(Err(e)); } } @@ -325,18 +243,7 @@ impl Iterator for FilterReplaceStatement

{ } fn size_hint(&self) -> (usize, Option) { - match &self.iterable { - VariableOrOp::Variable(s) => self - .context - .as_ref() - .and_then(|x| x.variables.get_opt(s)) - .and_then(|x| match x { - Type::Op(op) => Some(op.size_hint()), - _ => None, - }), - VariableOrOp::Op(op) => op.try_real_ref().map(|x| x.size_hint()).ok(), - } - .unwrap_or((0, None)) + self.iterable.try_real_ref().map(|x| x.size_hint()).ok().unwrap_or((0, None)) } } diff --git a/interpreter/src/lang/function.rs b/interpreter/src/lang/function.rs index 7aeacbe..298ec20 100644 --- a/interpreter/src/lang/function.rs +++ b/interpreter/src/lang/function.rs @@ -45,7 +45,6 @@ impl + 'static> BoxedOpFactory Token::Name(n) => { self.op_factory.is_function(n) && tokens[1].is_open_bracket() - && tokens[tokens_len - 1].is_close_bracket() } _ => false, } @@ -66,9 +65,9 @@ impl + 'static> BoxedOpFactory tokens, )?; assert_token_raw(Token::OpenBracket, tokens)?; - let end_tokens = tokens.split_off(tokens.len() - 1); + //let end_tokens = tokens.split_off(tokens.len() - 1); let func = self.op_factory.build_function_params(name, tokens, dict)?; - tokens.extend(end_tokens); + //tokens.extend(end_tokens); assert_token_raw(Token::CloseBracket, tokens)?; Ok(Box::new(func)) } diff --git a/interpreter/src/lang/iter_block.rs b/interpreter/src/lang/iter_block.rs index a481b7a..8034980 100644 --- a/interpreter/src/lang/iter_block.rs +++ b/interpreter/src/lang/iter_block.rs @@ -6,9 +6,9 @@ use std::iter::Iterator; use std::marker::PhantomData; use std::sync::Arc; -use crate::lang::utility::{assert_token_raw, assert_token_raw_back}; +use crate::lang::utility::assert_token_raw; use crate::lang::LanguageDictionary; -use crate::lang::{BoxedOpFactory, IteratorItem, Op, PseudoOp}; +use crate::lang::{BoxedTransformOpFactory, IteratorItem, Op, PseudoOp}; use crate::lang::{RuntimeError, RuntimeMsg, RuntimeOp, SyntaxError}; use crate::processing::general::Type; use crate::tokens::Token; @@ -72,7 +72,7 @@ impl Display for ItemBlockStatement { writeln!(f)?; } for statement in self.statements.iter() { - writeln!(f, "{}", statement)?; + writeln!(f, "{},", statement)?; } write!(f, "}}") } @@ -227,7 +227,7 @@ impl ItemBlockFactory { tokens: &mut VecDeque, dict: &LanguageDictionary, ) -> Result, SyntaxError> { - for factory in &self.vocabulary { + for (i, factory) in self.vocabulary.iter().enumerate() { if factory.is_item_op(tokens) { return factory.build_item_op(tokens, self, dict); } @@ -253,48 +253,44 @@ impl ItemBlockFactory { } } -impl BoxedOpFactory for ItemBlockFactory { - fn is_op_boxed(&self, tokens: &VecDeque) -> bool { - find_last_open_curly(tokens).is_some() - } - - fn build_op_boxed( +impl BoxedTransformOpFactory for ItemBlockFactory { + fn build_transform_op( &self, tokens: &mut VecDeque, dict: &LanguageDictionary, + op: Box, ) -> Result, SyntaxError> { - let open_curly_pos = if let Some(pos) = find_last_open_curly(tokens) { - Ok(pos) - } else { - Err(SyntaxError { - line: 0, - token: Token::OpenCurly, - got: tokens.pop_front(), - }) - }?; - let block_tokens = tokens.split_off(open_curly_pos - 1); // . always before { - let inner_op = dict.try_build_statement(tokens)?; - tokens.extend(block_tokens); assert_token_raw(Token::Dot, tokens)?; assert_token_raw(Token::OpenCurly, tokens)?; - assert_token_raw_back(Token::CloseCurly, tokens)?; let mut item_ops = Vec::with_capacity(tokens.len() / 8); while !tokens.is_empty() { - if let Some(next_comma) = find_next_comma(tokens) { - let end_tokens = tokens.split_off(next_comma); - item_ops.push(Arc::new(self.try_build_item_statement(tokens, dict)?)); - tokens.extend(end_tokens); - assert_token_raw(Token::Comma, tokens)?; + if tokens[0].is_close_curly() { + break; + } + item_ops.push(Arc::new(self.try_build_item_statement(tokens, dict)?)); + if !tokens.is_empty() { + if tokens[0].is_comma() { + assert_token_raw(Token::Comma, tokens)?; + } } else { - item_ops.push(Arc::new(self.try_build_item_statement(tokens, dict)?)); + return Err(SyntaxError { + got: tokens.pop_front(), + token: Token::Literal(", or }".into()), + line: 0, + }) } } + assert_token_raw(Token::CloseCurly, tokens)?; Ok(Box::new(ItemBlockStatement { statements: item_ops, - iterable: inner_op.into(), + iterable: op.into(), last_item: None, })) } + + fn is_transform_op(&self, tokens: &VecDeque) -> bool { + tokens.len() > 1 && tokens[0].is_dot() && tokens[1].is_open_curly() + } } fn replace_item_var(ctx: &mut Context, item: Type) -> Option { @@ -320,42 +316,7 @@ fn restore_item_var(ctx: &mut Context, old_var: Option) -> Result) -> Option { - let mut bracket_depth = 0; - let mut curly_found = false; - for i in (0..tokens.len()).rev() { - let token = &tokens[i]; - match token { - Token::OpenCurly => { - if bracket_depth != 0 { - bracket_depth -= 1; - } - } - Token::CloseCurly => { - bracket_depth += 1; - } - Token::Dot => { - if bracket_depth == 0 && curly_found { - return Some(i + 1); - } - } - Token::OpenBracket | Token::CloseBracket => { - if bracket_depth == 0 { - return None; - } - } - _ => {} - } - if token.is_open_curly() { - curly_found = true; - } else { - curly_found = false; - } - } - None -} - -fn find_next_comma(tokens: &VecDeque) -> Option { +/*fn find_next_comma(tokens: &VecDeque) -> Option { let mut bracket_depth = 0; let mut curly_depth = 0; for i in 0..tokens.len() { @@ -373,4 +334,4 @@ fn find_next_comma(tokens: &VecDeque) -> Option { } } None -} +}*/ diff --git a/interpreter/src/lang/mod.rs b/interpreter/src/lang/mod.rs index c41a88d..e13d15f 100644 --- a/interpreter/src/lang/mod.rs +++ b/interpreter/src/lang/mod.rs @@ -29,7 +29,7 @@ pub use function::{FunctionFactory, FunctionStatementFactory}; pub use generator_op::GeneratorOp; pub use iter_block::{ItemBlockFactory, ItemOp, ItemOpFactory}; pub use lookup::Lookup; -pub use operation::{BoxedOpFactory, IteratorItem, Op, OpFactory, SimpleOpFactory}; +pub use operation::{BoxedOpFactory, IteratorItem, Op, OpFactory, SimpleOpFactory, BoxedTransformOpFactory}; pub use pseudo_op::PseudoOp; pub use repeated_meme::{repeated_tokens, RepeatedTokens}; pub use single_op::SingleItem; diff --git a/interpreter/src/lang/operation.rs b/interpreter/src/lang/operation.rs index 581c168..330a456 100644 --- a/interpreter/src/lang/operation.rs +++ b/interpreter/src/lang/operation.rs @@ -12,20 +12,22 @@ use crate::Item; // TODO change API to allow for accumulating modifiers // e.g. build_op(&self, Option>, tokens) -> ... -pub trait SimpleOpFactory { - fn is_op_simple(&self, tokens: &VecDeque) -> bool; +type TokenList = VecDeque; - fn build_op_simple(&self, tokens: &mut VecDeque) -> Result; +pub trait SimpleOpFactory { + fn is_op_simple(&self, tokens: &TokenList) -> bool; + + fn build_op_simple(&self, tokens: &mut TokenList) -> Result; } impl + 'static> OpFactory for X { - fn is_op(&self, tokens: &VecDeque) -> bool { + fn is_op(&self, tokens: &TokenList) -> bool { self.is_op_simple(tokens) } fn build_op( &self, - tokens: &mut VecDeque, + tokens: &mut TokenList, _dict: &LanguageDictionary, ) -> Result { self.build_op_simple(tokens) @@ -33,18 +35,18 @@ impl + 'static> OpFactory for X { } pub trait OpFactory { - fn is_op(&self, tokens: &VecDeque) -> bool; + fn is_op(&self, tokens: &TokenList) -> bool; fn build_op( &self, - tokens: &mut VecDeque, + tokens: &mut TokenList, dict: &LanguageDictionary, ) -> Result; #[inline] fn build_box( &self, - tokens: &mut VecDeque, + tokens: &mut TokenList, dict: &LanguageDictionary, ) -> Result, SyntaxError> { Ok(Box::new(self.build_op(tokens, dict)?)) @@ -54,11 +56,22 @@ pub trait OpFactory { pub trait BoxedOpFactory: Send { fn build_op_boxed( &self, - tokens: &mut VecDeque, + tokens: &mut TokenList, dict: &LanguageDictionary, ) -> Result, SyntaxError>; - fn is_op_boxed(&self, tokens: &VecDeque) -> bool; + fn is_op_boxed(&self, tokens: &TokenList) -> bool; +} + +pub trait BoxedTransformOpFactory: Send { + fn build_transform_op( + &self, + tokens: &mut TokenList, + dict: &LanguageDictionary, + op: Box, + ) -> Result, SyntaxError>; + + fn is_transform_op(&self, tokens: &TokenList) -> bool; } pub type IteratorItem = Result; diff --git a/interpreter/src/lang/sorter.rs b/interpreter/src/lang/sorter.rs index ac68e9a..840fe9b 100644 --- a/interpreter/src/lang/sorter.rs +++ b/interpreter/src/lang/sorter.rs @@ -3,9 +3,9 @@ use std::fmt::{Debug, Display, Error, Formatter}; use std::iter::Iterator; use std::marker::PhantomData; -use crate::lang::utility::{assert_name, assert_token_raw, check_name}; +use crate::lang::utility::assert_token_raw; use crate::lang::LanguageDictionary; -use crate::lang::{BoxedOpFactory, IteratorItem, Op, PseudoOp}; +use crate::lang::{IteratorItem, Op, PseudoOp, BoxedTransformOpFactory}; use crate::lang::{RuntimeError, RuntimeMsg, RuntimeOp, SyntaxError}; use crate::tokens::Token; use crate::Context; @@ -125,58 +125,16 @@ impl + 'static> SortStatementFactory + 'static> BoxedOpFactory +impl + 'static> BoxedTransformOpFactory for SortStatementFactory { - fn is_op_boxed(&self, tokens: &VecDeque) -> bool { - let tokens_len = tokens.len(); - if let Some(tilde_location) = last_tilde(tokens, 0) { - // iterable~(sorter) - if tokens_len > tilde_location + 2 { - let tokens2: VecDeque<&Token> = - VecDeque::from_iter(tokens.range(tilde_location + 2..tokens_len - 1)); - tokens[tokens_len - 1].is_close_bracket() && self.sort_factory.is_sorter(&tokens2) - } else { - false - } - } else if let Some(dot_location) = last_dot_sort(tokens, 1) { - // iterable.sort(sorter) - if tokens_len > dot_location + 3 { - let tokens2: VecDeque<&Token> = - VecDeque::from_iter(tokens.range(dot_location + 3..tokens_len - 1)); - tokens[tokens_len - 1].is_close_bracket() && self.sort_factory.is_sorter(&tokens2) - } else { - false - } - } else { - false - } - } - - fn build_op_boxed( + fn build_transform_op( &self, tokens: &mut VecDeque, dict: &LanguageDictionary, + op: Box, ) -> Result, SyntaxError> { - let inner_op; - if let Some(tilde_location) = last_tilde(tokens, 0) { - let end_tokens = tokens.split_off(tilde_location); - inner_op = dict.try_build_statement(tokens)?; - tokens.extend(end_tokens); - assert_token_raw(Token::Tilde, tokens)?; - } else if let Some(dot_location) = last_dot_sort(tokens, 1) { - let end_tokens = tokens.split_off(dot_location); - inner_op = dict.try_build_statement(tokens)?; - tokens.extend(end_tokens); - assert_token_raw(Token::Dot, tokens)?; - assert_name("sort", tokens)?; - } else { - return Err(SyntaxError { - line: 0, - token: Token::Name(".|~".into()), - got: tokens.pop_front(), - }); - } + assert_token_raw(Token::Tilde, tokens)?; assert_token_raw(Token::OpenBracket, tokens)?; let end_tokens = tokens.split_off(tokens.len() - 1); let sorter = self.sort_factory.build_sorter(tokens, dict)?; @@ -184,58 +142,19 @@ impl + 'static> BoxedOpFactory assert_token_raw(Token::CloseBracket, tokens)?; Ok(Box::new(SortStatement { orderer: sorter, - iterable: inner_op.into(), + iterable: op.into(), item_cache: VecDeque::with_capacity(SORTER_ITEM_CACHE_SIZE), })) } -} -fn last_tilde(tokens: &VecDeque, target_depth: usize) -> Option { - let mut bracket_depth = 0; - for i in (0..tokens.len()).rev() { - let current_token = &tokens[i]; - if current_token.is_close_bracket() { - bracket_depth += 1; - } else if current_token.is_open_bracket() && bracket_depth != 0 { - bracket_depth -= 1; - } else if current_token.is_tilde() && bracket_depth == target_depth { - return Some(i); + fn is_transform_op(&self, tokens: &VecDeque) -> bool { + if tokens.len() > 2 { + let tokens2: VecDeque<&Token> = + VecDeque::from_iter(tokens.range(2..)); + tokens[0].is_tilde() && self.sort_factory.is_sorter(&tokens2) + } else { + false } - } - None -} -fn last_dot_sort(tokens: &VecDeque, target_depth: usize) -> Option { - let mut bracket_depth = 0; - let mut sort_found = false; - let mut bracket_found = false; - for i in (0..tokens.len()).rev() { - let current_token = &tokens[i]; - if sort_found { - return { - if current_token.is_dot() { - Some(i) - } else { - None - } - }; - } else if bracket_found { - if check_name("sort", current_token) { - sort_found = true; - } else { - bracket_found = false; - } - } - if current_token.is_close_bracket() { - bracket_depth += 1; - } else if current_token.is_open_bracket() { - if target_depth == bracket_depth { - bracket_found = true; - } - if bracket_depth != 0 { - bracket_depth -= 1; - } - } } - None } diff --git a/interpreter/src/lang/utility.rs b/interpreter/src/lang/utility.rs index c25e448..7030c6e 100644 --- a/interpreter/src/lang/utility.rs +++ b/interpreter/src/lang/utility.rs @@ -49,29 +49,6 @@ pub fn assert_token_raw(token: Token, tokens: &mut VecDeque) -> Result, -) -> Result { - let result = match tokens.pop_back() { - Some(x) => Ok(x), - None => Err(SyntaxError { - line: 0, - token: token.clone(), - got: None, - }), - }?; - if std::mem::discriminant(&token) == std::mem::discriminant(&result) { - Ok(result) - } else { - Err(SyntaxError { - line: 0, - token, - got: Some(result), - }) - } -} - pub fn check_token_raw(token: Token, token_target: &Token) -> bool { std::mem::discriminant(&token) == std::mem::discriminant(token_target) } diff --git a/interpreter/src/lang/vocabulary/files.rs b/interpreter/src/lang/vocabulary/files.rs index 75f3d1a..f28fe33 100644 --- a/interpreter/src/lang/vocabulary/files.rs +++ b/interpreter/src/lang/vocabulary/files.rs @@ -141,11 +141,11 @@ impl FunctionFactory for FilesFunctionFactory { tokens: &mut VecDeque, _dict: &LanguageDictionary, ) -> Result { - // files([folder|dir=]"path", [regex|re = "pattern"], [recursive = true|false]) + // files([folder|dir=]"path", [regex|re = "pattern",] [recursive = true|false,]) let mut root_path = None; let mut pattern = None; let mut recursive = None; - if !tokens.is_empty() { + if !tokens.is_empty() && !tokens[0].is_close_bracket() { if tokens[0].is_literal() { // folder is specified without keyword root_path = Some(assert_token( @@ -162,7 +162,7 @@ impl FunctionFactory for FilesFunctionFactory { } // parse keyword function parameters let ingest = |tokens2: &mut VecDeque| { - if tokens2.len() < 3 { + if tokens2[0].is_close_bracket() { return Ok(None); } // nothing wrong, nothing left to ingest let param_name = assert_token( diff --git a/interpreter/src/lang/vocabulary/filters/empty_filter.rs b/interpreter/src/lang/vocabulary/filters/empty_filter.rs index c18d66f..cf68cd0 100644 --- a/interpreter/src/lang/vocabulary/filters/empty_filter.rs +++ b/interpreter/src/lang/vocabulary/filters/empty_filter.rs @@ -35,7 +35,7 @@ pub struct EmptyFilterFactory; impl FilterFactory for EmptyFilterFactory { fn is_filter(&self, tokens: &VecDeque<&Token>) -> bool { - tokens.is_empty() + !tokens.is_empty() && tokens[0].is_close_bracket() } fn build_filter( diff --git a/interpreter/src/lang/vocabulary/filters/field/field_match_filter.rs b/interpreter/src/lang/vocabulary/filters/field/field_match_filter.rs index 0cc1f3c..6194b9b 100644 --- a/interpreter/src/lang/vocabulary/filters/field/field_match_filter.rs +++ b/interpreter/src/lang/vocabulary/filters/field/field_match_filter.rs @@ -167,7 +167,7 @@ impl FieldFilterFactory for FieldRegexFilterFactory { fn regex_flags(tokens: &mut VecDeque) -> Result { // syntax: , "flags" let mut result = 0_u8; - if tokens.is_empty() { + if tokens.is_empty() || !tokens[0].is_comma() { Ok(result) } else { assert_token_raw(Token::Comma, tokens)?; diff --git a/interpreter/src/lang/vocabulary/filters/index_filter.rs b/interpreter/src/lang/vocabulary/filters/index_filter.rs index 114593b..358bfd4 100644 --- a/interpreter/src/lang/vocabulary/filters/index_filter.rs +++ b/interpreter/src/lang/vocabulary/filters/index_filter.rs @@ -64,8 +64,8 @@ pub struct IndexFilterFactory; impl FilterFactory for IndexFilterFactory { fn is_filter(&self, tokens: &VecDeque<&Token>) -> bool { - (tokens.len() == 1 && Lookup::check_is(tokens[0])) - || (tokens.len() == 2 && tokens[0].is_exclamation() && Lookup::check_is(tokens[1])) + (tokens.len() >= 1 && Lookup::check_is(tokens[0])) + || (tokens.len() >= 2 && tokens[0].is_exclamation() && Lookup::check_is(tokens[1])) } fn build_filter( diff --git a/interpreter/src/lang/vocabulary/filters/range_filter.rs b/interpreter/src/lang/vocabulary/filters/range_filter.rs index c007315..d568268 100644 --- a/interpreter/src/lang/vocabulary/filters/range_filter.rs +++ b/interpreter/src/lang/vocabulary/filters/range_filter.rs @@ -101,9 +101,9 @@ pub struct RangeFilterFactory; impl FilterFactory for RangeFilterFactory { fn is_filter(&self, tokens: &VecDeque<&Token>) -> bool { - tokens.len() >= 2 - && ((tokens.len() >= 2 && tokens[0].is_dot() && tokens[1].is_dot()) - || (tokens.len() >= 3 + tokens.len() > 1 + && ((tokens[0].is_dot() && tokens[1].is_dot()) + || (tokens.len() > 2 && Lookup::check_is(tokens[0]) && tokens[1].is_dot() && tokens[2].is_dot())) @@ -132,7 +132,7 @@ impl FilterFactory for RangeFilterFactory { false }; // end index - let end = if !tokens.is_empty() { + let end = if !tokens.is_empty() && Lookup::check_is(&tokens[0]) { Some(Lookup::parse(tokens)?) } else { None diff --git a/interpreter/src/lang/vocabulary/filters/unique.rs b/interpreter/src/lang/vocabulary/filters/unique.rs index dcb12d9..ed88138 100644 --- a/interpreter/src/lang/vocabulary/filters/unique.rs +++ b/interpreter/src/lang/vocabulary/filters/unique.rs @@ -90,7 +90,7 @@ pub struct UniqueFilterFactory; impl FilterFactory for UniqueFilterFactory { fn is_filter(&self, tokens: &VecDeque<&Token>) -> bool { - tokens.len() >= 2 && check_name("unique", tokens[0]) && tokens[1].is_dot() + tokens.len() > 1 && check_name("unique", tokens[0]) && tokens[1].is_dot() } fn build_filter( @@ -108,7 +108,7 @@ impl FilterFactory for UniqueFilterFactory { Token::Name("field_name".into()), tokens, )?; - let error_handling = if !tokens.is_empty() { + let error_handling = if !tokens.is_empty() && (tokens[0].is_exclamation() || tokens[0].is_interrogation()) { if tokens[0].is_exclamation() { assert_token_raw(Token::Exclamation, tokens)?; FieldFilterErrorHandling::Ignore @@ -129,7 +129,7 @@ impl FilterFactory for UniqueFilterFactory { impl FilterFactory for UniqueFilterFactory { fn is_filter(&self, tokens: &VecDeque<&Token>) -> bool { - tokens.len() == 1 && check_name("unique", tokens[0]) + tokens.len() > 1 && check_name("unique", tokens[0]) } fn build_filter( diff --git a/interpreter/src/lang/vocabulary/item_ops/add.rs b/interpreter/src/lang/vocabulary/item_ops/add.rs index a27dc7b..c71c8b2 100644 --- a/interpreter/src/lang/vocabulary/item_ops/add.rs +++ b/interpreter/src/lang/vocabulary/item_ops/add.rs @@ -69,10 +69,11 @@ impl ItemOpFactory for AddItemOpFactory { dict: &LanguageDictionary, ) -> Result { let plus_location = first_plus(tokens).unwrap(); - let mut end_tokens = tokens.split_off(plus_location); + let end_tokens = tokens.split_off(plus_location); let lhs_op = factory.try_build_item_statement(tokens, dict)?; - assert_token_raw(Token::Plus, &mut end_tokens)?; - let rhs_op = factory.try_build_item_statement(&mut end_tokens, dict)?; + tokens.extend(end_tokens); + assert_token_raw(Token::Plus, tokens)?; + let rhs_op = factory.try_build_item_statement(tokens, dict)?; Ok(AddItemOp { lhs: lhs_op, rhs: rhs_op, @@ -90,6 +91,8 @@ fn first_plus(tokens: &VecDeque) -> Option { bracket_depth += 1; } else if token.is_close_bracket() && bracket_depth != 0 { bracket_depth -= 1; + } else if token.is_comma() && bracket_depth == 0 { + return None; } } None diff --git a/interpreter/src/lang/vocabulary/item_ops/brackets.rs b/interpreter/src/lang/vocabulary/item_ops/brackets.rs index a27faaa..8cc5826 100644 --- a/interpreter/src/lang/vocabulary/item_ops/brackets.rs +++ b/interpreter/src/lang/vocabulary/item_ops/brackets.rs @@ -1,7 +1,7 @@ use std::collections::VecDeque; use std::convert::AsRef; -use crate::lang::utility::{assert_token_raw, assert_token_raw_back}; +use crate::lang::utility::assert_token_raw; use crate::lang::LanguageDictionary; use crate::lang::{ItemBlockFactory, ItemOp, ItemOpFactory}; use crate::lang::{RuntimeMsg, SyntaxError}; @@ -13,9 +13,8 @@ pub struct BracketsItemOpFactory; impl ItemOpFactory> for BracketsItemOpFactory { fn is_item_op(&self, tokens: &VecDeque) -> bool { - tokens.len() >= 2 + !tokens.is_empty() && tokens[0].is_open_bracket() - && tokens[tokens.len() - 1].is_close_bracket() } fn build_item_op( @@ -25,8 +24,9 @@ impl ItemOpFactory> for BracketsItemOpFactory { dict: &LanguageDictionary, ) -> Result, SyntaxError> { assert_token_raw(Token::OpenBracket, tokens)?; - assert_token_raw_back(Token::CloseBracket, tokens)?; - factory.try_build_item_statement(tokens, dict) + let inner = factory.try_build_item_statement(tokens, dict)?; + assert_token_raw(Token::CloseBracket, tokens)?; + Ok(inner) } } diff --git a/interpreter/src/lang/vocabulary/item_ops/branch.rs b/interpreter/src/lang/vocabulary/item_ops/branch.rs index 72fab86..c06754a 100644 --- a/interpreter/src/lang/vocabulary/item_ops/branch.rs +++ b/interpreter/src/lang/vocabulary/item_ops/branch.rs @@ -126,10 +126,8 @@ impl ItemOpFactory for BranchItemOpFactory { let end_tokens = tokens.split_off(next_close_curly); let mut inner_if_ops = Vec::new(); while !tokens.is_empty() { - if let Some(next_comma) = find_next_comma(tokens) { - let end_tokens = tokens.split_off(next_comma); + if find_next_comma(tokens).is_some() { inner_if_ops.push(factory.try_build_item_statement(tokens, dict)?); - tokens.extend(end_tokens); assert_token_raw(Token::Comma, tokens)?; } else { inner_if_ops.push(factory.try_build_item_statement(tokens, dict)?); @@ -234,6 +232,8 @@ fn find_next_comma(tokens: &VecDeque) -> Option { let token = &tokens[i]; if token.is_comma() && bracket_depth == 0 && curly_depth == 0 { return Some(i); + } else if token.is_comma() && (bracket_depth < 0 || curly_depth < 0) { + return None; } else if token.is_open_bracket() { bracket_depth += 1; } else if token.is_close_bracket() && bracket_depth != 0 { diff --git a/interpreter/src/lang/vocabulary/item_ops/compare.rs b/interpreter/src/lang/vocabulary/item_ops/compare.rs index f03fd4f..af7be92 100644 --- a/interpreter/src/lang/vocabulary/item_ops/compare.rs +++ b/interpreter/src/lang/vocabulary/item_ops/compare.rs @@ -123,6 +123,9 @@ fn find_first_comparison(tokens: &VecDeque) -> Option { { return Some(i); } + }, + Token::Comma if curly_depth == 0 && bracket_depth == 0 => { + return None; } _ => {} } diff --git a/interpreter/src/lang/vocabulary/item_ops/constant.rs b/interpreter/src/lang/vocabulary/item_ops/constant.rs index 79a60f3..e5c035c 100644 --- a/interpreter/src/lang/vocabulary/item_ops/constant.rs +++ b/interpreter/src/lang/vocabulary/item_ops/constant.rs @@ -38,7 +38,7 @@ pub struct ConstantItemOpFactory; impl ItemOpFactory for ConstantItemOpFactory { fn is_item_op(&self, tokens: &VecDeque) -> bool { - tokens.len() == 1 && check_is_type(&tokens[0]) + !tokens.is_empty() && check_is_type(&tokens[0]) } fn build_item_op( diff --git a/interpreter/src/lang/vocabulary/item_ops/constructor.rs b/interpreter/src/lang/vocabulary/item_ops/constructor.rs index 1376e54..e654fc7 100644 --- a/interpreter/src/lang/vocabulary/item_ops/constructor.rs +++ b/interpreter/src/lang/vocabulary/item_ops/constructor.rs @@ -3,7 +3,7 @@ use std::collections::VecDeque; use std::fmt::{Debug, Display, Error, Formatter}; use crate::lang::utility::{ - assert_name, assert_token, assert_token_raw, assert_token_raw_back, check_name, + assert_name, assert_token, assert_token_raw, check_name, }; use crate::lang::LanguageDictionary; use crate::lang::{ItemBlockFactory, ItemOp, ItemOpFactory}; @@ -83,9 +83,11 @@ impl ItemOpFactory for ConstructorItemOpFactory { ) -> Result { assert_name("Item", tokens)?; assert_token_raw(Token::OpenBracket, tokens)?; - assert_token_raw_back(Token::CloseBracket, tokens)?; let mut field_descriptors = Vec::new(); while !tokens.is_empty() { + if tokens[0].is_close_bracket() { + break; + } let field_name = assert_token( |t| match t { Token::Name(n) => Some(n), @@ -96,10 +98,8 @@ impl ItemOpFactory for ConstructorItemOpFactory { )?; assert_token_raw(Token::Equals, tokens)?; let field_val; - if let Some(comma_pos) = find_next_comma(tokens) { - let end_tokens = tokens.split_off(comma_pos); + if find_next_comma(tokens).is_some() { field_val = factory.try_build_item_statement(tokens, dict)?; - tokens.extend(end_tokens); assert_token_raw(Token::Comma, tokens)?; } else { field_val = factory.try_build_item_statement(tokens, dict)?; @@ -109,6 +109,7 @@ impl ItemOpFactory for ConstructorItemOpFactory { value: field_val, }); } + assert_token_raw(Token::CloseBracket, tokens)?; Ok(ConstructorItemOp { fields: field_descriptors, }) diff --git a/interpreter/src/lang/vocabulary/item_ops/empty.rs b/interpreter/src/lang/vocabulary/item_ops/empty.rs index 00241b0..107fe7d 100644 --- a/interpreter/src/lang/vocabulary/item_ops/empty.rs +++ b/interpreter/src/lang/vocabulary/item_ops/empty.rs @@ -36,10 +36,8 @@ pub struct EmptyItemOpFactory; impl ItemOpFactory for EmptyItemOpFactory { fn is_item_op(&self, tokens: &VecDeque) -> bool { - tokens.len() == 3 + !tokens.is_empty() && check_name("empty", &tokens[0]) - && tokens[1].is_open_bracket() - && tokens[2].is_close_bracket() } fn build_item_op( diff --git a/interpreter/src/lang/vocabulary/item_ops/field_assign.rs b/interpreter/src/lang/vocabulary/item_ops/field_assign.rs index 764831f..cd924df 100644 --- a/interpreter/src/lang/vocabulary/item_ops/field_assign.rs +++ b/interpreter/src/lang/vocabulary/item_ops/field_assign.rs @@ -61,12 +61,12 @@ pub struct FieldAssignItemOpFactory; impl ItemOpFactory for FieldAssignItemOpFactory { fn is_item_op(&self, tokens: &VecDeque) -> bool { - (tokens.len() > 4 + (tokens.len() > 3 && tokens[0].is_name() && tokens[1].is_dot() && tokens[2].is_name() && tokens[3].is_equals()) - || (tokens.len() > 3 + || (tokens.len() > 2 && tokens[0].is_dot() && tokens[1].is_name() && tokens[2].is_equals()) diff --git a/interpreter/src/lang/vocabulary/item_ops/logical_and.rs b/interpreter/src/lang/vocabulary/item_ops/logical_and.rs index 34476fc..1130a9d 100644 --- a/interpreter/src/lang/vocabulary/item_ops/logical_and.rs +++ b/interpreter/src/lang/vocabulary/item_ops/logical_and.rs @@ -73,11 +73,12 @@ impl ItemOpFactory for AndItemOpFactory { dict: &LanguageDictionary, ) -> Result { let and_location = first_and(tokens).unwrap(); - let mut end_tokens = tokens.split_off(and_location); + let end_tokens = tokens.split_off(and_location); let lhs_op = factory.try_build_item_statement(tokens, dict)?; - assert_token_raw(Token::Ampersand, &mut end_tokens)?; - assert_token_raw(Token::Ampersand, &mut end_tokens)?; - let rhs_op = factory.try_build_item_statement(&mut end_tokens, dict)?; + tokens.extend(end_tokens); + assert_token_raw(Token::Ampersand, tokens)?; + assert_token_raw(Token::Ampersand, tokens)?; + let rhs_op = factory.try_build_item_statement(tokens, dict)?; Ok(AndItemOp { lhs: lhs_op, rhs: rhs_op, @@ -95,6 +96,8 @@ fn first_and(tokens: &VecDeque) -> Option { bracket_depth += 1; } else if token.is_close_bracket() && bracket_depth != 0 { bracket_depth -= 1; + } else if token.is_comma() && bracket_depth == 0 { + return None; } } None diff --git a/interpreter/src/lang/vocabulary/item_ops/logical_or.rs b/interpreter/src/lang/vocabulary/item_ops/logical_or.rs index e45f11a..90c4ee0 100644 --- a/interpreter/src/lang/vocabulary/item_ops/logical_or.rs +++ b/interpreter/src/lang/vocabulary/item_ops/logical_or.rs @@ -73,11 +73,12 @@ impl ItemOpFactory for OrItemOpFactory { dict: &LanguageDictionary, ) -> Result { let or_location = first_or(tokens).unwrap(); - let mut end_tokens = tokens.split_off(or_location); + let end_tokens = tokens.split_off(or_location); let lhs_op = factory.try_build_item_statement(tokens, dict)?; - assert_token_raw(Token::Pipe, &mut end_tokens)?; - assert_token_raw(Token::Pipe, &mut end_tokens)?; - let rhs_op = factory.try_build_item_statement(&mut end_tokens, dict)?; + tokens.extend(end_tokens); + assert_token_raw(Token::Pipe, tokens)?; + assert_token_raw(Token::Pipe, tokens)?; + let rhs_op = factory.try_build_item_statement(tokens, dict)?; Ok(OrItemOp { lhs: lhs_op, rhs: rhs_op, @@ -95,6 +96,8 @@ fn first_or(tokens: &VecDeque) -> Option { bracket_depth += 1; } else if token.is_close_bracket() && bracket_depth != 0 { bracket_depth -= 1; + } else if token.is_comma() && bracket_depth == 0 { + return None; } } None diff --git a/interpreter/src/lang/vocabulary/item_ops/mod.rs b/interpreter/src/lang/vocabulary/item_ops/mod.rs index d50dbc6..d7adb43 100644 --- a/interpreter/src/lang/vocabulary/item_ops/mod.rs +++ b/interpreter/src/lang/vocabulary/item_ops/mod.rs @@ -13,6 +13,7 @@ mod logical_or; mod negate; mod not; mod remove_variable; +mod retrieve_field; mod retrieve_variable; mod string_interpolate; mod subtract; @@ -34,6 +35,7 @@ pub use logical_or::{OrItemOp, OrItemOpFactory}; pub use negate::{NegateItemOp, NegateItemOpFactory}; pub use not::{NotItemOp, NotItemOpFactory}; pub use remove_variable::{RemoveItemOp, RemoveItemOpFactory}; +pub use retrieve_field::FieldRetrieveItemOpFactory; pub use retrieve_variable::{VariableRetrieveItemOp, VariableRetrieveItemOpFactory}; pub use string_interpolate::{InterpolateStringItemOp, InterpolateStringItemOpFactory}; pub use subtract::{SubtractItemOp, SubtractItemOpFactory}; diff --git a/interpreter/src/lang/vocabulary/item_ops/negate.rs b/interpreter/src/lang/vocabulary/item_ops/negate.rs index 20fb52c..590e851 100644 --- a/interpreter/src/lang/vocabulary/item_ops/negate.rs +++ b/interpreter/src/lang/vocabulary/item_ops/negate.rs @@ -46,7 +46,7 @@ pub struct NegateItemOpFactory; impl ItemOpFactory for NegateItemOpFactory { fn is_item_op(&self, tokens: &VecDeque) -> bool { - tokens.len() >= 2 && tokens[0].is_minus() + !tokens.is_empty() && tokens[0].is_minus() } fn build_item_op( diff --git a/interpreter/src/lang/vocabulary/item_ops/not.rs b/interpreter/src/lang/vocabulary/item_ops/not.rs index 45c66f3..c2aa777 100644 --- a/interpreter/src/lang/vocabulary/item_ops/not.rs +++ b/interpreter/src/lang/vocabulary/item_ops/not.rs @@ -46,7 +46,7 @@ pub struct NotItemOpFactory; impl ItemOpFactory for NotItemOpFactory { fn is_item_op(&self, tokens: &VecDeque) -> bool { - tokens.len() >= 2 && tokens[0].is_exclamation() + !tokens.is_empty() && tokens[0].is_exclamation() } fn build_item_op( diff --git a/interpreter/src/lang/vocabulary/item_ops/remove_variable.rs b/interpreter/src/lang/vocabulary/item_ops/remove_variable.rs index 718fa83..350ebd4 100644 --- a/interpreter/src/lang/vocabulary/item_ops/remove_variable.rs +++ b/interpreter/src/lang/vocabulary/item_ops/remove_variable.rs @@ -57,7 +57,7 @@ pub struct RemoveItemOpFactory; impl ItemOpFactory for RemoveItemOpFactory { fn is_item_op(&self, tokens: &VecDeque) -> bool { - (tokens.len() == 2 || tokens.len() == 4) && check_name("remove", &tokens[0]) + !tokens.is_empty() && check_name("remove", &tokens[0]) } fn build_item_op( @@ -75,7 +75,7 @@ impl ItemOpFactory for RemoveItemOpFactory { Token::Name("variable_name".into()), tokens, )?; - let field_opt = if tokens.is_empty() { + let field_opt = if tokens.is_empty() || !tokens[0].is_dot() { None } else { assert_token_raw(Token::Dot, tokens)?; diff --git a/interpreter/src/lang/vocabulary/item_ops/retrieve_field.rs b/interpreter/src/lang/vocabulary/item_ops/retrieve_field.rs new file mode 100644 index 0000000..5025bec --- /dev/null +++ b/interpreter/src/lang/vocabulary/item_ops/retrieve_field.rs @@ -0,0 +1,49 @@ +use std::collections::VecDeque; + +use crate::lang::utility::{assert_token, assert_token_raw}; +use crate::lang::LanguageDictionary; +use crate::lang::{ItemBlockFactory, ItemOpFactory}; +use crate::lang::SyntaxError; +use crate::tokens::Token; + +use super::VariableRetrieveItemOp; + +pub struct FieldRetrieveItemOpFactory; + +impl ItemOpFactory for FieldRetrieveItemOpFactory { + fn is_item_op(&self, tokens: &VecDeque) -> bool { + tokens.len() > 2 + && tokens[0].is_name() + && tokens[1].is_dot() + && tokens[2].is_name() + } + + fn build_item_op( + &self, + tokens: &mut VecDeque, + _factory: &ItemBlockFactory, + _dict: &LanguageDictionary, + ) -> Result { + let var_name = assert_token( + |t| match t { + Token::Name(s) => Some(s), + _ => None, + }, + Token::Name("variable_name".into()), + tokens, + )?; + assert_token_raw(Token::Dot, tokens)?; + let field = assert_token( + |t| match t { + Token::Name(s) => Some(s), + _ => None, + }, + Token::Name("field_name".into()), + tokens, + )?; + Ok(VariableRetrieveItemOp { + variable_name: var_name, + field_name: Some(field), + }) + } +} diff --git a/interpreter/src/lang/vocabulary/item_ops/retrieve_variable.rs b/interpreter/src/lang/vocabulary/item_ops/retrieve_variable.rs index 9cf3cdf..2dc3107 100644 --- a/interpreter/src/lang/vocabulary/item_ops/retrieve_variable.rs +++ b/interpreter/src/lang/vocabulary/item_ops/retrieve_variable.rs @@ -2,7 +2,7 @@ use core::ops::Deref; use std::collections::VecDeque; use std::fmt::{Debug, Display, Error, Formatter}; -use crate::lang::utility::{assert_token, assert_token_raw}; +use crate::lang::utility::assert_token; use crate::lang::LanguageDictionary; use crate::lang::{ItemBlockFactory, ItemOp, ItemOpFactory}; use crate::lang::{RuntimeMsg, SyntaxError}; @@ -12,8 +12,8 @@ use crate::Context; #[derive(Debug)] pub struct VariableRetrieveItemOp { - variable_name: String, - field_name: Option, + pub(super) variable_name: String, + pub(super) field_name: Option, } impl Deref for VariableRetrieveItemOp { @@ -65,11 +65,7 @@ pub struct VariableRetrieveItemOpFactory; impl ItemOpFactory for VariableRetrieveItemOpFactory { fn is_item_op(&self, tokens: &VecDeque) -> bool { - (tokens.len() == 1 && tokens[0].is_name()) - || (tokens.len() == 3 - && tokens[0].is_name() - && tokens[1].is_dot() - && tokens[2].is_name()) + !tokens.is_empty() && tokens[0].is_name() } fn build_item_op( @@ -86,22 +82,9 @@ impl ItemOpFactory for VariableRetrieveItemOpFactory { Token::Name("variable_name".into()), tokens, )?; - let field_opt = if tokens.is_empty() { - None - } else { - assert_token_raw(Token::Dot, tokens)?; - Some(assert_token( - |t| match t { - Token::Name(s) => Some(s), - _ => None, - }, - Token::Name("field_name".into()), - tokens, - )?) - }; Ok(VariableRetrieveItemOp { variable_name: var_name, - field_name: field_opt, + field_name: None, }) } } diff --git a/interpreter/src/lang/vocabulary/item_ops/subtract.rs b/interpreter/src/lang/vocabulary/item_ops/subtract.rs index e2480dd..5577a4b 100644 --- a/interpreter/src/lang/vocabulary/item_ops/subtract.rs +++ b/interpreter/src/lang/vocabulary/item_ops/subtract.rs @@ -69,10 +69,11 @@ impl ItemOpFactory for SubtractItemOpFactory { dict: &LanguageDictionary, ) -> Result { let minus_location = first_minus(tokens).unwrap(); - let mut end_tokens = tokens.split_off(minus_location); + let end_tokens = tokens.split_off(minus_location); let lhs_op = factory.try_build_item_statement(tokens, dict)?; - assert_token_raw(Token::Minus, &mut end_tokens)?; - let rhs_op = factory.try_build_item_statement(&mut end_tokens, dict)?; + tokens.extend(end_tokens); + assert_token_raw(Token::Minus, tokens)?; + let rhs_op = factory.try_build_item_statement(tokens, dict)?; Ok(SubtractItemOp { lhs: lhs_op, rhs: rhs_op, @@ -90,6 +91,8 @@ fn first_minus(tokens: &VecDeque) -> Option { bracket_depth += 1; } else if token.is_close_bracket() && bracket_depth != 0 { bracket_depth -= 1; + } else if token.is_comma() && bracket_depth == 0 { + return None; } } None diff --git a/interpreter/src/lang/vocabulary/item_ops/variable_declare.rs b/interpreter/src/lang/vocabulary/item_ops/variable_declare.rs index ba30a3c..a9b408f 100644 --- a/interpreter/src/lang/vocabulary/item_ops/variable_declare.rs +++ b/interpreter/src/lang/vocabulary/item_ops/variable_declare.rs @@ -72,7 +72,7 @@ impl ItemOpFactory for VariableDeclareItemOpFactory { Token::Name("variable_name".into()), tokens, )?; - let inner_op: Option> = if !tokens.is_empty() { + let inner_op: Option> = if !tokens.is_empty() && tokens[0].is_equals() { assert_token_raw(Token::Equals, tokens)?; Some(factory.try_build_item_statement(tokens, dict)?) } else { diff --git a/interpreter/src/lang/vocabulary/mod.rs b/interpreter/src/lang/vocabulary/mod.rs index 4773811..fc382d3 100644 --- a/interpreter/src/lang/vocabulary/mod.rs +++ b/interpreter/src/lang/vocabulary/mod.rs @@ -12,6 +12,7 @@ mod sql_query; mod sql_simple_query; mod union; mod variable_assign; +mod variable_iter; pub use empties::{empties_function_factory, EmptiesStatementFactory}; pub use empty::{empty_function_factory, EmptyStatementFactory}; @@ -26,6 +27,7 @@ pub use sql_query::{sql_function_factory, SqlStatementFactory}; pub use sql_simple_query::{simple_sql_function_factory, SimpleSqlStatementFactory}; pub use union::{union_function_factory, UnionStatementFactory}; pub use variable_assign::{AssignStatement, AssignStatementFactory}; +pub use variable_iter::{VariableRetrieveStatement, VariableRetrieveStatementFactory}; pub mod filters; pub mod item_ops; diff --git a/interpreter/src/lang/vocabulary/repeat.rs b/interpreter/src/lang/vocabulary/repeat.rs index 48a0ef1..9c910c7 100644 --- a/interpreter/src/lang/vocabulary/repeat.rs +++ b/interpreter/src/lang/vocabulary/repeat.rs @@ -15,7 +15,6 @@ use crate::lang::{RuntimeError, SyntaxError}; pub struct RepeatStatement { inner_statement: PseudoOp, inner_done: bool, - context: Option, cache: Vec, cache_position: usize, repetitions: usize, @@ -42,7 +41,6 @@ impl std::clone::Clone for RepeatStatement { Self { inner_statement: self.inner_statement.clone(), inner_done: self.inner_done, - context: None, cache: self.cache.clone(), cache_position: self.cache_position, repetitions: self.repetitions, @@ -60,11 +58,6 @@ impl Iterator for RepeatStatement { Err(e) => return Some(Err(e)), Ok(real) => real, }; - // give context to inner (should only occur on first run) - if self.context.is_some() { - let ctx = self.context.take().unwrap(); - real_op.enter(ctx); - } if real_op.is_resetable() { while self.loop_forever || !self.inner_done { if let Some(item) = real_op.next() { @@ -73,8 +66,6 @@ impl Iterator for RepeatStatement { if !self.loop_forever { if self.repetitions == 0 { self.inner_done = true; - // take context from inner (should only occur when inner is no longer needed) - self.context = Some(real_op.escape()); } else { self.repetitions -= 1; if let Err(e) = real_op.reset() { @@ -88,17 +79,10 @@ impl Iterator for RepeatStatement { } } } - if self.context.is_none() { - self.context = Some(real_op.escape()); - } None } else { // cache items in RepeatStatement since inner_statement cannot be reset if !self.inner_done { - if self.context.is_some() { - let ctx = self.context.take().unwrap(); - real_op.enter(ctx); - } let inner_item = real_op.next(); match inner_item { Some(x) => { @@ -113,7 +97,6 @@ impl Iterator for RepeatStatement { None => { // inner has completed it's only run self.inner_done = true; - self.context = Some(real_op.escape()); } } } @@ -156,27 +139,23 @@ impl Iterator for RepeatStatement { impl Op for RepeatStatement { fn enter(&mut self, ctx: Context) { - self.context = Some(ctx) + self.inner_statement.try_real().unwrap().enter(ctx) } fn escape(&mut self) -> Context { - if self.context.is_some() { - self.context.take().unwrap() - } else { - self.inner_statement.try_real().unwrap().escape() - } + self.inner_statement.try_real().unwrap().escape() } fn is_resetable(&self) -> bool { - true + if let Ok(real_op) = self.inner_statement.try_real_ref() { + real_op.is_resetable() + } else { + false + } } fn reset(&mut self) -> Result<(), RuntimeError> { let real_op = self.inner_statement.try_real()?; - if self.context.is_some() { - let ctx = self.context.take().unwrap(); - real_op.enter(ctx); - } if real_op.is_resetable() { real_op.reset()?; if self.original_repetitions == 0 { @@ -204,7 +183,6 @@ impl Op for RepeatStatement { let clone = Self { inner_statement: PseudoOp::from(self.inner_statement.try_real_ref().unwrap().dup()), inner_done: self.original_repetitions == 0, - context: None, cache: Vec::new(), cache_position: 0, repetitions: if self.original_repetitions != 0 { @@ -239,7 +217,7 @@ impl FunctionFactory for RepeatFunctionFactory { tokens.extend(end_tokens); let mut count: Option = None; let mut inner_done = false; - if !tokens.is_empty() { + if !tokens.is_empty() && tokens[0].is_comma() { // repititions specified assert_token_raw(Token::Comma, tokens)?; count = Some(assert_token( @@ -264,7 +242,6 @@ impl FunctionFactory for RepeatFunctionFactory { Ok(RepeatStatement { inner_statement: inner_statement.into(), inner_done, - context: None, cache: Vec::new(), cache_position: 0, repetitions: count.unwrap_or(0), diff --git a/interpreter/src/lang/vocabulary/sorters/empty_sorter.rs b/interpreter/src/lang/vocabulary/sorters/empty_sorter.rs index afa065f..4df5961 100644 --- a/interpreter/src/lang/vocabulary/sorters/empty_sorter.rs +++ b/interpreter/src/lang/vocabulary/sorters/empty_sorter.rs @@ -32,7 +32,7 @@ pub struct EmptySorterFactory; impl SorterFactory for EmptySorterFactory { fn is_sorter(&self, tokens: &VecDeque<&Token>) -> bool { - tokens.is_empty() + !tokens.is_empty() && tokens[0].is_close_bracket() } fn build_sorter( diff --git a/interpreter/src/lang/vocabulary/union.rs b/interpreter/src/lang/vocabulary/union.rs index 8740511..3b41da9 100644 --- a/interpreter/src/lang/vocabulary/union.rs +++ b/interpreter/src/lang/vocabulary/union.rs @@ -163,15 +163,10 @@ impl FunctionFactory for UnionFunctionFactory { ) -> Result { // union(op1, op2, ...) let operations = repeated_tokens( - |tokens| { - if let Some(comma_pos) = next_comma(tokens) { - let end_tokens = tokens.split_off(comma_pos); - let op = dict.try_build_statement(tokens); - tokens.extend(end_tokens); - Ok(Some(PseudoOp::from(op?))) - } else { - Ok(Some(PseudoOp::from(dict.try_build_statement(tokens)?))) - } + |tokens| if tokens[0].is_close_bracket() { + Ok(None) + } else { + Ok(Some(PseudoOp::from(dict.try_build_statement(tokens)?))) }, Token::Comma, ) diff --git a/interpreter/src/lang/vocabulary/variable_iter.rs b/interpreter/src/lang/vocabulary/variable_iter.rs new file mode 100644 index 0000000..3346ffc --- /dev/null +++ b/interpreter/src/lang/vocabulary/variable_iter.rs @@ -0,0 +1,177 @@ +use std::collections::VecDeque; +use std::fmt::{Debug, Display, Error, Formatter}; +use std::iter::Iterator; + +use crate::tokens::Token; +use crate::Context; + +use crate::lang::utility::assert_token; +use crate::lang::LanguageDictionary; +use crate::lang::{BoxedOpFactory, IteratorItem, Op, OpFactory, PseudoOp}; +use crate::lang::{RuntimeError, RuntimeOp, SyntaxError}; +use crate::processing::general::Type; + +#[derive(Debug)] +pub struct VariableRetrieveStatement { + variable_name: String, + context: Option, + is_tried: bool, +} + +impl Display for VariableRetrieveStatement { + fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { + write!(f, "{}", self.variable_name) + } +} + +impl std::clone::Clone for VariableRetrieveStatement { + fn clone(&self) -> Self { + Self { + variable_name: self.variable_name.clone(), + context: None, + is_tried: self.is_tried, + } + } +} + +impl Iterator for VariableRetrieveStatement { + type Item = IteratorItem; + + fn next(&mut self) -> Option { + if self.is_tried { + return None; + } + let var = self.context.as_mut() + .unwrap() + .variables.remove(&self.variable_name) + .map_err(|e| e.with(RuntimeOp(PseudoOp::from_printable(self)))); + match var { + Ok(Type::Op(mut op)) => { + op.enter(self.context.take().unwrap()); + let next_item = op.next(); + self.enter(op.escape()); + if let Err(e) = self.context.as_mut().unwrap().variables.declare(&self.variable_name, Type::Op(op)) { + return Some(Err(e.with(RuntimeOp(PseudoOp::from_printable(self))))); + } + next_item + }, + Ok(Type::Item(item)) => { + self.is_tried = true; + if let Err(e) = self.context.as_mut().unwrap().variables.declare(&self.variable_name, Type::Item(item.clone())) { + return Some(Err(e.with(RuntimeOp(PseudoOp::from_printable(self))))); + } + Some(Ok(item)) + }, + Ok(Type::Primitive(p)) => { + self.is_tried = true; + let err_msg = format!("Cannot iterate over primitive `{}` ({})", self.variable_name, p); + if let Err(e) = self.context.as_mut().unwrap().variables.declare(&self.variable_name, Type::Primitive(p)) { + return Some(Err(e.with(RuntimeOp(PseudoOp::from_printable(self))))); + } + Some(Err( + RuntimeError { + line: 0, + op: PseudoOp::from_printable(self), + msg: err_msg, + } + )) + } + Err(e) => { + self.is_tried = true; + Some(Err(e)) + } + } + } + + fn size_hint(&self) -> (usize, Option) { + (0, None) + } +} + +impl Op for VariableRetrieveStatement { + fn enter(&mut self, ctx: Context) { + self.context = Some(ctx) + } + + fn escape(&mut self) -> Context { + self.context.take().unwrap() + } + + fn is_resetable(&self) -> bool { + if let Some(ctx) = &self.context { + let var = ctx.variables.get(&self.variable_name); + match var { + Ok(Type::Op(op)) => op.is_resetable(), + Ok(Type::Primitive(_)) => false, + Ok(Type::Item(_)) => true, + Err(_) => false, + } + } else { + false + } + } + + fn reset(&mut self) -> Result<(), RuntimeError> { + self.is_tried = false; + let runtime_op = RuntimeOp(PseudoOp::from_printable(self)); + let var = self.context.as_mut() + .unwrap() + .variables.get_mut(&self.variable_name) + .map_err(|e| e.with(runtime_op))?; + + if let Type::Op(op) = var { + op.reset()?; + } + Ok(()) + } + + fn dup(&self) -> Box { + Box::new(Self { + variable_name: self.variable_name.clone(), + context: None, + is_tried: false, + }) + } +} + +pub struct VariableRetrieveStatementFactory; + +impl OpFactory for VariableRetrieveStatementFactory { + fn is_op(&self, tokens: &VecDeque) -> bool { + !tokens.is_empty() && tokens[0].is_name() + } + + fn build_op( + &self, + tokens: &mut VecDeque, + _dict: &LanguageDictionary, + ) -> Result { + let name = assert_token( + |t| match t { + Token::Name(s) => Some(s), + _ => None, + }, + Token::Name("variable_name".into()), + tokens, + )?; + Ok(VariableRetrieveStatement { + variable_name: name, + context: None, + is_tried: false, + }) + } +} + +impl BoxedOpFactory for VariableRetrieveStatementFactory { + fn build_op_boxed( + &self, + tokens: &mut VecDeque, + dict: &LanguageDictionary, + ) -> Result, SyntaxError> { + self.build_box(tokens, dict) + } + + fn is_op_boxed(&self, tokens: &VecDeque) -> bool { + self.is_op(tokens) + } +} diff --git a/interpreter/tests/single_line.rs b/interpreter/tests/single_line.rs index f971aec..bb1a8e7 100644 --- a/interpreter/tests/single_line.rs +++ b/interpreter/tests/single_line.rs @@ -315,7 +315,14 @@ fn execute_replacefilter_line() -> Result<(), InterpreterError> { true, )?; execute_single_line( - "files(`~/Music/MusicFlac/Bruno Mars/24K Magic/`).(if 4: item.() else files(`~/Music/MusicFlac/Bruno Mars/24K Magic/`).(0 || 1).(if 200: files() else repeat(item.(), 2)))", + r#"files(`~/Music/MusicFlac/Bruno Mars/24K Magic/`) + .( + if 4: item.() + else files(`~/Music/MusicFlac/Bruno Mars/24K Magic/`) + .(0 || 1) + + .(if 200: files() else repeat(item.(), 2)) + )"#, false, true, ) @@ -323,11 +330,6 @@ fn execute_replacefilter_line() -> Result<(), InterpreterError> { #[test] fn execute_emptysort_line() -> Result<(), InterpreterError> { - execute_single_line( - "files(`~/Music/MusicFlac/Bruno Mars/24K Magic/`).sort()", - false, - true, - )?; execute_single_line( "files(`~/Music/MusicFlac/Bruno Mars/24K Magic/`)~()", false, @@ -367,7 +369,7 @@ fn execute_fieldsort_line() -> Result<(), InterpreterError> { true, )?; execute_single_line( - "files(`~/Music/MusicFlac/Bruno Mars/24K Magic/`).sort(.not_a_field)", + "files(`~/Music/MusicFlac/Bruno Mars/24K Magic/`)~(.not_a_field)", false, true, ) @@ -661,6 +663,13 @@ fn execute_bracketsitemop_line() -> Result<(), InterpreterError> { #[test] fn execute_stringifyitemop_line() -> Result<(), InterpreterError> { + execute_single_line( + "files(`~/Music/MusicFlac/Bruno Mars/24K Magic/`).{ + item.title = ~`test out: {track_number}` item +}", + false, + true, + )?; execute_single_line( "files(`~/Music/MusicFlac/Bruno Mars/24K Magic/`).{ item.filepath = ~`test out: {test}` item, diff --git a/player/Cargo.toml b/player/Cargo.toml index 2a48467..900c66f 100644 --- a/player/Cargo.toml +++ b/player/Cargo.toml @@ -15,6 +15,7 @@ muss-interpreter = { path = "../interpreter", version = "0.9.0" } [target.'cfg(target_os = "linux")'.dependencies] #dbus = { version = "^0.9" } +# TODO replace mpris-player, maybe with mpris2-zbus https://github.com/pop-os/dbus-settings-bindings/tree/main/mpris2 mpris-player = { version = "^0.6", path = "../mpris-player", optional = true } base64 = { version = "0.13", optional = true }