JSON formatter written in jq

itchyny
2 min readMay 10, 2019

--

jq is a Turing-complete interpreter language with JSON iterator as the first-citizen object. The jq language has basic arithmetic and string operators, array and string indexing, as well as various modifiers against JSON. I wrote a simple JSON formatter written in jq.

 % echo '{"hello":[["jq"],{"world":42}]}' | jq -sRrf json_format.jq
{
"hello": [
[
"jq"
],
{
"world": 42
}
]
}

This script allows any JSON token stream so it cannot report invalid JSON as an error. But at least it formats any valid JSON (I believe) in almost same the way as jq . command (I know some format differences of numbers and strings).

What the script uses are

  • inside function to check the next character of the input
  • update operator |= to slice the input string; .source |= .[1:]
  • * operator to repeat the white space; " " * .depth
  • match function to get the value tokens including string, number, booleans and null
  • until function to repeat the procedure

Storing the variable values to an object, we can emulate any transition of variables using jq. Also using branching (if … then … else … end) and recursive call of function, jq is apparently a Turing-complete language.

I also wrote a Brainf*ck interpreter. I don’t optimize the loop position jump so the performance is bad, but the code actually runs any Brainf*ck code (excluding , instruction).

 % echo "+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++ \
++..+++.>-.------------.<++++++++.--------.+++.------.--- \
-----.>+." | jq -sRrf bf.jq
Hello, world!

I’ve enjoyed the language and liked it a lot. All the filters can be viewed as a map on JSON iterators and writing a jq script forces me to distinguish what is variable state and what is update on the states. It sometimes reminds me a flavor of functional programming languages, especially the fork feature of J language.

Using jq as an interpreter sounds like a kind of joke. But the power of jq as an interpreter enriches the builtin functions. The functions like map and recurse are actually defined using internal functions and operators. I learned a lot from the definition of builtin functions and especially like the definition of bsearch function.

Anyway, jq is a powerful interpreter beyond a JSON exploring tool and enjoy coding with jq!

--

--