11from pixie .vm .object import Object , Type
22from pixie .vm .primitives import nil , true , false
3- from rpython .rlib .jit import elidable , promote
3+ import rpython .rlib .jit as jit
44from pixie .vm .numbers import Integer
55from rpython .rlib .rarithmetic import r_uint
6+ from pixie .vm .code import as_var
7+ from pixie .vm .symbol import Symbol
8+ from pixie .vm .string import String
9+ from pixie .vm .keyword import Keyword
10+ import pixie .vm .rt as rt
611
712class CustomType (Type ):
8- __immutable_fields__ = ["slots " ]
9- def __init__ (self , name , slots_s ):
13+ __immutable_fields__ = ["_slots " ]
14+ def __init__ (self , name , slots ):
1015 Type .__init__ (self , name )
11- slots = {}
12-
13- idx = 0
14- while slots_s is not nil :
15- slots [slots_s .first ()] = len (slots )
16- slots_s = slots_s .next ()
1716
1817 self ._slots = slots
1918
20- @elidable
19+ @jit . elidable_promote ()
2120 def get_slot_idx (self , nm ):
2221 return self ._slots [nm ]
2322
23+ @jit .elidable_promote ()
24+ def get_num_slots (self ):
25+ return len (self ._slots )
26+
2427class CustomTypeInstance (Object ):
2528 __immutable_fields__ = ["_type" ]
2629 def __init__ (self , type ):
2730 assert isinstance (type , CustomType )
2831 self ._type = type
29- self ._fields = [None ] * len (type ._slots )
32+ self ._fields = [None ] * self ._type .get_num_slots ()
33+
34+ def type (self ):
35+ return self ._type
3036
3137 def set_field (self , name , val ):
32- idx = promote ( self ._type .get_slot_idx (name ) )
38+ idx = self ._type .get_slot_idx (name )
3339 self ._fields [idx ] = val
3440 return self
3541
3642 def get_field (self , name ):
37- idx = promote ( self ._type .get_slot_idx (name ) )
43+ idx = self ._type .get_slot_idx (name )
3844 return self ._fields [idx ]
3945
4046 def set_field_by_idx (self , idx , val ):
@@ -43,5 +49,35 @@ def set_field_by_idx(self, idx, val):
4349 return self
4450
4551
52+ @as_var ("create-type" )
53+ def create_type (type_name , fields ):
54+ assert isinstance (type_name , Keyword ), "Type name must be a keyword"
55+
56+ field_count = rt .count (fields ).int_val ()
57+ acc = {}
58+ for i in range (rt .count (fields ).int_val ()):
59+ val = rt .nth (fields , Integer (i ))
60+ assert isinstance (val , Keyword ), "Field names must be keywords"
61+ acc [val ] = i
62+
63+
64+ return CustomType (type_name ._name , acc )
65+
66+ @as_var ("new" )
67+ def _new (tp ):
68+ assert isinstance (tp , CustomType ), "Can only create a new instance of a custom type"
69+ return CustomTypeInstance (tp )
70+
71+ @as_var ("set-field!" )
72+ def set_field (inst , field , val ):
73+ assert isinstance (inst , CustomTypeInstance ), "Can only set fields on CustomType instances"
74+ assert isinstance (field , Keyword ), "Field must be a keyword"
75+ inst .set_field (field , val )
76+ return inst
4677
78+ @as_var ("get-field" )
79+ def get_field (inst , field ):
80+ assert isinstance (inst , CustomTypeInstance ), "Can only get fields on CustomType instances"
81+ assert isinstance (field , Keyword ), "Field must be a keyword"
82+ return inst .get_field (field )
4783
0 commit comments