| @@ -3,6 +3,7 @@ import interpreter.InterpreterException; | |||
| import parser.Parser; | |||
| import parser.SyntaxException; | |||
| import program.Program; | |||
| import printer.ProgramPrinter; | |||
| import java.io.IOException; | |||
| import java.nio.charset.StandardCharsets; | |||
| @@ -14,12 +15,20 @@ 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); | |||
| if (args.length == 2) { | |||
| if ("--print".equals(args[1])) { | |||
| print(code); | |||
| } else { | |||
| System.err.println("Invalid argument " + args[1]); | |||
| } | |||
| } else if (args.length == 1) { | |||
| run(code); | |||
| } else { | |||
| System.err.println("Too many arguments"); | |||
| } | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| @@ -31,6 +40,17 @@ public class Main { | |||
| return new String(encoded, StandardCharsets.UTF_8); | |||
| } | |||
| private static void print(String code) { | |||
| try { | |||
| Parser parser = new Parser(code); | |||
| Program program = parser.parse(); | |||
| ProgramPrinter printer = new ProgramPrinter(); | |||
| System.out.println(printer.print(program)); | |||
| } catch (SyntaxException se) { | |||
| System.err.println(se); | |||
| } | |||
| } | |||
| private static void run(String code) { | |||
| try { | |||
| Parser parser = new Parser(code); | |||
| @@ -28,12 +28,6 @@ public class Addition extends Expression { | |||
| this.rightHandSide = rightHandSide; | |||
| } | |||
| /*!- String serialization */ | |||
| @Override | |||
| public String toString() { | |||
| return "(" + leftHandSide + " + " + rightHandSide + ")"; | |||
| } | |||
| /*!- Generated equals implementation */ | |||
| @Override | |||
| public boolean equals(Object o) { | |||
| @@ -17,12 +17,6 @@ public class Identifier extends Expression { | |||
| this.name = name; | |||
| } | |||
| /*!- String serialization */ | |||
| @Override | |||
| public String toString() { | |||
| return name; | |||
| } | |||
| /*!- generated equals implementation */ | |||
| @Override | |||
| public boolean equals(Object o) { | |||
| @@ -22,12 +22,6 @@ public class Int extends Expression { | |||
| this.value = value; | |||
| } | |||
| /*!- String serialization */ | |||
| @Override | |||
| public String toString() { | |||
| return Integer.toString(value); | |||
| } | |||
| /*!- generated equals implementation */ | |||
| @Override | |||
| public boolean equals(Object o) { | |||
| @@ -28,12 +28,6 @@ public class Subtraction extends Expression { | |||
| this.rightHandSide = rightHandSide; | |||
| } | |||
| /*!- String serialization */ | |||
| @Override | |||
| public String toString() { | |||
| return "(" + leftHandSide + " - " + rightHandSide + ")"; | |||
| } | |||
| /*!- generated equals implementation */ | |||
| @Override | |||
| public boolean equals(Object o) { | |||
| @@ -0,0 +1,44 @@ | |||
| /*!! Printer */ | |||
| /*! | |||
| ExpressionPrinter | |||
| ================= | |||
| The `ExpressionPrinter` is used for string serialization of a given `Expression`. | |||
| */ | |||
| /*!- Header */ | |||
| package printer; | |||
| import expression.*; | |||
| import interpreter.Visitor; | |||
| /*! | |||
| The `ExpressionPrinter` implements the string serialization with the help of the | |||
| [Visitor](${basePath}/src/main/java/interpreter/Visitor.java.html). | |||
| */ | |||
| public class ExpressionPrinter extends Visitor<String> { | |||
| public String visitAddition(Addition addition) { | |||
| return visit(addition.leftHandSide) + " + " + visit(addition.rightHandSide); | |||
| } | |||
| public String visitIdentifier(Identifier identifier) { | |||
| return identifier.name; | |||
| } | |||
| public String visitInt(Int integer) { | |||
| return Integer.toString(integer.value); | |||
| } | |||
| public String visitSubtraction(Subtraction subtraction) { | |||
| return visit(subtraction.leftHandSide) + " - " + visit(subtraction.rightHandSide); | |||
| } | |||
| /*! | |||
| The `print` function takes an `Expression` instance as an argument and returns | |||
| the string serialization of the given expression. | |||
| */ | |||
| public String print(Expression expression) { | |||
| return visit(expression); | |||
| } | |||
| } | |||
| @@ -0,0 +1,46 @@ | |||
| /*!! Printer */ | |||
| /*! | |||
| ProgramPrinter | |||
| ============== | |||
| The `ProgramPrinter` is used for string serialization of a given `Program`. | |||
| */ | |||
| /*!- Header */ | |||
| package printer; | |||
| import interpreter.Visitor; | |||
| import program.*; | |||
| /*! | |||
| The `ProgramPrinter` implements the string serialization with the help of the | |||
| [Visitor](${basePath}/src/main/java/interpreter/Visitor.java.html). | |||
| */ | |||
| public class ProgramPrinter extends Visitor<String> { | |||
| private final ExpressionPrinter printer = new ExpressionPrinter(); | |||
| public String visitAssignment(Assignment assignment) { | |||
| return printer.print(assignment.identifier) + " := " + printer.print(assignment.expression); | |||
| } | |||
| public String visitComposition(Composition composition) { | |||
| return visit(composition.first) + " ; " + visit(composition.second); | |||
| } | |||
| public String visitConditional(Conditional conditional) { | |||
| return "if (" + printer.print(conditional.condition) + ") then { " + visit(conditional.thenCase) + " } else { " + visit(conditional.elseCase) + " }"; | |||
| } | |||
| public String visitLoop(Loop loop) { | |||
| return "while (" + printer.print(loop.condition) + ") { " + visit(loop.program) + " }"; | |||
| } | |||
| /*! | |||
| The `print` function takes a `Program` instance as an argument and returns | |||
| the string serialization of the given program. | |||
| */ | |||
| public String print(Program program) { | |||
| return visit(program); | |||
| } | |||
| } | |||
| @@ -32,12 +32,6 @@ public class Assignment extends Program { | |||
| this.expression = expression; | |||
| } | |||
| /*!- String serialization */ | |||
| @Override | |||
| public String toString() { | |||
| return identifier + " := " + expression; | |||
| } | |||
| /*!- generated equals method */ | |||
| @Override | |||
| public boolean equals(Object o) { | |||
| @@ -19,12 +19,6 @@ public class Composition extends Program { | |||
| this.second = second; | |||
| } | |||
| /*!- String serialization */ | |||
| @Override | |||
| public String toString() { | |||
| return first + " ; " + second; | |||
| } | |||
| /*!- generated equals implementation */ | |||
| @Override | |||
| public boolean equals(Object o) { | |||
| @@ -36,10 +36,4 @@ public class Conditional extends Program { | |||
| return elseCase.equals(that.elseCase); | |||
| } | |||
| /*!- String serialization */ | |||
| @Override | |||
| public String toString() { | |||
| return "if (" + condition + ") then { " + thenCase + " } else { " + elseCase + " }"; | |||
| } | |||
| } | |||
| @@ -21,12 +21,6 @@ public class Loop extends Program { | |||
| this.program = program; | |||
| } | |||
| /*!- String serialization */ | |||
| @Override | |||
| public String toString() { | |||
| return "while (" + condition + ") { " + program + " }"; | |||
| } | |||
| /*!- generated equals implementation */ | |||
| @Override | |||
| public boolean equals(Object o) { | |||
| @@ -0,0 +1,43 @@ | |||
| package printer; | |||
| import expression.*; | |||
| import org.junit.Test; | |||
| import static org.junit.Assert.*; | |||
| public class ExpressionPrinterTest { | |||
| final String identifierCode = "a"; | |||
| final Identifier identifier = new Identifier(identifierCode); | |||
| final String integerCode = "42"; | |||
| final Int integer = new Int(42); | |||
| final String additionCode = "a + 42"; | |||
| final Addition addition = new Addition(new Identifier("a"), new Int(42)); | |||
| final String subtractionCode = "1 - a"; | |||
| final Subtraction subtraction = new Subtraction(new Int(1), new Identifier("a")); | |||
| final ExpressionPrinter printer = new ExpressionPrinter(); | |||
| @Test | |||
| public void testVisitAddition() { | |||
| assertEquals(additionCode, printer.print(addition)); | |||
| } | |||
| @Test | |||
| public void testVisitIdentifier() { | |||
| assertEquals(identifierCode, printer.print(identifier)); | |||
| } | |||
| @Test | |||
| public void testVisitInt() { | |||
| assertEquals(integerCode, printer.print(integer)); | |||
| } | |||
| @Test | |||
| public void testVisitSubtraction() { | |||
| assertEquals(subtractionCode, printer.print(subtraction)); | |||
| } | |||
| } | |||
| @@ -0,0 +1,55 @@ | |||
| package printer; | |||
| import expression.Addition; | |||
| import expression.Identifier; | |||
| import expression.Int; | |||
| import expression.Subtraction; | |||
| import org.junit.Test; | |||
| import program.*; | |||
| import static org.junit.Assert.*; | |||
| public class ProgramPrinterTest { | |||
| 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); | |||
| final ProgramPrinter printer = new ProgramPrinter(); | |||
| @Test | |||
| public void testVisitAssignment() { | |||
| assertEquals(assignmentCode, printer.print(assignment)); | |||
| } | |||
| @Test | |||
| public void testVisitComposition() { | |||
| assertEquals(compositionCode, printer.print(composition)); | |||
| } | |||
| @Test | |||
| public void testVisitConditional() { | |||
| assertEquals(conditionalCode, printer.print(conditional)); | |||
| } | |||
| @Test | |||
| public void testVisitLoop() { | |||
| assertEquals(loopCode, printer.print(loop)); | |||
| } | |||
| @Test | |||
| public void testVisitProgram() { | |||
| assertEquals(programCode, printer.print(program)); | |||
| } | |||
| } | |||