/* SYNTAX EXPLANATION */
[name] -> ... - rule definition
'...' - string literal
() - grouping
| - or
* - 0 or more
+ - 1 or more
*(...) - 0 or more where each term is separated by a ... (if 0 terms, there is no ...)
+(...) - 1 or more where each term is separated by a ...
? - 0 or 1 (optional)
. - any char
$ - end of line
foo - rule reference
comment @ignore -> '--' .*$
/* EXPRESSIONS */
fn_call -> ident '(' (expression),* ')'
block_expr -> '{' expression '}'
if_expr -> 'if' expression block_expr ('else' 'if' expression block_expr)* 'else' expression block_expr
/* Expression hierarchy */
expression -> logical_or
logical_or -> logical_and ('or' logical_and)*
logical_and -> logical_not ('and' logical_not)*
logical_not -> 'not'? (logical_not | comparison)
comparison -> additive (('==' | '!=' | '<' | '>' | '<=' | '>=') additive)*
additive -> multiplicative (('+' | '-') multiplicative)*
multiplicative -> unary (('*' | '/') unary)*
unary -> '-' unary | term
term -> number_lit | boolean_lit | fn_call | ident | if_expr | '(' expression ')'
/* STATEMENTS */
stmt_end -> '\n' | ';'
block -> '{' stmt*(stmt_end+) '}'
let_decl -> 'let' ident (':' ident(type))? '=' expression
var_decl -> 'var' ident (':' ident(type))? '=' expression
reassign -> ident '=' expression
reassign_plus -> ident '+=' expression
reassign_minus -> ident '-=' expression
reassign_mul -> ident '*=' expression
reassign_div -> ident '/=' expression
if_statement -> 'if' expression block ('else' 'if' expression block)* ('else' expression block)?
control_keyword -> 'break' | 'continue' | 'return' expression | 'return'
for -> 'for' (let_decl | var_decl | reassign | expression)*; block
stmt -> let_decl | var_decl | fn_decl | reassign | fn_call | control_keyword | block | for | if_statement
/* FUNCTIONS */
arg -> ident ':' ident(type)
fn_decl -> 'let' ident '(' (arg)*, ')' ':' ident(retType) '=' (expression | block)
/* TOP LEVEL */
import -> 'import' string_lit
file -> ((fn_decl | import) (stmt_end | <eof>))*