mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2025-07-23 04:31:25 -04:00
Merge pull request #963 from towerofnix/foreach-vm
Implement for-each block
This commit is contained in:
commit
51306e3492
3 changed files with 75 additions and 0 deletions
|
@ -17,6 +17,7 @@ class Scratch3ControlBlocks {
|
|||
return {
|
||||
control_repeat: this.repeat,
|
||||
control_repeat_until: this.repeatUntil,
|
||||
control_for_each: this.forEach,
|
||||
control_forever: this.forever,
|
||||
control_wait: this.wait,
|
||||
control_wait_until: this.waitUntil,
|
||||
|
@ -61,6 +62,21 @@ class Scratch3ControlBlocks {
|
|||
}
|
||||
}
|
||||
|
||||
forEach (args, util) {
|
||||
const variable = util.target.lookupOrCreateVariable(
|
||||
args.VARIABLE.id, args.VARIABLE.name);
|
||||
|
||||
if (typeof util.stackFrame.index === 'undefined') {
|
||||
util.stackFrame.index = 0;
|
||||
}
|
||||
|
||||
if (util.stackFrame.index < Number(args.VALUE)) {
|
||||
util.stackFrame.index++;
|
||||
variable.value = util.stackFrame.index;
|
||||
util.startBranch(1, true);
|
||||
}
|
||||
}
|
||||
|
||||
waitUntil (args, util) {
|
||||
const condition = Cast.toBoolean(args.CONDITION);
|
||||
if (!condition) {
|
||||
|
|
|
@ -768,6 +768,24 @@ const specMap = {
|
|||
}
|
||||
]
|
||||
},
|
||||
'doForLoop': {
|
||||
opcode: 'control_for_each',
|
||||
argMap: [
|
||||
{
|
||||
type: 'field',
|
||||
fieldName: 'VARIABLE'
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
inputOp: 'text',
|
||||
inputName: 'VALUE'
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
inputName: 'SUBSTACK'
|
||||
}
|
||||
]
|
||||
},
|
||||
'stopScripts': {
|
||||
opcode: 'control_stop',
|
||||
argMap: [
|
||||
|
|
|
@ -52,6 +52,47 @@ test('repeatUntil', t => {
|
|||
t.end();
|
||||
});
|
||||
|
||||
test('forEach', t => {
|
||||
const rt = new Runtime();
|
||||
const c = new Control(rt);
|
||||
|
||||
const variableValues = [];
|
||||
const variable = {value: 0};
|
||||
let value;
|
||||
const util = {
|
||||
stackFrame: Object.create(null),
|
||||
target: {
|
||||
lookupOrCreateVariable: function () {
|
||||
return variable;
|
||||
}
|
||||
},
|
||||
startBranch: function () {
|
||||
variableValues.push(variable.value);
|
||||
c.forEach({VARIABLE: {}, VALUE: value}, util);
|
||||
}
|
||||
};
|
||||
|
||||
// for each (variable) in "5"
|
||||
// ..should yield variable values 1, 2, 3, 4, 5
|
||||
util.stackFrame = Object.create(null);
|
||||
variableValues.splice(0);
|
||||
variable.value = 0;
|
||||
value = '5';
|
||||
c.forEach({VARIABLE: {}, VALUE: value}, util);
|
||||
t.deepEqual(variableValues, [1, 2, 3, 4, 5]);
|
||||
|
||||
// for each (variable) in 4
|
||||
// ..should yield variable values 1, 2, 3, 4
|
||||
util.stackFrame = Object.create(null);
|
||||
variableValues.splice(0);
|
||||
variable.value = 0;
|
||||
value = 4;
|
||||
c.forEach({VARIABLE: {}, VALUE: value}, util);
|
||||
t.deepEqual(variableValues, [1, 2, 3, 4]);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('forever', t => {
|
||||
const rt = new Runtime();
|
||||
const c = new Control(rt);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue