Program ::= Statement+ Statement ::= (AssignmentStatement | FunctionCallStatement | IfStatement | WhileStatement | ReturnStatement) SEMICOLON AssignmentStatement ::= "let" IDENTIFIER EQUALS Expression FunctionCallStatement ::= IDENTIFIER LPAREN FunctionArguments? RPAREN IfStatement ::= "if" Expression LBRACE Statement* RBRACE -- TODO: Should function definitions be allowed? WhileStatement ::= "while" Expression LBRACE Statement* RBRACE ReturnStatement ::= RETURN Expression FunctionArguments ::= Expression ("," Expression)* Expression ::= EqualityExpression | AdditiveExpression | FunctionDefinition EqualityExpression ::= AdditiveExpression "==" AdditiveExpression AdditiveExpression ::= MultiplicativeExpression (("+" | "-") MultiplicativeExpression)* MultiplicativeExpression ::= UnaryExpression (("*" | "/") UnaryExpression)* UnaryExpression ::= ("!" | "-") UnaryExpression | PrimaryExpression PrimaryExpression ::= NUMBER | BOOLEAN | IDENTIFIER | FunctionCallStatement | LPAREN Expression RPAREN FunctionDefinition ::= LPAREN FunctionParameters? RPAREN ARROW LBRACE Statement* ReturnStatement SEMICOLON RBRACE FunctionParameters ::= IDENTIFIER ("," IDENTIFIER)*