summaryrefslogtreecommitdiff
path: root/lib/json/fmt.myr
blob: 04867f2fd5eaa263570317cf86dae3cfc50e438b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use std

use "types"

pkg json =
;;

const __init__ = {
	var j : elt

	std.fmtinstall(std.typeof(&j), jsonfmt, [][:])
}

const jsonfmt = {sb, ap, opts
	var e : elt#

	e = std.vanext(ap)
	eltfmt(sb, e, 0)
}

const eltfmt = {sb, e, ind
	match e
	| &(`Null):	std.sbfmt(sb, "null")
	| &(`Bool b):	std.sbfmt(sb, "{}", b)
	| &(`Num n):	std.sbfmt(sb, "{}", n)
	| &(`Str s):	jstrfmt(sb, s)
	| &(`Arr a):	arrfmt(sb, a, ind)
	| &(`Obj o):	objfmt(sb, o, ind)
	;;
}


const jstrfmt = {sb, str
	std.sbputs(sb, "\"")
	for c in str
		match (c : char)
		| '\x0c':	std.sbputs(sb, "\\f")
		| '\\':	std.sbputs(sb, "\\\\")
		| '\n': std.sbputs(sb, "\\n")
		| '\r':	std.sbputs(sb, "\\r")
		| '\t': std.sbputs(sb, "\\t")
		| _:	std.sbputb(sb, c)
		;;
	;;
	std.sbputs(sb, "\"")
}

const arrfmt = {sb, arr, ind
	var sep

	sep = ""
	std.sbputs(sb, "[\n")
	for e in arr
		std.sbputs(sb, sep)
		indent(sb, ind + 1)
		eltfmt(sb, e, ind + 1)
		sep = ",\n"
	;;
	std.sbputs(sb, "\n")
	indent(sb, ind)
	std.sbputs(sb, "]")
}

const objfmt = {sb, obj, ind
	var sep

	sep = ""
	std.sbputs(sb, "{\n")
	for (k, v) in obj
		std.sbputs(sb, sep)
		indent(sb, ind + 1)
		jstrfmt(sb, k)
		std.sbputs(sb, ": ")
		eltfmt(sb, v, ind + 1)
		sep = ",\n"
	;;
	std.sbputs(sb, "\n")
	indent(sb, ind)
	std.sbputs(sb, "}")
}

const indent = {sb, ind
	for var i = 0; i < ind; i++
		std.sbputc(sb, '\t')
	;;
}