Skip to content
This repository has been archived by the owner on Jun 4, 2023. It is now read-only.

Commit

Permalink
intcode: add for statement
Browse files Browse the repository at this point in the history
  • Loading branch information
mhw0 committed Apr 29, 2023
1 parent deb7951 commit aed3c64
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 1 deletion.
35 changes: 34 additions & 1 deletion src/intcode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import {
LiteralExpression,
IfStatement,
WhileStatement,
DoStatement
DoStatement,
ForStatement,
VariableDeclarationList
} from "typescript";

type IntcodeRelopOpcode = "LT" | "LTE" | "GT" | "GTE" | "EQ" | "NEQ";
Expand Down Expand Up @@ -482,6 +484,34 @@ export class IntermediateCode {
this.intcodeControlFlowExpression(statement.expression, lbegin);
}

private intcodeForStatement(statement: ForStatement): void {
assert(statement.kind == SyntaxKind.ForStatement);
const lbegin = this.allocLabel();
const ltrue = this.allocLabel();
const lexit = this.allocLabel();

if (statement.initializer != undefined) {
if (statement.initializer.kind == SyntaxKind.VariableDeclarationList)
for (const declaration of (statement.initializer as VariableDeclarationList).declarations)
this.intcodeVariableDeclaration(declaration);
else
this.intcodeExpression(statement.initializer as Expression);
}

this.intcode(["LAB", lbegin]);
if (statement.condition != undefined)
this.intcodeControlFlowExpression(statement.condition, ltrue, lexit);
// TODO: this label is not needed when the loop is infinite
this.intcode(["LAB", ltrue]);
if (statement.statement != undefined)
this.intcodeStatement(statement.statement);
if (statement.incrementor != undefined)
this.intcodeExpression(statement.incrementor);
this.intcode(["BR", lbegin]);
this.intcode(["LAB", lexit]);
}


private intcodeStatement(statement: Statement): void {
switch (statement.kind) {
case SyntaxKind.VariableStatement:
Expand All @@ -499,6 +529,9 @@ export class IntermediateCode {
case SyntaxKind.DoStatement:
this.intcodeDoStatement(statement as DoStatement);
break
case SyntaxKind.ForStatement:
this.intcodeForStatement(statement as ForStatement);
break
case SyntaxKind.Block:
this.intcodeBlock(statement as Block);
break
Expand Down
52 changes: 52 additions & 0 deletions test/intcode-statement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,55 @@ test("intermediate code do statement", function (testcase) {
]);
testcase.end();
});

test("intermediate code for statement", function (testcase) {
const source = createTestSource(`
for(let i = 0, b=8;i < 32;i++) {k++}
for(;i < 32;i++) {k++}
for(;;i++) {k++}
for(;;) {k++}
for(;;);
`);
const intcodes = new IntermediateCode(source).generate();

testcase.same(intcodes, [
["COPY", "i", ".%0"],
["COPY", "b", ".%8"],
["LAB", "L0"],
["BLT", "L1", "i", ".%32"],
["BR", "L2"],
["LAB", "L1"],
["ADD", "k", "k", ".%1"],
["ADD", "i", "i", ".%1"],
["BR", "L0"],
["LAB", "L2"],

["LAB", "L3"],
["BLT", "L4", "i", ".%32"],
["BR", "L5"],
["LAB", "L4"],
["ADD", "k", "k", ".%1"],
["ADD", "i", "i", ".%1"],
["BR", "L3"],
["LAB", "L5"],

["LAB", "L6"],
["LAB", "L7"],
["ADD", "k", "k", ".%1"],
["ADD", "i", "i", ".%1"],
["BR", "L6"],
["LAB", "L8"],

["LAB", "L9"],
["LAB", "L10"],
["ADD", "k", "k", ".%1"],
["BR", "L9"],
["LAB", "L11"],

["LAB", "L12"],
["LAB", "L13"],
["BR", "L12"],
["LAB", "L14"]
]);
testcase.end();
});

0 comments on commit aed3c64

Please sign in to comment.