Added threads, stackframes, and registers to the debug model
[Mograsim.git] / plugins / net.mograsim.plugin.core / src / net / mograsim / plugin / launch / MachineRegister.java
diff --git a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/launch/MachineRegister.java b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/launch/MachineRegister.java
new file mode 100644 (file)
index 0000000..8c0685d
--- /dev/null
@@ -0,0 +1,166 @@
+package net.mograsim.plugin.launch;
+
+import java.util.Arrays;
+import java.util.function.Consumer;
+
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.model.IDebugElement;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.IRegister;
+import org.eclipse.debug.core.model.IRegisterGroup;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.swt.SWT;
+
+import net.mograsim.logic.core.types.BitVector;
+import net.mograsim.machine.Machine;
+import net.mograsim.machine.Register;
+import net.mograsim.plugin.MograsimActivator;
+
+public class MachineRegister extends PlatformObject implements IRegister
+{
+       private final MachineRegisterGroup registerGroup;
+       private final Register machineRegister;
+
+       private final Consumer<BitVector> registerListener;
+
+       public MachineRegister(MachineRegisterGroup registerGroup, Register machineRegister)
+       {
+               this.registerGroup = registerGroup;
+               this.machineRegister = machineRegister;
+
+               this.registerListener = v -> fireChangeEvent();
+               getMachine().addRegisterListener(machineRegister, registerListener);
+
+               DebugPlugin.getDefault().addDebugEventListener(es -> Arrays.stream(es).filter(e -> e.getKind() == DebugEvent.TERMINATE).filter(e ->
+               {
+                       Object source = e.getSource();
+                       if (!(source instanceof IDebugElement))
+                               return false;
+                       return ((IDebugElement) source).getDebugTarget() == getDebugTarget();
+               }).forEach(e -> getMachine().removeRegisterListener(machineRegister, registerListener)));
+       }
+
+       public Machine getMachine()
+       {
+               return registerGroup.getMachine();
+       }
+
+       @Override
+       public IValue getValue() throws DebugException
+       {
+               return new MachineValue(this);
+       }
+
+       @Override
+       public String getName() throws DebugException
+       {
+               return machineRegister.id();// TODO name
+       }
+
+       @Override
+       public String getReferenceTypeName() throws DebugException
+       {
+               return "BitVector";
+       }
+
+       @Override
+       public boolean hasValueChanged() throws DebugException
+       {
+               // TODO
+               return false;
+       }
+
+       @Override
+       public String getModelIdentifier()
+       {
+               return MograsimActivator.PLUGIN_ID;
+       }
+
+       @Override
+       public IDebugTarget getDebugTarget()
+       {
+               return registerGroup.getDebugTarget();
+       }
+
+       @Override
+       public ILaunch getLaunch()
+       {
+               return registerGroup.getLaunch();
+       }
+
+       public String getValueString()
+       {
+               return getMachine().getRegister(machineRegister).toString();
+       }
+
+       @Override
+       public void setValue(String expression) throws DebugException
+       {
+               // TODO exception handling
+               getMachine().setRegister(machineRegister, BitVector.parse(expression));
+       }
+
+       @Override
+       public void setValue(IValue value) throws DebugException
+       {
+               if (!"Bitvector".equals(value.getReferenceTypeName()))
+                       throw new DebugException(new Status(SWT.ERROR, MograsimActivator.PLUGIN_ID, ""));
+               setValue(value.getValueString());
+       }
+
+       @Override
+       public boolean supportsValueModification()
+       {
+               return true;
+       }
+
+       @Override
+       public boolean verifyValue(String expression) throws DebugException
+       {
+               // TODO do this prettier; also check length too
+               try
+               {
+                       BitVector.parse(expression);
+               }
+               catch (@SuppressWarnings("unused") Exception e)
+               {
+                       return false;
+               }
+               return true;
+       }
+
+       @Override
+       public boolean verifyValue(IValue value) throws DebugException
+       {
+               return verifyValue(value.getValueString());
+       }
+
+       @Override
+       public IRegisterGroup getRegisterGroup() throws DebugException
+       {
+               return registerGroup;
+       }
+
+       /**
+        * Fires a change event for this debug element.
+        */
+       private void fireChangeEvent()
+       {
+               fireEvent(new DebugEvent(this, DebugEvent.CHANGE));
+       }
+
+       /**
+        * Fires a debug event.
+        *
+        * @param event debug event to fire
+        */
+       private static void fireEvent(DebugEvent event)
+       {
+               DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { event });
+       }
+}
\ No newline at end of file