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

[valueblocks] Scaffolding for branch terminal

Scaffolding for a new 'branch' terminal, which is the lower-level form of 'if' meant for use in value blocks. See design at https://fb.quip.com/b7N6AjkDcl2a#temp:C:bAO904b0cf06f154de4a7287af6d

Joe Savona committed Jan 25, 2023 at 17:05 UTC f88fa006e716a4a39cbf0608165956afb2b21fcb
6 files changed +58
compiler/forget/src/HIR/HIR.ts
+9
@@ -214,6 +214,7 @@ export type Terminal =
214 | ReturnTerminal
215 | GotoTerminal
216 | IfTerminal
217 + | BranchTerminal
218 | SwitchTerminal
219 | ForTerminal
220 | WhileTerminal
@@ -256,6 +257,14 @@ export type IfTerminal = {
257 id: InstructionId;
258 };
259
260 +export type BranchTerminal = {
261 + kind: "branch";
262 + test: Place;
263 + consequent: BlockId;
264 + alternate: BlockId;
265 + id: InstructionId;
266 +};
267 +
268 export type SwitchTerminal = {
269 kind: "switch";
270 test: Place;
compiler/forget/src/HIR/HIRBuilder.ts
+6
@@ -553,6 +553,12 @@ export function reversePostorderBlocks(func: HIR): void {
553 visit(consequent);
554 break;
555 }
556 + case "branch": {
557 + const { consequent, alternate } = terminal;
558 + visit(alternate);
559 + visit(consequent);
560 + break;
561 + }
562 case "switch": {
563 // can ignore fallthrough, if its reachable it will be reached through
564 // a case
compiler/forget/src/HIR/PrintHIR.ts
+7
@@ -75,6 +75,7 @@ export function printMixedHIR(
75 return printInstruction(value);
76 }
77 switch (value.kind) {
78 + case "branch":
79 case "if":
80 case "logical":
81 case "return":
@@ -134,6 +135,12 @@ export function printTerminal(terminal: Terminal): Array<string> | string {
135 }`;
136 break;
137 }
138 + case "branch": {
139 + value = `[${terminal.id}] Branch (${printPlace(terminal.test)}) then:bb${
140 + terminal.consequent
141 + } else:bb${terminal.alternate}`;
142 + break;
143 + }
144 case "logical": {
145 value = `[${terminal.id}] Logical ${terminal.operator} test:bb${terminal.test} fallthrough=bb${terminal.fallthrough}`;
146 break;
compiler/forget/src/HIR/visitors.ts
+24
@@ -253,6 +253,17 @@ export function mapTerminalSuccessors(
253 id: makeInstructionId(0),
254 };
255 }
256 + case "branch": {
257 + const consequent = fn(terminal.consequent);
258 + const alternate = fn(terminal.alternate);
259 + return {
260 + kind: "branch",
261 + test: terminal.test,
262 + consequent,
263 + alternate,
264 + id: makeInstructionId(0),
265 + };
266 + }
267 case "switch": {
268 const cases = terminal.cases.map((case_) => {
269 const target = fn(case_.block);
@@ -350,6 +361,11 @@ export function* eachTerminalSuccessor(terminal: Terminal): Iterable<BlockId> {
361 yield terminal.alternate;
362 break;
363 }
364 + case "branch": {
365 + yield terminal.consequent;
366 + yield terminal.alternate;
367 + break;
368 + }
369 case "switch": {
370 for (const case_ of terminal.cases) {
371 yield case_.block;
@@ -394,6 +410,10 @@ export function mapTerminalOperands(
410 terminal.test = fn(terminal.test);
411 break;
412 }
413 + case "branch": {
414 + terminal.test = fn(terminal.test);
415 + break;
416 + }
417 case "switch": {
418 terminal.test = fn(terminal.test);
419 for (const case_ of terminal.cases) {
@@ -434,6 +454,10 @@ export function* eachTerminalOperand(terminal: Terminal): Iterable<Place> {
454 yield terminal.test;
455 break;
456 }
457 + case "branch": {
458 + yield terminal.test;
459 + break;
460 + }
461 case "switch": {
462 yield terminal.test;
463 for (const case_ of terminal.cases) {
compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts
+3
@@ -360,6 +360,9 @@ class Driver {
360 }
361 break;
362 }
363 + case "branch": {
364 + todo("Implement tree visitor for branch terminal");
365 + }
366 case "logical": {
367 todo("Implement tree visitor for logical terminal");
368 }
compiler/forget/src/Utils/VisualizeHIRMermaid.ts
+9
@@ -77,6 +77,10 @@ function printTerminalLabel(terminal: Terminal): string {
77 buffer.push(`If (${printPlace(terminal.test)})`);
78 break;
79 }
80 + case "branch": {
81 + buffer.push(`Branch (${printPlace(terminal.test)})`);
82 + break;
83 + }
84 case "goto": {
85 buffer.push("Goto");
86 break;
@@ -130,6 +134,11 @@ function printTerminalArrows(blockId: BlockId, terminal: Terminal): string {
134 }
135 break;
136 }
137 + case "branch": {
138 + buffer.push(printJumpArrow(blockId, terminal.consequent, "then"));
139 + buffer.push(printJumpArrow(blockId, terminal.alternate, "else"));
140 + break;
141 + }
142 case "logical": {
143 buffer.push(printJumpArrow(blockId, terminal.test, "test"));
144 buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));