unified/swift: Clean up translation of patterns

Patterns have an unusual parse tree, but now the matching should
at least be a bit easier to follow.

The TODO regarding not being able to pass down context to handle
var/let is still relevant, and can't be solved in the mapping alone.
This commit is contained in:
Asger F
2026-06-19 11:32:07 +02:00
parent c01264d05c
commit 2675070291
3 changed files with 40 additions and 13 deletions

View File

@@ -282,9 +282,8 @@ fn translation_rules() -> Vec<yeast::Rule> {
rule!((type name: @inner) => {inner}),
// `directly_assignable_expression` is just a wrapper; unwrap it
rule!((directly_assignable_expression expr: @inner) => {inner}),
// tuple_pattern_item → pattern_element (preserves optional name/key)
rule!((tuple_pattern_item name: @key pattern: @pat) => (pattern_element key: (identifier #{key}) pattern: {pat})),
rule!((tuple_pattern_item pattern: @pat) => (pattern_element pattern: {pat})),
// Pattern with bound_identifier → name_pattern
rule!((pattern bound_identifier: @name) => (name_pattern identifier: (identifier #{name}))),
// Pattern with 'let' or 'var' binding: extract the inner pattern
// TODO: Names in a pattern need to be translated to expr_equality_pattern if not under a 'var/let' but we lack a way to pass down context to do this.
rule!(
@@ -308,10 +307,18 @@ fn translation_rules() -> Vec<yeast::Rule> {
constructor: (member_access_expr base: (inferred_type_expr #{dot}) member: (identifier #{name}))
element: {..items})
),
// Pattern with bound_identifier → name_pattern
rule!((pattern bound_identifier: @name) => (name_pattern identifier: (identifier #{name}))),
// Tuple pattern (destructuring)
rule!((pattern (pattern)* @elems) => (tuple_pattern element: {..elems})),
// Tuple pattern and its (optionally named) items
rule!((pattern kind: (tuple_pattern item: _* @elems)) => (tuple_pattern element: {..elems})),
rule!((tuple_pattern_item name: @key pattern: @pat) => (pattern_element key: (identifier #{key}) pattern: {pat})),
rule!((tuple_pattern_item pattern: @pat) => (pattern_element pattern: {pat})),
// Type casting pattern (TODO)
rule!((pattern kind: (type_casting_pattern)) => (unsupported_node)),
// Wildcard pattern
rule!((pattern kind: (wildcard_pattern)) => (ignore_pattern)),
// Expression pattern
// We lack a way to check if 'expr' is actually an expression, but due to rule ordering
// the 'expression' case is the only remaining possibility when this rule tries to match.
rule!((pattern kind: @expr) => (expr_equality_pattern expr: {expr})),
// ---- Functions ----
// Function declaration
// Function declaration (return type optional, body statements optional).

View File

@@ -558,7 +558,9 @@ top_level
callee:
name_expr
identifier: identifier "print"
pattern: tuple_pattern "1"
pattern:
expr_equality_pattern
expr: int_literal "1"
switch_case
body:
block
@@ -571,8 +573,10 @@ top_level
name_expr
identifier: identifier "print"
pattern:
tuple_pattern "2"
tuple_pattern "3"
expr_equality_pattern
expr: int_literal "2"
expr_equality_pattern
expr: int_literal "3"
switch_case
body:
block
@@ -844,7 +848,9 @@ top_level
element:
pattern_element
key: identifier "isAcknowledged"
pattern: tuple_pattern "false"
pattern:
expr_equality_pattern
expr: boolean_literal "false"
constructor:
member_access_expr
base: inferred_type_expr "."
@@ -867,7 +873,7 @@ top_level
element:
pattern_element
key: identifier "threadRowId"
pattern: tuple_pattern "_"
pattern: ignore_pattern "_"
pattern_element
pattern:
name_pattern

View File

@@ -195,7 +195,21 @@ top_level
stmt:
variable_declaration
modifier: modifier "let"
pattern: tuple_pattern "(a, b)"
pattern:
tuple_pattern
element:
pattern_element
pattern:
expr_equality_pattern
expr:
name_expr
identifier: identifier "a"
pattern_element
pattern:
expr_equality_pattern
expr:
name_expr
identifier: identifier "b"
value:
name_expr
identifier: identifier "pair"