diff --git a/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 b/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 index c88746e..136d971 100644 --- a/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 +++ b/src/main/antlr4/de/hsrm/compiler/Klang/Klang.g4 @@ -72,7 +72,10 @@ expression | OPAR lhs=expression GT rhs=expression CPAR #greaterThanExpression | OPAR lhs=expression LTE rhs=expression CPAR #lessThanOrEqualToExpression | OPAR lhs=expression GTE rhs=expression CPAR #GreaterThanOrEqualToExpression + | OPAR lhs=expression OR rhs=expression CPAR #OrExpression + | OPAR lhs=expression AND rhs=expression CPAR #AndExpression | SUB expression #negateExpression + | NOT expression #NotExpression | functionCall #functionCallExpression ; @@ -127,6 +130,9 @@ LT: '<'; GT: '>'; LTE: '<='; GTE: '>='; +OR: '||'; +AND: '&&'; +NOT: '!'; MUL: '*'; ADD: '+'; diff --git a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java index bfb3905..da7cfa0 100644 --- a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java +++ b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java @@ -10,6 +10,7 @@ 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; +import sun.tools.tree.OrExpression; public class ContextAnalysis extends KlangBaseVisitor { Set vars = new HashSet<>(); @@ -126,6 +127,16 @@ public class ContextAnalysis extends KlangBaseVisitor { return new ReturnStatement(expression); } + @Override + public Node visitOrExpression(KlangParser.OrExpressionContext ctx) { + return new OrExpression((Expression) this.visit(ctx.lhs), (Expression) this.visit(ctx.rhs)); + } + + @Override + public Node visitAndExpression(KlangParser.AndExpressionContext ctx) { + return new AndExpression((Expression) this.visit(ctx.lhs), (Expression) this.visit(ctx.rhs)); + } + @Override public Node visitAdditionExpression(KlangParser.AdditionExpressionContext ctx) { return new AdditionExpression((Expression) this.visit(ctx.lhs), (Expression) this.visit(ctx.rhs)); @@ -186,6 +197,11 @@ public class ContextAnalysis extends KlangBaseVisitor { return new NegateExpression((Expression) this.visit(ctx.expression())); } + @Override + public Node visitNotExpression(KlangParser.NotExpressionContext ctx) { + return new NotExpression((Expression) this.visit(ctx.expression())); + } + @Override public Node visitVariable(KlangParser.VariableContext ctx) { String name = ctx.IDENT().getText(); diff --git a/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/AndExpression.java b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/AndExpression.java new file mode 100644 index 0000000..523a8fe --- /dev/null +++ b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/AndExpression.java @@ -0,0 +1,14 @@ +package de.hsrm.compiler.Klang.nodes.expressions; + +import de.hsrm.compiler.Klang.visitors.Visitor; + +public class AndExpression extends BinaryExpression { + public AndExpression(Expression lhs, Expression rhs) { + super(lhs, rhs); + } + + @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/nodes/expressions/NotExpression.java b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/NotExpression.java new file mode 100644 index 0000000..f35dd29 --- /dev/null +++ b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/NotExpression.java @@ -0,0 +1,16 @@ +package de.hsrm.compiler.Klang.nodes.expressions; + +import de.hsrm.compiler.Klang.visitors.Visitor; + +public class NotExpression extends UnaryExpression { + + public NotExpression(Expression lhs) { + super(lhs); + } + + @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/nodes/expressions/OrExpression.java b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/OrExpression.java new file mode 100644 index 0000000..6514275 --- /dev/null +++ b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/OrExpression.java @@ -0,0 +1,14 @@ +package de.hsrm.compiler.Klang.nodes.expressions; + +import de.hsrm.compiler.Klang.visitors.Visitor; + +public class OrExpression extends BinaryExpression { + public OrExpression(Expression lhs, Expression rhs) { + super(lhs, rhs); + } + + @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/Visitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java index eb7121e..b0abb24 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java @@ -8,6 +8,9 @@ import de.hsrm.compiler.Klang.nodes.loops.*; import de.hsrm.compiler.Klang.nodes.statements.*; public interface Visitor { + R visit(OrExpression e); + R visit(AndExpression e); + R visit (NotExpression e); R visit(IntegerExpression e); R visit(BooleanExpression e); R visit(Variable e); diff --git a/src/test/comparison/comparison.c b/src/test/comparison/comparison.c index c6d12d4..e8f876f 100644 --- a/src/test/comparison/comparison.c +++ b/src/test/comparison/comparison.c @@ -1,4 +1,5 @@ #include +#include #include "comparison.h" #include "../print/print.h" @@ -12,6 +13,16 @@ int comparisonTest(char* name, int x, int y, int expected, int result) { } } +int boolTest(char* name, bool a, bool b, bool expected, bool result) { + if (expected == result) { + bool_succInfixTwo(name, a, b, expected, result); + return 0; + } else { + bool_errInfixTwo(name, a, b, expected, result); + return 1; + } +} + void runComparisonTests() { printf("\nComparison Tests \n"); comparisonTest("==", 1, 1, 1, eq(1, 1)); @@ -43,4 +54,9 @@ void runComparisonTests() { comparisonTest(">=", 1, 0, 1, gte(1, 0)); comparisonTest(">=", 0, 1, 0, gte(0, 1)); comparisonTest(">=", 0, 0, 1, gte(0, 0)); + + boolTest("&&", true, true, true, and(true, true)); + boolTest("&&", true, false, false, and(true, false)); + boolTest("&&", false, true, false, and(false, true)); + boolTest("&&", false, false, false, and(false, false)); } \ No newline at end of file diff --git a/src/test/comparison/comparison.h b/src/test/comparison/comparison.h index 9d4b35a..f5a9566 100644 --- a/src/test/comparison/comparison.h +++ b/src/test/comparison/comparison.h @@ -1,6 +1,12 @@ +#include + int eq(int x, int y); int neq(int x, int y); int lt(int x, int y); int lte(int x, int y); int gt(int x, int y); int gte(int x, int y); + +bool and(bool a, bool b); +bool or(bool a, bool b); +bool not(bool a); \ No newline at end of file diff --git a/src/test/print/print.c b/src/test/print/print.c index 511a67e..ae46b7f 100644 --- a/src/test/print/print.c +++ b/src/test/print/print.c @@ -1,3 +1,4 @@ +#include #include #include "print.h" @@ -39,4 +40,22 @@ void succPrefixTwo(char* name, int x, int y, int expected, int result) { void errPrefixTwo(char* name, int x, int y, int expected, int result) { incFailure(); printf("\033[0;31mERROR:\t\t%s(%d, %d)\tGOT: %d\tExpected: %d\033[0;0m\n", name, x, y, result, expected); +} + +void bool_succPrefixTwo(char* name, bool a, bool b, bool expected, bool result) { + incSuccess(); + printf("\033[0;32mSUCCESS:\t%s(%s, %s)\tGOT: %s\tExpected: %s\033[0;0m\n", name, printBool(a), printBool(b), printBool(result), printBool(expected)); +} + +void bool_errPrefixTwo(char* name, bool a, bool b, bool expected, bool result) { + incFailure(); + printf("\033[0;32mSUCCESS:\t%s(%s, %s)\tGOT: %s\tExpected: %s\033[0;0m\n", name, printBool(a), printBool(b), printBool(result), printBool(expected)); + +} + +char* printBool(bool a) { + if (a == true) { + return "true"; + } + return "false"; } \ No newline at end of file diff --git a/src/test/print/print.h b/src/test/print/print.h index d274b51..5673d5c 100644 --- a/src/test/print/print.h +++ b/src/test/print/print.h @@ -10,4 +10,7 @@ void succPrefixTwo(char* name, int x, int y, int expected, int result); void errPrefixTwo(char* name, int x, int y, int expected, int result); void succInfixTwo(char* name, int x, int y, int expected, int result); -void errInfixTwo(char* name, int x, int y, int expected, int result); \ No newline at end of file +void errInfixTwo(char* name, int x, int y, int expected, int result); + +void bool_succInfixTwo(char* name, bool x, bool y, bool expected, bool result); +void bool_errInfixTwo(char* name, bool x, bool y, bool expected, bool result); diff --git a/src/test/test.k b/src/test/test.k index 6a6abbf..b6066a8 100644 --- a/src/test/test.k +++ b/src/test/test.k @@ -162,4 +162,16 @@ function myFor(end) { return x; } +function and(a, b) { + return (a && b); +} + +function or(a, b) { + return (a || b); +} + +function not(a) { + return (!a); +} + add(1, 1);