On Wed, Jun 26, 2019 at 11:16 PM Chris Angelico <ros...@gmail.com> 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 -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/I5BR4WTECUYYGFQ4NX6VOZ3AJTPMMHH2/ Code of Conduct: http://python.org/psf/codeofconduct/