Value block final value has an InstrId

This commit is contained in:
Joe Savona
2023-01-12 09:12:01 -08:00
parent df8945b684
commit 09246207c7
11 changed files with 53 additions and 34 deletions
+3 -3
View File
@@ -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);
}
+4 -1
View File
@@ -61,7 +61,10 @@ export type ReactiveBlock = Array<ReactiveStatement>;
export type ReactiveValueBlock = {
kind: "value-block";
instructions: ReactiveBlock;
value: InstructionValue | null;
last: {
value: InstructionValue;
id: InstructionId;
} | null;
};
export type ReactiveStatement =
+8 -2
View File
@@ -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;
@@ -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;
}
@@ -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;
}
@@ -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(
@@ -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 {
@@ -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));
}
});
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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);