16
16
#include "objprivate.h"
17
17
#include "builtin.h"
18
18
19
+ py_obj_t py_builtin___build_class__ (py_obj_t o_class_fun , py_obj_t o_class_name ) {
20
+ // we differ from CPython: we set the new __locals__ object here
21
+ py_map_t * old_locals = rt_get_map_locals ();
22
+ py_map_t * class_locals = py_map_new (MAP_QSTR , 0 );
23
+ rt_set_map_locals (class_locals );
24
+
25
+ // call the class code
26
+ rt_call_function_1 (o_class_fun , (py_obj_t )0xdeadbeef );
27
+
28
+ // restore old __locals__ object
29
+ rt_set_map_locals (old_locals );
30
+
31
+ // create and return the new class
32
+ py_obj_base_t * o = m_new (py_obj_base_t , 1 );
33
+ o -> kind = O_CLASS ;
34
+ o -> u_class .locals = class_locals ;
35
+ return o ;
36
+ }
37
+
38
+ py_obj_t py_builtin___import__ (int n , py_obj_t * args ) {
39
+ printf ("import:\n" );
40
+ for (int i = 0 ; i < n ; i ++ ) {
41
+ printf (" " );
42
+ py_obj_print (args [i ]);
43
+ printf ("\n" );
44
+ }
45
+ return py_const_none ;
46
+ }
47
+
19
48
py_obj_t py_builtin___repl_print__ (py_obj_t o ) {
20
49
if (o != py_const_none ) {
21
50
py_obj_print (o );
@@ -24,21 +53,150 @@ py_obj_t py_builtin___repl_print__(py_obj_t o) {
24
53
return py_const_none ;
25
54
}
26
55
27
- py_obj_t py_builtin_print (int n_args , const py_obj_t * args ) {
28
- for (int i = 0 ; i < n_args ; i ++ ) {
29
- if (i > 0 ) {
30
- printf (" " );
56
+ py_obj_t py_builtin_abs (py_obj_t o_in ) {
57
+ if (IS_SMALL_INT (o_in )) {
58
+ py_small_int_t val = FROM_SMALL_INT (o_in );
59
+ if (val < 0 ) {
60
+ val = - val ;
31
61
}
32
- if (IS_O (args [i ], O_STR )) {
33
- // special case, print string raw
34
- printf ("%s" , qstr_str (((py_obj_base_t * )args [i ])-> u_str ));
62
+ return TO_SMALL_INT (val );
63
+ #if MICROPY_ENABLE_FLOAT
64
+ } else if (IS_O (o_in , O_FLOAT )) {
65
+ py_obj_base_t * o = o_in ;
66
+ // TODO check for NaN etc
67
+ if (o -> u_float < 0 ) {
68
+ return py_obj_new_float (- o -> u_float );
35
69
} else {
36
- // print the object Python style
37
- py_obj_print (args [i ]);
70
+ return o_in ;
38
71
}
72
+ } else if (IS_O (o_in , O_COMPLEX )) {
73
+ py_obj_base_t * o = o_in ;
74
+ return py_obj_new_float (machine_sqrt (o -> u_complex .real * o -> u_complex .real + o -> u_complex .imag * o -> u_complex .imag ));
75
+ #endif
76
+ } else {
77
+ assert (0 );
78
+ return py_const_none ;
79
+ }
80
+ }
81
+
82
+ py_obj_t py_builtin_all (py_obj_t o_in ) {
83
+ py_obj_t iterable = rt_getiter (o_in );
84
+ py_obj_t item ;
85
+ while ((item = rt_iternext (iterable )) != py_const_stop_iteration ) {
86
+ if (!rt_is_true (item )) {
87
+ return py_const_false ;
88
+ }
89
+ }
90
+ return py_const_true ;
91
+ }
92
+
93
+ py_obj_t py_builtin_any (py_obj_t o_in ) {
94
+ py_obj_t iterable = rt_getiter (o_in );
95
+ py_obj_t item ;
96
+ while ((item = rt_iternext (iterable )) != py_const_stop_iteration ) {
97
+ if (rt_is_true (item )) {
98
+ return py_const_true ;
99
+ }
100
+ }
101
+ return py_const_false ;
102
+ }
103
+
104
+ py_obj_t py_builtin_bool (int n_args , const py_obj_t * args ) {
105
+ switch (n_args ) {
106
+ case 0 : return py_const_false ;
107
+ case 1 : if (rt_is_true (args [0 ])) { return py_const_true ; } else { return py_const_false ; }
108
+ default : nlr_jump (py_obj_new_exception_2 (rt_q_TypeError , "bool() takes at most 1 argument (%d given)" , (void * )(machine_int_t )n_args , NULL ));
109
+ }
110
+ }
111
+
112
+ py_obj_t py_builtin_callable (py_obj_t o_in ) {
113
+ if (py_obj_is_callable (o_in )) {
114
+ return py_const_true ;
115
+ } else {
116
+ return py_const_false ;
117
+ }
118
+ }
119
+
120
+ #if MICROPY_ENABLE_FLOAT
121
+ py_obj_t py_builtin_complex (int n_args , const py_obj_t * args ) {
122
+ switch (n_args ) {
123
+ case 0 :
124
+ return py_obj_new_complex (0 , 0 );
125
+
126
+ case 1 :
127
+ // TODO allow string as first arg
128
+ if (IS_O (args [0 ], O_COMPLEX )) {
129
+ return args [0 ];
130
+ } else {
131
+ return py_obj_new_complex (py_obj_get_float (args [0 ]), 0 );
132
+ }
133
+
134
+ case 2 :
135
+ {
136
+ py_float_t real , imag ;
137
+ if (IS_O (args [0 ], O_COMPLEX )) {
138
+ py_obj_get_complex (args [0 ], & real , & imag );
139
+ } else {
140
+ real = py_obj_get_float (args [0 ]);
141
+ imag = 0 ;
142
+ }
143
+ if (IS_O (args [1 ], O_COMPLEX )) {
144
+ py_float_t real2 , imag2 ;
145
+ py_obj_get_complex (args [1 ], & real2 , & imag2 );
146
+ real -= imag2 ;
147
+ imag += real2 ;
148
+ } else {
149
+ imag += py_obj_get_float (args [1 ]);
150
+ }
151
+ return py_obj_new_complex (real , imag );
152
+ }
153
+
154
+ default : nlr_jump (py_obj_new_exception_2 (rt_q_TypeError , "comlpex() takes at most 2 arguments (%d given)" , (void * )(machine_int_t )n_args , NULL ));
155
+ }
156
+ }
157
+ #endif
158
+
159
+ py_obj_t py_builtin_chr (py_obj_t o_in ) {
160
+ int ord = py_obj_get_int (o_in );
161
+ if (0 <= ord && ord <= 0x10ffff ) {
162
+ char * str = m_new (char , 2 );
163
+ str [0 ] = ord ;
164
+ str [1 ] = '\0' ;
165
+ return py_obj_new_str (qstr_from_str_take (str ));
166
+ } else {
167
+ nlr_jump (py_obj_new_exception_2 (rt_q_ValueError , "chr() arg not in range(0x110000)" , NULL , NULL ));
39
168
}
40
- printf ("\n" );
41
- return py_const_none ;
169
+ }
170
+
171
+ py_obj_t py_builtin_dict (void ) {
172
+ // TODO create from an iterable!
173
+ return rt_build_map (0 );
174
+ }
175
+
176
+ py_obj_t py_builtin_divmod (py_obj_t o1_in , py_obj_t o2_in ) {
177
+ if (IS_SMALL_INT (o1_in ) && IS_SMALL_INT (o2_in )) {
178
+ py_small_int_t i1 = FROM_SMALL_INT (o1_in );
179
+ py_small_int_t i2 = FROM_SMALL_INT (o2_in );
180
+ py_obj_t revs_args [2 ];
181
+ revs_args [1 ] = TO_SMALL_INT (i1 / i2 );
182
+ revs_args [0 ] = TO_SMALL_INT (i1 % i2 );
183
+ return rt_build_tuple (2 , revs_args );
184
+ } else {
185
+ nlr_jump (py_obj_new_exception_2 (rt_q_TypeError , "unsupported operand type(s) for divmod(): '%s' and '%s'" , py_obj_get_type_str (o1_in ), py_obj_get_type_str (o2_in )));
186
+ }
187
+ }
188
+
189
+ py_obj_t py_builtin_hash (py_obj_t o_in ) {
190
+ // TODO hash will generally overflow small integer; can we safely truncate it?
191
+ return py_obj_new_int (py_obj_hash (o_in ));
192
+ }
193
+
194
+ py_obj_t py_builtin_iter (py_obj_t o_in ) {
195
+ return rt_getiter (o_in );
196
+ }
197
+
198
+ py_obj_t py_builtin_next (py_obj_t o_in ) {
199
+ return rt_gen_instance_next (o_in );
42
200
}
43
201
44
202
py_obj_t py_builtin_len (py_obj_t o_in ) {
@@ -53,61 +211,137 @@ py_obj_t py_builtin_len(py_obj_t o_in) {
53
211
py_obj_base_t * o = o_in ;
54
212
len = o -> u_map .used ;
55
213
} else {
56
- assert ( 0 );
214
+ nlr_jump ( py_obj_new_exception_2 ( rt_q_TypeError , "object of type '%s' has no len()" , py_obj_get_type_str ( o_in ), NULL ) );
57
215
}
58
216
return TO_SMALL_INT (len );
59
217
}
60
218
61
- py_obj_t py_builtin_abs (py_obj_t o_in ) {
62
- if (IS_SMALL_INT (o_in )) {
63
- py_small_int_t val = FROM_SMALL_INT (o_in );
64
- if (val < 0 ) {
65
- val = - val ;
219
+ py_obj_t py_builtin_list (int n_args , const py_obj_t * args ) {
220
+ switch (n_args ) {
221
+ case 0 : return rt_build_list (0 , NULL );
222
+ case 1 :
223
+ {
224
+ // make list from iterable
225
+ py_obj_t iterable = rt_getiter (args [0 ]);
226
+ py_obj_t list = rt_build_list (0 , NULL );
227
+ py_obj_t item ;
228
+ while ((item = rt_iternext (iterable )) != py_const_stop_iteration ) {
229
+ rt_list_append (list , item );
230
+ }
231
+ return list ;
66
232
}
67
- return TO_SMALL_INT (val );
68
- #if MICROPY_ENABLE_FLOAT
69
- } else if (IS_O (o_in , O_FLOAT )) {
70
- py_obj_base_t * o = o_in ;
71
- // TODO check for NaN etc
72
- if (o -> u_float < 0 ) {
73
- return py_obj_new_float (- o -> u_float );
74
- } else {
75
- return o_in ;
233
+ default : nlr_jump (py_obj_new_exception_2 (rt_q_TypeError , "list() takes at most 1 argument (%d given)" , (void * )(machine_int_t )n_args , NULL ));
234
+ }
235
+ }
236
+
237
+ py_obj_t py_builtin_max (int n_args , const py_obj_t * args ) {
238
+ if (n_args == 1 ) {
239
+ // given an iterable
240
+ py_obj_t iterable = rt_getiter (args [0 ]);
241
+ py_obj_t max_obj = NULL ;
242
+ py_obj_t item ;
243
+ while ((item = rt_iternext (iterable )) != py_const_stop_iteration ) {
244
+ if (max_obj == NULL || py_obj_less (max_obj , item )) {
245
+ max_obj = item ;
246
+ }
76
247
}
77
- } else if (IS_O ( o_in , O_COMPLEX ) ) {
78
- py_obj_base_t * o = o_in ;
79
- return py_obj_new_float ( machine_sqrt ( o -> u_complex . real * o -> u_complex . real + o -> u_complex . imag * o -> u_complex . imag ));
80
- #endif
248
+ if (max_obj == NULL ) {
249
+ nlr_jump ( py_obj_new_exception_2 ( rt_q_ValueError , "max() arg is an empty sequence" , NULL , NULL )) ;
250
+ }
251
+ return max_obj ;
81
252
} else {
82
- assert (0 );
83
- return py_const_none ;
253
+ // given many args
254
+ py_obj_t max_obj = args [0 ];
255
+ for (int i = 1 ; i < n_args ; i ++ ) {
256
+ if (py_obj_less (max_obj , args [i ])) {
257
+ max_obj = args [i ];
258
+ }
259
+ }
260
+ return max_obj ;
84
261
}
85
262
}
86
263
87
- py_obj_t py_builtin___build_class__ (py_obj_t o_class_fun , py_obj_t o_class_name ) {
88
- // we differ from CPython: we set the new __locals__ object here
89
- py_map_t * old_locals = rt_get_map_locals ();
90
- py_map_t * class_locals = py_map_new (MAP_QSTR , 0 );
91
- rt_set_map_locals (class_locals );
264
+ py_obj_t py_builtin_min (int n_args , const py_obj_t * args ) {
265
+ if (n_args == 1 ) {
266
+ // given an iterable
267
+ py_obj_t iterable = rt_getiter (args [0 ]);
268
+ py_obj_t min_obj = NULL ;
269
+ py_obj_t item ;
270
+ while ((item = rt_iternext (iterable )) != py_const_stop_iteration ) {
271
+ if (min_obj == NULL || py_obj_less (item , min_obj )) {
272
+ min_obj = item ;
273
+ }
274
+ }
275
+ if (min_obj == NULL ) {
276
+ nlr_jump (py_obj_new_exception_2 (rt_q_ValueError , "min() arg is an empty sequence" , NULL , NULL ));
277
+ }
278
+ return min_obj ;
279
+ } else {
280
+ // given many args
281
+ py_obj_t min_obj = args [0 ];
282
+ for (int i = 1 ; i < n_args ; i ++ ) {
283
+ if (py_obj_less (args [i ], min_obj )) {
284
+ min_obj = args [i ];
285
+ }
286
+ }
287
+ return min_obj ;
288
+ }
289
+ }
92
290
93
- // call the class code
94
- rt_call_function_1 (o_class_fun , (py_obj_t )0xdeadbeef );
291
+ py_obj_t py_builtin_ord (py_obj_t o_in ) {
292
+ const char * str = qstr_str (py_obj_get_qstr (o_in ));
293
+ if (strlen (str ) == 1 ) {
294
+ return py_obj_new_int (str [0 ]);
295
+ } else {
296
+ nlr_jump (py_obj_new_exception_2 (rt_q_TypeError , "ord() expected a character, but string of length %d found" , (void * )(machine_int_t )strlen (str ), NULL ));
297
+ }
298
+ }
95
299
96
- // restore old __locals__ object
97
- rt_set_map_locals (old_locals );
300
+ py_obj_t py_builtin_pow (int n_args , const py_obj_t * args ) {
301
+ switch (n_args ) {
302
+ case 2 : return rt_binary_op (RT_BINARY_OP_POWER , args [0 ], args [1 ]);
303
+ case 3 : return rt_binary_op (RT_BINARY_OP_MODULO , rt_binary_op (RT_BINARY_OP_POWER , args [0 ], args [1 ]), args [2 ]); // TODO optimise...
304
+ default : nlr_jump (py_obj_new_exception_2 (rt_q_TypeError , "pow expected at most 3 arguments, got %d" , (void * )(machine_int_t )n_args , NULL ));
305
+ }
306
+ }
98
307
99
- // create and return the new class
100
- py_obj_base_t * o = m_new (py_obj_base_t , 1 );
101
- o -> kind = O_CLASS ;
102
- o -> u_class .locals = class_locals ;
103
- return o ;
308
+ py_obj_t py_builtin_print (int n_args , const py_obj_t * args ) {
309
+ for (int i = 0 ; i < n_args ; i ++ ) {
310
+ if (i > 0 ) {
311
+ printf (" " );
312
+ }
313
+ if (IS_O (args [i ], O_STR )) {
314
+ // special case, print string raw
315
+ printf ("%s" , qstr_str (((py_obj_base_t * )args [i ])-> u_str ));
316
+ } else {
317
+ // print the object Python style
318
+ py_obj_print (args [i ]);
319
+ }
320
+ }
321
+ printf ("\n" );
322
+ return py_const_none ;
104
323
}
105
324
106
- py_obj_t py_builtin_range (int n_args , const py_obj_t * args ) {
325
+ py_obj_t py_builtin_range (int n_args , const py_obj_t * args ) {
107
326
switch (n_args ) {
108
327
case 1 : return py_obj_new_range (0 , py_obj_get_int (args [0 ]), 1 );
109
328
case 2 : return py_obj_new_range (py_obj_get_int (args [0 ]), py_obj_get_int (args [1 ]), 1 );
110
329
case 3 : return py_obj_new_range (py_obj_get_int (args [0 ]), py_obj_get_int (args [1 ]), py_obj_get_int (args [2 ]));
111
330
default : nlr_jump (py_obj_new_exception_2 (rt_q_TypeError , "range expected at most 3 arguments, got %d" , (void * )(machine_int_t )n_args , NULL ));
112
331
}
113
332
}
333
+
334
+ py_obj_t py_builtin_sum (int n_args , const py_obj_t * args ) {
335
+ py_obj_t value ;
336
+ switch (n_args ) {
337
+ case 1 : value = py_obj_new_int (0 ); break ;
338
+ case 2 : value = args [1 ]; break ;
339
+ default : nlr_jump (py_obj_new_exception_2 (rt_q_TypeError , "sum expected at most 2 arguments, got %d" , (void * )(machine_int_t )n_args , NULL ));
340
+ }
341
+ py_obj_t iterable = rt_getiter (args [0 ]);
342
+ py_obj_t item ;
343
+ while ((item = rt_iternext (iterable )) != py_const_stop_iteration ) {
344
+ value = rt_binary_op (RT_BINARY_OP_ADD , value , item );
345
+ }
346
+ return value ;
347
+ }
0 commit comments