ref: 8ff705e2485ef1aa6b95d038a4a38d0893e05471
parent: cb8b7343a04a8fd959e582b96969f43f2ea0c563
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Oct 6 14:39:20 EDT 2016
Add formatter, and pretty printer.
--- a/lib/json/bld.proj
+++ b/lib/json/bld.proj
@@ -1,5 +1,10 @@
lib json =
types.myr
parse.myr
+ fmt.myr
;;
+bin j =
+ j.myr
+ lib json
+;;
--- /dev/null
+++ b/lib/json/fmt.myr
@@ -1,0 +1,85 @@
+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)
+ | &(`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')
+ ;;
+}
--- a/lib/json/parse.myr
+++ b/lib/json/parse.myr
@@ -34,7 +34,7 @@
| &(`Str s): std.slfree(s)
| &(`Arr a):
for e in a
- free(j)
+ free(e)
;;
| &(`Obj o):
for (k, v) in o
@@ -60,10 +60,10 @@
elif std.isdigit(peekc(p)) || peekc(p) == '-'
match parsenum(p)
| `std.Some n: -> `std.Ok std.mk(`Num (n : flt64))
- | `std.None: -> `std.Err `Junk chr
+ | `std.None: -> `std.Err [.e=`Junk chr, .line=p.line, .off=p.off]
;;
else
- -> `std.Err `Junk chr
+ -> `std.Err [.e=`Junk chr, .line=p.line, .off=p.off]
;;
;;
}
@@ -79,11 +79,11 @@
| `std.Ok m:
std.slpush(&membs, m)
takespace(p)
- match peekc(p)
+ match takec(p)
| ',': /* nothing */
| '}': break
| chr:
- err = `Junk chr
+ err = [.e=`Junk chr, .line=p.line, .off=p.off]
goto error
;;
| `std.Err e:
@@ -113,7 +113,7 @@
takespace(p)
match takec(p)
| ':': /* nothing */
- | chr: -> `std.Err `Junk chr
+ | chr: -> `std.Err [.e=`Junk chr, .line=p.line, .off=p.off]
;;
takespace(p)
@@ -139,11 +139,11 @@
err = e
goto error
;;
- match peekc(p)
+ match takec(p)
| ',': /* nothing */
| ']': break
| chr:
- err = `Junk chr
+ err = [.e=`Junk chr, .line=p.line, .off=p.off]
goto error
;;
;;
@@ -208,7 +208,7 @@
match takec(p)
| '"': /* nothing */
| chr:
- err = `Junk chr
+ err = [.e=`Junk chr, .line=p.line, .off=p.off]
goto error
;;
while p.idx < p.str.len
@@ -225,7 +225,7 @@
| 'r': std.sbputc(sb, '\r')
| 't': std.sbputc(sb, '\t')
| chr:
- err = `Badesc chr
+ err = [.e=`Badesc chr, .line=p.line, .off=p.off]
goto error
;;
| '"':
@@ -246,8 +246,10 @@
match (p.str[p.idx] : char)
| ' ':
| '\t':
- | '\n':
| '\r':
+ | '\n':
+ p.line++
+ p.off=1
| _:
break
;;
--- a/lib/json/types.myr
+++ b/lib/json/types.myr
@@ -10,7 +10,13 @@
`Obj (byte[:], elt#)[:]
;;
- type err = union
+ type err = struct
+ e : errtype
+ line : std.size
+ off : std.size
+ ;;
+
+ type errtype = union
`Junk char
`Badesc char
`End