WHITESPACE = _{ " " | "\t" | NEWLINE } COMMENT = _{ "/*" ~ (!"*/" ~ ANY)* ~ "*/" | "//" ~ (!NEWLINE ~ ANY)* } number = @{ "-"? ~ ("0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*) ~ ("." ~ ASCII_DIGIT+)? ~ (^"e" ~ ("+" | "-")? ~ ASCII_DIGIT+)? } string = ${ "\"" ~ inner ~ "\"" } inner = @{ character* } character = { !("\"" | "\\") ~ ANY | "\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t") | "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4}) } char = ${ "\'" ~ character ~ "\'" } boolean = { "true" | "false" } identifier = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_" )* } call = ${ identifier ~ call_params } call_params = !{ "(" ~ (expression ~ ","?)* ~ ")" } parens = { "(" ~ expression ~ ")" } const_value = { number | string | char | boolean } value = { (const_value | call | identifier | parens) ~ method_call } method_call = { (("." ~ identifier ~ call_params) ~ method_call)? } expression = { if_block_expr | equality } equality = { inequality ~ ((equals | not_equals) ~ inequality)? } inequality = { sum ~ ((less_than | greater_than | less_than_or_equal | greater_than_or_equal) ~ sum)? } sum = { product ~ ((plus | minus) ~ product)* } product = { value ~ ((times | divide | modulo) ~ value)* } root_statement = { SOI ~ statement* ~ EOI } statement = { ( ret | assignment | assignment_let | expression ) ~ ";" | def | while_block | if_block | block } block = { "{" ~ statement* ~ "}" } func_block = { "{" ~ statement* ~ expression? ~ "}" } assignment_let = { "let" ~ identifier ~ "=" ~ expression } assignment = { identifier ~ "=" ~ expression } ret = { "return" ~ expression? } while_block = { "while" ~ expression ~ block } if_block = { "if" ~ expression ~ block ~ ("else if" ~ expression ~ block)* ~ ("else" ~ block)? } if_block_expr = { "if" ~ expression ~ if_block_expr_block ~ ("else if" ~ expression ~ if_block_expr_block)* ~ "else" ~ if_block_expr_block } if_block_expr_block = { "{" ~ statement* ~ expression ~ "}" } def_params = { "(" ~ (identifier ~ ","?)* ~ ")" } def = { "def" ~ identifier ~ def_params ~ func_block } equals = { "==" } not_equals = { "!=" } less_than = { "<" } greater_than = { ">" } less_than_or_equal = { "<=" } greater_than_or_equal = { ">=" } plus = { "+" } minus = { "-" } times = { "*" } divide = { "/" } modulo = { "%" }