Implemented do while loops
This commit is contained in:
2
makefile
2
makefile
@@ -18,7 +18,7 @@ runTest: ./src/test/test
|
|||||||
./src/test/test
|
./src/test/test
|
||||||
|
|
||||||
./src/test/test: ./src/test/tests.s
|
./src/test/test: ./src/test/tests.s
|
||||||
gcc -o ./src/test/test ./src/test/tests.s ./src/test/functionCall/functionCall.c ./src/test/while/while.c ./src/test/recursive/recursive.c ./src/test/comparison/comparison.c ./src/test/testCode.c
|
gcc -o ./src/test/test ./src/test/tests.s ./src/test/functionCall/functionCall.c ./src/test/loop/loop.c ./src/test/recursive/recursive.c ./src/test/comparison/comparison.c ./src/test/testCode.c
|
||||||
|
|
||||||
./src/test/tests.s: target/klang-1.0-jar-with-dependencies.jar
|
./src/test/tests.s: target/klang-1.0-jar-with-dependencies.jar
|
||||||
java -cp target/klang-1.0-jar-with-dependencies.jar de.hsrm.compiler.Klang.Klang < ./src/test/tests.k > ./src/test/tests.s
|
java -cp target/klang-1.0-jar-with-dependencies.jar de.hsrm.compiler.Klang.Klang < ./src/test/tests.k > ./src/test/tests.s
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ statement
|
|||||||
| variable_assignment
|
| variable_assignment
|
||||||
| return_statement
|
| return_statement
|
||||||
| whileLoop
|
| whileLoop
|
||||||
|
| doWhileLoop
|
||||||
;
|
;
|
||||||
|
|
||||||
print
|
print
|
||||||
@@ -84,6 +85,10 @@ whileLoop
|
|||||||
: WHILE OPAR cond = expression CPAR braced_block
|
: WHILE OPAR cond = expression CPAR braced_block
|
||||||
;
|
;
|
||||||
|
|
||||||
|
doWhileLoop
|
||||||
|
: DO braced_block WHILE OPAR cond = expression CPAR SCOL
|
||||||
|
;
|
||||||
|
|
||||||
PRINT: 'print';
|
PRINT: 'print';
|
||||||
IF: 'if';
|
IF: 'if';
|
||||||
ELSE: 'else';
|
ELSE: 'else';
|
||||||
@@ -91,6 +96,7 @@ FUNC: 'function';
|
|||||||
RETURN: 'return';
|
RETURN: 'return';
|
||||||
LET: 'let';
|
LET: 'let';
|
||||||
WHILE: 'while';
|
WHILE: 'while';
|
||||||
|
DO: 'do';
|
||||||
|
|
||||||
SCOL: ';';
|
SCOL: ';';
|
||||||
OBRK: '{';
|
OBRK: '{';
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import java.util.HashSet;
|
|||||||
|
|
||||||
import de.hsrm.compiler.Klang.nodes.*;
|
import de.hsrm.compiler.Klang.nodes.*;
|
||||||
import de.hsrm.compiler.Klang.nodes.expressions.*;
|
import de.hsrm.compiler.Klang.nodes.expressions.*;
|
||||||
|
import de.hsrm.compiler.Klang.nodes.loops.doWhileLoop;
|
||||||
import de.hsrm.compiler.Klang.nodes.loops.whileLoop;
|
import de.hsrm.compiler.Klang.nodes.loops.whileLoop;
|
||||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||||
import de.hsrm.compiler.Klang.types.Type;
|
import de.hsrm.compiler.Klang.types.Type;
|
||||||
@@ -65,6 +66,13 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
|||||||
return new whileLoop((Expression) condition, (Block) block);
|
return new whileLoop((Expression) condition, (Block) block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node visitDoWhileLoop(KlangParser.DoWhileLoopContext ctx) {
|
||||||
|
Node condition = this.visit(ctx.cond);
|
||||||
|
Node block = this.visit(ctx.braced_block());
|
||||||
|
return new doWhileLoop((Expression) condition, (Block) block);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node visitVariable_declaration(KlangParser.Variable_declarationContext ctx) {
|
public Node visitVariable_declaration(KlangParser.Variable_declarationContext ctx) {
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package de.hsrm.compiler.Klang.nodes.loops;
|
||||||
|
|
||||||
|
import de.hsrm.compiler.Klang.nodes.Block;
|
||||||
|
import de.hsrm.compiler.Klang.nodes.statements.Statement;;
|
||||||
|
import de.hsrm.compiler.Klang.nodes.expressions.Expression;
|
||||||
|
import de.hsrm.compiler.Klang.visitors.Visitor;
|
||||||
|
|
||||||
|
public class doWhileLoop extends Statement {
|
||||||
|
|
||||||
|
public Expression cond;
|
||||||
|
public Block block;
|
||||||
|
public Block alt;
|
||||||
|
|
||||||
|
public doWhileLoop(Expression cond, Block block) {
|
||||||
|
this.cond = cond;
|
||||||
|
this.block = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R> R welcome(Visitor<R> v) {
|
||||||
|
return v.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import de.hsrm.compiler.Klang.nodes.Block;
|
|||||||
import de.hsrm.compiler.Klang.nodes.FunctionDefinition;
|
import de.hsrm.compiler.Klang.nodes.FunctionDefinition;
|
||||||
import de.hsrm.compiler.Klang.nodes.Program;
|
import de.hsrm.compiler.Klang.nodes.Program;
|
||||||
import de.hsrm.compiler.Klang.nodes.expressions.*;
|
import de.hsrm.compiler.Klang.nodes.expressions.*;
|
||||||
|
import de.hsrm.compiler.Klang.nodes.loops.doWhileLoop;
|
||||||
import de.hsrm.compiler.Klang.nodes.loops.whileLoop;
|
import de.hsrm.compiler.Klang.nodes.loops.whileLoop;
|
||||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||||
|
|
||||||
@@ -156,14 +157,24 @@ public class EvalVisitor implements Visitor<Value> {
|
|||||||
public Value visit(whileLoop e) {
|
public Value visit(whileLoop e) {
|
||||||
Value condition = e.cond.welcome(this);
|
Value condition = e.cond.welcome(this);
|
||||||
Value result = null;
|
Value result = null;
|
||||||
while(condition.asInteger() != 0) {
|
while (condition.asInteger() != 0) {
|
||||||
System.out.println(condition.asInteger());
|
|
||||||
result = e.block.welcome(this);
|
result = e.block.welcome(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value visit(doWhileLoop e) {
|
||||||
|
Value condition = e.cond.welcome(this);
|
||||||
|
Value result = null;
|
||||||
|
do {
|
||||||
|
result = e.block.welcome(this);
|
||||||
|
} while (condition.asInteger() != 0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value visit(PrintStatement e) {
|
public Value visit(PrintStatement e) {
|
||||||
Value value = e.expression.welcome(this);
|
Value value = e.expression.welcome(this);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import java.util.TreeSet;
|
|||||||
|
|
||||||
import de.hsrm.compiler.Klang.nodes.*;
|
import de.hsrm.compiler.Klang.nodes.*;
|
||||||
import de.hsrm.compiler.Klang.nodes.expressions.*;
|
import de.hsrm.compiler.Klang.nodes.expressions.*;
|
||||||
|
import de.hsrm.compiler.Klang.nodes.loops.doWhileLoop;
|
||||||
import de.hsrm.compiler.Klang.nodes.loops.whileLoop;
|
import de.hsrm.compiler.Klang.nodes.loops.whileLoop;
|
||||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||||
|
|
||||||
@@ -305,6 +306,18 @@ public class GenASM implements Visitor<Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(doWhileLoop e) {
|
||||||
|
int lblStart = ++lCount;
|
||||||
|
this.ex.write(".L" + lblStart + ":\n");
|
||||||
|
e.block.welcome(this);
|
||||||
|
e.cond.welcome(this);
|
||||||
|
this.ex.write(" cmp $0, %rax\n");
|
||||||
|
this.ex.write(" jnz .L" + lblStart + "\n");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(PrintStatement e) {
|
public Void visit(PrintStatement e) {
|
||||||
throw new RuntimeException("Das machen wir mal nicht, ne?!");
|
throw new RuntimeException("Das machen wir mal nicht, ne?!");
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
import de.hsrm.compiler.Klang.nodes.*;
|
import de.hsrm.compiler.Klang.nodes.*;
|
||||||
import de.hsrm.compiler.Klang.nodes.expressions.*;
|
import de.hsrm.compiler.Klang.nodes.expressions.*;
|
||||||
|
import de.hsrm.compiler.Klang.nodes.loops.doWhileLoop;
|
||||||
import de.hsrm.compiler.Klang.nodes.loops.whileLoop;
|
import de.hsrm.compiler.Klang.nodes.loops.whileLoop;
|
||||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||||
|
|
||||||
@@ -127,6 +128,13 @@ class GetVars implements Visitor<Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(doWhileLoop e) {
|
||||||
|
e.cond.welcome(this);
|
||||||
|
e.block.welcome(this);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(PrintStatement e) {
|
public Void visit(PrintStatement e) {
|
||||||
e.expression.welcome(this);
|
e.expression.welcome(this);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package de.hsrm.compiler.Klang.visitors;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import de.hsrm.compiler.Klang.nodes.*;
|
import de.hsrm.compiler.Klang.nodes.*;
|
||||||
import de.hsrm.compiler.Klang.nodes.expressions.*;
|
import de.hsrm.compiler.Klang.nodes.expressions.*;
|
||||||
import de.hsrm.compiler.Klang.nodes.loops.whileLoop;
|
import de.hsrm.compiler.Klang.nodes.loops.*;
|
||||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||||
|
|
||||||
public class PrettyPrintVisitor implements Visitor<Void> {
|
public class PrettyPrintVisitor implements Visitor<Void> {
|
||||||
@@ -214,6 +214,16 @@ public class PrettyPrintVisitor implements Visitor<Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(doWhileLoop e) {
|
||||||
|
ex.write("do ");
|
||||||
|
e.block.welcome(this);
|
||||||
|
ex.write(" while (");
|
||||||
|
e.cond.welcome(this);
|
||||||
|
ex.write(");");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(PrintStatement e) {
|
public Void visit(PrintStatement e) {
|
||||||
ex.write("print ");
|
ex.write("print ");
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public interface Visitor<R> {
|
|||||||
R visit(NegateExpression e);
|
R visit(NegateExpression e);
|
||||||
R visit(IfStatement e);
|
R visit(IfStatement e);
|
||||||
R visit(whileLoop e);
|
R visit(whileLoop e);
|
||||||
|
R visit(doWhileLoop e);
|
||||||
R visit(PrintStatement e);
|
R visit(PrintStatement e);
|
||||||
R visit(VariableDeclaration e);
|
R visit(VariableDeclaration e);
|
||||||
R visit(VariableAssignment e);
|
R visit(VariableAssignment e);
|
||||||
|
|||||||
30
src/test/loop/loop.c
Normal file
30
src/test/loop/loop.c
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include "loop.h"
|
||||||
|
|
||||||
|
void printLoopSuccess(char* name, int x, int expected, int result) {
|
||||||
|
printf("SUCCESS:\t%s(%d)\tGOT: %d\tExpected: %d\n", name, x, result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printLoopError(char* name, int x, int expected, int result) {
|
||||||
|
printf("ERROR:\t\t%s(%d)\tGOT: %d\tExpected: %d\n", name, x, result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
int loopTest(char* name, int x, int expected, int result) {
|
||||||
|
if (expected == result) {
|
||||||
|
printLoopSuccess(name, x, expected, result);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
printLoopError(name, x, expected, result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int runLoopTests() {
|
||||||
|
printf("\nLoop Tests \n");
|
||||||
|
int failed = 0;
|
||||||
|
failed += loopTest("while", 5, 5, myWhile(5));
|
||||||
|
failed += loopTest("doWhile", 0, 1, myDoWhile(0));
|
||||||
|
failed += loopTest("doWhile", 1, 1, myDoWhile(1));
|
||||||
|
|
||||||
|
return failed;
|
||||||
|
}
|
||||||
2
src/test/loop/loop.h
Normal file
2
src/test/loop/loop.h
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
int myWhile(int x);
|
||||||
|
int myDoWhile(int x);
|
||||||
@@ -125,7 +125,7 @@ int main(){
|
|||||||
failed += runComparisonTests();
|
failed += runComparisonTests();
|
||||||
|
|
||||||
// Tests for while loop
|
// Tests for while loop
|
||||||
failed += runWhileTests();
|
failed += runLoopTests();
|
||||||
|
|
||||||
printf("\n=== Failed Tests: %d\n", failed);
|
printf("\n=== Failed Tests: %d\n", failed);
|
||||||
|
|
||||||
|
|||||||
@@ -5,4 +5,4 @@
|
|||||||
int runFunctionCallTests();
|
int runFunctionCallTests();
|
||||||
int runRecursiveTests();
|
int runRecursiveTests();
|
||||||
int runComparisonTests();
|
int runComparisonTests();
|
||||||
int runWhileTests();
|
int runLoopTests();
|
||||||
@@ -146,4 +146,12 @@ function myWhile(end) {
|
|||||||
return cond;
|
return cond;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function myDoWhile(end) {
|
||||||
|
let cond = 0;
|
||||||
|
do {
|
||||||
|
cond = (cond + 1);
|
||||||
|
} while((cond < end));
|
||||||
|
return cond;
|
||||||
|
}
|
||||||
|
|
||||||
add(1, 1);
|
add(1, 1);
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include "while.h"
|
|
||||||
|
|
||||||
void printWhileSuccess(char* name, int x, int expected, int result) {
|
|
||||||
printf("SUCCESS:\t%s(%d)\tGOT: %d\tExpected: %d\n", name, x, result, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
void printWhileError(char* name, int x, int expected, int result) {
|
|
||||||
printf("ERROR:\t\t%s(%d)\tGOT: %d\tExpected: %d\n", name, x, result, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
int whileTest(char* name, int x, int expected, int result) {
|
|
||||||
if (expected == result) {
|
|
||||||
printWhileSuccess(name, x, expected, result);
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
printWhileError(name, x, expected, result);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int runWhileTests() {
|
|
||||||
printf("\nWhile Tests \n");
|
|
||||||
int failed = 0;
|
|
||||||
failed += whileTest("while", 5, 5, myWhile(5));
|
|
||||||
return failed;
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
int myWhile(int x);
|
|
||||||
Reference in New Issue
Block a user