22import rpython .rlib .jit as jit
33from rpython .rlib .rarithmetic import r_uint
44from pixie .vm .code import as_var
5+ from pixie .vm .numbers import Integer
56from pixie .vm .keyword import Keyword
67import pixie .vm .rt as rt
78
@@ -46,12 +47,15 @@ def type(self):
4647 return self ._custom_type
4748
4849 def set_field (self , name , val ):
49- self ._custom_type .set_mutable (name )
5050 idx = self ._custom_type .get_slot_idx (name )
5151 if idx == - 1 :
5252 runtime_error (u"Invalid field named " + rt .name (rt .str (name )) + u" on type " + rt .name (rt .str (self .type ())))
5353
54- self ._fields [idx ] = val
54+ old_val = self ._fields [idx ]
55+ if isinstance (old_val , AbstractMutableCell ):
56+ old_val .set_mutable_cell_value (self ._custom_type , self ._fields , name , idx , val )
57+ else :
58+ self ._fields [idx ] = val
5559 return self
5660
5761 @jit .elidable_promote ()
@@ -65,9 +69,14 @@ def get_field(self, name):
6569 runtime_error (u"Invalid field named " + rt .name (rt .str (name )) + u" on type " + rt .name (rt .str (self .type ())))
6670
6771 if self ._custom_type .is_mutable (name ):
68- return self ._fields [idx ]
72+ value = self ._fields [idx ]
73+ else :
74+ value = self .get_field_immutable (idx )
75+
76+ if isinstance (value , AbstractMutableCell ):
77+ return value .get_mutable_cell_value ()
6978 else :
70- return self . get_field_immutable ( idx )
79+ return value
7180
7281 def set_field_by_idx (self , idx , val ):
7382 affirm (isinstance (idx , r_uint ), u"idx must be a r_uint" )
@@ -98,7 +107,10 @@ def _new__args(args):
98107 affirm (cnt - 1 != tp .get_num_slots (), u"Wrong number of initializer fields to custom type" )
99108 arr = [None ] * cnt
100109 for x in range (cnt ):
101- arr [x ] = args [x + 1 ]
110+ val = args [x + 1 ]
111+ if isinstance (val , Integer ):
112+ val = IntegerMutableCell (val .int_val ())
113+ arr [x ] = val
102114 return CustomTypeInstance (tp , arr )
103115
104116@as_var ("set-field!" )
@@ -114,3 +126,29 @@ def get_field(inst, field):
114126 affirm (isinstance (field , Keyword ), u"Field must be a keyword" )
115127 return inst .get_field (field )
116128
129+
130+
131+ class AbstractMutableCell (Object ):
132+ _type = Type (u"pixie.stdlib.AbstractMutableCell" )
133+ def type (self ):
134+ return self ._type
135+
136+ def set_mutable_cell_value (self , ct , fields , nm , idx , value ):
137+ pass
138+
139+ def get_mutable_cell_value (self ):
140+ pass
141+
142+ class IntegerMutableCell (AbstractMutableCell ):
143+ def __init__ (self , int_val ):
144+ self ._mutable_integer_val = int_val
145+
146+ def set_mutable_cell_value (self , ct , fields , nm , idx , value ):
147+ if not isinstance (value , Integer ):
148+ ct .set_mutable (nm )
149+ fields [idx ] = value
150+ else :
151+ self ._mutable_integer_val = value .int_val ()
152+
153+ def get_mutable_cell_value (self ):
154+ return rt .wrap (self ._mutable_integer_val )
0 commit comments