WHITESPACE = _{ " " | "\t" | NEWLINE }
COMMENT = _{ ("//" | ";;" ) ~ (!NEWLINE ~ ANY)* ~ NEWLINE }
// Primitives
list = { "(" ~ expression* ~ ")" }
symbol = @{ (LETTER | NUMBER | SYMBOL | DASH_PUNCTUATION | (!(number) ~ "-") | OTHER_PUNCTUATION )+ }
keyword = { ":" ~ symbol }
number = @{ "-"? ~ (ASCII_DIGIT)+ ~ ("." ~ ASCII_DIGIT+)? ~ (^"e" ~ ("+" | "-")? ~ ASCII_DIGIT+)? }
char = {
!("\"" | "\\") ~ ANY
| "\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t")
| "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4})
}
text = { "\"" ~ char* ~ "\"" }
byte = @{ "b" ~ number}
primitive = _{ list | keyword | text | number | byte | symbol }
// Functions & macros
arg_symbols = { ("(" ~ symbol* ~ ")") }
arg_symbol = { symbol }
lambda_def = {"(" ~ "lambda" ~ (arg_symbols | arg_symbol) ~ expression+ ~ ")"}
macro_def = {"(" ~ "macro" ~ (arg_symbols | arg_symbol) ~ expression+ ~ ")"}
func_notations = _{ lambda_def | macro_def }
// Sugar
quote = { "'" ~ expression }
eval = { "," ~ expression }
sugar = _{ quote | eval }
expression = _{ sugar | primitive }
expressions = _{ SOI ~ expression+ ~ EOI }