diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2023-09-03 20:34:22 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2023-09-03 20:34:22 -0700 |
commit | f9c7296269adc16675c96535a9bde8b7686866c0 (patch) | |
tree | f15011d4f35818c29143b010f46bf3c9d7ba52a4 | |
parent | 004dcc459539ce03587cfe3bdef0fd3c4ec68809 (diff) | |
download | txr-f9c7296269adc16675c96535a9bde8b7686866c0.tar.gz txr-f9c7296269adc16675c96535a9bde8b7686866c0.tar.bz2 txr-f9c7296269adc16675c96535a9bde8b7686866c0.zip |
json: allow integers and lists.
* lib.c (out_json_rec): Handle NUM and BGNUM cases same as FLNUM
so integers get printed. The restriction against integers has
been largely unhelpful and bothersome. Handle LCONS together with
CONS. Lists that are not special notation fall through to the VEC
case, which now uses seq_iter_t iteration to handle vectors and lists.
* tests/010/json.tl: New tests.
* txr.1: Documented support for printing integers and lists.
-rw-r--r-- | lib.c | 22 | ||||
-rw-r--r-- | tests/010/json.tl | 5 | ||||
-rw-r--r-- | txr.1 | 12 |
3 files changed, 30 insertions, 9 deletions
@@ -14412,6 +14412,7 @@ static void out_json_rec(val obj, val out, enum json_fmt jf, return; } break; + case LCONS: case CONS: if (ctx != 0) { val sym = car(obj); @@ -14504,13 +14505,14 @@ static void out_json_rec(val obj, val out, enum json_fmt jf, return; } } - break; + /* fallthrough */ case VEC: { val save_indent; int force_br = 0; - cnum len = c_num(length(obj), self); - cnum i; + seq_iter_t si; + val elem; + seq_iter_init(self, &si, obj); if (jf == json_fmt_standard) { put_string(lit("[\n"), out); @@ -14520,19 +14522,23 @@ static void out_json_rec(val obj, val out, enum json_fmt jf, save_indent = inc_indent(out, zero); } - for (i = 0; i < len; i++) { - val elem = obj->v.vec[i]; + if (seq_get(&si, &elem)) for (;;) { + val nxelem; + int more = seq_get(&si, &nxelem); out_json_rec(elem, out, jf, ctx); if (jf == json_fmt_standard) { - if (i < len - 1) + if (more) put_string(lit(",\n"), out); else put_char(chr('\n'), out); - } else if (i < len - 1) { + } else if (more) { put_char(chr(','), out); if (width_check(out, nil)) force_br = 1; } + if (!more) + break; + elem = nxelem; } set_indent(out, save_indent); put_char(chr(']'), out); @@ -14592,6 +14598,8 @@ static void out_json_rec(val obj, val out, enum json_fmt jf, } break; case FLNUM: + case NUM: + case BGNUM: format(out, lit("~a"), obj, nao); return; case LIT: diff --git a/tests/010/json.tl b/tests/010/json.tl index dfd45173..f613c93a 100644 --- a/tests/010/json.tl +++ b/tests/010/json.tl @@ -184,3 +184,8 @@ (command-put-jsons `cat > @name` '(#() 1.0 nil)) t (file-get-string name) "[]\n1\nfalse\n" (command-get-jsons `cat @name`) (#() 1.0 nil)))) + +(mtest + (tojson 1) "1" + (tojson 123123123123123123123123123123) "123123123123123123123123123123" + (tojson '(1 2 3 4 5)) "[1,2,3,4,5]") @@ -82127,11 +82127,11 @@ and .codn null , respectively. .IP 2. -a floating-point number. +a floating-point number or integer. .IP 3. a character string. .IP 4. -a vector of JSON-conforming objects. +a vector or list of JSON-conforming objects. .IP 5. a hash table whose keys and values are JSON-conforming objects. .RE @@ -82139,6 +82139,14 @@ a hash table whose keys and values are JSON-conforming objects. Note that unless the keys in a hash table are all strings, nonstandard JSON is produced, since RFC 8259 requires JSON object keys to be strings. +A list of object is rendered in the same way as vector, in the JSON +.code [] +notation. When such JSON notation is parsed, a vector is produced. + +When integer objects are output, they may not constitute valid JSON, since the +JSON specification supports only IEEE 64 bit floating-point numbers. JSON +numbers are read as floating-point. + If the .code flat-p argument is present and has a true value, then the JSON is generated |