33program = { SOI ~ declarations ~ EOI }
44declarations = { declaration* }
55declaration = { struct_decl | enum_decl | extern_fn_decl | fn_decl | const_decl | var_decl }
6- struct_decl = { "const" ~ identifier ~ "=" ~ "struct" ~ "{" ~ struct_fields ? ~ "}" ~ ";" }
7- struct_fields = { struct_field ~ ("," ~ struct_field)* ~ ","? }
8- struct_field = { identifier ~ ":" ~ type_expr }
9- enum_decl = { "const" ~ identifier ~ "=" ~ "enum" ~ "{" ~ enum_variants ? ~ "}" ~ ";" }
10- enum_variants = { enum_variant ~ ("," ~ enum_variant)* ~ ","? }
11- enum_variant = { identifier }
6+ struct_decl = { "const" ~ identifier ~ "=" ~ "struct" ~ "{" ~ struct_field_list ? ~ "}" ~ ";" }
7+ struct_field_list = { struct_field* }
8+ struct_field = { identifier ~ ":" ~ type_expr ~ ","? }
9+ enum_decl = { "const" ~ identifier ~ "=" ~ "enum" ~ "{" ~ enum_variant_list ? ~ "}" ~ ";" }
10+ enum_variant_list = { enum_variant* }
11+ enum_variant = { identifier ~ ","? }
1212extern_fn_decl = { extern_fn_decl_with_params | extern_fn_decl_no_params }
13- extern_fn_decl_with_params = { "extern" ~ "fn" ~ identifier ~ "(" ~ fn_params ~ ")" ~ type_expr ~ ";" }
13+ extern_fn_decl_with_params = { "extern" ~ "fn" ~ identifier ~ "(" ~ fn_param_list ~ ")" ~ type_expr ~ ";" }
1414extern_fn_decl_no_params = { "extern" ~ "fn" ~ identifier ~ "(" ~ ")" ~ type_expr ~ ";" }
1515fn_decl = { async_fn_decl | sync_fn_decl }
1616sync_fn_decl = { fn_decl_with_params | fn_decl_no_params }
1717async_fn_decl = { async_fn_decl_with_params | async_fn_decl_no_params }
18- async_fn_decl_with_params = { "async" ~ "fn" ~ identifier ~ "(" ~ fn_params ~ ")" ~ type_expr ~ block }
18+ async_fn_decl_with_params = { "async" ~ "fn" ~ identifier ~ "(" ~ fn_param_list ~ ")" ~ type_expr ~ block }
1919async_fn_decl_no_params = { "async" ~ "fn" ~ identifier ~ "(" ~ ")" ~ type_expr ~ block }
20- fn_decl_with_params = { "fn" ~ identifier ~ "(" ~ fn_params ~ ")" ~ type_expr ~ block }
20+ fn_decl_with_params = { "fn" ~ identifier ~ "(" ~ fn_param_list ~ ")" ~ type_expr ~ block }
2121fn_decl_no_params = { "fn" ~ identifier ~ "(" ~ ")" ~ type_expr ~ block }
22- fn_params = { fn_param_any ~ ("," ~ fn_param_any)* }
22+ fn_param_list = { fn_param_item* }
23+ fn_param_item = { fn_param_any ~ ","? }
2324fn_param_any = { comptime_param | fn_param }
2425comptime_param = { "comptime" ~ identifier ~ ":" ~ type_expr }
2526fn_param = { identifier ~ ":" ~ type_expr }
@@ -29,12 +30,13 @@ const_decl_untyped = { "const" ~ identifier ~ "=" ~ expr ~ ";" }
2930var_decl = { var_decl_typed | var_decl_untyped }
3031var_decl_typed = { "var" ~ identifier ~ ":" ~ type_expr ~ "=" ~ expr ~ ";" }
3132var_decl_untyped = { "var" ~ identifier ~ "=" ~ expr ~ ";" }
32- type_expr = { pointer_type | optional_type | error_union_type | array_type | primitive_type | identifier }
33+ type_expr = { pointer_type | optional_type | error_union_type | array_type | primitive_type | named_type }
3334pointer_type = { "*" ~ "const"? ~ type_expr }
3435optional_type = { "?" ~ type_expr }
3536error_union_type = { "!" ~ type_expr }
3637array_type = { "[" ~ integer_literal? ~ "]" ~ type_expr }
37- primitive_type = { "i8" | "i16" | "i32" | "i64" | "u8" | "u16" | "u32" | "u64" | "f32" | "f64" | "bool" | "void" | "type" }
38+ primitive_type = @{ "i8" | "i16" | "i32" | "i64" | "u8" | "u16" | "u32" | "u64" | "f32" | "f64" | "bool" | "void" | "type" }
39+ named_type = { identifier }
3840statement = { if_stmt | while_stmt | for_stmt | return_stmt | break_stmt | continue_stmt | local_const | local_var | assign_stmt | expr_stmt }
3941break_stmt = { "break" ~ ";" }
4042continue_stmt = { "continue" ~ ";" }
@@ -53,52 +55,33 @@ local_var_typed = { "var" ~ identifier ~ ":" ~ type_expr ~ "=" ~ expr ~ ";" }
5355local_var_untyped = { "var" ~ identifier ~ "=" ~ expr ~ ";" }
5456expr_stmt = { expr ~ ";" }
5557block = { "{" ~ statement* ~ "}" }
56- expr = { logical_or }
57- logical_or = { logical_and ~ (or_op ~ logical_and)* }
58- logical_and = { comparison ~ (and_op ~ comparison)* }
59- comparison = { addition ~ ((eq_op | neq_op | lte_op | gte_op | lt_op | gt_op) ~ addition)* }
60- addition = { multiplication ~ ((add_op | sub_op) ~ multiplication)* }
61- multiplication = { unary ~ ((mul_op | div_op) ~ unary)* }
62- unary = { unary_with_op | primary }
58+ expr = { comparison_expr }
59+ comparison_expr = { add_expr ~ (comparison_op ~ add_expr)? }
60+ comparison_op = @{ "==" | "!=" | "<=" | ">=" | "<" | ">" }
61+ add_expr = { mul_expr ~ (add_op ~ mul_expr)? }
62+ add_op = @{ "+" | "-" }
63+ mul_expr = { unary_expr ~ (mul_op ~ unary_expr)? }
64+ mul_op = @{ "*" | "/" }
65+ unary_expr = { unary_with_op | primary }
6366unary_with_op = { unary_op ~ primary }
67+ unary_op = { "-" | "!" }
6468primary = { postfix_expr }
6569postfix_expr = { call_expr | field_expr | index_expr | atom }
66- call_expr = { atom ~ "(" ~ call_args? ~ ")" }
70+ call_expr = { atom ~ "(" ~ call_arg_list? ~ ")" }
71+ call_arg_list = { call_arg* }
72+ call_arg = { expr ~ ","? }
6773field_expr = { atom ~ "." ~ identifier }
6874index_expr = { atom ~ "[" ~ expr ~ "]" }
69- call_args = { expr ~ ("," ~ expr)* }
70- atom = { switch_expr | try_expr | await_expr | struct_init | array_literal | bool_literal | string_literal | integer_literal | type_value | identifier_expr | paren_expr }
71- switch_expr = { "switch" ~ "(" ~ expr ~ ")" ~ "{" ~ switch_cases? ~ "}" }
72- switch_cases = { switch_case ~ ("," ~ switch_case)* ~ ","? }
73- switch_case = { switch_case_value | switch_case_else }
74- switch_case_value = { switch_pattern ~ "=>" ~ expr }
75- switch_case_else = { "else" ~ "=>" ~ expr }
76- switch_pattern = { switch_or_pattern }
77- switch_or_pattern = { switch_primary_pattern ~ ("|" ~ switch_primary_pattern)* }
78- switch_primary_pattern = { switch_struct_pattern | switch_tagged_union_pattern | switch_error_pattern | switch_pointer_pattern | switch_range_pattern | switch_array_pattern | switch_literal_pattern | switch_wildcard_pattern | switch_identifier_pattern }
79- switch_range_pattern = { switch_simple_literal ~ ".." ~ switch_simple_literal }
80- switch_array_pattern = { ".{" ~ switch_array_elements? ~ "}" }
81- switch_array_elements = { switch_pattern ~ ("," ~ switch_pattern)* ~ ","? }
82- switch_literal_pattern = { switch_simple_literal }
83- switch_simple_literal = { integer_literal | string_literal }
84- switch_wildcard_pattern = { "_" }
85- switch_identifier_pattern = { identifier }
86- switch_struct_pattern = { identifier ~ "{" ~ switch_struct_field_patterns? ~ "}" }
87- switch_struct_field_patterns = { switch_struct_field_pattern ~ ("," ~ switch_struct_field_pattern)* ~ ","? }
88- switch_struct_field_pattern = { "." ~ identifier ~ ("=" ~ switch_pattern)? }
89- switch_tagged_union_pattern = { "." ~ identifier }
90- switch_error_pattern = { "error" ~ "." ~ identifier }
91- switch_pointer_pattern = { "*" ~ switch_primary_pattern }
92- type_value = { type_expr_as_value }
93- type_expr_as_value = { primitive_type }
94- struct_init = { identifier ~ "{" ~ struct_init_fields? ~ "}" }
95- struct_init_fields = { struct_init_field ~ ("," ~ struct_init_field)* ~ ","? }
96- struct_init_field = { "." ~ identifier ~ "=" ~ expr }
75+ atom = { try_expr | await_expr | struct_init | array_literal | bool_literal | string_literal | integer_literal | identifier_expr | paren_expr }
9776try_expr = { "try" ~ primary }
9877await_expr = { "await" ~ primary }
78+ struct_init = { identifier ~ "{" ~ struct_init_field_list? ~ "}" }
79+ struct_init_field_list = { struct_init_field* }
80+ struct_init_field = { "." ~ identifier ~ "=" ~ expr ~ ","? }
81+ array_literal = { "[" ~ array_element_list? ~ "]" }
82+ array_element_list = { array_element* }
83+ array_element = { expr ~ ","? }
9984paren_expr = _{ "(" ~ expr ~ ")" }
100- array_literal = { "[" ~ array_elements? ~ "]" }
101- array_elements = { expr ~ ("," ~ expr)* }
10285identifier_expr = { identifier }
10386bool_literal = { "true" | "false" }
10487integer_literal = @{ "-"? ~ ASCII_DIGIT+ }
@@ -107,23 +90,10 @@ string_inner = { (!("\"" | "\\") ~ ANY) | escape_seq }
10790escape_seq = { "\\" ~ ("n" | "r" | "t" | "\\" | "\"" | "0") }
10891keyword = @{ ("struct" | "enum" | "fn" | "const" | "var" | "if" | "else" | "while" | "for" |
10992 "return" | "break" | "continue" | "try" | "await" | "async" | "and" | "or" | "true" | "false" |
110- "comptime" | "type" | "switch" |
93+ "comptime" | "type" | "switch" | "extern" | "error" |
11194 "i8" | "i16" | "i32" | "i64" | "u8" | "u16" | "u32" | "u64" | "f32" | "f64" | "bool" | "void")
11295 ~ !(ASCII_ALPHANUMERIC | "_")
11396 }
11497identifier = @{ !keyword ~ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")* }
115- and_op = { "and" }
116- or_op = { "or" }
117- eq_op = { "==" }
118- neq_op = { "!=" }
119- lte_op = { "<=" }
120- gte_op = { ">=" }
121- lt_op = { "<" }
122- gt_op = { ">" }
123- add_op = { "+" }
124- sub_op = { "-" }
125- mul_op = { "*" }
126- div_op = { "/" }
127- unary_op = { "-" | "!" }
12898WHITESPACE = _{ " " | "\t" | "\n" | "\r" }
12999COMMENT = _{ "//" ~ (!"\n" ~ ANY)* ~ "\n"? }
0 commit comments