kopia lustrzana https://github.com/backface/turtlestitch
refactored syntax trees
rodzic
19e985bc24
commit
7da004f63e
|
@ -69,6 +69,9 @@
|
|||
* Chinese, thanks, Simon!
|
||||
* Brazilian Portuguese, thank you, Cassiano D'Andrea!
|
||||
|
||||
### 2021-12-08
|
||||
* blocks: refactored syntax trees
|
||||
|
||||
### 2021-12-07
|
||||
* objects: backwards-compatibility fix for key-event hat blocks
|
||||
* store, objects: load category-less custom blocks into "other"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<script src="src/morphic.js?version=2021-07-09"></script>
|
||||
<script src="src/symbols.js?version=2021-03-03"></script>
|
||||
<script src="src/widgets.js?version=2021-17-09"></script>
|
||||
<script src="src/blocks.js?version=2021-12-06"></script>
|
||||
<script src="src/blocks.js?version=2021-12-08"></script>
|
||||
<script src="src/threads.js?version=2021-12-06"></script>
|
||||
<script src="src/objects.js?version=2021-12-07"></script>
|
||||
<script src="src/scenes.js?version=2021-11-24"></script>
|
||||
|
|
217
src/blocks.js
217
src/blocks.js
|
@ -160,7 +160,7 @@ CustomCommandBlockMorph, ToggleButtonMorph, DialMorph, SnapExtensions*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.blocks = '2021-December-06';
|
||||
modules.blocks = '2021-December-08';
|
||||
|
||||
var SyntaxElementMorph;
|
||||
var BlockMorph;
|
||||
|
@ -3721,8 +3721,72 @@ BlockMorph.prototype.exportResultPic = function () {
|
|||
|
||||
// BlockMorph components - EXPERIMENTAL
|
||||
|
||||
BlockMorph.prototype.components = function () {
|
||||
throw new Error('subclass responsility');
|
||||
BlockMorph.prototype.components = function (parameterNames = []) {
|
||||
if (this instanceof ReporterBlockMorph) {
|
||||
return this.syntaxTree(parameterNames);
|
||||
}
|
||||
var seq = new List(this.blockSequence()).map((block, i) =>
|
||||
block.syntaxTree(i < 1 ? parameterNames : [])
|
||||
);
|
||||
return seq.length() === 1 ? seq.at(1) : seq;
|
||||
};
|
||||
|
||||
BlockMorph.prototype.syntaxTree = function (parameterNames) {
|
||||
var expr = this.fullCopy(),
|
||||
nb = expr.nextBlock ? expr.nextBlock() : null,
|
||||
inputs, parts;
|
||||
if (nb) {
|
||||
nb.destroy();
|
||||
}
|
||||
expr.fixBlockColor(null, true);
|
||||
inputs = expr.inputs();
|
||||
parts = new List([expr.reify()]);
|
||||
inputs.forEach(inp => {
|
||||
var val;
|
||||
if (inp instanceof BlockMorph) {
|
||||
if (inp instanceof RingMorph && inp.isEmptySlot()) {
|
||||
parts.add();
|
||||
return;
|
||||
}
|
||||
parts.add(inp.components());
|
||||
expr.revertToDefaultInput(inp, true);
|
||||
} else if (inp.isEmptySlot()) {
|
||||
if (!inp.isStatic) {
|
||||
parts.add();
|
||||
expr.revertToDefaultInput(inp, true);
|
||||
}
|
||||
} else if (inp instanceof MultiArgMorph) {
|
||||
inp.inputs().forEach((slot, i) => {
|
||||
var entry;
|
||||
if (slot instanceof BlockMorph) {
|
||||
if (slot instanceof RingMorph && slot.isEmptySlot()) {
|
||||
parts.add();
|
||||
return;
|
||||
}
|
||||
parts.add(slot.components());
|
||||
} else if (slot.isEmptySlot()) {
|
||||
parts.add();
|
||||
} else {
|
||||
entry = slot.evaluate();
|
||||
parts.add(entry instanceof BlockMorph ?
|
||||
entry.components() : entry);
|
||||
}
|
||||
if (!(slot instanceof TemplateSlotMorph)) {
|
||||
inp.revertToDefaultInput(slot, true);
|
||||
}
|
||||
});
|
||||
} else if (inp instanceof ArgLabelMorph) {
|
||||
parts.add(inp.argMorph().components());
|
||||
expr.revertToDefaultInput(inp, true).collapseAll();
|
||||
} else {
|
||||
val = inp.evaluate();
|
||||
parts.add(val instanceof BlockMorph ? val.components() : val);
|
||||
expr.revertToDefaultInput(inp, true);
|
||||
}
|
||||
});
|
||||
parts.at(1).updateEmptySlots();
|
||||
parameterNames.forEach(name => parts.add(name));
|
||||
return parts;
|
||||
};
|
||||
|
||||
BlockMorph.prototype.equalTo = function (other) {
|
||||
|
@ -3815,6 +3879,19 @@ BlockMorph.prototype.copyWithInputs = function (inputs) {
|
|||
return cpy.reify(dta.slice(count));
|
||||
};
|
||||
|
||||
BlockMorph.prototype.copyWithNext = function (next, parameterNames) {
|
||||
var expr = this.fullCopy(),
|
||||
top;
|
||||
if (this instanceof ReporterBlockMorph) {
|
||||
return expr.reify();
|
||||
}
|
||||
top = next.fullCopy().topBlock();
|
||||
if (top instanceof CommandBlockMorph) {
|
||||
expr.bottomBlock().nextBlock(top);
|
||||
}
|
||||
return expr.reify(parameterNames);
|
||||
};
|
||||
|
||||
BlockMorph.prototype.reify = function (inputNames) {
|
||||
// private - assumes that I've already been deep copied
|
||||
var context = new Context();
|
||||
|
@ -5558,80 +5635,6 @@ CommandBlockMorph.prototype.extract = function () {
|
|||
}
|
||||
};
|
||||
|
||||
// CommandBlockMorph components - EXPERIMENTAL
|
||||
|
||||
CommandBlockMorph.prototype.components = function (parameterNames = []) {
|
||||
var seq = new List(this.blockSequence()).map(block => {
|
||||
var expr = block.fullCopy(),
|
||||
nb = expr.nextBlock(),
|
||||
inputs, parts;
|
||||
if (nb) {
|
||||
nb.destroy();
|
||||
}
|
||||
expr.fixBlockColor(null, true);
|
||||
inputs = expr.inputs();
|
||||
parts = new List([expr.reify()]);
|
||||
inputs.forEach(inp => {
|
||||
var val;
|
||||
if (inp instanceof BlockMorph) {
|
||||
if (inp instanceof RingMorph && inp.isEmptySlot()) {
|
||||
parts.add();
|
||||
return;
|
||||
}
|
||||
parts.add(inp.components());
|
||||
expr.revertToDefaultInput(inp, true);
|
||||
} else if (inp.isEmptySlot()) {
|
||||
if (!inp.isStatic) {
|
||||
parts.add();
|
||||
expr.revertToDefaultInput(inp, true);
|
||||
}
|
||||
} else if (inp instanceof MultiArgMorph) {
|
||||
inp.inputs().forEach((slot, i) => {
|
||||
var entry;
|
||||
if (slot instanceof BlockMorph) {
|
||||
if (slot instanceof RingMorph && slot.isEmptySlot()) {
|
||||
parts.add();
|
||||
return;
|
||||
}
|
||||
parts.add(slot.components());
|
||||
} else if (slot.isEmptySlot()) {
|
||||
parts.add();
|
||||
} else {
|
||||
entry = slot.evaluate();
|
||||
parts.add(entry instanceof BlockMorph ?
|
||||
entry.components() : entry);
|
||||
}
|
||||
if (!(slot instanceof TemplateSlotMorph)) {
|
||||
inp.revertToDefaultInput(slot, true);
|
||||
}
|
||||
});
|
||||
} else if (inp instanceof ArgLabelMorph) {
|
||||
parts.add(inp.argMorph().components());
|
||||
expr.revertToDefaultInput(inp, true).collapseAll();
|
||||
} else {
|
||||
val = inp.evaluate();
|
||||
parts.add(val instanceof BlockMorph ? val.components() : val);
|
||||
expr.revertToDefaultInput(inp, true);
|
||||
}
|
||||
});
|
||||
parts.at(1).updateEmptySlots();
|
||||
parameterNames.forEach(name => parts.add(name));
|
||||
return parts;
|
||||
});
|
||||
return seq.length() === 1 ? seq.at(1) : seq;
|
||||
};
|
||||
|
||||
CommandBlockMorph.prototype.copyWithNext = function (next, parameterNames) {
|
||||
var exp = this.fullCopy(),
|
||||
bottom = exp.bottomBlock(),
|
||||
top = next.fullCopy().topBlock();
|
||||
|
||||
if (top instanceof CommandBlockMorph) {
|
||||
bottom.nextBlock(top);
|
||||
}
|
||||
return exp.reify(parameterNames);
|
||||
};
|
||||
|
||||
// CommandBlockMorph drawing:
|
||||
|
||||
CommandBlockMorph.prototype.outlinePath = function(ctx, inset) {
|
||||
|
@ -6406,66 +6409,6 @@ ReporterBlockMorph.prototype.userDestroy = function () {
|
|||
this.destroy();
|
||||
};
|
||||
|
||||
// ReporterBlockMorph components - EXPERIMENTAL
|
||||
|
||||
ReporterBlockMorph.prototype.components = function (parameterNames = []) {
|
||||
var expr = this.fullCopy(),
|
||||
inputs = expr.inputs(),
|
||||
parts;
|
||||
expr.fixBlockColor(null, true);
|
||||
parts = new List([expr.reify()]);
|
||||
inputs.forEach(inp => {
|
||||
var val;
|
||||
if (inp instanceof BlockMorph) {
|
||||
if (inp instanceof RingMorph && inp.isEmptySlot()) {
|
||||
parts.add();
|
||||
return;
|
||||
}
|
||||
parts.add(inp.components());
|
||||
expr.revertToDefaultInput(inp, true);
|
||||
} else if (inp.isEmptySlot()) {
|
||||
if (!inp.isStatic) {
|
||||
parts.add();
|
||||
expr.revertToDefaultInput(inp, true);
|
||||
}
|
||||
} else if (inp instanceof MultiArgMorph) {
|
||||
inp.inputs().forEach((slot, i) => {
|
||||
var entry;
|
||||
if (slot instanceof BlockMorph) {
|
||||
if (slot instanceof RingMorph && slot.isEmptySlot()) {
|
||||
parts.add();
|
||||
return;
|
||||
}
|
||||
parts.add(slot.components());
|
||||
} else if (slot.isEmptySlot()) {
|
||||
parts.add();
|
||||
} else {
|
||||
entry = slot.evaluate();
|
||||
parts.add(entry instanceof BlockMorph ?
|
||||
entry.components() : entry);
|
||||
}
|
||||
if (!(slot instanceof TemplateSlotMorph)) {
|
||||
inp.revertToDefaultInput(slot, true);
|
||||
}
|
||||
});
|
||||
} else if (inp instanceof ArgLabelMorph) {
|
||||
parts.add(inp.argMorph().components());
|
||||
expr.revertToDefaultInput(inp, true).collapseAll();
|
||||
} else {
|
||||
val = inp.evaluate();
|
||||
parts.add(val instanceof BlockMorph ? val.components() : val);
|
||||
expr.revertToDefaultInput(inp, true);
|
||||
}
|
||||
});
|
||||
parameterNames.forEach(name => parts.add(name));
|
||||
parts.at(1).updateEmptySlots();
|
||||
return parts;
|
||||
};
|
||||
|
||||
ReporterBlockMorph.prototype.copyWithNext = function (next) {
|
||||
return this.fullCopy().reify();
|
||||
};
|
||||
|
||||
// ReporterBlockMorph drawing:
|
||||
|
||||
ReporterBlockMorph.prototype.outlinePath = function (ctx, inset) {
|
||||
|
|
Ładowanie…
Reference in New Issue