; Specification for this document:
; https://tools.ietf.org/html/rfc4234
; # Core ABNF rules
; !syntax("abnf")


; # Lexical
; ## Ignorables (whitespace and comments)

whitespace = %x09-0D / " "

not-newline = %x01-09 / %x0B-7F
singleline-comment = "//" *(not-newline)

not-star = %x01-29 / %x2B-7F
not-slash = %x01-2E / %x30-7F
multiline-comment = "/*" *(not-star / ("*" not-slash)) "*/"

comment = singleline-comment / multiline-comment
s =  *(whitespace / comment) ; space

; ## Values

; ### Numbers
digit = %x30-39
Number = *digit ["." 1*digit]
; TODO hex, binary?

; ### Strings
not-squote = %x01-26 / %x28-7F
not-dquote = %x01-21 / %x23-7F

common-escapes = "\" ("\" / "/" / "b" / "n" / "r" / "t" / ("u" 4*hex))
squote-string = "'" *(char-not-squote / "\'" / common-escapes) "'"
dquote-string = %x22 *(char-not-dquote / "\" %x22 / common-escapes) %x22
aquote-string = "`" *(not-aquote-dollar-slash / (not-dollar / "$" not-lacolade)) ("`" / "${")
; TODO string templates

; ### Boolean
true = "true"
false = "false"

; ## Identifier
alpha =  %x41-5A / %x61-7A ; A-Z / a-z
symbols = "+" / "-" / "*" / "/" / ">" / "<" / "=" / "!" / "@" / "#" / "$" / "%" / "^" / "&" / "|" / "\" / "_"
identifier = (alpha / symbols) *(alpha / symbols / digit)

; ## Operators and Symbols
dot = "."
lb = "["
rb = "]"
lp = "("
rp = ")"
la = "{"
ra = "}"
colon = ":"
dcolon = "::"
dots = "..."
delimiter =  ";" / ","
eq = "="
vbar = "|"
; # Parsing
; ## Primitive Values

string = squote-string / dquote-string
boolean = true / false
primitive = boolean / number / string

; ## Expressions and Compound Values
single-expr = object / primitive / identifier
expr = single-expr / ( expr dot identifier ) / ( expr lb s expr s rb ) / ( expr whitespace s expr ) / ( lp s expr s rp )


; ## Object

unbox-entry = ( constant-key s colon s constant-key ) / constant-key

parameteric-arg = ([dots] identifier[ s eq s expr]) / ( la s parameteric-args s ra ) / ( constant-key s colon s parameteric-arg )
parameteric-args = parameteric-arg s *(delimiter s parameteric-args)

unboxed-key = [constant-key] la s [unbox-entry *(s delimiter s unbox-entry)] s ra
constant-key = primitive / identifier *( dot identifier )
parameteric-key = [constant-key / parameteric-key] lb s parameteric-args [ vbar expr ] s rb *( dot identifier )
key = constant-key / parameteric-key / unboxed-key

definition = key s colon s expr
extension = [key] s dcolon s expr
indexed-definition = expr

lambda-object = definition
object-entry = (definition  / extension / indexed-definition)
object = lambda-object / la s [object-entry *(s delimiter s object-entry)] s ra 
