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.
This commit is contained in:
Joe Savona
2023-06-04 21:25:59 -04:00
parent e410815aeb
commit cd115ec128
6 changed files with 51 additions and 2 deletions
+10 -2
View File
@@ -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
+4
View File
@@ -697,6 +697,10 @@ export function reversePostorderBlocks(func: HIR): void {
visit(terminal.block);
break;
}
case "sequence": {
visit(terminal.block);
break;
}
case "unsupported": {
break;
}
+5
View File
@@ -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> | string {
}`;
break;
}
case "sequence": {
value = `[${terminal.id}] Sequence block=bb${terminal.block} fallthrough=bb${terminal.fallthrough}`;
break;
}
case "unsupported": {
value = `Unsupported`;
break;
+22
View File
@@ -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<BlockId> {
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<Place> {
yield terminal.value;
break;
}
case "sequence":
case "label":
case "optional":
case "ternary":
@@ -570,6 +570,7 @@ class Driver {
break;
}
case "sequence":
case "optional":
case "ternary":
case "logical": {
@@ -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": {