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.mi.parameters.MicroInstructionParameter.ParameterType;
13 public class MnemonicFamily implements ParameterClassification
15 private final Mnemonic[] values;
16 private final Mnemonic defaultValue;
17 private final String[] stringValues;
18 private Map<String, Mnemonic> byText;
19 private int vectorLength;
21 MnemonicFamily(String defaultValueName, MnemonicPair... values)
23 this.values = new Mnemonic[values.length];
24 this.stringValues = new String[values.length];
28 int defaultValueIndex = -1;
29 for (int i = 0; i < values.length; i++)
30 if (stringValues[i].equals(defaultValueName))
32 defaultValueIndex = i;
35 this.defaultValue = this.values[defaultValueIndex];
38 private void setup(MnemonicPair[] values)
40 for (int i = 0; i < values.length; i++)
42 this.values[i] = createMnemonic(values[i], i);
43 this.stringValues[i] = values[i].name;
45 if (values.length == 0)
49 vectorLength = values[0].value.length();
50 for (int i = 1; i < values.length; i++)
51 if (values[i].value.length() != vectorLength)
52 throw new IllegalArgumentException("MnemonicFamily is not of uniform vector length!");
54 byText = Arrays.stream(this.values).collect(Collectors.toMap(m -> m.getText(), m -> m));
55 if (values.length != byText.keySet().size())
56 throw new IllegalArgumentException("MnemonicFamily contains multiple Mnemonics with the same name!");
59 private Mnemonic createMnemonic(MnemonicPair mnemonicPair, int ordinal)
61 return new Mnemonic(mnemonicPair.name, mnemonicPair.value, this, ordinal);
64 public Mnemonic[] values()
66 return values.clone();
69 public Mnemonic get(int ordinal)
71 return values[ordinal];
74 public Mnemonic get(String text)
76 return byText.get(text);
80 public MicroInstructionParameter getDefault()
85 public boolean contains(Mnemonic m)
88 return m.owner == this;
92 public boolean contains(String value)
94 return byText.keySet().contains(value);
102 public int getVectorLength()
108 public boolean conforms(MicroInstructionParameter param)
110 return ParameterClassification.super.conforms(param) && (param instanceof Mnemonic ? contains((Mnemonic) param) : false);
114 public ParameterType getExpectedType()
116 return ParameterType.MNEMONIC;
120 public int getExpectedBits()
125 public String[] getStringValues()
127 return stringValues.clone();
131 public int hashCode()
133 final int prime = 31;
135 result = prime * result + Arrays.hashCode(values);
140 public boolean equals(Object obj)
146 public Mnemonic parse(String toParse)
148 Mnemonic parsed = get(toParse);
150 throw new UnknownMnemonicException(toParse);
154 public static class MnemonicPair
156 public final String name;
157 public final BitVector value;
159 public MnemonicPair(String name, BitVector value)
166 public static class MnemonicFamilyBuilder
168 private final List<MnemonicPair> pairs;
169 private final int bits;
170 private String defaultValue;
172 public MnemonicFamilyBuilder(int bits)
174 this.pairs = new LinkedList<>();
178 public MnemonicFamilyBuilder addX()
180 pairs.add(new MnemonicPair("X", BitVector.of(Bit.ZERO, bits)));
184 public MnemonicFamilyBuilder add(MnemonicPair... pairs)
186 this.pairs.addAll(List.of(pairs));
191 * Adds a name with its corresponding value to the {@link MnemonicFamily}
193 * @return this {@link MnemonicFamilyBuilder}
195 public MnemonicFamilyBuilder add(String name, BitVector value)
197 add(new MnemonicPair(name, value));
202 * Adds names with their corresponding values to the {@link MnemonicFamily}
204 * @param names The names to be added to the {@link MnemonicFamily}
205 * @param values The values as {@link BitVector}s
206 * @return this {@link MnemonicFamilyBuilder}
208 public MnemonicFamilyBuilder add(String name, long value)
210 add(new MnemonicPair(name, BitVector.from(value, bits)));
215 * Adds names with their corresponding values to the {@link MnemonicFamily}
217 * @param names The names to be added to the {@link MnemonicFamily}
218 * @param values The values as {@link BitVector}s
219 * @return this {@link MnemonicFamilyBuilder}
221 public MnemonicFamilyBuilder add(String names[], BitVector[] values)
223 if (names.length != values.length)
224 throw new IllegalArgumentException("Cannot add Mnemonics! Amount of names does not match amount of values!");
225 for (int i = 0; i < names.length; i++)
226 add(new MnemonicPair(names[i], values[i]));
231 * Adds names with their corresponding values (converted to a BitVector) to the {@link MnemonicFamily}
233 * @param names The names to be added to the {@link MnemonicFamily}
234 * @param values The values to be converted to {@link BitVector}s with a given amount of {@link MnemonicFamilyBuilder#bits}
235 * @return this {@link MnemonicFamilyBuilder}
237 public MnemonicFamilyBuilder add(String names[], long values[])
239 if (names.length != values.length)
240 throw new IllegalArgumentException("Cannot add Mnemonics! Amount of names does not match amount of values!");
241 for (int i = 0; i < names.length; i++)
242 add(new MnemonicPair(names[i], BitVector.from(values[i], bits)));
247 * Adds names to the {@link MnemonicFamily}; The corresponding {@link BitVector} value to a name is the value of its index
249 * @param names The names to be added to the {@link MnemonicFamily}
250 * @return this {@link MnemonicFamilyBuilder}
252 public MnemonicFamilyBuilder add(String... names)
254 for (int i = 0; i < names.length; i++)
260 * Sets the name of the default {@link Mnemonic} of this {@link MnemonicFamily}
262 public MnemonicFamilyBuilder setDefault(String defaultValue)
264 this.defaultValue = defaultValue;
269 * Sets the name of the default {@link Mnemonic} of this {@link MnemonicFamily} to "X"
271 public MnemonicFamilyBuilder setXDefault()
273 this.defaultValue = "X";
277 public MnemonicFamily build()
279 return new MnemonicFamily(defaultValue, pairs.toArray(new MnemonicPair[pairs.size()]));