feat(air-parser): VM-347 After next validator fold check (#774)

This commit is contained in:
raftedproc 2023-12-28 20:48:16 +03:00 committed by GitHub
parent 518bb95a17
commit c6f157a6e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 2577 additions and 858 deletions

View File

@ -190,13 +190,13 @@ fn stream_merge() {
let mut vm2 = create_avm(neighborhood_call_service, "B");
let script = r#"
(seq
(seq
(call "A" ("add_provider" "") [] $void)
(seq
(seq
(call "A" ("add_provider" "") [] $void)
(seq
(seq
(call "A" ("get_providers" "") [] $providers)
(seq
(seq
(call "A" ("get_providers" "") [] $providers)
(seq
(seq

View File

@ -22,6 +22,6 @@
(seq
(par
(call "{1}" ("" "") [v1 v2])
(next v2))
(call "{1}" ("" "") [v1 v2])))
(call "{1}" ("" "") [v1 v2]))
(next v2)))
(next v1)))))

View File

@ -48,8 +48,8 @@ fn ap_with_fold() {
(next pair)))
(fold $inner ns
(par
(next ns)
(null))))
(null)
(next ns))))
(seq
(call "{local_vm_peer_id}" ("op" "noop") [])
(seq

View File

@ -18,5 +18,9 @@
(par
(seq
(call "{4}" ("" "") [v])
(next v))
(call "{4}" ("" "") [v]))))
(call "{4}" ("" "") [v])
)
(next v)
)
)
)

View File

@ -251,17 +251,17 @@ fn stream_merging_v1() {
stream!("1", 0, peer = setter_1_id),
executed_state::request_sent_by(initiator_id),
executed_state::fold(vec![
executed_state::subtrace_lore(7, subtrace_desc(15, 2), subtrace_desc(23, 1)),
executed_state::subtrace_lore(9, subtrace_desc(17, 2), subtrace_desc(22, 1)),
executed_state::subtrace_lore(12, subtrace_desc(19, 2), subtrace_desc(21, 1)),
executed_state::subtrace_lore(7, subtrace_desc(15, 3), subtrace_desc(24, 0)),
executed_state::subtrace_lore(9, subtrace_desc(18, 3), subtrace_desc(24, 0)),
executed_state::subtrace_lore(12, subtrace_desc(21, 3), subtrace_desc(24, 0)),
]),
executed_state::par(7, 1),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(4, 1),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(1, 1),
executed_state::par(2, 6),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(2, 3),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(2, 0),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
]);
@ -292,25 +292,25 @@ fn stream_merging_v1() {
stream!("1", 0, peer = setter_1_id),
stream!("2", 1, peer = setter_2_id),
executed_state::fold(vec![
executed_state::subtrace_lore(7, subtrace_desc(15, 2), subtrace_desc(23, 1)),
executed_state::subtrace_lore(9, subtrace_desc(17, 2), subtrace_desc(22, 1)),
executed_state::subtrace_lore(12, subtrace_desc(19, 2), subtrace_desc(21, 1)),
executed_state::subtrace_lore(8, subtrace_desc(24, 2), subtrace_desc(29, 1)),
executed_state::subtrace_lore(13, subtrace_desc(26, 2), subtrace_desc(28, 1)),
executed_state::subtrace_lore(7, subtrace_desc(15, 3), subtrace_desc(24, 0)),
executed_state::subtrace_lore(9, subtrace_desc(18, 3), subtrace_desc(24, 0)),
executed_state::subtrace_lore(12, subtrace_desc(21, 3), subtrace_desc(24, 0)),
executed_state::subtrace_lore(8, subtrace_desc(24, 3), subtrace_desc(30, 0)),
executed_state::subtrace_lore(13, subtrace_desc(27, 3), subtrace_desc(30, 0)),
]),
executed_state::par(7, 1),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(4, 1),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(1, 1),
executed_state::par(2, 6),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(2, 3),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(4, 1),
executed_state::par(2, 0),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(2, 3),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
executed_state::par(1, 1),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
executed_state::par(2, 0),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
]);
@ -341,33 +341,33 @@ fn stream_merging_v1() {
stream!("1", 0, peer = setter_1_id),
stream!("2", 1, peer = setter_2_id),
executed_state::fold(vec![
executed_state::subtrace_lore(7, subtrace_desc(15, 2), subtrace_desc(23, 1)),
executed_state::subtrace_lore(9, subtrace_desc(17, 2), subtrace_desc(22, 1)),
executed_state::subtrace_lore(12, subtrace_desc(19, 2), subtrace_desc(21, 1)),
executed_state::subtrace_lore(8, subtrace_desc(24, 2), subtrace_desc(29, 1)),
executed_state::subtrace_lore(13, subtrace_desc(26, 2), subtrace_desc(28, 1)),
executed_state::subtrace_lore(10, subtrace_desc(30, 2), subtrace_desc(35, 1)),
executed_state::subtrace_lore(11, subtrace_desc(32, 2), subtrace_desc(34, 1)),
executed_state::subtrace_lore(7, subtrace_desc(15, 3), subtrace_desc(24, 0)),
executed_state::subtrace_lore(9, subtrace_desc(18, 3), subtrace_desc(24, 0)),
executed_state::subtrace_lore(12, subtrace_desc(21, 3), subtrace_desc(24, 0)),
executed_state::subtrace_lore(8, subtrace_desc(24, 3), subtrace_desc(30, 0)),
executed_state::subtrace_lore(13, subtrace_desc(27, 3), subtrace_desc(30, 0)),
executed_state::subtrace_lore(10, subtrace_desc(30, 3), subtrace_desc(36, 0)),
executed_state::subtrace_lore(11, subtrace_desc(33, 3), subtrace_desc(36, 0)),
]),
executed_state::par(7, 1),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(4, 1),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(1, 1),
executed_state::par(2, 6),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(2, 3),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(4, 1),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
executed_state::par(1, 1),
executed_state::par(2, 0),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
unused!(unit_call_service_result, peer = executor_id, args = ["1"]),
executed_state::par(2, 3),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
executed_state::par(2, 0),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
executed_state::par(4, 1),
unused!(unit_call_service_result, peer = executor_id, args = ["2"]),
executed_state::par(2, 3),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
executed_state::par(1, 1),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
executed_state::par(2, 0),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
unused!(unit_call_service_result, peer = executor_id, args = ["3"]),
]);

File diff suppressed because it is too large Load Diff

View File

