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.
This commit is contained in:
Joe Savona
2023-03-24 14:22:13 -07:00
parent 568048af0f
commit 40bd9b060c
7 changed files with 50 additions and 1 deletions
+7
View File
@@ -11,6 +11,7 @@ import { Expression } from "@babel/types";
import invariant from "invariant";
import { CompilerError, ErrorSeverity } from "../CompilerError";
import { Err, Ok, Result } from "../Utils/Result";
import todo from "../Utils/todo";
import { assertExhaustive } from "../Utils/utils";
import { Environment, EnvironmentOptions } from "./Environment";
import {
@@ -939,6 +940,12 @@ function lowerExpression(
loc: exprLoc,
};
}
case "OptionalCallExpression": {
const expr = exprPath as NodePath<t.OptionalCallExpression>;
const _optional = expr.get("optional");
return todo("OptionalCallExpression");
}
case "CallExpression": {
const expr = exprPath as NodePath<t.CallExpression>;
const calleePath = expr.get("callee");
+10 -1
View File
@@ -251,7 +251,8 @@ export type Terminal =
| DoWhileTerminal
| WhileTerminal
| LogicalTerminal
| TernaryTerminal;
| TernaryTerminal
| OptionalCallTerminal;
/**
* Terminal nodes allowed for a value block
@@ -352,6 +353,14 @@ export type TernaryTerminal = {
loc: SourceLocation;
};
export type OptionalCallTerminal = {
kind: "optional-call";
test: BlockId;
fallthrough: BlockId;
id: InstructionId;
loc: SourceLocation;
};
/**
* Instructions generally represent expressions but with all nesting flattened away,
* such that all operands to each instruction are either primitive values OR are
+1
View File
@@ -624,6 +624,7 @@ export function reversePostorderBlocks(func: HIR): void {
}
break;
}
case "optional-call":
case "ternary":
case "logical": {
visit(terminal.test);
+5
View File
@@ -79,6 +79,7 @@ export function printMixedHIR(
return printInstruction(value);
}
switch (value.kind) {
case "optional-call":
case "branch":
case "if":
case "logical":
@@ -155,6 +156,10 @@ export function printTerminal(terminal: Terminal): Array<string> | string {
value = `[${terminal.id}] Ternary test:bb${terminal.test} fallthrough=bb${terminal.fallthrough}`;
break;
}
case "optional-call": {
value = `[${terminal.id}] OptionalCall test:bb${terminal.test} fallthrough=bb${terminal.fallthrough}`;
break;
}
case "throw": {
value = `[${terminal.id}] Throw ${printPlace(terminal.value)}`;
break;
+14
View File
@@ -562,6 +562,17 @@ export function mapTerminalSuccessors(
loc: terminal.loc,
};
}
case "optional-call": {
const test = fn(terminal.test);
const fallthrough = fn(terminal.fallthrough);
return {
kind: "optional-call",
test,
fallthrough,
id: makeInstructionId(0),
loc: terminal.loc,
};
}
case "return": {
return {
kind: "return",
@@ -655,6 +666,7 @@ export function* eachTerminalSuccessor(terminal: Terminal): Iterable<BlockId> {
}
break;
}
case "optional-call":
case "ternary":
case "logical": {
yield terminal.test;
@@ -719,6 +731,7 @@ export function mapTerminalOperands(
}
break;
}
case "optional-call":
case "ternary":
case "logical":
case "do-while":
@@ -765,6 +778,7 @@ export function* eachTerminalOperand(terminal: Terminal): Iterable<Place> {
}
break;
}
case "optional-call":
case "ternary":
case "logical":
case "do-while":
@@ -29,6 +29,7 @@ import {
ReactiveValue,
Terminal,
} from "../HIR/HIR";
import todo from "../Utils/todo";
import { assertExhaustive } from "../Utils/utils";
/**
@@ -481,6 +482,9 @@ class Driver {
this.visitBlock(this.cx.ir.blocks.get(fallthroughId)!, blockValue);
break;
}
case "optional-call": {
todo("BuildReactiveFunction: support optional-call terminal");
}
case "goto": {
switch (terminal.variant) {
case GotoVariant.Break: {
@@ -107,6 +107,10 @@ function printTerminalLabel(terminal: Terminal): string {
buffer.push("Ternary");
break;
}
case "optional-call": {
buffer.push("OptionalCall");
break;
}
case "do-while": {
buffer.push("DoWhile");
break;
@@ -157,6 +161,11 @@ function printTerminalArrows(blockId: BlockId, terminal: Terminal): string {
buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));
break;
}
case "optional-call": {
buffer.push(printJumpArrow(blockId, terminal.test, "test"));
buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));
break;
}
case "goto": {
buffer.push(printJumpArrow(blockId, terminal.block, null));
break;