Hello, first time here.
I created a proof of concept json parser (
link to gist). It was originally intended as a decoder for persistent storage of achievements or something similar, but apparently the file API makes a line based format rather more advisable.
Anyway, due to the way the only composite data structure
with automatic deconstruction (the array) works in Danmakufu, I decided to put Json strings, arrays and objects into separate arrays.
A value is represented by an array containing two elements, the type represented by a number (e. g.
1 for a boolean) and a number representing either the value (e. g.
1 for
true) or the index in the corresponding array containing the actual entry. This is done because Danmakufu does not allow an array of elements with different types (unless you cheat).
Json arrays are represented by arrays containing Json values:
[11, 22]
-->
jsonArrays = [..., [[JsonTypeNumber, 11], [JsonTypeNumber, 22]], ...]
// at index 12 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// vvvv
jsonValueOfArray = [JsonTypeArray, 12]
Json objects are represented by arrays containing their values prefixed by the index of the key in the string table:
{ "key1": 33, "key2": [11, 22] }
-->
jsonStrings = [..., "key1", "key2", ...]
// at index 8 and 9 ^^^^^^ ^^^^^^
// vvv vvv
jsonObjects = [..., [[8, JsonTypeNumber, 33], [9, JsonTypeArray, 12]], ...]
// at index 31 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
jsonValueOfObject = [JsonTypeObject, 31]
Since it is impossible to put all of #1 the result value, #2 the string array, #3 the array array and #4 the object array into one Danmakufu array (again, without cheating), global variables are used for those instead.
Calling
JsonParse("{\"key\": [11]}") returns
[JsonTypeObject, 0], and the values of the global variables after the call are:
jsonResultStrings = ["key"]
jsonResultArrays = [[JsonTypeNumber, 11]]
jsonResultObjects = [[0, JsonTypeArray, 0]]
jsonParseErrorIndex = -1 // the index of the first wrong char otherwise; might be off by one
The graceful failure in invalid inputs was, as always, the most difficult part.
As implied, it is possible to "cheat" the somewhat limited type checking which the Danmakufu Executor enforces:
let array = [[], []];
array [0] = [11];
array [1] = ["str"];
I could have put all those troublesome global variables into one array using this, but decided not to, not least because I kind of want to create an external type checker which is supposed to catch all those vexing type errors before testing, which would also enable better tooling support...
Since I found no practical way to convert
\uXXXX escape sequences to Danmakufu chars, those are not implemented and considered a syntax error. (Is there any way to create a character with a given code point?)
While not actually part of the Json standard, C like comments are quite useful, but were also not implemented. Changing that is likely to require little effort.
The
stringify operation could be implemented for this representation, but I decided not to, because the actual representation of data is likely to be quite different from this. I consider a recursive approach to be better suited. This also avoids having to check for circles and other silly things.
The Json parser can be found
as a gist on my GitHub account; if you find any bugs or have any suggestions, please leave a comment or notify me otherwise.
Any recommended format for saving non-trivial persistent data using Dnamakufu?
Edit: Thank you for fixing the links, Helepolis.