1 package net.mograsim.machine.mi.parameters;
3 import java.util.Arrays;
5 import java.util.stream.Collectors;
7 import net.mograsim.logic.core.types.BitVector;
8 import net.mograsim.machine.mi.parameters.MicroInstructionParameter.ParameterType;
10 public class MnemonicFamily implements ParameterClassification
12 private final Mnemonic[] values;
13 private final Mnemonic defaultValue;
14 private final String[] stringValues;
15 private Map<String, Mnemonic> byText;
16 private int vectorLength;
18 public MnemonicFamily(String defaultValueName, String... names)
20 this(false, defaultValueName, (int) Math.round(Math.ceil(Math.log(names.length) / Math.log(2))), names);
23 public MnemonicFamily(boolean reverse, String defaultValueName, String... names)
25 this(reverse, defaultValueName, (int) Math.round(Math.ceil(Math.log(names.length) / Math.log(2))), names);
28 public MnemonicFamily(String defaultValueName, int bits, String... names)
30 this(false, defaultValueName, bits, names);
33 public MnemonicFamily(boolean reverse, String defaultValueName, int bits, String... names)
35 this.values = new Mnemonic[names.length];
36 this.stringValues = new String[names.length];
37 BitVector[] values = new BitVector[names.length];
38 for (int i = 0; i < names.length; i++)
40 values[i] = BitVector.from(i, bits);
43 setup(names, values, reverse);
45 int defaultValueIndex = -1;
46 for (int i = 0; i < names.length; i++)
47 if (names[i].equals(defaultValueName))
49 defaultValueIndex = i;
52 this.defaultValue = this.values[defaultValueIndex];
55 public MnemonicFamily(String defaultValueName, String[] names, long[] values, int bits)
57 this(false, defaultValueName, names, values, bits);
60 public MnemonicFamily(boolean reverse, String defaultValueName, String[] names, long[] values, int bits)
62 if (names.length != values.length)
63 throw new IllegalArgumentException();
64 this.values = new Mnemonic[values.length];
65 this.stringValues = new String[values.length];
66 BitVector[] vectors = new BitVector[values.length];
68 for (int i = 0; i < vectors.length; i++)
70 vectors[i] = BitVector.from(values[i], bits);
73 setup(names, vectors, reverse);
75 int defaultValueIndex = -1;
76 for (int i = 0; i < names.length; i++)
77 if (names[i].equals(defaultValueName))
79 defaultValueIndex = i;
82 this.defaultValue = this.values[defaultValueIndex];
85 public MnemonicFamily(String defaultValueName, String[] names, BitVector[] values)
87 this(false, defaultValueName, names, values);
90 public MnemonicFamily(boolean reverse, String defaultValueName, String[] names, BitVector[] values)
92 if (names.length != values.length)
93 throw new IllegalArgumentException();
94 this.values = new Mnemonic[values.length];
95 this.stringValues = new String[values.length];
97 setup(names, values, reverse);
99 int defaultValueIndex = -1;
100 for (int i = 0; i < names.length; i++)
101 if (names[i].equals(defaultValueName))
103 defaultValueIndex = i;
106 this.defaultValue = this.values[defaultValueIndex];
109 public MnemonicFamily(String defaultValueName, MnemonicPair... values)
111 this.values = new Mnemonic[values.length];
112 this.stringValues = new String[values.length];
116 int defaultValueIndex = -1;
117 for (int i = 0; i < values.length; i++)
118 if (stringValues[i].equals(defaultValueName))
120 defaultValueIndex = i;
123 this.defaultValue = this.values[defaultValueIndex];
126 private void setup(String[] names, BitVector[] values, boolean reverse)
128 MnemonicPair[] mnemonics = new MnemonicPair[values.length];
129 for (int i = 0; i < values.length; i++)
130 mnemonics[i] = new MnemonicPair(names[i], reverse ? values[i].reverse() : values[i]);
134 private void setup(MnemonicPair[] values)
136 for (int i = 0; i < values.length; i++)
138 this.values[i] = createMnemonic(values[i], i);
139 this.stringValues[i] = values[i].name;
141 if (values.length == 0)
145 vectorLength = values[0].value.length();
146 for (int i = 1; i < values.length; i++)
147 if (values[i].value.length() != vectorLength)
148 throw new IllegalArgumentException("MnemonicFamily is not of uniform vector length!");
150 byText = Arrays.stream(this.values).collect(Collectors.toMap(m -> m.getText(), m -> m));
151 if (values.length != byText.keySet().size())
152 throw new IllegalArgumentException("MnemonicFamily contains multiple Mnemonics with the same name!");
155 private Mnemonic createMnemonic(MnemonicPair mnemonicPair, int ordinal)
157 return new Mnemonic(mnemonicPair.name, mnemonicPair.value, this, ordinal);
160 public Mnemonic[] values()
162 return values.clone();
165 public Mnemonic get(int ordinal)
167 return values[ordinal];
170 public Mnemonic get(String text)
172 return byText.get(text);
176 public MicroInstructionParameter getDefault()
181 public boolean contains(Mnemonic m)
184 return m.owner == this;
188 public boolean contains(String value)
190 return byText.keySet().contains(value);
195 return values.length;
198 public int getVectorLength()
204 public boolean conforms(MicroInstructionParameter param)
206 return ParameterClassification.super.conforms(param) && (param instanceof Mnemonic ? contains((Mnemonic) param) : false);
210 public ParameterType getExpectedType()
212 return ParameterType.MNEMONIC;
216 public int getExpectedBits()
221 public String[] getStringValues()
223 return stringValues.clone();
227 public int hashCode()
229 final int prime = 31;
231 result = prime * result + Arrays.hashCode(values);
236 public boolean equals(Object obj)
242 public Mnemonic parse(String toParse)
244 Mnemonic parsed = get(toParse);
246 throw new UnknownMnemonicException(toParse);
250 public static class MnemonicPair
252 public final String name;
253 public final BitVector value;
255 public MnemonicPair(String name, BitVector value)