Apendix: Language Grammar

digit               ::= "0"  "9"
lower_letter        ::= "a"  "z"
upper_letter        ::= "A"  "Z"
inline_whitespace   ::= "\s"
                      | "\t"
letter              ::= lower_letter
                      | upper_letter
alphanumeric        ::= digit
                      | letter
lower_ident         ::= lower_letter ( alphanumeric )*
upper_ident         ::= upper_letter ( alphanumeric )*
path_head           ::= "::" ( upper_ident "::" )+
                      | ( "super" "::" )* ( upper_ident "::" )*
upper_path          ::= path_head upper_ident
lower_path          ::= path_head lower_ident
unit_type           ::= "()"
param_type          ::= "'" lower_ident
named_type          ::= upper_path ( "(" type ( "," type )* ")" )?
grouped_type        ::= "(" type ")"
list_type           ::= "[" type "]"
simple_type         ::= unit_type
                      | param_type
                      | named_type
                      | grouped_type
                      | list_type
function_type       ::= simple_type "->" type
type                ::= simple_type
                      | function_type
string_literal      ::= `"` ( inline_whitespace | alphanumeric )* `"`
float_literal       ::= ( digit )+ "." ( digit )+
integer_literal     ::= ( digit )+
boolean_literal     ::= "true"
                      | "false"
literal             ::= string_literal
                      | float_literal
                      | integer_literal
                      | boolean_literal
block               ::= "{" stmts "}"
condition           ::= expr
                      | "let" pattern "=" expr
consequent          ::= "if" condition block
alternative         ::= "else" consequent ( alternative )?
                      | "else" block
if_expr             ::= consequent ( alternative )?
literal_pattern     ::= literal
wildcard_pattern    ::= "_"
binding_pattern     ::= lower_ident
pattern_field       ::= lower_ident ":" pattern
variant_pattern     ::= upper_path "{" pattern_field ( "," pattern_field )* "}"
                      | upper_path "(" pattern ( "," pattern )* ")"
                      | upper_path
pattern             ::= literal_pattern
                      | wildcard_pattern
                      | binding_pattern
                      | variant_pattern
match_arm_handler   ::= expr
                      | block
match_arm           ::= pattern "=>" match_arm_handler
match_expr          ::= "match" "{" ( match_arm )+ "}"
expr                ::= literal
                      | if_expr
                      | match_expr
let_stmt            ::= "let" lower_ident ( ":" type )? "=" expr
expr_stmt           ::= expr
stmt                ::= let_stmt
                      | expr_stmt
stmts               ::= ( stmt ";" )* ( stmt ( ";" )? )?
use_path_tail       ::= lower_ident
                      | upper_ident
                      | "*"
use_item            ::= "use" path_head use_path_tail ";"
mod_item            ::= "mod" upper_ident "{" items "}"
named_variant_param ::= lower_item ":" type
variant_params      ::= "(" type ( "," type )* ")"
                      | "{" named_variant_param ( "," named_variant_param )* "}"
variant_definition  ::= "|" upper_ident ( variant_params )?
type_item           ::= "type" upper_ident "{" ( variant_definition )+ "}" ";"
fn_param            ::= lower_ident ":" type
fn_params           ::= fn_param ( "," fn_param )*
                      | ""
fn_item             ::= "fn" lower_ident "(" fn_params ")" "->" type "{" stmts "}"
item                ::= use_item
                      | mod_item
                      | type_item
                      | fn_item
items               ::= ( item )*
source_file         ::= items