pretty json

This commit is contained in:
2026-02-15 22:28:44 -06:00
parent 7fc4a205f6
commit dc440587ff
24 changed files with 159462 additions and 877405 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,7 @@ if get_option('force_gc')
add_project_arguments('-DFORCE_GC_AT_MALLOC', language: 'c')
endif
deps = []
if host_machine.system() == 'darwin'

View File

@@ -1,116 +0,0 @@
// prettify_mcode.ce — reformat .mcode files to be human-readable
// Usage: ./cell --dev prettify_mcode boot/tokenize.cm.mcode
// ./cell --dev prettify_mcode boot/*.mcode
var fd = use("fd")
var json = use("json")
if (length(args) == 0) {
print("usage: cell prettify_mcode <file.mcode> [...]")
disrupt
}
// Collapse leaf arrays (instruction arrays) onto single lines
var compact_arrays = function(json_text) {
var lines = array(json_text, "\n")
var result = []
var i = 0
var line = null
var trimmed = null
var collecting = false
var collected = null
var indent = null
var is_leaf = null
var j = 0
var inner = null
var parts = null
var trailing = null
var chars = null
var k = 0
while (i < length(lines)) {
line = lines[i]
trimmed = trim(line)
if (collecting == false && trimmed == "[") {
collecting = true
chars = array(line)
k = 0
while (k < length(chars) && chars[k] == " ") {
k = k + 1
}
indent = text(line, 0, k)
collected = []
i = i + 1
continue
}
if (collecting) {
if (trimmed == "]" || trimmed == "],") {
is_leaf = true
j = 0
while (j < length(collected)) {
inner = trim(collected[j])
if (starts_with(inner, "[") || starts_with(inner, "{")) {
is_leaf = false
}
j = j + 1
}
if (is_leaf && length(collected) > 0) {
parts = []
j = 0
while (j < length(collected)) {
inner = trim(collected[j])
if (ends_with(inner, ",")) {
inner = text(inner, 0, length(inner) - 1)
}
parts[] = inner
j = j + 1
}
trailing = ""
if (ends_with(trimmed, ",")) {
trailing = ","
}
result[] = `${indent}[${text(parts, ", ")}]${trailing}`
} else {
result[] = `${indent}[`
j = 0
while (j < length(collected)) {
result[] = collected[j]
j = j + 1
}
result[] = line
}
collecting = false
} else {
collected[] = line
}
i = i + 1
continue
}
result[] = line
i = i + 1
}
return text(result, "\n")
}
var i = 0
var path = null
var raw = null
var obj = null
var pretty = null
var f = null
while (i < length(args)) {
path = args[i]
if (!fd.is_file(path)) {
print(`skip ${path} (not found)`)
i = i + 1
continue
}
raw = text(fd.slurp(path))
obj = json.decode(raw)
pretty = compact_arrays(json.encode(obj, null, 2))
f = fd.open(path, "w")
fd.write(f, pretty)
fd.close(f)
print(`prettified ${path}`)
i = i + 1
}

View File

