@@ -156,6 +156,25 @@ def signed(width):
156
156
return Shape (width , signed = True )
157
157
158
158
159
+ def _overridable_by_reflected (method_name ):
160
+ """Allow overriding the decorated method.
161
+
162
+ Allows :class:`ValueCastable` to override the decorated method by implementing
163
+ a reflected method named ``method_name``. Intended for operators, but
164
+ also usable for other methods that have a reflected counterpart.
165
+ """
166
+ def decorator (f ):
167
+ @functools .wraps (f )
168
+ def wrapper (self , other ):
169
+ if isinstance (other , ValueCastable ) and hasattr (other , method_name ):
170
+ res = getattr (other , method_name )(self )
171
+ if res is not NotImplemented :
172
+ return res
173
+ return f (self , other )
174
+ return wrapper
175
+ return decorator
176
+
177
+
159
178
class Value (metaclass = ABCMeta ):
160
179
@staticmethod
161
180
def cast (obj ):
@@ -195,26 +214,31 @@ def __invert__(self):
195
214
def __neg__ (self ):
196
215
return Operator ("-" , [self ])
197
216
217
+ @_overridable_by_reflected ("__radd__" )
198
218
def __add__ (self , other ):
199
- return Operator ("+" , [self , other ])
219
+ return Operator ("+" , [self , other ], src_loc_at = 1 )
200
220
def __radd__ (self , other ):
201
221
return Operator ("+" , [other , self ])
222
+ @_overridable_by_reflected ("__rsub__" )
202
223
def __sub__ (self , other ):
203
- return Operator ("-" , [self , other ])
224
+ return Operator ("-" , [self , other ], src_loc_at = 1 )
204
225
def __rsub__ (self , other ):
205
226
return Operator ("-" , [other , self ])
206
227
228
+ @_overridable_by_reflected ("__rmul__" )
207
229
def __mul__ (self , other ):
208
- return Operator ("*" , [self , other ])
230
+ return Operator ("*" , [self , other ], src_loc_at = 1 )
209
231
def __rmul__ (self , other ):
210
232
return Operator ("*" , [other , self ])
211
233
234
+ @_overridable_by_reflected ("__rmod__" )
212
235
def __mod__ (self , other ):
213
- return Operator ("%" , [self , other ])
236
+ return Operator ("%" , [self , other ], src_loc_at = 1 )
214
237
def __rmod__ (self , other ):
215
238
return Operator ("%" , [other , self ])
239
+ @_overridable_by_reflected ("__rfloordiv__" )
216
240
def __floordiv__ (self , other ):
217
- return Operator ("//" , [self , other ])
241
+ return Operator ("//" , [self , other ], src_loc_at = 1 )
218
242
def __rfloordiv__ (self , other ):
219
243
return Operator ("//" , [other , self ])
220
244
@@ -224,46 +248,57 @@ def __check_shamt(self):
224
248
# by a signed value to make sure the shift amount can always be interpreted as
225
249
# an unsigned value.
226
250
raise TypeError ("Shift amount must be unsigned" )
251
+ @_overridable_by_reflected ("__rlshift__" )
227
252
def __lshift__ (self , other ):
228
253
other = Value .cast (other )
229
254
other .__check_shamt ()
230
- return Operator ("<<" , [self , other ])
255
+ return Operator ("<<" , [self , other ], src_loc_at = 1 )
231
256
def __rlshift__ (self , other ):
232
257
self .__check_shamt ()
233
258
return Operator ("<<" , [other , self ])
259
+ @_overridable_by_reflected ("__rrshift__" )
234
260
def __rshift__ (self , other ):
235
261
other = Value .cast (other )
236
262
other .__check_shamt ()
237
- return Operator (">>" , [self , other ])
263
+ return Operator (">>" , [self , other ], src_loc_at = 1 )
238
264
def __rrshift__ (self , other ):
239
265
self .__check_shamt ()
240
266
return Operator (">>" , [other , self ])
241
267
268
+ @_overridable_by_reflected ("__rand__" )
242
269
def __and__ (self , other ):
243
- return Operator ("&" , [self , other ])
270
+ return Operator ("&" , [self , other ], src_loc_at = 1 )
244
271
def __rand__ (self , other ):
245
272
return Operator ("&" , [other , self ])
273
+ @_overridable_by_reflected ("__rxor__" )
246
274
def __xor__ (self , other ):
247
- return Operator ("^" , [self , other ])
275
+ return Operator ("^" , [self , other ], src_loc_at = 1 )
248
276
def __rxor__ (self , other ):
249
277
return Operator ("^" , [other , self ])
278
+ @_overridable_by_reflected ("__ror__" )
250
279
def __or__ (self , other ):
251
- return Operator ("|" , [self , other ])
280
+ return Operator ("|" , [self , other ], src_loc_at = 1 )
252
281
def __ror__ (self , other ):
253
282
return Operator ("|" , [other , self ])
254
283
284
+ @_overridable_by_reflected ("__eq__" )
255
285
def __eq__ (self , other ):
256
- return Operator ("==" , [self , other ])
286
+ return Operator ("==" , [self , other ], src_loc_at = 1 )
287
+ @_overridable_by_reflected ("__ne__" )
257
288
def __ne__ (self , other ):
258
- return Operator ("!=" , [self , other ])
289
+ return Operator ("!=" , [self , other ], src_loc_at = 1 )
290
+ @_overridable_by_reflected ("__gt__" )
259
291
def __lt__ (self , other ):
260
- return Operator ("<" , [self , other ])
292
+ return Operator ("<" , [self , other ], src_loc_at = 1 )
293
+ @_overridable_by_reflected ("__ge__" )
261
294
def __le__ (self , other ):
262
- return Operator ("<=" , [self , other ])
295
+ return Operator ("<=" , [self , other ], src_loc_at = 1 )
296
+ @_overridable_by_reflected ("__lt__" )
263
297
def __gt__ (self , other ):
264
- return Operator (">" , [self , other ])
298
+ return Operator (">" , [self , other ], src_loc_at = 1 )
299
+ @_overridable_by_reflected ("__le__" )
265
300
def __ge__ (self , other ):
266
- return Operator (">=" , [self , other ])
301
+ return Operator (">=" , [self , other ], src_loc_at = 1 )
267
302
268
303
def __abs__ (self ):
269
304
if self .shape ().signed :
0 commit comments