diff --git a/compiler/forget/src/HIR/BuildHIR.ts b/compiler/forget/src/HIR/BuildHIR.ts index 0c6eec81ed..19379f7fc8 100644 --- a/compiler/forget/src/HIR/BuildHIR.ts +++ b/compiler/forget/src/HIR/BuildHIR.ts @@ -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; + const _optional = expr.get("optional"); + + return todo("OptionalCallExpression"); + } case "CallExpression": { const expr = exprPath as NodePath; const calleePath = expr.get("callee"); diff --git a/compiler/forget/src/HIR/HIR.ts b/compiler/forget/src/HIR/HIR.ts index e79cd69c8e..aadc215d9e 100644 --- a/compiler/forget/src/HIR/HIR.ts +++ b/compiler/forget/src/HIR/HIR.ts @@ -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 diff --git a/compiler/forget/src/HIR/HIRBuilder.ts b/compiler/forget/src/HIR/HIRBuilder.ts index 6a7d38320e..3671265730 100644 --- a/compiler/forget/src/HIR/HIRBuilder.ts +++ b/compiler/forget/src/HIR/HIRBuilder.ts @@ -624,6 +624,7 @@ export function reversePostorderBlocks(func: HIR): void { } break; } + case "optional-call": case "ternary": case "logical": { visit(terminal.test); diff --git a/compiler/forget/src/HIR/PrintHIR.ts b/compiler/forget/src/HIR/PrintHIR.ts index f7c3087577..766192ca08 100644 --- a/compiler/forget/src/HIR/PrintHIR.ts +++ b/compiler/forget/src/HIR/PrintHIR.ts @@ -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 { 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; diff --git a/compiler/forget/src/HIR/visitors.ts b/compiler/forget/src/HIR/visitors.ts index 1dc6060b61..0951313b1d 100644 --- a/compiler/forget/src/HIR/visitors.ts +++ b/compiler/forget/src/HIR/visitors.ts @@ -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 { } 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 { } break; } + case "optional-call": case "ternary": case "logical": case "do-while": diff --git a/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts b/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts index a775633b06..81499ce6e7 100644 --- a/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts +++ b/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts @@ -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: { diff --git a/compiler/forget/src/Utils/VisualizeHIRMermaid.ts b/compiler/forget/src/Utils/VisualizeHIRMermaid.ts index da2e50571f..19b0cfcf59 100644 --- a/compiler/forget/src/Utils/VisualizeHIRMermaid.ts +++ b/compiler/forget/src/Utils/VisualizeHIRMermaid.ts @@ -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;