diff --git a/compiler/forget/src/HIR/Codegen.ts b/compiler/forget/src/HIR/Codegen.ts index 8019b7f924..4004871607 100644 --- a/compiler/forget/src/HIR/Codegen.ts +++ b/compiler/forget/src/HIR/Codegen.ts @@ -141,12 +141,12 @@ class CodegenVisitor } leaveValueBlock( block: t.Statement[], - place: t.Expression | null + place: { value: t.Expression; id: InstructionId } | null ): t.Expression { this.depth--; if (block.length === 0) { invariant(place !== null, "Unexpected empty value block"); - return place; + return place.value; } const expressions = block.map((stmt) => { switch (stmt.type) { @@ -160,7 +160,7 @@ class CodegenVisitor } }); if (place !== null) { - expressions.push(place); + expressions.push(place.value); } return t.sequenceExpression(expressions); } diff --git a/compiler/forget/src/HIR/HIR.ts b/compiler/forget/src/HIR/HIR.ts index f36caa8bf2..a4d8a4c9d3 100644 --- a/compiler/forget/src/HIR/HIR.ts +++ b/compiler/forget/src/HIR/HIR.ts @@ -61,7 +61,10 @@ export type ReactiveBlock = Array; export type ReactiveValueBlock = { kind: "value-block"; instructions: ReactiveBlock; - value: InstructionValue | null; + last: { + value: InstructionValue; + id: InstructionId; + } | null; }; export type ReactiveStatement = diff --git a/compiler/forget/src/HIR/HIRTreeVisitor.ts b/compiler/forget/src/HIR/HIRTreeVisitor.ts index 3ee7a8dd8e..cfe91654fe 100644 --- a/compiler/forget/src/HIR/HIRTreeVisitor.ts +++ b/compiler/forget/src/HIR/HIRTreeVisitor.ts @@ -519,7 +519,10 @@ class Driver< } const value = lastValue !== null - ? this.visitor.visitValue(lastValue.value, lastValue.id) + ? { + value: this.visitor.visitValue(lastValue.value, lastValue.id), + id: lastValue.id, + } : null; return this.visitor.leaveValueBlock(valueBlock, value); } @@ -873,7 +876,10 @@ export interface Visitor< * Converts the visitor's value block (and final value) to the visitor's * value representation. */ - leaveValueBlock(block: TValueBlock, value: TValue | null): TValue; + leaveValueBlock( + block: TValueBlock, + value: { value: TValue; id: InstructionId } | null + ): TValue; enterInitBlock(block: TBlockBuilder): TValueBlock; diff --git a/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts b/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts index 8a90029263..5b39e05dd1 100644 --- a/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts +++ b/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts @@ -152,7 +152,7 @@ class ReactiveFunctionBuilder return { kind: "value-block", instructions: [], - value: null, + last: null, }; } appendValueBlock(block: ReactiveValueBlock, item: ReactiveStatement): void { @@ -160,14 +160,18 @@ class ReactiveFunctionBuilder } leaveValueBlock( block: ReactiveValueBlock, - value: InstructionValue | ReactiveValueBlock | null + last: { + value: InstructionValue | ReactiveValueBlock; + id: InstructionId; + } | null ): InstructionValue | ReactiveValueBlock { - if (value !== null) { + if (last !== null) { + const { id, value } = last; invariant( value.kind !== "value-block", "Expected value block to end in a value" ); - block.value = value; + block.last = { id, value }; } return block; } diff --git a/compiler/forget/src/ReactiveScopes/BuildReactiveFunctionWithoutScopes.ts b/compiler/forget/src/ReactiveScopes/BuildReactiveFunctionWithoutScopes.ts index 690c932d0b..de081db311 100644 --- a/compiler/forget/src/ReactiveScopes/BuildReactiveFunctionWithoutScopes.ts +++ b/compiler/forget/src/ReactiveScopes/BuildReactiveFunctionWithoutScopes.ts @@ -19,11 +19,7 @@ import { ReactiveTerminal, ReactiveValueBlock, } from "../HIR/HIR"; -import { - BlockTerminal, - Visitor, - visitTreeForReactiveFunction as visitTree, -} from "../HIR/ReactiveFunctionVisitor"; +import { BlockTerminal, Visitor, visitTree } from "../HIR/HIRTreeVisitor"; import { assertExhaustive } from "../Utils/utils"; export function buildReactiveFunction(fn: HIRFunction): ReactiveFunction { @@ -86,7 +82,7 @@ class ReactiveFunctionBuilder return { kind: "value-block", instructions: [], - value: null, + last: null, }; } appendValueBlock(block: ReactiveValueBlock, item: ReactiveStatement): void { @@ -94,14 +90,18 @@ class ReactiveFunctionBuilder } leaveValueBlock( block: ReactiveValueBlock, - value: InstructionValue | ReactiveValueBlock | null + last: { + value: InstructionValue | ReactiveValueBlock; + id: InstructionId; + } | null ): InstructionValue | ReactiveValueBlock { - if (value !== null) { + if (last !== null) { + const { id, value } = last; invariant( value.kind !== "value-block", "Expected value block to end in a value" ); - block.value = value; + block.last = { id, value }; } return block; } diff --git a/compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts b/compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts index e3274393b9..9cd3c19995 100644 --- a/compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts +++ b/compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts @@ -331,12 +331,12 @@ function codegenForInit( init: ReactiveValueBlock ): t.Expression | t.VariableDeclaration | null { const body = codegenBlock(cx, init.instructions).body; - if (init.value !== null) { + if (init.last !== null) { invariant( body.length === 0, "Expected for init block to produce only temporaries" ); - return codegenInstructionValue(cx.temp, init.value); + return codegenInstructionValue(cx.temp, init.last.value); } else { invariant( body.length === 1, @@ -363,8 +363,8 @@ function codegenValueBlock( todoInvariant(false, `Handle conversion of ${stmt.type} to expression`); } }); - if (block.value !== null) { - const value = codegenInstructionValue(cx.temp, block.value); + if (block.last !== null) { + const value = codegenInstructionValue(cx.temp, block.last.value); expressions.push(value); } invariant( diff --git a/compiler/forget/src/ReactiveScopes/InferReactiveScopes.ts b/compiler/forget/src/ReactiveScopes/InferReactiveScopes.ts index 4e7fa7d19f..f2c47bd8a4 100644 --- a/compiler/forget/src/ReactiveScopes/InferReactiveScopes.ts +++ b/compiler/forget/src/ReactiveScopes/InferReactiveScopes.ts @@ -268,7 +268,10 @@ class MergeOverlappingReactiveScopesVisitor leaveInitBlock(block: void): void { this.leaveBlock(); } - leaveValueBlock(block: void, value: void): void { + leaveValueBlock( + block: void, + value: { value: void; id: InstructionId } | null + ): void { this.leaveBlock(); } visitValue(value: InstructionValue, id: InstructionId): void { @@ -389,7 +392,10 @@ class AlignReactiveScopesToBlockScopeRangeVisitor this.blockScopes.push({ kind: "value", scopes: [] }); } appendValueBlock(block: void, item: void): void {} - leaveValueBlock(block: void, value: void): void { + leaveValueBlock( + block: void, + value: { value: void; id: InstructionId } | null + ): void { const lastScope = this.blockScopes.pop(); invariant( lastScope !== undefined && lastScope.kind === "value", @@ -409,7 +415,7 @@ class AlignReactiveScopesToBlockScopeRangeVisitor } appendInitBlock(block: void, item: void): void {} leaveInitBlock(block: void): void { - this.leaveValueBlock(block); + this.leaveValueBlock(block, null); } visitInstruction(instruction: Instruction, value: void): void { diff --git a/compiler/forget/src/ReactiveScopes/PrintReactiveFunction.ts b/compiler/forget/src/ReactiveScopes/PrintReactiveFunction.ts index 7149e9e9b8..8bd7294689 100644 --- a/compiler/forget/src/ReactiveScopes/PrintReactiveFunction.ts +++ b/compiler/forget/src/ReactiveScopes/PrintReactiveFunction.ts @@ -104,8 +104,8 @@ function printValueBlock(writer: Writer, block: ReactiveValueBlock): void { for (const instr of block.instructions) { printReactiveInstruction(writer, instr); } - if (block.value !== null) { - writer.writeLine(printInstructionValue(block.value)); + if (block.last !== null) { + writer.writeLine(printInstructionValue(block.last.value)); } }); } diff --git a/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts b/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts index 818e14a642..def6f9b899 100644 --- a/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts +++ b/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts @@ -260,8 +260,8 @@ function visitValueBlock(context: Context, block: ReactiveValueBlock): void { visitInstruction(context, initItem.instruction); } } - if (block.value !== null) { - visitInstructionValue(context, block.value, null); + if (block.last !== null) { + visitInstructionValue(context, block.last.value, null); } } diff --git a/compiler/forget/src/ReactiveScopes/RenameVariables.ts b/compiler/forget/src/ReactiveScopes/RenameVariables.ts index 3cdc50d78d..0f8a99175a 100644 --- a/compiler/forget/src/ReactiveScopes/RenameVariables.ts +++ b/compiler/forget/src/ReactiveScopes/RenameVariables.ts @@ -83,8 +83,8 @@ function visitValueBlock(scopes: Scopes, block: ReactiveValueBlock): void { scopes.visit(stmt.instruction.lvalue.place.identifier); } } - if (block.value !== null) { - for (const operand of eachInstructionValueOperand(block.value)) { + if (block.last !== null) { + for (const operand of eachInstructionValueOperand(block.last.value)) { scopes.visit(operand.identifier); } } diff --git a/compiler/forget/src/ReactiveScopes/visitors.ts b/compiler/forget/src/ReactiveScopes/visitors.ts index e23dd5844e..6b7f172b33 100644 --- a/compiler/forget/src/ReactiveScopes/visitors.ts +++ b/compiler/forget/src/ReactiveScopes/visitors.ts @@ -74,8 +74,8 @@ export function visitFunction( } function visitValueBlock(block: ReactiveValueBlock): void { visitBlock(block.instructions); - if (block.value !== null && visitValue) { - visitValue(block.value); + if (block.last !== null && visitValue) { + visitValue(block.last.value); } } visitBlock(fn.body);