1 package net.mograsim.plugin.launch;
3 import java.math.BigInteger;
4 import java.util.Arrays;
5 import java.util.function.Consumer;
7 import org.eclipse.core.runtime.IStatus;
8 import org.eclipse.core.runtime.PlatformObject;
9 import org.eclipse.core.runtime.Status;
10 import org.eclipse.debug.core.DebugEvent;
11 import org.eclipse.debug.core.DebugException;
12 import org.eclipse.debug.core.DebugPlugin;
13 import org.eclipse.debug.core.ILaunch;
14 import org.eclipse.debug.core.model.IDebugElement;
15 import org.eclipse.debug.core.model.IDebugTarget;
16 import org.eclipse.debug.core.model.IRegister;
17 import org.eclipse.debug.core.model.IRegisterGroup;
18 import org.eclipse.debug.core.model.IValue;
19 import org.eclipse.swt.SWT;
21 import net.mograsim.logic.core.types.BitVector;
22 import net.mograsim.machine.Machine;
23 import net.mograsim.machine.registers.Register;
24 import net.mograsim.plugin.MograsimActivator;
26 public class MachineRegister extends PlatformObject implements IRegister
28 private final MachineRegisterGroup registerGroup;
29 private final Register machineRegister;
31 private final Consumer<BitVector> registerListener;
33 public MachineRegister(MachineRegisterGroup registerGroup, Register machineRegister)
35 this.registerGroup = registerGroup;
36 this.machineRegister = machineRegister;
38 this.registerListener = v -> fireChangeEvent();
39 getMachine().addRegisterListener(machineRegister, registerListener);
41 DebugPlugin.getDefault().addDebugEventListener(es -> Arrays.stream(es).filter(e -> e.getKind() == DebugEvent.TERMINATE).filter(e ->
43 Object source = e.getSource();
44 if (!(source instanceof IDebugElement))
46 return ((IDebugElement) source).getDebugTarget() == getDebugTarget();
47 }).forEach(e -> getMachine().removeRegisterListener(machineRegister, registerListener)));
50 public Machine getMachine()
52 return registerGroup.getMachine();
56 public IValue getValue() throws DebugException
58 return new MachineValue(this);
62 public String getName() throws DebugException
64 return machineRegister.id();// TODO name
68 public String getReferenceTypeName() throws DebugException
74 public boolean hasValueChanged() throws DebugException
81 public String getModelIdentifier()
83 return MograsimActivator.PLUGIN_ID;
87 public IDebugTarget getDebugTarget()
89 return registerGroup.getDebugTarget();
93 public ILaunch getLaunch()
95 return registerGroup.getLaunch();
98 public String getValueString()
100 BitVector bitvector = getMachine().getRegister(machineRegister);
101 if (bitvector.isBinary())
103 String hexdigits = bitvector.getUnsignedValue().toString(16);
104 StringBuilder sb = new StringBuilder();
106 sb.append("0".repeat((machineRegister.getWidth() + 3) / 4 - hexdigits.length()));
107 sb.append(hexdigits);
108 return sb.toString();
110 return bitvector.toString();
114 public void setValue(String expression) throws DebugException
116 BitVector bitvector = parseValue(expression);
117 if (bitvector == null)
118 throw new DebugException(
119 new Status(IStatus.ERROR, MograsimActivator.PLUGIN_ID, "Couldn't parse value string: " + expression, null));
120 getMachine().setRegister(machineRegister, bitvector);
123 private BitVector parseValue(String expression)
125 BitVector bitvector = null;
126 if (expression.matches("0x[0-9a-fA-F]+"))
127 // TODO should we check for overflows?
128 bitvector = BitVector.from(new BigInteger(expression.substring(2), 16), machineRegister.getWidth());
129 else if (expression.length() == machineRegister.getWidth())
130 // TODO do this without exceptions
133 bitvector = BitVector.parse(expression);
135 catch (@SuppressWarnings("unused") NullPointerException x)
139 if (bitvector == null)
142 // TODO should we check for overflows?
143 bitvector = BitVector.from(new BigInteger(expression), machineRegister.getWidth());
145 catch (@SuppressWarnings("unused") NumberFormatException x)
153 public void setValue(IValue value) throws DebugException
155 if (!"Bitvector".equals(value.getReferenceTypeName()))
156 throw new DebugException(new Status(SWT.ERROR, MograsimActivator.PLUGIN_ID, ""));
157 setValue(value.getValueString());
161 public boolean supportsValueModification()
167 public boolean verifyValue(String expression) throws DebugException
169 return parseValue(expression) != null;
173 public boolean verifyValue(IValue value) throws DebugException
175 return verifyValue(value.getValueString());
179 public IRegisterGroup getRegisterGroup() throws DebugException
181 return registerGroup;
185 * Fires a change event for this debug element.
187 private void fireChangeEvent()
189 fireEvent(new DebugEvent(this, DebugEvent.CHANGE));
193 * Fires a debug event.
195 * @param event debug event to fire
197 private static void fireEvent(DebugEvent event)
199 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { event });