val grammar
===========
tokens
------
```
EOF = emitted at the end of the input
IDENTIFIER = [_\p{XID_Start}]\p{XID_Continue}* # excluding reserved words
LINE_COMMENT = //[^\n]*
NUMBER = (0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?
STRING = "[^"]*"|'[^']*'
WHITESPACE = Unicode whitespace
```
grammar syntax
--------------
```
| alternation
() grouping
_? option (0 or 1 times)
_* repetition (0 or more times)
_+ repetition (1 or more times)
```
grammar
-------
```
program : padding statement_list padding EOF
statement_list : (statement ';'?)*
statement : assignment
| block
| break
| continue
| expression_statement
| for
| function
| if
| loop
| return
| while
assignment : assignment_target '=' expression
assignment_target : IDENTIFIER ('[' expression ']')*
block : '{' statement_list '}'
break : 'break'
continue : 'continue'
expression_statement : expression
for : 'for' IDENTIFIER 'in' expression block
function : 'fn' IDENTIFIER '(' (parameters ','?)? ')' block
if : 'if' '(' expression ')' block ('else' block)?
loop : 'loop' block
return : 'return' expression?
while : 'while' '(' expression ')' block
parameters : IDENTIFIER (',' IDENTIFIER)*
expression : logical_or
logical_or : logical_and ('||' logical_and)*
logical_and : equality ('&&' equality)*
equality : relational (('==' | '!=') relational)*
relational : sum (('>=' | '<=' | '>' | '<') sum)*
sum : product (('+' | '-') product)*
product : power (('*' | '/' | '%') power)*
power : unary ('^' power)?
unary : ('-' | '!')* postfix
postfix : atom (call | list_access)*
atom : NUMBER
| boolean
| null
| STRING
| list
| function_expression
| IDENTIFIER
| '(' expression ')'
boolean : 'true'
| 'false'
null : 'null'
list : '[' (arguments ','?)? ']'
function_expression : 'fn' '(' (parameters ','?)? ')' block
call : '(' (arguments ','?)? ')'
list_access : '[' expression ']'
arguments : expression (',' expression)*
padding : (WHITESPACE | LINE_COMMENT)*
```
The reserved words excluded from `IDENTIFIER` are `break`, `continue`, `else`,
`false`, `fn`, `for`, `if`, `in`, `loop`, `null`, `return`, `true`, and
`while`.
A `NUMBER` cannot be immediately followed by an identifier continuation
character.