diff --git a/Cargo.lock b/Cargo.lock index 3553ad20..797ff920 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,6 +9,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "air-parser" +version = "0.1.0" +dependencies = [ + "codespan", + "codespan-reporting", + "fstrings", + "lalrpop", + "lalrpop-util", + "regex", +] + [[package]] name = "ansi_term" version = "0.11.0" @@ -20,9 +32,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.33" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fd36ffbb1fb7c834eac128ea8d0e310c5aeb635548f9d58861e1308d46e71c" +checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7" [[package]] name = "aqua-test-module" @@ -80,6 +92,15 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "ascii-canvas" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff8eb72df928aafb99fe5d37b383f2fe25bd2a765e3e5f7c365916b6f2463a29" +dependencies = [ + "term", +] + [[package]] name = "atty" version = "0.2.14" @@ -97,6 +118,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + [[package]] name = "bincode" version = "1.3.1" @@ -107,12 +134,38 @@ dependencies = [ "serde", ] +[[package]] +name = "bit-set" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0dc55f2d8a1a85650ac47858bb001b4c0dd73d79e3c455a842925e68d29cd3" + [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + [[package]] name = "blake3" version = "0.3.7" @@ -128,6 +181,27 @@ dependencies = [ "digest 0.9.0", ] +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array 0.12.3", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + [[package]] name = "boolinator" version = "2.4.0" @@ -152,6 +226,12 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + [[package]] name = "byteorder" version = "1.3.4" @@ -212,10 +292,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "475bd7aa7680b4ed8f6bb59745e882bcbaeb39326532bb79ffb1716480d9a274" [[package]] -name = "const_fn" -version = "0.4.2" +name = "codespan" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce90df4c658c62f12d78f7508cf92f9173e5184a539c10bfe54a3107b3ffd0f2" +checksum = "8ebaf6bb6a863ad6aa3a18729e9710c53d75df03306714d9cc1f7357a00cd789" +dependencies = [ + "codespan-reporting", +] + +[[package]] +name = "codespan-reporting" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e0762455306b1ed42bc651ef6a2197aabda5e1d4a43c34d5eab5c1a3634e81d" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "const_fn" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c478836e029dcef17fb47c89023448c64f781a046e0300e257ad8225ae59afab" [[package]] name = "constant_time_eq" @@ -326,7 +425,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils", + "crossbeam-utils 0.8.0", ] [[package]] @@ -337,7 +436,7 @@ checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", - "crossbeam-utils", + "crossbeam-utils 0.8.0", ] [[package]] @@ -348,12 +447,23 @@ checksum = "ec0f606a85340376eef0d6d8fec399e6d4a544d648386c6645eb6d0653b27d9f" dependencies = [ "cfg-if 1.0.0", "const_fn", - "crossbeam-utils", + "crossbeam-utils 0.8.0", "lazy_static", "memoffset", "scopeguard", ] +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if 0.1.10", + "lazy_static", +] + [[package]] name = "crossbeam-utils" version = "0.8.0" @@ -408,6 +518,12 @@ dependencies = [ "syn", ] +[[package]] +name = "diff" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" + [[package]] name = "difference" version = "2.0.0" @@ -432,12 +548,44 @@ dependencies = [ "generic-array 0.14.4", ] +[[package]] +name = "dirs" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "docopt" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f525a586d310c87df72ebcd98009e57f1cc030c8c268305287a476beb653969" +dependencies = [ + "lazy_static", + "regex", + "serde", + "strsim", +] + [[package]] name = "either" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +[[package]] +name = "ena" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3" +dependencies = [ + "log", +] + [[package]] name = "env_logger" version = "0.7.1" @@ -481,6 +629,12 @@ dependencies = [ "libc", ] +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + [[package]] name = "fce" version = "0.1.9" @@ -523,6 +677,12 @@ dependencies = [ "wasmer-runtime-core-fl", ] +[[package]] +name = "fixedbitset" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" + [[package]] name = "fluence" version = "0.2.8" @@ -618,6 +778,28 @@ dependencies = [ "uuid", ] +[[package]] +name = "fstrings" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7845a0f15da505ac36baad0486612dab57f8b8d34e19c5470a265bbcdd572ae6" +dependencies = [ + "fstrings-proc-macro", + "proc-macro-hack", +] + +[[package]] +name = "fstrings-proc-macro" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b58c0e7581dc33478a32299182cbe5ae3b8c028be26728a47fb0a113c92d9d" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "gcc" version = "0.3.55" @@ -650,7 +832,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" dependencies = [ "typenum", - "version_check 0.9.2", + "version_check", ] [[package]] @@ -806,6 +988,40 @@ dependencies = [ "serde_json", ] +[[package]] +name = "lalrpop" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60fb56191fb8ed5311597e5750debe6779c9fdb487dbaa5ff302592897d7a2c8" +dependencies = [ + "ascii-canvas", + "atty", + "bit-set", + "diff", + "docopt", + "ena", + "itertools", + "lalrpop-util", + "petgraph", + "regex", + "regex-syntax", + "serde", + "serde_derive", + "sha2", + "string_cache", + "term", + "unicode-xid", +] + +[[package]] +name = "lalrpop-util" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6771161eff561647fad8bb7e745e002c304864fb8f436b52b30acda51fca4408" +dependencies = [ + "regex", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -901,6 +1117,12 @@ dependencies = [ "serde", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + [[package]] name = "nix" version = "0.15.0" @@ -914,16 +1136,6 @@ dependencies = [ "void", ] -[[package]] -name = "nom" -version = "4.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -dependencies = [ - "memchr", - "version_check 0.1.5", -] - [[package]] name = "nom" version = "5.1.2" @@ -932,7 +1144,7 @@ checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" dependencies = [ "lexical-core", "memchr", - "version_check 0.9.2", + "version_check", ] [[package]] @@ -966,6 +1178,12 @@ version = "11.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a170cebd8021a008ea92e4db85a72f80b35df514ec664b296fdcbb654eac0b2c" +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + [[package]] name = "output_vt100" version = "0.1.2" @@ -1015,6 +1233,25 @@ dependencies = [ "winapi", ] +[[package]] +name = "petgraph" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + [[package]] name = "plotters" version = "0.2.15" @@ -1029,9 +1266,15 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "pretty_assertions" @@ -1045,6 +1288,12 @@ dependencies = [ "output_vt100", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + [[package]] name = "proc-macro2" version = "1.0.24" @@ -1152,7 +1401,7 @@ checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" dependencies = [ "crossbeam-channel", "crossbeam-deque", - "crossbeam-utils", + "crossbeam-utils 0.8.0", "lazy_static", "num_cpus", ] @@ -1164,10 +1413,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] -name = "regex" -version = "1.4.1" +name = "redox_users" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8963b85b8ce3074fecffde43b4b0dded83ce2f367dc8d363afc56679f3ee820b" +checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +dependencies = [ + "getrandom", + "redox_syscall", + "rust-argon2", +] + +[[package]] +name = "regex" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" dependencies = [ "aho-corasick", "memchr", @@ -1186,9 +1446,21 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cab7a364d15cde1e505267766a2d3c4e22a843e1a601f0fa7564c0f82ced11c" +checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" + +[[package]] +name = "rust-argon2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19" +dependencies = [ + "base64", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils 0.7.2", +] [[package]] name = "rustc_version" @@ -1303,15 +1575,23 @@ dependencies = [ ] [[package]] -name = "serde_sexpr" -version = "0.1.0" +name = "sha2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5318bfeed779c64075ce317c81462ed54dc00021be1c6b34957d798e11a68bdb" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" dependencies = [ - "nom 4.2.3", - "serde", + "block-buffer", + "digest 0.8.1", + "fake-simd", + "opaque-debug", ] +[[package]] +name = "siphasher" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7" + [[package]] name = "smallvec" version = "1.4.2" @@ -1328,6 +1608,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" name = "stepper-lib" version = "0.1.2" dependencies = [ + "air-parser", "aqua-test-utils", "aquamarine-vm", "boolinator", @@ -1342,10 +1623,28 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "serde_sexpr", "wasm-bindgen", ] +[[package]] +name = "string_cache" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2940c75beb4e3bf3a494cef919a747a2cb81e52571e212bfbd185074add7208a" +dependencies = [ + "lazy_static", + "new_debug_unreachable", + "phf_shared", + "precomputed-hash", + "serde", +] + +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + [[package]] name = "subtle" version = "2.3.0" @@ -1369,6 +1668,17 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab0e7238dcc7b40a7be719a25365910f6807bd864f4cce6b2e6b873658e2b19d" +[[package]] +name = "term" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" +dependencies = [ + "byteorder", + "dirs", + "winapi", +] + [[package]] name = "termcolor" version = "1.1.0" @@ -1503,12 +1813,6 @@ dependencies = [ "rand", ] -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" - [[package]] name = "version_check" version = "0.9.2" @@ -1683,7 +1987,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1de496e366bd1c198942248fc1de4b94e4647b263dd60099d5f7776f0d621656" dependencies = [ "log", - "nom 5.1.2", + "nom", "safe-transmute", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 5a0ba7c6..ee1ca13f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,6 @@ [workspace] members = [ + "crates/air-parser", "crates/test-module", "crates/test-utils", "stepper", diff --git a/artifacts/aquamarine.wasm b/artifacts/aquamarine.wasm deleted file mode 100644 index 0c394581..00000000 Binary files a/artifacts/aquamarine.wasm and /dev/null differ diff --git a/crates/air-parser/Cargo.toml b/crates/air-parser/Cargo.toml new file mode 100644 index 00000000..bb947066 --- /dev/null +++ b/crates/air-parser/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "air-parser" +version = "0.1.0" +authors = ["Fluence Labs"] +edition = "2018" + +[build-dependencies] +lalrpop = { version = "0.19.1", features = ["lexer"] } + +[dependencies] +lalrpop-util = { version = "0.19.1", features = ["lexer"] } +regex = "1.4.1" +codespan = "0.9.5" +codespan-reporting = "0.9.5" + +[dev-dependencies] +fstrings = "0.2.3" diff --git a/crates/air-parser/build.rs b/crates/air-parser/build.rs new file mode 100644 index 00000000..e8855cd0 --- /dev/null +++ b/crates/air-parser/build.rs @@ -0,0 +1,24 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +extern crate lalrpop; + +fn main() { + lalrpop::Configuration::new() + .generate_in_source_tree() + .process() + .unwrap(); +} diff --git a/crates/air-parser/src/ast.rs b/crates/air-parser/src/ast.rs new file mode 100644 index 00000000..522d9b24 --- /dev/null +++ b/crates/air-parser/src/ast.rs @@ -0,0 +1,95 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use std::rc::Rc; + +#[derive(Debug, PartialEq, Eq)] +pub enum Instruction<'i> { + Null(Null), + Call(Call<'i>), + Seq(Seq<'i>), + Par(Par<'i>), + Xor(Xor<'i>), + Fold(Fold<'i>), + Next(Next<'i>), + Error, +} + +#[derive(Debug, PartialEq, Eq)] +pub enum PeerPart<'i> { + PeerPk(Value<'i>), + PeerPkWithServiceId(Value<'i>, Value<'i>), +} + +#[derive(Debug, PartialEq, Eq)] +pub enum FunctionPart<'i> { + FuncName(Value<'i>), + ServiceIdWithFuncName(Value<'i>, Value<'i>), +} + +#[derive(Debug, PartialEq, Eq)] +pub struct Call<'i> { + pub peer_part: PeerPart<'i>, + pub function_part: FunctionPart<'i>, + pub args: Vec>, + pub output: CallOutput<'i>, +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum Value<'i> { + Variable(&'i str), + Literal(&'i str), + JsonPath { variable: &'i str, path: &'i str }, + CurrentPeerId, +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum CallOutput<'i> { + Scalar(&'i str), + Accumulator(&'i str), +} + +impl<'i> CallOutput<'i> { + pub fn name(&self) -> &'i str { + use CallOutput::*; + + match self { + Scalar(name) | Accumulator(name) => name, + } + } +} + +#[derive(Debug, PartialEq, Eq)] +pub struct Seq<'i>(pub Box>, pub Box>); + +#[derive(Debug, PartialEq, Eq)] +pub struct Par<'i>(pub Box>, pub Box>); + +#[derive(Debug, PartialEq, Eq)] +pub struct Xor<'i>(pub Box>, pub Box>); + +#[derive(Debug, PartialEq, Eq)] +pub struct Fold<'i> { + pub iterable: &'i str, + pub iterator: &'i str, + pub instruction: Rc>, +} + +#[derive(Debug, PartialEq, Eq)] +pub struct Next<'i>(pub &'i str); + +#[derive(Debug, PartialEq, Eq)] +pub struct Null; diff --git a/crates/air-parser/src/lalrpop/aqua.lalrpop b/crates/air-parser/src/lalrpop/aqua.lalrpop new file mode 100644 index 00000000..590ad271 --- /dev/null +++ b/crates/air-parser/src/lalrpop/aqua.lalrpop @@ -0,0 +1,90 @@ +use crate::ast::*; +use crate::lalrpop::parser::InstructionError; + +use lalrpop_util::ErrorRecovery; +use std::rc::Rc; + +grammar<'err>(errors: &'err mut Vec, InstructionError>>); + +extern { + type Error = InstructionError; +} + +pub Instr: Box> = { + "(" "seq" ")" => Box::new(Instruction::Seq(Seq(l, r))), + "(" "par" ")" => Box::new(Instruction::Par(Par(l, r))), + "(" "xor" ")" => Box::new(Instruction::Xor(Xor(l, r))), + + "(" "call" ")" => + Box::new(Instruction::Call(Call{peer, f, args, output})), + + "(" "fold" ")" => { + let instruction = Rc::new(*i); + Box::new(Instruction::Fold(Fold{ iterable, iterator, instruction })) + }, + + "(" "next" ")" => Box::new(Instruction::Next(Next(i))), + "(" "null" ")" => Box::new(Instruction::Null(Null)), + ! => { errors.push(<>); Box::new(Instruction::Error) }, +} + +Args: Vec> = { + "[" )*> "]" => args +} + + +FPart: FunctionPart<'input> = { + => FunctionPart::FuncName(f), + "(" ")" => FunctionPart::ServiceIdWithFuncName(sid, f), +} + + +PeerPart: PeerPart<'input> = { + => PeerPart::PeerPk(pid), + "(" ")" => PeerPart::PeerPkWithServiceId(pid, sid), +} + +// TODO: make output one of _ () "" and absence +Output: CallOutput<'input> = { + => CallOutput::Scalar(o), + => CallOutput::Accumulator(&o[..o.len()-2]), +}; + +Function = Value; +PeerId = Value; +ServiceId = Value; +Arg = Value; + +Value: Value<'input> = { + "\"" "\"" => Value::Literal(""), // TODO: signal absence somehow? + "\"" "\"" => Value::Literal(v), + => Value::Variable(v), + => { + let mut path = v.splitn(2, "."); + let variable = path.next().expect("must contain dot"); + let path = path.next().expect("contain component after dot"); + Value::JsonPath { variable, path } + }, + CURRENT_PEER_ID => Value::CurrentPeerId, +} + + + +Alphanumeric = ALPHANUMERIC; + +match { + r"[\w_-]+" => ALPHANUMERIC, + r"[\w_-]+\[\]" => ACCUMULATOR, + r"[\w_-]+\.\$[^ ]+" => JSON_PATH, + "%current_peer_id%" => CURRENT_PEER_ID, + "seq", + "call", + "null", + "par", + "xor", + "fold", + "next", +} else { + _ +} + diff --git a/crates/air-parser/src/lalrpop/aqua.rs b/crates/air-parser/src/lalrpop/aqua.rs new file mode 100644 index 00000000..0ce9fe0d --- /dev/null +++ b/crates/air-parser/src/lalrpop/aqua.rs @@ -0,0 +1,2132 @@ +// auto-generated: "lalrpop 0.19.1" +// sha256: fa6ea5baecd44655b8abc437c5b5ee123eb73a92a59ff6ad15d7671350686b +use crate::ast::*; +use crate::lalrpop::parser::InstructionError; +use lalrpop_util::ErrorRecovery; +use std::rc::Rc; +#[allow(unused_extern_crates)] +extern crate lalrpop_util as __lalrpop_util; +#[allow(unused_imports)] +use self::__lalrpop_util::state_machine as __state_machine; + +#[cfg_attr(rustfmt, rustfmt_skip)] +mod __parse__Instr { + #![allow(non_snake_case, non_camel_case_types, unused_mut, unused_variables, unused_imports, unused_parens)] + + use crate::ast::*; + use crate::lalrpop::parser::InstructionError; + use lalrpop_util::ErrorRecovery; + use std::rc::Rc; + #[allow(unused_extern_crates)] + extern crate lalrpop_util as __lalrpop_util; + #[allow(unused_imports)] + use self::__lalrpop_util::state_machine as __state_machine; + use self::__lalrpop_util::lexer::Token; + #[allow(dead_code)] + pub enum __Symbol<'input> + { + Variant0(&'input str), + Variant1(__lalrpop_util::ErrorRecovery, InstructionError>), + Variant2(Value<'input>), + Variant3(::std::vec::Vec>), + Variant4(Vec>), + Variant5(FunctionPart<'input>), + Variant6(Box>), + Variant7(CallOutput<'input>), + Variant8(PeerPart<'input>), + } + const __ACTION: &[i8] = &[ + // State 0 + 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + // State 1 + 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, + // State 2 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, + // State 3 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, + // State 4 + 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + // State 5 + 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + // State 6 + 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + // State 7 + 9, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, + // State 8 + 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, + // State 9 + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, + // State 10 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, + // State 11 + 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + // State 12 + 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + // State 13 + 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + // State 14 + 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 15 + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, + // State 16 + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, + // State 17 + 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + // State 18 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 30, 0, 0, 0, + // State 19 + 9, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, + // State 20 + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, + // State 21 + 9, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, + // State 22 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 23 + 0, 0, 0, 0, 0, 2, 3, 4, 26, 5, 6, 7, 0, 0, 0, 0, 0, + // State 24 + 0, -20, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -20, + // State 25 + 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 26 + -29, -29, -29, -29, -29, 0, 0, 0, 0, 0, 0, 0, 0, -29, -29, -29, 0, + // State 27 + -24, -24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -24, -24, -24, 0, + // State 28 + -23, -23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -23, -23, -23, 0, + // State 29 + -6, -6, -6, -6, -6, 0, 0, 0, 0, 0, 0, 0, 0, -6, -6, -6, -6, + // State 30 + -31, -31, -31, -31, -31, 0, 0, 0, 0, 0, 0, 0, 0, -31, -31, -31, 0, + // State 31 + -30, -30, -30, -30, -30, 0, 0, 0, 0, 0, 0, 0, 0, -30, -30, -30, 0, + // State 32 + 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 33 + 0, -19, -19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -19, + // State 34 + 0, 0, 0, -10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 35 + 0, 0, -12, -12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 36 + 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 37 + -27, -27, -27, -27, -27, 0, 0, 0, 0, 0, 0, 0, 0, -27, -27, -27, 0, + // State 38 + 0, -18, -18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -18, + // State 39 + 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 40 + 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 41 + 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 42 + -26, 0, -26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -26, -26, -26, 0, + // State 43 + -28, -28, -28, -28, -28, 0, 0, 0, 0, 0, 0, 0, 0, -28, -28, -28, 0, + // State 44 + 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 45 + 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 46 + 0, -14, -14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -14, + // State 47 + 0, -13, -13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -13, + // State 48 + 0, -15, -15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -15, + // State 49 + 0, 0, -21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 50 + 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 51 + 0, 0, -22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 52 + -4, 0, 0, 0, -4, 0, 0, 0, 0, 0, 0, 0, 0, -4, -4, -4, 0, + // State 53 + -7, 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, 0, 0, -7, -7, -7, 0, + // State 54 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -8, -8, 0, 0, 0, + // State 55 + 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 56 + -25, -25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -25, -25, -25, 0, + // State 57 + 0, -17, -17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -17, + // State 58 + 0, -16, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -16, + // State 59 + -5, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, 0, 0, -5, -5, -5, 0, + // State 60 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9, -9, 0, 0, 0, + // State 61 + 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + fn __action(state: i8, integer: usize) -> i8 { + __ACTION[(state as usize) * 17 + integer] + } + const __EOF_ACTION: &[i8] = &[ + // State 0 + 0, + // State 1 + 0, + // State 2 + 0, + // State 3 + 0, + // State 4 + 0, + // State 5 + 0, + // State 6 + 0, + // State 7 + 0, + // State 8 + 0, + // State 9 + 0, + // State 10 + 0, + // State 11 + 0, + // State 12 + 0, + // State 13 + 0, + // State 14 + 0, + // State 15 + 0, + // State 16 + 0, + // State 17 + 0, + // State 18 + 0, + // State 19 + 0, + // State 20 + 0, + // State 21 + 0, + // State 22 + -32, + // State 23 + 0, + // State 24 + -20, + // State 25 + 0, + // State 26 + 0, + // State 27 + 0, + // State 28 + 0, + // State 29 + 0, + // State 30 + 0, + // State 31 + 0, + // State 32 + 0, + // State 33 + -19, + // State 34 + 0, + // State 35 + 0, + // State 36 + 0, + // State 37 + 0, + // State 38 + -18, + // State 39 + 0, + // State 40 + 0, + // State 41 + 0, + // State 42 + 0, + // State 43 + 0, + // State 44 + 0, + // State 45 + 0, + // State 46 + -14, + // State 47 + -13, + // State 48 + -15, + // State 49 + 0, + // State 50 + 0, + // State 51 + 0, + // State 52 + 0, + // State 53 + 0, + // State 54 + 0, + // State 55 + 0, + // State 56 + 0, + // State 57 + -17, + // State 58 + -16, + // State 59 + 0, + // State 60 + 0, + // State 61 + 0, + ]; + fn __goto(state: i8, nt: usize) -> i8 { + match nt { + 2 => 21, + 3 => match state { + 2 => 10, + 10 => 17, + 3 => 32, + 8 => 36, + 18 => 49, + _ => 26, + }, + 4 => match state { + 21 => 59, + _ => 52, + }, + 5 => 18, + 6 => 14, + 7 => match state { + 20 => 55, + _ => 34, + }, + 8 => match state { + 5 => 12, + 6 => 13, + 0 => 22, + 11 => 39, + 12 => 40, + 13 => 41, + 17 => 45, + _ => 11, + }, + 9 => 50, + 10 => match state { + 1 => 27, + _ => 16, + }, + 11 => 7, + 12 => match state { + 16 => 44, + _ => 20, + }, + 13 => match state { + 7 | 20 => 35, + 15..=16 => 42, + 19 | 21 => 53, + _ => 28, + }, + _ => 0, + } + } + fn __expected_tokens(__state: i8) -> Vec<::std::string::String> { + const __TERMINAL: &[&str] = &[ + r###""\"""###, + r###""(""###, + r###"")""###, + r###""[""###, + r###""]""###, + r###""call""###, + r###""fold""###, + r###""next""###, + r###""null""###, + r###""par""###, + r###""seq""###, + r###""xor""###, + r###"ACCUMULATOR"###, + r###"ALPHANUMERIC"###, + r###"CURRENT_PEER_ID"###, + r###"JSON_PATH"###, + ]; + __TERMINAL.iter().enumerate().filter_map(|(index, terminal)| { + let next_state = __action(__state, index); + if next_state == 0 { + None + } else { + Some(terminal.to_string()) + } + }).collect() + } + pub struct __StateMachine<'input, 'err> + where 'input: 'err + { + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __phantom: ::std::marker::PhantomData<(&'input (), &'err ())>, + } + impl<'input, 'err> __state_machine::ParserDefinition for __StateMachine<'input, 'err> + where 'input: 'err + { + type Location = usize; + type Error = InstructionError; + type Token = Token<'input>; + type TokenIndex = usize; + type Symbol = __Symbol<'input>; + type Success = Box>; + type StateIndex = i8; + type Action = i8; + type ReduceIndex = i8; + type NonterminalIndex = usize; + + #[inline] + fn start_location(&self) -> Self::Location { + Default::default() + } + + #[inline] + fn start_state(&self) -> Self::StateIndex { + 0 + } + + #[inline] + fn token_to_index(&self, token: &Self::Token) -> Option { + __token_to_integer(token, ::std::marker::PhantomData::<(&(), &())>) + } + + #[inline] + fn action(&self, state: i8, integer: usize) -> i8 { + __action(state, integer) + } + + #[inline] + fn error_action(&self, state: i8) -> i8 { + __action(state, 17 - 1) + } + + #[inline] + fn eof_action(&self, state: i8) -> i8 { + __EOF_ACTION[state as usize] + } + + #[inline] + fn goto(&self, state: i8, nt: usize) -> i8 { + __goto(state, nt) + } + + fn token_to_symbol(&self, token_index: usize, token: Self::Token) -> Self::Symbol { + __token_to_symbol(token_index, token, ::std::marker::PhantomData::<(&(), &())>) + } + + fn expected_tokens(&self, state: i8) -> Vec { + __expected_tokens(state) + } + + #[inline] + fn uses_error_recovery(&self) -> bool { + true + } + + #[inline] + fn error_recovery_symbol( + &self, + recovery: __state_machine::ErrorRecovery, + ) -> Self::Symbol { + __Symbol::Variant1(recovery) + } + + fn reduce( + &mut self, + action: i8, + start_location: Option<&Self::Location>, + states: &mut Vec, + symbols: &mut Vec<__state_machine::SymbolTriple>, + ) -> Option<__state_machine::ParseResult> { + __reduce( + self.errors, + self.input, + action, + start_location, + states, + symbols, + ::std::marker::PhantomData::<(&(), &())>, + ) + } + + fn simulate_reduce(&self, action: i8) -> __state_machine::SimulatedReduce { + __simulate_reduce(action, ::std::marker::PhantomData::<(&(), &())>) + } + } + fn __token_to_integer< + 'input, + 'err, + >( + __token: &Token<'input>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> Option + { + match *__token { + Token(0, _) if true => Some(0), + Token(1, _) if true => Some(1), + Token(2, _) if true => Some(2), + Token(3, _) if true => Some(3), + Token(4, _) if true => Some(4), + Token(9, _) if true => Some(5), + Token(10, _) if true => Some(6), + Token(11, _) if true => Some(7), + Token(12, _) if true => Some(8), + Token(13, _) if true => Some(9), + Token(14, _) if true => Some(10), + Token(15, _) if true => Some(11), + Token(7, _) if true => Some(12), + Token(5, _) if true => Some(13), + Token(8, _) if true => Some(14), + Token(6, _) if true => Some(15), + _ => None, + } + } + fn __token_to_symbol< + 'input, + 'err, + >( + __token_index: usize, + __token: Token<'input>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> __Symbol<'input> + { + match __token_index { + 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 => match __token { + Token(0, __tok0) | Token(1, __tok0) | Token(2, __tok0) | Token(3, __tok0) | Token(4, __tok0) | Token(9, __tok0) | Token(10, __tok0) | Token(11, __tok0) | Token(12, __tok0) | Token(13, __tok0) | Token(14, __tok0) | Token(15, __tok0) | Token(7, __tok0) | Token(5, __tok0) | Token(8, __tok0) | Token(6, __tok0) if true => __Symbol::Variant0(__tok0), + _ => unreachable!(), + }, + _ => unreachable!(), + } + } + fn __simulate_reduce< + 'input, + 'err, + >( + __reduce_index: i8, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> __state_machine::SimulatedReduce<__StateMachine<'input, 'err>> + where + 'input: 'err, + { + match __reduce_index { + 0 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 0, + } + } + 1 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 0, + nonterminal_produced: 1, + } + } + 2 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 1, + } + } + 3 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 2, + } + } + 4 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 2, + } + } + 5 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 3, + } + } + 6 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 4, + } + } + 7 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 5, + } + } + 8 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 3, + nonterminal_produced: 5, + } + } + 9 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 6, + } + } + 10 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 4, + nonterminal_produced: 6, + } + } + 11 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 7, + } + } + 12 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 5, + nonterminal_produced: 8, + } + } + 13 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 5, + nonterminal_produced: 8, + } + } + 14 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 5, + nonterminal_produced: 8, + } + } + 15 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 7, + nonterminal_produced: 8, + } + } + 16 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 6, + nonterminal_produced: 8, + } + } + 17 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 4, + nonterminal_produced: 8, + } + } + 18 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 3, + nonterminal_produced: 8, + } + } + 19 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 8, + } + } + 20 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 9, + } + } + 21 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 9, + } + } + 22 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 10, + } + } + 23 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 11, + } + } + 24 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 4, + nonterminal_produced: 11, + } + } + 25 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 12, + } + } + 26 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 13, + } + } + 27 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 3, + nonterminal_produced: 13, + } + } + 28 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 13, + } + } + 29 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 13, + } + } + 30 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 13, + } + } + 31 => __state_machine::SimulatedReduce::Accept, + _ => panic!("invalid reduction index {}", __reduce_index) + } + } + pub struct InstrParser { + builder: __lalrpop_util::lexer::MatcherBuilder, + _priv: (), + } + + impl InstrParser { + pub fn new() -> InstrParser { + let __builder = super::__intern_token::new_builder(); + InstrParser { + builder: __builder, + _priv: (), + } + } + + #[allow(dead_code)] + pub fn parse< + 'input, + 'err, + >( + &self, + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + ) -> Result>, __lalrpop_util::ParseError, InstructionError>> + { + let mut __tokens = self.builder.matcher(input); + __state_machine::Parser::drive( + __StateMachine { + errors, + input, + __phantom: ::std::marker::PhantomData::<(&(), &())>, + }, + __tokens, + ) + } + } + fn __accepts< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __error_state: i8, + __states: & [i8], + __opt_integer: Option, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> bool + { + let mut __states = __states.to_vec(); + __states.push(__error_state); + loop { + let mut __states_len = __states.len(); + let __top = __states[__states_len - 1]; + let __action = match __opt_integer { + None => __EOF_ACTION[__top as usize], + Some(__integer) => __action(__top, __integer), + }; + if __action == 0 { return false; } + if __action > 0 { return true; } + let (__to_pop, __nt) = match __simulate_reduce(-(__action + 1), ::std::marker::PhantomData::<(&(), &())>) { + __state_machine::SimulatedReduce::Reduce { + states_to_pop, nonterminal_produced + } => (states_to_pop, nonterminal_produced), + __state_machine::SimulatedReduce::Accept => return true, + }; + __states_len -= __to_pop; + __states.truncate(__states_len); + let __top = __states[__states_len - 1]; + let __next_state = __goto(__top, __nt); + __states.push(__next_state); + } + } + pub(crate) fn __reduce< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> Option>,__lalrpop_util::ParseError, InstructionError>>> + { + let (__pop_states, __nonterminal) = match __action { + 0 => { + __reduce0(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 1 => { + __reduce1(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 2 => { + __reduce2(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 3 => { + __reduce3(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 4 => { + __reduce4(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 5 => { + __reduce5(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 6 => { + __reduce6(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 7 => { + __reduce7(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 8 => { + __reduce8(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 9 => { + __reduce9(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 10 => { + __reduce10(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 11 => { + __reduce11(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 12 => { + __reduce12(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 13 => { + __reduce13(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 14 => { + __reduce14(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 15 => { + __reduce15(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 16 => { + __reduce16(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 17 => { + __reduce17(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 18 => { + __reduce18(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 19 => { + __reduce19(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 20 => { + __reduce20(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 21 => { + __reduce21(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 22 => { + __reduce22(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 23 => { + __reduce23(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 24 => { + __reduce24(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 25 => { + __reduce25(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 26 => { + __reduce26(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 27 => { + __reduce27(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 28 => { + __reduce28(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 29 => { + __reduce29(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 30 => { + __reduce30(errors, input, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 31 => { + // __Instr = Instr => ActionFn(0); + let __sym0 = __pop_Variant6(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action0::<>(errors, input, __sym0); + return Some(Ok(__nt)); + } + _ => panic!("invalid action code {}", __action) + }; + let __states_len = __states.len(); + __states.truncate(__states_len - __pop_states); + let __state = *__states.last().unwrap(); + let __next_state = __goto(__state, __nonterminal); + __states.push(__next_state); + None + } + #[inline(never)] + fn __symbol_type_mismatch() -> ! { + panic!("symbol type mismatch") + } + fn __pop_Variant6< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, Box>, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant6(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant7< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, CallOutput<'input>, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant7(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant5< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, FunctionPart<'input>, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant5(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant8< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, PeerPart<'input>, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant8(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant2< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, Value<'input>, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant2(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant4< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, Vec>, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant4(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant1< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, __lalrpop_util::ErrorRecovery, InstructionError>, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant1(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant3< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, ::std::vec::Vec>, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant0< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, &'input str, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant0(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + pub(crate) fn __reduce0< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // () = Arg => ActionFn(28); + let __sym0 = __pop_Variant2(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action28::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant2(__nt), __end)); + (1, 0) + } + pub(crate) fn __reduce1< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // ()* = => ActionFn(26); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action26::<>(errors, input, &__start, &__end); + __symbols.push((__start, __Symbol::Variant3(__nt), __end)); + (0, 1) + } + pub(crate) fn __reduce2< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // ()* = ()+ => ActionFn(27); + let __sym0 = __pop_Variant3(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action27::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant3(__nt), __end)); + (1, 1) + } + pub(crate) fn __reduce3< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // ()+ = Arg => ActionFn(31); + let __sym0 = __pop_Variant2(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action31::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant3(__nt), __end)); + (1, 2) + } + pub(crate) fn __reduce4< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // ()+ = ()+, Arg => ActionFn(32); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant2(__symbols); + let __sym0 = __pop_Variant3(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym1.2.clone(); + let __nt = super::__action32::<>(errors, input, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant3(__nt), __end)); + (2, 2) + } + pub(crate) fn __reduce5< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Alphanumeric = ALPHANUMERIC => ActionFn(25); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action25::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant0(__nt), __end)); + (1, 3) + } + pub(crate) fn __reduce6< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Arg = Value => ActionFn(19); + let __sym0 = __pop_Variant2(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action19::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant2(__nt), __end)); + (1, 4) + } + pub(crate) fn __reduce7< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Args = "[", "]" => ActionFn(33); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym1.2.clone(); + let __nt = super::__action33::<>(errors, input, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant4(__nt), __end)); + (2, 5) + } + pub(crate) fn __reduce8< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Args = "[", ()+, "]" => ActionFn(34); + assert!(__symbols.len() >= 3); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant3(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym2.2.clone(); + let __nt = super::__action34::<>(errors, input, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant4(__nt), __end)); + (3, 5) + } + pub(crate) fn __reduce9< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // FPart = Function => ActionFn(10); + let __sym0 = __pop_Variant2(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action10::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant5(__nt), __end)); + (1, 6) + } + pub(crate) fn __reduce10< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // FPart = "(", ServiceId, Function, ")" => ActionFn(11); + assert!(__symbols.len() >= 4); + let __sym3 = __pop_Variant0(__symbols); + let __sym2 = __pop_Variant2(__symbols); + let __sym1 = __pop_Variant2(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym3.2.clone(); + let __nt = super::__action11::<>(errors, input, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant5(__nt), __end)); + (4, 6) + } + pub(crate) fn __reduce11< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Function = Value => ActionFn(16); + let __sym0 = __pop_Variant2(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action16::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant2(__nt), __end)); + (1, 7) + } + pub(crate) fn __reduce12< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Instr = "(", "seq", Instr, Instr, ")" => ActionFn(1); + assert!(__symbols.len() >= 5); + let __sym4 = __pop_Variant0(__symbols); + let __sym3 = __pop_Variant6(__symbols); + let __sym2 = __pop_Variant6(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym4.2.clone(); + let __nt = super::__action1::<>(errors, input, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant6(__nt), __end)); + (5, 8) + } + pub(crate) fn __reduce13< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Instr = "(", "par", Instr, Instr, ")" => ActionFn(2); + assert!(__symbols.len() >= 5); + let __sym4 = __pop_Variant0(__symbols); + let __sym3 = __pop_Variant6(__symbols); + let __sym2 = __pop_Variant6(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym4.2.clone(); + let __nt = super::__action2::<>(errors, input, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant6(__nt), __end)); + (5, 8) + } + pub(crate) fn __reduce14< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Instr = "(", "xor", Instr, Instr, ")" => ActionFn(3); + assert!(__symbols.len() >= 5); + let __sym4 = __pop_Variant0(__symbols); + let __sym3 = __pop_Variant6(__symbols); + let __sym2 = __pop_Variant6(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym4.2.clone(); + let __nt = super::__action3::<>(errors, input, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant6(__nt), __end)); + (5, 8) + } + pub(crate) fn __reduce15< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Instr = "(", "call", PeerPart, FPart, Args, Output, ")" => ActionFn(4); + assert!(__symbols.len() >= 7); + let __sym6 = __pop_Variant0(__symbols); + let __sym5 = __pop_Variant7(__symbols); + let __sym4 = __pop_Variant4(__symbols); + let __sym3 = __pop_Variant5(__symbols); + let __sym2 = __pop_Variant8(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym6.2.clone(); + let __nt = super::__action4::<>(errors, input, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant6(__nt), __end)); + (7, 8) + } + pub(crate) fn __reduce16< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Instr = "(", "fold", Alphanumeric, Alphanumeric, Instr, ")" => ActionFn(5); + assert!(__symbols.len() >= 6); + let __sym5 = __pop_Variant0(__symbols); + let __sym4 = __pop_Variant6(__symbols); + let __sym3 = __pop_Variant0(__symbols); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym5.2.clone(); + let __nt = super::__action5::<>(errors, input, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant6(__nt), __end)); + (6, 8) + } + pub(crate) fn __reduce17< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Instr = "(", "next", Alphanumeric, ")" => ActionFn(6); + assert!(__symbols.len() >= 4); + let __sym3 = __pop_Variant0(__symbols); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym3.2.clone(); + let __nt = super::__action6::<>(errors, input, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant6(__nt), __end)); + (4, 8) + } + pub(crate) fn __reduce18< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Instr = "(", "null", ")" => ActionFn(7); + assert!(__symbols.len() >= 3); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym2.2.clone(); + let __nt = super::__action7::<>(errors, input, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant6(__nt), __end)); + (3, 8) + } + pub(crate) fn __reduce19< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Instr = error => ActionFn(8); + let __sym0 = __pop_Variant1(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action8::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant6(__nt), __end)); + (1, 8) + } + pub(crate) fn __reduce20< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Output = Alphanumeric => ActionFn(14); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action14::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant7(__nt), __end)); + (1, 9) + } + pub(crate) fn __reduce21< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Output = ACCUMULATOR => ActionFn(15); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action15::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant7(__nt), __end)); + (1, 9) + } + pub(crate) fn __reduce22< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // PeerId = Value => ActionFn(17); + let __sym0 = __pop_Variant2(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action17::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant2(__nt), __end)); + (1, 10) + } + pub(crate) fn __reduce23< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // PeerPart = PeerId => ActionFn(12); + let __sym0 = __pop_Variant2(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action12::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant8(__nt), __end)); + (1, 11) + } + pub(crate) fn __reduce24< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // PeerPart = "(", PeerId, ServiceId, ")" => ActionFn(13); + assert!(__symbols.len() >= 4); + let __sym3 = __pop_Variant0(__symbols); + let __sym2 = __pop_Variant2(__symbols); + let __sym1 = __pop_Variant2(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym3.2.clone(); + let __nt = super::__action13::<>(errors, input, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant8(__nt), __end)); + (4, 11) + } + pub(crate) fn __reduce25< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // ServiceId = Value => ActionFn(18); + let __sym0 = __pop_Variant2(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action18::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant2(__nt), __end)); + (1, 12) + } + pub(crate) fn __reduce26< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Value = "\"", "\"" => ActionFn(20); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym1.2.clone(); + let __nt = super::__action20::<>(errors, input, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant2(__nt), __end)); + (2, 13) + } + pub(crate) fn __reduce27< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Value = "\"", Alphanumeric, "\"" => ActionFn(21); + assert!(__symbols.len() >= 3); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym2.2.clone(); + let __nt = super::__action21::<>(errors, input, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant2(__nt), __end)); + (3, 13) + } + pub(crate) fn __reduce28< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Value = Alphanumeric => ActionFn(22); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action22::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant2(__nt), __end)); + (1, 13) + } + pub(crate) fn __reduce29< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Value = JSON_PATH => ActionFn(23); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action23::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant2(__nt), __end)); + (1, 13) + } + pub(crate) fn __reduce30< + 'input, + 'err, + >( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input (), &'err ())>, + ) -> (usize, usize) + { + // Value = CURRENT_PEER_ID => ActionFn(24); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action24::<>(errors, input, __sym0); + __symbols.push((__start, __Symbol::Variant2(__nt), __end)); + (1, 13) + } +} +pub use self::__parse__Instr::InstrParser; +#[cfg_attr(rustfmt, rustfmt_skip)] +mod __intern_token { + #![allow(unused_imports)] + use crate::ast::*; + use crate::lalrpop::parser::InstructionError; + use lalrpop_util::ErrorRecovery; + use std::rc::Rc; + #[allow(unused_extern_crates)] + extern crate lalrpop_util as __lalrpop_util; + #[allow(unused_imports)] + use self::__lalrpop_util::state_machine as __state_machine; + pub fn new_builder() -> __lalrpop_util::lexer::MatcherBuilder { + let __strs: &[(&str, bool)] = &[ + ("^(\")", false), + ("^(\\()", false), + ("^(\\))", false), + ("^(\\[)", false), + ("^(\\])", false), + ("^([\\-0-9A-Z_a-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮ\u{300}-ʹͶ-ͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁ\u{483}-ԯԱ-Ֆՙՠ-ֈ\u{591}-\u{5bd}\u{5bf}\u{5c1}-\u{5c2}\u{5c4}-\u{5c5}\u{5c7}א-תׯ-ײ\u{610}-\u{61a}ؠ-٩ٮ-ۓە-\u{6dc}\u{6df}-\u{6e8}\u{6ea}-ۼۿܐ-\u{74a}ݍ-ޱ߀-ߵߺ\u{7fd}ࠀ-\u{82d}ࡀ-\u{85b}ࡠ-ࡪࢠ-ࢴࢶ-ࣇ\u{8d3}-\u{8e1}\u{8e3}-\u{963}०-९ॱ-ঃঅ-ঌএ-ঐও-নপ-রলশ-হ\u{9bc}-\u{9c4}ে-ৈো-ৎ\u{9d7}ড়-ঢ়য়-\u{9e3}০-ৱৼ\u{9fe}\u{a01}-ਃਅ-ਊਏ-ਐਓ-ਨਪ-ਰਲ-ਲ਼ਵ-ਸ਼ਸ-ਹ\u{a3c}ਾ-\u{a42}\u{a47}-\u{a48}\u{a4b}-\u{a4d}\u{a51}ਖ਼-ੜਫ਼੦-\u{a75}\u{a81}-ઃઅ-ઍએ-ઑઓ-નપ-રલ-ળવ-હ\u{abc}-\u{ac5}\u{ac7}-ૉો-\u{acd}ૐૠ-\u{ae3}૦-૯ૹ-\u{aff}\u{b01}-ଃଅ-ଌଏ-ଐଓ-ନପ-ରଲ-ଳଵ-ହ\u{b3c}-\u{b44}େ-ୈୋ-\u{b4d}\u{b55}-\u{b57}ଡ଼-ଢ଼ୟ-\u{b63}୦-୯ୱ\u{b82}-ஃஅ-ஊஎ-ஐஒ-கங-சஜஞ-டண-தந-பம-ஹ\u{bbe}-ூெ-ைொ-\u{bcd}ௐ\u{bd7}௦-௯\u{c00}-ఌఎ-ఐఒ-నప-హఽ-ౄ\u{c46}-\u{c48}\u{c4a}-\u{c4d}\u{c55}-\u{c56}ౘ-ౚౠ-\u{c63}౦-౯ಀ-ಃಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹ\u{cbc}-ೄ\u{cc6}-ೈೊ-\u{ccd}\u{cd5}-\u{cd6}ೞೠ-\u{ce3}೦-೯ೱ-ೲ\u{d00}-ഌഎ-ഐഒ-\u{d44}െ-ൈൊ-ൎൔ-\u{d57}ൟ-\u{d63}൦-൯ൺ-ൿ\u{d81}-ඃඅ-ඖක-නඳ-රලව-ෆ\u{dca}\u{dcf}-\u{dd4}\u{dd6}ෘ-\u{ddf}෦-෯ෲ-ෳก-\u{e3a}เ-\u{e4e}๐-๙ກ-ຂຄຆ-ຊຌ-ຣລວ-ຽເ-ໄໆ\u{ec8}-\u{ecd}໐-໙ໜ-ໟༀ\u{f18}-\u{f19}༠-༩\u{f35}\u{f37}\u{f39}༾-ཇཉ-ཬ\u{f71}-\u{f84}\u{f86}-\u{f97}\u{f99}-\u{fbc}\u{fc6}က-၉ၐ-\u{109d}Ⴀ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚ\u{135d}-\u{135f}ᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-\u{1714}ᜠ-\u{1734}ᝀ-\u{1753}ᝠ-ᝬᝮ-ᝰ\u{1772}-\u{1773}ក-\u{17d3}ៗៜ-\u{17dd}០-៩\u{180b}-\u{180d}᠐-᠙ᠠ-ᡸᢀ-ᢪᢰ-ᣵᤀ-ᤞ\u{1920}-ᤫᤰ-\u{193b}᥆-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉ᧐-᧙ᨀ-\u{1a1b}ᨠ-\u{1a5e}\u{1a60}-\u{1a7c}\u{1a7f}-᪉᪐-᪙ᪧ\u{1ab0}-\u{1ac0}\u{1b00}-ᭋ᭐-᭙\u{1b6b}-\u{1b73}\u{1b80}-᯳ᰀ-\u{1c37}᱀-᱉ᱍ-ᱽᲀ-ᲈᲐ-ᲺᲽ-Ჿ\u{1cd0}-\u{1cd2}\u{1cd4}-ᳺᴀ-\u{1df9}\u{1dfb}-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼ\u{200c}-\u{200d}‿-⁀⁔ⁱⁿₐ-ₜ\u{20d0}-\u{20f0}ℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⒶ-ⓩⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯ\u{2d7f}-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ\u{2de0}-\u{2dff}ⸯ々-〇〡-\u{302f}〱-〵〸-〼ぁ-ゖ\u{3099}-\u{309a}ゝ-ゟァ-ヺー-ヿㄅ-ㄯㄱ-ㆎㆠ-ㆿㇰ-ㇿ㐀-䶿一-鿼ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘫꙀ-\u{a672}\u{a674}-\u{a67d}ꙿ-\u{a6f1}ꜗ-ꜟꜢ-ꞈꞋ-ꞿꟂ-ꟊꟵ-ꠧ\u{a82c}ꡀ-ꡳꢀ-\u{a8c5}꣐-꣙\u{a8e0}-ꣷꣻꣽ-\u{a92d}ꤰ-꥓ꥠ-ꥼ\u{a980}-꧀ꧏ-꧙ꧠ-ꧾꨀ-\u{aa36}ꩀ-ꩍ꩐-꩙ꩠ-ꩶꩺ-ꫂꫛ-ꫝꫠ-ꫯꫲ-\u{aaf6}ꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭩꭰ-ꯪ꯬-\u{abed}꯰-꯹가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִ-ﬨשׁ-זּטּ-לּמּנּ-סּףּ-פּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻ\u{fe00}-\u{fe0f}\u{fe20}-\u{fe2f}︳-︴﹍-﹏ﹰ-ﹴﹶ-ﻼ0-9A-Z_a-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ𐀀-𐀋𐀍-𐀦𐀨-𐀺𐀼-𐀽𐀿-𐁍𐁐-𐁝𐂀-𐃺𐅀-𐅴\u{101fd}𐊀-𐊜𐊠-𐋐\u{102e0}𐌀-𐌟𐌭-𐍊𐍐-\u{1037a}𐎀-𐎝𐎠-𐏃𐏈-𐏏𐏑-𐏕𐐀-𐒝𐒠-𐒩𐒰-𐓓𐓘-𐓻𐔀-𐔧𐔰-𐕣𐘀-𐜶𐝀-𐝕𐝠-𐝧𐠀-𐠅𐠈𐠊-𐠵𐠷-𐠸𐠼𐠿-𐡕𐡠-𐡶𐢀-𐢞𐣠-𐣲𐣴-𐣵𐤀-𐤕𐤠-𐤹𐦀-𐦷𐦾-𐦿𐨀-\u{10a03}\u{10a05}-\u{10a06}\u{10a0c}-𐨓𐨕-𐨗𐨙-𐨵\u{10a38}-\u{10a3a}\u{10a3f}𐩠-𐩼𐪀-𐪜𐫀-𐫇𐫉-\u{10ae6}𐬀-𐬵𐭀-𐭕𐭠-𐭲𐮀-𐮑𐰀-𐱈𐲀-𐲲𐳀-𐳲𐴀-\u{10d27}𐴰-𐴹𐺀-𐺩\u{10eab}-\u{10eac}𐺰-𐺱𐼀-𐼜𐼧𐼰-\u{10f50}𐾰-𐿄𐿠-𐿶𑀀-\u{11046}𑁦-𑁯\u{1107f}-\u{110ba}𑃐-𑃨𑃰-𑃹\u{11100}-\u{11134}𑄶-𑄿𑅄-𑅇𑅐-\u{11173}𑅶\u{11180}-𑇄\u{111c9}-\u{111cc}𑇎-𑇚𑇜𑈀-𑈑𑈓-\u{11237}\u{1123e}𑊀-𑊆𑊈𑊊-𑊍𑊏-𑊝𑊟-𑊨𑊰-\u{112ea}𑋰-𑋹\u{11300}-𑌃𑌅-𑌌𑌏-𑌐𑌓-𑌨𑌪-𑌰𑌲-𑌳𑌵-𑌹\u{1133b}-𑍄𑍇-𑍈𑍋-𑍍𑍐\u{11357}𑍝-𑍣\u{11366}-\u{1136c}\u{11370}-\u{11374}𑐀-𑑊𑑐-𑑙\u{1145e}-𑑡𑒀-𑓅𑓇𑓐-𑓙𑖀-\u{115b5}𑖸-\u{115c0}𑗘-\u{115dd}𑘀-\u{11640}𑙄𑙐-𑙙𑚀-𑚸𑛀-𑛉𑜀-𑜚\u{1171d}-\u{1172b}𑜰-𑜹𑠀-\u{1183a}𑢠-𑣩𑣿-𑤆𑤉𑤌-𑤓𑤕-𑤖𑤘-𑤵𑤷-𑤸\u{1193b}-\u{11943}𑥐-𑥙𑦠-𑦧𑦪-\u{119d7}\u{119da}-𑧡𑧣-𑧤𑨀-\u{11a3e}\u{11a47}𑩐-\u{11a99}𑪝𑫀-𑫸𑰀-𑰈𑰊-\u{11c36}\u{11c38}-𑱀𑱐-𑱙𑱲-𑲏\u{11c92}-\u{11ca7}𑲩-\u{11cb6}𑴀-𑴆𑴈-𑴉𑴋-\u{11d36}\u{11d3a}\u{11d3c}-\u{11d3d}\u{11d3f}-\u{11d47}𑵐-𑵙𑵠-𑵥𑵧-𑵨𑵪-𑶎\u{11d90}-\u{11d91}𑶓-𑶘𑶠-𑶩𑻠-𑻶𑾰𒀀-𒎙𒐀-𒑮𒒀-𒕃𓀀-𓐮𔐀-𔙆𖠀-𖨸𖩀-𖩞𖩠-𖩩𖫐-𖫭\u{16af0}-\u{16af4}𖬀-\u{16b36}𖭀-𖭃𖭐-𖭙𖭣-𖭷𖭽-𖮏𖹀-𖹿𖼀-𖽊\u{16f4f}-𖾇\u{16f8f}-𖾟𖿠-𖿡𖿣-\u{16fe4}𖿰-𖿱𗀀-𘟷𘠀-𘳕𘴀-𘴈𛀀-𛄞𛅐-𛅒𛅤-𛅧𛅰-𛋻𛰀-𛱪𛱰-𛱼𛲀-𛲈𛲐-𛲙\u{1bc9d}-\u{1bc9e}\u{1d165}-\u{1d169}𝅭-\u{1d172}\u{1d17b}-\u{1d182}\u{1d185}-\u{1d18b}\u{1d1aa}-\u{1d1ad}\u{1d242}-\u{1d244}𝐀-𝑔𝑖-𝒜𝒞-𝒟𝒢𝒥-𝒦𝒩-𝒬𝒮-𝒹𝒻𝒽-𝓃𝓅-𝔅𝔇-𝔊𝔍-𝔔𝔖-𝔜𝔞-𝔹𝔻-𝔾𝕀-𝕄𝕆𝕊-𝕐𝕒-𝚥𝚨-𝛀𝛂-𝛚𝛜-𝛺𝛼-𝜔𝜖-𝜴𝜶-𝝎𝝐-𝝮𝝰-𝞈𝞊-𝞨𝞪-𝟂𝟄-𝟋𝟎-𝟿\u{1da00}-\u{1da36}\u{1da3b}-\u{1da6c}\u{1da75}\u{1da84}\u{1da9b}-\u{1da9f}\u{1daa1}-\u{1daaf}\u{1e000}-\u{1e006}\u{1e008}-\u{1e018}\u{1e01b}-\u{1e021}\u{1e023}-\u{1e024}\u{1e026}-\u{1e02a}𞄀-𞄬\u{1e130}-𞄽𞅀-𞅉𞅎𞋀-𞋹𞠀-𞣄\u{1e8d0}-\u{1e8d6}𞤀-𞥋𞥐-𞥙𞸀-𞸃𞸅-𞸟𞸡-𞸢𞸤𞸧𞸩-𞸲𞸴-𞸷𞸹𞸻𞹂𞹇𞹉𞹋𞹍-𞹏𞹑-𞹒𞹔𞹗𞹙𞹛𞹝𞹟𞹡-𞹢𞹤𞹧-𞹪𞹬-𞹲𞹴-𞹷𞹹-𞹼𞹾𞺀-𞺉𞺋-𞺛𞺡-𞺣𞺥-𞺩𞺫-𞺻🄰-🅉🅐-🅩🅰-🆉🯰-🯹𠀀-𪛝𪜀-𫜴𫝀-𫠝𫠠-𬺡𬺰-𮯠丽-𪘀𰀀-𱍊\u{e0100}-\u{e01ef}]+)", false), + ("^([\\-0-9A-Z_a-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮ\u{300}-ʹͶ-ͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁ\u{483}-ԯԱ-Ֆՙՠ-ֈ\u{591}-\u{5bd}\u{5bf}\u{5c1}-\u{5c2}\u{5c4}-\u{5c5}\u{5c7}א-תׯ-ײ\u{610}-\u{61a}ؠ-٩ٮ-ۓە-\u{6dc}\u{6df}-\u{6e8}\u{6ea}-ۼۿܐ-\u{74a}ݍ-ޱ߀-ߵߺ\u{7fd}ࠀ-\u{82d}ࡀ-\u{85b}ࡠ-ࡪࢠ-ࢴࢶ-ࣇ\u{8d3}-\u{8e1}\u{8e3}-\u{963}०-९ॱ-ঃঅ-ঌএ-ঐও-নপ-রলশ-হ\u{9bc}-\u{9c4}ে-ৈো-ৎ\u{9d7}ড়-ঢ়য়-\u{9e3}০-ৱৼ\u{9fe}\u{a01}-ਃਅ-ਊਏ-ਐਓ-ਨਪ-ਰਲ-ਲ਼ਵ-ਸ਼ਸ-ਹ\u{a3c}ਾ-\u{a42}\u{a47}-\u{a48}\u{a4b}-\u{a4d}\u{a51}ਖ਼-ੜਫ਼੦-\u{a75}\u{a81}-ઃઅ-ઍએ-ઑઓ-નપ-રલ-ળવ-હ\u{abc}-\u{ac5}\u{ac7}-ૉો-\u{acd}ૐૠ-\u{ae3}૦-૯ૹ-\u{aff}\u{b01}-ଃଅ-ଌଏ-ଐଓ-ନପ-ରଲ-ଳଵ-ହ\u{b3c}-\u{b44}େ-ୈୋ-\u{b4d}\u{b55}-\u{b57}ଡ଼-ଢ଼ୟ-\u{b63}୦-୯ୱ\u{b82}-ஃஅ-ஊஎ-ஐஒ-கங-சஜஞ-டண-தந-பம-ஹ\u{bbe}-ூெ-ைொ-\u{bcd}ௐ\u{bd7}௦-௯\u{c00}-ఌఎ-ఐఒ-నప-హఽ-ౄ\u{c46}-\u{c48}\u{c4a}-\u{c4d}\u{c55}-\u{c56}ౘ-ౚౠ-\u{c63}౦-౯ಀ-ಃಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹ\u{cbc}-ೄ\u{cc6}-ೈೊ-\u{ccd}\u{cd5}-\u{cd6}ೞೠ-\u{ce3}೦-೯ೱ-ೲ\u{d00}-ഌഎ-ഐഒ-\u{d44}െ-ൈൊ-ൎൔ-\u{d57}ൟ-\u{d63}൦-൯ൺ-ൿ\u{d81}-ඃඅ-ඖක-නඳ-රලව-ෆ\u{dca}\u{dcf}-\u{dd4}\u{dd6}ෘ-\u{ddf}෦-෯ෲ-ෳก-\u{e3a}เ-\u{e4e}๐-๙ກ-ຂຄຆ-ຊຌ-ຣລວ-ຽເ-ໄໆ\u{ec8}-\u{ecd}໐-໙ໜ-ໟༀ\u{f18}-\u{f19}༠-༩\u{f35}\u{f37}\u{f39}༾-ཇཉ-ཬ\u{f71}-\u{f84}\u{f86}-\u{f97}\u{f99}-\u{fbc}\u{fc6}က-၉ၐ-\u{109d}Ⴀ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚ\u{135d}-\u{135f}ᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-\u{1714}ᜠ-\u{1734}ᝀ-\u{1753}ᝠ-ᝬᝮ-ᝰ\u{1772}-\u{1773}ក-\u{17d3}ៗៜ-\u{17dd}០-៩\u{180b}-\u{180d}᠐-᠙ᠠ-ᡸᢀ-ᢪᢰ-ᣵᤀ-ᤞ\u{1920}-ᤫᤰ-\u{193b}᥆-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉ᧐-᧙ᨀ-\u{1a1b}ᨠ-\u{1a5e}\u{1a60}-\u{1a7c}\u{1a7f}-᪉᪐-᪙ᪧ\u{1ab0}-\u{1ac0}\u{1b00}-ᭋ᭐-᭙\u{1b6b}-\u{1b73}\u{1b80}-᯳ᰀ-\u{1c37}᱀-᱉ᱍ-ᱽᲀ-ᲈᲐ-ᲺᲽ-Ჿ\u{1cd0}-\u{1cd2}\u{1cd4}-ᳺᴀ-\u{1df9}\u{1dfb}-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼ\u{200c}-\u{200d}‿-⁀⁔ⁱⁿₐ-ₜ\u{20d0}-\u{20f0}ℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⒶ-ⓩⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯ\u{2d7f}-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ\u{2de0}-\u{2dff}ⸯ々-〇〡-\u{302f}〱-〵〸-〼ぁ-ゖ\u{3099}-\u{309a}ゝ-ゟァ-ヺー-ヿㄅ-ㄯㄱ-ㆎㆠ-ㆿㇰ-ㇿ㐀-䶿一-鿼ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘫꙀ-\u{a672}\u{a674}-\u{a67d}ꙿ-\u{a6f1}ꜗ-ꜟꜢ-ꞈꞋ-ꞿꟂ-ꟊꟵ-ꠧ\u{a82c}ꡀ-ꡳꢀ-\u{a8c5}꣐-꣙\u{a8e0}-ꣷꣻꣽ-\u{a92d}ꤰ-꥓ꥠ-ꥼ\u{a980}-꧀ꧏ-꧙ꧠ-ꧾꨀ-\u{aa36}ꩀ-ꩍ꩐-꩙ꩠ-ꩶꩺ-ꫂꫛ-ꫝꫠ-ꫯꫲ-\u{aaf6}ꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭩꭰ-ꯪ꯬-\u{abed}꯰-꯹가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִ-ﬨשׁ-זּטּ-לּמּנּ-סּףּ-פּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻ\u{fe00}-\u{fe0f}\u{fe20}-\u{fe2f}︳-︴﹍-﹏ﹰ-ﹴﹶ-ﻼ0-9A-Z_a-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ𐀀-𐀋𐀍-𐀦𐀨-𐀺𐀼-𐀽𐀿-𐁍𐁐-𐁝𐂀-𐃺𐅀-𐅴\u{101fd}𐊀-𐊜𐊠-𐋐\u{102e0}𐌀-𐌟𐌭-𐍊𐍐-\u{1037a}𐎀-𐎝𐎠-𐏃𐏈-𐏏𐏑-𐏕𐐀-𐒝𐒠-𐒩𐒰-𐓓𐓘-𐓻𐔀-𐔧𐔰-𐕣𐘀-𐜶𐝀-𐝕𐝠-𐝧𐠀-𐠅𐠈𐠊-𐠵𐠷-𐠸𐠼𐠿-𐡕𐡠-𐡶𐢀-𐢞𐣠-𐣲𐣴-𐣵𐤀-𐤕𐤠-𐤹𐦀-𐦷𐦾-𐦿𐨀-\u{10a03}\u{10a05}-\u{10a06}\u{10a0c}-𐨓𐨕-𐨗𐨙-𐨵\u{10a38}-\u{10a3a}\u{10a3f}𐩠-𐩼𐪀-𐪜𐫀-𐫇𐫉-\u{10ae6}𐬀-𐬵𐭀-𐭕𐭠-𐭲𐮀-𐮑𐰀-𐱈𐲀-𐲲𐳀-𐳲𐴀-\u{10d27}𐴰-𐴹𐺀-𐺩\u{10eab}-\u{10eac}𐺰-𐺱𐼀-𐼜𐼧𐼰-\u{10f50}𐾰-𐿄𐿠-𐿶𑀀-\u{11046}𑁦-𑁯\u{1107f}-\u{110ba}𑃐-𑃨𑃰-𑃹\u{11100}-\u{11134}𑄶-𑄿𑅄-𑅇𑅐-\u{11173}𑅶\u{11180}-𑇄\u{111c9}-\u{111cc}𑇎-𑇚𑇜𑈀-𑈑𑈓-\u{11237}\u{1123e}𑊀-𑊆𑊈𑊊-𑊍𑊏-𑊝𑊟-𑊨𑊰-\u{112ea}𑋰-𑋹\u{11300}-𑌃𑌅-𑌌𑌏-𑌐𑌓-𑌨𑌪-𑌰𑌲-𑌳𑌵-𑌹\u{1133b}-𑍄𑍇-𑍈𑍋-𑍍𑍐\u{11357}𑍝-𑍣\u{11366}-\u{1136c}\u{11370}-\u{11374}𑐀-𑑊𑑐-𑑙\u{1145e}-𑑡𑒀-𑓅𑓇𑓐-𑓙𑖀-\u{115b5}𑖸-\u{115c0}𑗘-\u{115dd}𑘀-\u{11640}𑙄𑙐-𑙙𑚀-𑚸𑛀-𑛉𑜀-𑜚\u{1171d}-\u{1172b}𑜰-𑜹𑠀-\u{1183a}𑢠-𑣩𑣿-𑤆𑤉𑤌-𑤓𑤕-𑤖𑤘-𑤵𑤷-𑤸\u{1193b}-\u{11943}𑥐-𑥙𑦠-𑦧𑦪-\u{119d7}\u{119da}-𑧡𑧣-𑧤𑨀-\u{11a3e}\u{11a47}𑩐-\u{11a99}𑪝𑫀-𑫸𑰀-𑰈𑰊-\u{11c36}\u{11c38}-𑱀𑱐-𑱙𑱲-𑲏\u{11c92}-\u{11ca7}𑲩-\u{11cb6}𑴀-𑴆𑴈-𑴉𑴋-\u{11d36}\u{11d3a}\u{11d3c}-\u{11d3d}\u{11d3f}-\u{11d47}𑵐-𑵙𑵠-𑵥𑵧-𑵨𑵪-𑶎\u{11d90}-\u{11d91}𑶓-𑶘𑶠-𑶩𑻠-𑻶𑾰𒀀-𒎙𒐀-𒑮𒒀-𒕃𓀀-𓐮𔐀-𔙆𖠀-𖨸𖩀-𖩞𖩠-𖩩𖫐-𖫭\u{16af0}-\u{16af4}𖬀-\u{16b36}𖭀-𖭃𖭐-𖭙𖭣-𖭷𖭽-𖮏𖹀-𖹿𖼀-𖽊\u{16f4f}-𖾇\u{16f8f}-𖾟𖿠-𖿡𖿣-\u{16fe4}𖿰-𖿱𗀀-𘟷𘠀-𘳕𘴀-𘴈𛀀-𛄞𛅐-𛅒𛅤-𛅧𛅰-𛋻𛰀-𛱪𛱰-𛱼𛲀-𛲈𛲐-𛲙\u{1bc9d}-\u{1bc9e}\u{1d165}-\u{1d169}𝅭-\u{1d172}\u{1d17b}-\u{1d182}\u{1d185}-\u{1d18b}\u{1d1aa}-\u{1d1ad}\u{1d242}-\u{1d244}𝐀-𝑔𝑖-𝒜𝒞-𝒟𝒢𝒥-𝒦𝒩-𝒬𝒮-𝒹𝒻𝒽-𝓃𝓅-𝔅𝔇-𝔊𝔍-𝔔𝔖-𝔜𝔞-𝔹𝔻-𝔾𝕀-𝕄𝕆𝕊-𝕐𝕒-𝚥𝚨-𝛀𝛂-𝛚𝛜-𝛺𝛼-𝜔𝜖-𝜴𝜶-𝝎𝝐-𝝮𝝰-𝞈𝞊-𝞨𝞪-𝟂𝟄-𝟋𝟎-𝟿\u{1da00}-\u{1da36}\u{1da3b}-\u{1da6c}\u{1da75}\u{1da84}\u{1da9b}-\u{1da9f}\u{1daa1}-\u{1daaf}\u{1e000}-\u{1e006}\u{1e008}-\u{1e018}\u{1e01b}-\u{1e021}\u{1e023}-\u{1e024}\u{1e026}-\u{1e02a}𞄀-𞄬\u{1e130}-𞄽𞅀-𞅉𞅎𞋀-𞋹𞠀-𞣄\u{1e8d0}-\u{1e8d6}𞤀-𞥋𞥐-𞥙𞸀-𞸃𞸅-𞸟𞸡-𞸢𞸤𞸧𞸩-𞸲𞸴-𞸷𞸹𞸻𞹂𞹇𞹉𞹋𞹍-𞹏𞹑-𞹒𞹔𞹗𞹙𞹛𞹝𞹟𞹡-𞹢𞹤𞹧-𞹪𞹬-𞹲𞹴-𞹷𞹹-𞹼𞹾𞺀-𞺉𞺋-𞺛𞺡-𞺣𞺥-𞺩𞺫-𞺻🄰-🅉🅐-🅩🅰-🆉🯰-🯹𠀀-𪛝𪜀-𫜴𫝀-𫠝𫠠-𬺡𬺰-𮯠丽-𪘀𰀀-𱍊\u{e0100}-\u{e01ef}]+\\.\\$[\u{0}-\u{1f}!-\u{10ffff}]+)", false), + ("^([\\-0-9A-Z_a-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮ\u{300}-ʹͶ-ͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁ\u{483}-ԯԱ-Ֆՙՠ-ֈ\u{591}-\u{5bd}\u{5bf}\u{5c1}-\u{5c2}\u{5c4}-\u{5c5}\u{5c7}א-תׯ-ײ\u{610}-\u{61a}ؠ-٩ٮ-ۓە-\u{6dc}\u{6df}-\u{6e8}\u{6ea}-ۼۿܐ-\u{74a}ݍ-ޱ߀-ߵߺ\u{7fd}ࠀ-\u{82d}ࡀ-\u{85b}ࡠ-ࡪࢠ-ࢴࢶ-ࣇ\u{8d3}-\u{8e1}\u{8e3}-\u{963}०-९ॱ-ঃঅ-ঌএ-ঐও-নপ-রলশ-হ\u{9bc}-\u{9c4}ে-ৈো-ৎ\u{9d7}ড়-ঢ়য়-\u{9e3}০-ৱৼ\u{9fe}\u{a01}-ਃਅ-ਊਏ-ਐਓ-ਨਪ-ਰਲ-ਲ਼ਵ-ਸ਼ਸ-ਹ\u{a3c}ਾ-\u{a42}\u{a47}-\u{a48}\u{a4b}-\u{a4d}\u{a51}ਖ਼-ੜਫ਼੦-\u{a75}\u{a81}-ઃઅ-ઍએ-ઑઓ-નપ-રલ-ળવ-હ\u{abc}-\u{ac5}\u{ac7}-ૉો-\u{acd}ૐૠ-\u{ae3}૦-૯ૹ-\u{aff}\u{b01}-ଃଅ-ଌଏ-ଐଓ-ନପ-ରଲ-ଳଵ-ହ\u{b3c}-\u{b44}େ-ୈୋ-\u{b4d}\u{b55}-\u{b57}ଡ଼-ଢ଼ୟ-\u{b63}୦-୯ୱ\u{b82}-ஃஅ-ஊஎ-ஐஒ-கங-சஜஞ-டண-தந-பம-ஹ\u{bbe}-ூெ-ைொ-\u{bcd}ௐ\u{bd7}௦-௯\u{c00}-ఌఎ-ఐఒ-నప-హఽ-ౄ\u{c46}-\u{c48}\u{c4a}-\u{c4d}\u{c55}-\u{c56}ౘ-ౚౠ-\u{c63}౦-౯ಀ-ಃಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹ\u{cbc}-ೄ\u{cc6}-ೈೊ-\u{ccd}\u{cd5}-\u{cd6}ೞೠ-\u{ce3}೦-೯ೱ-ೲ\u{d00}-ഌഎ-ഐഒ-\u{d44}െ-ൈൊ-ൎൔ-\u{d57}ൟ-\u{d63}൦-൯ൺ-ൿ\u{d81}-ඃඅ-ඖක-නඳ-රලව-ෆ\u{dca}\u{dcf}-\u{dd4}\u{dd6}ෘ-\u{ddf}෦-෯ෲ-ෳก-\u{e3a}เ-\u{e4e}๐-๙ກ-ຂຄຆ-ຊຌ-ຣລວ-ຽເ-ໄໆ\u{ec8}-\u{ecd}໐-໙ໜ-ໟༀ\u{f18}-\u{f19}༠-༩\u{f35}\u{f37}\u{f39}༾-ཇཉ-ཬ\u{f71}-\u{f84}\u{f86}-\u{f97}\u{f99}-\u{fbc}\u{fc6}က-၉ၐ-\u{109d}Ⴀ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚ\u{135d}-\u{135f}ᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-\u{1714}ᜠ-\u{1734}ᝀ-\u{1753}ᝠ-ᝬᝮ-ᝰ\u{1772}-\u{1773}ក-\u{17d3}ៗៜ-\u{17dd}០-៩\u{180b}-\u{180d}᠐-᠙ᠠ-ᡸᢀ-ᢪᢰ-ᣵᤀ-ᤞ\u{1920}-ᤫᤰ-\u{193b}᥆-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉ᧐-᧙ᨀ-\u{1a1b}ᨠ-\u{1a5e}\u{1a60}-\u{1a7c}\u{1a7f}-᪉᪐-᪙ᪧ\u{1ab0}-\u{1ac0}\u{1b00}-ᭋ᭐-᭙\u{1b6b}-\u{1b73}\u{1b80}-᯳ᰀ-\u{1c37}᱀-᱉ᱍ-ᱽᲀ-ᲈᲐ-ᲺᲽ-Ჿ\u{1cd0}-\u{1cd2}\u{1cd4}-ᳺᴀ-\u{1df9}\u{1dfb}-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼ\u{200c}-\u{200d}‿-⁀⁔ⁱⁿₐ-ₜ\u{20d0}-\u{20f0}ℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⒶ-ⓩⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯ\u{2d7f}-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ\u{2de0}-\u{2dff}ⸯ々-〇〡-\u{302f}〱-〵〸-〼ぁ-ゖ\u{3099}-\u{309a}ゝ-ゟァ-ヺー-ヿㄅ-ㄯㄱ-ㆎㆠ-ㆿㇰ-ㇿ㐀-䶿一-鿼ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘫꙀ-\u{a672}\u{a674}-\u{a67d}ꙿ-\u{a6f1}ꜗ-ꜟꜢ-ꞈꞋ-ꞿꟂ-ꟊꟵ-ꠧ\u{a82c}ꡀ-ꡳꢀ-\u{a8c5}꣐-꣙\u{a8e0}-ꣷꣻꣽ-\u{a92d}ꤰ-꥓ꥠ-ꥼ\u{a980}-꧀ꧏ-꧙ꧠ-ꧾꨀ-\u{aa36}ꩀ-ꩍ꩐-꩙ꩠ-ꩶꩺ-ꫂꫛ-ꫝꫠ-ꫯꫲ-\u{aaf6}ꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭩꭰ-ꯪ꯬-\u{abed}꯰-꯹가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִ-ﬨשׁ-זּטּ-לּמּנּ-סּףּ-פּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻ\u{fe00}-\u{fe0f}\u{fe20}-\u{fe2f}︳-︴﹍-﹏ﹰ-ﹴﹶ-ﻼ0-9A-Z_a-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ𐀀-𐀋𐀍-𐀦𐀨-𐀺𐀼-𐀽𐀿-𐁍𐁐-𐁝𐂀-𐃺𐅀-𐅴\u{101fd}𐊀-𐊜𐊠-𐋐\u{102e0}𐌀-𐌟𐌭-𐍊𐍐-\u{1037a}𐎀-𐎝𐎠-𐏃𐏈-𐏏𐏑-𐏕𐐀-𐒝𐒠-𐒩𐒰-𐓓𐓘-𐓻𐔀-𐔧𐔰-𐕣𐘀-𐜶𐝀-𐝕𐝠-𐝧𐠀-𐠅𐠈𐠊-𐠵𐠷-𐠸𐠼𐠿-𐡕𐡠-𐡶𐢀-𐢞𐣠-𐣲𐣴-𐣵𐤀-𐤕𐤠-𐤹𐦀-𐦷𐦾-𐦿𐨀-\u{10a03}\u{10a05}-\u{10a06}\u{10a0c}-𐨓𐨕-𐨗𐨙-𐨵\u{10a38}-\u{10a3a}\u{10a3f}𐩠-𐩼𐪀-𐪜𐫀-𐫇𐫉-\u{10ae6}𐬀-𐬵𐭀-𐭕𐭠-𐭲𐮀-𐮑𐰀-𐱈𐲀-𐲲𐳀-𐳲𐴀-\u{10d27}𐴰-𐴹𐺀-𐺩\u{10eab}-\u{10eac}𐺰-𐺱𐼀-𐼜𐼧𐼰-\u{10f50}𐾰-𐿄𐿠-𐿶𑀀-\u{11046}𑁦-𑁯\u{1107f}-\u{110ba}𑃐-𑃨𑃰-𑃹\u{11100}-\u{11134}𑄶-𑄿𑅄-𑅇𑅐-\u{11173}𑅶\u{11180}-𑇄\u{111c9}-\u{111cc}𑇎-𑇚𑇜𑈀-𑈑𑈓-\u{11237}\u{1123e}𑊀-𑊆𑊈𑊊-𑊍𑊏-𑊝𑊟-𑊨𑊰-\u{112ea}𑋰-𑋹\u{11300}-𑌃𑌅-𑌌𑌏-𑌐𑌓-𑌨𑌪-𑌰𑌲-𑌳𑌵-𑌹\u{1133b}-𑍄𑍇-𑍈𑍋-𑍍𑍐\u{11357}𑍝-𑍣\u{11366}-\u{1136c}\u{11370}-\u{11374}𑐀-𑑊𑑐-𑑙\u{1145e}-𑑡𑒀-𑓅𑓇𑓐-𑓙𑖀-\u{115b5}𑖸-\u{115c0}𑗘-\u{115dd}𑘀-\u{11640}𑙄𑙐-𑙙𑚀-𑚸𑛀-𑛉𑜀-𑜚\u{1171d}-\u{1172b}𑜰-𑜹𑠀-\u{1183a}𑢠-𑣩𑣿-𑤆𑤉𑤌-𑤓𑤕-𑤖𑤘-𑤵𑤷-𑤸\u{1193b}-\u{11943}𑥐-𑥙𑦠-𑦧𑦪-\u{119d7}\u{119da}-𑧡𑧣-𑧤𑨀-\u{11a3e}\u{11a47}𑩐-\u{11a99}𑪝𑫀-𑫸𑰀-𑰈𑰊-\u{11c36}\u{11c38}-𑱀𑱐-𑱙𑱲-𑲏\u{11c92}-\u{11ca7}𑲩-\u{11cb6}𑴀-𑴆𑴈-𑴉𑴋-\u{11d36}\u{11d3a}\u{11d3c}-\u{11d3d}\u{11d3f}-\u{11d47}𑵐-𑵙𑵠-𑵥𑵧-𑵨𑵪-𑶎\u{11d90}-\u{11d91}𑶓-𑶘𑶠-𑶩𑻠-𑻶𑾰𒀀-𒎙𒐀-𒑮𒒀-𒕃𓀀-𓐮𔐀-𔙆𖠀-𖨸𖩀-𖩞𖩠-𖩩𖫐-𖫭\u{16af0}-\u{16af4}𖬀-\u{16b36}𖭀-𖭃𖭐-𖭙𖭣-𖭷𖭽-𖮏𖹀-𖹿𖼀-𖽊\u{16f4f}-𖾇\u{16f8f}-𖾟𖿠-𖿡𖿣-\u{16fe4}𖿰-𖿱𗀀-𘟷𘠀-𘳕𘴀-𘴈𛀀-𛄞𛅐-𛅒𛅤-𛅧𛅰-𛋻𛰀-𛱪𛱰-𛱼𛲀-𛲈𛲐-𛲙\u{1bc9d}-\u{1bc9e}\u{1d165}-\u{1d169}𝅭-\u{1d172}\u{1d17b}-\u{1d182}\u{1d185}-\u{1d18b}\u{1d1aa}-\u{1d1ad}\u{1d242}-\u{1d244}𝐀-𝑔𝑖-𝒜𝒞-𝒟𝒢𝒥-𝒦𝒩-𝒬𝒮-𝒹𝒻𝒽-𝓃𝓅-𝔅𝔇-𝔊𝔍-𝔔𝔖-𝔜𝔞-𝔹𝔻-𝔾𝕀-𝕄𝕆𝕊-𝕐𝕒-𝚥𝚨-𝛀𝛂-𝛚𝛜-𝛺𝛼-𝜔𝜖-𝜴𝜶-𝝎𝝐-𝝮𝝰-𝞈𝞊-𝞨𝞪-𝟂𝟄-𝟋𝟎-𝟿\u{1da00}-\u{1da36}\u{1da3b}-\u{1da6c}\u{1da75}\u{1da84}\u{1da9b}-\u{1da9f}\u{1daa1}-\u{1daaf}\u{1e000}-\u{1e006}\u{1e008}-\u{1e018}\u{1e01b}-\u{1e021}\u{1e023}-\u{1e024}\u{1e026}-\u{1e02a}𞄀-𞄬\u{1e130}-𞄽𞅀-𞅉𞅎𞋀-𞋹𞠀-𞣄\u{1e8d0}-\u{1e8d6}𞤀-𞥋𞥐-𞥙𞸀-𞸃𞸅-𞸟𞸡-𞸢𞸤𞸧𞸩-𞸲𞸴-𞸷𞸹𞸻𞹂𞹇𞹉𞹋𞹍-𞹏𞹑-𞹒𞹔𞹗𞹙𞹛𞹝𞹟𞹡-𞹢𞹤𞹧-𞹪𞹬-𞹲𞹴-𞹷𞹹-𞹼𞹾𞺀-𞺉𞺋-𞺛𞺡-𞺣𞺥-𞺩𞺫-𞺻🄰-🅉🅐-🅩🅰-🆉🯰-🯹𠀀-𪛝𪜀-𫜴𫝀-𫠝𫠠-𬺡𬺰-𮯠丽-𪘀𰀀-𱍊\u{e0100}-\u{e01ef}]+\\[\\])", false), + ("^(%current_peer_id%)", false), + ("^(call)", false), + ("^(fold)", false), + ("^(next)", false), + ("^(null)", false), + ("^(par)", false), + ("^(seq)", false), + ("^(xor)", false), + (r"^(\s*)", true), + ]; + __lalrpop_util::lexer::MatcherBuilder::new(__strs.iter().copied()).unwrap() + } +} +pub use self::__lalrpop_util::lexer::Token; + +#[allow(unused_variables)] +fn __action0<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, __0, _): (usize, Box>, usize), +) -> Box> { + __0 +} + +#[allow(unused_variables)] +fn __action1<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, _, _): (usize, &'input str, usize), + (_, _, _): (usize, &'input str, usize), + (_, l, _): (usize, Box>, usize), + (_, r, _): (usize, Box>, usize), + (_, _, _): (usize, &'input str, usize), +) -> Box> { + Box::new(Instruction::Seq(Seq(l, r))) +} + +#[allow(unused_variables)] +fn __action2<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, _, _): (usize, &'input str, usize), + (_, _, _): (usize, &'input str, usize), + (_, l, _): (usize, Box>, usize), + (_, r, _): (usize, Box>, usize), + (_, _, _): (usize, &'input str, usize), +) -> Box> { + Box::new(Instruction::Par(Par(l, r))) +} + +#[allow(unused_variables)] +fn __action3<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, _, _): (usize, &'input str, usize), + (_, _, _): (usize, &'input str, usize), + (_, l, _): (usize, Box>, usize), + (_, r, _): (usize, Box>, usize), + (_, _, _): (usize, &'input str, usize), +) -> Box> { + Box::new(Instruction::Xor(Xor(l, r))) +} + +#[allow(unused_variables)] +fn __action4<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, _, _): (usize, &'input str, usize), + (_, _, _): (usize, &'input str, usize), + (_, peer, _): (usize, PeerPart<'input>, usize), + (_, f, _): (usize, FunctionPart<'input>, usize), + (_, args, _): (usize, Vec>, usize), + (_, output, _): (usize, CallOutput<'input>, usize), + (_, _, _): (usize, &'input str, usize), +) -> Box> { + Box::new(Instruction::Call(Call { + peer_part: peer, + function_part: f, + args, + output, + })) +} + +#[allow(unused_variables)] +fn __action5<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, _, _): (usize, &'input str, usize), + (_, _, _): (usize, &'input str, usize), + (_, iterable, _): (usize, &'input str, usize), + (_, iterator, _): (usize, &'input str, usize), + (_, i, _): (usize, Box>, usize), + (_, _, _): (usize, &'input str, usize), +) -> Box> { + { + let instruction = Rc::new(*i); + Box::new(Instruction::Fold(Fold { + iterable, + iterator, + instruction, + })) + } +} + +#[allow(unused_variables)] +fn __action6<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, _, _): (usize, &'input str, usize), + (_, _, _): (usize, &'input str, usize), + (_, i, _): (usize, &'input str, usize), + (_, _, _): (usize, &'input str, usize), +) -> Box> { + Box::new(Instruction::Next(Next(i))) +} + +#[allow(unused_variables)] +fn __action7<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, __0, _): (usize, &'input str, usize), + (_, __1, _): (usize, &'input str, usize), + (_, __2, _): (usize, &'input str, usize), +) -> Box> { + Box::new(Instruction::Null(Null)) +} + +#[allow(unused_variables)] +fn __action8<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, __0, _): ( + usize, + __lalrpop_util::ErrorRecovery, InstructionError>, + usize, + ), +) -> Box> { + { + errors.push(__0); + Box::new(Instruction::Error) + } +} + +#[allow(unused_variables)] +fn __action9<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, _, _): (usize, &'input str, usize), + (_, args, _): (usize, ::std::vec::Vec>, usize), + (_, _, _): (usize, &'input str, usize), +) -> Vec> { + args +} + +#[allow(unused_variables)] +fn __action10<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, f, _): (usize, Value<'input>, usize), +) -> FunctionPart<'input> { + FunctionPart::FuncName(f) +} + +#[allow(unused_variables)] +fn __action11<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, _, _): (usize, &'input str, usize), + (_, sid, _): (usize, Value<'input>, usize), + (_, f, _): (usize, Value<'input>, usize), + (_, _, _): (usize, &'input str, usize), +) -> FunctionPart<'input> { + FunctionPart::ServiceIdWithFuncName(sid, f) +} + +#[allow(unused_variables)] +fn __action12<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, pid, _): (usize, Value<'input>, usize), +) -> PeerPart<'input> { + PeerPart::PeerPk(pid) +} + +#[allow(unused_variables)] +fn __action13<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, _, _): (usize, &'input str, usize), + (_, pid, _): (usize, Value<'input>, usize), + (_, sid, _): (usize, Value<'input>, usize), + (_, _, _): (usize, &'input str, usize), +) -> PeerPart<'input> { + PeerPart::PeerPkWithServiceId(pid, sid) +} + +#[allow(unused_variables)] +fn __action14<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, o, _): (usize, &'input str, usize), +) -> CallOutput<'input> { + CallOutput::Scalar(o) +} + +#[allow(unused_variables)] +fn __action15<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, o, _): (usize, &'input str, usize), +) -> CallOutput<'input> { + CallOutput::Accumulator(&o[..o.len() - 2]) +} + +#[allow(unused_variables)] +fn __action16<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, __0, _): (usize, Value<'input>, usize), +) -> Value<'input> { + __0 +} + +#[allow(unused_variables)] +fn __action17<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, __0, _): (usize, Value<'input>, usize), +) -> Value<'input> { + __0 +} + +#[allow(unused_variables)] +fn __action18<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, __0, _): (usize, Value<'input>, usize), +) -> Value<'input> { + __0 +} + +#[allow(unused_variables)] +fn __action19<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, __0, _): (usize, Value<'input>, usize), +) -> Value<'input> { + __0 +} + +#[allow(unused_variables)] +fn __action20<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, __0, _): (usize, &'input str, usize), + (_, __1, _): (usize, &'input str, usize), +) -> Value<'input> { + Value::Literal("") +} + +#[allow(unused_variables)] +fn __action21<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, _, _): (usize, &'input str, usize), + (_, v, _): (usize, &'input str, usize), + (_, _, _): (usize, &'input str, usize), +) -> Value<'input> { + Value::Literal(v) +} + +#[allow(unused_variables)] +fn __action22<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, v, _): (usize, &'input str, usize), +) -> Value<'input> { + Value::Variable(v) +} + +#[allow(unused_variables)] +fn __action23<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, v, _): (usize, &'input str, usize), +) -> Value<'input> { + { + let mut path = v.splitn(2, "."); + let variable = path.next().expect("must contain dot"); + let path = path.next().expect("contain component after dot"); + Value::JsonPath { variable, path } + } +} + +#[allow(unused_variables)] +fn __action24<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, __0, _): (usize, &'input str, usize), +) -> Value<'input> { + Value::CurrentPeerId +} + +#[allow(unused_variables)] +fn __action25<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, __0, _): (usize, &'input str, usize), +) -> &'input str { + __0 +} + +#[allow(unused_variables)] +fn __action26<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __lookbehind: &usize, + __lookahead: &usize, +) -> ::std::vec::Vec> { + vec![] +} + +#[allow(unused_variables)] +fn __action27<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, v, _): (usize, ::std::vec::Vec>, usize), +) -> ::std::vec::Vec> { + v +} + +#[allow(unused_variables)] +fn __action28<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, __0, _): (usize, Value<'input>, usize), +) -> Value<'input> { + __0 +} + +#[allow(unused_variables)] +fn __action29<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, __0, _): (usize, Value<'input>, usize), +) -> ::std::vec::Vec> { + vec![__0] +} + +#[allow(unused_variables)] +fn __action30<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + (_, v, _): (usize, ::std::vec::Vec>, usize), + (_, e, _): (usize, Value<'input>, usize), +) -> ::std::vec::Vec> { + { + let mut v = v; + v.push(e); + v + } +} + +#[allow(unused_variables)] +fn __action31<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __0: (usize, Value<'input>, usize), +) -> ::std::vec::Vec> { + let __start0 = __0.0.clone(); + let __end0 = __0.2.clone(); + let __temp0 = __action28(errors, input, __0); + let __temp0 = (__start0, __temp0, __end0); + __action29(errors, input, __temp0) +} + +#[allow(unused_variables)] +fn __action32<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __0: (usize, ::std::vec::Vec>, usize), + __1: (usize, Value<'input>, usize), +) -> ::std::vec::Vec> { + let __start0 = __1.0.clone(); + let __end0 = __1.2.clone(); + let __temp0 = __action28(errors, input, __1); + let __temp0 = (__start0, __temp0, __end0); + __action30(errors, input, __0, __temp0) +} + +#[allow(unused_variables)] +fn __action33<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __0: (usize, &'input str, usize), + __1: (usize, &'input str, usize), +) -> Vec> { + let __start0 = __0.2.clone(); + let __end0 = __1.0.clone(); + let __temp0 = __action26(errors, input, &__start0, &__end0); + let __temp0 = (__start0, __temp0, __end0); + __action9(errors, input, __0, __temp0, __1) +} + +#[allow(unused_variables)] +fn __action34<'input, 'err>( + errors: &'err mut Vec, InstructionError>>, + input: &'input str, + __0: (usize, &'input str, usize), + __1: (usize, ::std::vec::Vec>, usize), + __2: (usize, &'input str, usize), +) -> Vec> { + let __start0 = __1.0.clone(); + let __end0 = __1.2.clone(); + let __temp0 = __action27(errors, input, __1); + let __temp0 = (__start0, __temp0, __end0); + __action9(errors, input, __0, __temp0, __2) +} + +pub trait __ToTriple<'input, 'err> { + fn to_triple( + value: Self, + ) -> Result< + (usize, Token<'input>, usize), + __lalrpop_util::ParseError, InstructionError>, + >; +} + +impl<'input, 'err> __ToTriple<'input, 'err> for (usize, Token<'input>, usize) { + fn to_triple( + value: Self, + ) -> Result< + (usize, Token<'input>, usize), + __lalrpop_util::ParseError, InstructionError>, + > { + Ok(value) + } +} +impl<'input, 'err> __ToTriple<'input, 'err> + for Result<(usize, Token<'input>, usize), InstructionError> +{ + fn to_triple( + value: Self, + ) -> Result< + (usize, Token<'input>, usize), + __lalrpop_util::ParseError, InstructionError>, + > { + match value { + Ok(v) => Ok(v), + Err(error) => Err(__lalrpop_util::ParseError::User { error }), + } + } +} diff --git a/crates/air-parser/src/lalrpop/parser.rs b/crates/air-parser/src/lalrpop/parser.rs new file mode 100644 index 00000000..1bc1bbd6 --- /dev/null +++ b/crates/air-parser/src/lalrpop/parser.rs @@ -0,0 +1,119 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use super::aqua; +use crate::ast::Instruction; +use crate::lalrpop::aqua::Token; + +use codespan_reporting::diagnostic::{Diagnostic, Label}; +use codespan_reporting::files::SimpleFiles; +use codespan_reporting::term; +use codespan_reporting::term::termcolor::{Buffer, ColorChoice, StandardStream}; +use lalrpop_util::{ErrorRecovery, ParseError}; + +use std::fmt::Formatter; + +#[derive(Debug)] +/// Represents custom parsing errors. Isn't used yet. +pub enum InstructionError { + #[allow(dead_code)] + InvalidPeerId, +} + +impl std::error::Error for InstructionError {} +impl std::fmt::Display for InstructionError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "InstructionError") + } +} + +// Caching parser to cache internal regexes, which are expensive to instantiate +// See also https://github.com/lalrpop/lalrpop/issues/269 +thread_local!(static PARSER: aqua::InstrParser = aqua::InstrParser::new()); + +/// Parse AIR `source_code` to `Box` +pub fn parse(source_code: &str) -> Result, String> { + let mut files = SimpleFiles::new(); + let file_id = files.add("script.aqua", source_code); + + PARSER.with(|parser| { + let mut errors = Vec::new(); + match parser.parse(&mut errors, source_code) { + Ok(r) if errors.is_empty() => Ok(r), + Ok(_) => Err(report_errors(file_id, files, errors)), + Err(err) => Err(report_errors( + file_id, + files, + vec![ErrorRecovery { + error: err, + dropped_tokens: vec![], + }], + )), + } + }) +} + +fn report_errors( + file_id: usize, + files: SimpleFiles<&str, &str>, + errors: Vec>, +) -> String { + let labels: Vec> = errors + .into_iter() + .map(|err| match err.error { + ParseError::UnrecognizedToken { + token: (start, _, end), + expected, + } => Label::primary(file_id, start..end) + .with_message(format!("expected {}", pretty_expected(expected))), + ParseError::InvalidToken { location } => { + Label::primary(file_id, location..(location + 1)).with_message("unexpected token") + } + ParseError::ExtraToken { + token: (start, _, end), + } => Label::primary(file_id, start..end).with_message("extra token"), + ParseError::UnrecognizedEOF { location, expected } => { + Label::primary(file_id, location..(location + 1)) + .with_message(format!("expected {}", pretty_expected(expected))) + } + // TODO: capture start & end in user error; maybe return it as a separate Diagnostic::error? + ParseError::User { error } => { + Label::primary(file_id, 0..0).with_message(error.to_string()) + } + }) + .collect(); + let diagnostic = Diagnostic::error().with_labels(labels); + let config = codespan_reporting::term::Config::default(); + + // Write to stderr + let writer = StandardStream::stderr(ColorChoice::Auto); + term::emit(&mut writer.lock(), &config, &files, &diagnostic).expect("term emit to stderr"); + + // Return as a string + let mut buffer = Buffer::no_color(); + term::emit(&mut buffer, &config, &files, &diagnostic).expect("term emit to buffer"); + String::from_utf8_lossy(buffer.as_slice()) + .as_ref() + .to_string() +} + +fn pretty_expected(expected: Vec) -> String { + if expected.is_empty() { + "".to_string() + } else { + expected.join(" or ") + } +} diff --git a/crates/air-parser/src/lalrpop/tests.rs b/crates/air-parser/src/lalrpop/tests.rs new file mode 100644 index 00000000..417a263b --- /dev/null +++ b/crates/air-parser/src/lalrpop/tests.rs @@ -0,0 +1,364 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use crate::ast::*; +use CallOutput::*; +use FunctionPart::*; +use PeerPart::*; +use Value::*; + +use fstrings::f; + +fn parse(source_code: &str) -> Instruction { + *super::parse(source_code).expect("parsing failed") +} + +#[test] +fn parse_seq() { + let source_code = r#" + (seq + (call peerid function [] void) + (call "id" "f" ["hello" name] void[]) + ) + "#; + let instruction = parse(source_code); + let expected = seq( + Instruction::Call(Call { + peer_part: PeerPk(Variable("peerid")), + function_part: FuncName(Variable("function")), + args: vec![], + output: Scalar("void"), + }), + Instruction::Call(Call { + peer_part: PeerPk(Literal("id")), + function_part: FuncName(Literal("f")), + args: vec![Literal("hello"), Variable("name")], + output: Accumulator("void"), + }), + ); + assert_eq!(instruction, expected); +} + +#[test] +fn parse_seq_seq() { + let source_code = r#" + (seq + (seq + (call peerid function [] void) + (call (peerid serviceA) ("serviceB" function) [] void) + ) + (call "id" "f" ["hello" name] void[]) + ) + "#; + let instruction = parse(source_code); + let expected = seq( + seq( + Instruction::Call(Call { + peer_part: PeerPk(Variable("peerid")), + function_part: FuncName(Variable("function")), + args: vec![], + output: Scalar("void"), + }), + Instruction::Call(Call { + peer_part: PeerPkWithServiceId(Variable("peerid"), Variable("serviceA")), + function_part: ServiceIdWithFuncName(Literal("serviceB"), Variable("function")), + args: vec![], + output: Scalar("void"), + }), + ), + Instruction::Call(Call { + peer_part: PeerPk(Literal("id")), + function_part: FuncName(Literal("f")), + args: vec![Literal("hello"), Variable("name")], + output: Accumulator("void"), + }), + ); + assert_eq!(instruction, expected); +} + +#[test] +fn parse_json_path() { + let source_code = r#" + (call id.$.a "f" ["hello" name] void[]) + "#; + let instruction = parse(source_code); + let expected = Instruction::Call(Call { + peer_part: PeerPk(JsonPath { + variable: "id", + path: "$.a", + }), + function_part: FuncName(Literal("f")), + args: vec![Literal("hello"), Variable("name")], + output: Accumulator("void"), + }); + assert_eq!(instruction, expected); +} + +#[test] +fn parse_json_path_complex() { + let source_code = r#" + (seq + (call m.$.[1] "f" [] void) + (call m.$.abc.cde[a][0].cde "f" [] void) + ) + "#; + let instruction = parse(source_code); + let expected = seq( + Instruction::Call(Call { + peer_part: PeerPk(JsonPath { + variable: "m", + path: "$.[1]", + }), + function_part: FuncName(Literal("f")), + args: vec![], + output: Scalar("void"), + }), + Instruction::Call(Call { + peer_part: PeerPk(JsonPath { + variable: "m", + path: "$.abc.cde[a][0].cde", + }), + function_part: FuncName(Literal("f")), + args: vec![], + output: Scalar("void"), + }), + ); + assert_eq!(instruction, expected); +} + +#[test] +fn parse_null() { + let source_code = r#" + (seq + (null) + + ( null ) + ) + "#; + let instruction = parse(source_code); + let expected = Instruction::Seq(Seq(Box::new(null()), Box::new(null()))); + assert_eq!(instruction, expected) +} + +fn source_seq_with(name: &'static str) -> String { + f!(r#" + (seq + ({name} + (seq (null) (null)) + (null) + ) + ({name} (null) (seq (null) (null)) ) + ) + "#) +} + +#[test] +fn parse_seq_par_xor_seq() { + for name in &["xor", "par", "seq"] { + let source_code = source_seq_with(name); + let instruction = parse(&source_code.as_ref()); + let instr = binary_instruction(*name); + let expected = seq(instr(seqnn(), null()), instr(null(), seqnn())); + assert_eq!(instruction, expected); + } +} + +#[test] +fn parse_fold() { + let source_code = r#" + (fold iterable i + (null) + ) + "#; + let instruction = parse(&source_code.as_ref()); + let expected = fold("iterable", "i", null()); + assert_eq!(instruction, expected); +} + +fn source_fold_with(name: &str) -> String { + f!(r#"(fold iterable i + ({name} (null) (null)) + )"#) +} +#[test] +fn parse_fold_with_xor_par_seq() { + for name in &["xor", "par", "seq"] { + let source_code = source_fold_with(name); + let instruction = parse(&source_code.as_ref()); + let instr = binary_instruction(*name); + let expected = fold("iterable", "i", instr(null(), null())); + assert_eq!(instruction, expected); + } +} + +#[test] +fn seq_par_call() { + let source_code = r#" + (seq + (par + (call %current_peer_id% ("local_service_id" "local_fn_name") [] result_1) + (call "remote_peer_id" ("service_id" "fn_name") [] g) + ) + (call %current_peer_id% ("local_service_id" "local_fn_name") [] result_2) + )"#; + let instruction = parse(&source_code.as_ref()); + let expected = seq( + par( + Instruction::Call(Call { + peer_part: PeerPk(CurrentPeerId), + function_part: ServiceIdWithFuncName( + Literal("local_service_id"), + Literal("local_fn_name"), + ), + args: vec![], + output: Scalar("result_1"), + }), + Instruction::Call(Call { + peer_part: PeerPk(Literal("remote_peer_id")), + function_part: ServiceIdWithFuncName(Literal("service_id"), Literal("fn_name")), + args: vec![], + output: Scalar("g"), + }), + ), + Instruction::Call(Call { + peer_part: PeerPk(CurrentPeerId), + function_part: ServiceIdWithFuncName( + Literal("local_service_id"), + Literal("local_fn_name"), + ), + args: vec![], + output: Scalar("result_2"), + }), + ); + assert_eq!(instruction, expected); +} + +#[test] +fn seq_with_empty_and_dash() { + let source_code = r#" + (seq + (seq + (seq + (call "set_variables" ("" "") ["module-bytes"] module-bytes) + (call "set_variables" ("" "") ["module_config"] module_config) + ) + (call "set_variables" ("" "") ["blueprint"] blueprint) + ) + (seq + (call "A" ("add_module" "") [module-bytes module_config] module) + (seq + (call "A" ("add_blueprint" "") [blueprint] blueprint_id) + (seq + (call "A" ("create" "") [blueprint_id] service_id) + (call "remote_peer_id" ("" "") [service_id] client_result) + ) + ) + ) + ) + "#; + let instruction = parse(&source_code.as_ref()); + let expected = seq( + seq( + seq( + Instruction::Call(Call { + peer_part: PeerPk(Literal("set_variables")), + function_part: ServiceIdWithFuncName(Literal(""), Literal("")), + args: vec![Literal("module-bytes")], + output: Scalar("module-bytes"), + }), + Instruction::Call(Call { + peer_part: PeerPk(Literal("set_variables")), + function_part: ServiceIdWithFuncName(Literal(""), Literal("")), + args: vec![Literal("module_config")], + output: Scalar("module_config"), + }), + ), + Instruction::Call(Call { + peer_part: PeerPk(Literal("set_variables")), + function_part: ServiceIdWithFuncName(Literal(""), Literal("")), + args: vec![Literal("blueprint")], + output: Scalar("blueprint"), + }), + ), + seq( + Instruction::Call(Call { + peer_part: PeerPk(Literal("A")), + function_part: ServiceIdWithFuncName(Literal("add_module"), Literal("")), + args: vec![Variable("module-bytes"), Variable("module_config")], + output: Scalar("module"), + }), + seq( + Instruction::Call(Call { + peer_part: PeerPk(Literal("A")), + function_part: ServiceIdWithFuncName(Literal("add_blueprint"), Literal("")), + args: vec![Variable("blueprint")], + output: Scalar("blueprint_id"), + }), + seq( + Instruction::Call(Call { + peer_part: PeerPk(Literal("A")), + function_part: ServiceIdWithFuncName(Literal("create"), Literal("")), + args: vec![Variable("blueprint_id")], + output: Scalar("service_id"), + }), + Instruction::Call(Call { + peer_part: PeerPk(Literal("remote_peer_id")), + function_part: ServiceIdWithFuncName(Literal(""), Literal("")), + args: vec![Variable("service_id")], + output: Scalar("client_result"), + }), + ), + ), + ), + ); + + assert_eq!(instruction, expected); +} + +// Test DSL + +fn seq<'a>(l: Instruction<'a>, r: Instruction<'a>) -> Instruction<'a> { + Instruction::Seq(Seq(Box::new(l), Box::new(r))) +} +fn par<'a>(l: Instruction<'a>, r: Instruction<'a>) -> Instruction<'a> { + Instruction::Par(Par(Box::new(l), Box::new(r))) +} +fn xor<'a>(l: Instruction<'a>, r: Instruction<'a>) -> Instruction<'a> { + Instruction::Xor(Xor(Box::new(l), Box::new(r))) +} +fn seqnn() -> Instruction<'static> { + seq(null(), null()) +} +fn null() -> Instruction<'static> { + Instruction::Null(Null) +} +fn fold<'a>(iterable: &'a str, iterator: &'a str, instruction: Instruction<'a>) -> Instruction<'a> { + Instruction::Fold(Fold { + iterable, + iterator, + instruction: std::rc::Rc::new(instruction), + }) +} +fn binary_instruction<'a, 'b>( + name: &'a str, +) -> impl Fn(Instruction<'b>, Instruction<'b>) -> Instruction<'b> { + match name { + "xor" => |l, r| xor(l, r), + "par" => |l, r| par(l, r), + "seq" => |l, r| seq(l, r), + _ => unreachable!(), + } +} diff --git a/crates/air-parser/src/lib.rs b/crates/air-parser/src/lib.rs new file mode 100644 index 00000000..4ab68609 --- /dev/null +++ b/crates/air-parser/src/lib.rs @@ -0,0 +1,20 @@ +#![deny(unused_imports, unused_variables, dead_code)] + +#[cfg(test)] +#[macro_use] +extern crate fstrings; + +pub mod ast; +mod lalrpop { + #[cfg(test)] + mod tests; + + // aqua is auto-generated, so exclude it from `cargo fmt -- --check` + #[rustfmt::skip] + mod aqua; + mod parser; + + pub use parser::parse; +} + +pub use lalrpop::parse; diff --git a/crates/test-utils/src/lib.rs b/crates/test-utils/src/lib.rs index f591694b..f9342d42 100644 --- a/crates/test-utils/src/lib.rs +++ b/crates/test-utils/src/lib.rs @@ -147,7 +147,9 @@ pub fn set_variables_call_service(ret_mapping: HashMap) -> HostE #[macro_export] macro_rules! call_vm { ($vm:expr, $init_user_id:expr, $script:expr, $prev_data:expr, $data:expr) => { - $vm.call_with_prev_data($init_user_id, $script, $prev_data, $data) - .expect("call should be successful"); + match $vm.call_with_prev_data($init_user_id, $script, $prev_data, $data) { + Ok(v) => v, + Err(err) => panic!("VM call failed: {}", err), + } }; } diff --git a/stepper-lib/Cargo.toml b/stepper-lib/Cargo.toml index 1362bc36..94e94fdc 100644 --- a/stepper-lib/Cargo.toml +++ b/stepper-lib/Cargo.toml @@ -9,11 +9,11 @@ name = "stepper_lib" path = "src/lib.rs" [dependencies] +air-parser = { path = "../crates/air-parser" } fluence = { git = "https://github.com/fluencelabs/rust-sdk", features = ["logger"] } serde = { version = "1.0.116", features = [ "derive", "rc" ] } serde_derive = "1.0.116" -serde_sexpr = "0.1.0" jsonpath_lib = "0.2.5" diff --git a/stepper-lib/benches/call_benchmark.rs b/stepper-lib/benches/call_benchmark.rs index e7515b01..957d646a 100644 --- a/stepper-lib/benches/call_benchmark.rs +++ b/stepper-lib/benches/call_benchmark.rs @@ -13,7 +13,7 @@ use std::cell::RefCell; thread_local!(static VM: RefCell = RefCell::new(create_aqua_vm(unit_call_service(), "test_peer_id"))); thread_local!(static SCRIPT: String = String::from( r#" - (call (%current_peer_id% ("local_service_id" "local_fn_name") () result_name)) + (call %current_peer_id% ("local_service_id" "local_fn_name") [] result_name) "#, ) ); diff --git a/stepper-lib/benches/chat_benchmark.rs b/stepper-lib/benches/chat_benchmark.rs index d6722e42..1dfeadb9 100644 --- a/stepper-lib/benches/chat_benchmark.rs +++ b/stepper-lib/benches/chat_benchmark.rs @@ -34,24 +34,24 @@ thread_local!(static CLIENT_2_VM: RefCell = RefCell::new(create_aq fn chat_sent_message_benchmark() -> Result { let script = String::from( r#" - (seq ( - (call ("Relay1" ("identity" "") () void1[])) - (seq ( - (call ("Remote" ("552196ea-b9b2-4761-98d4-8e7dba77fac4" "add") () void2[])) - (seq ( - (call ("Remote" ("920e3ba3-cbdf-4ae3-8972-0fa2f31fffd9" "get_users") () members)) - (fold (members m - (par ( - (seq ( - (call (m.$.[1] ("identity" "") () void[])) - (call (m.$.[0] ("fgemb3" "add") () void3[])) - )) + (seq + (call "Relay1" ("identity" "") [] void1[]) + (seq + (call "Remote" ("552196ea-b9b2-4761-98d4-8e7dba77fac4" "add") [] void2[]) + (seq + (call "Remote" ("920e3ba3-cbdf-4ae3-8972-0fa2f31fffd9" "get_users") [] members) + (fold members m + (par + (seq + (call m.$.[1] ("identity" "") [] void[]) + (call m.$.[0] ("fgemb3" "add") [] void3[]) + ) (next m) - )) - )) - )) - )) - )) + ) + ) + ) + ) + ) "#, ); diff --git a/stepper-lib/benches/create_service_benchmark.rs b/stepper-lib/benches/create_service_benchmark.rs index c42ec699..52b69b32 100644 --- a/stepper-lib/benches/create_service_benchmark.rs +++ b/stepper-lib/benches/create_service_benchmark.rs @@ -71,25 +71,25 @@ thread_local!(static SET_VARIABLES_VM: RefCell = RefCell::new({ fn create_service_benchmark() -> Result { let script = String::from( r#" - (seq ( - (seq ( - (seq ( - (call ("set_variables" ("" "") ("module_bytes") module_bytes)) - (call ("set_variables" ("" "") ("module_config") module_config)) - )) - (call ("set_variables" ("" "") ("blueprint") blueprint)) - )) - (seq ( - (call ("A" ("add_module" "") (module_bytes module_config) module)) - (seq ( - (call ("A" ("add_blueprint" "") (blueprint) blueprint_id)) - (seq ( - (call ("A" ("create" "") (blueprint_id) service_id)) - (call ("remote_peer_id" ("" "") (service_id) client_result)) - )) - )) - )) - ))"#, + (seq + (seq + (seq + (call "set_variables" ("" "") ["module_bytes"] module_bytes) + (call "set_variables" ("" "") ["module_config"] module_config) + ) + (call "set_variables" ("" "") ["blueprint"] blueprint) + ) + (seq + (call "A" ("add_module" "") [module_bytes module_config] module) + (seq + (call "A" ("add_blueprint" "") [blueprint] blueprint_id) + (seq + (call "A" ("create" "") [blueprint_id] service_id) + (call "remote_peer_id" ("" "") [service_id] client_result) + ) + ) + ) + )"#, ); let res = SET_VARIABLES_VM diff --git a/stepper-lib/src/air/call.rs b/stepper-lib/src/air/call.rs index 4609c935..0a7fd0f7 100644 --- a/stepper-lib/src/air/call.rs +++ b/stepper-lib/src/air/call.rs @@ -15,6 +15,7 @@ */ mod parsed_call; +mod triplet; mod utils; use parsed_call::ParsedCall; @@ -26,10 +27,7 @@ use crate::AquamarineError::VariableNotFound; use crate::AquamarineError::VariableNotInJsonPath; use crate::Result; -use serde_derive::Deserialize; -use serde_derive::Serialize; - -const CURRENT_PEER_ALIAS: &str = "%current_peer_id%"; +use air_parser::ast::Call; /* (current) @@ -42,25 +40,8 @@ const CURRENT_PEER_ALIAS: &str = "%current_peer_id%"; FN_PART: resolves to (fn_name) \/ (fn_srv_id, fn_name) */ -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] -#[serde(untagged)] -pub(self) enum PeerPart { - PeerPk(String), - PeerPkWithServiceId(String, String), -} - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] -#[serde(untagged)] -pub(self) enum FunctionPart { - FuncName(String), - ServiceIdWithFuncName(String, String), -} - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] -pub(crate) struct Call(PeerPart, FunctionPart, Vec, String); - -impl super::ExecutableInstruction for Call { - fn execute(&self, exec_ctx: &mut ExecutionCtx, call_ctx: &mut CallEvidenceCtx) -> Result<()> { +impl<'i> super::ExecutableInstruction<'i> for Call<'i> { + fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx) -> Result<()> { log_instruction!(call, exec_ctx, call_ctx); let parsed_call = match ParsedCall::new(self, exec_ctx) { @@ -113,7 +94,7 @@ mod tests { let script = String::from( r#" - (call (%current_peer_id% ("local_service_id" "local_fn_name") () result_name)) + (call %current_peer_id% ("local_service_id" "local_fn_name") [] result_name) "#, ); @@ -129,7 +110,7 @@ mod tests { let script = String::from( r#" - (call ("test_peer_id" ("local_service_id" "local_fn_name") () result_name)) + (call "test_peer_id" ("local_service_id" "local_fn_name") [] result_name) "#, ); @@ -154,7 +135,7 @@ mod tests { let remote_peer_id = String::from("some_remote_peer_id"); let script = format!( - r#"(call ("{}" ("local_service_id" "local_fn_name") (value) result_name))"#, + r#"(call "{}" ("local_service_id" "local_fn_name") [value] result_name)"#, remote_peer_id ); @@ -173,10 +154,10 @@ mod tests { let script = format!( r#" - (seq ( - (call ("set_variable" ("some_service_id" "local_fn_name") () remote_peer_id)) - (call (remote_peer_id ("some_service_id" "local_fn_name") () result_name)) - )) + (seq + (call "set_variable" ("some_service_id" "local_fn_name") [] remote_peer_id) + (call remote_peer_id ("some_service_id" "local_fn_name") [] result_name) + ) "#, ); @@ -207,10 +188,10 @@ mod tests { let script = String::from( r#" - (seq ( - (call ("set_variable" ("some_service_id" "local_fn_name") () arg3)) - (call ("A" ("some_service_id" "local_fn_name") ("arg1" "arg2" arg3) result)) - )) + (seq + (call "set_variable" ("some_service_id" "local_fn_name") [] arg3) + (call "A" ("some_service_id" "local_fn_name") ["arg1" "arg2" arg3] result) + ) "#, ); diff --git a/stepper-lib/src/air/call/parsed_call.rs b/stepper-lib/src/air/call/parsed_call.rs index 9b241d6f..20748e16 100644 --- a/stepper-lib/src/air/call/parsed_call.rs +++ b/stepper-lib/src/air/call/parsed_call.rs @@ -16,63 +16,62 @@ #![allow(unused_unsafe)] // for wasm_bindgen target where calling FFI is safe -use super::utils::find_by_json_path; -use super::utils::is_string_literal; -use super::utils::set_local_call_result; +use super::triplet::{ResolvedTriplet, Triplet}; +use super::utils::{resolve_jvalue, set_local_call_result, set_remote_call_result}; use super::Call; -use super::CURRENT_PEER_ALIAS; + use crate::air::ExecutionCtx; use crate::build_targets::CALL_SERVICE_SUCCESS; -use crate::call_evidence::CallEvidenceCtx; -use crate::call_evidence::CallResult; -use crate::call_evidence::EvidenceState; +use crate::call_evidence::{CallEvidenceCtx, CallResult, EvidenceState}; use crate::log_targets::EVIDENCE_CHANGING; -use crate::AValue; use crate::AquamarineError; use crate::JValue; use crate::Result; -use std::borrow::Cow; +use air_parser::ast::{CallOutput, Value}; + use std::rc::Rc; #[derive(Debug, PartialEq, Eq)] -pub(super) struct ParsedCall { +pub(super) struct ParsedCall<'i> { peer_pk: String, service_id: String, function_name: String, - function_arg_paths: Vec, - result_variable_name: String, + function_arg_paths: Vec>, + output: CallOutput<'i>, } -impl ParsedCall { - pub(super) fn new(raw_call: &Call, exec_ctx: &ExecutionCtx) -> Result { - let (peer_pk, service_id, function_name) = prepare_peer_fn_parts(raw_call, exec_ctx)?; - let result_variable_name = parse_result_variable_name(raw_call)?; +impl<'i> ParsedCall<'i> { + /// Builds `ParsedCall` from `Call` by transforming `PeerPart` & `FunctionPart` into `ResolvedTriplet` + pub(super) fn new(raw_call: &Call<'i>, exec_ctx: &ExecutionCtx<'i>) -> Result { + let triplet = Triplet::try_from(&raw_call.peer_part, &raw_call.function_part)?; + #[rustfmt::skip] + let ResolvedTriplet { peer_pk, service_id, function_name } = triplet.resolve(exec_ctx)?; Ok(Self { peer_pk, service_id, function_name, - function_arg_paths: raw_call.2.clone(), - result_variable_name: result_variable_name.to_string(), + function_arg_paths: raw_call.args.clone(), + output: raw_call.output.clone(), }) } - pub(super) fn execute(self, exec_ctx: &mut ExecutionCtx, call_ctx: &mut CallEvidenceCtx) -> Result<()> { - let should_executed = self.prepare_evidence_state(exec_ctx, call_ctx)?; - if !should_executed { + pub(super) fn execute(self, exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx) -> Result<()> { + let should_execute = self.prepare_evidence_state(exec_ctx, call_ctx)?; + if !should_execute { return Ok(()); } - if self.peer_pk != exec_ctx.current_peer_id && self.peer_pk != CURRENT_PEER_ALIAS { - super::utils::set_remote_call_result(self.peer_pk, exec_ctx, call_ctx); + if self.peer_pk != exec_ctx.current_peer_id { + set_remote_call_result(self.peer_pk, exec_ctx, call_ctx); return Ok(()); } - let function_args = extract_args_by_paths(&self.function_arg_paths, exec_ctx)?; - let function_args = serde_json::to_string(&function_args) - .map_err(|e| AquamarineError::FuncArgsSerializationError(function_args, e))?; + let function_args = self.function_arg_paths.iter(); + let function_args: Result> = function_args.map(|v| resolve_jvalue(v, exec_ctx)).collect(); + let function_args = JValue::Array(function_args?).to_string(); let result = unsafe { crate::call_service(self.service_id, self.function_name, function_args) }; @@ -88,7 +87,7 @@ impl ParsedCall { let result: JValue = serde_json::from_str(&result.result) .map_err(|e| AquamarineError::CallServiceResultDeserializationError(result, e))?; let result = Rc::new(result); - super::utils::set_local_call_result(self.result_variable_name, exec_ctx, result.clone())?; + set_local_call_result(self.output, exec_ctx, result.clone())?; let new_evidence_state = EvidenceState::Call(CallResult::Executed(result)); log::info!( @@ -103,7 +102,7 @@ impl ParsedCall { pub(super) fn prepare_evidence_state( &self, - exec_ctx: &mut ExecutionCtx, + exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx, ) -> Result { use crate::call_evidence::CallResult::*; @@ -147,7 +146,7 @@ impl ParsedCall { } // this instruction's been already executed Call(Executed(result)) => { - set_local_call_result(self.result_variable_name.clone(), exec_ctx, result.clone())?; + set_local_call_result(self.output.clone(), exec_ctx, result.clone())?; call_ctx.new_path.push_back(prev_state); Ok(false) } @@ -159,132 +158,3 @@ impl ParsedCall { } } } - -fn prepare_peer_fn_parts<'a>(raw_call: &'a Call, exec_ctx: &'a ExecutionCtx) -> Result<(String, String, String)> { - use super::FunctionPart::*; - use super::PeerPart::*; - - let (peer_pk, service_id, func_name) = match (&raw_call.0, &raw_call.1) { - (PeerPkWithServiceId(peer_pk, peer_service_id), ServiceIdWithFuncName(_service_id, func_name)) => { - Ok((peer_pk, peer_service_id, func_name)) - } - (PeerPkWithServiceId(peer_pk, peer_service_id), FuncName(func_name)) => { - Ok((peer_pk, peer_service_id, func_name)) - } - (PeerPk(peer_pk), ServiceIdWithFuncName(service_id, func_name)) => Ok((peer_pk, service_id, func_name)), - (PeerPk(_), FuncName(_)) => Err(AquamarineError::InstructionError(String::from( - "call should have service id specified by peer part or function part", - ))), - }?; - - let peer_pk = if peer_pk != CURRENT_PEER_ALIAS { - prepare_call_arg(peer_pk, exec_ctx)? - } else { - peer_pk.to_string() - }; - - let service_id = prepare_call_arg(service_id, exec_ctx)?; - let func_name = prepare_call_arg(func_name, exec_ctx)?; - - Ok((peer_pk, service_id, func_name)) -} - -fn extract_args_by_paths(function_arg_paths: &[String], ctx: &ExecutionCtx) -> Result { - let mut result = Vec::with_capacity(function_arg_paths.len()); - let owned_maybe_json_path = |jvalue: Cow<'_, JValue>, json_path: Option<&str>| -> Result> { - if json_path.is_none() { - return Ok(vec![jvalue.into_owned()]); - } - - let json_path = json_path.unwrap(); - let values = find_by_json_path(jvalue.as_ref(), json_path)?; - Ok(values.into_iter().cloned().collect()) - }; - - for arg_path in function_arg_paths.iter() { - if is_string_literal(arg_path) { - result.push(JValue::String(arg_path[1..arg_path.len() - 1].to_string())); - } else { - let arg = get_args_by_path(arg_path, ctx, owned_maybe_json_path)?; - result.extend(arg); - } - } - - Ok(JValue::Array(result)) -} - -fn parse_result_variable_name(call: &Call) -> Result<&str> { - let result_variable_name = &call.3; - - if result_variable_name.is_empty() { - return Err(AquamarineError::InstructionError(String::from( - "result name of a call instruction must be non empty", - ))); - } - - if is_string_literal(result_variable_name) { - return Err(AquamarineError::InstructionError(String::from( - "result name of a call instruction must be non string literal", - ))); - } - - Ok(result_variable_name) -} - -fn get_args_by_path<'args_path, 'exec_ctx, T: 'exec_ctx>( - args_path: &'args_path str, - ctx: &'exec_ctx ExecutionCtx, - maybe_json_path: impl FnOnce(Cow<'exec_ctx, JValue>, Option<&str>) -> Result, -) -> Result { - let mut split_arg: Vec<&str> = args_path.splitn(2, '.').collect(); - let arg_path_head = split_arg.remove(0); - - match ctx.data_cache.get(arg_path_head) { - Some(AValue::JValueFoldCursor(fold_state)) => match fold_state.iterable.as_ref() { - JValue::Array(array) => { - let jvalue = &array[fold_state.cursor]; - maybe_json_path(Cow::Borrowed(jvalue), split_arg.pop()) - } - _ => unreachable!("fold state must be well-formed because it is changed only by stepper"), - }, - Some(AValue::JValueRef(value)) => maybe_json_path(Cow::Borrowed(value.as_ref()), split_arg.pop()), - Some(AValue::JValueAccumulatorRef(acc)) => { - let owned_acc = acc.borrow().iter().map(|v| v.as_ref()).cloned().collect::>(); - let jvalue = JValue::Array(owned_acc); - maybe_json_path(Cow::Owned(jvalue), split_arg.pop()) - } - None => Err(AquamarineError::VariableNotFound(arg_path_head.to_string())), - } -} - -// Prepare arguments of call -fn prepare_call_arg<'a>(arg_path: &'a str, ctx: &'a ExecutionCtx) -> Result { - fn borrowed_maybe_json_path(jvalue: Cow<'_, JValue>, json_path: Option<&str>) -> Result { - if json_path.is_none() { - return Ok(jvalue.into_owned()); - } - - let json_path = json_path.unwrap(); - let values = find_by_json_path(jvalue.as_ref(), json_path)?; - if values.is_empty() { - return Err(AquamarineError::VariableNotFound(json_path.to_string())); - } - - if values.len() != 1 { - return Err(AquamarineError::MultipleValuesInJsonPath(json_path.to_string())); - } - - Ok(values[0].clone()) - } - - if is_string_literal(arg_path) { - return Ok(arg_path[1..arg_path.len() - 1].to_string()); - } - - let arg = get_args_by_path(arg_path, ctx, borrowed_maybe_json_path)?; - - match arg { - JValue::String(str) => Ok(str), - v => Err(AquamarineError::IncompatibleJValueType(v, String::from("string"))), - } -} diff --git a/stepper-lib/src/air/call/triplet.rs b/stepper-lib/src/air/call/triplet.rs new file mode 100644 index 00000000..66f41ee2 --- /dev/null +++ b/stepper-lib/src/air/call/triplet.rs @@ -0,0 +1,83 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use super::utils::resolve_value; + +use crate::air::ExecutionCtx; +use crate::{AquamarineError, Result}; + +use air_parser::ast::{FunctionPart, PeerPart, Value}; + +/// Triplet represents a location of the executable code in the network +/// It is build from `PeerPart` and `FunctionPart` of a `Call` instruction +pub(super) struct Triplet<'a, 'i> { + pub(super) peer_pk: &'a Value<'i>, + pub(super) service_id: &'a Value<'i>, + pub(super) function_name: &'a Value<'i>, +} + +/// ResolvedTriplet represents same location as `Triplet`, but with all +/// variables, literals and etc resolved into final `String` +pub(super) struct ResolvedTriplet { + pub(super) peer_pk: String, + pub(super) service_id: String, + pub(super) function_name: String, +} + +impl<'a, 'i> Triplet<'a, 'i> { + /// Build a `Triplet` from `Call`'s `PeerPart` and `FunctionPart` + pub fn try_from(peer: &'a PeerPart<'i>, f: &'a FunctionPart<'i>) -> Result { + use air_parser::ast::FunctionPart::*; + use air_parser::ast::PeerPart::*; + + let (peer_pk, service_id, function_name) = match (peer, f) { + (PeerPkWithServiceId(peer_pk, peer_service_id), ServiceIdWithFuncName(_service_id, func_name)) => { + Ok((peer_pk, peer_service_id, func_name)) + } + (PeerPkWithServiceId(peer_pk, peer_service_id), FuncName(func_name)) => { + Ok((peer_pk, peer_service_id, func_name)) + } + (PeerPk(peer_pk), ServiceIdWithFuncName(service_id, func_name)) => Ok((peer_pk, service_id, func_name)), + (PeerPk(_), FuncName(_)) => Err(AquamarineError::InstructionError(String::from( + "call should have service id specified by peer part or function part", + ))), + }?; + + Ok(Self { + peer_pk, + service_id, + function_name, + }) + } + + /// Resolve variables, literals, etc in the `Triplet`, and build a `ResolvedTriplet` + pub fn resolve(self, ctx: &'a ExecutionCtx<'i>) -> Result { + let Triplet { + peer_pk, + service_id, + function_name, + } = self; + let peer_pk = resolve_value(peer_pk, ctx)?.as_ref().to_string(); + let service_id = resolve_value(service_id, ctx)?.as_ref().to_string(); + let function_name = resolve_value(function_name, ctx)?.as_ref().to_string(); + + Ok(ResolvedTriplet { + peer_pk, + service_id, + function_name, + }) + } +} diff --git a/stepper-lib/src/air/call/utils.rs b/stepper-lib/src/air/call/utils.rs index 01b14d60..39892234 100644 --- a/stepper-lib/src/air/call/utils.rs +++ b/stepper-lib/src/air/call/utils.rs @@ -24,43 +24,49 @@ use crate::AquamarineError; use crate::JValue; use crate::Result; -use std::cell::RefCell; -use std::rc::Rc; +use air_parser::ast::{CallOutput, Value}; -pub(super) fn set_local_call_result( - result_variable_name: String, - exec_ctx: &mut ExecutionCtx, +use std::{borrow::Cow, cell::RefCell, rc::Rc}; + +/// Writes result of a local `Call` instruction to `ExecutionCtx` at `output` +pub(super) fn set_local_call_result<'i>( + output: CallOutput<'i>, + exec_ctx: &mut ExecutionCtx<'i>, result: Rc, ) -> Result<()> { use std::collections::hash_map::Entry::{Occupied, Vacant}; use AquamarineError::*; - let stripped_result_name = result_variable_name.strip_suffix("[]"); - if stripped_result_name.is_none() { - // if result is not an array, simply insert it into data - match exec_ctx.data_cache.entry(result_variable_name) { - Vacant(entry) => entry.insert(AValue::JValueRef(result)), - Occupied(entry) => return Err(MultipleVariablesFound(entry.key().clone())), - }; - return Ok(()); - } - - // unwrap is safe because it's been checked for [] - match exec_ctx.data_cache.entry(stripped_result_name.unwrap().to_string()) { - Occupied(mut entry) => match entry.get_mut() { - // if result is an array, insert result to the end of the array - AValue::JValueAccumulatorRef(values) => values.borrow_mut().push(result), - v => return Err(IncompatibleAValueType(format!("{:?}", v), String::from("Array"))), - }, - Vacant(entry) => { - entry.insert(AValue::JValueAccumulatorRef(RefCell::new(vec![result]))); + match output { + CallOutput::Scalar(name) => { + match exec_ctx.data_cache.entry(name.to_string()) { + Vacant(entry) => entry.insert(AValue::JValueRef(result)), + Occupied(entry) => return Err(MultipleVariablesFound(entry.key().clone())), + }; + } + CallOutput::Accumulator(name) => { + match exec_ctx.data_cache.entry(name.to_string()) { + Occupied(mut entry) => match entry.get_mut() { + // if result is an array, insert result to the end of the array + AValue::JValueAccumulatorRef(values) => values.borrow_mut().push(result), + v => return Err(IncompatibleAValueType(format!("{:?}", v), String::from("Array"))), + }, + Vacant(entry) => { + entry.insert(AValue::JValueAccumulatorRef(RefCell::new(vec![result]))); + } + }; } } Ok(()) } -pub(super) fn set_remote_call_result(peer_pk: String, exec_ctx: &mut ExecutionCtx, call_ctx: &mut CallEvidenceCtx) { +/// Writes evidence of a particle being sent to remote node +pub(super) fn set_remote_call_result<'i>( + peer_pk: String, + exec_ctx: &mut ExecutionCtx<'i>, + call_ctx: &mut CallEvidenceCtx, +) { exec_ctx.next_peer_pks.push(peer_pk); exec_ctx.subtree_complete = false; @@ -73,6 +79,7 @@ pub(super) fn set_remote_call_result(peer_pk: String, exec_ctx: &mut ExecutionCt call_ctx.new_path.push_back(new_evidence_state); } +/// Applies `json_path` to `jvalue` pub(super) fn find_by_json_path<'jvalue, 'json_path>( jvalue: &'jvalue JValue, json_path: &'json_path str, @@ -82,6 +89,86 @@ pub(super) fn find_by_json_path<'jvalue, 'json_path>( jsonpath_lib::select(jvalue, json_path).map_err(|e| JsonPathError(jvalue.clone(), String::from(json_path), e)) } -pub(super) fn is_string_literal(value: &str) -> bool { - value.starts_with('"') && value.ends_with('"') +/// Takes variable's value from `ExecutionCtx::data_cache` +/// TODO: maybe return &'i JValue? +pub(super) fn resolve_variable<'exec_ctx, 'i>(variable: &'i str, ctx: &'exec_ctx ExecutionCtx<'i>) -> Result { + use AquamarineError::VariableNotFound; + + let value = ctx + .data_cache + .get(variable) + .ok_or_else(|| VariableNotFound(variable.to_string()))?; + + match value { + AValue::JValueFoldCursor(fold_state) => { + if let JValue::Array(array) = fold_state.iterable.as_ref() { + Ok(array[fold_state.cursor].clone()) + } else { + unreachable!("fold state must be well-formed because it is changed only by stepper") + } + } + AValue::JValueRef(value) => Ok(value.as_ref().clone()), + AValue::JValueAccumulatorRef(acc) => { + let owned_acc = acc.borrow().iter().map(|v| v.as_ref()).cloned().collect::>(); + Ok(JValue::Array(owned_acc)) + } + } +} + +pub(super) fn apply_json_path<'i>(jvalue: JValue, json_path: &'i str) -> Result { + let values = find_by_json_path(&jvalue, json_path)?; + if values.is_empty() { + return Err(AquamarineError::VariableNotFound(json_path.to_string())); + } + + if values.len() != 1 { + return Err(AquamarineError::MultipleValuesInJsonPath(json_path.to_string())); + } + + // TODO: sure need this clone? + Ok(values[0].clone()) +} + +pub(super) fn require_string(value: JValue) -> Result { + if let JValue::String(s) = value { + Ok(s) + } else { + Err(AquamarineError::IncompatibleJValueType(value, "string".to_string())) + } +} + +/// Resolve value to string by either resolving variable from `ExecutionCtx`, taking literal value, or etc +pub(super) fn resolve_value<'i, 'a: 'i>(value: &'a Value<'i>, ctx: &'a ExecutionCtx<'i>) -> Result> { + let resolved = match value { + Value::CurrentPeerId => Cow::Borrowed(ctx.current_peer_id.as_str()), + Value::Literal(value) => Cow::Borrowed(*value), + Value::Variable(name) => { + let resolved = resolve_variable(name, ctx)?; + let resolved = require_string(resolved)?; + Cow::Owned(resolved) + } + Value::JsonPath { variable, path } => { + let resolved = resolve_variable(variable, ctx)?; + let resolved = apply_json_path(resolved, path)?; + let resolved = require_string(resolved)?; + Cow::Owned(resolved) + } + }; + + Ok(resolved) +} + +/// Resolve value to JValue, similar to `resolve_value` +pub(super) fn resolve_jvalue<'i>(value: &Value<'i>, ctx: &ExecutionCtx<'i>) -> Result { + let value = match value { + Value::CurrentPeerId => JValue::String(ctx.current_peer_id.clone()), + Value::Literal(value) => JValue::String(value.to_string()), + Value::Variable(name) => resolve_variable(name, ctx)?, + Value::JsonPath { variable, path } => { + let value = resolve_variable(variable, ctx)?; + apply_json_path(value, path)? + } + }; + + Ok(value) } diff --git a/stepper-lib/src/air/execution_context.rs b/stepper-lib/src/air/execution_context.rs index 36793bb6..3344e4b8 100644 --- a/stepper-lib/src/air/execution_context.rs +++ b/stepper-lib/src/air/execution_context.rs @@ -22,9 +22,9 @@ use std::fmt::Formatter; /// Execution context contains all necessary information needed to execute aqua script. #[derive(Clone, Default, Debug)] -pub(crate) struct ExecutionCtx { +pub(crate) struct ExecutionCtx<'i> { /// Contains all set variables. - pub data_cache: HashMap, + pub data_cache: HashMap>, /// Set of peer public keys that should receive resulted data. pub next_peer_pks: Vec, @@ -41,7 +41,7 @@ pub(crate) struct ExecutionCtx { pub subtree_complete: bool, } -impl ExecutionCtx { +impl<'i> ExecutionCtx<'i> { pub(crate) fn new(current_peer_id: String) -> Self { Self { data_cache: HashMap::new(), @@ -52,7 +52,7 @@ impl ExecutionCtx { } } -impl Display for ExecutionCtx { +impl<'i> Display for ExecutionCtx<'i> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { writeln!(f, "data cache:")?; for (key, value) in self.data_cache.iter() { diff --git a/stepper-lib/src/air/fold.rs b/stepper-lib/src/air/fold.rs index b176a7c4..0b2a0d61 100644 --- a/stepper-lib/src/air/fold.rs +++ b/stepper-lib/src/air/fold.rs @@ -23,8 +23,8 @@ use crate::AquamarineError; use crate::JValue; use crate::Result; -use serde_derive::Deserialize; -use serde_derive::Serialize; +use air_parser::ast::{Fold, Next}; + use std::rc::Rc; /* @@ -36,32 +36,22 @@ use std::rc::Rc; ) */ -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] -pub(crate) struct Fold(String, String, Rc); - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] -pub(crate) struct Next(String); - #[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct FoldState { +pub(crate) struct FoldState<'i> { // TODO: maybe change to bidirectional iterator pub(crate) cursor: usize, pub(crate) iterable: Rc, - pub(crate) instr_head: Rc, + pub(crate) instr_head: Rc>, } -impl super::ExecutableInstruction for Fold { - fn execute(&self, exec_ctx: &mut ExecutionCtx, call_ctx: &mut CallEvidenceCtx) -> Result<()> { +impl<'i> super::ExecutableInstruction<'i> for Fold<'i> { + fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx) -> Result<()> { use AquamarineError::*; log_instruction!(fold, exec_ctx, call_ctx); - let iterable_name = &self.0; - let iterator_name = &self.1; - let instr_head = self.2.clone(); - // check that value exists and has array type - let iterable = match exec_ctx.data_cache.get(iterable_name) { + let iterable = match exec_ctx.data_cache.get(self.iterable) { Some(AValue::JValueRef(jvalue_rc)) => { match jvalue_rc.as_ref() { JValue::Array(array) => { @@ -76,41 +66,41 @@ impl super::ExecutableInstruction for Fold { } } Some(v) => return Err(IncompatibleAValueType(format!("{:?}", v), String::from("JValueRef"))), - None => return Err(VariableNotFound(String::from(iterable_name))), + None => return Err(VariableNotFound(self.iterable.to_string())), }; let fold_state = FoldState { cursor: 0, iterable: iterable.clone(), - instr_head: instr_head.clone(), + instr_head: self.instruction.clone(), }; let previous_value = exec_ctx .data_cache - .insert(iterator_name.clone(), AValue::JValueFoldCursor(fold_state)); + .insert(self.iterator.to_string(), AValue::JValueFoldCursor(fold_state)); if previous_value.is_some() { - return Err(MultipleFoldStates(iterable_name.clone())); + return Err(MultipleFoldStates(self.iterable.to_string())); } - instr_head.execute(exec_ctx, call_ctx)?; - exec_ctx.data_cache.remove(iterator_name); + self.instruction.execute(exec_ctx, call_ctx)?; + exec_ctx.data_cache.remove(self.iterator); Ok(()) } } -impl super::ExecutableInstruction for Next { - fn execute(&self, exec_ctx: &mut ExecutionCtx, call_ctx: &mut CallEvidenceCtx) -> Result<()> { +impl<'i> super::ExecutableInstruction<'i> for Next<'i> { + fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx) -> Result<()> { use AquamarineError::IncompatibleAValueType; log_instruction!(next, exec_ctx, call_ctx); - let iterator_name = &self.0; + let iterator_name = self.0; let avalue = exec_ctx .data_cache .get_mut(iterator_name) - .ok_or_else(|| AquamarineError::FoldStateNotFound(iterator_name.clone()))?; + .ok_or_else(|| AquamarineError::FoldStateNotFound(iterator_name.to_string()))?; let fold_state = match avalue { AValue::JValueFoldCursor(state) => state, v => { @@ -172,15 +162,15 @@ mod tests { let lfold = String::from( r#" - (seq ( - (call ("set_variable" ("" "") () Iterable)) - (fold (Iterable i - (seq ( - (call ("A" ("" "") (i) acc[])) + (seq + (call "set_variable" ("" "") [] Iterable) + (fold Iterable i + (seq + (call "A" ("" "") [i] acc[]) (next i) - )) - )) - ))"#, + ) + ) + )"#, ); let res = call_vm!(set_variable_vm, "", lfold.clone(), "[]", "[]"); @@ -205,15 +195,15 @@ mod tests { let rfold = String::from( r#" - (seq ( - (call ("set_variable" ("" "") () Iterable)) - (fold (Iterable i - (seq ( + (seq + (call "set_variable" ("" "") [] Iterable) + (fold Iterable i + (seq (next i) - (call ("A" ("" "") (i) acc[])) - )) - )) - ))"#, + (call "A" ("" "") [i] acc[]) + ) + ) + )"#, ); let res = call_vm!(set_variable_vm, "", rfold.clone(), "[]", "[]"); @@ -238,23 +228,23 @@ mod tests { let script = String::from( r#" - (seq ( - (seq ( - (call ("set_variable" ("" "") () Iterable1)) - (call ("set_variable" ("" "") () Iterable2)) - )) - (fold (Iterable1 i - (seq ( - (fold (Iterable2 j - (seq ( - (call ("A" ("" "") (i) acc[])) + (seq + (seq + (call "set_variable" ("" "") [] Iterable1) + (call "set_variable" ("" "") [] Iterable2) + ) + (fold Iterable1 i + (seq + (fold Iterable2 j + (seq + (call "A" ("" "") [i] acc[]) (next j) - )) - )) + ) + ) (next i) - )) - )) - ))"#, + ) + ) + )"#, ); let res = call_vm!(set_variable_vm, "", script.clone(), "[]", "[]"); @@ -281,23 +271,23 @@ mod tests { let script = String::from( r#" - (seq ( - (seq ( - (call ("set_variable" ("" "") () Iterable1)) - (call ("set_variable" ("" "") () Iterable2)) - )) - (fold (Iterable1 i - (seq ( - (fold (Iterable2 i - (seq ( - (call ("A" ("" "") (i) acc[])) + (seq + (seq + (call "set_variable" ("" "") [] Iterable1) + (call "set_variable" ("" "") [] Iterable2) + ) + (fold Iterable1 i + (seq + (fold Iterable2 i + (seq + (call "A" ("" "") [i] acc[]) (next i) - )) - )) + ) + ) (next i) - )) - )) - ))"#, + ) + ) + )"#, ); let res = vm.call_with_prev_data("", script, "[]", "[]"); @@ -325,15 +315,15 @@ mod tests { let empty_fold = String::from( r#" - (seq ( - (call ("set_variable" ("" "") () Iterable)) - (fold (Iterable i - (seq ( - (call ("A" ("" "") (i) acc[])) + (seq + (call "set_variable" ("" "") [] Iterable) + (fold Iterable i + (seq + (call "A" ("" "") [i] acc[]) (next i) - )) - )) - ))"#, + ) + ) + )"#, ); let res = call_vm!(set_variable_vm, "", empty_fold.clone(), "[]", "[]"); diff --git a/stepper-lib/src/air/mod.rs b/stepper-lib/src/air/mod.rs index 922864ce..abf87e7a 100644 --- a/stepper-lib/src/air/mod.rs +++ b/stepper-lib/src/air/mod.rs @@ -29,43 +29,24 @@ pub(self) use crate::call_evidence::CallEvidenceCtx; pub(self) use crate::call_evidence::EvidenceState; use crate::Result; -use call::Call; -use fold::Fold; -use fold::Next; -use null::Null; -use par::Par; -use seq::Seq; -use xor::Xor; -use serde_derive::Deserialize; -use serde_derive::Serialize; +use air_parser::ast::Instruction; -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] -#[serde(rename_all = "kebab-case")] -pub(crate) enum Instruction { - Null(Null), - Call(Call), - Fold(Fold), - Next(Next), - Par(Par), - Seq(Seq), - Xor(Xor), +pub(crate) trait ExecutableInstruction<'i> { + fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx) -> Result<()>; } -pub(crate) trait ExecutableInstruction { - fn execute(&self, exec_ctx: &mut ExecutionCtx, call_ctx: &mut CallEvidenceCtx) -> Result<()>; -} - -impl ExecutableInstruction for Instruction { - fn execute(&self, exec_ctx: &mut ExecutionCtx, call_ctx: &mut CallEvidenceCtx) -> Result<()> { +impl<'i> ExecutableInstruction<'i> for Instruction<'i> { + fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx) -> Result<()> { match self { - Instruction::Null(null) => null.execute(exec_ctx, call_ctx), + Instruction::Seq(seq) => seq.execute(exec_ctx, call_ctx), Instruction::Call(call) => call.execute(exec_ctx, call_ctx), + Instruction::Null(null) => null.execute(exec_ctx, call_ctx), Instruction::Fold(fold) => fold.execute(exec_ctx, call_ctx), Instruction::Next(next) => next.execute(exec_ctx, call_ctx), Instruction::Par(par) => par.execute(exec_ctx, call_ctx), - Instruction::Seq(seq) => seq.execute(exec_ctx, call_ctx), Instruction::Xor(xor) => xor.execute(exec_ctx, call_ctx), + Instruction::Error => unreachable!("should not execute if parsing failed. QED."), } } } diff --git a/stepper-lib/src/air/null.rs b/stepper-lib/src/air/null.rs index 5b8c920d..2fbd2c71 100644 --- a/stepper-lib/src/air/null.rs +++ b/stepper-lib/src/air/null.rs @@ -19,14 +19,10 @@ use super::ExecutionCtx; use crate::log_instruction; use crate::Result; -use serde_derive::Deserialize; -use serde_derive::Serialize; +use air_parser::ast::Null; -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] -pub(crate) struct Null {} - -impl super::ExecutableInstruction for Null { - fn execute(&self, exec_ctx: &mut ExecutionCtx, call_ctx: &mut CallEvidenceCtx) -> Result<()> { +impl<'i> super::ExecutableInstruction<'i> for Null { + fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx) -> Result<()> { log_instruction!(null, exec_ctx, call_ctx); Ok(()) diff --git a/stepper-lib/src/air/par.rs b/stepper-lib/src/air/par.rs index 3d119bb8..b1ab5160 100644 --- a/stepper-lib/src/air/par.rs +++ b/stepper-lib/src/air/par.rs @@ -23,14 +23,10 @@ use crate::log_instruction; use crate::log_targets::EVIDENCE_CHANGING; use crate::Result; -use serde_derive::Deserialize; -use serde_derive::Serialize; +use air_parser::ast::Par; -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] -pub(crate) struct Par(Box, Box); - -impl ExecutableInstruction for Par { - fn execute(&self, exec_ctx: &mut ExecutionCtx, call_ctx: &mut CallEvidenceCtx) -> Result<()> { +impl<'i> ExecutableInstruction<'i> for Par<'i> { + fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx) -> Result<()> { log_instruction!(par, exec_ctx, call_ctx); let (left_subtree_size, right_subtree_size) = extract_subtree_sizes(call_ctx)?; @@ -87,10 +83,10 @@ fn extract_subtree_sizes(call_ctx: &mut CallEvidenceCtx) -> Result<(usize, usize } } -fn execute_subtree( - subtree: &Instruction, +fn execute_subtree<'i>( + subtree: &Instruction<'i>, subtree_size: usize, - exec_ctx: &mut ExecutionCtx, + exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx, ) -> Result { call_ctx.current_subtree_elements_count = subtree_size; @@ -104,14 +100,14 @@ fn execute_subtree( Ok(call_ctx.new_path.len() - before_states_count) } -fn determine_subtree_complete(next_instruction: &Instruction) -> bool { +fn determine_subtree_complete(next_instruction: &Instruction<'_>) -> bool { // this is needed to prevent situation when on such pattern // (fold (Iterable i - // (par ( - // (call (..)) + // (par + // (call ..) // (next i) - // )) - // )) + // ) + // ) // par will be executed after the last next that wouldn't change subtree_complete !matches!(next_instruction, Instruction::Next(_)) } @@ -130,10 +126,10 @@ mod tests { let script = String::from( r#" - (par ( - (call ("remote_peer_id_1" ("local_service_id" "local_fn_name") () result_name)) - (call ("remote_peer_id_2" ("service_id" "fn_name") () g)) - ))"#, + (par + (call "remote_peer_id_1" ("local_service_id" "local_fn_name") [] result_name) + (call "remote_peer_id_2" ("service_id" "fn_name") [] g) + )"#, ); let mut res = call_vm!(vm, "", script, "[]", "[]"); @@ -151,10 +147,10 @@ mod tests { let script = String::from( r#" - (par ( - (call (%current_peer_id% ("local_service_id" "local_fn_name") () result_name)) - (call ("remote_peer_id_2" ("service_id" "fn_name") () g)) - ))"#, + (par + (call %current_peer_id% ("local_service_id" "local_fn_name") [] result_name) + (call "remote_peer_id_2" ("service_id" "fn_name") [] g) + )"#, ); let res = call_vm!(vm, "", script, "[]", "[]"); diff --git a/stepper-lib/src/air/seq.rs b/stepper-lib/src/air/seq.rs index da8ad845..c5f70eaf 100644 --- a/stepper-lib/src/air/seq.rs +++ b/stepper-lib/src/air/seq.rs @@ -16,18 +16,13 @@ use super::CallEvidenceCtx; use super::ExecutionCtx; -use super::Instruction; use crate::log_instruction; use crate::Result; -use serde_derive::Deserialize; -use serde_derive::Serialize; +use air_parser::ast::Seq; -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] -pub(crate) struct Seq(Box, Box); - -impl super::ExecutableInstruction for Seq { - fn execute(&self, exec_ctx: &mut ExecutionCtx, call_ctx: &mut CallEvidenceCtx) -> Result<()> { +impl<'i> super::ExecutableInstruction<'i> for Seq<'i> { + fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx) -> Result<()> { log_instruction!(seq, exec_ctx, call_ctx); exec_ctx.subtree_complete = true; @@ -55,10 +50,10 @@ mod tests { let script = String::from( r#" - (seq ( - (call ("remote_peer_id_1" ("local_service_id" "local_fn_name") () result_name)) - (call ("remote_peer_id_2" ("service_id" "fn_name") () g)) - ))"#, + (seq + (call "remote_peer_id_1" ("local_service_id" "local_fn_name") [] result_name) + (call "remote_peer_id_2" ("service_id" "fn_name") [] g) + )"#, ); let res = call_vm!(vm, "asd", script.clone(), "[]", "[]"); @@ -74,10 +69,10 @@ mod tests { let script = String::from( r#" - (seq ( - (call (%current_peer_id% ("local_service_id" "local_fn_name") () result_name)) - (call ("remote_peer_id_2" ("service_id" "fn_name") () g)) - ))"#, + (seq + (call %current_peer_id% ("local_service_id" "local_fn_name") [] result_name) + (call "remote_peer_id_2" ("service_id" "fn_name") [] g) + )"#, ); let res = call_vm!(vm, "asd", script, "[]", "[]"); diff --git a/stepper-lib/src/air/xor.rs b/stepper-lib/src/air/xor.rs index 4cbc0efd..311ca017 100644 --- a/stepper-lib/src/air/xor.rs +++ b/stepper-lib/src/air/xor.rs @@ -16,19 +16,14 @@ use super::CallEvidenceCtx; use super::ExecutionCtx; -use super::Instruction; use crate::log_instruction; use crate::AquamarineError::LocalServiceError; use crate::Result; -use serde_derive::Deserialize; -use serde_derive::Serialize; +use air_parser::ast::Xor; -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] -pub(crate) struct Xor(Box, Box); - -impl super::ExecutableInstruction for Xor { - fn execute(&self, exec_ctx: &mut ExecutionCtx, call_ctx: &mut CallEvidenceCtx) -> Result<()> { +impl<'i> super::ExecutableInstruction<'i> for Xor<'i> { + fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx) -> Result<()> { log_instruction!(xor, exec_ctx, call_ctx); exec_ctx.subtree_complete = true; @@ -83,10 +78,10 @@ mod tests { let script = String::from( r#" - (xor ( - (call (%current_peer_id% ("service_id_1" "local_fn_name") () result_1)) - (call (%current_peer_id% ("service_id_2" "local_fn_name") () result_2)) - ))"#, + (xor + (call %current_peer_id% ("service_id_1" "local_fn_name") [] result_1) + (call %current_peer_id% ("service_id_2" "local_fn_name") [] result_2) + )"#, ); let res = call_vm!(vm, "asd", script, "[]", "[]"); @@ -101,10 +96,10 @@ mod tests { let script = String::from( r#" - (xor ( - (call (%current_peer_id% ("service_id_2" "local_fn_name") () result_1)) - (call (%current_peer_id% ("service_id_1" "local_fn_name") () result_2)) - ))"#, + (xor + (call %current_peer_id% ("service_id_2" "local_fn_name") [] result_1) + (call %current_peer_id% ("service_id_1" "local_fn_name") [] result_2) + )"#, ); let res = call_vm!(vm, "asd", script, "[]", "[]"); diff --git a/stepper-lib/src/errors.rs b/stepper-lib/src/errors.rs index 2c10cd63..dd4bab09 100644 --- a/stepper-lib/src/errors.rs +++ b/stepper-lib/src/errors.rs @@ -22,7 +22,6 @@ use crate::StepperOutcome; use jsonpath_lib::JsonPathError; use serde_json::Error as SerdeJsonError; -use serde_sexpr::Error as SExprError; use std::convert::Into; use std::env::VarError; @@ -30,8 +29,8 @@ use std::error::Error; #[derive(Debug)] pub enum AquamarineError { - /// Errors occurred while parsing aqua script in the form of S expressions. - SExprParseError(SExprError), + /// Error occurred while parsing AIR script + AIRParseError(String), /// Errors occurred while parsing function arguments of an expression. FuncArgsSerializationError(JValue, SerdeJsonError), @@ -76,7 +75,7 @@ pub enum AquamarineError { InvalidEvidenceState(EvidenceState, String), /// Errors occurred on call evidence deserialization. - CallEvidenceDeserializationError(SerdeJsonError), + CallEvidenceDeserializationError(SerdeJsonError, String), /// Errors occurred on call evidence serialization. CallEvidenceSerializationError(SerdeJsonError), @@ -96,7 +95,7 @@ impl Error for AquamarineError {} impl std::fmt::Display for AquamarineError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { match self { - AquamarineError::SExprParseError(err) => write!(f, "aqua script can't be parsed: {:?}", err), + AquamarineError::AIRParseError(err) => write!(f, "aqua script can't be parsed:\n{}", err), AquamarineError::FuncArgsSerializationError(args, err) => write!( f, "function arguments {} can't be serialized or deserialized with an error: {:?}", @@ -145,9 +144,11 @@ impl std::fmt::Display for AquamarineError { "invalid evidence state: expected {}, but found {:?}", expected, found ), - AquamarineError::CallEvidenceDeserializationError(err) => { - write!(f, "an error occurred while data deserialization: {:?}", err) - } + AquamarineError::CallEvidenceDeserializationError(err, path) => write!( + f, + "an error occurred while call evidence path deserialization on {:?}: {:?}", + path, err + ), AquamarineError::CallEvidenceSerializationError(err) => { write!(f, "an error occurred while data serialization: {:?}", err) } @@ -170,12 +171,6 @@ impl std::fmt::Display for AquamarineError { } } -impl From for AquamarineError { - fn from(err: SExprError) -> Self { - AquamarineError::SExprParseError(err) - } -} - impl From for AquamarineError { fn from(_: std::convert::Infallible) -> Self { unreachable!() @@ -185,7 +180,7 @@ impl From for AquamarineError { impl Into for AquamarineError { fn into(self) -> StepperOutcome { let ret_code = match self { - AquamarineError::SExprParseError(_) => 1, + AquamarineError::AIRParseError(_) => 1, AquamarineError::FuncArgsSerializationError(..) => 2, AquamarineError::CallServiceResultDeserializationError(..) => 3, AquamarineError::CurrentPeerIdEnvError(..) => 4, diff --git a/stepper-lib/src/execution.rs b/stepper-lib/src/execution.rs index c275e01c..1f0496fd 100644 --- a/stepper-lib/src/execution.rs +++ b/stepper-lib/src/execution.rs @@ -38,7 +38,7 @@ pub fn execute_aqua(init_user_id: String, aqua: String, prev_data: String, data: } fn execute_aqua_impl(_init_user_id: String, aqua: String, prev_path: String, path: String) -> Result { - let (prev_path, path, aqua) = prepare(prev_path, path, aqua)?; + let (prev_path, path, aqua) = prepare(prev_path, path, aqua.as_str())?; let (mut exec_ctx, mut call_ctx) = make_contexts(prev_path, path)?; aqua.execute(&mut exec_ctx, &mut call_ctx)?; diff --git a/stepper-lib/src/execution/prolog.rs b/stepper-lib/src/execution/prolog.rs index 6af2935d..fd26a7d6 100644 --- a/stepper-lib/src/execution/prolog.rs +++ b/stepper-lib/src/execution/prolog.rs @@ -14,9 +14,7 @@ * limitations under the License. */ -use super::utils::format_aqua; use crate::air::ExecutionCtx; -use crate::air::Instruction; use crate::call_evidence::merge_call_paths; use crate::call_evidence::CallEvidenceCtx; use crate::get_current_peer_id; @@ -25,19 +23,21 @@ use crate::AquamarineError; use crate::CallEvidencePath; use crate::Result; +use air_parser::ast::Instruction; + /// Parse and prepare supplied data and aqua script. -pub(super) fn prepare( +pub(super) fn prepare<'i>( raw_prev_path: String, raw_path: String, - raw_aqua: String, -) -> Result<(CallEvidencePath, CallEvidencePath, Instruction)> { + raw_aqua: &'i str, +) -> Result<(CallEvidencePath, CallEvidencePath, Instruction<'i>)> { use AquamarineError::CallEvidenceDeserializationError as CallDeError; - let prev_path: CallEvidencePath = serde_json::from_str(&raw_prev_path).map_err(CallDeError)?; - let path: CallEvidencePath = serde_json::from_str(&raw_path).map_err(CallDeError)?; + let prev_path: CallEvidencePath = + serde_json::from_str(&raw_prev_path).map_err(|err| CallDeError(err, raw_prev_path))?; + let path: CallEvidencePath = serde_json::from_str(&raw_path).map_err(|err| CallDeError(err, raw_path))?; - let formatted_aqua = format_aqua(raw_aqua); - let aqua: Instruction = serde_sexpr::from_str(&formatted_aqua)?; + let aqua: Instruction<'i> = *air_parser::parse(raw_aqua).map_err(|msg| AquamarineError::AIRParseError(msg))?; log::info!( target: RUN_PARAMS, @@ -55,7 +55,7 @@ pub(super) fn prepare( pub(super) fn make_contexts( prev_path: CallEvidencePath, path: CallEvidencePath, -) -> Result<(ExecutionCtx, CallEvidenceCtx)> { +) -> Result<(ExecutionCtx<'static>, CallEvidenceCtx)> { use AquamarineError::CurrentPeerIdEnvError as EnvError; let current_peer_id = get_current_peer_id().map_err(|e| EnvError(e, String::from("CURRENT_PEER_ID")))?; diff --git a/stepper-lib/src/execution/utils.rs b/stepper-lib/src/execution/utils.rs index 042833b5..cb0ef5f6 100644 --- a/stepper-lib/src/execution/utils.rs +++ b/stepper-lib/src/execution/utils.rs @@ -16,36 +16,6 @@ use std::hash::Hash; -/// Formats aqua script in a form of S-expressions to a form compatible with the serde_sexpr crate. -pub(super) fn format_aqua(aqua: String) -> String { - use std::iter::FromIterator; - - let mut formatted_aqua = Vec::with_capacity(aqua.len()); - // whether to skip the next whitespace - let mut skip_next_whitespace = false; - // whether c was a closing brace - let mut was_cbr = false; - - for c in aqua.chars() { - let is_whitespace = c == ' '; - if (skip_next_whitespace && is_whitespace) || c == '\n' { - continue; - } - - let is_cbr = c == ')'; - - skip_next_whitespace = is_whitespace || c == '(' || is_cbr; - if was_cbr && !is_cbr { - formatted_aqua.push(' '); - } - - was_cbr = is_cbr; - formatted_aqua.push(c) - } - - String::from_iter(formatted_aqua.into_iter()) -} - /// Deduplicate values in a supplied vector. pub(super) fn dedup(mut vec: Vec) -> Vec { use std::collections::HashSet; @@ -53,28 +23,3 @@ pub(super) fn dedup(mut vec: Vec) -> Vec { let set: HashSet<_> = vec.drain(..).collect(); set.into_iter().collect() } - -#[cfg(test)] -mod tests { - #[test] - fn format_aqua_test() { - let aqua = format!( - r#"(( (( (seq ( - (call (%current_peer_id% (add_module ||) (module) module)) - (seq ( - (call (%current_peer_id% (add_blueprint ||) (blueprint) blueprint_id)) - (seq ( - (call (%current_peer_id% (create ||) (blueprint_id) service_id)) - (call ({} (|| ||) (service_id) client_result)) - ) ) - ) ) - ))"#, - "abc" - ); - - let aqua = super::format_aqua(aqua); - let formatted_aqua = String::from("(((((seq ((call (%current_peer_id% (add_module ||) (module) module)) (seq ((call (%current_peer_id% (add_blueprint ||) (blueprint) blueprint_id)) (seq ((call (%current_peer_id% (create ||) (blueprint_id) service_id)) (call (abc (|| ||) (service_id) client_result))))))))"); - - assert_eq!(aqua, formatted_aqua); - } -} diff --git a/stepper-lib/src/lib.rs b/stepper-lib/src/lib.rs index 451c6f05..1888a1c8 100644 --- a/stepper-lib/src/lib.rs +++ b/stepper-lib/src/lib.rs @@ -54,13 +54,13 @@ use std::fmt::Formatter; use std::rc::Rc; #[derive(Debug, Clone, Eq, PartialEq)] -pub(crate) enum AValue { +pub(crate) enum AValue<'i> { JValueRef(Rc), JValueAccumulatorRef(RefCell>>), - JValueFoldCursor(crate::air::FoldState), + JValueFoldCursor(crate::air::FoldState<'i>), } -impl Display for AValue { +impl<'i> Display for AValue<'i> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { AValue::JValueRef(value) => write!(f, "{:?}", value)?, diff --git a/stepper-lib/tests/air_basic.rs b/stepper-lib/tests/air_basic.rs index 68fcc948..7ccb350d 100644 --- a/stepper-lib/tests/air_basic.rs +++ b/stepper-lib/tests/air_basic.rs @@ -38,13 +38,13 @@ fn seq_par_call() { let script = String::from( r#" - (seq ( - (par ( - (call (%current_peer_id% ("local_service_id" "local_fn_name") () result_1)) - (call ("remote_peer_id" ("service_id" "fn_name") () g)) - )) - (call (%current_peer_id% ("local_service_id" "local_fn_name") () result_2)) - ))"#, + (seq + (par + (call %current_peer_id% ("local_service_id" "local_fn_name") [] result_1) + (call "remote_peer_id" ("service_id" "fn_name") [] g) + ) + (call %current_peer_id% ("local_service_id" "local_fn_name") [] result_2) + )"#, ); let res = call_vm!(vm, "asd", script, "[]", "[]"); @@ -72,13 +72,13 @@ fn par_par_call() { let script = String::from( r#" - (par ( - (par ( - (call (%current_peer_id% ("local_service_id" "local_fn_name") () result_1)) - (call ("remote_peer_id" ("service_id" "fn_name") () g)) - )) - (call (%current_peer_id% ("local_service_id" "local_fn_name") () result_2)) - ))"#, + (par + (par + (call %current_peer_id% ("local_service_id" "local_fn_name") [] result_1) + (call "remote_peer_id" ("service_id" "fn_name") [] g) + ) + (call %current_peer_id% ("local_service_id" "local_fn_name") [] result_2) + )"#, ); let res = call_vm!(vm, "asd", script, "[]", "[]"); @@ -153,25 +153,25 @@ fn create_service() { let script = String::from( r#" - (seq ( - (seq ( - (seq ( - (call ("set_variables" ("" "") ("module_bytes") module_bytes)) - (call ("set_variables" ("" "") ("module_config") module_config)) - )) - (call ("set_variables" ("" "") ("blueprint") blueprint)) - )) - (seq ( - (call ("A" ("add_module" "") (module_bytes module_config) module)) - (seq ( - (call ("A" ("add_blueprint" "") (blueprint) blueprint_id)) - (seq ( - (call ("A" ("create" "") (blueprint_id) service_id)) - (call ("remote_peer_id" ("" "") (service_id) client_result)) - )) - )) - )) - ))"#, + (seq + (seq + (seq + (call "set_variables" ("" "") ["module_bytes"] module_bytes) + (call "set_variables" ("" "") ["module_config"] module_config) + ) + (call "set_variables" ("" "") ["blueprint"] blueprint) + ) + (seq + (call "A" ("add_module" "") [module_bytes module_config] module) + (seq + (call "A" ("add_blueprint" "") [blueprint] blueprint_id) + (seq + (call "A" ("create" "") [blueprint_id] service_id) + (call "remote_peer_id" ("" "") [service_id] client_result) + ) + ) + ) + )"#, ); let res = call_vm!(set_variables_vm, "init_user_id", script.clone(), "[]", "[]"); diff --git a/stepper-lib/tests/call_evidence_basic.rs b/stepper-lib/tests/call_evidence_basic.rs index 1c30fa11..fd4e938e 100644 --- a/stepper-lib/tests/call_evidence_basic.rs +++ b/stepper-lib/tests/call_evidence_basic.rs @@ -37,13 +37,13 @@ fn evidence_seq_par_call() { let script = String::from( r#" - (seq ( - (par ( - (call (%current_peer_id% ("local_service_id" "local_fn_name") () result_1)) - (call ("remote_peer_id" ("service_id" "fn_name") () g)) - )) - (call (%current_peer_id% ("local_service_id" "local_fn_name") () result_2)) - ))"#, + (seq + (par + (call %current_peer_id% ("local_service_id" "local_fn_name") [] result_1) + (call "remote_peer_id" ("service_id" "fn_name") [] g) + ) + (call %current_peer_id% ("local_service_id" "local_fn_name") [] result_2) + )"#, ); let initial_state = json!([ @@ -77,13 +77,13 @@ fn evidence_par_par_call() { let script = String::from( r#" - (par ( - (par ( - (call ("some_peer_id" ("local_service_id" "local_fn_name") () result_1)) - (call ("remote_peer_id" ("service_id" "fn_name") () g)) - )) - (call (%current_peer_id% ("local_service_id" "local_fn_name") () result_2)) - ))"#, + (par + (par + (call "some_peer_id" ("local_service_id" "local_fn_name") [] result_1) + (call "remote_peer_id" ("service_id" "fn_name") [] g) + ) + (call %current_peer_id% ("local_service_id" "local_fn_name") [] result_2) + )"#, ); let initial_state = json!([ @@ -122,13 +122,13 @@ fn evidence_seq_seq() { let script = format!( r#" - (seq ( - (call ("{}" ("identity" "") () void0)) - (seq ( - (call ("{}" ("add_blueprint" "") () blueprint_id)) - (call ("{}" ("addBlueprint-14d8488e-d10d-474d-96b2-878f6a7d74c8" "") () void1)) - )) - )) + (seq + (call "{}" ("identity" "") [] void0) + (seq + (call "{}" ("add_blueprint" "") [] blueprint_id) + (call "{}" ("addBlueprint-14d8488e-d10d-474d-96b2-878f6a7d74c8" "") [] void1) + ) + ) "#, peer_id_1, peer_id_1, peer_id_2 ); @@ -201,25 +201,25 @@ fn evidence_create_service() { let script = String::from( r#" - (seq ( - (seq ( - (seq ( - (call ("set_variables" ("add_module" "") ("module_bytes") module_bytes)) - (call ("set_variables" ("add_module" "") ("module_config") module_config)) - )) - (call ("set_variables" ("add_module" "") ("blueprint") blueprint)) - )) - (seq ( - (call ("A" ("add_module" "") (module_bytes module_config) module)) - (seq ( - (call ("A" ("add_blueprint" "") (blueprint) blueprint_id)) - (seq ( - (call ("A" ("create" "") (blueprint_id) service_id)) - (call ("remote_peer_id" ("" "") (service_id) client_result)) - )) - )) - )) - ))"#, + (seq + (seq + (seq + (call "set_variables" ("add_module" "") ["module_bytes"] module_bytes) + (call "set_variables" ("add_module" "") ["module_config"] module_config) + ) + (call "set_variables" ("add_module" "") ["blueprint"] blueprint) + ) + (seq + (call "A" ("add_module" "") [module_bytes module_config] module) + (seq + (call "A" ("add_blueprint" "") [blueprint] blueprint_id) + (seq + (call "A" ("create" "") [blueprint_id] service_id) + (call "remote_peer_id" ("" "") [service_id] client_result) + ) + ) + ) + )"#, ); let add_module_response = String::from("add_module response"); @@ -263,18 +263,18 @@ fn evidence_par_seq_fold_call() { let script = String::from( r#" - (par ( - (seq ( - (call ("some_peer_id_1" ("local_service_id" "local_fn_name") () IterableResultPeer1)) - (fold (IterableResultPeer1 i - (par ( - (call ("some_peer_id_2" ("local_service_id" "local_fn_name") (i) acc[])) + (par + (seq + (call "some_peer_id_1" ("local_service_id" "local_fn_name") [] IterableResultPeer1) + (fold IterableResultPeer1 i + (par + (call "some_peer_id_2" ("local_service_id" "local_fn_name") [i] acc[]) (next i) - )) - )) - )) - (call ("some_peer_id_3" ("local_service_id" "local_fn_name") () result_2)) - ))"#, + ) + ) + ) + (call "some_peer_id_3" ("local_service_id" "local_fn_name") [] result_2) + )"#, ); let res = call_vm!(vm2, "asd", script.clone(), "[]", "[]"); @@ -339,18 +339,18 @@ fn evidence_par_seq_fold_in_cycle_call() { let script = String::from( r#" - (par ( - (seq ( - (call ("some_peer_id_1" ("local_service_id" "local_fn_name") () IterableResultPeer1)) - (fold (IterableResultPeer1 i - (par ( - (call ("some_peer_id_2" ("local_service_id" "local_fn_name") (i) acc[])) + (par + (seq + (call "some_peer_id_1" ("local_service_id" "local_fn_name") [] IterableResultPeer1) + (fold IterableResultPeer1 i + (par + (call "some_peer_id_2" ("local_service_id" "local_fn_name") [i] acc[]) (next i) - )) - )) - )) - (call ("some_peer_id_3" ("local_service_id" "local_fn_name") () result_2)) - ))"#, + ) + ) + ) + (call "some_peer_id_3" ("local_service_id" "local_fn_name") [] result_2) + )"#, ); let mut data = String::from("[]"); @@ -401,19 +401,19 @@ fn evidence_seq_par_seq_seq() { let mut vm2 = create_aqua_vm(unit_call_service(), peer_id_2.clone()); let script = format!( r#" - (seq ( - (par ( - (seq ( - (call ("{}" ("" "") () result_1)) - (call ("{}" ("" "") () result_2)) - )) - (seq ( - (call ("{}" ("" "") () result_3)) - (call ("{}" ("" "") () result_4)) - )) - )) - (call ("{}" ("" "") () result_5)) - )) + (seq + (par + (seq + (call "{}" ("" "") [] result_1) + (call "{}" ("" "") [] result_2) + ) + (seq + (call "{}" ("" "") [] result_3) + (call "{}" ("" "") [] result_4) + ) + ) + (call "{}" ("" "") [] result_5) + ) "#, peer_id_1, peer_id_2, peer_id_2, peer_id_1, peer_id_2 ); diff --git a/stepper-lib/tests/data_merge.rs b/stepper-lib/tests/data_merge.rs index ac9590b5..1d1039e8 100644 --- a/stepper-lib/tests/data_merge.rs +++ b/stepper-lib/tests/data_merge.rs @@ -45,29 +45,29 @@ fn data_merge() { let script = String::from( r#" - (seq ( - (call (%current_peer_id% ("neighborhood" "") () neighborhood)) - (seq ( - (seq ( - (fold (neighborhood i - (par ( - (call (i ("add_provider" "") () void[])) + (seq + (call %current_peer_id% ("neighborhood" "") [] neighborhood) + (seq + (seq + (fold neighborhood i + (par + (call i ("add_provider" "") [] void[]) (next i) - )) - )) - (fold (neighborhood i - (par ( - (call (i ("get_providers" "") () providers[])) + ) + ) + (fold neighborhood i + (par + (call i ("get_providers" "") [] providers[]) (next i) - )) - )) - )) - (seq ( - (call ("A" ("identity" "") () void[])) - (call ("B" ("" "") () none)) - )) - )) - )) + ) + ) + ) + (seq + (call "A" ("identity" "") [] void[]) + (call "B" ("" "") [] none) + ) + ) + ) "#, ); @@ -187,22 +187,22 @@ fn acc_merge() { let script = String::from( r#" - (seq ( - (call ("A" ("add_provider" "") () void[])) - (seq ( - (call ("A" ("add_provider" "") () void[])) - (seq ( - (call ("A" ("get_providers" "") () providers[])) - (seq ( - (call ("A" ("get_providers" "") () providers[])) - (seq ( - (call ("B" ("" "2") (providers) void[])) - (call ("B" ("" "3") (void) void[])) - )) - )) - )) - )) - )) + (seq + (call "A" ("add_provider" "") [] void[]) + (seq + (call "A" ("add_provider" "") [] void[]) + (seq + (call "A" ("get_providers" "") [] providers[]) + (seq + (call "A" ("get_providers" "") [] providers[]) + (seq + (call "B" ("" "2") [providers] void[]) + (call "B" ("" "3") [void] void[]) + ) + ) + ) + ) + ) "#, ); diff --git a/stepper-lib/tests/join.rs b/stepper-lib/tests/join.rs index 7cb77450..66d20d01 100644 --- a/stepper-lib/tests/join.rs +++ b/stepper-lib/tests/join.rs @@ -48,24 +48,24 @@ fn join_chat() { let script = String::from( r#" - (seq ( - (call ("Relay1" ("identity" "") () void1[])) - (seq ( - (call ("Remote" ("552196ea-b9b2-4761-98d4-8e7dba77fac4" "add") () void2[])) - (seq ( - (call ("Remote" ("920e3ba3-cbdf-4ae3-8972-0fa2f31fffd9" "get_users") () members)) - (fold (members m - (par ( - (seq ( - (call (m.$.[1] ("identity" "") () void[])) - (call (m.$.[0] ("fgemb3" "add") () void3[])) - )) + (seq + (call "Relay1" ("identity" "") [] void1[]) + (seq + (call "Remote" ("552196ea-b9b2-4761-98d4-8e7dba77fac4" "add") [] void2[]) + (seq + (call "Remote" ("920e3ba3-cbdf-4ae3-8972-0fa2f31fffd9" "get_users") [] members) + (fold members m + (par + (seq + (call m.$.[1] ("identity" "") [] void[]) + (call m.$.[0] ("fgemb3" "add") [] void3[]) + ) (next m) - )) - )) - )) - )) - )) + ) + ) + ) + ) + ) "#, ); @@ -202,21 +202,21 @@ fn join() { let script = String::from( r#" - (seq ( - (call ("Relay1" ("identity" "") () void1[])) - (seq ( - (call ("Remote" ("920e3ba3-cbdf-4ae3-8972-0fa2f31fffd9" "get_users") () members)) - (fold (members m - (par ( - (seq ( - (call ("Relay1" ("identity" "") () void[])) - (call ("A" ("fgemb3" "add") (m) void3[])) - )) - (next m) - )) - )) - )) - )) + (seq + (call "Relay1" ("identity" "") [] void1[]) + (seq + (call "Remote" ("920e3ba3-cbdf-4ae3-8972-0fa2f31fffd9" "get_users") [] members) + (fold members m + (par + (seq + (call "Relay1" ("identity" "") [] void[]) + (call "A" ("fgemb3" "add") [m] void3[]) + ) + (next m) + ) + ) + ) + ) "#, );