implement for loops

This commit is contained in:
Marvin Kaiser
2020-01-14 10:21:04 +01:00
parent 1980e1ba8c
commit be43cc9a77
11 changed files with 125 additions and 8 deletions

View File

@@ -6,6 +6,7 @@ import java.util.HashSet;
import de.hsrm.compiler.Klang.nodes.*;
import de.hsrm.compiler.Klang.nodes.expressions.*;
import de.hsrm.compiler.Klang.nodes.loops.DoWhileLoop;
import de.hsrm.compiler.Klang.nodes.loops.ForLoop;
import de.hsrm.compiler.Klang.nodes.loops.WhileLoop;
import de.hsrm.compiler.Klang.nodes.statements.*;
import de.hsrm.compiler.Klang.types.Type;
@@ -81,6 +82,14 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
return new DoWhileLoop((Expression) condition, (Block) block);
}
@Override
public Node visitForLoop(KlangParser.ForLoopContext ctx) {
Node init = this.visit(ctx.init);
Node condition = this.visit(ctx.cond);
Node step = this.visit(ctx.step);
Node block = this.visit(ctx.braced_block());
return new ForLoop((Statement) init, (Expression) condition, (VariableAssignment) step, (Block) block);
}
@Override
public Node visitVariable_declaration(KlangParser.Variable_declarationContext ctx) {

View File

@@ -0,0 +1,28 @@
package de.hsrm.compiler.Klang.nodes.loops;
import de.hsrm.compiler.Klang.nodes.statements.Statement;
import de.hsrm.compiler.Klang.nodes.statements.VariableAssignment;
import de.hsrm.compiler.Klang.nodes.Block;
import de.hsrm.compiler.Klang.nodes.expressions.Expression;
import de.hsrm.compiler.Klang.visitors.Visitor;
public class ForLoop extends Statement {
public Statement init;
public Expression condition;
public VariableAssignment step;
public Block block;
public ForLoop(Statement init, Expression condition, VariableAssignment step, Block block) {
this.init = init;
this.condition = condition;
this.step = step;
this.block = block;
}
@Override
public <R> R welcome(Visitor<R> v) {
return v.visit(this);
}
}

View File

@@ -9,6 +9,7 @@ import de.hsrm.compiler.Klang.nodes.FunctionDefinition;
import de.hsrm.compiler.Klang.nodes.Program;
import de.hsrm.compiler.Klang.nodes.expressions.*;
import de.hsrm.compiler.Klang.nodes.loops.DoWhileLoop;
import de.hsrm.compiler.Klang.nodes.loops.ForLoop;
import de.hsrm.compiler.Klang.nodes.loops.WhileLoop;
import de.hsrm.compiler.Klang.nodes.statements.*;
@@ -175,6 +176,20 @@ public class EvalVisitor implements Visitor<Value> {
return result;
}
@Override
public Value visit(ForLoop e) {
e.init.welcome(this);
Value cond = e.condition.welcome(this);
Value result = null;
while (cond.asInteger() != 0) {
result = e.block.welcome(this);
e.step.welcome(this);
cond = e.condition.welcome(this);
}
return result;
}
@Override
public Value visit(PrintStatement e) {
Value value = e.expression.welcome(this);

View File

@@ -9,6 +9,7 @@ import java.util.TreeSet;
import de.hsrm.compiler.Klang.nodes.*;
import de.hsrm.compiler.Klang.nodes.expressions.*;
import de.hsrm.compiler.Klang.nodes.loops.DoWhileLoop;
import de.hsrm.compiler.Klang.nodes.loops.ForLoop;
import de.hsrm.compiler.Klang.nodes.loops.WhileLoop;
import de.hsrm.compiler.Klang.nodes.statements.*;
@@ -291,7 +292,7 @@ public class GenASM implements Visitor<Void> {
this.ex.write(".L" + lblEnd + ":\n");
return null;
}
@Override
public Void visit(WhileLoop e) {
int lblCond = ++lCount;
@@ -306,7 +307,6 @@ public class GenASM implements Visitor<Void> {
return null;
}
@Override
public Void visit(DoWhileLoop e) {
int lblStart = ++lCount;
@@ -317,6 +317,23 @@ public class GenASM implements Visitor<Void> {
this.ex.write(" jnz .L" + lblStart + "\n");
return null;
}
@Override
public Void visit(ForLoop e) {
int lblStart = ++lCount;
int lblEnd = ++lCount;
e.init.welcome(this);
this.ex.write(".L" + lblStart + ":\n");
e.condition.welcome(this);
this.ex.write(" cmp $0, %rax\n");
this.ex.write(" jz .L" + lblEnd + "\n");
e.block.welcome(this);
e.step.welcome(this);
this.ex.write(" jmp .L" + lblStart + "\n");
this.ex.write(".L" + lblEnd + ":\n");
return null;
}
@Override
public Void visit(PrintStatement e) {

View File

@@ -5,6 +5,7 @@ import java.util.Set;
import de.hsrm.compiler.Klang.nodes.*;
import de.hsrm.compiler.Klang.nodes.expressions.*;
import de.hsrm.compiler.Klang.nodes.loops.DoWhileLoop;
import de.hsrm.compiler.Klang.nodes.loops.ForLoop;
import de.hsrm.compiler.Klang.nodes.loops.WhileLoop;
import de.hsrm.compiler.Klang.nodes.statements.*;
@@ -135,6 +136,15 @@ class GetVars implements Visitor<Void> {
return null;
}
@Override
public Void visit(ForLoop e) {
e.init.welcome(this);
e.condition.welcome(this);
e.step.welcome(this);
e.block.welcome(this);
return null;
}
@Override
public Void visit(PrintStatement e) {
e.expression.welcome(this);

View File

@@ -224,6 +224,19 @@ public class PrettyPrintVisitor implements Visitor<Void> {
return null;
}
@Override
public Void visit(ForLoop e) {
ex.write("for (");
e.init.welcome(this);
ex.write(" ");
e.condition.welcome(this);
ex.write("; ");
e.step.welcome(this);
ex.write(") ");
e.block.welcome(this);
return null;
}
@Override
public Void visit(PrintStatement e) {
ex.write("print ");
@@ -241,7 +254,6 @@ public class PrettyPrintVisitor implements Visitor<Void> {
e.expression.welcome(this);
}
ex.write(";");
return null;
}
@@ -249,7 +261,6 @@ public class PrettyPrintVisitor implements Visitor<Void> {
public Void visit(VariableAssignment e) {
ex.write(e.name + " = ");
e.expression.welcome(this);
ex.write(";");
return null;
}
@@ -268,6 +279,9 @@ public class PrettyPrintVisitor implements Visitor<Void> {
for (Statement stmt : e.statements) {
ex.nl();
stmt.welcome(this);
if (stmt.getClass() == VariableAssignment.class || stmt.getClass() == VariableDeclaration.class) {
ex.write(";");
}
}
ex.subIndent();
ex.nl();

View File

@@ -25,6 +25,7 @@ public interface Visitor<R> {
R visit(IfStatement e);
R visit(WhileLoop e);
R visit(DoWhileLoop e);
R visit(ForLoop e);
R visit(PrintStatement e);
R visit(VariableDeclaration e);
R visit(VariableAssignment e);