feat: add enum declarations and multi-arm enum match expressions#336
Draft
stringhandler wants to merge 2 commits into
Draft
feat: add enum declarations and multi-arm enum match expressions#336stringhandler wants to merge 2 commits into
stringhandler wants to merge 2 commits into
Conversation
Contributor
|
3666ffb needs rebase |
ce66af6 to
0eb01e6
Compare
Collaborator
|
0eb01e6 needs rebase |
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.
Move enum definitions from the global `Scope.enums` map to per-module storage in `ModuleScope.enums`. This aligns enum scoping with other module-level declarations and simplifies the scope hierarchy. Also refactor `insert_enum` to handle type alias registration directly, eliminating the need for separate `insert_alias` calls during enum declaration analysis.
0eb01e6 to
2fa2122
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.