@samitouri / QOS-React-2 / commits / cd115ec128

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": {