@ -328,347 +328,347 @@ Machine 62dabcde478dc58760ebbe71ef6047299144a5f63990c6c3d826ebf30175adfc:
new: 42.00µs
Machine 88756ca30bfb93b0da6a64252adc98fc3e97e142c3b4970af3d2948fd66107b4:
Platform: Linux-6.5.9-arch2-1-x86_64-with-glibc2.35
Timestamp: 2023-12-25 12:09:49.153856+00:00
Timestamp: 2023-12-26 11:57:40.853306+00:00
AquaVM version: 0.55.0
Benches:
Features:
big-values-data (19.30ms; 59.000 MiB, 59.000 MiB): Loading a trace with huge values
air::runner::execute_air: 19.30ms
preparation_step::preparation::parse_data: 6.94ms
try_from_slice: 6.90ms
preparation_step::preparation::prepare: 275.00µs
air::preparation_step::preparation::make_exec_ctx: 43.00µs
CallResultsRepr.deserialize: 11.00µs
air_parser::parser::air_parser::parse: 18.00µs
runner::execute: 17.00µs
runner::farewell: 5.50ms
from_success_result: 5.48ms
populate_outcome_from_contexts: 5.44ms
CallRequestsRepr.serialize: 14.00µs
InterpreterData::serialize: 4.13ms
signing_step::sign_produced_cids: 185.00µs
verification_step::verify: 6.24ms
verify: 5.63ms
call-requests500 (52.20ms; 70.562 MiB, 70.562 MiB): multiple call requests
air::runner::execute_air: 52.20ms
preparation_step::preparation::parse_data: 115.00µs
try_from_slice: 78.00µs
preparation_step::preparation::prepare: 315.00µs
air::preparation_step::preparation::make_exec_ctx: 62.00µs
CallResultsRepr.deserialize: 35.00µs
air_parser::parser::air_parser::parse: 47.00µs
runner::execute: 25.40ms
runner::farewell: 25.90ms
from_success_result: 25.90ms
populate_outcome_from_contexts: 25.70ms
CallRequestsRepr.serialize: 25.10ms
InterpreterData::serialize: 374.00µs
signing_step::sign_produced_cids: 196.00µs
verification_step::verify: 71.00µs
verify: 11.00µs
call-results500 (21.10ms; 54.438 MiB, 54.438 MiB): multiple call results
air::runner::execute_air: 21.10ms
preparation_step::preparation::parse_data: 657.00µs
try_from_slice: 615.00µs
preparation_step::preparation::prepare: 988.00µs
air::preparation_step::preparation::make_exec_ctx: 731.00µs
CallResultsRepr.deserialize: 700.00µs
big-values-data (19.20ms; 59.000 MiB, 59.000 MiB): Loading a trace with huge values
air::runner::execute_air: 19.20ms
preparation_step::preparation::parse_data: 7.01ms
try_from_slice: 6.96ms
preparation_step::preparation::prepare: 184.00µs
air::preparation_step::preparation::make_exec_ctx: 44.00µs
CallResultsRepr.deserialize: 10.00µs
air_parser::parser::air_parser::parse: 19.00µs
runner::execute: 9.00µs
runner::farewell: 5.81ms
from_success_result: 5.78ms
populate_outcome_from_contexts: 5.74ms
CallRequestsRepr.serialize: 15.00µs
InterpreterData::serialize: 4.44ms
signing_step::sign_produced_cids: 98.00µs
verification_step::verify: 5.99ms
verify: 5.66ms
call-requests500 (53.00ms; 70.562 MiB, 70.562 MiB): multiple call requests
air::runner::execute_air: 53.00ms
preparation_step::preparation::parse_data: 105.00µs
try_from_slice: 66.00µs
preparation_step::preparation::prepare: 235.00µs
air::preparation_step::preparation::make_exec_ctx: 60.00µs
CallResultsRepr.deserialize: 34.00µs
air_parser::parser::air_parser::parse: 48.00µs
runner::execute: 15.90ms
runner::farewell: 2.69ms
from_success_result: 2.66ms
populate_outcome_from_contexts: 2.22ms
CallRequestsRepr.serialize: 14.00µs
runner::execute: 25.00ms
runner::farewell: 27.30ms
from_success_result: 27.30ms
populate_outcome_from_contexts: 27.10ms
CallRequestsRepr.serialize: 26.50ms
InterpreterData::serialize: 377.00µs
signing_step::sign_produced_cids: 136.00µs
verification_step::verify: 64.00µs
verify: 10.00µs
call-results500 (21.20ms; 54.438 MiB, 54.438 MiB): multiple call results
air::runner::execute_air: 21.20ms
preparation_step::preparation::parse_data: 587.00µs
try_from_slice: 546.00µs
preparation_step::preparation::prepare: 895.00µs
air::preparation_step::preparation::make_exec_ctx: 718.00µs
CallResultsRepr.deserialize: 686.00µs
air_parser::parser::air_parser::parse: 50.00µs
runner::execute: 16.50ms
runner::farewell: 2.63ms
from_success_result: 2.60ms
populate_outcome_from_contexts: 2.15ms
CallRequestsRepr.serialize: 13.00µs
InterpreterData::serialize: 1.54ms
signing_step::sign_produced_cids: 548.00µs
signing_step::sign_produced_cids: 456.00µs
verification_step::verify: 67.00µs
verify: 9.00µs
verify: 10.00µs
canon-map-key-by-lens (16.00ms; 56.625 MiB, 56.625 MiB): benchmarking a map insert operation
air::runner::execute_air: 16.00ms
preparation_step::preparation::parse_data: 4.02ms
try_from_slice: 3.97ms
preparation_step::preparation::prepare: 623.00µs
air::preparation_step::preparation::make_exec_ctx: 360.00µs
preparation_step::preparation::parse_data: 4.07ms
try_from_slice: 4.01ms
preparation_step::preparation::prepare: 549.00µs
air::preparation_step::preparation::make_exec_ctx: 365.00µs
CallResultsRepr.deserialize: 10.00µs
air_parser::parser::air_parser::parse: 53.00µs
runner::execute: 2.82ms
air_parser::parser::air_parser::parse: 56.00µs
runner::execute: 2.84ms
runner::farewell: 3.49ms
from_success_result: 3.46ms
populate_outcome_from_contexts: 3.00ms
CallRequestsRepr.serialize: 15.00µs
InterpreterData::serialize: 2.55ms
signing_step::sign_produced_cids: 102.00µs
verification_step::verify: 4.84ms
verify: 4.51ms
canon-map-key-element-by-lens (17.10ms; 56.625 MiB, 56.625 MiB): benchmarking a map insert operation
air::runner::execute_air: 17.10ms
preparation_step::preparation::parse_data: 4.03ms
try_from_slice: 3.99ms
preparation_step::preparation::prepare: 868.00µs
air::preparation_step::preparation::make_exec_ctx: 614.00µs
CallResultsRepr.deserialize: 18.00µs
air_parser::parser::air_parser::parse: 90.00µs
runner::execute: 3.21ms
runner::farewell: 3.22ms
from_success_result: 3.19ms
populate_outcome_from_contexts: 2.79ms
CallRequestsRepr.serialize: 14.00µs
InterpreterData::serialize: 2.42ms
signing_step::sign_produced_cids: 108.00µs
verification_step::verify: 5.46ms
verify: 4.90ms
canon-map-multiple-keys (13.20ms; 54.500 MiB, 54.500 MiB): benchmarking a map insert operation
air::runner::execute_air: 13.20ms
preparation_step::preparation::parse_data: 326.00µs
try_from_slice: 286.00µs
preparation_step::preparation::prepare: 212.00µs
air::preparation_step::preparation::make_exec_ctx: 38.00µs
CallResultsRepr.deserialize: 10.00µs
air_parser::parser::air_parser::parse: 47.00µs
runner::execute: 9.08ms
runner::farewell: 3.05ms
from_success_result: 3.03ms
populate_outcome_from_contexts: 2.69ms
CallRequestsRepr.serialize: 15.00µs
InterpreterData::serialize: 2.33ms
signing_step::sign_produced_cids: 108.00µs
verification_step::verify: 337.00µs
verify: 25.00µs
canon-map-scalar-multiple-keys (4.91ms; 53.125 MiB, 53.125 MiB): benchmarking a map insert operation
air::runner::execute_air: 4.91ms
preparation_step::preparation::parse_data: 325.00µs
try_from_slice: 285.00µs
preparation_step::preparation::prepare: 205.00µs
air::preparation_step::preparation::make_exec_ctx: 37.00µs
CallResultsRepr.deserialize: 10.00µs
air_parser::parser::air_parser::parse: 44.00µs
runner::execute: 3.32ms
runner::farewell: 495.00µs
from_success_result: 473.00µs
populate_outcome_from_contexts: 435.00µs
CallRequestsRepr.serialize: 13.00µs
InterpreterData::serialize: 171.00µs
signing_step::sign_produced_cids: 101.00µs
verification_step::verify: 338.00µs
verify: 25.00µs
canon-map-scalar-single-key (4.26ms; 53.000 MiB, 53.000 MiB): benchmarking a map insert operation
air::runner::execute_air: 4.26ms
preparation_step::preparation::parse_data: 378.00µs
try_from_slice: 328.00µs
preparation_step::preparation::prepare: 205.00µs
air::preparation_step::preparation::make_exec_ctx: 37.00µs
CallResultsRepr.deserialize: 10.00µs
air_parser::parser::air_parser::parse: 43.00µs
runner::execute: 2.49ms
runner::farewell: 493.00µs
from_success_result: 471.00µs
populate_outcome_from_contexts: 418.00µs
CallRequestsRepr.serialize: 12.00µs
InterpreterData::serialize: 179.00µs
signing_step::sign_produced_cids: 103.00µs
verification_step::verify: 452.00µs
verify: 82.00µs
canon-map-single-key (11.60ms; 55.312 MiB, 55.312 MiB): benchmarking a map insert operation
air::runner::execute_air: 11.60ms
preparation_step::preparation::parse_data: 395.00µs
try_from_slice: 356.00µs
preparation_step::preparation::prepare: 205.00µs
air::preparation_step::preparation::make_exec_ctx: 42.00µs
CallResultsRepr.deserialize: 10.00µs
air_parser::parser::air_parser::parse: 41.00µs
runner::execute: 7.10ms
runner::farewell: 3.24ms
from_success_result: 3.22ms
populate_outcome_from_contexts: 2.81ms
CallRequestsRepr.serialize: 13.00µs
InterpreterData::serialize: 2.37ms
signing_step::sign_produced_cids: 186.00µs
verification_step::verify: 5.00ms
verify: 4.39ms
canon-map-key-element-by-lens (57.60ms; 56.625 MiB, 56.625 MiB): benchmarking a map insert operation
air::runner::execute_air: 57.60ms
preparation_step::preparation::parse_data: 8.23ms
try_from_slice: 8.09ms
preparation_step::preparation::prepare: 1.47ms
air::preparation_step::preparation::make_exec_ctx: 892.00µs
CallResultsRepr.deserialize: 26.00µs
air_parser::parser::air_parser::parse: 106.00µs
runner::execute: 7.37ms
runner::farewell: 20.60ms
from_success_result: 20.50ms
populate_outcome_from_contexts: 19.50ms
CallRequestsRepr.serialize: 44.00µs
InterpreterData::serialize: 18.30ms
signing_step::sign_produced_cids: 678.00µs
verification_step::verify: 18.80ms
verify: 17.50ms
canon-map-multiple-keys (62.20ms; 54.500 MiB, 54.500 MiB): benchmarking a map insert operation
air::runner::execute_air: 62.20ms
preparation_step::preparation::parse_data: 770.00µs
try_from_slice: 612.00µs
preparation_step::preparation::prepare: 617.00µs
air::preparation_step::preparation::make_exec_ctx: 101.00µs
CallResultsRepr.deserialize: 29.00µs
air_parser::parser::air_parser::parse: 88.00µs
runner::execute: 31.80ms
runner::farewell: 13.20ms
from_success_result: 9.57ms
populate_outcome_from_contexts: 8.79ms
CallRequestsRepr.serialize: 80.00µs
InterpreterData::serialize: 4.23ms
signing_step::sign_produced_cids: 376.00µs
verification_step::verify: 1.21ms
verify: 55.00µs
canon-map-scalar-multiple-keys (12.20ms; 53.125 MiB, 53.125 MiB): benchmarking a map insert operation
air::runner::execute_air: 12.20ms
preparation_step::preparation::parse_data: 728.00µs
try_from_slice: 612.00µs
preparation_step::preparation::prepare: 599.00µs
air::preparation_step::preparation::make_exec_ctx: 94.00µs
CallResultsRepr.deserialize: 26.00µs
air_parser::parser::air_parser::parse: 92.00µs
runner::execute: 7.29ms
runner::farewell: 1.55ms
from_success_result: 1.49ms
populate_outcome_from_contexts: 1.39ms
CallRequestsRepr.serialize: 50.00µs
InterpreterData::serialize: 332.00µs
signing_step::sign_produced_cids: 386.00µs
verification_step::verify: 1.24ms
verify: 64.00µs
canon-map-scalar-single-key (13.60ms; 53.000 MiB, 53.000 MiB): benchmarking a map insert operation
air::runner::execute_air: 13.60ms
preparation_step::preparation::parse_data: 3.23ms
try_from_slice: 2.39ms
preparation_step::preparation::prepare: 673.00µs
air::preparation_step::preparation::make_exec_ctx: 96.00µs
CallResultsRepr.deserialize: 26.00µs
air_parser::parser::air_parser::parse: 81.00µs
runner::execute: 5.26ms
runner::farewell: 1.25ms
from_success_result: 1.18ms
populate_outcome_from_contexts: 1.06ms
CallRequestsRepr.serialize: 34.00µs
InterpreterData::serialize: 339.00µs
signing_step::sign_produced_cids: 362.00µs
verification_step::verify: 1.36ms
verify: 133.00µs
canon-map-single-key (27.90ms; 55.312 MiB, 55.312 MiB): benchmarking a map insert operation
air::runner::execute_air: 27.90ms
preparation_step::preparation::parse_data: 773.00µs
try_from_slice: 668.00µs
preparation_step::preparation::prepare: 745.00µs
air::preparation_step::preparation::make_exec_ctx: 104.00µs
CallResultsRepr.deserialize: 28.00µs
air_parser::parser::air_parser::parse: 83.00µs
runner::execute: 17.00ms
runner::farewell: 7.10ms
from_success_result: 7.00ms
populate_outcome_from_contexts: 6.33ms
CallRequestsRepr.serialize: 60.00µs
InterpreterData::serialize: 5.24ms
signing_step::sign_produced_cids: 396.00µs
verification_step::verify: 1.40ms
verify: 137.00µs
dashboard (25.50ms; 52.625 MiB, 52.625 MiB): big dashboard test
air::runner::execute_air: 25.50ms
preparation_step::preparation::parse_data: 8.05ms
try_from_slice: 7.82ms
preparation_step::preparation::prepare: 993.00µs
air::preparation_step::preparation::make_exec_ctx: 182.00µs
CallResultsRepr.deserialize: 33.00µs
air_parser::parser::air_parser::parse: 297.00µs
runner::execute: 2.53ms
runner::farewell: 1.85ms
from_success_result: 1.78ms
populate_outcome_from_contexts: 1.66ms
CallRequestsRepr.serialize: 82.00µs
InterpreterData::serialize: 859.00µs
signing_step::sign_produced_cids: 443.00µs
verification_step::verify: 11.10ms
verify: 484.00µs
long-data (16.20ms; 53.812 MiB, 53.812 MiB): Long data trace
air::runner::execute_air: 16.20ms
preparation_step::preparation::parse_data: 4.14ms
try_from_slice: 4.00ms
preparation_step::preparation::prepare: 667.00µs
air::preparation_step::preparation::make_exec_ctx: 168.00µs
CallResultsRepr.deserialize: 29.00µs
air_parser::parser::air_parser::parse: 42.00µs
runner::execute: 27.00µs
runner::farewell: 3.00ms
from_success_result: 2.94ms
populate_outcome_from_contexts: 2.82ms
CallRequestsRepr.serialize: 40.00µs
InterpreterData::serialize: 1.36ms
signing_step::sign_produced_cids: 373.00µs
verification_step::verify: 7.58ms
verify: 4.10ms
multiple-cids10 (9.58ms; 52.438 MiB, 52.438 MiB): verifying multiple CIDs for single peer
air::runner::execute_air: 9.58ms
preparation_step::preparation::parse_data: 950.00µs
try_from_slice: 804.00µs
preparation_step::preparation::prepare: 1.21ms
air::preparation_step::preparation::make_exec_ctx: 139.00µs
CallResultsRepr.deserialize: 27.00µs
air_parser::parser::air_parser::parse: 395.00µs
runner::execute: 1.17ms
runner::farewell: 1.26ms
from_success_result: 1.19ms
populate_outcome_from_contexts: 1.07ms
CallRequestsRepr.serialize: 36.00µs
InterpreterData::serialize: 459.00µs
signing_step::sign_produced_cids: 406.00µs
verification_step::verify: 4.12ms
verify: 512.00µs
multiple-peers8 (32.90ms; 53.375 MiB, 53.375 MiB): verifying many CIDs for many peers
air::runner::execute_air: 32.90ms
preparation_step::preparation::parse_data: 3.59ms
try_from_slice: 3.41ms
preparation_step::preparation::prepare: 1.34ms
air::preparation_step::preparation::make_exec_ctx: 362.00µs
CallResultsRepr.deserialize: 28.00µs
air_parser::parser::air_parser::parse: 445.00µs
runner::execute: 8.54ms
runner::farewell: 3.83ms
from_success_result: 3.77ms
populate_outcome_from_contexts: 3.54ms
CallRequestsRepr.serialize: 41.00µs
InterpreterData::serialize: 2.67ms
signing_step::sign_produced_cids: 414.00µs
verification_step::verify: 14.70ms
verify: 2.37ms
multiple-sigs30 (64.60ms; 56.188 MiB, 56.188 MiB): signing multiple CIDs
air::runner::execute_air: 64.60ms
preparation_step::preparation::parse_data: 11.90ms
try_from_slice: 11.69ms
preparation_step::preparation::prepare: 1.54ms
air::preparation_step::preparation::make_exec_ctx: 815.00µs
CallResultsRepr.deserialize: 31.00µs
air_parser::parser::air_parser::parse: 100.00µs
runner::execute: 26.90ms
runner::farewell: 11.30ms
from_success_result: 11.20ms
populate_outcome_from_contexts: 10.80ms
CallRequestsRepr.serialize: 44.00µs
InterpreterData::serialize: 7.67ms
signing_step::sign_produced_cids: 1.63ms
verification_step::verify: 10.80ms
verify: 4.52ms
network-explore (10.30ms; 52.375 MiB, 52.375 MiB): 5 peers of network are discovered
air::runner::execute_air: 10.30ms
preparation_step::preparation::parse_data: 1.42ms
try_from_slice: 1.25ms
preparation_step::preparation::prepare: 702.00µs
air::preparation_step::preparation::make_exec_ctx: 114.00µs
CallResultsRepr.deserialize: 28.00µs
air_parser::parser::air_parser::parse: 142.00µs
runner::execute: 336.00µs
runner::farewell: 1.07ms
from_success_result: 1.00ms
populate_outcome_from_contexts: 896.00µs
CallRequestsRepr.serialize: 38.00µs
InterpreterData::serialize: 312.00µs
signing_step::sign_produced_cids: 385.00µs
verification_step::verify: 5.94ms
verify: 128.00µs
null (12.90ms; 52.375 MiB, 52.375 MiB): Empty data and null script
air::runner::execute_air: 12.90ms
preparation_step::preparation::parse_data: 84.00µs
preparation_step::preparation::prepare: 599.00µs
air::preparation_step::preparation::make_exec_ctx: 95.00µs
CallResultsRepr.deserialize: 28.00µs
air_parser::parser::air_parser::parse: 39.00µs
runner::execute: 30.00µs
runner::farewell: 797.00µs
from_success_result: 730.00µs
populate_outcome_from_contexts: 642.00µs
CallRequestsRepr.serialize: 37.00µs
InterpreterData::serialize: 99.00µs
signing_step::sign_produced_cids: 433.00µs
verification_step::verify: 114.00µs
verify: 41.00µs
parser-10000-100 (68.60ms; 54.625 MiB, 54.625 MiB): long air script with lot of variable assignments
air::runner::execute_air: 68.60ms
preparation_step::preparation::parse_data: 48.00µs
preparation_step::preparation::prepare: 65.20ms
air::preparation_step::preparation::make_exec_ctx: 118.00µs
CallResultsRepr.deserialize: 33.00µs
air_parser::parser::air_parser::parse: 64.60ms
runner::execute: 56.00µs
runner::farewell: 843.00µs
from_success_result: 776.00µs
populate_outcome_from_contexts: 687.00µs
CallRequestsRepr.serialize: 38.00µs
InterpreterData::serialize: 108.00µs
signing_step::sign_produced_cids: 416.00µs
verification_step::verify: 96.00µs
verify: 29.00µs
parser-calls-10000-100 (55.80ms; 54.375 MiB, 54.375 MiB): multiple calls parser benchmark
air::runner::execute_air: 55.80ms
preparation_step::preparation::parse_data: 44.00µs
preparation_step::preparation::prepare: 51.90ms
air::preparation_step::preparation::make_exec_ctx: 100.00µs
CallResultsRepr.deserialize: 28.00µs
air_parser::parser::air_parser::parse: 51.30ms
runner::execute: 51.00µs
runner::farewell: 708.00µs
from_success_result: 657.00µs
populate_outcome_from_contexts: 585.00µs
CallRequestsRepr.serialize: 29.00µs
InterpreterData::serialize: 88.00µs
signing_step::sign_produced_cids: 366.00µs
verification_step::verify: 80.00µs
verify: 24.00µs
populate-map-multiple-keys (10.50ms; 53.000 MiB, 53.000 MiB): benchmarking a map insert operation
air::runner::execute_air: 10.50ms
preparation_step::preparation::parse_data: 301.00µs
try_from_slice: 198.00µs
preparation_step::preparation::prepare: 713.00µs
air::preparation_step::preparation::make_exec_ctx: 104.00µs
CallResultsRepr.deserialize: 29.00µs
air_parser::parser::air_parser::parse: 101.00µs
runner::execute: 6.05ms
runner::farewell: 1.30ms
from_success_result: 1.23ms
populate_outcome_from_contexts: 1.13ms
CallRequestsRepr.serialize: 41.00µs
InterpreterData::serialize: 465.00µs
signing_step::sign_produced_cids: 403.00µs
verification_step::verify: 1.27ms
verify: 57.00µs
populate-map-single-key (8.85ms; 52.938 MiB, 52.938 MiB): benchmarking a map insert operation
air::runner::execute_air: 8.85ms
preparation_step::preparation::parse_data: 420.00µs
try_from_slice: 317.00µs
preparation_step::preparation::prepare: 668.00µs
air::preparation_step::preparation::make_exec_ctx: 115.00µs
CallResultsRepr.deserialize: 28.00µs
air_parser::parser::air_parser::parse: 89.00µs
runner::execute: 4.29ms
runner::farewell: 1.21ms
populate_outcome_from_contexts: 2.92ms
CallRequestsRepr.serialize: 14.00µs
InterpreterData::serialize: 2.59ms
signing_step::sign_produced_cids: 114.00µs
verification_step::verify: 383.00µs
verify: 67.00µs
dashboard (6.67ms; 52.625 MiB, 52.625 MiB): big dashboard test
air::runner::execute_air: 6.67ms
preparation_step::preparation::parse_data: 1.05ms
try_from_slice: 986.00µs
preparation_step::preparation::prepare: 336.00µs
air::preparation_step::preparation::make_exec_ctx: 63.00µs
CallResultsRepr.deserialize: 10.00µs
air_parser::parser::air_parser::parse: 138.00µs
runner::execute: 1.41ms
runner::farewell: 805.00µs
from_success_result: 784.00µs
populate_outcome_from_contexts: 736.00µs
CallRequestsRepr.serialize: 28.00µs
InterpreterData::serialize: 496.00µs
signing_step::sign_produced_cids: 108.00µs
verification_step::verify: 2.82ms
verify: 213.00µs
long-data (6.39ms; 53.812 MiB, 53.812 MiB): Long data trace
air::runner::execute_air: 6.39ms
preparation_step::preparation::parse_data: 2.40ms
try_from_slice: 2.36ms
preparation_step::preparation::prepare: 203.00µs
air::preparation_step::preparation::make_exec_ctx: 65.00µs
CallResultsRepr.deserialize: 10.00µs
air_parser::parser::air_parser::parse: 17.00µs
runner::execute: 9.00µs
runner::farewell: 1.16ms
from_success_result: 1.13ms
populate_outcome_from_contexts: 1.01ms
CallRequestsRepr.serialize: 34.00µs
InterpreterData::serialize: 390.00µs
signing_step::sign_produced_cids: 427.00µs
verification_step::verify: 1.42ms
verify: 144.00µs
populate_outcome_from_contexts: 1.10ms
CallRequestsRepr.serialize: 14.00µs
InterpreterData::serialize: 589.00µs
signing_step::sign_produced_cids: 100.00µs
verification_step::verify: 2.39ms
verify: 943.00µs
multiple-cids10 (3.07ms; 52.438 MiB, 52.438 MiB): verifying multiple CIDs for single peer
air::runner::execute_air: 3.07ms
preparation_step::preparation::parse_data: 420.00µs
try_from_slice: 364.00µs
preparation_step::preparation::prepare: 221.00µs
air::preparation_step::preparation::make_exec_ctx: 55.00µs
CallResultsRepr.deserialize: 11.00µs
air_parser::parser::air_parser::parse: 43.00µs
runner::execute: 574.00µs
runner::farewell: 622.00µs
from_success_result: 600.00µs
populate_outcome_from_contexts: 544.00µs
CallRequestsRepr.serialize: 15.00µs
InterpreterData::serialize: 329.00µs
signing_step::sign_produced_cids: 102.00µs
verification_step::verify: 1.01ms
verify: 253.00µs
multiple-peers8 (12.00ms; 53.375 MiB, 53.375 MiB): verifying many CIDs for many peers
air::runner::execute_air: 12.00ms
preparation_step::preparation::parse_data: 1.60ms
try_from_slice: 1.53ms
preparation_step::preparation::prepare: 330.00µs
air::preparation_step::preparation::make_exec_ctx: 152.00µs
CallResultsRepr.deserialize: 10.00µs
air_parser::parser::air_parser::parse: 50.00µs
runner::execute: 3.96ms
runner::farewell: 1.57ms
from_success_result: 1.55ms
populate_outcome_from_contexts: 1.43ms
CallRequestsRepr.serialize: 14.00µs
InterpreterData::serialize: 1.16ms
signing_step::sign_produced_cids: 104.00µs
verification_step::verify: 4.30ms
verify: 1.18ms
multiple-sigs30 (26.20ms; 56.188 MiB, 56.188 MiB): signing multiple CIDs
air::runner::execute_air: 26.20ms
preparation_step::preparation::parse_data: 4.93ms
try_from_slice: 4.88ms
preparation_step::preparation::prepare: 438.00µs
air::preparation_step::preparation::make_exec_ctx: 261.00µs
CallResultsRepr.deserialize: 10.00µs
air_parser::parser::air_parser::parse: 49.00µs
runner::execute: 11.10ms
runner::farewell: 4.39ms
from_success_result: 4.37ms
populate_outcome_from_contexts: 4.17ms
CallRequestsRepr.serialize: 14.00µs
InterpreterData::serialize: 3.04ms
signing_step::sign_produced_cids: 742.00µs
verification_step::verify: 4.36ms
verify: 2.03ms
network-explore (3.35ms; 52.375 MiB, 52.375 MiB): 5 peers of network are discovered
air::runner::execute_air: 3.35ms
preparation_step::preparation::parse_data: 596.00µs
try_from_slice: 509.00µs
preparation_step::preparation::prepare: 249.00µs
air::preparation_step::preparation::make_exec_ctx: 46.00µs
CallResultsRepr.deserialize: 10.00µs
air_parser::parser::air_parser::parse: 74.00µs
runner::execute: 168.00µs
runner::farewell: 441.00µs
from_success_result: 418.00µs
populate_outcome_from_contexts: 376.00µs
CallRequestsRepr.serialize: 14.00µs
InterpreterData::serialize: 199.00µs
signing_step::sign_produced_cids: 105.00µs
verification_step::verify: 1.64ms
verify: 99.00µs
null (712.00µs; 52.375 MiB, 52.375 MiB): Empty data and null script
air::runner::execute_air: 712.00µs
preparation_step::preparation::parse_data: 16.00µs
preparation_step::preparation::prepare: 183.00µs
air::preparation_step::preparation::make_exec_ctx: 35.00µs
CallResultsRepr.deserialize: 10.00µs
air_parser::parser::air_parser::parse: 17.00µs
runner::execute: 9.00µs
runner::farewell: 257.00µs
from_success_result: 237.00µs
populate_outcome_from_contexts: 204.00µs
CallRequestsRepr.serialize: 13.00µs
InterpreterData::serialize: 51.00µs
signing_step::sign_produced_cids: 101.00µs
verification_step::verify: 32.00µs
verify: 10.00µs
parser-10000-100 (31.70ms; 54.625 MiB, 54.625 MiB): long air script with lot of variable assignments
air::runner::execute_air: 31.70ms
preparation_step::preparation::parse_data: 16.00µs
preparation_step::preparation::prepare: 30.40ms
air::preparation_step::preparation::make_exec_ctx: 43.00µs
CallResultsRepr.deserialize: 12.00µs
air_parser::parser::air_parser::parse: 30.10ms
runner::execute: 27.00µs
runner::farewell: 284.00µs
from_success_result: 262.00µs
populate_outcome_from_contexts: 220.00µs
CallRequestsRepr.serialize: 12.00µs
InterpreterData::serialize: 56.00µs
signing_step::sign_produced_cids: 101.00µs
verification_step::verify: 33.00µs
verify: 10.00µs
parser-calls-10000-100 (26.50ms; 54.375 MiB, 54.375 MiB): multiple calls parser benchmark
air::runner::execute_air: 26.50ms
preparation_step::preparation::parse_data: 17.00µs
preparation_step::preparation::prepare: 24.80ms
air::preparation_step::preparation::make_exec_ctx: 44.00µs
CallResultsRepr.deserialize: 11.00µs
air_parser::parser::air_parser::parse: 24.60ms
runner::execute: 31.00µs
runner::farewell: 414.00µs
from_success_result: 379.00µs
populate_outcome_from_contexts: 327.00µs
CallRequestsRepr.serialize: 21.00µs
InterpreterData::serialize: 71.00µs
signing_step::sign_produced_cids: 156.00µs
verification_step::verify: 34.00µs
verify: 10.00µs
populate-map-multiple-keys (4.10ms; 53.000 MiB, 53.000 MiB): benchmarking a map insert operation
air::runner::execute_air: 4.10ms
preparation_step::preparation::parse_data: 116.00µs
try_from_slice: 72.00µs
preparation_step::preparation::prepare: 212.00µs
air::preparation_step::preparation::make_exec_ctx: 40.00µs
CallResultsRepr.deserialize: 10.00µs
air_parser::parser::air_parser::parse: 50.00µs
runner::execute: 2.78ms
runner::farewell: 414.00µs
from_success_result: 393.00µs
populate_outcome_from_contexts: 356.00µs
CallRequestsRepr.serialize: 13.00µs
InterpreterData::serialize: 165.00µs
signing_step::sign_produced_cids: 101.00µs
verification_step::verify: 336.00µs
verify: 26.00µs
populate-map-single-key (3.40ms; 52.938 MiB, 52.938 MiB): benchmarking a map insert operation
air::runner::execute_air: 3.40ms
preparation_step::preparation::parse_data: 170.00µs
try_from_slice: 131.00µs
preparation_step::preparation::prepare: 216.00µs
air::preparation_step::preparation::make_exec_ctx: 39.00µs
CallResultsRepr.deserialize: 10.00µs
air_parser::parser::air_parser::parse: 50.00µs
runner::execute: 1.95ms
runner::farewell: 436.00µs
from_success_result: 412.00µs
populate_outcome_from_contexts: 360.00µs
CallRequestsRepr.serialize: 13.00µs
InterpreterData::serialize: 179.00µs
signing_step::sign_produced_cids: 105.00µs
verification_step::verify: 401.00µs
verify: 68.00µs
Machine c1f3ea5950db0a10b44da931c25774d64ab25084f47d504f72f311e694550ff1:
Platform: macOS-12.0.1-x86_64-i386-64bit
Timestamp: 2023-02-13 13:19:34.106863+00:00

