Scaffolding for LogicalTerminal
Joe Savona committed
Jan 10, 2023 at 13:49 UTC
a4fc97534051d18c0a46238afd0a63c77e17b5a6
6 files changed
+49
-1
compiler/forget/src/HIR/HIR.ts
+10
-1
@@ -162,7 +162,8 @@ export type Terminal =
162
| IfTerminal
163
| SwitchTerminal
164
| ForTerminal
165
- | WhileTerminal;
165
+ | WhileTerminal
166
+ | LogicalTerminal;
167
168
/**
169
* Terminal nodes allowed for a value block
@@ -226,6 +227,14 @@ export type ForTerminal = {
227
id: InstructionId;
228
};
229
230
+export type LogicalTerminal = {
231
+ kind: "logical";
232
+ operator: t.LogicalExpression["operator"];
233
+ test: BlockId;
234
+ fallthrough: BlockId;
235
+ id: InstructionId;
236
+};
237
+
238
/**
239
* Instructions generally represent expressions but with all nesting flattened away,
240
* such that all operands to each instruction are either primitive values OR are
compiler/forget/src/HIR/HIRBuilder.ts
+4
@@ -503,6 +503,10 @@ export function reversePostorderBlocks(func: HIR): void {
503
}
504
break;
505
}
506
+ case "logical": {
507
+ visit(terminal.test);
508
+ break;
509
+ }
510
case "while": {
511
visit(terminal.test);
512
break;
compiler/forget/src/HIR/HIRTreeVisitor.ts
+4
@@ -6,6 +6,7 @@
6
*/
7
8
import invariant from "invariant";
9
+import todo from "../Utils/todo";
10
import { assertExhaustive } from "../Utils/utils";
11
import {
12
BasicBlock,
@@ -445,6 +446,9 @@ class Driver<
446
}
447
break;
448
}
449
+ case "logical": {
450
+ todo("Implement tree visitor for logical terminal");
451
+ }
452
case "goto": {
453
this.visitor.visitTerminalId(terminal.id);
454
switch (terminal.variant) {
compiler/forget/src/HIR/PrintHIR.ts
+5
@@ -79,6 +79,7 @@ export function printMixedHIR(
79
}
80
switch (value.kind) {
81
case "if":
82
+ case "logical":
83
case "return":
84
case "switch":
85
case "throw":
@@ -135,6 +136,10 @@ export function printTerminal(terminal: Terminal): Array<string> | string {
136
}`;
137
break;
138
}
139
+ case "logical": {
140
+ value = `[${terminal.id}] Logical ${terminal.operator} test:bb${terminal.test} fallthrough=bb${terminal.fallthrough}`;
141
+ break;
142
+ }
143
case "throw": {
144
value = `[${terminal.id}] Throw ${printPlace(terminal.value)}`;
145
break;
compiler/forget/src/HIR/visitors.ts
+17
@@ -241,6 +241,17 @@ export function mapTerminalSuccessors(
241
id: makeInstructionId(0),
242
};
243
}
244
+ case "logical": {
245
+ const test = fn(terminal.test);
246
+ const fallthrough = fn(terminal.fallthrough);
247
+ return {
248
+ kind: "logical",
249
+ test,
250
+ fallthrough,
251
+ operator: terminal.operator,
252
+ id: makeInstructionId(0),
253
+ };
254
+ }
255
case "return": {
256
return {
257
kind: "return",
@@ -312,6 +323,10 @@ export function* eachTerminalSuccessor(terminal: Terminal): Iterable<BlockId> {
323
}
324
break;
325
}
326
+ case "logical": {
327
+ yield terminal.test;
328
+ break;
329
+ }
330
case "return": {
331
break;
332
}
@@ -361,6 +376,7 @@ export function mapTerminalOperands(
376
}
377
break;
378
}
379
+ case "logical":
380
case "while":
381
case "for":
382
case "goto": {
@@ -399,6 +415,7 @@ export function* eachTerminalOperand(terminal: Terminal): Iterable<Place> {
415
}
416
break;
417
}
418
+ case "logical":
419
case "while":
420
case "for":
421
case "goto": {
compiler/forget/src/Utils/VisualizeHIRMermaid.ts
+9
@@ -95,6 +95,10 @@ function printTerminalLabel(terminal: Terminal): string {
95
case "throw":
96
buffer.push(`Throw ${printPlace(terminal.value)}`);
97
break;
98
+ case "logical": {
99
+ buffer.push(`Logical ${terminal.operator}`);
100
+ break;
101
+ }
102
case "while":
103
buffer.push("While");
104
break;
@@ -123,6 +127,11 @@ function printTerminalArrows(blockId: BlockId, terminal: Terminal): string {
127
}
128
break;
129
}
130
+ case "logical": {
131
+ buffer.push(printJumpArrow(blockId, terminal.test, "test"));
132
+ buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));
133
+ break;
134
+ }
135
case "goto": {
136
buffer.push(printJumpArrow(blockId, terminal.block, null));
137
break;