shithub: mc

Download patch

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