{"cells":[{"cell_type":"markdown","metadata":{},"source":["# JsonParser (Polyglot)"]},{"cell_type":"code","execution_count":1,"metadata":{"duration_ms":12008,"language":"fsharp"},"outputs":[],"source":["#!import ../../lib/fsharp/Notebooks.livemd"]},{"cell_type":"code","execution_count":2,"metadata":{"duration_ms":932,"language":"fsharp"},"outputs":[],"source":["#!import ../../lib/fsharp/Testing.livemd"]},{"cell_type":"code","execution_count":3,"metadata":{"duration_ms":53,"language":"fsharp"},"outputs":[],"source":["#!import ../../lib/fsharp/Common.fs"]},{"cell_type":"code","execution_count":4,"metadata":{"duration_ms":485,"language":"fsharp"},"outputs":[],"source":["#!import Parser.fs"]},{"cell_type":"code","execution_count":5,"metadata":{"duration_ms":12,"language":"fsharp"},"outputs":[],"source":["open Common\n","open Parser"]},{"cell_type":"markdown","metadata":{},"source":["## JsonParser"]},{"cell_type":"code","execution_count":6,"metadata":{"duration_ms":8,"language":"fsharp"},"outputs":[],"source":["(*\n","// --------------------------------\n","JSON spec from http://www.json.org/\n","// --------------------------------\n","\n","The JSON spec is available at [json.org](http://www.json.org/). I'll paraphase it here:\n","\n","* A `value` can be a `string` or a `number` or a `bool` or `null` or an `object` or an `array`.\n","  * These structures can be nested.\n","* A `string` is a sequence of zero or more Unicode characters, wrapped in double quotes, using backslash escapes.\n","* A `number` is very much like a C or Java number, except that the octal and hexadecimal formats are not used.\n","* A `boolean` is the literal `true` or `false`\n","* A `null` is the literal `null`\n","* An `object` is an unordered set of name/value pairs.\n","  * An object begins with { (left brace) and ends with } (right brace).\n","  * Each name is followed by : (colon) and the name/value pairs are separated by , (comma).\n","* An `array` is an ordered collection of values.\n","  * An array begins with [ (left bracket) and ends with ] (right bracket).\n","  * Values are separated by , (comma).\n","* Whitespace can be inserted between any pair of tokens.\n","*)"]},{"cell_type":"code","execution_count":7,"metadata":{"duration_ms":33,"language":"fsharp"},"outputs":[],"source":["///- --test\n","\n","let inline parserEqual (expected : ParseResult<'a>) (actual : ParseResult<'a * Input>) =\n","    match actual, expected with\n","    | Success (_actual, _), Success _expected ->\n","        printResult actual\n","        _actual |> _assertEqual _expected\n","    | Failure (l1, e1, p1), Failure (l2, e2, p2) when l1 = l2 && e1 = e2 && p1 = p2 ->\n","        printResult actual\n","    | _ ->\n","        printfn $\"Actual: {actual}\"\n","        printfn $\"Expected: {expected}\"\n","        failwith \"Parse failed\"\n","    actual"]},{"cell_type":"markdown","metadata":{},"source":["### JValue"]},{"cell_type":"code","execution_count":8,"metadata":{"duration_ms":64,"language":"fsharp"},"outputs":[],"source":["type JValue =\n","    | JString of string\n","    | JNumber of float\n","    | JBool   of bool\n","    | JNull\n","    | JObject of Map<string, JValue>\n","    | JArray  of JValue list"]},{"cell_type":"code","execution_count":9,"metadata":{"duration_ms":15,"language":"fsharp"},"outputs":[],"source":["let jValue, jValueRef = createParserForwardedToRef<JValue> ()"]},{"cell_type":"markdown","metadata":{},"source":["### jNull"]},{"cell_type":"code","execution_count":10,"metadata":{"duration_ms":30,"language":"fsharp"},"outputs":[],"source":["let jNull =\n","    pstring \"null\"\n","    >>% JNull\n","    <?> \"null\""]},{"cell_type":"code","execution_count":11,"metadata":{"duration_ms":14,"language":"fsharp"},"outputs":[],"source":["///- --test\n","\n","jValueRef <|\n","    choice\n","        [\n","            jNull\n","        ]"]},{"cell_type":"code","execution_count":12,"metadata":{"duration_ms":61,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JNull\n","JNull"]},{"data":{"text/plain":["Success (JNull, { lines = [|\"null\"|]\n","                  position = { line = 0\n","                               column = 4 } })"]},"execution_count":12,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jValue \"null\"\n","|> parserEqual (Success JNull)"]},{"cell_type":"code","execution_count":13,"metadata":{"duration_ms":30,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["Line:0 Col:3 Error parsing null\n","nulp\n","   ^Unexpected 'p'"]},{"data":{"text/plain":["Failure (\"null\", \"Unexpected 'p'\", { currentLine = \"nulp\"\n","                                     line = 0\n","                                     column = 3 })"]},"execution_count":13,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jNull \"nulp\"\n","|> parserEqual (\n","    Failure (\n","        \"null\",\n","        \"Unexpected 'p'\",\n","        { currentLine = \"nulp\"; line = 0; column = 3 }\n","    )\n",")"]},{"cell_type":"markdown","metadata":{},"source":["### jBool"]},{"cell_type":"code","execution_count":14,"metadata":{"duration_ms":45,"language":"fsharp"},"outputs":[],"source":["let jBool =\n","    let jtrue =\n","        pstring \"true\"\n","        >>% JBool true\n","    let jfalse =\n","        pstring \"false\"\n","        >>% JBool false\n","\n","    jtrue <|> jfalse\n","    <?> \"bool\""]},{"cell_type":"code","execution_count":15,"metadata":{"duration_ms":14,"language":"fsharp"},"outputs":[],"source":["///- --test\n","\n","jValueRef <|\n","    choice\n","        [\n","            jNull\n","            jBool\n","        ]"]},{"cell_type":"code","execution_count":16,"metadata":{"duration_ms":38,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JBool true\n","JBool true"]},{"data":{"text/plain":["Success (JBool true, { lines = [|\"true\"|]\n","                       position = { line = 0\n","                                    column = 4 } })"]},"execution_count":16,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jBool \"true\"\n","|> parserEqual (Success (JBool true))"]},{"cell_type":"code","execution_count":17,"metadata":{"duration_ms":32,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JBool false\n","JBool false"]},{"data":{"text/plain":["Success (JBool false, { lines = [|\"false\"|]\n","                        position = { line = 0\n","                                     column = 5 } })"]},"execution_count":17,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jBool \"false\"\n","|> parserEqual (Success (JBool false))"]},{"cell_type":"code","execution_count":18,"metadata":{"duration_ms":36,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["Line:0 Col:0 Error parsing bool\n","truX\n","^Unexpected 't'"]},{"data":{"text/plain":["Failure (\"bool\", \"Unexpected 't'\", { currentLine = \"truX\"\n","                                     line = 0\n","                                     column = 0 })"]},"execution_count":18,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jBool \"truX\"\n","|> parserEqual (\n","    Failure (\n","        \"bool\",\n","        \"Unexpected 't'\",\n","        { currentLine = \"truX\"; line = 0; column = 0 }\n","    )\n",")"]},{"cell_type":"markdown","metadata":{},"source":["### jUnescapedChar"]},{"cell_type":"code","execution_count":19,"metadata":{"duration_ms":47,"language":"fsharp"},"outputs":[],"source":["let jUnescapedChar =\n","    satisfy (fun ch -> ch <> '\\\\' && ch <> '\\\"') \"char\""]},{"cell_type":"code","execution_count":20,"metadata":{"duration_ms":40,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["'a'\n","'a'"]},{"data":{"text/plain":["Success ('a', { lines = [|\"a\"|]\n","                position = { line = 0\n","                             column = 1 } })"]},"execution_count":20,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jUnescapedChar \"a\"\n","|> parserEqual (Success 'a')"]},{"cell_type":"code","execution_count":21,"metadata":{"duration_ms":30,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["Line:0 Col:0 Error parsing char\n","\\\n","^Unexpected '\\'"]},{"data":{"text/plain":["Failure (\"char\", \"Unexpected '\\'\", { currentLine = \"\\\"\n","                                     line = 0\n","                                     column = 0 })"]},"execution_count":21,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jUnescapedChar \"\\\\\"\n","|> parserEqual (\n","    Failure (\n","        \"char\",\n","        \"Unexpected '\\\\'\",\n","        { currentLine = \"\\\\\"; line = 0; column = 0 }\n","    )\n",")"]},{"cell_type":"markdown","metadata":{},"source":["### jEscapedChar"]},{"cell_type":"code","execution_count":22,"metadata":{"duration_ms":39,"language":"fsharp"},"outputs":[],"source":["let jEscapedChar =\n","    [\n","        (\"\\\\\\\"\",'\\\"')\n","        (\"\\\\\\\\\",'\\\\')\n","        (\"\\\\/\",'/')\n","        (\"\\\\b\",'\\b')\n","        (\"\\\\f\",'\\f')\n","        (\"\\\\n\",'\\n')\n","        (\"\\\\r\",'\\r')\n","        (\"\\\\t\",'\\t')\n","    ]\n","    |> List.map (fun (toMatch, result) ->\n","        pstring toMatch >>% result\n","    )\n","    |> choice\n","    <?> \"escaped char\""]},{"cell_type":"code","execution_count":23,"metadata":{"duration_ms":33,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["'\\\\'\n","'\\\\'"]},{"data":{"text/plain":["Success ('\\\\', { lines = [|\"\\\\\"|]\n","                 position = { line = 0\n","                              column = 2 } })"]},"execution_count":23,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jEscapedChar \"\\\\\\\\\"\n","|> parserEqual (Success '\\\\')"]},{"cell_type":"code","execution_count":24,"metadata":{"duration_ms":32,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["'\\009'\n","'\\009'"]},{"data":{"text/plain":["Success ('\\009', { lines = [|\"\\t\"|]\n","                   position = { line = 0\n","                                column = 2 } })"]},"execution_count":24,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jEscapedChar \"\\\\t\"\n","|> parserEqual (Success '\\t')"]},{"cell_type":"code","execution_count":25,"metadata":{"duration_ms":28,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["'\\\\'\n","'\\\\'"]},{"data":{"text/plain":["Success ('\\\\', { lines = [|\"\\\\\"|]\n","                 position = { line = 0\n","                              column = 2 } })"]},"execution_count":25,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jEscapedChar @\"\\\\\"\n","|> parserEqual (Success '\\\\')"]},{"cell_type":"code","execution_count":26,"metadata":{"duration_ms":29,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["'\\010'\n","'\\010'"]},{"data":{"text/plain":["Success ('\\010', { lines = [|\"\\n\"|]\n","                   position = { line = 0\n","                                column = 2 } })"]},"execution_count":26,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jEscapedChar @\"\\n\"\n","|> parserEqual (Success '\\n')"]},{"cell_type":"code","execution_count":27,"metadata":{"duration_ms":31,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["Line:0 Col:0 Error parsing escaped char\n","a\n","^Unexpected 'a'"]},{"data":{"text/plain":["Failure (\"escaped char\", \"Unexpected 'a'\", { currentLine = \"a\"\n","                                             line = 0\n","                                             column = 0 })"]},"execution_count":27,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jEscapedChar \"a\"\n","|> parserEqual (\n","    Failure (\n","        \"escaped char\",\n","        \"Unexpected 'a'\",\n","        { currentLine = \"a\"; line = 0; column = 0 }\n","    )\n",")"]},{"cell_type":"markdown","metadata":{},"source":["### jUnicodeChar"]},{"cell_type":"code","execution_count":28,"metadata":{"duration_ms":68,"language":"fsharp"},"outputs":[],"source":["let jUnicodeChar =\n","    let backslash = pchar '\\\\'\n","    let uChar = pchar 'u'\n","    let hexdigit = anyOf ([ '0' .. '9' ] @ [ 'A' .. 'F' ] @ [ 'a' .. 'f' ])\n","    let fourHexDigits = hexdigit .>>. hexdigit .>>. hexdigit .>>. hexdigit\n","\n","    let inline convertToChar (((h1, h2), h3), h4) =\n","        let str = $\"%c{h1}%c{h2}%c{h3}%c{h4}\"\n","        Int32.Parse (str, Globalization.NumberStyles.HexNumber) |> char\n","\n","    backslash >>. uChar >>. fourHexDigits\n","    |>> convertToChar"]},{"cell_type":"code","execution_count":29,"metadata":{"duration_ms":36,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["'☺'\n","'☺'"]},{"data":{"text/plain":["Success ('☺', { lines = [|\"\\u263A\"|]\n","                position = { line = 0\n","                             column = 6 } })"]},"execution_count":29,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jUnicodeChar \"\\\\u263A\"\n","|> parserEqual (Success '☺')"]},{"cell_type":"markdown","metadata":{},"source":["### jString"]},{"cell_type":"code","execution_count":30,"metadata":{"duration_ms":36,"language":"fsharp"},"outputs":[],"source":["let quotedString =\n","    let quote = pchar '\\\"' <?> \"quote\"\n","    let jchar = jUnescapedChar <|> jEscapedChar <|> jUnicodeChar\n","\n","    quote >>. manyChars jchar .>> quote"]},{"cell_type":"code","execution_count":31,"metadata":{"duration_ms":15,"language":"fsharp"},"outputs":[],"source":["let jString =\n","    quotedString\n","    |>> JString\n","    <?> \"quoted string\""]},{"cell_type":"code","execution_count":32,"metadata":{"duration_ms":15,"language":"fsharp"},"outputs":[],"source":["///- --test\n","\n","jValueRef <|\n","    choice\n","        [\n","            jNull\n","            jBool\n","            jString\n","        ]"]},{"cell_type":"code","execution_count":33,"metadata":{"duration_ms":37,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JString \"\"\n","JString \"\""]},{"data":{"text/plain":["Success (JString \"\", { lines = [|\"\"\"\"|]\n","                       position = { line = 0\n","                                    column = 2 } })"]},"execution_count":33,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jString \"\\\"\\\"\"\n","|> parserEqual (Success (JString \"\"))"]},{"cell_type":"code","execution_count":34,"metadata":{"duration_ms":30,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JString \"a\"\n","JString \"a\""]},{"data":{"text/plain":["Success (JString \"a\", { lines = [|\"\"a\"\"|]\n","                        position = { line = 0\n","                                     column = 3 } })"]},"execution_count":34,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jString \"\\\"a\\\"\"\n","|> parserEqual (Success (JString \"a\"))"]},{"cell_type":"code","execution_count":35,"metadata":{"duration_ms":34,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JString \"ab\"\n","JString \"ab\""]},{"data":{"text/plain":["Success (JString \"ab\", { lines = [|\"\"ab\"\"|]\n","                         position = { line = 0\n","                                      column = 4 } })"]},"execution_count":35,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jString \"\\\"ab\\\"\"\n","|> parserEqual (Success (JString \"ab\"))"]},{"cell_type":"code","execution_count":36,"metadata":{"duration_ms":33,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JString \"ab\tde\"\n","JString \"ab\tde\""]},{"data":{"text/plain":["Success (JString \"ab\tde\", { lines = [|\"\"ab\\tde\"\"|]\n","                            position = { line = 0\n","                                         column = 8 } })"]},"execution_count":36,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jString \"\\\"ab\\\\tde\\\"\"\n","|> parserEqual (Success (JString \"ab\\tde\"))"]},{"cell_type":"code","execution_count":37,"metadata":{"duration_ms":76,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JString \"ab☺de\"\n","JString \"ab☺de\""]},{"data":{"text/plain":["Success (JString \"ab☺de\", { lines = [|\"\"ab\\u263Ade\"\"|]\n","                            position = { line = 0\n","                                         column = 12 } })"]},"execution_count":37,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jString \"\\\"ab\\\\u263Ade\\\"\"\n","|> parserEqual (Success (JString \"ab☺de\"))"]},{"cell_type":"markdown","metadata":{},"source":["### jNumber"]},{"cell_type":"code","execution_count":38,"metadata":{"duration_ms":166,"language":"fsharp"},"outputs":[],"source":["let jNumber =\n","    let optSign = opt (pchar '-')\n","\n","    let zero = pstring \"0\"\n","\n","    let digitOneNine =\n","        satisfy (fun ch -> Char.IsDigit ch && ch <> '0') \"1-9\"\n","\n","    let digit =\n","        satisfy Char.IsDigit \"digit\"\n","\n","    let point = pchar '.'\n","\n","    let e = pchar 'e' <|> pchar 'E'\n","\n","    let optPlusMinus = opt (pchar '-' <|> pchar '+')\n","\n","    let nonZeroInt =\n","        digitOneNine .>>. manyChars digit\n","        |>> fun (first, rest) -> string first + rest\n","\n","    let intPart = zero <|> nonZeroInt\n","\n","    let fractionPart = point >>. manyChars1 digit\n","\n","    let exponentPart = e >>. optPlusMinus .>>. manyChars1 digit\n","\n","    let inline (|>?) opt f =\n","        match opt with\n","        | None -> \"\"\n","        | Some x -> f x\n","\n","    let inline convertToJNumber (((optSign, intPart), fractionPart), expPart) =\n","        let signStr =\n","            optSign\n","            |>? string\n","\n","        let fractionPartStr =\n","            fractionPart\n","            |>? (fun digits -> \".\" + digits)\n","\n","        let expPartStr =\n","            expPart\n","            |>? fun (optSign, digits) ->\n","                let sign = optSign |>? string\n","                \"e\" + sign + digits\n","\n","        (signStr + intPart + fractionPartStr + expPartStr)\n","        |> float\n","        |> JNumber\n","\n","    optSign .>>. intPart .>>. opt fractionPart .>>. opt exponentPart\n","    |>> convertToJNumber\n","    <?> \"number\""]},{"cell_type":"code","execution_count":39,"metadata":{"duration_ms":22,"language":"fsharp"},"outputs":[],"source":["///- --test\n","\n","jValueRef <|\n","    choice\n","        [\n","            jNull\n","            jBool\n","            jString\n","            jNumber\n","        ]"]},{"cell_type":"code","execution_count":40,"metadata":{"duration_ms":48,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JNumber 123.0\n","JNumber 123.0"]},{"data":{"text/plain":["Success (JNumber 123.0, { lines = [|\"123\"|]\n","                          position = { line = 0\n","                                       column = 3 } })"]},"execution_count":40,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jNumber \"123\"\n","|> parserEqual (Success (JNumber 123.0))"]},{"cell_type":"code","execution_count":41,"metadata":{"duration_ms":39,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JNumber -123.0\n","JNumber -123.0"]},{"data":{"text/plain":["Success (JNumber -123.0, { lines = [|\"-123\"|]\n","                           position = { line = 0\n","                                        column = 4 } })"]},"execution_count":41,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jNumber \"-123\"\n","|> parserEqual (Success (JNumber -123.0))"]},{"cell_type":"code","execution_count":42,"metadata":{"duration_ms":41,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JNumber 123.4\n","JNumber 123.4"]},{"data":{"text/plain":["Success (JNumber 123.4, { lines = [|\"123.4\"|]\n","                          position = { line = 0\n","                                       column = 5 } })"]},"execution_count":42,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jNumber \"123.4\"\n","|> parserEqual (Success (JNumber 123.4))"]},{"cell_type":"code","execution_count":43,"metadata":{"duration_ms":39,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JNumber -123.0\n","JNumber -123.0"]},{"data":{"text/plain":["Success (JNumber -123.0, { lines = [|\"-123.\"|]\n","                           position = { line = 0\n","                                        column = 4 } })"]},"execution_count":43,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jNumber \"-123.\"\n","|> parserEqual (Success (JNumber -123.0))"]},{"cell_type":"code","execution_count":44,"metadata":{"duration_ms":36,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JNumber 0.0\n","JNumber 0.0"]},{"data":{"text/plain":["Success (JNumber 0.0, { lines = [|\"00.1\"|]\n","                        position = { line = 0\n","                                     column = 1 } })"]},"execution_count":44,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jNumber \"00.1\"\n","|> parserEqual (Success (JNumber 0.0))"]},{"cell_type":"code","execution_count":45,"metadata":{"duration_ms":25,"language":"fsharp"},"outputs":[],"source":["///- --test\n","\n","let jNumber_ = jNumber .>> spaces1"]},{"cell_type":"code","execution_count":46,"metadata":{"duration_ms":38,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JNumber 123.0\n","JNumber 123.0"]},{"data":{"text/plain":["Success (JNumber 123.0, { lines = [|\"123\"|]\n","                          position = { line = 1\n","                                       column = 0 } })"]},"execution_count":46,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jNumber_ \"123\"\n","|> parserEqual (Success (JNumber 123.0))"]},{"cell_type":"code","execution_count":47,"metadata":{"duration_ms":41,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JNumber -123.0\n","JNumber -123.0"]},{"data":{"text/plain":["Success (JNumber -123.0, { lines = [|\"-123\"|]\n","                           position = { line = 1\n","                                        column = 0 } })"]},"execution_count":47,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jNumber_ \"-123\"\n","|> parserEqual (Success (JNumber -123.0))"]},{"cell_type":"code","execution_count":48,"metadata":{"duration_ms":39,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["Line:0 Col:4 Error parsing number andThen many1 whitespace\n","-123.\n","    ^Unexpected '.'"]},{"data":{"text/plain":["Failure (\"number andThen many1 whitespace\", \"Unexpected '.'\", { currentLine = \"-123.\"\n","                                                                line = 0\n","                                                                column = 4 })"]},"execution_count":48,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jNumber_ \"-123.\"\n","|> parserEqual (\n","    Failure (\n","        \"number andThen many1 whitespace\",\n","        \"Unexpected '.'\",\n","        { currentLine = \"-123.\"; line = 0; column = 4 }\n","    )\n",")"]},{"cell_type":"code","execution_count":49,"metadata":{"duration_ms":36,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JNumber 123.4\n","JNumber 123.4"]},{"data":{"text/plain":["Success (JNumber 123.4, { lines = [|\"123.4\"|]\n","                          position = { line = 1\n","                                       column = 0 } })"]},"execution_count":49,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jNumber_ \"123.4\"\n","|> parserEqual (Success (JNumber 123.4))"]},{"cell_type":"code","execution_count":50,"metadata":{"duration_ms":37,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["Line:0 Col:1 Error parsing number andThen many1 whitespace\n","00.4\n"," ^Unexpected '0'"]},{"data":{"text/plain":["Failure (\"number andThen many1 whitespace\", \"Unexpected '0'\", { currentLine = \"00.4\"\n","                                                                line = 0\n","                                                                column = 1 })"]},"execution_count":50,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jNumber_ \"00.4\"\n","|> parserEqual (\n","    Failure (\n","        \"number andThen many1 whitespace\",\n","        \"Unexpected '0'\",\n","        { currentLine = \"00.4\"; line = 0; column = 1 }\n","    )\n",")"]},{"cell_type":"code","execution_count":51,"metadata":{"duration_ms":82,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JNumber 1230000.0\n","JNumber 1230000.0"]},{"data":{"text/plain":["Success (JNumber 1230000.0, { lines = [|\"123e4\"|]\n","                              position = { line = 1\n","                                           column = 0 } })"]},"execution_count":51,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jNumber_ \"123e4\"\n","|> parserEqual (Success (JNumber 1230000.0))"]},{"cell_type":"code","execution_count":52,"metadata":{"duration_ms":44,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JNumber 12340000.0\n","JNumber 12340000.0"]},{"data":{"text/plain":["Success (JNumber 12340000.0, { lines = [|\"123.4e5\"|]\n","                               position = { line = 1\n","                                            column = 0 } })"]},"execution_count":52,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jNumber_ \"123.4e5\"\n","|> parserEqual (Success (JNumber 12340000.0))"]},{"cell_type":"code","execution_count":53,"metadata":{"duration_ms":49,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JNumber 0.001234\n","JNumber 0.001234"]},{"data":{"text/plain":["Success (JNumber 0.001234, { lines = [|\"123.4e-5\"|]\n","                             position = { line = 1\n","                                          column = 0 } })"]},"execution_count":53,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jNumber_ \"123.4e-5\"\n","|> parserEqual (Success (JNumber 0.001234))"]},{"cell_type":"markdown","metadata":{},"source":["### jArray"]},{"cell_type":"code","execution_count":54,"metadata":{"duration_ms":104,"language":"fsharp"},"outputs":[],"source":["let jArray =\n","    let left = pchar '[' .>> spaces\n","    let right = pchar ']' .>> spaces\n","    let comma = pchar ',' .>> spaces\n","    let value = jValue .>> spaces\n","\n","    let values = sepBy value comma\n","\n","    between left values right\n","    |>> JArray\n","    <?> \"array\""]},{"cell_type":"code","execution_count":55,"metadata":{"duration_ms":28,"language":"fsharp"},"outputs":[],"source":["///- --test\n","\n","jValueRef <|\n","    choice\n","        [\n","            jNull\n","            jBool\n","            jString\n","            jNumber\n","            jArray\n","        ]"]},{"cell_type":"code","execution_count":56,"metadata":{"duration_ms":63,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JArray [JNumber 1.0; JNumber 2.0]\n","JArray [JNumber 1.0; JNumber 2.0]"]},{"data":{"text/plain":["Success (JArray [JNumber 1.0; JNumber 2.0], { lines = [|\"[ 1, 2 ]\"|]\n","                                              position = { line = 1\n","                                                           column = 0 } })"]},"execution_count":56,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jArray \"[ 1, 2 ]\"\n","|> parserEqual (Success (JArray [ JNumber 1.0; JNumber 2.0 ]))"]},{"cell_type":"code","execution_count":57,"metadata":{"duration_ms":41,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["Line:0 Col:6 Error parsing array\n","[ 1, 2, ]\n","      ^Unexpected ','"]},{"data":{"text/plain":["Failure (\"array\", \"Unexpected ','\", { currentLine = \"[ 1, 2, ]\"\n","                                      line = 0\n","                                      column = 6 })"]},"execution_count":57,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jArray \"[ 1, 2, ]\"\n","|> parserEqual (\n","    Failure (\n","        \"array\",\n","        \"Unexpected ','\",\n","        { currentLine = \"[ 1, 2, ]\"; line = 0; column = 6 }\n","    )\n",")"]},{"cell_type":"markdown","metadata":{},"source":["### jObject"]},{"cell_type":"code","execution_count":58,"metadata":{"duration_ms":124,"language":"fsharp"},"outputs":[],"source":["let jObject =\n","    let left = spaces >>. pchar '{' .>> spaces\n","    let right = pchar '}' .>> spaces\n","    let colon = pchar ':' .>> spaces\n","    let comma = pchar ',' .>> spaces\n","    let key = quotedString .>> spaces\n","    let value = jValue .>> spaces\n","\n","    let keyValue = (key .>> colon) .>>. value\n","    let keyValues = sepBy keyValue comma\n","\n","    between left keyValues right\n","    |>> Map.ofList\n","    |>> JObject\n","    <?> \"object\""]},{"cell_type":"code","execution_count":59,"metadata":{"duration_ms":23,"language":"fsharp"},"outputs":[],"source":["jValueRef <|\n","    choice\n","        [\n","            jNull\n","            jBool\n","            jString\n","            jNumber\n","            jArray\n","            jObject\n","        ]"]},{"cell_type":"code","execution_count":60,"metadata":{"duration_ms":64,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JObject (map [(\"a\", JNumber 1.0); (\"b\", JNumber 2.0)])\n","JObject (map [(\"a\", JNumber 1.0); (\"b\", JNumber 2.0)])"]},{"data":{"text/plain":["Success (JObject (map [(\"a\", JNumber 1.0); (\"b\", JNumber 2.0)]), { lines = [|\"{ \"a\":1, \"b\"  :  2 }\"|]\n","                                                                   position = { line = 1\n","                                                                                column = 0 } })"]},"execution_count":60,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jObject \"\"\"{ \"a\":1, \"b\"  :  2 }\"\"\"\n","|> parserEqual (\n","    Success (\n","        JObject (\n","            Map.ofList [\n","                \"a\", JNumber 1.0\n","                \"b\", JNumber 2.0\n","            ]\n","        )\n","    )\n",")"]},{"cell_type":"code","execution_count":61,"metadata":{"duration_ms":45,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["Line:0 Col:18 Error parsing object\n","{ \"a\":1, \"b\"  :  2, }\n","                  ^Unexpected ','"]},{"data":{"text/plain":["Failure (\"object\", \"Unexpected ','\", { currentLine = \"{ \"a\":1, \"b\"  :  2, }\"\n","                                       line = 0\n","                                       column = 18 })"]},"execution_count":61,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","run jObject \"\"\"{ \"a\":1, \"b\"  :  2, }\"\"\"\n","|> parserEqual (\n","    Failure (\n","        \"object\",\n","        \"Unexpected ','\",\n","        { currentLine = \"\"\"{ \"a\":1, \"b\"  :  2, }\"\"\"; line = 0; column = 18 }\n","    )\n",")"]},{"cell_type":"markdown","metadata":{},"source":["### jValue"]},{"cell_type":"code","execution_count":62,"metadata":{"duration_ms":91,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["JObject\n","  (map\n","     [(\"bday\",\n","       JObject\n","         (map\n","            [(\"day\", JNumber 25.0); (\"month\", JNumber 12.0);\n","             (\"year\", JNumber 2001.0)])); (\"emptyArray\", JArray []);\n","      (\"emptyObject\", JObject (map []));\n","      (\"favouriteColors\", JArray [JString \"blue\"; JString \"green\"]);\n","      (\"isMale\", JBool true); (\"name\", JString \"Scott\")])\n","JObject\n","  (map\n","     [(\"bday\", JObject (map [(\"day\", JNumber 25.0); (\"month\", JNumber 12.0); (\"year\", JNumber 2001.0)]));\n","      (\"emptyArray\", JArray []); (\"emptyObject\", JObject (map []));\n","      (\"favouriteColors\", JArray [JString \"blue\"; JString \"green\"]); (\"isMale\", JBool true); (\"name\", JString \"Scott\")])"]},{"data":{"text/plain":["Success\n","  (JObject\n","     (map\n","        [(\"bday\", JObject (map [(\"day\", JNumber 25.0); (\"month\", JNumber 12.0); (\"year\", JNumber 2001.0)]));\n","         (\"emptyArray\", JArray []); (\"emptyObject\", JObject (map []));\n","         (\"favouriteColors\", JArray [JString \"blue\"; JString \"green\"]); (\"isMale\", JBool true);\n","         (\"name\", JString \"Scott\")]),\n","   { lines =\n","      [|\"{\"; \"    \"name\" : \"Scott\",\"; \"    \"isMale\" : true,\"; \"    \"bday\" : {\"year\":2001, \"month\":12, \"day\":25 },\";\n","        \"    \"favouriteColors\" : [\"blue\", \"green\"],\"; \"    \"emptyArray\" : [],\"; \"    \"emptyObject\" : {}\"; \"}\"|]\n","     position = { line = 8\n","                  column = 0 } })"]},"execution_count":62,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","let example1 = \"\"\"{\n","    \"name\" : \"Scott\",\n","    \"isMale\" : true,\n","    \"bday\" : {\"year\":2001, \"month\":12, \"day\":25 },\n","    \"favouriteColors\" : [\"blue\", \"green\"],\n","    \"emptyArray\" : [],\n","    \"emptyObject\" : {}\n","}\"\"\"\n","run jValue example1\n","|> parserEqual (\n","    Success (\n","        JObject (\n","            Map.ofList [\n","                \"name\", JString \"Scott\"\n","                \"isMale\", JBool true\n","                \"bday\", JObject (\n","                    Map.ofList [\n","                        \"year\", JNumber 2001.0\n","                        \"month\", JNumber 12.0\n","                        \"day\", JNumber 25.0\n","                    ]\n","                )\n","                \"favouriteColors\", JArray [ JString \"blue\"; JString \"green\" ]\n","                \"emptyArray\", JArray []\n","                \"emptyObject\", JObject Map.empty\n","            ]\n","        )\n","    )\n",")"]},{"cell_type":"code","execution_count":63,"metadata":{"duration_ms":234,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["\n","\n","/home/runner/work/polyglot/polyglot/apps/parser/input.fsx(34,24): info FS3886: This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements?\n","\n","JObject\n","  (map\n","     [(\"widget\",\n","       JObject\n","         (map\n","            [(\"debug\", JString \"on\");\n","             (\"image\",\n","              JObject\n","                (map\n","                   [(\"alignment\", JString \"center\"); (\"hOffset\", JNumber 250.0);\n","                    (\"name\", JString \"sun1\"); (\"src\", JString \"Images/Sun.png\");\n","                    (\"vOffset\", JNumber 250.0)]));\n","             (\"text\",\n","              JObject\n","                (map\n","                   [(\"alignment\", JString \"center\");\n","                    (\"data\", JString \"Click Here\"); (\"hOffset\", JNumber 250.0);\n","                    (\"name\", JString \"text1\");\n","                    (\"onMouseUp\",\n","                     JString \"sun1.opacity = (sun1.opacity / 100) * 90;\");\n","                    (\"size\", JNumber 36.0); (\"style\", JString \"bold\");\n","                    (\"vOffset\", JNumber 100.0)]));\n","             (\"window\",\n","              JObject\n","                (map\n","                   [(\"height\", JNumber 500.0); (\"name\", JString \"main_window\");\n","                    (\"title\", JString \"Sample Konfabulator Widget\");\n","                    (\"width\", JNumber 500.0)]))]))])\n","JObject\n","  (map\n","     [(\"widget\",\n","       JObject\n","         (map\n","            [(\"debug\", JString \"on\");\n","             (\"image\",\n","              JObject\n","                (map\n","                   [(\"alignment\", JString \"center\"); (\"hOffset\", JNumber 250.0); (\"name\", JString \"sun1\");\n","                    (\"src\", JString \"Images/Sun.png\"); (\"vOffset\", JNumber 250.0)]));\n","             (\"text\",\n","              JObject\n","                (map\n","                   [(\"alignment\", JString \"center\"); (\"data\", JString \"Click Here\"); (\"hOffset\", JNumber 250.0);\n","                    (\"name\", JString \"text1\"); (\"onMouseUp\", JString \"sun1.opacity = (sun1.opacity / 100) * 90;\");\n","                    (\"size\", JNumber 36.0); (\"style\", JString \"bold\"); (\"vOffset\", JNumber 100.0)]));\n","             (\"window\",\n","              JObject\n","                (map\n","                   [(\"height\", JNumber 500.0); (\"name\", JString \"main_window\");\n","                    (\"title\", JString \"Sample Konfabulator Widget\"); (\"width\", JNumber 500.0)]))]))])"]},{"data":{"text/plain":["Success\n","  (JObject\n","     (map\n","        [(\"widget\",\n","          JObject\n","            (map\n","               [(\"debug\", JString \"on\");\n","                (\"image\",\n","                 JObject\n","                   (map\n","                      [(\"alignment\", JString \"center\"); (\"hOffset\", JNumber 250.0); (\"name\", JString \"sun1\");\n","                       (\"src\", JString \"Images/Sun.png\"); (\"vOffset\", JNumber 250.0)]));\n","                (\"text\",\n","                 JObject\n","                   (map\n","                      [(\"alignment\", JString \"center\"); (\"data\", JString \"Click Here\"); (\"hOffset\", JNumber 250.0);\n","                       (\"name\", JString \"text1\"); (\"onMouseUp\", JString \"sun1.opacity = (sun1.opacity / 100) * 90;\");\n","                       (\"size\", JNumber 36.0); (\"style\", JString \"bold\"); (\"vOffset\", JNumber 100.0)]));\n","                (\"window\",\n","                 JObject\n","                   (map\n","                      [(\"height\", JNumber 500.0); (\"name\", JString \"main_window\");\n","                       (\"title\", JString \"Sample Konfabulator Widget\"); (\"width\", JNumber 500.0)]))]))]),\n","   { lines =\n","      [|\"{\"widget\": {\"; \"    \"debug\": \"on\",\"; \"    \"window\": {\"; \"        \"title\": \"Sample Konfabulator Widget\",\";\n","        \"        \"name\": \"main_window\",\"; \"        \"width\": 500,\"; \"        \"height\": 500\"; \"    },\"; \"    \"image\": {\";\n","        \"        \"src\": \"Images/Sun.png\",\"; \"        \"name\": \"sun1\",\"; \"        \"hOffset\": 250,\";\n","        \"        \"vOffset\": 250,\"; \"        \"alignment\": \"center\"\"; \"    },\"; \"    \"text\": {\";\n","        \"        \"data\": \"Click Here\",\"; \"        \"size\": 36,\"; \"        \"style\": \"bold\",\"; \"        \"name\": \"text1\",\";\n","        \"        \"hOffset\": 250,\"; \"        \"vOffset\": 100,\"; \"        \"alignment\": \"center\",\";\n","        \"        \"onMouseUp\": \"sun1.opacity = (sun1.opacity / 100) * 90;\"\"; \"    }\"; \"}}\"|]\n","     position = { line = 26\n","                  column = 0 } })"]},"execution_count":63,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","let example2 = \"\"\"{\"widget\": {\n","    \"debug\": \"on\",\n","    \"window\": {\n","        \"title\": \"Sample Konfabulator Widget\",\n","        \"name\": \"main_window\",\n","        \"width\": 500,\n","        \"height\": 500\n","    },\n","    \"image\": {\n","        \"src\": \"Images/Sun.png\",\n","        \"name\": \"sun1\",\n","        \"hOffset\": 250,\n","        \"vOffset\": 250,\n","        \"alignment\": \"center\"\n","    },\n","    \"text\": {\n","        \"data\": \"Click Here\",\n","        \"size\": 36,\n","        \"style\": \"bold\",\n","        \"name\": \"text1\",\n","        \"hOffset\": 250,\n","        \"vOffset\": 100,\n","        \"alignment\": \"center\",\n","        \"onMouseUp\": \"sun1.opacity = (sun1.opacity / 100) * 90;\"\n","    }\n","}}\"\"\"\n","\n","run jValue example2\n","|> parserEqual (\n","    Success (\n","        JObject (\n","            Map.ofList [\n","                \"widget\", JObject (\n","                    Map.ofList [\n","                        \"debug\", JString \"on\"\n","                        \"window\", JObject (\n","                            Map.ofList [\n","                                \"title\", JString \"Sample Konfabulator Widget\"\n","                                \"name\", JString \"main_window\"\n","                                \"width\", JNumber 500.0\n","                                \"height\", JNumber 500.0\n","                            ]\n","                        )\n","                        \"image\", JObject (\n","                            Map.ofList [\n","                                \"src\", JString \"Images/Sun.png\"\n","                                \"name\", JString \"sun1\"\n","                                \"hOffset\", JNumber 250.0\n","                                \"vOffset\", JNumber 250.0\n","                                \"alignment\", JString \"center\"\n","                            ]\n","                        )\n","                        \"text\", JObject (\n","                            Map.ofList [\n","                                \"data\", JString \"Click Here\"\n","                                \"size\", JNumber 36.0\n","                                \"style\", JString \"bold\"\n","                                \"name\", JString \"text1\"\n","                                \"hOffset\", JNumber 250.0\n","                                \"vOffset\", JNumber 100.0\n","                                \"alignment\", JString \"center\"\n","                                \"onMouseUp\", JString \"sun1.opacity = (sun1.opacity / 100) * 90;\"\n","                            ]\n","                        )\n","                    ]\n","                )\n","            ]\n","        )\n","    )\n",")"]},{"cell_type":"code","execution_count":64,"metadata":{"duration_ms":238,"language":"fsharp"},"outputs":[{"name":"stdout","output_type":"stream","text":["\n","\n","/home/runner/work/polyglot/polyglot/apps/parser/input.fsx(63,40): info FS3886: This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements?\n","\n","JObject\n","  (map\n","     [(\"array\",\n","       JArray [JNumber 1.0; JNumber 2.0; JNumber 3.0; JNumber 4.0; JNumber 5.0]);\n","      (\"boolean\", JBool true); (\"emptyArray\", JArray []);\n","      (\"emptyObject\", JObject (map []));\n","      (\"escapedString\", JString \"This string contains \\/\\\\\\b\\f\\n\\r\\t\\\"\\'\");\n","      (\"nestedArrays\",\n","       JArray\n","         [JArray [JNumber 1.0; JNumber 2.0; JNumber 3.0];\n","          JArray [JNumber 4.0; JNumber 5.0; JNumber 6.0]]);\n","      (\"nestedObjects\",\n","       JArray\n","         [JObject (map [(\"age\", JNumber 25.0); (\"name\", JString \"Alice\")]);\n","          JObject (map [(\"age\", JNumber 30.0); (\"name\", JString \"Bob\")])]);\n","      (\"nullValue\", JNull); (\"number\", JNumber 42.0); ...])\n","JObject\n","  (map\n","     [(\"array\", JArray [JNumber 1.0; JNumber 2.0; JNumber 3.0; JNumber 4.0; JNumber 5.0]); (\"boolean\", JBool true);\n","      (\"emptyArray\", JArray []); (\"emptyObject\", JObject (map []));\n","      (\"escapedString\", JString \"This string contains \\/\\\\\\b\\f\\n\\r\\t\\\"\\'\");\n","      (\"nestedArrays\",\n","       JArray [JArray [JNumber 1.0; JNumber 2.0; JNumber 3.0]; JArray [JNumber 4.0; JNumber 5.0; JNumber 6.0]]);\n","      (\"nestedObjects\",\n","       JArray\n","         [JObject (map [(\"age\", JNumber 25.0); (\"name\", JString \"Alice\")]);\n","          JObject (map [(\"age\", JNumber 30.0); (\"name\", JString \"Bob\")])]); (\"nullValue\", JNull);\n","      (\"number\", JNumber 42.0); ...])"]},{"data":{"text/plain":["Success\n","  (JObject\n","     (map\n","        [(\"array\", JArray [JNumber 1.0; JNumber 2.0; JNumber 3.0; JNumber 4.0; JNumber 5.0]); (\"boolean\", JBool true);\n","         (\"emptyArray\", JArray []); (\"emptyObject\", JObject (map []));\n","         (\"escapedString\", JString \"This string contains \\/\\\\\\b\\f\\n\\r\\t\\\"\\'\");\n","         (\"nestedArrays\",\n","          JArray [JArray [JNumber 1.0; JNumber 2.0; JNumber 3.0]; JArray [JNumber 4.0; JNumber 5.0; JNumber 6.0]]);\n","         (\"nestedObjects\",\n","          JArray\n","            [JObject (map [(\"age\", JNumber 25.0); (\"name\", JString \"Alice\")]);\n","             JObject (map [(\"age\", JNumber 30.0); (\"name\", JString \"Bob\")])]); (\"nullValue\", JNull);\n","         (\"number\", JNumber 42.0); ...]),\n","   { lines =\n","      [|\"{\"; \"  \"string\": \"Hello, \\\"World\\\"!\",\";\n","        \"  \"escapedString\": \"This string contains \\\\/\\\\\\\\\\\\b\\\\f\\\\n\\\\r\\\\t\\\\\\\"\\\\'\",\"; \"  \"number\": 42,\";\n","        \"  \"scientificNumber\": 3.14e-10,\"; \"  \"boolean\": true,\"; \"  \"nullValue\": null,\"; \"  \"array\": [1, 2, 3, 4, 5],\";\n","        \"  \"unicodeString1\": \"프리마\",\";\n","        \"  \"unicodeString2\": \"\\u0048\\u0065\\u006C\\u006C\\u006F, \\u0022\\u0057\\u006F\\u0072\\u006C\\u0064\\u0022!\",\";\n","        \"  \"specialCharacters\": \"!@#$%^&*()\",\"; \"  \"emptyArray\": [],\"; \"  \"emptyObject\": {},\";\n","        \"  \"nestedArrays\": [[1, 2, 3], [4, 5, 6]],\"; \"  \"object\": {\"; \"    \"nestedString\": \"Nested Value\",\";\n","        \"    \"nestedNumber\": 3.14,\"; \"    \"nestedBoolean\": false,\"; \"    \"nestedNull\": null,\";\n","        \"    \"nestedArray\": [\"a\", \"b\", \"c\"],\"; \"    \"nestedObject\": {\"; \"      \"nestedProperty\": \"Nested Object Value\"\";\n","        \"    }\"; \"  },\"; \"  \"nestedObjects\": [\"; \"    {\"name\": \"Alice\", \"age\": 25},\"; \"    {\"name\": \"Bob\", \"age\": 30}\";\n","        \"  ]\"; \"}\"|]\n","     position = { line = 29\n","                  column = 0 } })"]},"execution_count":64,"metadata":{},"output_type":"execute_result"}],"source":["///- --test\n","\n","let example3 = \"\"\"{\n","  \"string\": \"Hello, \\\"World\\\"!\",\n","  \"escapedString\": \"This string contains \\\\/\\\\\\\\\\\\b\\\\f\\\\n\\\\r\\\\t\\\\\\\"\\\\'\",\n","  \"number\": 42,\n","  \"scientificNumber\": 3.14e-10,\n","  \"boolean\": true,\n","  \"nullValue\": null,\n","  \"array\": [1, 2, 3, 4, 5],\n","  \"unicodeString1\": \"프리마\",\n","  \"unicodeString2\": \"\\u0048\\u0065\\u006C\\u006C\\u006F, \\u0022\\u0057\\u006F\\u0072\\u006C\\u0064\\u0022!\",\n","  \"specialCharacters\": \"!@#$%^&*()\",\n","  \"emptyArray\": [],\n","  \"emptyObject\": {},\n","  \"nestedArrays\": [[1, 2, 3], [4, 5, 6]],\n","  \"object\": {\n","    \"nestedString\": \"Nested Value\",\n","    \"nestedNumber\": 3.14,\n","    \"nestedBoolean\": false,\n","    \"nestedNull\": null,\n","    \"nestedArray\": [\"a\", \"b\", \"c\"],\n","    \"nestedObject\": {\n","      \"nestedProperty\": \"Nested Object Value\"\n","    }\n","  },\n","  \"nestedObjects\": [\n","    {\"name\": \"Alice\", \"age\": 25},\n","    {\"name\": \"Bob\", \"age\": 30}\n","  ]\n","}\"\"\"\n","run jValue example3\n","|> parserEqual (\n","    Success (\n","        JObject (\n","            Map.ofList [\n","                \"string\", JString @\"Hello, \"\"World\"\"!\"\n","                \"escapedString\", JString @\"This string contains \\/\\\\\\b\\f\\n\\r\\t\\\"\"\\'\"\n","                \"number\", JNumber 42.0\n","                \"scientificNumber\", JNumber 3.14e-10\n","                \"boolean\", JBool true\n","                \"nullValue\", JNull\n","                \"array\", JArray [\n","                    JNumber 1.0; JNumber 2.0; JNumber 3.0; JNumber 4.0; JNumber 5.0\n","                ]\n","                \"unicodeString1\", JString \"프리마\"\n","                \"unicodeString2\", JString @\"Hello, \"\"World\"\"!\"\n","                \"specialCharacters\", JString \"!@#$%^&*()\"\n","                \"emptyArray\", JArray []\n","                \"emptyObject\", JObject Map.empty\n","                \"nestedArrays\", JArray [\n","                    JArray [ JNumber 1.0; JNumber 2.0; JNumber 3.0 ]\n","                    JArray [ JNumber 4.0; JNumber 5.0; JNumber 6.0 ]\n","                ]\n","                \"object\", JObject (\n","                    Map.ofList [\n","                        \"nestedString\", JString \"Nested Value\"\n","                        \"nestedNumber\", JNumber 3.14\n","                        \"nestedBoolean\", JBool false\n","                        \"nestedNull\", JNull\n","                        \"nestedArray\", JArray [JString \"a\"; JString \"b\"; JString \"c\"]\n","                        \"nestedObject\", JObject (\n","                            Map.ofList [\n","                                \"nestedProperty\", JString \"Nested Object Value\"\n","                            ]\n","                        )\n","                    ]\n","                )\n","                \"nestedObjects\", JArray [\n","                  JObject (Map.ofList [ \"name\", JString \"Alice\"; \"age\", JNumber 25.0 ])\n","                  JObject (Map.ofList [ \"name\", JString \"Bob\"; \"age\", JNumber 30.0 ])\n","                ]\n","            ]\n","        )\n","    )\n",")"]}],"metadata":{"kernelspec":{"display_name":"Spiral","language":"spiral","name":"spiral"}},"nbformat":4,"nbformat_minor":5}