feat: add enum declarations and multi-arm enum match expressions#336
Open
stringhandler wants to merge 1 commit into
Open
feat: add enum declarations and multi-arm enum match expressions#336stringhandler wants to merge 1 commit into
stringhandler wants to merge 1 commit into
Conversation
Contributor
|
3666ffb needs rebase |
3666ffb to
ce66af6
Compare
Introduces `enum` with explicit u8 discriminants and N-arm `match` over enum variants, desugared into `jet::eq_8` comparison chains at the AST level. Missing witness values are zero-filled before Simplicity witness population; a post-prune check errors if any zero-filled witness appears on a surviving (non-pruned) branch.
ce66af6 to
0eb01e6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduces
enumwith explicit u8 discriminants and N-armmatchover enum variants, desugared intojet::eq_8comparison chains at the AST level. Missing witness values are zero-filled before Simplicity witness population; a post-prune check errors if any zero-filled witness appears on a surviving (non-pruned) branch.Example
Implementation notes
Some things to note that are missing:
1. Enums with structured fields.
I originally wanted to implement enums as something like
or potentially even with tuples, like
Inherit(<inner tuple>). This would certainly look cleaner in the witness file (i.e. asACTION: { value = "Inherit("0x....")}, however the enum declaration is not present in scope when parsing the file and this makes decoding it difficult.As a trade off enums must have a u8 encoding, so that they can be parsed from the witness. This explicit declaration should also help when the transaction is examined on the explorer.
Structured enums can possibly be implemented in a future PR.
2. Empty witness filling
By splitting the action/path witness variable into it's own
u8, we now have to specify individual witness variables for each of the actions/paths taken in the program. This means that we would now have to specify values for all witnesses, even if they are not called.I did a deep dive and confirmed that unused witness values are pruned, but calling a program with a witness file or programmatically is still inconvenient. To combat this, I've added a step to fill unspecified witness values with defaults of zero, and then an additional step to make sure that none of the filled values remain when pruned. This is done through
satisfy_with_env, so lib callers should not have to do any extra lifting.3. Enum values in code are out of scope
A limit of the implementation is that using enums in code is not supported. This should be done in another PR.
For example, the following is not supported:
This is unfortunate but the PR is already quite large and tricky to review.
4. Desugaring into
jet::eq_u8chainsUnder the hood, the
matchstatement is desugared into a list ofifs(actuallymatchif you are specific), each with a jet::eq_u8.While it might have been more efficient to utilize an
Either::Leftstructure, hoping for a tree like evaluation, it was difficult to decode a u8 reliably into Left/Right nodes and allow for skipping enum values (e..genum ACTION { One = 1, /* Two = 2 --deprecated */, Three = 3 }). That said, it is not impossible, and I can (reluctantly) create another PR for that implementation if desired.