package de.bse.prgm.cmd.loop; import de.bse.prgm.cmd.ICommand; import de.bse.prgm.err.runtime.InvalidAllocationRuntimeError; import de.bse.run.app.IConsole; import de.bse.vm.Machine; import de.bse.vm.var.Constant; import de.bse.vm.var.IVariable; /** * For command which loops through the following code block until it finds a next * whilst increasing the iterator by stepSize until it hits is goal. * @author Elias Groll, Jonas Reichmann * @version 2.15 */ public class For implements ICommand { private final String fromInit; private final String goal; private final String stepSize; private boolean negative = false; private IVariable from; private IVariable to; private IVariable step; /** * Constructor of the For class which loops through the following code block * until it hits a valid Next command or an END command. * @param fromInit value to begin from * @param goal value to reach * @param stepSize how much the iterator shall increase with each cycle, can be negative */ public For(String fromInit, String goal, String stepSize) { this.fromInit = fromInit; this.goal = goal; this.stepSize = stepSize; } public void execute(Machine machine, IConsole console) { initVars(machine, console); initNext(machine, console); } public String infoMsg() { return "[Info]Iterating from " + String.valueOf(fromInit.replace(".*=\\s*", "").trim()) + " to " + goal + " with step-size=" + stepSize + " on " + fromInit.replace("\\s*=.*", "").trim(); } private void initVars(Machine machine, IConsole console) { String[] alloc = fromInit.split("="); if (alloc.length != 2) { machine.getProgram() .addError(new InvalidAllocationRuntimeError(fromInit)); } try { setFrom(machine.parseIVariable(alloc[0].trim())); IVariable init = machine.parseIVariable(alloc[1].trim()); getFrom().setValue(init.getValue()); to = machine.parseIVariable(goal); if (stepSize != null) { if (stepSize.startsWith("-")) { negative = true; } step = machine.parseIVariable(stepSize); } else { step = new Constant(1); } } catch (NullPointerException e) { machine.getProgram() .addError(new InvalidAllocationRuntimeError(fromInit)); } catch (NumberFormatException e) { machine.getProgram() .addError(new InvalidAllocationRuntimeError(fromInit)); } catch (ArrayIndexOutOfBoundsException e){ machine.getProgram() .addError(new InvalidAllocationRuntimeError(fromInit)); } } private void initNext(Machine machine, IConsole console) { int searchCounter = 0; for (int i = machine.getProgram().getCommands().indexOf(this) + 1; i < machine .getProgram().getCommands().size(); i++) { ICommand cmd = machine.getProgram().getCommands().get(i); if (cmd instanceof For) { searchCounter++; } else if (cmd instanceof Next) { if (searchCounter == 0) { Next next = (Next) cmd; next.setHead(this); break; } else { searchCounter--; } } } } public String toString() { return "FOR"; } public IVariable getStep() { return step; } public IVariable getTo() { return to; } public IVariable getFrom() { return from; } public void setFrom(IVariable from) { this.from = from; } public boolean isNegative() { return negative; } }