if_any(Reg, Types, Body) -> [{push, [false]}, [[{push, [Reg, T]}, strict_equals, 'or'] || T <- Types], 'not', {'if', Body}]. define_regs() -> [{push, ["_r0", "_r1", "_r2", "_r3"]}, define_local2, define_local2, define_local2, define_local2]. with_regs(L) -> [{push, ["_r0", r0]}, set_variable, {push, ["_r1", r1]}, set_variable, {push, ["_r2", r2]}, set_variable, {push, ["_r3", r3]}, set_variable, L, {store_register, 0, [{get_variable, "_r0"}]}, {store_register, 1, [{get_variable, "_r1"}]}, {store_register, 2, [{get_variable, "_r2"}]}, {store_register, 3, [{get_variable, "_r3"}]}]. json_function() -> Recurse = with_regs([{push, [1]}, {get_variable, "arguments"}, {push, ["callee"]}, call_method]), {define_function, "", ["arg"], [% var lut = "0123456789abcdef"; {push, ["lut", "0123456789abcdef"]}, define_local, % var _r0, _r1, _r2, _r3; define_regs(), % r0 = arg; {store_register, 0, [{get_variable, "arg"}]}, % r1 = typeof(r0); {store_register, 1, [{push, [r0]}, typeof]}, % if (!!(r0 === undefined || r0 === null)) { return "null"; } if_any(r0, [null, undefined], [{push, ["null"]}, return]), % if (!!(r1 == "number" || r1 == "boolean")) { return r0.toString(); } if_any(r1, ["number", "boolean"], [{push, [r0]}, to_string, return]), % if (!!(r1 == "movieclip" || r1 == "function")) { ... } if_any(r1, ["movieclip", "function"], [% r0 = r1.toString(); {store_register, 0, [{push, [r0]}, to_string]}, % r1 = "string"; {store_register, 1, [{push, ["string"]}]}]), % r3 = new Array(); {store_register, 3, [{new_object, "Array"}]}, % if (!!(r1 == "string")) { ... } if_any(r1, ["string"], [% r2 = r0.length; {store_register, 2, [{push, [r0, "length"]}, get_member]}, % if (!r2) { return "\"\""; } {push, [r2]}, {'if', [{push, ["\"\""]}, return]}, % do { ... } while (r2) {dowhile, [% r2 -= 1; {store_register, 2, [{push, [r2]}, decrement]}, % r1 = r0.charAt(r2); {store_register, 1, [{push, [r2, 1, r0, "charAt"]}, call_method]}, % if (r1 === "\b") r1 = "\\b"; if_any(r1, ["\b"], [{store_register, 1, [{push, ["\\b"]}]}]), % if (r1 === "\f") r1 = "\\f"; if_any(r1, ["\f"], [{store_register, 1, [{push, ["\\f"]}]}]), % if (r1 === "\n") r1 = "\\n"; if_any(r1, ["\n"], [{store_register, 1, [{push, ["\\n"]}]}]), % if (r1 === "\r") r1 = "\\r"; if_any(r1, ["\r"], [{store_register, 1, [{push, ["\\r"]}]}]), % if (r1 === "\t") r1 = "\\t"; if_any(r1, ["\t"], [{store_register, 1, [{push, ["\\t"]}]}]), % if (r1 === "\"" || r1 === "\\" || r1 === "/") { ... } if_any(r1, ["\"", "\\", "/"], [% r1 = "\\" + r1; {store_register, 1, [{push, ["\\", r1]}, string_add]}]), % if (!!(r1 < ' ' || '~' < r1)) { ... } {push, [r1, " "]}, string_less, {push, ["~", r1]}, string_less, 'or', 'not', {'if', [% r1 = r0.charCodeAt(r2); {store_register, 1, [{push, [r2, 1, r0, "charCodeAt"]}, call_method]}, % r1 = "\\u" + % lut[(r1 >> 24) & 15] + % lut[(r1 >> 16) & 15] + % lut[(r1 >> 8) & 15] + % lut[r1 & 15]; {store_register, 1, [{push, ["\\u"]}, {get_variable, "lut"}, {push, [15, r1, 24]}, bit_urshift, bit_and, get_member, {get_variable, "lut"}, {push, [15, r1, 16]}, bit_urshift, bit_and, get_member, {get_variable, "lut"}, {push, [15, r1, 8]}, bit_urshift, bit_and, get_member, {get_variable, "lut"}, {push, [15, r1]}, bit_and, get_member, string_add, string_add, string_add, string_add]}]}, % r3[r2] = r1; {push, [r3, r2, r1]}, set_member, % ... while (r2) {push, [r2]}]}, % r3 = r3.join(""); {store_register, 3, [{push, ["", 1, r3, "join"]}, call_method]}, % return "\"" + r3 + "\""; {push, ["\"", r3, "\""]}, string_add, string_add, return]), % if (!!(r0 instanceof Array)) { ... } {push, [r0, "Array"]}, get_variable, instance_of, 'not', {'if', [% r2 = r0.length; {store_register, 2, [{push, [r0, "length"]}, get_member]}, % if (!!r2) { ... } {push, [r2]}, 'not', {'if', [% do { ... } while (r2) {dowhile, [% r2 -= 1; {store_register, 2, [{push, [r2]}, decrement]}, % r1 = fn(fn, r0[r2]); {store_register, 1, [{push, [r0, r2]}, get_member | Recurse]}, % r3[r2] = r1; {push, [r3, r2, r1]}, set_member, % ... while (r2) {push, [r2]}]}]}, % r3 = r3.join(","); {store_register, 3, [{push, [",", 1, r3, "join"]}, call_method]}, % return "[" + r3 + "]"; {push, ["[", r3, "]"]}, string_add, string_add, return]}, % r2 = 0; {store_register, 2, [{push, [0]}]}, % for (stack in r0) { ... } {push, [r0]}, {enumerate, [% r1 = stack; // no pop {store_register, 1}, % r3[r2] = fn(fn, r1) + ":" + fn(fn, r0[r1]); {push, [r3, r2]}, [{push, [r1]} | Recurse], {push, [":"]}, [{push, [r0, r1]}, get_member | Recurse], string_add, string_add, set_member, % r2 += 1; {store_register, 2, [{push, [r2]}, increment]}]}, % r3 = r3.join(","); {store_register, 3, [{push, [",", 1, r3, "join"]}, call_method]}, % return "{" + r3 + "}"; {push, ["{", r3, "}"]}, string_add, string_add, return]}.