From 0d14afa496cae44200f84f3b67d67db0ae65fb6c Mon Sep 17 00:00:00 2001 From: Malte Schmitz Date: Sat, 26 Nov 2016 00:08:39 +0100 Subject: [PATCH] Switch to maven and Java 1.6 --- .gitignore | 2 +- pom.xml | 35 +++ src/Main.java | 47 ---- src/expression/Addition.java | 35 --- src/expression/Expression.java | 4 - src/expression/Identifier.java | 30 --- src/expression/Int.java | 30 --- src/expression/Subtraction.java | 35 --- src/interpreter/Evaluator.java | 41 ---- src/interpreter/Interpreter.java | 48 ---- src/interpreter/InterpreterException.java | 7 - src/interpreter/Visitor.java | 12 - src/main/java/Main.java | 47 ++++ src/main/java/expression/Addition.java | 35 +++ src/main/java/expression/Expression.java | 4 + src/main/java/expression/Identifier.java | 30 +++ src/main/java/expression/Int.java | 30 +++ src/main/java/expression/Subtraction.java | 35 +++ src/main/java/interpreter/Evaluator.java | 41 ++++ src/main/java/interpreter/Interpreter.java | 48 ++++ .../java/interpreter/InterpreterException.java | 7 + src/main/java/interpreter/Visitor.java | 12 + src/main/java/parser/Parser.java | 252 +++++++++++++++++++++ src/main/java/parser/SyntaxException.java | 20 ++ src/main/java/program/Assignment.java | 38 ++++ src/main/java/program/Call.java | 38 ++++ src/main/java/program/Composition.java | 35 +++ src/main/java/program/Conditional.java | 41 ++++ src/main/java/program/Loop.java | 37 +++ src/main/java/program/Program.java | 4 + src/parser/Parser.java | 252 --------------------- src/parser/SyntaxException.java | 20 -- src/program/Assignment.java | 38 ---- src/program/Call.java | 38 ---- src/program/Composition.java | 35 --- src/program/Conditional.java | 41 ---- src/program/Loop.java | 37 --- src/program/Program.java | 4 - src/test/java/interpreter/EvaluatorTest.java | 21 ++ src/test/java/interpreter/InterpreterTest.java | 35 +++ src/test/java/parser/ParserTest.java | 126 +++++++++++ test/interpreter/EvaluatorTest.java | 21 -- test/interpreter/InterpreterTest.java | 35 --- test/parser/ParserTest.java | 126 ----------- 44 files changed, 972 insertions(+), 937 deletions(-) create mode 100644 pom.xml delete mode 100644 src/Main.java delete mode 100644 src/expression/Addition.java delete mode 100644 src/expression/Expression.java delete mode 100644 src/expression/Identifier.java delete mode 100644 src/expression/Int.java delete mode 100644 src/expression/Subtraction.java delete mode 100644 src/interpreter/Evaluator.java delete mode 100644 src/interpreter/Interpreter.java delete mode 100644 src/interpreter/InterpreterException.java delete mode 100644 src/interpreter/Visitor.java create mode 100644 src/main/java/Main.java create mode 100644 src/main/java/expression/Addition.java create mode 100644 src/main/java/expression/Expression.java create mode 100644 src/main/java/expression/Identifier.java create mode 100644 src/main/java/expression/Int.java create mode 100644 src/main/java/expression/Subtraction.java create mode 100644 src/main/java/interpreter/Evaluator.java create mode 100644 src/main/java/interpreter/Interpreter.java create mode 100644 src/main/java/interpreter/InterpreterException.java create mode 100644 src/main/java/interpreter/Visitor.java create mode 100644 src/main/java/parser/Parser.java create mode 100644 src/main/java/parser/SyntaxException.java create mode 100644 src/main/java/program/Assignment.java create mode 100644 src/main/java/program/Call.java create mode 100644 src/main/java/program/Composition.java create mode 100644 src/main/java/program/Conditional.java create mode 100644 src/main/java/program/Loop.java create mode 100644 src/main/java/program/Program.java delete mode 100644 src/parser/Parser.java delete mode 100644 src/parser/SyntaxException.java delete mode 100644 src/program/Assignment.java delete mode 100644 src/program/Call.java delete mode 100644 src/program/Composition.java delete mode 100644 src/program/Conditional.java delete mode 100644 src/program/Loop.java delete mode 100644 src/program/Program.java create mode 100644 src/test/java/interpreter/EvaluatorTest.java create mode 100644 src/test/java/interpreter/InterpreterTest.java create mode 100644 src/test/java/parser/ParserTest.java delete mode 100644 test/interpreter/EvaluatorTest.java delete mode 100644 test/interpreter/InterpreterTest.java delete mode 100644 test/parser/ParserTest.java diff --git a/.gitignore b/.gitignore index de447e7..4ef6b74 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ .idea/ *.iml -/out +/target diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..f3eccf3 --- /dev/null +++ b/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + de.uni_luebeck.isp + WhileInterpreter + 1.0 + + + UTF-8 + + + + + + maven-compiler-plugin + 3.6.0 + + 1.6 + 1.6 + + + + + + + + junit + junit + 4.12 + + + \ No newline at end of file diff --git a/src/Main.java b/src/Main.java deleted file mode 100644 index 4dfd0e5..0000000 --- a/src/Main.java +++ /dev/null @@ -1,47 +0,0 @@ -import interpreter.Interpreter; -import interpreter.InterpreterException; -import parser.Parser; -import parser.SyntaxException; -import program.Program; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Map; - -public class Main { - public static void main(String[] args) { - if (args.length == 0) { - System.err.println("No file given"); - } else if (args.length > 1) { - System.err.println("Too many arguments"); - } else { - try { - String code = readFile(args[0]); - run(code); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - private static String readFile(String filename) throws IOException { - byte[] encoded = Files.readAllBytes(Paths.get(filename)); - return new String(encoded, StandardCharsets.UTF_8); - } - - private static void run(String code) { - try { - Parser parser = new Parser(code); - Program program = parser.parse(); - Interpreter interpreter = new Interpreter(program); - Map valuation = interpreter.getValuation(); - System.out.println(valuation); - } catch (SyntaxException se) { - System.err.println(se); - } catch (InterpreterException ie) { - System.err.println(ie); - } - } -} diff --git a/src/expression/Addition.java b/src/expression/Addition.java deleted file mode 100644 index e0c82a4..0000000 --- a/src/expression/Addition.java +++ /dev/null @@ -1,35 +0,0 @@ -package expression; - -public class Addition extends Expression { - public final Expression leftHandSide; - public final Expression rightHandSide; - - public Addition(Expression leftHandSide, Expression rightHandSide) { - this.leftHandSide = leftHandSide; - this.rightHandSide = rightHandSide; - } - - @Override - public String toString() { - return "(" + leftHandSide + " + " + rightHandSide + ")"; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Addition addition = (Addition) o; - - if (!leftHandSide.equals(addition.leftHandSide)) return false; - return rightHandSide.equals(addition.rightHandSide); - - } - - @Override - public int hashCode() { - int result = leftHandSide.hashCode(); - result = 31 * result + rightHandSide.hashCode(); - return result; - } -} diff --git a/src/expression/Expression.java b/src/expression/Expression.java deleted file mode 100644 index 9e91fa8..0000000 --- a/src/expression/Expression.java +++ /dev/null @@ -1,4 +0,0 @@ -package expression; - -abstract public class Expression { -} diff --git a/src/expression/Identifier.java b/src/expression/Identifier.java deleted file mode 100644 index d3b977b..0000000 --- a/src/expression/Identifier.java +++ /dev/null @@ -1,30 +0,0 @@ -package expression; - -public class Identifier extends Expression { - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Identifier that = (Identifier) o; - - return name.equals(that.name); - - } - - @Override - public String toString() { - return name; - } - - @Override - public int hashCode() { - return name.hashCode(); - } - - public final String name; - - public Identifier(String name) { - this.name = name; - } -} diff --git a/src/expression/Int.java b/src/expression/Int.java deleted file mode 100644 index 6932c75..0000000 --- a/src/expression/Int.java +++ /dev/null @@ -1,30 +0,0 @@ -package expression; - -public class Int extends Expression { - public final int value; - - public Int(int value) { - this.value = value; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Int integer = (Int) o; - - return value == integer.value; - - } - - @Override - public String toString() { - return Integer.toString(value); - } - - @Override - public int hashCode() { - return value; - } -} diff --git a/src/expression/Subtraction.java b/src/expression/Subtraction.java deleted file mode 100644 index 52d4571..0000000 --- a/src/expression/Subtraction.java +++ /dev/null @@ -1,35 +0,0 @@ -package expression; - -public class Subtraction extends Expression { - public final Expression leftHandSide; - public final Expression rightHandSide; - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Subtraction that = (Subtraction) o; - - if (!leftHandSide.equals(that.leftHandSide)) return false; - return rightHandSide.equals(that.rightHandSide); - - } - - @Override - public String toString() { - return "(" + leftHandSide + " - " + rightHandSide + ")"; - } - - @Override - public int hashCode() { - int result = leftHandSide.hashCode(); - result = 31 * result + rightHandSide.hashCode(); - return result; - } - - public Subtraction(Expression leftHandSide, Expression rightHandSide) { - this.leftHandSide = leftHandSide; - this.rightHandSide = rightHandSide; - } -} diff --git a/src/interpreter/Evaluator.java b/src/interpreter/Evaluator.java deleted file mode 100644 index 526f16b..0000000 --- a/src/interpreter/Evaluator.java +++ /dev/null @@ -1,41 +0,0 @@ -package interpreter; - -import expression.*; - -import java.util.HashMap; -import java.util.Map; - -public class Evaluator extends Visitor { - - final Expression expression; - final Map valuation = new HashMap<>(); - - public Evaluator(Expression expression, Map valuation) { - this.expression = expression; - this.valuation.putAll(valuation); - } - - public int eval() { - return visit(expression); - } - - public Integer visitAddition(Addition addition) { - return visit(addition.leftHandSide) + visit(addition.rightHandSide); - } - - public Integer visitSubtraction(Subtraction subtraction) { - return visit(subtraction.leftHandSide) - visit(subtraction.rightHandSide); - } - - public Integer visitInt(Int integer) { - return integer.value; - } - - public Integer visitIdentifier(Identifier identifier) { - if (valuation.containsKey(identifier.name)) { - return valuation.get(identifier.name); - } else { - throw new InterpreterException("Identifier " + identifier.name + " not found."); - } - } -} diff --git a/src/interpreter/Interpreter.java b/src/interpreter/Interpreter.java deleted file mode 100644 index 541adf8..0000000 --- a/src/interpreter/Interpreter.java +++ /dev/null @@ -1,48 +0,0 @@ -package interpreter; - -import program.*; - -import java.util.HashMap; -import java.util.Map; - -public class Interpreter extends Visitor { - final Program program; - final Map valuation = new HashMap<>(); - - public Map getValuation() { - Map result = new HashMap<>(); - result.putAll(valuation); - return result; - } - - public Interpreter(Program program) { - this.program = program; - visit(program); - } - - public void visitAssignment(Assignment assignment) { - Evaluator evaluator = new Evaluator(assignment.expression, valuation); - valuation.put(assignment.identifier.name, evaluator.eval()); - } - - public void visitComposition(Composition composition) { - visit(composition.first); - visit(composition.second); - } - - public void visitConditional(Conditional conditional) { - Evaluator evaluator = new Evaluator(conditional.condition, valuation); - if (evaluator.eval() != 0) { - visit(conditional.thenCase); - } else { - visit(conditional.elseCase); - } - } - - public void visitLoop(Loop loop) { - Evaluator evaluator = new Evaluator(loop.condition, valuation); - if (evaluator.eval() != 0) { - visit(new Composition(loop.program, loop)); - } - } -} diff --git a/src/interpreter/InterpreterException.java b/src/interpreter/InterpreterException.java deleted file mode 100644 index 4bde0ae..0000000 --- a/src/interpreter/InterpreterException.java +++ /dev/null @@ -1,7 +0,0 @@ -package interpreter; - -public class InterpreterException extends RuntimeException { - public InterpreterException(String error) { - super(error); - } -} diff --git a/src/interpreter/Visitor.java b/src/interpreter/Visitor.java deleted file mode 100644 index 5fa2145..0000000 --- a/src/interpreter/Visitor.java +++ /dev/null @@ -1,12 +0,0 @@ -package interpreter; - -public abstract class Visitor { - @SuppressWarnings("unchecked") - public T visit(Object object) { - try { - return (T) this.getClass().getMethod("visit" + object.getClass().getSimpleName(), object.getClass()).invoke(this, object); - } catch (Exception e) { - throw new RuntimeException(e); - } - } -} \ No newline at end of file diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 0000000..4dfd0e5 --- /dev/null +++ b/src/main/java/Main.java @@ -0,0 +1,47 @@ +import interpreter.Interpreter; +import interpreter.InterpreterException; +import parser.Parser; +import parser.SyntaxException; +import program.Program; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Map; + +public class Main { + public static void main(String[] args) { + if (args.length == 0) { + System.err.println("No file given"); + } else if (args.length > 1) { + System.err.println("Too many arguments"); + } else { + try { + String code = readFile(args[0]); + run(code); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + private static String readFile(String filename) throws IOException { + byte[] encoded = Files.readAllBytes(Paths.get(filename)); + return new String(encoded, StandardCharsets.UTF_8); + } + + private static void run(String code) { + try { + Parser parser = new Parser(code); + Program program = parser.parse(); + Interpreter interpreter = new Interpreter(program); + Map valuation = interpreter.getValuation(); + System.out.println(valuation); + } catch (SyntaxException se) { + System.err.println(se); + } catch (InterpreterException ie) { + System.err.println(ie); + } + } +} diff --git a/src/main/java/expression/Addition.java b/src/main/java/expression/Addition.java new file mode 100644 index 0000000..e0c82a4 --- /dev/null +++ b/src/main/java/expression/Addition.java @@ -0,0 +1,35 @@ +package expression; + +public class Addition extends Expression { + public final Expression leftHandSide; + public final Expression rightHandSide; + + public Addition(Expression leftHandSide, Expression rightHandSide) { + this.leftHandSide = leftHandSide; + this.rightHandSide = rightHandSide; + } + + @Override + public String toString() { + return "(" + leftHandSide + " + " + rightHandSide + ")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Addition addition = (Addition) o; + + if (!leftHandSide.equals(addition.leftHandSide)) return false; + return rightHandSide.equals(addition.rightHandSide); + + } + + @Override + public int hashCode() { + int result = leftHandSide.hashCode(); + result = 31 * result + rightHandSide.hashCode(); + return result; + } +} diff --git a/src/main/java/expression/Expression.java b/src/main/java/expression/Expression.java new file mode 100644 index 0000000..9e91fa8 --- /dev/null +++ b/src/main/java/expression/Expression.java @@ -0,0 +1,4 @@ +package expression; + +abstract public class Expression { +} diff --git a/src/main/java/expression/Identifier.java b/src/main/java/expression/Identifier.java new file mode 100644 index 0000000..d3b977b --- /dev/null +++ b/src/main/java/expression/Identifier.java @@ -0,0 +1,30 @@ +package expression; + +public class Identifier extends Expression { + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Identifier that = (Identifier) o; + + return name.equals(that.name); + + } + + @Override + public String toString() { + return name; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + public final String name; + + public Identifier(String name) { + this.name = name; + } +} diff --git a/src/main/java/expression/Int.java b/src/main/java/expression/Int.java new file mode 100644 index 0000000..6932c75 --- /dev/null +++ b/src/main/java/expression/Int.java @@ -0,0 +1,30 @@ +package expression; + +public class Int extends Expression { + public final int value; + + public Int(int value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Int integer = (Int) o; + + return value == integer.value; + + } + + @Override + public String toString() { + return Integer.toString(value); + } + + @Override + public int hashCode() { + return value; + } +} diff --git a/src/main/java/expression/Subtraction.java b/src/main/java/expression/Subtraction.java new file mode 100644 index 0000000..52d4571 --- /dev/null +++ b/src/main/java/expression/Subtraction.java @@ -0,0 +1,35 @@ +package expression; + +public class Subtraction extends Expression { + public final Expression leftHandSide; + public final Expression rightHandSide; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Subtraction that = (Subtraction) o; + + if (!leftHandSide.equals(that.leftHandSide)) return false; + return rightHandSide.equals(that.rightHandSide); + + } + + @Override + public String toString() { + return "(" + leftHandSide + " - " + rightHandSide + ")"; + } + + @Override + public int hashCode() { + int result = leftHandSide.hashCode(); + result = 31 * result + rightHandSide.hashCode(); + return result; + } + + public Subtraction(Expression leftHandSide, Expression rightHandSide) { + this.leftHandSide = leftHandSide; + this.rightHandSide = rightHandSide; + } +} diff --git a/src/main/java/interpreter/Evaluator.java b/src/main/java/interpreter/Evaluator.java new file mode 100644 index 0000000..6aec331 --- /dev/null +++ b/src/main/java/interpreter/Evaluator.java @@ -0,0 +1,41 @@ +package interpreter; + +import expression.*; + +import java.util.HashMap; +import java.util.Map; + +public class Evaluator extends Visitor { + + final Expression expression; + final Map valuation = new HashMap(); + + public Evaluator(Expression expression, Map valuation) { + this.expression = expression; + this.valuation.putAll(valuation); + } + + public int eval() { + return visit(expression); + } + + public Integer visitAddition(Addition addition) { + return visit(addition.leftHandSide) + visit(addition.rightHandSide); + } + + public Integer visitSubtraction(Subtraction subtraction) { + return visit(subtraction.leftHandSide) - visit(subtraction.rightHandSide); + } + + public Integer visitInt(Int integer) { + return integer.value; + } + + public Integer visitIdentifier(Identifier identifier) { + if (valuation.containsKey(identifier.name)) { + return valuation.get(identifier.name); + } else { + throw new InterpreterException("Identifier " + identifier.name + " not found."); + } + } +} diff --git a/src/main/java/interpreter/Interpreter.java b/src/main/java/interpreter/Interpreter.java new file mode 100644 index 0000000..eb965f6 --- /dev/null +++ b/src/main/java/interpreter/Interpreter.java @@ -0,0 +1,48 @@ +package interpreter; + +import program.*; + +import java.util.HashMap; +import java.util.Map; + +public class Interpreter extends Visitor { + final Program program; + final Map valuation = new HashMap(); + + public Map getValuation() { + Map result = new HashMap(); + result.putAll(valuation); + return result; + } + + public Interpreter(Program program) { + this.program = program; + visit(program); + } + + public void visitAssignment(Assignment assignment) { + Evaluator evaluator = new Evaluator(assignment.expression, valuation); + valuation.put(assignment.identifier.name, evaluator.eval()); + } + + public void visitComposition(Composition composition) { + visit(composition.first); + visit(composition.second); + } + + public void visitConditional(Conditional conditional) { + Evaluator evaluator = new Evaluator(conditional.condition, valuation); + if (evaluator.eval() != 0) { + visit(conditional.thenCase); + } else { + visit(conditional.elseCase); + } + } + + public void visitLoop(Loop loop) { + Evaluator evaluator = new Evaluator(loop.condition, valuation); + if (evaluator.eval() != 0) { + visit(new Composition(loop.program, loop)); + } + } +} diff --git a/src/main/java/interpreter/InterpreterException.java b/src/main/java/interpreter/InterpreterException.java new file mode 100644 index 0000000..4bde0ae --- /dev/null +++ b/src/main/java/interpreter/InterpreterException.java @@ -0,0 +1,7 @@ +package interpreter; + +public class InterpreterException extends RuntimeException { + public InterpreterException(String error) { + super(error); + } +} diff --git a/src/main/java/interpreter/Visitor.java b/src/main/java/interpreter/Visitor.java new file mode 100644 index 0000000..5fa2145 --- /dev/null +++ b/src/main/java/interpreter/Visitor.java @@ -0,0 +1,12 @@ +package interpreter; + +public abstract class Visitor { + @SuppressWarnings("unchecked") + public T visit(Object object) { + try { + return (T) this.getClass().getMethod("visit" + object.getClass().getSimpleName(), object.getClass()).invoke(this, object); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/src/main/java/parser/Parser.java b/src/main/java/parser/Parser.java new file mode 100644 index 0000000..65dfbd8 --- /dev/null +++ b/src/main/java/parser/Parser.java @@ -0,0 +1,252 @@ +package parser; + +import expression.*; +import expression.Identifier; +import expression.Int; +import program.*; + +import java.util.ArrayList; +import java.util.List; + +public class Parser { + + int position = 0; + String input; + + public Parser(String input) { + this.input = input; + } + + public Program parse() { + Program program = program(); + whitespace(); + if (position < input.length()) { + throw new SyntaxException("End of input", position); + } + return program; + } + + Program program() { + Program firstStatement = statement(); + List moreStatements = new ArrayList(); + while (test(";")) { + consume(";"); + Program statement = statement(); + moreStatements.add(statement); + } + Program program = firstStatement; + for (Program statement: moreStatements) { + program = new Composition(program, statement); + } + return program; + } + + Program statement() { + int start = position; + Program statement; + try { + statement = assignment(); + } catch (SyntaxException se) { + position = start; + try { + statement = conditional(); + } catch (SyntaxException se2) { + position = start; + try { + statement = loop(); + } catch (SyntaxException se3) { + position = start; + statement = call(); + } + } + } + return statement; + } + + Program call() { + Identifier name = identifier(); + consume("("); + Expression argument = expression(); + consume(")"); + return new Call(name, argument); + } + + Program loop() { + consume("while"); + consume("("); + Expression condition = expression(); + consume(")"); + consume("{"); + Program program = program(); + consume("}"); + return new Loop(condition, program); + } + + Program conditional() { + consume("if"); + consume("("); + Expression condition = expression(); + consume(")"); + consume("then"); + consume("{"); + Program thenCase = program(); + consume("}"); + consume("else"); + consume("{"); + Program elseCase = program(); + consume("}"); + return new Conditional(condition, thenCase, elseCase); + } + + Program assignment() { + Identifier identifier = identifier(); + consume(":="); + Expression expression = expression(); + return new Assignment(identifier, expression); + } + + private static class OperatorWithExpression { + private final Operator operator; + private final Expression expression; + + OperatorWithExpression(Operator operator, Expression expression) { + this.operator = operator; + this.expression = expression; + } + } + + private enum Operator { PLUS, MINUS } + + private boolean testOperator() { + int start = position; + boolean result; + try { + operator(); + result = true; + } catch (SyntaxException se) { + result = false; + } + position = start; + return result; + } + + private Operator operator() { + whitespace(); + char next = (char) 0; + if (position < input.length()) { + next = input.charAt(position); + position += 1; + } + if (next == '+') { + return Operator.PLUS; + } else if (next == '-') { + return Operator.MINUS; + } else { + throw new SyntaxException("Operator", position); + } + } + + Expression expression() { + Expression firstAtom = atom(); + List moreAtoms = new ArrayList(); + while(testOperator()) { + Operator operator = operator(); + Expression expression = atom(); + moreAtoms.add(new OperatorWithExpression(operator, expression)); + } + Expression expression = firstAtom; + for (OperatorWithExpression atom: moreAtoms) { + switch (atom.operator) { + case PLUS: + expression = new Addition(expression, atom.expression); + break; + case MINUS: + expression = new Subtraction(expression, atom.expression); + break; + } + } + return expression; + } + + Expression atom() { + int start = position; + Expression result; + try { + consume("("); + result = expression(); + consume(")"); + } catch (SyntaxException se) { + position = start; + try { + result = integer(); + } catch (SyntaxException se2) { + result = identifier(); + } + } + return result; + } + + private boolean isLowerLetter(char ch) { + return ch >= 'a' && ch <= 'z'; + } + + Expression integer() { + whitespace(); + int start = position; + boolean minus = position < input.length() && input.charAt(position) == '-'; + if (minus) { + position += 1; + } + boolean digitsFound = false; + while (position < input.length() && Character.isDigit(input.charAt(position))) { + position += 1; + digitsFound = true; + } + if (digitsFound) { + return new Int(Integer.parseInt(input.substring(start, position))); + } else { + throw new SyntaxException("Integer", position); + } + } + + Identifier identifier() { + whitespace(); + int start = position; + while (position < input.length() && isLowerLetter(input.charAt(position))) { + position += 1; + } + if (position > start) { + return new Identifier(input.substring(start, position)); + } else { + throw new SyntaxException("Identifier", position); + } + } + + private void whitespace() { + while(position < input.length() && Character.isWhitespace(input.charAt(position))) { + position += 1; + } + } + + private void consume(String token) { + whitespace(); + if (position + token.length() <= input.length() && input.substring(position, position + token.length()).equals(token)) { + position += token.length(); + } else { + throw new SyntaxException(token, position); + } + } + + private boolean test(String token) { + int start = position; + boolean success; + try { + consume(token); + success = true; + } catch (SyntaxException se) { + success = false; + } + position = start; + return success; + } +} diff --git a/src/main/java/parser/SyntaxException.java b/src/main/java/parser/SyntaxException.java new file mode 100644 index 0000000..494deaf --- /dev/null +++ b/src/main/java/parser/SyntaxException.java @@ -0,0 +1,20 @@ +package parser; + +public class SyntaxException extends RuntimeException { + private String expected; + private int position; + + public SyntaxException(String expected, int atPosition) { + super(expected + " expected at position " + atPosition); + this.expected = expected; + this.position = atPosition; + } + + public String getExpected() { + return expected; + } + + public int getPosition() { + return position; + } +} diff --git a/src/main/java/program/Assignment.java b/src/main/java/program/Assignment.java new file mode 100644 index 0000000..f0a077f --- /dev/null +++ b/src/main/java/program/Assignment.java @@ -0,0 +1,38 @@ +package program; + +import expression.Expression; +import expression.Identifier; + +public class Assignment extends Program { + public final Identifier identifier; + public final Expression expression; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Assignment that = (Assignment) o; + + if (!identifier.equals(that.identifier)) return false; + return expression.equals(that.expression); + + } + + @Override + public String toString() { + return identifier + " := " + expression; + } + + @Override + public int hashCode() { + int result = identifier.hashCode(); + result = 31 * result + expression.hashCode(); + return result; + } + + public Assignment(Identifier identifier, Expression expression) { + this.identifier = identifier; + this.expression = expression; + } +} diff --git a/src/main/java/program/Call.java b/src/main/java/program/Call.java new file mode 100644 index 0000000..effb040 --- /dev/null +++ b/src/main/java/program/Call.java @@ -0,0 +1,38 @@ +package program; + +import expression.Expression; +import expression.Identifier; + +public class Call extends Program { + final Identifier name; + final Expression argument; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Call that = (Call) o; + + if (!name.equals(that.name)) return false; + return argument.equals(that.argument); + + } + + @Override + public String toString() { + return name + "(" + argument + ")"; + } + + @Override + public int hashCode() { + int result = name.hashCode(); + result = 31 * result + argument.hashCode(); + return result; + } + + public Call(Identifier name, Expression argument) { + this.name = name; + this.argument = argument; + } +} diff --git a/src/main/java/program/Composition.java b/src/main/java/program/Composition.java new file mode 100644 index 0000000..cc11f8a --- /dev/null +++ b/src/main/java/program/Composition.java @@ -0,0 +1,35 @@ +package program; + +public class Composition extends Program { + public final Program first; + public final Program second; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Composition that = (Composition) o; + + if (!first.equals(that.first)) return false; + return second.equals(that.second); + + } + + @Override + public String toString() { + return first + " ; " + second; + } + + @Override + public int hashCode() { + int result = first.hashCode(); + result = 31 * result + second.hashCode(); + return result; + } + + public Composition(Program first, Program second) { + this.first = first; + this.second = second; + } +} diff --git a/src/main/java/program/Conditional.java b/src/main/java/program/Conditional.java new file mode 100644 index 0000000..4202622 --- /dev/null +++ b/src/main/java/program/Conditional.java @@ -0,0 +1,41 @@ +package program; + +import expression.Expression; + +public class Conditional extends Program { + public final Expression condition; + public final Program thenCase; + public final Program elseCase; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Conditional that = (Conditional) o; + + if (!condition.equals(that.condition)) return false; + if (!thenCase.equals(that.thenCase)) return false; + return elseCase.equals(that.elseCase); + + } + + @Override + public String toString() { + return "if (" + condition + ") then { " + thenCase + " } else { " + elseCase + " }"; + } + + @Override + public int hashCode() { + int result = condition.hashCode(); + result = 31 * result + thenCase.hashCode(); + result = 31 * result + elseCase.hashCode(); + return result; + } + + public Conditional(Expression condition, Program thenCase, Program elseCase) { + this.condition = condition; + this.thenCase = thenCase; + this.elseCase = elseCase; + } +} diff --git a/src/main/java/program/Loop.java b/src/main/java/program/Loop.java new file mode 100644 index 0000000..bb1691b --- /dev/null +++ b/src/main/java/program/Loop.java @@ -0,0 +1,37 @@ +package program; + +import expression.Expression; + +public class Loop extends Program { + public final Expression condition; + public final Program program; + + public Loop(Expression condition, Program program) { + this.condition = condition; + this.program = program; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Loop loop = (Loop) o; + + if (!condition.equals(loop.condition)) return false; + return program.equals(loop.program); + + } + + @Override + public String toString() { + return "while (" + condition + ") { " + program + " }"; + } + + @Override + public int hashCode() { + int result = condition.hashCode(); + result = 31 * result + program.hashCode(); + return result; + } +} diff --git a/src/main/java/program/Program.java b/src/main/java/program/Program.java new file mode 100644 index 0000000..c7969be --- /dev/null +++ b/src/main/java/program/Program.java @@ -0,0 +1,4 @@ +package program; + +abstract public class Program { +} diff --git a/src/parser/Parser.java b/src/parser/Parser.java deleted file mode 100644 index 2981cde..0000000 --- a/src/parser/Parser.java +++ /dev/null @@ -1,252 +0,0 @@ -package parser; - -import expression.*; -import expression.Identifier; -import expression.Int; -import program.*; - -import java.util.ArrayList; -import java.util.List; - -public class Parser { - - int position = 0; - String input; - - public Parser(String input) { - this.input = input; - } - - public Program parse() { - Program program = program(); - whitespace(); - if (position < input.length()) { - throw new SyntaxException("End of input", position); - } - return program; - } - - Program program() { - Program firstStatement = statement(); - List moreStatements = new ArrayList<>(); - while (test(";")) { - consume(";"); - Program statement = statement(); - moreStatements.add(statement); - } - Program program = firstStatement; - for (Program statement: moreStatements) { - program = new Composition(program, statement); - } - return program; - } - - Program statement() { - int start = position; - Program statement; - try { - statement = assignment(); - } catch (SyntaxException se) { - position = start; - try { - statement = conditional(); - } catch (SyntaxException se2) { - position = start; - try { - statement = loop(); - } catch (SyntaxException se3) { - position = start; - statement = call(); - } - } - } - return statement; - } - - Program call() { - Identifier name = identifier(); - consume("("); - Expression argument = expression(); - consume(")"); - return new Call(name, argument); - } - - Program loop() { - consume("while"); - consume("("); - Expression condition = expression(); - consume(")"); - consume("{"); - Program program = program(); - consume("}"); - return new Loop(condition, program); - } - - Program conditional() { - consume("if"); - consume("("); - Expression condition = expression(); - consume(")"); - consume("then"); - consume("{"); - Program thenCase = program(); - consume("}"); - consume("else"); - consume("{"); - Program elseCase = program(); - consume("}"); - return new Conditional(condition, thenCase, elseCase); - } - - Program assignment() { - Identifier identifier = identifier(); - consume(":="); - Expression expression = expression(); - return new Assignment(identifier, expression); - } - - private static class OperatorWithExpression { - private final Operator operator; - private final Expression expression; - - OperatorWithExpression(Operator operator, Expression expression) { - this.operator = operator; - this.expression = expression; - } - } - - private enum Operator { PLUS, MINUS } - - private boolean testOperator() { - int start = position; - boolean result; - try { - operator(); - result = true; - } catch (SyntaxException se) { - result = false; - } - position = start; - return result; - } - - private Operator operator() { - whitespace(); - char next = (char) 0; - if (position < input.length()) { - next = input.charAt(position); - position += 1; - } - if (next == '+') { - return Operator.PLUS; - } else if (next == '-') { - return Operator.MINUS; - } else { - throw new SyntaxException("Operator", position); - } - } - - Expression expression() { - Expression firstAtom = atom(); - List moreAtoms = new ArrayList<>(); - while(testOperator()) { - Operator operator = operator(); - Expression expression = atom(); - moreAtoms.add(new OperatorWithExpression(operator, expression)); - } - Expression expression = firstAtom; - for (OperatorWithExpression atom: moreAtoms) { - switch (atom.operator) { - case PLUS: - expression = new Addition(expression, atom.expression); - break; - case MINUS: - expression = new Subtraction(expression, atom.expression); - break; - } - } - return expression; - } - - Expression atom() { - int start = position; - Expression result; - try { - consume("("); - result = expression(); - consume(")"); - } catch (SyntaxException se) { - position = start; - try { - result = integer(); - } catch (SyntaxException se2) { - result = identifier(); - } - } - return result; - } - - private boolean isLowerLetter(char ch) { - return ch >= 'a' && ch <= 'z'; - } - - Expression integer() { - whitespace(); - int start = position; - boolean minus = position < input.length() && input.charAt(position) == '-'; - if (minus) { - position += 1; - } - boolean digitsFound = false; - while (position < input.length() && Character.isDigit(input.charAt(position))) { - position += 1; - digitsFound = true; - } - if (digitsFound) { - return new Int(Integer.parseInt(input.substring(start, position))); - } else { - throw new SyntaxException("Integer", position); - } - } - - Identifier identifier() { - whitespace(); - int start = position; - while (position < input.length() && isLowerLetter(input.charAt(position))) { - position += 1; - } - if (position > start) { - return new Identifier(input.substring(start, position)); - } else { - throw new SyntaxException("Identifier", position); - } - } - - private void whitespace() { - while(position < input.length() && Character.isWhitespace(input.charAt(position))) { - position += 1; - } - } - - private void consume(String token) { - whitespace(); - if (position + token.length() <= input.length() && input.substring(position, position + token.length()).equals(token)) { - position += token.length(); - } else { - throw new SyntaxException(token, position); - } - } - - private boolean test(String token) { - int start = position; - boolean success; - try { - consume(token); - success = true; - } catch (SyntaxException se) { - success = false; - } - position = start; - return success; - } -} diff --git a/src/parser/SyntaxException.java b/src/parser/SyntaxException.java deleted file mode 100644 index 494deaf..0000000 --- a/src/parser/SyntaxException.java +++ /dev/null @@ -1,20 +0,0 @@ -package parser; - -public class SyntaxException extends RuntimeException { - private String expected; - private int position; - - public SyntaxException(String expected, int atPosition) { - super(expected + " expected at position " + atPosition); - this.expected = expected; - this.position = atPosition; - } - - public String getExpected() { - return expected; - } - - public int getPosition() { - return position; - } -} diff --git a/src/program/Assignment.java b/src/program/Assignment.java deleted file mode 100644 index f0a077f..0000000 --- a/src/program/Assignment.java +++ /dev/null @@ -1,38 +0,0 @@ -package program; - -import expression.Expression; -import expression.Identifier; - -public class Assignment extends Program { - public final Identifier identifier; - public final Expression expression; - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Assignment that = (Assignment) o; - - if (!identifier.equals(that.identifier)) return false; - return expression.equals(that.expression); - - } - - @Override - public String toString() { - return identifier + " := " + expression; - } - - @Override - public int hashCode() { - int result = identifier.hashCode(); - result = 31 * result + expression.hashCode(); - return result; - } - - public Assignment(Identifier identifier, Expression expression) { - this.identifier = identifier; - this.expression = expression; - } -} diff --git a/src/program/Call.java b/src/program/Call.java deleted file mode 100644 index effb040..0000000 --- a/src/program/Call.java +++ /dev/null @@ -1,38 +0,0 @@ -package program; - -import expression.Expression; -import expression.Identifier; - -public class Call extends Program { - final Identifier name; - final Expression argument; - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Call that = (Call) o; - - if (!name.equals(that.name)) return false; - return argument.equals(that.argument); - - } - - @Override - public String toString() { - return name + "(" + argument + ")"; - } - - @Override - public int hashCode() { - int result = name.hashCode(); - result = 31 * result + argument.hashCode(); - return result; - } - - public Call(Identifier name, Expression argument) { - this.name = name; - this.argument = argument; - } -} diff --git a/src/program/Composition.java b/src/program/Composition.java deleted file mode 100644 index cc11f8a..0000000 --- a/src/program/Composition.java +++ /dev/null @@ -1,35 +0,0 @@ -package program; - -public class Composition extends Program { - public final Program first; - public final Program second; - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Composition that = (Composition) o; - - if (!first.equals(that.first)) return false; - return second.equals(that.second); - - } - - @Override - public String toString() { - return first + " ; " + second; - } - - @Override - public int hashCode() { - int result = first.hashCode(); - result = 31 * result + second.hashCode(); - return result; - } - - public Composition(Program first, Program second) { - this.first = first; - this.second = second; - } -} diff --git a/src/program/Conditional.java b/src/program/Conditional.java deleted file mode 100644 index 4202622..0000000 --- a/src/program/Conditional.java +++ /dev/null @@ -1,41 +0,0 @@ -package program; - -import expression.Expression; - -public class Conditional extends Program { - public final Expression condition; - public final Program thenCase; - public final Program elseCase; - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Conditional that = (Conditional) o; - - if (!condition.equals(that.condition)) return false; - if (!thenCase.equals(that.thenCase)) return false; - return elseCase.equals(that.elseCase); - - } - - @Override - public String toString() { - return "if (" + condition + ") then { " + thenCase + " } else { " + elseCase + " }"; - } - - @Override - public int hashCode() { - int result = condition.hashCode(); - result = 31 * result + thenCase.hashCode(); - result = 31 * result + elseCase.hashCode(); - return result; - } - - public Conditional(Expression condition, Program thenCase, Program elseCase) { - this.condition = condition; - this.thenCase = thenCase; - this.elseCase = elseCase; - } -} diff --git a/src/program/Loop.java b/src/program/Loop.java deleted file mode 100644 index bb1691b..0000000 --- a/src/program/Loop.java +++ /dev/null @@ -1,37 +0,0 @@ -package program; - -import expression.Expression; - -public class Loop extends Program { - public final Expression condition; - public final Program program; - - public Loop(Expression condition, Program program) { - this.condition = condition; - this.program = program; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Loop loop = (Loop) o; - - if (!condition.equals(loop.condition)) return false; - return program.equals(loop.program); - - } - - @Override - public String toString() { - return "while (" + condition + ") { " + program + " }"; - } - - @Override - public int hashCode() { - int result = condition.hashCode(); - result = 31 * result + program.hashCode(); - return result; - } -} diff --git a/src/program/Program.java b/src/program/Program.java deleted file mode 100644 index c7969be..0000000 --- a/src/program/Program.java +++ /dev/null @@ -1,4 +0,0 @@ -package program; - -abstract public class Program { -} diff --git a/src/test/java/interpreter/EvaluatorTest.java b/src/test/java/interpreter/EvaluatorTest.java new file mode 100644 index 0000000..ef87dc9 --- /dev/null +++ b/src/test/java/interpreter/EvaluatorTest.java @@ -0,0 +1,21 @@ +package interpreter; + +import expression.*; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +public class EvaluatorTest { + @Test + public void testEval() { + Map valuation = new HashMap(); + valuation.put("x", 7); + valuation.put("y", 2); + Expression expression = new Addition(new Identifier("x"), new Subtraction(new Identifier("y"), new Int(-4))); + Evaluator evaluator = new Evaluator(expression, valuation); + assertEquals(13, evaluator.eval()); + } +} diff --git a/src/test/java/interpreter/InterpreterTest.java b/src/test/java/interpreter/InterpreterTest.java new file mode 100644 index 0000000..ab60691 --- /dev/null +++ b/src/test/java/interpreter/InterpreterTest.java @@ -0,0 +1,35 @@ +package interpreter; + +import expression.Addition; +import expression.Identifier; +import expression.Int; +import expression.Subtraction; +import org.junit.Test; +import program.Assignment; +import program.Composition; +import program.Loop; +import program.Program; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +public class InterpreterTest { + @Test + public void testSem() { + Program initialization = new Composition( + new Composition( + new Assignment(new Identifier("a"), new Int(2)), + new Assignment(new Identifier("b"), new Int(4))), + new Assignment(new Identifier("r"), new Int(0))); + Program body = new Composition( + new Assignment(new Identifier("r"), new Addition(new Identifier("r"), new Identifier("b"))), + new Assignment(new Identifier("a"), new Subtraction(new Identifier("a"), new Int(1)))); + Program loop = new Loop(new Identifier("a"), body); + Program program = new Composition(initialization, loop); + Interpreter interpreter = new Interpreter(program); + Map valuation = interpreter.getValuation(); + assertEquals(8, valuation.get("r").intValue()); + assertEquals(0, valuation.get("a").intValue()); + assertEquals(4, valuation.get("b").intValue()); + } +} diff --git a/src/test/java/parser/ParserTest.java b/src/test/java/parser/ParserTest.java new file mode 100644 index 0000000..a1fb186 --- /dev/null +++ b/src/test/java/parser/ParserTest.java @@ -0,0 +1,126 @@ +package parser; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import expression.*; +import program.*; + +public class ParserTest { + final String loopCode = "while (a) { r := r + b ; a := a - 1 }"; + final Loop loop = new Loop(new Identifier("a"), new Composition(new Assignment(new Identifier("r"), new Addition(new Identifier("r"), new Identifier("b"))), new Assignment(new Identifier("a"), new Subtraction(new Identifier("a"), new Int(1))))); + + final String assignmentCode = "a := 2"; + final Assignment assignment = new Assignment(new Identifier("a"), new Int(2)); + + final String compositionCode = assignmentCode + " ; b := bar"; + final Composition composition = new Composition(assignment, new Assignment(new Identifier("b"), new Identifier("bar"))); + + final String conditionalCode = "if (foo - bar) then { x := 5 } else { x := x }"; + final Conditional conditional = new Conditional(new Subtraction(new Identifier("foo"), new Identifier("bar")), new Assignment(new Identifier("x"), new Int(5)), new Assignment(new Identifier("x"), new Identifier("x"))); + + final String programCode = compositionCode + " ; " + loopCode + " ; " + conditionalCode; + final Program program = new Composition(new Composition(composition, loop), conditional); + + @Test + public void testParse() { + Parser parser = new Parser(programCode); + assertEquals(program, parser.parse()); + } + + @Test + public void testProgram() { + Parser parser = new Parser(programCode); + assertEquals(program, parser.program()); + } + + @Test + public void testStatementAssignment() { + Parser parser = new Parser(assignmentCode); + assertEquals(assignment, parser.statement()); + } + + @Test + public void testStatementConditional() { + Parser parser = new Parser(conditionalCode); + assertEquals(conditional, parser.statement()); + } + + @Test + public void testStatementLoop() { + Parser parser = new Parser(loopCode); + assertEquals(loop, parser.statement()); + } + + final String callCode = "print(x + 36)"; + final Call call = new Call(new Identifier("print"), new Addition(new Identifier("x"), new Int(36))); + + @Test + public void testStatementCall() { + Parser parser = new Parser(callCode); + assertEquals(call, parser.statement()); + } + + @Test + public void testAssignment() { + Parser parser = new Parser(assignmentCode); + assertEquals(assignment, parser.assignment()); + } + + @Test + public void testConditional() { + Parser parser = new Parser(conditionalCode); + assertEquals(conditional, parser.conditional()); + } + + @Test + public void testLoop() { + Parser parser = new Parser(loopCode); + assertEquals(loop, parser.loop()); + } + + @Test + public void testCall() { + Parser parser = new Parser(callCode); + assertEquals(call, parser.call()); + } + + final String expressionCode = "a+b - (c - 56) + -47"; + final Expression expression = new Addition(new Subtraction(new Addition(new Identifier("a"), new Identifier("b")), new Subtraction(new Identifier("c"), new Int(56))), new Int(-47)); + + @Test + public void testExpression() { + Parser parser = new Parser(expressionCode); + assertEquals(expression, parser.expression()); + } + + @Test + public void testAtomExpression() { + Parser parser = new Parser("(" + expressionCode + ")"); + assertEquals(expression, parser.atom()); + } + + @Test + public void testAtomNumber() { + Parser parser = new Parser("37658"); + assertEquals(new Int(37658), parser.atom()); + } + + @Test + public void testAtomIdentifier() { + Parser parser = new Parser("egjfd"); + assertEquals(new Identifier("egjfd"), parser.atom()); + } + + @Test + public void testNumber() { + Parser parser = new Parser("37658"); + assertEquals(new Int(37658), parser.integer()); + } + + @Test + public void testIdentifier() { + Parser parser = new Parser("egjfd"); + assertEquals(new Identifier("egjfd"), parser.identifier()); + } +} diff --git a/test/interpreter/EvaluatorTest.java b/test/interpreter/EvaluatorTest.java deleted file mode 100644 index 9a08a41..0000000 --- a/test/interpreter/EvaluatorTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package interpreter; - -import expression.*; -import org.junit.Test; - -import java.util.HashMap; -import java.util.Map; - -import static org.junit.Assert.assertEquals; - -public class EvaluatorTest { - @Test - public void testEval() { - Map valuation = new HashMap<>(); - valuation.put("x", 7); - valuation.put("y", 2); - Expression expression = new Addition(new Identifier("x"), new Subtraction(new Identifier("y"), new Int(-4))); - Evaluator evaluator = new Evaluator(expression, valuation); - assertEquals(13, evaluator.eval()); - } -} diff --git a/test/interpreter/InterpreterTest.java b/test/interpreter/InterpreterTest.java deleted file mode 100644 index ab60691..0000000 --- a/test/interpreter/InterpreterTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package interpreter; - -import expression.Addition; -import expression.Identifier; -import expression.Int; -import expression.Subtraction; -import org.junit.Test; -import program.Assignment; -import program.Composition; -import program.Loop; -import program.Program; -import java.util.Map; - -import static org.junit.Assert.assertEquals; - -public class InterpreterTest { - @Test - public void testSem() { - Program initialization = new Composition( - new Composition( - new Assignment(new Identifier("a"), new Int(2)), - new Assignment(new Identifier("b"), new Int(4))), - new Assignment(new Identifier("r"), new Int(0))); - Program body = new Composition( - new Assignment(new Identifier("r"), new Addition(new Identifier("r"), new Identifier("b"))), - new Assignment(new Identifier("a"), new Subtraction(new Identifier("a"), new Int(1)))); - Program loop = new Loop(new Identifier("a"), body); - Program program = new Composition(initialization, loop); - Interpreter interpreter = new Interpreter(program); - Map valuation = interpreter.getValuation(); - assertEquals(8, valuation.get("r").intValue()); - assertEquals(0, valuation.get("a").intValue()); - assertEquals(4, valuation.get("b").intValue()); - } -} diff --git a/test/parser/ParserTest.java b/test/parser/ParserTest.java deleted file mode 100644 index a1fb186..0000000 --- a/test/parser/ParserTest.java +++ /dev/null @@ -1,126 +0,0 @@ -package parser; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import expression.*; -import program.*; - -public class ParserTest { - final String loopCode = "while (a) { r := r + b ; a := a - 1 }"; - final Loop loop = new Loop(new Identifier("a"), new Composition(new Assignment(new Identifier("r"), new Addition(new Identifier("r"), new Identifier("b"))), new Assignment(new Identifier("a"), new Subtraction(new Identifier("a"), new Int(1))))); - - final String assignmentCode = "a := 2"; - final Assignment assignment = new Assignment(new Identifier("a"), new Int(2)); - - final String compositionCode = assignmentCode + " ; b := bar"; - final Composition composition = new Composition(assignment, new Assignment(new Identifier("b"), new Identifier("bar"))); - - final String conditionalCode = "if (foo - bar) then { x := 5 } else { x := x }"; - final Conditional conditional = new Conditional(new Subtraction(new Identifier("foo"), new Identifier("bar")), new Assignment(new Identifier("x"), new Int(5)), new Assignment(new Identifier("x"), new Identifier("x"))); - - final String programCode = compositionCode + " ; " + loopCode + " ; " + conditionalCode; - final Program program = new Composition(new Composition(composition, loop), conditional); - - @Test - public void testParse() { - Parser parser = new Parser(programCode); - assertEquals(program, parser.parse()); - } - - @Test - public void testProgram() { - Parser parser = new Parser(programCode); - assertEquals(program, parser.program()); - } - - @Test - public void testStatementAssignment() { - Parser parser = new Parser(assignmentCode); - assertEquals(assignment, parser.statement()); - } - - @Test - public void testStatementConditional() { - Parser parser = new Parser(conditionalCode); - assertEquals(conditional, parser.statement()); - } - - @Test - public void testStatementLoop() { - Parser parser = new Parser(loopCode); - assertEquals(loop, parser.statement()); - } - - final String callCode = "print(x + 36)"; - final Call call = new Call(new Identifier("print"), new Addition(new Identifier("x"), new Int(36))); - - @Test - public void testStatementCall() { - Parser parser = new Parser(callCode); - assertEquals(call, parser.statement()); - } - - @Test - public void testAssignment() { - Parser parser = new Parser(assignmentCode); - assertEquals(assignment, parser.assignment()); - } - - @Test - public void testConditional() { - Parser parser = new Parser(conditionalCode); - assertEquals(conditional, parser.conditional()); - } - - @Test - public void testLoop() { - Parser parser = new Parser(loopCode); - assertEquals(loop, parser.loop()); - } - - @Test - public void testCall() { - Parser parser = new Parser(callCode); - assertEquals(call, parser.call()); - } - - final String expressionCode = "a+b - (c - 56) + -47"; - final Expression expression = new Addition(new Subtraction(new Addition(new Identifier("a"), new Identifier("b")), new Subtraction(new Identifier("c"), new Int(56))), new Int(-47)); - - @Test - public void testExpression() { - Parser parser = new Parser(expressionCode); - assertEquals(expression, parser.expression()); - } - - @Test - public void testAtomExpression() { - Parser parser = new Parser("(" + expressionCode + ")"); - assertEquals(expression, parser.atom()); - } - - @Test - public void testAtomNumber() { - Parser parser = new Parser("37658"); - assertEquals(new Int(37658), parser.atom()); - } - - @Test - public void testAtomIdentifier() { - Parser parser = new Parser("egjfd"); - assertEquals(new Identifier("egjfd"), parser.atom()); - } - - @Test - public void testNumber() { - Parser parser = new Parser("37658"); - assertEquals(new Int(37658), parser.integer()); - } - - @Test - public void testIdentifier() { - Parser parser = new Parser("egjfd"); - assertEquals(new Identifier("egjfd"), parser.identifier()); - } -}