Skip to content
This repository has been archived by the owner on Jul 10, 2024. It is now read-only.

Commit

Permalink
Implemented visitForLoop in IRGenerator and added ForLoopIntegrationTest
Browse files Browse the repository at this point in the history
  • Loading branch information
maxschwinghammer committed Jun 5, 2024
1 parent bab67bc commit 919aca1
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.auberer.compilerdesignlectureproject.codegen;

import com.auberer.compilerdesignlectureproject.ast.ASTEntryNode;
import com.auberer.compilerdesignlectureproject.ast.ASTForNode;
import com.auberer.compilerdesignlectureproject.ast.ASTPrintBuiltinCallNode;
import com.auberer.compilerdesignlectureproject.ast.ASTVisitor;
import com.auberer.compilerdesignlectureproject.codegen.instructions.CondJumpInstruction;
import com.auberer.compilerdesignlectureproject.codegen.instructions.Instruction;
import com.auberer.compilerdesignlectureproject.codegen.instructions.JumpInstruction;
import com.auberer.compilerdesignlectureproject.codegen.instructions.PrintInstruction;
import lombok.Getter;

Expand All @@ -19,6 +22,36 @@ public IRGenerator(String moduleName) {
module = new Module(moduleName);
}

@Override
public IRExprResult visitForLoop(ASTForNode node) {
BasicBlock loopHeadBlock = new BasicBlock("loopHead");
BasicBlock loopBodyBlock = new BasicBlock("loopBody");
BasicBlock loopEndBlock = new BasicBlock("loopEnd");

visit(node.getInitialization());

JumpInstruction jumpToLoopHead = new JumpInstruction(node, loopHeadBlock);
pushToCurrentBlock(jumpToLoopHead);

switchToBlock(loopHeadBlock);
IRExprResult conditionResult = visit(node.getCondition());

CondJumpInstruction condJumpInstruction = new CondJumpInstruction(node, conditionResult.getValue().getNode(), loopBodyBlock, loopEndBlock);
pushToCurrentBlock(condJumpInstruction);

switchToBlock(loopBodyBlock);
visit(node.getBody());

visit(node.getIncrement());

JumpInstruction jumpInstruction = new JumpInstruction(node, loopHeadBlock);
pushToCurrentBlock(jumpInstruction);

switchToBlock(loopEndBlock);

return null;
}

@Override
public IRExprResult visitEntry(ASTEntryNode node) {
// We did not enter a function yet, so the current block has to be null
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.auberer.compilerdesignlectureproject.codegen;

import com.auberer.compilerdesignlectureproject.ast.ASTEntryNode;
import com.auberer.compilerdesignlectureproject.lexer.Lexer;
import com.auberer.compilerdesignlectureproject.parser.Parser;
import com.auberer.compilerdesignlectureproject.reader.Reader;
import com.auberer.compilerdesignlectureproject.sema.SymbolTableBuilder;
import com.auberer.compilerdesignlectureproject.sema.TypeChecker;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertTrue;

public class ForLoopIntegrationTest {

@Test
public void testSuccessfulForLoop() {
String input = """
func int main()
for (int i = 0; i == 10; i = i + 1) {
print(i);
}
return 0;
cnuf
""";

Reader reader = new Reader(input);
Lexer lexer = new Lexer(reader, false);
Parser parser = new Parser(lexer);
ASTEntryNode ast = parser.parse();

SymbolTableBuilder symbolTableBuilder = new SymbolTableBuilder();
symbolTableBuilder.visit(ast);

TypeChecker typeChecker = new TypeChecker(ast);
typeChecker.visit(ast);

String moduleName = "test.tinf";
IRGenerator irGenerator = new IRGenerator(moduleName);
irGenerator.visit(ast);
Module module = irGenerator.getModule();

StringBuilder sb = new StringBuilder();
module.dumpIR(sb);

assertTrue(sb.toString().contains("loopHead"));
assertTrue(sb.toString().contains("loopBody"));
assertTrue(sb.toString().contains("loopEnd"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func empty main()
assertEquals("module test.tinf:", sb.toString());
}

private static Module compileModule(String input) {
static Module compileModule(String input) {
Reader reader = new Reader(input);
Lexer lexer = new Lexer(reader, false);
Parser parser = new Parser(lexer);
Expand Down

0 comments on commit 919aca1

Please sign in to comment.