whitespace = _{ " " | "\t" }
sep = _{ "," | "\n" | "\r" }
plus = { "+" }
minus = { "-" }
times = { "*" }
divide = { "/" }
intdiv = { "\\" }
modulus = { "%" }
power = { "^" }
quote = _{ "\"" }
infix = _{ plus | minus | times | divide | intdiv | modulus | power }
backslash = _{"\\" }
oct = _{ '0'..'7' }
hex = _{ '0'..'9' | 'a'..'f' | 'A'..'F' }
esc = @{
    "\\" ~ ("n" | "r" | "t" | "\\" | "\'" | "\"")
  | "\\0" ~ oct ~ oct
  | "\\x" ~ hex ~ hex
  | "\\U" ~ hex{8}
  | "\\u" ~ hex{4}
}
quoted_chars = @{ (!quote ~ !backslash ~ any)+ }
quoted_string = ${ (esc | quoted_chars)* }
bare_string = @{ minus? ~ ('a'..'z' | 'A'..'Z' | '0'..'9' | "." | "_" )+ }
function = ${ bare_string ~ "(" ~ list ~ ")" }
value = {
    function
  | bare_string
  | quote ~ quoted_string ~ quote
  | "(" ~ expression ~ ")"
  | "{" ~ dict ~ "}"
  | "[" ~ list ~ "]"
}
template = { "let(" ~ sep* ~ (bare_string | quoted_string) ~ sep* ~ expression ~ sep* ~ ")" }
expression = { value ~ (infix ~ value)* }
exp_list = _{ ((template | expression) ~ sep ~ exp_list | sep ~ exp_list | (template | expression))? }
key_value = { expression{2,} }
kv_list = _{((template | key_value) ~ sep ~ kv_list | sep ~ kv_list | (template | key_value))? }
list = !{ exp_list }
dict = !{ kv_list }
root = _{ dict ~ eoi }
