file = { "hello world" } statement = { decl } decl = { "let" ~ #name = ident ~ #args = (ident)* ~ "=" ~ expr } expr = { infix_expr | call_expr | term } term = _{ ident | literal | "(" ~ expr ~ ")" } call_expr = { #name = ident ~ #args = (term)+ } infix_expr = { #lhs = term ~ operator ~ #rhs = expr } operator = { "+" | "-" | "*" | "/" | "&&" | "||" | "<" | ">" | "==" | "!=" } ident = @{ ALPHABETIC ~ (ALPHABETIC | NUMBER | "_")* | quoted_indent } quoted_indent = _{ "`" ~ (!"`" ~ ANY)+ ~ "`" } literal = { string | number | boolean | char } string = { "\"" ~ (!"\"" ~ ANY)* ~ "\"" } char = { "'" ~ !"'" ~ ANY ~ "'" } number = _{ byte | float | integer } integer = @{ "-"? ~ ASCII_DIGIT+ } float = @{ "-"? ~ (ASCII_DIGIT+ ~ "." ~ ASCII_DIGIT* | ASCII_DIGIT* ~ "." ~ ASCII_DIGIT+) } byte = @{ "0x" ~ ASCII_HEX_DIGIT{1, 2} | "0b" ~ ASCII_BIN_DIGIT{0, 8} } boolean = @{ "true" | "false" } WHITESPACE = _{ " " | "\t" | "\r" | "\n" }