Merge pull request #150 from TurboWarp/return
Allow custom blocks to return values - VM part
This commit is contained in:
103 files changed
+1704
-401
No files matched your search
@@ -15,6 +15,7 @@ class Scratch3ProcedureBlocks {
|
||||
return {
|
||||
procedures_definition: this.definition,
|
||||
procedures_call: this.call,
|
||||
procedures_return: this.return,
|
||||
argument_reporter_string_number: this.argumentReporterStringNumber,
|
||||
argument_reporter_boolean: this.argumentReporterBoolean
|
||||
};
|
||||
@@ -25,45 +26,76 @@ class Scratch3ProcedureBlocks {
|
||||
}
|
||||
|
||||
call (args, util) {
|
||||
if (!util.stackFrame.executed) {
|
||||
const procedureCode = args.mutation.proccode;
|
||||
const paramNamesIdsAndDefaults = util.getProcedureParamNamesIdsAndDefaults(procedureCode);
|
||||
const stackFrame = util.stackFrame;
|
||||
const isReporter = !!args.mutation.return;
|
||||
|
||||
// If null, procedure could not be found, which can happen if custom
|
||||
// block is dragged between sprites without the definition.
|
||||
// Match Scratch 2.0 behavior and noop.
|
||||
if (paramNamesIdsAndDefaults === null) {
|
||||
return;
|
||||
if (stackFrame.executed) {
|
||||
if (isReporter) {
|
||||
const returnValue = stackFrame.returnValue;
|
||||
// This stackframe will be reused for other reporters in this block, so clean it up for them.
|
||||
// Can't use reset() because that will reset too much.
|
||||
const threadStackFrame = util.thread.peekStackFrame();
|
||||
threadStackFrame.params = null;
|
||||
threadStackFrame.executionContext = null;
|
||||
return returnValue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const [paramNames, paramIds, paramDefaults] = paramNamesIdsAndDefaults;
|
||||
const procedureCode = args.mutation.proccode;
|
||||
const paramNamesIdsAndDefaults = util.getProcedureParamNamesIdsAndDefaults(procedureCode);
|
||||
|
||||
// Initialize params for the current stackFrame to {}, even if the procedure does
|
||||
// not take any arguments. This is so that `getParam` down the line does not look
|
||||
// at earlier stack frames for the values of a given parameter (#1729)
|
||||
util.initParams();
|
||||
for (let i = 0; i < paramIds.length; i++) {
|
||||
if (args.hasOwnProperty(paramIds[i])) {
|
||||
util.pushParam(paramNames[i], args[paramIds[i]]);
|
||||
} else {
|
||||
util.pushParam(paramNames[i], paramDefaults[i]);
|
||||
}
|
||||
// If null, procedure could not be found, which can happen if custom
|
||||
// block is dragged between sprites without the definition.
|
||||
// Match Scratch 2.0 behavior and noop.
|
||||
if (paramNamesIdsAndDefaults === null) {
|
||||
if (isReporter) {
|
||||
return '';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const addonBlock = util.runtime.getAddonBlock(procedureCode);
|
||||
if (addonBlock) {
|
||||
const result = addonBlock.callback(util.thread.getAllparams(), util);
|
||||
if (util.thread.status === 1 /* STATUS_PROMISE_WAIT */) {
|
||||
// If the addon block is using STATUS_PROMISE_WAIT to force us to sleep,
|
||||
// make sure to not re-run this block when we resume.
|
||||
util.stackFrame.executed = true;
|
||||
}
|
||||
return result;
|
||||
const [paramNames, paramIds, paramDefaults] = paramNamesIdsAndDefaults;
|
||||
|
||||
// Initialize params for the current stackFrame to {}, even if the procedure does
|
||||
// not take any arguments. This is so that `getParam` down the line does not look
|
||||
// at earlier stack frames for the values of a given parameter (#1729)
|
||||
util.initParams();
|
||||
for (let i = 0; i < paramIds.length; i++) {
|
||||
if (args.hasOwnProperty(paramIds[i])) {
|
||||
util.pushParam(paramNames[i], args[paramIds[i]]);
|
||||
} else {
|
||||
util.pushParam(paramNames[i], paramDefaults[i]);
|
||||
}
|
||||
}
|
||||
|
||||
util.stackFrame.executed = true;
|
||||
const addonBlock = util.runtime.getAddonBlock(procedureCode);
|
||||
if (addonBlock) {
|
||||
const result = addonBlock.callback(util.thread.getAllparams(), util);
|
||||
if (util.thread.status === 1 /* STATUS_PROMISE_WAIT */) {
|
||||
// If the addon block is using STATUS_PROMISE_WAIT to force us to sleep,
|
||||
// make sure to not re-run this block when we resume.
|
||||
stackFrame.executed = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
util.startProcedure(procedureCode);
|
||||
stackFrame.executed = true;
|
||||
|
||||
if (isReporter) {
|
||||
util.thread.peekStackFrame().waitingReporter = true;
|
||||
// Default return value
|
||||
stackFrame.returnValue = '';
|
||||
}
|
||||
|
||||
util.startProcedure(procedureCode);
|
||||
}
|
||||
|
||||
return (args, util) {
|
||||
util.stopThisScript();
|
||||
// If used outside of a custom block, there may be no stackframe.
|
||||
if (util.thread.peekStackFrame()) {
|
||||
util.stackFrame.returnValue = args.VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+123
-101
@@ -535,6 +535,9 @@ class ScriptTreeGenerator {
|
||||
right: this.descendInputOfBlock(block, 'NUM2')
|
||||
};
|
||||
|
||||
case 'procedures_call':
|
||||
return this.descendProcedure(block);
|
||||
|
||||
case 'sensing_answer':
|
||||
return {
|
||||
kind: 'sensing.answer'
|
||||
@@ -1106,102 +1109,25 @@ class ScriptTreeGenerator {
|
||||
};
|
||||
|
||||
case 'procedures_call': {
|
||||
// setting of yields will be handled later in the analysis phase
|
||||
|
||||
const procedureCode = block.mutation.proccode;
|
||||
if (block.mutation.return) {
|
||||
const visualReport = this.descendVisualReport(block);
|
||||
if (visualReport) {
|
||||
return visualReport;
|
||||
}
|
||||
}
|
||||
if (procedureCode === 'tw:debugger;') {
|
||||
return {
|
||||
kind: 'tw.debugger'
|
||||
};
|
||||
}
|
||||
const paramNamesIdsAndDefaults = this.blocks.getProcedureParamNamesIdsAndDefaults(procedureCode);
|
||||
if (paramNamesIdsAndDefaults === null) {
|
||||
return {
|
||||
kind: 'noop'
|
||||
};
|
||||
}
|
||||
|
||||
const [paramNames, paramIds, paramDefaults] = paramNamesIdsAndDefaults;
|
||||
|
||||
const addonBlock = this.runtime.getAddonBlock(procedureCode);
|
||||
if (addonBlock) {
|
||||
this.script.yields = true;
|
||||
const args = {};
|
||||
for (let i = 0; i < paramIds.length; i++) {
|
||||
let value;
|
||||
if (block.inputs[paramIds[i]] && block.inputs[paramIds[i]].block) {
|
||||
value = this.descendInputOfBlock(block, paramIds[i]);
|
||||
} else {
|
||||
value = {
|
||||
kind: 'constant',
|
||||
value: paramDefaults[i]
|
||||
};
|
||||
}
|
||||
args[paramNames[i]] = value;
|
||||
}
|
||||
return {
|
||||
kind: 'addons.call',
|
||||
code: procedureCode,
|
||||
arguments: args,
|
||||
blockId: block.id
|
||||
};
|
||||
}
|
||||
|
||||
const definitionId = this.blocks.getProcedureDefinition(procedureCode);
|
||||
const definitionBlock = this.blocks.getBlock(definitionId);
|
||||
if (!definitionBlock) {
|
||||
return {
|
||||
kind: 'noop'
|
||||
};
|
||||
}
|
||||
const innerDefinition = this.blocks.getBlock(definitionBlock.inputs.custom_block.block);
|
||||
|
||||
let isWarp = this.script.isWarp;
|
||||
if (!isWarp) {
|
||||
if (innerDefinition && innerDefinition.mutation) {
|
||||
const warp = innerDefinition.mutation.warp;
|
||||
if (typeof warp === 'boolean') {
|
||||
isWarp = warp;
|
||||
} else if (typeof warp === 'string') {
|
||||
isWarp = JSON.parse(warp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const variant = generateProcedureVariant(procedureCode, isWarp);
|
||||
|
||||
if (!this.script.dependedProcedures.includes(variant)) {
|
||||
this.script.dependedProcedures.push(variant);
|
||||
}
|
||||
|
||||
// Non-warp direct recursion yields.
|
||||
if (!this.script.isWarp) {
|
||||
if (procedureCode === this.script.procedureCode) {
|
||||
this.script.yields = true;
|
||||
}
|
||||
}
|
||||
|
||||
const args = [];
|
||||
for (let i = 0; i < paramIds.length; i++) {
|
||||
let value;
|
||||
if (block.inputs[paramIds[i]] && block.inputs[paramIds[i]].block) {
|
||||
value = this.descendInputOfBlock(block, paramIds[i]);
|
||||
} else {
|
||||
value = {
|
||||
kind: 'constant',
|
||||
value: paramDefaults[i]
|
||||
};
|
||||
}
|
||||
args.push(value);
|
||||
}
|
||||
|
||||
return {
|
||||
kind: 'procedures.call',
|
||||
code: procedureCode,
|
||||
variant,
|
||||
arguments: args
|
||||
};
|
||||
return this.descendProcedure(block);
|
||||
}
|
||||
case 'procedures_return':
|
||||
return {
|
||||
kind: 'procedures.return',
|
||||
value: this.descendInputOfBlock(block, 'VALUE')
|
||||
};
|
||||
|
||||
case 'sensing_resettimer':
|
||||
return {
|
||||
@@ -1225,18 +1151,9 @@ class ScriptTreeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
// When this thread was triggered by a stack click, attempt to compile as an input.
|
||||
// TODO: perhaps this should be moved to generate()?
|
||||
if (this.thread.stackClick) {
|
||||
try {
|
||||
const inputNode = this.descendInput(block);
|
||||
return {
|
||||
kind: 'visualReport',
|
||||
input: inputNode
|
||||
};
|
||||
} catch (e) {
|
||||
// Ignore
|
||||
}
|
||||
const asVisualReport = this.descendVisualReport(block);
|
||||
if (asVisualReport) {
|
||||
return asVisualReport;
|
||||
}
|
||||
|
||||
log.warn(`IR: Unknown stacked block: ${block.opcode}`, block);
|
||||
@@ -1370,6 +1287,97 @@ class ScriptTreeGenerator {
|
||||
return createVariableData('target', newVariable);
|
||||
}
|
||||
|
||||
descendProcedure (block) {
|
||||
const procedureCode = block.mutation.proccode;
|
||||
const paramNamesIdsAndDefaults = this.blocks.getProcedureParamNamesIdsAndDefaults(procedureCode);
|
||||
if (paramNamesIdsAndDefaults === null) {
|
||||
return {
|
||||
kind: 'noop'
|
||||
};
|
||||
}
|
||||
|
||||
const [paramNames, paramIds, paramDefaults] = paramNamesIdsAndDefaults;
|
||||
|
||||
const addonBlock = this.runtime.getAddonBlock(procedureCode);
|
||||
if (addonBlock) {
|
||||
this.script.yields = true;
|
||||
const args = {};
|
||||
for (let i = 0; i < paramIds.length; i++) {
|
||||
let value;
|
||||
if (block.inputs[paramIds[i]] && block.inputs[paramIds[i]].block) {
|
||||
value = this.descendInputOfBlock(block, paramIds[i]);
|
||||
} else {
|
||||
value = {
|
||||
kind: 'constant',
|
||||
value: paramDefaults[i]
|
||||
};
|
||||
}
|
||||
args[paramNames[i]] = value;
|
||||
}
|
||||
return {
|
||||
kind: 'addons.call',
|
||||
code: procedureCode,
|
||||
arguments: args,
|
||||
blockId: block.id
|
||||
};
|
||||
}
|
||||
|
||||
const definitionId = this.blocks.getProcedureDefinition(procedureCode);
|
||||
const definitionBlock = this.blocks.getBlock(definitionId);
|
||||
if (!definitionBlock) {
|
||||
return {
|
||||
kind: 'noop'
|
||||
};
|
||||
}
|
||||
const innerDefinition = this.blocks.getBlock(definitionBlock.inputs.custom_block.block);
|
||||
|
||||
let isWarp = this.script.isWarp;
|
||||
if (!isWarp) {
|
||||
if (innerDefinition && innerDefinition.mutation) {
|
||||
const warp = innerDefinition.mutation.warp;
|
||||
if (typeof warp === 'boolean') {
|
||||
isWarp = warp;
|
||||
} else if (typeof warp === 'string') {
|
||||
isWarp = JSON.parse(warp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const variant = generateProcedureVariant(procedureCode, isWarp);
|
||||
|
||||
if (!this.script.dependedProcedures.includes(variant)) {
|
||||
this.script.dependedProcedures.push(variant);
|
||||
}
|
||||
|
||||
// Non-warp direct recursion yields.
|
||||
if (!this.script.isWarp) {
|
||||
if (procedureCode === this.script.procedureCode) {
|
||||
this.script.yields = true;
|
||||
}
|
||||
}
|
||||
|
||||
const args = [];
|
||||
for (let i = 0; i < paramIds.length; i++) {
|
||||
let value;
|
||||
if (block.inputs[paramIds[i]] && block.inputs[paramIds[i]].block) {
|
||||
value = this.descendInputOfBlock(block, paramIds[i]);
|
||||
} else {
|
||||
value = {
|
||||
kind: 'constant',
|
||||
value: paramDefaults[i]
|
||||
};
|
||||
}
|
||||
args.push(value);
|
||||
}
|
||||
|
||||
return {
|
||||
kind: 'procedures.call',
|
||||
code: procedureCode,
|
||||
variant,
|
||||
arguments: args
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Descend into a block that uses the compatibility layer.
|
||||
* @param {*} block The block to use the compatibility layer for.
|
||||
@@ -1431,6 +1439,20 @@ class ScriptTreeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
descendVisualReport (block) {
|
||||
if (!this.thread.stackClick || block.next) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return {
|
||||
kind: 'visualReport',
|
||||
input: this.descendInput(block)
|
||||
};
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} topBlockId The ID of the top block of the script.
|
||||
* @returns {IntermediateScript}
|
||||
|
||||
@@ -549,6 +549,26 @@ runtimeFunctions.tan = `const tan = (angle) => {
|
||||
return Math.round(Math.tan((Math.PI * angle) / 180) * 1e10) / 1e10;
|
||||
}`;
|
||||
|
||||
/**
|
||||
* @param {function} callback The function to run
|
||||
* @param {...unknown} args The arguments to pass to the function
|
||||
* @returns {unknown} A generator that will yield once then call the function and return its value.
|
||||
*/
|
||||
runtimeFunctions.yieldThenCall = `const yieldThenCall = function* (callback, ...args) {
|
||||
yield;
|
||||
return callback(...args);
|
||||
}`;
|
||||
|
||||
/**
|
||||
* @param {function} callback The generator function to run
|
||||
* @param {...unknown} args The arguments to pass to the generator function
|
||||
* @returns {unknown} A generator that will yield once then delegate to the generator function and return its value.
|
||||
*/
|
||||
runtimeFunctions.yieldThenCallGenerator = `const yieldThenCallGenerator = function* (callback, ...args) {
|
||||
yield;
|
||||
return yield* callback(...args);
|
||||
}`;
|
||||
|
||||
/**
|
||||
* Step a compiled thread.
|
||||
* @param {Thread} thread The thread to step.
|
||||
|
||||
+78
-30
@@ -428,6 +428,9 @@ class JSGenerator {
|
||||
*/
|
||||
descendInput (node) {
|
||||
switch (node.kind) {
|
||||
case 'addons.call':
|
||||
return new TypedInput(`(${this.descendAddonCall(node)})`, TYPE_UNKNOWN);
|
||||
|
||||
case 'args.boolean':
|
||||
return new TypedInput(`toBoolean(p${node.index})`, TYPE_BOOLEAN);
|
||||
case 'args.stringNumber':
|
||||
@@ -623,6 +626,37 @@ class JSGenerator {
|
||||
case 'op.10^':
|
||||
return new TypedInput(`(10 ** ${this.descendInput(node.value).asNumber()})`, TYPE_NUMBER);
|
||||
|
||||
case 'procedures.call': {
|
||||
const procedureCode = node.code;
|
||||
const procedureVariant = node.variant;
|
||||
const procedureData = this.ir.procedures[procedureVariant];
|
||||
if (procedureData.stack === null) {
|
||||
// TODO still need to evaluate arguments for side effects
|
||||
return new TypedInput('""', TYPE_STRING);
|
||||
}
|
||||
|
||||
// Recursion makes this complicated because:
|
||||
// - We need to yield *between* each call in the same command block
|
||||
// - We need to evaluate arguments *before* that yield happens
|
||||
|
||||
const procedureReference = `thread.procedures["${sanitize(procedureVariant)}"]`;
|
||||
const args = [];
|
||||
for (const input of node.arguments) {
|
||||
args.push(this.descendInput(input).asSafe());
|
||||
}
|
||||
const joinedArgs = args.join(',');
|
||||
|
||||
const yieldForRecursion = !this.isWarp && procedureCode === this.script.procedureCode;
|
||||
if (yieldForRecursion) {
|
||||
const runtimeFunction = procedureData.yields ? 'yieldThenCallGenerator' : 'yieldThenCall';
|
||||
return new TypedInput(`(yield* ${runtimeFunction}(${procedureReference}, ${joinedArgs}))`, TYPE_UNKNOWN);
|
||||
}
|
||||
if (procedureData.yields) {
|
||||
return new TypedInput(`(yield* ${procedureReference}(${joinedArgs}))`, TYPE_UNKNOWN);
|
||||
}
|
||||
return new TypedInput(`${procedureReference}(${joinedArgs})`, TYPE_UNKNOWN);
|
||||
}
|
||||
|
||||
case 'sensing.answer':
|
||||
return new TypedInput(`runtime.ext_scratch3_sensing._answer`, TYPE_STRING);
|
||||
case 'sensing.colorTouchingColor':
|
||||
@@ -713,13 +747,9 @@ class JSGenerator {
|
||||
*/
|
||||
descendStackedBlock (node) {
|
||||
switch (node.kind) {
|
||||
case 'addons.call': {
|
||||
const inputs = this.descendInputRecord(node.arguments);
|
||||
const blockFunction = `runtime.getAddonBlock("${sanitize(node.code)}").callback`;
|
||||
const blockId = `"${sanitize(node.blockId)}"`;
|
||||
this.source += `yield* executeInCompatibilityLayer(${inputs}, ${blockFunction}, ${this.isWarp}, false, ${blockId});\n`;
|
||||
case 'addons.call':
|
||||
this.source += `${this.descendAddonCall(node)};\n`;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'compat': {
|
||||
// If the last command in a loop returns a promise, immediately continue to the next iteration.
|
||||
@@ -781,11 +811,7 @@ class JSGenerator {
|
||||
this.source += 'runtime.stopForTarget(target, thread);\n';
|
||||
break;
|
||||
case 'control.stopScript':
|
||||
if (this.isProcedure) {
|
||||
this.source += 'return;\n';
|
||||
} else {
|
||||
this.retire();
|
||||
}
|
||||
this.stopScript();
|
||||
break;
|
||||
case 'control.wait': {
|
||||
const duration = this.localVariables.next();
|
||||
@@ -1016,35 +1042,34 @@ class JSGenerator {
|
||||
case 'procedures.call': {
|
||||
const procedureCode = node.code;
|
||||
const procedureVariant = node.variant;
|
||||
// Do not generate any code for empty procedures.
|
||||
const procedureData = this.ir.procedures[procedureVariant];
|
||||
if (procedureData.stack === null) {
|
||||
// TODO still need to evaluate arguments
|
||||
break;
|
||||
}
|
||||
if (!this.isWarp && procedureCode === this.script.procedureCode) {
|
||||
// Direct recursion yields.
|
||||
|
||||
const yieldForRecursion = !this.isWarp && procedureCode === this.script.procedureCode;
|
||||
if (yieldForRecursion) {
|
||||
this.yieldNotWarp();
|
||||
}
|
||||
|
||||
if (procedureData.yields) {
|
||||
this.source += 'yield* ';
|
||||
if (!this.script.yields) {
|
||||
throw new Error('Script uses yielding procedure but is not marked as yielding.');
|
||||
}
|
||||
}
|
||||
this.source += `thread.procedures["${sanitize(procedureVariant)}"](`;
|
||||
// Only include arguments if the procedure accepts any.
|
||||
if (procedureData.arguments.length) {
|
||||
const args = [];
|
||||
for (const input of node.arguments) {
|
||||
args.push(this.descendInput(input).asSafe());
|
||||
}
|
||||
this.source += args.join(',');
|
||||
const args = [];
|
||||
for (const input of node.arguments) {
|
||||
args.push(this.descendInput(input).asSafe());
|
||||
}
|
||||
this.source += `);\n`;
|
||||
// Variable input types may have changes after a procedure call.
|
||||
this.source += args.join(',');
|
||||
this.source += ');\n';
|
||||
|
||||
this.resetVariableInputs();
|
||||
break;
|
||||
}
|
||||
case 'procedures.return':
|
||||
this.stopScriptAndReturn(this.descendInput(node.value).asSafe());
|
||||
break;
|
||||
|
||||
case 'timer.reset':
|
||||
this.source += 'runtime.ioDevices.clock.resetProjectTimer();\n';
|
||||
@@ -1137,6 +1162,13 @@ class JSGenerator {
|
||||
return this.evaluateOnce(`stage.variables["${sanitize(variable.id)}"]`);
|
||||
}
|
||||
|
||||
descendAddonCall (node) {
|
||||
const inputs = this.descendInputRecord(node.arguments);
|
||||
const blockFunction = `runtime.getAddonBlock("${sanitize(node.code)}").callback`;
|
||||
const blockId = `"${sanitize(node.blockId)}"`;
|
||||
return `yield* executeInCompatibilityLayer(${inputs}, ${blockFunction}, ${this.isWarp}, false, ${blockId})`;
|
||||
}
|
||||
|
||||
evaluateOnce (source) {
|
||||
if (this._setupVariables.hasOwnProperty(source)) {
|
||||
return this._setupVariables[source];
|
||||
@@ -1157,6 +1189,25 @@ class JSGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
stopScript () {
|
||||
if (this.isProcedure) {
|
||||
this.source += 'return "";\n';
|
||||
} else {
|
||||
this.retire();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} valueJS JS code of value to return.
|
||||
*/
|
||||
stopScriptAndReturn (valueJS) {
|
||||
if (this.isProcedure) {
|
||||
this.source += `return ${valueJS};\n`;
|
||||
} else {
|
||||
this.retire();
|
||||
}
|
||||
}
|
||||
|
||||
yieldLoop () {
|
||||
if (this.warpTimer) {
|
||||
this.yieldStuckOrNotWarp();
|
||||
@@ -1286,10 +1337,6 @@ class JSGenerator {
|
||||
|
||||
script += this.source;
|
||||
|
||||
if (!this.isProcedure) {
|
||||
script += 'retire();\n';
|
||||
}
|
||||
|
||||
script += '}; })';
|
||||
|
||||
return script;
|
||||
@@ -1303,6 +1350,7 @@ class JSGenerator {
|
||||
if (this.script.stack) {
|
||||
this.descendStack(this.script.stack, new Frame(false));
|
||||
}
|
||||
this.stopScript();
|
||||
|
||||
const factory = this.createScriptFactory();
|
||||
const fn = jsexecute.scopedEval(factory);
|
||||
|
||||
@@ -490,6 +490,7 @@ const execute = function (sequencer, thread) {
|
||||
|
||||
currentStackFrame.reporting = null;
|
||||
currentStackFrame.reported = null;
|
||||
currentStackFrame.waitingReporter = false;
|
||||
}
|
||||
|
||||
const start = i;
|
||||
@@ -497,6 +498,7 @@ const execute = function (sequencer, thread) {
|
||||
for (; i < length; i++) {
|
||||
const lastOperation = i === length - 1;
|
||||
const opCached = ops[i];
|
||||
currentStackFrame.op = opCached;
|
||||
|
||||
const blockFunction = opCached._blockFunction;
|
||||
|
||||
@@ -517,9 +519,11 @@ const execute = function (sequencer, thread) {
|
||||
|
||||
const primitiveReportedValue = blockFunction(argValues, blockUtility);
|
||||
|
||||
// If it's a promise, wait until promise resolves.
|
||||
if (isPromise(primitiveReportedValue)) {
|
||||
handlePromise(primitiveReportedValue, sequencer, thread, opCached, lastOperation);
|
||||
const primitiveIsPromise = isPromise(primitiveReportedValue);
|
||||
if (primitiveIsPromise || currentStackFrame.waitingReporter) {
|
||||
if (primitiveIsPromise) {
|
||||
handlePromise(primitiveReportedValue, sequencer, thread, opCached, lastOperation);
|
||||
}
|
||||
|
||||
// Store the already reported values. They will be thawed into the
|
||||
// future versions of the same operations by block id. The reporting
|
||||
@@ -543,7 +547,7 @@ const execute = function (sequencer, thread) {
|
||||
};
|
||||
});
|
||||
|
||||
// We are waiting for a promise. Stop running this set of operations
|
||||
// We are waiting to be resumed later. Stop running this set of operations
|
||||
// and continue them later after thawing the reported values.
|
||||
break;
|
||||
} else if (thread.status === Thread.STATUS_RUNNING) {
|
||||
|
||||
@@ -2587,14 +2587,17 @@ class Runtime extends EventEmitter {
|
||||
* @param {object} options Options object
|
||||
* @param {string} options.procedureCode The ID of the block
|
||||
* @param {function} options.callback The callback, called with (args, BlockUtility). May return a promise.
|
||||
* @param {string[]} options.arguments Names of the arguments accepted
|
||||
* @param {boolean} [hidden] True to not include this block in the block palette
|
||||
* @param {string[]} [options.arguments] Names of the arguments accepted. Optional if no arguments.
|
||||
* @param {boolean} [options.hidden] True to not include this block in the block palette
|
||||
* @param {1|2} [options.return] 1 for round reporter, 2 for boolean reported, leave empty for statement.
|
||||
*/
|
||||
addAddonBlock (options) {
|
||||
const procedureCode = options.procedureCode;
|
||||
const names = options.arguments;
|
||||
const ids = options.arguments.map((_, i) => `arg${i}`);
|
||||
const defaults = options.arguments.map(() => '');
|
||||
|
||||
const argumentNames = options.arguments || [];
|
||||
const names = argumentNames;
|
||||
const ids = argumentNames.map((_, i) => `arg${i}`);
|
||||
const defaults = argumentNames.map(() => '');
|
||||
this.addonBlocks[procedureCode] = {
|
||||
namesIdsDefaults: [names, ids, defaults],
|
||||
...options
|
||||
@@ -2631,6 +2634,7 @@ class Runtime extends EventEmitter {
|
||||
` argumentnames="${xmlEscape(JSON.stringify(names))}"` +
|
||||
` argumentids="${xmlEscape(JSON.stringify(ids))}"` +
|
||||
` argumentdefaults="${xmlEscape(JSON.stringify(defaults))}"` +
|
||||
`${options.return ? ` return="${xmlEscape(options.return.toString())}"` : ''}` +
|
||||
'></mutation></block>'
|
||||
});
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ class Sequencer {
|
||||
return;
|
||||
}
|
||||
// If no control flow has happened, switch to next block.
|
||||
if (thread.peekStack() === currentBlockId) {
|
||||
if (thread.peekStack() === currentBlockId && !thread.peekStackFrame().waitingReporter) {
|
||||
thread.goToNextBlock();
|
||||
}
|
||||
// If no next block has been found at this point, look on the stack.
|
||||
@@ -274,7 +274,7 @@ class Sequencer {
|
||||
// This level of the stack was waiting for a value.
|
||||
// This means a reporter has just returned - so don't go
|
||||
// to the next block for this level of the stack.
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
// Get next block of existing block on the stack.
|
||||
thread.goToNextBlock();
|
||||
|
||||
+14
-3
@@ -63,6 +63,13 @@ class _StackFrame {
|
||||
* @type {Object}
|
||||
*/
|
||||
this.executionContext = null;
|
||||
|
||||
/**
|
||||
* Internal block object being executed. This is *not* the same as the object found
|
||||
* in target.blocks.
|
||||
* @type {object}
|
||||
*/
|
||||
this.op = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,6 +86,7 @@ class _StackFrame {
|
||||
this.waitingReporter = null;
|
||||
this.params = null;
|
||||
this.executionContext = null;
|
||||
this.op = null;
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -307,7 +315,10 @@ class Thread {
|
||||
let blockID = this.peekStack();
|
||||
while (blockID !== null) {
|
||||
const block = this.target.blocks.getBlock(blockID);
|
||||
if (typeof block !== 'undefined' && block.opcode === 'procedures_call') {
|
||||
if (
|
||||
(typeof block !== 'undefined' && block.opcode === 'procedures_call') ||
|
||||
this.peekStackFrame().waitingReporter
|
||||
) {
|
||||
break;
|
||||
}
|
||||
this.popStack();
|
||||
@@ -426,9 +437,9 @@ class Thread {
|
||||
*/
|
||||
isRecursiveCall (procedureCode) {
|
||||
let callCount = 5; // Max number of enclosing procedure calls to examine.
|
||||
const sp = this.stack.length - 1;
|
||||
const sp = this.stackFrames.length - 1;
|
||||
for (let i = sp - 1; i >= 0; i--) {
|
||||
const block = this.target.blocks.getBlock(this.stack[i]);
|
||||
const block = this.target.blocks.getBlock(this.stackFrames[i].op.id);
|
||||
if (block.opcode === 'procedures_call' &&
|
||||
block.mutation.proccode === procedureCode) {
|
||||
return true;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
+251
-116
@@ -2,145 +2,269 @@ const tap = require('tap');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const VirtualMachine = require('../../src/virtual-machine');
|
||||
const Thread = require('../../src/engine/thread');
|
||||
|
||||
const fixtureData = fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'tw-addon-blocks.sb3'));
|
||||
|
||||
const runExecutionTests = compilerEnabled => async test => {
|
||||
const runExecutionTests = compilerEnabled => test => {
|
||||
const load = async () => {
|
||||
const vm = new VirtualMachine();
|
||||
vm.setCompilerOptions({
|
||||
enabled: compilerEnabled
|
||||
});
|
||||
vm.on('COMPILE_ERROR', (target, error) => {
|
||||
test.fail(`Compile error in ${target.getName()}: ${error}`);
|
||||
});
|
||||
await vm.loadProject(fixtureData);
|
||||
vm.on('COMPILE_ERROR', (target, error) => test.fail(`Compile error ${target.getName()} ${error}`));
|
||||
return vm;
|
||||
};
|
||||
|
||||
const getOutput = vm => vm.runtime.getTargetForStage().lookupVariableByNameAndType('output').value;
|
||||
const getVar = (vm, variableName) => {
|
||||
const variable = vm.runtime.getTargetForStage().lookupVariableByNameAndType(variableName, '');
|
||||
return variable.value;
|
||||
};
|
||||
|
||||
await test.test('simple use', async t => {
|
||||
t.plan(7);
|
||||
test.test('baseline - no addon blocks', t => {
|
||||
load().then(vm => {
|
||||
t.equal(getVar(vm, 'block 1'), 'initial');
|
||||
t.equal(getVar(vm, 'block 2'), 'initial');
|
||||
t.equal(getVar(vm, 'block 3'), 'initial');
|
||||
t.equal(getVar(vm, 'block 4'), 'initial');
|
||||
t.equal(getVar(vm, 'block 4 output'), 'initial');
|
||||
|
||||
const vm = await load();
|
||||
|
||||
let calledBlock1 = false;
|
||||
let calledBlock2 = false;
|
||||
|
||||
vm.addAddonBlock({
|
||||
procedureCode: 'block 2 %s',
|
||||
callback: (args, util) => {
|
||||
calledBlock1 = true;
|
||||
t.type(util.thread, 'object');
|
||||
// may have to update this ID when the project changes to match whatever the ID is for the
|
||||
// procedures_call block to block 2 %s
|
||||
t.equal(util.thread.peekStack(), 'c');
|
||||
t.same(args, {
|
||||
'number or text': 'banana'
|
||||
});
|
||||
},
|
||||
arguments: ['number or text']
|
||||
});
|
||||
|
||||
vm.addAddonBlock({
|
||||
procedureCode: 'block 3',
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
callback: (args, util) => {
|
||||
calledBlock2 = true;
|
||||
t.same(args, {});
|
||||
},
|
||||
arguments: []
|
||||
});
|
||||
|
||||
vm.greenFlag();
|
||||
vm.runtime._step();
|
||||
|
||||
t.equal(getOutput(vm), 'block 1 value');
|
||||
t.ok(calledBlock1);
|
||||
t.ok(calledBlock2);
|
||||
t.end();
|
||||
});
|
||||
|
||||
await test.test('yield by thread.status = STATUS_PROMISE_WAIT', async t => {
|
||||
const vm = await load();
|
||||
|
||||
let threadToResume;
|
||||
|
||||
vm.addAddonBlock({
|
||||
procedureCode: 'block 1',
|
||||
callback: (args, util) => {
|
||||
util.thread.status = 1; // STATUS_PROMISE_WAIT
|
||||
threadToResume = util.thread;
|
||||
},
|
||||
arguments: []
|
||||
});
|
||||
|
||||
vm.greenFlag();
|
||||
vm.runtime._step();
|
||||
if (!threadToResume) {
|
||||
t.fail('did not run addon block');
|
||||
}
|
||||
|
||||
t.equal(getOutput(vm), 'initial value');
|
||||
threadToResume.status = 0; // STATUS_RUNNING
|
||||
vm.runtime._step();
|
||||
t.equal(getOutput(vm), 'block 3 value');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
await test.test('yield by block utility methods', async t => {
|
||||
const vm = await load();
|
||||
|
||||
let shouldYield = true;
|
||||
|
||||
vm.addAddonBlock({
|
||||
procedureCode: 'block 1',
|
||||
callback: (args, util) => {
|
||||
if (shouldYield) {
|
||||
util.runtime.requestRedraw();
|
||||
util.yield();
|
||||
}
|
||||
},
|
||||
arguments: []
|
||||
});
|
||||
|
||||
vm.greenFlag();
|
||||
for (let i = 0; i < 10; i++) {
|
||||
vm.greenFlag();
|
||||
vm.runtime._step();
|
||||
}
|
||||
t.equal(getOutput(vm), 'initial value');
|
||||
|
||||
shouldYield = false;
|
||||
vm.runtime._step();
|
||||
t.equal(getOutput(vm), 'block 3 value');
|
||||
t.equal(getVar(vm, 'block 1'), 'block 1 ran');
|
||||
t.equal(getVar(vm, 'block 2'), 'block 2: banana');
|
||||
t.equal(getVar(vm, 'block 3'), 'block 3 ran');
|
||||
t.equal(getVar(vm, 'block 4'), 'block 4 ran');
|
||||
t.equal(getVar(vm, 'block 4 output'), 'block 4: apple');
|
||||
|
||||
t.end();
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
await test.test('yield by returning Promise', async t => {
|
||||
const vm = await load();
|
||||
test.test('simple statement blocks', t => {
|
||||
load().then(vm => {
|
||||
t.plan(9);
|
||||
|
||||
let resolveCallback;
|
||||
vm.addAddonBlock({
|
||||
procedureCode: 'block 1',
|
||||
callback: () => new Promise(resolve => {
|
||||
resolveCallback = resolve;
|
||||
}),
|
||||
arguments: []
|
||||
let calledBlock1 = false;
|
||||
let calledBlock2 = false;
|
||||
|
||||
vm.addAddonBlock({
|
||||
procedureCode: 'block 1',
|
||||
callback: (args, util) => {
|
||||
calledBlock1 = true;
|
||||
t.same(args, {});
|
||||
t.ok(util.thread instanceof Thread);
|
||||
// may have to update when project changes
|
||||
t.equal(util.thread.peekStack(), 'd');
|
||||
}
|
||||
});
|
||||
|
||||
vm.addAddonBlock({
|
||||
procedureCode: 'block 2 %s',
|
||||
arguments: ['number or text'],
|
||||
callback: (args, util) => {
|
||||
calledBlock2 = true;
|
||||
t.same(args, {
|
||||
'number or text': 'banana'
|
||||
});
|
||||
// may have to update when project changes
|
||||
t.equal(util.thread.peekStack(), 'c');
|
||||
}
|
||||
});
|
||||
|
||||
vm.greenFlag();
|
||||
vm.runtime._step();
|
||||
|
||||
t.ok(calledBlock1);
|
||||
t.ok(calledBlock2);
|
||||
|
||||
// Overridden blocks should not run
|
||||
t.equal(getVar(vm, 'block 1'), 'false');
|
||||
t.equal(getVar(vm, 'block 2'), 'false');
|
||||
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
vm.greenFlag();
|
||||
vm.runtime._step();
|
||||
t.equal(getOutput(vm), 'initial value');
|
||||
test.test('yield with thread.status = STATUS_PROMISE_WAIT', t => {
|
||||
load().then(vm => {
|
||||
t.plan(7);
|
||||
|
||||
resolveCallback();
|
||||
// Allow the promise callback to run
|
||||
await Promise.resolve();
|
||||
let threadToResume;
|
||||
let ranBlock3 = false;
|
||||
vm.addAddonBlock({
|
||||
procedureCode: 'block 3',
|
||||
callback: (args, util) => {
|
||||
ranBlock3 = true;
|
||||
util.thread.status = Thread.STATUS_PROMISE_WAIT;
|
||||
threadToResume = util.thread;
|
||||
},
|
||||
arguments: []
|
||||
});
|
||||
|
||||
vm.runtime._step();
|
||||
t.equal(getOutput(vm), 'block 3 value');
|
||||
vm.greenFlag();
|
||||
vm.runtime._step();
|
||||
|
||||
t.end();
|
||||
// Make sure we paused it
|
||||
t.ok(ranBlock3);
|
||||
t.equal(threadToResume.status, Thread.STATUS_PROMISE_WAIT);
|
||||
|
||||
// Should've stopped after block 2
|
||||
t.equal(getVar(vm, 'block 2'), 'block 2: banana');
|
||||
t.equal(getVar(vm, 'block 3'), 'false');
|
||||
t.equal(getVar(vm, 'block 4'), 'false');
|
||||
|
||||
threadToResume.status = Thread.STATUS_RUNNING;
|
||||
vm.runtime._step();
|
||||
|
||||
// Should've finished running
|
||||
t.equal(getVar(vm, 'block 3'), 'false'); // overridden, should not run
|
||||
t.equal(getVar(vm, 'block 4'), 'block 4 ran');
|
||||
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test.test('yield with util.yield()', t => {
|
||||
load().then(vm => {
|
||||
t.plan(10);
|
||||
|
||||
let shouldYield = true;
|
||||
let calledBlock1 = 0;
|
||||
|
||||
vm.addAddonBlock({
|
||||
procedureCode: 'block 1',
|
||||
callback: (args, util) => {
|
||||
calledBlock1++;
|
||||
|
||||
if (shouldYield) {
|
||||
util.runtime.requestRedraw();
|
||||
util.yield();
|
||||
}
|
||||
},
|
||||
arguments: []
|
||||
});
|
||||
|
||||
vm.greenFlag();
|
||||
for (let i = 0; i < 10; i++) {
|
||||
vm.runtime._step();
|
||||
}
|
||||
|
||||
t.equal(calledBlock1, 10);
|
||||
t.equal(getVar(vm, 'block 1'), 'false');
|
||||
t.equal(getVar(vm, 'block 2'), 'false');
|
||||
t.equal(getVar(vm, 'block 3'), 'false');
|
||||
t.equal(getVar(vm, 'block 4'), 'false');
|
||||
|
||||
shouldYield = false;
|
||||
vm.runtime._step();
|
||||
|
||||
t.equal(calledBlock1, 11);
|
||||
t.equal(getVar(vm, 'block 1'), 'false'); // overrridden, should not run
|
||||
t.equal(getVar(vm, 'block 2'), 'block 2: banana');
|
||||
t.equal(getVar(vm, 'block 3'), 'block 3 ran');
|
||||
t.equal(getVar(vm, 'block 4'), 'block 4 ran');
|
||||
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test.test('yield with resolved Promise', t => {
|
||||
load().then(vm => {
|
||||
let resolveCallback;
|
||||
vm.addAddonBlock({
|
||||
procedureCode: 'block 2 %s',
|
||||
arguments: ['number or text'],
|
||||
callback: () => new Promise(resolve => {
|
||||
resolveCallback = resolve;
|
||||
})
|
||||
});
|
||||
|
||||
vm.greenFlag();
|
||||
for (let i = 0; i < 5; i++) {
|
||||
vm.runtime._step();
|
||||
}
|
||||
|
||||
t.type(resolveCallback, 'function');
|
||||
t.equal(getVar(vm, 'block 1'), 'block 1 ran');
|
||||
t.equal(getVar(vm, 'block 2'), 'false');
|
||||
t.equal(getVar(vm, 'block 3'), 'false');
|
||||
t.equal(getVar(vm, 'block 4'), 'false');
|
||||
|
||||
resolveCallback();
|
||||
Promise.resolve().then(() => {
|
||||
vm.runtime._step();
|
||||
t.equal(getVar(vm, 'block 2'), 'false'); // overridden, should not run
|
||||
t.equal(getVar(vm, 'block 3'), 'block 3 ran');
|
||||
t.equal(getVar(vm, 'block 4'), 'block 4 ran');
|
||||
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.skip('yield with resolved Promise', t => {
|
||||
load().then(vm => {
|
||||
let rejectCallback;
|
||||
vm.addAddonBlock({
|
||||
procedureCode: 'block 2 %s',
|
||||
arguments: ['number or text'],
|
||||
callback: () => new Promise((resolve, reject) => {
|
||||
rejectCallback = reject;
|
||||
})
|
||||
});
|
||||
|
||||
vm.greenFlag();
|
||||
for (let i = 0; i < 5; i++) {
|
||||
vm.runtime._step();
|
||||
}
|
||||
|
||||
t.type(rejectCallback, 'function');
|
||||
t.equal(getVar(vm, 'block 1'), 'block 1 ran');
|
||||
t.equal(getVar(vm, 'block 2'), 'false');
|
||||
t.equal(getVar(vm, 'block 3'), 'false');
|
||||
t.equal(getVar(vm, 'block 4'), 'false');
|
||||
|
||||
rejectCallback(new Error('Intentional error for testing'));
|
||||
Promise.resolve().then(() => {
|
||||
vm.runtime._step();
|
||||
t.equal(getVar(vm, 'block 2'), 'false'); // overridden, should not run
|
||||
t.equal(getVar(vm, 'block 3'), 'block 3 ran');
|
||||
t.equal(getVar(vm, 'block 4'), 'block 4 ran');
|
||||
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.test('returning values', t => {
|
||||
load().then(vm => {
|
||||
vm.addAddonBlock({
|
||||
procedureCode: 'block 4 %s',
|
||||
callback: args => {
|
||||
t.same(args, {
|
||||
'number or text': 'apple'
|
||||
});
|
||||
return `value from addon block: ${args['number or text']}`;
|
||||
},
|
||||
arguments: ['number or text']
|
||||
});
|
||||
|
||||
vm.greenFlag();
|
||||
vm.runtime._step();
|
||||
|
||||
t.equal(getVar(vm, 'block 1'), 'block 1 ran');
|
||||
t.equal(getVar(vm, 'block 2'), 'block 2: banana');
|
||||
t.equal(getVar(vm, 'block 3'), 'block 3 ran');
|
||||
t.equal(getVar(vm, 'block 4'), 'false'); // block 4 itself should not have run, we overrode it
|
||||
t.equal(getVar(vm, 'block 4 output'), 'value from addon block: apple');
|
||||
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test.end();
|
||||
@@ -165,10 +289,16 @@ tap.test('block info', t => {
|
||||
t.equal(blockInfo, undefined);
|
||||
|
||||
vm.addAddonBlock({
|
||||
procedureCode: 'something %s',
|
||||
procedureCode: 'statement %s',
|
||||
arguments: ['number or text'],
|
||||
callback: () => {}
|
||||
});
|
||||
vm.addAddonBlock({
|
||||
procedureCode: 'input %s',
|
||||
arguments: ['an argument'],
|
||||
callback: () => {},
|
||||
return: 1
|
||||
});
|
||||
|
||||
blockInfo = vm.runtime._blockInfo.find(i => i.id === BLOCK_INFO_ID);
|
||||
t.type(blockInfo.id, 'string');
|
||||
@@ -180,7 +310,12 @@ tap.test('block info', t => {
|
||||
{
|
||||
info: {},
|
||||
// eslint-disable-next-line max-len
|
||||
xml: '<block type="procedures_call" gap="16"><mutation generateshadows="true" warp="false" proccode="something %s" argumentnames="["number or text"]" argumentids="["arg0"]" argumentdefaults="[""]"></mutation></block>'
|
||||
xml: '<block type="procedures_call" gap="16"><mutation generateshadows="true" warp="false" proccode="statement %s" argumentnames="["number or text"]" argumentids="["arg0"]" argumentdefaults="[""]"></mutation></block>'
|
||||
},
|
||||
{
|
||||
info: {},
|
||||
// eslint-disable-next-line max-len
|
||||
xml: '<block type="procedures_call" gap="16"><mutation generateshadows="true" warp="false" proccode="input %s" argumentnames="["an argument"]" argumentids="["arg0"]" argumentdefaults="[""]" return="1"></mutation></block>'
|
||||
}
|
||||
]);
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const {test} = require('tap');
|
||||
const VirtualMachine = require('../../src/virtual-machine');
|
||||
|
||||
const projectPath = path.join(__dirname, '..', 'fixtures', 'tw-stackframe-op.sb3');
|
||||
|
||||
test('util.thread.peekStackFrame().op', t => {
|
||||
const vm = new VirtualMachine();
|
||||
|
||||
vm.runtime.setCompilerOptions({
|
||||
enabled: false
|
||||
});
|
||||
|
||||
// Easiest way to test this is to overwrite an existing block
|
||||
vm.runtime._primitives.operator_add = function (args, util) {
|
||||
const op = util.thread.peekStackFrame().op;
|
||||
t.equal(op.id, 'c');
|
||||
t.end();
|
||||
|
||||
// return value not used
|
||||
return 4;
|
||||
};
|
||||
|
||||
vm.loadProject(fs.readFileSync(projectPath)).then(() => {
|
||||
vm.greenFlag();
|
||||
vm.runtime._step();
|
||||
});
|
||||
});
|
||||
@@ -22,7 +22,7 @@ yield* executeInCompatibilityLayer({"MESSAGE":"pass order is correct (1)",}, b2,
|
||||
} else {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":("fail order is incorrect 1 != " + ("" + b0.value)),}, b2, false, false, null);
|
||||
}
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite3 script
|
||||
@@ -56,7 +56,7 @@ yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -80,5 +80,5 @@ yield* executeInCompatibilityLayer({"MESSAGE":"pass order is correct (2)",}, b2,
|
||||
} else {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":("fail order is incorrect 2 != " + ("" + b0.value)),}, b2, false, false, null);
|
||||
}
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -32,7 +32,7 @@ yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -56,7 +56,7 @@ yield* executeInCompatibilityLayer({"MESSAGE":"pass order is correct (1)",}, b2,
|
||||
} else {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":("fail order is incorrect 1 != " + ("" + b0.value)),}, b2, false, false, null);
|
||||
}
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite2 script
|
||||
@@ -80,5 +80,5 @@ yield* executeInCompatibilityLayer({"MESSAGE":"pass order is correct (2)",}, b2,
|
||||
} else {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":("fail order is incorrect 2 != " + ("" + b0.value)),}, b2, false, false, null);
|
||||
}
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -67,5 +67,5 @@ if (compareEqual(((runtime.ext_scratch3_operators._random((-1 / 0), (1 / 0)) ||
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -10,5 +10,5 @@ if (!((Infinity + -Infinity) <= 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -10,5 +10,5 @@ if (true) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -6,7 +6,7 @@
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -16,5 +16,5 @@ return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 1",}, b0, false, false, null);
|
||||
yield* waitThreads(startHats("event_whenbroadcastreceived", { BROADCAST_OPTION: "message1" }));
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+1
-1
@@ -18,5 +18,5 @@ if (((+b1.value || 0) === 20)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -12,5 +12,5 @@ if ((("" + b1.value).toLowerCase() === "#22388a".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -1771,5 +1771,5 @@ if (!(("" + compareGreaterThan("", "")).toLowerCase() === "false".toLowerCase())
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"fail 588: should be > ",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -8,7 +8,7 @@ return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 0",}, b0, false, false, null);
|
||||
yield* thread.procedures["Wrun test"]();
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 run test
|
||||
@@ -43,6 +43,7 @@ if (hasResumedFromPromise) {hasResumedFromPromise = false;continue;}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 setup values
|
||||
@@ -126,4 +127,5 @@ b0.value.push(" ");
|
||||
b0._monitorUpToDate = false;
|
||||
b0.value.push("🎉");
|
||||
b0._monitorUpToDate = false;
|
||||
return "";
|
||||
}; })
|
||||
@@ -32,5 +32,5 @@ if ((limitPrecision(target.x) === 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass x slightly below 0 rounds",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+1
-1
@@ -19,5 +19,5 @@ if (compareLessThan(("something".toLowerCase() === "else".toLowerCase()), (1 + 0
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -24,5 +24,5 @@ if ((target.direction === 90)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass 4",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+1
-1
@@ -28,5 +28,5 @@ if ((("" + b1.value).toLowerCase().indexOf(".".toLowerCase()) !== -1)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+1
-1
@@ -19,5 +19,5 @@ if (((+(b2.value[(1 | 0) - 1] ?? "") || 0) === 3)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass list",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+5
-2
@@ -18,7 +18,7 @@ yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b2, false, false, null);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b2, false, false, null);
|
||||
runtime.stopAll();
|
||||
retire(); return;
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 no refresh
|
||||
@@ -38,12 +38,14 @@ yield* executeInCompatibilityLayer({"BEATS":0,}, b0, true, false, null);
|
||||
yield* executeInCompatibilityLayer({"DRUM":1,"BEATS":0,}, b1, true, false, null);
|
||||
runtime.ext_scratch3_motion._moveSteps(0, target);
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 runs below with no refresh
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function* genXYZ_runs_below_with_no_r () {
|
||||
yield* thread.procedures["Whas refresh"]();
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 has refresh
|
||||
@@ -63,6 +65,7 @@ yield* executeInCompatibilityLayer({"BEATS":0,}, b0, true, false, null);
|
||||
yield* executeInCompatibilityLayer({"DRUM":1,"BEATS":0,}, b1, true, false, null);
|
||||
runtime.ext_scratch3_motion._moveSteps(0, target);
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -73,5 +76,5 @@ while (true) {
|
||||
b0.value = ((+b0.value || 0) + 1);
|
||||
yield;
|
||||
}
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -34,5 +34,5 @@ if (compareEqual(listGet(b1.value, "*"), "")) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -29,5 +29,5 @@ yield* executeInCompatibilityLayer({"CHANGE":10,}, b9, false, false, null);
|
||||
yield* executeInCompatibilityLayer({}, b10, false, false, null);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -10,5 +10,5 @@ if ((((1 / -0) || 0) === -Infinity)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -23,5 +23,5 @@ yield;
|
||||
}
|
||||
b0.value = 1;
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b1, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+2
-1
@@ -8,7 +8,7 @@ return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 1",}, b0, false, false, null);
|
||||
yield* thread.procedures["ZSet Costume"]();
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Player Set Costume
|
||||
@@ -16,4 +16,5 @@ retire();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ_Set_Costume () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
return "";
|
||||
}; })
|
||||
@@ -9,7 +9,7 @@ yield* executeInCompatibilityLayer({"MESSAGE":"plan 2",}, b0, false, false, null
|
||||
yield* thread.procedures["Znumber or text %s %s"]("bad","ok");
|
||||
yield* thread.procedures["Zboolean %b %b"]("false",!false);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 number or text %s %s
|
||||
@@ -19,6 +19,7 @@ return function* genXYZ_number_or_text__ (p0,p1) {
|
||||
if ((("" + p1).toLowerCase() === "ok".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 boolean %b %b
|
||||
@@ -28,4 +29,5 @@ return function* genXYZ_boolean__ (p0,p1) {
|
||||
if (toBoolean(p1)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
+2
-1
@@ -13,7 +13,7 @@ if (!compareEqual(b1.value, "")) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 do something
|
||||
@@ -21,4 +21,5 @@ retire();
|
||||
const b0 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
return function funXYZ_do_something () {
|
||||
b0.value = "help";
|
||||
return "";
|
||||
}; })
|
||||
+1
-1
@@ -7,5 +7,5 @@ const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 0",}, b0, false, false, null);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -0,0 +1,54 @@
|
||||
// TW Snapshot
|
||||
// Input SHA-256: b9110339d39947f68168cbb129a20b23b7d4e607ffd5624bd67e096451f6a329
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
return function* genXYZ () {
|
||||
b0.value = 0;
|
||||
while (true) {
|
||||
b0.value = ((+b0.value || 0) + 1);
|
||||
thread.timer = timer();
|
||||
var a0 = Math.max(0, 1000 * -1);
|
||||
runtime.requestRedraw();
|
||||
yield;
|
||||
while (thread.timer.timeElapsed() < a0) {
|
||||
yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield;
|
||||
}
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
const b1 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 2",}, b0, false, false, null);
|
||||
b1.value = 0;
|
||||
if (compareEqual(thread.procedures["Zinvalid params - reporter"](), 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass invalid params reporter",}, b0, false, false, null);
|
||||
}
|
||||
if (compareEqual(thread.procedures["Zinvalid params - boolean"](), 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass invalid params boolean",}, b0, false, false, null);
|
||||
}
|
||||
runtime.stopForTarget(target, thread);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 invalid params - reporter
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_invalid_params___rep () {
|
||||
return 0;
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 invalid params - boolean
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_invalid_params___boo () {
|
||||
return 0;
|
||||
return "";
|
||||
}; })
|
||||
@@ -0,0 +1,146 @@
|
||||
// TW Snapshot
|
||||
// Input SHA-256: b1802636bbbd479dcf8634a525798c5b4dd9b0201cf6af6f5b4879455368c328
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
const b1 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
const b2 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 18",}, b0, false, false, null);
|
||||
b1.value = 0;
|
||||
b2.value = (yield* thread.procedures["Znon warp recursion should yield %s"](8));
|
||||
if (((+b1.value || 0) === 4)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass non warp recursion yields",}, b0, false, false, null);
|
||||
}
|
||||
b1.value = 0;
|
||||
b2.value = thread.procedures["Wwarp recursion should not yield %s"](8);
|
||||
if (((+b1.value || 0) === 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass warp recursion does not yield",}, b0, false, false, null);
|
||||
}
|
||||
b1.value = 0;
|
||||
b2.value = (yield* thread.procedures["Zfib %s"](7));
|
||||
if (((+b1.value || 0) === 20)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass non warp fib yielded",}, b0, false, false, null);
|
||||
}
|
||||
yield* thread.procedures["Zrecursing yields between each %s"]("initial");
|
||||
yield* thread.procedures["Zrecursing arguments eval order %s %s %s %s"]("initial","","","");
|
||||
runtime.stopForTarget(target, thread);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 non warp recursion should yield %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function* genXYZ_non_warp_recursion_s (p0) {
|
||||
if (compareGreaterThan(p0, 0)) {
|
||||
return (yield* yieldThenCallGenerator(thread.procedures["Znon warp recursion should yield %s"], ((+p0 || 0) - 1)));
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 warp recursion should not yield %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_warp_recursion_shoul (p0) {
|
||||
if (compareGreaterThan(p0, 0)) {
|
||||
return thread.procedures["Wwarp recursion should not yield %s"](((+p0 || 0) - 1));
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 fib %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function* genXYZ_fib_ (p0) {
|
||||
if (compareLessThan(p0, 2)) {
|
||||
return p0;
|
||||
} else {
|
||||
return ((+(yield* yieldThenCallGenerator(thread.procedures["Zfib %s"], ((+p0 || 0) - 1))) || 0) + (+(yield* yieldThenCallGenerator(thread.procedures["Zfib %s"], ((+p0 || 0) - 2))) || 0));
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 recursing yields between each %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
const b1 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
const b2 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ_recursing_yields_bet (p0) {
|
||||
if ((("" + p0).toLowerCase() === "initial".toLowerCase())) {
|
||||
b0.value = 0;
|
||||
b1.value = ((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 1)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 1)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 2)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 2)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 3)) || 0) + (+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 3)) || 0)) || 0)) || 0)) || 0)) || 0));
|
||||
if (((+b0.value || 0) === 3)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recursing between calls yields final",}, b2, false, false, null);
|
||||
} else {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"fail recursing between calls yields final",}, b2, false, false, null);
|
||||
}
|
||||
} else {
|
||||
if (compareEqual(b0.value, p0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":("pass recursing between calls yields " + ("" + p0)),}, b2, false, false, null);
|
||||
} else {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":("fail recursing between calls yields " + ("" + p0)),}, b2, false, false, null);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 recursing arguments eval order %s %s %s %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["4HH82mPlVMOONdl(Ot*7"];
|
||||
const b1 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
const b2 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
const b3 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ_recursing_arguments_ (p0,p1,p2,p3) {
|
||||
if ((("" + p0).toLowerCase() === "initial".toLowerCase())) {
|
||||
b0.value = [];
|
||||
b1.value = 0;
|
||||
b2.value = (yield* yieldThenCallGenerator(thread.procedures["Zrecursing arguments eval order %s %s %s %s"], "child 1",(yield* yieldThenCallGenerator(thread.procedures["Zrecursing arguments eval order %s %s %s %s"], "child 2",(yield* yieldThenCallGenerator(thread.procedures["Zrecursing arguments eval order %s %s %s %s"], "child 3",(yield* yieldThenCallGenerator(thread.procedures["Zrecursing arguments eval order %s %s %s %s"], "child 4","","","")),(yield* yieldThenCallGenerator(thread.procedures["Zrecursing arguments eval order %s %s %s %s"], "child 5","","","")),(yield* yieldThenCallGenerator(thread.procedures["Zrecursing arguments eval order %s %s %s %s"], "child 6","","","")))),"","")),"",(yield* yieldThenCallGenerator(thread.procedures["Zrecursing arguments eval order %s %s %s %s"], "child 7","","",""))));
|
||||
if ((("" + (b0.value[(1 | 0) - 1] ?? "")).toLowerCase() === "1/child 4".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - 1",}, b3, false, false, null);
|
||||
}
|
||||
if ((("" + (b0.value[(2 | 0) - 1] ?? "")).toLowerCase() === "1/child 5".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - 2",}, b3, false, false, null);
|
||||
}
|
||||
if ((("" + (b0.value[(3 | 0) - 1] ?? "")).toLowerCase() === "2/child 6".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - 3",}, b3, false, false, null);
|
||||
}
|
||||
if ((("" + (b0.value[(4 | 0) - 1] ?? "")).toLowerCase() === "2/child 3".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - 4",}, b3, false, false, null);
|
||||
}
|
||||
if ((("" + (b0.value[(5 | 0) - 1] ?? "")).toLowerCase() === "3/child 2".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - 5",}, b3, false, false, null);
|
||||
}
|
||||
if ((("" + (b0.value[(6 | 0) - 1] ?? "")).toLowerCase() === "3/child 7".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - 6",}, b3, false, false, null);
|
||||
}
|
||||
if ((("" + (b0.value[(7 | 0) - 1] ?? "")).toLowerCase() === "4/child 1".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - 7",}, b3, false, false, null);
|
||||
}
|
||||
if ((b0.value.length === 7)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - length is correct",}, b3, false, false, null);
|
||||
}
|
||||
} else {
|
||||
b0.value.push((("" + b1.value) + ("/" + ("" + p0))));
|
||||
b0._monitorUpToDate = false;
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
return function* genXYZ () {
|
||||
b0.value = 0;
|
||||
while (true) {
|
||||
b0.value = ((+b0.value || 0) + 1);
|
||||
thread.timer = timer();
|
||||
var a0 = Math.max(0, 1000 * -1);
|
||||
runtime.requestRedraw();
|
||||
yield;
|
||||
while (thread.timer.timeElapsed() < a0) {
|
||||
yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield;
|
||||
}
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -0,0 +1,111 @@
|
||||
// TW Snapshot
|
||||
// Input SHA-256: cd516553f3cbf4a41ae9a8bc1f5d06a3392d365226bccdfa294578314f18facb
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
const b1 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 8",}, b0, false, false, null);
|
||||
if ((("" + thread.procedures["Zsimplest"]()).toLowerCase() === "It works!".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass simplest",}, b0, false, false, null);
|
||||
}
|
||||
if ((("" + thread.procedures["Znesting 1"]()).toLowerCase() === "42-54".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass nesting1",}, b0, false, false, null);
|
||||
}
|
||||
if (((+thread.procedures["Wwarp fib %s"](12) || 0) === 144)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass fib 12",}, b0, false, false, null);
|
||||
}
|
||||
if (((+thread.procedures["Wfactorial %s"](12) || 0) === 479001600)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass factorial 12",}, b0, false, false, null);
|
||||
}
|
||||
b1.value = (yield* thread.procedures["Zno shadowing 1 %s %s"]("f","g"));
|
||||
if (compareEqual(b1.value, "")) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass default return value",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 simplest
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_simplest () {
|
||||
return "It works!";
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 nesting 1
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_nesting_1 () {
|
||||
thread.procedures["Znesting 2"]();
|
||||
return (("" + thread.procedures["Znesting 3 %s %s"](6,7)) + ("" + thread.procedures["Znesting 3 %s %s"](-1,54)));
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 warp fib %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_warp_fib_ (p0) {
|
||||
return thread.procedures["Wfib %s"](p0);
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 factorial %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_factorial_ (p0) {
|
||||
if (compareGreaterThan(p0, 1)) {
|
||||
return ((+p0 || 0) * (+thread.procedures["Wfactorial %s"](((+p0 || 0) - 1)) || 0));
|
||||
}
|
||||
return 1;
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 no shadowing 1 %s %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
const b1 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
return function* genXYZ_no_shadowing_1__ (p0,p1) {
|
||||
if (((("" + p0).toLowerCase() === "f".toLowerCase()) && (("" + p1).toLowerCase() === "g".toLowerCase()))) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass shadow check 1",}, b0, false, false, null);
|
||||
}
|
||||
b1.value = thread.procedures["Zno shadowing 2 %s %s"](1,2);
|
||||
if (((("" + p0).toLowerCase() === "f".toLowerCase()) && (("" + p1).toLowerCase() === "g".toLowerCase()))) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass shadow check 2",}, b0, false, false, null);
|
||||
}
|
||||
b1.value = thread.procedures["Zno shadowing 2 %s %s"](3,4);
|
||||
if (((("" + p0).toLowerCase() === "f".toLowerCase()) && (("" + p1).toLowerCase() === "g".toLowerCase()))) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass shadow check 3",}, b0, false, false, null);
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 nesting 2
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_nesting_2 () {
|
||||
return "discard nesting 2";
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 nesting 3 %s %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_nesting_3__ (p0,p1) {
|
||||
return ((+p0 || 0) * (+p1 || 0));
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 fib %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_fib_ (p0) {
|
||||
if (compareLessThan(p0, 2)) {
|
||||
return p0;
|
||||
} else {
|
||||
return ((+thread.procedures["Wfib %s"](((+p0 || 0) - 1)) || 0) + (+thread.procedures["Wfib %s"](((+p0 || 0) - 2)) || 0));
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 no shadowing 2 %s %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_no_shadowing_2__ (p0,p1) {
|
||||
return "discard shadow 2";
|
||||
return "";
|
||||
}; })
|
||||
@@ -0,0 +1,51 @@
|
||||
// TW Snapshot
|
||||
// Input SHA-256: 27368530b97e0ab5053bf4faf8fd116aa30cea34adcbd95fc6ddcf0a9d6d4976
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
const b1 = stage.variables["PsAI*C{QHI3*4?O8p#TM"];
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 2",}, b0, false, false, null);
|
||||
yield* thread.procedures["Wreturn stops the script immediately"]();
|
||||
if (((+b1.value || 0) === 25)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass return stopped the script immediately",}, b0, false, false, null);
|
||||
}
|
||||
yield* waitThreads(startHats("event_whenbroadcastreceived", { BROADCAST_OPTION: "Test return outside of custom block" }));
|
||||
if (((+b1.value || 0) === 18)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass return worked to stop outside of custom block",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 return stops the script immediately
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["PsAI*C{QHI3*4?O8p#TM"];
|
||||
const b1 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ_return_stops_the_scr () {
|
||||
b0.value = 0;
|
||||
for (var a0 = 100; a0 >= 0.5; a0--) {
|
||||
b0.value = ((+b0.value || 0) + 1);
|
||||
if (((b0.value || 0) === 25)) {
|
||||
return "stopped!";
|
||||
}
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"fail return did not stop the script immediately",}, b1, true, false, null);
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["PsAI*C{QHI3*4?O8p#TM"];
|
||||
return function* genXYZ () {
|
||||
b0.value = 0;
|
||||
while (true) {
|
||||
b0.value = ((+b0.value || 0) + 1);
|
||||
if (((b0.value || 0) === 18)) {
|
||||
retire(); return;
|
||||
}
|
||||
yield;
|
||||
}
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -0,0 +1,120 @@
|
||||
// TW Snapshot
|
||||
// Input SHA-256: e652f448fbf09a37afacb03afa9f3448cce43aef06439b58b44aeec73edb0438
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
return function* genXYZ () {
|
||||
b0.value = 0;
|
||||
while (true) {
|
||||
b0.value = ((+b0.value || 0) + 1);
|
||||
thread.timer = timer();
|
||||
var a0 = Math.max(0, 1000 * -1);
|
||||
runtime.requestRedraw();
|
||||
yield;
|
||||
while (thread.timer.timeElapsed() < a0) {
|
||||
yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield;
|
||||
}
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 3",}, b0, false, false, null);
|
||||
yield* thread.procedures["Znon warp"]();
|
||||
runtime.stopForTarget(target, thread);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 non warp
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
const b1 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ_non_warp () {
|
||||
b0.value = 0;
|
||||
for (var a0 = 5; a0 >= 0.5; a0--) {
|
||||
thread.timer = timer();
|
||||
var a1 = Math.max(0, 1000 * 0);
|
||||
runtime.requestRedraw();
|
||||
yield;
|
||||
while (thread.timer.timeElapsed() < a1) {
|
||||
yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield;
|
||||
}
|
||||
if (((+b0.value || 0) === 5)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass non warp 1",}, b1, false, false, null);
|
||||
}
|
||||
if ((("" + (yield* thread.procedures["Wverify runs warp %s"]((yield* thread.procedures["Zverify runs non warp %s"]((yield* thread.procedures["Wverify runs warp %s"]("abc"))))))).toLowerCase() === "warp: non warp: warp: abc".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass non warp and warp mix",}, b1, false, false, null);
|
||||
}
|
||||
b0.value = 0;
|
||||
for (var a2 = 5; a2 >= 0.5; a2--) {
|
||||
thread.timer = timer();
|
||||
var a3 = Math.max(0, 1000 * 0);
|
||||
runtime.requestRedraw();
|
||||
yield;
|
||||
while (thread.timer.timeElapsed() < a3) {
|
||||
yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield;
|
||||
}
|
||||
if (((+b0.value || 0) === 5)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass non warp 2",}, b1, false, false, null);
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 verify runs warp %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
const b1 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ_verify_runs_warp_ (p0) {
|
||||
b0.value = 0;
|
||||
for (var a0 = 5; a0 >= 0.5; a0--) {
|
||||
thread.timer = timer();
|
||||
var a1 = Math.max(0, 1000 * 0);
|
||||
runtime.requestRedraw();
|
||||
while (thread.timer.timeElapsed() < a1) {
|
||||
if (isStuck()) yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
}
|
||||
if (!compareEqual(b0.value, 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"fail did not run warp",}, b1, true, false, null);
|
||||
}
|
||||
return ("warp: " + ("" + p0));
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 verify runs non warp %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
const b1 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ_verify_runs_non_warp (p0) {
|
||||
b0.value = 0;
|
||||
for (var a0 = 5; a0 >= 0.5; a0--) {
|
||||
thread.timer = timer();
|
||||
var a1 = Math.max(0, 1000 * 0);
|
||||
runtime.requestRedraw();
|
||||
yield;
|
||||
while (thread.timer.timeElapsed() < a1) {
|
||||
yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield;
|
||||
}
|
||||
if (compareEqual(b0.value, 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"fail ran warp",}, b1, false, false, null);
|
||||
}
|
||||
return ("non warp: " + ("" + p0));
|
||||
return "";
|
||||
}; })
|
||||
@@ -18,7 +18,7 @@ if (hasResumedFromPromise) {hasResumedFromPromise = false;continue;}
|
||||
}
|
||||
yield;
|
||||
}
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -48,5 +48,5 @@ yield;
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b1, false, false, null);
|
||||
runtime.stopAll();
|
||||
retire(); return;
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -22,7 +22,7 @@ if (((+b1.value || 0) === 1)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite2 script
|
||||
@@ -30,5 +30,5 @@ retire();
|
||||
const b0 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
return function* genXYZ () {
|
||||
b0.value = ((+b0.value || 0) + 1);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -15,11 +15,12 @@ if ((((target.currentCostume + 1) === 1) && ((+target.getCostumes()[target.curre
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 switch %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_switch_ (p0) {
|
||||
runtime.ext_scratch3_looks._setCostume(target, p0);
|
||||
return "";
|
||||
}; })
|
||||
@@ -110,5 +110,5 @@ if (((b6 ? b6.volume : 0) === 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass NE direction",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -18,7 +18,7 @@ yield;
|
||||
thread.timer = null;
|
||||
yield* waitThreads(startHats("event_whenbroadcastreceived", { BROADCAST_OPTION: "Test 1" }));
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -29,13 +29,13 @@ return function* genXYZ () {
|
||||
if ((("" + b0.value).toLowerCase() === "Initial".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b1, false, false, null);
|
||||
}
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Stage script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function* genXYZ () {
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Stage script
|
||||
@@ -43,5 +43,5 @@ retire();
|
||||
const b0 = target.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
return function* genXYZ () {
|
||||
b0.value = "Stage callback";
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -10,5 +10,5 @@ if (!((Infinity - Infinity) <= 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -9,7 +9,7 @@ return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 6",}, b0, false, false, null);
|
||||
b1.value = "\t";
|
||||
startHats("event_whenbroadcastreceived", { BROADCAST_OPTION: "message1" });
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -36,5 +36,5 @@ if (compareEqual((" " + ("" + b0.value)), (0 + 0))) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass \\t and other spaces = number 0",}, b1, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b1, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -52,5 +52,5 @@ if (((tan(-450) || 0) === -Infinity)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass -450",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -82,5 +82,5 @@ if (compareEqual(0, "")) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"fail",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -8,7 +8,7 @@ return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 1",}, b0, false, false, null);
|
||||
yield* thread.procedures["Wrun without screen refresh"]();
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 run without screen refresh
|
||||
@@ -24,4 +24,5 @@ if (isStuck()) yield;
|
||||
if (compareLessThan((daysSince2000() * 86400), b0.value)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b1, true, false, null);
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -15,5 +15,5 @@ const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 0",}, b0, false, false, null);
|
||||
runtime.ext_scratch3_looks._setBackdrop(stage, stage.currentCostume + 1, true);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -15,5 +15,5 @@ const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 0",}, b0, false, false, null);
|
||||
runtime.ext_scratch3_looks._setBackdrop(stage, "backdrop2");
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -16,7 +16,7 @@ yield;
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite2 script
|
||||
@@ -28,5 +28,5 @@ b0.value = ((+b0.value || 0) + 1);
|
||||
if (((b0.value || 0) === 5)) {
|
||||
b1.value = "end";
|
||||
}
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -22,7 +22,7 @@ yield* executeInCompatibilityLayer({"MESSAGE":"pass order is correct (1)",}, b2,
|
||||
} else {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":("fail order is incorrect 1 != " + ("" + b0.value)),}, b2, false, false, null);
|
||||
}
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite3 script
|
||||
@@ -56,7 +56,7 @@ yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -80,5 +80,5 @@ yield* executeInCompatibilityLayer({"MESSAGE":"pass order is correct (2)",}, b2,
|
||||
} else {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":("fail order is incorrect 2 != " + ("" + b0.value)),}, b2, false, false, null);
|
||||
}
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -32,7 +32,7 @@ yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -56,7 +56,7 @@ yield* executeInCompatibilityLayer({"MESSAGE":"pass order is correct (1)",}, b2,
|
||||
} else {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":("fail order is incorrect 1 != " + ("" + b0.value)),}, b2, false, false, null);
|
||||
}
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite2 script
|
||||
@@ -80,5 +80,5 @@ yield* executeInCompatibilityLayer({"MESSAGE":"pass order is correct (2)",}, b2,
|
||||
} else {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":("fail order is incorrect 2 != " + ("" + b0.value)),}, b2, false, false, null);
|
||||
}
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -67,5 +67,5 @@ if (compareEqual(((runtime.ext_scratch3_operators._random((-1 / 0), (1 / 0)) ||
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -10,5 +10,5 @@ if (!((Infinity + -Infinity) <= 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -10,5 +10,5 @@ if (true) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -16,5 +16,5 @@ return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 1",}, b0, false, false, null);
|
||||
yield* waitThreads(startHats("event_whenbroadcastreceived", { BROADCAST_OPTION: "message1" }));
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+1
-1
@@ -18,5 +18,5 @@ if (((+b1.value || 0) === 20)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -12,5 +12,5 @@ if ((("" + b1.value).toLowerCase() === "#22388a".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -1771,5 +1771,5 @@ if (!(("" + compareGreaterThan("", "")).toLowerCase() === "false".toLowerCase())
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"fail 588: should be > ",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -8,7 +8,7 @@ return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 0",}, b0, false, false, null);
|
||||
yield* thread.procedures["Wrun test"]();
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 run test
|
||||
@@ -45,6 +45,7 @@ if (isStuck()) yield;
|
||||
}
|
||||
if (isStuck()) yield;
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 setup values
|
||||
@@ -128,4 +129,5 @@ b0.value.push(" ");
|
||||
b0._monitorUpToDate = false;
|
||||
b0.value.push("🎉");
|
||||
b0._monitorUpToDate = false;
|
||||
return "";
|
||||
}; })
|
||||
@@ -32,5 +32,5 @@ if ((limitPrecision(target.x) === 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass x slightly below 0 rounds",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+1
-1
@@ -19,5 +19,5 @@ if (compareLessThan(("something".toLowerCase() === "else".toLowerCase()), (1 + 0
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+1
-1
@@ -24,5 +24,5 @@ if ((target.direction === 90)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass 4",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+1
-1
@@ -28,5 +28,5 @@ if ((("" + b1.value).toLowerCase().indexOf(".".toLowerCase()) !== -1)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+1
-1
@@ -19,5 +19,5 @@ if (((+(b2.value[(1 | 0) - 1] ?? "") || 0) === 3)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass list",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+5
-2
@@ -18,7 +18,7 @@ yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b2, false, false, null);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b2, false, false, null);
|
||||
runtime.stopAll();
|
||||
retire(); return;
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 no refresh
|
||||
@@ -39,12 +39,14 @@ yield* executeInCompatibilityLayer({"DRUM":1,"BEATS":0,}, b1, true, false, null)
|
||||
runtime.ext_scratch3_motion._moveSteps(0, target);
|
||||
if (isStuck()) yield;
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 runs below with no refresh
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function* genXYZ_runs_below_with_no_r () {
|
||||
yield* thread.procedures["Whas refresh"]();
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 has refresh
|
||||
@@ -65,6 +67,7 @@ yield* executeInCompatibilityLayer({"DRUM":1,"BEATS":0,}, b1, true, false, null)
|
||||
runtime.ext_scratch3_motion._moveSteps(0, target);
|
||||
if (isStuck()) yield;
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -75,5 +78,5 @@ while (true) {
|
||||
b0.value = ((+b0.value || 0) + 1);
|
||||
yield;
|
||||
}
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -34,5 +34,5 @@ if (compareEqual(listGet(b1.value, "*"), "")) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -29,5 +29,5 @@ yield* executeInCompatibilityLayer({"CHANGE":10,}, b9, false, false, null);
|
||||
yield* executeInCompatibilityLayer({}, b10, false, false, null);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -10,5 +10,5 @@ if ((((1 / -0) || 0) === -Infinity)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+1
-1
@@ -23,5 +23,5 @@ yield;
|
||||
}
|
||||
b0.value = 1;
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b1, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+2
-1
@@ -8,7 +8,7 @@ return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 1",}, b0, false, false, null);
|
||||
yield* thread.procedures["ZSet Costume"]();
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Player Set Costume
|
||||
@@ -16,4 +16,5 @@ retire();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ_Set_Costume () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
return "";
|
||||
}; })
|
||||
+3
-1
@@ -9,7 +9,7 @@ yield* executeInCompatibilityLayer({"MESSAGE":"plan 2",}, b0, false, false, null
|
||||
yield* thread.procedures["Znumber or text %s %s"]("bad","ok");
|
||||
yield* thread.procedures["Zboolean %b %b"]("false",!false);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 number or text %s %s
|
||||
@@ -19,6 +19,7 @@ return function* genXYZ_number_or_text__ (p0,p1) {
|
||||
if ((("" + p1).toLowerCase() === "ok".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 boolean %b %b
|
||||
@@ -28,4 +29,5 @@ return function* genXYZ_boolean__ (p0,p1) {
|
||||
if (toBoolean(p1)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
+2
-1
@@ -13,7 +13,7 @@ if (!compareEqual(b1.value, "")) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 do something
|
||||
@@ -21,4 +21,5 @@ retire();
|
||||
const b0 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
return function funXYZ_do_something () {
|
||||
b0.value = "help";
|
||||
return "";
|
||||
}; })
|
||||
+1
-1
@@ -7,5 +7,5 @@ const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 0",}, b0, false, false, null);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
// TW Snapshot
|
||||
// Input SHA-256: b9110339d39947f68168cbb129a20b23b7d4e607ffd5624bd67e096451f6a329
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
return function* genXYZ () {
|
||||
b0.value = 0;
|
||||
while (true) {
|
||||
b0.value = ((+b0.value || 0) + 1);
|
||||
thread.timer = timer();
|
||||
var a0 = Math.max(0, 1000 * -1);
|
||||
runtime.requestRedraw();
|
||||
yield;
|
||||
while (thread.timer.timeElapsed() < a0) {
|
||||
yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield;
|
||||
}
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
const b1 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 2",}, b0, false, false, null);
|
||||
b1.value = 0;
|
||||
if (compareEqual(thread.procedures["Zinvalid params - reporter"](), 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass invalid params reporter",}, b0, false, false, null);
|
||||
}
|
||||
if (compareEqual(thread.procedures["Zinvalid params - boolean"](), 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass invalid params boolean",}, b0, false, false, null);
|
||||
}
|
||||
runtime.stopForTarget(target, thread);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 invalid params - reporter
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_invalid_params___rep () {
|
||||
return 0;
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 invalid params - boolean
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_invalid_params___boo () {
|
||||
return 0;
|
||||
return "";
|
||||
}; })
|
||||
@@ -0,0 +1,146 @@
|
||||
// TW Snapshot
|
||||
// Input SHA-256: b1802636bbbd479dcf8634a525798c5b4dd9b0201cf6af6f5b4879455368c328
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
const b1 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
const b2 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 18",}, b0, false, false, null);
|
||||
b1.value = 0;
|
||||
b2.value = (yield* thread.procedures["Znon warp recursion should yield %s"](8));
|
||||
if (((+b1.value || 0) === 4)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass non warp recursion yields",}, b0, false, false, null);
|
||||
}
|
||||
b1.value = 0;
|
||||
b2.value = thread.procedures["Wwarp recursion should not yield %s"](8);
|
||||
if (((+b1.value || 0) === 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass warp recursion does not yield",}, b0, false, false, null);
|
||||
}
|
||||
b1.value = 0;
|
||||
b2.value = (yield* thread.procedures["Zfib %s"](7));
|
||||
if (((+b1.value || 0) === 20)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass non warp fib yielded",}, b0, false, false, null);
|
||||
}
|
||||
yield* thread.procedures["Zrecursing yields between each %s"]("initial");
|
||||
yield* thread.procedures["Zrecursing arguments eval order %s %s %s %s"]("initial","","","");
|
||||
runtime.stopForTarget(target, thread);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 non warp recursion should yield %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function* genXYZ_non_warp_recursion_s (p0) {
|
||||
if (compareGreaterThan(p0, 0)) {
|
||||
return (yield* yieldThenCallGenerator(thread.procedures["Znon warp recursion should yield %s"], ((+p0 || 0) - 1)));
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 warp recursion should not yield %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_warp_recursion_shoul (p0) {
|
||||
if (compareGreaterThan(p0, 0)) {
|
||||
return thread.procedures["Wwarp recursion should not yield %s"](((+p0 || 0) - 1));
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 fib %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function* genXYZ_fib_ (p0) {
|
||||
if (compareLessThan(p0, 2)) {
|
||||
return p0;
|
||||
} else {
|
||||
return ((+(yield* yieldThenCallGenerator(thread.procedures["Zfib %s"], ((+p0 || 0) - 1))) || 0) + (+(yield* yieldThenCallGenerator(thread.procedures["Zfib %s"], ((+p0 || 0) - 2))) || 0));
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 recursing yields between each %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
const b1 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
const b2 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ_recursing_yields_bet (p0) {
|
||||
if ((("" + p0).toLowerCase() === "initial".toLowerCase())) {
|
||||
b0.value = 0;
|
||||
b1.value = ((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 1)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 1)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 2)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 2)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 3)) || 0) + (+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 3)) || 0)) || 0)) || 0)) || 0)) || 0));
|
||||
if (((+b0.value || 0) === 3)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recursing between calls yields final",}, b2, false, false, null);
|
||||
} else {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"fail recursing between calls yields final",}, b2, false, false, null);
|
||||
}
|
||||
} else {
|
||||
if (compareEqual(b0.value, p0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":("pass recursing between calls yields " + ("" + p0)),}, b2, false, false, null);
|
||||
} else {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":("fail recursing between calls yields " + ("" + p0)),}, b2, false, false, null);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 recursing arguments eval order %s %s %s %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["4HH82mPlVMOONdl(Ot*7"];
|
||||
const b1 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
const b2 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
const b3 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ_recursing_arguments_ (p0,p1,p2,p3) {
|
||||
if ((("" + p0).toLowerCase() === "initial".toLowerCase())) {
|
||||
b0.value = [];
|
||||
b1.value = 0;
|
||||
b2.value = (yield* yieldThenCallGenerator(thread.procedures["Zrecursing arguments eval order %s %s %s %s"], "child 1",(yield* yieldThenCallGenerator(thread.procedures["Zrecursing arguments eval order %s %s %s %s"], "child 2",(yield* yieldThenCallGenerator(thread.procedures["Zrecursing arguments eval order %s %s %s %s"], "child 3",(yield* yieldThenCallGenerator(thread.procedures["Zrecursing arguments eval order %s %s %s %s"], "child 4","","","")),(yield* yieldThenCallGenerator(thread.procedures["Zrecursing arguments eval order %s %s %s %s"], "child 5","","","")),(yield* yieldThenCallGenerator(thread.procedures["Zrecursing arguments eval order %s %s %s %s"], "child 6","","","")))),"","")),"",(yield* yieldThenCallGenerator(thread.procedures["Zrecursing arguments eval order %s %s %s %s"], "child 7","","",""))));
|
||||
if ((("" + (b0.value[(1 | 0) - 1] ?? "")).toLowerCase() === "1/child 4".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - 1",}, b3, false, false, null);
|
||||
}
|
||||
if ((("" + (b0.value[(2 | 0) - 1] ?? "")).toLowerCase() === "1/child 5".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - 2",}, b3, false, false, null);
|
||||
}
|
||||
if ((("" + (b0.value[(3 | 0) - 1] ?? "")).toLowerCase() === "2/child 6".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - 3",}, b3, false, false, null);
|
||||
}
|
||||
if ((("" + (b0.value[(4 | 0) - 1] ?? "")).toLowerCase() === "2/child 3".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - 4",}, b3, false, false, null);
|
||||
}
|
||||
if ((("" + (b0.value[(5 | 0) - 1] ?? "")).toLowerCase() === "3/child 2".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - 5",}, b3, false, false, null);
|
||||
}
|
||||
if ((("" + (b0.value[(6 | 0) - 1] ?? "")).toLowerCase() === "3/child 7".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - 6",}, b3, false, false, null);
|
||||
}
|
||||
if ((("" + (b0.value[(7 | 0) - 1] ?? "")).toLowerCase() === "4/child 1".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - 7",}, b3, false, false, null);
|
||||
}
|
||||
if ((b0.value.length === 7)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass recurse arg order - length is correct",}, b3, false, false, null);
|
||||
}
|
||||
} else {
|
||||
b0.value.push((("" + b1.value) + ("/" + ("" + p0))));
|
||||
b0._monitorUpToDate = false;
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
return function* genXYZ () {
|
||||
b0.value = 0;
|
||||
while (true) {
|
||||
b0.value = ((+b0.value || 0) + 1);
|
||||
thread.timer = timer();
|
||||
var a0 = Math.max(0, 1000 * -1);
|
||||
runtime.requestRedraw();
|
||||
yield;
|
||||
while (thread.timer.timeElapsed() < a0) {
|
||||
yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield;
|
||||
}
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -0,0 +1,111 @@
|
||||
// TW Snapshot
|
||||
// Input SHA-256: cd516553f3cbf4a41ae9a8bc1f5d06a3392d365226bccdfa294578314f18facb
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
const b1 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 8",}, b0, false, false, null);
|
||||
if ((("" + thread.procedures["Zsimplest"]()).toLowerCase() === "It works!".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass simplest",}, b0, false, false, null);
|
||||
}
|
||||
if ((("" + thread.procedures["Znesting 1"]()).toLowerCase() === "42-54".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass nesting1",}, b0, false, false, null);
|
||||
}
|
||||
if (((+thread.procedures["Wwarp fib %s"](12) || 0) === 144)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass fib 12",}, b0, false, false, null);
|
||||
}
|
||||
if (((+thread.procedures["Wfactorial %s"](12) || 0) === 479001600)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass factorial 12",}, b0, false, false, null);
|
||||
}
|
||||
b1.value = (yield* thread.procedures["Zno shadowing 1 %s %s"]("f","g"));
|
||||
if (compareEqual(b1.value, "")) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass default return value",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 simplest
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_simplest () {
|
||||
return "It works!";
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 nesting 1
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_nesting_1 () {
|
||||
thread.procedures["Znesting 2"]();
|
||||
return (("" + thread.procedures["Znesting 3 %s %s"](6,7)) + ("" + thread.procedures["Znesting 3 %s %s"](-1,54)));
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 warp fib %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_warp_fib_ (p0) {
|
||||
return thread.procedures["Wfib %s"](p0);
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 factorial %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_factorial_ (p0) {
|
||||
if (compareGreaterThan(p0, 1)) {
|
||||
return ((+p0 || 0) * (+thread.procedures["Wfactorial %s"](((+p0 || 0) - 1)) || 0));
|
||||
}
|
||||
return 1;
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 no shadowing 1 %s %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
const b1 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
return function* genXYZ_no_shadowing_1__ (p0,p1) {
|
||||
if (((("" + p0).toLowerCase() === "f".toLowerCase()) && (("" + p1).toLowerCase() === "g".toLowerCase()))) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass shadow check 1",}, b0, false, false, null);
|
||||
}
|
||||
b1.value = thread.procedures["Zno shadowing 2 %s %s"](1,2);
|
||||
if (((("" + p0).toLowerCase() === "f".toLowerCase()) && (("" + p1).toLowerCase() === "g".toLowerCase()))) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass shadow check 2",}, b0, false, false, null);
|
||||
}
|
||||
b1.value = thread.procedures["Zno shadowing 2 %s %s"](3,4);
|
||||
if (((("" + p0).toLowerCase() === "f".toLowerCase()) && (("" + p1).toLowerCase() === "g".toLowerCase()))) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass shadow check 3",}, b0, false, false, null);
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 nesting 2
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_nesting_2 () {
|
||||
return "discard nesting 2";
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 nesting 3 %s %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_nesting_3__ (p0,p1) {
|
||||
return ((+p0 || 0) * (+p1 || 0));
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 fib %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_fib_ (p0) {
|
||||
if (compareLessThan(p0, 2)) {
|
||||
return p0;
|
||||
} else {
|
||||
return ((+thread.procedures["Wfib %s"](((+p0 || 0) - 1)) || 0) + (+thread.procedures["Wfib %s"](((+p0 || 0) - 2)) || 0));
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 no shadowing 2 %s %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_no_shadowing_2__ (p0,p1) {
|
||||
return "discard shadow 2";
|
||||
return "";
|
||||
}; })
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
// TW Snapshot
|
||||
// Input SHA-256: 27368530b97e0ab5053bf4faf8fd116aa30cea34adcbd95fc6ddcf0a9d6d4976
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
const b1 = stage.variables["PsAI*C{QHI3*4?O8p#TM"];
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 2",}, b0, false, false, null);
|
||||
yield* thread.procedures["Wreturn stops the script immediately"]();
|
||||
if (((+b1.value || 0) === 25)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass return stopped the script immediately",}, b0, false, false, null);
|
||||
}
|
||||
yield* waitThreads(startHats("event_whenbroadcastreceived", { BROADCAST_OPTION: "Test return outside of custom block" }));
|
||||
if (((+b1.value || 0) === 18)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass return worked to stop outside of custom block",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 return stops the script immediately
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["PsAI*C{QHI3*4?O8p#TM"];
|
||||
const b1 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ_return_stops_the_scr () {
|
||||
b0.value = 0;
|
||||
for (var a0 = 100; a0 >= 0.5; a0--) {
|
||||
b0.value = ((+b0.value || 0) + 1);
|
||||
if (((b0.value || 0) === 25)) {
|
||||
return "stopped!";
|
||||
}
|
||||
if (isStuck()) yield;
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"fail return did not stop the script immediately",}, b1, true, false, null);
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["PsAI*C{QHI3*4?O8p#TM"];
|
||||
return function* genXYZ () {
|
||||
b0.value = 0;
|
||||
while (true) {
|
||||
b0.value = ((+b0.value || 0) + 1);
|
||||
if (((b0.value || 0) === 18)) {
|
||||
retire(); return;
|
||||
}
|
||||
yield;
|
||||
}
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -0,0 +1,121 @@
|
||||
// TW Snapshot
|
||||
// Input SHA-256: e652f448fbf09a37afacb03afa9f3448cce43aef06439b58b44aeec73edb0438
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
return function* genXYZ () {
|
||||
b0.value = 0;
|
||||
while (true) {
|
||||
b0.value = ((+b0.value || 0) + 1);
|
||||
thread.timer = timer();
|
||||
var a0 = Math.max(0, 1000 * -1);
|
||||
runtime.requestRedraw();
|
||||
yield;
|
||||
while (thread.timer.timeElapsed() < a0) {
|
||||
yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield;
|
||||
}
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 3",}, b0, false, false, null);
|
||||
yield* thread.procedures["Znon warp"]();
|
||||
runtime.stopForTarget(target, thread);
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 non warp
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
const b1 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ_non_warp () {
|
||||
b0.value = 0;
|
||||
for (var a0 = 5; a0 >= 0.5; a0--) {
|
||||
thread.timer = timer();
|
||||
var a1 = Math.max(0, 1000 * 0);
|
||||
runtime.requestRedraw();
|
||||
yield;
|
||||
while (thread.timer.timeElapsed() < a1) {
|
||||
yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield;
|
||||
}
|
||||
if (((+b0.value || 0) === 5)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass non warp 1",}, b1, false, false, null);
|
||||
}
|
||||
if ((("" + (yield* thread.procedures["Wverify runs warp %s"]((yield* thread.procedures["Zverify runs non warp %s"]((yield* thread.procedures["Wverify runs warp %s"]("abc"))))))).toLowerCase() === "warp: non warp: warp: abc".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass non warp and warp mix",}, b1, false, false, null);
|
||||
}
|
||||
b0.value = 0;
|
||||
for (var a2 = 5; a2 >= 0.5; a2--) {
|
||||
thread.timer = timer();
|
||||
var a3 = Math.max(0, 1000 * 0);
|
||||
runtime.requestRedraw();
|
||||
yield;
|
||||
while (thread.timer.timeElapsed() < a3) {
|
||||
yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield;
|
||||
}
|
||||
if (((+b0.value || 0) === 5)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass non warp 2",}, b1, false, false, null);
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 verify runs warp %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
const b1 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ_verify_runs_warp_ (p0) {
|
||||
b0.value = 0;
|
||||
for (var a0 = 5; a0 >= 0.5; a0--) {
|
||||
thread.timer = timer();
|
||||
var a1 = Math.max(0, 1000 * 0);
|
||||
runtime.requestRedraw();
|
||||
while (thread.timer.timeElapsed() < a1) {
|
||||
if (isStuck()) yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
if (isStuck()) yield;
|
||||
}
|
||||
if (!compareEqual(b0.value, 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"fail did not run warp",}, b1, true, false, null);
|
||||
}
|
||||
return ("warp: " + ("" + p0));
|
||||
return "";
|
||||
}; })
|
||||
|
||||
// Sprite1 verify runs non warp %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["Go=PJS7BFXYo_qi2S:kQ"];
|
||||
const b1 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ_verify_runs_non_warp (p0) {
|
||||
b0.value = 0;
|
||||
for (var a0 = 5; a0 >= 0.5; a0--) {
|
||||
thread.timer = timer();
|
||||
var a1 = Math.max(0, 1000 * 0);
|
||||
runtime.requestRedraw();
|
||||
yield;
|
||||
while (thread.timer.timeElapsed() < a1) {
|
||||
yield;
|
||||
}
|
||||
thread.timer = null;
|
||||
yield;
|
||||
}
|
||||
if (compareEqual(b0.value, 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"fail ran warp",}, b1, false, false, null);
|
||||
}
|
||||
return ("non warp: " + ("" + p0));
|
||||
return "";
|
||||
}; })
|
||||
+2
-2
@@ -18,7 +18,7 @@ if (hasResumedFromPromise) {hasResumedFromPromise = false;continue;}
|
||||
}
|
||||
yield;
|
||||
}
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -48,5 +48,5 @@ yield;
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b1, false, false, null);
|
||||
runtime.stopAll();
|
||||
retire(); return;
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -22,7 +22,7 @@ if (((+b1.value || 0) === 1)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite2 script
|
||||
@@ -30,5 +30,5 @@ retire();
|
||||
const b0 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
return function* genXYZ () {
|
||||
b0.value = ((+b0.value || 0) + 1);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+2
-1
@@ -15,11 +15,12 @@ if ((((target.currentCostume + 1) === 1) && ((+target.getCostumes()[target.curre
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 switch %s
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function funXYZ_switch_ (p0) {
|
||||
runtime.ext_scratch3_looks._setCostume(target, p0);
|
||||
return "";
|
||||
}; })
|
||||
@@ -110,5 +110,5 @@ if (((b6 ? b6.volume : 0) === 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass NE direction",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -18,7 +18,7 @@ yield;
|
||||
thread.timer = null;
|
||||
yield* waitThreads(startHats("event_whenbroadcastreceived", { BROADCAST_OPTION: "Test 1" }));
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -29,13 +29,13 @@ return function* genXYZ () {
|
||||
if ((("" + b0.value).toLowerCase() === "Initial".toLowerCase())) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b1, false, false, null);
|
||||
}
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Stage script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
return function* genXYZ () {
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Stage script
|
||||
@@ -43,5 +43,5 @@ retire();
|
||||
const b0 = target.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
return function* genXYZ () {
|
||||
b0.value = "Stage callback";
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -10,5 +10,5 @@ if (!((Infinity - Infinity) <= 0)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -9,7 +9,7 @@ return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 6",}, b0, false, false, null);
|
||||
b1.value = "\t";
|
||||
startHats("event_whenbroadcastreceived", { BROADCAST_OPTION: "message1" });
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -36,5 +36,5 @@ if (compareEqual((" " + ("" + b0.value)), (0 + 0))) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass \\t and other spaces = number 0",}, b1, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b1, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -52,5 +52,5 @@ if (((tan(-450) || 0) === -Infinity)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass -450",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
@@ -82,5 +82,5 @@ if (compareEqual(0, "")) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"fail",}, b0, false, false, null);
|
||||
}
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+2
-1
@@ -8,7 +8,7 @@ return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 1",}, b0, false, false, null);
|
||||
yield* thread.procedures["Wrun without screen refresh"]();
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 run without screen refresh
|
||||
@@ -24,4 +24,5 @@ if (isStuck()) yield;
|
||||
if (compareLessThan((daysSince2000() * 86400), b0.value)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b1, true, false, null);
|
||||
}
|
||||
return "";
|
||||
}; })
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -15,5 +15,5 @@ const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 0",}, b0, false, false, null);
|
||||
runtime.ext_scratch3_looks._setBackdrop(stage, stage.currentCostume + 1, true);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, null);
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
@@ -15,5 +15,5 @@ const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 0",}, b0, false, false, null);
|
||||
runtime.ext_scratch3_looks._setBackdrop(stage, "backdrop2");
|
||||
retire();
|
||||
retire(); return;
|
||||
}; })
|
||||
Loaded 100 of 103 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user