unified/swift: add literals, names, and operator expression mappings

This commit is contained in:
Asger F
2026-06-18 13:42:22 +02:00
parent 0e9d17b59c
commit 4e9c3fb436
4 changed files with 198 additions and 22 deletions

View File

@@ -15,6 +15,74 @@ fn translation_rules() -> Vec<yeast::Rule> {
// Declarations may be wrapped in local/global wrapper nodes.
rule!((global_declaration _ @inner) => {inner}),
rule!((local_declaration _ @inner) => {inner}),
// ---- Literals ----
rule!((integer_literal) => (int_literal)),
rule!((hex_literal) => (int_literal)),
rule!((bin_literal) => (int_literal)),
rule!((oct_literal) => (int_literal)),
rule!((real_literal) => (float_literal)),
rule!((boolean_literal) => (boolean_literal)),
rule!("nil" => (builtin_expr)),
rule!((special_literal) => (builtin_expr)),
rule!((line_string_literal) => (string_literal)),
rule!((multi_line_string_literal) => (string_literal)),
rule!((raw_string_literal) => (string_literal)),
rule!((regex_literal) => (regex_literal)),
// ---- Names ----
rule!((simple_identifier) @id => (name_expr identifier: (identifier #{id}))),
// A referenceable_operator (e.g. `+` used as a value, as in `reduce(0, +)`)
// is treated as a name reference to the operator symbol.
rule!((referenceable_operator) @op => (name_expr identifier: (identifier #{op}))),
// ---- Operators ----
// All binary operators share the lhs/op/rhs shape.
rule!((additive_expression lhs: @l op: @op rhs: @r) => (binary_expr left: {l} operator: (infix_operator #{op}) right: {r})),
rule!((multiplicative_expression lhs: @l op: @op rhs: @r) => (binary_expr left: {l} operator: (infix_operator #{op}) right: {r})),
rule!((comparison_expression lhs: @l op: @op rhs: @r) => (binary_expr left: {l} operator: (infix_operator #{op}) right: {r})),
rule!((equality_expression lhs: @l op: @op rhs: @r) => (binary_expr left: {l} operator: (infix_operator #{op}) right: {r})),
rule!((conjunction_expression lhs: @l op: @op rhs: @r) => (binary_expr left: {l} operator: (infix_operator #{op}) right: {r})),
rule!((disjunction_expression lhs: @l op: @op rhs: @r) => (binary_expr left: {l} operator: (infix_operator #{op}) right: {r})),
rule!((infix_expression lhs: @l op: @op rhs: @r) => (binary_expr left: {l} operator: (infix_operator #{op}) right: {r})),
// Range expression `a..<b` / `a...b`
rule!((range_expression start: @l op: @op end: @r) => (binary_expr left: {l} operator: (infix_operator #{op}) right: {r})),
// Open-ended ranges `a...` / `...b`
rule!((open_end_range_expression start: @l) => (unary_expr operator: (postfix_operator "...") operand: {l})),
rule!((open_start_range_expression end: @r) => (unary_expr operator: (prefix_operator "...") operand: {r})),
// Custom operator declaration: `[prefix|infix|postfix] operator OP [: PrecedenceGroup]`.
// The fixity keyword is an anonymous child of `operator_declaration`, so we
// dispatch on it with one rule per keyword.
rule!(
(operator_declaration "prefix" (referenceable_operator _ @op) (simple_identifier)? @prec)
=>
(operator_syntax_declaration name: (identifier #{op}) fixity: (fixity "prefix") precedence: {..prec})
),
rule!(
(operator_declaration "postfix" (referenceable_operator _ @op) (simple_identifier)? @prec)
=>
(operator_syntax_declaration name: (identifier #{op}) fixity: (fixity "postfix") precedence: {..prec})
),
rule!(
(operator_declaration "infix" (referenceable_operator _ @op) (simple_identifier)? @prec)
=>
(operator_syntax_declaration
name: (identifier #{op})
fixity: (fixity "infix")
precedence: {..prec})
),
rule!((bitwise_operation lhs: @l op: @op rhs: @r) => (binary_expr left: {l} operator: (infix_operator #{op}) right: {r})),
rule!((nil_coalescing_expression value: @l if_nil: @r) => (binary_expr left: {l} operator: (infix_operator "??") right: {r})),
// Leading-dot member shorthand (e.g. `.some`, `.foo`) means member access
// on a contextually inferred type.
rule!((prefix_expression operation: "." target: @member) => (member_access_expr base: (inferred_type_expr) member: (identifier #{member}))),
// Prefix unary operators
rule!((prefix_expression operation: @op target: @operand) => (unary_expr operator: (prefix_operator #{op}) operand: {operand})),
// Postfix unary operators
rule!((postfix_expression operation: @op target: @operand) => (unary_expr operator: (postfix_operator #{op}) operand: {operand})),
// Parenthesised single-value tuple is a grouping expression; pass through.
// Multi-value tuples become tuple_expr.
rule!((tuple_expression value: _* @v) => (tuple_expr element: {..v})),
// Blocks contain statement* directly.
rule!((block statement: _+ @stmts) => (block stmt: {..stmts})),
rule!((block) => (block)),
// ---- Fallbacks ----
rule!(
(_)

View File

@@ -18,7 +18,11 @@ source_file
top_level
body:
block
stmt: unsupported_node "1 + 2"
stmt:
binary_expr
operator: infix_operator "+"
left: int_literal "1"
right: int_literal "2"
===
Another additive expression is desugared
@@ -40,4 +44,12 @@ source_file
top_level
body:
block
stmt: unsupported_node "foo + bar"
stmt:
binary_expr
operator: infix_operator "+"
left:
name_expr
identifier: identifier "foo"
right:
name_expr
identifier: identifier "bar"

View File

@@ -14,7 +14,7 @@ source_file
top_level
body:
block
stmt: unsupported_node "42"
stmt: int_literal "42"
===
Negative integer literal
@@ -35,7 +35,10 @@ source_file
top_level
body:
block
stmt: unsupported_node "-7"
stmt:
unary_expr
operand: int_literal "7"
operator: prefix_operator "-"
===
Floating-point literal
@@ -53,7 +56,7 @@ source_file
top_level
body:
block
stmt: unsupported_node "3.14"
stmt: float_literal "3.14"
===
Boolean literals
@@ -75,8 +78,8 @@ top_level
body:
block
stmt:
unsupported_node "true"
unsupported_node "false"
boolean_literal "true"
boolean_literal "false"
===
Nil literal
@@ -94,7 +97,7 @@ source_file
top_level
body:
block
stmt: unsupported_node "nil"
stmt: builtin_expr "nil"
===
String literal
@@ -114,7 +117,7 @@ source_file
top_level
body:
block
stmt: unsupported_node "\"hello\""
stmt: string_literal "\"hello\""
===
String with interpolation
@@ -137,4 +140,4 @@ source_file
top_level
body:
block
stmt: unsupported_node "\"hello \\(name)\""
stmt: string_literal "\"hello \\(name)\""

View File

@@ -18,7 +18,15 @@ source_file
top_level
body:
block
stmt: unsupported_node "a + b"
stmt:
binary_expr
operator: infix_operator "+"
left:
name_expr
identifier: identifier "a"
right:
name_expr
identifier: identifier "b"
===
Subtraction
@@ -40,7 +48,15 @@ source_file
top_level
body:
block
stmt: unsupported_node "a - b"
stmt:
binary_expr
operator: infix_operator "-"
left:
name_expr
identifier: identifier "a"
right:
name_expr
identifier: identifier "b"
===
Multiplication
@@ -62,7 +78,15 @@ source_file
top_level
body:
block
stmt: unsupported_node "a * b"
stmt:
binary_expr
operator: infix_operator "*"
left:
name_expr
identifier: identifier "a"
right:
name_expr
identifier: identifier "b"
===
Division
@@ -84,7 +108,15 @@ source_file
top_level
body:
block
stmt: unsupported_node "a / b"
stmt:
binary_expr
operator: infix_operator "/"
left:
name_expr
identifier: identifier "a"
right:
name_expr
identifier: identifier "b"
===
Operator precedence: addition and multiplication
@@ -110,7 +142,21 @@ source_file
top_level
body:
block
stmt: unsupported_node "a + b * c"
stmt:
binary_expr
operator: infix_operator "+"
left:
name_expr
identifier: identifier "a"
right:
binary_expr
operator: infix_operator "*"
left:
name_expr
identifier: identifier "b"
right:
name_expr
identifier: identifier "c"
===
Parenthesised expression
@@ -140,7 +186,13 @@ source_file
top_level
body:
block
stmt: unsupported_node "(a + b) * c"
stmt:
binary_expr
operator: infix_operator "*"
left: tuple_expr "(a + b)"
right:
name_expr
identifier: identifier "c"
===
Comparison
@@ -162,7 +214,15 @@ source_file
top_level
body:
block
stmt: unsupported_node "a < b"
stmt:
binary_expr
operator: infix_operator "<"
left:
name_expr
identifier: identifier "a"
right:
name_expr
identifier: identifier "b"
===
Equality
@@ -184,7 +244,15 @@ source_file
top_level
body:
block
stmt: unsupported_node "a == b"
stmt:
binary_expr
operator: infix_operator "=="
left:
name_expr
identifier: identifier "a"
right:
name_expr
identifier: identifier "b"
===
Logical and
@@ -206,7 +274,15 @@ source_file
top_level
body:
block
stmt: unsupported_node "a && b"
stmt:
binary_expr
operator: infix_operator "&&"
left:
name_expr
identifier: identifier "a"
right:
name_expr
identifier: identifier "b"
===
Logical or
@@ -228,7 +304,15 @@ source_file
top_level
body:
block
stmt: unsupported_node "a || b"
stmt:
binary_expr
operator: infix_operator "||"
left:
name_expr
identifier: identifier "a"
right:
name_expr
identifier: identifier "b"
===
Logical not
@@ -249,7 +333,12 @@ source_file
top_level
body:
block
stmt: unsupported_node "!a"
stmt:
unary_expr
operand:
name_expr
identifier: identifier "a"
operator: prefix_operator "!"
===
Range operator
@@ -271,4 +360,8 @@ source_file
top_level
body:
block
stmt: unsupported_node "1...10"
stmt:
binary_expr
operator: infix_operator "..."
left: int_literal "1"
right: int_literal "10"