Make match mismatch joinable (#77)

This commit is contained in:
vms
2021-03-24 10:00:07 +03:00
committed by GitHub
parent 52af952dfd
commit 0b2bfe1b84
7 changed files with 281 additions and 68 deletions

View File

@ -48,13 +48,19 @@ Instr: Box<Instruction<'input>> = {
"(" xor <l:Instr> <r:Instr> ")" => Box::new(Instruction::Xor(Xor(l, r))), "(" xor <l:Instr> <r:Instr> ")" => Box::new(Instruction::Xor(Xor(l, r))),
"(" match_ <l:Matchable> <r:Matchable> <i:Instr> ")" => { <left: @L> "(" match_ <l:Matchable> <r:Matchable> <i:Instr> ")" <right: @R> => {
let match_ = Match { left_value: l, right_value: r, instruction: i}; let match_ = Match { left_value: l, right_value: r, instruction: i};
let span = Span { left, right };
validator.met_match(&match_, span);
Box::new(Instruction::Match(match_)) Box::new(Instruction::Match(match_))
}, },
"(" mismatch <l:Matchable> <r:Matchable> <i:Instr> ")" => { <left: @L> "(" mismatch <l:Matchable> <r:Matchable> <i:Instr> ")" <right: @R> => {
let mismatch = MisMatch { left_value: l, right_value: r, instruction: i}; let mismatch = MisMatch { left_value: l, right_value: r, instruction: i};
let span = Span { left, right };
validator.met_mismatch(&mismatch, span);
Box::new(Instruction::MisMatch(mismatch)) Box::new(Instruction::MisMatch(mismatch))
}, },

View File

@ -1,5 +1,5 @@
// auto-generated: "lalrpop 0.19.5" // auto-generated: "lalrpop 0.19.5"
// sha3: 9261142c295e3b691816383a436d7d9ae0591e6fd2e556966d1dfe61ccff84 // sha3: d38ac259b3aeaaf2d8bcb5763e5e661b26266a5c1fde80f88eaeeabbbe9f9f
use crate::parser::ast::*; use crate::parser::ast::*;
use crate::parser::air_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::air_parser::make_flattened_error;
@ -1853,11 +1853,11 @@ mod __parse__AIR {
_: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// CallInstrValue = JsonPath => ActionFn(56); // CallInstrValue = JsonPath => ActionFn(58);
let __sym0 = __pop_Variant3(__symbols); let __sym0 = __pop_Variant3(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym0.2.clone(); let __end = __sym0.2.clone();
let __nt = super::__action56::<>(input, errors, validator, __sym0); let __nt = super::__action58::<>(input, errors, validator, __sym0);
__symbols.push((__start, __Symbol::Variant11(__nt), __end)); __symbols.push((__start, __Symbol::Variant11(__nt), __end));
(1, 9) (1, 9)
} }
@ -1962,7 +1962,7 @@ mod __parse__AIR {
_: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Instr = "(", call, PeerPart, FPart, Args, Output, ")" => ActionFn(60); // Instr = "(", call, PeerPart, FPart, Args, Output, ")" => ActionFn(64);
assert!(__symbols.len() >= 7); assert!(__symbols.len() >= 7);
let __sym6 = __pop_Variant0(__symbols); let __sym6 = __pop_Variant0(__symbols);
let __sym5 = __pop_Variant15(__symbols); let __sym5 = __pop_Variant15(__symbols);
@ -1973,7 +1973,7 @@ mod __parse__AIR {
let __sym0 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym6.2.clone(); let __end = __sym6.2.clone();
let __nt = super::__action60::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6); let __nt = super::__action64::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5, __sym6);
__symbols.push((__start, __Symbol::Variant9(__nt), __end)); __symbols.push((__start, __Symbol::Variant9(__nt), __end));
(7, 12) (7, 12)
} }
@ -1990,7 +1990,7 @@ mod __parse__AIR {
_: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Instr = "(", call, PeerPart, FPart, Args, ")" => ActionFn(61); // Instr = "(", call, PeerPart, FPart, Args, ")" => ActionFn(65);
assert!(__symbols.len() >= 6); assert!(__symbols.len() >= 6);
let __sym5 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols);
let __sym4 = __pop_Variant10(__symbols); let __sym4 = __pop_Variant10(__symbols);
@ -2000,7 +2000,7 @@ mod __parse__AIR {
let __sym0 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym5.2.clone(); let __end = __sym5.2.clone();
let __nt = super::__action61::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); let __nt = super::__action65::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5);
__symbols.push((__start, __Symbol::Variant9(__nt), __end)); __symbols.push((__start, __Symbol::Variant9(__nt), __end));
(6, 12) (6, 12)
} }
@ -2093,7 +2093,7 @@ mod __parse__AIR {
_: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Instr = "(", fold, Iterable, Alphanumeric, Instr, ")" => ActionFn(58); // Instr = "(", fold, Iterable, Alphanumeric, Instr, ")" => ActionFn(60);
assert!(__symbols.len() >= 6); assert!(__symbols.len() >= 6);
let __sym5 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols);
let __sym4 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant9(__symbols);
@ -2103,7 +2103,7 @@ mod __parse__AIR {
let __sym0 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym5.2.clone(); let __end = __sym5.2.clone();
let __nt = super::__action58::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); let __nt = super::__action60::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5);
__symbols.push((__start, __Symbol::Variant9(__nt), __end)); __symbols.push((__start, __Symbol::Variant9(__nt), __end));
(6, 12) (6, 12)
} }
@ -2120,7 +2120,7 @@ mod __parse__AIR {
_: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Instr = "(", next, Alphanumeric, ")" => ActionFn(59); // Instr = "(", next, Alphanumeric, ")" => ActionFn(61);
assert!(__symbols.len() >= 4); assert!(__symbols.len() >= 4);
let __sym3 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols);
let __sym2 = __pop_Variant1(__symbols); let __sym2 = __pop_Variant1(__symbols);
@ -2128,7 +2128,7 @@ mod __parse__AIR {
let __sym0 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym3.2.clone(); let __end = __sym3.2.clone();
let __nt = super::__action59::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3); let __nt = super::__action61::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3);
__symbols.push((__start, __Symbol::Variant9(__nt), __end)); __symbols.push((__start, __Symbol::Variant9(__nt), __end));
(4, 12) (4, 12)
} }
@ -2171,7 +2171,7 @@ mod __parse__AIR {
_: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Instr = "(", match_, Matchable, Matchable, Instr, ")" => ActionFn(9); // Instr = "(", match_, Matchable, Matchable, Instr, ")" => ActionFn(62);
assert!(__symbols.len() >= 6); assert!(__symbols.len() >= 6);
let __sym5 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols);
let __sym4 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant9(__symbols);
@ -2181,7 +2181,7 @@ mod __parse__AIR {
let __sym0 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym5.2.clone(); let __end = __sym5.2.clone();
let __nt = super::__action9::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); let __nt = super::__action62::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5);
__symbols.push((__start, __Symbol::Variant9(__nt), __end)); __symbols.push((__start, __Symbol::Variant9(__nt), __end));
(6, 12) (6, 12)
} }
@ -2198,7 +2198,7 @@ mod __parse__AIR {
_: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Instr = "(", mismatch, Matchable, Matchable, Instr, ")" => ActionFn(10); // Instr = "(", mismatch, Matchable, Matchable, Instr, ")" => ActionFn(63);
assert!(__symbols.len() >= 6); assert!(__symbols.len() >= 6);
let __sym5 = __pop_Variant0(__symbols); let __sym5 = __pop_Variant0(__symbols);
let __sym4 = __pop_Variant9(__symbols); let __sym4 = __pop_Variant9(__symbols);
@ -2208,7 +2208,7 @@ mod __parse__AIR {
let __sym0 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym5.2.clone(); let __end = __sym5.2.clone();
let __nt = super::__action10::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); let __nt = super::__action63::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5);
__symbols.push((__start, __Symbol::Variant9(__nt), __end)); __symbols.push((__start, __Symbol::Variant9(__nt), __end));
(6, 12) (6, 12)
} }
@ -2711,16 +2711,21 @@ fn __action9<
input: &'input str, input: &'input str,
errors: &'err mut Vec<ErrorRecovery<usize, Token<'input>, ParserError>>, errors: &'err mut Vec<ErrorRecovery<usize, Token<'input>, ParserError>>,
validator: &'v mut VariableValidator<'input>, validator: &'v mut VariableValidator<'input>,
(_, left, _): (usize, usize, usize),
(_, _, _): (usize, Token<'input>, usize), (_, _, _): (usize, Token<'input>, usize),
(_, _, _): (usize, Token<'input>, usize), (_, _, _): (usize, Token<'input>, usize),
(_, l, _): (usize, MatchableValue<'input>, usize), (_, l, _): (usize, MatchableValue<'input>, usize),
(_, r, _): (usize, MatchableValue<'input>, usize), (_, r, _): (usize, MatchableValue<'input>, usize),
(_, i, _): (usize, Box<Instruction<'input>>, usize), (_, i, _): (usize, Box<Instruction<'input>>, usize),
(_, _, _): (usize, Token<'input>, usize), (_, _, _): (usize, Token<'input>, usize),
(_, right, _): (usize, usize, usize),
) -> Box<Instruction<'input>> ) -> Box<Instruction<'input>>
{ {
{ {
let match_ = Match { left_value: l, right_value: r, instruction: i}; let match_ = Match { left_value: l, right_value: r, instruction: i};
let span = Span { left, right };
validator.met_match(&match_, span);
Box::new(Instruction::Match(match_)) Box::new(Instruction::Match(match_))
} }
} }
@ -2734,16 +2739,21 @@ fn __action10<
input: &'input str, input: &'input str,
errors: &'err mut Vec<ErrorRecovery<usize, Token<'input>, ParserError>>, errors: &'err mut Vec<ErrorRecovery<usize, Token<'input>, ParserError>>,
validator: &'v mut VariableValidator<'input>, validator: &'v mut VariableValidator<'input>,
(_, left, _): (usize, usize, usize),
(_, _, _): (usize, Token<'input>, usize), (_, _, _): (usize, Token<'input>, usize),
(_, _, _): (usize, Token<'input>, usize), (_, _, _): (usize, Token<'input>, usize),
(_, l, _): (usize, MatchableValue<'input>, usize), (_, l, _): (usize, MatchableValue<'input>, usize),
(_, r, _): (usize, MatchableValue<'input>, usize), (_, r, _): (usize, MatchableValue<'input>, usize),
(_, i, _): (usize, Box<Instruction<'input>>, usize), (_, i, _): (usize, Box<Instruction<'input>>, usize),
(_, _, _): (usize, Token<'input>, usize), (_, _, _): (usize, Token<'input>, usize),
(_, right, _): (usize, usize, usize),
) -> Box<Instruction<'input>> ) -> Box<Instruction<'input>>
{ {
{ {
let mismatch = MisMatch { left_value: l, right_value: r, instruction: i}; let mismatch = MisMatch { left_value: l, right_value: r, instruction: i};
let span = Span { left, right };
validator.met_mismatch(&mismatch, span);
Box::new(Instruction::MisMatch(mismatch)) Box::new(Instruction::MisMatch(mismatch))
} }
} }
@ -3630,6 +3640,92 @@ fn __action56<
'err, 'err,
'input, 'input,
'v, 'v,
>(
input: &'input str,
errors: &'err mut Vec<ErrorRecovery<usize, Token<'input>, ParserError>>,
validator: &'v mut VariableValidator<'input>,
__0: (usize, Token<'input>, usize),
__1: (usize, Token<'input>, usize),
__2: (usize, MatchableValue<'input>, usize),
__3: (usize, MatchableValue<'input>, usize),
__4: (usize, Box<Instruction<'input>>, usize),
__5: (usize, Token<'input>, usize),
__6: (usize, usize, usize),
) -> Box<Instruction<'input>>
{
let __start0 = __0.0.clone();
let __end0 = __0.0.clone();
let __temp0 = __action45(
input,
errors,
validator,
&__start0,
&__end0,
);
let __temp0 = (__start0, __temp0, __end0);
__action9(
input,
errors,
validator,
__temp0,
__0,
__1,
__2,
__3,
__4,
__5,
__6,
)
}
#[allow(unused_variables)]
fn __action57<
'err,
'input,
'v,
>(
input: &'input str,
errors: &'err mut Vec<ErrorRecovery<usize, Token<'input>, ParserError>>,
validator: &'v mut VariableValidator<'input>,
__0: (usize, Token<'input>, usize),
__1: (usize, Token<'input>, usize),
__2: (usize, MatchableValue<'input>, usize),
__3: (usize, MatchableValue<'input>, usize),
__4: (usize, Box<Instruction<'input>>, usize),
__5: (usize, Token<'input>, usize),
__6: (usize, usize, usize),
) -> Box<Instruction<'input>>
{
let __start0 = __0.0.clone();
let __end0 = __0.0.clone();
let __temp0 = __action45(
input,
errors,
validator,
&__start0,
&__end0,
);
let __temp0 = (__start0, __temp0, __end0);
__action10(
input,
errors,
validator,
__temp0,
__0,
__1,
__2,
__3,
__4,
__5,
__6,
)
}
#[allow(unused_variables)]
fn __action58<
'err,
'input,
'v,
>( >(
input: &'input str, input: &'input str,
errors: &'err mut Vec<ErrorRecovery<usize, Token<'input>, ParserError>>, errors: &'err mut Vec<ErrorRecovery<usize, Token<'input>, ParserError>>,
@ -3657,7 +3753,7 @@ fn __action56<
} }
#[allow(unused_variables)] #[allow(unused_variables)]
fn __action57< fn __action59<
'err, 'err,
'input, 'input,
'v, 'v,
@ -3700,7 +3796,7 @@ fn __action57<
} }
#[allow(unused_variables)] #[allow(unused_variables)]
fn __action58< fn __action60<
'err, 'err,
'input, 'input,
'v, 'v,
@ -3741,7 +3837,7 @@ fn __action58<
} }
#[allow(unused_variables)] #[allow(unused_variables)]
fn __action59< fn __action61<
'err, 'err,
'input, 'input,
'v, 'v,
@ -3778,7 +3874,89 @@ fn __action59<
} }
#[allow(unused_variables)] #[allow(unused_variables)]
fn __action60< fn __action62<
'err,
'input,
'v,
>(
input: &'input str,
errors: &'err mut Vec<ErrorRecovery<usize, Token<'input>, ParserError>>,
validator: &'v mut VariableValidator<'input>,
__0: (usize, Token<'input>, usize),
__1: (usize, Token<'input>, usize),
__2: (usize, MatchableValue<'input>, usize),
__3: (usize, MatchableValue<'input>, usize),
__4: (usize, Box<Instruction<'input>>, usize),
__5: (usize, Token<'input>, usize),
) -> Box<Instruction<'input>>
{
let __start0 = __5.2.clone();
let __end0 = __5.2.clone();
let __temp0 = __action42(
input,
errors,
validator,
&__start0,
&__end0,
);
let __temp0 = (__start0, __temp0, __end0);
__action56(
input,
errors,
validator,
__0,
__1,
__2,
__3,
__4,
__5,
__temp0,
)
}
#[allow(unused_variables)]
fn __action63<
'err,
'input,
'v,
>(
input: &'input str,
errors: &'err mut Vec<ErrorRecovery<usize, Token<'input>, ParserError>>,
validator: &'v mut VariableValidator<'input>,
__0: (usize, Token<'input>, usize),
__1: (usize, Token<'input>, usize),
__2: (usize, MatchableValue<'input>, usize),
__3: (usize, MatchableValue<'input>, usize),
__4: (usize, Box<Instruction<'input>>, usize),
__5: (usize, Token<'input>, usize),
) -> Box<Instruction<'input>>
{
let __start0 = __5.2.clone();
let __end0 = __5.2.clone();
let __temp0 = __action42(
input,
errors,
validator,
&__start0,
&__end0,
);
let __temp0 = (__start0, __temp0, __end0);
__action57(
input,
errors,
validator,
__0,
__1,
__2,
__3,
__4,
__5,
__temp0,
)
}
#[allow(unused_variables)]
fn __action64<
'err, 'err,
'input, 'input,
'v, 'v,
@ -3804,7 +3982,7 @@ fn __action60<
__5, __5,
); );
let __temp0 = (__start0, __temp0, __end0); let __temp0 = (__start0, __temp0, __end0);
__action57( __action59(
input, input,
errors, errors,
validator, validator,
@ -3819,7 +3997,7 @@ fn __action60<
} }
#[allow(unused_variables)] #[allow(unused_variables)]
fn __action61< fn __action65<
'err, 'err,
'input, 'input,
'v, 'v,
@ -3845,7 +4023,7 @@ fn __action61<
&__end0, &__end0,
); );
let __temp0 = (__start0, __temp0, __end0); let __temp0 = (__start0, __temp0, __end0);
__action57( __action59(
input, input,
errors, errors,
validator, validator,

View File

@ -61,6 +61,16 @@ impl<'i> VariableValidator<'i> {
self.met_call_output_definition(&call.output, span) self.met_call_output_definition(&call.output, span)
} }
pub(super) fn met_match(&mut self, match_: &Match<'i>, span: Span) {
self.met_matchable(&match_.left_value, span);
self.met_matchable(&match_.right_value, span);
}
pub(super) fn met_mismatch(&mut self, mismatch: &MisMatch<'i>, span: Span) {
self.met_matchable(&mismatch.left_value, span);
self.met_matchable(&mismatch.right_value, span);
}
pub(super) fn met_fold(&mut self, fold: &Fold<'i>, span: Span) { pub(super) fn met_fold(&mut self, fold: &Fold<'i>, span: Span) {
self.met_iterable_value(&fold.iterable, span); self.met_iterable_value(&fold.iterable, span);
self.met_iterator_definition(&fold.iterator, span); self.met_iterator_definition(&fold.iterator, span);
@ -175,6 +185,15 @@ impl<'i> VariableValidator<'i> {
} }
} }
fn met_matchable(&mut self, matchable: &MatchableValue<'i>, span: Span) {
match matchable {
MatchableValue::Number(_) | MatchableValue::Boolean(_) | MatchableValue::Literal(_) => {
}
MatchableValue::Variable(variable) => self.met_variable(variable, span),
MatchableValue::JsonPath { variable, .. } => self.met_variable(variable, span),
}
}
/// Checks that multimap contains a span for given key such that provided span lies inside it. /// Checks that multimap contains a span for given key such that provided span lies inside it.
fn contains_iterable(&self, key: &str, key_span: Span) -> bool { fn contains_iterable(&self, key: &str, key_span: Span) -> bool {
let found_spans = match self.met_iterators.get_vec(key) { let found_spans = match self.met_iterators.get_vec(key) {

View File

@ -25,6 +25,7 @@ use super::ExecutionError;
use super::ExecutionResult; use super::ExecutionResult;
use super::ExecutionTraceCtx; use super::ExecutionTraceCtx;
use crate::contexts::execution::LastErrorDescriptor; use crate::contexts::execution::LastErrorDescriptor;
use crate::joinable;
use crate::log_instruction; use crate::log_instruction;
use crate::SecurityTetraplet; use crate::SecurityTetraplet;
@ -32,19 +33,6 @@ use air_parser::ast::Call;
use std::rc::Rc; use std::rc::Rc;
/// This macro converts joinable errors to Ok and sets subtree complete to true.
macro_rules! joinable {
($cmd:expr, $exec_ctx:expr) => {
match $cmd {
Err(e) if is_joinable_error_type(&e) => {
$exec_ctx.subtree_complete = false;
return Ok(());
}
v => v,
}
};
}
impl<'i> super::ExecutableInstruction<'i> for Call<'i> { impl<'i> super::ExecutableInstruction<'i> for Call<'i> {
fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut ExecutionTraceCtx) -> ExecutionResult<()> { fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut ExecutionTraceCtx) -> ExecutionResult<()> {
log_instruction!(call, exec_ctx, trace_ctx); log_instruction!(call, exec_ctx, trace_ctx);
@ -78,35 +66,6 @@ fn set_last_error<'i>(
exec_ctx.last_error_could_be_set = false; exec_ctx.last_error_could_be_set = false;
} }
macro_rules! log_join {
($($args:tt)*) => {
log::info!(target: crate::log_targets::JOIN_BEHAVIOUR, $($args)*)
}
}
/// Returns true, if supplied error is related to variable not found errors type.
/// Print log if this is joinable error type.
#[rustfmt::skip::macros(log_join)]
fn is_joinable_error_type(exec_error: &ExecutionError) -> bool {
use ExecutionError::*;
match exec_error {
VariableNotFound(var_name) => {
log_join!(" call is waiting for an argument with name '{}'", var_name);
true
}
JValueJsonPathError(value, json_path, _) => {
log_join!(" call is waiting for an argument with path '{}' on jvalue '{:?}'", json_path, value);
true
}
JValueAccJsonPathError(acc, json_path, _) => {
log_join!(" call is waiting for an argument with path '{}' on accumulator '{:?}'", json_path, acc);
true
}
_ => false,
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::contexts::execution_trace::ExecutionTrace; use crate::contexts::execution_trace::ExecutionTrace;

View File

@ -19,6 +19,7 @@ use super::ExecutionCtx;
use super::ExecutionError; use super::ExecutionError;
use super::ExecutionResult; use super::ExecutionResult;
use super::ExecutionTraceCtx; use super::ExecutionTraceCtx;
use crate::joinable;
use crate::log_instruction; use crate::log_instruction;
use air_parser::ast::Match; use air_parser::ast::Match;
@ -27,7 +28,10 @@ impl<'i> super::ExecutableInstruction<'i> for Match<'i> {
fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut ExecutionTraceCtx) -> ExecutionResult<()> { fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut ExecutionTraceCtx) -> ExecutionResult<()> {
log_instruction!(match_, exec_ctx, trace_ctx); log_instruction!(match_, exec_ctx, trace_ctx);
let are_values_equal = are_matchable_eq(&self.left_value, &self.right_value, exec_ctx)?; let are_values_equal = joinable!(
are_matchable_eq(&self.left_value, &self.right_value, exec_ctx),
exec_ctx
)?;
if !are_values_equal { if !are_values_equal {
return crate::exec_err!(ExecutionError::MatchWithoutXorError); return crate::exec_err!(ExecutionError::MatchWithoutXorError);

View File

@ -19,6 +19,7 @@ use super::ExecutionCtx;
use super::ExecutionError; use super::ExecutionError;
use super::ExecutionResult; use super::ExecutionResult;
use super::ExecutionTraceCtx; use super::ExecutionTraceCtx;
use crate::joinable;
use crate::log_instruction; use crate::log_instruction;
use air_parser::ast::MisMatch; use air_parser::ast::MisMatch;
@ -27,7 +28,10 @@ impl<'i> super::ExecutableInstruction<'i> for MisMatch<'i> {
fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut ExecutionTraceCtx) -> ExecutionResult<()> { fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut ExecutionTraceCtx) -> ExecutionResult<()> {
log_instruction!(match_, exec_ctx, trace_ctx); log_instruction!(match_, exec_ctx, trace_ctx);
let are_values_equal = are_matchable_eq(&self.left_value, &self.right_value, exec_ctx)?; let are_values_equal = joinable!(
are_matchable_eq(&self.left_value, &self.right_value, exec_ctx),
exec_ctx
)?;
if are_values_equal { if are_values_equal {
return crate::exec_err!(ExecutionError::MismatchWithoutXorError); return crate::exec_err!(ExecutionError::MismatchWithoutXorError);

View File

@ -147,3 +147,46 @@ macro_rules! log_instruction {
); );
}; };
} }
/// This macro converts joinable errors to Ok and sets subtree complete to false.
#[macro_export]
macro_rules! joinable {
($cmd:expr, $exec_ctx:expr) => {
match $cmd {
Err(e) if crate::execution::air::is_joinable_error_type(&e) => {
$exec_ctx.subtree_complete = false;
return Ok(());
}
v => v,
}
};
}
macro_rules! log_join {
($($args:tt)*) => {
log::info!(target: crate::log_targets::JOIN_BEHAVIOUR, $($args)*)
}
}
/// Returns true, if supplied error is related to variable not found errors type.
/// Print log if this is joinable error type.
#[rustfmt::skip::macros(log_join)]
fn is_joinable_error_type(exec_error: &ExecutionError) -> bool {
use ExecutionError::*;
match exec_error {
VariableNotFound(var_name) => {
log_join!(" waiting for an argument with name '{}'", var_name);
true
}
JValueJsonPathError(value, json_path, _) => {
log_join!(" waiting for an argument with path '{}' on jvalue '{:?}'", json_path, value);
true
}
JValueAccJsonPathError(acc, json_path, _) => {
log_join!(" waiting for an argument with path '{}' on accumulator '{:?}'", json_path, acc);
true
}
_ => false,
}
}