@samitouri / QOS-React-2 / commits / 40bd9b060c

Scaffolding for OptionalCall

Adds a new `optional-call` terminal and sets up the appropriate handling in the visitors, with lowering/reactivefunction/codegen as todos for now and implemented in follow-ups.

Joe Savona committed Mar 24, 2023 at 14:22 UTC 40bd9b060ce72b16d135018deec95bbf6b24e33f
7 files changed +50 -1
compiler/forget/src/HIR/BuildHIR.ts
+7
@@ -11,6 +11,7 @@ import { Expression } from "@babel/types";
11 import invariant from "invariant";
12 import { CompilerError, ErrorSeverity } from "../CompilerError";
13 import { Err, Ok, Result } from "../Utils/Result";
14 +import todo from "../Utils/todo";
15 import { assertExhaustive } from "../Utils/utils";
16 import { Environment, EnvironmentOptions } from "./Environment";
17 import {
@@ -939,6 +940,12 @@ function lowerExpression(
940 loc: exprLoc,
941 };
942 }
943 + case "OptionalCallExpression": {
944 + const expr = exprPath as NodePath<t.OptionalCallExpression>;
945 + const _optional = expr.get("optional");
946 +
947 + return todo("OptionalCallExpression");
948 + }
949 case "CallExpression": {
950 const expr = exprPath as NodePath<t.CallExpression>;
951 const calleePath = expr.get("callee");
compiler/forget/src/HIR/HIR.ts
+10 -1
@@ -251,7 +251,8 @@ export type Terminal =
251 | DoWhileTerminal
252 | WhileTerminal
253 | LogicalTerminal
254 - | TernaryTerminal;
254 + | TernaryTerminal
255 + | OptionalCallTerminal;
256
257 /**
258 * Terminal nodes allowed for a value block
@@ -352,6 +353,14 @@ export type TernaryTerminal = {
353 loc: SourceLocation;
354 };
355
356 +export type OptionalCallTerminal = {
357 + kind: "optional-call";
358 + test: BlockId;
359 + fallthrough: BlockId;
360 + id: InstructionId;
361 + loc: SourceLocation;
362 +};
363 +
364 /**
365 * Instructions generally represent expressions but with all nesting flattened away,
366 * such that all operands to each instruction are either primitive values OR are
compiler/forget/src/HIR/HIRBuilder.ts
+1
@@ -624,6 +624,7 @@ export function reversePostorderBlocks(func: HIR): void {
624 }
625 break;
626 }
627 + case "optional-call":
628 case "ternary":
629 case "logical": {
630 visit(terminal.test);
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 "optional-call":
83 case "branch":
84 case "if":
85 case "logical":
@@ -155,6 +156,10 @@ export function printTerminal(terminal: Terminal): Array<string> | string {
156 value = `[${terminal.id}] Ternary test:bb${terminal.test} fallthrough=bb${terminal.fallthrough}`;
157 break;
158 }
159 + case "optional-call": {
160 + value = `[${terminal.id}] OptionalCall test:bb${terminal.test} fallthrough=bb${terminal.fallthrough}`;
161 + break;
162 + }
163 case "throw": {
164 value = `[${terminal.id}] Throw ${printPlace(terminal.value)}`;
165 break;
compiler/forget/src/HIR/visitors.ts
+14
@@ -562,6 +562,17 @@ export function mapTerminalSuccessors(
562 loc: terminal.loc,
563 };
564 }
565 + case "optional-call": {
566 + const test = fn(terminal.test);
567 + const fallthrough = fn(terminal.fallthrough);
568 + return {
569 + kind: "optional-call",
570 + test,
571 + fallthrough,
572 + id: makeInstructionId(0),
573 + loc: terminal.loc,
574 + };
575 + }
576 case "return": {
577 return {
578 kind: "return",
@@ -655,6 +666,7 @@ export function* eachTerminalSuccessor(terminal: Terminal): Iterable<BlockId> {
666 }
667 break;
668 }
669 + case "optional-call":
670 case "ternary":
671 case "logical": {
672 yield terminal.test;
@@ -719,6 +731,7 @@ export function mapTerminalOperands(
731 }
732 break;
733 }
734 + case "optional-call":
735 case "ternary":
736 case "logical":
737 case "do-while":
@@ -765,6 +778,7 @@ export function* eachTerminalOperand(terminal: Terminal): Iterable<Place> {
778 }
779 break;
780 }
781 + case "optional-call":
782 case "ternary":
783 case "logical":
784 case "do-while":
compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts
+4
@@ -29,6 +29,7 @@ import {
29 ReactiveValue,
30 Terminal,
31 } from "../HIR/HIR";
32 +import todo from "../Utils/todo";
33 import { assertExhaustive } from "../Utils/utils";
34
35 /**
@@ -481,6 +482,9 @@ class Driver {
482 this.visitBlock(this.cx.ir.blocks.get(fallthroughId)!, blockValue);
483 break;
484 }
485 + case "optional-call": {
486 + todo("BuildReactiveFunction: support optional-call terminal");
487 + }
488 case "goto": {
489 switch (terminal.variant) {
490 case GotoVariant.Break: {
compiler/forget/src/Utils/VisualizeHIRMermaid.ts
+9
@@ -107,6 +107,10 @@ function printTerminalLabel(terminal: Terminal): string {
107 buffer.push("Ternary");
108 break;
109 }
110 + case "optional-call": {
111 + buffer.push("OptionalCall");
112 + break;
113 + }
114 case "do-while": {
115 buffer.push("DoWhile");
116 break;
@@ -157,6 +161,11 @@ function printTerminalArrows(blockId: BlockId, terminal: Terminal): string {
161 buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));
162 break;
163 }
164 + case "optional-call": {
165 + buffer.push(printJumpArrow(blockId, terminal.test, "test"));
166 + buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));
167 + break;
168 + }
169 case "goto": {
170 buffer.push(printJumpArrow(blockId, terminal.block, null));
171 break;