From bd4ae1d60534c9c7afc8fbf70d4267e3f62bb6c4 Mon Sep 17 00:00:00 2001 From: Marvin Kaiser Date: Mon, 13 Jan 2020 16:00:42 +0100 Subject: [PATCH] Added while loop --- README.md | 4 +- makefile | 2 +- .../antlr4/de/hsrm/compiler/Klang/Klang.g4 | 6 + .../hsrm/compiler/Klang/ContextAnalysis.java | 9 + .../compiler/Klang/nodes/loops/whileLoop.java | 24 + .../compiler/Klang/visitors/EvalVisitor.java | 13 + .../hsrm/compiler/Klang/visitors/GenASM.java | 71 ++- .../hsrm/compiler/Klang/visitors/GetVars.java | 8 + .../Klang/visitors/PrettyPrintVisitor.java | 546 +++++++++--------- .../hsrm/compiler/Klang/visitors/Visitor.java | 2 + src/test/testCode.c | 3 + src/test/tests.h | 3 +- src/test/tests.k | 8 + src/test/while/while.c | 27 + src/test/while/while.h | 1 + 15 files changed, 428 insertions(+), 299 deletions(-) create mode 100644 src/main/java/de/hsrm/compiler/Klang/nodes/loops/whileLoop.java create mode 100644 src/test/while/while.c create mode 100644 src/test/while/while.h diff --git a/README.md b/README.md index 9a39d39..85421be 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # Klang - The Kaiser language -This is the project for Klang - the Kaiser language. \ No newline at end of file +This is the project for Klang - the Kaiser language. + +0 is false \ No newline at end of file diff --git a/makefile b/makefile index 691f713..7c3ab16 100644 --- a/makefile +++ b/makefile @@ -18,7 +18,7 @@ runTest: ./src/test/test ./src/test/test ./src/test/test: ./src/test/tests.s - gcc -o ./src/test/test ./src/test/tests.s ./src/test/functionCall/functionCall.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/while/while.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 java -cp target/klang-1.0-jar-with-dependencies.jar de.hsrm.compiler.Klang.Klang < ./src/test/tests.k > ./src/test/tests.s diff --git a/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 b/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 index 70d0655..a670088 100644 --- a/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 +++ b/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 @@ -26,6 +26,7 @@ statement | variable_declaration | variable_assignment | return_statement + | whileLoop ; print @@ -79,12 +80,17 @@ arguments : (expression (COMMA expression)*)? ; +whileLoop + : WHILE OPAR cond = expression CPAR braced_block + ; + PRINT: 'print'; IF: 'if'; ELSE: 'else'; FUNC: 'function'; RETURN: 'return'; LET: 'let'; +WHILE: 'while'; SCOL: ';'; OBRK: '{'; diff --git a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java index 6ee3244..11af808 100644 --- a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java +++ b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java @@ -5,6 +5,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.whileLoop; import de.hsrm.compiler.Klang.nodes.statements.*; import de.hsrm.compiler.Klang.types.Type; @@ -57,6 +58,14 @@ public class ContextAnalysis extends KlangBaseVisitor { } } + @Override + public Node visitWhileLoop(KlangParser.WhileLoopContext ctx) { + Node condition = this.visit(ctx.cond); + Node block = this.visit(ctx.braced_block()); + return new whileLoop((Expression) condition, (Block) block); + } + + @Override public Node visitVariable_declaration(KlangParser.Variable_declarationContext ctx) { String name = ctx.IDENT().getText(); diff --git a/src/main/java/de/hsrm/compiler/Klang/nodes/loops/whileLoop.java b/src/main/java/de/hsrm/compiler/Klang/nodes/loops/whileLoop.java new file mode 100644 index 0000000..e217263 --- /dev/null +++ b/src/main/java/de/hsrm/compiler/Klang/nodes/loops/whileLoop.java @@ -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 whileLoop extends Statement { + + public Expression cond; + public Block block; + public Block alt; + + public whileLoop(Expression cond, Block block) { + this.cond = cond; + this.block = block; + } + + @Override + public R welcome(Visitor v) { + return v.visit(this); + } + +} \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java index 7caad2e..eceb805 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java @@ -8,6 +8,7 @@ import de.hsrm.compiler.Klang.nodes.Block; 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.whileLoop; import de.hsrm.compiler.Klang.nodes.statements.*; public class EvalVisitor implements Visitor { @@ -151,6 +152,18 @@ public class EvalVisitor implements Visitor { return result; } + @Override + public Value visit(whileLoop e) { + Value condition = e.cond.welcome(this); + Value result = null; + while(condition.asInteger() != 0) { + System.out.println(condition.asInteger()); + result = e.block.welcome(this); + } + + return result; + } + @Override public Value visit(PrintStatement e) { Value value = e.expression.welcome(this); diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java b/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java index 93f40d2..e44ce3a 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java @@ -8,6 +8,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.whileLoop; import de.hsrm.compiler.Klang.nodes.statements.*; public class GenASM implements Visitor { @@ -264,30 +265,44 @@ public class GenASM implements Visitor { @Override public Void visit(IfStatement e) { - int lblElse = ++lCount; - int lblEnd = ++lCount; - boolean hasElse = e.alt != null || e.elif != null; - e.cond.welcome(this); - this.ex.write(" cmp $0, %rax\n"); - // in case of cond evaluating to false, jump to else/elif - // Jump to end if there is no else part, this saves a label declaration - if (hasElse) { - this.ex.write(" jz .L" + lblElse + "\n"); + int lblElse = ++lCount; + int lblEnd = ++lCount; + boolean hasElse = e.alt != null || e.elif != null; + e.cond.welcome(this); + this.ex.write(" cmp $0, %rax\n"); + // in case of cond evaluating to false, jump to else/elif + // Jump to end if there is no else part, this saves a label declaration + if (hasElse) { + this.ex.write(" jz .L" + lblElse + "\n"); + } else { + this.ex.write(" jz .L" + lblEnd + "\n"); + } + e.then.welcome(this); + if (hasElse) { + this.ex.write(" jmp .L" + lblEnd + "\n"); + this.ex.write(".L" + lblElse + ":\n"); + if (e.alt != null) { + e.alt.welcome(this); } else { - this.ex.write(" jz .L" + lblEnd + "\n"); + e.elif.welcome(this); } - e.then.welcome(this); - if (hasElse) { - this.ex.write(" jmp .L" + lblEnd + "\n"); - this.ex.write(".L" + lblElse + ":\n"); - if (e.alt != null) { - e.alt.welcome(this); - } else { - e.elif.welcome(this); - } - } - this.ex.write(".L" + lblEnd + ":\n"); - return null; + } + this.ex.write(".L" + lblEnd + ":\n"); + return null; + } + + @Override + public Void visit(whileLoop e) { + int lblCond = ++lCount; + int lblEnd = ++lCount; + this.ex.write(".L" + lblCond + ":\n"); + e.cond.welcome(this); + this.ex.write(" cmp $0, %rax\n"); + this.ex.write(" jz .L" + lblEnd + "\n"); + e.block.welcome(this); + this.ex.write(" jmp .L" + lblCond + "\n"); + this.ex.write(".L" + lblEnd + ":\n"); + return null; } @Override @@ -351,10 +366,10 @@ public class GenASM implements Visitor { // Merke dir die offsets der parameter, die direkt auf den stack gelegt wurden int offset = 16; // Per Stack übergebene Parameter liegen über unserm BSP // Per stack übergebene variablen in env registrieren - for (int i = this.rs.length; i < e.parameters.length; i++) { - env.put(e.parameters[i], offset); - offset += 8; - } + for (int i = this.rs.length; i < e.parameters.length; i++) { + env.put(e.parameters[i], offset); + offset += 8; + } // pushe die aufrufparameter aus den Registern wieder auf den Stack offset = 0; @@ -363,7 +378,7 @@ public class GenASM implements Visitor { offset -= 8; this.env.put(e.parameters[i], offset); // negative, liegt unter aktuellem BP } - + // Reserviere Platz auf dem Stack für jede lokale variable for (String lok_var : vars) { offset -= 8; @@ -384,7 +399,7 @@ public class GenASM implements Visitor { } // Den Rest auf den stack pushen - for (int i = e.arguments.length -1; i >= this.rs.length; i--) { + for (int i = e.arguments.length - 1; i >= this.rs.length; i--) { e.arguments[i].welcome(this); this.ex.write(" pushq %rax\n"); } diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java b/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java index dfb99fa..6f41e46 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java @@ -4,6 +4,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.whileLoop; import de.hsrm.compiler.Klang.nodes.statements.*; class GetVars implements Visitor { @@ -119,6 +120,13 @@ class GetVars implements Visitor { return null; } + @Override + public Void visit(whileLoop e) { + e.cond.welcome(this); + e.block.welcome(this); + return null; + } + @Override public Void visit(PrintStatement e) { e.expression.welcome(this); diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java index b09ff34..9a7976e 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java @@ -3,298 +3,308 @@ package de.hsrm.compiler.Klang.visitors; import java.io.*; import de.hsrm.compiler.Klang.nodes.*; import de.hsrm.compiler.Klang.nodes.expressions.*; +import de.hsrm.compiler.Klang.nodes.loops.whileLoop; import de.hsrm.compiler.Klang.nodes.statements.*; public class PrettyPrintVisitor implements Visitor { - public static class ExWriter { - Writer w; - String indent = ""; + public static class ExWriter { + Writer w; + String indent = ""; - void addIndent() { - indent = indent + " "; - } - - void subIndent() { - indent = indent.substring(2); - } - - void nl() { - write("\n" + indent); - } - - int lbl = 0; - - int next() { - return lbl++; - } - - public ExWriter(Writer w) { - this.w = w; - } - - void lnwrite(Object o) { - nl(); - write(o); - } - - void write(Object o) { - try { - w.write(o + ""); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + void addIndent() { + indent = indent + " "; } - public ExWriter ex; - - public PrettyPrintVisitor(ExWriter ex) { - this.ex = ex; + void subIndent() { + indent = indent.substring(2); } - @Override - public Void visit(Program e) { - for (var funcDef : e.funcs) { - funcDef.welcome(this); - ex.nl(); - ex.nl(); - } - e.expression.welcome(this); - ex.write(";"); - return null; + void nl() { + write("\n" + indent); } - @Override - public Void visit(IntegerExpression e) { - ex.write(e.value); - return null; + int lbl = 0; + + int next() { + return lbl++; } - @Override - public Void visit(EqualityExpression e) { - ex.write("("); - e.lhs.welcome(this); - ex.write(" == "); - e.rhs.welcome(this); - ex.write(")"); - return null; + public ExWriter(Writer w) { + this.w = w; } - @Override - public Void visit(NotEqualityExpression e) { - ex.write("("); - e.lhs.welcome(this); - ex.write(" != "); - e.rhs.welcome(this); - ex.write(")"); - return null; - } - - @Override - public Void visit(GTExpression e) { - ex.write("("); - e.lhs.welcome(this); - ex.write(" > "); - e.rhs.welcome(this); - ex.write(")"); - return null; - } - - @Override - public Void visit(GTEExpression e) { - ex.write("("); - e.lhs.welcome(this); - ex.write(" >= "); - e.rhs.welcome(this); - ex.write(")"); - return null; - } - - @Override - public Void visit(LTExpression e) { - ex.write("("); - e.lhs.welcome(this); - ex.write(" < "); - e.rhs.welcome(this); - ex.write(")"); - return null; - } - - @Override - public Void visit(LTEExpression e) { - ex.write("("); - e.lhs.welcome(this); - ex.write(" <= "); - e.rhs.welcome(this); - ex.write(")"); - return null; + void lnwrite(Object o) { + nl(); + write(o); } - @Override - public Void visit(AdditionExpression e) { - ex.write("("); - e.lhs.welcome(this); - ex.write(" + "); - e.rhs.welcome(this); - ex.write(")"); - return null; + void write(Object o) { + try { + w.write(o + ""); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + public ExWriter ex; + + public PrettyPrintVisitor(ExWriter ex) { + this.ex = ex; + } + + @Override + public Void visit(Program e) { + for (var funcDef : e.funcs) { + funcDef.welcome(this); + ex.nl(); + ex.nl(); + } + e.expression.welcome(this); + ex.write(";"); + return null; + } + + @Override + public Void visit(IntegerExpression e) { + ex.write(e.value); + return null; + } + + @Override + public Void visit(EqualityExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" == "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(NotEqualityExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" != "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(GTExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" > "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(GTEExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" >= "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(LTExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" < "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(LTEExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" <= "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(AdditionExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" + "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(SubstractionExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" - "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(MultiplicationExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" * "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(DivisionExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" / "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(ModuloExpression e) { + ex.write("("); + e.lhs.welcome(this); + ex.write(" % "); + e.rhs.welcome(this); + ex.write(")"); + return null; + } + + @Override + public Void visit(NegateExpression e) { + ex.write(" - "); + e.lhs.welcome(this); + return null; + } + + @Override + public Void visit(IfStatement e) { + ex.write("if ("); + e.cond.welcome(this); + ex.write(") "); + e.then.welcome(this); + if (e.alt != null) { + ex.write(" else "); + e.alt.welcome(this); + } else if (e.elif != null) { + ex.write(" else "); + e.elif.welcome(this); + } + return null; + } + + @Override + public Void visit(whileLoop e) { + ex.write("while ("); + e.cond.welcome(this); + ex.write(") "); + e.block.welcome(this); + return null; + } + + @Override + public Void visit(PrintStatement e) { + ex.write("print "); + e.expression.welcome(this); + ex.write(";"); + return null; + } + + @Override + public Void visit(VariableDeclaration e) { + ex.write("let " + e.name); + + if (e.expression != null) { + ex.write(" = "); + e.expression.welcome(this); } - @Override - public Void visit(SubstractionExpression e) { - ex.write("("); - e.lhs.welcome(this); - ex.write(" - "); - e.rhs.welcome(this); - ex.write(")"); - return null; + ex.write(";"); + return null; + } + + @Override + public Void visit(VariableAssignment e) { + ex.write(e.name + " = "); + e.expression.welcome(this); + ex.write(";"); + return null; + } + + @Override + public Void visit(ReturnStatement e) { + ex.write("return "); + e.expression.welcome(this); + ex.write(";"); + return null; + } + + @Override + public Void visit(Block e) { + ex.write("{"); + ex.addIndent(); + for (Statement stmt : e.statements) { + ex.nl(); + stmt.welcome(this); } + ex.subIndent(); + ex.nl(); + ex.write("}"); + return null; + } - @Override - public Void visit(MultiplicationExpression e) { - ex.write("("); - e.lhs.welcome(this); - ex.write(" * "); - e.rhs.welcome(this); - ex.write(")"); - return null; + @Override + public Void visit(FunctionDefinition e) { + ex.write("function "); + ex.write(e.name); + ex.write("("); + boolean first = true; + for (String param : e.parameters) { + if (!first) { + ex.write(", "); + } else { + first = false; + } + ex.write(param); } + ex.write(") "); + e.block.welcome(this); + return null; + } - @Override - public Void visit(DivisionExpression e) { - ex.write("("); - e.lhs.welcome(this); - ex.write(" / "); - e.rhs.welcome(this); - ex.write(")"); - return null; + @Override + public Void visit(FunctionCall e) { + ex.write(e.name); + ex.write("("); + boolean first = true; + for (Expression arg : e.arguments) { + if (!first) { + ex.write(", "); + } else { + first = false; + } + arg.welcome(this); } + ex.write(")"); + return null; + } - @Override - public Void visit(ModuloExpression e) { - ex.write("("); - e.lhs.welcome(this); - ex.write(" % "); - e.rhs.welcome(this); - ex.write(")"); - return null; - } - - @Override - public Void visit(NegateExpression e) { - ex.write(" - "); - e.lhs.welcome(this); - return null; - } - - @Override - public Void visit(IfStatement e) { - ex.write("if ("); - e.cond.welcome(this); - ex.write(") "); - e.then.welcome(this); - if (e.alt != null) { - ex.write(" else "); - e.alt.welcome(this); - } else if (e.elif != null) { - ex.write(" else "); - e.elif.welcome(this); - } - return null; - } - - @Override - public Void visit(PrintStatement e) { - ex.write("print "); - e.expression.welcome(this); - ex.write(";"); - return null; - } - - @Override - public Void visit(VariableDeclaration e) { - ex.write("let " + e.name); - - if (e.expression != null) { - ex.write(" = "); - e.expression.welcome(this); - } - - ex.write(";"); - return null; - } - - @Override - public Void visit(VariableAssignment e) { - ex.write(e.name + " = "); - e.expression.welcome(this); - ex.write(";"); - return null; - } - - @Override - public Void visit(ReturnStatement e) { - ex.write("return "); - e.expression.welcome(this); - ex.write(";"); - return null; - } - - @Override - public Void visit(Block e) { - ex.write("{"); - ex.addIndent(); - for (Statement stmt : e.statements) { - ex.nl(); - stmt.welcome(this); - } - ex.subIndent(); - ex.nl(); - ex.write("}"); - return null; - } - - @Override - public Void visit(FunctionDefinition e) { - ex.write("function "); - ex.write(e.name); - ex.write("("); - boolean first = true; - for (String param : e.parameters) { - if (!first) { - ex.write(", "); - } else { - first = false; - } - ex.write(param); - } - ex.write(") "); - e.block.welcome(this); - return null; - } - - @Override - public Void visit(FunctionCall e) { - ex.write(e.name); - ex.write("("); - boolean first = true; - for (Expression arg : e.arguments) { - if (!first) { - ex.write(", "); - } else { - first = false; - } - arg.welcome(this); - } - ex.write(")"); - return null; - } - - @Override - public Void visit(Variable e) { - ex.write(e.name); - return null; - } + @Override + public Void visit(Variable e) { + ex.write(e.name); + return null; + } } \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java index c838b9f..c062d2a 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java @@ -4,6 +4,7 @@ import de.hsrm.compiler.Klang.nodes.Block; 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.*; import de.hsrm.compiler.Klang.nodes.statements.*; public interface Visitor { @@ -22,6 +23,7 @@ public interface Visitor { R visit(ModuloExpression e); R visit(NegateExpression e); R visit(IfStatement e); + R visit(whileLoop e); R visit(PrintStatement e); R visit(VariableDeclaration e); R visit(VariableAssignment e); diff --git a/src/test/testCode.c b/src/test/testCode.c index 9973c33..409702d 100644 --- a/src/test/testCode.c +++ b/src/test/testCode.c @@ -114,6 +114,9 @@ int main(){ // Tests for comparison expressions failed += runComparisonTests(); + // Tests for while loop + failed += runWhileTests(); + printf("\n=== Failed Tests: %d\n", failed); if (failed > 0) { diff --git a/src/test/tests.h b/src/test/tests.h index 1215d5e..a8c9a1b 100644 --- a/src/test/tests.h +++ b/src/test/tests.h @@ -4,4 +4,5 @@ int runFunctionCallTests(); int runRecursiveTests(); -int runComparisonTests(); \ No newline at end of file +int runComparisonTests(); +int runWhileTests(); \ No newline at end of file diff --git a/src/test/tests.k b/src/test/tests.k index 32b21d3..1386717 100644 --- a/src/test/tests.k +++ b/src/test/tests.k @@ -133,4 +133,12 @@ function gte(x, y) { return (x >= y); } +function myWhile(end) { + let cond = 0; + while ((cond < end)) { + cond = (cond + 1); + } + return cond; +} + add(1, 1); diff --git a/src/test/while/while.c b/src/test/while/while.c new file mode 100644 index 0000000..a44d065 --- /dev/null +++ b/src/test/while/while.c @@ -0,0 +1,27 @@ +#include +#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; +} \ No newline at end of file diff --git a/src/test/while/while.h b/src/test/while/while.h new file mode 100644 index 0000000..940c076 --- /dev/null +++ b/src/test/while/while.h @@ -0,0 +1 @@ +int myWhile(int x); \ No newline at end of file