From 709b5e0a52a65a88d58bb2859ed6726e33eff47f Mon Sep 17 00:00:00 2001 From: vms Date: Mon, 1 Feb 2021 18:53:00 +0300 Subject: [PATCH] Introduce mismatch (#62) --- Cargo.lock | 4 +- crates/air-parser/src/parser/air.lalrpop | 11 +- crates/air-parser/src/parser/air.rs | 695 ++++++++++-------- crates/air-parser/src/parser/ast.rs | 18 +- .../air-parser/src/parser/lexer/air_lexer.rs | 2 + crates/air-parser/src/parser/lexer/tests.rs | 26 + crates/air-parser/src/parser/lexer/token.rs | 1 + crates/air-parser/src/parser/tests.rs | 58 ++ .../compare_matchable/compare_matchable.rs | 90 +++ .../execution/air/compare_matchable/mod.rs | 19 + stepper-lib/src/execution/air/match_.rs | 81 +- stepper-lib/src/execution/air/mismatch.rs | 193 +++++ stepper-lib/src/execution/air/mod.rs | 3 + 13 files changed, 810 insertions(+), 391 deletions(-) create mode 100644 stepper-lib/src/execution/air/compare_matchable/compare_matchable.rs create mode 100644 stepper-lib/src/execution/air/compare_matchable/mod.rs create mode 100644 stepper-lib/src/execution/air/mismatch.rs diff --git a/Cargo.lock b/Cargo.lock index bd71621c..6df85f38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -57,7 +57,7 @@ dependencies = [ [[package]] name = "aquamarine" -version = "0.3.0" +version = "0.4.1" dependencies = [ "fluence", "log", @@ -1693,7 +1693,7 @@ dependencies = [ [[package]] name = "stepper-lib" -version = "0.4.0" +version = "0.4.1" dependencies = [ "air-parser", "aqua-test-utils", diff --git a/crates/air-parser/src/parser/air.lalrpop b/crates/air-parser/src/parser/air.lalrpop index 2d64a1d4..42430359 100644 --- a/crates/air-parser/src/parser/air.lalrpop +++ b/crates/air-parser/src/parser/air.lalrpop @@ -31,7 +31,15 @@ Instr: Box> = { "(" xor ")" => Box::new(Instruction::Xor(Xor(l, r))), - "(" match_ ")" => Box::new(Instruction::Match(Match(l, r, i))), + "(" match_ ")" => { + let match_ = Match { left_value: l, right_value: r, instruction: i}; + Box::new(Instruction::Match(match_)) + }, + + "(" mismatch ")" => { + let mismatch = MisMatch { left_value: l, right_value: r, instruction: i}; + Box::new(Instruction::MisMatch(mismatch)) + }, ! => { errors.push(<>); Box::new(Instruction::Error) }, } @@ -112,5 +120,6 @@ extern { xor => Token::Xor, next => Token::Next, match_ => Token::Match, + mismatch => Token::MisMatch, } } diff --git a/crates/air-parser/src/parser/air.rs b/crates/air-parser/src/parser/air.rs index d67e7029..55ad43bf 100644 --- a/crates/air-parser/src/parser/air.rs +++ b/crates/air-parser/src/parser/air.rs @@ -1,5 +1,5 @@ // auto-generated: "lalrpop 0.19.1" -// sha256: bb2efa4b9cde2613385df98e0d4cbff3b9851ed43c3eaa46d3a6773f1b0913b +// sha256: 1893aaaa3cc9f281c81afab956e5d868b6d3124e663cdaa9f4652925d0d0f7 use crate::parser::ast::*; use crate::parser::into_variable_and_path; use crate::parser::lexer::LexerError; @@ -46,148 +46,158 @@ mod __parse__AIR { } const __ACTION: &[i8] = &[ // State 0 - 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, // State 1 - 9, 0, 0, 0, 0, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 0, 34, 35, 36, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 2 - 0, 0, 0, 0, 0, 36, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 39, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 3 - 0, 0, 0, 0, 0, 38, 0, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 4 - 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 0, 0, 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 5 - 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, // State 6 - 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, // State 7 - 15, 0, 0, 0, 0, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, // State 8 - 0, 0, 0, 0, 0, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 0, 34, 35, 36, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 9 - 0, 0, 0, 0, 0, 38, 0, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 34, 35, 36, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 10 - 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 0, 0, 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 11 - 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 0, 0, 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 12 - 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, // State 13 - 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, // State 14 - 0, 0, 0, 0, 0, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, // State 15 - 0, 0, 0, 0, 0, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 16 - 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 0, 0, 0, 0, 0, 34, 35, 36, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 17 - 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 0, 0, 0, 0, 0, 34, 35, 36, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 18 - 0, 57, 0, 0, 58, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, // State 19 - 0, 0, 0, 62, 0, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, // State 20 - 0, 0, 0, 0, 0, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, // State 21 - 0, 0, 0, 69, 0, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 61, 0, 0, 62, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 22 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 66, 0, 34, 35, 36, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 23 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 34, 35, 36, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 24 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 27, 28, 5, 6, 7, 0, + 0, 0, 0, 74, 0, 34, 35, 36, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 25 - -26, -26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 26 - 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 27 - 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 30, 31, 6, 7, 8, 0, // State 28 - -36, 0, 0, 0, 0, -36, -36, -36, -36, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -27, -27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -27, // State 29 - -37, 0, 0, 0, 0, -37, -37, -37, -37, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 30 - -11, -11, -11, -11, 0, -11, -11, -11, -11, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 31 - -13, -13, -13, -13, 0, -13, -13, -13, -13, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -37, 0, 0, 0, 0, -37, -37, -37, -37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 32 - -12, -12, -12, -12, 0, -12, -12, -12, -12, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -38, 0, 0, 0, 0, -38, -38, -38, -38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 33 - -10, -10, -10, -10, 0, -10, -10, -10, -10, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -11, -11, -11, -11, 0, -11, -11, -11, -11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 34 - 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -13, -13, -13, -13, 0, -13, -13, -13, -13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 35 - 0, 0, 0, 0, 0, -27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -12, -12, -12, -12, 0, -12, -12, -12, -12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 36 - 0, 0, 0, 0, 0, -28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -10, -10, -10, -10, 0, -10, -10, -10, -10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 37 - -29, 0, 0, 0, 0, -29, 0, -29, -29, 0, 0, 0, 0, 0, 0, 0, 0, -29, + 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 38 - -31, 0, 0, 0, 0, -31, 0, -31, -31, 0, 0, 0, 0, 0, 0, 0, 0, -31, + 0, 0, 0, 0, 0, -28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 39 - -30, 0, 0, 0, 0, -30, 0, -30, -30, 0, 0, 0, 0, 0, 0, 0, 0, -30, + 0, 0, 0, 0, 0, -29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 40 - 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -30, 0, 0, 0, 0, -30, 0, -30, -30, 0, 0, 0, 0, 0, 0, 0, 0, 0, -30, // State 41 - -21, -21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -21, + -32, 0, 0, 0, 0, -32, 0, -32, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, -32, // State 42 - 0, -16, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -31, 0, 0, 0, 0, -31, 0, -31, -31, 0, 0, 0, 0, 0, 0, 0, 0, 0, -31, // State 43 - 0, 0, -14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 44 - -23, -23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -23, + -21, -21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -21, // State 45 - 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -16, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 46 - 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 47 - 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -23, -23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -23, // State 48 - 0, -39, 0, 0, 0, -39, -39, -39, -39, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 49 - 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 50 - 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 51 - 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -40, 0, 0, 0, -40, -40, -40, -40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 52 - -20, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -20, + 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 53 - -19, -19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -19, + 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 54 - -24, -24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -24, + 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 55 - 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 56 - -18, -18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -18, + -20, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -20, // State 57 - 0, -33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -19, -19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -19, // State 58 - 0, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -24, -24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -24, // State 59 - 0, 0, 0, -4, 0, -4, -4, -4, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 60 - 0, 0, 0, -7, 0, -7, -7, -7, -7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -18, -18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -18, // State 61 - 0, -8, 0, 0, -8, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 62 - 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 63 - -38, 0, 0, 0, 0, -38, -38, -38, -38, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -4, 0, -4, -4, -4, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 64 - -22, -22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -22, + 0, 0, 0, -7, 0, -7, -7, -7, -7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 65 - -25, -25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -25, + 0, -8, 0, 0, -8, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 66 - -17, -17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -17, + 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 67 - 0, 0, 0, -5, 0, -5, -5, -5, -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -39, 0, 0, 0, 0, -39, -39, -39, -39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 68 - 0, -9, 0, 0, -9, -9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -22, -22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -22, // State 69 - 0, 0, -15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -25, -25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -25, + // State 70 + -26, -26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -26, + // State 71 + -17, -17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -17, + // State 72 + 0, 0, 0, -5, 0, -5, -5, -5, -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 73 + 0, -9, 0, 0, -9, -9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 74 + 0, 0, -15, 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) * 18 + integer] + __ACTION[(state as usize) * 19 + integer] } const __EOF_ACTION: &[i8] = &[ // State 0 @@ -235,19 +245,19 @@ mod __parse__AIR { // State 21 0, // State 22 - -40, + 0, // State 23 - -6, + 0, // State 24 0, // State 25 - -26, + -41, // State 26 - 0, + -6, // State 27 0, // State 28 - 0, + -27, // State 29 0, // State 30 @@ -273,19 +283,19 @@ mod __parse__AIR { // State 40 0, // State 41 - -21, + 0, // State 42 0, // State 43 0, // State 44 - -23, + -21, // State 45 0, // State 46 0, // State 47 - 0, + -23, // State 48 0, // State 49 @@ -295,23 +305,23 @@ mod __parse__AIR { // State 51 0, // State 52 - -20, + 0, // State 53 - -19, + 0, // State 54 - -24, + 0, // State 55 0, // State 56 - -18, + -20, // State 57 - 0, + -19, // State 58 - 0, + -24, // State 59 0, // State 60 - 0, + -18, // State 61 0, // State 62 @@ -319,63 +329,76 @@ mod __parse__AIR { // State 63 0, // State 64 - -22, + 0, // State 65 - -25, + 0, // State 66 - -17, + 0, // State 67 0, // State 68 - 0, + -22, // State 69 + -25, + // State 70 + -26, + // State 71 + -17, + // State 72 + 0, + // State 73 + 0, + // State 74 0, ]; fn __goto(state: i8, nt: usize) -> i8 { match nt { - 2 => 21, - 3 => 22, + 2 => 24, + 3 => 25, 4 => match state { - 21 => 67, - _ => 59, + 24 => 72, + _ => 63, }, - 5 => 18, + 5 => 21, 6 => match state { - 7 | 20 => 42, - 14..=15 => 48, - 19 | 21 => 60, - _ => 28, + 8 | 23 => 45, + 16..=17 => 51, + 22 | 24 => 64, + _ => 31, }, - 7 => 13, + 7 => 15, 8 => match state { - 20 => 62, - _ => 43, + 23 => 66, + _ => 46, }, 9 => match state { - 5 => 11, - 6 => 12, - 0 => 23, - 10 => 45, - 11 => 46, - 12 => 47, - 16 => 50, - 17 => 51, + 6 => 13, + 7 => 14, + 0 => 26, + 12 => 48, + 13 => 49, + 14 => 50, + 18 => 53, + 19 => 54, + 20 => 55, + _ => 12, + }, + 10 => 37, + 11 => match state { + 4 => 11, + 10 => 19, + 11 => 20, _ => 10, }, - 10 => 34, - 11 => match state { - 9 => 17, - _ => 9, - }, - 12 => 55, + 12 => 59, 14 => match state { - 1 => 29, - _ => 15, + 1 => 32, + _ => 17, }, - 15 => 7, + 15 => 8, 16 => match state { - 15 => 49, - _ => 20, + 17 => 52, + _ => 23, }, _ => 0, } @@ -394,6 +417,7 @@ mod __parse__AIR { r###"call"###, r###"fold"###, r###"match_"###, + r###"mismatch"###, r###"next"###, r###"null"###, r###"par"###, @@ -452,7 +476,7 @@ mod __parse__AIR { #[inline] fn error_action(&self, state: i8) -> i8 { - __action(state, 18 - 1) + __action(state, 19 - 1) } #[inline] @@ -529,11 +553,12 @@ mod __parse__AIR { Token::Call if true => Some(9), Token::Fold if true => Some(10), Token::Match if true => Some(11), - Token::Next if true => Some(12), - Token::Null if true => Some(13), - Token::Par if true => Some(14), - Token::Seq if true => Some(15), - Token::Xor if true => Some(16), + Token::MisMatch if true => Some(12), + Token::Next if true => Some(13), + Token::Null if true => Some(14), + Token::Par if true => Some(15), + Token::Seq if true => Some(16), + Token::Xor if true => Some(17), _ => None, } } @@ -547,7 +572,7 @@ mod __parse__AIR { ) -> __Symbol<'input> { match __token_index { - 0 | 1 | 2 | 3 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 => __Symbol::Variant0(__token), + 0 | 1 | 2 | 3 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 => __Symbol::Variant0(__token), 4 | 5 | 8 => match __token { Token::Accumulator(__tok0) | Token::Alphanumeric(__tok0) | Token::StringLiteral(__tok0) if true => __Symbol::Variant1(__tok0), _ => unreachable!(), @@ -722,14 +747,14 @@ mod __parse__AIR { } 25 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 6, nonterminal_produced: 9, } } 26 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 10, + nonterminal_produced: 9, } } 27 => { @@ -741,7 +766,7 @@ mod __parse__AIR { 28 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 11, + nonterminal_produced: 10, } } 29 => { @@ -759,7 +784,7 @@ mod __parse__AIR { 31 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 12, + nonterminal_produced: 11, } } 32 => { @@ -771,40 +796,46 @@ mod __parse__AIR { 33 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 13, + nonterminal_produced: 12, } } 34 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, + states_to_pop: 1, nonterminal_produced: 13, } } 35 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 14, + states_to_pop: 0, + nonterminal_produced: 13, } } 36 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 15, + nonterminal_produced: 14, } } 37 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, + states_to_pop: 1, nonterminal_produced: 15, } } 38 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 4, + nonterminal_produced: 15, + } + } + 39 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, nonterminal_produced: 16, } } - 39 => __state_machine::SimulatedReduce::Accept, + 40 => __state_machine::SimulatedReduce::Accept, _ => panic!("invalid reduction index {}", __reduce_index) } } @@ -1013,6 +1044,9 @@ mod __parse__AIR { __reduce38(input, errors, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) } 39 => { + __reduce39(input, errors, __lookahead_start, __symbols, ::std::marker::PhantomData::<(&(), &())>) + } + 40 => { // __AIR = AIR => ActionFn(0); let __sym0 = __pop_Variant6(__symbols); let __start = __sym0.0.clone(); @@ -1198,11 +1232,11 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // () = Arg => ActionFn(33); + // () = Arg => ActionFn(34); let __sym0 = __pop_Variant4(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action33::<>(input, errors, __sym0); + let __nt = super::__action34::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant4(__nt), __end)); (1, 0) } @@ -1217,10 +1251,10 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // ()* = => ActionFn(31); + // ()* = => ActionFn(32); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action31::<>(input, errors, &__start, &__end); + let __nt = super::__action32::<>(input, errors, &__start, &__end); __symbols.push((__start, __Symbol::Variant5(__nt), __end)); (0, 1) } @@ -1235,11 +1269,11 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // ()* = ()+ => ActionFn(32); + // ()* = ()+ => ActionFn(33); let __sym0 = __pop_Variant5(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action32::<>(input, errors, __sym0); + let __nt = super::__action33::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant5(__nt), __end)); (1, 1) } @@ -1254,11 +1288,11 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // ()+ = Arg => ActionFn(38); + // ()+ = Arg => ActionFn(39); let __sym0 = __pop_Variant4(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action38::<>(input, errors, __sym0); + let __nt = super::__action39::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant5(__nt), __end)); (1, 2) } @@ -1273,13 +1307,13 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // ()+ = ()+, Arg => ActionFn(39); + // ()+ = ()+, Arg => ActionFn(40); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant4(__symbols); let __sym0 = __pop_Variant5(__symbols); let __start = __sym0.0.clone(); let __end = __sym1.2.clone(); - let __nt = super::__action39::<>(input, errors, __sym0, __sym1); + let __nt = super::__action40::<>(input, errors, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant5(__nt), __end)); (2, 2) } @@ -1313,11 +1347,11 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Arg = CallArgValue => ActionFn(21); + // Arg = CallArgValue => ActionFn(22); let __sym0 = __pop_Variant4(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action21::<>(input, errors, __sym0); + let __nt = super::__action22::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant4(__nt), __end)); (1, 4) } @@ -1332,13 +1366,13 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Args = "[", "]" => ActionFn(40); + // Args = "[", "]" => ActionFn(41); 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::__action40::<>(input, errors, __sym0, __sym1); + let __nt = super::__action41::<>(input, errors, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant7(__nt), __end)); (2, 5) } @@ -1353,14 +1387,14 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Args = "[", ()+, "]" => ActionFn(41); + // Args = "[", ()+, "]" => ActionFn(42); assert!(__symbols.len() >= 3); let __sym2 = __pop_Variant0(__symbols); let __sym1 = __pop_Variant5(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym2.2.clone(); - let __nt = super::__action41::<>(input, errors, __sym0, __sym1, __sym2); + let __nt = super::__action42::<>(input, errors, __sym0, __sym1, __sym2); __symbols.push((__start, __Symbol::Variant7(__nt), __end)); (3, 5) } @@ -1375,11 +1409,11 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // CallArgValue = Literal => ActionFn(22); + // CallArgValue = Literal => ActionFn(23); let __sym0 = __pop_Variant1(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action22::<>(input, errors, __sym0); + let __nt = super::__action23::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant4(__nt), __end)); (1, 6) } @@ -1394,11 +1428,11 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // CallArgValue = Alphanumeric => ActionFn(23); + // CallArgValue = Alphanumeric => ActionFn(24); let __sym0 = __pop_Variant1(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action23::<>(input, errors, __sym0); + let __nt = super::__action24::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant4(__nt), __end)); (1, 6) } @@ -1413,11 +1447,11 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // CallArgValue = JsonPath => ActionFn(24); + // CallArgValue = JsonPath => ActionFn(25); let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action24::<>(input, errors, __sym0); + let __nt = super::__action25::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant4(__nt), __end)); (1, 6) } @@ -1432,11 +1466,11 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // CallArgValue = InitPeerId => ActionFn(25); + // CallArgValue = InitPeerId => ActionFn(26); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action25::<>(input, errors, __sym0); + let __nt = super::__action26::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant4(__nt), __end)); (1, 6) } @@ -1451,11 +1485,11 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // FPart = Function => ActionFn(12); + // FPart = Function => ActionFn(13); let __sym0 = __pop_Variant4(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action12::<>(input, errors, __sym0); + let __nt = super::__action13::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (1, 7) } @@ -1470,7 +1504,7 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // FPart = "(", ServiceId, Function, ")" => ActionFn(13); + // FPart = "(", ServiceId, Function, ")" => ActionFn(14); assert!(__symbols.len() >= 4); let __sym3 = __pop_Variant0(__symbols); let __sym2 = __pop_Variant4(__symbols); @@ -1478,7 +1512,7 @@ mod __parse__AIR { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym3.2.clone(); - let __nt = super::__action13::<>(input, errors, __sym0, __sym1, __sym2, __sym3); + let __nt = super::__action14::<>(input, errors, __sym0, __sym1, __sym2, __sym3); __symbols.push((__start, __Symbol::Variant8(__nt), __end)); (4, 7) } @@ -1493,11 +1527,11 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Function = CallArgValue => ActionFn(18); + // Function = CallArgValue => ActionFn(19); let __sym0 = __pop_Variant4(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action18::<>(input, errors, __sym0); + let __nt = super::__action19::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant4(__nt), __end)); (1, 8) } @@ -1512,7 +1546,7 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Instr = "(", call, PeerPart, FPart, Args, Output, ")" => ActionFn(42); + // Instr = "(", call, PeerPart, FPart, Args, Output, ")" => ActionFn(43); assert!(__symbols.len() >= 7); let __sym6 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant11(__symbols); @@ -1523,7 +1557,7 @@ mod __parse__AIR { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym6.2.clone(); - let __nt = super::__action42::<>(input, errors, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); + let __nt = super::__action43::<>(input, errors, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); __symbols.push((__start, __Symbol::Variant6(__nt), __end)); (7, 9) } @@ -1538,7 +1572,7 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Instr = "(", call, PeerPart, FPart, Args, ")" => ActionFn(43); + // Instr = "(", call, PeerPart, FPart, Args, ")" => ActionFn(44); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); let __sym4 = __pop_Variant7(__symbols); @@ -1548,7 +1582,7 @@ mod __parse__AIR { let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym5.2.clone(); - let __nt = super::__action43::<>(input, errors, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __nt = super::__action44::<>(input, errors, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant6(__nt), __end)); (6, 9) } @@ -1730,13 +1764,19 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Instr = error => ActionFn(10); - let __sym0 = __pop_Variant3(__symbols); + // Instr = "(", mismatch, Matchable, Matchable, Instr, ")" => ActionFn(10); + assert!(__symbols.len() >= 6); + let __sym5 = __pop_Variant0(__symbols); + let __sym4 = __pop_Variant6(__symbols); + let __sym3 = __pop_Variant10(__symbols); + let __sym2 = __pop_Variant10(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action10::<>(input, errors, __sym0); + let __end = __sym5.2.clone(); + let __nt = super::__action10::<>(input, errors, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant6(__nt), __end)); - (1, 9) + (6, 9) } pub(crate) fn __reduce26< 'err, @@ -1749,13 +1789,13 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Iterable = Alphanumeric => ActionFn(26); - let __sym0 = __pop_Variant1(__symbols); + // Instr = error => ActionFn(11); + let __sym0 = __pop_Variant3(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action26::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (1, 10) + let __nt = super::__action11::<>(input, errors, __sym0); + __symbols.push((__start, __Symbol::Variant6(__nt), __end)); + (1, 9) } pub(crate) fn __reduce27< 'err, @@ -1768,8 +1808,8 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Iterable = JsonPath => ActionFn(27); - let __sym0 = __pop_Variant2(__symbols); + // Iterable = Alphanumeric => ActionFn(27); + let __sym0 = __pop_Variant1(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action27::<>(input, errors, __sym0); @@ -1787,13 +1827,13 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Matchable = Alphanumeric => ActionFn(28); - let __sym0 = __pop_Variant1(__symbols); + // Iterable = JsonPath => ActionFn(28); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action28::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant10(__nt), __end)); - (1, 11) + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 10) } pub(crate) fn __reduce29< 'err, @@ -1806,7 +1846,7 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Matchable = Literal => ActionFn(29); + // Matchable = Alphanumeric => ActionFn(29); let __sym0 = __pop_Variant1(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); @@ -1825,8 +1865,8 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Matchable = JsonPath => ActionFn(30); - let __sym0 = __pop_Variant2(__symbols); + // Matchable = Literal => ActionFn(30); + let __sym0 = __pop_Variant1(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action30::<>(input, errors, __sym0); @@ -1844,13 +1884,13 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Output = Alphanumeric => ActionFn(16); - let __sym0 = __pop_Variant1(__symbols); + // Matchable = JsonPath => ActionFn(31); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action16::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant11(__nt), __end)); - (1, 12) + let __nt = super::__action31::<>(input, errors, __sym0); + __symbols.push((__start, __Symbol::Variant10(__nt), __end)); + (1, 11) } pub(crate) fn __reduce32< 'err, @@ -1863,7 +1903,7 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Output = Accumulator => ActionFn(17); + // Output = Alphanumeric => ActionFn(17); let __sym0 = __pop_Variant1(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); @@ -1882,13 +1922,13 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Output? = Output => ActionFn(34); - let __sym0 = __pop_Variant11(__symbols); + // Output = Accumulator => ActionFn(18); + let __sym0 = __pop_Variant1(__symbols); 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, 13) + let __nt = super::__action18::<>(input, errors, __sym0); + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (1, 12) } pub(crate) fn __reduce34< 'err, @@ -1901,12 +1941,13 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // Output? = => ActionFn(35); - let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); - let __end = __start.clone(); - let __nt = super::__action35::<>(input, errors, &__start, &__end); + // Output? = Output => ActionFn(35); + let __sym0 = __pop_Variant11(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action35::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (0, 13) + (1, 13) } pub(crate) fn __reduce35< 'err, @@ -1919,13 +1960,12 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // PeerId = CallArgValue => ActionFn(19); - let __sym0 = __pop_Variant4(__symbols); - let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action19::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant4(__nt), __end)); - (1, 14) + // Output? = => ActionFn(36); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action36::<>(input, errors, &__start, &__end); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (0, 13) } pub(crate) fn __reduce36< 'err, @@ -1938,13 +1978,13 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // PeerPart = PeerId => ActionFn(14); + // PeerId = CallArgValue => ActionFn(20); let __sym0 = __pop_Variant4(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action14::<>(input, errors, __sym0); - __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (1, 15) + let __nt = super::__action20::<>(input, errors, __sym0); + __symbols.push((__start, __Symbol::Variant4(__nt), __end)); + (1, 14) } pub(crate) fn __reduce37< 'err, @@ -1957,17 +1997,13 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // PeerPart = "(", PeerId, ServiceId, ")" => ActionFn(15); - assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant4(__symbols); - let __sym1 = __pop_Variant4(__symbols); - let __sym0 = __pop_Variant0(__symbols); + // PeerPart = PeerId => ActionFn(15); + let __sym0 = __pop_Variant4(__symbols); let __start = __sym0.0.clone(); - let __end = __sym3.2.clone(); - let __nt = super::__action15::<>(input, errors, __sym0, __sym1, __sym2, __sym3); + let __end = __sym0.2.clone(); + let __nt = super::__action15::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant13(__nt), __end)); - (4, 15) + (1, 15) } pub(crate) fn __reduce38< 'err, @@ -1980,11 +2016,34 @@ mod __parse__AIR { _: ::std::marker::PhantomData<(&'err (), &'input ())>, ) -> (usize, usize) { - // ServiceId = CallArgValue => ActionFn(20); + // PeerPart = "(", PeerId, ServiceId, ")" => ActionFn(16); + assert!(__symbols.len() >= 4); + let __sym3 = __pop_Variant0(__symbols); + let __sym2 = __pop_Variant4(__symbols); + let __sym1 = __pop_Variant4(__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::Variant13(__nt), __end)); + (4, 15) + } + pub(crate) fn __reduce39< + '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) + { + // ServiceId = CallArgValue => ActionFn(21); let __sym0 = __pop_Variant4(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action20::<>(input, errors, __sym0); + let __nt = super::__action21::<>(input, errors, __sym0); __symbols.push((__start, __Symbol::Variant4(__nt), __end)); (1, 16) } @@ -2158,13 +2217,37 @@ fn __action9< (_, _, _): (usize, Token<'input>, usize), ) -> Box> { - Box::new(Instruction::Match(Match(l, r, i))) + { + let match_ = Match { left_value: l, right_value: r, instruction: i}; + Box::new(Instruction::Match(match_)) + } } #[allow(unused_variables)] fn __action10< 'err, 'input, +>( + input: &'input str, + errors: &'err mut Vec, LexerError>>, + (_, _, _): (usize, Token<'input>, usize), + (_, _, _): (usize, Token<'input>, usize), + (_, l, _): (usize, MatchableValue<'input>, usize), + (_, r, _): (usize, MatchableValue<'input>, usize), + (_, i, _): (usize, Box>, usize), + (_, _, _): (usize, Token<'input>, usize), +) -> Box> +{ + { + let mismatch = MisMatch { left_value: l, right_value: r, instruction: i}; + Box::new(Instruction::MisMatch(mismatch)) + } +} + +#[allow(unused_variables)] +fn __action11< + 'err, + 'input, >( input: &'input str, errors: &'err mut Vec, LexerError>>, @@ -2175,7 +2258,7 @@ fn __action10< } #[allow(unused_variables)] -fn __action11< +fn __action12< 'err, 'input, >( @@ -2190,7 +2273,7 @@ fn __action11< } #[allow(unused_variables)] -fn __action12< +fn __action13< 'err, 'input, >( @@ -2203,7 +2286,7 @@ fn __action12< } #[allow(unused_variables)] -fn __action13< +fn __action14< 'err, 'input, >( @@ -2219,7 +2302,7 @@ fn __action13< } #[allow(unused_variables)] -fn __action14< +fn __action15< 'err, 'input, >( @@ -2232,7 +2315,7 @@ fn __action14< } #[allow(unused_variables)] -fn __action15< +fn __action16< 'err, 'input, >( @@ -2248,7 +2331,7 @@ fn __action15< } #[allow(unused_variables)] -fn __action16< +fn __action17< 'err, 'input, >( @@ -2261,7 +2344,7 @@ fn __action16< } #[allow(unused_variables)] -fn __action17< +fn __action18< 'err, 'input, >( @@ -2273,19 +2356,6 @@ fn __action17< CallOutputValue::Accumulator(a) } -#[allow(unused_variables)] -fn __action18< - 'err, - 'input, ->( - input: &'input str, - errors: &'err mut Vec, LexerError>>, - (_, __0, _): (usize, CallArgValue<'input>, usize), -) -> CallArgValue<'input> -{ - __0 -} - #[allow(unused_variables)] fn __action19< 'err, @@ -2332,10 +2402,10 @@ fn __action22< >( input: &'input str, errors: &'err mut Vec, LexerError>>, - (_, s, _): (usize, &'input str, usize), + (_, __0, _): (usize, CallArgValue<'input>, usize), ) -> CallArgValue<'input> { - CallArgValue::Literal(s) + __0 } #[allow(unused_variables)] @@ -2348,13 +2418,26 @@ fn __action23< (_, s, _): (usize, &'input str, usize), ) -> CallArgValue<'input> { - CallArgValue::Variable(s) + CallArgValue::Literal(s) } #[allow(unused_variables)] fn __action24< 'err, 'input, +>( + input: &'input str, + errors: &'err mut Vec, LexerError>>, + (_, s, _): (usize, &'input str, usize), +) -> CallArgValue<'input> +{ + CallArgValue::Variable(s) +} + +#[allow(unused_variables)] +fn __action25< + 'err, + 'input, >( input: &'input str, errors: &'err mut Vec, LexerError>>, @@ -2368,7 +2451,7 @@ fn __action24< } #[allow(unused_variables)] -fn __action25< +fn __action26< 'err, 'input, >( @@ -2381,7 +2464,7 @@ fn __action25< } #[allow(unused_variables)] -fn __action26< +fn __action27< 'err, 'input, >( @@ -2394,7 +2477,7 @@ fn __action26< } #[allow(unused_variables)] -fn __action27< +fn __action28< 'err, 'input, >( @@ -2410,7 +2493,7 @@ fn __action27< } #[allow(unused_variables)] -fn __action28< +fn __action29< 'err, 'input, >( @@ -2423,7 +2506,7 @@ fn __action28< } #[allow(unused_variables)] -fn __action29< +fn __action30< 'err, 'input, >( @@ -2436,7 +2519,7 @@ fn __action29< } #[allow(unused_variables)] -fn __action30< +fn __action31< 'err, 'input, >( @@ -2452,7 +2535,7 @@ fn __action30< } #[allow(unused_variables)] -fn __action31< +fn __action32< 'err, 'input, >( @@ -2466,7 +2549,7 @@ fn __action31< } #[allow(unused_variables)] -fn __action32< +fn __action33< 'err, 'input, >( @@ -2479,7 +2562,7 @@ fn __action32< } #[allow(unused_variables)] -fn __action33< +fn __action34< 'err, 'input, >( @@ -2492,7 +2575,7 @@ fn __action33< } #[allow(unused_variables)] -fn __action34< +fn __action35< 'err, 'input, >( @@ -2505,7 +2588,7 @@ fn __action34< } #[allow(unused_variables)] -fn __action35< +fn __action36< 'err, 'input, >( @@ -2519,7 +2602,7 @@ fn __action35< } #[allow(unused_variables)] -fn __action36< +fn __action37< 'err, 'input, >( @@ -2532,7 +2615,7 @@ fn __action36< } #[allow(unused_variables)] -fn __action37< +fn __action38< 'err, 'input, >( @@ -2546,7 +2629,7 @@ fn __action37< } #[allow(unused_variables)] -fn __action38< +fn __action39< 'err, 'input, >( @@ -2557,42 +2640,15 @@ fn __action38< { let __start0 = __0.0.clone(); let __end0 = __0.2.clone(); - let __temp0 = __action33( + let __temp0 = __action34( input, errors, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action36( - input, - errors, - __temp0, - ) -} - -#[allow(unused_variables)] -fn __action39< - 'err, - 'input, ->( - input: &'input str, - errors: &'err mut Vec, LexerError>>, - __0: (usize, ::std::vec::Vec>, usize), - __1: (usize, CallArgValue<'input>, usize), -) -> ::std::vec::Vec> -{ - let __start0 = __1.0.clone(); - let __end0 = __1.2.clone(); - let __temp0 = __action33( - input, - errors, - __1, - ); - let __temp0 = (__start0, __temp0, __end0); __action37( input, errors, - __0, __temp0, ) } @@ -2601,6 +2657,33 @@ fn __action39< fn __action40< 'err, 'input, +>( + input: &'input str, + errors: &'err mut Vec, LexerError>>, + __0: (usize, ::std::vec::Vec>, usize), + __1: (usize, CallArgValue<'input>, usize), +) -> ::std::vec::Vec> +{ + let __start0 = __1.0.clone(); + let __end0 = __1.2.clone(); + let __temp0 = __action34( + input, + errors, + __1, + ); + let __temp0 = (__start0, __temp0, __end0); + __action38( + input, + errors, + __0, + __temp0, + ) +} + +#[allow(unused_variables)] +fn __action41< + 'err, + 'input, >( input: &'input str, errors: &'err mut Vec, LexerError>>, @@ -2610,14 +2693,14 @@ fn __action40< { let __start0 = __0.2.clone(); let __end0 = __1.0.clone(); - let __temp0 = __action31( + let __temp0 = __action32( input, errors, &__start0, &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action11( + __action12( input, errors, __0, @@ -2627,7 +2710,7 @@ fn __action40< } #[allow(unused_variables)] -fn __action41< +fn __action42< 'err, 'input, >( @@ -2640,13 +2723,13 @@ fn __action41< { let __start0 = __1.0.clone(); let __end0 = __1.2.clone(); - let __temp0 = __action32( + let __temp0 = __action33( input, errors, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action11( + __action12( input, errors, __0, @@ -2656,7 +2739,7 @@ fn __action41< } #[allow(unused_variables)] -fn __action42< +fn __action43< 'err, 'input, >( @@ -2673,7 +2756,7 @@ fn __action42< { let __start0 = __5.0.clone(); let __end0 = __5.2.clone(); - let __temp0 = __action34( + let __temp0 = __action35( input, errors, __5, @@ -2693,7 +2776,7 @@ fn __action42< } #[allow(unused_variables)] -fn __action43< +fn __action44< 'err, 'input, >( @@ -2709,7 +2792,7 @@ fn __action43< { let __start0 = __4.2.clone(); let __end0 = __5.0.clone(); - let __temp0 = __action35( + let __temp0 = __action36( input, errors, &__start0, diff --git a/crates/air-parser/src/parser/ast.rs b/crates/air-parser/src/parser/ast.rs index ffb29da3..7a251ae1 100644 --- a/crates/air-parser/src/parser/ast.rs +++ b/crates/air-parser/src/parser/ast.rs @@ -28,6 +28,7 @@ pub enum Instruction<'i> { Par(Par<'i>), Xor(Xor<'i>), Match(Match<'i>), + MisMatch(MisMatch<'i>), Fold(Fold<'i>), Next(Next<'i>), Error, @@ -91,11 +92,18 @@ pub struct Par<'i>(pub Box>, pub Box>); pub struct Xor<'i>(pub Box>, pub Box>); #[derive(Serialize, Debug, PartialEq, Eq)] -pub struct Match<'i>( - pub MatchableValue<'i>, - pub MatchableValue<'i>, - pub Box>, -); +pub struct Match<'i> { + pub left_value: MatchableValue<'i>, + pub right_value: MatchableValue<'i>, + pub instruction: Box>, +} + +#[derive(Serialize, Debug, PartialEq, Eq)] +pub struct MisMatch<'i> { + pub left_value: MatchableValue<'i>, + pub right_value: MatchableValue<'i>, + pub instruction: Box>, +} #[derive(Serialize, Debug, PartialEq, Eq)] pub struct Fold<'i> { diff --git a/crates/air-parser/src/parser/lexer/air_lexer.rs b/crates/air-parser/src/parser/lexer/air_lexer.rs index aee3ced7..8048f34c 100644 --- a/crates/air-parser/src/parser/lexer/air_lexer.rs +++ b/crates/air-parser/src/parser/lexer/air_lexer.rs @@ -181,6 +181,7 @@ fn string_to_token(input: &str, start_pos: usize) -> Result { XOR_INSTR => Ok(Token::Xor), NEXT_INSTR => Ok(Token::Next), MATCH_INSTR => Ok(Token::Match), + MISMATCH_INSTR => Ok(Token::MisMatch), INIT_PEER_ID => Ok(Token::InitPeerId), @@ -236,6 +237,7 @@ const FOLD_INSTR: &str = "fold"; const XOR_INSTR: &str = "xor"; const NEXT_INSTR: &str = "next"; const MATCH_INSTR: &str = "match"; +const MISMATCH_INSTR: &str = "mismatch"; const INIT_PEER_ID: &str = "%init_peer_id%"; diff --git a/crates/air-parser/src/parser/lexer/tests.rs b/crates/air-parser/src/parser/lexer/tests.rs index 27a4a62e..45fcc88e 100644 --- a/crates/air-parser/src/parser/lexer/tests.rs +++ b/crates/air-parser/src/parser/lexer/tests.rs @@ -103,6 +103,32 @@ fn air_instructions() { Ok((5, Token::CloseRoundBracket, 6)) ] ); + + let match_tokens = run_lexer("match"); + assert_eq!(match_tokens, vec![Ok((0, Token::Match, 5))]); + + let match_tokens = run_lexer("(match)"); + assert_eq!( + match_tokens, + vec![ + Ok((0, Token::OpenRoundBracket, 1)), + Ok((1, Token::Match, 6)), + Ok((6, Token::CloseRoundBracket, 7)) + ] + ); + + let mismatch_tokens = run_lexer("mismatch"); + assert_eq!(mismatch_tokens, vec![Ok((0, Token::MisMatch, 8))]); + + let mismatch_tokens = run_lexer("(mismatch)"); + assert_eq!( + mismatch_tokens, + vec![ + Ok((0, Token::OpenRoundBracket, 1)), + Ok((1, Token::MisMatch, 9)), + Ok((9, Token::CloseRoundBracket, 10)) + ] + ); } #[test] diff --git a/crates/air-parser/src/parser/lexer/token.rs b/crates/air-parser/src/parser/lexer/token.rs index e31e9193..e6f846d9 100644 --- a/crates/air-parser/src/parser/lexer/token.rs +++ b/crates/air-parser/src/parser/lexer/token.rs @@ -36,4 +36,5 @@ pub enum Token<'input> { Xor, Next, Match, + MisMatch, } diff --git a/crates/air-parser/src/parser/tests.rs b/crates/air-parser/src/parser/tests.rs index 1877eb3b..9dca685f 100644 --- a/crates/air-parser/src/parser/tests.rs +++ b/crates/air-parser/src/parser/tests.rs @@ -244,6 +244,34 @@ fn parse_fold() { assert_eq!(instruction, expected); } +#[test] +fn parse_match() { + use ast::MatchableValue::Variable; + + let source_code = r#" + (match v1 v2 + (null) + ) + "#; + let instruction = parse(&source_code.as_ref()); + let expected = match_(Variable("v1"), Variable("v2"), null()); + assert_eq!(instruction, expected); +} + +#[test] +fn parse_mismatch() { + use ast::MatchableValue::Variable; + + let source_code = r#" + (mismatch v1 v2 + (null) + ) + "#; + let instruction = parse(&source_code.as_ref()); + let expected = mismatch(Variable("v1"), Variable("v2"), null()); + assert_eq!(instruction, expected); +} + fn source_fold_with(name: &str) -> String { f!(r#"(fold iterable i ({name} (null) (null)) @@ -516,18 +544,23 @@ fn comments() { fn seq<'a>(l: Instruction<'a>, r: Instruction<'a>) -> Instruction<'a> { Instruction::Seq(ast::Seq(Box::new(l), Box::new(r))) } + fn par<'a>(l: Instruction<'a>, r: Instruction<'a>) -> Instruction<'a> { Instruction::Par(ast::Par(Box::new(l), Box::new(r))) } + fn xor<'a>(l: Instruction<'a>, r: Instruction<'a>) -> Instruction<'a> { Instruction::Xor(ast::Xor(Box::new(l), Box::new(r))) } + fn seqnn() -> Instruction<'static> { seq(null(), null()) } + fn null() -> Instruction<'static> { Instruction::Null(ast::Null) } + fn fold<'a>( iterable: ast::IterableValue<'a>, iterator: &'a str, @@ -539,6 +572,31 @@ fn fold<'a>( instruction: std::rc::Rc::new(instruction), }) } + +fn match_<'a>( + left_value: ast::MatchableValue<'a>, + right_value: ast::MatchableValue<'a>, + instruction: Instruction<'a>, +) -> Instruction<'a> { + Instruction::Match(ast::Match { + left_value, + right_value, + instruction: Box::new(instruction), + }) +} + +fn mismatch<'a>( + left_value: ast::MatchableValue<'a>, + right_value: ast::MatchableValue<'a>, + instruction: Instruction<'a>, +) -> Instruction<'a> { + Instruction::MisMatch(ast::MisMatch { + left_value, + right_value, + instruction: Box::new(instruction), + }) +} + fn binary_instruction<'a, 'b>( name: &'a str, ) -> impl Fn(Instruction<'b>, Instruction<'b>) -> Instruction<'b> { diff --git a/stepper-lib/src/execution/air/compare_matchable/compare_matchable.rs b/stepper-lib/src/execution/air/compare_matchable/compare_matchable.rs new file mode 100644 index 00000000..87410c5e --- /dev/null +++ b/stepper-lib/src/execution/air/compare_matchable/compare_matchable.rs @@ -0,0 +1,90 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use crate::contexts::execution::ExecutionCtx; +use crate::execution::air::ExecutionResult; +use crate::execution::utils::resolve_to_jvaluable; +use crate::JValue; + +use air_parser::ast::MatchableValue; + +pub(crate) fn are_matchable_eq<'ctx>( + left: &MatchableValue<'_>, + right: &MatchableValue<'_>, + exec_ctx: &'ctx ExecutionCtx<'_>, +) -> ExecutionResult { + use MatchableValue::*; + + match (left, right) { + (Literal(name), matchable) => compare_matchable_and_literal(matchable, name, exec_ctx), + (matchable, Literal(name)) => compare_matchable_and_literal(matchable, name, exec_ctx), + (Variable(left_name), Variable(right_name)) => { + let left_jvaluable = resolve_to_jvaluable(left_name, exec_ctx)?; + let left_value = left_jvaluable.as_jvalue(); + + let right_jvaluable = resolve_to_jvaluable(right_name, exec_ctx)?; + let right_value = right_jvaluable.as_jvalue(); + + Ok(left_value == right_value) + } + (JsonPath { variable: lv, path: lp }, JsonPath { variable: rv, path: rp }) => { + let left_jvaluable = resolve_to_jvaluable(lv, exec_ctx)?; + let left_value = left_jvaluable.apply_json_path(lp)?; + + let right_jvaluable = resolve_to_jvaluable(rv, exec_ctx)?; + let right_value = right_jvaluable.apply_json_path(rp)?; + + Ok(left_value == right_value) + } + _ => Ok(false), + } +} + +fn compare_matchable_and_literal<'ctx>( + matchable: &MatchableValue<'_>, + string_literal: &str, + exec_ctx: &'ctx ExecutionCtx<'_>, +) -> ExecutionResult { + use std::borrow::Cow; + use MatchableValue::*; + + fn compare_jvalue_and_literal(jvalue: Cow<'_, JValue>, string_literal: &str) -> bool { + use std::ops::Deref; + + match jvalue.deref() { + JValue::String(value) => value == string_literal, + _ => false, + } + } + + match matchable { + Literal(name) => Ok(name == &string_literal), + Variable(name) => { + let jvaluable = resolve_to_jvaluable(name, exec_ctx)?; + let jvalue = jvaluable.as_jvalue(); + Ok(compare_jvalue_and_literal(jvalue, string_literal)) + } + JsonPath { variable, path } => { + let jvaluable = resolve_to_jvaluable(variable, exec_ctx)?; + let jvalues = jvaluable.apply_json_path(path)?; + if jvalues.len() != 1 { + return Ok(false); + } + + Ok(compare_jvalue_and_literal(Cow::Borrowed(jvalues[0]), string_literal)) + } + } +} diff --git a/stepper-lib/src/execution/air/compare_matchable/mod.rs b/stepper-lib/src/execution/air/compare_matchable/mod.rs new file mode 100644 index 00000000..9f529851 --- /dev/null +++ b/stepper-lib/src/execution/air/compare_matchable/mod.rs @@ -0,0 +1,19 @@ +/* + * 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. + */ + +mod compare_matchable; + +pub(super) use compare_matchable::are_matchable_eq; diff --git a/stepper-lib/src/execution/air/match_.rs b/stepper-lib/src/execution/air/match_.rs index f99d66f1..614254c3 100644 --- a/stepper-lib/src/execution/air/match_.rs +++ b/stepper-lib/src/execution/air/match_.rs @@ -14,6 +14,7 @@ * limitations under the License. */ +use super::compare_matchable::are_matchable_eq; use super::ExecutionCtx; use super::ExecutionError; use super::ExecutionResult; @@ -21,92 +22,18 @@ use super::ExecutionTraceCtx; use crate::log_instruction; use air_parser::ast::Match; -use air_parser::ast::MatchableValue; impl<'i> super::ExecutableInstruction<'i> for Match<'i> { fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut ExecutionTraceCtx) -> ExecutionResult<()> { log_instruction!(match_, exec_ctx, trace_ctx); - let left_value = &self.0; - let right_value = &self.1; - let is_equal_values = compare_matchable(left_value, right_value, exec_ctx)?; + let are_values_equal = are_matchable_eq(&self.left_value, &self.right_value, exec_ctx)?; - if !is_equal_values { + if !are_values_equal { return Err(ExecutionError::MatchWithoutXorError); } - self.2.execute(exec_ctx, trace_ctx) - } -} - -use crate::execution::utils::resolve_to_jvaluable; -use crate::JValue; - -fn compare_matchable<'ctx>( - left: &MatchableValue<'_>, - right: &MatchableValue<'_>, - exec_ctx: &'ctx ExecutionCtx<'_>, -) -> ExecutionResult { - use MatchableValue::*; - - match (left, right) { - (Literal(name), matchable) => compare_matchable_and_literal(matchable, name, exec_ctx), - (matchable, Literal(name)) => compare_matchable_and_literal(matchable, name, exec_ctx), - (Variable(left_name), Variable(right_name)) => { - let left_jvaluable = resolve_to_jvaluable(left_name, exec_ctx)?; - let left_value = left_jvaluable.as_jvalue(); - - let right_jvaluable = resolve_to_jvaluable(right_name, exec_ctx)?; - let right_value = right_jvaluable.as_jvalue(); - - Ok(left_value == right_value) - } - (JsonPath { variable: lv, path: lp }, JsonPath { variable: rv, path: rp }) => { - let left_jvaluable = resolve_to_jvaluable(lv, exec_ctx)?; - let left_value = left_jvaluable.apply_json_path(lp)?; - - let right_jvaluable = resolve_to_jvaluable(rv, exec_ctx)?; - let right_value = right_jvaluable.apply_json_path(rp)?; - - Ok(left_value == right_value) - } - _ => Ok(false), - } -} - -fn compare_matchable_and_literal<'ctx>( - matchable: &MatchableValue<'_>, - string_literal: &str, - exec_ctx: &'ctx ExecutionCtx<'_>, -) -> ExecutionResult { - use std::borrow::Cow; - use MatchableValue::*; - - fn compare_jvalue_and_literal(jvalue: Cow<'_, JValue>, string_literal: &str) -> bool { - use std::ops::Deref; - - match jvalue.deref() { - JValue::String(value) => value == string_literal, - _ => false, - } - } - - match matchable { - Literal(name) => Ok(name == &string_literal), - Variable(name) => { - let jvaluable = resolve_to_jvaluable(name, exec_ctx)?; - let jvalue = jvaluable.as_jvalue(); - Ok(compare_jvalue_and_literal(jvalue, string_literal)) - } - JsonPath { variable, path } => { - let jvaluable = resolve_to_jvaluable(variable, exec_ctx)?; - let jvalues = jvaluable.apply_json_path(path)?; - if jvalues.len() != 1 { - return Ok(false); - } - - Ok(compare_jvalue_and_literal(Cow::Borrowed(jvalues[0]), string_literal)) - } + self.instruction.execute(exec_ctx, trace_ctx) } } diff --git a/stepper-lib/src/execution/air/mismatch.rs b/stepper-lib/src/execution/air/mismatch.rs new file mode 100644 index 00000000..c360720e --- /dev/null +++ b/stepper-lib/src/execution/air/mismatch.rs @@ -0,0 +1,193 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use super::compare_matchable::are_matchable_eq; +use super::ExecutionCtx; +use super::ExecutionError; +use super::ExecutionResult; +use super::ExecutionTraceCtx; +use crate::log_instruction; + +use air_parser::ast::MisMatch; + +impl<'i> super::ExecutableInstruction<'i> for MisMatch<'i> { + fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut ExecutionTraceCtx) -> ExecutionResult<()> { + log_instruction!(match_, exec_ctx, trace_ctx); + + let are_values_equal = are_matchable_eq(&self.left_value, &self.right_value, exec_ctx)?; + + if are_values_equal { + return Err(ExecutionError::MatchWithoutXorError); + } + + self.instruction.execute(exec_ctx, trace_ctx) + } +} + +#[cfg(test)] +mod tests { + use crate::contexts::execution_trace::ExecutionTrace; + use crate::JValue; + + use aqua_test_utils::call_vm; + use aqua_test_utils::create_aqua_vm; + use aqua_test_utils::echo_string_call_service; + + use std::rc::Rc; + + #[test] + fn mismatch_equal() { + use crate::contexts::execution_trace::CallResult::*; + use crate::contexts::execution_trace::ExecutedState::*; + + let set_variable_peer_id = "set_variable_peer_id"; + let mut set_variable_vm = create_aqua_vm(echo_string_call_service(), set_variable_peer_id); + + let local_peer_id = "local_peer_id"; + let mut vm = create_aqua_vm(echo_string_call_service(), local_peer_id); + + let script = format!( + r#" + (seq + (seq + (call "{0}" ("" "") ["value_1"] value_1) + (call "{0}" ("" "") ["value_1"] value_2) + ) + (xor + (mismatch value_1 value_2 + (call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1) + ) + (call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2) + ) + )"#, + set_variable_peer_id, local_peer_id + ); + + let res = call_vm!(set_variable_vm, "asd", script.clone(), "", ""); + let res = call_vm!(vm, "asd", script, "", res.data); + + let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json"); + let expected_executed_call_result = Call(Executed(Rc::new(JValue::String(String::from("result_2"))))); + + assert_eq!(actual_trace.len(), 3); + assert_eq!(actual_trace[2], expected_executed_call_result); + } + + #[test] + fn mismatch_not_equal() { + use crate::contexts::execution_trace::CallResult::*; + use crate::contexts::execution_trace::ExecutedState::*; + + let set_variable_peer_id = "set_variable_peer_id"; + let mut set_variable_vm = create_aqua_vm(echo_string_call_service(), set_variable_peer_id); + + let local_peer_id = "local_peer_id"; + let mut vm = create_aqua_vm(echo_string_call_service(), local_peer_id); + + let script = format!( + r#" + (seq + (seq + (call "{0}" ("" "") ["value_1"] value_1) + (call "{0}" ("" "") ["value_2"] value_2) + ) + (xor + (mismatch value_1 value_2 + (call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1) + ) + (call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2) + ) + )"#, + set_variable_peer_id, local_peer_id + ); + + let res = call_vm!(set_variable_vm, "asd", script.clone(), "", ""); + let res = call_vm!(vm, "asd", script, "", res.data); + + let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json"); + let expected_executed_call_result = Call(Executed(Rc::new(JValue::String(String::from("result_1"))))); + + assert_eq!(actual_trace.len(), 3); + assert_eq!(actual_trace[2], expected_executed_call_result); + } + + #[test] + fn mismatch_with_string() { + use crate::contexts::execution_trace::CallResult::*; + use crate::contexts::execution_trace::ExecutedState::*; + + let set_variable_peer_id = "set_variable_peer_id"; + let mut set_variable_vm = create_aqua_vm(echo_string_call_service(), set_variable_peer_id); + + let local_peer_id = "local_peer_id"; + let mut vm = create_aqua_vm(echo_string_call_service(), local_peer_id); + + let script = format!( + r#" + (seq + (call "{0}" ("" "") ["value_1"] value_1) + (xor + (mismatch value_1 "value_1" + (call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1) + ) + (call "{1}" ("service_id_2" "local_fn_name") ["result_2"] result_2) + ) + )"#, + set_variable_peer_id, local_peer_id + ); + + let res = call_vm!(set_variable_vm, "asd", script.clone(), "", ""); + let res = call_vm!(vm, "asd", script, "", res.data); + + let actual_trace: ExecutionTrace = serde_json::from_slice(&res.data).expect("should be valid json"); + let expected_executed_call_result = Call(Executed(Rc::new(JValue::String(String::from("result_2"))))); + + assert_eq!(actual_trace.len(), 2); + assert_eq!(actual_trace[1], expected_executed_call_result); + } + + #[test] + fn mismatch_without_xor() { + let set_variable_peer_id = "set_variable_peer_id"; + let mut set_variable_vm = create_aqua_vm(echo_string_call_service(), set_variable_peer_id); + + let local_peer_id = "local_peer_id"; + let mut vm = create_aqua_vm(echo_string_call_service(), local_peer_id); + + let script = format!( + r#" + (seq + (seq + (call "{0}" ("" "") ["value_1"] value_1) + (call "{0}" ("" "") ["value_1"] value_2) + ) + (mismatch value_1 value_2 + (call "{1}" ("service_id_2" "local_fn_name") ["result_1"] result_1) + ) + )"#, + set_variable_peer_id, local_peer_id + ); + + let res = call_vm!(set_variable_vm, "asd", script.clone(), "", ""); + let res = call_vm!(vm, "asd", script.clone(), "", res.data); + + assert_eq!(res.ret_code, 1015); + + let res = call_vm!(vm, "asd", script, "", res.data); + + assert_eq!(res.ret_code, 1015); + } +} diff --git a/stepper-lib/src/execution/air/mod.rs b/stepper-lib/src/execution/air/mod.rs index 43d20d71..b7eae9f7 100644 --- a/stepper-lib/src/execution/air/mod.rs +++ b/stepper-lib/src/execution/air/mod.rs @@ -15,8 +15,10 @@ */ mod call; +mod compare_matchable; mod fold; mod match_; +mod mismatch; mod null; mod par; mod seq; @@ -46,6 +48,7 @@ impl<'i> ExecutableInstruction<'i> for Instruction<'i> { Instruction::Seq(seq) => seq.execute(exec_ctx, trace_ctx), Instruction::Xor(xor) => xor.execute(exec_ctx, trace_ctx), Instruction::Match(match_) => match_.execute(exec_ctx, trace_ctx), + Instruction::MisMatch(mismatch) => mismatch.execute(exec_ctx, trace_ctx), Instruction::Error => unreachable!("should not execute if parsing succeeded. QED."), } }