View File

@ -72,10 +72,30 @@ Instr: Instruction<'input> = {
Instruction::ApMap(apply.into())
},
"(" seq <l:Instr> <r:Instr> ")" => Instruction::Seq(Seq::new(l, r).into()),
"(" par <l:Instr> <r:Instr> ")" => Instruction::Par(Par::new(l, r).into()),
"(" never ")" => Instruction::Never(Never),
"(" null ")" => Instruction::Null(Null),
<left: @L> "(" seq <l:Instr> <r:Instr> ")" <right: @R> => {
let span = Span::new(left, right);
validator.met_merging_instr(span);
Instruction::Seq(Seq::new(l, r).into())
},
<left: @L> "(" par <l:Instr> <r:Instr> ")" <right: @R> => {
let span = Span::new(left, right);
validator.met_merging_instr(span);
Instruction::Par(Par::new(l, r).into())
},
<left: @L> "(" never ")" <right: @R> => {
let span = Span::new(left, right);
validator.met_simple_instr(span);
Instruction::Never(Never)
},
<left: @L> "(" null ")" <right: @R> => {
let span = Span::new(left, right);
validator.met_simple_instr(span);
Instruction::Null(Null)
},
<left: @L> "(" new <argument: NewArgument> <instruction:Instr> ")" <right: @R> => {
let span = Span::new(left, right);
@ -132,7 +152,12 @@ Instr: Instruction<'input> = {
Instruction::Next(next.into())
},
"(" xor <l:Instr> <r:Instr> ")" => Instruction::Xor(Xor(l, r).into()),
<left: @L> "(" xor <l:Instr> <r:Instr> ")" <right: @R> => {
let span = Span::new(left, right);
validator.met_xoring_instr(span);
Instruction::Xor(Xor(l, r).into())
},
<left: @L> "(" match_ <l:Value> <r:Value> <i:Instr> ")" <right: @R> => {
let match_ = Match::new(l, r, i);

File diff suppressed because it is too large Load Diff

View File

@ -56,6 +56,9 @@ pub enum ParserError {
#[error("error code 0 with fail is unsupported")]
UnsupportedLiteralErrCodes { span: Span },
#[error("fold can not have instructions after next")]
FoldHasInstructionAfterNext(Span),
}
impl ParserError {
@ -71,6 +74,7 @@ impl ParserError {
Self::MultipleNextInFold { span, .. } => *span,
Self::UnsupportedMapKeyType { span, .. } => *span,
Self::UnsupportedLiteralErrCodes { span } => *span,
Self::FoldHasInstructionAfterNext(span) => *span,
}
}
@ -124,6 +128,10 @@ impl ParserError {
pub fn unsupported_literal_errcodes(span: Span) -> Self {
Self::UnsupportedLiteralErrCodes { span }
}
pub fn fold_has_instruction_after_next(span: Span) -> Self {
Self::FoldHasInstructionAfterNext(span)
}
}
impl From<std::convert::Infallible> for ParserError {

View File

@ -489,3 +489,961 @@ fn fold_on_canon_stream_map() {
);
assert_eq!(instruction, expected);
}
#[test]
fn fold_on_scalar_with_subtree_and_next() {
let source_code = r#"
(seq
(call "" ("" "") [] iterable)
(fold iterable i
(seq
(seq
(call "" ("" "") ["hello" ""] $void)
(call "" ("" "") ["hello" ""] $voida)
)
(next i)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 0);
}
#[test]
fn fold_on_scalar_with_next_in_a_fold() {
let source_code = r#"
(seq
(seq
(call "" ("" "") [] iterable1)
(call "" ("" "") [] iterable2)
)
(fold iterable1 i
(seq
(fold iterable2 it
(call "" ("" "") ["hello" ""] $void)
)
(next i)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 0);
}
#[test]
fn fold_on_scalar_with_next() {
let source_code = r#"
(seq
(call "" ("" "") [] iterable)
(fold iterable i
(seq
(next i)
(call "" ("" "") ["hello" ""] $void)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 0);
}
#[test]
fn fold_on_scalar_with_next_in_a_fold1() {
let source_code = r#"
(seq
(seq
(call "" ("" "") [] iterable1)
(call "" ("" "") [] iterable2)
)
(fold iterable1 i
(seq
(fold iterable2 it
(seq
(next i)
(call "" ("" "") ["hello" ""] $void)
)
)
(call "" ("" "") ["hello" ""] $voida)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 0);
}
#[test]
fn fold_on_scalar_with_next_in_a_fold2() {
let source_code = r#"
(seq
(seq
(call "" ("" "") [] iterable1)
(call "" ("" "") [] iterable2)
)
(fold iterable1 i
(seq
(fold iterable2 it
(seq
(call "" ("" "") ["hello" ""] $void)
(next i)
)
)
(call "" ("" "") ["hello" ""] $voida)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 0);
}
#[test]
fn fold_on_scalar_with_next_in_a_branch1() {
let source_code = r#"
(seq
(call "" ("" "") [] iterable)
(fold iterable i
(seq
(seq
(call "" ("" "") ["hello" ""] $void)
(next i)
)
(call "" ("" "") ["hello" ""] $voida)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 0);
}
#[test]
fn fold_on_scalar_with_next_in_a_branch2() {
let source_code = r#"
(seq
(call "" ("" "") [] $iterable)
(fold $iterable i
(seq
(call "" ("" "") ["hello" ""] $voida)
(seq
(next i)
(call "" ("" "") ["hello" ""] $void)
)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
dbg!(&errors);
assert_eq!(errors.len(), 1);
let error = &errors[0].error;
let parser_error = match error {
ParseError::User { error } => error,
_ => panic!("unexpected error type"),
};
assert!(matches!(
parser_error,
ParserError::FoldHasInstructionAfterNext { .. }
));
}
#[test]
fn fold_on_stream_with_subtree_and_next() {
let source_code = r#"
(seq
(call "" ("" "") [] $iterable)
(fold $iterable i
(seq
(seq
(call "" ("" "") ["hello" ""] $void)
(call "" ("" "") ["hello" ""] $voida)
)
(next i)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 0);
}
#[test]
fn fold_on_stream_with_next_in_a_fold() {
let source_code = r#"
(seq
(seq
(call "" ("" "") [] $iterable1)
(call "" ("" "") [] $iterable2)
)
(fold $iterable1 i
(seq
(fold $iterable2 it
(call "" ("" "") ["hello" ""] $void)
)
(next i)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 0);
}
#[test]
fn fold_on_stream_with_next_neg() {
let source_code = r#"
(seq
(call "" ("" "") [] $iterable)
(fold $iterable i
(seq
(next i)
(call "" ("" "") ["hello" ""] $void)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
dbg!(&errors);
assert_eq!(errors.len(), 1);
let error = &errors[0].error;
let parser_error = match error {
ParseError::User { error } => error,
_ => panic!("unexpected error type"),
};
assert!(matches!(
parser_error,
ParserError::FoldHasInstructionAfterNext { .. }
));
}
#[test]
fn fold_on_stream_with_next_in_a_fold1() {
let source_code = r#"
(seq
(seq
(call "" ("" "") [] $iterable1)
(call "" ("" "") [] $iterable2)
)
(fold $iterable1 i
(seq
(fold $iterable2 it
(seq
(next i)
(call "" ("" "") ["hello" ""] $void)
)
)
(call "" ("" "") ["hello" ""] $voida)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
dbg!(&errors);
assert_eq!(errors.len(), 1);
let error = &errors[0].error;
let parser_error = match error {
ParseError::User { error } => error,
_ => panic!("unexpected error type"),
};
assert!(matches!(
parser_error,
ParserError::FoldHasInstructionAfterNext { .. }
));
}
#[test]
fn fold_on_stream_with_next_in_a_fold2() {
let source_code = r#"
(seq
(seq
(call "" ("" "") [] $iterable1)
(call "" ("" "") [] $iterable2)
)
(fold $iterable1 i
(seq
(fold $iterable2 it
(seq
(call "" ("" "") ["hello" ""] $void)
(next i)
)
)
(call "" ("" "") ["hello" ""] $voida)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
dbg!(&errors); // WIP remove all
assert_eq!(errors.len(), 1);
let error = &errors[0].error;
let parser_error = match error {
ParseError::User { error } => error,
_ => panic!("unexpected error type"),
};
assert!(matches!(
parser_error,
ParserError::FoldHasInstructionAfterNext { .. }
));
}
#[test]
fn fold_on_stream_with_next_in_a_branch1_neg() {
let source_code = r#"
(seq
(call "" ("" "") [] $iterable)
(fold $iterable i
(seq
(seq
(call "" ("" "") ["hello" ""] $void)
(next i)
)
(call "" ("" "") ["hello" ""] $voida)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
dbg!(&errors);
assert_eq!(errors.len(), 1);
let error = &errors[0].error;
let parser_error = match error {
ParseError::User { error } => error,
_ => panic!("unexpected error type"),
};
assert!(matches!(
parser_error,
ParserError::FoldHasInstructionAfterNext { .. }
));
}
#[test]
fn fold_on_stream_with_next_in_a_branch2_neg() {
let source_code = r#"
(seq
(call "" ("" "") [] $iterable)
(fold $iterable i
(seq
(call "" ("" "") ["hello" ""] $voida)
(seq
(next i)
(call "" ("" "") ["hello" ""] $void)
)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
dbg!(&errors);
assert_eq!(errors.len(), 1);
let error = &errors[0].error;
let parser_error = match error {
ParseError::User { error } => error,
_ => panic!("unexpected error type"),
};
assert!(matches!(
parser_error,
ParserError::FoldHasInstructionAfterNext { .. }
));
}
#[test]
fn fold_on_stream_with_xor() {
let source_code = r#"
(seq
(call "" ("" "") [] $iterable)
(fold $iterable i
(xor
(next i)
(call "" ("" "") ["hello" ""] $void)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 0);
}
#[test]
fn fold_on_stream_with_xor_and_par() {
let source_code = r#"
(seq
(call "" ("" "") [] $iterable)
(fold $iterable i
(xor
(par
(ap 42 some)
(next i)
)
(par
(call "" ("" "") ["hello" ""] $void)
(ap 42 some)
)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 0);
}
#[test]
fn fold_on_stream_multiple_folds_same_iter_names() {
let source_code = r#"
(seq
(call "" ("" "") [] $iterable)
(seq
(fold $iterable i
(seq
(ap 42 scalar)
(next i)
)
)
(fold $iterable i
(seq
(ap 42 scalar)
(next i)
)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 0);
}
#[test]
fn fold_on_stream_with_next_in_a_fold1_neg() {
let source_code = r#"
(seq
(seq
(call "" ("" "") [] $iterable1)
(call "" ("" "") [] $iterable2)
)
(fold $iterable1 i
(seq
(fold $iterable2 it
(seq
(next i)
(call "" ("" "") ["hello" ""] $void)
)
)
(call "" ("" "") ["hello" ""] $voida)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 1);
let error = &errors[0].error;
let parser_error = match error {
ParseError::User { error } => error,
_ => panic!("unexpected error type"),
};
assert!(matches!(
parser_error,
ParserError::FoldHasInstructionAfterNext { .. }
));
}
#[test]
fn fold_on_stream_with_next_in_a_fold2_neg() {
let source_code = r#"
(seq
(seq
(call "" ("" "") [] $iterable1)
(call "" ("" "") [] $iterable2)
)
(fold $iterable1 i
(seq
(fold $iterable2 it
(seq
(call "" ("" "") ["hello" ""] $void)
(next i)
)
)
(call "" ("" "") ["hello" ""] $voida)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 1);
let error = &errors[0].error;
let parser_error = match error {
ParseError::User { error } => error,
_ => panic!("unexpected error type"),
};
assert!(matches!(
parser_error,
ParserError::FoldHasInstructionAfterNext { .. }
));
}
#[test]
fn fold_on_stream_multiple_folds_same_iter_names_neg() {
let source_code = r#"
(seq
(call "" ("" "") [] $iterable)
(seq
(fold $iterable i
(seq
(next i)
(ap 42 scalar)
)
)
(fold $iterable i
(seq
(next i)
(ap 42 scalar)
)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 2);
errors.iter().map(|e| &e.error).for_each(|error| {
let parser_error = match error {
ParseError::User { error } => error,
_ => panic!("unexpected error type"),
};
assert!(matches!(
parser_error,
ParserError::FoldHasInstructionAfterNext { .. }
));
})
}
#[test]
fn fold_on_stream_with_xor_and_par_neg() {
let source_code = r#"
(seq
(call "" ("" "") [] $iterable)
(fold $iterable i
(xor
(par
(next i)
(ap 42 some)
)
(par
(call "" ("" "") ["hello" ""] $void)
(ap 42 some)
)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 1);
let error = &errors[0].error;
let parser_error = match error {
ParseError::User { error } => error,
_ => panic!("unexpected error type"),
};
assert!(matches!(
parser_error,
ParserError::FoldHasInstructionAfterNext { .. }
));
}
#[test]
fn fold_on_stream_with_xor_and_nested_fold_neg_1() {
let source_code = r#"
(seq
(call "" ("" "") [] $iterable)
(fold $iterable i
(xor
(seq
(fold $iterable it
(seq
(next it)
(ap 42 some)
)
)
(next i)
)
(seq
(call "" ("" "") ["hello" ""] $void)
(ap 42 some)
)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 1);
let error = &errors[0].error;
let parser_error = match error {
ParseError::User { error } => error,
_ => panic!("unexpected error type"),
};
assert!(matches!(
parser_error,
ParserError::FoldHasInstructionAfterNext { .. }
));
}
#[test]
fn fold_on_stream_with_xor_and_nested_fold_2() {
let source_code = r#"
(seq
(call "" ("" "") [] $iterable)
(fold $iterable i
(seq
(ap 42 some)
(xor
(next i)
(fold $iterable it
(seq
(ap 42 some)
(next it)
)
)
)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 0);
}
#[test]
fn fold_on_stream_with_xor_and_nested_fold_neg_2() {
let source_code = r#"
(seq
(call "" ("" "") [] $iterable)
(fold $iterable i
(seq
(xor
(next i)
(fold $iterable it
(seq
(next it)
(ap 42 some)
)
)
)
(ap 42 some)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 2);
errors.iter().map(|e| &e.error).for_each(|error| {
let parser_error = match error {
ParseError::User { error } => error,
_ => panic!("unexpected error type"),
};
assert!(matches!(
parser_error,
ParserError::FoldHasInstructionAfterNext { .. }
));
})
}
#[test]
fn fold_on_stream_with_multiple_folds() {
let source_code = r#"
(new $inner
(seq
(par
(fold $inner ns
(seq
(ap ns $result)
(next ns)
)
)
(null)
)
(par
(fold $inner ns
(next ns)
)
(null)
)
)
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
dbg!(errors.clone());
assert_eq!(errors.len(), 0);
}

View File

@ -30,6 +30,217 @@ use multimap::MultiMap;
use std::collections::HashMap;
use std::ops::Deref;
#[derive(Clone, Copy, Debug)]
pub enum CheckInstructionKind<'names> {
PivotalNext(&'names str),
Merging,
PopStack1,
PopStack2,
Replacing,
ReplacingWithCheck(&'names str),
Xoring,
PopStack1ReplacingWithCheck(&'names str),
Simple,
}
/// This machine is used to check that there are no instructions after next
/// in a fold block over stream and map, e.g.
/// (fold $iterable iterator
/// (seq
/// (next iterator)
/// (call ...) <- instruction after next
/// )
/// )
/// Note that the fold over scalar doesn't have this restriction.
#[derive(Clone, Debug)]
struct AfterNextCheckMachine<'name> {
/// stack for the machine.
stack: Vec<(CheckInstructionKind<'name>, Span)>,
/// lalrpop parses AIR so that `next`
/// is met before `fold``. At the moment when `next` is met
/// it is impossible to tell whether it belongs to a stream/map fold or not.
/// This field stores iterator name to span mapping to be used when `fold` is met.
potentially_malformed_spans: HashMap<&'name str, Span>,
/// This vector contains all spans where an instruction after next was met.
malformed_spans: Vec<Span>,
/// This flag disables the machine if invariants are broken, e.g. par/seq must see
/// at least 2 instruction kinds in the stack.
is_enabled: bool,
}
impl<'name> Default for AfterNextCheckMachine<'name> {
fn default() -> Self {
Self {
stack: Default::default(),
potentially_malformed_spans: Default::default(),
malformed_spans: Default::default(),
is_enabled: true,
}
}
}
impl<'name> AfterNextCheckMachine<'name> {
fn disable(&mut self) {
self.stack.clear();
self.is_enabled = false;
}
fn malformed_spans_iter(&self) -> std::slice::Iter<Span> {
self.malformed_spans.iter()
}
fn met_instruction_kind(&mut self, instr_kind: CheckInstructionKind<'name>, span: Span) {
use CheckInstructionKind::*;
if !self.is_enabled {
return;
}
match instr_kind {
CheckInstructionKind::Replacing => {
self.process_replacing(span);
}
CheckInstructionKind::Xoring => {
self.process_xoring(span);
}
CheckInstructionKind::Merging => {
self.process_merging(span);
}
CheckInstructionKind::ReplacingWithCheck(iterator_name) => {
self.replacing_with_check_common(iterator_name, span, &instr_kind);
}
PopStack1ReplacingWithCheck(iterator_name) => {
self.stack.pop();
self.replacing_with_check_common(iterator_name, span, &instr_kind);
}
PivotalNext(_) | Simple => self.stack.push((instr_kind, span)),
PopStack1 => {
self.stack.pop();
self.stack.push((instr_kind, span))
}
PopStack2 => {
self.stack.pop();
self.stack.pop();
self.stack.push((instr_kind, span))
}
}
}
fn process_replacing(&mut self, span: Span) {
use CheckInstructionKind::*;
let child = self.stack.pop();
match child {
Some((pattern_kind @ PivotalNext(_), ..)) => {
self.stack.push((pattern_kind, span));
}
Some(_) => {
self.stack.push((Replacing, span));
}
None => self.disable(),
}
}
fn process_xoring(&mut self, span: Span) {
use CheckInstructionKind::*;
let right_branch = self.stack.pop();
let left_branch = self.stack.pop();
let left_right = left_branch.zip(right_branch);
match left_right {
Some(((PivotalNext(_), ..), (PivotalNext(_), ..))) => {
// `xor` has `next` in both branches. It is impossible
// to tell which branch should poped up.
self.disable();
}
Some(((pattern_kind @ PivotalNext(_), ..), ..))
| Some((_, (pattern_kind @ PivotalNext(_), _))) => {
// potential failure but need to check when fold pops up.
self.stack.push((pattern_kind, span));
}
Some(_) => {
self.stack.push((Xoring, span));
}
_ => {
// disable machine if Xoring invariant, namely there must be 2 kinds on a stack, is broken.
self.disable();
}
}
}
fn process_merging(&mut self, span: Span) {
use CheckInstructionKind::*;
let right_branch = self.stack.pop();
let left_branch = self.stack.pop();
let left_right = left_branch.zip(right_branch);
match left_right {
Some((
(pattern_kind @ PivotalNext(left_iterable), ..),
(PivotalNext(right_iterable), ..),
)) if left_iterable == right_iterable => {
self.stack.push((pattern_kind, span));
}
Some(((PivotalNext(iterator), _), ..)) => {
// potential failure but need to check when fold pops up.
self.stack.push((Merging, span));
self.potentially_malformed_spans
.entry(iterator)
.or_insert(span);
}
Some((_, (pattern_kind @ PivotalNext(_), ..))) => {
self.stack.push((pattern_kind, span));
}
Some(_) => {
self.stack.push((Merging, span));
}
_ => {
// disable machine if Merging invariant, namely there must be 2 kinds on a stack, is broken.
self.disable();
}
}
}
fn after_next_check(&mut self, iterable: &'name str) {
let malformed_span = self.potentially_malformed_spans.get(iterable);
if let Some(span) = malformed_span {
self.malformed_spans.push(*span);
}
}
fn replacing_with_check_common(
&mut self,
iterator_name: &'name str,
span: Span,
instr_kind: &CheckInstructionKind<'name>,
) {
use CheckInstructionKind::*;
let child = self.stack.pop();
match child {
Some((PivotalNext(pivotal_next_iterator_name), ..))
if pivotal_next_iterator_name == iterator_name =>
{
self.after_next_check(iterator_name);
self.potentially_malformed_spans.remove(iterator_name);
self.stack.push((Simple, span));
}
Some((pattern_kind @ PivotalNext(_), ..)) => {
self.after_next_check(iterator_name);
self.stack.push((pattern_kind, span));
}
Some(_) => {
self.after_next_check(iterator_name);
self.stack.push((*instr_kind, span));
}
None => self.is_enabled = false,
}
}
}
/// Intermediate implementation of variable validator.
///
/// It is intended to track variables (i.e., those that were defined as
@ -65,6 +276,9 @@ pub struct VariableValidator<'i> {
/// This vector contains all literal error codes used with fail.
unsupported_literal_errcodes: Vec<(i64, Span)>,
/// This machine is for after next instruction check.
after_next_machine: AfterNextCheckMachine<'i>,
}
impl<'i> VariableValidator<'i> {
@ -79,6 +293,8 @@ impl<'i> VariableValidator<'i> {
self.met_args(call.args.deref(), span);
self.met_simple_instr(span);
match &call.output {
CallOutputValue::Scalar(scalar) => self.met_variable_name_definition(scalar.name, span),
CallOutputValue::Stream(stream) => self.met_variable_name_definition(stream.name, span),
@ -90,10 +306,12 @@ impl<'i> VariableValidator<'i> {
// and it is useful for code generation
pub(super) fn met_canon(&mut self, canon: &Canon<'i>, span: Span) {
self.met_variable_name_definition(canon.canon_stream.name, span);
self.met_simple_instr(span);
}
pub(super) fn met_canon_map(&mut self, canon_map: &CanonMap<'i>, span: Span) {
self.met_variable_name_definition(canon_map.canon_stream_map.name, span);
self.met_simple_instr(span);
}
pub(super) fn met_canon_map_scalar(
@ -102,16 +320,20 @@ impl<'i> VariableValidator<'i> {
span: Span,
) {
self.met_variable_name_definition(canon_stream_map_scalar.scalar.name, span);
self.met_simple_instr(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);
self.met_replacing_instr(span);
}
pub(super) fn met_mismatch(&mut self, mismatch: &MisMatch<'i>, span: Span) {
self.met_matchable(&mismatch.left_value, span);
self.met_matchable(&mismatch.right_value, span);
self.met_replacing_instr(span);
}
pub(super) fn met_fold_scalar(&mut self, fold: &FoldScalar<'i>, span: Span) {
@ -128,16 +350,27 @@ impl<'i> VariableValidator<'i> {
EmptyArray => {}
};
self.met_iterator_definition(&fold.iterator, span);
self.met_popstack_instr(fold, span);
}
pub(super) fn meet_fold_stream(&mut self, fold: &FoldStream<'i>, span: Span) {
self.met_variable_name(fold.iterable.name, span);
self.met_iterator_definition(&fold.iterator, span);
match fold.last_instruction {
Some(_) => self.met_popstack_replacing_with_check_instr(fold.iterator.name, span),
None => self.met_replacing_with_check_instr(fold.iterator.name, span),
}
}
pub(super) fn meet_fold_stream_map(&mut self, fold: &FoldStreamMap<'i>, span: Span) {
self.met_variable_name(fold.iterable.name, span);
self.met_iterator_definition(&fold.iterator, span);
match fold.last_instruction {
Some(_) => self.met_popstack_replacing_with_check_instr(fold.iterator.name, span),
None => self.met_replacing_with_check_instr(fold.iterator.name, span),
}
}
pub(super) fn met_new(&mut self, new: &New<'i>, span: Span) {
@ -145,6 +378,7 @@ impl<'i> VariableValidator<'i> {
.push((new.argument.name(), span));
// new defines a new variable
self.met_variable_name_definition(new.argument.name(), span);
self.met_replacing_instr(span);
}
pub(super) fn met_next(&mut self, next: &Next<'i>, span: Span) {
@ -154,6 +388,7 @@ impl<'i> VariableValidator<'i> {
// just put without a check for being already met
self.unresolved_iterables.insert(iterable_name, span);
self.multiple_next_candidates.insert(iterable_name, span);
self.met_pivotalnext_instr(iterable_name, span);
}
pub(super) fn met_ap(&mut self, ap: &Ap<'i>, span: Span) {
@ -181,12 +416,14 @@ impl<'i> VariableValidator<'i> {
}
}
self.met_variable_name_definition(ap.result.name(), span);
self.met_simple_instr(span);
}
pub(super) fn met_ap_map(&mut self, ap_map: &ApMap<'i>, span: Span) {
let key = &ap_map.key;
self.met_map_key(key, span);
self.met_variable_name_definition(ap_map.map.name, span);
self.met_simple_instr(span);
}
fn met_map_key(&mut self, key: &StreamMapKeyClause<'i>, span: Span) {
@ -207,6 +444,55 @@ impl<'i> VariableValidator<'i> {
}
_ => {}
}
self.met_simple_instr(span);
}
pub(super) fn met_merging_instr(&mut self, span: Span) {
self.after_next_machine
.met_instruction_kind(CheckInstructionKind::Merging, span);
}
pub(super) fn met_pivotalnext_instr(&mut self, iterable_name: &'i str, span: Span) {
self.after_next_machine
.met_instruction_kind(CheckInstructionKind::PivotalNext(iterable_name), span);
}
fn met_popstack_instr(&mut self, fold: &FoldScalar<'i>, span: Span) {
let instruction_kind = match fold.last_instruction {
Some(_) => CheckInstructionKind::PopStack2,
None => CheckInstructionKind::PopStack1,
};
self.after_next_machine
.met_instruction_kind(instruction_kind, span);
}
fn met_popstack_replacing_with_check_instr(&mut self, iterator_name: &'i str, span: Span) {
self.after_next_machine.met_instruction_kind(
CheckInstructionKind::PopStack1ReplacingWithCheck(iterator_name),
span,
);
}
pub(super) fn met_replacing_instr(&mut self, span: Span) {
self.after_next_machine
.met_instruction_kind(CheckInstructionKind::Replacing, span);
}
pub(super) fn met_replacing_with_check_instr(&mut self, iterator_name: &'i str, span: Span) {
self.after_next_machine.met_instruction_kind(
CheckInstructionKind::ReplacingWithCheck(iterator_name),
span,
);
}
pub(super) fn met_xoring_instr(&mut self, span: Span) {
self.after_next_machine
.met_instruction_kind(CheckInstructionKind::Xoring, span);
}
pub(super) fn met_simple_instr(&mut self, span: Span) {
self.after_next_machine
.met_instruction_kind(CheckInstructionKind::Simple, span);
}
pub(super) fn finalize(self) -> Vec<ErrorRecovery<AirPos, Token<'i>, ParserError>> {
@ -218,6 +504,7 @@ impl<'i> VariableValidator<'i> {
.check_iterator_for_multiple_definitions()
.check_for_unsupported_map_keys()
.check_for_unsupported_literal_errcodes()
.check_after_next_instr()
.build()
}
@ -517,6 +804,14 @@ impl<'i> ValidatorErrorBuilder<'i> {
self
}
fn check_after_next_instr(mut self) -> Self {
for span in self.validator.after_next_machine.malformed_spans_iter() {
let error = ParserError::fold_has_instruction_after_next(*span);
add_to_errors(&mut self.errors, *span, Token::Next, error);
}
self
}
fn build(self) -> Vec<ErrorRecovery<AirPos, Token<'i>, ParserError>> {
self.errors
}