ref: 8e7d57959c9c69930d4cc5df8130ae4ebb87e5c0
parent: 58b44200948f0691f34b45b2718ec572f4261277
author: Tor Andersson <tor.andersson@gmail.com>
date: Wed Apr 19 09:22:36 EDT 2017
JSON.parse reviver callback.
--- a/json.c
+++ b/json.c
@@ -92,13 +92,68 @@
}
}
+static void jsonrevive(js_State *J, const char *name)
+{
+ const char *key;
+ char buf[32];
+
+ /* revive is in 2 */
+ /* holder is in -1 */
+
+ js_getproperty(J, -1, name); /* get value from holder */
+
+ if (js_isobject(J, -1)) {
+ if (js_isarray(J, -1)) {
+ int i = 0;
+ int n = js_getlength(J, -1);
+ for (i = 0; i < n; ++i) {
+ jsonrevive(J, js_itoa(buf, i));
+ if (js_isundefined(J, -1)) {
+ js_pop(J, 1);
+ js_delproperty(J, -1, buf);
+ } else {
+ js_setproperty(J, -2, buf);
+ }
+ }
+ } else {
+ js_pushiterator(J, -1, 1);
+ while ((key = js_nextiterator(J, -1))) {
+ js_rot2(J);
+ jsonrevive(J, key);
+ if (js_isundefined(J, -1)) {
+ js_pop(J, 1);
+ js_delproperty(J, -1, key);
+ } else {
+ js_setproperty(J, -2, key);
+ }
+ js_rot2(J);
+ }
+ js_pop(J, 1);
+ }
+ }
+
+ js_copy(J, 2); /* reviver function */
+ js_copy(J, -3); /* holder as this */
+ js_pushstring(J, name); /* name */
+ js_copy(J, -4); /* value */
+ js_call(J, 2);
+ js_rot2pop1(J); /* pop old value, leave new value on stack */
+}
+
static void JSON_parse(js_State *J)
{
const char *source = js_tostring(J, 1);
jsY_initlex(J, "JSON", source);
jsonnext(J);
- jsonvalue(J);
- /* TODO: reviver Walk() */
+
+ if (js_iscallable(J, 2)) {
+ js_newobject(J);
+ jsonvalue(J);
+ js_defproperty(J, -2, "", 0);
+ jsonrevive(J, "");
+ } else {
+ jsonvalue(J);
+ }
}
static void fmtnum(js_State *J, js_Buffer **sb, double n)