val 0.4.2

An arbitrary precision calculator language
Documentation
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.