diff --git a/CHANGELOG.md b/CHANGELOG.md index df5be1cc..3a1610e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,41 @@ -## Version 0.24.0 (2021-04-21) +## Version 0.27.0 (2022-08-23) + +[PR 292](https://github.com/fluencelabs/aquavm/pull/292): +Introduced a new `canon` instruction + +[PR 296](https://github.com/fluencelabs/aquavm/pull/296): +A bug with an inappropriate check of states in the `Ap` merger was fixed + +## Version 0.26.0 (2022-08-19) + +[PR 294](https://github.com/fluencelabs/aquavm/pull/294): +Accompanying to air-interpreter update that makes interface more handy for `air-trace` + +## Version 0.25.0 (2022-07-27) + +[PR 287](https://github.com/fluencelabs/aquavm/pull/287): +Memory leak introduced by switching to reactor/command model in WASI fixed + +[PR 276](https://github.com/fluencelabs/aquavm/pull/276): +AquaVM performance was improved by removing excess logging + +[PR 273](https://github.com/fluencelabs/aquavm/pull/273): +Introduced `TracePos` for `TraceHandler` positions + +[PR 270](https://github.com/fluencelabs/aquavm/pull/270): +A bug with empty subtrace lore in TraceHandler was fixed + +## Version 0.24.0 (2022-04-21) [PR 253](https://github.com/fluencelabs/aquavm/pull/253): Introduced %ttl% keyword -## Version 0.24.0 (2021-04-20) +## Version 0.24.0 (2022-04-20) [PR 250](https://github.com/fluencelabs/aquavm/pull/250): Introduced %timestamp% keyword -## Version 0.23.0 (2021-04-20) +## Version 0.23.0 (2022-04-20) [PR 248](https://github.com/fluencelabs/aquavm/pull/248): Introduced new for scalars @@ -16,7 +43,7 @@ Introduced new for scalars [PR 244](https://github.com/fluencelabs/aquavm/pull/244): Stack size was increased to 50 MiB -## Version 0.22.0 (2021-04-14) +## Version 0.22.0 (2022-04-14) [PR 243](https://github.com/fluencelabs/aquavm/pull/243): Clean scalars at the end of scope, only one next in a fold over scalar is possible now @@ -27,13 +54,13 @@ Test refactoring [PR 228](https://github.com/fluencelabs/aquavm/pull/228): Improve stream determinism -## Version 0.21.0 (2021-02-26) +## Version 0.21.0 (2022-02-26) [PR 225](https://github.com/fluencelabs/aquavm/pull/225): Introduce recursive streams [PR 224](https://github.com/fluencelabs/aquavm/pull/224) [PR 220](https://github.com/fluencelabs/aquavm/pull/224) [PR 217](https://github.com/fluencelabs/aquavm/pull/217) [PR 215](https://github.com/fluencelabs/aquavm/pull/215) [PR 212](https://github.com/fluencelabs/aquavm/pull/212) [PR 207](https://github.com/fluencelabs/aquavm/pull/207): -Various bugs fixed +Various bugs were fixed [PR 210](https://github.com/fluencelabs/aquavm/pull/210): Add API for returning AquaVM consumed memory size diff --git a/Cargo.lock b/Cargo.lock index ca004fa7..e0711546 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,7 +13,7 @@ dependencies = [ [[package]] name = "air" -version = "0.26.0" +version = "0.27.0" dependencies = [ "air-execution-info-collector", "air-interpreter-data", @@ -72,7 +72,7 @@ version = "0.1.0" [[package]] name = "air-interpreter" -version = "0.26.0" +version = "0.27.0" dependencies = [ "air", "air-interpreter-interface", @@ -88,7 +88,7 @@ dependencies = [ [[package]] name = "air-interpreter-data" -version = "0.2.2" +version = "0.3.0" dependencies = [ "air-utils", "once_cell", @@ -199,6 +199,7 @@ dependencies = [ "air-interpreter-data", "air-log-targets", "air-parser", + "bimap", "log", "serde_json", "thiserror", @@ -307,6 +308,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "bimap" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0455254eb5c6964c4545d8bac815e1a1be4f3afe0ae695ea539c12d728d44b" + [[package]] name = "bincode" version = "1.3.3" @@ -1829,7 +1836,7 @@ dependencies = [ [[package]] name = "polyplets" -version = "0.3.0" +version = "0.3.1" dependencies = [ "marine-macro", "marine-rs-sdk-main", diff --git a/README.md b/README.md index 6d91656a..84030dde 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,24 @@ Example: ) ``` +#### canon + +```wasm +(canon "peer_id" <$stream> <#canon_stream>) +``` + +- executes on peer_id, takes $stream as it is on the moment of first canonicalization +- every next execution #canon_stream will be the same — as first seen by peer_id + +Example: + +```wasm +(seq + (ap user $users) + (canon "peer_id" $stream #canon_stream) +) +``` + #### match/mismath ```wasm @@ -178,3 +196,11 @@ Example - versioned - could be used only by call and fold instructions (more instructions for streams to come) - could be turned to scalar (canonicalized) + +#### Canonicalized streams + +- contains an array of elements that was in a stream at the moment of canonicalization +- canonicalized streams are imutable and fully consistent as scalars +- has the same algebra as a stream for `match`/`mismatch` and `call` argument +- has the same algebra as a scalar for `new` +- has mixed behaviour for with other instructions diff --git a/air-interpreter/Cargo.toml b/air-interpreter/Cargo.toml index 9cb17f05..118ec0f0 100644 --- a/air-interpreter/Cargo.toml +++ b/air-interpreter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "air-interpreter" -version = "0.26.0" +version = "0.27.0" description = "Crate-wrapper for air" authors = ["Fluence Labs"] edition = "2018" diff --git a/air/Cargo.toml b/air/Cargo.toml index 8623a63d..116337f1 100644 --- a/air/Cargo.toml +++ b/air/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "air" -version = "0.26.0" +version = "0.27.0" description = "Interpreter of AIR scripts intended to coordinate request flow in the Fluence network" authors = ["Fluence Labs"] edition = "2018" diff --git a/air/src/execution_step/air/ap.rs b/air/src/execution_step/air/ap.rs index 6fe00f0c..27dbe45c 100644 --- a/air/src/execution_step/air/ap.rs +++ b/air/src/execution_step/air/ap.rs @@ -30,8 +30,8 @@ use crate::SecurityTetraplet; use apply_to_arguments::*; use utils::*; -use air_parser::ast; use air_parser::ast::Ap; +use air_parser::ast::ApResult; use air_trace_handler::MergerApResult; use std::rc::Rc; @@ -57,7 +57,7 @@ impl<'i> super::ExecutableInstruction<'i> for Ap<'i> { /// This function is intended to check whether a Ap instruction should produce /// a new state in data. fn should_touch_trace(ap: &Ap<'_>) -> bool { - matches!(ap.result, ast::Variable::Stream(_)) + matches!(ap.result, ApResult::Stream(_)) } fn to_merger_ap_result( @@ -77,16 +77,14 @@ fn to_merger_ap_result( } fn update_context<'ctx>( - ap_result_type: &ast::Variable<'ctx>, + ap_result_type: &ApResult<'ctx>, merger_ap_result: &MergerApResult, result: ValueAggregate, exec_ctx: &mut ExecutionCtx<'ctx>, ) -> ExecutionResult> { - use ast::Variable::*; - match ap_result_type { - Scalar(scalar) => exec_ctx.scalars.set_value(scalar.name, result).map(|_| None), - Stream(stream) => { + ApResult::Scalar(scalar) => exec_ctx.scalars.set_scalar_value(scalar.name, result).map(|_| None), + ApResult::Stream(stream) => { let generation = ap_result_to_generation(merger_ap_result); exec_ctx .streams diff --git a/air/src/execution_step/air/ap/apply_to_arguments.rs b/air/src/execution_step/air/ap/apply_to_arguments.rs index dccb8261..ae242c78 100644 --- a/air/src/execution_step/air/ap/apply_to_arguments.rs +++ b/air/src/execution_step/air/ap/apply_to_arguments.rs @@ -36,6 +36,7 @@ pub(super) fn apply_to_arg( Boolean(value) => apply_const(*value, exec_ctx, trace_ctx), EmptyArray => apply_const(serde_json::json!([]), exec_ctx, trace_ctx), Scalar(scalar) => apply_scalar(scalar, exec_ctx, trace_ctx, should_touch_trace)?, + CanonStream(canon_stream) => apply_canon_stream(canon_stream, exec_ctx)?, }; Ok(result) @@ -71,7 +72,7 @@ fn apply_scalar( ) -> ExecutionResult { // TODO: refactor this code after boxed value match &scalar.lambda { - Some(lambda) => apply_scalar_wl_impl(scalar.name, scalar.position, lambda, exec_ctx, trace_ctx), + Some(lambda) => apply_scalar_wl_impl(scalar.name, lambda, exec_ctx, trace_ctx), None => apply_scalar_impl(scalar.name, exec_ctx, trace_ctx, should_touch_trace), } } @@ -106,15 +107,53 @@ fn apply_scalar_impl( fn apply_scalar_wl_impl( scalar_name: &str, - position: usize, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'_>, trace_ctx: &TraceHandler, ) -> ExecutionResult { - let variable = Variable::scalar(scalar_name, position); + let variable = Variable::scalar(scalar_name); let (jvalue, tetraplet) = apply_lambda(variable, lambda, exec_ctx)?; let tetraplet = Rc::new(tetraplet); let result = ValueAggregate::new(Rc::new(jvalue), tetraplet, trace_ctx.trace_pos()); Ok(result) } + +fn apply_canon_stream( + canon_stream: &ast::CanonStreamWithLambda<'_>, + exec_ctx: &ExecutionCtx<'_>, +) -> ExecutionResult { + match &canon_stream.lambda { + Some(lambda) => apply_canon_stream_with_lambda(canon_stream.name, lambda, exec_ctx), + None => apply_canon_stream_without_lambda(canon_stream.name, exec_ctx), + } +} + +fn apply_canon_stream_with_lambda( + stream_name: &str, + lambda: &LambdaAST<'_>, + exec_ctx: &ExecutionCtx<'_>, +) -> ExecutionResult { + use crate::execution_step::boxed_value::JValuable; + + let canon_stream = exec_ctx.scalars.get_canon_stream(stream_name)?; + let (result, tetraplet) = JValuable::apply_lambda_with_tetraplets(&canon_stream, lambda, exec_ctx)?; + // TODO: refactor this code after boxed value + let value = ValueAggregate::new(Rc::new(result.clone()), Rc::new(tetraplet), canon_stream.position()); + Ok(value) +} + +fn apply_canon_stream_without_lambda( + stream_name: &str, + exec_ctx: &ExecutionCtx<'_>, +) -> ExecutionResult { + use crate::execution_step::boxed_value::JValuable; + + let canon_stream = exec_ctx.scalars.get_canon_stream(stream_name)?; + // TODO: refactor this code after boxed value + let value = JValuable::as_jvalue(&canon_stream).into_owned(); + + let tetraplet = canon_stream.tetraplet().clone(); + let value = ValueAggregate::new(Rc::new(value), tetraplet, canon_stream.position()); + Ok(value) +} diff --git a/air/src/execution_step/air/ap/utils.rs b/air/src/execution_step/air/ap/utils.rs index aeb6dff8..a61b4462 100644 --- a/air/src/execution_step/air/ap/utils.rs +++ b/air/src/execution_step/air/ap/utils.rs @@ -39,12 +39,12 @@ pub(super) fn try_match_trace_to_instr(merger_ap_result: &MergerApResult, instr: } fn match_position_variable( - variable: &ast::Variable<'_>, + variable: &ast::ApResult<'_>, generation: Option, ap_result: &MergerApResult, ) -> ExecutionResult<()> { use crate::execution_step::UncatchableError::ApResultNotCorrespondToInstr; - use ast::Variable::*; + use ast::ApResult::*; match (variable, generation) { (Stream(_), Some(_)) => Ok(()), diff --git a/air/src/execution_step/air/call.rs b/air/src/execution_step/air/call.rs index 6d6f9776..730b3c6d 100644 --- a/air/src/execution_step/air/call.rs +++ b/air/src/execution_step/air/call.rs @@ -17,7 +17,7 @@ pub(crate) mod call_result_setter; mod prev_result_handler; mod resolved_call; -mod triplet; +pub(crate) mod triplet; use resolved_call::ResolvedCall; diff --git a/air/src/execution_step/air/call/call_result_setter.rs b/air/src/execution_step/air/call/call_result_setter.rs index 5a3c4830..c88da431 100644 --- a/air/src/execution_step/air/call/call_result_setter.rs +++ b/air/src/execution_step/air/call/call_result_setter.rs @@ -23,7 +23,6 @@ use air_interpreter_data::CallResult; use air_interpreter_data::TracePos; use air_interpreter_data::Value; use air_parser::ast::CallOutputValue; -use air_parser::ast::Variable; use air_trace_handler::TraceHandler; /// Writes result of a local `Call` instruction to `ExecutionCtx` at `output`. @@ -35,11 +34,11 @@ pub(crate) fn set_local_result<'i>( ) -> ExecutionResult { let result_value = executed_result.result.clone(); match output { - CallOutputValue::Variable(Variable::Scalar(scalar)) => { - exec_ctx.scalars.set_value(scalar.name, executed_result)?; + CallOutputValue::Scalar(scalar) => { + exec_ctx.scalars.set_scalar_value(scalar.name, executed_result)?; Ok(CallResult::executed_scalar(result_value)) } - CallOutputValue::Variable(Variable::Stream(stream)) => { + CallOutputValue::Stream(stream) => { let generation = exec_ctx .streams @@ -58,11 +57,11 @@ pub(crate) fn set_result_from_value<'i>( exec_ctx: &mut ExecutionCtx<'i>, ) -> ExecutionResult<()> { match (output, value) { - (CallOutputValue::Variable(Variable::Scalar(scalar)), Value::Scalar(value)) => { + (CallOutputValue::Scalar(scalar), Value::Scalar(value)) => { let result = ValueAggregate::new(value, tetraplet, trace_pos); - exec_ctx.scalars.set_value(scalar.name, result)?; + exec_ctx.scalars.set_scalar_value(scalar.name, result)?; } - (CallOutputValue::Variable(Variable::Stream(stream)), Value::Stream { value, generation }) => { + (CallOutputValue::Stream(stream), Value::Stream { value, generation }) => { let result = ValueAggregate::new(value, tetraplet, trace_pos); let generation = Generation::Nth(generation); let _ = exec_ctx diff --git a/air/src/execution_step/air/call/resolved_call.rs b/air/src/execution_step/air/call/resolved_call.rs index 3f973189..23b92c38 100644 --- a/air/src/execution_step/air/call/resolved_call.rs +++ b/air/src/execution_step/air/call/resolved_call.rs @@ -217,7 +217,7 @@ fn check_output_name(output: &ast::CallOutputValue<'_>, exec_ctx: &ExecutionCtx< use crate::execution_step::boxed_value::ScalarRef; let scalar_name = match output { - ast::CallOutputValue::Variable(ast::Variable::Scalar(scalar)) => scalar.name, + ast::CallOutputValue::Scalar(scalar) => scalar.name, _ => return Ok(()), }; diff --git a/air/src/execution_step/air/call/triplet.rs b/air/src/execution_step/air/call/triplet.rs index a28b954b..ce4337ce 100644 --- a/air/src/execution_step/air/call/triplet.rs +++ b/air/src/execution_step/air/call/triplet.rs @@ -43,7 +43,11 @@ pub(crate) fn resolve<'i>(triplet: &ast::Triplet<'i>, ctx: &ExecutionCtx<'i>) -> /// Resolve value to string by either resolving variable from `ExecutionCtx`, taking literal value, or etc. // TODO: return Rc to avoid excess cloning -fn resolve_to_string<'i>(value: &ast::CallInstrValue<'i>, ctx: &ExecutionCtx<'i>) -> ExecutionResult { +// TODO: move this function into resolve in boxed value PR +pub(crate) fn resolve_to_string<'i>( + value: &ast::CallInstrValue<'i>, + ctx: &ExecutionCtx<'i>, +) -> ExecutionResult { use crate::execution_step::resolver::resolve_ast_variable_wl; use ast::CallInstrValue::*; diff --git a/air/src/execution_step/air/canon.rs b/air/src/execution_step/air/canon.rs new file mode 100644 index 00000000..46f2964b --- /dev/null +++ b/air/src/execution_step/air/canon.rs @@ -0,0 +1,170 @@ +/* + * Copyright 2022 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::ExecutionCtx; +use super::ExecutionResult; +use super::TraceHandler; +use crate::execution_step::boxed_value::CanonStream; +use crate::execution_step::Generation; +use crate::log_instruction; +use crate::trace_to_exec_err; +use crate::CatchableError; +use crate::ExecutionError; +use crate::UncatchableError; + +use air_interpreter_data::CanonResult; +use air_interpreter_data::TracePos; +use air_parser::ast; +use air_trace_handler::MergerCanonResult; + +use std::rc::Rc; + +impl<'i> super::ExecutableInstruction<'i> for ast::Canon<'i> { + #[tracing::instrument(level = "debug", skip(exec_ctx, trace_ctx))] + fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> { + log_instruction!(call, exec_ctx, trace_ctx); + let canon_result = trace_to_exec_err!(trace_ctx.meet_canon_start(), self)?; + + match canon_result { + MergerCanonResult::CanonResult { stream_elements_pos } => { + handle_seen_canon(self, stream_elements_pos, exec_ctx, trace_ctx) + } + MergerCanonResult::Empty => handle_unseen_canon(self, exec_ctx, trace_ctx), + } + } +} + +fn handle_seen_canon( + ast_canon: &ast::Canon<'_>, + stream_elements_pos: Vec, + exec_ctx: &mut ExecutionCtx<'_>, + trace_ctx: &mut TraceHandler, +) -> ExecutionResult<()> { + let canon_stream = create_canon_stream_from_pos(&stream_elements_pos, ast_canon, exec_ctx)?; + let stream_with_positions = StreamWithPositions { + canon_stream, + stream_elements_pos, + }; + + epilog(ast_canon.canon_stream.name, stream_with_positions, exec_ctx, trace_ctx) +} + +fn handle_unseen_canon( + ast_canon: &ast::Canon<'_>, + exec_ctx: &mut ExecutionCtx<'_>, + trace_ctx: &mut TraceHandler, +) -> ExecutionResult<()> { + let peer_id = crate::execution_step::air::resolve_to_string(&ast_canon.peer_pk, exec_ctx)?; + + if exec_ctx.run_parameters.current_peer_id.as_str() != peer_id { + exec_ctx.subgraph_complete = false; + exec_ctx.next_peer_pks.push(peer_id); + //this branch is executed only when + // this canon instruction executes for the first time + // a peer is different from one set in peer_id of a this canon instruction + // + // the former means that there wasn't canon associated state in data, the latter that it + // can't be obtained on this peer, so it's intended not to call meet_canon_end here. + return Ok(()); + } + + let stream_with_positions = create_canon_stream_from_name(ast_canon, peer_id, exec_ctx)?; + epilog(ast_canon.canon_stream.name, stream_with_positions, exec_ctx, trace_ctx) +} + +fn create_canon_stream_from_pos( + stream_elements_pos: &[TracePos], + ast_canon: &ast::Canon<'_>, + exec_ctx: &ExecutionCtx<'_>, +) -> ExecutionResult { + let stream = exec_ctx + .streams + .get(ast_canon.stream.name, ast_canon.stream.position) + .ok_or_else(|| { + ExecutionError::Catchable(Rc::new(CatchableError::StreamsForCanonNotFound( + ast_canon.stream.name.to_string(), + ))) + })?; + + let values = stream_elements_pos + .iter() + .map(|&position| { + stream + .get_value_by_pos(position) + .ok_or(ExecutionError::Uncatchable(UncatchableError::VariableNotFoundByPos( + position, + ))) + .cloned() + }) + .collect::, _>>()?; + + let peer_id = crate::execution_step::air::resolve_to_string(&ast_canon.peer_pk, exec_ctx)?; + let canon_stream = CanonStream::new(values, peer_id, ast_canon.stream.position.into()); + Ok(canon_stream) +} + +fn epilog( + canon_stream_name: &str, + stream_with_positions: StreamWithPositions, + exec_ctx: &mut ExecutionCtx<'_>, + trace_ctx: &mut TraceHandler, +) -> ExecutionResult<()> { + let StreamWithPositions { + canon_stream, + stream_elements_pos, + } = stream_with_positions; + + exec_ctx + .scalars + .set_canon_value(canon_stream_name, canon_stream) + .map(|_| ())?; + trace_ctx.meet_canon_end(CanonResult::new(stream_elements_pos)); + Ok(()) +} + +struct StreamWithPositions { + canon_stream: CanonStream, + stream_elements_pos: Vec, +} + +fn create_canon_stream_from_name( + ast_canon: &ast::Canon<'_>, + peer_id: String, + exec_ctx: &ExecutionCtx<'_>, +) -> ExecutionResult { + let stream = exec_ctx + .streams + .get(ast_canon.stream.name, ast_canon.stream.position) + .ok_or_else(|| { + ExecutionError::Catchable(Rc::new(CatchableError::StreamsForCanonNotFound( + ast_canon.stream.name.to_string(), + ))) + })?; + let canon_stream = CanonStream::from_stream(stream, peer_id, ast_canon.canon_stream.position.into()); + let stream_elements_pos = stream + .iter(Generation::Last) + // it's always safe to iter over all generations + .unwrap() + .map(|value| value.trace_pos) + .collect::>(); + + let result = StreamWithPositions { + canon_stream, + stream_elements_pos, + }; + + Ok(result) +} diff --git a/air/src/execution_step/air/fail.rs b/air/src/execution_step/air/fail.rs index 3e19c053..0b552b76 100644 --- a/air/src/execution_step/air/fail.rs +++ b/air/src/execution_step/air/fail.rs @@ -18,7 +18,7 @@ use super::ExecutionCtx; use super::ExecutionResult; use super::TraceHandler; use crate::execution_step::execution_context::check_error_object; -use crate::execution_step::resolver::resolve_ast_scalar_wl; +use crate::execution_step::resolver::{apply_lambda, resolve_ast_scalar_wl}; use crate::execution_step::CatchableError; use crate::execution_step::LastError; use crate::execution_step::RcSecurityTetraplet; @@ -30,6 +30,8 @@ use air_parser::ast; use air_parser::ast::Fail; use polyplets::SecurityTetraplet; +use crate::execution_step::boxed_value::Variable; +use air_lambda_ast::LambdaAST; use std::rc::Rc; impl<'i> super::ExecutableInstruction<'i> for Fail<'i> { @@ -42,6 +44,7 @@ impl<'i> super::ExecutableInstruction<'i> for Fail<'i> { ret_code, error_message, } => fail_with_literals(ret_code, error_message, self, exec_ctx), + Fail::CanonStream { name, lambda } => fail_with_canon_stream(name, lambda, exec_ctx), // bubble last error up Fail::LastError => fail_with_last_error(exec_ctx), } @@ -76,6 +79,20 @@ fn fail_with_literals<'i>( fail_with_error_object(exec_ctx, Rc::new(error_object), Some(literal_tetraplet)) } +fn fail_with_canon_stream<'i>( + name: &'i str, + lambda: &LambdaAST<'i>, + exec_ctx: &mut ExecutionCtx<'i>, +) -> ExecutionResult<()> { + let variable = Variable::CanonStream { name }; + + let (value, tetraplet) = apply_lambda(variable, lambda, exec_ctx)?; + // tetraplets always have one element here and it'll be refactored after boxed value + check_error_object(&value).map_err(CatchableError::InvalidLastErrorObjectError)?; + + fail_with_error_object(exec_ctx, Rc::new(value), Some(Rc::new(tetraplet))) +} + fn fail_with_last_error(exec_ctx: &mut ExecutionCtx<'_>) -> ExecutionResult<()> { let LastError { error, tetraplet } = exec_ctx.last_error_descriptor.last_error(); diff --git a/air/src/execution_step/air/fold/mod.rs b/air/src/execution_step/air/fold/mod.rs index 3dca8ad5..d9095a2e 100644 --- a/air/src/execution_step/air/fold/mod.rs +++ b/air/src/execution_step/air/fold/mod.rs @@ -25,5 +25,4 @@ use super::ExecutionCtx; use super::ExecutionResult; use super::Instruction; use super::ScalarRef; -use super::ValueAggregate; use crate::execution_step::boxed_value::*; diff --git a/air/src/execution_step/air/fold/utils.rs b/air/src/execution_step/air/fold/utils.rs index 3c883a59..d2db8dab 100644 --- a/air/src/execution_step/air/fold/utils.rs +++ b/air/src/execution_step/air/fold/utils.rs @@ -31,7 +31,7 @@ pub(crate) type IterableValue = Box Iterable<'ctx, Item = Iterable pub(crate) enum FoldIterableScalar { Empty, - Scalar(IterableValue), + ScalarBased(IterableValue), } /// Constructs iterable value for given scalar iterable. @@ -45,6 +45,18 @@ pub(crate) fn construct_scalar_iterable_value<'ctx>( } } +/// Constructs iterable value for given canon stream. +pub(crate) fn construct_canon_stream_iterable_value<'ctx>( + ast_canon_stream: &ast::CanonStream<'ctx>, + exec_ctx: &ExecutionCtx<'ctx>, +) -> ExecutionResult { + let canon_stream = exec_ctx.scalars.get_canon_stream(ast_canon_stream.name)?; + // TODO: this one is a relatively long operation and will be refactored in Boxed Value + let iterable_ingredients = CanonStreamIterableIngredients::init(canon_stream.clone()); + let iterable = Box::new(iterable_ingredients); + Ok(FoldIterableScalar::ScalarBased(iterable)) +} + /// Constructs iterable value for given stream iterable. pub(crate) fn construct_stream_iterable_values( stream: &Stream, @@ -72,17 +84,17 @@ fn create_scalar_iterable<'ctx>( variable_name: &str, ) -> ExecutionResult { match exec_ctx.scalars.get_value(variable_name)? { - ScalarRef::Value(call_result) => from_call_result(call_result.clone(), variable_name), + ScalarRef::Value(call_result) => from_value(call_result.clone(), variable_name), ScalarRef::IterableValue(fold_state) => { let iterable_value = fold_state.iterable.peek().unwrap(); let call_result = iterable_value.into_resolved_result(); - from_call_result(call_result, variable_name) + from_value(call_result, variable_name) } } } /// Constructs iterable value from resolved call result. -fn from_call_result(call_result: ValueAggregate, variable_name: &str) -> ExecutionResult { +fn from_value(call_result: ValueAggregate, variable_name: &str) -> ExecutionResult { let len = match &call_result.result.deref() { JValue::Array(array) => { if array.is_empty() { @@ -103,7 +115,7 @@ fn from_call_result(call_result: ValueAggregate, variable_name: &str) -> Executi let foldable = IterableResolvedCall::init(call_result, len); let foldable = Box::new(foldable); - let iterable = FoldIterableScalar::Scalar(foldable); + let iterable = FoldIterableScalar::ScalarBased(foldable); Ok(iterable) } @@ -154,7 +166,7 @@ fn from_jvalue( let iterable = iterable.to_vec(); let foldable = IterableLambdaResult::init(iterable, tetraplet); - let iterable = FoldIterableScalar::Scalar(Box::new(foldable)); + let iterable = FoldIterableScalar::ScalarBased(Box::new(foldable)); Ok(iterable) } diff --git a/air/src/execution_step/air/fold_scalar.rs b/air/src/execution_step/air/fold_scalar.rs index 7d9a502b..7f7f4617 100644 --- a/air/src/execution_step/air/fold_scalar.rs +++ b/air/src/execution_step/air/fold_scalar.rs @@ -33,17 +33,21 @@ impl<'i> ExecutableInstruction<'i> for FoldScalar<'i> { fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> { log_instruction!(fold, exec_ctx, trace_ctx); - let scalar = match &self.iterable { - FoldScalarIterable::Scalar(scalar) => scalar, + let iterable = match &self.iterable { + FoldScalarIterable::Scalar(scalar) => { + joinable!(construct_scalar_iterable_value(scalar, exec_ctx), exec_ctx)? + } + FoldScalarIterable::CanonStream(canon_stream) => { + construct_canon_stream_iterable_value(canon_stream, exec_ctx)? + } // just do nothing on an empty array FoldScalarIterable::EmptyArray => return Ok(()), }; - let scalar_iterable = joinable!(construct_scalar_iterable_value(scalar, exec_ctx), exec_ctx)?; - match scalar_iterable { + match iterable { // just exit on empty iterable FoldIterableScalar::Empty => Ok(()), - FoldIterableScalar::Scalar(iterable) => fold( + FoldIterableScalar::ScalarBased(iterable) => fold( iterable, IterableType::Scalar, self.iterator.name, diff --git a/air/src/execution_step/air/mod.rs b/air/src/execution_step/air/mod.rs index 1c2390a5..02078c6b 100644 --- a/air/src/execution_step/air/mod.rs +++ b/air/src/execution_step/air/mod.rs @@ -16,6 +16,7 @@ mod ap; mod call; +mod canon; mod compare_matchable; mod fail; mod fold; @@ -30,6 +31,7 @@ mod par; mod seq; mod xor; +pub(crate) use call::triplet::resolve_to_string; pub(crate) use fold::FoldState; use super::boxed_value::ScalarRef; @@ -74,6 +76,7 @@ impl<'i> ExecutableInstruction<'i> for Instruction<'i> { Instruction::Call(call) => call.execute(exec_ctx, trace_ctx), Instruction::Ap(ap) => execute!(self, ap, exec_ctx, trace_ctx), + Instruction::Canon(canon) => execute!(self, canon, exec_ctx, trace_ctx), Instruction::Fail(fail) => execute!(self, fail, exec_ctx, trace_ctx), Instruction::FoldScalar(fold) => execute!(self, fold, exec_ctx, trace_ctx), Instruction::FoldStream(fold) => execute!(self, fold, exec_ctx, trace_ctx), diff --git a/air/src/execution_step/air/new.rs b/air/src/execution_step/air/new.rs index afb192b7..5148a685 100644 --- a/air/src/execution_step/air/new.rs +++ b/air/src/execution_step/air/new.rs @@ -20,7 +20,7 @@ use super::TraceHandler; use crate::log_instruction; use air_parser::ast::New; -use air_parser::ast::Variable; +use air_parser::ast::NewArgument; impl<'i> super::ExecutableInstruction<'i> for New<'i> { fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> { @@ -48,12 +48,15 @@ impl<'i> super::ExecutableInstruction<'i> for New<'i> { fn prolog<'i>(new: &New<'i>, exec_ctx: &mut ExecutionCtx<'i>) { let position = new.span.left; - match &new.variable { - Variable::Stream(stream) => { + match &new.argument { + NewArgument::Stream(stream) => { let iteration = exec_ctx.tracker.new_tracker.get_iteration(position); exec_ctx.streams.meet_scope_start(stream.name, new.span, iteration); } - Variable::Scalar(scalar) => exec_ctx.scalars.meet_new_start(scalar.name), + NewArgument::Scalar(scalar) => exec_ctx.scalars.meet_new_start_scalar(scalar.name.to_string()), + NewArgument::CanonStream(canon_stream) => exec_ctx + .scalars + .meet_new_start_canon_stream(canon_stream.name.to_string()), } exec_ctx.tracker.meet_new(position); @@ -61,13 +64,14 @@ fn prolog<'i>(new: &New<'i>, exec_ctx: &mut ExecutionCtx<'i>) { fn epilog<'i>(new: &New<'i>, exec_ctx: &mut ExecutionCtx<'i>) -> ExecutionResult<()> { let position = new.span.left; - match &new.variable { - Variable::Stream(stream) => { + match &new.argument { + NewArgument::Stream(stream) => { exec_ctx .streams .meet_scope_end(stream.name.to_string(), position as u32); Ok(()) } - Variable::Scalar(scalar) => exec_ctx.scalars.meet_new_end(scalar.name), + NewArgument::Scalar(scalar) => exec_ctx.scalars.meet_new_end_scalar(scalar.name), + NewArgument::CanonStream(canon_stream) => exec_ctx.scalars.meet_new_end_canon_stream(canon_stream.name), } } diff --git a/air/src/execution_step/boxed_value/canon_stream.rs b/air/src/execution_step/boxed_value/canon_stream.rs new file mode 100644 index 00000000..a528c0d4 --- /dev/null +++ b/air/src/execution_step/boxed_value/canon_stream.rs @@ -0,0 +1,102 @@ +/* + * Copyright 2022 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::Stream; +use super::ValueAggregate; +use crate::execution_step::Generation; +use crate::JValue; + +use air_interpreter_data::TracePos; +use polyplets::SecurityTetraplet; + +use std::rc::Rc; + +/// Canon stream is a value type lies between a scalar and a stream, it has the same algebra as +/// scalars, and represent a stream fixed at some execution point. +#[derive(Debug, Default, Clone)] +pub struct CanonStream { + values: Vec, + // tetraplet is needed to handle adding canon streams as a whole to a stream + tetraplet: Rc, + position: TracePos, +} + +impl CanonStream { + pub(crate) fn new(values: Vec, peer_pk: String, position: TracePos) -> Self { + // tetraplet is comprised only from peer_pk here + let tetraplet = SecurityTetraplet::new(peer_pk, "", "", ""); + Self { + values, + tetraplet: Rc::new(tetraplet), + position, + } + } + + pub(crate) fn from_stream(stream: &Stream, peer_pk: String, position: TracePos) -> Self { + // it's always possible to iter over all generations of a stream + let values = stream.iter(Generation::Last).unwrap().cloned().collect::>(); + let tetraplet = SecurityTetraplet::new(peer_pk, "", "", ""); + Self { + values, + tetraplet: Rc::new(tetraplet), + position, + } + } + + pub(crate) fn len(&self) -> usize { + self.values.len() + } + + pub(crate) fn is_empty(&self) -> bool { + self.values.is_empty() + } + + pub(crate) fn as_jvalue(&self) -> JValue { + use std::ops::Deref; + + // TODO: this clone will be removed after boxed values + let jvalue_array = self.values.iter().map(|r| r.result.deref().clone()).collect::>(); + JValue::Array(jvalue_array) + } + + pub(crate) fn iter(&self) -> impl ExactSizeIterator { + self.values.iter() + } + + pub(crate) fn nth(&self, idx: usize) -> Option<&ValueAggregate> { + self.values.get(idx) + } + + pub(crate) fn tetraplet(&self) -> &Rc { + &self.tetraplet + } + + pub(crate) fn position(&self) -> TracePos { + self.position + } +} + +use std::fmt; + +impl fmt::Display for CanonStream { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "[")?; + for value in self.values.iter() { + write!(f, "{}, ", value)?; + } + write!(f, "]") + } +} diff --git a/air/src/execution_step/boxed_value/iterable.rs b/air/src/execution_step/boxed_value/iterable.rs index 5ed984f8..1fa4bdce 100644 --- a/air/src/execution_step/boxed_value/iterable.rs +++ b/air/src/execution_step/boxed_value/iterable.rs @@ -14,11 +14,12 @@ * limitations under the License. */ +mod canon_stream; mod json_path_result; mod resolved_call; -mod vec_json_path_result; mod vec_resolved_call; +pub(crate) use canon_stream::CanonStreamIterableIngredients; pub(crate) use json_path_result::IterableLambdaResult; pub(crate) use resolved_call::IterableResolvedCall; pub(crate) use vec_resolved_call::IterableVecResolvedCall; diff --git a/air/src/execution_step/boxed_value/iterable/vec_json_path_result.rs b/air/src/execution_step/boxed_value/iterable/canon_stream.rs similarity index 53% rename from air/src/execution_step/boxed_value/iterable/vec_json_path_result.rs rename to air/src/execution_step/boxed_value/iterable/canon_stream.rs index f370a9c1..95982218 100644 --- a/air/src/execution_step/boxed_value/iterable/vec_json_path_result.rs +++ b/air/src/execution_step/boxed_value/iterable/canon_stream.rs @@ -16,36 +16,31 @@ use super::Iterable; use super::IterableItem; -use crate::execution_step::RcSecurityTetraplets; +use crate::execution_step::boxed_value::CanonStream; use crate::foldable_next; use crate::foldable_prev; -use crate::JValue; -/// Used for iterating over a result of applied to a stream lambda. -#[derive(Clone, Debug, Eq, PartialEq)] -pub(crate) struct IterableVecJsonPathResult { - pub(crate) jvalues: Vec, - pub(crate) tetraplets: RcSecurityTetraplets, - pub(crate) cursor: usize, +const EXPECT_VALUE_IN_STREAM: &str = "value must exist, because length checked before creation and canonicalized stream can't be modified during iteration"; + +pub(crate) struct CanonStreamIterableIngredients { + canon_stream: CanonStream, + cursor: usize, } -impl IterableVecJsonPathResult { - #[allow(dead_code)] - pub(crate) fn init(jvalues: Vec, tetraplets: RcSecurityTetraplets) -> Self { - // TODO: add assert on length +impl CanonStreamIterableIngredients { + pub(crate) fn init(canon_stream: CanonStream) -> Self { Self { - jvalues, - tetraplets, + canon_stream, cursor: 0, } } } -impl<'ctx> Iterable<'ctx> for IterableVecJsonPathResult { +impl<'ctx> Iterable<'ctx> for CanonStreamIterableIngredients { type Item = IterableItem<'ctx>; fn next(&mut self) -> bool { - foldable_next!(self, self.jvalues.len()) + foldable_next!(self, self.len()) } fn prev(&mut self) -> bool { @@ -53,18 +48,16 @@ impl<'ctx> Iterable<'ctx> for IterableVecJsonPathResult { } fn peek(&'ctx self) -> Option { - if self.jvalues.is_empty() { + if self.canon_stream.is_empty() { return None; } - let jvalue = &self.jvalues[self.cursor]; - let tetraplet = &self.tetraplets[self.cursor]; - let result = IterableItem::RefRef((jvalue, tetraplet, 0.into())); - + let value = self.canon_stream.nth(self.cursor).expect(EXPECT_VALUE_IN_STREAM); + let result = IterableItem::RefRef((&value.result, &value.tetraplet, value.trace_pos)); Some(result) } fn len(&self) -> usize { - self.jvalues.len() + self.canon_stream.len() } } diff --git a/air/src/execution_step/boxed_value/jvaluable.rs b/air/src/execution_step/boxed_value/jvaluable.rs index ae8b5c42..7a51b12f 100644 --- a/air/src/execution_step/boxed_value/jvaluable.rs +++ b/air/src/execution_step/boxed_value/jvaluable.rs @@ -14,6 +14,7 @@ * limitations under the License. */ +mod canon_stream; mod cell_vec_resolved_call_result; mod empty_stream; mod iterable_item; diff --git a/air/src/execution_step/boxed_value/jvaluable/canon_stream.rs b/air/src/execution_step/boxed_value/jvaluable/canon_stream.rs new file mode 100644 index 00000000..5551c4c5 --- /dev/null +++ b/air/src/execution_step/boxed_value/jvaluable/canon_stream.rs @@ -0,0 +1,68 @@ +/* + * Copyright 2022 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::select_from_stream; +use super::ExecutionResult; +use super::JValuable; +use crate::execution_step::boxed_value::CanonStream; +use crate::execution_step::ExecutionCtx; +use crate::execution_step::RcSecurityTetraplets; +use crate::JValue; +use crate::LambdaAST; +use crate::SecurityTetraplet; + +use air_lambda_ast::format_ast; + +use std::borrow::Cow; +use std::ops::Deref; + +impl JValuable for &CanonStream { + fn apply_lambda<'i>(&self, lambda: &LambdaAST<'_>, exec_ctx: &ExecutionCtx<'i>) -> ExecutionResult<&JValue> { + let iter = self.iter().map(|v| v.result.deref()); + let select_result = select_from_stream(iter, lambda, exec_ctx)?; + + Ok(select_result.result) + } + + fn apply_lambda_with_tetraplets<'i>( + &self, + lambda: &LambdaAST<'_>, + exec_ctx: &ExecutionCtx<'i>, + ) -> ExecutionResult<(&JValue, SecurityTetraplet)> { + let iter = self.iter().map(|v| v.result.deref()); + let select_result = select_from_stream(iter, lambda, exec_ctx)?; + + // unwrap is safe here because each value has a tetraplet and a lambda always returns a valid index + let resolved_call = self.nth(select_result.tetraplet_idx).unwrap(); + let mut tetraplet = resolved_call.tetraplet.as_ref().clone(); + tetraplet.add_lambda(&format_ast(lambda)); + + Ok((select_result.result, tetraplet)) + } + + fn as_jvalue(&self) -> Cow<'_, JValue> { + let jvalue = CanonStream::as_jvalue(self); + Cow::Owned(jvalue) + } + + fn into_jvalue(self: Box) -> JValue { + CanonStream::as_jvalue(&self) + } + + fn as_tetraplets(&self) -> RcSecurityTetraplets { + self.iter().map(|r| r.tetraplet.clone()).collect::>() + } +} diff --git a/air/src/execution_step/boxed_value/mod.rs b/air/src/execution_step/boxed_value/mod.rs index fabf23ba..56f51ceb 100644 --- a/air/src/execution_step/boxed_value/mod.rs +++ b/air/src/execution_step/boxed_value/mod.rs @@ -14,12 +14,14 @@ * limitations under the License. */ +mod canon_stream; mod iterable; mod jvaluable; mod scalar; mod stream; mod variable; +pub(crate) use canon_stream::*; pub(crate) use iterable::*; pub(crate) use jvaluable::*; pub(crate) use scalar::ScalarRef; diff --git a/air/src/execution_step/boxed_value/scalar.rs b/air/src/execution_step/boxed_value/scalar.rs index f3591902..f041be22 100644 --- a/air/src/execution_step/boxed_value/scalar.rs +++ b/air/src/execution_step/boxed_value/scalar.rs @@ -23,8 +23,6 @@ use air_interpreter_data::TracePos; use serde::Deserialize; use serde::Serialize; -use std::fmt::Display; -use std::fmt::Formatter; use std::rc::Rc; #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] @@ -61,8 +59,20 @@ impl ValueAggregate { } } -impl<'i> Display for ScalarRef<'i> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +use std::fmt; + +impl fmt::Display for ValueAggregate { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "value: {}, tetraplet: {}, position: {} ", + self.result, self.tetraplet, self.trace_pos + ) + } +} + +impl<'i> fmt::Display for ScalarRef<'i> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { ScalarRef::Value(value) => write!(f, "{:?}", value)?, ScalarRef::IterableValue(cursor) => { diff --git a/air/src/execution_step/boxed_value/stream.rs b/air/src/execution_step/boxed_value/stream.rs index d08ae342..7f08a64e 100644 --- a/air/src/execution_step/boxed_value/stream.rs +++ b/air/src/execution_step/boxed_value/stream.rs @@ -19,70 +19,90 @@ use super::ValueAggregate; use crate::execution_step::CatchableError; use crate::JValue; +use air_interpreter_data::TracePos; + +use std::collections::HashMap; use std::fmt::Formatter; /// Streams are CRDT-like append only data structures. They are guaranteed to have the same order /// of values on each peer. -/// -/// The first Vec represents generations, the second values in a generation. Generation is a set -/// of values that interpreter obtained from one particle. It means that number of generation on -/// a peer is equal to number of the interpreter runs in context of one particle. And each set of -/// obtained values from a current_data that were not present in prev_data becomes a new generation. #[derive(Debug, Default, Clone)] -pub struct Stream(Vec>); +pub struct Stream { + /// The first Vec represents generations, the second values in a generation. Generation is a set + /// of values that interpreter obtained from one particle. It means that number of generation on + /// a peer is equal to number of the interpreter runs in context of one particle. And each set of + /// obtained values from a current_data that were not present in prev_data becomes a new generation. + values: Vec>, + + /// This map is intended to support canonicalized stream creation, such streams has + /// corresponding value positions in a data and this field are used to create such streams. + values_by_pos: HashMap, +} impl Stream { pub(crate) fn from_generations_count(count: usize) -> Self { - Self(vec![vec![]; count + 1]) + Self { + values: vec![vec![]; count + 1], + values_by_pos: HashMap::new(), + } } pub(crate) fn from_value(value: ValueAggregate) -> Self { - Self(vec![vec![value]]) + let values_by_pos = maplit::hashmap! { + value.trace_pos => StreamValueLocation::new(0, 0), + }; + Self { + values: vec![vec![value]], + values_by_pos, + } } // if generation is None, value would be added to the last generation, otherwise it would // be added to given generation pub(crate) fn add_value(&mut self, value: ValueAggregate, generation: Generation) -> ExecutionResult { let generation = match generation { - Generation::Last => self.0.len() - 1, + Generation::Last => self.values.len() - 1, Generation::Nth(id) => id as usize, }; - if generation >= self.0.len() { + if generation >= self.values.len() { return Err(CatchableError::StreamDontHaveSuchGeneration(self.clone(), generation).into()); } - self.0[generation].push(value); + let values = &mut self.values[generation]; + self.values_by_pos + .insert(value.trace_pos, StreamValueLocation::new(generation, values.len())); + values.push(value); Ok(generation as u32) } pub(crate) fn generations_count(&self) -> usize { // the last generation could be empty due to the logic of from_generations_count ctor - self.0.iter().filter(|gen| !gen.is_empty()).count() + self.values.iter().filter(|gen| !gen.is_empty()).count() } /// Add a new empty generation if the latest isn't empty. pub(crate) fn add_new_generation_if_non_empty(&mut self) -> bool { - let should_add_generation = match self.0.last() { + let should_add_generation = match self.values.last() { Some(last) => !last.is_empty(), None => true, }; if should_add_generation { - self.0.push(vec![]); + self.values.push(vec![]); } should_add_generation } /// Remove a last generation if it's empty. pub(crate) fn remove_last_generation_if_empty(&mut self) -> bool { - let should_remove_generation = match self.0.last() { + let should_remove_generation = match self.values.last() { Some(last) => last.is_empty(), None => false, }; if should_remove_generation { - self.0.pop(); + self.values.pop(); } should_remove_generation @@ -91,17 +111,17 @@ impl Stream { pub(crate) fn elements_count(&self, generation: Generation) -> Option { match generation { Generation::Nth(generation) if generation as usize > self.generations_count() => None, - Generation::Nth(generation) => Some(self.0.iter().take(generation as usize).map(|v| v.len()).sum()), - Generation::Last => Some(self.0.iter().map(|v| v.len()).sum()), + Generation::Nth(generation) => Some(self.values.iter().take(generation as usize).map(|v| v.len()).sum()), + Generation::Last => Some(self.values.iter().map(|v| v.len()).sum()), } } pub(crate) fn is_empty(&self) -> bool { - if self.0.is_empty() { + if self.values.is_empty() { return false; } - self.0.iter().all(|v| v.is_empty()) + self.values.iter().all(|v| v.is_empty()) } pub(crate) fn as_jvalue(&self, generation: Generation) -> Option { @@ -113,11 +133,22 @@ impl Stream { Some(JValue::Array(jvalue_array)) } + pub(crate) fn get_value_by_pos(&self, position: TracePos) -> Option<&ValueAggregate> { + let StreamValueLocation { + generation, + position_in_generation, + } = self.values_by_pos.get(&position)?; + let value = &self.values[*generation][*position_in_generation]; + Some(value) + } + pub(crate) fn iter(&self, generation: Generation) -> Option> { let iter: Box> = match generation { Generation::Nth(generation) if generation as usize >= self.generations_count() => return None, - Generation::Nth(generation) => Box::new(self.0.iter().take(generation as usize + 1).flat_map(|v| v.iter())), - Generation::Last => Box::new(self.0.iter().flat_map(|v| v.iter())), + Generation::Nth(generation) => { + Box::new(self.values.iter().take(generation as usize + 1).flat_map(|v| v.iter())) + } + Generation::Last => Box::new(self.values.iter().flat_map(|v| v.iter())), }; // unwrap is safe here, because generation's been already checked let len = self.elements_count(generation).unwrap(); @@ -146,7 +177,7 @@ impl Stream { let len = (end - start) as usize + 1; let iter: Box> = - Box::new(self.0.iter().skip(start as usize).take(len).map(|v| v.as_slice())); + Box::new(self.values.iter().skip(start as usize).take(len).map(|v| v.as_slice())); let iter = StreamSliceIter { iter, len }; Some(iter) @@ -210,16 +241,31 @@ impl<'slice> Iterator for StreamSliceIter<'slice> { } } +#[derive(Clone, Copy, Debug, Default)] +struct StreamValueLocation { + pub generation: usize, + pub position_in_generation: usize, +} + +impl StreamValueLocation { + pub(super) fn new(generation: usize, position_in_generation: usize) -> Self { + Self { + generation, + position_in_generation, + } + } +} + use std::fmt; impl fmt::Display for Stream { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - if self.0.is_empty() { + if self.values.is_empty() { return write!(f, "[]"); } writeln!(f, "[")?; - for (id, generation) in self.0.iter().enumerate() { + for (id, generation) in self.values.iter().enumerate() { write!(f, " -- {}: ", id)?; for value in generation.iter() { write!(f, "{:?}, ", value)?; diff --git a/air/src/execution_step/boxed_value/variable.rs b/air/src/execution_step/boxed_value/variable.rs index 9280a677..290a37b7 100644 --- a/air/src/execution_step/boxed_value/variable.rs +++ b/air/src/execution_step/boxed_value/variable.rs @@ -19,19 +19,22 @@ use air_parser::ast; #[derive(Clone, Copy, Debug)] pub(crate) enum Variable<'i> { - #[allow(dead_code)] - // position will be needed to implement new for operators - Scalar { name: &'i str, position: usize }, + Scalar { + name: &'i str, + }, Stream { name: &'i str, generation: Generation, position: usize, }, + CanonStream { + name: &'i str, + }, } impl<'i> Variable<'i> { - pub(crate) fn scalar(name: &'i str, position: usize) -> Self { - Self::Scalar { name, position } + pub(crate) fn scalar(name: &'i str) -> Self { + Self::Scalar { name } } pub(crate) fn stream(name: &'i str, generation: Generation, position: usize) -> Self { @@ -41,6 +44,10 @@ impl<'i> Variable<'i> { position, } } + + pub(crate) fn canon_stream(name: &'i str) -> Self { + Self::CanonStream { name } + } } impl<'i> From<&ast::Variable<'i>> for Variable<'i> { @@ -48,8 +55,9 @@ impl<'i> From<&ast::Variable<'i>> for Variable<'i> { use ast::Variable::*; match ast_variable { - Scalar(scalar) => Self::scalar(scalar.name, scalar.position), + Scalar(scalar) => Self::scalar(scalar.name), Stream(stream) => Self::stream(stream.name, Generation::Last, stream.position), + CanonStream(canon_stream) => Self::canon_stream(canon_stream.name), } } } @@ -59,8 +67,9 @@ impl<'i> From<&ast::VariableWithLambda<'i>> for Variable<'i> { use ast::VariableWithLambda::*; match ast_variable { - Scalar(scalar) => Self::scalar(scalar.name, scalar.position), + Scalar(scalar) => Self::scalar(scalar.name), Stream(stream) => Self::stream(stream.name, Generation::Last, stream.position), + CanonStream(canon_stream) => Self::canon_stream(canon_stream.name), } } } diff --git a/air/src/execution_step/errors/catchable_errors.rs b/air/src/execution_step/errors/catchable_errors.rs index f1ad4edc..4f7c3cd7 100644 --- a/air/src/execution_step/errors/catchable_errors.rs +++ b/air/src/execution_step/errors/catchable_errors.rs @@ -87,6 +87,10 @@ pub enum CatchableError { /// that is prohibited. #[error("variable with name '{0}' was cleared by new and then wasn't set")] VariableWasNotInitializedAfterNew(String), + + /// Canon instruction can't canonicalize a stream since it's been found. + #[error("stream with name {0} wasn't defined, so canon instruction can't canonicalize it")] + StreamsForCanonNotFound(String), } impl From for Rc { diff --git a/air/src/execution_step/errors/uncatchable_errors.rs b/air/src/execution_step/errors/uncatchable_errors.rs index e377809a..2827a302 100644 --- a/air/src/execution_step/errors/uncatchable_errors.rs +++ b/air/src/execution_step/errors/uncatchable_errors.rs @@ -16,6 +16,7 @@ use crate::ToErrorCode; +use air_interpreter_data::TracePos; use air_trace_handler::MergerApResult; use air_trace_handler::TraceHandlerError; use strum::IntoEnumIterator; @@ -65,6 +66,12 @@ pub enum UncatchableError { /// be caught by a xor instruction. #[error("new end block tries to pop up a variable '{scalar_name}' that wasn't defined at depth {depth}")] ScalarsStateCorrupted { scalar_name: String, depth: usize }, + + /// Variable with such a position wasn't defined during AIR script execution. + /// Canon instruction requires this value to be present in data, otherwise it's considered + /// as a hard error. + #[error("variable with position '{0}' wasn't defined during script execution")] + VariableNotFoundByPos(TracePos), } impl ToErrorCode for UncatchableError { diff --git a/air/src/execution_step/execution_context/scalar_variables.rs b/air/src/execution_step/execution_context/scalar_variables.rs index f56d98c5..21fcd937 100644 --- a/air/src/execution_step/execution_context/scalar_variables.rs +++ b/air/src/execution_step/execution_context/scalar_variables.rs @@ -14,20 +14,17 @@ * limitations under the License. */ +mod values_sparse_matrix; + +use crate::execution_step::boxed_value::CanonStream; use crate::execution_step::boxed_value::ScalarRef; use crate::execution_step::errors_prelude::*; use crate::execution_step::ExecutionResult; use crate::execution_step::FoldState; use crate::execution_step::ValueAggregate; - -use non_empty_vec::NonEmpty; +use values_sparse_matrix::ValuesSparseMatrix; use std::collections::HashMap; -use std::collections::HashSet; -use std::rc::Rc; - -/// Depth of a global scope. -const GLOBAL_DEPTH: usize = 0; // TODO: move this code snippet to documentation when it's ready @@ -87,85 +84,32 @@ pub(crate) struct Scalars<'i> { /// - global variables have 0 depth /// - cells in a row are sorted by depth /// - all depths in cell in one row are unique - pub(crate) non_iterable_variables: HashMap>, + pub(crate) non_iterable_variables: ValuesSparseMatrix, - /// This set contains depths were invalidated at the certain moment of script execution. - /// They are needed for careful isolation of scopes produced by iterations in fold blocks, - /// precisely to limit access of non iterable variables defined on one depths to ones - /// defined on another. - pub(crate) allowed_depths: HashSet, + pub(crate) canon_streams: ValuesSparseMatrix, pub(crate) iterable_variables: HashMap>, - - /// Count of met scopes at the particular moment of execution. - pub(crate) current_depth: usize, -} - -#[derive(Debug)] -pub(crate) struct SparseCell { - /// Scope depth where the value was set. - pub(crate) depth: usize, - pub(crate) value: Option, -} - -impl SparseCell { - pub(crate) fn from_value(depth: usize, value: ValueAggregate) -> Self { - Self { - depth, - value: Some(value), - } - } - - pub(crate) fn from_met_new(depth: usize) -> Self { - Self { depth, value: None } - } } impl<'i> Scalars<'i> { pub fn new() -> Self { - let allowed_depths = maplit::hashset! { GLOBAL_DEPTH }; - Self { - non_iterable_variables: HashMap::new(), - allowed_depths, + non_iterable_variables: ValuesSparseMatrix::new(), + canon_streams: ValuesSparseMatrix::new(), iterable_variables: HashMap::new(), - current_depth: GLOBAL_DEPTH, } } /// Returns true if there was a previous value for the provided key on the same /// fold block. - pub(crate) fn set_value(&mut self, name: impl Into, value: ValueAggregate) -> ExecutionResult { - use std::collections::hash_map::Entry::{Occupied, Vacant}; + pub(crate) fn set_scalar_value(&mut self, name: impl Into, value: ValueAggregate) -> ExecutionResult { + self.non_iterable_variables.set_value(name, value) + } - let name = name.into(); - let variable_could_be_set = self.variable_could_be_set(&name); - match self.non_iterable_variables.entry(name) { - Vacant(entry) => { - let cell = SparseCell::from_value(self.current_depth, value); - let cells = NonEmpty::new(cell); - entry.insert(cells); - - Ok(false) - } - Occupied(entry) => { - if !variable_could_be_set { - return Err(UncatchableError::ShadowingIsNotAllowed(entry.key().clone()).into()); - } - - let values = entry.into_mut(); - let last_cell = values.last_mut(); - if last_cell.depth == self.current_depth { - // just rewrite a value if fold level is the same - last_cell.value = Some(value); - Ok(true) - } else { - let new_cell = SparseCell::from_value(self.current_depth, value); - values.push(new_cell); - Ok(false) - } - } - } + /// Returns true if there was a previous value for the provided key on the same + /// fold block. + pub(crate) fn set_canon_value(&mut self, name: impl Into, value: CanonStream) -> ExecutionResult { + self.canon_streams.set_value(name, value) } pub(crate) fn set_iterable_value( @@ -188,20 +132,8 @@ impl<'i> Scalars<'i> { self.iterable_variables.remove(name); } - pub(crate) fn get_non_iterable_value(&'i self, name: &str) -> ExecutionResult> { - self.non_iterable_variables - .get(name) - .and_then(|values| { - let last_cell = values.last(); - let depth_allowed = self.allowed_depths.contains(&last_cell.depth); - - if depth_allowed { - Some(last_cell.value.as_ref()) - } else { - None - } - }) - .ok_or_else(|| ExecutionError::Catchable(Rc::new(CatchableError::VariableNotFound(name.to_string())))) + pub(crate) fn get_non_iterable_scalar(&'i self, name: &str) -> ExecutionResult> { + self.non_iterable_variables.get_value(name) } pub(crate) fn get_iterable_mut(&mut self, name: &str) -> ExecutionResult<&mut FoldState<'i>> { @@ -210,8 +142,14 @@ impl<'i> Scalars<'i> { .ok_or_else(|| UncatchableError::FoldStateNotFound(name.to_string()).into()) } + pub(crate) fn get_canon_stream(&'i self, name: &str) -> ExecutionResult<&'i CanonStream> { + self.canon_streams + .get_value(name)? + .ok_or_else(|| CatchableError::VariableWasNotInitializedAfterNew(name.to_string()).into()) + } + pub(crate) fn get_value(&'i self, name: &str) -> ExecutionResult> { - let value = self.get_non_iterable_value(name); + let value = self.get_non_iterable_scalar(name); let iterable_value = self.iterable_variables.get(name); match (value, iterable_value) { @@ -223,141 +161,62 @@ impl<'i> Scalars<'i> { } } + pub(crate) fn variable_could_be_set(&self, variable_name: &str) -> bool { + self.non_iterable_variables.variable_could_be_set(variable_name) + || self.canon_streams.variable_could_be_set(variable_name) + } + pub(crate) fn meet_fold_start(&mut self) { - self.current_depth += 1; - self.allowed_depths.insert(self.current_depth); + self.non_iterable_variables.meet_fold_start(); + self.canon_streams.meet_fold_start(); } // meet next before recursion pub(crate) fn meet_next_before(&mut self) { - self.allowed_depths.remove(&self.current_depth); - self.current_depth += 1; - self.allowed_depths.insert(self.current_depth); + self.non_iterable_variables.meet_next_before(); + self.canon_streams.meet_next_before(); } // meet next after recursion pub(crate) fn meet_next_after(&mut self) { - self.allowed_depths.remove(&self.current_depth); - self.current_depth -= 1; - self.allowed_depths.insert(self.current_depth); - - self.cleanup_obsolete_values(); + self.non_iterable_variables.meet_next_after(); + self.canon_streams.meet_next_after(); } pub(crate) fn meet_fold_end(&mut self) { - self.allowed_depths.remove(&self.current_depth); - self.current_depth -= 1; - self.cleanup_obsolete_values(); + self.non_iterable_variables.meet_fold_end(); + self.canon_streams.meet_fold_end(); } - pub(crate) fn meet_new_start(&mut self, scalar_name: &str) { - use std::collections::hash_map::Entry::{Occupied, Vacant}; - - let new_cell = SparseCell::from_met_new(self.current_depth); - match self.non_iterable_variables.entry(scalar_name.to_string()) { - Vacant(entry) => { - let ne_vec = NonEmpty::new(new_cell); - entry.insert(ne_vec); - } - Occupied(entry) => { - let entry = entry.into_mut(); - entry.push(new_cell); - } - } + pub(crate) fn meet_new_start_scalar(&mut self, scalar_name: String) { + self.non_iterable_variables.meet_new_start(scalar_name); } - pub(crate) fn meet_new_end(&mut self, scalar_name: &str) -> ExecutionResult<()> { - let current_depth = self.current_depth; - let should_remove_values = self - .non_iterable_variables - .get_mut(scalar_name) - .and_then(|values| { - // carefully check that we're popping up an appropriate value, - // returning None means an error here - match values.pop() { - Some(value) if value.depth == current_depth => Some(false), - Some(_) => None, - // None means that the value was last in a row - None if values.last().depth == current_depth => Some(true), - None => None, - } - }) - .ok_or_else(|| UncatchableError::ScalarsStateCorrupted { - scalar_name: scalar_name.to_string(), - depth: self.current_depth, - }) - .map_err(Into::::into)?; - - if should_remove_values { - self.non_iterable_variables.remove(scalar_name); - } - Ok(()) + pub(crate) fn meet_new_start_canon_stream(&mut self, canon_stream_name: String) { + self.canon_streams.meet_new_start(canon_stream_name); } - pub(crate) fn variable_could_be_set(&self, variable_name: &str) -> bool { - if self.shadowing_allowed() { - return true; - } - - match self.non_iterable_variables.get(variable_name) { - Some(values) => values.last().value.is_none(), - None => false, - } + pub(crate) fn meet_new_end_scalar(&mut self, scalar_name: &str) -> ExecutionResult<()> { + self.non_iterable_variables.meet_new_end(scalar_name) } - pub(crate) fn shadowing_allowed(&self) -> bool { - // shadowing is allowed only inside a fold block, 0 here means that execution flow - // is in a global scope - self.current_depth != 0 - } - - fn cleanup_obsolete_values(&mut self) { - // TODO: it takes O(N) where N is a count of all scalars, but it could be optimized - // by maintaining array of value indices that should be removed on each depth level - let mut values_to_delete = Vec::new(); - for (name, values) in self.non_iterable_variables.iter_mut() { - let value_depth = values.last().depth; - if !is_global_value(value_depth) && is_value_obsolete(value_depth, self.current_depth) { - // it can't be empty, so it returns None if it contains 1 element - if values.pop().is_none() { - // TODO: optimize this cloning in next PR - values_to_delete.push(name.to_string()); - } - } - } - - for value_name in values_to_delete { - self.non_iterable_variables.remove(&value_name); - } + pub(crate) fn meet_new_end_canon_stream(&mut self, canon_name: &str) -> ExecutionResult<()> { + self.canon_streams.meet_new_end(canon_name) } } -fn is_global_value(value_depth: usize) -> bool { - value_depth == GLOBAL_DEPTH -} - -fn is_value_obsolete(value_depth: usize, current_scope_depth: usize) -> bool { - value_depth > current_scope_depth -} - -use std::fmt; - impl Default for Scalars<'_> { fn default() -> Self { Scalars::new() } } +use std::fmt; + impl<'i> fmt::Display for Scalars<'i> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - writeln!(f, "fold_block_id: {}", self.current_depth)?; - - for (name, _) in self.non_iterable_variables.iter() { - let value = self.get_non_iterable_value(name); - if let Ok(Some(last_value)) = value { - writeln!(f, "{} => {}", name, last_value.result)?; - } - } + writeln!(f, "scalars:\n{}", self.non_iterable_variables)?; + writeln!(f, "canon_streams:\n{}", self.canon_streams)?; for (name, _) in self.iterable_variables.iter() { // it's impossible to print an iterable value for now @@ -367,46 +226,3 @@ impl<'i> fmt::Display for Scalars<'i> { Ok(()) } } - -#[cfg(test)] -mod test { - use super::*; - use polyplets::SecurityTetraplet; - - use serde_json::json; - - use std::num::NonZeroUsize; - use std::rc::Rc; - - #[test] - fn test_local_cleanup() { - let mut scalars = Scalars::default(); - - let tetraplet = SecurityTetraplet::default(); - let rc_tetraplet = Rc::new(tetraplet); - let value = json!(1u64); - let rc_value = Rc::new(value); - let value_aggregate = ValueAggregate::new(rc_value, rc_tetraplet, 1.into()); - let value_1_name = "name_1"; - scalars.set_value(value_1_name, value_aggregate.clone()).unwrap(); - - let value_2_name = "name_2"; - scalars.meet_fold_start(); - scalars.set_value(value_2_name, value_aggregate.clone()).unwrap(); - scalars.meet_fold_start(); - scalars.set_value(value_2_name, value_aggregate.clone()).unwrap(); - - let expected_values_count = scalars.non_iterable_variables.get(value_2_name).unwrap().len(); - assert_eq!(expected_values_count, NonZeroUsize::new(2).unwrap()); - - scalars.meet_fold_end(); - let expected_values_count = scalars.non_iterable_variables.get(value_2_name).unwrap().len(); - assert_eq!(expected_values_count, NonZeroUsize::new(1).unwrap()); - - scalars.meet_fold_end(); - assert!(scalars.non_iterable_variables.get(value_2_name).is_none()); - - let expected_values_count = scalars.non_iterable_variables.get(value_1_name).unwrap().len(); - assert_eq!(expected_values_count, NonZeroUsize::new(1).unwrap()); - } -} diff --git a/air/src/execution_step/execution_context/scalar_variables/traits.rs b/air/src/execution_step/execution_context/scalar_variables/traits.rs deleted file mode 100644 index 765c6ca7..00000000 --- a/air/src/execution_step/execution_context/scalar_variables/traits.rs +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2021 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::Scalars; - -use std::fmt; - -impl<'i> fmt::Display for Scalars<'i> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - writeln!(f, "fold_block_id: {}", self.fold_blocks_sequence.len())?; - - for (name, _) in self.values.iter() { - let descriptor = self.values.get(name); - if let Some(descriptor) = descriptor { - writeln!(f, "{} => {:?}", name, descriptor.values.last())?; - } - } - - for (name, _) in self.iterable_values.iter() { - // it's impossible to print an iterable value for now - writeln!(f, "{} => iterable", name)?; - } - - Ok(()) - } -} diff --git a/air/src/execution_step/execution_context/scalar_variables/values_sparse_matrix.rs b/air/src/execution_step/execution_context/scalar_variables/values_sparse_matrix.rs new file mode 100644 index 00000000..6004875e --- /dev/null +++ b/air/src/execution_step/execution_context/scalar_variables/values_sparse_matrix.rs @@ -0,0 +1,323 @@ +/* + * Copyright 2022 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::execution_step::CatchableError; +use crate::execution_step::ExecutionError; +use crate::execution_step::ExecutionResult; +use crate::execution_step::UncatchableError; + +use non_empty_vec::NonEmpty; + +use std::collections::HashMap; +use std::collections::HashSet; +use std::rc::Rc; + +/// Depth of a global scope. +const GLOBAL_DEPTH: usize = 0; + +pub(crate) struct ValuesSparseMatrix { + cells: HashMap>>, + + /// This set contains depths were invalidated at the certain moment of script execution. + /// They are needed for careful isolation of scopes produced by iterations in fold blocks, + /// precisely to limit access of non iterable variables defined on one depths to ones + /// defined on another. + allowed_depths: HashSet, + + /// Count of met scopes at the particular moment of execution. + current_depth: usize, +} + +impl ValuesSparseMatrix { + pub(super) fn new() -> Self { + let allowed_depths = maplit::hashset! { GLOBAL_DEPTH }; + + Self { + cells: HashMap::new(), + allowed_depths, + current_depth: GLOBAL_DEPTH, + } + } + + pub(super) fn set_value(&mut self, name: impl Into, value: T) -> ExecutionResult { + use std::collections::hash_map::Entry::{Occupied, Vacant}; + + let name = name.into(); + let variable_could_be_set = self.variable_could_be_set(&name); + match self.cells.entry(name) { + Vacant(entry) => { + let cell = SparseCell::from_value(self.current_depth, value); + let cells = NonEmpty::new(cell); + entry.insert(cells); + + Ok(false) + } + Occupied(entry) => { + if !variable_could_be_set { + return Err(UncatchableError::ShadowingIsNotAllowed(entry.key().clone()).into()); + } + + let values = entry.into_mut(); + let last_cell = values.last_mut(); + if last_cell.depth == self.current_depth { + // just rewrite a value if fold level is the same + last_cell.value = Some(value); + Ok(true) + } else { + let new_cell = SparseCell::from_value(self.current_depth, value); + values.push(new_cell); + Ok(false) + } + } + } + } + + pub(super) fn get_value(&self, name: &str) -> ExecutionResult> { + self.cells + .get(name) + .and_then(|values| { + let last_cell = values.last(); + let depth_allowed = self.allowed_depths.contains(&last_cell.depth); + + if depth_allowed { + Some(last_cell.value.as_ref()) + } else { + None + } + }) + .ok_or_else(|| ExecutionError::Catchable(Rc::new(CatchableError::VariableNotFound(name.to_string())))) + } + + pub(super) fn meet_fold_start(&mut self) { + self.current_depth += 1; + self.allowed_depths.insert(self.current_depth); + } + + // meet next before recursion + pub(super) fn meet_next_before(&mut self) { + self.allowed_depths.remove(&self.current_depth); + self.current_depth += 1; + self.allowed_depths.insert(self.current_depth); + } + + // meet next after recursion + pub(super) fn meet_next_after(&mut self) { + self.allowed_depths.remove(&self.current_depth); + self.current_depth -= 1; + self.allowed_depths.insert(self.current_depth); + + self.cleanup_obsolete_values(); + } + + pub(super) fn meet_fold_end(&mut self) { + self.allowed_depths.remove(&self.current_depth); + self.current_depth -= 1; + self.cleanup_obsolete_values(); + } + + pub(super) fn meet_new_start(&mut self, scalar_name: String) { + use std::collections::hash_map::Entry::{Occupied, Vacant}; + + let new_cell = SparseCell::from_met_new(self.current_depth); + match self.cells.entry(scalar_name) { + Vacant(entry) => { + let ne_vec = NonEmpty::new(new_cell); + entry.insert(ne_vec); + } + Occupied(entry) => { + let entry = entry.into_mut(); + entry.push(new_cell); + } + } + } + + pub(super) fn meet_new_end(&mut self, scalar_name: &str) -> ExecutionResult<()> { + let current_depth = self.current_depth; + let should_remove_values = self + .cells + .get_mut(scalar_name) + .and_then(|values| { + // carefully check that we're popping up an appropriate value, + // returning None means an error here + match values.pop() { + Some(value) if value.depth == current_depth => Some(false), + Some(_) => None, + // None means that the value was last in a row + None if values.last().depth == current_depth => Some(true), + None => None, + } + }) + .ok_or_else(|| UncatchableError::ScalarsStateCorrupted { + scalar_name: scalar_name.to_string(), + depth: self.current_depth, + }) + .map_err(Into::::into)?; + + if should_remove_values { + self.cells.remove(scalar_name); + } + Ok(()) + } + + pub(super) fn variable_could_be_set(&self, variable_name: &str) -> bool { + if self.shadowing_allowed() { + return true; + } + + match self.cells.get(variable_name) { + Some(values) => values.last().value.is_none(), + None => false, + } + } + + pub(super) fn shadowing_allowed(&self) -> bool { + // shadowing is allowed only inside a fold block, 0 here means that execution flow + // is in a global scope + self.current_depth != 0 + } + + fn cleanup_obsolete_values(&mut self) { + // TODO: it takes O(N) where N is a count of all scalars, but it could be optimized + // by maintaining array of value indices that should be removed on each depth level + let mut values_to_delete = Vec::new(); + for (name, values) in self.cells.iter_mut() { + let value_depth = values.last().depth; + if !is_global_value(value_depth) && is_value_obsolete(value_depth, self.current_depth) { + // it can't be empty, so it returns None if it contains 1 element + if values.pop().is_none() { + // TODO: optimize this cloning in next PR + values_to_delete.push(name.to_string()); + } + } + } + + for value_name in values_to_delete { + self.cells.remove(&value_name); + } + } +} + +impl Default for ValuesSparseMatrix { + fn default() -> Self { + Self::new() + } +} + +fn is_global_value(value_depth: usize) -> bool { + value_depth == GLOBAL_DEPTH +} + +fn is_value_obsolete(value_depth: usize, current_scope_depth: usize) -> bool { + value_depth > current_scope_depth +} + +#[derive(Debug)] +pub(crate) struct SparseCell { + /// Scope depth where the value was set. + pub(crate) depth: usize, + pub(crate) value: Option, +} + +impl SparseCell { + pub(crate) fn from_value(depth: usize, value: T) -> Self { + Self { + depth, + value: Some(value), + } + } + + pub(crate) fn from_met_new(depth: usize) -> Self { + Self { depth, value: None } + } +} + +use std::fmt; + +impl fmt::Display for SparseCell +where + T: fmt::Display, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.value { + Some(value) => write!(f, "{}", value), + None => write!(f, "none"), + } + } +} + +impl fmt::Display for ValuesSparseMatrix +where + T: fmt::Display, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + writeln!(f, "current_depth: {}", self.current_depth)?; + + for (name, values) in self.cells.iter() { + write!(f, "{}: ", name)?; + + for value in values.iter() { + write!(f, "{} ", value)?; + } + writeln!(f)?; + } + + Ok(()) + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::execution_step::ValueAggregate; + use polyplets::SecurityTetraplet; + + use serde_json::json; + + use std::num::NonZeroUsize; + use std::rc::Rc; + + #[test] + fn test_local_cleanup() { + let mut scalars = ValuesSparseMatrix::new(); + + let tetraplet = SecurityTetraplet::default(); + let rc_tetraplet = Rc::new(tetraplet); + let value = json!(1u64); + let rc_value = Rc::new(value); + let value_aggregate = ValueAggregate::new(rc_value, rc_tetraplet, 1.into()); + let value_1_name = "name_1"; + scalars.set_value(value_1_name, value_aggregate.clone()).unwrap(); + + let value_2_name = "name_2"; + scalars.meet_fold_start(); + scalars.set_value(value_2_name, value_aggregate.clone()).unwrap(); + scalars.meet_fold_start(); + scalars.set_value(value_2_name, value_aggregate.clone()).unwrap(); + + let expected_values_count = scalars.cells.get(value_2_name).unwrap().len(); + assert_eq!(expected_values_count, NonZeroUsize::new(2).unwrap()); + + scalars.meet_fold_end(); + let expected_values_count = scalars.cells.get(value_2_name).unwrap().len(); + assert_eq!(expected_values_count, NonZeroUsize::new(1).unwrap()); + + scalars.meet_fold_end(); + assert!(scalars.cells.get(value_2_name).is_none()); + + let expected_values_count = scalars.cells.get(value_1_name).unwrap().len(); + assert_eq!(expected_values_count, NonZeroUsize::new(1).unwrap()); + } +} diff --git a/air/src/execution_step/resolver/resolve.rs b/air/src/execution_step/resolver/resolve.rs index 93940e0f..52a4e0f9 100644 --- a/air/src/execution_step/resolver/resolve.rs +++ b/air/src/execution_step/resolver/resolve.rs @@ -111,6 +111,10 @@ pub(crate) fn resolve_variable<'ctx, 'i>( None => Ok(Box::new(())), } } + Variable::CanonStream { name, .. } => { + let canon_stream = ctx.scalars.get_canon_stream(name)?; + Ok(Box::new(canon_stream)) + } } } diff --git a/air/tests/test_module/features/join_behaviour/join_behaviour.rs b/air/tests/test_module/features/join_behaviour/join_behaviour.rs index 50739da0..079e96f2 100644 --- a/air/tests/test_module/features/join_behaviour/join_behaviour.rs +++ b/air/tests/test_module/features/join_behaviour/join_behaviour.rs @@ -246,3 +246,23 @@ fn fold_with_join_behaviour() { let trace = trace_from_result(&result); assert_eq!(trace.len(), 2); } + +#[test] +fn canon_with_join_behaviour() { + let peer_1_id = "peer_1_id"; + let peer_2_id = "peer_2_id"; + + let mut peer_2 = create_avm(unit_call_service(), peer_2_id); + + let script = f!(r#" + (par + (call "{peer_1_id}" ("" "") [] $stream) + (canon "{peer_2_id}" $stream #canon_stream)) + "#); + + let result = checked_call_vm!(peer_2, <_>::default(), script, "", ""); + let actual_trace = trace_from_result(&result); + let expected_trace = vec![executed_state::par(1, 0), executed_state::request_sent_by(peer_2_id)]; + + assert_eq!(actual_trace, expected_trace); +} diff --git a/air/tests/test_module/instructions/ap.rs b/air/tests/test_module/instructions/ap.rs index 12bcbecb..192e0648 100644 --- a/air/tests/test_module/instructions/ap.rs +++ b/air/tests/test_module/instructions/ap.rs @@ -16,6 +16,8 @@ use air_test_utils::prelude::*; +use std::cell::RefCell; + #[test] fn ap_with_scalars() { let vm_1_peer_id = "vm_1_peer_id"; @@ -210,3 +212,80 @@ fn ap_with_dst_stream() { assert_eq!(actual_trace, expected_state); assert!(result.next_peer_pks.is_empty()); } + +#[test] +fn ap_canon_stream_with_lambda() { + let vm_1_peer_id = "vm_1_peer_id"; + let (echo_call_service, tetraplet_checker) = tetraplet_host_function(echo_call_service()); + let mut vm_1 = create_avm(echo_call_service, vm_1_peer_id); + + let service_name = "some_service_name"; + let function_name = "some_function_name"; + let script = f!(r#" + (seq + (seq + (call "{vm_1_peer_id}" ("" "") [0] $stream) + (call "{vm_1_peer_id}" ("{service_name}" "{function_name}") [1] $stream)) + (seq + (canon "{vm_1_peer_id}" $stream #canon_stream) + (seq + (ap #canon_stream.$.[1] $stream_2) + (call "{vm_1_peer_id}" ("" "") [$stream_2])))) + "#); + + let result = checked_call_vm!(vm_1, <_>::default(), &script, "", ""); + + let actual_trace = trace_from_result(&result); + let expected_state = vec![ + executed_state::stream_number(0, 0), + executed_state::stream_number(1, 1), + executed_state::canon(vec![0.into(), 1.into()]), + executed_state::ap(Some(0)), + executed_state::scalar(json!([1])), + ]; + assert_eq!(actual_trace, expected_state); + + let expected_tetraplet = RefCell::new(vec![vec![SecurityTetraplet::new( + vm_1_peer_id, + service_name, + function_name, + ".[1]", + )]]); + assert_eq!(tetraplet_checker.as_ref(), &expected_tetraplet); +} + +#[test] +fn ap_canon_stream() { + let vm_1_peer_id = "vm_1_peer_id"; + let (echo_call_service, tetraplet_checker) = tetraplet_host_function(echo_call_service()); + let mut vm_1 = create_avm(echo_call_service, vm_1_peer_id); + + let service_name = "some_service_name"; + let function_name = "some_function_name"; + let script = f!(r#" + (seq + (seq + (call "{vm_1_peer_id}" ("" "") [0] $stream) + (call "{vm_1_peer_id}" ("{service_name}" "{function_name}") [1] $stream)) + (seq + (canon "{vm_1_peer_id}" $stream #canon_stream) + (seq + (ap #canon_stream $stream_2) + (call "{vm_1_peer_id}" ("" "") [$stream_2])))) + "#); + + let result = checked_call_vm!(vm_1, <_>::default(), &script, "", ""); + + let actual_trace = trace_from_result(&result); + let expected_state = vec![ + executed_state::stream_number(0, 0), + executed_state::stream_number(1, 1), + executed_state::canon(vec![0.into(), 1.into()]), + executed_state::ap(Some(0)), + executed_state::scalar(json!([[0, 1]])), + ]; + assert_eq!(actual_trace, expected_state); + + let expected_tetraplet = RefCell::new(vec![vec![SecurityTetraplet::new(vm_1_peer_id, "", "", "")]]); + assert_eq!(tetraplet_checker.as_ref(), &expected_tetraplet); +} diff --git a/air/tests/test_module/instructions/canon.rs b/air/tests/test_module/instructions/canon.rs new file mode 100644 index 00000000..982fcfe2 --- /dev/null +++ b/air/tests/test_module/instructions/canon.rs @@ -0,0 +1,235 @@ +/* + * Copyright 2022 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 air_test_utils::prelude::*; + +use fstrings::f; +use fstrings::format_args_f; + +#[test] +fn canon_moves_execution_flow() { + let mut vm = create_avm(echo_call_service(), "A"); + let peer_id_1 = "peer_id_1"; + let peer_id_2 = "peer_id_2"; + + let script = f!(r#" + (par + (call "{peer_id_1}" ("" "") [] $stream) + (canon "{peer_id_2}" $stream #canon_stream) + )"#); + + let result = checked_call_vm!(vm, <_>::default(), script, "", ""); + + assert_next_pks!(&result.next_peer_pks, &[peer_id_1, peer_id_2]); +} + +#[test] +fn basic_canon() { + let mut vm = create_avm(echo_call_service(), "A"); + let mut set_variable_vm = create_avm( + set_variable_call_service(json!(["1", "2", "3", "4", "5"])), + "set_variable", + ); + + let script = r#" + (seq + (call "set_variable" ("" "") [] Iterable) + (seq + (fold Iterable i + (seq + (call "A" ("" "") [i] $stream) + (next i))) + (canon "A" $stream #canon_stream))) + "#; + + let result = checked_call_vm!(set_variable_vm, <_>::default(), script, "", ""); + let result = checked_call_vm!(vm, <_>::default(), script, "", result.data); + let actual_state = &trace_from_result(&result)[6.into()]; + + let expected_state = executed_state::canon(vec![1.into(), 2.into(), 3.into(), 4.into(), 5.into()]); + assert_eq!(actual_state, &expected_state); +} + +#[test] +fn canon_fixes_stream_correct() { + let peer_id_1 = "peer_id_1"; + let mut vm_1 = create_avm(echo_call_service(), peer_id_1); + let peer_id_2 = "peer_id_2"; + let mut vm_2 = create_avm(echo_call_service(), peer_id_2); + let peer_id_3 = "peer_id_3"; + let mut vm_3 = create_avm(echo_call_service(), peer_id_3); + let peer_id_4 = "peer_id_4"; + let mut vm_4 = create_avm(echo_call_service(), peer_id_4); + + let script = f!(r#" + (seq + (par + (call "{peer_id_1}" ("" "") [1] $stream) + (par + (call "{peer_id_2}" ("" "") [2] $stream) + (call "{peer_id_3}" ("" "") [3] $stream))) + (seq + (call "{peer_id_4}" ("" "") [4]) + (seq + (canon "{peer_id_3}" $stream #canon_stream) + (par + (call "{peer_id_3}" ("" "") [#canon_stream]) + (call "{peer_id_1}" ("" "") [#canon_stream]))))) + "#); + + let vm_1_result_1 = checked_call_vm!(vm_1, <_>::default(), &script, "", ""); + let vm_2_result = checked_call_vm!(vm_2, <_>::default(), &script, "", ""); + let vm_3_result_1 = checked_call_vm!(vm_3, <_>::default(), &script, "", vm_2_result.data); + let vm_4_result = checked_call_vm!(vm_4, <_>::default(), &script, "", vm_3_result_1.data.clone()); + let vm_3_result_2 = checked_call_vm!(vm_3, <_>::default(), &script, vm_3_result_1.data, vm_4_result.data); + let actual_vm_3_result_2_trace = trace_from_result(&vm_3_result_2); + let expected_vm_3_result_2_trace = vec![ + executed_state::par(1, 3), + executed_state::request_sent_by(peer_id_2), + executed_state::par(1, 1), + executed_state::stream_number(2, 0), + executed_state::stream_number(3, 1), + executed_state::scalar_number(4), + executed_state::canon(vec![3.into(), 4.into()]), + executed_state::par(1, 1), + executed_state::scalar(json!([2, 3])), + executed_state::request_sent_by(peer_id_3), + ]; + assert_eq!(actual_vm_3_result_2_trace, expected_vm_3_result_2_trace); + + let vm_1_result_2 = checked_call_vm!(vm_1, <_>::default(), script, vm_1_result_1.data, vm_3_result_2.data); + let vm_1_result_2_trace = trace_from_result(&vm_1_result_2); + let expected_vm_1_result_2_trace = vec![ + executed_state::par(1, 3), + executed_state::stream_number(1, 0), + executed_state::par(1, 1), + executed_state::stream_number(2, 1), + executed_state::stream_number(3, 1), + executed_state::scalar_number(4), + executed_state::canon(vec![3.into(), 4.into()]), + executed_state::par(1, 1), + executed_state::scalar(json!([2, 3])), + executed_state::scalar(json!([2, 3])), + ]; + assert_eq!(vm_1_result_2_trace, expected_vm_1_result_2_trace); +} + +#[test] +fn canon_stream_can_be_created_from_aps() { + let vm_1_peer_id = "vm_1_peer_id"; + let mut vm_1 = create_avm(echo_call_service(), vm_1_peer_id); + + let vm_2_peer_id = "vm_2_peer_id"; + let mut vm_2 = create_avm(echo_call_service(), vm_2_peer_id); + + let script = f!(r#" + (seq + (seq + (ap 0 $stream) + (ap 1 $stream)) + (seq + (canon "{vm_1_peer_id}" $stream #canon_stream) + (seq + (ap #canon_stream $stream_2) + (call "{vm_2_peer_id}" ("" "") [$stream_2])))) + "#); + + let result_1 = checked_call_vm!(vm_1, <_>::default(), &script, "", ""); + let result_2 = checked_call_vm!(vm_2, <_>::default(), &script, "", result_1.data.clone()); + // it fails on this call if canon merger can't handle ap results + let _ = checked_call_vm!(vm_2, <_>::default(), &script, result_1.data, result_2.data); +} + +#[test] +fn canon_gates() { + let peer_id_1 = "peer_id_1"; + let mut vm_1 = create_avm(set_variable_call_service(json!([1, 2, 3, 4, 5])), peer_id_1); + + let peer_id_2 = "peer_id_2"; + let mut vm_2 = create_avm(echo_call_service(), peer_id_2); + + let peer_id_3 = "peer_id_3"; + let stop_len_count = 2; + let vm_3_call_service: CallServiceClosure = Box::new(move |params: CallRequestParams| -> CallServiceResult { + let value = params.arguments[0].as_array().unwrap().len(); + if value >= stop_len_count { + CallServiceResult::ok(json!(true)) + } else { + CallServiceResult::ok(json!(false)) + } + }); + let mut vm_3 = create_avm(vm_3_call_service, peer_id_3); + + let script = f!(r#" + (seq + (seq + (call "{peer_id_1}" ("" "") [] iterable) + (fold iterable iterator + (par + (call "{peer_id_2}" ("" "") [iterator] $stream) + (next iterator)))) + (new $tmp + (fold $stream s + (xor + (seq + (ap s $tmp) + (seq + (seq + (canon "{peer_id_3}" $tmp #t) + (call "{peer_id_3}" ("" "") [#t] x)) + (match x true + (call "{peer_id_3}" ("" "") [#t])))) + (next s))))) + "#); + + let vm_1_result = checked_call_vm!(vm_1, <_>::default(), &script, "", ""); + let vm_2_result = checked_call_vm!(vm_2, <_>::default(), &script, "", vm_1_result.data); + let vm_3_result = checked_call_vm!(vm_3, <_>::default(), &script, "", vm_2_result.data); + + let actual_trace = trace_from_result(&vm_3_result); + let fold = match &actual_trace[11.into()] { + ExecutedState::Fold(fold_result) => fold_result, + _ => unreachable!(), + }; + + // fold should stop at the correspond len + assert_eq!(fold.lore.len(), stop_len_count); +} + +#[test] +fn canon_empty_stream() { + let peer_id_1 = "peer_id_1"; + let mut vm_1 = create_avm(echo_call_service(), peer_id_1); + let peer_id_2 = "peer_id_2"; + let mut vm_2 = create_avm(echo_call_service(), peer_id_2); + + let script = f!(r#" + (new $stream + (seq + (canon "{peer_id_1}" $stream #canon_stream) + (call "{peer_id_1}" ("" "") [#canon_stream]))) + "#); + + let result = checked_call_vm!(vm_1, <_>::default(), &script, "", ""); + let actual_trace = trace_from_result(&result); + let expected_trace = vec![executed_state::canon(vec![]), executed_state::scalar(json!([]))]; + assert_eq!(actual_trace, expected_trace); + + let result = checked_call_vm!(vm_2, <_>::default(), script, "", result.data); + let actual_trace = trace_from_result(&result); + let expected_trace = vec![executed_state::canon(vec![]), executed_state::scalar(json!([]))]; + assert_eq!(actual_trace, expected_trace); +} diff --git a/air/tests/test_module/instructions/fail.rs b/air/tests/test_module/instructions/fail.rs index e341f2b8..8f6efb37 100644 --- a/air/tests/test_module/instructions/fail.rs +++ b/air/tests/test_module/instructions/fail.rs @@ -115,3 +115,34 @@ fn fail_with_literals_tetraplets() { SecurityTetraplet::literal_tetraplet(local_peer_id) ); } + +#[test] +fn fail_with_canon_stream() { + let vm_peer_id = "local_peer_id"; + let error_code = 1337i64; + let error_message = "error message"; + let mut vm = create_avm( + set_variable_call_service(json!({"error_code": error_code, "message": error_message})), + vm_peer_id, + ); + + let script = f!(r#" + (seq + (seq + (call "{vm_peer_id}" ("" "") [] $stream) + (canon "{vm_peer_id}" $stream #canon_stream) + ) + (fail #canon_stream.$.[0]) + )"#); + + let test_params = TestRunParameters::from_init_peer_id("init_peer_id"); + let result = call_vm!(vm, test_params.clone(), script, "", ""); + + let expected_error = CatchableError::UserError { + error: rc!(json!( { + "error_code": error_code, + "message": error_message, + })), + }; + assert!(check_error(&result, expected_error)); +} diff --git a/air/tests/test_module/instructions/mod.rs b/air/tests/test_module/instructions/mod.rs index d8566679..06d94541 100644 --- a/air/tests/test_module/instructions/mod.rs +++ b/air/tests/test_module/instructions/mod.rs @@ -16,6 +16,7 @@ mod ap; mod call; +mod canon; mod fail; mod fold; mod match_; diff --git a/crates/air-lib/air-parser/src/ast/instruction_arguments.rs b/crates/air-lib/air-parser/src/ast/instruction_arguments.rs index a6404373..6b91670b 100644 --- a/crates/air-lib/air-parser/src/ast/instruction_arguments.rs +++ b/crates/air-lib/air-parser/src/ast/instruction_arguments.rs @@ -14,17 +14,22 @@ * limitations under the License. */ +mod impls; mod traits; -use super::Variable; +use super::CanonStream; +use super::Scalar; +use super::ScalarWithLambda; +use super::Stream; use super::VariableWithLambda; -use crate::ast::ScalarWithLambda; use air_lambda_ast::LambdaAST; +use crate::ast::CanonStreamWithLambda; use serde::Deserialize; use serde::Serialize; +// TODO: rename CallInstrValue, since it'd used by the canon instruction #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] pub enum CallInstrValue<'i> { InitPeerId, @@ -60,7 +65,10 @@ pub enum Value<'i> { #[derive(Serialize, Debug, PartialEq, Eq, Clone)] pub enum CallOutputValue<'i> { - Variable(Variable<'i>), + #[serde(borrow)] + Scalar(Scalar<'i>), + #[serde(borrow)] + Stream(Stream<'i>), None, } @@ -75,6 +83,15 @@ pub enum ApArgument<'i> { Boolean(bool), EmptyArray, Scalar(ScalarWithLambda<'i>), + CanonStream(CanonStreamWithLambda<'i>), +} + +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +pub enum ApResult<'i> { + #[serde(borrow)] + Scalar(Scalar<'i>), + #[serde(borrow)] + Stream(Stream<'i>), } #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] @@ -87,5 +104,18 @@ pub enum Number { pub enum FoldScalarIterable<'i> { #[serde(borrow)] Scalar(ScalarWithLambda<'i>), + // it's important not to have lambda here + #[serde(borrow)] + CanonStream(CanonStream<'i>), EmptyArray, } + +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +pub enum NewArgument<'i> { + #[serde(borrow)] + Scalar(Scalar<'i>), + #[serde(borrow)] + Stream(Stream<'i>), + #[serde(borrow)] + CanonStream(CanonStream<'i>), +} diff --git a/crates/air-lib/air-parser/src/ast/instruction_arguments/impls.rs b/crates/air-lib/air-parser/src/ast/instruction_arguments/impls.rs new file mode 100644 index 00000000..1302456f --- /dev/null +++ b/crates/air-lib/air-parser/src/ast/instruction_arguments/impls.rs @@ -0,0 +1,58 @@ +/* + * Copyright 2022 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::ApResult; +use super::CallOutputValue; +use super::NewArgument; +use super::Scalar; +use super::Stream; + +impl<'i> NewArgument<'i> { + pub fn name(&self) -> &'i str { + match self { + Self::Scalar(scalar) => scalar.name, + Self::Stream(stream) => stream.name, + Self::CanonStream(canon_stream) => canon_stream.name, + } + } +} + +impl<'i> ApResult<'i> { + pub fn scalar(name: &'i str, position: usize) -> Self { + Self::Scalar(Scalar { name, position }) + } + + pub fn stream(name: &'i str, position: usize) -> Self { + Self::Stream(Stream { name, position }) + } + + pub fn name(&self) -> &'i str { + match self { + Self::Scalar(scalar) => scalar.name, + Self::Stream(stream) => stream.name, + } + } +} + +impl<'i> CallOutputValue<'i> { + pub fn scalar(name: &'i str, position: usize) -> Self { + Self::Scalar(Scalar { name, position }) + } + + pub fn stream(name: &'i str, position: usize) -> Self { + Self::Stream(Stream { name, position }) + } +} diff --git a/crates/air-lib/air-parser/src/ast/instruction_arguments/traits.rs b/crates/air-lib/air-parser/src/ast/instruction_arguments/traits.rs index 6b26e450..0a3d1748 100644 --- a/crates/air-lib/air-parser/src/ast/instruction_arguments/traits.rs +++ b/crates/air-lib/air-parser/src/ast/instruction_arguments/traits.rs @@ -17,6 +17,17 @@ use super::*; use std::fmt; +impl fmt::Display for ApResult<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use ApResult::*; + + match self { + Scalar(scalar) => write!(f, "{}", scalar), + Stream(stream) => write!(f, "{}", stream), + } + } +} + impl fmt::Display for Value<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use Value::*; @@ -52,7 +63,8 @@ impl fmt::Display for CallOutputValue<'_> { use CallOutputValue::*; match self { - Variable(variable) => write!(f, "{}", variable), + Scalar(scalar) => write!(f, "{}", scalar), + Stream(stream) => write!(f, "{}", stream), None => Ok(()), } } @@ -72,6 +84,7 @@ impl fmt::Display for ApArgument<'_> { Boolean(bool) => write!(f, "{}", bool), EmptyArray => write!(f, "[]"), Scalar(scalar) => write!(f, "{}", scalar), + CanonStream(canon_stream) => write!(f, "{}", canon_stream), } } } @@ -86,6 +99,16 @@ impl fmt::Display for Triplet<'_> { } } +impl fmt::Display for NewArgument<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Scalar(scalar) => write!(f, "{}", scalar), + Self::Stream(stream) => write!(f, "{}", stream), + Self::CanonStream(canon_stream) => write!(f, "{}", canon_stream), + } + } +} + impl fmt::Display for Number { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use Number::*; @@ -103,6 +126,7 @@ impl fmt::Display for FoldScalarIterable<'_> { match self { Scalar(variable) => write!(f, "{}", variable), + CanonStream(canon_stream) => write!(f, "{}", canon_stream), EmptyArray => write!(f, "[]"), } } diff --git a/crates/air-lib/air-parser/src/ast/instructions.rs b/crates/air-lib/air-parser/src/ast/instructions.rs index 3b1097ff..e23f8429 100644 --- a/crates/air-lib/air-parser/src/ast/instructions.rs +++ b/crates/air-lib/air-parser/src/ast/instructions.rs @@ -18,6 +18,7 @@ mod impls; mod traits; use super::*; +use air_lambda_ast::LambdaAST; use serde::Serialize; use std::rc::Rc; @@ -27,6 +28,7 @@ use std::rc::Rc; pub enum Instruction<'i> { Call(Call<'i>), Ap(Ap<'i>), + Canon(Canon<'i>), Seq(Seq<'i>), Par(Par<'i>), Xor(Xor<'i>), @@ -53,7 +55,15 @@ pub struct Call<'i> { #[derive(Serialize, Debug, PartialEq)] pub struct Ap<'i> { pub argument: ApArgument<'i>, - pub result: Variable<'i>, + pub result: ApResult<'i>, +} + +/// (canon peer_id $stream #canon_stream) +#[derive(Serialize, Debug, PartialEq, Eq)] +pub struct Canon<'i> { + pub peer_pk: CallInstrValue<'i>, + pub stream: Stream<'i>, + pub canon_stream: CanonStream<'i>, } /// (seq instruction instruction) @@ -93,6 +103,10 @@ pub enum Fail<'i> { ret_code: i64, error_message: &'i str, }, + CanonStream { + name: &'i str, + lambda: LambdaAST<'i>, + }, LastError, } @@ -126,7 +140,7 @@ pub struct Next<'i> { /// (new variable instruction) #[derive(Serialize, Debug, PartialEq)] pub struct New<'i> { - pub variable: Variable<'i>, + pub argument: NewArgument<'i>, pub instruction: Box>, pub span: Span, } diff --git a/crates/air-lib/air-parser/src/ast/instructions/impls.rs b/crates/air-lib/air-parser/src/ast/instructions/impls.rs index 16ae6a9f..4bbf333d 100644 --- a/crates/air-lib/air-parser/src/ast/instructions/impls.rs +++ b/crates/air-lib/air-parser/src/ast/instructions/impls.rs @@ -17,7 +17,7 @@ use super::*; impl<'i> Ap<'i> { - pub fn new(argument: ApArgument<'i>, result: Variable<'i>) -> Self { + pub fn new(argument: ApArgument<'i>, result: ApResult<'i>) -> Self { Self { argument, result } } } @@ -36,6 +36,20 @@ impl<'i> Call<'i> { } } +impl<'i> Canon<'i> { + pub fn new( + peer_pk: CallInstrValue<'i>, + stream: Stream<'i>, + canon_stream: CanonStream<'i>, + ) -> Self { + Self { + peer_pk, + stream, + canon_stream, + } + } +} + impl<'i> Seq<'i> { pub fn new( left_instruction: Box>, @@ -131,9 +145,9 @@ impl<'i> Next<'i> { impl<'i> New<'i> { #[allow(clippy::self_named_constructors)] - pub fn new(variable: Variable<'i>, instruction: Box>, span: Span) -> Self { + pub fn new(argument: NewArgument<'i>, instruction: Box>, span: Span) -> Self { Self { - variable, + argument, instruction, span, } diff --git a/crates/air-lib/air-parser/src/ast/instructions/traits.rs b/crates/air-lib/air-parser/src/ast/instructions/traits.rs index 8dc28e16..befe0107 100644 --- a/crates/air-lib/air-parser/src/ast/instructions/traits.rs +++ b/crates/air-lib/air-parser/src/ast/instructions/traits.rs @@ -16,6 +16,7 @@ use super::*; +use air_lambda_ast::format_ast; use std::fmt; impl fmt::Display for Instruction<'_> { @@ -24,6 +25,7 @@ impl fmt::Display for Instruction<'_> { match self { Call(call) => write!(f, "{}", call), + Canon(canon) => write!(f, "{}", canon), Ap(ap) => write!(f, "{}", ap), Seq(seq) => write!(f, "{}", seq), Par(par) => write!(f, "{}", par), @@ -50,6 +52,16 @@ impl fmt::Display for Call<'_> { } } +impl fmt::Display for Canon<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "canon {} {} {}", + self.peer_pk, self.stream, self.canon_stream + ) + } +} + impl fmt::Display for Ap<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "ap {} {}", self.argument, self.result) @@ -64,6 +76,9 @@ impl fmt::Display for Fail<'_> { ret_code, error_message, } => write!(f, r#"fail {} "{}""#, ret_code, error_message), + Fail::CanonStream { name, lambda, .. } => { + write!(f, "fail {}.$.{}", name, format_ast(lambda)) + } Fail::LastError => write!(f, "fail %last_error%"), } } @@ -125,6 +140,6 @@ impl fmt::Display for Next<'_> { impl fmt::Display for New<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "new {}", self.variable) + write!(f, "new {}", self.argument) } } diff --git a/crates/air-lib/air-parser/src/ast/values.rs b/crates/air-lib/air-parser/src/ast/values.rs index 4b5c4853..9c62e841 100644 --- a/crates/air-lib/air-parser/src/ast/values.rs +++ b/crates/air-lib/air-parser/src/ast/values.rs @@ -54,6 +54,22 @@ pub struct StreamWithLambda<'i> { pub position: usize, } +/// A canonicalized stream without lambda. +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +pub struct CanonStream<'i> { + pub name: &'i str, + pub position: usize, +} + +/// A canonicalized stream with lambda. +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +pub struct CanonStreamWithLambda<'i> { + pub name: &'i str, + #[serde(borrow)] + pub lambda: Option>, + pub position: usize, +} + /// A variable that could be either scalar or stream without lambda. #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] pub enum Variable<'i> { @@ -61,6 +77,8 @@ pub enum Variable<'i> { Scalar(Scalar<'i>), #[serde(borrow)] Stream(Stream<'i>), + #[serde(borrow)] + CanonStream(CanonStream<'i>), } /// A variable that could be either scalar or stream with possible lambda expression. @@ -70,4 +88,6 @@ pub enum VariableWithLambda<'i> { Scalar(ScalarWithLambda<'i>), #[serde(borrow)] Stream(StreamWithLambda<'i>), + #[serde(borrow)] + CanonStream(CanonStreamWithLambda<'i>), } diff --git a/crates/air-lib/air-parser/src/ast/values/impls.rs b/crates/air-lib/air-parser/src/ast/values/impls.rs index 9b666788..bfdd2b2d 100644 --- a/crates/air-lib/air-parser/src/ast/values/impls.rs +++ b/crates/air-lib/air-parser/src/ast/values/impls.rs @@ -67,6 +67,22 @@ impl<'i> StreamWithLambda<'i> { } } +impl<'i> CanonStream<'i> { + pub fn new(name: &'i str, position: usize) -> Self { + Self { name, position } + } +} + +impl<'i> CanonStreamWithLambda<'i> { + pub fn new(name: &'i str, lambda: Option>, position: usize) -> Self { + Self { + name, + lambda, + position, + } + } +} + impl<'i> Scalar<'i> { pub fn new(name: &'i str, position: usize) -> Self { Self { name, position } @@ -92,6 +108,7 @@ impl<'i> Variable<'i> { match self { Variable::Scalar(scalar) => scalar.name, Variable::Stream(stream) => stream.name, + Variable::CanonStream(stream) => stream.name, } } } @@ -113,10 +130,19 @@ impl<'i> VariableWithLambda<'i> { Self::Stream(StreamWithLambda::new(name, Some(lambda), position)) } + pub fn canon_stream(name: &'i str, position: usize) -> Self { + Self::CanonStream(CanonStreamWithLambda::new(name, None, position)) + } + + pub fn canon_stream_wl(name: &'i str, lambda: LambdaAST<'i>, position: usize) -> Self { + Self::CanonStream(CanonStreamWithLambda::new(name, Some(lambda), position)) + } + pub fn name(&self) -> &'i str { match self { VariableWithLambda::Scalar(scalar) => scalar.name, VariableWithLambda::Stream(stream) => stream.name, + VariableWithLambda::CanonStream(canon_stream) => canon_stream.name, } } @@ -124,6 +150,7 @@ impl<'i> VariableWithLambda<'i> { match self { VariableWithLambda::Scalar(scalar) => &scalar.lambda, VariableWithLambda::Stream(stream) => &stream.lambda, + VariableWithLambda::CanonStream(canon_stream) => &canon_stream.lambda, } } diff --git a/crates/air-lib/air-parser/src/ast/values/traits.rs b/crates/air-lib/air-parser/src/ast/values/traits.rs index 5c0bbd97..375f4ef6 100644 --- a/crates/air-lib/air-parser/src/ast/values/traits.rs +++ b/crates/air-lib/air-parser/src/ast/values/traits.rs @@ -39,6 +39,12 @@ impl fmt::Display for Stream<'_> { } } +impl fmt::Display for CanonStream<'_> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.name) + } +} + impl fmt::Display for StreamWithLambda<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match &self.lambda { @@ -48,6 +54,15 @@ impl fmt::Display for StreamWithLambda<'_> { } } +impl fmt::Display for CanonStreamWithLambda<'_> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match &self.lambda { + Some(lambda) => write!(f, "{}.${}", self.name, format_ast(lambda)), + None => write!(f, "{}", self.name), + } + } +} + impl fmt::Display for Variable<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use Variable::*; @@ -55,6 +70,7 @@ impl fmt::Display for Variable<'_> { match self { Scalar(scalar) => write!(f, "{}", scalar), Stream(stream) => write!(f, "{}", stream), + CanonStream(canon_stream) => write!(f, "{}", canon_stream), } } } @@ -66,6 +82,7 @@ impl fmt::Display for VariableWithLambda<'_> { match self { Scalar(scalar) => write!(f, "{}", scalar), Stream(stream) => write!(f, "{}", stream), + CanonStream(canon_stream) => write!(f, "{}", canon_stream), } } } diff --git a/crates/air-lib/air-parser/src/parser/air.lalrpop b/crates/air-lib/air-parser/src/parser/air.lalrpop index 044d0f2c..1c7db7dc 100644 --- a/crates/air-lib/air-parser/src/parser/air.lalrpop +++ b/crates/air-lib/air-parser/src/parser/air.lalrpop @@ -16,7 +16,7 @@ pub AIR = Instr; Instr: Box> = { "(" call ")" => { let args = Rc::new(args); - let output = output.map(CallOutputValue::Variable).unwrap_or(CallOutputValue::None); + let output = output.unwrap_or(CallOutputValue::None); let call = Call::new(triplet, args, output); let span = Span::new(left, right); @@ -25,6 +25,16 @@ Instr: Box> = { Box::new(Instruction::Call(call)) }, + "(" canon ")" => { + let canon = Canon::new(peer_pk, stream, canon_stream); + + let span = Span::new(left, right); + validator.met_canon(&canon, span); + + Box::new(Instruction::Canon(canon)) + }, + + "(" ap ")" => { let apply = Ap::new(arg, result); @@ -38,9 +48,9 @@ Instr: Box> = { "(" par ")" => Box::new(Instruction::Par(Par::new(l, r))), "(" null ")" => Box::new(Instruction::Null(Null)), - "(" new ")" => { + "(" new ")" => { let span = Span::new(left, right); - let new = New::new(variable, instruction, span); + let new = New::new(argument, instruction, span); validator.met_new(&new, span); @@ -114,12 +124,14 @@ Triplet: Triplet<'input> = { } } -ApResult = ScriptVariable; -CallOutput = ScriptVariable; +ApResult: ApResult<'input> = { + => ApResult::scalar(scalar.0, scalar.1), + => ApResult::stream(stream.0, stream.1), +}; -ScriptVariable: Variable<'input> = { - => Variable::scalar(scalar.0, scalar.1), - => Variable::stream(stream.0, stream.1), +CallOutput: CallOutputValue<'input> = { + => CallOutputValue::scalar(scalar.0, scalar.1), + => CallOutputValue::stream(stream.0, stream.1), }; FailBody: Fail<'input> = { @@ -129,6 +141,10 @@ FailBody: Fail<'input> = { ret_code, error_message, }, + => Fail::CanonStream { + name: canon_stream.0, + lambda: canon_stream.1, + }, => { Fail::LastError } @@ -137,6 +153,7 @@ FailBody: Fail<'input> = { FoldScalarIterable: FoldScalarIterable<'input> = { => FoldScalarIterable::Scalar(ScalarWithLambda::new(scalar.0, None, scalar.1)), => FoldScalarIterable::Scalar(ScalarWithLambda::new(scalar.0, Some(scalar.1), scalar.2)), + => FoldScalarIterable::CanonStream(CanonStream::new(canon_stream.0, canon_stream.1)), "[" "]" => FoldScalarIterable::EmptyArray, }; @@ -144,6 +161,7 @@ Function = CallInstrValue; PeerId = CallInstrValue; ServiceId = CallInstrValue; +// TODO: call triplet should receive only streams with lambdas CallInstrValue: CallInstrValue<'input> = { InitPeerId => CallInstrValue::InitPeerId, => CallInstrValue::Literal(l), @@ -151,6 +169,14 @@ CallInstrValue: CallInstrValue<'input> = { => CallInstrValue::Variable(VariableWithLambda::scalar_wl(scalar.0, scalar.1, scalar.2)), => CallInstrValue::Variable(VariableWithLambda::stream(stream.0, stream.1)), => CallInstrValue::Variable(VariableWithLambda::stream_wl(stream.0, stream.1, stream.2)), + => CallInstrValue::Variable(VariableWithLambda::canon_stream(canon_stream.0, canon_stream.1)), + => CallInstrValue::Variable(VariableWithLambda::canon_stream_wl(canon_stream.0, canon_stream.1, canon_stream.2)), +} + +NewArgument: NewArgument<'input> = { + => NewArgument::Scalar(Scalar::new(scalar.0, scalar.1)), + => NewArgument::Stream(Stream::new(stream.0, stream.1)), + => NewArgument::CanonStream(CanonStream::new(canon_stream.0, canon_stream.1)), } Number: Number = { @@ -174,6 +200,8 @@ Value: Value<'input> = { => Value::Variable(VariableWithLambda::scalar_wl(scalar.0, scalar.1, scalar.2)), => Value::Variable(VariableWithLambda::stream(stream.0, stream.1)), => Value::Variable(VariableWithLambda::stream_wl(stream.0, stream.1, stream.2)), + => Value::Variable(VariableWithLambda::canon_stream(canon_stream.0, canon_stream.1)), + => Value::Variable(VariableWithLambda::canon_stream_wl(canon_stream.0, canon_stream.1, canon_stream.2)), } ApArgument: ApArgument<'input> = { @@ -188,6 +216,16 @@ ApArgument: ApArgument<'input> = { "[" "]" => ApArgument::EmptyArray, => ApArgument::Scalar(ScalarWithLambda::new(scalar.0, None, scalar.1)), => ApArgument::Scalar(ScalarWithLambda::new(scalar.0, Some(scalar.1), scalar.2)), + => ApArgument::CanonStream(CanonStreamWithLambda::new(canon_stream.0, None, canon_stream.1)), + => ApArgument::CanonStream(CanonStreamWithLambda::new(canon_stream.0, Some(canon_stream.1), canon_stream.2)), +} + +StreamArgument: Stream<'input> = { + => Stream::new(stream.0, stream.1), +} + +CanonStreamArgument: CanonStream<'input> = { + => CanonStream::new(canon_stream.0, canon_stream.1), } extern { @@ -204,6 +242,8 @@ extern { ScalarWithLambda => Token::ScalarWithLambda { name: <&'input str>, lambda: >, position: }, Stream => Token::Stream { name: <&'input str>, position: }, StreamWithLambda => Token::StreamWithLambda {name: <&'input str>, lambda:>, position: }, + CanonStream => Token::CanonStream { name: <&'input str>, position: }, + CanonStreamWithLambda => Token::CanonStreamWithLambda {name: <&'input str>, lambda:>, position: }, Literal => Token::StringLiteral(<&'input str>), I64 => Token::I64(), @@ -217,6 +257,7 @@ extern { TTL => Token::TTL, call => Token::Call, + canon => Token::Canon, ap => Token::Ap, seq => Token::Seq, par => Token::Par, diff --git a/crates/air-lib/air-parser/src/parser/air.rs b/crates/air-lib/air-parser/src/parser/air.rs index c2342ed9..19de596c 100644 --- a/crates/air-lib/air-parser/src/parser/air.rs +++ b/crates/air-lib/air-parser/src/parser/air.rs @@ -1,5 +1,5 @@ // auto-generated: "lalrpop 0.19.8" -// sha3: bd630e614fda5f25993172a583a29b4959c0d20cdba69f5e05343f48f72b98ee +// sha3: c1d6038a914f4d058915d1d80f6943a98fd99e21c303f874a4393a619d95eb9b use crate::ast::*; use crate::parser::ParserError; use crate::parser::VariableValidator; @@ -39,273 +39,313 @@ mod __parse__AIR { { Variant0(Token<'input>), Variant1(bool), - Variant2(f64), - Variant3(i64), - Variant4(LambdaAST<'input>), - Variant5(&'input str), - Variant6((&'input str, usize)), - Variant7((&'input str, LambdaAST<'input>, usize)), + Variant2((&'input str, usize)), + Variant3((&'input str, LambdaAST<'input>, usize)), + Variant4(f64), + Variant5(i64), + Variant6(LambdaAST<'input>), + Variant7(&'input str), Variant8(__lalrpop_util::ErrorRecovery, ParserError>), Variant9(Value<'input>), Variant10(alloc::vec::Vec>), Variant11(usize), Variant12(Box>), Variant13(ApArgument<'input>), - Variant14(Variable<'input>), + Variant14(ApResult<'input>), Variant15(Vec>), Variant16(CallInstrValue<'input>), - Variant17(core::option::Option>), - Variant18(Fail<'input>), - Variant19(FoldScalarIterable<'input>), - Variant20(Number), - Variant21(Triplet<'input>), + Variant17(CallOutputValue<'input>), + Variant18(core::option::Option>), + Variant19(CanonStream<'input>), + Variant20(Fail<'input>), + Variant21(FoldScalarIterable<'input>), + Variant22(NewArgument<'input>), + Variant23(Number), + Variant24(Stream<'input>), + Variant25(Triplet<'input>), } - const __ACTION: &[i8] = &[ + const __ACTION: &[i16] = &[ // State 0 - 31, 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, 32, + 34, 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, 35, // State 1 - 0, 0, 36, 0, 37, 38, 39, 40, 41, 42, 43, 44, 45, 0, 0, 46, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 39, 0, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 0, 51, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 2 - 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 51, 52, 53, 54, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 55, 56, 0, 0, 57, 0, 0, 58, 59, 60, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 3 - 0, 0, 0, 0, 0, 0, 57, 0, 58, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 55, 56, 0, 0, 57, 0, 0, 58, 59, 60, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 4 - 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 64, 0, 65, 0, 66, 0, 0, 67, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 5 - 0, 0, 67, 0, 68, 38, 39, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 72, 73, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 6 - 0, 0, 67, 0, 68, 38, 39, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 76, 0, 77, 78, 79, 43, 44, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 7 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 76, 0, 77, 78, 79, 43, 44, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 8 - 31, 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, 32, + 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 91, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 9 - 31, 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, 32, + 34, 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, 35, // State 10 - 31, 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, 32, + 34, 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, 35, // State 11 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 80, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, // State 12 - 0, 0, 22, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 13 - 0, 0, 67, 0, 68, 38, 39, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 14 - 0, 0, 67, 0, 68, 38, 39, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 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, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 15 - 31, 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, 32, + 0, 0, 76, 0, 77, 78, 79, 43, 44, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 16 - 31, 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, 32, + 0, 0, 76, 0, 77, 78, 79, 43, 44, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 17 - 31, 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, 32, + 34, 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, 35, // State 18 - 31, 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, 32, + 34, 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, 35, // State 19 - 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 51, 52, 53, 54, 55, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, // State 20 - 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 80, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, // State 21 - 0, 0, 67, 102, 68, 38, 39, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 55, 56, 0, 0, 57, 0, 0, 58, 59, 60, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 22 - 31, 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, 32, + 0, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 23 - 31, 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, 32, + 0, 0, 76, 117, 77, 78, 79, 43, 44, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 24 - 31, 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, 32, + 0, 0, 0, 0, 0, 119, 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 25 - 31, 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, 32, + 34, 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, 35, // State 26 - 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 51, 52, 53, 54, 55, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, // State 27 - 0, 0, 67, 115, 68, 38, 39, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, // State 28 - 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, + 34, 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, 35, // State 29 - 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, 0, 0, 0, 0, 55, 56, 0, 0, 57, 0, 0, 58, 59, 60, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 30 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 7, 8, 33, 34, 9, 10, 11, 0, + 0, 0, 76, 132, 77, 78, 79, 43, 44, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 31 - -55, -55, 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, -55, + 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, 0, 0, // State 32 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 33 - 0, 82, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 36, 37, 10, 11, 12, 0, // State 34 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -15, 0, -15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -65, -65, 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, -65, // State 35 - 0, 0, 0, 85, 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, 0, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 36 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -16, 0, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 94, 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 37 - -57, 0, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -57, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -15, 0, -15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 38 - -56, 0, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -56, + 0, 0, 0, 98, 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 39 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9, 0, -9, 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, -16, 0, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 40 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10, 0, -10, 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, -20, 0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 41 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11, 0, -11, 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, -21, 0, -21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 42 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -14, 0, -14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -70, 0, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -70, // State 43 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -18, 0, -18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -69, 0, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -69, // State 44 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -19, 0, -19, 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, -9, 0, -9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 45 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -13, 0, -13, 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, -10, 0, -10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 46 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -12, 0, -12, 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, -11, 0, -11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 47 - -58, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -14, 0, -14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 48 - 20, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -18, 0, -18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 49 - -24, -24, 0, 0, 0, 0, 0, -24, 0, 0, -24, -24, -24, -24, -24, 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, -19, 0, -19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 50 - -25, -25, 0, 0, 0, 0, 0, -25, 0, 0, -25, -25, -25, -25, -25, 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, -13, 0, -13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 51 - -26, -26, 0, 0, 0, 0, 0, -26, 0, 0, -26, -26, -26, -26, -26, 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, -12, 0, -12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 52 - -27, -27, 0, 0, 0, 0, 0, -27, 0, 0, -27, -27, -27, -27, -27, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 53 - -28, -28, 0, 0, 0, 0, 0, -28, 0, 0, -28, -28, -28, -28, -28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 22, 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, 0, // State 54 - -29, -29, 0, 0, 0, 0, 0, -29, 0, 0, -29, -29, -29, -29, -29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -33, -33, 0, 0, 0, -33, -33, 0, 0, -33, 0, 0, -33, -33, -33, -33, -33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 55 - 0, 86, 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, + -34, -34, 0, 0, 0, -34, -34, 0, 0, -34, 0, 0, -34, -34, -34, -34, -34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 56 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -27, -27, 0, 0, 0, -27, -27, 0, 0, -27, 0, 0, -27, -27, -27, -27, -27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 57 - 0, -36, 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, + -28, -28, 0, 0, 0, -28, -28, 0, 0, -28, 0, 0, -28, -28, -28, -28, -28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 58 - 0, -33, 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, + -29, -29, 0, 0, 0, -29, -29, 0, 0, -29, 0, 0, -29, -29, -29, -29, -29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 59 - 0, -34, 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, + -30, -30, 0, 0, 0, -30, -30, 0, 0, -30, 0, 0, -30, -30, -30, -30, -30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 60 - 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, 0, 0, + -31, -31, 0, 0, 0, -31, -31, 0, 0, -31, 0, 0, -31, -31, -31, -31, -31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 61 - 0, 0, 0, 88, 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, + -32, -32, 0, 0, 0, -32, -32, 0, 0, -32, 0, 0, -32, -32, -32, -32, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 62 - 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, 0, 0, + 0, 100, 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 63 - 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, 0, 0, + 0, -43, 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 64 - 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 65 - -69, 0, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -69, + 0, -44, 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 66 - 0, 0, 0, 89, 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, -40, 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 67 - -70, 0, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -70, + 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 68 - -63, 0, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -63, + 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 69 - -64, 0, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -64, + 0, 0, 0, 102, 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 70 - -65, 0, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -65, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 71 - -66, 0, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -66, + 0, 0, 0, 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, 0, 0, // State 72 - -72, 0, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -72, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 73 - -73, 0, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -73, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 74 - -74, 0, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -74, + -81, 0, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -81, // State 75 - -75, 0, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -75, + 0, 0, 0, 103, 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 76 - -68, 0, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -68, + -82, 0, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -82, // State 77 - -67, 0, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -67, + -88, 0, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -88, // State 78 - -59, -59, 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, -59, + -89, 0, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -89, // State 79 - -60, -60, 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, -60, + -75, 0, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -75, // State 80 - 0, 91, 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, + -76, 0, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -76, // State 81 - -46, -46, 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, -46, + -77, 0, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -77, // State 82 - 0, 95, 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, + -78, 0, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -78, // State 83 - 0, -20, 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, + -84, 0, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -84, // State 84 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -17, 0, -17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -85, 0, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -85, // State 85 - -48, -48, 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, -48, + -86, 0, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -86, // State 86 - 0, -35, 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, + -87, 0, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -87, // State 87 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -80, 0, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -80, // State 88 - -71, 0, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -71, + -79, 0, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -79, // State 89 - 0, 107, 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, + -68, 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, -68, // State 90 - -51, -51, 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, -51, + -66, 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, -66, // State 91 - 0, 108, 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, + -67, 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, -67, // State 92 - 0, 109, 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, 105, 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 93 - 0, 110, 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, + -56, -56, 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, -56, // State 94 - -43, -43, 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, -43, + 0, 109, 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 95 - 0, 0, 0, 0, 0, 0, 0, -61, 0, 0, -61, -61, -61, -61, -61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -22, 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 96 - 0, 113, 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, -23, 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 97 - 0, -30, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -17, 0, -17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 98 - -42, -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, 0, 0, -42, + 0, 0, 0, 0, 0, -73, 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 99 - 0, 0, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -58, -58, 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, -58, // State 100 - 0, 0, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 101 - 0, -22, 0, 0, 0, 0, 0, 0, 0, 0, 0, -22, 0, -22, 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, -48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 102 - 0, 116, 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, + -83, 0, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -83, // State 103 - 0, 117, 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, 124, 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 104 - 0, 118, 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, + -61, -61, 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, -61, // State 105 - 0, 119, 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, 125, 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 106 - -47, -47, 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, -47, + 0, 126, 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 107 - -45, -45, 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, -45, + 0, 127, 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 108 - -44, -44, 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, -44, + -53, -53, 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, -53, // State 109 - -52, -52, 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, -52, + 0, 0, 0, 0, 0, -72, -72, 0, 0, -72, 0, 0, -72, -72, -72, -72, -72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 110 - 0, -40, 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, 130, 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 111 - 0, 120, 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, + -51, -51, 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, -51, // State 112 - -41, -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, -41, + 0, -35, 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 113 - 0, 0, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 114 - 0, -23, 0, 0, 0, 0, 0, 0, 0, 0, 0, -23, 0, -23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 115 - -49, -49, 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, -49, + 0, 0, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 116 - -50, -50, 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, -50, + 0, -25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -25, 0, -25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // State 117 - -53, -53, 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, -53, + 0, 133, 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 118 - -54, -54, 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, -54, + 0, -39, 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 119 - 0, 0, -62, 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, 134, 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 120 + 0, 135, 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 121 + 0, 136, 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 122 + 0, 137, 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 123 + -57, -57, 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, -57, + // State 124 + -55, -55, 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, -55, + // State 125 + -54, -54, 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, -54, + // State 126 + -62, -62, 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, -62, + // State 127 + 0, -49, 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 128 + 0, 138, 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 129 + -50, -50, 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, -50, + // State 130 + 0, 0, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 131 + 0, -26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -26, 0, -26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 132 + -52, -52, 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, -52, + // State 133 + -59, -59, 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, -59, + // State 134 + -60, -60, 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, -60, + // State 135 + -63, -63, 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, -63, + // State 136 + -64, -64, 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, -64, + // State 137 + 0, 0, -74, 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, ]; - fn __action(state: i8, integer: usize) -> i8 { - __ACTION[(state as usize) * 30 + integer] + fn __action(state: i16, integer: usize) -> i16 { + __ACTION[(state as usize) * 33 + integer] } - const __EOF_ACTION: &[i8] = &[ + const __EOF_ACTION: &[i16] = &[ // State 0 0, // State 1 @@ -363,19 +403,19 @@ mod __parse__AIR { // State 27 0, // State 28 - -76, + 0, // State 29 + 0, + // State 30 + 0, + // State 31 + -90, + // State 32 -8, - // State 30 - 0, - // State 31 - -55, - // State 32 - 0, // State 33 0, // State 34 - 0, + -65, // State 35 0, // State 36 @@ -469,7 +509,7 @@ mod __parse__AIR { // State 80 0, // State 81 - -46, + 0, // State 82 0, // State 83 @@ -477,7 +517,7 @@ mod __parse__AIR { // State 84 0, // State 85 - -48, + 0, // State 86 0, // State 87 @@ -487,15 +527,15 @@ mod __parse__AIR { // State 89 0, // State 90 - -51, + 0, // State 91 0, // State 92 0, // State 93 - 0, + -56, // State 94 - -43, + 0, // State 95 0, // State 96 @@ -503,9 +543,9 @@ mod __parse__AIR { // State 97 0, // State 98 - -42, - // State 99 0, + // State 99 + -58, // State 100 0, // State 101 @@ -515,101 +555,138 @@ mod __parse__AIR { // State 103 0, // State 104 - 0, + -61, // State 105 0, // State 106 - -47, + 0, // State 107 - -45, + 0, // State 108 - -44, + -53, // State 109 - -52, + 0, // State 110 0, // State 111 - 0, + -51, // State 112 - -41, + 0, // State 113 0, // State 114 0, // State 115 - -49, + 0, // State 116 - -50, + 0, // State 117 - -53, + 0, // State 118 - -54, + 0, // State 119 0, + // State 120 + 0, + // State 121 + 0, + // State 122 + 0, + // State 123 + -57, + // State 124 + -55, + // State 125 + -54, + // State 126 + -62, + // State 127 + 0, + // State 128 + 0, + // State 129 + -50, + // State 130 + 0, + // State 131 + 0, + // State 132 + -52, + // State 133 + -59, + // State 134 + -60, + // State 135 + -63, + // State 136 + -64, + // State 137 + 0, ]; - fn __goto(state: i8, nt: usize) -> i8 { + fn __goto(state: i16, nt: usize) -> i16 { match nt { - 2 => 27, - 5 => 28, - 6 => 11, - 7 => 82, + 2 => 30, + 5 => 31, + 6 => 12, + 7 => 94, 8 => match state { - 27 => 113, - _ => 99, + 30 => 130, + _ => 114, }, - 9 => 20, + 9 => 22, 10 => match state { - 19 => 95, - 26 => 110, - _ => 47, - }, - 11 => 96, - 13 => 55, - 14 => 60, - 15 => 111, - 16 => match state { - 9 => 17, - 10 => 18, - 0 => 29, - 15 => 89, - 16 => 91, - 17 => 92, - 18 => 93, - 22 => 102, - 23 => 103, - 24 => 104, - 25 => 105, - _ => 16, + 2 => 52, + 21 => 109, + 29 => 127, + _ => 14, }, + 11 => 110, + 13 => 117, + 14 => 62, + 15 => 68, + 16 => 128, 17 => match state { - 1 => 34, - _ => 65, + 10 => 19, + 11 => 20, + 0 => 32, + 17 => 103, + 18 => 105, + 19 => 106, + 20 => 107, + 25 => 119, + 26 => 120, + 27 => 121, + 28 => 122, + _ => 18, }, - 18 => 48, + 18 => 17, 19 => match state { - 11 => 83, - 20 => 97, - _ => 15, + 1 => 37, + _ => 74, }, - 20 => 26, - 21 => 12, - 22 => match state { - 5 => 13, - 6 => 14, - 13 => 24, - 14 => 25, - _ => 100, + 20 => 53, + 21 => 29, + 22 => 24, + 23 => 13, + 24 => match state { + 6 => 15, + 7 => 16, + 15 => 27, + 16 => 28, + _ => 115, }, _ => 0, } } - fn __expected_tokens(__state: i8) -> alloc::vec::Vec { + fn __expected_tokens(__state: i16) -> alloc::vec::Vec { const __TERMINAL: &[&str] = &[ r###""(""###, r###"")""###, r###""[""###, r###""]""###, r###"Boolean"###, + r###"CanonStream"###, + r###"CanonStreamWithLambda"###, r###"F64"###, r###"I64"###, r###"InitPeerId"###, @@ -624,6 +701,7 @@ mod __parse__AIR { r###"Timestamp"###, r###"ap"###, r###"call"###, + r###"canon"###, r###"fail"###, r###"fold"###, r###"match_"###, @@ -661,9 +739,9 @@ mod __parse__AIR { type TokenIndex = usize; type Symbol = __Symbol<'input>; type Success = Box>; - type StateIndex = i8; - type Action = i8; - type ReduceIndex = i8; + type StateIndex = i16; + type Action = i16; + type ReduceIndex = i16; type NonterminalIndex = usize; #[inline] @@ -682,22 +760,22 @@ mod __parse__AIR { } #[inline] - fn action(&self, state: i8, integer: usize) -> i8 { + fn action(&self, state: i16, integer: usize) -> i16 { __action(state, integer) } #[inline] - fn error_action(&self, state: i8) -> i8 { - __action(state, 30 - 1) + fn error_action(&self, state: i16) -> i16 { + __action(state, 33 - 1) } #[inline] - fn eof_action(&self, state: i8) -> i8 { + fn eof_action(&self, state: i16) -> i16 { __EOF_ACTION[state as usize] } #[inline] - fn goto(&self, state: i8, nt: usize) -> i8 { + fn goto(&self, state: i16, nt: usize) -> i16 { __goto(state, nt) } @@ -705,7 +783,7 @@ mod __parse__AIR { __token_to_symbol(token_index, token, core::marker::PhantomData::<(&(), &(), &())>) } - fn expected_tokens(&self, state: i8) -> alloc::vec::Vec { + fn expected_tokens(&self, state: i16) -> alloc::vec::Vec { __expected_tokens(state) } @@ -724,9 +802,9 @@ mod __parse__AIR { fn reduce( &mut self, - action: i8, + action: i16, start_location: Option<&Self::Location>, - states: &mut alloc::vec::Vec, + states: &mut alloc::vec::Vec, symbols: &mut alloc::vec::Vec<__state_machine::SymbolTriple>, ) -> Option<__state_machine::ParseResult> { __reduce( @@ -741,7 +819,7 @@ mod __parse__AIR { ) } - fn simulate_reduce(&self, action: i8) -> __state_machine::SimulatedReduce { + fn simulate_reduce(&self, action: i16) -> __state_machine::SimulatedReduce { __simulate_reduce(action, core::marker::PhantomData::<(&(), &(), &())>) } } @@ -760,30 +838,33 @@ mod __parse__AIR { Token::OpenSquareBracket if true => Some(2), Token::CloseSquareBracket if true => Some(3), Token::Boolean(_) if true => Some(4), - Token::F64(_) if true => Some(5), - Token::I64(_) if true => Some(6), - Token::InitPeerId if true => Some(7), - Token::LastError if true => Some(8), - Token::LastErrorWithLambda(_) if true => Some(9), - Token::StringLiteral(_) if true => Some(10), - Token::Scalar { name: _, position: _ } if true => Some(11), - Token::ScalarWithLambda { name: _, lambda: _, position: _ } if true => Some(12), - Token::Stream { name: _, position: _ } if true => Some(13), - Token::StreamWithLambda { name: _, lambda: _, position: _ } if true => Some(14), - Token::TTL if true => Some(15), - Token::Timestamp if true => Some(16), - Token::Ap if true => Some(17), - Token::Call if true => Some(18), - Token::Fail if true => Some(19), - Token::Fold if true => Some(20), - Token::Match if true => Some(21), - Token::MisMatch if true => Some(22), - Token::New if true => Some(23), - Token::Next if true => Some(24), - Token::Null if true => Some(25), - Token::Par if true => Some(26), - Token::Seq if true => Some(27), - Token::Xor if true => Some(28), + Token::CanonStream { name: _, position: _ } if true => Some(5), + Token::CanonStreamWithLambda { name: _, lambda: _, position: _ } if true => Some(6), + Token::F64(_) if true => Some(7), + Token::I64(_) if true => Some(8), + Token::InitPeerId if true => Some(9), + Token::LastError if true => Some(10), + Token::LastErrorWithLambda(_) if true => Some(11), + Token::StringLiteral(_) if true => Some(12), + Token::Scalar { name: _, position: _ } if true => Some(13), + Token::ScalarWithLambda { name: _, lambda: _, position: _ } if true => Some(14), + Token::Stream { name: _, position: _ } if true => Some(15), + Token::StreamWithLambda { name: _, lambda: _, position: _ } if true => Some(16), + Token::TTL if true => Some(17), + Token::Timestamp if true => Some(18), + Token::Ap if true => Some(19), + Token::Call if true => Some(20), + Token::Canon if true => Some(21), + Token::Fail if true => Some(22), + Token::Fold if true => Some(23), + Token::Match if true => Some(24), + Token::MisMatch if true => Some(25), + Token::New if true => Some(26), + Token::Next if true => Some(27), + Token::Null if true => Some(28), + Token::Par if true => Some(29), + Token::Seq if true => Some(30), + Token::Xor if true => Some(31), _ => None, } } @@ -798,33 +879,33 @@ mod __parse__AIR { ) -> __Symbol<'input> { match __token_index { - 0 | 1 | 2 | 3 | 7 | 8 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 => __Symbol::Variant0(__token), + 0 | 1 | 2 | 3 | 9 | 10 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 => __Symbol::Variant0(__token), 4 => match __token { Token::Boolean(__tok0) if true => __Symbol::Variant1(__tok0), _ => unreachable!(), }, - 5 => match __token { - Token::F64(__tok0) if true => __Symbol::Variant2(__tok0), + 5 | 13 | 15 => match __token { + Token::CanonStream { name: __tok0, position: __tok1 } | Token::Scalar { name: __tok0, position: __tok1 } | Token::Stream { name: __tok0, position: __tok1 } if true => __Symbol::Variant2((__tok0, __tok1)), _ => unreachable!(), }, - 6 => match __token { - Token::I64(__tok0) if true => __Symbol::Variant3(__tok0), + 6 | 14 | 16 => match __token { + Token::CanonStreamWithLambda { name: __tok0, lambda: __tok1, position: __tok2 } | Token::ScalarWithLambda { name: __tok0, lambda: __tok1, position: __tok2 } | Token::StreamWithLambda { name: __tok0, lambda: __tok1, position: __tok2 } if true => __Symbol::Variant3((__tok0, __tok1, __tok2)), _ => unreachable!(), }, - 9 => match __token { - Token::LastErrorWithLambda(__tok0) if true => __Symbol::Variant4(__tok0), + 7 => match __token { + Token::F64(__tok0) if true => __Symbol::Variant4(__tok0), _ => unreachable!(), }, - 10 => match __token { - Token::StringLiteral(__tok0) if true => __Symbol::Variant5(__tok0), + 8 => match __token { + Token::I64(__tok0) if true => __Symbol::Variant5(__tok0), _ => unreachable!(), }, - 11 | 13 => match __token { - Token::Scalar { name: __tok0, position: __tok1 } | Token::Stream { name: __tok0, position: __tok1 } if true => __Symbol::Variant6((__tok0, __tok1)), + 11 => match __token { + Token::LastErrorWithLambda(__tok0) if true => __Symbol::Variant6(__tok0), _ => unreachable!(), }, - 12 | 14 => match __token { - Token::ScalarWithLambda { name: __tok0, lambda: __tok1, position: __tok2 } | Token::StreamWithLambda { name: __tok0, lambda: __tok1, position: __tok2 } if true => __Symbol::Variant7((__tok0, __tok1, __tok2)), + 12 => match __token { + Token::StringLiteral(__tok0) if true => __Symbol::Variant7(__tok0), _ => unreachable!(), }, _ => unreachable!(), @@ -835,7 +916,7 @@ mod __parse__AIR { 'input, 'v, >( - __reduce_index: i8, + __reduce_index: i16, _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> __state_machine::SimulatedReduce<__StateMachine<'err, 'input, 'v>> where @@ -960,43 +1041,43 @@ mod __parse__AIR { 19 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 7, + nonterminal_produced: 6, } } 20 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 8, + nonterminal_produced: 6, } } 21 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 9, + states_to_pop: 1, + nonterminal_produced: 7, } } 22 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 9, + states_to_pop: 1, + nonterminal_produced: 7, } } 23 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 10, + nonterminal_produced: 8, } } 24 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 10, + states_to_pop: 2, + nonterminal_produced: 9, } } 25 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 10, + states_to_pop: 3, + nonterminal_produced: 9, } } 26 => { @@ -1020,259 +1101,259 @@ mod __parse__AIR { 29 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 11, + nonterminal_produced: 10, } } 30 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 12, + nonterminal_produced: 10, } } 31 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 0, - nonterminal_produced: 12, + states_to_pop: 1, + nonterminal_produced: 10, } } 32 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 13, + nonterminal_produced: 10, } } 33 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 13, + nonterminal_produced: 10, } } 34 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 13, + states_to_pop: 1, + nonterminal_produced: 11, } } 35 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 13, + nonterminal_produced: 11, } } 36 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 14, + nonterminal_produced: 12, } } 37 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 14, + states_to_pop: 0, + nonterminal_produced: 12, } } 38 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 14, + states_to_pop: 1, + nonterminal_produced: 13, } } 39 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 15, + nonterminal_produced: 14, } } 40 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 16, + states_to_pop: 1, + nonterminal_produced: 14, } } 41 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 16, + states_to_pop: 2, + nonterminal_produced: 14, } } 42 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 16, + states_to_pop: 1, + nonterminal_produced: 14, } } 43 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 16, + states_to_pop: 1, + nonterminal_produced: 14, } } 44 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 16, + states_to_pop: 1, + nonterminal_produced: 15, } } 45 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 3, - nonterminal_produced: 16, + states_to_pop: 1, + nonterminal_produced: 15, } } 46 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 16, + states_to_pop: 1, + nonterminal_produced: 15, } } 47 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 16, + states_to_pop: 2, + nonterminal_produced: 15, } } 48 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, + states_to_pop: 1, nonterminal_produced: 16, } } 49 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 6, - nonterminal_produced: 16, + nonterminal_produced: 17, } } 50 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 4, - nonterminal_produced: 16, + states_to_pop: 5, + nonterminal_produced: 17, } } 51 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 5, - nonterminal_produced: 16, + states_to_pop: 6, + nonterminal_produced: 17, } } 52 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 16, + states_to_pop: 5, + nonterminal_produced: 17, } } 53 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 6, - nonterminal_produced: 16, + states_to_pop: 5, + nonterminal_produced: 17, } } 54 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 16, + states_to_pop: 5, + nonterminal_produced: 17, } } 55 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 3, nonterminal_produced: 17, } } 56 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, + states_to_pop: 5, nonterminal_produced: 17, } } 57 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 18, + states_to_pop: 4, + nonterminal_produced: 17, } } 58 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 19, + states_to_pop: 6, + nonterminal_produced: 17, } } 59 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 19, + states_to_pop: 6, + nonterminal_produced: 17, } } 60 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 20, + states_to_pop: 4, + nonterminal_produced: 17, } } 61 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 5, - nonterminal_produced: 21, + nonterminal_produced: 17, } } 62 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 22, + states_to_pop: 6, + nonterminal_produced: 17, } } 63 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 22, + states_to_pop: 6, + nonterminal_produced: 17, } } 64 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 22, + nonterminal_produced: 17, } } 65 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 22, + nonterminal_produced: 18, } } 66 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 22, + nonterminal_produced: 18, } } 67 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 22, + nonterminal_produced: 18, } } 68 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 22, + nonterminal_produced: 19, } } 69 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 22, + nonterminal_produced: 19, } } 70 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 2, - nonterminal_produced: 22, + states_to_pop: 1, + nonterminal_produced: 20, } } 71 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 22, + nonterminal_produced: 21, } } 72 => { @@ -1283,17 +1364,101 @@ mod __parse__AIR { } 73 => { __state_machine::SimulatedReduce::Reduce { - states_to_pop: 1, - nonterminal_produced: 22, + states_to_pop: 5, + nonterminal_produced: 23, } } 74 => { __state_machine::SimulatedReduce::Reduce { states_to_pop: 1, - nonterminal_produced: 22, + nonterminal_produced: 24, } } - 75 => __state_machine::SimulatedReduce::Accept, + 75 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 24, + } + } + 76 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 24, + } + } + 77 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 24, + } + } + 78 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 24, + } + } + 79 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 24, + } + } + 80 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 24, + } + } + 81 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 24, + } + } + 82 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 24, + } + } + 83 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 24, + } + } + 84 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 24, + } + } + 85 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 24, + } + } + 86 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 24, + } + } + 87 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 24, + } + } + 88 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 24, + } + } + 89 => __state_machine::SimulatedReduce::Accept, _ => panic!("invalid reduction index {}", __reduce_index) } } @@ -1344,8 +1509,8 @@ mod __parse__AIR { input: &'input str, errors: &'err mut Vec, ParserError>>, validator: &'v mut VariableValidator<'input>, - __error_state: i8, - __states: & [i8], + __error_state: i16, + __states: & [i16], __opt_integer: Option, _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> bool @@ -1382,9 +1547,9 @@ mod __parse__AIR { input: &'input str, errors: &'err mut Vec, ParserError>>, validator: &'v mut VariableValidator<'input>, - __action: i8, + __action: i16, __lookahead_start: Option<&usize>, - __states: &mut alloc::vec::Vec, + __states: &mut alloc::vec::Vec, __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> Option>,__lalrpop_util::ParseError, ParserError>>> @@ -1616,6 +1781,48 @@ mod __parse__AIR { __reduce74(input, errors, validator, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &(), &())>) } 75 => { + __reduce75(input, errors, validator, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &(), &())>) + } + 76 => { + __reduce76(input, errors, validator, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &(), &())>) + } + 77 => { + __reduce77(input, errors, validator, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &(), &())>) + } + 78 => { + __reduce78(input, errors, validator, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &(), &())>) + } + 79 => { + __reduce79(input, errors, validator, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &(), &())>) + } + 80 => { + __reduce80(input, errors, validator, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &(), &())>) + } + 81 => { + __reduce81(input, errors, validator, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &(), &())>) + } + 82 => { + __reduce82(input, errors, validator, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &(), &())>) + } + 83 => { + __reduce83(input, errors, validator, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &(), &())>) + } + 84 => { + __reduce84(input, errors, validator, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &(), &())>) + } + 85 => { + __reduce85(input, errors, validator, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &(), &())>) + } + 86 => { + __reduce86(input, errors, validator, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &(), &())>) + } + 87 => { + __reduce87(input, errors, validator, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &(), &())>) + } + 88 => { + __reduce88(input, errors, validator, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &(), &())>) + } + 89 => { // __AIR = AIR => ActionFn(0); let __sym0 = __pop_Variant12(__symbols); let __start = __sym0.0.clone(); @@ -1636,25 +1843,25 @@ mod __parse__AIR { fn __symbol_type_mismatch() -> ! { panic!("symbol type mismatch") } - fn __pop_Variant7< + fn __pop_Variant3< 'input, >( __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> ) -> (usize, (&'input str, LambdaAST<'input>, usize), usize) { match __symbols.pop() { - Some((__l, __Symbol::Variant7(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant6< + fn __pop_Variant2< 'input, >( __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> ) -> (usize, (&'input str, usize), usize) { match __symbols.pop() { - Some((__l, __Symbol::Variant6(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant2(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -1669,6 +1876,17 @@ mod __parse__AIR { _ => __symbol_type_mismatch() } } + fn __pop_Variant14< + 'input, + >( + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, ApResult<'input>, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant14(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } fn __pop_Variant12< 'input, >( @@ -1691,14 +1909,14 @@ mod __parse__AIR { _ => __symbol_type_mismatch() } } - fn __pop_Variant18< + fn __pop_Variant17< 'input, >( __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> - ) -> (usize, Fail<'input>, usize) + ) -> (usize, CallOutputValue<'input>, usize) { match __symbols.pop() { - Some((__l, __Symbol::Variant18(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant17(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -1706,35 +1924,79 @@ mod __parse__AIR { 'input, >( __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> - ) -> (usize, FoldScalarIterable<'input>, usize) + ) -> (usize, CanonStream<'input>, usize) { match __symbols.pop() { Some((__l, __Symbol::Variant19(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant4< - 'input, - >( - __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> - ) -> (usize, LambdaAST<'input>, usize) - { - match __symbols.pop() { - Some((__l, __Symbol::Variant4(__v), __r)) => (__l, __v, __r), - _ => __symbol_type_mismatch() - } - } fn __pop_Variant20< 'input, >( __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> - ) -> (usize, Number, usize) + ) -> (usize, Fail<'input>, usize) { match __symbols.pop() { Some((__l, __Symbol::Variant20(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } + fn __pop_Variant21< + 'input, + >( + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, FoldScalarIterable<'input>, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant21(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant6< + 'input, + >( + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, LambdaAST<'input>, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant6(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant22< + 'input, + >( + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, NewArgument<'input>, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant22(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant23< + 'input, + >( + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, Number, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant23(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant24< + 'input, + >( + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, Stream<'input>, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant24(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } fn __pop_Variant0< 'input, >( @@ -1746,14 +2008,14 @@ mod __parse__AIR { _ => __symbol_type_mismatch() } } - fn __pop_Variant21< + fn __pop_Variant25< 'input, >( __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> ) -> (usize, Triplet<'input>, usize) { match __symbols.pop() { - Some((__l, __Symbol::Variant21(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant25(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -1768,17 +2030,6 @@ mod __parse__AIR { _ => __symbol_type_mismatch() } } - fn __pop_Variant14< - 'input, - >( - __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> - ) -> (usize, Variable<'input>, usize) - { - match __symbols.pop() { - Some((__l, __Symbol::Variant14(__v), __r)) => (__l, __v, __r), - _ => __symbol_type_mismatch() - } - } fn __pop_Variant15< 'input, >( @@ -1823,36 +2074,36 @@ mod __parse__AIR { _ => __symbol_type_mismatch() } } - fn __pop_Variant17< + fn __pop_Variant18< 'input, >( __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> - ) -> (usize, core::option::Option>, usize) + ) -> (usize, core::option::Option>, usize) { match __symbols.pop() { - Some((__l, __Symbol::Variant17(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant18(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant2< + fn __pop_Variant4< 'input, >( __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> ) -> (usize, f64, usize) { match __symbols.pop() { - Some((__l, __Symbol::Variant2(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant4(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } - fn __pop_Variant3< + fn __pop_Variant5< 'input, >( __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> ) -> (usize, i64, usize) { match __symbols.pop() { - Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant5(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -1867,14 +2118,14 @@ mod __parse__AIR { _ => __symbol_type_mismatch() } } - fn __pop_Variant5< + fn __pop_Variant7< 'input, >( __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> ) -> (usize, &'input str, usize) { match __symbols.pop() { - Some((__l, __Symbol::Variant5(__v), __r)) => (__l, __v, __r), + Some((__l, __Symbol::Variant7(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } @@ -1891,11 +2142,11 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // () = Arg => ActionFn(67); + // () = Arg => ActionFn(81); let __sym0 = __pop_Variant9(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action67::<>(input, errors, validator, __sym0); + let __nt = super::__action81::<>(input, errors, validator, __sym0); __symbols.push((__start, __Symbol::Variant9(__nt), __end)); (1, 0) } @@ -1912,10 +2163,10 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ()* = => ActionFn(65); + // ()* = => ActionFn(79); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action65::<>(input, errors, validator, &__start, &__end); + let __nt = super::__action79::<>(input, errors, validator, &__start, &__end); __symbols.push((__start, __Symbol::Variant10(__nt), __end)); (0, 1) } @@ -1932,11 +2183,11 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ()* = ()+ => ActionFn(66); + // ()* = ()+ => ActionFn(80); let __sym0 = __pop_Variant10(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action66::<>(input, errors, validator, __sym0); + let __nt = super::__action80::<>(input, errors, validator, __sym0); __symbols.push((__start, __Symbol::Variant10(__nt), __end)); (1, 1) } @@ -1953,11 +2204,11 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ()+ = Arg => ActionFn(74); + // ()+ = Arg => ActionFn(88); let __sym0 = __pop_Variant9(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action74::<>(input, errors, validator, __sym0); + let __nt = super::__action88::<>(input, errors, validator, __sym0); __symbols.push((__start, __Symbol::Variant10(__nt), __end)); (1, 2) } @@ -1974,13 +2225,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ()+ = ()+, Arg => ActionFn(75); + // ()+ = ()+, Arg => ActionFn(89); assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant9(__symbols); let __sym0 = __pop_Variant10(__symbols); let __start = __sym0.0.clone(); let __end = __sym1.2.clone(); - let __nt = super::__action75::<>(input, errors, validator, __sym0, __sym1); + let __nt = super::__action89::<>(input, errors, validator, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant10(__nt), __end)); (2, 2) } @@ -1997,10 +2248,10 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // @L = => ActionFn(71); + // @L = => ActionFn(85); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action71::<>(input, errors, validator, &__start, &__end); + let __nt = super::__action85::<>(input, errors, validator, &__start, &__end); __symbols.push((__start, __Symbol::Variant11(__nt), __end)); (0, 3) } @@ -2017,10 +2268,10 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // @R = => ActionFn(68); + // @R = => ActionFn(82); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); let __end = __start.clone(); - let __nt = super::__action68::<>(input, errors, validator, &__start, &__end); + let __nt = super::__action82::<>(input, errors, validator, &__start, &__end); __symbols.push((__start, __Symbol::Variant11(__nt), __end)); (0, 4) } @@ -2058,11 +2309,11 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ApArgument = InitPeerId => ActionFn(54); + // ApArgument = InitPeerId => ActionFn(64); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action54::<>(input, errors, validator, __sym0); + let __nt = super::__action64::<>(input, errors, validator, __sym0); __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (1, 6) } @@ -2079,11 +2330,11 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ApArgument = LastError => ActionFn(55); + // ApArgument = LastError => ActionFn(65); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action55::<>(input, errors, validator, __sym0); + let __nt = super::__action65::<>(input, errors, validator, __sym0); __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (1, 6) } @@ -2100,11 +2351,11 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ApArgument = LastErrorWithLambda => ActionFn(56); - let __sym0 = __pop_Variant4(__symbols); + // ApArgument = LastErrorWithLambda => ActionFn(66); + let __sym0 = __pop_Variant6(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action56::<>(input, errors, validator, __sym0); + let __nt = super::__action66::<>(input, errors, validator, __sym0); __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (1, 6) } @@ -2121,11 +2372,11 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ApArgument = Timestamp => ActionFn(57); + // ApArgument = Timestamp => ActionFn(67); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action57::<>(input, errors, validator, __sym0); + let __nt = super::__action67::<>(input, errors, validator, __sym0); __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (1, 6) } @@ -2142,11 +2393,11 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ApArgument = TTL => ActionFn(58); + // ApArgument = TTL => ActionFn(68); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action58::<>(input, errors, validator, __sym0); + let __nt = super::__action68::<>(input, errors, validator, __sym0); __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (1, 6) } @@ -2163,11 +2414,11 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ApArgument = Literal => ActionFn(59); - let __sym0 = __pop_Variant5(__symbols); + // ApArgument = Literal => ActionFn(69); + let __sym0 = __pop_Variant7(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action59::<>(input, errors, validator, __sym0); + let __nt = super::__action69::<>(input, errors, validator, __sym0); __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (1, 6) } @@ -2184,11 +2435,11 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ApArgument = Number => ActionFn(60); - let __sym0 = __pop_Variant20(__symbols); + // ApArgument = Number => ActionFn(70); + let __sym0 = __pop_Variant23(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action60::<>(input, errors, validator, __sym0); + let __nt = super::__action70::<>(input, errors, validator, __sym0); __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (1, 6) } @@ -2205,11 +2456,11 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ApArgument = Boolean => ActionFn(61); + // ApArgument = Boolean => ActionFn(71); let __sym0 = __pop_Variant1(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action61::<>(input, errors, validator, __sym0); + let __nt = super::__action71::<>(input, errors, validator, __sym0); __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (1, 6) } @@ -2226,13 +2477,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ApArgument = "[", "]" => ActionFn(62); + // ApArgument = "[", "]" => ActionFn(72); 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::__action62::<>(input, errors, validator, __sym0, __sym1); + let __nt = super::__action72::<>(input, errors, validator, __sym0, __sym1); __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (2, 6) } @@ -2249,11 +2500,11 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ApArgument = Scalar => ActionFn(63); - let __sym0 = __pop_Variant6(__symbols); + // ApArgument = Scalar => ActionFn(73); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action63::<>(input, errors, validator, __sym0); + let __nt = super::__action73::<>(input, errors, validator, __sym0); __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (1, 6) } @@ -2270,11 +2521,11 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ApArgument = ScalarWithLambda => ActionFn(64); - let __sym0 = __pop_Variant7(__symbols); + // ApArgument = ScalarWithLambda => ActionFn(74); + let __sym0 = __pop_Variant3(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action64::<>(input, errors, validator, __sym0); + let __nt = super::__action74::<>(input, errors, validator, __sym0); __symbols.push((__start, __Symbol::Variant13(__nt), __end)); (1, 6) } @@ -2291,13 +2542,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ApResult = ScriptVariable => ActionFn(18); - let __sym0 = __pop_Variant14(__symbols); + // ApArgument = CanonStream => ActionFn(75); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action18::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 7) + let __nt = super::__action75::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (1, 6) } pub(crate) fn __reduce20< 'err, @@ -2312,13 +2563,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Arg = Value => ActionFn(40); - let __sym0 = __pop_Variant9(__symbols); + // ApArgument = CanonStreamWithLambda => ActionFn(76); + let __sym0 = __pop_Variant3(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action40::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (1, 8) + let __nt = super::__action76::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant13(__nt), __end)); + (1, 6) } pub(crate) fn __reduce21< 'err, @@ -2333,15 +2584,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Args = "[", "]" => ActionFn(76); - assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant0(__symbols); + // ApResult = Scalar => ActionFn(19); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); - let __end = __sym1.2.clone(); - let __nt = super::__action76::<>(input, errors, validator, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (2, 9) + let __end = __sym0.2.clone(); + let __nt = super::__action19::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (1, 7) } pub(crate) fn __reduce22< 'err, @@ -2356,16 +2605,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Args = "[", ()+, "]" => ActionFn(77); - assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant10(__symbols); - let __sym0 = __pop_Variant0(__symbols); + // ApResult = Stream => ActionFn(20); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); - let __end = __sym2.2.clone(); - let __nt = super::__action77::<>(input, errors, validator, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant15(__nt), __end)); - (3, 9) + let __end = __sym0.2.clone(); + let __nt = super::__action20::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant14(__nt), __end)); + (1, 7) } pub(crate) fn __reduce23< 'err, @@ -2380,13 +2626,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // CallInstrValue = InitPeerId => ActionFn(32); - let __sym0 = __pop_Variant0(__symbols); + // Arg = Value => ActionFn(48); + let __sym0 = __pop_Variant9(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action32::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (1, 10) + let __nt = super::__action48::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 8) } pub(crate) fn __reduce24< 'err, @@ -2401,13 +2647,15 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // CallInstrValue = Literal => ActionFn(33); - let __sym0 = __pop_Variant5(__symbols); + // Args = "[", "]" => ActionFn(90); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action33::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (1, 10) + let __end = __sym1.2.clone(); + let __nt = super::__action90::<>(input, errors, validator, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (2, 9) } pub(crate) fn __reduce25< 'err, @@ -2422,13 +2670,16 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // CallInstrValue = Scalar => ActionFn(34); - let __sym0 = __pop_Variant6(__symbols); + // Args = "[", ()+, "]" => ActionFn(91); + assert!(__symbols.len() >= 3); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant10(__symbols); + let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action34::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (1, 10) + let __end = __sym2.2.clone(); + let __nt = super::__action91::<>(input, errors, validator, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant15(__nt), __end)); + (3, 9) } pub(crate) fn __reduce26< 'err, @@ -2443,8 +2694,8 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // CallInstrValue = ScalarWithLambda => ActionFn(35); - let __sym0 = __pop_Variant7(__symbols); + // CallInstrValue = InitPeerId => ActionFn(35); + let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action35::<>(input, errors, validator, __sym0); @@ -2464,8 +2715,8 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // CallInstrValue = Stream => ActionFn(36); - let __sym0 = __pop_Variant6(__symbols); + // CallInstrValue = Literal => ActionFn(36); + let __sym0 = __pop_Variant7(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action36::<>(input, errors, validator, __sym0); @@ -2485,8 +2736,8 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // CallInstrValue = StreamWithLambda => ActionFn(37); - let __sym0 = __pop_Variant7(__symbols); + // CallInstrValue = Scalar => ActionFn(37); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action37::<>(input, errors, validator, __sym0); @@ -2506,13 +2757,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // CallOutput = ScriptVariable => ActionFn(19); - let __sym0 = __pop_Variant14(__symbols); + // CallInstrValue = ScalarWithLambda => ActionFn(38); + let __sym0 = __pop_Variant3(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action19::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 11) + let __nt = super::__action38::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (1, 10) } pub(crate) fn __reduce30< 'err, @@ -2527,13 +2778,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // CallOutput? = CallOutput => ActionFn(69); - let __sym0 = __pop_Variant14(__symbols); + // CallInstrValue = Stream => ActionFn(39); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action69::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant17(__nt), __end)); - (1, 12) + let __nt = super::__action39::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (1, 10) } pub(crate) fn __reduce31< 'err, @@ -2548,12 +2799,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // CallOutput? = => ActionFn(70); - let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); - let __end = __start.clone(); - let __nt = super::__action70::<>(input, errors, validator, &__start, &__end); - __symbols.push((__start, __Symbol::Variant17(__nt), __end)); - (0, 12) + // CallInstrValue = StreamWithLambda => ActionFn(40); + let __sym0 = __pop_Variant3(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action40::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (1, 10) } pub(crate) fn __reduce32< 'err, @@ -2568,13 +2820,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // FailBody = Scalar => ActionFn(22); - let __sym0 = __pop_Variant6(__symbols); + // CallInstrValue = CanonStream => ActionFn(41); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action22::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant18(__nt), __end)); - (1, 13) + let __nt = super::__action41::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (1, 10) } pub(crate) fn __reduce33< 'err, @@ -2589,13 +2841,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // FailBody = ScalarWithLambda => ActionFn(23); - let __sym0 = __pop_Variant7(__symbols); + // CallInstrValue = CanonStreamWithLambda => ActionFn(42); + let __sym0 = __pop_Variant3(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action23::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant18(__nt), __end)); - (1, 13) + let __nt = super::__action42::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (1, 10) } pub(crate) fn __reduce34< 'err, @@ -2610,15 +2862,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // FailBody = I64, Literal => ActionFn(24); - assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant5(__symbols); - let __sym0 = __pop_Variant3(__symbols); + // CallOutput = Scalar => ActionFn(21); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); - let __end = __sym1.2.clone(); - let __nt = super::__action24::<>(input, errors, validator, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant18(__nt), __end)); - (2, 13) + let __end = __sym0.2.clone(); + let __nt = super::__action21::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (1, 11) } pub(crate) fn __reduce35< 'err, @@ -2633,13 +2883,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // FailBody = LastError => ActionFn(87); - let __sym0 = __pop_Variant0(__symbols); + // CallOutput = Stream => ActionFn(22); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action87::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant18(__nt), __end)); - (1, 13) + let __nt = super::__action22::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant17(__nt), __end)); + (1, 11) } pub(crate) fn __reduce36< 'err, @@ -2654,13 +2904,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // FoldScalarIterable = Scalar => ActionFn(26); - let __sym0 = __pop_Variant6(__symbols); + // CallOutput? = CallOutput => ActionFn(83); + let __sym0 = __pop_Variant17(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action26::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant19(__nt), __end)); - (1, 14) + let __nt = super::__action83::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant18(__nt), __end)); + (1, 12) } pub(crate) fn __reduce37< 'err, @@ -2675,13 +2925,12 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // FoldScalarIterable = ScalarWithLambda => ActionFn(27); - let __sym0 = __pop_Variant7(__symbols); - let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action27::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant19(__nt), __end)); - (1, 14) + // CallOutput? = => ActionFn(84); + let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); + let __end = __start.clone(); + let __nt = super::__action84::<>(input, errors, validator, &__start, &__end); + __symbols.push((__start, __Symbol::Variant18(__nt), __end)); + (0, 12) } pub(crate) fn __reduce38< 'err, @@ -2696,15 +2945,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // FoldScalarIterable = "[", "]" => ActionFn(28); - assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant0(__symbols); + // CanonStreamArgument = CanonStream => ActionFn(78); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); - let __end = __sym1.2.clone(); - let __nt = super::__action28::<>(input, errors, validator, __sym0, __sym1); + let __end = __sym0.2.clone(); + let __nt = super::__action78::<>(input, errors, validator, __sym0); __symbols.push((__start, __Symbol::Variant19(__nt), __end)); - (2, 14) + (1, 13) } pub(crate) fn __reduce39< 'err, @@ -2719,13 +2966,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Function = CallInstrValue => ActionFn(29); - let __sym0 = __pop_Variant16(__symbols); + // FailBody = Scalar => ActionFn(23); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action29::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (1, 15) + let __nt = super::__action23::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant20(__nt), __end)); + (1, 14) } pub(crate) fn __reduce40< 'err, @@ -2740,19 +2987,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Instr = "(", call, Triplet, Args, CallOutput, ")" => ActionFn(96); - assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant14(__symbols); - let __sym3 = __pop_Variant15(__symbols); - let __sym2 = __pop_Variant21(__symbols); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant0(__symbols); + // FailBody = ScalarWithLambda => ActionFn(24); + let __sym0 = __pop_Variant3(__symbols); let __start = __sym0.0.clone(); - let __end = __sym5.2.clone(); - let __nt = super::__action96::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (6, 16) + let __end = __sym0.2.clone(); + let __nt = super::__action24::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant20(__nt), __end)); + (1, 14) } pub(crate) fn __reduce41< 'err, @@ -2767,18 +3008,15 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Instr = "(", call, Triplet, Args, ")" => ActionFn(97); - assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant15(__symbols); - let __sym2 = __pop_Variant21(__symbols); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant0(__symbols); + // FailBody = I64, Literal => ActionFn(25); + assert!(__symbols.len() >= 2); + let __sym1 = __pop_Variant7(__symbols); + let __sym0 = __pop_Variant5(__symbols); let __start = __sym0.0.clone(); - let __end = __sym4.2.clone(); - let __nt = super::__action97::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (5, 16) + let __end = __sym1.2.clone(); + let __nt = super::__action25::<>(input, errors, validator, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant20(__nt), __end)); + (2, 14) } pub(crate) fn __reduce42< 'err, @@ -2793,18 +3031,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Instr = "(", ap, ApArgument, ApResult, ")" => ActionFn(89); - assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant14(__symbols); - let __sym2 = __pop_Variant13(__symbols); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant0(__symbols); + // FailBody = CanonStreamWithLambda => ActionFn(26); + let __sym0 = __pop_Variant3(__symbols); let __start = __sym0.0.clone(); - let __end = __sym4.2.clone(); - let __nt = super::__action89::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (5, 16) + let __end = __sym0.2.clone(); + let __nt = super::__action26::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant20(__nt), __end)); + (1, 14) } pub(crate) fn __reduce43< 'err, @@ -2819,18 +3052,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Instr = "(", seq, Instr, Instr, ")" => ActionFn(4); - assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant12(__symbols); - let __sym2 = __pop_Variant12(__symbols); - let __sym1 = __pop_Variant0(__symbols); + // FailBody = LastError => ActionFn(102); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym4.2.clone(); - let __nt = super::__action4::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (5, 16) + let __end = __sym0.2.clone(); + let __nt = super::__action102::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant20(__nt), __end)); + (1, 14) } pub(crate) fn __reduce44< 'err, @@ -2845,18 +3073,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Instr = "(", par, Instr, Instr, ")" => ActionFn(5); - assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant12(__symbols); - let __sym2 = __pop_Variant12(__symbols); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant0(__symbols); + // FoldScalarIterable = Scalar => ActionFn(28); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); - let __end = __sym4.2.clone(); - let __nt = super::__action5::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (5, 16) + let __end = __sym0.2.clone(); + let __nt = super::__action28::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant21(__nt), __end)); + (1, 15) } pub(crate) fn __reduce45< 'err, @@ -2871,16 +3094,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Instr = "(", null, ")" => ActionFn(6); - assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant0(__symbols); + // FoldScalarIterable = ScalarWithLambda => ActionFn(29); + let __sym0 = __pop_Variant3(__symbols); let __start = __sym0.0.clone(); - let __end = __sym2.2.clone(); - let __nt = super::__action6::<>(input, errors, validator, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (3, 16) + let __end = __sym0.2.clone(); + let __nt = super::__action29::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant21(__nt), __end)); + (1, 15) } pub(crate) fn __reduce46< 'err, @@ -2895,18 +3115,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Instr = "(", new, ScriptVariable, Instr, ")" => ActionFn(90); - assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant12(__symbols); - let __sym2 = __pop_Variant14(__symbols); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant0(__symbols); + // FoldScalarIterable = CanonStream => ActionFn(30); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); - let __end = __sym4.2.clone(); - let __nt = super::__action90::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (5, 16) + let __end = __sym0.2.clone(); + let __nt = super::__action30::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant21(__nt), __end)); + (1, 15) } pub(crate) fn __reduce47< 'err, @@ -2921,17 +3136,15 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Instr = "(", fail, FailBody, ")" => ActionFn(8); - assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant18(__symbols); + // FoldScalarIterable = "[", "]" => ActionFn(31); + assert!(__symbols.len() >= 2); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym3.2.clone(); - let __nt = super::__action8::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (4, 16) + let __end = __sym1.2.clone(); + let __nt = super::__action31::<>(input, errors, validator, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant21(__nt), __end)); + (2, 15) } pub(crate) fn __reduce48< 'err, @@ -2946,19 +3159,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Instr = "(", fold, FoldScalarIterable, Scalar, Instr, ")" => ActionFn(91); - assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant12(__symbols); - let __sym3 = __pop_Variant6(__symbols); - let __sym2 = __pop_Variant19(__symbols); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant0(__symbols); + // Function = CallInstrValue => ActionFn(32); + let __sym0 = __pop_Variant16(__symbols); let __start = __sym0.0.clone(); - let __end = __sym5.2.clone(); - let __nt = super::__action91::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); - __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (6, 16) + let __end = __sym0.2.clone(); + let __nt = super::__action32::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (1, 16) } pub(crate) fn __reduce49< 'err, @@ -2973,19 +3180,19 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Instr = "(", fold, Stream, Scalar, Instr, ")" => ActionFn(92); + // Instr = "(", call, Triplet, Args, CallOutput, ")" => ActionFn(112); assert!(__symbols.len() >= 6); let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant12(__symbols); - let __sym3 = __pop_Variant6(__symbols); - let __sym2 = __pop_Variant6(__symbols); + let __sym4 = __pop_Variant17(__symbols); + let __sym3 = __pop_Variant15(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym5.2.clone(); - let __nt = super::__action92::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __nt = super::__action112::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (6, 16) + (6, 17) } pub(crate) fn __reduce50< 'err, @@ -3000,17 +3207,18 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Instr = "(", next, Scalar, ")" => ActionFn(93); - assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant6(__symbols); + // Instr = "(", call, Triplet, Args, ")" => ActionFn(113); + assert!(__symbols.len() >= 5); + let __sym4 = __pop_Variant0(__symbols); + let __sym3 = __pop_Variant15(__symbols); + let __sym2 = __pop_Variant25(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym3.2.clone(); - let __nt = super::__action93::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3); + let __end = __sym4.2.clone(); + let __nt = super::__action113::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (4, 16) + (5, 17) } pub(crate) fn __reduce51< 'err, @@ -3025,18 +3233,19 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Instr = "(", xor, Instr, Instr, ")" => ActionFn(12); - assert!(__symbols.len() >= 5); - let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant12(__symbols); - let __sym2 = __pop_Variant12(__symbols); + // Instr = "(", canon, CallInstrValue, StreamArgument, CanonStreamArgument, ")" => ActionFn(104); + assert!(__symbols.len() >= 6); + let __sym5 = __pop_Variant0(__symbols); + let __sym4 = __pop_Variant19(__symbols); + let __sym3 = __pop_Variant24(__symbols); + let __sym2 = __pop_Variant16(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym4.2.clone(); - let __nt = super::__action12::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4); + let __end = __sym5.2.clone(); + let __nt = super::__action104::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (5, 16) + (6, 17) } pub(crate) fn __reduce52< 'err, @@ -3051,19 +3260,18 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Instr = "(", match_, Value, Value, Instr, ")" => ActionFn(94); - assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant12(__symbols); - let __sym3 = __pop_Variant9(__symbols); - let __sym2 = __pop_Variant9(__symbols); + // Instr = "(", ap, ApArgument, ApResult, ")" => ActionFn(105); + assert!(__symbols.len() >= 5); + let __sym4 = __pop_Variant0(__symbols); + let __sym3 = __pop_Variant14(__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::__action94::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __end = __sym4.2.clone(); + let __nt = super::__action105::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (6, 16) + (5, 17) } pub(crate) fn __reduce53< 'err, @@ -3078,19 +3286,18 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Instr = "(", mismatch, Value, Value, Instr, ")" => ActionFn(95); - assert!(__symbols.len() >= 6); - let __sym5 = __pop_Variant0(__symbols); - let __sym4 = __pop_Variant12(__symbols); - let __sym3 = __pop_Variant9(__symbols); - let __sym2 = __pop_Variant9(__symbols); + // Instr = "(", seq, Instr, Instr, ")" => ActionFn(5); + assert!(__symbols.len() >= 5); + let __sym4 = __pop_Variant0(__symbols); + let __sym3 = __pop_Variant12(__symbols); + let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym5.2.clone(); - let __nt = super::__action95::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + let __end = __sym4.2.clone(); + let __nt = super::__action5::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (6, 16) + (5, 17) } pub(crate) fn __reduce54< 'err, @@ -3105,13 +3312,18 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Instr = error => ActionFn(15); - let __sym0 = __pop_Variant8(__symbols); + // Instr = "(", par, Instr, Instr, ")" => ActionFn(6); + assert!(__symbols.len() >= 5); + let __sym4 = __pop_Variant0(__symbols); + let __sym3 = __pop_Variant12(__symbols); + let __sym2 = __pop_Variant12(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action15::<>(input, errors, validator, __sym0); + let __end = __sym4.2.clone(); + let __nt = super::__action6::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4); __symbols.push((__start, __Symbol::Variant12(__nt), __end)); - (1, 16) + (5, 17) } pub(crate) fn __reduce55< 'err, @@ -3126,13 +3338,16 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Number = I64 => ActionFn(38); - let __sym0 = __pop_Variant3(__symbols); + // Instr = "(", null, ")" => ActionFn(7); + assert!(__symbols.len() >= 3); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action38::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant20(__nt), __end)); - (1, 17) + let __end = __sym2.2.clone(); + let __nt = super::__action7::<>(input, errors, validator, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (3, 17) } pub(crate) fn __reduce56< 'err, @@ -3147,13 +3362,18 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Number = F64 => ActionFn(39); - let __sym0 = __pop_Variant2(__symbols); + // Instr = "(", new, NewArgument, Instr, ")" => ActionFn(106); + assert!(__symbols.len() >= 5); + let __sym4 = __pop_Variant0(__symbols); + let __sym3 = __pop_Variant12(__symbols); + let __sym2 = __pop_Variant22(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action39::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant20(__nt), __end)); - (1, 17) + let __end = __sym4.2.clone(); + let __nt = super::__action106::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (5, 17) } pub(crate) fn __reduce57< 'err, @@ -3168,13 +3388,17 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // PeerId = CallInstrValue => ActionFn(30); - let __sym0 = __pop_Variant16(__symbols); + // Instr = "(", fail, FailBody, ")" => ActionFn(9); + assert!(__symbols.len() >= 4); + let __sym3 = __pop_Variant0(__symbols); + let __sym2 = __pop_Variant20(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action30::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (1, 18) + let __end = __sym3.2.clone(); + let __nt = super::__action9::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (4, 17) } pub(crate) fn __reduce58< 'err, @@ -3189,13 +3413,19 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ScriptVariable = Scalar => ActionFn(20); - let __sym0 = __pop_Variant6(__symbols); + // Instr = "(", fold, FoldScalarIterable, Scalar, Instr, ")" => ActionFn(107); + assert!(__symbols.len() >= 6); + let __sym5 = __pop_Variant0(__symbols); + let __sym4 = __pop_Variant12(__symbols); + let __sym3 = __pop_Variant2(__symbols); + let __sym2 = __pop_Variant21(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action20::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 19) + let __end = __sym5.2.clone(); + let __nt = super::__action107::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (6, 17) } pub(crate) fn __reduce59< 'err, @@ -3210,13 +3440,19 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ScriptVariable = Stream => ActionFn(21); - let __sym0 = __pop_Variant6(__symbols); + // Instr = "(", fold, Stream, Scalar, Instr, ")" => ActionFn(108); + assert!(__symbols.len() >= 6); + let __sym5 = __pop_Variant0(__symbols); + let __sym4 = __pop_Variant12(__symbols); + let __sym3 = __pop_Variant2(__symbols); + let __sym2 = __pop_Variant2(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action21::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant14(__nt), __end)); - (1, 19) + let __end = __sym5.2.clone(); + let __nt = super::__action108::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (6, 17) } pub(crate) fn __reduce60< 'err, @@ -3231,13 +3467,17 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // ServiceId = CallInstrValue => ActionFn(31); - let __sym0 = __pop_Variant16(__symbols); + // Instr = "(", next, Scalar, ")" => ActionFn(109); + assert!(__symbols.len() >= 4); + let __sym3 = __pop_Variant0(__symbols); + let __sym2 = __pop_Variant2(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action31::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant16(__nt), __end)); - (1, 20) + let __end = __sym3.2.clone(); + let __nt = super::__action109::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (4, 17) } pub(crate) fn __reduce61< 'err, @@ -3252,18 +3492,18 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Triplet = PeerId, "(", ServiceId, Function, ")" => ActionFn(17); + // Instr = "(", xor, Instr, Instr, ")" => ActionFn(13); assert!(__symbols.len() >= 5); let __sym4 = __pop_Variant0(__symbols); - let __sym3 = __pop_Variant16(__symbols); - let __sym2 = __pop_Variant16(__symbols); + let __sym3 = __pop_Variant12(__symbols); + let __sym2 = __pop_Variant12(__symbols); let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant16(__symbols); + let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); let __end = __sym4.2.clone(); - let __nt = super::__action17::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4); - __symbols.push((__start, __Symbol::Variant21(__nt), __end)); - (5, 21) + let __nt = super::__action13::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (5, 17) } pub(crate) fn __reduce62< 'err, @@ -3278,13 +3518,19 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Value = InitPeerId => ActionFn(41); + // Instr = "(", match_, Value, Value, Instr, ")" => ActionFn(110); + assert!(__symbols.len() >= 6); + let __sym5 = __pop_Variant0(__symbols); + let __sym4 = __pop_Variant12(__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 = __sym0.2.clone(); - let __nt = super::__action41::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (1, 22) + let __end = __sym5.2.clone(); + let __nt = super::__action110::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (6, 17) } pub(crate) fn __reduce63< 'err, @@ -3299,13 +3545,19 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Value = LastError => ActionFn(42); + // Instr = "(", mismatch, Value, Value, Instr, ")" => ActionFn(111); + assert!(__symbols.len() >= 6); + let __sym5 = __pop_Variant0(__symbols); + let __sym4 = __pop_Variant12(__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 = __sym0.2.clone(); - let __nt = super::__action42::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (1, 22) + let __end = __sym5.2.clone(); + let __nt = super::__action111::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (6, 17) } pub(crate) fn __reduce64< 'err, @@ -3320,13 +3572,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Value = LastErrorWithLambda => ActionFn(43); - let __sym0 = __pop_Variant4(__symbols); + // Instr = error => ActionFn(16); + let __sym0 = __pop_Variant8(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action43::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (1, 22) + let __nt = super::__action16::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant12(__nt), __end)); + (1, 17) } pub(crate) fn __reduce65< 'err, @@ -3341,13 +3593,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Value = Literal => ActionFn(44); - let __sym0 = __pop_Variant5(__symbols); + // NewArgument = Scalar => ActionFn(43); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action44::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (1, 22) + let __nt = super::__action43::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant22(__nt), __end)); + (1, 18) } pub(crate) fn __reduce66< 'err, @@ -3362,13 +3614,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Value = Timestamp => ActionFn(45); - let __sym0 = __pop_Variant0(__symbols); + // NewArgument = Stream => ActionFn(44); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action45::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (1, 22) + let __nt = super::__action44::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant22(__nt), __end)); + (1, 18) } pub(crate) fn __reduce67< 'err, @@ -3383,13 +3635,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Value = TTL => ActionFn(46); - let __sym0 = __pop_Variant0(__symbols); + // NewArgument = CanonStream => ActionFn(45); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action46::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (1, 22) + let __nt = super::__action45::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant22(__nt), __end)); + (1, 18) } pub(crate) fn __reduce68< 'err, @@ -3404,13 +3656,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Value = Number => ActionFn(47); - let __sym0 = __pop_Variant20(__symbols); + // Number = I64 => ActionFn(46); + let __sym0 = __pop_Variant5(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action47::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (1, 22) + let __nt = super::__action46::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant23(__nt), __end)); + (1, 19) } pub(crate) fn __reduce69< 'err, @@ -3425,13 +3677,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Value = Boolean => ActionFn(48); - let __sym0 = __pop_Variant1(__symbols); + // Number = F64 => ActionFn(47); + let __sym0 = __pop_Variant4(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action48::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (1, 22) + let __nt = super::__action47::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant23(__nt), __end)); + (1, 19) } pub(crate) fn __reduce70< 'err, @@ -3446,15 +3698,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Value = "[", "]" => ActionFn(49); - assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant0(__symbols); + // PeerId = CallInstrValue => ActionFn(33); + let __sym0 = __pop_Variant16(__symbols); let __start = __sym0.0.clone(); - let __end = __sym1.2.clone(); - let __nt = super::__action49::<>(input, errors, validator, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (2, 22) + let __end = __sym0.2.clone(); + let __nt = super::__action33::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (1, 20) } pub(crate) fn __reduce71< 'err, @@ -3469,13 +3719,13 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Value = Scalar => ActionFn(50); - let __sym0 = __pop_Variant6(__symbols); + // ServiceId = CallInstrValue => ActionFn(34); + let __sym0 = __pop_Variant16(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action50::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (1, 22) + let __nt = super::__action34::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant16(__nt), __end)); + (1, 21) } pub(crate) fn __reduce72< 'err, @@ -3490,12 +3740,12 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Value = ScalarWithLambda => ActionFn(51); - let __sym0 = __pop_Variant7(__symbols); + // StreamArgument = Stream => ActionFn(77); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action51::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + let __nt = super::__action77::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant24(__nt), __end)); (1, 22) } pub(crate) fn __reduce73< @@ -3511,13 +3761,18 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Value = Stream => ActionFn(52); - let __sym0 = __pop_Variant6(__symbols); + // Triplet = PeerId, "(", ServiceId, Function, ")" => ActionFn(18); + assert!(__symbols.len() >= 5); + let __sym4 = __pop_Variant0(__symbols); + let __sym3 = __pop_Variant16(__symbols); + let __sym2 = __pop_Variant16(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant16(__symbols); let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action52::<>(input, errors, validator, __sym0); - __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (1, 22) + let __end = __sym4.2.clone(); + let __nt = super::__action18::<>(input, errors, validator, __sym0, __sym1, __sym2, __sym3, __sym4); + __symbols.push((__start, __Symbol::Variant25(__nt), __end)); + (5, 23) } pub(crate) fn __reduce74< 'err, @@ -3532,13 +3787,309 @@ mod __parse__AIR { _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, ) -> (usize, usize) { - // Value = StreamWithLambda => ActionFn(53); + // Value = InitPeerId => ActionFn(49); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action49::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 24) + } + pub(crate) fn __reduce75< + 'err, + 'input, + 'v, + >( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __lookahead_start: Option<&usize>, + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, + ) -> (usize, usize) + { + // Value = LastError => ActionFn(50); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action50::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 24) + } + pub(crate) fn __reduce76< + 'err, + 'input, + 'v, + >( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __lookahead_start: Option<&usize>, + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, + ) -> (usize, usize) + { + // Value = LastErrorWithLambda => ActionFn(51); + let __sym0 = __pop_Variant6(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action51::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 24) + } + pub(crate) fn __reduce77< + 'err, + 'input, + 'v, + >( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __lookahead_start: Option<&usize>, + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, + ) -> (usize, usize) + { + // Value = Literal => ActionFn(52); let __sym0 = __pop_Variant7(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); + let __nt = super::__action52::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 24) + } + pub(crate) fn __reduce78< + 'err, + 'input, + 'v, + >( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __lookahead_start: Option<&usize>, + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, + ) -> (usize, usize) + { + // Value = Timestamp => ActionFn(53); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); let __nt = super::__action53::<>(input, errors, validator, __sym0); __symbols.push((__start, __Symbol::Variant9(__nt), __end)); - (1, 22) + (1, 24) + } + pub(crate) fn __reduce79< + 'err, + 'input, + 'v, + >( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __lookahead_start: Option<&usize>, + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, + ) -> (usize, usize) + { + // Value = TTL => ActionFn(54); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action54::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 24) + } + pub(crate) fn __reduce80< + 'err, + 'input, + 'v, + >( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __lookahead_start: Option<&usize>, + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, + ) -> (usize, usize) + { + // Value = Number => ActionFn(55); + let __sym0 = __pop_Variant23(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action55::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 24) + } + pub(crate) fn __reduce81< + 'err, + 'input, + 'v, + >( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __lookahead_start: Option<&usize>, + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, + ) -> (usize, usize) + { + // Value = Boolean => ActionFn(56); + let __sym0 = __pop_Variant1(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action56::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 24) + } + pub(crate) fn __reduce82< + 'err, + 'input, + 'v, + >( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __lookahead_start: Option<&usize>, + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, + ) -> (usize, usize) + { + // Value = "[", "]" => ActionFn(57); + 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::__action57::<>(input, errors, validator, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (2, 24) + } + pub(crate) fn __reduce83< + 'err, + 'input, + 'v, + >( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __lookahead_start: Option<&usize>, + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, + ) -> (usize, usize) + { + // Value = Scalar => ActionFn(58); + let __sym0 = __pop_Variant2(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action58::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 24) + } + pub(crate) fn __reduce84< + 'err, + 'input, + 'v, + >( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __lookahead_start: Option<&usize>, + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, + ) -> (usize, usize) + { + // Value = ScalarWithLambda => ActionFn(59); + let __sym0 = __pop_Variant3(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action59::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 24) + } + pub(crate) fn __reduce85< + 'err, + 'input, + 'v, + >( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __lookahead_start: Option<&usize>, + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, + ) -> (usize, usize) + { + // Value = Stream => ActionFn(60); + let __sym0 = __pop_Variant2(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action60::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 24) + } + pub(crate) fn __reduce86< + 'err, + 'input, + 'v, + >( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __lookahead_start: Option<&usize>, + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, + ) -> (usize, usize) + { + // Value = StreamWithLambda => ActionFn(61); + let __sym0 = __pop_Variant3(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action61::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 24) + } + pub(crate) fn __reduce87< + 'err, + 'input, + 'v, + >( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __lookahead_start: Option<&usize>, + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, + ) -> (usize, usize) + { + // Value = CanonStream => ActionFn(62); + let __sym0 = __pop_Variant2(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action62::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 24) + } + pub(crate) fn __reduce88< + 'err, + 'input, + 'v, + >( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __lookahead_start: Option<&usize>, + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: core::marker::PhantomData<(&'err (), &'input (), &'v ())>, + ) -> (usize, usize) + { + // Value = CanonStreamWithLambda => ActionFn(63); + let __sym0 = __pop_Variant3(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action63::<>(input, errors, validator, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 24) } } pub use self::__parse__AIR::AIRParser; @@ -3587,14 +4138,14 @@ fn __action2< (_, _, _): (usize, Token<'input>, usize), (_, triplet, _): (usize, Triplet<'input>, usize), (_, args, _): (usize, Vec>, usize), - (_, output, _): (usize, core::option::Option>, usize), + (_, output, _): (usize, core::option::Option>, usize), (_, _, _): (usize, Token<'input>, usize), (_, right, _): (usize, usize, usize), ) -> Box> { { let args = Rc::new(args); - let output = output.map(CallOutputValue::Variable).unwrap_or(CallOutputValue::None); + let output = output.unwrap_or(CallOutputValue::None); let call = Call::new(triplet, args, output); let span = Span::new(left, right); @@ -3616,19 +4167,20 @@ fn __action3< (_, left, _): (usize, usize, usize), (_, _, _): (usize, Token<'input>, usize), (_, _, _): (usize, Token<'input>, usize), - (_, arg, _): (usize, ApArgument<'input>, usize), - (_, result, _): (usize, Variable<'input>, usize), + (_, peer_pk, _): (usize, CallInstrValue<'input>, usize), + (_, stream, _): (usize, Stream<'input>, usize), + (_, canon_stream, _): (usize, CanonStream<'input>, usize), (_, _, _): (usize, Token<'input>, usize), (_, right, _): (usize, usize, usize), ) -> Box> { { - let apply = Ap::new(arg, result); + let canon = Canon::new(peer_pk, stream, canon_stream); let span = Span::new(left, right); - validator.met_ap(&apply, span); + validator.met_canon(&canon, span); - Box::new(Instruction::Ap(apply)) + Box::new(Instruction::Canon(canon)) } } @@ -3641,14 +4193,23 @@ fn __action4< input: &'input str, errors: &'err mut Vec, ParserError>>, validator: &'v mut VariableValidator<'input>, + (_, left, _): (usize, usize, usize), (_, _, _): (usize, Token<'input>, usize), (_, _, _): (usize, Token<'input>, usize), - (_, l, _): (usize, Box>, usize), - (_, r, _): (usize, Box>, usize), + (_, arg, _): (usize, ApArgument<'input>, usize), + (_, result, _): (usize, ApResult<'input>, usize), (_, _, _): (usize, Token<'input>, usize), + (_, right, _): (usize, usize, usize), ) -> Box> { - Box::new(Instruction::Seq(Seq::new(l, r))) + { + let apply = Ap::new(arg, result); + + let span = Span::new(left, right); + validator.met_ap(&apply, span); + + Box::new(Instruction::Ap(apply)) + } } #[allow(unused_variables)] @@ -3667,7 +4228,7 @@ fn __action5< (_, _, _): (usize, Token<'input>, usize), ) -> Box> { - Box::new(Instruction::Par(Par::new(l, r))) + Box::new(Instruction::Seq(Seq::new(l, r))) } #[allow(unused_variables)] @@ -3675,6 +4236,25 @@ fn __action6< 'err, 'input, 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, _, _): (usize, Token<'input>, usize), + (_, _, _): (usize, Token<'input>, usize), + (_, l, _): (usize, Box>, usize), + (_, r, _): (usize, Box>, usize), + (_, _, _): (usize, Token<'input>, usize), +) -> Box> +{ + Box::new(Instruction::Par(Par::new(l, r))) +} + +#[allow(unused_variables)] +fn __action7< + 'err, + 'input, + 'v, >( input: &'input str, errors: &'err mut Vec, ParserError>>, @@ -3688,7 +4268,7 @@ fn __action6< } #[allow(unused_variables)] -fn __action7< +fn __action8< 'err, 'input, 'v, @@ -3699,7 +4279,7 @@ fn __action7< (_, left, _): (usize, usize, usize), (_, _, _): (usize, Token<'input>, usize), (_, _, _): (usize, Token<'input>, usize), - (_, variable, _): (usize, Variable<'input>, usize), + (_, argument, _): (usize, NewArgument<'input>, usize), (_, instruction, _): (usize, Box>, usize), (_, _, _): (usize, Token<'input>, usize), (_, right, _): (usize, usize, usize), @@ -3707,7 +4287,7 @@ fn __action7< { { let span = Span::new(left, right); - let new = New::new(variable, instruction, span); + let new = New::new(argument, instruction, span); validator.met_new(&new, span); @@ -3716,7 +4296,7 @@ fn __action7< } #[allow(unused_variables)] -fn __action8< +fn __action9< 'err, 'input, 'v, @@ -3736,7 +4316,7 @@ fn __action8< } #[allow(unused_variables)] -fn __action9< +fn __action10< 'err, 'input, 'v, @@ -3766,7 +4346,7 @@ fn __action9< } #[allow(unused_variables)] -fn __action10< +fn __action11< 'err, 'input, 'v, @@ -3797,7 +4377,7 @@ fn __action10< } #[allow(unused_variables)] -fn __action11< +fn __action12< 'err, 'input, 'v, @@ -3824,7 +4404,7 @@ fn __action11< } #[allow(unused_variables)] -fn __action12< +fn __action13< 'err, 'input, 'v, @@ -3843,7 +4423,7 @@ fn __action12< } #[allow(unused_variables)] -fn __action13< +fn __action14< 'err, 'input, 'v, @@ -3871,7 +4451,7 @@ fn __action13< } #[allow(unused_variables)] -fn __action14< +fn __action15< 'err, 'input, 'v, @@ -3899,7 +4479,7 @@ fn __action14< } #[allow(unused_variables)] -fn __action15< +fn __action16< 'err, 'input, 'v, @@ -3914,7 +4494,7 @@ fn __action15< } #[allow(unused_variables)] -fn __action16< +fn __action17< 'err, 'input, 'v, @@ -3931,7 +4511,7 @@ fn __action16< } #[allow(unused_variables)] -fn __action17< +fn __action18< 'err, 'input, 'v, @@ -3953,21 +4533,6 @@ fn __action17< } } -#[allow(unused_variables)] -fn __action18< - 'err, - 'input, - 'v, ->( - input: &'input str, - errors: &'err mut Vec, ParserError>>, - validator: &'v mut VariableValidator<'input>, - (_, __0, _): (usize, Variable<'input>, usize), -) -> Variable<'input> -{ - __0 -} - #[allow(unused_variables)] fn __action19< 'err, @@ -3977,10 +4542,10 @@ fn __action19< input: &'input str, errors: &'err mut Vec, ParserError>>, validator: &'v mut VariableValidator<'input>, - (_, __0, _): (usize, Variable<'input>, usize), -) -> Variable<'input> + (_, scalar, _): (usize, (&'input str, usize), usize), +) -> ApResult<'input> { - __0 + ApResult::scalar(scalar.0, scalar.1) } #[allow(unused_variables)] @@ -3992,10 +4557,10 @@ fn __action20< input: &'input str, errors: &'err mut Vec, ParserError>>, validator: &'v mut VariableValidator<'input>, - (_, scalar, _): (usize, (&'input str, usize), usize), -) -> Variable<'input> + (_, stream, _): (usize, (&'input str, usize), usize), +) -> ApResult<'input> { - Variable::scalar(scalar.0, scalar.1) + ApResult::stream(stream.0, stream.1) } #[allow(unused_variables)] @@ -4007,10 +4572,10 @@ fn __action21< input: &'input str, errors: &'err mut Vec, ParserError>>, validator: &'v mut VariableValidator<'input>, - (_, stream, _): (usize, (&'input str, usize), usize), -) -> Variable<'input> + (_, scalar, _): (usize, (&'input str, usize), usize), +) -> CallOutputValue<'input> { - Variable::stream(stream.0, stream.1) + CallOutputValue::scalar(scalar.0, scalar.1) } #[allow(unused_variables)] @@ -4018,6 +4583,21 @@ fn __action22< 'err, 'input, 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, stream, _): (usize, (&'input str, usize), usize), +) -> CallOutputValue<'input> +{ + CallOutputValue::stream(stream.0, stream.1) +} + +#[allow(unused_variables)] +fn __action23< + 'err, + 'input, + 'v, >( input: &'input str, errors: &'err mut Vec, ParserError>>, @@ -4029,7 +4609,7 @@ fn __action22< } #[allow(unused_variables)] -fn __action23< +fn __action24< 'err, 'input, 'v, @@ -4044,7 +4624,7 @@ fn __action23< } #[allow(unused_variables)] -fn __action24< +fn __action25< 'err, 'input, 'v, @@ -4063,7 +4643,25 @@ fn __action24< } #[allow(unused_variables)] -fn __action25< +fn __action26< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, canon_stream, _): (usize, (&'input str, LambdaAST<'input>, usize), usize), +) -> Fail<'input> +{ + Fail::CanonStream { + name: canon_stream.0, + lambda: canon_stream.1, + } +} + +#[allow(unused_variables)] +fn __action27< 'err, 'input, 'v, @@ -4082,7 +4680,7 @@ fn __action25< } #[allow(unused_variables)] -fn __action26< +fn __action28< 'err, 'input, 'v, @@ -4097,7 +4695,7 @@ fn __action26< } #[allow(unused_variables)] -fn __action27< +fn __action29< 'err, 'input, 'v, @@ -4112,7 +4710,22 @@ fn __action27< } #[allow(unused_variables)] -fn __action28< +fn __action30< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, canon_stream, _): (usize, (&'input str, usize), usize), +) -> FoldScalarIterable<'input> +{ + FoldScalarIterable::CanonStream(CanonStream::new(canon_stream.0, canon_stream.1)) +} + +#[allow(unused_variables)] +fn __action31< 'err, 'input, 'v, @@ -4127,56 +4740,56 @@ fn __action28< FoldScalarIterable::EmptyArray } -#[allow(unused_variables)] -fn __action29< - 'err, - 'input, - 'v, ->( - input: &'input str, - errors: &'err mut Vec, ParserError>>, - validator: &'v mut VariableValidator<'input>, - (_, __0, _): (usize, CallInstrValue<'input>, usize), -) -> CallInstrValue<'input> -{ - __0 -} - -#[allow(unused_variables)] -fn __action30< - 'err, - 'input, - 'v, ->( - input: &'input str, - errors: &'err mut Vec, ParserError>>, - validator: &'v mut VariableValidator<'input>, - (_, __0, _): (usize, CallInstrValue<'input>, usize), -) -> CallInstrValue<'input> -{ - __0 -} - -#[allow(unused_variables)] -fn __action31< - 'err, - 'input, - 'v, ->( - input: &'input str, - errors: &'err mut Vec, ParserError>>, - validator: &'v mut VariableValidator<'input>, - (_, __0, _): (usize, CallInstrValue<'input>, usize), -) -> CallInstrValue<'input> -{ - __0 -} - #[allow(unused_variables)] fn __action32< 'err, 'input, 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, __0, _): (usize, CallInstrValue<'input>, usize), +) -> CallInstrValue<'input> +{ + __0 +} + +#[allow(unused_variables)] +fn __action33< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, __0, _): (usize, CallInstrValue<'input>, usize), +) -> CallInstrValue<'input> +{ + __0 +} + +#[allow(unused_variables)] +fn __action34< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, __0, _): (usize, CallInstrValue<'input>, usize), +) -> CallInstrValue<'input> +{ + __0 +} + +#[allow(unused_variables)] +fn __action35< + 'err, + 'input, + 'v, >( input: &'input str, errors: &'err mut Vec, ParserError>>, @@ -4188,7 +4801,7 @@ fn __action32< } #[allow(unused_variables)] -fn __action33< +fn __action36< 'err, 'input, 'v, @@ -4203,7 +4816,7 @@ fn __action33< } #[allow(unused_variables)] -fn __action34< +fn __action37< 'err, 'input, 'v, @@ -4218,7 +4831,7 @@ fn __action34< } #[allow(unused_variables)] -fn __action35< +fn __action38< 'err, 'input, 'v, @@ -4233,7 +4846,7 @@ fn __action35< } #[allow(unused_variables)] -fn __action36< +fn __action39< 'err, 'input, 'v, @@ -4248,7 +4861,7 @@ fn __action36< } #[allow(unused_variables)] -fn __action37< +fn __action40< 'err, 'input, 'v, @@ -4263,7 +4876,82 @@ fn __action37< } #[allow(unused_variables)] -fn __action38< +fn __action41< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, canon_stream, _): (usize, (&'input str, usize), usize), +) -> CallInstrValue<'input> +{ + CallInstrValue::Variable(VariableWithLambda::canon_stream(canon_stream.0, canon_stream.1)) +} + +#[allow(unused_variables)] +fn __action42< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, canon_stream, _): (usize, (&'input str, LambdaAST<'input>, usize), usize), +) -> CallInstrValue<'input> +{ + CallInstrValue::Variable(VariableWithLambda::canon_stream_wl(canon_stream.0, canon_stream.1, canon_stream.2)) +} + +#[allow(unused_variables)] +fn __action43< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, scalar, _): (usize, (&'input str, usize), usize), +) -> NewArgument<'input> +{ + NewArgument::Scalar(Scalar::new(scalar.0, scalar.1)) +} + +#[allow(unused_variables)] +fn __action44< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, stream, _): (usize, (&'input str, usize), usize), +) -> NewArgument<'input> +{ + NewArgument::Stream(Stream::new(stream.0, stream.1)) +} + +#[allow(unused_variables)] +fn __action45< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, canon_stream, _): (usize, (&'input str, usize), usize), +) -> NewArgument<'input> +{ + NewArgument::CanonStream(CanonStream::new(canon_stream.0, canon_stream.1)) +} + +#[allow(unused_variables)] +fn __action46< 'err, 'input, 'v, @@ -4278,7 +4966,7 @@ fn __action38< } #[allow(unused_variables)] -fn __action39< +fn __action47< 'err, 'input, 'v, @@ -4293,7 +4981,7 @@ fn __action39< } #[allow(unused_variables)] -fn __action40< +fn __action48< 'err, 'input, 'v, @@ -4308,7 +4996,7 @@ fn __action40< } #[allow(unused_variables)] -fn __action41< +fn __action49< 'err, 'input, 'v, @@ -4323,7 +5011,7 @@ fn __action41< } #[allow(unused_variables)] -fn __action42< +fn __action50< 'err, 'input, 'v, @@ -4338,7 +5026,7 @@ fn __action42< } #[allow(unused_variables)] -fn __action43< +fn __action51< 'err, 'input, 'v, @@ -4353,7 +5041,7 @@ fn __action43< } #[allow(unused_variables)] -fn __action44< +fn __action52< 'err, 'input, 'v, @@ -4368,7 +5056,7 @@ fn __action44< } #[allow(unused_variables)] -fn __action45< +fn __action53< 'err, 'input, 'v, @@ -4383,7 +5071,7 @@ fn __action45< } #[allow(unused_variables)] -fn __action46< +fn __action54< 'err, 'input, 'v, @@ -4398,7 +5086,7 @@ fn __action46< } #[allow(unused_variables)] -fn __action47< +fn __action55< 'err, 'input, 'v, @@ -4413,7 +5101,7 @@ fn __action47< } #[allow(unused_variables)] -fn __action48< +fn __action56< 'err, 'input, 'v, @@ -4428,7 +5116,7 @@ fn __action48< } #[allow(unused_variables)] -fn __action49< +fn __action57< 'err, 'input, 'v, @@ -4444,7 +5132,7 @@ fn __action49< } #[allow(unused_variables)] -fn __action50< +fn __action58< 'err, 'input, 'v, @@ -4459,7 +5147,7 @@ fn __action50< } #[allow(unused_variables)] -fn __action51< +fn __action59< 'err, 'input, 'v, @@ -4474,7 +5162,7 @@ fn __action51< } #[allow(unused_variables)] -fn __action52< +fn __action60< 'err, 'input, 'v, @@ -4489,7 +5177,7 @@ fn __action52< } #[allow(unused_variables)] -fn __action53< +fn __action61< 'err, 'input, 'v, @@ -4504,7 +5192,37 @@ fn __action53< } #[allow(unused_variables)] -fn __action54< +fn __action62< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, canon_stream, _): (usize, (&'input str, usize), usize), +) -> Value<'input> +{ + Value::Variable(VariableWithLambda::canon_stream(canon_stream.0, canon_stream.1)) +} + +#[allow(unused_variables)] +fn __action63< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, canon_stream, _): (usize, (&'input str, LambdaAST<'input>, usize), usize), +) -> Value<'input> +{ + Value::Variable(VariableWithLambda::canon_stream_wl(canon_stream.0, canon_stream.1, canon_stream.2)) +} + +#[allow(unused_variables)] +fn __action64< 'err, 'input, 'v, @@ -4519,7 +5237,7 @@ fn __action54< } #[allow(unused_variables)] -fn __action55< +fn __action65< 'err, 'input, 'v, @@ -4534,7 +5252,7 @@ fn __action55< } #[allow(unused_variables)] -fn __action56< +fn __action66< 'err, 'input, 'v, @@ -4549,7 +5267,7 @@ fn __action56< } #[allow(unused_variables)] -fn __action57< +fn __action67< 'err, 'input, 'v, @@ -4564,7 +5282,7 @@ fn __action57< } #[allow(unused_variables)] -fn __action58< +fn __action68< 'err, 'input, 'v, @@ -4579,7 +5297,7 @@ fn __action58< } #[allow(unused_variables)] -fn __action59< +fn __action69< 'err, 'input, 'v, @@ -4594,7 +5312,7 @@ fn __action59< } #[allow(unused_variables)] -fn __action60< +fn __action70< 'err, 'input, 'v, @@ -4609,7 +5327,7 @@ fn __action60< } #[allow(unused_variables)] -fn __action61< +fn __action71< 'err, 'input, 'v, @@ -4624,7 +5342,7 @@ fn __action61< } #[allow(unused_variables)] -fn __action62< +fn __action72< 'err, 'input, 'v, @@ -4640,7 +5358,7 @@ fn __action62< } #[allow(unused_variables)] -fn __action63< +fn __action73< 'err, 'input, 'v, @@ -4655,7 +5373,7 @@ fn __action63< } #[allow(unused_variables)] -fn __action64< +fn __action74< 'err, 'input, 'v, @@ -4670,7 +5388,67 @@ fn __action64< } #[allow(unused_variables)] -fn __action65< +fn __action75< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, canon_stream, _): (usize, (&'input str, usize), usize), +) -> ApArgument<'input> +{ + ApArgument::CanonStream(CanonStreamWithLambda::new(canon_stream.0, None, canon_stream.1)) +} + +#[allow(unused_variables)] +fn __action76< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, canon_stream, _): (usize, (&'input str, LambdaAST<'input>, usize), usize), +) -> ApArgument<'input> +{ + ApArgument::CanonStream(CanonStreamWithLambda::new(canon_stream.0, Some(canon_stream.1), canon_stream.2)) +} + +#[allow(unused_variables)] +fn __action77< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, stream, _): (usize, (&'input str, usize), usize), +) -> Stream<'input> +{ + Stream::new(stream.0, stream.1) +} + +#[allow(unused_variables)] +fn __action78< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + (_, canon_stream, _): (usize, (&'input str, usize), usize), +) -> CanonStream<'input> +{ + CanonStream::new(canon_stream.0, canon_stream.1) +} + +#[allow(unused_variables)] +fn __action79< 'err, 'input, 'v, @@ -4686,7 +5464,7 @@ fn __action65< } #[allow(unused_variables)] -fn __action66< +fn __action80< 'err, 'input, 'v, @@ -4701,7 +5479,7 @@ fn __action66< } #[allow(unused_variables)] -fn __action67< +fn __action81< 'err, 'input, 'v, @@ -4716,7 +5494,7 @@ fn __action67< } #[allow(unused_variables)] -fn __action68< +fn __action82< 'err, 'input, 'v, @@ -4732,7 +5510,7 @@ fn __action68< } #[allow(unused_variables)] -fn __action69< +fn __action83< 'err, 'input, 'v, @@ -4740,14 +5518,14 @@ fn __action69< input: &'input str, errors: &'err mut Vec, ParserError>>, validator: &'v mut VariableValidator<'input>, - (_, __0, _): (usize, Variable<'input>, usize), -) -> core::option::Option> + (_, __0, _): (usize, CallOutputValue<'input>, usize), +) -> core::option::Option> { Some(__0) } #[allow(unused_variables)] -fn __action70< +fn __action84< 'err, 'input, 'v, @@ -4757,13 +5535,13 @@ fn __action70< validator: &'v mut VariableValidator<'input>, __lookbehind: &usize, __lookahead: &usize, -) -> core::option::Option> +) -> core::option::Option> { None } #[allow(unused_variables)] -fn __action71< +fn __action85< 'err, 'input, 'v, @@ -4779,7 +5557,7 @@ fn __action71< } #[allow(unused_variables)] -fn __action72< +fn __action86< 'err, 'input, 'v, @@ -4794,7 +5572,7 @@ fn __action72< } #[allow(unused_variables)] -fn __action73< +fn __action87< 'err, 'input, 'v, @@ -4810,7 +5588,7 @@ fn __action73< } #[allow(unused_variables)] -fn __action74< +fn __action88< 'err, 'input, 'v, @@ -4823,14 +5601,14 @@ fn __action74< { let __start0 = __0.0.clone(); let __end0 = __0.2.clone(); - let __temp0 = __action67( + let __temp0 = __action81( input, errors, validator, __0, ); let __temp0 = (__start0, __temp0, __end0); - __action72( + __action86( input, errors, validator, @@ -4839,7 +5617,7 @@ fn __action74< } #[allow(unused_variables)] -fn __action75< +fn __action89< 'err, 'input, 'v, @@ -4853,14 +5631,14 @@ fn __action75< { let __start0 = __1.0.clone(); let __end0 = __1.2.clone(); - let __temp0 = __action67( + let __temp0 = __action81( input, errors, validator, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action73( + __action87( input, errors, validator, @@ -4870,7 +5648,7 @@ fn __action75< } #[allow(unused_variables)] -fn __action76< +fn __action90< 'err, 'input, 'v, @@ -4884,7 +5662,7 @@ fn __action76< { let __start0 = __0.2.clone(); let __end0 = __1.0.clone(); - let __temp0 = __action65( + let __temp0 = __action79( input, errors, validator, @@ -4892,7 +5670,7 @@ fn __action76< &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action16( + __action17( input, errors, validator, @@ -4903,7 +5681,7 @@ fn __action76< } #[allow(unused_variables)] -fn __action77< +fn __action91< 'err, 'input, 'v, @@ -4918,14 +5696,14 @@ fn __action77< { let __start0 = __1.0.clone(); let __end0 = __1.2.clone(); - let __temp0 = __action66( + let __temp0 = __action80( input, errors, validator, __1, ); let __temp0 = (__start0, __temp0, __end0); - __action16( + __action17( input, errors, validator, @@ -4936,7 +5714,7 @@ fn __action77< } #[allow(unused_variables)] -fn __action78< +fn __action92< 'err, 'input, 'v, @@ -4950,7 +5728,7 @@ fn __action78< { let __start0 = __0.0.clone(); let __end0 = __0.0.clone(); - let __temp0 = __action71( + let __temp0 = __action85( input, errors, validator, @@ -4958,7 +5736,7 @@ fn __action78< &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action25( + __action27( input, errors, validator, @@ -4969,7 +5747,7 @@ fn __action78< } #[allow(unused_variables)] -fn __action79< +fn __action93< 'err, 'input, 'v, @@ -4981,14 +5759,14 @@ fn __action79< __1: (usize, Token<'input>, usize), __2: (usize, Triplet<'input>, usize), __3: (usize, Vec>, usize), - __4: (usize, core::option::Option>, usize), + __4: (usize, core::option::Option>, usize), __5: (usize, Token<'input>, usize), __6: (usize, usize, usize), ) -> Box> { let __start0 = __0.0.clone(); let __end0 = __0.0.clone(); - let __temp0 = __action71( + let __temp0 = __action85( input, errors, validator, @@ -5012,7 +5790,7 @@ fn __action79< } #[allow(unused_variables)] -fn __action80< +fn __action94< 'err, 'input, 'v, @@ -5022,15 +5800,16 @@ fn __action80< validator: &'v mut VariableValidator<'input>, __0: (usize, Token<'input>, usize), __1: (usize, Token<'input>, usize), - __2: (usize, ApArgument<'input>, usize), - __3: (usize, Variable<'input>, usize), - __4: (usize, Token<'input>, usize), - __5: (usize, usize, usize), + __2: (usize, CallInstrValue<'input>, usize), + __3: (usize, Stream<'input>, usize), + __4: (usize, CanonStream<'input>, usize), + __5: (usize, Token<'input>, usize), + __6: (usize, usize, usize), ) -> Box> { let __start0 = __0.0.clone(); let __end0 = __0.0.clone(); - let __temp0 = __action71( + let __temp0 = __action85( input, errors, validator, @@ -5049,11 +5828,12 @@ fn __action80< __3, __4, __5, + __6, ) } #[allow(unused_variables)] -fn __action81< +fn __action95< 'err, 'input, 'v, @@ -5063,15 +5843,15 @@ fn __action81< validator: &'v mut VariableValidator<'input>, __0: (usize, Token<'input>, usize), __1: (usize, Token<'input>, usize), - __2: (usize, Variable<'input>, usize), - __3: (usize, Box>, usize), + __2: (usize, ApArgument<'input>, usize), + __3: (usize, ApResult<'input>, usize), __4: (usize, Token<'input>, usize), __5: (usize, usize, usize), ) -> Box> { let __start0 = __0.0.clone(); let __end0 = __0.0.clone(); - let __temp0 = __action71( + let __temp0 = __action85( input, errors, validator, @@ -5079,7 +5859,7 @@ fn __action81< &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action7( + __action4( input, errors, validator, @@ -5094,7 +5874,48 @@ fn __action81< } #[allow(unused_variables)] -fn __action82< +fn __action96< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __0: (usize, Token<'input>, usize), + __1: (usize, Token<'input>, usize), + __2: (usize, NewArgument<'input>, usize), + __3: (usize, Box>, usize), + __4: (usize, Token<'input>, usize), + __5: (usize, usize, usize), +) -> Box> +{ + let __start0 = __0.0.clone(); + let __end0 = __0.0.clone(); + let __temp0 = __action85( + input, + errors, + validator, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action8( + input, + errors, + validator, + __temp0, + __0, + __1, + __2, + __3, + __4, + __5, + ) +} + +#[allow(unused_variables)] +fn __action97< 'err, 'input, 'v, @@ -5113,50 +5934,7 @@ fn __action82< { let __start0 = __0.0.clone(); let __end0 = __0.0.clone(); - let __temp0 = __action71( - 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 __action83< - 'err, - 'input, - 'v, ->( - input: &'input str, - errors: &'err mut Vec, ParserError>>, - validator: &'v mut VariableValidator<'input>, - __0: (usize, Token<'input>, usize), - __1: (usize, Token<'input>, usize), - __2: (usize, (&'input str, usize), usize), - __3: (usize, (&'input str, usize), usize), - __4: (usize, Box>, usize), - __5: (usize, Token<'input>, usize), - __6: (usize, usize, usize), -) -> Box> -{ - let __start0 = __0.0.clone(); - let __end0 = __0.0.clone(); - let __temp0 = __action71( + let __temp0 = __action85( input, errors, validator, @@ -5180,7 +5958,7 @@ fn __action83< } #[allow(unused_variables)] -fn __action84< +fn __action98< 'err, 'input, 'v, @@ -5191,13 +5969,15 @@ fn __action84< __0: (usize, Token<'input>, usize), __1: (usize, Token<'input>, usize), __2: (usize, (&'input str, usize), usize), - __3: (usize, Token<'input>, usize), - __4: (usize, usize, usize), + __3: (usize, (&'input str, usize), usize), + __4: (usize, Box>, usize), + __5: (usize, Token<'input>, usize), + __6: (usize, usize, usize), ) -> Box> { let __start0 = __0.0.clone(); let __end0 = __0.0.clone(); - let __temp0 = __action71( + let __temp0 = __action85( input, errors, validator, @@ -5215,11 +5995,13 @@ fn __action84< __2, __3, __4, + __5, + __6, ) } #[allow(unused_variables)] -fn __action85< +fn __action99< 'err, 'input, 'v, @@ -5229,16 +6011,14 @@ fn __action85< validator: &'v mut VariableValidator<'input>, __0: (usize, Token<'input>, usize), __1: (usize, Token<'input>, usize), - __2: (usize, Value<'input>, usize), - __3: (usize, Value<'input>, usize), - __4: (usize, Box>, usize), - __5: (usize, Token<'input>, usize), - __6: (usize, usize, usize), + __2: (usize, (&'input str, usize), usize), + __3: (usize, Token<'input>, usize), + __4: (usize, usize, usize), ) -> Box> { let __start0 = __0.0.clone(); let __end0 = __0.0.clone(); - let __temp0 = __action71( + let __temp0 = __action85( input, errors, validator, @@ -5246,7 +6026,7 @@ fn __action85< &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action13( + __action12( input, errors, validator, @@ -5256,13 +6036,11 @@ fn __action85< __2, __3, __4, - __5, - __6, ) } #[allow(unused_variables)] -fn __action86< +fn __action100< 'err, 'input, 'v, @@ -5281,7 +6059,7 @@ fn __action86< { let __start0 = __0.0.clone(); let __end0 = __0.0.clone(); - let __temp0 = __action71( + let __temp0 = __action85( input, errors, validator, @@ -5305,7 +6083,50 @@ fn __action86< } #[allow(unused_variables)] -fn __action87< +fn __action101< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __0: (usize, Token<'input>, usize), + __1: (usize, Token<'input>, usize), + __2: (usize, Value<'input>, usize), + __3: (usize, Value<'input>, usize), + __4: (usize, Box>, usize), + __5: (usize, Token<'input>, usize), + __6: (usize, usize, usize), +) -> Box> +{ + let __start0 = __0.0.clone(); + let __end0 = __0.0.clone(); + let __temp0 = __action85( + input, + errors, + validator, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action15( + input, + errors, + validator, + __temp0, + __0, + __1, + __2, + __3, + __4, + __5, + __6, + ) +} + +#[allow(unused_variables)] +fn __action102< 'err, 'input, 'v, @@ -5318,7 +6139,7 @@ fn __action87< { let __start0 = __0.2.clone(); let __end0 = __0.2.clone(); - let __temp0 = __action68( + let __temp0 = __action82( input, errors, validator, @@ -5326,7 +6147,7 @@ fn __action87< &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action78( + __action92( input, errors, validator, @@ -5336,7 +6157,7 @@ fn __action87< } #[allow(unused_variables)] -fn __action88< +fn __action103< 'err, 'input, 'v, @@ -5348,13 +6169,13 @@ fn __action88< __1: (usize, Token<'input>, usize), __2: (usize, Triplet<'input>, usize), __3: (usize, Vec>, usize), - __4: (usize, core::option::Option>, usize), + __4: (usize, core::option::Option>, usize), __5: (usize, Token<'input>, usize), ) -> Box> { let __start0 = __5.2.clone(); let __end0 = __5.2.clone(); - let __temp0 = __action68( + let __temp0 = __action82( input, errors, validator, @@ -5362,7 +6183,7 @@ fn __action88< &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action79( + __action93( input, errors, validator, @@ -5377,7 +6198,48 @@ fn __action88< } #[allow(unused_variables)] -fn __action89< +fn __action104< + 'err, + 'input, + 'v, +>( + input: &'input str, + errors: &'err mut Vec, ParserError>>, + validator: &'v mut VariableValidator<'input>, + __0: (usize, Token<'input>, usize), + __1: (usize, Token<'input>, usize), + __2: (usize, CallInstrValue<'input>, usize), + __3: (usize, Stream<'input>, usize), + __4: (usize, CanonStream<'input>, usize), + __5: (usize, Token<'input>, usize), +) -> Box> +{ + let __start0 = __5.2.clone(); + let __end0 = __5.2.clone(); + let __temp0 = __action82( + input, + errors, + validator, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action94( + input, + errors, + validator, + __0, + __1, + __2, + __3, + __4, + __5, + __temp0, + ) +} + +#[allow(unused_variables)] +fn __action105< 'err, 'input, 'v, @@ -5388,13 +6250,13 @@ fn __action89< __0: (usize, Token<'input>, usize), __1: (usize, Token<'input>, usize), __2: (usize, ApArgument<'input>, usize), - __3: (usize, Variable<'input>, usize), + __3: (usize, ApResult<'input>, usize), __4: (usize, Token<'input>, usize), ) -> Box> { let __start0 = __4.2.clone(); let __end0 = __4.2.clone(); - let __temp0 = __action68( + let __temp0 = __action82( input, errors, validator, @@ -5402,7 +6264,7 @@ fn __action89< &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action80( + __action95( input, errors, validator, @@ -5416,7 +6278,7 @@ fn __action89< } #[allow(unused_variables)] -fn __action90< +fn __action106< 'err, 'input, 'v, @@ -5426,14 +6288,14 @@ fn __action90< validator: &'v mut VariableValidator<'input>, __0: (usize, Token<'input>, usize), __1: (usize, Token<'input>, usize), - __2: (usize, Variable<'input>, usize), + __2: (usize, NewArgument<'input>, usize), __3: (usize, Box>, usize), __4: (usize, Token<'input>, usize), ) -> Box> { let __start0 = __4.2.clone(); let __end0 = __4.2.clone(); - let __temp0 = __action68( + let __temp0 = __action82( input, errors, validator, @@ -5441,7 +6303,7 @@ fn __action90< &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action81( + __action96( input, errors, validator, @@ -5455,7 +6317,7 @@ fn __action90< } #[allow(unused_variables)] -fn __action91< +fn __action107< 'err, 'input, 'v, @@ -5473,7 +6335,7 @@ fn __action91< { let __start0 = __5.2.clone(); let __end0 = __5.2.clone(); - let __temp0 = __action68( + let __temp0 = __action82( input, errors, validator, @@ -5481,7 +6343,7 @@ fn __action91< &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action82( + __action97( input, errors, validator, @@ -5496,7 +6358,7 @@ fn __action91< } #[allow(unused_variables)] -fn __action92< +fn __action108< 'err, 'input, 'v, @@ -5514,7 +6376,7 @@ fn __action92< { let __start0 = __5.2.clone(); let __end0 = __5.2.clone(); - let __temp0 = __action68( + let __temp0 = __action82( input, errors, validator, @@ -5522,7 +6384,7 @@ fn __action92< &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action83( + __action98( input, errors, validator, @@ -5537,7 +6399,7 @@ fn __action92< } #[allow(unused_variables)] -fn __action93< +fn __action109< 'err, 'input, 'v, @@ -5553,7 +6415,7 @@ fn __action93< { let __start0 = __3.2.clone(); let __end0 = __3.2.clone(); - let __temp0 = __action68( + let __temp0 = __action82( input, errors, validator, @@ -5561,7 +6423,7 @@ fn __action93< &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action84( + __action99( input, errors, validator, @@ -5574,7 +6436,7 @@ fn __action93< } #[allow(unused_variables)] -fn __action94< +fn __action110< 'err, 'input, 'v, @@ -5592,7 +6454,7 @@ fn __action94< { let __start0 = __5.2.clone(); let __end0 = __5.2.clone(); - let __temp0 = __action68( + let __temp0 = __action82( input, errors, validator, @@ -5600,7 +6462,7 @@ fn __action94< &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action85( + __action100( input, errors, validator, @@ -5615,7 +6477,7 @@ fn __action94< } #[allow(unused_variables)] -fn __action95< +fn __action111< 'err, 'input, 'v, @@ -5633,7 +6495,7 @@ fn __action95< { let __start0 = __5.2.clone(); let __end0 = __5.2.clone(); - let __temp0 = __action68( + let __temp0 = __action82( input, errors, validator, @@ -5641,7 +6503,7 @@ fn __action95< &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action86( + __action101( input, errors, validator, @@ -5656,7 +6518,7 @@ fn __action95< } #[allow(unused_variables)] -fn __action96< +fn __action112< 'err, 'input, 'v, @@ -5668,20 +6530,20 @@ fn __action96< __1: (usize, Token<'input>, usize), __2: (usize, Triplet<'input>, usize), __3: (usize, Vec>, usize), - __4: (usize, Variable<'input>, usize), + __4: (usize, CallOutputValue<'input>, usize), __5: (usize, Token<'input>, usize), ) -> Box> { let __start0 = __4.0.clone(); let __end0 = __4.2.clone(); - let __temp0 = __action69( + let __temp0 = __action83( input, errors, validator, __4, ); let __temp0 = (__start0, __temp0, __end0); - __action88( + __action103( input, errors, validator, @@ -5695,7 +6557,7 @@ fn __action96< } #[allow(unused_variables)] -fn __action97< +fn __action113< 'err, 'input, 'v, @@ -5712,7 +6574,7 @@ fn __action97< { let __start0 = __3.2.clone(); let __end0 = __4.0.clone(); - let __temp0 = __action70( + let __temp0 = __action84( input, errors, validator, @@ -5720,7 +6582,7 @@ fn __action97< &__end0, ); let __temp0 = (__start0, __temp0, __end0); - __action88( + __action103( input, errors, validator, diff --git a/crates/air-lib/air-parser/src/parser/lexer/air_lexer.rs b/crates/air-lib/air-parser/src/parser/lexer/air_lexer.rs index 46a162c2..44e80e23 100644 --- a/crates/air-lib/air-parser/src/parser/lexer/air_lexer.rs +++ b/crates/air-lib/air-parser/src/parser/lexer/air_lexer.rs @@ -176,6 +176,7 @@ fn string_to_token(input: &str, start_pos: usize) -> LexerResult { "" => Err(LexerError::empty_string(start_pos..start_pos)), CALL_INSTR => Ok(Token::Call), + CANON_INSTR => Ok(Token::Canon), AP_INSTR => Ok(Token::Ap), SEQ_INSTR => Ok(Token::Seq), PAR_INSTR => Ok(Token::Par), @@ -226,6 +227,7 @@ fn parse_last_error(input: &str, start_pos: usize) -> LexerResult> { } const CALL_INSTR: &str = "call"; +const CANON_INSTR: &str = "canon"; const AP_INSTR: &str = "ap"; const SEQ_INSTR: &str = "seq"; const PAR_INSTR: &str = "par"; diff --git a/crates/air-lib/air-parser/src/parser/lexer/call_variable_parser.rs b/crates/air-lib/air-parser/src/parser/lexer/call_variable_parser.rs index 63d5cf46..112d38fb 100644 --- a/crates/air-lib/air-parser/src/parser/lexer/call_variable_parser.rs +++ b/crates/air-lib/air-parser/src/parser/lexer/call_variable_parser.rs @@ -22,8 +22,6 @@ use crate::LambdaAST; use std::iter::Peekable; use std::str::CharIndices; -const STREAM_START_TAG: char = '$'; - pub(super) fn try_parse_call_variable( string_to_parse: &str, start_pos: usize, @@ -31,14 +29,21 @@ pub(super) fn try_parse_call_variable( CallVariableParser::try_parse(string_to_parse, start_pos) } +#[derive(Debug)] +enum MetTag { + None, + Stream, + CanonStream, +} + #[derive(Debug)] 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) met_tag: MetTag, pub(self) is_first_char: bool, - pub(self) is_first_stream_tag: bool, pub(self) current_char: char, pub(self) current_pos: usize, } @@ -64,7 +69,7 @@ impl<'input> CallVariableParser<'input> { digit_met: false, flattening_met: false, is_first_char: true, - is_first_stream_tag: false, + met_tag: MetTag::None, current_char, current_pos, }; @@ -180,13 +185,14 @@ impl<'input> CallVariableParser<'input> { } fn try_parse_as_stream_start(&mut self) -> LexerResult { - if self.current_pos() == 0 && self.current_char() == STREAM_START_TAG { + let stream_tag = MetTag::from_tag(self.current_char()); + if self.current_pos() == 0 && stream_tag.is_tag() { if self.string_to_parse.len() == 1 { let error_pos = self.pos_in_string_to_parse(); return Err(LexerError::empty_stream_name(error_pos..error_pos)); } - self.state.is_first_stream_tag = true; + self.state.met_tag = stream_tag; return Ok(true); } @@ -271,32 +277,39 @@ impl<'input> CallVariableParser<'input> { } fn to_variable_token<'v>(&self, name: &'v str) -> Token<'v> { - if self.state.is_first_stream_tag { - Token::Stream { + match self.state.met_tag { + MetTag::None => Token::Scalar { name, position: self.start_pos, - } - } else { - Token::Scalar { + }, + MetTag::Stream => Token::Stream { name, position: self.start_pos, - } + }, + MetTag::CanonStream => Token::CanonStream { + name, + position: self.start_pos, + }, } } fn to_variable_token_with_lambda<'v>(&self, name: &'v str, lambda: LambdaAST<'v>) -> Token<'v> { - if self.state.is_first_stream_tag { - Token::StreamWithLambda { + match self.state.met_tag { + MetTag::None => Token::ScalarWithLambda { name, lambda, position: self.start_pos, - } - } else { - Token::ScalarWithLambda { + }, + MetTag::Stream => Token::StreamWithLambda { name, lambda, position: self.start_pos, - } + }, + MetTag::CanonStream => Token::CanonStreamWithLambda { + name, + lambda, + position: self.start_pos, + }, } } @@ -356,3 +369,17 @@ impl<'input> CallVariableParser<'input> { } } } + +impl MetTag { + fn from_tag(tag: char) -> Self { + match tag { + '$' => Self::Stream, + '#' => Self::CanonStream, + _ => Self::None, + } + } + + fn is_tag(&self) -> bool { + !matches!(self, Self::None) + } +} diff --git a/crates/air-lib/air-parser/src/parser/lexer/token.rs b/crates/air-lib/air-parser/src/parser/lexer/token.rs index ee8e531c..9a7ab217 100644 --- a/crates/air-lib/air-parser/src/parser/lexer/token.rs +++ b/crates/air-lib/air-parser/src/parser/lexer/token.rs @@ -45,6 +45,15 @@ pub enum Token<'input> { lambda: LambdaAST<'input>, position: usize, }, + CanonStream { + name: &'input str, + position: usize, + }, + CanonStreamWithLambda { + name: &'input str, + lambda: LambdaAST<'input>, + position: usize, + }, StringLiteral(&'input str), I64(i64), @@ -58,6 +67,7 @@ pub enum Token<'input> { TTL, Call, + Canon, Ap, Seq, Par, diff --git a/crates/air-lib/air-parser/src/parser/tests/ap.rs b/crates/air-lib/air-parser/src/parser/tests/ap.rs index cf2f7701..639938b8 100644 --- a/crates/air-lib/air-parser/src/parser/tests/ap.rs +++ b/crates/air-lib/air-parser/src/parser/tests/ap.rs @@ -19,6 +19,8 @@ use super::parse; use crate::ast::*; use air_lambda_ast::{LambdaAST, ValueAccessor}; +use fstrings::f; +use fstrings::format_args_f; #[test] fn ap_with_literal() { @@ -29,7 +31,7 @@ fn ap_with_literal() { let actual = parse(source_code); let expected = ap( ApArgument::Literal("some_string"), - Variable::stream("$stream", 27), + ApResult::Stream(Stream::new("$stream", 27)), ); assert_eq!(actual, expected); @@ -44,7 +46,7 @@ fn ap_with_number() { let actual = parse(source_code); let expected = ap( ApArgument::Number(Number::Int(-100)), - Variable::stream("$stream", 18), + ApResult::Stream(Stream::new("$stream", 18)), ); assert_eq!(actual, expected); @@ -57,7 +59,10 @@ fn ap_with_bool() { "#; let actual = parse(source_code); - let expected = ap(ApArgument::Boolean(true), Variable::stream("$stream", 18)); + let expected = ap( + ApArgument::Boolean(true), + ApResult::Stream(Stream::new("$stream", 18)), + ); assert_eq!(actual, expected); } @@ -75,7 +80,7 @@ fn ap_with_last_error() { field_name: "message", }]) })), - Variable::stream("$stream", 37), + ApResult::Stream(Stream::new("$stream", 37)), ); assert_eq!(actual, expected); @@ -88,7 +93,10 @@ fn ap_with_empty_array() { "#; let actual = parse(source_code); - let expected = ap(ApArgument::EmptyArray, Variable::stream("$stream", 16)); + let expected = ap( + ApArgument::EmptyArray, + ApResult::Stream(Stream::new("$stream", 16)), + ); assert_eq!(actual, expected); } @@ -100,7 +108,10 @@ fn ap_with_init_peer_id() { "#; let actual = parse(source_code); - let expected = ap(ApArgument::InitPeerId, Variable::stream("$stream", 28)); + let expected = ap( + ApArgument::InitPeerId, + ApResult::Stream(Stream::new("$stream", 28)), + ); assert_eq!(actual, expected); } @@ -112,7 +123,10 @@ fn ap_with_timestamp() { "#; let actual = parse(source_code); - let expected = ap(ApArgument::Timestamp, Variable::stream("$stream", 25)); + let expected = ap( + ApArgument::Timestamp, + ApResult::Stream(Stream::new("$stream", 25)), + ); assert_eq!(actual, expected); } @@ -124,7 +138,48 @@ fn ap_with_ttl() { "#; let actual = parse(source_code); - let expected = ap(ApArgument::TTL, Variable::stream("$stream", 19)); + let expected = ap( + ApArgument::TTL, + ApResult::Stream(Stream::new("$stream", 19)), + ); + + assert_eq!(actual, expected); +} + +#[test] +fn ap_with_canon_stream() { + let canon_stream = "#canon_stream"; + let scalar = "scalar"; + let source_code = f!(r#" + (ap {canon_stream} {scalar}) + "#); + + let actual = parse(&source_code); + let expected = ap( + ApArgument::CanonStream(CanonStreamWithLambda::new(canon_stream, None, 13)), + ApResult::Scalar(Scalar::new(scalar, 27)), + ); + + assert_eq!(actual, expected); +} + +#[test] +fn ap_with_canon_stream_with_lambda() { + let canon_stream = "#canon_stream"; + let scalar = "scalar"; + let source_code = f!(r#" + (ap {canon_stream}.$.[0] {scalar}) + "#); + + let actual = parse(&source_code); + let expected = ap( + ApArgument::CanonStream(CanonStreamWithLambda::new( + canon_stream, + Some(unsafe { LambdaAST::new_unchecked(vec![ValueAccessor::ArrayAccess { idx: 0 }]) }), + 13, + )), + ApResult::Scalar(Scalar::new(scalar, 33)), + ); assert_eq!(actual, expected); } diff --git a/crates/air-lib/air-parser/src/parser/tests/call.rs b/crates/air-lib/air-parser/src/parser/tests/call.rs index b330e101..0efcd5e2 100644 --- a/crates/air-lib/air-parser/src/parser/tests/call.rs +++ b/crates/air-lib/air-parser/src/parser/tests/call.rs @@ -19,7 +19,9 @@ use super::parse; use crate::ast::*; use crate::parser::ParserError; -use air_lambda_ast::ValueAccessor; +use air_lambda_ast::{LambdaAST, ValueAccessor}; +use fstrings::f; +use fstrings::format_args_f; use lalrpop_util::ParseError; use std::rc::Rc; @@ -43,7 +45,7 @@ fn parse_json_path() { Value::Literal("hello"), Value::Variable(VariableWithLambda::scalar("name", 68)), ]), - CallOutputValue::Variable(Variable::stream("$void", 74)), + CallOutputValue::Stream(Stream::new("$void", 74)), ); assert_eq!(instruction, expected); } @@ -193,7 +195,7 @@ fn parse_lambda_complex() { CallInstrValue::Literal("service_id"), CallInstrValue::Literal("function_name"), Rc::new(vec![]), - CallOutputValue::Variable(Variable::scalar("void", 75)), + CallOutputValue::Scalar(Scalar::new("void", 75)), ), call( CallInstrValue::Variable(VariableWithLambda::from_raw_lambda_scalar( @@ -212,7 +214,7 @@ fn parse_lambda_complex() { CallInstrValue::Literal("service_id"), CallInstrValue::Literal("function_name"), Rc::new(vec![]), - CallOutputValue::Variable(Variable::scalar("void", 162)), + CallOutputValue::Scalar(Scalar::new("void", 162)), ), ); assert_eq!(instruction, expected); @@ -245,7 +247,7 @@ fn parse_lambda_with_scalars_complex() { CallInstrValue::Literal("service_id"), CallInstrValue::Literal("function_name"), Rc::new(vec![]), - CallOutputValue::Variable(Variable::scalar("void", 97)), + CallOutputValue::Scalar(Scalar::new("void", 97)), ), call( CallInstrValue::Variable(VariableWithLambda::from_raw_lambda_scalar( @@ -270,7 +272,7 @@ fn parse_lambda_with_scalars_complex() { CallInstrValue::Literal("service_id"), CallInstrValue::Literal("function_name"), Rc::new(vec![]), - CallOutputValue::Variable(Variable::scalar("void", 205)), + CallOutputValue::Scalar(Scalar::new("void", 205)), ), ); assert_eq!(instruction, expected); @@ -310,7 +312,7 @@ fn json_path_square_braces() { 64, )), ]), - CallOutputValue::Variable(Variable::stream("$void", 74)), + CallOutputValue::Stream(Stream::new("$void", 74)), ); assert_eq!(instruction, expected); @@ -410,6 +412,82 @@ fn parse_last_error() { assert_eq!(instruction, expected); } +#[test] +fn canon_stream_in_args() { + let service_id = "service_id"; + let function_name = "function_name"; + let canon_stream = "#canon_stream"; + let source_code = f!(r#" + (call %init_peer_id% ("{service_id}" "{function_name}") [{canon_stream}]) + "#); + + let instruction = parse(&source_code); + let expected = call( + CallInstrValue::InitPeerId, + CallInstrValue::Literal(service_id), + CallInstrValue::Literal(function_name), + Rc::new(vec![Value::Variable(VariableWithLambda::canon_stream( + canon_stream, + 66, + ))]), + CallOutputValue::None, + ); + + assert_eq!(instruction, expected); +} + +#[test] +fn canon_stream_in_triplet() { + let service_id = "service_id"; + let function_name = "function_name"; + let canon_stream = "#canon_stream"; + let source_code = f!(r#" + (call {canon_stream} ("{service_id}" "{function_name}") []) + "#); + + let instruction = parse(&source_code); + let expected = call( + CallInstrValue::Variable(VariableWithLambda::canon_stream(canon_stream, 19)), + CallInstrValue::Literal(service_id), + CallInstrValue::Literal(function_name), + Rc::new(vec![]), + CallOutputValue::None, + ); + + assert_eq!(instruction, expected); +} + +#[test] +fn canon_stream_with_lambda_in_triplet() { + let service_id = "service_id"; + let function_name = "function_name"; + let canon_stream = "#canon_stream"; + let canon_stream_lambda = ".$.[0].path!"; + let source_code = f!(r#" + (call {canon_stream}{canon_stream_lambda} ("{service_id}" "{function_name}") []) + "#); + + let instruction = parse(&source_code); + let expected = call( + CallInstrValue::Variable(VariableWithLambda::canon_stream_wl( + canon_stream, + unsafe { + LambdaAST::new_unchecked(vec![ + ValueAccessor::ArrayAccess { idx: 0 }, + ValueAccessor::FieldAccessByName { field_name: "path" }, + ]) + }, + 19, + )), + CallInstrValue::Literal(service_id), + CallInstrValue::Literal(function_name), + Rc::new(vec![]), + CallOutputValue::None, + ); + + assert_eq!(instruction, expected); +} + #[test] fn seq_par_call() { let peer_id = "some_peer_id"; @@ -430,14 +508,14 @@ fn seq_par_call() { CallInstrValue::Literal("local_service_id"), CallInstrValue::Literal("local_fn_name"), Rc::new(vec![]), - CallOutputValue::Variable(Variable::scalar("result_1", 108)), + CallOutputValue::Scalar(Scalar::new("result_1", 108)), ), call( CallInstrValue::Literal(peer_id), CallInstrValue::Literal("service_id"), CallInstrValue::Literal("fn_name"), Rc::new(vec![]), - CallOutputValue::Variable(Variable::scalar("g", 183)), + CallOutputValue::Scalar(Scalar::new("g", 183)), ), ), call( @@ -445,7 +523,7 @@ fn seq_par_call() { CallInstrValue::Literal("local_service_id"), CallInstrValue::Literal("local_fn_name"), Rc::new(vec![]), - CallOutputValue::Variable(Variable::scalar("result_2", 273)), + CallOutputValue::Scalar(Scalar::new("result_2", 273)), ), ); @@ -485,14 +563,14 @@ fn seq_with_empty_and_dash() { CallInstrValue::Literal(""), CallInstrValue::Literal(""), Rc::new(vec![Value::Literal("module-bytes")]), - CallOutputValue::Variable(Variable::scalar("module-bytes", 119)), + CallOutputValue::Scalar(Scalar::new("module-bytes", 119)), ), call( CallInstrValue::Literal("set_variables"), CallInstrValue::Literal(""), CallInstrValue::Literal(""), Rc::new(vec![Value::Literal("module_config")]), - CallOutputValue::Variable(Variable::scalar("module_config", 201)), + CallOutputValue::Scalar(Scalar::new("module_config", 201)), ), ), call( @@ -500,7 +578,7 @@ fn seq_with_empty_and_dash() { CallInstrValue::Literal(""), CallInstrValue::Literal(""), Rc::new(vec![Value::Literal("blueprint")]), - CallOutputValue::Variable(Variable::scalar("blueprint", 294)), + CallOutputValue::Scalar(Scalar::new("blueprint", 294)), ), ), seq( @@ -512,7 +590,7 @@ fn seq_with_empty_and_dash() { Value::Variable(VariableWithLambda::scalar("module-bytes", 381)), Value::Variable(VariableWithLambda::scalar("module_config", 394)), ]), - CallOutputValue::Variable(Variable::scalar("module", 409)), + CallOutputValue::Scalar(Scalar::new("module", 409)), ), seq( Instruction::Call(Call { @@ -525,7 +603,7 @@ fn seq_with_empty_and_dash() { "blueprint", 490, ))]), - output: CallOutputValue::Variable(Variable::scalar("blueprint_id", 501)), + output: CallOutputValue::Scalar(Scalar::new("blueprint_id", 501)), }), seq( call( @@ -536,7 +614,7 @@ fn seq_with_empty_and_dash() { "blueprint_id", 589, ))]), - CallOutputValue::Variable(Variable::scalar("service_id", 603)), + CallOutputValue::Scalar(Scalar::new("service_id", 603)), ), call( CallInstrValue::Literal("remote_peer_id"), @@ -546,7 +624,7 @@ fn seq_with_empty_and_dash() { "service_id", 671, ))]), - CallOutputValue::Variable(Variable::scalar("client_result", 683)), + CallOutputValue::Scalar(Scalar::new("client_result", 683)), ), ), ), diff --git a/crates/air-lib/air-parser/src/parser/tests/canon.rs b/crates/air-lib/air-parser/src/parser/tests/canon.rs new file mode 100644 index 00000000..392c49e6 --- /dev/null +++ b/crates/air-lib/air-parser/src/parser/tests/canon.rs @@ -0,0 +1,60 @@ +/* + * Copyright 2022 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::dsl::*; +use super::parse; +use crate::ast::*; + +use fstrings::f; +use fstrings::format_args_f; + +#[test] +fn canon_with_literal_peer_id() { + let peer_id = "peer_id"; + let stream = "$stream"; + let canon_stream = "#canon_stream"; + let source_code = f!(r#" + (canon "{peer_id}" {stream} {canon_stream}) + "#); + + let actual = parse(&source_code); + let expected = canon( + CallInstrValue::Literal(peer_id), + Stream::new(stream, 26), + CanonStream::new(canon_stream, 34), + ); + + assert_eq!(actual, expected); +} + +#[test] +fn canon_with_variable_peer_id() { + let peer_id = "peer_id"; + let stream = "$stream"; + let canon_stream = "#canon_stream"; + let source_code = f!(r#" + (canon {peer_id} {stream} {canon_stream}) + "#); + + let actual = parse(&source_code); + let expected = canon( + CallInstrValue::Variable(VariableWithLambda::scalar(peer_id, 16)), + Stream::new(stream, 24), + CanonStream::new(canon_stream, 32), + ); + + assert_eq!(actual, expected); +} diff --git a/crates/air-lib/air-parser/src/parser/tests/dsl.rs b/crates/air-lib/air-parser/src/parser/tests/dsl.rs index 18288437..6d374fb1 100644 --- a/crates/air-lib/air-parser/src/parser/tests/dsl.rs +++ b/crates/air-lib/air-parser/src/parser/tests/dsl.rs @@ -54,12 +54,12 @@ pub(super) fn seqnn() -> Instruction<'static> { } pub(super) fn new<'i>( - variable: Variable<'i>, + argument: NewArgument<'i>, instruction: Instruction<'i>, span: Span, ) -> Instruction<'i> { Instruction::New(New { - variable, + argument, instruction: Box::new(instruction), span, }) @@ -98,6 +98,20 @@ pub(super) fn fold_scalar_variable<'i>( }) } +pub(super) fn fold_scalar_canon_stream<'i>( + canon_stream: CanonStream<'i>, + iterator: Scalar<'i>, + instruction: Instruction<'i>, + span: Span, +) -> Instruction<'i> { + Instruction::FoldScalar(FoldScalar { + iterable: FoldScalarIterable::CanonStream(canon_stream), + iterator, + instruction: Rc::new(instruction), + span, + }) +} + pub(super) fn fold_scalar_empty_array<'i>( iterator: Scalar<'i>, instruction: Instruction<'i>, @@ -149,10 +163,22 @@ pub(super) fn mismatch<'i>( }) } -pub(super) fn ap<'i>(argument: ApArgument<'i>, result: Variable<'i>) -> Instruction<'i> { +pub(super) fn ap<'i>(argument: ApArgument<'i>, result: ApResult<'i>) -> Instruction<'i> { Instruction::Ap(Ap { argument, result }) } +pub(super) fn canon<'i>( + peer_pk: CallInstrValue<'i>, + stream: Stream<'i>, + canon_stream: CanonStream<'i>, +) -> Instruction<'i> { + Instruction::Canon(Canon { + peer_pk, + stream, + canon_stream, + }) +} + pub(super) fn binary_instruction<'i, 'b>( name: &'i str, ) -> impl Fn(Instruction<'b>, Instruction<'b>) -> Instruction<'b> { diff --git a/crates/air-lib/air-parser/src/parser/tests/fold.rs b/crates/air-lib/air-parser/src/parser/tests/fold.rs index f52157fb..10574a3f 100644 --- a/crates/air-lib/air-parser/src/parser/tests/fold.rs +++ b/crates/air-lib/air-parser/src/parser/tests/fold.rs @@ -20,6 +20,8 @@ use crate::ast::*; use crate::parser::ParserError; use air_lambda_ast::ValueAccessor; +use fstrings::f; +use fstrings::format_args_f; use lalrpop_util::ParseError; #[test] @@ -329,6 +331,24 @@ fn fold_on_stream() { assert_eq!(instruction, expected); } +#[test] +fn fold_on_canon_stream() { + let canon_stream = "#canon_stream"; + let iterator = "iterator"; + let source_code = f!(r#" + (fold {canon_stream} {iterator} (null)) + "#); + + let instruction = parse(&source_code); + let expected = fold_scalar_canon_stream( + CanonStream::new(canon_stream, 15), + Scalar::new(iterator, 29), + null(), + Span::new(9, 45), + ); + assert_eq!(instruction, expected); +} + #[test] fn comments() { let source_code = r#" diff --git a/crates/air-lib/air-parser/src/parser/tests/match_.rs b/crates/air-lib/air-parser/src/parser/tests/match_.rs index 04b5e524..8fcebe15 100644 --- a/crates/air-lib/air-parser/src/parser/tests/match_.rs +++ b/crates/air-lib/air-parser/src/parser/tests/match_.rs @@ -18,6 +18,10 @@ use super::dsl::*; use super::parse; use crate::ast::*; +use air_lambda_ast::{LambdaAST, ValueAccessor}; +use fstrings::f; +use fstrings::format_args_f; + #[test] fn parse_match() { let source_code = r#" @@ -34,6 +38,29 @@ fn parse_match() { assert_eq!(instruction, expected); } +#[test] +fn parse_match_with_canon_stream() { + let canon_stream = "#canon_stream"; + let canon_stream_lambda = ".$.[0]"; + let source_code = f!(r#" + (match {canon_stream}{canon_stream_lambda} v2 + (null) + ) + "#); + + let instruction = parse(&source_code); + let expected = match_( + Value::Variable(VariableWithLambda::canon_stream_wl( + canon_stream, + unsafe { LambdaAST::new_unchecked(vec![ValueAccessor::ArrayAccess { idx: 0 }]) }, + 16, + )), + Value::Variable(VariableWithLambda::scalar("v2", 36)), + null(), + ); + assert_eq!(instruction, expected); +} + #[test] fn parse_match_with_init_peer_id() { let source_code = r#" diff --git a/crates/air-lib/air-parser/src/parser/tests/mod.rs b/crates/air-lib/air-parser/src/parser/tests/mod.rs index 6462b03e..fb516176 100644 --- a/crates/air-lib/air-parser/src/parser/tests/mod.rs +++ b/crates/air-lib/air-parser/src/parser/tests/mod.rs @@ -16,6 +16,7 @@ mod ap; mod call; +mod canon; mod dsl; mod fail; mod fold; @@ -35,6 +36,7 @@ fn parse(source_code: &str) -> Instruction { let mut errors = Vec::new(); let lexer = crate::parser::AIRLexer::new(source_code); let mut validator = crate::parser::VariableValidator::new(); + parser .parse(source_code, &mut errors, &mut validator, lexer) .expect("parsing should be successful") diff --git a/crates/air-lib/air-parser/src/parser/tests/new.rs b/crates/air-lib/air-parser/src/parser/tests/new.rs index 5a8f2dc1..b9c6234d 100644 --- a/crates/air-lib/air-parser/src/parser/tests/new.rs +++ b/crates/air-lib/air-parser/src/parser/tests/new.rs @@ -29,7 +29,11 @@ fn parse_new_with_scalar() { "#; let instruction = parse(source_code); - let expected = new(Variable::scalar("scalar", 5), null(), Span::new(0, 40)); + let expected = new( + NewArgument::Scalar(Scalar::new("scalar", 5)), + null(), + Span::new(0, 40), + ); assert_eq!(instruction, expected); } @@ -41,7 +45,27 @@ fn parse_new_with_stream() { "#; let instruction = parse(source_code); - let expected = new(Variable::stream("$stream", 5), null(), Span::new(0, 41)); + let expected = new( + NewArgument::Stream(Stream::new("$stream", 5)), + null(), + Span::new(0, 41), + ); + assert_eq!(instruction, expected); +} + +#[test] +fn parse_new_with_canon_stream() { + let source_code = r#"(new #canon_stream + (null) + ) + "#; + + let instruction = parse(source_code); + let expected = new( + NewArgument::CanonStream(CanonStream::new("#canon_stream", 5)), + null(), + Span::new(0, 47), + ); assert_eq!(instruction, expected); } diff --git a/crates/air-lib/air-parser/src/parser/tests/seq.rs b/crates/air-lib/air-parser/src/parser/tests/seq.rs index 3287141e..60da8c86 100644 --- a/crates/air-lib/air-parser/src/parser/tests/seq.rs +++ b/crates/air-lib/air-parser/src/parser/tests/seq.rs @@ -36,7 +36,7 @@ fn parse_seq() { CallInstrValue::Variable(VariableWithLambda::scalar("service_id", 41)), CallInstrValue::Variable(VariableWithLambda::scalar("function_name", 52)), Rc::new(vec![Value::EmptyArray, Value::EmptyArray]), - CallOutputValue::Variable(Variable::scalar("output", 75)), + CallOutputValue::Scalar(Scalar::new("output", 75)), ), call( CallInstrValue::Literal("peer_id"), @@ -90,7 +90,7 @@ fn parse_seq_seq() { Value::Literal("hello"), Value::Variable(VariableWithLambda::scalar("name", 236)), ]), - CallOutputValue::Variable(Variable::stream("$output", 242)), + CallOutputValue::Stream(Stream::new("$output", 242)), ), ); assert_eq!(instruction, expected); diff --git a/crates/air-lib/air-parser/src/parser/validator.rs b/crates/air-lib/air-parser/src/parser/validator.rs index c049757f..6f33b063 100644 --- a/crates/air-lib/air-parser/src/parser/validator.rs +++ b/crates/air-lib/air-parser/src/parser/validator.rs @@ -20,6 +20,7 @@ use crate::parser::lexer::Token; use crate::parser::ParserError; use crate::parser::Span; +use air_lambda_ast::LambdaAST; use air_lambda_ast::ValueAccessor; use lalrpop_util::ErrorRecovery; use lalrpop_util::ParseError; @@ -71,11 +72,17 @@ impl<'i> VariableValidator<'i> { self.met_args(call.args.deref(), span); match &call.output { - CallOutputValue::Variable(variable) => self.met_variable_definition(variable, span), + CallOutputValue::Scalar(scalar) => self.met_variable_name_definition(scalar.name, span), + CallOutputValue::Stream(stream) => self.met_variable_name_definition(stream.name, span), CallOutputValue::None => {} }; } + pub(super) fn met_canon(&mut self, canon: &Canon<'i>, span: Span) { + self.met_variable_name(canon.stream.name, span); + self.met_variable_name_definition(canon.canon_stream.name, 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); @@ -90,7 +97,13 @@ impl<'i> VariableValidator<'i> { use FoldScalarIterable::*; match &fold.iterable { - Scalar(variable) => self.met_variable_name(variable.name, span), + Scalar(variable) => { + self.met_variable_name(variable.name, span); + self.met_maybe_lambda(&variable.lambda, span); + } + CanonStream(canon_stream) => { + self.met_variable_name(canon_stream.name, span); + } EmptyArray => {} }; self.met_iterator_definition(&fold.iterator, span); @@ -103,9 +116,9 @@ impl<'i> VariableValidator<'i> { pub(super) fn met_new(&mut self, new: &New<'i>, span: Span) { self.not_iterators_candidates - .push((new.variable.name(), span)); + .push((new.argument.name(), span)); // new defines a new variable - self.met_variable_definition(&new.variable, span); + self.met_variable_name_definition(new.argument.name(), span); } pub(super) fn met_next(&mut self, next: &Next<'i>, span: Span) { @@ -128,10 +141,15 @@ impl<'i> VariableValidator<'i> { | ApArgument::EmptyArray | ApArgument::LastError(_) => {} ApArgument::Scalar(scalar) => { - self.met_variable_wl(&VariableWithLambda::Scalar(scalar.clone()), span) + self.met_variable_name(scalar.name, span); + self.met_maybe_lambda(&scalar.lambda, span); + } + ApArgument::CanonStream(canon_stream) => { + self.met_variable_name(canon_stream.name, span); + self.met_maybe_lambda(&canon_stream.lambda, span); } } - self.met_variable_definition(&ap.result, span); + self.met_variable_name_definition(ap.result.name(), span); } pub(super) fn finalize(self) -> Vec, ParserError>> { @@ -171,11 +189,24 @@ impl<'i> VariableValidator<'i> { fn met_variable_wl(&mut self, variable: &VariableWithLambda<'i>, span: Span) { self.met_variable_name(variable.name(), span); - let lambda = match variable.lambda() { + self.met_maybe_lambda(variable.lambda(), span); + } + + fn met_variable_name(&mut self, name: &'i str, span: Span) { + if !self.contains_variable(name, span) { + self.unresolved_variables.insert(name, span); + } + } + + fn met_maybe_lambda(&mut self, lambda: &Option>, span: Span) { + let lambda = match lambda { Some(lambda) => lambda, None => return, }; + self.met_lambda(lambda, span) + } + fn met_lambda(&mut self, lambda: &LambdaAST<'i>, span: Span) { for accessor in lambda.iter() { match accessor { &ValueAccessor::FieldAccessByScalar { scalar_name } => { @@ -188,12 +219,6 @@ impl<'i> VariableValidator<'i> { } } - fn met_variable_name(&mut self, name: &'i str, span: Span) { - if !self.contains_variable(name, span) { - self.unresolved_variables.insert(name, span); - } - } - fn contains_variable(&self, key: &str, key_span: Span) -> bool { if let Some(found_span) = self.met_variable_definitions.get(key) { if found_span < &key_span { @@ -209,10 +234,6 @@ impl<'i> VariableValidator<'i> { found_spans.iter().any(|s| s < &key_span) } - fn met_variable_definition(&mut self, variable: &Variable<'i>, span: Span) { - self.met_variable_name_definition(variable.name(), span); - } - fn met_variable_name_definition(&mut self, name: &'i str, span: Span) { use std::collections::hash_map::Entry; diff --git a/crates/air-lib/interpreter-data/CHANGELOG.md b/crates/air-lib/interpreter-data/CHANGELOG.md index 74f1010a..68e24a3c 100644 --- a/crates/air-lib/interpreter-data/CHANGELOG.md +++ b/crates/air-lib/interpreter-data/CHANGELOG.md @@ -1,3 +1,8 @@ +## Version 0.3.0 + +[PR 292](https://github.com/fluencelabs/aquavm/pull/292): +- added a new state in data for a canon instruction result + ## Version 0.2.2 [PR 169](https://github.com/fluencelabs/aquavm/pull/169): diff --git a/crates/air-lib/interpreter-data/Cargo.toml b/crates/air-lib/interpreter-data/Cargo.toml index ae6b5a01..9b026003 100644 --- a/crates/air-lib/interpreter-data/Cargo.toml +++ b/crates/air-lib/interpreter-data/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "air-interpreter-data" description = "Data format of the AIR interpreter" -version = "0.2.2" +version = "0.3.0" authors = ["Fluence Labs"] edition = "2018" license = "Apache-2.0" diff --git a/crates/air-lib/interpreter-data/src/executed_state.rs b/crates/air-lib/interpreter-data/src/executed_state.rs index f557900a..d1e94299 100644 --- a/crates/air-lib/interpreter-data/src/executed_state.rs +++ b/crates/air-lib/interpreter-data/src/executed_state.rs @@ -124,6 +124,14 @@ pub struct ApResult { pub res_generations: Vec, } +/// Contains ids of element that were on a stream at the moment of an appropriate canon call. +#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub struct CanonResult { + #[serde(rename = "ids")] + pub stream_elements_pos: Vec, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum ExecutedState { @@ -132,4 +140,5 @@ pub enum ExecutedState { Call(CallResult), Fold(FoldResult), Ap(ApResult), + Canon(CanonResult), } diff --git a/crates/air-lib/interpreter-data/src/executed_state/impls.rs b/crates/air-lib/interpreter-data/src/executed_state/impls.rs index 880488d5..0ff89cbf 100644 --- a/crates/air-lib/interpreter-data/src/executed_state/impls.rs +++ b/crates/air-lib/interpreter-data/src/executed_state/impls.rs @@ -86,6 +86,14 @@ impl ApResult { } } +impl CanonResult { + pub fn new(stream_elements_pos: Vec) -> Self { + Self { + stream_elements_pos, + } + } +} + impl std::fmt::Display for ExecutedState { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { use CallResult::*; @@ -121,6 +129,9 @@ impl std::fmt::Display for ExecutedState { Ap(ap) => { write!(f, "ap: _ -> {:?}", ap.res_generations) } + Canon(canon) => { + write!(f, "canon {:?}", canon.stream_elements_pos) + } } } } diff --git a/crates/air-lib/polyplets/Cargo.toml b/crates/air-lib/polyplets/Cargo.toml index 864e70af..c30ebf06 100644 --- a/crates/air-lib/polyplets/Cargo.toml +++ b/crates/air-lib/polyplets/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polyplets" -version = "0.3.0" +version = "0.3.1" description = "Security primitives to verify origin of service calls in Fluence network" authors = ["Fluence Labs"] edition = "2018" diff --git a/crates/air-lib/polyplets/src/tetraplet.rs b/crates/air-lib/polyplets/src/tetraplet.rs index 3fb1150c..ab81b93b 100644 --- a/crates/air-lib/polyplets/src/tetraplet.rs +++ b/crates/air-lib/polyplets/src/tetraplet.rs @@ -79,3 +79,15 @@ impl SecurityTetraplet { self.json_path.push_str(json_path) } } + +use std::fmt; + +impl fmt::Display for SecurityTetraplet { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "peer_pk: {}, service_id: {}, function_name: {}, json_path: {}", + self.peer_pk, self.service_id, self.function_name, self.json_path + ) + } +} diff --git a/crates/air-lib/test-utils/src/executed_state.rs b/crates/air-lib/test-utils/src/executed_state.rs index 6c21db08..ec6f8cdf 100644 --- a/crates/air-lib/test-utils/src/executed_state.rs +++ b/crates/air-lib/test-utils/src/executed_state.rs @@ -16,6 +16,7 @@ use super::ApResult; use super::CallResult; +use super::CanonResult; use super::ExecutedState; use super::JValue; use super::ParResult; @@ -138,6 +139,11 @@ pub fn ap(dst: Option) -> ExecutedState { ExecutedState::Ap(ap_result) } +pub fn canon(stream_elements_pos: Vec) -> ExecutedState { + let canon_result = CanonResult::new(stream_elements_pos); + ExecutedState::Canon(canon_result) +} + fn option_to_vec(maybe_value: Option) -> Vec { match maybe_value { Some(value) => vec![value], diff --git a/crates/air-lib/trace-handler/Cargo.toml b/crates/air-lib/trace-handler/Cargo.toml index a3223ca9..b8829fde 100644 --- a/crates/air-lib/trace-handler/Cargo.toml +++ b/crates/air-lib/trace-handler/Cargo.toml @@ -18,6 +18,7 @@ air-interpreter-data = { path = "../interpreter-data" } air-log-targets = { path = "../log-targets" } air-parser = { path = "../air-parser" } +bimap = "0.6.2" serde_json = "1.0.68" log = "0.4.14" thiserror = "1.0.29" diff --git a/crates/air-lib/trace-handler/src/data_keeper/keeper.rs b/crates/air-lib/trace-handler/src/data_keeper/keeper.rs index 3bfca0b6..ae4e4419 100644 --- a/crates/air-lib/trace-handler/src/data_keeper/keeper.rs +++ b/crates/air-lib/trace-handler/src/data_keeper/keeper.rs @@ -21,14 +21,15 @@ use crate::TracePos; use air_interpreter_data::InterpreterData; -use std::collections::HashMap; +use bimap::BiHashMap; /// Keeps all necessary data for merging. #[derive(Debug, Default, PartialEq)] pub(crate) struct DataKeeper { pub(crate) prev_ctx: MergeCtx, pub(crate) current_ctx: MergeCtx, - pub(crate) new_to_old_pos: HashMap, + pub(crate) new_to_prev_pos: BiHashMap, + pub(crate) new_to_current_pos: BiHashMap, pub(crate) result_trace: ExecutionTrace, } @@ -40,7 +41,8 @@ impl DataKeeper { Self { prev_ctx, current_ctx, - new_to_old_pos: <_>::default(), + new_to_prev_pos: <_>::default(), + new_to_current_pos: <_>::default(), result_trace: <_>::default(), } } @@ -69,9 +71,3 @@ impl DataKeeper { &mut self.current_ctx.slider } } - -#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] -pub(crate) struct DataPositions { - pub(crate) prev_pos: Option, - pub(crate) current_pos: Option, -} diff --git a/crates/air-lib/trace-handler/src/data_keeper/mod.rs b/crates/air-lib/trace-handler/src/data_keeper/mod.rs index a5f6d879..cc7edc6e 100644 --- a/crates/air-lib/trace-handler/src/data_keeper/mod.rs +++ b/crates/air-lib/trace-handler/src/data_keeper/mod.rs @@ -24,7 +24,6 @@ pub use merge_ctx::MergeCtx; pub use trace_slider::TraceSlider; pub(crate) use keeper::DataKeeper; -pub(crate) use keeper::DataPositions; pub(self) type KeeperResult = std::result::Result; diff --git a/crates/air-lib/trace-handler/src/data_keeper/trace_slider.rs b/crates/air-lib/trace-handler/src/data_keeper/trace_slider.rs index 6059a8a7..0fcfd2a7 100644 --- a/crates/air-lib/trace-handler/src/data_keeper/trace_slider.rs +++ b/crates/air-lib/trace-handler/src/data_keeper/trace_slider.rs @@ -106,7 +106,7 @@ impl TraceSlider { self.subtrace_len - self.seen_elements } - pub(super) fn state_at_position(&self, position: TracePos) -> Option<&ExecutedState> { + pub(crate) fn state_at_position(&self, position: TracePos) -> Option<&ExecutedState> { // it would be nice to have the `impl SliceIndex for TracePos`, but it is unstable self.trace.get(position) } diff --git a/crates/air-lib/trace-handler/src/handler.rs b/crates/air-lib/trace-handler/src/handler.rs index 829c19af..435378e8 100644 --- a/crates/air-lib/trace-handler/src/handler.rs +++ b/crates/air-lib/trace-handler/src/handler.rs @@ -86,6 +86,16 @@ impl TraceHandler { } } +impl TraceHandler { + pub fn meet_canon_start(&mut self) -> TraceHandlerResult { + try_merge_next_state_as_canon(&mut self.data_keeper).map_err(Into::into) + } + + pub fn meet_canon_end(&mut self, canon_result: CanonResult) { + self.data_keeper.result_trace.push(ExecutedState::Canon(canon_result)); + } +} + impl TraceHandler { pub fn meet_par_start(&mut self) -> TraceHandlerResult<()> { let ingredients = merger::try_merge_next_state_as_par(&mut self.data_keeper)?; diff --git a/crates/air-lib/trace-handler/src/lib.rs b/crates/air-lib/trace-handler/src/lib.rs index 9928e4e2..970e7367 100644 --- a/crates/air-lib/trace-handler/src/lib.rs +++ b/crates/air-lib/trace-handler/src/lib.rs @@ -14,6 +14,17 @@ * limitations under the License. */ +#![warn(rust_2018_idioms)] +#![deny( + dead_code, + nonstandard_style, + unused_imports, + unused_mut, + unused_variables, + unused_unsafe, + unreachable_patterns +)] + mod data_keeper; mod errors; mod handler; @@ -29,6 +40,7 @@ pub use merger::MergeCtxType; pub use merger::MergeError; pub use merger::MergerApResult; pub use merger::MergerCallResult; +pub use merger::MergerCanonResult; pub use state_automata::SubgraphType; pub type TraceHandlerResult = std::result::Result; diff --git a/crates/air-lib/trace-handler/src/merger/call_merger.rs b/crates/air-lib/trace-handler/src/merger/call_merger.rs index 5f3f3293..df8a0112 100644 --- a/crates/air-lib/trace-handler/src/merger/call_merger.rs +++ b/crates/air-lib/trace-handler/src/merger/call_merger.rs @@ -117,10 +117,8 @@ pub(crate) enum ValueType<'i> { impl<'i> ValueType<'i> { pub(self) fn from_output_value(output_value: &'i CallOutputValue<'_>) -> Self { - use air_parser::ast::Variable; - match output_value { - CallOutputValue::Variable(Variable::Stream(stream)) => ValueType::Stream(stream.name), + CallOutputValue::Stream(stream) => ValueType::Stream(stream.name), _ => ValueType::Scalar, } } diff --git a/crates/air-lib/trace-handler/src/merger/canon_merger.rs b/crates/air-lib/trace-handler/src/merger/canon_merger.rs new file mode 100644 index 00000000..68a660e0 --- /dev/null +++ b/crates/air-lib/trace-handler/src/merger/canon_merger.rs @@ -0,0 +1,135 @@ +/* + * Copyright 2022 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::*; +use crate::merger::errors::CanonResultError; + +use bimap::BiHashMap; + +const EXPECTED_STATE_NAME: &str = "canon"; + +#[derive(Debug, Clone)] +pub enum MergerCanonResult { + /// There is no corresponding state in a trace for this call. + Empty, + + /// There was a state in at least one of the contexts. If there were two states in + /// both contexts, they were successfully merged. + /// Positions correspond to a new data trace. + CanonResult { stream_elements_pos: Vec }, +} + +pub(crate) fn try_merge_next_state_as_canon(data_keeper: &mut DataKeeper) -> MergeResult { + use ExecutedState::Canon; + + let prev_state = data_keeper.prev_slider_mut().next_state(); + let current_state = data_keeper.current_slider_mut().next_state(); + + match (prev_state, current_state) { + (Some(Canon(prev_canon)), Some(Canon(current_canon))) => { + prepare_both_canon_result(&prev_canon, ¤t_canon, data_keeper) + } + (Some(Canon(prev_canon)), None) => prepare_single_canon_result(&prev_canon, &data_keeper.new_to_prev_pos), + (None, Some(Canon(current_canon))) => { + prepare_single_canon_result(¤t_canon, &data_keeper.new_to_current_pos) + } + (None, None) => Ok(MergerCanonResult::Empty), + (prev_state, current_state) => Err(MergeError::incompatible_states( + prev_state, + current_state, + EXPECTED_STATE_NAME, + )), + } +} + +fn prepare_both_canon_result( + prev_canon_result: &CanonResult, + current_canon_result: &CanonResult, + data_keeper: &DataKeeper, +) -> MergeResult { + check_canon_results(prev_canon_result, current_canon_result, data_keeper) + .map_err(MergeError::IncorrectCanonResult)?; + prepare_single_canon_result(prev_canon_result, &data_keeper.new_to_prev_pos) +} + +fn prepare_single_canon_result( + canon_result: &CanonResult, + new_to_other_pos: &BiHashMap, +) -> MergeResult { + let new_positions = canon_result + .stream_elements_pos + .iter() + .map(|pos| { + new_to_other_pos + .get_by_right(pos) + .cloned() + .ok_or_else(|| CanonResultError::not_met_position(canon_result.clone(), *pos)) + }) + .collect::, _>>()?; + + Ok(MergerCanonResult::CanonResult { + stream_elements_pos: new_positions, + }) +} + +fn check_canon_results( + prev_canon_result: &CanonResult, + current_canon_result: &CanonResult, + data_keeper: &DataKeeper, +) -> Result<(), CanonResultError> { + if prev_canon_result.stream_elements_pos.len() != current_canon_result.stream_elements_pos.len() { + return Err(CanonResultError::different_lens( + prev_canon_result.clone(), + current_canon_result.clone(), + )); + } + + let prev_slider = data_keeper.prev_slider(); + let current_slider = data_keeper.current_slider(); + for (position, (prev_idx, current_idx)) in prev_canon_result + .stream_elements_pos + .iter() + .zip(current_canon_result.stream_elements_pos.iter()) + .enumerate() + { + let prev_state = prev_slider.state_at_position(*prev_idx); + let current_state = current_slider.state_at_position(*current_idx); + + match (prev_state, current_state) { + (Some(ExecutedState::Call(prev_call_result)), Some(ExecutedState::Call(current_call_result))) + if prev_call_result == current_call_result => + { + continue; + } + (Some(ExecutedState::Ap(prev_ap_result)), Some(ExecutedState::Ap(current_ap_result))) + if prev_ap_result == current_ap_result => + { + continue; + } + _ => { + return Err(CanonResultError::incompatible_state( + prev_canon_result.clone(), + current_canon_result.clone(), + prev_state.cloned(), + current_state.cloned(), + position, + )) + } + } + } + + Ok(()) +} diff --git a/crates/air-lib/trace-handler/src/merger/errors.rs b/crates/air-lib/trace-handler/src/merger/errors.rs index dc1ba3c2..4ea97567 100644 --- a/crates/air-lib/trace-handler/src/merger/errors.rs +++ b/crates/air-lib/trace-handler/src/merger/errors.rs @@ -22,6 +22,7 @@ use super::FoldResult; use super::KeeperError; use super::Value; +use air_interpreter_data::CanonResult; use air_interpreter_data::TracePos; use thiserror::Error as ThisError; @@ -46,6 +47,9 @@ pub enum MergeError { #[error(transparent)] IncorrectCallResult(#[from] CallResultError), + #[error(transparent)] + IncorrectCanonResult(#[from] CanonResultError), + #[error(transparent)] IncorrectFoldResult(#[from] FoldResultError), } @@ -73,6 +77,30 @@ pub enum CallResultError { DataNotMatchAIR { air_type: String, data_value: Value }, } +#[derive(ThisError, Debug)] +pub enum CanonResultError { + #[error("canon results have different length: {prev_canon_result:?} != {current_canon_result:?}")] + LensNotEqual { + prev_canon_result: CanonResult, + current_canon_result: CanonResult, + }, + + #[error("canon results {prev_canon_result:?} {current_canon_result:?} at position {position} points to incompatible execution states: {prev_state:?} {current_state:?}")] + IncompatibleState { + prev_canon_result: CanonResult, + current_canon_result: CanonResult, + prev_state: Option, + current_state: Option, + position: usize, + }, + + #[error("position {position} from canon result {canon_result:?} hasn't been met yet")] + NotMetPosition { + canon_result: CanonResult, + position: TracePos, + }, +} + #[derive(ThisError, Debug)] pub enum FoldResultError { #[error("the first {count} subtrace descriptors lens of fold {fold_result:?} overflows")] @@ -138,6 +166,35 @@ impl CallResultError { } } +impl CanonResultError { + pub(crate) fn different_lens(prev_canon_result: CanonResult, current_canon_result: CanonResult) -> Self { + Self::LensNotEqual { + prev_canon_result, + current_canon_result, + } + } + + pub(crate) fn incompatible_state( + prev_canon_result: CanonResult, + current_canon_result: CanonResult, + prev_state: Option, + current_state: Option, + position: usize, + ) -> Self { + Self::IncompatibleState { + prev_canon_result, + current_canon_result, + prev_state, + current_state, + position, + } + } + + pub(crate) fn not_met_position(canon_result: CanonResult, position: TracePos) -> Self { + Self::NotMetPosition { canon_result, position } + } +} + #[derive(Clone, Copy, Debug)] pub enum DataType { Previous, diff --git a/crates/air-lib/trace-handler/src/merger/mod.rs b/crates/air-lib/trace-handler/src/merger/mod.rs index a8394632..fbcdd474 100644 --- a/crates/air-lib/trace-handler/src/merger/mod.rs +++ b/crates/air-lib/trace-handler/src/merger/mod.rs @@ -16,6 +16,7 @@ mod ap_merger; mod call_merger; +mod canon_merger; mod errors; mod fold_merger; mod par_merger; @@ -23,6 +24,7 @@ mod position_mapping; pub use ap_merger::MergerApResult; pub use call_merger::MergerCallResult; +pub use canon_merger::MergerCanonResult; pub use fold_merger::MergerFoldResult; pub use par_merger::MergerParResult; @@ -36,6 +38,7 @@ pub use fold_merger::ResolvedSubTraceDescs; pub(super) use ap_merger::try_merge_next_state_as_ap; pub(super) use call_merger::try_merge_next_state_as_call; +pub(super) use canon_merger::try_merge_next_state_as_canon; pub(crate) use fold_merger::try_merge_next_state_as_fold; pub(crate) use par_merger::try_merge_next_state_as_par; @@ -44,7 +47,6 @@ use position_mapping::PreparationScheme; type MergeResult = std::result::Result; -use super::data_keeper::DataPositions; use super::data_keeper::KeeperError; use super::DataKeeper; diff --git a/crates/air-lib/trace-handler/src/merger/position_mapping.rs b/crates/air-lib/trace-handler/src/merger/position_mapping.rs index 255cef7d..0d57cda2 100644 --- a/crates/air-lib/trace-handler/src/merger/position_mapping.rs +++ b/crates/air-lib/trace-handler/src/merger/position_mapping.rs @@ -15,7 +15,6 @@ */ use super::DataKeeper; -use super::DataPositions; pub(super) enum PreparationScheme { Previous, @@ -27,19 +26,23 @@ pub(super) enum PreparationScheme { pub(super) fn prepare_positions_mapping(scheme: PreparationScheme, data_keeper: &mut DataKeeper) { use PreparationScheme::*; - // it's safe to sub 1 from positions iff scheme was set correctly - let prev_pos = match scheme { - Previous | Both => Some(data_keeper.prev_slider().position() - 1), - Current => None, + let new_pos = data_keeper.result_trace_next_pos(); + + // it's safe to sub 1 from positions here iff scheme was set correctly + match scheme { + Previous => { + let prev_pos = data_keeper.prev_slider().position() - 1; + data_keeper.new_to_prev_pos.insert(new_pos, prev_pos); + } + Current => { + let current_pos = data_keeper.current_slider().position() - 1; + data_keeper.new_to_current_pos.insert(new_pos, current_pos); + } + Both => { + let prev_pos = data_keeper.prev_slider().position() - 1; + let current_pos = data_keeper.current_slider().position() - 1; + data_keeper.new_to_prev_pos.insert(new_pos, prev_pos); + data_keeper.new_to_current_pos.insert(new_pos, current_pos); + } }; - - let current_pos = match scheme { - Current | Both => Some(data_keeper.current_slider().position() - 1), - Previous => None, - }; - - let data_positions = DataPositions { prev_pos, current_pos }; - - let trace_pos = data_keeper.result_trace_next_pos(); - data_keeper.new_to_old_pos.insert(trace_pos, data_positions); } diff --git a/crates/air-lib/trace-handler/src/state_automata/fold_fsm.rs b/crates/air-lib/trace-handler/src/state_automata/fold_fsm.rs index 3096b983..74cb5d43 100644 --- a/crates/air-lib/trace-handler/src/state_automata/fold_fsm.rs +++ b/crates/air-lib/trace-handler/src/state_automata/fold_fsm.rs @@ -66,13 +66,11 @@ impl FoldFSM { } pub(crate) fn meet_iteration_start(&mut self, value_pos: TracePos, data_keeper: &mut DataKeeper) -> FSMResult<()> { - let (prev_pos, current_pos) = match data_keeper.new_to_old_pos.get(&value_pos) { - Some(DataPositions { prev_pos, current_pos }) => (prev_pos, current_pos), - None => return self.prepare(None, None, value_pos, data_keeper), - }; + let prev_pos = data_keeper.new_to_prev_pos.get_by_left(&value_pos); + let current_pos = data_keeper.new_to_current_pos.get_by_left(&value_pos); - let prev_lore = prev_pos.map(|pos| self.prev_fold.lore.remove(&pos)).flatten(); - let current_lore = current_pos.map(|pos| self.current_fold.lore.remove(&pos)).flatten(); + let prev_lore = prev_pos.and_then(|pos| self.prev_fold.lore.remove(pos)); + let current_lore = current_pos.and_then(|pos| self.current_fold.lore.remove(pos)); self.prepare(prev_lore, current_lore, value_pos, data_keeper) } diff --git a/crates/air-lib/trace-handler/src/state_automata/mod.rs b/crates/air-lib/trace-handler/src/state_automata/mod.rs index 6d4d8337..41ef33db 100644 --- a/crates/air-lib/trace-handler/src/state_automata/mod.rs +++ b/crates/air-lib/trace-handler/src/state_automata/mod.rs @@ -30,7 +30,6 @@ pub(super) use fold_fsm::FoldFSM; pub(super) use fsm_queue::FSMKeeper; pub(super) use par_fsm::ParFSM; -use super::data_keeper::DataPositions; use super::data_keeper::KeeperError; use super::merger::MergerParResult; use super::DataKeeper; diff --git a/crates/beautifier/src/beautifier.rs b/crates/beautifier/src/beautifier.rs index c1accae6..15a10caa 100644 --- a/crates/beautifier/src/beautifier.rs +++ b/crates/beautifier/src/beautifier.rs @@ -135,6 +135,7 @@ impl Beautifier { match node { ast::Instruction::Call(call) => self.beautify_call(call, indent), ast::Instruction::Ap(ap) => self.beautify_simple(ap, indent), + ast::Instruction::Canon(canon) => self.beautify_simple(canon, indent), ast::Instruction::Seq(seq) => self.beautify_seq(seq, indent), ast::Instruction::Par(par) => self.beautify_par(par, indent), ast::Instruction::Xor(xor) => self.beautify_xor(xor, indent), @@ -157,7 +158,8 @@ impl Beautifier { fn beautify_call(&mut self, call: &ast::Call, indent: usize) -> io::Result<()> { fmt_indent(&mut self.output, indent)?; match &call.output { - ast::CallOutputValue::Variable(v) => write!(&mut self.output, "{} <- ", v)?, + ast::CallOutputValue::Scalar(v) => write!(&mut self.output, "{} <- ", v)?, + ast::CallOutputValue::Stream(v) => write!(&mut self.output, "{} <- ", v)?, ast::CallOutputValue::None => {} } writeln!(