From 13f93a0f880139834638bd99ce62cdc75cac1f5b Mon Sep 17 00:00:00 2001 From: vms Date: Thu, 18 Feb 2021 17:30:14 +0300 Subject: [PATCH] Improve flattening (#69) --- Cargo.lock | 71 +- crates/air-parser/Cargo.toml | 2 +- crates/air-parser/src/parser/air.lalrpop | 31 +- crates/air-parser/src/parser/air.rs | 1046 ++++++++++------- crates/air-parser/src/parser/air_parser.rs | 29 + crates/air-parser/src/parser/ast.rs | 24 +- crates/air-parser/src/parser/ast/traits.rs | 35 +- .../src/parser/lexer/call_variable_parser.rs | 20 +- crates/air-parser/src/parser/lexer/errors.rs | 3 + crates/air-parser/src/parser/lexer/tests.rs | 24 +- crates/air-parser/src/parser/lexer/token.rs | 2 +- crates/air-parser/src/parser/lexer/utils.rs | 1 - crates/air-parser/src/parser/mod.rs | 4 - crates/air-parser/src/parser/tests.rs | 34 +- interpreter-lib/Cargo.toml | 4 +- .../src/execution/air/call/triplet.rs | 9 +- .../compare_matchable/compare_matchable.rs | 41 +- .../src/execution/air/fold/utils.rs | 56 +- interpreter-lib/src/execution/air/mod.rs | 1 - interpreter-lib/src/execution/errors.rs | 5 + .../src/execution/utils/resolve.rs | 20 +- interpreter-lib/tests/flattening.rs | 209 ++++ interpreter-lib/tests/join.rs | 4 +- interpreter/Cargo.toml | 2 +- 24 files changed, 1137 insertions(+), 540 deletions(-) create mode 100644 interpreter-lib/tests/flattening.rs diff --git a/Cargo.lock b/Cargo.lock index bfae44e5..3adfc76d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,7 +11,7 @@ dependencies = [ [[package]] name = "air-parser" -version = "0.4.0" +version = "0.5.0" dependencies = [ "codespan", "codespan-reporting", @@ -79,7 +79,7 @@ dependencies = [ [[package]] name = "aquamarine" -version = "0.6.0" +version = "0.7.0" dependencies = [ "fluence", "interpreter-lib", @@ -240,9 +240,9 @@ checksum = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9" [[package]] name = "bstr" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "473fc6b38233f9af7baa94fb5852dca389e3d95b8e21c8e3719301462c5d9faf" +checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" dependencies = [ "lazy_static", "memchr", @@ -252,9 +252,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.5.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f07aa6688c702439a1be0307b6a94dffe1168569e45b9500c1372bc580740d59" +checksum = "099e596ef14349721d9016f6b80dd3419ea1bf289ab9b44df8e4dfd3a005d5d9" [[package]] name = "byte-tools" @@ -528,9 +528,9 @@ dependencies = [ [[package]] name = "ctor" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10bcb9d7dcbf7002aaffbb53eac22906b64cdcc127971dcc387d8eb7c95d5560" +checksum = "e8f45d9ad417bcef4817d614a501ab55cdd96a6fdb24f49aab89a54acfd66b19" dependencies = [ "quote", "syn", @@ -976,7 +976,7 @@ checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.10.1+wasi-snapshot-preview1", + "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] @@ -1073,7 +1073,7 @@ dependencies = [ [[package]] name = "interpreter-lib" -version = "0.6.0" +version = "0.7.0" dependencies = [ "air-parser", "aqua-interpreter-interface 0.3.1", @@ -1159,9 +1159,9 @@ dependencies = [ [[package]] name = "jsonpath_lib-fl" -version = "0.2.6" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243653439f0992adf0bbf6ed5b798966fdbacd417b9dcb025b50200ec20c17ff" +checksum = "e81233a3c2e1f4579f1fdb856eeec115dcb23817374268212ebad691bd53e664" dependencies = [ "array_tool", "env_logger", @@ -1216,22 +1216,22 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" [[package]] name = "lexical-core" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db65c6da02e61f55dae90a0ae427b2a5f6b3e8db09f58d10efab23af92592616" +checksum = "21f866863575d0e1d654fbeeabdc927292fdf862873dc3c96c6f753357e13374" dependencies = [ "arrayvec", "bitflags", - "cfg-if 0.1.10", + "cfg-if 1.0.0", "ryu", "static_assertions", ] [[package]] name = "libc" -version = "0.2.83" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0c4e9c72ee9d69b767adebc5f4788462a3b45624acd919475c92597bcaf4f" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" [[package]] name = "lock_api" @@ -1416,7 +1416,7 @@ checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" dependencies = [ "instant", "lock_api 0.4.2", - "parking_lot_core 0.8.2", + "parking_lot_core 0.8.3", ] [[package]] @@ -1428,21 +1428,21 @@ dependencies = [ "cfg-if 0.1.10", "cloudabi", "libc", - "redox_syscall", + "redox_syscall 0.1.57", "smallvec", "winapi", ] [[package]] name = "parking_lot_core" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ccb628cad4f84851442432c60ad8e1f607e29752d0bf072cbd0baf28aa34272" +checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" dependencies = [ "cfg-if 1.0.0", "instant", "libc", - "redox_syscall", + "redox_syscall 0.2.5", "smallvec", "winapi", ] @@ -1554,9 +1554,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ "proc-macro2", ] @@ -1603,6 +1603,15 @@ version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +[[package]] +name = "redox_syscall" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" version = "0.3.5" @@ -1610,7 +1619,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" dependencies = [ "getrandom 0.1.16", - "redox_syscall", + "redox_syscall 0.1.57", "rust-argon2", ] @@ -1670,9 +1679,9 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "safe-transmute" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b8b2cd387f744f69469aaed197954ba4c0ecdb31e02edf99b023e0df11178a" +checksum = "1d95e7284b4bd97e24af76023904cd0157c9cc9da0310beb4139a1e88a748d47" [[package]] name = "same-file" @@ -1888,9 +1897,9 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8208a331e1cb318dd5bd76951d2b8fc48ca38a69f5f4e4af1b6a9f8c6236915" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" dependencies = [ "once_cell", ] @@ -2038,9 +2047,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.10.1+wasi-snapshot-preview1" +version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93c6c3420963c5c64bca373b25e77acb562081b9bb4dd5bb864187742186cea9" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" diff --git a/crates/air-parser/Cargo.toml b/crates/air-parser/Cargo.toml index 0e519091..ca7f76be 100644 --- a/crates/air-parser/Cargo.toml +++ b/crates/air-parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "air-parser" -version = "0.4.0" +version = "0.5.0" authors = ["Fluence Labs"] edition = "2018" license = "Apache-2.0" diff --git a/crates/air-parser/src/parser/air.lalrpop b/crates/air-parser/src/parser/air.lalrpop index d2cac464..0e206a70 100644 --- a/crates/air-parser/src/parser/air.lalrpop +++ b/crates/air-parser/src/parser/air.lalrpop @@ -1,5 +1,6 @@ use crate::parser::ast::*; -use crate::parser::into_variable_and_path; +use crate::parser::air_parser::into_variable_and_path; +use crate::parser::air_parser::make_flattened_error; use crate::parser::lexer::LexerError; use crate::parser::lexer::Token; use crate::parser::lexer::Number; @@ -71,9 +72,14 @@ ServiceId = CallInstrValue; CallInstrValue: CallInstrValue<'input> = { => CallInstrValue::Literal(s), => CallInstrValue::Variable(s), - => { - let (variable, path) = into_variable_and_path(v.0, v.1); - CallInstrValue::JsonPath { variable, path } + => { + let (variable, path) = into_variable_and_path(v.0, v.1, v.2); + let should_flatten = v.2; + if !should_flatten { + let token = Token::JsonPath(v.0, v.1, v.2); + errors.push(make_flattened_error(l, token, r)); + } + CallInstrValue::JsonPath { variable, path, should_flatten } }, InitPeerId => CallInstrValue::InitPeerId, } @@ -84,8 +90,9 @@ CallInstrArgValue: CallInstrArgValue<'input> = { => CallInstrArgValue::Literal(s), => CallInstrArgValue::Variable(s), => { - let (variable, path) = into_variable_and_path(v.0, v.1); - CallInstrArgValue::JsonPath { variable, path } + let (variable, path) = into_variable_and_path(v.0, v.1, v.2); + let should_flatten = v.2; + CallInstrArgValue::JsonPath { variable, path, should_flatten } }, => CallInstrArgValue::Number(n), => CallInstrArgValue::Boolean(b), @@ -96,8 +103,9 @@ CallInstrArgValue: CallInstrArgValue<'input> = { Iterable: IterableValue<'input> = { => IterableValue::Variable(s), => { - let (variable, path) = into_variable_and_path(v.0, v.1); - IterableValue::JsonPath { variable, path } + let (variable, path) = into_variable_and_path(v.0, v.1, v.2); + let should_flatten = v.2; + IterableValue::JsonPath { variable, path, should_flatten } }, } @@ -105,8 +113,9 @@ Matchable: MatchableValue<'input> = { => MatchableValue::Variable(s), => MatchableValue::Literal(s), => { - let (variable, path) = into_variable_and_path(v.0, v.1); - MatchableValue::JsonPath { variable, path } + let (variable, path) = into_variable_and_path(v.0, v.1, v.2); + let should_flatten = v.2; + MatchableValue::JsonPath { variable, path, should_flatten } }, } @@ -122,7 +131,7 @@ extern { Alphanumeric => Token::Alphanumeric(<&'input str>), Literal => Token::StringLiteral(<&'input str>), - JsonPath => Token::JsonPath(<&'input str>, ), + JsonPath => Token::JsonPath(<&'input str>, , ), Accumulator => Token::Accumulator(<&'input str>), Number => Token::Number(), Boolean => Token::Boolean(), diff --git a/crates/air-parser/src/parser/air.rs b/crates/air-parser/src/parser/air.rs index 239d98d7..ae89d60a 100644 --- a/crates/air-parser/src/parser/air.rs +++ b/crates/air-parser/src/parser/air.rs @@ -1,7 +1,8 @@ // auto-generated: "lalrpop 0.19.1" -// sha256: 9acb4e3c4d44725be0dbab976a8a638baa8eab91f1c9cd533f2469fe8e6e9fbb +// sha256: 398273c66ddd518ce5f42ace9c37bc569614e0e19f8eb9a5c85b7385c932 use crate::parser::ast::*; -use crate::parser::into_variable_and_path; +use crate::parser::air_parser::into_variable_and_path; +use crate::parser::air_parser::make_flattened_error; use crate::parser::lexer::LexerError; use crate::parser::lexer::Token; use crate::parser::lexer::Number; @@ -17,7 +18,8 @@ mod __parse__AIR { #![allow(non_snake_case, non_camel_case_types, unused_mut, unused_variables, unused_imports, unused_parens)] use crate::parser::ast::*; - use crate::parser::into_variable_and_path; + use crate::parser::air_parser::into_variable_and_path; + use crate::parser::air_parser::make_flattened_error; use crate::parser::lexer::LexerError; use crate::parser::lexer::Token; use crate::parser::lexer::Number; @@ -34,20 +36,21 @@ mod __parse__AIR { Variant0(Token<'input>), Variant1(&'input str), Variant2(bool), - Variant3((&'input str, usize)), + Variant3((&'input str, usize, bool)), Variant4(Number), Variant5(__lalrpop_util::ErrorRecovery, LexerError>), Variant6(CallInstrArgValue<'input>), Variant7(::std::vec::Vec>), - Variant8(Box>), - Variant9(Vec>), - Variant10(CallInstrValue<'input>), - Variant11(FunctionPart<'input>), - Variant12(IterableValue<'input>), - Variant13(MatchableValue<'input>), - Variant14(CallOutputValue<'input>), - Variant15(::std::option::Option>), - Variant16(PeerPart<'input>), + Variant8(usize), + Variant9(Box>), + Variant10(Vec>), + Variant11(CallInstrValue<'input>), + Variant12(FunctionPart<'input>), + Variant13(IterableValue<'input>), + Variant14(MatchableValue<'input>), + Variant15(CallOutputValue<'input>), + Variant16(::std::option::Option>), + Variant17(PeerPart<'input>), } const __ACTION: &[i8] = &[ // State 0 @@ -107,45 +110,45 @@ mod __parse__AIR { // State 27 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 30, 31, 6, 7, 8, 0, // State 28 - -34, -34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -34, + -36, -36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -36, // State 29 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 30 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 31 - -44, 0, 0, 0, 0, -44, 0, -44, -44, 0, -44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -46, 0, 0, 0, 0, -46, 0, -46, -46, 0, -46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 32 - -45, 0, 0, 0, 0, -45, 0, -45, -45, 0, -45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -47, 0, 0, 0, 0, -47, 0, -47, -47, 0, -47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 33 - -18, -18, -18, 0, 0, -18, 0, -18, -18, 0, -18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // State 34 -20, -20, -20, 0, 0, -20, 0, -20, -20, 0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 34 + -22, -22, -22, 0, 0, -22, 0, -22, -22, 0, -22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 35 - -19, -19, -19, 0, 0, -19, 0, -19, -19, 0, -19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -21, -21, -21, 0, 0, -21, 0, -21, -21, 0, -21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 36 - -17, -17, -17, 0, 0, -17, 0, -17, -17, 0, -17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -19, -19, -19, 0, 0, -19, 0, -19, -19, 0, -19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 37 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 38 - 0, 0, 0, 0, 0, -35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 39 - 0, 0, 0, 0, 0, -36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 40 - -37, 0, 0, 0, 0, -37, 0, 0, -37, 0, -37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -37, - // State 41 -39, 0, 0, 0, 0, -39, 0, 0, -39, 0, -39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -39, + // State 41 + -41, 0, 0, 0, 0, -41, 0, 0, -41, 0, -41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -41, // State 42 - -38, 0, 0, 0, 0, -38, 0, 0, -38, 0, -38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -38, + -40, 0, 0, 0, 0, -40, 0, 0, -40, 0, -40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -40, // State 43 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 44 - -28, -28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -28, - // State 45 - 0, -23, -23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // State 46 - 0, 0, -21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // State 47 -30, -30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -30, + // State 45 + 0, -25, -25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 46 + 0, 0, -23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 47 + -32, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -32, // State 48 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 49 @@ -153,7 +156,7 @@ mod __parse__AIR { // State 50 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 51 - 0, -47, 0, 0, 0, -47, 0, -47, -47, 0, -47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -49, 0, 0, 0, -49, 0, -49, -49, 0, -49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 52 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 53 @@ -163,57 +166,57 @@ mod __parse__AIR { // State 55 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 56 - -27, -27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -27, + -29, -29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -29, // State 57 - -26, -26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -26, + -28, -28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -28, // State 58 - -31, -31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -31, + -33, -33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -33, // State 59 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 60 - -25, -25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -25, + -27, -27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -27, // State 61 - 0, -41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 62 - 0, -40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 63 0, 0, 0, -4, 0, -4, -4, -4, -4, -4, -4, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 64 - 0, 0, 0, -7, 0, -7, -7, -7, -7, -7, -7, -7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -9, 0, -9, -9, -9, -9, -9, -9, -9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 65 - 0, -8, 0, 0, -8, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -10, 0, 0, -10, -10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 66 - 0, 0, 0, -11, 0, -11, -11, -11, -11, -11, -11, -11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // State 67 - 0, 0, 0, -14, 0, -14, -14, -14, -14, -14, -14, -14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // State 68 - 0, 0, 0, -15, 0, -15, -15, -15, -15, -15, -15, -15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // State 69 - 0, 0, 0, -12, 0, -12, -12, -12, -12, -12, -12, -12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // State 70 - 0, 0, 0, -16, 0, -16, -16, -16, -16, -16, -16, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // State 71 - 0, 0, 0, -10, 0, -10, -10, -10, -10, -10, -10, -10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // State 72 0, 0, 0, -13, 0, -13, -13, -13, -13, -13, -13, -13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 67 + 0, 0, 0, -16, 0, -16, -16, -16, -16, -16, -16, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 68 + 0, 0, 0, -17, 0, -17, -17, -17, -17, -17, -17, -17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 69 + 0, 0, 0, -14, 0, -14, -14, -14, -14, -14, -14, -14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 70 + 0, 0, 0, -18, 0, -18, -18, -18, -18, -18, -18, -18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 71 + 0, 0, 0, -12, 0, -12, -12, -12, -12, -12, -12, -12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 72 + 0, 0, 0, -15, 0, -15, -15, -15, -15, -15, -15, -15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 73 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 74 - -46, 0, 0, 0, 0, -46, 0, -46, -46, 0, -46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -48, 0, 0, 0, 0, -48, 0, -48, -48, 0, -48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 75 - -29, -29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -29, + -31, -31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -31, // State 76 - -32, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -32, + -34, -34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -34, // State 77 - -33, -33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -33, + -35, -35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -35, // State 78 - -24, -24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -24, + -26, -26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -26, // State 79 0, 0, 0, -5, 0, -5, -5, -5, -5, -5, -5, -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 80 - 0, -9, 0, 0, -9, -9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -11, 0, 0, -11, -11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 81 - 0, 0, -22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; fn __action(state: i8, integer: usize) -> i8 { __ACTION[(state as usize) * 22 + integer] @@ -270,13 +273,13 @@ mod __parse__AIR { // State 24 0, // State 25 - -48, + -50, // State 26 - -6, + -8, // State 27 0, // State 28 - -34, + -36, // State 29 0, // State 30 @@ -308,13 +311,13 @@ mod __parse__AIR { // State 43 0, // State 44 - -28, + -30, // State 45 0, // State 46 0, // State 47 - -30, + -32, // State 48 0, // State 49 @@ -332,15 +335,15 @@ mod __parse__AIR { // State 55 0, // State 56 - -27, + -29, // State 57 - -26, + -28, // State 58 - -31, + -33, // State 59 0, // State 60 - -25, + -27, // State 61 0, // State 62 @@ -370,13 +373,13 @@ mod __parse__AIR { // State 74 0, // State 75 - -29, + -31, // State 76 - -32, + -34, // State 77 - -33, + -35, // State 78 - -24, + -26, // State 79 0, // State 80 @@ -387,24 +390,24 @@ mod __parse__AIR { fn __goto(state: i8, nt: usize) -> i8 { match nt { 2 => 24, - 3 => 25, - 4 => match state { + 5 => 25, + 6 => match state { 24 => 79, _ => 63, }, - 5 => 21, - 6 => 64, - 7 => match state { + 7 => 21, + 8 => 64, + 9 => match state { 8 | 23 => 45, 16..=17 => 51, _ => 31, }, - 8 => 15, - 9 => match state { + 10 => 15, + 11 => match state { 23 => 73, _ => 46, }, - 10 => match state { + 12 => match state { 6 => 13, 7 => 14, 0 => 26, @@ -416,20 +419,20 @@ mod __parse__AIR { 20 => 55, _ => 12, }, - 11 => 37, - 12 => match state { + 13 => 37, + 14 => match state { 4 => 11, 10 => 19, 11 => 20, _ => 10, }, - 13 => 59, - 15 => match state { + 15 => 59, + 17 => match state { 1 => 32, _ => 17, }, - 16 => 8, - 17 => match state { + 18 => 8, + 19 => match state { 17 => 52, _ => 23, }, @@ -585,7 +588,7 @@ mod __parse__AIR { Token::Alphanumeric(_) if true => Some(5), Token::Boolean(_) if true => Some(6), Token::InitPeerId if true => Some(7), - Token::JsonPath(_, _) if true => Some(8), + Token::JsonPath(_, _, _) if true => Some(8), Token::LastError if true => Some(9), Token::StringLiteral(_) if true => Some(10), Token::Number(_) if true => Some(11), @@ -621,7 +624,7 @@ mod __parse__AIR { _ => unreachable!(), }, 8 => match __token { - Token::JsonPath(__tok0, __tok1) if true => __Symbol::Variant3((__tok0, __tok1)), + Token::JsonPath(__tok0, __tok1, __tok2) if true => __Symbol::Variant3((__tok0, __tok1, __tok2)), _ => unreachable!(), }, 11 => match __token { @@ -674,257 +677,269 @@ mod __parse__AIR { } 5 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 0, nonterminal_produced: 3, } } 6 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 0, nonterminal_produced: 4, } } 7 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, + states_to_pop: 1, nonterminal_produced: 5, } } 8 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 5, + states_to_pop: 1, + nonterminal_produced: 6, } } 9 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 6, + states_to_pop: 2, + nonterminal_produced: 7, } } 10 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 6, + states_to_pop: 3, + nonterminal_produced: 7, } } 11 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 6, + nonterminal_produced: 8, } } 12 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 6, + nonterminal_produced: 8, } } 13 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 6, + nonterminal_produced: 8, } } 14 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 6, + nonterminal_produced: 8, } } 15 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 6, + nonterminal_produced: 8, } } 16 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 7, + nonterminal_produced: 8, } } 17 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 7, + nonterminal_produced: 8, } } 18 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 7, + nonterminal_produced: 9, } } 19 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 7, + nonterminal_produced: 9, } } 20 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 8, + nonterminal_produced: 9, } } 21 => { - __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 8, - } - } - 22 => { __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: 7, + states_to_pop: 4, nonterminal_produced: 10, } } 24 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 10, + states_to_pop: 1, + nonterminal_produced: 11, } } 25 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 10, + states_to_pop: 7, + nonterminal_produced: 12, } } 26 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 10, + states_to_pop: 6, + nonterminal_produced: 12, } } 27 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 10, + states_to_pop: 5, + nonterminal_produced: 12, } } 28 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 10, + states_to_pop: 5, + nonterminal_produced: 12, } } 29 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 10, + states_to_pop: 3, + nonterminal_produced: 12, } } 30 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 10, + states_to_pop: 6, + nonterminal_produced: 12, } } 31 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 10, + states_to_pop: 4, + nonterminal_produced: 12, } } 32 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 10, + states_to_pop: 5, + nonterminal_produced: 12, } } 33 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 10, + states_to_pop: 6, + nonterminal_produced: 12, } } 34 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 11, + states_to_pop: 6, + nonterminal_produced: 12, } } 35 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 11, + nonterminal_produced: 12, } } 36 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 12, + nonterminal_produced: 13, } } 37 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 12, + nonterminal_produced: 13, } } 38 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 12, + nonterminal_produced: 14, } } 39 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 13, + nonterminal_produced: 14, } } 40 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 13, + nonterminal_produced: 14, } } 41 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 14, + nonterminal_produced: 15, } } 42 => { - __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 14, - } - } - 43 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 15, } } - 44 => { + 43 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 16, } } + 44 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 0, + nonterminal_produced: 16, + } + } 45 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 16, + states_to_pop: 1, + nonterminal_produced: 17, } } 46 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 17, + nonterminal_produced: 18, } } - 47 => __state_machine::SimulatedReduce::Accept, + 47 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 4, + nonterminal_produced: 18, + } + } + 48 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 19, + } + } + 49 => __state_machine::SimulatedReduce::Accept, _ => panic!("invalid reduction index {}", __reduce_index) } } @@ -1157,8 +1172,14 @@ mod __parse__AIR { __reduce46(input, errors, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) } 47 => { + __reduce47(input, errors, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 48 => { + __reduce48(input, errors, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 49 => { // __AIR = AIR => ActionFn(0); - let __sym0 = __pop_Variant8(__symbols); + let __sym0 = __pop_Variant9(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action0::<>(input, errors, __sym0); @@ -1181,21 +1202,21 @@ mod __parse__AIR { 'input, >( __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> - ) -> (usize, (&'input str, usize), usize) + ) -> (usize, (&'input str, usize, bool), usize) { match __symbols.pop() { Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant8< + fn __pop_Variant9< 'input, >( __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> ) -> (usize, Box>, usize) { match __symbols.pop() { - Some((__l, __Symbol::Variant8(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant9(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -1210,36 +1231,25 @@ mod __parse__AIR { _ => __symbol_type_mismatch() } } - fn __pop_Variant10< + fn __pop_Variant11< 'input, >( __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> ) -> (usize, CallInstrValue<'input>, usize) { match __symbols.pop() { - Some((__l, __Symbol::Variant10(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant11(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant14< + fn __pop_Variant15< 'input, >( __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> ) -> (usize, CallOutputValue<'input>, usize) { match __symbols.pop() { - Some((__l, __Symbol::Variant14(__v), __r)) => (__l, __v, __r), - _ => __symbol_type_mismatch() - } - } - fn __pop_Variant11< - 'input, - >( - __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> - ) -> (usize, FunctionPart<'input>, usize) - { - match __symbols.pop() { - Some((__l, __Symbol::Variant11(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant15(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -1247,7 +1257,7 @@ mod __parse__AIR { 'input, >( __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> - ) -> (usize, IterableValue<'input>, usize) + ) -> (usize, FunctionPart<'input>, usize) { match __symbols.pop() { Some((__l, __Symbol::Variant12(__v), __r)) => (__l, __v, __r), @@ -1258,13 +1268,24 @@ mod __parse__AIR { 'input, >( __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> - ) -> (usize, MatchableValue<'input>, usize) + ) -> (usize, IterableValue<'input>, usize) { match __symbols.pop() { Some((__l, __Symbol::Variant13(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } + fn __pop_Variant14< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, MatchableValue<'input>, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant14(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } fn __pop_Variant4< 'input, >( @@ -1276,14 +1297,14 @@ mod __parse__AIR { _ => __symbol_type_mismatch() } } - fn __pop_Variant16< + fn __pop_Variant17< 'input, >( __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> ) -> (usize, PeerPart<'input>, usize) { match __symbols.pop() { - Some((__l, __Symbol::Variant16(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant17(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -1298,14 +1319,14 @@ mod __parse__AIR { _ => __symbol_type_mismatch() } } - fn __pop_Variant9< + fn __pop_Variant10< 'input, >( __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> ) -> (usize, Vec>, usize) { match __symbols.pop() { - Some((__l, __Symbol::Variant9(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant10(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -1331,14 +1352,25 @@ mod __parse__AIR { _ => __symbol_type_mismatch() } } - fn __pop_Variant15< + fn __pop_Variant8< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, usize, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant8(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant16< 'input, >( __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> ) -> (usize, ::std::option::Option>, usize) { match __symbols.pop() { - Some((__l, __Symbol::Variant15(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant16(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -1375,11 +1407,11 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // () = Arg => ActionFn(41); + // () = Arg => ActionFn(43); let __sym0 = __pop_Variant6(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action41::<>(input, errors, __sym0); + let __nt = super::__action43::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant6(__nt), __end)); (1, 0) } @@ -1394,10 +1426,10 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // ()* = => ActionFn(39); + // ()* = => ActionFn(41); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action39::<>(input, errors, &__start, &__end); + let __nt = super::__action41::<>(input, errors, &__start, &__end); __symbols.push((__start, __Symbol::Variant7(__nt), __end)); (0, 1) } @@ -1412,11 +1444,11 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // ()* = ()+ => ActionFn(40); + // ()* = ()+ => ActionFn(42); let __sym0 = __pop_Variant7(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action40::<>(input, errors, __sym0); + let __nt = super::__action42::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant7(__nt), __end)); (1, 1) } @@ -1431,11 +1463,11 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // ()+ = Arg => ActionFn(46); + // ()+ = Arg => ActionFn(48); let __sym0 = __pop_Variant6(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action46::<>(input, errors, __sym0); + let __nt = super::__action48::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant7(__nt), __end)); (1, 2) } @@ -1450,13 +1482,13 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // ()+ = ()+, Arg => ActionFn(47); + // ()+ = ()+, Arg => ActionFn(49); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant6(__symbols); let __sym0 = __pop_Variant7(__symbols); let __start = __sym0.0.clone(); let __end = __sym1.2.clone(); - let __nt = super::__action47::<>(input, errors, __sym0, __sym1); + let __nt = super::__action49::<>(input, errors, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant7(__nt), __end)); (2, 2) } @@ -1470,16 +1502,52 @@ mod __parse__AIR { __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) + { + // @L = => ActionFn(40); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action40::<>(input, errors, &__start, &__end); + __symbols.push((__start, __Symbol::Variant8(__nt), __end)); + (0, 3) + } + pub(crate) fn __reduce6< + 'err, + 'input, + >( + input: &'input str, + errors: &'err mut Vec, LexerError>>, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'err (), &'input ())>, + ) -> (usize, usize) + { + // @R = => ActionFn(39); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action39::<>(input, errors, &__start, &__end); + __symbols.push((__start, __Symbol::Variant8(__nt), __end)); + (0, 4) + } + pub(crate) fn __reduce7< + 'err, + 'input, + >( + input: &'input str, + errors: &'err mut Vec, LexerError>>, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'err (), &'input ())>, + ) -> (usize, usize) { // AIR = Instr => ActionFn(1); - let __sym0 = __pop_Variant8(__symbols); + let __sym0 = __pop_Variant9(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action1::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (1, 3) + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 5) } - pub(crate) fn __reduce6< + pub(crate) fn __reduce8< 'err, 'input, >( @@ -1496,9 +1564,9 @@ mod __parse__AIR { let __end = __sym0.2.clone(); let __nt = super::__action26::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant6(__nt), __end)); - (1, 4) + (1, 6) } - pub(crate) fn __reduce7< + pub(crate) fn __reduce9< 'err, 'input, >( @@ -1509,17 +1577,17 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Args = "[", "]" => ActionFn(48); + // Args = "[", "]" => ActionFn(50); 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::__action48::<>(input, errors, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (2, 5) + let __nt = super::__action50::<>(input, errors, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant10(__nt), __end)); + (2, 7) } - pub(crate) fn __reduce8< + pub(crate) fn __reduce10< 'err, 'input, >( @@ -1530,18 +1598,18 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Args = "[", ()+, "]" => ActionFn(49); + // Args = "[", ()+, "]" => ActionFn(51); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant7(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym2.2.clone(); - let __nt = super::__action49::<>(input, errors, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (3, 5) + let __nt = super::__action51::<>(input, errors, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant10(__nt), __end)); + (3, 7) } - pub(crate) fn __reduce9< + pub(crate) fn __reduce11< 'err, 'input, >( @@ -1558,9 +1626,9 @@ mod __parse__AIR { let __end = __sym0.2.clone(); let __nt = super::__action27::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant6(__nt), __end)); - (1, 6) + (1, 8) } - pub(crate) fn __reduce10< + pub(crate) fn __reduce12< 'err, 'input, >( @@ -1577,9 +1645,9 @@ mod __parse__AIR { let __end = __sym0.2.clone(); let __nt = super::__action28::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant6(__nt), __end)); - (1, 6) + (1, 8) } - pub(crate) fn __reduce11< + pub(crate) fn __reduce13< 'err, 'input, >( @@ -1596,9 +1664,9 @@ mod __parse__AIR { let __end = __sym0.2.clone(); let __nt = super::__action29::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant6(__nt), __end)); - (1, 6) + (1, 8) } - pub(crate) fn __reduce12< + pub(crate) fn __reduce14< 'err, 'input, >( @@ -1615,9 +1683,9 @@ mod __parse__AIR { let __end = __sym0.2.clone(); let __nt = super::__action30::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant6(__nt), __end)); - (1, 6) + (1, 8) } - pub(crate) fn __reduce13< + pub(crate) fn __reduce15< 'err, 'input, >( @@ -1634,9 +1702,9 @@ mod __parse__AIR { let __end = __sym0.2.clone(); let __nt = super::__action31::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant6(__nt), __end)); - (1, 6) + (1, 8) } - pub(crate) fn __reduce14< + pub(crate) fn __reduce16< 'err, 'input, >( @@ -1653,9 +1721,9 @@ mod __parse__AIR { let __end = __sym0.2.clone(); let __nt = super::__action32::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant6(__nt), __end)); - (1, 6) + (1, 8) } - pub(crate) fn __reduce15< + pub(crate) fn __reduce17< 'err, 'input, >( @@ -1672,9 +1740,9 @@ mod __parse__AIR { let __end = __sym0.2.clone(); let __nt = super::__action33::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant6(__nt), __end)); - (1, 6) + (1, 8) } - pub(crate) fn __reduce16< + pub(crate) fn __reduce18< 'err, 'input, >( @@ -1690,10 +1758,10 @@ mod __parse__AIR { let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action22::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (1, 7) + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (1, 9) } - pub(crate) fn __reduce17< + pub(crate) fn __reduce19< 'err, 'input, >( @@ -1709,10 +1777,10 @@ mod __parse__AIR { let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action23::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (1, 7) + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (1, 9) } - pub(crate) fn __reduce18< + pub(crate) fn __reduce20< 'err, 'input, >( @@ -1723,15 +1791,15 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // CallInstrValue = JsonPath => ActionFn(24); + // CallInstrValue = JsonPath => ActionFn(53); let __sym0 = __pop_Variant3(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action24::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (1, 7) + let __nt = super::__action53::<>(input, errors, __sym0); + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (1, 9) } - pub(crate) fn __reduce19< + pub(crate) fn __reduce21< 'err, 'input, >( @@ -1747,10 +1815,10 @@ mod __parse__AIR { let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action25::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (1, 7) + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (1, 9) } - pub(crate) fn __reduce20< + pub(crate) fn __reduce22< 'err, 'input, >( @@ -1762,14 +1830,14 @@ mod __parse__AIR { ) -> (usize, usize) { // FPart = Function => ActionFn(13); - let __sym0 = __pop_Variant10(__symbols); + let __sym0 = __pop_Variant11(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action13::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant11(__nt), __end)); - (1, 8) + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (1, 10) } - pub(crate) fn __reduce21< + pub(crate) fn __reduce23< 'err, 'input, >( @@ -1783,59 +1851,14 @@ mod __parse__AIR { // FPart = "(", ServiceId, Function, ")" => ActionFn(14); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant10(__symbols); - let __sym1 = __pop_Variant10(__symbols); + let __sym2 = __pop_Variant11(__symbols); + let __sym1 = __pop_Variant11(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym3.2.clone(); let __nt = super::__action14::<>(input, errors, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant11(__nt), __end)); - (4, 8) - } - pub(crate) fn __reduce22< - 'err, - 'input, - >( - input: &'input str, - errors: &'err mut Vec, LexerError>>, - __lookahead_start: Option<&usize>, - __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, - _: ::std::marker::PhantomData<(&'err (), &'input ())>, - ) -> (usize, usize) - { - // Function = CallInstrValue => ActionFn(19); - let __sym0 = __pop_Variant10(__symbols); - let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action19::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (1, 9) - } - pub(crate) fn __reduce23< - 'err, - 'input, - >( - input: &'input str, - errors: &'err mut Vec, LexerError>>, - __lookahead_start: Option<&usize>, - __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, - _: ::std::marker::PhantomData<(&'err (), &'input ())>, - ) -> (usize, usize) - { - // Instr = "(", call, PeerPart, FPart, Args, Output, ")" => ActionFn(50); - assert!(__symbols.len() >= 7); - let __sym6 = __pop_Variant0(__symbols); - let __sym5 = __pop_Variant14(__symbols); - let __sym4 = __pop_Variant9(__symbols); - let __sym3 = __pop_Variant11(__symbols); - let __sym2 = __pop_Variant16(__symbols); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant0(__symbols); - let __start = __sym0.0.clone(); - let __end = __sym6.2.clone(); - let __nt = super::__action50::<>(input, errors, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (7, 10) + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (4, 10) } pub(crate) fn __reduce24< 'err, @@ -1848,21 +1871,66 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Instr = "(", call, PeerPart, FPart, Args, ")" => ActionFn(51); + // Function = CallInstrValue => ActionFn(19); + let __sym0 = __pop_Variant11(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action19::<>(input, errors, __sym0); + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (1, 11) + } + pub(crate) fn __reduce25< + 'err, + 'input, + >( + input: &'input str, + errors: &'err mut Vec, LexerError>>, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'err (), &'input ())>, + ) -> (usize, usize) + { + // Instr = "(", call, PeerPart, FPart, Args, Output, ")" => ActionFn(54); + assert!(__symbols.len() >= 7); + let __sym6 = __pop_Variant0(__symbols); + let __sym5 = __pop_Variant15(__symbols); + let __sym4 = __pop_Variant10(__symbols); + let __sym3 = __pop_Variant12(__symbols); + let __sym2 = __pop_Variant17(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym6.2.clone(); + let __nt = super::__action54::<>(input, errors, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (7, 12) + } + pub(crate) fn __reduce26< + 'err, + 'input, + >( + input: &'input str, + errors: &'err mut Vec, LexerError>>, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'err (), &'input ())>, + ) -> (usize, usize) + { + // Instr = "(", call, PeerPart, FPart, Args, ")" => ActionFn(55); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant9(__symbols); - let __sym3 = __pop_Variant11(__symbols); - let __sym2 = __pop_Variant16(__symbols); + let __sym4 = __pop_Variant10(__symbols); + let __sym3 = __pop_Variant12(__symbols); + let __sym2 = __pop_Variant17(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym5.2.clone(); - let __nt = super::__action51::<>(input, errors, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (6, 10) + let __nt = super::__action55::<>(input, errors, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (6, 12) } - pub(crate) fn __reduce25< + pub(crate) fn __reduce27< 'err, 'input, >( @@ -1876,17 +1944,17 @@ mod __parse__AIR { // Instr = "(", seq, Instr, Instr, ")" => ActionFn(3); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant8(__symbols); - let __sym2 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); + let __sym2 = __pop_Variant9(__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::<>(input, errors, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (5, 10) + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (5, 12) } - pub(crate) fn __reduce26< + pub(crate) fn __reduce28< 'err, 'input, >( @@ -1900,17 +1968,17 @@ mod __parse__AIR { // Instr = "(", par, Instr, Instr, ")" => ActionFn(4); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant8(__symbols); - let __sym2 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); + let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym4.2.clone(); let __nt = super::__action4::<>(input, errors, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (5, 10) + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (5, 12) } - pub(crate) fn __reduce27< + pub(crate) fn __reduce29< 'err, 'input, >( @@ -1929,10 +1997,10 @@ mod __parse__AIR { let __start = __sym0.0.clone(); let __end = __sym2.2.clone(); let __nt = super::__action5::<>(input, errors, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (3, 10) + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (3, 12) } - pub(crate) fn __reduce28< + pub(crate) fn __reduce30< 'err, 'input, >( @@ -1946,18 +2014,18 @@ mod __parse__AIR { // Instr = "(", fold, Iterable, Alphanumeric, Instr, ")" => ActionFn(6); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant8(__symbols); + let __sym4 = __pop_Variant9(__symbols); let __sym3 = __pop_Variant1(__symbols); - let __sym2 = __pop_Variant12(__symbols); + let __sym2 = __pop_Variant13(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym5.2.clone(); let __nt = super::__action6::<>(input, errors, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (6, 10) + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (6, 12) } - pub(crate) fn __reduce29< + pub(crate) fn __reduce31< 'err, 'input, >( @@ -1977,10 +2045,10 @@ mod __parse__AIR { let __start = __sym0.0.clone(); let __end = __sym3.2.clone(); let __nt = super::__action7::<>(input, errors, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (4, 10) + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (4, 12) } - pub(crate) fn __reduce30< + pub(crate) fn __reduce32< 'err, 'input, >( @@ -1994,17 +2062,17 @@ mod __parse__AIR { // Instr = "(", xor, Instr, Instr, ")" => ActionFn(8); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant8(__symbols); - let __sym2 = __pop_Variant8(__symbols); + let __sym3 = __pop_Variant9(__symbols); + let __sym2 = __pop_Variant9(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym4.2.clone(); let __nt = super::__action8::<>(input, errors, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (5, 10) + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (5, 12) } - pub(crate) fn __reduce31< + pub(crate) fn __reduce33< 'err, 'input, >( @@ -2018,18 +2086,18 @@ mod __parse__AIR { // Instr = "(", match_, Matchable, Matchable, Instr, ")" => ActionFn(9); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant8(__symbols); - let __sym3 = __pop_Variant13(__symbols); - let __sym2 = __pop_Variant13(__symbols); + let __sym4 = __pop_Variant9(__symbols); + let __sym3 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant14(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym5.2.clone(); let __nt = super::__action9::<>(input, errors, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (6, 10) + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (6, 12) } - pub(crate) fn __reduce32< + pub(crate) fn __reduce34< 'err, 'input, >( @@ -2043,18 +2111,18 @@ mod __parse__AIR { // Instr = "(", mismatch, Matchable, Matchable, Instr, ")" => ActionFn(10); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant8(__symbols); - let __sym3 = __pop_Variant13(__symbols); - let __sym2 = __pop_Variant13(__symbols); + let __sym4 = __pop_Variant9(__symbols); + let __sym3 = __pop_Variant14(__symbols); + let __sym2 = __pop_Variant14(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym5.2.clone(); let __nt = super::__action10::<>(input, errors, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (6, 10) + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (6, 12) } - pub(crate) fn __reduce33< + pub(crate) fn __reduce35< 'err, 'input, >( @@ -2070,10 +2138,10 @@ mod __parse__AIR { let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action11::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant8(__nt), __end)); - (1, 10) + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 12) } - pub(crate) fn __reduce34< + pub(crate) fn __reduce36< 'err, 'input, >( @@ -2089,10 +2157,10 @@ mod __parse__AIR { let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action34::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (1, 11) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (1, 13) } - pub(crate) fn __reduce35< + pub(crate) fn __reduce37< 'err, 'input, >( @@ -2108,10 +2176,10 @@ mod __parse__AIR { let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action35::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (1, 11) + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (1, 13) } - pub(crate) fn __reduce36< + pub(crate) fn __reduce38< 'err, 'input, >( @@ -2127,10 +2195,10 @@ mod __parse__AIR { let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action36::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (1, 12) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (1, 14) } - pub(crate) fn __reduce37< + pub(crate) fn __reduce39< 'err, 'input, >( @@ -2146,10 +2214,10 @@ mod __parse__AIR { let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action37::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (1, 12) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (1, 14) } - pub(crate) fn __reduce38< + pub(crate) fn __reduce40< 'err, 'input, >( @@ -2165,10 +2233,10 @@ mod __parse__AIR { let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action38::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (1, 12) + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (1, 14) } - pub(crate) fn __reduce39< + pub(crate) fn __reduce41< 'err, 'input, >( @@ -2184,10 +2252,10 @@ mod __parse__AIR { let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action17::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 13) + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (1, 15) } - pub(crate) fn __reduce40< + pub(crate) fn __reduce42< 'err, 'input, >( @@ -2203,45 +2271,8 @@ mod __parse__AIR { let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action18::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 13) - } - pub(crate) fn __reduce41< - 'err, - 'input, - >( - input: &'input str, - errors: &'err mut Vec, LexerError>>, - __lookahead_start: Option<&usize>, - __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, - _: ::std::marker::PhantomData<(&'err (), &'input ())>, - ) -> (usize, usize) - { - // Output? = Output => ActionFn(42); - let __sym0 = __pop_Variant14(__symbols); - let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action42::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (1, 14) - } - pub(crate) fn __reduce42< - 'err, - 'input, - >( - input: &'input str, - errors: &'err mut Vec, LexerError>>, - __lookahead_start: Option<&usize>, - __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, - _: ::std::marker::PhantomData<(&'err (), &'input ())>, - ) -> (usize, usize) - { - // Output? = => ActionFn(43); - let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); - let __end = __start.clone(); - let __nt = super::__action43::<>(input, errors, &__start, &__end); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (0, 14) + (1, 15) } pub(crate) fn __reduce43< 'err, @@ -2254,13 +2285,13 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // PeerId = CallInstrValue => ActionFn(20); - let __sym0 = __pop_Variant10(__symbols); + // Output? = Output => ActionFn(44); + let __sym0 = __pop_Variant15(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action20::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (1, 15) + let __nt = super::__action44::<>(input, errors, __sym0); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (1, 16) } pub(crate) fn __reduce44< 'err, @@ -2272,16 +2303,53 @@ mod __parse__AIR { __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) + { + // Output? = => ActionFn(45); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action45::<>(input, errors, &__start, &__end); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (0, 16) + } + pub(crate) fn __reduce45< + 'err, + 'input, + >( + input: &'input str, + errors: &'err mut Vec, LexerError>>, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'err (), &'input ())>, + ) -> (usize, usize) + { + // PeerId = CallInstrValue => ActionFn(20); + let __sym0 = __pop_Variant11(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action20::<>(input, errors, __sym0); + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (1, 17) + } + pub(crate) fn __reduce46< + 'err, + 'input, + >( + input: &'input str, + errors: &'err mut Vec, LexerError>>, + __lookahead_start: Option<&usize>, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'err (), &'input ())>, + ) -> (usize, usize) { // PeerPart = PeerId => ActionFn(15); - let __sym0 = __pop_Variant10(__symbols); + let __sym0 = __pop_Variant11(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action15::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (1, 16) + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (1, 18) } - pub(crate) fn __reduce45< + pub(crate) fn __reduce47< 'err, 'input, >( @@ -2295,16 +2363,16 @@ mod __parse__AIR { // PeerPart = "(", PeerId, ServiceId, ")" => ActionFn(16); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant10(__symbols); - let __sym1 = __pop_Variant10(__symbols); + let __sym2 = __pop_Variant11(__symbols); + let __sym1 = __pop_Variant11(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym3.2.clone(); let __nt = super::__action16::<>(input, errors, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (4, 16) + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (4, 18) } - pub(crate) fn __reduce46< + pub(crate) fn __reduce48< 'err, 'input, >( @@ -2316,12 +2384,12 @@ mod __parse__AIR { ) -> (usize, usize) { // ServiceId = CallInstrValue => ActionFn(21); - let __sym0 = __pop_Variant10(__symbols); + let __sym0 = __pop_Variant11(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action21::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (1, 17) + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (1, 19) } } pub use self::__parse__AIR::AIRParser; @@ -2704,12 +2772,19 @@ fn __action24< >( input: &'input str, errors: &'err mut Vec, LexerError>>, - (_, v, _): (usize, (&'input str, usize), usize), + (_, l, _): (usize, usize, usize), + (_, v, _): (usize, (&'input str, usize, bool), usize), + (_, r, _): (usize, usize, usize), ) -> CallInstrValue<'input> { { - let (variable, path) = into_variable_and_path(v.0, v.1); - CallInstrValue::JsonPath { variable, path } + let (variable, path) = into_variable_and_path(v.0, v.1, v.2); + let should_flatten = v.2; + if !should_flatten { + let token = Token::JsonPath(v.0, v.1, v.2); + errors.push(make_flattened_error(l, token, r)); + } + CallInstrValue::JsonPath { variable, path, should_flatten } } } @@ -2772,12 +2847,13 @@ fn __action29< >( input: &'input str, errors: &'err mut Vec, LexerError>>, - (_, v, _): (usize, (&'input str, usize), usize), + (_, v, _): (usize, (&'input str, usize, bool), usize), ) -> CallInstrArgValue<'input> { { - let (variable, path) = into_variable_and_path(v.0, v.1); - CallInstrArgValue::JsonPath { variable, path } + let (variable, path) = into_variable_and_path(v.0, v.1, v.2); + let should_flatten = v.2; + CallInstrArgValue::JsonPath { variable, path, should_flatten } } } @@ -2853,12 +2929,13 @@ fn __action35< >( input: &'input str, errors: &'err mut Vec, LexerError>>, - (_, v, _): (usize, (&'input str, usize), usize), + (_, v, _): (usize, (&'input str, usize, bool), usize), ) -> IterableValue<'input> { { - let (variable, path) = into_variable_and_path(v.0, v.1); - IterableValue::JsonPath { variable, path } + let (variable, path) = into_variable_and_path(v.0, v.1, v.2); + let should_flatten = v.2; + IterableValue::JsonPath { variable, path, should_flatten } } } @@ -2895,12 +2972,13 @@ fn __action38< >( input: &'input str, errors: &'err mut Vec, LexerError>>, - (_, v, _): (usize, (&'input str, usize), usize), + (_, v, _): (usize, (&'input str, usize, bool), usize), ) -> MatchableValue<'input> { { - let (variable, path) = into_variable_and_path(v.0, v.1); - MatchableValue::JsonPath { variable, path } + let (variable, path) = into_variable_and_path(v.0, v.1, v.2); + let should_flatten = v.2; + MatchableValue::JsonPath { variable, path, should_flatten } } } @@ -2913,13 +2991,41 @@ fn __action39< errors: &'err mut Vec, LexerError>>, __lookbehind: &usize, __lookahead: &usize, +) -> usize +{ + __lookbehind.clone() +} + +#[allow(unused_variables)] +fn __action40< + 'err, + 'input, +>( + input: &'input str, + errors: &'err mut Vec, LexerError>>, + __lookbehind: &usize, + __lookahead: &usize, +) -> usize +{ + __lookahead.clone() +} + +#[allow(unused_variables)] +fn __action41< + 'err, + 'input, +>( + input: &'input str, + errors: &'err mut Vec, LexerError>>, + __lookbehind: &usize, + __lookahead: &usize, ) -> ::std::vec::Vec> { vec![] } #[allow(unused_variables)] -fn __action40< +fn __action42< 'err, 'input, >( @@ -2932,7 +3038,7 @@ fn __action40< } #[allow(unused_variables)] -fn __action41< +fn __action43< 'err, 'input, >( @@ -2945,7 +3051,7 @@ fn __action41< } #[allow(unused_variables)] -fn __action42< +fn __action44< 'err, 'input, >( @@ -2958,7 +3064,7 @@ fn __action42< } #[allow(unused_variables)] -fn __action43< +fn __action45< 'err, 'input, >( @@ -2972,7 +3078,7 @@ fn __action43< } #[allow(unused_variables)] -fn __action44< +fn __action46< 'err, 'input, >( @@ -2985,7 +3091,7 @@ fn __action44< } #[allow(unused_variables)] -fn __action45< +fn __action47< 'err, 'input, >( @@ -2999,7 +3105,7 @@ fn __action45< } #[allow(unused_variables)] -fn __action46< +fn __action48< 'err, 'input, >( @@ -3010,13 +3116,13 @@ fn __action46< { let __start0 = __0.0.clone(); let __end0 = __0.2.clone(); - let __temp0 = __action41( + let __temp0 = __action43( input, errors, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action44( + __action46( input, errors, __temp0, @@ -3024,7 +3130,7 @@ fn __action46< } #[allow(unused_variables)] -fn __action47< +fn __action49< 'err, 'input, >( @@ -3036,13 +3142,13 @@ fn __action47< { let __start0 = __1.0.clone(); let __end0 = __1.2.clone(); - let __temp0 = __action41( + let __temp0 = __action43( input, errors, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action45( + __action47( input, errors, __0, @@ -3051,7 +3157,7 @@ fn __action47< } #[allow(unused_variables)] -fn __action48< +fn __action50< 'err, 'input, >( @@ -3063,7 +3169,7 @@ fn __action48< { let __start0 = __0.2.clone(); let __end0 = __1.0.clone(); - let __temp0 = __action39( + let __temp0 = __action41( input, errors, &__start0, @@ -3080,7 +3186,7 @@ fn __action48< } #[allow(unused_variables)] -fn __action49< +fn __action51< 'err, 'input, >( @@ -3093,7 +3199,7 @@ fn __action49< { let __start0 = __1.0.clone(); let __end0 = __1.2.clone(); - let __temp0 = __action40( + let __temp0 = __action42( input, errors, __1, @@ -3109,7 +3215,63 @@ fn __action49< } #[allow(unused_variables)] -fn __action50< +fn __action52< + 'err, + 'input, +>( + input: &'input str, + errors: &'err mut Vec, LexerError>>, + __0: (usize, (&'input str, usize, bool), usize), + __1: (usize, usize, usize), +) -> CallInstrValue<'input> +{ + let __start0 = __0.0.clone(); + let __end0 = __0.0.clone(); + let __temp0 = __action40( + input, + errors, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action24( + input, + errors, + __temp0, + __0, + __1, + ) +} + +#[allow(unused_variables)] +fn __action53< + 'err, + 'input, +>( + input: &'input str, + errors: &'err mut Vec, LexerError>>, + __0: (usize, (&'input str, usize, bool), usize), +) -> CallInstrValue<'input> +{ + let __start0 = __0.2.clone(); + let __end0 = __0.2.clone(); + let __temp0 = __action39( + input, + errors, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action52( + input, + errors, + __0, + __temp0, + ) +} + +#[allow(unused_variables)] +fn __action54< 'err, 'input, >( @@ -3126,7 +3288,7 @@ fn __action50< { let __start0 = __5.0.clone(); let __end0 = __5.2.clone(); - let __temp0 = __action42( + let __temp0 = __action44( input, errors, __5, @@ -3146,7 +3308,7 @@ fn __action50< } #[allow(unused_variables)] -fn __action51< +fn __action55< 'err, 'input, >( @@ -3162,7 +3324,7 @@ fn __action51< { let __start0 = __4.2.clone(); let __end0 = __5.0.clone(); - let __temp0 = __action43( + let __temp0 = __action45( input, errors, &__start0, diff --git a/crates/air-parser/src/parser/air_parser.rs b/crates/air-parser/src/parser/air_parser.rs index b3911b70..dd5b342d 100644 --- a/crates/air-parser/src/parser/air_parser.rs +++ b/crates/air-parser/src/parser/air_parser.rs @@ -147,5 +147,34 @@ fn lexical_error_to_label(file_id: usize, error: LexerError) -> Label { LeadingDot(start, end) => { Label::primary(file_id, start..end).with_message(error.to_string()) } + CallArgsNotFlattened(start, end) => { + Label::primary(file_id, start..end).with_message(error.to_string()) + } + } +} + +pub(super) fn into_variable_and_path(str: &str, pos: usize, should_flatten: bool) -> (&str, &str) { + let json_path = if should_flatten { + &str[pos + 1..str.len() - 1] + } else { + &str[pos + 1..] + }; + + (&str[0..pos], json_path) +} + +pub(super) fn make_flattened_error( + start_pos: usize, + token: Token<'_>, + end_pos: usize, +) -> ErrorRecovery, LexerError> { + let error = LexerError::CallArgsNotFlattened(start_pos, end_pos); + let error = ParseError::User { error }; + + let dropped_tokens = vec![(start_pos, token, end_pos)]; + + ErrorRecovery { + error, + dropped_tokens, } } diff --git a/crates/air-parser/src/parser/ast.rs b/crates/air-parser/src/parser/ast.rs index e91a2952..f9cf286b 100644 --- a/crates/air-parser/src/parser/ast.rs +++ b/crates/air-parser/src/parser/ast.rs @@ -63,7 +63,11 @@ pub enum CallInstrValue<'i> { InitPeerId, Literal(&'i str), Variable(&'i str), - JsonPath { variable: &'i str, path: &'i str }, + JsonPath { + variable: &'i str, + path: &'i str, + should_flatten: bool, + }, } #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] @@ -74,13 +78,21 @@ pub enum CallInstrArgValue<'i> { Number(Number), Boolean(bool), Variable(&'i str), - JsonPath { variable: &'i str, path: &'i str }, + JsonPath { + variable: &'i str, + path: &'i str, + should_flatten: bool, + }, } #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub enum IterableValue<'i> { Variable(&'i str), - JsonPath { variable: &'i str, path: &'i str }, + JsonPath { + variable: &'i str, + path: &'i str, + should_flatten: bool, + }, } #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] @@ -89,7 +101,11 @@ pub enum MatchableValue<'i> { Number(Number), Boolean(bool), Variable(&'i str), - JsonPath { variable: &'i str, path: &'i str }, + JsonPath { + variable: &'i str, + path: &'i str, + should_flatten: bool, + }, } #[derive(Serialize, Debug, PartialEq, Clone)] diff --git a/crates/air-parser/src/parser/ast/traits.rs b/crates/air-parser/src/parser/ast/traits.rs index 4f0bdea4..d8c5a60d 100644 --- a/crates/air-parser/src/parser/ast/traits.rs +++ b/crates/air-parser/src/parser/ast/traits.rs @@ -29,11 +29,26 @@ impl fmt::Display for CallInstrArgValue<'_> { Number(number) => write!(f, "{}", number), Boolean(bool) => write!(f, "{}", bool), Variable(str) => write!(f, "{}", str), - JsonPath { variable, path } => write!(f, "{}.{}", variable, path), + JsonPath { + variable, + path, + should_flatten, + } => print_json_path(variable, path, should_flatten, f), } } } +fn print_json_path( + variable: &str, + path: &str, + should_flatten: &bool, + f: &mut fmt::Formatter, +) -> fmt::Result { + let maybe_flatten_char = if *should_flatten { "!" } else { "" }; + + write!(f, "{}.{}{}", variable, path, maybe_flatten_char) +} + impl fmt::Display for CallInstrValue<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use CallInstrValue::*; @@ -42,7 +57,11 @@ impl fmt::Display for CallInstrValue<'_> { InitPeerId => write!(f, "%init_peer_id%"), Literal(str) => write!(f, r#""{}""#, str), Variable(str) => write!(f, "{}", str), - JsonPath { variable, path } => write!(f, "{}.{}", variable, path), + JsonPath { + variable, + path, + should_flatten, + } => print_json_path(variable, path, should_flatten, f), } } } @@ -53,7 +72,11 @@ impl fmt::Display for IterableValue<'_> { match self { Variable(str) => write!(f, "{}", str), - JsonPath { variable, path } => write!(f, "{}.{}", variable, path), + JsonPath { + variable, + path, + should_flatten, + } => print_json_path(variable, path, should_flatten, f), } } } @@ -67,7 +90,11 @@ impl fmt::Display for MatchableValue<'_> { Number(number) => write!(f, "{}", number), Boolean(bool) => write!(f, "{}", bool), Variable(str) => write!(f, "{}", str), - JsonPath { variable, path } => write!(f, "{}.{}", variable, path), + JsonPath { + variable, + path, + should_flatten, + } => print_json_path(variable, path, should_flatten, f), } } } diff --git a/crates/air-parser/src/parser/lexer/call_variable_parser.rs b/crates/air-parser/src/parser/lexer/call_variable_parser.rs index 59e5520b..38b5e5a5 100644 --- a/crates/air-parser/src/parser/lexer/call_variable_parser.rs +++ b/crates/air-parser/src/parser/lexer/call_variable_parser.rs @@ -34,6 +34,7 @@ struct ParserState { pub(self) first_dot_met_pos: Option, pub(self) non_numeric_met: bool, pub(self) digit_met: bool, + pub(self) flattening_met: bool, pub(self) is_first_char: bool, pub(self) current_char: char, pub(self) current_pos: usize, @@ -58,6 +59,7 @@ impl<'input> CallVariableParser<'input> { first_dot_met_pos: None, non_numeric_met: false, digit_met: false, + flattening_met: false, is_first_char: true, current_char, current_pos, @@ -186,8 +188,8 @@ impl<'input> CallVariableParser<'input> { Ok(()) } - fn try_parse_as_json_path(&self) -> LexerResult<()> { - if !self.json_path_allowed_char() { + fn try_parse_as_json_path(&mut self) -> LexerResult<()> { + if !self.json_path_allowed_char() && !self.try_parse_as_flattening() { let error_pos = self.pos_in_string_to_parse(); return Err(LexerError::InvalidJsonPath(error_pos, error_pos)); } @@ -195,6 +197,15 @@ impl<'input> CallVariableParser<'input> { Ok(()) } + fn try_parse_as_flattening(&mut self) -> bool { + if self.is_last_char() && self.current_char() == '!' { + self.state.flattening_met = true; + return true; + } + + false + } + fn try_parse_first_met_dot(&mut self) -> LexerResult { if !self.dot_met() && self.current_char() == '.' { if self.current_pos() == 0 { @@ -238,6 +249,10 @@ impl<'input> CallVariableParser<'input> { self.state.current_char } + fn is_last_char(&self) -> bool { + self.current_pos() == self.string_to_parse.len() - 1 + } + fn to_token(&self) -> LexerResult> { use super::token::UnparsedNumber; @@ -256,6 +271,7 @@ impl<'input> CallVariableParser<'input> { (false, true) => Ok(Token::JsonPath( self.string_to_parse, self.state.first_dot_met_pos.unwrap(), + self.state.flattening_met, )), } } diff --git a/crates/air-parser/src/parser/lexer/errors.rs b/crates/air-parser/src/parser/lexer/errors.rs index 12b8dd16..2e979153 100644 --- a/crates/air-parser/src/parser/lexer/errors.rs +++ b/crates/air-parser/src/parser/lexer/errors.rs @@ -53,6 +53,9 @@ pub enum LexerError { #[error("leading dot without any symbols before - please write 0 if it's float or variable name if it's json path")] LeadingDot(usize, usize), + + #[error("while using json path in call triplet, result should be flattened, add ! at the end")] + CallArgsNotFlattened(usize, usize), } impl From for LexerError { diff --git a/crates/air-parser/src/parser/lexer/tests.rs b/crates/air-parser/src/parser/lexer/tests.rs index 0403a453..afa2c751 100644 --- a/crates/air-parser/src/parser/lexer/tests.rs +++ b/crates/air-parser/src/parser/lexer/tests.rs @@ -269,24 +269,28 @@ fn too_big_float_number() { #[test] fn json_path() { // this json path contains all allowed in json path charactes - const JSON_PATH: &str = r#"value.$[$@[]():?.*,"!]"#; + const JSON_PATH: &str = r#"value.$[$@[]():?.*,"]"#; lexer_test( JSON_PATH, - Single(Ok((0, Token::JsonPath(JSON_PATH, 5), JSON_PATH.len()))), + Single(Ok(( + 0, + Token::JsonPath(JSON_PATH, 5, false), + JSON_PATH.len(), + ))), ); } #[test] fn json_path_numbers() { - const JSON_PATH: &str = r#"12345.$[$@[]():?.*,"!]"#; + const JSON_PATH: &str = r#"12345.$[$@[]():?.*,"]"#; lexer_test( JSON_PATH, Single(Err(LexerError::UnallowedCharInNumber(6, 6))), ); - const JSON_PATH1: &str = r#"+12345.$[$@[]():?.*,"!]"#; + const JSON_PATH1: &str = r#"+12345.$[$@[]():?.*,"]"#; lexer_test( JSON_PATH1, @@ -320,13 +324,21 @@ fn unclosed_quote() { #[test] fn bad_value() { - // value contains ! that only allowed in json path - const INVALID_VALUE: &str = r#"val!ue.$[$@[]():?.*,"\!]"#; + // value contains ! that only allowed at the end of a json path + const INVALID_VALUE: &str = r#"val!ue.$[$@[]():?.*,"\]"#; lexer_test( INVALID_VALUE, Single(Err(LexerError::IsNotAlphanumeric(3, 3))), ); + + // value contains ! that only allowed at the end of a json path + const INVALID_VALUE2: &str = r#"value.$![$@[]():?.*,"\]"#; + + lexer_test( + INVALID_VALUE2, + Single(Err(LexerError::InvalidJsonPath(7, 7))), + ); } #[test] diff --git a/crates/air-parser/src/parser/lexer/token.rs b/crates/air-parser/src/parser/lexer/token.rs index e2c98f65..416e2a07 100644 --- a/crates/air-parser/src/parser/lexer/token.rs +++ b/crates/air-parser/src/parser/lexer/token.rs @@ -26,7 +26,7 @@ pub enum Token<'input> { StringLiteral(&'input str), Alphanumeric(&'input str), - JsonPath(&'input str, usize), + JsonPath(&'input str, usize, bool), Accumulator(&'input str), Number(Number), Boolean(bool), diff --git a/crates/air-parser/src/parser/lexer/utils.rs b/crates/air-parser/src/parser/lexer/utils.rs index 31776668..660fe6df 100644 --- a/crates/air-parser/src/parser/lexer/utils.rs +++ b/crates/air-parser/src/parser/lexer/utils.rs @@ -37,7 +37,6 @@ pub(super) fn is_json_path_allowed_char(ch: char) -> bool { ',' => true, '"' => true, '\'' => true, - '!' => true, ch => is_aqua_alphanumeric(ch), } } diff --git a/crates/air-parser/src/parser/mod.rs b/crates/air-parser/src/parser/mod.rs index d5cef575..0bf2c875 100644 --- a/crates/air-parser/src/parser/mod.rs +++ b/crates/air-parser/src/parser/mod.rs @@ -30,7 +30,3 @@ pub mod tests; pub use self::air_parser::parse; pub use air::AIRParser; pub use lexer::AIRLexer; - -fn into_variable_and_path(str: &str, pos: usize) -> (&str, &str) { - (&str[0..pos], &str[pos + 1..]) -} diff --git a/crates/air-parser/src/parser/tests.rs b/crates/air-parser/src/parser/tests.rs index f9fd66fb..78227e53 100644 --- a/crates/air-parser/src/parser/tests.rs +++ b/crates/air-parser/src/parser/tests.rs @@ -123,13 +123,14 @@ fn parse_json_path() { use ast::PeerPart::*; let source_code = r#" - (call id.$.a "f" ["hello" name] void[]) + (call id.$.a! "f" ["hello" name] void[]) "#; let instruction = parse(source_code); let expected = Instruction::Call(Call { peer_part: PeerPk(CallInstrValue::JsonPath { variable: "id", path: "$.a", + should_flatten: true, }), function_part: FuncName(CallInstrValue::Literal("f")), args: Rc::new(vec![ @@ -141,6 +142,24 @@ fn parse_json_path() { assert_eq!(instruction, expected); } +#[test] +fn parse_json_path_without_flattening() { + let source_code = r#" + (call id.$.a "f" ["hello" name] void[]) + "#; + + let lexer = crate::AIRLexer::new(source_code); + + let parser = crate::AIRParser::new(); + let mut errors = Vec::new(); + parser + .parse(source_code, &mut errors, lexer) + .expect("parser shoudn't fail"); + + assert_eq!(errors.len(), 1); + assert!(matches!(errors[0], lalrpop_util::ErrorRecovery { .. })); +} + #[test] fn parse_json_path_complex() { use ast::Call; @@ -151,8 +170,8 @@ fn parse_json_path_complex() { let source_code = r#" (seq - (call m.$.[1] "f" [] void) - (call m.$.abc["c"].cde[a][0].cde["bcd"] "f" [] void) + (call m.$.[1]! "f" [] void) + (call m.$.abc["c"].cde[a][0].cde["bcd"]! "f" [] void) ) "#; let instruction = parse(source_code); @@ -161,6 +180,7 @@ fn parse_json_path_complex() { peer_part: PeerPk(CallInstrValue::JsonPath { variable: "m", path: "$.[1]", + should_flatten: true, }), function_part: FuncName(CallInstrValue::Literal("f")), args: Rc::new(vec![]), @@ -170,6 +190,7 @@ fn parse_json_path_complex() { peer_part: PeerPk(CallInstrValue::JsonPath { variable: "m", path: r#"$.abc["c"].cde[a][0].cde["bcd"]"#, + should_flatten: true, }), function_part: FuncName(CallInstrValue::Literal("f")), args: Rc::new(vec![]), @@ -189,13 +210,14 @@ fn json_path_square_braces() { use ast::PeerPart::*; let source_code = r#" - (call u.$["peer_id"] ("return" "") [u.$["peer_id"].cde[0]["abc"].abc u.$["name"]] void[]) + (call u.$["peer_id"]! ("return" "") [u.$["peer_id"].cde[0]["abc"].abc u.$["name"]] void[]) "#; let instruction = parse(source_code); let expected = Instruction::Call(Call { peer_part: PeerPk(CallInstrValue::JsonPath { variable: "u", path: r#"$["peer_id"]"#, + should_flatten: true, }), function_part: ServiceIdWithFuncName( CallInstrValue::Literal("return"), @@ -205,10 +227,12 @@ fn json_path_square_braces() { CallInstrArgValue::JsonPath { variable: "u", path: r#"$["peer_id"].cde[0]["abc"].abc"#, + should_flatten: false, }, CallInstrArgValue::JsonPath { variable: "u", path: r#"$["name"]"#, + should_flatten: false, }, ]), output: Accumulator("void"), @@ -600,6 +624,7 @@ fn fold_json_path() { iterable: JsonPath { variable: "members", path: "$.[\"users\"]", + should_flatten: false, }, iterator: "m", instruction: Rc::new(null()), @@ -622,6 +647,7 @@ fn comments() { iterable: JsonPath { variable: "members", path: "$.[\"users\"]", + should_flatten: false, }, iterator: "m", instruction: Rc::new(null()), diff --git a/interpreter-lib/Cargo.toml b/interpreter-lib/Cargo.toml index 0f62fc4f..5139c7de 100644 --- a/interpreter-lib/Cargo.toml +++ b/interpreter-lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "interpreter-lib" -version = "0.6.0" +version = "0.7.0" authors = ["Fluence Labs"] edition = "2018" @@ -17,7 +17,7 @@ aqua-interpreter-interface = { path = "../crates/interpreter-interface" } serde = { version = "=1.0.118", features = [ "derive", "rc" ] } serde_json = "=1.0.61" -jsonpath_lib-fl = "=0.2.6" +jsonpath_lib-fl = "=0.2.5" boolinator = "2.4.0" log = "0.4.11" diff --git a/interpreter-lib/src/execution/air/call/triplet.rs b/interpreter-lib/src/execution/air/call/triplet.rs index 31369d10..6f2d9cae 100644 --- a/interpreter-lib/src/execution/air/call/triplet.rs +++ b/interpreter-lib/src/execution/air/call/triplet.rs @@ -89,7 +89,14 @@ fn resolve_to_string<'i>(value: &CallInstrValue<'i>, ctx: &ExecutionCtx<'i>) -> let jvalue = resolved.into_jvalue(); jvalue_to_string(jvalue)? } - CallInstrValue::JsonPath { variable, path } => { + CallInstrValue::JsonPath { + variable, + path, + should_flatten, + } => { + // this is checked on the parsing stage + debug_assert!(*should_flatten); + let resolved = resolve_to_jvaluable(variable, ctx)?; let resolved = resolved.apply_json_path(path)?; vec_to_string(resolved, path)? diff --git a/interpreter-lib/src/execution/air/compare_matchable/compare_matchable.rs b/interpreter-lib/src/execution/air/compare_matchable/compare_matchable.rs index 860af767..95517bf8 100644 --- a/interpreter-lib/src/execution/air/compare_matchable/compare_matchable.rs +++ b/interpreter-lib/src/execution/air/compare_matchable/compare_matchable.rs @@ -50,7 +50,23 @@ pub(crate) fn are_matchable_eq<'ctx>( Ok(left_value == right_value) } - (JsonPath { variable: lv, path: lp }, JsonPath { variable: rv, path: rp }) => { + ( + JsonPath { + variable: lv, + path: lp, + should_flatten: lsf, + }, + JsonPath { + variable: rv, + path: rp, + should_flatten: rsf, + }, + ) => { + // TODO: improve comparison + if lsf != rsf { + return Ok(false); + } + let left_jvaluable = resolve_to_jvaluable(lv, exec_ctx)?; let left_value = left_jvaluable.apply_json_path(lp)?; @@ -91,14 +107,27 @@ fn compare_matchable<'ctx>( let jvalue = jvaluable.as_jvalue(); Ok(comparator(jvalue)) } - JsonPath { variable, path } => { + JsonPath { + variable, + path, + should_flatten, + } => { let jvaluable = resolve_to_jvaluable(variable, exec_ctx)?; let jvalues = jvaluable.apply_json_path(path)?; - if jvalues.len() != 1 { - return Ok(false); - } - Ok(comparator(Cow::Borrowed(jvalues[0]))) + let jvalue = if *should_flatten { + if jvalues.len() != 1 { + return Ok(false); + } + Cow::Borrowed(jvalues[0]) + } else { + let jvalue = jvalues.into_iter().cloned().collect::>(); + let jvalue = JValue::Array(jvalue); + + Cow::Owned(jvalue) + }; + + Ok(comparator(jvalue)) } } } diff --git a/interpreter-lib/src/execution/air/fold/utils.rs b/interpreter-lib/src/execution/air/fold/utils.rs index 4aa0c5ff..527112f9 100644 --- a/interpreter-lib/src/execution/air/fold/utils.rs +++ b/interpreter-lib/src/execution/air/fold/utils.rs @@ -37,7 +37,11 @@ pub(super) fn construct_iterable_value<'ctx>( ) -> ExecutionResult> { match ast_iterable { ast::IterableValue::Variable(name) => handle_instruction_variable(exec_ctx, name), - ast::IterableValue::JsonPath { variable, path } => handle_instruction_json_path(exec_ctx, variable, path), + ast::IterableValue::JsonPath { + variable, + path, + should_flatten, + } => handle_instruction_json_path(exec_ctx, variable, path, *should_flatten), } } @@ -97,13 +101,14 @@ fn handle_instruction_json_path<'ctx>( exec_ctx: &ExecutionCtx<'ctx>, variable_name: &str, json_path: &str, + should_flatten: bool, ) -> ExecutionResult> { use ExecutionError::JValueAccJsonPathError; - let iterable: Option = match exec_ctx.data_cache.get(variable_name) { + match exec_ctx.data_cache.get(variable_name) { Some(AValue::JValueRef(variable)) => { let jvalues = apply_json_path(&variable.result, json_path)?; - from_jvalues(jvalues, variable.triplet.clone(), json_path) + from_jvalues(jvalues, variable.triplet.clone(), json_path, should_flatten) } Some(AValue::JValueAccumulatorRef(acc)) => { let acc = acc.borrow(); @@ -115,7 +120,7 @@ fn handle_instruction_json_path<'ctx>( let (jvalues, tetraplet_indices) = select_with_iter(acc_iter, &json_path) .map_err(|e| JValueAccJsonPathError(acc.clone(), json_path.to_string(), e))?; - let jvalues = jvalues.into_iter().cloned().collect(); + let jvalues = construct_iterable_jvalues(jvalues, should_flatten)?; let tetraplets = tetraplet_indices .into_iter() .map(|id| SecurityTetraplet { @@ -125,19 +130,17 @@ fn handle_instruction_json_path<'ctx>( .collect::>(); let foldable = IterableVecJsonPathResult::init(jvalues, tetraplets); - Some(Box::new(foldable)) + Ok(Some(Box::new(foldable))) } Some(AValue::JValueFoldCursor(fold_state)) => { let iterable_value = fold_state.iterable.peek().unwrap(); let jvalues = iterable_value.apply_json_path(json_path)?; let triplet = as_triplet(&iterable_value); - from_jvalues(jvalues, triplet, json_path) + from_jvalues(jvalues, triplet, json_path, should_flatten) } _ => return exec_err!(ExecutionError::VariableNotFound(variable_name.to_string())), - }; - - Ok(iterable) + } } fn apply_json_path<'jvalue, 'str>( @@ -150,12 +153,17 @@ fn apply_json_path<'jvalue, 'str>( } /// Applies json_path to provided jvalues and construct IterableValue from the result and given triplet. -fn from_jvalues(jvalues: Vec<&JValue>, triplet: Rc, json_path: &str) -> Option { +fn from_jvalues( + jvalues: Vec<&JValue>, + triplet: Rc, + json_path: &str, + should_flatten: bool, +) -> ExecutionResult> { if jvalues.is_empty() { - return None; + return Ok(None); } - let jvalues = jvalues.into_iter().cloned().collect(); + let jvalues = construct_iterable_jvalues(jvalues, should_flatten)?; let tetraplet = SecurityTetraplet { triplet, @@ -163,7 +171,29 @@ fn from_jvalues(jvalues: Vec<&JValue>, triplet: Rc, json_path: }; let foldable = IterableJsonPathResult::init(jvalues, tetraplet); - Some(Box::new(foldable)) + Ok(Some(Box::new(foldable))) +} + +fn construct_iterable_jvalues(jvalues: Vec<&JValue>, should_flatten: bool) -> ExecutionResult> { + if !should_flatten { + let jvalues = jvalues.into_iter().cloned().collect(); + return Ok(jvalues); + } + + if jvalues.len() != 1 { + let jvalues = jvalues.into_iter().cloned().collect(); + let jvalue = JValue::Array(jvalues); + return exec_err!(ExecutionError::FlatteningError(jvalue)); + } + + match jvalues[0] { + JValue::Array(values) => Ok(values.into_iter().cloned().collect::>()), + _ => { + let jvalues = jvalues.into_iter().cloned().collect(); + let jvalue = JValue::Array(jvalues); + exec_err!(ExecutionError::FlatteningError(jvalue)) + } + } } fn as_triplet(iterable: &IterableItem<'_>) -> Rc { diff --git a/interpreter-lib/src/execution/air/mod.rs b/interpreter-lib/src/execution/air/mod.rs index d086ff4e..39c5497b 100644 --- a/interpreter-lib/src/execution/air/mod.rs +++ b/interpreter-lib/src/execution/air/mod.rs @@ -44,7 +44,6 @@ macro_rules! execute { } let instruction = format!("{}", $self); - println!("set error on {}", instruction); let last_error = LastErrorDescriptor::new(e.clone(), instruction, None); $exec_ctx.last_error = Some(last_error); Err(e) diff --git a/interpreter-lib/src/execution/errors.rs b/interpreter-lib/src/execution/errors.rs index 6f7618a3..3bcb68df 100644 --- a/interpreter-lib/src/execution/errors.rs +++ b/interpreter-lib/src/execution/errors.rs @@ -91,6 +91,10 @@ pub(crate) enum ExecutionError { /// This error type is produced by a mismatch to notify xor that compared values aren't equal. #[error("mismatch is used without corresponding xor")] MismatchWithoutXorError, + + /// This error type is produced by a mismatch to notify xor that compared values aren't equal. + #[error("jvalue '{0}' can't be flattened, to be flattened a jvalue should have an array type and consist only one value")] + FlatteningError(JValue), } impl ExecutionError { @@ -114,6 +118,7 @@ impl ExecutionError { ShadowingError(_) => 14, MatchWithoutXorError => 15, MismatchWithoutXorError => 16, + FlatteningError(_) => 17, } } } diff --git a/interpreter-lib/src/execution/utils/resolve.rs b/interpreter-lib/src/execution/utils/resolve.rs index 52f0ddb0..53c92a66 100644 --- a/interpreter-lib/src/execution/utils/resolve.rs +++ b/interpreter-lib/src/execution/utils/resolve.rs @@ -36,7 +36,11 @@ pub(crate) fn resolve_to_args<'i>( CallInstrArgValue::Boolean(value) => prepare_consts(*value, ctx), CallInstrArgValue::Number(value) => prepare_consts(value, ctx), CallInstrArgValue::Variable(name) => prepare_variable(name, ctx), - CallInstrArgValue::JsonPath { variable, path } => prepare_json_path(variable, path, ctx), + CallInstrArgValue::JsonPath { + variable, + path, + should_flatten, + } => prepare_json_path(variable, path, *should_flatten, ctx), } } @@ -84,12 +88,22 @@ fn prepare_variable<'i>(name: &str, ctx: &ExecutionCtx<'i>) -> ExecutionResult<( fn prepare_json_path<'i>( name: &str, json_path: &str, + should_flatten: bool, ctx: &ExecutionCtx<'i>, ) -> ExecutionResult<(JValue, Vec)> { let resolved = resolve_to_jvaluable(name, ctx)?; let (jvalue, tetraplets) = resolved.apply_json_path_with_tetraplets(json_path)?; - let jvalue = jvalue.into_iter().cloned().collect::>(); - let jvalue = JValue::Array(jvalue); + + let jvalue = if should_flatten { + if jvalue.len() != 1 { + let jvalue = jvalue.into_iter().cloned().collect::>(); + return crate::exec_err!(ExecutionError::FlatteningError(JValue::Array(jvalue))); + } + jvalue[0].clone() + } else { + let jvalue = jvalue.into_iter().cloned().collect::>(); + JValue::Array(jvalue) + }; Ok((jvalue, tetraplets)) } diff --git a/interpreter-lib/tests/flattening.rs b/interpreter-lib/tests/flattening.rs new file mode 100644 index 00000000..172eefc0 --- /dev/null +++ b/interpreter-lib/tests/flattening.rs @@ -0,0 +1,209 @@ +/* + * 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 aqua_test_utils::call_vm; +use aqua_test_utils::create_aqua_vm; +use aqua_test_utils::set_variable_call_service; +use aqua_test_utils::CallServiceClosure; +use aqua_test_utils::IValue; +use aqua_test_utils::NEVec; + +use serde_json::json; + +use std::cell::RefCell; +use std::rc::Rc; + +type ClosureSettableVar = Rc>; + +#[derive(Default, Clone, Debug, PartialEq, Eq)] +struct ClosureCallArgs { + pub(self) service_id_var: Rc>, + pub(self) function_name_var: ClosureSettableVar, + pub(self) args_var: ClosureSettableVar>, + pub(self) tetraplets: ClosureSettableVar>>, +} + +fn create_check_service_closure(closure_call_args: ClosureCallArgs) -> CallServiceClosure { + Box::new(move |_, args| -> Option { + use std::ops::Deref; + + let service_id = match &args[0] { + IValue::String(str) => str, + _ => unreachable!(), + }; + *closure_call_args.service_id_var.deref().borrow_mut() = service_id.clone(); + + let function_name = match &args[1] { + IValue::String(str) => str, + _ => unreachable!(), + }; + *closure_call_args.function_name_var.deref().borrow_mut() = function_name.clone(); + + let call_args = match &args[2] { + IValue::String(str) => str, + _ => unreachable!(), + }; + + let call_args: Vec = serde_json::from_str(call_args).expect("json deserialization shouldn't fail"); + *closure_call_args.args_var.deref().borrow_mut() = call_args; + + Some(IValue::Record( + NEVec::new(vec![IValue::S32(0), IValue::String(r#""""#.to_string())]).unwrap(), + )) + }) +} + +#[test] +fn flattening_scalar_arrays() { + let scalar_array = json!({"iterable": [ + {"peer_id" : "local_peer_id", "service_id": "local_service_id", "function_name": "local_function_name", "args": [0, 1]}, + {"peer_id" : "local_peer_id", "service_id": "local_service_id", "function_name": "local_function_name", "args": [2, 3]}, + ]}); + + let scalar_array = serde_json::to_string(&scalar_array).expect("the default serializer shouldn't fail"); + let set_variable_peer_id = "set_variable"; + let mut set_variable_vm = create_aqua_vm(set_variable_call_service(scalar_array), set_variable_peer_id); + + let closure_call_args = ClosureCallArgs::default(); + let local_peer_id = "local_peer_id"; + let mut local_vm = create_aqua_vm(create_check_service_closure(closure_call_args.clone()), local_peer_id); + + let script = format!( + r#" + (seq + (call "{0}" ("" "") [] scalar_array) + (fold scalar_array.$.iterable! v + (seq + (call v.$.peer_id! (v.$.service_id! v.$.function_name!) [v.$.args[0]! v.$.args[1]!]) + (next v) + ) + ) + ) + "#, + set_variable_peer_id + ); + + let res = call_vm!(set_variable_vm, "asd", script.clone(), "", ""); + let res = call_vm!(local_vm, "asd", script.clone(), "", res.data); + + assert_eq!(res.ret_code, 0); + assert_eq!( + closure_call_args.service_id_var, + Rc::new(RefCell::new("local_service_id".to_string())) + ); + assert_eq!( + closure_call_args.function_name_var, + Rc::new(RefCell::new("local_function_name".to_string())) + ); + assert_eq!(closure_call_args.args_var, Rc::new(RefCell::new(vec![2, 3]))); +} + +#[test] +fn flattening_streams() { + let stream_value = json!( + {"peer_id" : "local_peer_id", "service_id": "local_service_id", "function_name": "local_function_name", "args": [0, 1]} + ); + + let stream_value = serde_json::to_string(&stream_value).expect("the default serializer shouldn't fail"); + let set_variable_peer_id = "set_variable"; + let mut set_variable_vm = create_aqua_vm(set_variable_call_service(stream_value), set_variable_peer_id); + + let closure_call_args = ClosureCallArgs::default(); + let local_peer_id = "local_peer_id"; + let mut local_vm = create_aqua_vm(create_check_service_closure(closure_call_args.clone()), local_peer_id); + + let script = format!( + r#" + (seq + (seq + (seq + (call "{0}" ("" "") [] stream[]) + (call "{0}" ("" "") [] stream[]) + ) + (call "{0}" ("" "") [] stream[]) + ) + (fold stream.$.[0,1,2] v + (seq + (call v.$.peer_id! (v.$.service_id! v.$.function_name!) [v.$.args[0]! v.$.args[1]!]) + (next v) + ) + ) + ) + "#, + set_variable_peer_id + ); + + let res = call_vm!(set_variable_vm, "asd", script.clone(), "", ""); + let res = call_vm!(local_vm, "asd", script.clone(), "", res.data); + + assert_eq!(res.ret_code, 0); + assert_eq!( + closure_call_args.service_id_var, + Rc::new(RefCell::new("local_service_id".to_string())) + ); + assert_eq!( + closure_call_args.function_name_var, + Rc::new(RefCell::new("local_function_name".to_string())) + ); + assert_eq!(closure_call_args.args_var, Rc::new(RefCell::new(vec![0, 1]))); +} + +#[test] +fn test_handling_non_flattening_values() { + let stream_value = json!( + {"peer_id" : "local_peer_id", "service_id": "local_service_id", "function_name": "local_function_name", "args": [0, 1]} + ); + + let stream_value = serde_json::to_string(&stream_value).expect("the default serializer shouldn't fail"); + let set_variable_peer_id = "set_variable"; + let mut set_variable_vm = create_aqua_vm(set_variable_call_service(stream_value), set_variable_peer_id); + + let closure_call_args = ClosureCallArgs::default(); + let local_peer_id = "local_peer_id"; + let mut local_vm = create_aqua_vm(create_check_service_closure(closure_call_args.clone()), local_peer_id); + + let script = format!( + r#" + (seq + (seq + (seq + (call "{0}" ("" "") [] stream[]) + (call "{0}" ("" "") [] stream[]) + ) + (call "{0}" ("" "") [] stream[]) + ) + (fold stream.$.[0,1,2]! v + (seq + (call v.$.peer_id! (v.$.service_id! v.$.function_name!) [v.$.args[0]! v.$.args[1]!]) + (next v) + ) + ) + ) + "#, + set_variable_peer_id + ); + + let res = call_vm!(set_variable_vm, "asd", script.clone(), "", ""); + let res = call_vm!(local_vm, "asd", script.clone(), "", res.data); + + assert_eq!(res.ret_code, 1017); + assert_eq!( + res.error_message, + String::from( + r#"jvalue '[{"peer_id":"local_peer_id","service_id":"local_service_id","function_name":"local_function_name","args":[0,1]},{"peer_id":"local_peer_id","service_id":"local_service_id","function_name":"local_function_name","args":[0,1]},{"peer_id":"local_peer_id","service_id":"local_service_id","function_name":"local_function_name","args":[0,1]}]' can't be flattened, to be flattened a jvalue should have an array type and consist only one value"# + ) + ); +} diff --git a/interpreter-lib/tests/join.rs b/interpreter-lib/tests/join.rs index 3292b6a7..7c39dc10 100644 --- a/interpreter-lib/tests/join.rs +++ b/interpreter-lib/tests/join.rs @@ -57,8 +57,8 @@ fn join_chat() { (fold members m (par (seq - (call m.$.[1] ("identity" "") [] void[]) - (call m.$.[0] ("fgemb3" "add") [] void3[]) + (call m.$.[1]! ("identity" "") [] void[]) + (call m.$.[0]! ("fgemb3" "add") [] void3[]) ) (next m) ) diff --git a/interpreter/Cargo.toml b/interpreter/Cargo.toml index aed77da1..0eaaabd0 100644 --- a/interpreter/Cargo.toml +++ b/interpreter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aquamarine" -version = "0.6.0" +version = "0.7.0" authors = ["Fluence Labs"] edition = "2018"