Removed some more warnings and cleaned more SWT listeners
[Mograsim.git] / plugins / net.mograsim.machine / src / net / mograsim / machine / mi / parameters / MnemonicFamily.java
1 package net.mograsim.machine.mi.parameters;
2
3 import java.util.Arrays;
4 import java.util.Map;
5 import java.util.stream.Collectors;
6
7 import net.mograsim.logic.core.types.BitVector;
8 import net.mograsim.machine.mi.parameters.MicroInstructionParameter.ParameterType;
9
10 public class MnemonicFamily implements ParameterClassification
11 {
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;
17
18         public MnemonicFamily(String defaultValueName, String... names)
19         {
20                 this(false, defaultValueName, (int) Math.round(Math.ceil(Math.log(names.length) / Math.log(2))), names);
21         }
22
23         public MnemonicFamily(boolean reverse, String defaultValueName, String... names)
24         {
25                 this(reverse, defaultValueName, (int) Math.round(Math.ceil(Math.log(names.length) / Math.log(2))), names);
26         }
27
28         public MnemonicFamily(String defaultValueName, int bits, String... names)
29         {
30                 this(false, defaultValueName, bits, names);
31         }
32
33         public MnemonicFamily(boolean reverse, String defaultValueName, int bits, String... names)
34         {
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++)
39                 {
40                         values[i] = BitVector.from(i, bits);
41                 }
42
43                 setup(names, values, reverse);
44
45                 int defaultValueIndex = -1;
46                 for (int i = 0; i < names.length; i++)
47                         if (names[i].equals(defaultValueName))
48                         {
49                                 defaultValueIndex = i;
50                                 break;
51                         }
52                 this.defaultValue = this.values[defaultValueIndex];
53         }
54
55         public MnemonicFamily(String defaultValueName, String[] names, long[] values, int bits)
56         {
57                 this(false, defaultValueName, names, values, bits);
58         }
59
60         public MnemonicFamily(boolean reverse, String defaultValueName, String[] names, long[] values, int bits)
61         {
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];
67
68                 for (int i = 0; i < vectors.length; i++)
69                 {
70                         vectors[i] = BitVector.from(values[i], bits);
71                 }
72
73                 setup(names, vectors, reverse);
74
75                 int defaultValueIndex = -1;
76                 for (int i = 0; i < names.length; i++)
77                         if (names[i].equals(defaultValueName))
78                         {
79                                 defaultValueIndex = i;
80                                 break;
81                         }
82                 this.defaultValue = this.values[defaultValueIndex];
83         }
84
85         public MnemonicFamily(String defaultValueName, String[] names, BitVector[] values)
86         {
87                 this(false, defaultValueName, names, values);
88         }
89
90         public MnemonicFamily(boolean reverse, String defaultValueName, String[] names, BitVector[] values)
91         {
92                 if (names.length != values.length)
93                         throw new IllegalArgumentException();
94                 this.values = new Mnemonic[values.length];
95                 this.stringValues = new String[values.length];
96
97                 setup(names, values, reverse);
98
99                 int defaultValueIndex = -1;
100                 for (int i = 0; i < names.length; i++)
101                         if (names[i].equals(defaultValueName))
102                         {
103                                 defaultValueIndex = i;
104                                 break;
105                         }
106                 this.defaultValue = this.values[defaultValueIndex];
107         }
108
109         public MnemonicFamily(String defaultValueName, MnemonicPair... values)
110         {
111                 this.values = new Mnemonic[values.length];
112                 this.stringValues = new String[values.length];
113
114                 setup(values);
115
116                 int defaultValueIndex = -1;
117                 for (int i = 0; i < values.length; i++)
118                         if (stringValues[i].equals(defaultValueName))
119                         {
120                                 defaultValueIndex = i;
121                                 break;
122                         }
123                 this.defaultValue = this.values[defaultValueIndex];
124         }
125
126         private void setup(String[] names, BitVector[] values, boolean reverse)
127         {
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]);
131                 setup(mnemonics);
132         }
133
134         private void setup(MnemonicPair[] values)
135         {
136                 for (int i = 0; i < values.length; i++)
137                 {
138                         this.values[i] = createMnemonic(values[i], i);
139                         this.stringValues[i] = values[i].name;
140                 }
141                 if (values.length == 0)
142                         vectorLength = 0;
143                 else
144                 {
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!");
149                 }
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!");
153         }
154
155         private Mnemonic createMnemonic(MnemonicPair mnemonicPair, int ordinal)
156         {
157                 return new Mnemonic(mnemonicPair.name, mnemonicPair.value, this, ordinal);
158         }
159
160         public Mnemonic[] values()
161         {
162                 return values.clone();
163         }
164
165         public Mnemonic get(int ordinal)
166         {
167                 return values[ordinal];
168         }
169
170         public Mnemonic get(String text)
171         {
172                 return byText.get(text);
173         }
174
175         @Override
176         public MicroInstructionParameter getDefault()
177         {
178                 return defaultValue;
179         }
180
181         public boolean contains(Mnemonic m)
182         {
183                 if (m != null)
184                         return m.owner == this;
185                 return false;
186         }
187
188         public boolean contains(String value)
189         {
190                 return byText.keySet().contains(value);
191         }
192
193         public int size()
194         {
195                 return values.length;
196         }
197
198         public int getVectorLength()
199         {
200                 return vectorLength;
201         }
202
203         @Override
204         public boolean conforms(MicroInstructionParameter param)
205         {
206                 return ParameterClassification.super.conforms(param) && (param instanceof Mnemonic ? contains((Mnemonic) param) : false);
207         }
208
209         @Override
210         public ParameterType getExpectedType()
211         {
212                 return ParameterType.MNEMONIC;
213         }
214
215         @Override
216         public int getExpectedBits()
217         {
218                 return vectorLength;
219         }
220
221         public String[] getStringValues()
222         {
223                 return stringValues.clone();
224         }
225
226         @Override
227         public int hashCode()
228         {
229                 final int prime = 31;
230                 int result = 1;
231                 result = prime * result + Arrays.hashCode(values);
232                 return result;
233         }
234
235         @Override
236         public boolean equals(Object obj)
237         {
238                 return this == obj;
239         }
240
241         @Override
242         public Mnemonic parse(String toParse)
243         {
244                 Mnemonic parsed = get(toParse);
245                 if (parsed == null)
246                         throw new UnknownMnemonicException(toParse);
247                 return parsed;
248         }
249
250         public static class MnemonicPair
251         {
252                 public final String name;
253                 public final BitVector value;
254
255                 public MnemonicPair(String name, BitVector value)
256                 {
257                         this.name = name;
258                         this.value = value;
259                 }
260         }
261 }