| 1 | // Copyright © 2004-2006 University of Helsinki, Department of Computer Science | |
| 2 | // Copyright © 2012 various contributors | |
| 3 | // This software is released under GNU Lesser General Public License 2.1. | |
| 4 | // The license text is at http://www.gnu.org/licenses/lgpl-2.1.html | |
| 5 | ||
| 6 | package fi.helsinki.cs.titokone; | |
| 7 | ||
| 8 | import java.util.HashMap; | |
| 9 | ||
| 10 | /** | |
| 11 | * This class contains the bulk data needed to translate commands to | |
| 12 | * opcodes etc. The main purpose for this class is to provide methods to convert | |
| 13 | * symbolic commands to binary form. | |
| 14 | */ | |
| 15 | public class SymbolicInterpreter extends Interpreter { | |
| 16 | /** | |
| 17 | * This hashtable contains the opcode values keyed to the symbolic commands. | |
| 18 | */ | |
| 19 | private HashMap<Object, Object> opcodes; | |
| 20 | /** | |
| 21 | * This hashtable contains integer values for given addressingmodes. | |
| 22 | */ | |
| 23 | private HashMap<Object, Object> addressModes; | |
| 24 | /** | |
| 25 | * This hashtable | |
| 26 | */ | |
| 27 | private HashMap<Object, Object> registers; | |
| 28 | ||
| 29 | // constructor | |
| 30 | ||
| 31 | /** | |
| 32 | * This constructor sets up a SymbolicInterpreter instance. It calls | |
| 33 | * the private method dataSetup() to set up its data structures. | |
| 34 | */ | |
| 35 | public SymbolicInterpreter() { | |
| 36 | 1 | dataSetup(); |
| 37 | } | |
| 38 | ||
| 39 | /** | |
| 40 | * This method sets up the HashTables. | |
| 41 | */ | |
| 42 | private void dataSetup() { | |
| 43 | 2 | opcodes = new HashMap<Object, Object>(commandData.length); |
| 44 | 5 | for (int i = 0; i < commandData.length; i++) { |
| 45 | 5 | opcodes.put(commandData[i][0], commandData[i][1]); |
| 46 | } | |
| 47 | ||
| 48 | 2 | addressModes = new HashMap<Object, Object>(addressingData.length); |
| 49 | 5 | for (int i = 0; i < addressingData.length; i++) { |
| 50 | 5 | addressModes.put(addressingData[i][0], addressingData[i][1]); |
| 51 | } | |
| 52 | ||
| 53 | 2 | registers = new HashMap<Object, Object>(registerData.length); |
| 54 | 5 | for (int i = 0; i < registerData.length; i++) { |
| 55 | 5 | registers.put(registerData[i][0], registerData[i][1]); |
| 56 | } | |
| 57 | } | |
| 58 | ||
| 59 | // public methods --> | |
| 60 | ||
| 61 | /** | |
| 62 | * This method checks if a command is a valid opCode. | |
| 63 | * | |
| 64 | * @param command String form of a possible opCode. | |
| 65 | */ | |
| 66 | public int getOpcode(String command) { | |
| 67 | 1 | command = command.trim(); |
| 68 | 1 | command = command.toUpperCase(); |
| 69 | 1 | Integer value = (Integer) opcodes.get(command); |
| 70 | 1 | if (value != null) { |
| 71 | 2 | return value.intValue(); |
| 72 | } | |
| 73 | 3 | return -1; |
| 74 | } | |
| 75 | ||
| 76 | /** | |
| 77 | * This method transforms an addressing mode (=, @ or nothing) to | |
| 78 | * a number identifying it. | |
| 79 | * | |
| 80 | * @param identifier String form of an addressing mode. | |
| 81 | * @return Int value telling how many times memory must be accessed. | |
| 82 | */ | |
| 83 | public int getAddressingMode(String identifier) { | |
| 84 | 1 | identifier = identifier.trim(); |
| 85 | 1 | identifier = identifier.toUpperCase(); |
| 86 | 1 | Integer value = (Integer) addressModes.get(identifier); |
| 87 | 1 | if (value != null) { |
| 88 | 2 | return value.intValue(); |
| 89 | } | |
| 90 | 3 | return -1; |
| 91 | } | |
| 92 | ||
| 93 | /** | |
| 94 | * This method returns the binary form of a given register as an integer. | |
| 95 | * | |
| 96 | * @param registerName String form of a register (R0-R7, SP or FP). | |
| 97 | * @return Int value of a given register. | |
| 98 | */ | |
| 99 | public int getRegisterId(String registerName) { | |
| 100 | 1 | registerName = registerName.trim(); |
| 101 | 1 | registerName = registerName.toUpperCase(); |
| 102 | 1 | Integer value = (Integer) registers.get(registerName); |
| 103 | 1 | if (value != null) { |
| 104 | 2 | return value.intValue(); |
| 105 | } | |
| 106 | 3 | return -1; |
| 107 | } | |
| 108 | ||
| 109 | /** | |
| 110 | * This method coverts a complete command in a symbolic form to a binary form. | |
| 111 | * caller must split up the original command and give the parts as parameters | |
| 112 | * | |
| 113 | * @param opcode String form of an operation code. (STORE) | |
| 114 | * @param firstRegister String form of a first register. (R0-R7, SP or FP) | |
| 115 | * @param addressingMode = or @ or an empty string that representes the memory addressing | |
| 116 | * mode. | |
| 117 | * @param address String form of an address, must be a valid int. | |
| 118 | * @param otherRegister String form of an other register. (R0-R7, SP or FP) | |
| 119 | * @return Int format of a symbolic opCode. (etc 00000010 00101000 00000000 01100100 as int) | |
| 120 | */ | |
| 121 | public int stringToBinary(String opcode, String firstRegister, String addressingMode, | |
| 122 | String address, String otherRegister) { | |
| 123 | 2 | boolean allOk = true; |
| 124 | boolean addressEmpty; | |
| 125 | ||
| 126 | 2 | if (address.equals("")) { |
| 127 | 2 | addressEmpty = true; |
| 128 | } else { | |
| 129 | 2 | addressEmpty = false; |
| 130 | } | |
| 131 | ||
| 132 | 1 | int opcodeAsInt = getOpcode(opcode); |
| 133 | 1 | int firstRegisterAsInt = getRegisterId(firstRegister); |
| 134 | 1 | int addressingModeAsInt = getAddressingMode(addressingMode); |
| 135 | 2 | int addressAsInt = 0; |
| 136 | 1 | int secondRegisterIdAsInt = getRegisterId(otherRegister); |
| 137 | ||
| 138 | 2 | if (address.equals("")) { |
| 139 | address = "0"; | |
| 140 | } | |
| 141 | ||
| 142 | try { | |
| 143 | 1 | addressAsInt = Integer.parseInt(address); |
| 144 | } catch (NumberFormatException e) { | |
| 145 | 2 | allOk = false; |
| 146 | } | |
| 147 | ||
| 148 | 2 | if (opcodeAsInt < 0) { |
| 149 | 2 | allOk = false; |
| 150 | } | |
| 151 | 2 | if (firstRegisterAsInt < 0) { |
| 152 | 2 | firstRegisterAsInt = 0; |
| 153 | } | |
| 154 | 2 | if (addressingModeAsInt < 0) { |
| 155 | 2 | addressingModeAsInt = 1; |
| 156 | } | |
| 157 | 2 | if (secondRegisterIdAsInt < 0) { |
| 158 | 2 | secondRegisterIdAsInt = 0; |
| 159 | } | |
| 160 | ||
| 161 | 1 | if (allOk) { |
| 162 | ||
| 163 | // if store or jump then addressinmode as int -= 1; | |
| 164 | 17 | if (opcodeAsInt == 1 || |
| 165 | (opcodeAsInt >= 32 && opcodeAsInt <= 44) || | |
| 166 | (addressEmpty && !otherRegister.equals("")) || | |
| 167 | opcodeAsInt == 49 | |
| 168 | ) { | |
| 169 | 3 | addressingModeAsInt = addressingModeAsInt - 1; |
| 170 | 3 | if (addressingModeAsInt == -1) { |
| 171 | 1 | ++addressingModeAsInt; |
| 172 | } | |
| 173 | } | |
| 174 | ||
| 175 | 22 | String binary = StringUtils.intToBinary(opcodeAsInt, 8) + StringUtils.intToBinary(firstRegisterAsInt, 3) + |
| 176 | StringUtils.intToBinary(addressingModeAsInt, 2) + | |
| 177 | StringUtils.intToBinary(secondRegisterIdAsInt, 3) + StringUtils.intToBinary(addressAsInt, 16); | |
| 178 | 4 | return StringUtils.binaryToInt(binary, true); |
| 179 | } | |
| 180 | ||
| 181 | 3 | return -1; |
| 182 | } | |
| 183 | } | |
Mutations | ||
| 36 |
removed call to fi/helsinki/cs/titokone/SymbolicInterpreter::dataSetup : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 43 |
removed call to java/util/HashMap::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Removed assignment to member variable opcodes : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 44 |
negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Substituted 0 with 1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Changed increment from 1 to -1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Substituted 0 with 1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) changed conditional boundary : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 45 |
Substituted 0 with 1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Substituted 0 with 1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) removed call to java/util/HashMap::put : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Substituted 1 with 0 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Substituted 1 with 0 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 48 |
Removed assignment to member variable addressModes : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) removed call to java/util/HashMap::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 49 |
Substituted 0 with 1 : SURVIVED Changed increment from 1 to -1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) changed conditional boundary : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) negated conditional : SURVIVED Substituted 0 with 1 : SURVIVED |
|
| 50 |
removed call to java/util/HashMap::put : SURVIVED Substituted 0 with 1 : SURVIVED Substituted 0 with 1 : SURVIVED Substituted 1 with 0 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Substituted 1 with 0 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 53 |
Removed assignment to member variable registers : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) removed call to java/util/HashMap::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 54 |
Substituted 0 with 1 : SURVIVED changed conditional boundary : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) negated conditional : SURVIVED Substituted 0 with 1 : SURVIVED Changed increment from 1 to -1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 55 |
Substituted 1 with 0 : SURVIVED removed call to java/util/HashMap::put : SURVIVED Substituted 1 with 0 : SURVIVED Substituted 0 with 1 : TIMED_OUT Substituted 0 with 1 : SURVIVED |
|
| 67 |
removed call to java/lang/String::trim : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 68 |
removed call to java/lang/String::toUpperCase : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 69 |
removed call to java/util/HashMap::get : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 70 |
negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 71 |
removed call to java/lang/Integer::intValue : SURVIVED replaced return of integer sized value with (x == 0 ? 1 : 0) : SURVIVED |
|
| 73 |
replaced return of integer sized value with (x == 0 ? 1 : 0) : NO_COVERAGE Substituted -1 with 1 : NO_COVERAGE Substituted -1 with 0 : NO_COVERAGE |
|
| 84 |
removed call to java/lang/String::trim : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 85 |
removed call to java/lang/String::toUpperCase : SURVIVED |
|
| 86 |
removed call to java/util/HashMap::get : SURVIVED |
|
| 87 |
negated conditional : SURVIVED |
|
| 88 |
removed call to java/lang/Integer::intValue : SURVIVED replaced return of integer sized value with (x == 0 ? 1 : 0) : SURVIVED |
|
| 90 |
Substituted -1 with 1 : NO_COVERAGE replaced return of integer sized value with (x == 0 ? 1 : 0) : NO_COVERAGE Substituted -1 with 0 : NO_COVERAGE |
|
| 100 |
removed call to java/lang/String::trim : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 101 |
removed call to java/lang/String::toUpperCase : SURVIVED |
|
| 102 |
removed call to java/util/HashMap::get : SURVIVED |
|
| 103 |
negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 104 |
replaced return of integer sized value with (x == 0 ? 1 : 0) : NO_COVERAGE removed call to java/lang/Integer::intValue : NO_COVERAGE |
|
| 106 |
Substituted -1 with 1 : SURVIVED replaced return of integer sized value with (x == 0 ? 1 : 0) : SURVIVED Substituted -1 with 0 : SURVIVED |
|
| 123 |
Substituted 1 with 0 : SURVIVED Substituted 1 with 0 : SURVIVED |
|
| 126 |
removed call to java/lang/String::equals : SURVIVED negated conditional : SURVIVED |
|
| 127 |
Substituted 1 with 0 : SURVIVED Substituted 1 with 0 : SURVIVED |
|
| 129 |
Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 132 |
removed call to fi/helsinki/cs/titokone/SymbolicInterpreter::getOpcode : SURVIVED |
|
| 133 |
removed call to fi/helsinki/cs/titokone/SymbolicInterpreter::getRegisterId : SURVIVED |
|
| 134 |
removed call to fi/helsinki/cs/titokone/SymbolicInterpreter::getAddressingMode : SURVIVED |
|
| 135 |
Substituted 0 with 1 : SURVIVED Substituted 0 with 1 : SURVIVED |
|
| 136 |
removed call to fi/helsinki/cs/titokone/SymbolicInterpreter::getRegisterId : SURVIVED |
|
| 138 |
negated conditional : SURVIVED removed call to java/lang/String::equals : SURVIVED |
|
| 143 |
removed call to java/lang/Integer::parseInt : SURVIVED |
|
| 145 |
Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 148 |
changed conditional boundary : SURVIVED negated conditional : SURVIVED |
|
| 149 |
Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 151 |
changed conditional boundary : SURVIVED negated conditional : SURVIVED |
|
| 152 |
Substituted 0 with 1 : SURVIVED Substituted 0 with 1 : SURVIVED |
|
| 154 |
changed conditional boundary : SURVIVED negated conditional : SURVIVED |
|
| 155 |
Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE |
|
| 157 |
changed conditional boundary : SURVIVED negated conditional : SURVIVED |
|
| 158 |
Substituted 0 with 1 : SURVIVED Substituted 0 with 1 : SURVIVED |
|
| 161 |
negated conditional : SURVIVED |
|
| 164 |
negated conditional : SURVIVED negated conditional : SURVIVED Replaced constant value of 49 with 50 : SURVIVED negated conditional : SURVIVED changed conditional boundary : SURVIVED negated conditional : SURVIVED changed conditional boundary : SURVIVED negated conditional : SURVIVED Substituted 1 with 0 : SURVIVED removed call to java/lang/String::equals : SURVIVED negated conditional : SURVIVED Substituted 49 with 50 : SURVIVED Replaced constant value of 32 with 33 : SURVIVED Substituted 32 with 33 : SURVIVED Replaced constant value of 44 with 45 : SURVIVED Substituted 44 with 45 : SURVIVED Substituted 1 with 0 : SURVIVED |
|
| 169 |
Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE Replaced integer subtraction with addition : NO_COVERAGE |
|
| 170 |
negated conditional : NO_COVERAGE Substituted -1 with 0 : NO_COVERAGE Substituted -1 with 1 : NO_COVERAGE |
|
| 171 |
Changed increment from 1 to -1 : NO_COVERAGE |
|
| 175 |
removed call to fi/helsinki/cs/titokone/StringUtils::intToBinary : SURVIVED removed call to fi/helsinki/cs/titokone/StringUtils::intToBinary : SURVIVED removed call to java/lang/StringBuilder::append : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Substituted 8 with 9 : SURVIVED removed call to java/lang/StringBuilder::append : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/StringUtils::intToBinary : SURVIVED removed call to java/lang/StringBuilder::toString : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) removed call to java/lang/StringBuilder::append : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Substituted 16 with 17 : SURVIVED Replaced constant value of 8 with 9 : SURVIVED Substituted 2 with 3 : SURVIVED Replaced constant value of 16 with 17 : SURVIVED removed call to java/lang/StringBuilder::append : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) removed call to java/lang/StringBuilder::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) removed call to java/lang/StringBuilder::append : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Substituted 3 with 4 : SURVIVED Substituted 3 with 4 : SURVIVED removed call to fi/helsinki/cs/titokone/StringUtils::intToBinary : SURVIVED Substituted 3 with 4 : SURVIVED Substituted 3 with 4 : SURVIVED Substituted 2 with 3 : SURVIVED removed call to fi/helsinki/cs/titokone/StringUtils::intToBinary : SURVIVED |
|
| 178 |
replaced return of integer sized value with (x == 0 ? 1 : 0) : SURVIVED Substituted 1 with 0 : SURVIVED removed call to fi/helsinki/cs/titokone/StringUtils::binaryToInt : SURVIVED Substituted 1 with 0 : SURVIVED |
|
| 181 |
replaced return of integer sized value with (x == 0 ? 1 : 0) : NO_COVERAGE Substituted -1 with 0 : NO_COVERAGE Substituted -1 with 1 : NO_COVERAGE |