Scaffold for sequence terminal
I realized that we can use our value block system to fix _most_ of the remaining order-of-evaluation issues we had with sequence expressions. This PR adds a new SequenceTerminal to HIR; there is already a ReactiveFunction equivalent (ReactiveSequenceValue) that the next PR will convert this terminal into.
Joe Savona committed
Jun 4, 2023 at 21:25 UTC
cd115ec128a80a69c4aac253c853d12026f1ea61
6 files changed
+51
-2
compiler/forget/src/HIR/HIR.ts
+10
-2
@@ -279,7 +279,8 @@ export type Terminal =
279
| LogicalTerminal
280
| TernaryTerminal
281
| OptionalTerminal
282
- | LabelTerminal;
282
+ | LabelTerminal
283
+ | SequenceTerminal;
284
285
function _staticInvariantTerminalHasLocation(
286
terminal: Terminal
@@ -298,7 +299,6 @@ function _staticInvariantTerminalHasInstructionId(
299
/**
300
* Terminal nodes allowed for a value block
301
*/
301
-export type ValueTerminal = IfTerminal | GotoTerminal;
302
// A terminal that couldn't be lowered correctly.
303
export type UnsupportedTerminal = {
304
kind: "unsupported";
@@ -437,6 +437,14 @@ export type OptionalTerminal = {
437
loc: SourceLocation;
438
};
439
440
+export type SequenceTerminal = {
441
+ kind: "sequence";
442
+ block: BlockId;
443
+ fallthrough: BlockId;
444
+ id: InstructionId;
445
+ loc: SourceLocation;
446
+};
447
+
448
/**
449
* Instructions generally represent expressions but with all nesting flattened away,
450
* such that all operands to each instruction are either primitive values OR are
compiler/forget/src/HIR/HIRBuilder.ts
+4
@@ -697,6 +697,10 @@ export function reversePostorderBlocks(func: HIR): void {
697
visit(terminal.block);
698
break;
699
}
700
+ case "sequence": {
701
+ visit(terminal.block);
702
+ break;
703
+ }
704
case "unsupported": {
705
break;
706
}
compiler/forget/src/HIR/PrintHIR.ts
+5
@@ -79,6 +79,7 @@ export function printMixedHIR(
79
return printInstruction(value);
80
}
81
switch (value.kind) {
82
+ case "sequence":
83
case "label":
84
case "optional":
85
case "branch":
@@ -220,6 +221,10 @@ export function printTerminal(terminal: Terminal): Array<string> | string {
221
}`;
222
break;
223
}
224
+ case "sequence": {
225
+ value = `[${terminal.id}] Sequence block=bb${terminal.block} fallthrough=bb${terminal.fallthrough}`;
226
+ break;
227
+ }
228
case "unsupported": {
229
value = `Unsupported`;
230
break;
compiler/forget/src/HIR/visitors.ts
+22
@@ -704,6 +704,17 @@ export function mapTerminalSuccessors(
704
loc: terminal.loc,
705
};
706
}
707
+ case "sequence": {
708
+ const block = fn(terminal.block);
709
+ const fallthrough = fn(terminal.fallthrough);
710
+ return {
711
+ kind: "sequence",
712
+ block,
713
+ fallthrough,
714
+ id: makeInstructionId(0),
715
+ loc: terminal.loc,
716
+ };
717
+ }
718
case "unsupported": {
719
return terminal;
720
}
@@ -737,6 +748,7 @@ export function terminalFallthrough(terminal: Terminal): BlockId | null {
748
case "label":
749
case "logical":
750
case "optional":
751
+ case "sequence":
752
case "switch":
753
case "ternary":
754
case "while": {
@@ -813,6 +825,10 @@ export function mapOptionalFallthroughs(
825
}
826
break;
827
}
828
+ case "sequence": {
829
+ const _: BlockId = terminal.fallthrough;
830
+ break;
831
+ }
832
default: {
833
assertExhaustive(
834
terminal,
@@ -881,6 +897,10 @@ export function* eachTerminalSuccessor(terminal: Terminal): Iterable<BlockId> {
897
yield terminal.block;
898
break;
899
}
900
+ case "sequence": {
901
+ yield terminal.block;
902
+ break;
903
+ }
904
case "unsupported":
905
break;
906
default: {
@@ -920,6 +940,7 @@ export function mapTerminalOperands(
940
terminal.value = fn(terminal.value);
941
break;
942
}
943
+ case "sequence":
944
case "label":
945
case "optional":
946
case "ternary":
@@ -967,6 +988,7 @@ export function* eachTerminalOperand(terminal: Terminal): Iterable<Place> {
988
yield terminal.value;
989
break;
990
}
991
+ case "sequence":
992
case "label":
993
case "optional":
994
case "ternary":
compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts
+1
@@ -570,6 +570,7 @@ class Driver {
570
571
break;
572
}
573
+ case "sequence":
574
case "optional":
575
case "ternary":
576
case "logical": {
compiler/forget/src/Utils/VisualizeHIRMermaid.ts
+9
@@ -135,6 +135,10 @@ function printTerminalLabel(terminal: Terminal): string {
135
buffer.push("Label");
136
break;
137
}
138
+ case "sequence": {
139
+ buffer.push("Sequence");
140
+ break;
141
+ }
142
case "unsupported": {
143
break;
144
}
@@ -237,6 +241,11 @@ function printTerminalArrows(blockId: BlockId, terminal: Terminal): string {
241
}
242
break;
243
}
244
+ case "sequence": {
245
+ buffer.push(printJumpArrow(blockId, terminal.block, "block"));
246
+ buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));
247
+ break;
248
+ }
249
case "throw":
250
case "return":
251
case "unsupported": {