@@ -588,7 +588,8 @@ JSValue JS_ParseJSON (JSContext *ctx, const char *buf, size_t buf_len,
JSValue JS_ParseJSON2 (JSContext *ctx, const char *buf, size_t buf_len,
const char *filename, int flags);
JSValue JS_JSONStringify (JSContext *ctx, JSValue obj,
JSValue replacer, JSValue space0);
JSValue replacer, JSValue space0,
JS_BOOL compact_arrays);
/* ============================================================
9. Intrinsic Wrappers (JS_Cell* / JS_Array*)

View File

@@ -5628,6 +5628,8 @@ typedef struct JSONStringifyContext {
JSValue gap;
JSValue empty;
JSGCRef b_root; /* GC root for buffer - use JSC_B_GET/SET macros */
BOOL compact_arrays;
BOOL in_compact_array;
} JSONStringifyContext;
/* Macros to access the buffer from the rooted JSValue */
@@ -5732,7 +5734,7 @@ static int js_json_to_str (JSContext *ctx, JSONStringifyContext *jsc, JSValue ho
}
indent1_ref.val = JS_ConcatString (ctx, indent_ref.val, jsc->gap);
if (JS_IsException (indent1_ref.val)) goto exception;
if (!JS_IsEmptyString (jsc->gap)) {
if (!JS_IsEmptyString (jsc->gap) && !jsc->in_compact_array) {
sep_ref.val = JS_ConcatString3 (ctx, "\n", indent1_ref.val, "");
if (JS_IsException (sep_ref.val)) goto exception;
sep1_ref.val = js_new_string8 (ctx, " ");
@@ -5747,12 +5749,49 @@ static int js_json_to_str (JSContext *ctx, JSONStringifyContext *jsc, JSValue ho
if (ret < 0) goto exception;
if (ret) {
if (js_get_length64 (ctx, &len, val_ref.val)) goto exception;
/* Check if this is a leaf array for compact mode.
Leaf = no element is an array, and no element is an object
that has array-valued properties. */
BOOL was_compact = jsc->in_compact_array;
if (jsc->compact_arrays && !jsc->in_compact_array && !JS_IsEmptyString (jsc->gap)) {
BOOL is_leaf = TRUE;
for (i = 0; i < len && is_leaf; i++) {
v = JS_GetPropertyNumber (ctx, val_ref.val, i);
if (JS_IsException (v)) goto exception;
if (JS_IsArray (v) > 0) {
is_leaf = FALSE;
} else if (mist_is_gc_object (v) && !JS_IsText (v)) {
/* Element is an object — check if any property is an array */
v_ref.val = v;
prop_ref.val = JS_GetOwnPropertyNames (ctx, v_ref.val);
if (!JS_IsException (prop_ref.val)) {
int64_t nprops;
if (!js_get_length64 (ctx, &nprops, prop_ref.val)) {
for (int64_t j = 0; j < nprops && is_leaf; j++) {
JSValue key = JS_GetPropertyNumber (ctx, prop_ref.val, j);
if (!JS_IsException (key)) {
JSValue pval = JS_GetPropertyValue (ctx, v_ref.val, key);
if (JS_IsArray (pval) > 0) is_leaf = FALSE;
}
}
}
}
v_ref.val = JS_NULL;
prop_ref.val = JS_NULL;
}
}
if (is_leaf) jsc->in_compact_array = TRUE;
}
JSC_B_PUTC (jsc, '[');
for (i = 0; i < len; i++) {
if (i > 0) {
JSC_B_PUTC (jsc, ',');
}
JSC_B_CONCAT (jsc, sep_ref.val);
if (jsc->in_compact_array && !was_compact) {
if (i > 0) JSC_B_PUTC (jsc, ' ');
} else {
JSC_B_CONCAT (jsc, sep_ref.val);
}
v = JS_GetPropertyNumber (ctx, val_ref.val, i);
if (JS_IsException (v)) goto exception;
v_ref.val = v; /* root v — JS_ToString below can trigger GC */
@@ -5765,11 +5804,12 @@ static int js_json_to_str (JSContext *ctx, JSONStringifyContext *jsc, JSValue ho
if (JS_IsNull (v)) v = JS_NULL;
if (js_json_to_str (ctx, jsc, val_ref.val, v, indent1_ref.val)) goto exception;
}
if (len > 0 && !JS_IsEmptyString (jsc->gap)) {
if (len > 0 && !JS_IsEmptyString (jsc->gap) && !jsc->in_compact_array) {
JSC_B_PUTC (jsc, '\n');
JSC_B_CONCAT (jsc, indent_ref.val);
}
JSC_B_PUTC (jsc, ']');
jsc->in_compact_array = was_compact;
} else {
if (!JS_IsNull (jsc->property_list))
tab_ref.val = jsc->property_list;
@@ -5803,7 +5843,7 @@ static int js_json_to_str (JSContext *ctx, JSONStringifyContext *jsc, JSValue ho
has_content = TRUE;
}
}
if (has_content && !JS_IsEmptyString (jsc->gap)) {
if (has_content && !JS_IsEmptyString (jsc->gap) && !jsc->in_compact_array) {
JSC_B_PUTC (jsc, '\n');
JSC_B_CONCAT (jsc, indent_ref.val);
}
@@ -5867,7 +5907,7 @@ exception:
return -1;
}
JSValue JS_JSONStringify (JSContext *ctx, JSValue obj, JSValue replacer, JSValue space0) {
JSValue JS_JSONStringify (JSContext *ctx, JSValue obj, JSValue replacer, JSValue space0, BOOL compact_arrays) {
JSONStringifyContext jsc_s, *jsc = &jsc_s;
JSValue val, v, space, ret, wrapper;
int res;
@@ -5885,6 +5925,8 @@ JSValue JS_JSONStringify (JSContext *ctx, JSValue obj, JSValue replacer, JSValue
jsc->property_list = JS_NULL;
jsc->gap = JS_NULL;
jsc->empty = JS_KEY_empty;
jsc->compact_arrays = compact_arrays;
jsc->in_compact_array = FALSE;
ret = JS_NULL;
wrapper = JS_NULL;
@@ -11160,9 +11202,14 @@ static JSValue js_cell_json_encode (JSContext *ctx, JSValue this_val, int argc,
if (argc < 1)
return JS_ThrowTypeError (ctx, "json.encode requires at least 1 argument");
JSValue replacer = argc > 1 ? argv[1] : JS_NULL;
JSValue space = argc > 2 ? argv[2] : JS_NewInt32 (ctx, 1);
JSValue result = JS_JSONStringify (ctx, argv[0], replacer, space);
BOOL pretty = argc <= 1 || JS_ToBool (ctx, argv[1]);
JSValue space = pretty ? JS_NewInt32 (ctx, 2) : JS_NULL;
JSValue replacer = JS_NULL;
if (argc > 2 && JS_IsFunction (argv[2]))
replacer = argv[2];
else if (argc > 3 && JS_IsArray (argv[3]))
replacer = argv[3];
JSValue result = JS_JSONStringify (ctx, argv[0], replacer, space, pretty);
return result;
}

View File

@@ -1428,7 +1428,7 @@ TEST(stringify_json_object) {
obj_ref.val = JS_NewObject(ctx);
JSValue v1 = JS_NewInt32(ctx, 1);
JS_SetPropertyStr(ctx, obj_ref.val, "a", v1);
JSValue str = JS_JSONStringify(ctx, obj_ref.val, JS_NULL, JS_NULL);
JSValue str = JS_JSONStringify(ctx, obj_ref.val, JS_NULL, JS_NULL, 0);
JS_PopGCRef(ctx, &obj_ref);
ASSERT(JS_IsText(str));
const char *s = JS_ToCString(ctx, str);
@@ -1444,7 +1444,7 @@ TEST(stringify_json_array) {
arr_ref.val = JS_NewArray(ctx);
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 1));
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 2));
JSValue str = JS_JSONStringify(ctx, arr_ref.val, JS_NULL, JS_NULL);
JSValue str = JS_JSONStringify(ctx, arr_ref.val, JS_NULL, JS_NULL, 0);
JS_PopGCRef(ctx, &arr_ref);
ASSERT(JS_IsText(str));
const char *s = JS_ToCString(ctx, str);