@@ -74,6 +74,18 @@ static mp_obj_t tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m
7474 }
7575}
7676
77+ // Don't pass RT_BINARY_OP_NOT_EQUAL here
78+ static bool tuple_cmp_helper (int op , mp_obj_t self_in , mp_obj_t another_in ) {
79+ assert (MP_OBJ_IS_TYPE (self_in , & tuple_type ));
80+ if (!MP_OBJ_IS_TYPE (another_in , & tuple_type )) {
81+ return false;
82+ }
83+ mp_obj_tuple_t * self = self_in ;
84+ mp_obj_tuple_t * another = another_in ;
85+
86+ return mp_seq_cmp_objs (op , self -> items , self -> len , another -> items , another -> len );
87+ }
88+
7789static mp_obj_t tuple_unary_op (int op , mp_obj_t self_in ) {
7890 mp_obj_tuple_t * self = self_in ;
7991 switch (op ) {
@@ -102,6 +114,35 @@ static mp_obj_t tuple_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
102114 uint index = mp_get_index (o -> base .type , o -> len , rhs );
103115 return o -> items [index ];
104116 }
117+ case RT_BINARY_OP_ADD :
118+ {
119+ if (!MP_OBJ_IS_TYPE (rhs , & tuple_type )) {
120+ return NULL ;
121+ }
122+ mp_obj_tuple_t * p = rhs ;
123+ mp_obj_tuple_t * s = mp_obj_new_tuple (o -> len + p -> len , NULL );
124+ m_seq_cat (s -> items , o -> items , o -> len , p -> items , p -> len , mp_obj_t );
125+ return s ;
126+ }
127+ case RT_BINARY_OP_MULTIPLY :
128+ {
129+ if (!MP_OBJ_IS_SMALL_INT (rhs )) {
130+ return NULL ;
131+ }
132+ int n = MP_OBJ_SMALL_INT_VALUE (rhs );
133+ mp_obj_tuple_t * s = mp_obj_new_tuple (o -> len * n , NULL );
134+ mp_seq_multiply (o -> items , sizeof (* o -> items ), o -> len , n , s -> items );
135+ return s ;
136+ }
137+ case RT_BINARY_OP_EQUAL :
138+ case RT_BINARY_OP_LESS :
139+ case RT_BINARY_OP_LESS_EQUAL :
140+ case RT_BINARY_OP_MORE :
141+ case RT_BINARY_OP_MORE_EQUAL :
142+ return MP_BOOL (tuple_cmp_helper (op , lhs , rhs ));
143+ case RT_BINARY_OP_NOT_EQUAL :
144+ return MP_BOOL (!tuple_cmp_helper (RT_BINARY_OP_EQUAL , lhs , rhs ));
145+
105146 default :
106147 // op not supported
107148 return NULL ;
@@ -112,6 +153,26 @@ static mp_obj_t tuple_getiter(mp_obj_t o_in) {
112153 return mp_obj_new_tuple_iterator (o_in , 0 );
113154}
114155
156+ static mp_obj_t tuple_count (mp_obj_t self_in , mp_obj_t value ) {
157+ assert (MP_OBJ_IS_TYPE (self_in , & tuple_type ));
158+ mp_obj_tuple_t * self = self_in ;
159+ return mp_seq_count_obj (self -> items , self -> len , value );
160+ }
161+ static MP_DEFINE_CONST_FUN_OBJ_2 (tuple_count_obj , tuple_count ) ;
162+
163+ static mp_obj_t tuple_index (uint n_args , const mp_obj_t * args ) {
164+ assert (MP_OBJ_IS_TYPE (args [0 ], & tuple_type ));
165+ mp_obj_tuple_t * self = args [0 ];
166+ return mp_seq_index_obj (self -> items , self -> len , n_args , args );
167+ }
168+ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (tuple_index_obj , 2 , 4 , tuple_index ) ;
169+
170+ static const mp_method_t tuple_type_methods [] = {
171+ { "count" , & tuple_count_obj },
172+ { "index" , & tuple_index_obj },
173+ { NULL , NULL }, // end-of-list sentinel
174+ };
175+
115176const mp_obj_type_t tuple_type = {
116177 { & mp_const_type },
117178 "tuple" ,
@@ -120,6 +181,7 @@ const mp_obj_type_t tuple_type = {
120181 .unary_op = tuple_unary_op ,
121182 .binary_op = tuple_binary_op ,
122183 .getiter = tuple_getiter ,
184+ .methods = tuple_type_methods ,
123185};
124186
125187// the zero-length tuple
0 commit comments