diff --git a/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/AbstractMachine.java b/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/AbstractMachine.java index be564a7..17d136f 100644 --- a/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/AbstractMachine.java +++ b/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/AbstractMachine.java @@ -1,6 +1,4 @@ package de.unitrier.st.uap.w25.tram; - -import java.nio.file.attribute.UserPrincipalLookupService; import java.util.*; public class AbstractMachine { @@ -12,11 +10,13 @@ public class AbstractMachine { protected int PC = 0; protected int TOP = -1; + // Init machine with program and empty stack public AbstractMachine(Instruction[] prog) { this.prog = new ArrayList<>(Arrays.asList(prog)); this.stack = new ArrayList<>(); } + // Init machine with program and stack public AbstractMachine(Instruction[] prog, Integer[] stack) { this(prog); @@ -25,25 +25,15 @@ public class AbstractMachine { } // Executes until halts and returns final configuration - public String execute() { + public void execute() { while(!isHalted()) { executeStep(); } - return configuration(); - } - - // Executes until halts and returns configurations of all steps - public ArrayList executeDebug() { - ArrayList out = new ArrayList<>(); - while(!isHalted()) { - String conf = executeStep(); - out.add(conf); - } - return out; + confStr(); } // Executes single step and returns configuration - public String executeStep() { + public void executeStep() { ensureCapacity(this.TOP); Instruction inst = this.prog.get(this.PC); @@ -191,8 +181,6 @@ public class AbstractMachine { break; default: break; } - - return configuration(); } public boolean isHalted() { @@ -233,23 +221,30 @@ public class AbstractMachine { } } - // Prints the machine's current configuration - public String configuration() { + // Returns the machine's current configuration as string + public String confStr() { StringBuilder sb = new StringBuilder(); sb.append("TOP=").append(this.TOP) - .append(" PC=").append(this.PC) - .append(" PP=").append(this.PP) - .append(" FP=").append(this.FP) - .append("\nSTACK: ["); + .append(" PC=").append(this.PC) + .append(" PP=").append(this.PP) + .append(" FP=").append(this.FP) + .append("\nSTACK: ") + .append(stackStr()); + return sb.toString(); + } + + // Returns the machine's current stack as string + public String stackStr() { + StringBuilder sb = new StringBuilder(); + sb.append("["); int limit = Math.min(this.stack.size(), this.TOP + 1); for (int i = 0; i < limit; i++) { sb.append(this.stack.get(i)); if (i < limit - 1) sb.append(", "); } sb.append("]"); - return sb.toString(); } diff --git a/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/AbstractMachineTests.java b/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/AbstractMachineTests.java index 1c024ad..60f837b 100644 --- a/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/AbstractMachineTests.java +++ b/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/AbstractMachineTests.java @@ -4,7 +4,6 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; public class AbstractMachineTests { - @Test void testExample1() { Instruction[] code = Assembler.readTRAMCode("tramcode/example1.tram"); @@ -25,7 +24,7 @@ public class AbstractMachineTests { assertTrue(tram.isHalted(), "Machine should halt."); var results = tram.results(); assertEquals(200, results.get(results.size() - 2), "Expected value 200 since x!=0."); - assertEquals(3, results.get(results.size() - 1), "Expected final constant 3 on stack."); + assertEquals(3, results.getLast(), "Expected final constant 3 on stack."); } @Test diff --git a/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/Instruction.java b/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/Instruction.java index 434cad4..f26333d 100644 --- a/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/Instruction.java +++ b/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/Instruction.java @@ -1,7 +1,3 @@ -/** - * Instructions for TRAM 2025 - */ - package de.unitrier.st.uap.w25.tram; public class Instruction diff --git a/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/LoggedMachine.java b/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/LoggedMachine.java index dd622c7..0b58c15 100644 --- a/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/LoggedMachine.java +++ b/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/LoggedMachine.java @@ -2,42 +2,60 @@ package de.unitrier.st.uap.w25.tram; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder; +import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory; +import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration; +import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder; +// Write subclass to enhance Single-Responsibility-Principle public class LoggedMachine extends AbstractMachine { - private static final Logger logger = LogManager.getLogger(LoggedMachine.class); + protected static Logger logger = LogManager.getLogger(LoggedMachine.class); + protected int stepCounter = 0; + // No changes in the constructor public LoggedMachine(Instruction[] prog) { super(prog); } + // No changes in the constructor public LoggedMachine(Instruction[] prog, Integer[] stack) { super(prog, stack); } - @Override - public String executeStep() { - String confBefore = configuration(); - logger.debug("Before step:\n" + confBefore); + // Enable file logging + public static void toFile(String fileName) { + ConfigurationBuilder builder = ConfigurationBuilderFactory.newConfigurationBuilder(); - String confAfter = super.executeStep(); - logger.debug("After step:\n" + confAfter); + AppenderComponentBuilder fileAppender = builder.newAppender("File", "File") + .addAttribute("fileName", fileName) + .add(builder.newLayout("PatternLayout") + .addAttribute("pattern", "%d{HH:mm:ss} %-5level %msg%n")); - return confAfter; + builder.add(fileAppender); + builder.add(builder.newRootLogger(Level.DEBUG).add(builder.newAppenderRef("File"))); + + LoggerContext ctx = LoggerContext.getContext(false); + ctx.start(builder.build()); + + logger = LogManager.getLogger(LoggedMachine.class); } @Override - public String execute() { - logger.info("Execution started"); - String result = super.execute(); - logger.info("Execution finished:\n" + configuration()); - return result; + public void execute() { + logger.info("Executing..."); + logger.debug("{}: {}", 0, confStr()); + while(!isHalted()) { + executeStep(); + } + logger.info("Finished with STACK: {}", stackStr()); } @Override - public java.util.ArrayList executeDebug() { - logger.info("Debug execution started"); - var out = super.executeDebug(); - logger.info("Debug execution finished"); - return out; + public void executeStep() { + int step = stepCounter++; + super.executeStep(); + logger.debug("{}: {}", step, confStr()); } } diff --git a/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/Main.java b/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/Main.java index f777331..2475d84 100644 --- a/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/Main.java +++ b/Project-01/uap25-pro01-tram/src/de/unitrier/st/uap/w25/tram/Main.java @@ -1,40 +1,33 @@ package de.unitrier.st.uap.w25.tram; -final class Main -{ - private Main(){} - - static void main(String[] argv) { - Instruction[] code = Assembler.readTRAMCode( - // "tramcode/square.tram" - // "tramcode/wrapper.tram" - // "tramcode/example1.tram" - // "tramcode/example2.tram" - //"tramcode/example3.tram" - "tramcode/test.tram" - ); +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.config.Configurator; - int lineNr=0; - for(Instruction instr: code) { - if (instr != null) { - System.out.println(String.format("%03d", lineNr) + "| " + instr.toString()); - lineNr++; - } - } +final class Main { + private Main() {} - // TODO: Create an instance of the abstract machine with reasonable parameters - AbstractMachine tram = new AbstractMachine(code, new Integer[]{}); // empty stack or predefined args + static void main(String[] argv) { + // Configurator.setRootLevel(Level.DEBUG); + Configurator.setRootLevel(Level.INFO); - System.out.println("Initial configuration:"); - System.out.println(tram.configuration()); + Instruction[] code = Assembler.readTRAMCode( + //"tramcode/square.tram" + //"tramcode/wrapper.tram" + //"tramcode/example1.tram" + //"tramcode/example2.tram" + //"tramcode/example3.tram" + "tramcode/test.tram" + ); - // Stepwise execution (debug) - System.out.println("\nExecution trace:"); - for (String conf : tram.executeDebug()) { - System.out.println(conf); - } + // int lineNr = 0; + // for (Instruction instr : code) { + // if (instr != null) { + // System.out.println(String.format("%03d", lineNr) + "| " + instr); + // lineNr++; + // } + // } - System.out.println("\nFinal configuration:"); - System.out.println(tram.configuration()); - } -} \ No newline at end of file + LoggedMachine tram = new LoggedMachine(code, new Integer[]{}); // empty stack or predefined args + tram.execute(); + } +} diff --git a/Project-01/uap25-pro01-tram/uap25-pro01-tram.iml b/Project-01/uap25-pro01-tram/uap25-pro01-tram.iml index 5abe807..5b5f268 100644 --- a/Project-01/uap25-pro01-tram/uap25-pro01-tram.iml +++ b/Project-01/uap25-pro01-tram/uap25-pro01-tram.iml @@ -10,8 +10,8 @@ - - + + @@ -33,5 +33,23 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file