@@ -495,11 +495,131 @@ call_args = { expr ~ ("," ~ expr)* }
495495 }
496496
497497// Atom: the base of postfix expressions
498- atom = { try_expr | struct_init | array_literal | bool_literal | string_literal | integer_literal | type_value | identifier_expr | paren_expr }
498+ atom = { switch_expr | try_expr | struct_init | array_literal | bool_literal | string_literal | integer_literal | type_value | identifier_expr | paren_expr }
499499 -> TypedExpression {
500500 "get_child": { "index": 0 }
501501 }
502502
503+ // ===== Switch Expression =====
504+
505+ // switch (expr) { cases... }
506+ switch_expr = { "switch" ~ "(" ~ expr ~ ")" ~ "{" ~ switch_cases? ~ "}" }
507+ -> TypedExpression {
508+ "commands": [
509+ { "define": "switch_expr", "args": {
510+ "scrutinee": "$1",
511+ "cases": "$2"
512+ }}
513+ ]
514+ }
515+
516+ switch_cases = { switch_case ~ ("," ~ switch_case)* ~ ","? }
517+ -> List {
518+ "get_all_children": true
519+ }
520+
521+ // Handle both value => expr and else => expr
522+ switch_case = { switch_case_value | switch_case_else }
523+ -> TypedExpression {
524+ "get_child": { "index": 0 }
525+ }
526+
527+ // Value case: pattern => expr
528+ switch_case_value = { switch_pattern ~ "=>" ~ expr }
529+ -> TypedExpression {
530+ "commands": [
531+ { "define": "switch_case", "args": {
532+ "pattern": { "get_child": { "index": 0 } },
533+ "body": { "get_child": { "index": 1 } }
534+ }}
535+ ]
536+ }
537+
538+ // Else case: else => expr
539+ switch_case_else = { "else" ~ "=>" ~ expr }
540+ -> TypedExpression {
541+ "commands": [
542+ { "define": "switch_case", "args": {
543+ "pattern": { "define": "wildcard_pattern" },
544+ "body": "$1"
545+ }}
546+ ]
547+ }
548+
549+ // Pattern for switch case - supports various pattern types
550+ switch_pattern = { switch_or_pattern }
551+ -> TypedExpression {
552+ "get_child": { "index": 0 }
553+ }
554+
555+ // Or pattern: 1 | 2 | 3
556+ // For now, simplified to just pass through the first pattern
557+ // TODO: Implement proper or_pattern support when multiple alternatives
558+ switch_or_pattern = { switch_primary_pattern ~ ("|" ~ switch_primary_pattern)* }
559+ -> TypedExpression {
560+ "get_child": { "index": 0 }
561+ }
562+
563+ // Primary patterns (non-or)
564+ switch_primary_pattern = { switch_range_pattern | switch_array_pattern | switch_literal_pattern | switch_wildcard_pattern | switch_identifier_pattern }
565+ -> TypedExpression {
566+ "get_child": { "index": 0 }
567+ }
568+
569+ // Range pattern: 1..10 or 'a'..'z'
570+ switch_range_pattern = { switch_simple_literal ~ ".." ~ switch_simple_literal }
571+ -> TypedExpression {
572+ "commands": [
573+ { "define": "range_pattern", "args": {
574+ "start": { "define": "literal_pattern", "args": { "value": "$1" } },
575+ "end": { "define": "literal_pattern", "args": { "value": "$2" } },
576+ "inclusive": false
577+ }}
578+ ]
579+ }
580+
581+ // Array pattern: [a, b, c] or .{a, b}
582+ switch_array_pattern = { ".{" ~ switch_array_elements? ~ "}" }
583+ -> TypedExpression {
584+ "commands": [
585+ { "define": "array_pattern", "args": { "elements": "$1" } }
586+ ]
587+ }
588+
589+ switch_array_elements = { switch_pattern ~ ("," ~ switch_pattern)* ~ ","? }
590+ -> List {
591+ "get_all_children": true
592+ }
593+
594+ // Literal patterns (integers, strings, chars, bools)
595+ switch_literal_pattern = { switch_simple_literal }
596+ -> TypedExpression {
597+ "commands": [
598+ { "define": "literal_pattern", "args": { "value": "$1" } }
599+ ]
600+ }
601+
602+ switch_simple_literal = { integer_literal | string_literal }
603+ -> TypedExpression {
604+ "get_child": { "index": 0 }
605+ }
606+
607+ // Wildcard pattern: _
608+ switch_wildcard_pattern = { "_" }
609+ -> TypedExpression {
610+ "commands": [
611+ { "define": "wildcard_pattern" }
612+ ]
613+ }
614+
615+ // Identifier pattern (variable binding): x, value
616+ switch_identifier_pattern = { identifier }
617+ -> TypedExpression {
618+ "commands": [
619+ { "define": "identifier_pattern", "args": { "name": { "text": "$1" } } }
620+ ]
621+ }
622+
503623// Type as a value (for comptime type parameters)
504624type_value = { type_expr_as_value }
505625 -> TypedExpression {
@@ -597,7 +717,7 @@ escape_seq = { "\\" ~ ("n" | "r" | "t" | "\\" | "\"" | "0") }
597717keyword = @{
598718 ("struct" | "enum" | "fn" | "const" | "var" | "if" | "else" | "while" | "for" |
599719 "return" | "break" | "continue" | "try" | "and" | "or" | "true" | "false" |
600- "comptime" | "type" |
720+ "comptime" | "type" | "switch" |
601721 "i8" | "i16" | "i32" | "i64" | "u8" | "u16" | "u32" | "u64" | "f32" | "f64" | "bool" | "void")
602722 ~ !(ASCII_ALPHANUMERIC | "_")
603723}
0 commit comments