[valueblocks] For.init is a value block
Joe Savona committed
Jan 31, 2023 at 13:39 UTC
fa525e0b6f58602f5d9578828c64939a1d818951
6 files changed
+39
-25
compiler/forget/src/HIR/HIR.ts
+1
-1
@@ -171,7 +171,7 @@ export type ReactiveWhileTerminal = {
171
};
172
export type ReactiveForTerminal = {
173
kind: "for";
174
- init: ReactiveValueBlock;
174
+ init: ReactiveValue;
175
test: ReactiveValue;
176
update: ReactiveValue;
177
loop: ReactiveBlock;
compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts
+23
-7
@@ -307,13 +307,29 @@ class Driver {
307
);
308
scheduleIds.push(scheduleId);
309
310
- const initBlock = this.cx.ir.blocks.get(terminal.init)!;
311
- const initTerminal = initBlock.terminal;
312
- invariant(
313
- initTerminal.kind === "goto",
314
- "Expected for loop init block to end in a goto"
315
- );
316
- const initValue = this.visitInitBlock(blockValue, initBlock);
310
+ const init = this.visitValueBlockNew(terminal.init, terminal.loc);
311
+ const initBlock = this.cx.ir.blocks.get(init.block)!;
312
+ let initValue = init.value;
313
+ if (initValue.kind === "SequenceExpression") {
314
+ const last = initBlock.instructions.at(-1)!;
315
+ initValue.instructions.push(last);
316
+ initValue.value = {
317
+ kind: "Primitive",
318
+ value: undefined,
319
+ loc: terminal.loc,
320
+ };
321
+ } else {
322
+ initValue = {
323
+ kind: "SequenceExpression",
324
+ instructions: [initBlock.instructions.at(-1)!],
325
+ loc: terminal.loc,
326
+ value: {
327
+ kind: "Primitive",
328
+ value: undefined,
329
+ loc: terminal.loc,
330
+ },
331
+ };
332
+ }
333
334
const testValue = this.visitValueBlockNew(
335
terminal.test,
compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+11
-13
@@ -340,26 +340,24 @@ function codegenInstructionNullable(
340
341
function codegenForInit(
342
cx: Context,
343
- init: ReactiveValueBlock
343
+ init: ReactiveValue
344
): t.Expression | t.VariableDeclaration | null {
345
- const body = codegenBlock(cx, init.instructions).body;
346
- if (init.last !== null) {
347
- invariant(
348
- body.length === 0,
349
- "Expected for init block to produce only temporaries"
350
- );
351
- return codegenInstructionValue(cx, init.last.value);
352
- } else {
353
- invariant(
354
- body.length === 1,
355
- "Expected for init to have a variable declaration"
356
- );
345
+ if (init.kind === "SequenceExpression") {
346
+ const body = codegenBlock(
347
+ cx,
348
+ init.instructions.map((instruction) => ({
349
+ kind: "instruction",
350
+ instruction,
351
+ }))
352
+ ).body;
353
const declaration = body[0]!;
354
invariant(
355
declaration.type === "VariableDeclaration",
356
"Expected a variable declaration"
357
);
358
return declaration;
359
+ } else {
360
+ return codegenInstructionValue(cx, init);
361
}
362
}
363
compiler/forget/src/ReactiveScopes/PrintReactiveFunction.ts
+1
-1
@@ -231,7 +231,7 @@ function printTerminal(writer: Writer, terminal: ReactiveTerminal): void {
231
}
232
case "for": {
233
writer.writeLine("[${terminal.id}] for (");
234
- printValueBlock(writer, terminal.init);
234
+ printReactiveValue(writer, terminal.init);
235
writer.writeLine(";");
236
printReactiveValue(writer, terminal.test);
237
writer.writeLine(";");
compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts
+1
-1
@@ -230,7 +230,7 @@ function visit(context: Context, block: ReactiveBlock): void {
230
break;
231
}
232
case "for": {
233
- visitValueBlock(context, terminal.init);
233
+ visitReactiveValue(context, terminal.init);
234
visitReactiveValue(context, terminal.test);
235
visitReactiveValue(context, terminal.update);
236
visit(context, terminal.loop);
compiler/forget/src/ReactiveScopes/visitors.ts
+2
-2
@@ -102,7 +102,7 @@ export class ReactiveFunctionVisitor<TState = void> {
102
break;
103
}
104
case "for": {
105
- this.visitValueBlock(terminal.init, state);
105
+ this.visitValue(terminal.id, terminal.init, state);
106
this.visitValue(terminal.id, terminal.test, state);
107
this.visitValue(terminal.id, terminal.update, state);
108
this.visitBlock(terminal.loop, state);
@@ -333,8 +333,8 @@ export function eachTerminalBlock(
333
break;
334
}
335
case "for": {
336
- visitValueBlock(terminal.init);
336
// TODO
337
+ // visitValueBlock(terminal.init);
338
// visitValueBlock(terminal.test);
339
// visitValueBlock(terminal.update);
340
visitBlock(terminal.loop);