Skip to content

Commit 7de26c9

Browse files
authored
Merge pull request #275 from Tacodiva/misc-compiler-fixes
Misc compiler fixes
2 parents cd353ca + d17cecc commit 7de26c9

File tree

9 files changed

+78
-35
lines changed

9 files changed

+78
-35
lines changed

src/compiler/intermediate.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,46 @@ class IntermediateInput {
209209
}
210210
}
211211

212+
213+
/**
214+
* @param {InputType} type
215+
* @returns {string}
216+
*/
217+
const stringifyType = type => {
218+
let formatFlags = [];
219+
220+
for (const enumValue in InputType) {
221+
const testFormat = InputType[enumValue];
222+
223+
if ((testFormat & type) === testFormat) {
224+
for (const existingFormat of formatFlags) {
225+
if ((testFormat & InputType[existingFormat]) === testFormat) {
226+
continue;
227+
}
228+
}
229+
230+
formatFlags = formatFlags.filter(value => (InputType[value] & testFormat) !== InputType[value]);
231+
formatFlags.push(enumValue);
232+
}
233+
}
234+
235+
let str = null;
236+
237+
for (const formatFlag of formatFlags) {
238+
if (str === null) {
239+
str = formatFlag;
240+
} else {
241+
str = `${str} | ${formatFlag}`;
242+
}
243+
}
244+
245+
if (str === null) {
246+
return 'INVALID';
247+
}
248+
249+
return str;
250+
};
251+
212252
/**
213253
* A 'stack' of blocks, like the contents of a script or the inside
214254
* of a C block.
@@ -350,5 +390,6 @@ module.exports = {
350390
IntermediateInput,
351391
IntermediateStack,
352392
IntermediateScript,
353-
IntermediateRepresentation
393+
IntermediateRepresentation,
394+
stringifyType
354395
};

src/compiler/irgen.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -299,14 +299,14 @@ class ScriptTreeGenerator {
299299
}
300300
return new IntermediateInput(InputOpcode.LOOKS_COSTUME_NAME, InputType.STRING);
301301
case 'looks_size':
302-
return new IntermediateInput(InputOpcode.LOOKS_SIZE_GET, InputType.NUMBER_POS_REAL);
302+
return new IntermediateInput(InputOpcode.LOOKS_SIZE_GET, InputType.NUMBER_POS);
303303

304304
case 'motion_direction':
305305
return new IntermediateInput(InputOpcode.MOTION_DIRECTION_GET, InputType.NUMBER_REAL);
306306
case 'motion_xposition':
307-
return new IntermediateInput(InputOpcode.MOTION_X_GET, InputType.NUMBER_REAL);
307+
return new IntermediateInput(InputOpcode.MOTION_X_GET, InputType.NUMBER);
308308
case 'motion_yposition':
309-
return new IntermediateInput(InputOpcode.MOTION_Y_GET, InputType.NUMBER_REAL);
309+
return new IntermediateInput(InputOpcode.MOTION_Y_GET, InputType.NUMBER);
310310

311311
case 'operator_add':
312312
return new IntermediateInput(InputOpcode.OP_ADD, InputType.NUMBER_OR_NAN, {
@@ -494,7 +494,7 @@ class ScriptTreeGenerator {
494494
case 'sensing_dayssince2000':
495495
return new IntermediateInput(InputOpcode.SENSING_TIME_DAYS_SINCE_2000, InputType.NUMBER);
496496
case 'sensing_distanceto':
497-
return new IntermediateInput(InputOpcode.SENSING_DISTANCE, InputType.NUMBER_POS_REAL | InputType.NUMBER_ZERO, {
497+
return new IntermediateInput(InputOpcode.SENSING_DISTANCE, InputType.NUMBER_POS | InputType.NUMBER_ZERO, {
498498
target: this.descendInputOfBlock(block, 'DISTANCETOMENU').toType(InputType.STRING)
499499
});
500500
case 'sensing_keypressed':

src/compiler/iroptimizer.js

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,8 @@ class IROptimizer {
377377
let resultType = 0;
378378

379379
const canBeNaN = function () {
380-
// REAL / 0 = NaN
381-
if ((leftType & InputType.NUMBER_REAL) && (rightType & InputType.NUMBER_ZERO)) return true;
380+
// (-)0 / (-)0 = NaN
381+
if ((leftType & InputType.NUMBER_ANY_ZERO) && (rightType & InputType.NUMBER_ANY_ZERO)) return true;
382382
// (-)Infinity / (-)Infinity = NaN
383383
if ((leftType & InputType.NUMBER_INF) && (rightType & InputType.NUMBER_INF)) return true;
384384
// (-)0 / NaN = NaN
@@ -395,24 +395,26 @@ class IROptimizer {
395395
if (canBePos()) resultType |= InputType.NUMBER_POS;
396396

397397
const canBeNegInfinity = function () {
398-
// -Infinity / 0 = -Infinity
399-
if ((leftType & InputType.NUMBER_NEG_INF) && (rightType & InputType.NUMBER_ZERO)) return true;
400-
// Infinity / -0 = -Infinity
401-
if ((leftType & InputType.NUMBER_POS_INF) && (rightType & InputType.NUMBER_NEG_ZERO)) return true;
402-
// NEG_REAL / NaN = -Infinity
403-
if ((leftType & InputType.NUMBER_NEG_REAL) && (rightType & InputType.NUMBER_NAN)) return true;
404-
// NEG_REAL / NUMBER_OR_NAN ~= -Infinity
405-
if ((leftType & InputType.NUMBER_NEG_REAL) && (rightType & InputType.NUMBER_OR_NAN)) return true;
398+
// NEG / 0 = -Infinity
399+
if ((leftType & InputType.NUMBER_NEG) && (rightType & InputType.NUMBER_ZERO)) return true;
400+
// POS / -0 = -Infinity
401+
if ((leftType & InputType.NUMBER_POS) && (rightType & InputType.NUMBER_NEG_ZERO)) return true;
402+
// NEG_REAL / POS_REAL ~= -Infinity
403+
if ((leftType & InputType.NUMBER_NEG_REAL) && (rightType & InputType.NUMBER_POS_REAL)) return true;
404+
// POS_REAL / NEG_REAL ~= -Infinity
405+
if ((leftType & InputType.NUMBER_POS_REAL) && (rightType & InputType.NUMBER_NEG_REAL)) return true;
406406
};
407407
if (canBeNegInfinity()) resultType |= InputType.NUMBER_NEG_INF;
408408

409409
const canBeInfinity = function () {
410-
// Infinity / 0 = Infinity
411-
if ((leftType & InputType.NUMBER_POS_INF) && (rightType & InputType.NUMBER_ZERO)) return true;
412-
// -Infinity / -0 = Infinity
413-
if ((leftType & InputType.NUMBER_NEG_INF) && (rightType & InputType.NUMBER_NEG_ZERO)) return true;
414-
// POS_REAL / NUMBER_OR_NAN ~= Infinity
415-
if ((leftType & InputType.NUMBER_POS_REAL) && (rightType & InputType.NUMBER_OR_NAN)) return true;
410+
// POS / 0 = Infinity
411+
if ((leftType & InputType.NUMBER_POS) && (rightType & InputType.NUMBER_ZERO)) return true;
412+
// NEG / -0 = Infinity
413+
if ((leftType & InputType.NUMBER_NEG) && (rightType & InputType.NUMBER_NEG_ZERO)) return true;
414+
// POS_REAL / POS_REAL ~= Infinity
415+
if ((leftType & InputType.NUMBER_POS_REAL) && (rightType & InputType.NUMBER_POS_REAL)) return true;
416+
// NEG_REAL / NEG_REAL ~= Infinity
417+
if ((leftType & InputType.NUMBER_NEG_REAL) && (rightType & InputType.NUMBER_NEG_REAL)) return true;
416418
};
417419
if (canBeInfinity()) resultType |= InputType.NUMBER_POS_INF;
418420

@@ -644,8 +646,8 @@ class IROptimizer {
644646

645647
const newState = state.clone();
646648
modified = this.analyzeStack(stack, newState) || modified;
649+
modified = this.analyzeInputs(block.inputs, newState) || modified;
647650
modified = (keepLooping = state.or(newState)) || modified;
648-
modified = this.analyzeInputs(block.inputs, state) || modified;
649651
} while (keepLooping);
650652
block.entryState = state.clone();
651653
return modified;

test/integration/tw_operator_type_matrix.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const VM = require('../../src/virtual-machine');
33
const {BlockType, ArgumentType} = require('../../src/extension-support/tw-extension-api-common');
44
const {IRGenerator} = require('../../src/compiler/irgen');
55
const {IROptimizer} = require('../../src/compiler/iroptimizer');
6-
const {IntermediateInput} = require('../../src/compiler/intermediate');
6+
const {IntermediateInput, stringifyType} = require('../../src/compiler/intermediate');
77
const nanolog = require('@turbowarp/nanolog');
88

99
const VALUES = [
@@ -113,7 +113,7 @@ test('operator type matrix', async t => {
113113
1,
114114
[
115115
4,
116-
`${inputs[i]}`
116+
`${Object.is(inputs[i], -0) ? '-0' : inputs[i]}`
117117
]
118118
];
119119
}
@@ -180,7 +180,7 @@ test('operator type matrix', async t => {
180180
t.ok(
181181
irOperator.isSometimesType(expectedType),
182182
`${operator.opcode}${JSON.stringify(operator.fields)}[${inputs.map(str)}] ` +
183-
`outputted value ${str(reportedValue)} is of the expected type ${irOperator.type}.`
183+
`outputted value ${str(reportedValue)} is of the expected type ${stringifyType(irOperator.type)}.`
184184
);
185185
};
186186

test/snapshot/__snapshots__/tw-NaN.sb3.tw-snapshot

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "ao",
5757
if (((((Math.log(-1) / Math.LN10) || 0) * 1) === 0)) {
5858
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "aq", null);
5959
}
60-
if (((((Math.round(Math.sin((Math.PI * ((1 / 0) || 0)) / 180) * 1e10) / 1e10) || 0) * 1) === 0)) {
60+
if (((((Math.round(Math.sin((Math.PI * (1 / 0)) / 180) * 1e10) / 1e10) || 0) * 1) === 0)) {
6161
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "as", null);
6262
}
63-
if (((((Math.round(Math.cos((Math.PI * ((1 / 0) || 0)) / 180) * 1e10) / 1e10) || 0) * 1) === 0)) {
63+
if (((((Math.round(Math.cos((Math.PI * (1 / 0)) / 180) * 1e10) / 1e10) || 0) * 1) === 0)) {
6464
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "au", null);
6565
}
66-
if ((((tan(((1 / 0) || 0)) || 0) * 1) === 0)) {
66+
if ((((tan((1 / 0)) || 0) * 1) === 0)) {
6767
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "aw", null);
6868
}
6969
if ((((runtime.ext_scratch3_operators._random((-1 / 0), (1 / 0)) || 0) * 1) === 0)) {

test/snapshot/__snapshots__/tw-forkphorus-515-non-finite-direction.sb3.tw-snapshot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ target.setDirection(95);
1111
if ((target.direction === 95)) {
1212
yield* executeInCompatibilityLayer({"MESSAGE":"pass 1",}, b0, false, false, "o", null);
1313
}
14-
target.setDirection(((1 / 0) || 0));
14+
target.setDirection((1 / 0));
1515
if ((target.direction === 95)) {
1616
yield* executeInCompatibilityLayer({"MESSAGE":"pass 2",}, b0, false, false, "r", null);
1717
}

test/snapshot/__snapshots__/tw-gh-249-quicksort.sb3.tw-snapshot

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ b0.value = (b1.value[(((((+p1 || 0) + (+p0 || 0)) || 0) / 2) | 0) - 1] ?? "");
6767
b2.value = p0;
6868
b3.value = p1;
6969
while (true) {
70-
while (compareLessThan(listGet(b1.value, b2.value), b0.value)) {
70+
while (compareLessThan((b1.value[(b2.value | 0) - 1] ?? ""), b0.value)) {
7171
b2.value = ((+b2.value || 0) + 1);
7272
}
73-
while (compareGreaterThan(listGet(b1.value, b3.value), b0.value)) {
73+
while (compareGreaterThan((b1.value[(b3.value | 0) - 1] ?? ""), b0.value)) {
7474
b3.value = ((+b3.value || 0) + -1);
7575
}
7676
if (compareGreaterThan(b2.value, b3.value)) {

test/snapshot/__snapshots__/warp-timer/tw-NaN.sb3.tw-snapshot

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "ao",
5757
if (((((Math.log(-1) / Math.LN10) || 0) * 1) === 0)) {
5858
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "aq", null);
5959
}
60-
if (((((Math.round(Math.sin((Math.PI * ((1 / 0) || 0)) / 180) * 1e10) / 1e10) || 0) * 1) === 0)) {
60+
if (((((Math.round(Math.sin((Math.PI * (1 / 0)) / 180) * 1e10) / 1e10) || 0) * 1) === 0)) {
6161
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "as", null);
6262
}
63-
if (((((Math.round(Math.cos((Math.PI * ((1 / 0) || 0)) / 180) * 1e10) / 1e10) || 0) * 1) === 0)) {
63+
if (((((Math.round(Math.cos((Math.PI * (1 / 0)) / 180) * 1e10) / 1e10) || 0) * 1) === 0)) {
6464
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "au", null);
6565
}
66-
if ((((tan(((1 / 0) || 0)) || 0) * 1) === 0)) {
66+
if ((((tan((1 / 0)) || 0) * 1) === 0)) {
6767
yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "aw", null);
6868
}
6969
if ((((runtime.ext_scratch3_operators._random((-1 / 0), (1 / 0)) || 0) * 1) === 0)) {

test/snapshot/__snapshots__/warp-timer/tw-forkphorus-515-non-finite-direction.sb3.tw-snapshot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ target.setDirection(95);
1111
if ((target.direction === 95)) {
1212
yield* executeInCompatibilityLayer({"MESSAGE":"pass 1",}, b0, false, false, "o", null);
1313
}
14-
target.setDirection(((1 / 0) || 0));
14+
target.setDirection((1 / 0));
1515
if ((target.direction === 95)) {
1616
yield* executeInCompatibilityLayer({"MESSAGE":"pass 2",}, b0, false, false, "r", null);
1717
}

0 commit comments

Comments
 (0)