// Generate via:
//   npm i -g pegjs terser
//   pegjs < ./lib/util/jsonc.pegjs | terser -cm > ./lib/util/jsonc.js

JSON = _ v:value _ { return v }
value = object / array / null / true / false / number / string

object
  = o:(_"{"_ {return{}}) (
    ( k:string colon v:value {o[k]=v})
    ( comma k:string colon v:value {o[k]=v})* comma?
  )? _"}"_
  { return o }

array
  = a:(_"["_ {return[]}) (
    ( v:value {a.push(v)})
    ( comma v:value {a.push(v)})* comma?
  )? _"]"_
  { return a }

number
    = x:$( [+-]? [0-9]+ ("." [0-9]+)? ([eE] [+-]? [0-9]+)? )
    { return Number(x) }

string "string"
  = '"' chars:(
    ( "\\" x:( '"' / "\\" / "/"
      / "n" { return "\n" }
      / "r" { return "\r" }
      / "t" { return "\t" }
      / "b" { return "\b" }
      / "f" { return "\f" }
      / "u" u:$([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]) {
        return String.fromCharCode(parseInt(u,16))
      }
    ) {return x}) / [^"]
  )* '"'
  { return chars.join('') }

null  = "null"  { return null  }
true  = "true"  { return true  }
false = "false" { return false }

colon = _":"_ {return}
comma = _","_ {return}

// _ = [ \t\n\r]* {} //> standard JSON
_ = ([ \t\n\r] / line_comment / block_comment )* {}
line_comment = $( "//" (![\n\r\u2028\u2029] .)* )
block_comment = $( "/*" (!"*/" .)* "*/" )
