package de.bse.vm; import de.bse.prgm.err.runtime.BadFormatRuntimeError; import de.bse.prgm.err.runtime.ConstantReferenceRuntimeError; import de.bse.prgm.err.runtime.VariableNotFoundRuntimeError; import de.bse.prgm.struct.Program; import de.bse.vm.storage.EEPROM; import de.bse.vm.storage.IEEPROMMonitor; import de.bse.vm.var.Bit; import de.bse.vm.var.Byte; import de.bse.vm.var.Clock; import de.bse.vm.var.Constant; import de.bse.vm.var.IVariable; import de.bse.vm.var.Word; import de.bse.vm.var.format.Formatter; import java.util.HashMap; import java.util.Map; /** * The vm of the emulated microcontroller. Manages all variables. * * @author Elias Groll, Jonas Reichmann * @version 2.15 */ public class Machine { private final Program program; private int executionIndex = 0; private final EEPROM eeprom; private final Settings settings; /** * Stores all available Formatters for DEBUG as a regex group. */ private final String allFormatters = "[%$@]"; /** * Stores all available Formatters and the HashTag for DEBUG as a regex * group. */ private final String allFormattersAndHashTag = "[#%$@]"; private Bit BIT0 = new Bit(0), BIT1 = new Bit(0), BIT2 = new Bit(0), BIT3 = new Bit(0), BIT4 = new Bit(0), BIT5 = new Bit(0), BIT6 = new Bit(0), BIT7 = new Bit(0), BIT8 = new Bit(0), BIT9 = new Bit(0), BIT10 = new Bit(0), BIT11 = new Bit(0), BIT12 = new Bit(0), BIT13 = new Bit(0), BIT14 = new Bit(0), BIT15 = new Bit(0), PIN0 = new Bit(0), PIN1 = new Bit(0), PIN2 = new Bit(0), PIN3 = new Bit(0), PIN4 = new Bit(0), PIN5 = new Bit(0), PIN6 = new Bit(0), PIN7 = new Bit(0), DIR0 = new Bit(0), DIR1 = new Bit(0), DIR2 = new Bit(0), DIR3 = new Bit(0), DIR4 = new Bit(0), DIR5 = new Bit(0), DIR6 = new Bit(0), DIR7 = new Bit(0); private Byte PINS = new Byte(PIN7, PIN6, PIN5, PIN3, PIN3, PIN2, PIN1, PIN0); private Byte DIRS = new Byte(DIR7, DIR6, DIR5, DIR4, DIR3, DIR2, DIR1, DIR0); private Byte B0 = new Byte(BIT7, BIT6, BIT5, BIT4, BIT3, BIT2, BIT1, BIT0); private Byte B1 = new Byte(BIT14, BIT13, BIT12, BIT11, BIT10, BIT9, BIT8, BIT15); private Byte B2 = new Byte(), B3 = new Byte(), B4 = new Byte(), B5 = new Byte(), B6 = new Byte(), B7 = new Byte(), B8 = new Byte(), B9 = new Byte(), B10 = new Byte(), B11 = new Byte(), B12 = new Byte(), B13 = new Byte(); private Word PORT = new Word(DIRS, PINS), W0 = new Word(B1, B0), W1 = new Word(B3, B2), W2 = new Word(B5, B4), W3 = new Word(B7, B6), W4 = new Word(B9, B8), W5 = new Word(B11, B10), W6 = new Word(B13, B12); private Map<String, IVariable> allVariables = new HashMap<String, IVariable>(); /** * Constructor of the Machine class, expects a program and settings. * * @param program * which the machine shall run * @param settings * with which the machine shall run * @param monitor * additional EEPROM-monitor (null if not needed) */ public Machine(Program program, Settings settings, IEEPROMMonitor monitor) { this.program = program; allVariables.put("B0", B0); allVariables.put("B1", B1); allVariables.put("B2", B2); allVariables.put("B3", B3); allVariables.put("B4", B4); allVariables.put("B5", B5); allVariables.put("B6", B6); allVariables.put("B7", B7); allVariables.put("B8", B8); allVariables.put("B9", B9); allVariables.put("B10", B10); allVariables.put("B11", B11); allVariables.put("B12", B12); allVariables.put("B13", B13); allVariables.put("DIRS", DIRS); allVariables.put("PINS", PINS); allVariables.put("PIN0", PIN0); allVariables.put("PIN1", PIN1); allVariables.put("PIN2", PIN2); allVariables.put("PIN3", PIN3); allVariables.put("PIN4", PIN4); allVariables.put("PIN5", PIN5); allVariables.put("PIN6", PIN6); allVariables.put("PIN7", PIN7); allVariables.put("DIR0", DIR0); allVariables.put("DIR1", DIR1); allVariables.put("DIR2", DIR2); allVariables.put("DIR3", DIR3); allVariables.put("DIR4", DIR4); allVariables.put("DIR5", DIR5); allVariables.put("DIR6", DIR6); allVariables.put("DIR7", DIR7); allVariables.put("BIT0", BIT0); allVariables.put("BIT1", BIT1); allVariables.put("BIT2", BIT2); allVariables.put("BIT3", BIT3); allVariables.put("BIT4", BIT4); allVariables.put("BIT5", BIT5); allVariables.put("BIT6", BIT6); allVariables.put("BIT7", BIT7); allVariables.put("BIT8", BIT8); allVariables.put("BIT9", BIT9); allVariables.put("BIT10", BIT10); allVariables.put("BIT11", BIT11); allVariables.put("BIT12", BIT12); allVariables.put("BIT13", BIT13); allVariables.put("BIT14", BIT14); allVariables.put("BIT15", BIT15); allVariables.put("W0", W0); allVariables.put("W1", W1); allVariables.put("W2", W2); allVariables.put("W3", W3); allVariables.put("W4", W4); allVariables.put("W5", W5); allVariables.put("W6", W6); allVariables.put("PORT", PORT); allVariables.put("SYSCLOCK", new Clock()); this.settings = settings; this.eeprom = new EEPROM(program.getCommands().size(), monitor); } /** * Returns an IVariable in the machine by its name. * * @param name * of the IVariable * @return IVariable in the machine with this name or constant if name is a * number */ public IVariable parseIVariable(String name) { String tmp = name; try { if (tmp.startsWith("@")) { tmp = tmp.substring(1); tmp = String.valueOf(Formatter.parseAsciiString(tmp)); } else if (tmp.startsWith("$")) { tmp = tmp.substring(1); tmp = tmp.toLowerCase(); tmp = String.valueOf(Formatter.parseHexString(tmp)); } else if (tmp.startsWith("%")) { tmp = tmp.substring(1); tmp = String.valueOf(Formatter.parseBinaryString(tmp)); } } catch (NumberFormatException e) { program.addError(new BadFormatRuntimeError(tmp)); } IVariable retVal = allVariables.get(tmp); if (retVal == null) { try { retVal = new Constant(Integer.parseInt(tmp)); } catch (NumberFormatException e) { program.addError(new VariableNotFoundRuntimeError(tmp)); } } return retVal; } /** * Creates a new IVariable in the machine using a name and a IVariable to be * put into the machine. * * @param name * of the new IVariable * @param var * to be inserted into the machine */ public void addIVariable(String name, IVariable var) { if (!allVariables.containsKey(name)) { allVariables.put(name, var); } else { program.addError(new ConstantReferenceRuntimeError(name)); } } public Program getProgram() { return program; } public int getExecutionIndex() { return executionIndex; } public void setExecutionIndex(int executionIndex) { this.executionIndex = executionIndex; } public EEPROM getEeprom() { return eeprom; } public Settings getSettings() { return settings; } public String getAllFormatters() { return allFormatters; } public String getAllFormattersAndHashTag() { return allFormattersAndHashTag; } }