\$\begingroup\$

Your code is impressingly well structured and easy to follow, thanks to its comprehensive documentation.

The first thing I noticed that I would do differently is when initializing the space character. Your code reads:

> 20 space >[-]++[-<++++++++++++++++>]<

You can leave out the [-] since the memory is zeroed out when the process starts.

There are some instances where adjacent <> or >< can be eliminated, but that job should be left to the compiler, since these are well-known optimization techniques. Having code that expresses its intention clearly is more important than doing the compiler's job.

Back to cell 0 <[<]<[<]<<<<<<<

Since there are exactly 2 JSON-specific characters, I would have replaced the first [<] with the simpler << . This applies to the other situations as well where the code skips over this zero-terminated string.

When I saw the placeholder string, I thought about storing the indentation string as a plain number instead. I don't know whether this would make the code simpler overall. Did you try that?

Representing the indentation string as a number would additionally prevent it from consisting of characters other than spaces and tabs. Having other characters could produce malformed JSON.

Instead of naming it "placeholder", a more accurate name would be "indentation string", but that could easily be confused with the "indent", which then would have to be named "indentation depth".

Memory cells 5 and 6 both contain the "indent copy". This could be documented a little more detailed, to prevent confusion. It would be nice to know at which points in time each of these cells contains valid data.

In the two switch blocks you rely on the VM allowing numeric underflow, which is not guaranteed. I would have preferred code that deals with this situation in the most portable manner, but that would have been much more complicated, I guess.

in each switch case <.> outputs current char

This line confused me since it embeds code into a string that otherwise looks like a comment. You didn't state in your description that you intended to participate in the Underhanded Brainfuck Contest, and the rest of your code doesn't look that way. Or does it? That's hard to tell.

Newline >>>>>>[>]>. Back to cell 2 [<]<[<]<<<<<

I would have combined these two lines into a single line to keep the data pointer on cell 2 consistently, thereby making the comment in the second line redundant. As I already mentioned above, I would replace the first [<] with a simple < , to make it symmetric with the single > in the line above.

I like the shortcut you took for skipping the string escapes, even if that means that the code does not mirror each syntactical rules of the JSON format on its own. The gain in code simplicity is worth more in this case.

Overall, it's a really good example of careful program design, memory management, algorithms, design patterns and efficiency.