program = { declaration } ;
declaration = type_def | function_def | import_decl | module_decl ;
module_decl = "module" qualified_name ;
import_decl = "import" qualified_name [ "{" import_list "}" ] ;
import_list = import_item { "," import_item } ;
import_item = identifier [ "as" identifier ] ;
type_def = "type" identifier [ type_params ] "=" type_body ;
type_params = "[" identifier { "," identifier } "]" ;
type_body = sum_type | record_type ;
sum_type = "|" variant { "|" variant } ;
variant = identifier [ "(" type_list ")" ] ;
record_type = "{" field_def { "," field_def } "}" ;
field_def = identifier ":" type ;
function_def = [ "pub" ] [ "effect" ] "fn" identifier [ type_params ]
"(" [ param_list ] ")" "->" type block ;
param_list = param { "," param } ;
param = identifier ":" type ;
type = primitive_type | identifier [ type_args ] | tuple_type
| array_type | function_type ;
type_args = "[" type { "," type } "]" ;
tuple_type = "(" type "," type { "," type } ")" ;
array_type = "[" type ";" integer "]" ;
function_type = "fn" "(" [ type_list ] ")" "->" type ;
type_list = type { "," type } ;
block = "{" { statement } "}" ;
statement = let_stmt | var_stmt | assign_stmt | if_stmt | match_stmt
| for_stmt | while_stmt | loop_stmt | return_stmt
| break_stmt | expr_stmt ;
let_stmt = "let" pattern ":" type "=" expression ;
var_stmt = "var" identifier ":" type "=" expression ;
assign_stmt = lvalue "=" expression ;
if_stmt = "if" expression block [ "else" ( if_stmt | block ) ] ;
match_stmt = "match" expression "{" { match_arm } "}" ;
match_arm = pattern [ "if" expression ] "=>" block ;
for_stmt = "for" identifier "in" expression block ;
while_stmt = "while" expression block ;
loop_stmt = "loop" block ;
return_stmt = "return" [ expression ] ;
break_stmt = "break" ;
expr_stmt = expression ;
expression = /* standard expression grammar with operators */ ;
pattern = /* pattern grammar for matching */ ;