From cd115ec128a80a69c4aac253c853d12026f1ea61 Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Sun, 4 Jun 2023 21:25:59 -0400 Subject: [PATCH] Scaffold for sequence terminal I realized that we can use our value block system to fix _most_ of the remaining order-of-evaluation issues we had with sequence expressions. This PR adds a new SequenceTerminal to HIR; there is already a ReactiveFunction equivalent (ReactiveSequenceValue) that the next PR will convert this terminal into. --- compiler/forget/src/HIR/HIR.ts | 12 ++++++++-- compiler/forget/src/HIR/HIRBuilder.ts | 4 ++++ compiler/forget/src/HIR/PrintHIR.ts | 5 +++++ compiler/forget/src/HIR/visitors.ts | 22 +++++++++++++++++++ .../ReactiveScopes/BuildReactiveFunction.ts | 1 + .../forget/src/Utils/VisualizeHIRMermaid.ts | 9 ++++++++ 6 files changed, 51 insertions(+), 2 deletions(-) diff --git a/compiler/forget/src/HIR/HIR.ts b/compiler/forget/src/HIR/HIR.ts index b1ecd44d3f..923ae83ca1 100644 --- a/compiler/forget/src/HIR/HIR.ts +++ b/compiler/forget/src/HIR/HIR.ts @@ -279,7 +279,8 @@ export type Terminal = | LogicalTerminal | TernaryTerminal | OptionalTerminal - | LabelTerminal; + | LabelTerminal + | SequenceTerminal; function _staticInvariantTerminalHasLocation( terminal: Terminal @@ -298,7 +299,6 @@ function _staticInvariantTerminalHasInstructionId( /** * Terminal nodes allowed for a value block */ -export type ValueTerminal = IfTerminal | GotoTerminal; // A terminal that couldn't be lowered correctly. export type UnsupportedTerminal = { kind: "unsupported"; @@ -437,6 +437,14 @@ export type OptionalTerminal = { loc: SourceLocation; }; +export type SequenceTerminal = { + kind: "sequence"; + block: 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 8955c9447d..bf3b2ec0a9 100644 --- a/compiler/forget/src/HIR/HIRBuilder.ts +++ b/compiler/forget/src/HIR/HIRBuilder.ts @@ -697,6 +697,10 @@ export function reversePostorderBlocks(func: HIR): void { visit(terminal.block); break; } + case "sequence": { + visit(terminal.block); + break; + } case "unsupported": { break; } diff --git a/compiler/forget/src/HIR/PrintHIR.ts b/compiler/forget/src/HIR/PrintHIR.ts index c993f1d651..753ae91beb 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 "sequence": case "label": case "optional": case "branch": @@ -220,6 +221,10 @@ export function printTerminal(terminal: Terminal): Array | string { }`; break; } + case "sequence": { + value = `[${terminal.id}] Sequence block=bb${terminal.block} fallthrough=bb${terminal.fallthrough}`; + break; + } case "unsupported": { value = `Unsupported`; break; diff --git a/compiler/forget/src/HIR/visitors.ts b/compiler/forget/src/HIR/visitors.ts index c49ad29c46..fcd7caaf2f 100644 --- a/compiler/forget/src/HIR/visitors.ts +++ b/compiler/forget/src/HIR/visitors.ts @@ -704,6 +704,17 @@ export function mapTerminalSuccessors( loc: terminal.loc, }; } + case "sequence": { + const block = fn(terminal.block); + const fallthrough = fn(terminal.fallthrough); + return { + kind: "sequence", + block, + fallthrough, + id: makeInstructionId(0), + loc: terminal.loc, + }; + } case "unsupported": { return terminal; } @@ -737,6 +748,7 @@ export function terminalFallthrough(terminal: Terminal): BlockId | null { case "label": case "logical": case "optional": + case "sequence": case "switch": case "ternary": case "while": { @@ -813,6 +825,10 @@ export function mapOptionalFallthroughs( } break; } + case "sequence": { + const _: BlockId = terminal.fallthrough; + break; + } default: { assertExhaustive( terminal, @@ -881,6 +897,10 @@ export function* eachTerminalSuccessor(terminal: Terminal): Iterable { yield terminal.block; break; } + case "sequence": { + yield terminal.block; + break; + } case "unsupported": break; default: { @@ -920,6 +940,7 @@ export function mapTerminalOperands( terminal.value = fn(terminal.value); break; } + case "sequence": case "label": case "optional": case "ternary": @@ -967,6 +988,7 @@ export function* eachTerminalOperand(terminal: Terminal): Iterable { yield terminal.value; break; } + case "sequence": case "label": case "optional": case "ternary": diff --git a/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts b/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts index e2aa716365..f3be13fa34 100644 --- a/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts +++ b/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts @@ -570,6 +570,7 @@ class Driver { break; } + case "sequence": case "optional": case "ternary": case "logical": { diff --git a/compiler/forget/src/Utils/VisualizeHIRMermaid.ts b/compiler/forget/src/Utils/VisualizeHIRMermaid.ts index 73bd38fbab..6696c85ef5 100644 --- a/compiler/forget/src/Utils/VisualizeHIRMermaid.ts +++ b/compiler/forget/src/Utils/VisualizeHIRMermaid.ts @@ -135,6 +135,10 @@ function printTerminalLabel(terminal: Terminal): string { buffer.push("Label"); break; } + case "sequence": { + buffer.push("Sequence"); + break; + } case "unsupported": { break; } @@ -237,6 +241,11 @@ function printTerminalArrows(blockId: BlockId, terminal: Terminal): string { } break; } + case "sequence": { + buffer.push(printJumpArrow(blockId, terminal.block, "block")); + buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough")); + break; + } case "throw": case "return": case "unsupported": {