MOO Grammar
===========
program ::= [statement program]
statement ::= [expression] ";"
| if-condition
| for-loop
| while-loop
| fork-statements
| return
if-condition ::= "if" "(" expression ")" program [else-conds] "endif"
else-conds ::= "elseif" "(" expression ")" program [else-conds]
| "else" program
for-loop ::= "for" for-vars "in" for-range program "endfor"
for-vars ::= <identifier> ["~" <identifier>]
for-range ::= "(" expression ")"
| "[" expression ".." expression "]"
while-loop ::= "while" "(" expression ")" program "endwhile"
return ::= "return" [expression] ";"
fork-statements ::= "fork" [<identifier>] "(" expression ")" program "endfork"
expression ::= lvalue [lvalue-indices] "=" expression
| rvalue
lvalue ::= variable
| property
lvalue-indices ::= "[" expression "]" [lvalue-indices]
| "[" expression ".." expression "]"
rvalue ::= conditional ["?" expression "|" rvalue]
conditional ::= logical [logical-op conditional]
logical-op ::= "&&" | "||"
logical ::= relational [relational-op logical]
relational-op ::= "==" | "!=" | "<" | "<=" | ">" | ">=" | "in"
relational ::= term [term-op relational]
term-op ::= "+" | "-"
term ::= factor [factor-op term]
factor-op ::= "*" | "/" | "%"
factor ::= unary-op factor
| unary
unary-op ::= "!" | "-"
unary ::= primary [rvalue-indices]
primary ::= "(" expression ")"
| literal
| variable
| property
| verb-call
| builtin-call
variable ::= <identifier>
verb-call ::= unary ":" name "(" [list-elems] ")"
builtin-call ::= <identifier> "(" [list-elems] ")"
property ::= unary "." name
| "$" <identifier>
name ::= <identifier>
| "(" expression ")"
rvalue-indices ::= "[" expression "]" [rvalue-indices]
| "[" expression ".." expression "]" [rvalue-indices]
literal ::= <number> | <objref> | <errval> | <string> | list
| <float> | table
list ::= "{" [list-elems] "}"
list-elems ::= ["@"] expression ["," list-elems]
table ::= "{" [table-elems] "}"
table-elems ::= table-item ["," table-elems]
| "~"
table-item ::= "@" expression
| expression "~" expression