(* ======================== *) (* Core Character Sequences *) (* ======================== *) white_space ::= '\u0020' | '\u0009' | '\u000D' | '\u000A' lparen ::= '('; rparen ::= ')'; paren ::= lparen | rparen; lbracket ::= '['; rbracket ::= ']'; bracket ::= lbracket | rbracket; lbrace ::= '{'; rbrace ::= '}'; brace ::= lbrace | rbrace; digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; hex ::= '0' | ... | '9' | 'A' | ... | 'F' | 'a' | ... | 'f' ; upper ::= 'A' | ... | 'Z' | Lu | Lt | Nl | Lo upper only | Lm upper only; lower ::= 'a' | ... | 'z' | Ll | Lo lower only | Lm lower only; letter ::= upper | lower; escape_unicode ::= '\', 'u', hex, hex, hex, hex; escape_char ::= '\', ('b' | 'f' | 'n' | 'r' | 't' | '\' | '"'); escape_seq ::= escape_unicode | escape_char; number_integer ::= '0' | digit, [{digit}]; number_float ::= number_integer, '.', number_integer; newline ::= '\n'; printable_char ::= printable utf8; char_char ::= printable_char without newline or single quote | escape_seq; string_char ::= printable_char without newline or double quote | escape_seq; (* Comments *) comment ::= '-', '-', {utf8}; docstring ::= '-', '-', '-', {utf8}; (* ======== *) (* Keywords *) (* ======== *) k_type ::= 't', 'y', 'p', 'e'; k_class ::= 'c', 'l', 'a', 's', 's'; k_alias ::= 'a', 'l', 'i', 'a', 's'; k_const ::= 'c', 'o', 'n', 's', 't'; k_enum ::= 'e', 'n', 'u', 'm'; k_record ::= 'r', 'e', 'c', 'o', 'r', 'd'; k_object ::= 'o', 'b', 'j', 'e', 'c', 't'; k_let ::= 'l', 'e', 't'; k_mut ::= 'm', 'u', 't'; k_export ::= 'e', 'x', 'p', 'o', 'r', 't'; k_import ::= 'i', 'm', 'p', 'o', 'r', 't'; k_namespace ::= 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e'; k_infix ::= 'i', 'n', 'f', 'i', 'x'; k_fn ::= 'f', 'n'; k_end ::= 'e', 'n', 'd'; (* Initiates a pattern match against some value. *) k_match ::= 'm', 'a', 't', 'c', 'h'; (* Initiates a pattern matching case. Applicable to functions and matches. *) k_case ::= 'c', 'a', 's', 'e'; (* Used in if/else syntax. Starts such a block and used in 'else if'. *) k_if ::= 'i', 'f'; (* Used in if/else syntax. Must follow the condition of any 'if'. *) k_then ::= 't', 'h', 'e', 'n'; (* Used in if/else syntax. Indicates an 'else if' or 'else'. *) k_else ::= 'e', 'l', 's', 'e'; (* Used in do/return syntax. Indicates the start of such a structure. *) k_do ::= 'd', 'o'; (* Used in do/return syntax. Indicates the final output value. *) k_return ::= 'r', 'e', 't', 'u', 'r', 'n'; (* Indicates a type constructor. *) k_given ::= 'g', 'i', 'v', 'e', 'n'; (* Function modifier which restricts use to the enclosing scope. *) k_private ::= 'p', 'r', 'i', 'v', 'a', 't', 'e'; (* true is a Boolean literal *) k_true ::= 't', 'r', 'u', 'e'; (* false is a Boolean literal *) k_false ::= 'f', 'a', 'l', 's', 'e'; keyword ::= k_type | k_class | k_alias | k_const | k_enum | k_record | k_object | k_let | k_mut | k_export | k_import | k_namespace | k_infix | k_fn | k_end | k_match | k_case | k_if | k_then | k_else | k_do | k_return | k_given | k_private | k_true | k_false; (* ============== *) (* Literal Values *) (* ============== *) literal_bool ::= k_true | k_false; literal_integer ::= ['-'], number_integer; literal_float ::= ['-'], number_float; literal_char ::= "'", char_char, "'"; literal_string ::= '"', {string_char}, "'"; empty_tuple ::= lparen, rparen; empty_list ::= lbracket, rbracket; literal ::= literal_bool | literal_integer | literal_float | literal_char | literal_string | empty_tuple | empty_list; (* ========= *) (* Operators *) (* ========= *) (* Type hole used for development -- will resolve/compile, but fail at runtime. *) hole ::= '?', '?', '?'; (* Used to access members. Relevant for namespaces, records, enums, classes. *) op_member ::= '.'; (* Standard separator for type definitions, tuples and records. *) op_comma ::= ','; (* A | B is a type which can be either A or B. *) op_type_union ::= '|'; (* List operator. Prepend LHS to RHS. Can be used in pattern matching. *) op_list_prepend ::= ':'; (* Only valid adjacent to a name declaration. Explicitly declare the type that the name has. *) op_bind_type ::= ':'; (* Bind the RHS expression to the LHS name. *) op_bind_value ::= ':', '='; (* Used in function definitions: the LHS input produces RHS output. *) op_fn_return ::= '-', '>'; (* Binds the result contained in the RHS expression to the name on the LHS. *) (* Note that "contained" refers to the value in the [Bi]Monad. *) op_bind_do ::= '<', '-'; (* Indicates some type is constrained by some type class, ex F * :: Functor *) op_class_member ::= ':', ':'; (* Indicates the start of a case, case => *) op_case ::= '=', '>'; (* ===== *) (* Names *) (* ===== *) (* Used to denote an anonymous value, such as ignoring a pattern part. *) name_anon_value ::= '_'; (* Used to denote an anonymous parameter in a type definition. Helps to describe some type with a particular shape without naming each part. *) name_anon_type ::= '*';