Skip to content

Commit 83b410d

Browse files
authored
Merge pull request #455 from DogeisCut/extension-dogeiscutObject
Objects: New Stringify Block + fix weird stringinifcation/misc issues
2 parents 7512575 + 9510d88 commit 83b410d

1 file changed

Lines changed: 59 additions & 65 deletions

File tree

static/extensions/DogeisCut/dogeiscutObject.js

Lines changed: 59 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -109,36 +109,8 @@
109109
return x
110110
}
111111

112-
toString() {
113-
const stringify = (obj) => {
114-
if (obj instanceof jwArray.Type) {
115-
return `[${obj.array.map(item => stringify(item)).join(",")}]`;
116-
}
117-
if (isArray(obj)) {
118-
return `[${obj.map(stringify).join(",")}]`;
119-
}
120-
if (obj instanceof dogeiscutObject.Type) {
121-
return obj.toString();
122-
}
123-
if (obj !== null && typeof obj === "object") {
124-
if (typeof obj.dogeiscutObjectHandler == "function") {
125-
return obj.dogeiscutObjectHandler()
126-
}
127-
if (typeof obj.jwArrayHandler == "function") {
128-
return obj.jwArrayHandler()
129-
}
130-
const entries = Object.entries(obj)
131-
.map(([key, value]) => `"${key.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}":${stringify(value)}`)
132-
.join(",");
133-
return `{${entries}}`;
134-
}
135-
if (obj === null || obj === undefined) return "null";
136-
if (typeof obj === "string") return JSON.stringify(obj);
137-
if (typeof obj === "number" || typeof obj === "boolean") return obj.toString();
138-
return "?";
139-
};
140-
141-
return stringify(this.object);
112+
toString(pretty = false) {
113+
return JSON.stringify(this.object, null, pretty ? "\t" : null)
142114
}
143115

144116
toVisualContent(border = '1px solid #ccc', keyBackground = '#f9f9f9', background = '#fff') {
@@ -295,7 +267,7 @@
295267
Object.entries(this.object).map(([key, value]) => {
296268
if (typeof value === "object" && value !== null) {
297269
if (typeof value.toJSON === "function") return [key, value.toJSON()]
298-
if (typeof value.toString === "function") return [key, value.toString()]
270+
//if (typeof value.toString === "function") return [key, value.toString()]
299271
return [key, JSON.stringify(value)]
300272
}
301273
return [key, value]
@@ -359,10 +331,7 @@
359331

360332
class Extension {
361333
constructor() {
362-
vm.runtime.registerCompiledExtensionBlocks('dogeiscutObject', this.getCompileInfo());
363-
364334
vm.dogeiscutObject = dogeiscutObject
365-
366335
vm.runtime.registerSerializer(
367336
"dogeiscutObject",
368337
v => {
@@ -400,6 +369,8 @@
400369

401370
if (!vm.jwArray) vm.extensionManager.loadExtensionIdSync('jwArray')
402371
jwArray = vm.jwArray
372+
373+
vm.runtime.registerCompiledExtensionBlocks('dogeiscutObject', this.getCompileInfo());
403374
}
404375

405376
getInfo() {
@@ -453,6 +424,12 @@
453424
ARRAY: jwArray.Argument
454425
}
455426
},
427+
// future idea
428+
// {
429+
// opcode: 'fromLists',
430+
// text: 'from lists keys: [KEY_LIST] values: [VALUE_LIST}',
431+
// ...dogeiscutObject.Block,
432+
// },
456433
'---',
457434
{
458435
opcode: 'currentObject',
@@ -464,21 +441,18 @@
464441
{
465442
opcode: 'builder',
466443
text: 'object builder [CURRENT_OBJECT]',
467-
...dogeiscutObject.Block,
444+
branches: [{}],
468445
arguments: {
469446
CURRENT_OBJECT: {
470447
fillIn: 'currentObject'
471448
},
472449
},
473-
branches: [{
474-
//accepts: 'dogeiscutObjectBuilder'
475-
}],
450+
...dogeiscutObject.Block,
476451
},
477452
{
478453
opcode: 'builderAppend',
479454
text: 'append key [KEY] value [VALUE] to builder',
480455
blockType: Scratch.BlockType.COMMAND,
481-
//notchAccepts: 'dogeiscutObjectBuilder',
482456
arguments: {
483457
KEY: {
484458
type: Scratch.ArgumentType.STRING,
@@ -496,7 +470,6 @@
496470
opcode: 'builderAppendEmpty',
497471
text: 'append key [KEY] to builder',
498472
blockType: Scratch.BlockType.COMMAND,
499-
//notchAccepts: 'dogeiscutObjectBuilder',
500473
arguments: {
501474
KEY: {
502475
type: Scratch.ArgumentType.STRING,
@@ -509,7 +482,6 @@
509482
opcode: 'builderSet',
510483
text: 'set builder to [OBJECT]',
511484
blockType: Scratch.BlockType.COMMAND,
512-
//notchAccepts: 'dogeiscutObjectBuilder',
513485
arguments: {
514486
OBJECT: dogeiscutObject.Argument
515487
}
@@ -603,6 +575,19 @@
603575
...dogeiscutObject.Block,
604576
},
605577
'---',
578+
{
579+
opcode: 'toString',
580+
text: 'stringify [OBJECT] [FORMAT]',
581+
blockType: Scratch.BlockType.REPORTER,
582+
arguments: {
583+
OBJECT: dogeiscutObject.Argument,
584+
FORMAT: {
585+
menu: "stringifyFormat",
586+
defaultValue: "compact"
587+
}
588+
}
589+
},
590+
'---',
606591
{
607592
opcode: 'keys',
608593
text: 'keys of [OBJECT]',
@@ -670,34 +655,43 @@
670655
}
671656
}
672657
},
673-
]
658+
],
659+
menus: {
660+
list: {
661+
acceptReporters: false,
662+
items: "getLists",
663+
},
664+
stringifyFormat: {
665+
acceptReporters: false,
666+
items: [
667+
"compact",
668+
"pretty"
669+
]
670+
}
671+
}
674672
}
675673
}
676674

677675
getCompileInfo() {
678676
return {
679677
ir: {
680-
builder: (generator, block) => ({
681-
kind: 'input',
682-
substack: generator.descendSubstack(block, 'SUBSTACK')
683-
}),
678+
builder: (generator, block) => {
679+
generator.script.yields = true
680+
return {
681+
kind: 'input',
682+
substack: generator.descendSubstack(block, 'SUBSTACK')
683+
}
684+
}
684685
},
685686
js: {
686687
builder: (node, compiler, imports) => {
687688
const originalSource = compiler.source;
688689

689-
compiler.source = '(yield* (function*() {';
690-
compiler.source += ' const __inner = (yield* (function*() {';
691-
compiler.source += ` thread._dogeiscutObjectBuilderIndex ??= [];`;
692-
compiler.source += ` thread._dogeiscutObjectBuilderIndex.push(Object.create(null));`;
690+
compiler.source = 'vm.dogeiscutObject.Type.toObject(yield* (function*() {';
691+
compiler.source += 'thread._dogeiscutObjectBuilderIndex ??= [];';
692+
compiler.source += 'thread._dogeiscutObjectBuilderIndex.push(Object.create(null));';
693693
compiler.descendStack(node.substack, new imports.Frame(false, undefined, true));
694-
compiler.source += ` return new runtime.ext_dogeiscutObject.BuilderReturnValue(thread._dogeiscutObjectBuilderIndex.pop());`;
695-
compiler.source += ' })());';
696-
compiler.source += ' const __result = __inner;';
697-
compiler.source += ' if (!(__result instanceof runtime.ext_dogeiscutObject.BuilderReturnValue)) {';
698-
compiler.source += ' throw "Return statements are not supported in builders.";';
699-
compiler.source += ' }';
700-
compiler.source += ' return new runtime.vm.dogeiscutObject.Type(__result.value);';
694+
compiler.source += 'return thread._dogeiscutObjectBuilderIndex.pop();';
701695
compiler.source += '})())';
702696

703697
const stackSource = compiler.source;
@@ -708,12 +702,6 @@
708702
};
709703
}
710704

711-
BuilderReturnValue = class {
712-
constructor(value) {
713-
this.value = value
714-
}
715-
}
716-
717705
/* Blocks */
718706

719707
blank() {
@@ -745,11 +733,11 @@
745733
if (util.thread._dogeiscutObjectBuilderIndex && util.thread._dogeiscutObjectBuilderIndex.length > 0) {
746734
return dogeiscutObject.Type.toObject(util.thread._dogeiscutObjectBuilderIndex[util.thread._dogeiscutObjectBuilderIndex.length-1])
747735
} else {
748-
throw 'This block must be inside of a "string builder" block.';
736+
throw 'This block must be inside of a "object builder" block.';
749737
}
750738
}
751739

752-
async builder({}, util) {
740+
builder() {
753741
return 'noop'
754742
}
755743

@@ -880,6 +868,12 @@
880868
return TWO;
881869
}
882870

871+
toString({OBJECT, FORMAT}) {
872+
OBJECT = dogeiscutObject.Type.toObject(OBJECT, false);
873+
874+
return OBJECT.toString(FORMAT === "pretty")
875+
}
876+
883877
keys({ OBJECT }) {
884878
OBJECT = dogeiscutObject.Type.toObject(OBJECT, false);
885879

0 commit comments

Comments
 (0)