On Wed, Jun 26, 2019 at 11:16 PM Chris Angelico <[email protected]> wrote:
[...]
> Then I completely don't understand getself. Can you give an example of
> how it would be used? So far, it just seems like an utter total mess.
Sure, below is my code snippet for signal get/set, using "L[:] =
thing" syntax and overriding get/setitem(). In this case, signal
follow a declaration (e.g. x = signal()) and use (e.g. x[:] = thing,
thing = x[...]) paradigm. getitem always return a integer or delegates
it to another object (self.current).
207 def __setitem__(self, key, value):
208 if self.typ == IN:
209 raise SignalError("IN type signal cannot be assigned")
210 if self.edge != 0:
211 raise SignalError("edge signal cannot be assigned")
212 elif isinstance(value, self.__class__):
213 self._set_next(key, value.current)
214 delay = Delay(0, value.current, signal=self)
215 self.sim.delta_next.append(delay)
216 elif isinstance(value, Delay):
217 value.next = value.delay + self.sim.current_time #
relative delay to absolute time
218 value.signal = self
219 self._set_next(key, value.value)
220 if value.delay == 0:
221 self.sim.delta_next.append(value)
222 else:
223 self.sim._event(value)
224 else:
225 self._set_next(key, value)
226 delay = Delay(0, value, signal=self)
227 delay.next = self.sim.current_time
228 self.sim.delta_next.append(delay)
230 def __getitem__(self, key):
231 '''
232 Slicing of signals
233 '''
234 if self.value_type != int:
235 return self.current.__getitem__(key) # support generic
payloads, not just int, so delegate it to "current"
236 # int signal always returns an int
237 if key in [slice(None, None, None), ...]:
238 return self.current # behaves like an int if explicitly indexed
239 elif isinstance(key, slice):
240 start = key.start
241 stop = key.stop
242 step = key.step
243 if key.step:
244 step = key.step
245 else:
246 step = 1
247 if start < stop: # the little endian case
248 if stop > self.width:
249 raise SignalError("slice stop is too big: %d
(> width %d)" % (stop, self.width))
250 stop += 1
251 else: # the big endian case
252 if start >= self.width:
253 raise SignalError("slice start is too big: %d
(>= width %d)" % (start, self.width))
254 stop -= 1
255 step = 0 - step
256 vrange = range(start, stop, step)
257 length = len(vrange)
258 current = self.current
259 value_list = []
260 #print("current:", current)
261 for i in vrange:
262 v = (current >> i) & 0x1
263 #print("v:", v)
264 value_list.append(v)
265 return self._get_value(value_list)
266 elif isinstance(key, int):
267 if key >= self.width:
268 raise SignalError("key is too big: %d (>= width
%d)" % (key, self.width))
269 return (self.current >> key) & 0x1
270 elif isinstance(key, tuple):
271 raise SignalError("signal indices must be integers or
slices, not tuple")
And this is how it can be used by a user:
8 @block("hdl")
9 def ADD(name,
10 a: signal(32, IN),
11 b: signal(32, IN),
12 out: signal(32, OUT),
13 ):
14
15 x = signal(1, OUT, "x")
16
17 @always(a, b)
18 def add():
19 out[:] = (a + b)
EOF.
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/I5BR4WTECUYYGFQ4NX6VOZ3AJTPMMHH2/
Code of Conduct: http://python.org/psf/codeofconduct/