Some work on improving BitVector<->String conversions
[Mograsim.git] / plugins / net.mograsim.plugin.core / src / net / mograsim / plugin / launch / MachineRegister.java
1 package net.mograsim.plugin.launch;
2
3 import java.util.Arrays;
4 import java.util.function.Consumer;
5
6 import org.eclipse.core.runtime.IStatus;
7 import org.eclipse.core.runtime.PlatformObject;
8 import org.eclipse.core.runtime.Status;
9 import org.eclipse.debug.core.DebugEvent;
10 import org.eclipse.debug.core.DebugException;
11 import org.eclipse.debug.core.DebugPlugin;
12 import org.eclipse.debug.core.ILaunch;
13 import org.eclipse.debug.core.model.IDebugElement;
14 import org.eclipse.debug.core.model.IDebugTarget;
15 import org.eclipse.debug.core.model.IRegister;
16 import org.eclipse.debug.core.model.IRegisterGroup;
17 import org.eclipse.debug.core.model.IValue;
18 import org.eclipse.swt.SWT;
19
20 import net.mograsim.logic.core.types.BitVector;
21 import net.mograsim.logic.core.types.BitVectorFormatter;
22 import net.mograsim.machine.Machine;
23 import net.mograsim.machine.registers.Register;
24 import net.mograsim.plugin.MograsimActivator;
25
26 public class MachineRegister extends PlatformObject implements IRegister
27 {
28         private final MachineRegisterGroup registerGroup;
29         private final Register machineRegister;
30
31         private final Consumer<BitVector> registerListener;
32
33         public MachineRegister(MachineRegisterGroup registerGroup, Register machineRegister)
34         {
35                 this.registerGroup = registerGroup;
36                 this.machineRegister = machineRegister;
37
38                 this.registerListener = v -> fireChangeEvent();
39                 getMachine().addRegisterListener(machineRegister, registerListener);
40
41                 DebugPlugin.getDefault().addDebugEventListener(es -> Arrays.stream(es).filter(e -> e.getKind() == DebugEvent.TERMINATE).filter(e ->
42                 {
43                         Object source = e.getSource();
44                         if (!(source instanceof IDebugElement))
45                                 return false;
46                         return ((IDebugElement) source).getDebugTarget() == getDebugTarget();
47                 }).forEach(e -> getMachine().removeRegisterListener(machineRegister, registerListener)));
48         }
49
50         public Machine getMachine()
51         {
52                 return registerGroup.getMachine();
53         }
54
55         @Override
56         public IValue getValue() throws DebugException
57         {
58                 return new MachineValue(this);
59         }
60
61         @Override
62         public String getName() throws DebugException
63         {
64                 return machineRegister.id();// TODO name
65         }
66
67         @Override
68         public String getReferenceTypeName() throws DebugException
69         {
70                 return "BitVector";
71         }
72
73         @Override
74         public boolean hasValueChanged() throws DebugException
75         {
76                 // TODO
77                 return false;
78         }
79
80         @Override
81         public String getModelIdentifier()
82         {
83                 return MograsimActivator.PLUGIN_ID;
84         }
85
86         @Override
87         public IDebugTarget getDebugTarget()
88         {
89                 return registerGroup.getDebugTarget();
90         }
91
92         @Override
93         public ILaunch getLaunch()
94         {
95                 return registerGroup.getLaunch();
96         }
97
98         public String getValueString()
99         {
100                 return BitVectorFormatter.formatAsString(getMachine().getRegister(machineRegister));
101         }
102
103         @Override
104         public void setValue(String expression) throws DebugException
105         {
106                 BitVector bitvector = BitVectorFormatter.parseUserBitVector(expression, machineRegister.getWidth());
107                 if (bitvector == null)
108                         throw new DebugException(
109                                         new Status(IStatus.ERROR, MograsimActivator.PLUGIN_ID, "Couldn't parse value string: " + expression, null));
110                 getMachine().setRegister(machineRegister, bitvector);
111         }
112
113         @Override
114         public void setValue(IValue value) throws DebugException
115         {
116                 if (!"Bitvector".equals(value.getReferenceTypeName()))
117                         throw new DebugException(new Status(SWT.ERROR, MograsimActivator.PLUGIN_ID, ""));
118                 setValue(value.getValueString());
119         }
120
121         @Override
122         public boolean supportsValueModification()
123         {
124                 return true;
125         }
126
127         @Override
128         public boolean verifyValue(String expression) throws DebugException
129         {
130                 return BitVectorFormatter.parseUserBitVector(expression, machineRegister.getWidth()) != null;
131         }
132
133         @Override
134         public boolean verifyValue(IValue value) throws DebugException
135         {
136                 return verifyValue(value.getValueString());
137         }
138
139         @Override
140         public IRegisterGroup getRegisterGroup() throws DebugException
141         {
142                 return registerGroup;
143         }
144
145         /**
146          * Fires a change event for this debug element.
147          */
148         private void fireChangeEvent()
149         {
150                 fireEvent(new DebugEvent(this, DebugEvent.CHANGE));
151         }
152
153         /**
154          * Fires a debug event.
155          *
156          * @param event debug event to fire
157          */
158         private static void fireEvent(DebugEvent event)
159         {
160                 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { event });
161         }
162 }