Skip to content

Commit beed8f4

Browse files
committed
toLeopard: stub desirable / satisfying traits
1 parent ca45552 commit beed8f4

File tree

1 file changed

+159
-12
lines changed

1 file changed

+159
-12
lines changed

src/io/leopard/toLeopard.ts

Lines changed: 159 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,110 @@ const LEOPARD_RESERVED_SPRITE_PROPERTIES = [
282282
"stamp"
283283
];
284284

285+
enum DesirableTraits {
286+
/**
287+
* Indicates an exact boolean (true/false) value is desired.
288+
*/
289+
IsBoolean,
290+
291+
/**
292+
* Indicates a number value is desired (typeof x === 'number').
293+
* By default, this indicates it's OK to leave NaN as it is.
294+
* Other non-number values will be cast to zero, but if the
295+
* value is NaN to begin with, that will be left as-is.
296+
*
297+
* Behavior can be customized by specifying, alongside IsNumber,
298+
* IsCastToNaN or IsCastToZero.
299+
*/
300+
IsNumber,
301+
302+
/**
303+
* Indicates an index value is desired - this is a normal number,
304+
* but decremented by one compared to its value in Scratch.
305+
*
306+
* The traits for customizing IsNumber don't apply to IsIndex.
307+
*/
308+
IsIndex,
309+
310+
/**
311+
* Indicates a string value is desired (typeof x === 'string').
312+
*/
313+
IsString,
314+
315+
/**
316+
* Indicates a series of stack blocks is desired.
317+
*/
318+
IsStack,
319+
320+
/**
321+
* Indicates that if a value can't be converted to a number
322+
* (according to `toNumber(expr, true)` rules), NaN should be
323+
* returned. NaN itself is also returned as NaN.
324+
*
325+
* May only be specified alongside IsNumber.
326+
*/
327+
IsCastToNaN,
328+
329+
/**
330+
* Indicates that if a value can't be converted to a number,
331+
* or if the value is NaN itself, zero shuold be returned.
332+
*
333+
* May only be specifeid alongside IsNumber.
334+
*/
335+
IsCastToZero
336+
}
337+
338+
enum SatisfyingTraits {
339+
/**
340+
* Indicates an exact boolean (true/false) value is satisfied.
341+
*/
342+
IsBoolean,
343+
344+
/**
345+
* Indicates a number value is satisfied (typeof x === 'number').
346+
* By default, this implies the number value may be NaN, but this
347+
* can be ruled out by specifying, alongside IsNumber, IsNotNaN.
348+
*/
349+
IsNumber,
350+
351+
/**
352+
* Indicates an index is satisfied. Within the definition for a
353+
* particular reporter, this means the reporter already took care
354+
* of decrementing its numeric return value by one.
355+
*/
356+
IsIndex,
357+
358+
/**
359+
* Indicates a string value is satisfied (typeof x === 'string').
360+
*/
361+
IsString,
362+
363+
/**
364+
* Indicates that the satisfied number value isn't NaN - i.e,
365+
* it's a non-NaN number.
366+
*
367+
* May only be specified alongside IsNumber.
368+
*/
369+
IsNotNaN
370+
}
371+
372+
type DesirableTraitCombo =
373+
| []
374+
| [DesirableTraits.IsBoolean]
375+
| [DesirableTraits.IsNumber]
376+
| [DesirableTraits.IsNumber, DesirableTraits.IsCastToNaN]
377+
| [DesirableTraits.IsNumber, DesirableTraits.IsCastToZero]
378+
| [DesirableTraits.IsIndex]
379+
| [DesirableTraits.IsStack]
380+
| [DesirableTraits.IsString];
381+
382+
type SatisfyingTraitCombo =
383+
| []
384+
| [SatisfyingTraits.IsBoolean]
385+
| [SatisfyingTraits.IsNumber]
386+
| [SatisfyingTraits.IsNumber, SatisfyingTraits.IsNotNaN]
387+
| [SatisfyingTraits.IsString];
388+
285389
/**
286390
* Input shapes are the basic attribute controlling which of a set of syntaxes
287391
* is returned for any given block (or primitive value). Provide an input shape
@@ -686,7 +790,7 @@ export default function toLeopard(
686790
}
687791
}
688792

689-
function blockToJS(block: Block, desiredInputShape?: InputShape): string {
793+
function blockToJS(block: Block, desiredInputShape?: InputShape, desiredTraits: DesirableTraitCombo = []): string {
690794
const warp =
691795
script && script.hat && script.hat.opcode === OpCode.procedures_definition && script.hat.inputs.WARP.value;
692796

@@ -715,6 +819,7 @@ export default function toLeopard(
715819
const stage = "this" + (target.isStage ? "" : ".stage");
716820

717821
let satisfiesInputShape: InputShape;
822+
let satisfiesTraits: SatisfyingTraitCombo = [];
718823
let blockSource: string;
719824

720825
makeBlockSource: switch (block.opcode) {
@@ -2494,31 +2599,73 @@ export default function toLeopard(
24942599
}
24952600
}
24962601

2497-
switch (desiredInputShape) {
2498-
case satisfiesInputShape: {
2499-
return blockSource;
2602+
if (!desiredTraits.length) {
2603+
return blockSource;
2604+
}
2605+
2606+
if (desiredTraits[0] === DesirableTraits.IsStack) {
2607+
return blockSource;
2608+
}
2609+
2610+
if (desiredTraits[0] === DesirableTraits.IsNumber) {
2611+
if (desiredTraits[1] === DesirableTraits.IsCastToNaN) {
2612+
if (satisfiesTraits.length && satisfiesTraits[0] === SatisfyingTraits.IsNumber) {
2613+
return blockSource;
2614+
}
2615+
2616+
return `this.toNumber(${blockSource}, true)`;
25002617
}
25012618

2502-
case InputShape.Number: {
2619+
if (desiredTraits[1] === DesirableTraits.IsCastToZero) {
2620+
if (
2621+
satisfiesTraits.length &&
2622+
satisfiesTraits[0] === SatisfyingTraits.IsNumber &&
2623+
satisfiesTraits[1] === SatisfyingTraits.IsNotNaN
2624+
) {
2625+
return blockSource;
2626+
}
2627+
25032628
return `this.toNumber(${blockSource})`;
25042629
}
25052630

2506-
case InputShape.Index: {
2507-
return `(${blockSource}) - 1`;
2631+
if (satisfiesTraits.length && satisfiesTraits[0] === SatisfyingTraits.IsNumber) {
2632+
return blockSource;
25082633
}
25092634

2510-
case InputShape.Boolean: {
2511-
return `this.toBoolean(${blockSource})`;
2635+
return `this.toNumber(${blockSource})`;
2636+
}
2637+
2638+
if (desiredTraits[0] === DesirableTraits.IsIndex) {
2639+
if (satisfiesTraits.length) {
2640+
if (satisfiesTraits[0] === SatisfyingTraits.IsIndex) {
2641+
return blockSource;
2642+
}
2643+
2644+
if (satisfiesTraits[0] === SatisfyingTraits.IsNumber && satisfiesTraits[1] === SatisfyingTraits.IsNotNaN) {
2645+
return `(${blockSource}) - 1`;
2646+
}
25122647
}
25132648

2514-
case InputShape.String: {
2515-
return `this.toString(${blockSource})`;
2649+
return `this.toNumber(${blockSource}) - 1`;
2650+
}
2651+
2652+
if (desiredTraits[0] === DesirableTraits.IsString) {
2653+
if (satisfiesTraits.length && satisfiesTraits[0] === SatisfyingTraits.IsString) {
2654+
return blockSource;
25162655
}
25172656

2518-
default: {
2657+
return `this.toString(${blockSource})`;
2658+
}
2659+
2660+
if (desiredTraits[0] === DesirableTraits.IsBoolean) {
2661+
if (satisfiesTraits.length && satisfiesTraits[0] === SatisfyingTraits.IsBoolean) {
25192662
return blockSource;
25202663
}
2664+
2665+
return `this.toBoolean(${blockSource})`;
25212666
}
2667+
2668+
return blockSource;
25222669
}
25232670
}
25242671

0 commit comments

Comments
 (0)