diff options
Diffstat (limited to 'lib/json')
| -rw-r--r-- | lib/json/CHANGES.md | 9 | ||||
| -rw-r--r-- | lib/json/README.md | 18 | ||||
| -rw-r--r-- | lib/json/json.tm | 173 |
3 files changed, 0 insertions, 200 deletions
diff --git a/lib/json/CHANGES.md b/lib/json/CHANGES.md deleted file mode 100644 index 6c67c96d..00000000 --- a/lib/json/CHANGES.md +++ /dev/null @@ -1,9 +0,0 @@ -# Version History - -## v1.1 - -Update syntax for Tomo. - -## v1.0 - -Initial version diff --git a/lib/json/README.md b/lib/json/README.md deleted file mode 100644 index 33e2101a..00000000 --- a/lib/json/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# JSON - -This is a library for encoding/decoding JSON values. - -## Usage - -```tomo ->> j := JSON({"key1"=123, "key2"=[yes, {"ok"="inner"}, JSON.Null]}) -= JSON.Object({"key1"=Number(123), "key2"=Array([Boolean(yes), Object({"ok"=String("inner")}), Null])}) - -say("$(j.encode())") -say("$(j.pretty_print())") - -when JSON.parse("[1, null, true]") is Success(obj) - >> obj -is Failure(msg) - fail("Failed to parse JSON: $msg") -``` diff --git a/lib/json/json.tm b/lib/json/json.tm deleted file mode 100644 index 1ac19426..00000000 --- a/lib/json/json.tm +++ /dev/null @@ -1,173 +0,0 @@ -# Base 64 encoding and decoding -use patterns - -enum JSONDecodeResult( - Success(json:JSON) - Failure(reason:Text) -) - func invalid(text:Text -> JSONDecodeResult) - return Failure("Unrecognized JSON: $(text.quoted())") - -extend Text - func json_quoted(text:Text -> Text) - return '"' ++ text.translate({ - "\\"="\\\\", - '"'='\\"', - "\f"="\\f", - "\r"="\\r", - "\n"="\\n", - "\b"="\\b", - "\t"="\\t", - }) ++ '"' - -enum JSON( - Object(items:{Text=JSON}) - Array(items:[JSON]) - Boolean(value:Bool) - String(text:Text) - Number(n:Num) - Null -) - func encode(j:JSON -> Text) - when j is Object(items) - return "{" ++ ", ".join([ - '$(k.json_quoted()): $(v.encode())' - for k,v in items - ]) ++ "}" - is Array(items) - return "[" ++ ", ".join([item.encode() for item in items]) ++ "]" - is Boolean(value) - return (if value then "true" else "false") - is String(text) - return text.json_quoted() - is Number(n) - return "$n" - is Null - return "null" - - func pretty_print(j:JSON, max_line:Int=80, indent:Text=" ", current_indent:Text="" -> Text) - inline := j.encode() - if inline.length > max_line - next_indent := current_indent ++ indent - when j is Object(items) - return "{\n$next_indent" ++ ",\n$next_indent".join([ - '$(k.json_quoted()): $(v.pretty_print(max_line, indent, next_indent))' - for k,v in items - ]) ++ "\n$current_indent}" - is Array(items) - return "[\n$next_indent" ++ ",\n$next_indent".join([item.pretty_print(max_line, indent, next_indent) for item in items]) ++ "\n$current_indent]" - else pass - - return inline - - func parse_text(text:Text, remainder:&Text? = none -> JSONDecodeResult) - if text.starts_with('"') - string := "" - pos := 2 - escapes := {"n"="\n", "t"="\t", "r"="\r", '"'='"', "\\"="\\", "/"="/", "b"="\b", "f"="\f"} - repeat - c := text[pos] or stop - if c == '"' - if remainder - remainder[] = text.from(pos + 1) - return Success(JSON.String(string)) - - if c == "\\" - stop if pos + 1 > text.length - - if esc := escapes[text[pos+1]] - string ++= esc - pos += 2 - else if m := text.matching_pattern($Pat/u{4 digit}/) - string ++= Text.from_codepoints([Int32.parse(m.captures[1]!)!]) - pos += 1 + m.text.length - else - if remainder - remainder[] = text - return JSONDecodeResult.invalid(text) - else - string ++= c - pos += 1 - - if remainder - remainder[] = text - return JSONDecodeResult.invalid(text) - - func parse(text:Text, remainder:&Text? = none, trailing_commas:Bool=no -> JSONDecodeResult) - if text.starts_with("true", remainder) - return Success(JSON.Boolean(yes)) - else if text.starts_with("false", remainder) - return Success(JSON.Boolean(no)) - else if text.starts_with("null", remainder) - return Success(JSON.Null) - else if n := Num.parse(text, remainder) - return Success(JSON.Number(n)) - else if text.starts_with('"') - return JSON.parse_text(text, remainder) - else if text.starts_with("[") - elements : &[JSON] - text = text.from(2).trim_pattern($Pat"{whitespace}", right=no) - repeat - when JSON.parse(text, &text) is Success(elem) - elements.insert(elem) - else stop - - if delim := text.matching_pattern($Pat'{0+ ws},{0+ ws}') - text = text.from(delim.text.length + 1) - else stop - - if trailing_commas - if delim := text.matching_pattern($Pat'{0+ ws},{0+ ws}') - text = text.from(delim.text.length + 1) - - if terminator := text.matching_pattern($Pat'{0+ ws}]') - if remainder - remainder[] = text.from(terminator.text.length + 1) - return Success(JSON.Array(elements)) - else if text.starts_with("{") - object : &{Text=JSON} - text = text.from(2).trim_pattern($Pat"{whitespace}", right=no) - repeat - key_text := text - when JSON.parse_text(text, &text) is Success(key) - if separator := text.matching_pattern($Pat'{0+ ws}:{0+ ws}') - text = text.from(separator.text.length + 1) - else - return JSONDecodeResult.invalid(text) - - when JSON.parse(text, &text) is Success(value) - when key is String(str) - object[str] = value - else - return JSONDecodeResult.invalid(key_text) - else - return JSONDecodeResult.invalid(text) - else stop - - if delim := text.matching_pattern($Pat'{0+ ws},{0+ ws}') - text = text.from(delim.text.length + 1) - else stop - - if trailing_commas - if delim := text.matching_pattern($Pat'{0+ ws},{0+ ws}') - text = text.from(delim.text.length + 1) - - if terminator := text.matching_pattern($Pat'{0+ ws}{}}') - if remainder - remainder[] = text.from(terminator.text.length + 1) - return Success(JSON.Object(object)) - - return JSONDecodeResult.invalid(text) - -func main(input=(/dev/stdin), pretty_print:Bool = no, trailing_commas:Bool = yes) - text := (input.read() or exit("Invalid file: $input")).trim_pattern($Pat"{whitespace}") - while text.length > 0 - when JSON.parse(text, remainder=&text, trailing_commas=trailing_commas) is Success(json) - if pretty_print - say(json.pretty_print()) - else - say(json.encode()) - is Failure(msg) - exit("\033[31;1m$msg\033[m", code=1) - - text = text.trim_pattern($Pat"{whitespace}") |
