MOD ::= EXPR* EXPR ::= | ASSERT | VARDECL | VARSET | SCOPE | IF | OR ASSERT ::= assert EXPR VARDECL ::= let ident assign EXPR VARSET ::= ident assign EXPR BLOCK ::= EXPR* SCOPE ::= begin BLOCK end IF ::= if EXPR then BLOCK (else BLOCK | IF)? end OR ::= AND (or AND)* AND ::= EQNE (and EQNE)* EQNE ::= | CMP | CMP eq CMP | CMP ne CMP CMP ::= TERM ((lt | le | ge | gt) TERM)? TERM ::= FACTOR ((add | sub) FACTOR)* FACTOR ::= POWER ((mul | div | mod) POWER)* POWER ::= UNARY (pow UNARY)? UNARY ::= sub? GROUP | not? GROUP GROUP ::= BUILTIN | opar EXPR cpar BUILTIN ::= num | bool | str | ident