@@ -29,25 +29,43 @@ def __init__(self, v, engine):
2929
3030 # --- Reassembling Arithmetic from C ---
3131 def __add__ (self , o ):
32- left = self ._val
33- right = unwrap (o )
34- # If either operand is a string, concatenate as strings (JS-like)
35- if isinstance (left , str ) or isinstance (right , str ):
36- result = str (left ) + str (right )
37- return self .__class__ (result , self ._engine )
38- # Attempt to convert to float otherwise
39- for idx , val in enumerate ([left , right ]):
40- if isinstance (val , str ):
41- try :
42- if idx == 0 :
43- left = float (left )
44- else :
45- right = float (right )
46- except ValueError :
47- pass
48- if isinstance (left , (int , float )) and isinstance (right , (int , float )):
49- return self .__class__ (_core .add (left , right ), self ._engine )
50- raise TypeError (f"Cannot add { type (left ).__name__ } and { type (right ).__name__ } " )
32+ left = self ._val
33+ right = unwrap (o )
34+
35+ # 1) Check for metamethod on left operand (e.g. Lua/PHP metatable __add)
36+ mm = get_mm (left , '__add' , self ._engine )
37+ if mm :
38+ mm_func = unwrap (mm ) if mm is not None else mm
39+ if callable (mm_func ):
40+ return self .__class__ (mm_func (left , right ), self ._engine )
41+
42+ # 2) Check for metamethod on right operand (swapped operands)
43+ mm = get_mm (right , '__add' , self ._engine )
44+ if mm :
45+ mm_func = unwrap (mm ) if mm is not None else mm
46+ if callable (mm_func ):
47+ return self .__class__ (mm_func (right , left ), self ._engine )
48+
49+ # 3) JS-like string concatenation if either operand is a string
50+ if isinstance (left , str ) or isinstance (right , str ):
51+ result = str (left ) + str (right )
52+ return self .__class__ (result , self ._engine )
53+
54+ # 4) Try converting string operands to numeric floats and do numeric add
55+ for idx , val in enumerate ([left , right ]):
56+ if isinstance (val , str ):
57+ try :
58+ if idx == 0 :
59+ left = float (left )
60+ else :
61+ right = float (right )
62+ except ValueError :
63+ pass
64+
65+ if isinstance (left , (int , float )) and isinstance (right , (int , float )):
66+ return self .__class__ (_core .add (left , right ), self ._engine )
67+
68+ raise TypeError (f"Cannot add { type (left ).__name__ } and { type (right ).__name__ } " )
5169
5270 def __sub__ (self , o ): return self .__class__ (_core .sub (self ._val , unwrap (o )), self ._engine )
5371 def __mul__ (self , o ): return self .__class__ (_core .mul (self ._val , unwrap (o )), self ._engine )
0 commit comments