Added while loop
This commit is contained in:
@@ -1,2 +1,4 @@
|
|||||||
# Klang - The Kaiser language
|
# Klang - The Kaiser language
|
||||||
This is the project for Klang - the Kaiser language.
|
This is the project for Klang - the Kaiser language.
|
||||||
|
|
||||||
|
0 is false
|
||||||
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/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
|
./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
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ statement
|
|||||||
| variable_declaration
|
| variable_declaration
|
||||||
| variable_assignment
|
| variable_assignment
|
||||||
| return_statement
|
| return_statement
|
||||||
|
| whileLoop
|
||||||
;
|
;
|
||||||
|
|
||||||
print
|
print
|
||||||
@@ -79,12 +80,17 @@ arguments
|
|||||||
: (expression (COMMA expression)*)?
|
: (expression (COMMA expression)*)?
|
||||||
;
|
;
|
||||||
|
|
||||||
|
whileLoop
|
||||||
|
: WHILE OPAR cond = expression CPAR braced_block
|
||||||
|
;
|
||||||
|
|
||||||
PRINT: 'print';
|
PRINT: 'print';
|
||||||
IF: 'if';
|
IF: 'if';
|
||||||
ELSE: 'else';
|
ELSE: 'else';
|
||||||
FUNC: 'function';
|
FUNC: 'function';
|
||||||
RETURN: 'return';
|
RETURN: 'return';
|
||||||
LET: 'let';
|
LET: 'let';
|
||||||
|
WHILE: 'while';
|
||||||
|
|
||||||
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.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;
|
||||||
|
|
||||||
@@ -57,6 +58,14 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Override
|
||||||
public Node visitVariable_declaration(KlangParser.Variable_declarationContext ctx) {
|
public Node visitVariable_declaration(KlangParser.Variable_declarationContext ctx) {
|
||||||
String name = ctx.IDENT().getText();
|
String name = ctx.IDENT().getText();
|
||||||
|
|||||||
@@ -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> 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.whileLoop;
|
||||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||||
|
|
||||||
public class EvalVisitor implements Visitor<Value> {
|
public class EvalVisitor implements Visitor<Value> {
|
||||||
@@ -151,6 +152,18 @@ public class EvalVisitor implements Visitor<Value> {
|
|||||||
return result;
|
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
|
@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.whileLoop;
|
||||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||||
|
|
||||||
public class GenASM implements Visitor<Void> {
|
public class GenASM implements Visitor<Void> {
|
||||||
@@ -290,6 +291,20 @@ public class GenASM implements Visitor<Void> {
|
|||||||
return null;
|
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
|
@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?!");
|
||||||
@@ -384,7 +399,7 @@ public class GenASM implements Visitor<Void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Den Rest auf den stack pushen
|
// 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);
|
e.arguments[i].welcome(this);
|
||||||
this.ex.write(" pushq %rax\n");
|
this.ex.write(" pushq %rax\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.whileLoop;
|
||||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||||
|
|
||||||
class GetVars implements Visitor<Void> {
|
class GetVars implements Visitor<Void> {
|
||||||
@@ -119,6 +120,13 @@ class GetVars implements Visitor<Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(whileLoop 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,6 +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.statements.*;
|
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||||
|
|
||||||
public class PrettyPrintVisitor implements Visitor<Void> {
|
public class PrettyPrintVisitor implements Visitor<Void> {
|
||||||
@@ -204,6 +205,15 @@ public class PrettyPrintVisitor implements Visitor<Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(whileLoop e) {
|
||||||
|
ex.write("while (");
|
||||||
|
e.cond.welcome(this);
|
||||||
|
ex.write(") ");
|
||||||
|
e.block.welcome(this);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(PrintStatement e) {
|
public Void visit(PrintStatement e) {
|
||||||
ex.write("print ");
|
ex.write("print ");
|
||||||
|
|||||||
@@ -4,6 +4,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.*;
|
||||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||||
|
|
||||||
public interface Visitor<R> {
|
public interface Visitor<R> {
|
||||||
@@ -22,6 +23,7 @@ public interface Visitor<R> {
|
|||||||
R visit(ModuloExpression e);
|
R visit(ModuloExpression e);
|
||||||
R visit(NegateExpression e);
|
R visit(NegateExpression e);
|
||||||
R visit(IfStatement e);
|
R visit(IfStatement e);
|
||||||
|
R visit(whileLoop 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);
|
||||||
|
|||||||
@@ -114,6 +114,9 @@ int main(){
|
|||||||
// Tests for comparison expressions
|
// Tests for comparison expressions
|
||||||
failed += runComparisonTests();
|
failed += runComparisonTests();
|
||||||
|
|
||||||
|
// Tests for while loop
|
||||||
|
failed += runWhileTests();
|
||||||
|
|
||||||
printf("\n=== Failed Tests: %d\n", failed);
|
printf("\n=== Failed Tests: %d\n", failed);
|
||||||
|
|
||||||
if (failed > 0) {
|
if (failed > 0) {
|
||||||
|
|||||||
@@ -5,3 +5,4 @@
|
|||||||
int runFunctionCallTests();
|
int runFunctionCallTests();
|
||||||
int runRecursiveTests();
|
int runRecursiveTests();
|
||||||
int runComparisonTests();
|
int runComparisonTests();
|
||||||
|
int runWhileTests();
|
||||||
@@ -133,4 +133,12 @@ function gte(x, y) {
|
|||||||
return (x >= y);
|
return (x >= y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function myWhile(end) {
|
||||||
|
let cond = 0;
|
||||||
|
while ((cond < end)) {
|
||||||
|
cond = (cond + 1);
|
||||||
|
}
|
||||||
|
return cond;
|
||||||
|
}
|
||||||
|
|
||||||
add(1, 1);
|
add(1, 1);
|
||||||
|
|||||||
27
src/test/while/while.c
Normal file
27
src/test/while/while.c
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#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
src/test/while/while.h
Normal file
1
src/test/while/while.h
Normal file
@@ -0,0 +1 @@
|
|||||||
|
int myWhile(int x);
|
||||||
Reference in New Issue
Block a user