hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit a51f33512a0740b9e2a81bc75abb6aec7481d42d
parent 2f8897a58bd120190d279e56cc7b8e9db8c90c64
Author: Sebastian <sebastian@sebsite.pw>
Date:   Wed, 18 May 2022 23:41:12 -0400

encoding::json: add dump and dumpstr

Tests aren't included; those are added in the "expand tests" commit.

Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Aencoding/json/dump.ha | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mscripts/gen-stdlib | 4+++-
Mstdlib.mk | 6++++--
3 files changed, 91 insertions(+), 3 deletions(-)

diff --git a/encoding/json/dump.ha b/encoding/json/dump.ha @@ -0,0 +1,84 @@ +// License: MPL-2.0 +// (c) 2022 Sebastian <sebastian@sebsite.pw> +use fmt; +use io; +use strings; +use strio; + +// Dumps a [[value]] into an [[io::handle]] as a string without any additional +// formatting. +export fn dump(out: io::handle, val: value) (size | io::error) = { + let z = 0z; + match (val) { + case let v: (f64 | bool) => + z += fmt::fprint(out, v)?; + case let s: str => + z += fmt::fprint(out, `"`)?; + let it = strings::iter(s); + for (true) match (strings::next(&it)) { + case void => + break; + case let r: rune => + switch (r) { + case '\b' => + z += fmt::fprint(out, `\b`)?; + case '\f' => + z += fmt::fprint(out, `\f`)?; + case '\n' => + z += fmt::fprint(out, `\n`)?; + case '\r' => + z += fmt::fprint(out, `\r`)?; + case '\t' => + z += fmt::fprint(out, `\t`)?; + case '\"' => + z += fmt::fprint(out, `\"`)?; + case '\\' => + z += fmt::fprint(out, `\\`)?; + case => + if (iscntrl(r)) { + z += fmt::fprintf(out, `\u{:04x}`, + r: u32)?; + } else { + z += fmt::fprint(out, r)?; + }; + }; + }; + z += fmt::fprint(out, `"`)?; + case _null => + z += fmt::fprint(out, "null")?; + case let a: []value => + z += fmt::fprint(out, "[")?; + for (let i = 0z; i < len(a); i += 1) { + z += dump(out, a[i])?; + if (i < len(a) - 1) { + z += fmt::fprint(out, ",")?; + }; + }; + z += fmt::fprint(out, "]")?; + case let o: object => + z += fmt::fprint(out, "{")?; + let comma = false; + let it = iter(&o); + for (true) match (next(&it)) { + case void => break; + case let pair: (const str, const *value) => + if (comma) { + z += fmt::fprint(out, ",")?; + }; + comma = true; + z += dump(out, pair.0)?; + z += fmt::fprint(out, ":")?; + z += dump(out, *pair.1)?; + }; + z += fmt::fprint(out, "}")?; + }; + return z; +}; + +// Dumps a [[value]] into a string without any additional formatting. The caller +// must free the return value. +export fn dumpstr(val: value) str = { + let s = strio::dynamic(); + dump(&s, val)!; + return strio::string(&s); +}; diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -522,19 +522,21 @@ encoding_json() { types.ha \ lex.ha \ load.ha \ + dump.ha \ value.ha else gen_srcs encoding::json \ types.ha \ lex.ha \ load.ha \ + dump.ha \ value.ha \ +test/lexer.ha \ +test/load.ha \ +test/value.ha fi gen_ssa encoding::json ascii bufio io strio os encoding::utf8 strings \ - strconv hash::fnv types + strconv hash::fnv fmt types } encoding_pem() { diff --git a/stdlib.mk b/stdlib.mk @@ -1070,9 +1070,10 @@ stdlib_encoding_json_any_srcs = \ $(STDLIB)/encoding/json/types.ha \ $(STDLIB)/encoding/json/lex.ha \ $(STDLIB)/encoding/json/load.ha \ + $(STDLIB)/encoding/json/dump.ha \ $(STDLIB)/encoding/json/value.ha -$(HARECACHE)/encoding/json/encoding_json-any.ssa: $(stdlib_encoding_json_any_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_hash_fnv_$(PLATFORM)) $(stdlib_types_$(PLATFORM)) +$(HARECACHE)/encoding/json/encoding_json-any.ssa: $(stdlib_encoding_json_any_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_hash_fnv_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/encoding/json @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nencoding::json \ @@ -3190,12 +3191,13 @@ testlib_encoding_json_any_srcs = \ $(STDLIB)/encoding/json/types.ha \ $(STDLIB)/encoding/json/lex.ha \ $(STDLIB)/encoding/json/load.ha \ + $(STDLIB)/encoding/json/dump.ha \ $(STDLIB)/encoding/json/value.ha \ $(STDLIB)/encoding/json/+test/lexer.ha \ $(STDLIB)/encoding/json/+test/load.ha \ $(STDLIB)/encoding/json/+test/value.ha -$(TESTCACHE)/encoding/json/encoding_json-any.ssa: $(testlib_encoding_json_any_srcs) $(testlib_rt) $(testlib_ascii_$(PLATFORM)) $(testlib_bufio_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_encoding_utf8_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_strconv_$(PLATFORM)) $(testlib_hash_fnv_$(PLATFORM)) $(testlib_types_$(PLATFORM)) +$(TESTCACHE)/encoding/json/encoding_json-any.ssa: $(testlib_encoding_json_any_srcs) $(testlib_rt) $(testlib_ascii_$(PLATFORM)) $(testlib_bufio_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_encoding_utf8_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_strconv_$(PLATFORM)) $(testlib_hash_fnv_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_types_$(PLATFORM)) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/encoding/json @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nencoding::json \