Program = (Statement / _)* end:PROGRAM_END _? Statement = Definition / Expression Definition = EnumDefinition / InterfaceDefinition / FunctionDefinition Expression = BinaryExpression / UnaryExpression / Literal // recursion here after removing LPAREN - maybe move to prefix notation? BinaryExpression = LPAREN left:Expression _ op:BinaryOperation _ right:Expression BinaryOperation = ArithmeticOperation / ComparisonOperation / BooleanOperation ArithmeticOperation = "+" / "-" / "/" / "%" / "*" / "**" / ">>" / "<<" / "|" / "&" ComparisonOperation = "<" / ">" / "<=" / ">=" / "==" / "!=" BooleanOperation = "||" / "&&" UnaryExpression = PrefixOperation Expression / LPAREN Expression PostfixOperation PrefixOperation = "!" / "~" PostfixOperation = LBRACKET _? index:PositiveInteger _? RBRACKET EnumDefinition = ENUM_DEF _ name:PASCAL_CASE _ ENUM_CONT _ SCOPE_START _ options:EnumBody+ _ SCOPE_END EnumBody = name:Identifier "," InterfaceDefinition = INTERFACE_DEF _ name:PASCAL_CASE _ INTERFACE_CONT _ signatures:FunctionSignature* _ SCOPE_END FunctionDefinition = FunctionSignature _ SCOPE_START _ body:Expression* _ SCOPE_END FunctionSignature = FUNCTION_DEF _ name:CAMEL_CASE _ (FUNCTION_DEF_ARGS _ args:FunctionArgsList _)? FUNCTION_RETURN_TYPE _ result:Type FunctionArgsList = (type:Type _ name:CAMEL_CASE _? "," _?)? type:Type _ name:CAMEL_CASE Type = name:PASCAL_CASE (_ generic:Generic)? / TupleType / UnionType TupleType = tupleType:PASCAL_CASE _? LBRACKET _? tupleLength:PositiveInteger _? RBRACKET UnionType = firstType:PASCAL_CASE _ TYPE_UNION _ secondType:(UnionType / Type) Generic = LPAREN _? generic:((Type _? COMMA _?)* Type _?) RPAREN Identifier = PASCAL_CASE / CAMEL_CASE PASCAL_CASE = [A-Z](LETTER / DIGIT / SAFE_SYMBOL)+ CAMEL_CASE = [a-z](LETTER / DIGIT / SAFE_SYMBOL)+ PositiveInteger = [1-9][0-9]* TYPE_UNION = "OR" FUNCTION_DEF = "DISCOVER" _ "HOW" _ "TO" FUNCTION_DEF_ARGS = "WITH" FUNCTION_RETURN_TYPE = "GIVES" _ "YOU" INTERFACE_DEF = "STUFF" _ "OF" INTERFACE_CONT = "LOOKS" _ "LIKE" ENUM_DEF = "ONLY" _ "OPTIONS" _ "OF" ENUM_CONT = "ARE" SCOPE_START = "RUMOR" _ "HAS" _ "IT" SCOPE_END = "END" _ "OF" _ "STORY" PROGRAM_END = "PLEASE" _ "LIKE" _ "AND" _ "SUBSCRIBE" COMMA = "," LBRACKET = "[" RBRACKET = "]" LPAREN = "(" RPAREN = ")" _ = (" " / "\n" / "\t" / "\r\n")+ LETTER = [A-Za-z] SAFE_SYMBOL = "_" DIGIT = [0-9]