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