1 package net.mograsim.machine.mi.parameters;
3 import java.util.Arrays;
4 import java.util.LinkedList;
7 import java.util.stream.Collectors;
9 import net.mograsim.logic.core.types.Bit;
10 import net.mograsim.logic.core.types.BitVector;
11 import net.mograsim.machine.MachineException;
12 import net.mograsim.machine.mi.parameters.MicroInstructionParameter.ParameterType;
14 public class MnemonicFamily implements ParameterClassification
16 private final Mnemonic[] values;
17 private final Mnemonic defaultValue;
18 private final String[] stringValues;
19 private Map<String, Mnemonic> byText;
20 private int vectorLength;
22 MnemonicFamily(String defaultValueName, MnemonicPair... values)
24 if (values.length == 0)
25 throw new MachineException("Mnemonics must not be empty!");
26 this.values = new Mnemonic[values.length];
27 this.stringValues = new String[values.length];
31 // if no valid defaultValue is specified, pick first value as default
32 int defaultValueIndex = 0;
33 for (int i = 0; i < values.length; i++)
34 if (stringValues[i].equals(defaultValueName))
36 defaultValueIndex = i;
39 this.defaultValue = this.values[defaultValueIndex];
42 private void setup(MnemonicPair[] values)
44 for (int i = 0; i < values.length; i++)
46 this.values[i] = createMnemonic(values[i], i);
47 this.stringValues[i] = values[i].name;
49 if (values.length == 0)
53 vectorLength = values[0].value.length();
54 for (int i = 1; i < values.length; i++)
55 if (values[i].value.length() != vectorLength)
56 throw new IllegalArgumentException("MnemonicFamily is not of uniform vector length!");
58 byText = Arrays.stream(this.values).collect(Collectors.toMap(m -> m.getText(), m -> m));
59 if (values.length != byText.keySet().size())
60 throw new IllegalArgumentException("MnemonicFamily contains multiple Mnemonics with the same name!");
63 private Mnemonic createMnemonic(MnemonicPair mnemonicPair, int ordinal)
65 return new Mnemonic(mnemonicPair.name, mnemonicPair.value, this, ordinal);
68 public Mnemonic[] values()
70 return values.clone();
73 public Mnemonic get(int ordinal)
75 return values[ordinal];
78 public Mnemonic get(String text)
80 return byText.get(text);
84 public MicroInstructionParameter getDefault()
89 public boolean contains(Mnemonic m)
92 return m.owner == this;
96 public boolean contains(String value)
98 return byText.keySet().contains(value);
103 return values.length;
106 public int getVectorLength()
112 public boolean conforms(MicroInstructionParameter param)
114 return ParameterClassification.super.conforms(param) && (param instanceof Mnemonic ? contains((Mnemonic) param) : false);
118 public ParameterType getExpectedType()
120 return ParameterType.MNEMONIC;
124 public int getExpectedBits()
129 public String[] getStringValues()
131 return stringValues.clone();
135 public int hashCode()
137 final int prime = 31;
139 result = prime * result + Arrays.hashCode(values);
144 public boolean equals(Object obj)
150 public Mnemonic parse(String toParse)
152 Mnemonic parsed = get(toParse);
154 throw new UnknownMnemonicException(toParse);
158 public static class MnemonicPair
160 public final String name;
161 public final BitVector value;
163 public MnemonicPair(String name, BitVector value)
170 public static class MnemonicFamilyBuilder
172 private final List<MnemonicPair> pairs;
173 private final int bits;
174 private String defaultValue;
176 public MnemonicFamilyBuilder(int bits)
178 this.pairs = new LinkedList<>();
182 public MnemonicFamilyBuilder addX()
184 pairs.add(new MnemonicPair("X", BitVector.of(Bit.ZERO, bits)));
188 public MnemonicFamilyBuilder add(MnemonicPair... pairs)
190 this.pairs.addAll(List.of(pairs));
195 * Adds a name with its corresponding value to the {@link MnemonicFamily}
197 * @return this {@link MnemonicFamilyBuilder}
199 public MnemonicFamilyBuilder add(String name, BitVector value)
201 add(new MnemonicPair(name, value));
206 * Adds names with their corresponding values to the {@link MnemonicFamily}
208 * @param names The names to be added to the {@link MnemonicFamily}
209 * @param values The values as {@link BitVector}s
210 * @return this {@link MnemonicFamilyBuilder}
212 public MnemonicFamilyBuilder add(String name, long value)
214 add(new MnemonicPair(name, BitVector.from(value, bits)));
219 * Adds names with their corresponding values to the {@link MnemonicFamily}
221 * @param names The names to be added to the {@link MnemonicFamily}
222 * @param values The values as {@link BitVector}s
223 * @return this {@link MnemonicFamilyBuilder}
225 public MnemonicFamilyBuilder add(String names[], BitVector[] values)
227 if (names.length != values.length)
228 throw new IllegalArgumentException("Cannot add Mnemonics! Amount of names does not match amount of values!");
229 for (int i = 0; i < names.length; i++)
230 add(new MnemonicPair(names[i], values[i]));
235 * Adds names with their corresponding values (converted to a BitVector) to the {@link MnemonicFamily}
237 * @param names The names to be added to the {@link MnemonicFamily}
238 * @param values The values to be converted to {@link BitVector}s with a given amount of {@link MnemonicFamilyBuilder#bits}
239 * @return this {@link MnemonicFamilyBuilder}
241 public MnemonicFamilyBuilder add(String names[], long values[])
243 if (names.length != values.length)
244 throw new IllegalArgumentException("Cannot add Mnemonics! Amount of names does not match amount of values!");
245 for (int i = 0; i < names.length; i++)
246 add(new MnemonicPair(names[i], BitVector.from(values[i], bits)));
251 * Adds names to the {@link MnemonicFamily}; The corresponding {@link BitVector} value to a name is the value of its index
253 * @param names The names to be added to the {@link MnemonicFamily}
254 * @return this {@link MnemonicFamilyBuilder}
256 public MnemonicFamilyBuilder add(String... names)
258 for (int i = 0; i < names.length; i++)
264 * Sets the name of the default {@link Mnemonic} of this {@link MnemonicFamily}
266 public MnemonicFamilyBuilder setDefault(String defaultValue)
268 this.defaultValue = defaultValue;
273 * Sets the name of the default {@link Mnemonic} of this {@link MnemonicFamily} to "X"
275 public MnemonicFamilyBuilder setXDefault()
277 this.defaultValue = "X";
281 public MnemonicFamily build()
283 return new MnemonicFamily(defaultValue, pairs.toArray(new MnemonicPair[pairs.size()]));