Control flow
The pattern language offers multiple ways to modify the behaviour of the parser on the go based on the values already parsed, allowing you to parse complex formats with relative ease.
Conditionals
In the pattern language, not all structs need to be the same size or have the same layout. It’s possible to change what variables are getting declared based on the value of other variables.
This code looks at the first byte of each Packet
to determine its type so it can decode the body of the packet accordingly using the correct types defined in PacketA
, PacketB
and PacketC
.
Conditionals like this can be used in Structs, Unions and Bitfields
Match statements
Match statements are a more powerful alternative to conditionals. They allow you to more easily match against multiple values and have more forms of comparison logic available.
But the match statement allows for much more than just a simple switch. It also allows you to match multiple values at once and use more complex comparison logic. Alongside this is the _
wildcard that matches any value, and thus also creates the default case.
Also the match statement has special comparisons that allow for more batchful comparisons. The … operator allows you to match a range of values, and the |
operator allows to match between multiple values.
Pattern control flow
The most basic form of conditional parsing are array control flow statements, break
and continue
. These allow you to stop the parsing of the array or skip elements based on conditions in the currently parsed item instance.
Break
When a break is reached, the current array creation process is terminated. This means, the array keeps all entries that have already been parsed, including the one that’s being currently processed, but won’t expand further, even if the requested number of entries hasn’t been reached yet.
break
can also be used in regular patterns to prematurely stop parsing of the current pattern.
If the pattern where break
is being used in is nested inside of another pattern, only evaluation of the current pattern is stopped and continues in the parent struct after the definition of the current pattern.
Continue
When a continue is reached, the currently evaluated array entry gets evaluated to find next array entry offset but then gets discarded. This can be used to conditionally exclude certain array entries from the list that are either invalid or shouldn’t be displayed in the pattern data list while still scanning the entire range the array would span.
This can for instance be used in combination with In/Out Variables to easily filter array items.
continue
can also be used in regular patterns to discard the pattern entirely.
If the pattern where continue
is being used in is nested inside of another pattern, only the current pattern is discarded and evaluation continues in the parent struct after the definition of the current pattern.
Return statements
Return statements outside of functions can be used to prematurely terminate execution of the current program.
Evaluation stops at the location the return
statement was executed. All patterns that have been evaluated up until this point will be finished up and placed into memory before execution halts.
Try-Catch statements
Try-Catch blocks are used to try placing down patterns that might error and then handling that error.
The following code will try to place all the patterns in the try
block and if any error occurred while doing so, it will discard the patterns it tried to place, revert the cursor back to where it was at the start of the try
block and then execute the catch
block instead.
Last updated