Merge branch 'feature/add-bool-literal' into 'master'
Feature/add bool literal See merge request mkais001/klang!6
This commit is contained in:
@@ -72,13 +72,17 @@ expression
|
|||||||
| OPAR lhs=expression GT rhs=expression CPAR #greaterThanExpression
|
| OPAR lhs=expression GT rhs=expression CPAR #greaterThanExpression
|
||||||
| OPAR lhs=expression LTE rhs=expression CPAR #lessThanOrEqualToExpression
|
| OPAR lhs=expression LTE rhs=expression CPAR #lessThanOrEqualToExpression
|
||||||
| OPAR lhs=expression GTE rhs=expression CPAR #GreaterThanOrEqualToExpression
|
| 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
|
| SUB expression #negateExpression
|
||||||
|
| NOT expression #NotExpression
|
||||||
| functionCall #functionCallExpression
|
| functionCall #functionCallExpression
|
||||||
;
|
;
|
||||||
|
|
||||||
atom
|
atom
|
||||||
: INTEGER_LITERAL #intAtom
|
: INTEGER_LITERAL #intAtom
|
||||||
| IDENT # variable
|
| BOOLEAN_LITERAL #boolAtom
|
||||||
|
| IDENT #variable
|
||||||
;
|
;
|
||||||
|
|
||||||
functionCall
|
functionCall
|
||||||
@@ -126,6 +130,9 @@ LT: '<';
|
|||||||
GT: '>';
|
GT: '>';
|
||||||
LTE: '<=';
|
LTE: '<=';
|
||||||
GTE: '>=';
|
GTE: '>=';
|
||||||
|
OR: '||';
|
||||||
|
AND: '&&';
|
||||||
|
NOT: '!';
|
||||||
|
|
||||||
MUL: '*';
|
MUL: '*';
|
||||||
ADD: '+';
|
ADD: '+';
|
||||||
@@ -137,6 +144,11 @@ INTEGER_LITERAL
|
|||||||
: [0-9]+
|
: [0-9]+
|
||||||
;
|
;
|
||||||
|
|
||||||
|
BOOLEAN_LITERAL
|
||||||
|
: 'true'
|
||||||
|
| 'false'
|
||||||
|
;
|
||||||
|
|
||||||
IDENT
|
IDENT
|
||||||
: [a-zA-Z][a-zA-Z0-9]*
|
: [a-zA-Z][a-zA-Z0-9]*
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -126,6 +126,16 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
|||||||
return new ReturnStatement(expression);
|
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
|
@Override
|
||||||
public Node visitAdditionExpression(KlangParser.AdditionExpressionContext ctx) {
|
public Node visitAdditionExpression(KlangParser.AdditionExpressionContext ctx) {
|
||||||
return new AdditionExpression((Expression) this.visit(ctx.lhs), (Expression) this.visit(ctx.rhs));
|
return new AdditionExpression((Expression) this.visit(ctx.lhs), (Expression) this.visit(ctx.rhs));
|
||||||
@@ -186,6 +196,11 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
|||||||
return new NegateExpression((Expression) this.visit(ctx.expression()));
|
return new NegateExpression((Expression) this.visit(ctx.expression()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node visitNotExpression(KlangParser.NotExpressionContext ctx) {
|
||||||
|
return new NotExpression((Expression) this.visit(ctx.expression()));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node visitVariable(KlangParser.VariableContext ctx) {
|
public Node visitVariable(KlangParser.VariableContext ctx) {
|
||||||
String name = ctx.IDENT().getText();
|
String name = ctx.IDENT().getText();
|
||||||
@@ -209,6 +224,13 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node visitBoolAtom(KlangParser.BoolAtomContext ctx) {
|
||||||
|
Node n = new BooleanExpression(ctx.getText().equals("true") ? true : false);
|
||||||
|
n.type = Type.getBooleanType();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node visitFunctionDef(KlangParser.FunctionDefContext ctx) {
|
public Node visitFunctionDef(KlangParser.FunctionDefContext ctx) {
|
||||||
String name = ctx.funcName.getText();
|
String name = ctx.funcName.getText();
|
||||||
|
|||||||
@@ -10,4 +10,8 @@ public class Value {
|
|||||||
public int asInteger() {
|
public int asInteger() {
|
||||||
return (int) this.value;
|
return (int) this.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean asBoolean() {
|
||||||
|
return (boolean) this.value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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> R welcome(Visitor<R> v) {
|
||||||
|
return v.visit(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package de.hsrm.compiler.Klang.nodes.expressions;
|
||||||
|
|
||||||
|
import de.hsrm.compiler.Klang.visitors.Visitor;
|
||||||
|
|
||||||
|
public class BooleanExpression extends Expression {
|
||||||
|
public boolean value;
|
||||||
|
|
||||||
|
public BooleanExpression(boolean value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R> R welcome(Visitor<R> v) {
|
||||||
|
return v.visit(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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> R welcome(Visitor<R> v) {
|
||||||
|
return v.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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> R welcome(Visitor<R> v) {
|
||||||
|
return v.visit(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/main/java/de/hsrm/compiler/Klang/types/BooleanType.java
Normal file
20
src/main/java/de/hsrm/compiler/Klang/types/BooleanType.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package de.hsrm.compiler.Klang.types;
|
||||||
|
|
||||||
|
public class BooleanType extends PrimitiveType {
|
||||||
|
|
||||||
|
private static BooleanType instance = null;
|
||||||
|
|
||||||
|
public static BooleanType getType() {
|
||||||
|
if (instance != null) {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
instance = new BooleanType();
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBooleanType() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,4 +10,8 @@ public abstract class PrimitiveType extends Type {
|
|||||||
public boolean isIntegerType() {
|
public boolean isIntegerType() {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public boolean isBooleanType() {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -8,5 +8,9 @@ public abstract class Type {
|
|||||||
return IntegerType.getType();
|
return IntegerType.getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BooleanType getBooleanType() {
|
||||||
|
return BooleanType.getType();
|
||||||
|
}
|
||||||
|
|
||||||
public abstract boolean isPrimitiveType();
|
public abstract boolean isPrimitiveType();
|
||||||
}
|
}
|
||||||
@@ -23,6 +23,11 @@ public class EvalVisitor implements Visitor<Value> {
|
|||||||
return new Value(e.value);
|
return new Value(e.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value visit(BooleanExpression e) {
|
||||||
|
return new Value(e.value);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value visit(EqualityExpression e) {
|
public Value visit(EqualityExpression e) {
|
||||||
Value lhs = e.lhs.welcome(this);
|
Value lhs = e.lhs.welcome(this);
|
||||||
@@ -124,6 +129,26 @@ public class EvalVisitor implements Visitor<Value> {
|
|||||||
return new Value(-a.asInteger());
|
return new Value(-a.asInteger());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value visit(OrExpression e) {
|
||||||
|
Value lhs = e.lhs.welcome(this);
|
||||||
|
Value rhs = e.rhs.welcome(this);
|
||||||
|
return new Value(lhs.asBoolean() || rhs.asBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value visit(AndExpression e) {
|
||||||
|
Value lhs = e.lhs.welcome(this);
|
||||||
|
Value rhs = e.rhs.welcome(this);
|
||||||
|
return new Value(lhs.asBoolean() && rhs.asBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value visit(NotExpression e) {
|
||||||
|
Value lhs = e.lhs.welcome(this);
|
||||||
|
return new Value(!lhs.asBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value visit(Variable e) {
|
public Value visit(Variable e) {
|
||||||
Value result = this.env.get(e.name);
|
Value result = this.env.get(e.name);
|
||||||
|
|||||||
@@ -78,6 +78,12 @@ public class GenASM implements Visitor<Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(BooleanExpression e) {
|
||||||
|
this.ex.write(" movq $" + (e.value ? 1 : 0) + ", %rax\n");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(Variable e) {
|
public Void visit(Variable e) {
|
||||||
this.ex.write(" movq " + this.env.get(e.name) + "(%rbp), %rax\n");
|
this.ex.write(" movq " + this.env.get(e.name) + "(%rbp), %rax\n");
|
||||||
@@ -272,6 +278,103 @@ public class GenASM implements Visitor<Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(OrExpression e) {
|
||||||
|
int lblTrue = ++lCount;
|
||||||
|
int lblFalse = ++lCount;
|
||||||
|
int lblEnd = ++lCount;
|
||||||
|
|
||||||
|
// Werte LHS aus
|
||||||
|
// Wenn LHS != 0 bedeutet das true
|
||||||
|
// also können wir direkt sagen dass das Ergebnis true ist
|
||||||
|
e.lhs.welcome(this);
|
||||||
|
this.ex.write(" cmpq $0, %rax\n");
|
||||||
|
this.ex.write(" jne .L" + lblTrue + "\n");
|
||||||
|
|
||||||
|
// LHS war false, also werte RHS aus
|
||||||
|
// Wenn RHS == 0 bedeutet das false,
|
||||||
|
// also ist das Gesamtergebnis false
|
||||||
|
e.rhs.welcome(this);
|
||||||
|
this.ex.write(" cmpq $0, %rax\n");
|
||||||
|
this.ex.write(" je .L" + lblFalse + "\n");
|
||||||
|
|
||||||
|
// Die Expression wertet zu true aus
|
||||||
|
// Springe am false Teil vorbei
|
||||||
|
this.ex.write(".L" + lblTrue + ":\n");
|
||||||
|
this.ex.write(" movq $1, %rax\n");
|
||||||
|
this.ex.write(" jmp .L" + lblEnd + "\n");
|
||||||
|
|
||||||
|
// Die Expressoin wertet zu false aus
|
||||||
|
this.ex.write(".L" + lblFalse + ":\n");
|
||||||
|
this.ex.write(" movq $0, %rax\n");
|
||||||
|
|
||||||
|
// Das hier ist das ende
|
||||||
|
this.ex.write(".L" + lblEnd + ":\n");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(AndExpression e) {
|
||||||
|
int lblTrue = ++lCount;
|
||||||
|
int lblFalse = ++lCount;
|
||||||
|
int lblEnd = ++lCount;
|
||||||
|
|
||||||
|
// Werte LHS aus
|
||||||
|
// Wenn LHS == 0, bedeutet das false
|
||||||
|
// also können wir direkt sagen dass das Ergebnis false ist
|
||||||
|
e.lhs.welcome(this);
|
||||||
|
this.ex.write(" cmpq $0, %rax\n");
|
||||||
|
this.ex.write(" je .L" + lblFalse + "\n");
|
||||||
|
|
||||||
|
// LHS war true, also werte RHS aus.
|
||||||
|
// Wenn RHS == 0, bedeutet das false
|
||||||
|
// also ist das Gesamtergebnis false
|
||||||
|
e.rhs.welcome(this);
|
||||||
|
this.ex.write(" cmpq $0, %rax\n");
|
||||||
|
this.ex.write(" je .L" + lblFalse +"\n");
|
||||||
|
|
||||||
|
// Die Expression wertet zu true aus
|
||||||
|
// Springe am false Teil vorbei
|
||||||
|
this.ex.write(".L" + lblTrue +":\n");
|
||||||
|
this.ex.write(" movq $1, %rax\n");
|
||||||
|
this.ex.write(" jmp .L" + lblEnd + "\n");
|
||||||
|
|
||||||
|
// Die Expressoin wertet zu false aus
|
||||||
|
this.ex.write(".L" + lblFalse +":\n");
|
||||||
|
this.ex.write(" movq $0, %rax\n");
|
||||||
|
|
||||||
|
// Das hier ist das ende
|
||||||
|
this.ex.write(".L" + lblEnd +":\n");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(NotExpression e) {
|
||||||
|
int lblFalse = ++lCount;
|
||||||
|
int lblEnd = ++lCount;
|
||||||
|
|
||||||
|
// Werte LHS aus
|
||||||
|
// Wenn LHS != 0 bedeutet das true, also jumpe zum false Teil
|
||||||
|
// Wenn nicht, falle durch zum true Teil
|
||||||
|
e.lhs.welcome(this);
|
||||||
|
this.ex.write(" cmpq $0, %rax\n");
|
||||||
|
this.ex.write(" jne .L" +lblFalse +"\n");
|
||||||
|
|
||||||
|
// Hier ist das Ergebnis true
|
||||||
|
// Springe am false Teil vorbei
|
||||||
|
this.ex.write(" movq $1, %rax\n");
|
||||||
|
this.ex.write(" jmp .L" +lblEnd +"\n");
|
||||||
|
|
||||||
|
// Hier ist das Ergebnis false
|
||||||
|
// Falle zum Ende durch
|
||||||
|
this.ex.write(".L" +lblFalse + ":\n");
|
||||||
|
this.ex.write("movq $0, %rax\n");
|
||||||
|
|
||||||
|
// Hier ist das Ende
|
||||||
|
this.ex.write(".L" +lblEnd + ":\n");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(IfStatement e) {
|
public Void visit(IfStatement e) {
|
||||||
int lblElse = ++lCount;
|
int lblElse = ++lCount;
|
||||||
@@ -324,7 +427,7 @@ public class GenASM implements Visitor<Void> {
|
|||||||
this.ex.write(" jnz .L" + lblStart + "\n");
|
this.ex.write(" jnz .L" + lblStart + "\n");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(ForLoop e) {
|
public Void visit(ForLoop e) {
|
||||||
int lblStart = ++lCount;
|
int lblStart = ++lCount;
|
||||||
@@ -338,7 +441,7 @@ public class GenASM implements Visitor<Void> {
|
|||||||
e.step.welcome(this);
|
e.step.welcome(this);
|
||||||
this.ex.write(" jmp .L" + lblStart + "\n");
|
this.ex.write(" jmp .L" + lblStart + "\n");
|
||||||
this.ex.write(".L" + lblEnd + ":\n");
|
this.ex.write(".L" + lblEnd + ":\n");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,7 +556,7 @@ public class GenASM implements Visitor<Void> {
|
|||||||
this.ex.write("\n");
|
this.ex.write("\n");
|
||||||
}
|
}
|
||||||
this.ex.write(".globl " + mainName + "\n");
|
this.ex.write(".globl " + mainName + "\n");
|
||||||
this.ex.write(".type " +mainName + ", @function\n");
|
this.ex.write(".type " + mainName + ", @function\n");
|
||||||
this.ex.write(mainName + ":\n");
|
this.ex.write(mainName + ":\n");
|
||||||
this.ex.write(" pushq %rbp\n");
|
this.ex.write(" pushq %rbp\n");
|
||||||
this.ex.write(" movq %rsp, %rbp\n");
|
this.ex.write(" movq %rsp, %rbp\n");
|
||||||
|
|||||||
@@ -22,6 +22,11 @@ class GetVars implements Visitor<Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(BooleanExpression e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(Variable e) {
|
public Void visit(Variable e) {
|
||||||
return null;
|
return null;
|
||||||
@@ -110,6 +115,26 @@ class GetVars implements Visitor<Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(OrExpression e) {
|
||||||
|
e.lhs.welcome(this);
|
||||||
|
e.rhs.welcome(this);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(AndExpression e) {
|
||||||
|
e.lhs.welcome(this);
|
||||||
|
e.rhs.welcome(this);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(NotExpression e) {
|
||||||
|
e.lhs.welcome(this);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(IfStatement e) {
|
public Void visit(IfStatement e) {
|
||||||
e.cond.welcome(this);
|
e.cond.welcome(this);
|
||||||
|
|||||||
@@ -72,6 +72,12 @@ public class PrettyPrintVisitor implements Visitor<Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(BooleanExpression e) {
|
||||||
|
ex.write(e.value);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(EqualityExpression e) {
|
public Void visit(EqualityExpression e) {
|
||||||
ex.write("(");
|
ex.write("(");
|
||||||
@@ -189,6 +195,33 @@ public class PrettyPrintVisitor implements Visitor<Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(OrExpression e) {
|
||||||
|
ex.write("(");
|
||||||
|
e.lhs.welcome(this);
|
||||||
|
ex.write(" || ");
|
||||||
|
e.rhs.welcome(this);
|
||||||
|
ex.write(")");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(AndExpression e) {
|
||||||
|
ex.write("(");
|
||||||
|
e.lhs.welcome(this);
|
||||||
|
ex.write(" && ");
|
||||||
|
e.rhs.welcome(this);
|
||||||
|
ex.write(")");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(NotExpression e) {
|
||||||
|
ex.write("!");
|
||||||
|
e.lhs.welcome(this);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(IfStatement e) {
|
public Void visit(IfStatement e) {
|
||||||
ex.write("if (");
|
ex.write("if (");
|
||||||
|
|||||||
@@ -8,7 +8,11 @@ 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> {
|
||||||
|
R visit(OrExpression e);
|
||||||
|
R visit(AndExpression e);
|
||||||
|
R visit (NotExpression e);
|
||||||
R visit(IntegerExpression e);
|
R visit(IntegerExpression e);
|
||||||
|
R visit(BooleanExpression e);
|
||||||
R visit(Variable e);
|
R visit(Variable e);
|
||||||
R visit(AdditionExpression e);
|
R visit(AdditionExpression e);
|
||||||
R visit(EqualityExpression e);
|
R visit(EqualityExpression e);
|
||||||
|
|||||||
@@ -12,6 +12,26 @@ int comparisonTest(char* name, int x, int y, int expected, int result) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int boolTestOne(char* name, bool x, bool expected, bool result) {
|
||||||
|
if (expected == result) {
|
||||||
|
bool_succPrefixOne(name, x, expected, result);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
bool_errPrefixOne(name, x, expected, result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int boolTestTwo(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() {
|
void runComparisonTests() {
|
||||||
printf("\nComparison Tests \n");
|
printf("\nComparison Tests \n");
|
||||||
comparisonTest("==", 1, 1, 1, eq(1, 1));
|
comparisonTest("==", 1, 1, 1, eq(1, 1));
|
||||||
@@ -43,4 +63,17 @@ void runComparisonTests() {
|
|||||||
comparisonTest(">=", 1, 0, 1, gte(1, 0));
|
comparisonTest(">=", 1, 0, 1, gte(1, 0));
|
||||||
comparisonTest(">=", 0, 1, 0, gte(0, 1));
|
comparisonTest(">=", 0, 1, 0, gte(0, 1));
|
||||||
comparisonTest(">=", 0, 0, 1, gte(0, 0));
|
comparisonTest(">=", 0, 0, 1, gte(0, 0));
|
||||||
|
|
||||||
|
boolTestTwo("&&", true, true, true, and(true, true));
|
||||||
|
boolTestTwo("&&", true, false, false, and(true, false));
|
||||||
|
boolTestTwo("&&", false, true, false, and(false, true));
|
||||||
|
boolTestTwo("&&", false, false, false, and(false, false));
|
||||||
|
|
||||||
|
boolTestTwo("||", true, true, true, or(true, true));
|
||||||
|
boolTestTwo("||", true, false, true, or(true, false));
|
||||||
|
boolTestTwo("||", false, true, true, or(false, true));
|
||||||
|
boolTestTwo("||", false, false, false, or(false, false));
|
||||||
|
|
||||||
|
boolTestOne("!", true, false, not(true));
|
||||||
|
boolTestOne("!", false, true, not(false));
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
int eq(int x, int y);
|
int eq(int x, int y);
|
||||||
int neq(int x, int y);
|
int neq(int x, int y);
|
||||||
int lt(int x, int y);
|
int lt(int x, int y);
|
||||||
int lte(int x, int y);
|
int lte(int x, int y);
|
||||||
int gt(int x, int y);
|
int gt(int x, int y);
|
||||||
int gte(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);
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
|
|
||||||
|
char* printBool(bool a) {
|
||||||
|
if (a == true) {
|
||||||
|
return "true";
|
||||||
|
}
|
||||||
|
return "false";
|
||||||
|
}
|
||||||
|
|
||||||
void succInfixTwo(char* name, int x, int y, int expected, int result) {
|
void succInfixTwo(char* name, int x, int y, int expected, int result) {
|
||||||
incSuccess();
|
incSuccess();
|
||||||
printf("\033[0;32mSUCCESS:\t%d %s %d\tGOT: %d\tExpected: %d\033[0;0m\n", x, name, y, result, expected);
|
printf("\033[0;32mSUCCESS:\t%d %s %d\tGOT: %d\tExpected: %d\033[0;0m\n", x, name, y, result, expected);
|
||||||
@@ -39,4 +46,24 @@ 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 errPrefixTwo(char* name, int x, int y, int expected, int result) {
|
||||||
incFailure();
|
incFailure();
|
||||||
printf("\033[0;31mERROR:\t\t%s(%d, %d)\tGOT: %d\tExpected: %d\033[0;0m\n", name, x, y, result, expected);
|
printf("\033[0;31mERROR:\t\t%s(%d, %d)\tGOT: %d\tExpected: %d\033[0;0m\n", name, x, y, result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bool_succPrefixOne(char* name, bool x, bool expected, bool result) {
|
||||||
|
incSuccess();
|
||||||
|
printf("\033[0;32mSUCCESS:\t%s%s\tGOT: %s\tExpected: %s\033[0;0m\n", name, printBool(x), printBool(result), printBool(expected));
|
||||||
|
}
|
||||||
|
|
||||||
|
void bool_errPrefixOne(char* name, bool x, bool expected, bool result) {
|
||||||
|
incFailure();
|
||||||
|
printf("\033[0;31mERROR:\t\t%s%s\tGOT: %s\tExpected: %s\033[0;0m\n", name, printBool(x), printBool(result), printBool(expected));
|
||||||
|
}
|
||||||
|
|
||||||
|
void bool_succInfixTwo(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", printBool(a), name, printBool(b), printBool(result), printBool(expected));
|
||||||
|
}
|
||||||
|
|
||||||
|
void bool_errInfixTwo(char* name, bool a, bool b, bool expected, bool result) {
|
||||||
|
incFailure();
|
||||||
|
printf("\033[0;31mERROR:\t\t%s %s %s\tGOT: %s\tExpected: %s\033[0;0m\n", printBool(a), name, printBool(b), printBool(result), printBool(expected));
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
void incSuccess();
|
void incSuccess();
|
||||||
void incFailure();
|
void incFailure();
|
||||||
|
|
||||||
@@ -6,8 +8,15 @@ void err(char* name, int expected, int result);
|
|||||||
|
|
||||||
void succPrefixOne(char* name, int x, int expected, int result);
|
void succPrefixOne(char* name, int x, int expected, int result);
|
||||||
void errPrefixOne(char* name, int x, int expected, int result);
|
void errPrefixOne(char* name, int x, int expected, int result);
|
||||||
|
|
||||||
void succPrefixTwo(char* name, int x, int y, int expected, int result);
|
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 errPrefixTwo(char* name, int x, int y, int expected, int result);
|
||||||
|
|
||||||
void succInfixTwo(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);
|
void errInfixTwo(char* name, int x, int y, int expected, int result);
|
||||||
|
|
||||||
|
void bool_succPrefixOne(char* name, bool x, bool expected, bool result);
|
||||||
|
void bool_errPrefixOne(char* name, bool x, bool expected, bool 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);
|
||||||
|
|||||||
@@ -162,4 +162,16 @@ function myFor(end) {
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function and(a, b) {
|
||||||
|
return (a && b);
|
||||||
|
}
|
||||||
|
|
||||||
|
function or(a, b) {
|
||||||
|
return (a || b);
|
||||||
|
}
|
||||||
|
|
||||||
|
function not(a) {
|
||||||
|
return !a;
|
||||||
|
}
|
||||||
|
|
||||||
add(1, 1);
|
add(1, 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user