blob: 51cf3137bfddb744403474ce18ff9100aaa9abab [file] [log] [blame]
Damien George04b91472014-05-03 23:27:38 +01001/*
Alexander Steffen55f33242017-06-30 09:22:17 +02002 * This file is part of the MicroPython project, http://micropython.org/
Damien George04b91472014-05-03 23:27:38 +01003 *
4 * The MIT License (MIT)
5 *
6 * Copyright (c) 2013, 2014 Damien P. George
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
Damien660365e2013-12-17 18:27:24 +000027#include <stdio.h>
Damien660365e2013-12-17 18:27:24 +000028#include <assert.h>
29
Damien George51dfcb42015-01-01 20:27:54 +000030#include "py/smallint.h"
Damien George6837d462015-03-14 22:07:30 +000031#include "py/objint.h"
Damien George51dfcb42015-01-01 20:27:54 +000032#include "py/objstr.h"
Dave Hylands7281d952015-12-28 20:03:15 -080033#include "py/objtype.h"
Damien George51dfcb42015-01-01 20:27:54 +000034#include "py/runtime.h"
35#include "py/builtin.h"
36#include "py/stream.h"
Damien660365e2013-12-17 18:27:24 +000037
Damien Georgefb510b32014-06-01 13:32:54 +010038#if MICROPY_PY_BUILTINS_FLOAT
Damien George0c36da02014-03-08 15:24:39 +000039#include <math.h>
40#endif
41
Damien George2e2e4042015-03-19 00:21:29 +000042#if MICROPY_PY_IO
stijne50cff62015-04-09 12:27:15 +020043extern struct _mp_dummy_t mp_sys_stdout_obj; // type is irrelevant, just need pointer
Damien George2e2e4042015-03-19 00:21:29 +000044#endif
45
Damien Georgeb97669a2014-01-08 11:47:55 +000046// args[0] is function from class body
47// args[1] is class name
48// args[2:] are base objects
Angus Grattondecf8e62024-02-27 15:32:29 +110049static mp_obj_t mp_builtin___build_class__(size_t n_args, const mp_obj_t *args) {
Damien Georgeb97669a2014-01-08 11:47:55 +000050 assert(2 <= n_args);
51
Damien George7efc5b32014-04-05 22:36:42 +010052 // set the new classes __locals__ object
53 mp_obj_dict_t *old_locals = mp_locals_get();
Damien George062478e2014-01-09 20:57:50 +000054 mp_obj_t class_locals = mp_obj_new_dict(0);
Damien George999cedb2015-11-27 17:01:44 +000055 mp_locals_set(MP_OBJ_TO_PTR(class_locals));
Damiena3dcd9e2013-12-17 21:35:38 +000056
57 // call the class code
Damien George882b3632014-04-02 15:56:31 +010058 mp_obj_t cell = mp_call_function_0(args[0]);
Damiena3dcd9e2013-12-17 21:35:38 +000059
60 // restore old __locals__ object
Damien Georged17926d2014-03-30 13:35:08 +010061 mp_locals_set(old_locals);
Damiena3dcd9e2013-12-17 21:35:38 +000062
Damien Georgeb97669a2014-01-08 11:47:55 +000063 // get the class type (meta object) from the base objects
64 mp_obj_t meta;
65 if (n_args == 2) {
66 // no explicit bases, so use 'type'
Damien George999cedb2015-11-27 17:01:44 +000067 meta = MP_OBJ_FROM_PTR(&mp_type_type);
Damien Georgeb97669a2014-01-08 11:47:55 +000068 } else {
69 // use type of first base object
Damien George999cedb2015-11-27 17:01:44 +000070 meta = MP_OBJ_FROM_PTR(mp_obj_get_type(args[2]));
Damien Georgeb97669a2014-01-08 11:47:55 +000071 }
Damien Georgeb97669a2014-01-08 11:47:55 +000072
73 // TODO do proper metaclass resolution for multiple base objects
74
Damien Georgeb97669a2014-01-08 11:47:55 +000075 // create the new class using a call to the meta object
Damien Georgeb97669a2014-01-08 11:47:55 +000076 mp_obj_t meta_args[3];
Damien George20006db2014-01-18 14:10:48 +000077 meta_args[0] = args[1]; // class name
Damien Georgeb97669a2014-01-08 11:47:55 +000078 meta_args[1] = mp_obj_new_tuple(n_args - 2, args + 2); // tuple of bases
Damien George20006db2014-01-18 14:10:48 +000079 meta_args[2] = class_locals; // dict of members
Damien Georged17926d2014-03-30 13:35:08 +010080 mp_obj_t new_class = mp_call_function_n_kw(meta, 3, 0, meta_args);
Damien Georgeb97669a2014-01-08 11:47:55 +000081
Damien Georgeb1229ef2023-03-08 14:10:02 +110082 // store into cell if needed
Damien Georgeb97669a2014-01-08 11:47:55 +000083 if (cell != mp_const_none) {
84 mp_obj_cell_set(cell, new_class);
85 }
86
87 return new_class;
Damiena3dcd9e2013-12-17 21:35:38 +000088}
Damien Georgeb97669a2014-01-08 11:47:55 +000089MP_DEFINE_CONST_FUN_OBJ_VAR(mp_builtin___build_class___obj, 2, mp_builtin___build_class__);
90
Angus Grattondecf8e62024-02-27 15:32:29 +110091static mp_obj_t mp_builtin_abs(mp_obj_t o_in) {
Paul Sokolovsky9dce8232017-09-18 00:06:43 +030092 return mp_unary_op(MP_UNARY_OP_ABS, o_in);
Damien660365e2013-12-17 18:27:24 +000093}
Damien George23005372014-01-13 19:39:01 +000094MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_abs_obj, mp_builtin_abs);
95
Angus Grattondecf8e62024-02-27 15:32:29 +110096static mp_obj_t mp_builtin_all(mp_obj_t o_in) {
Damien Georgeae8d8672016-01-09 23:14:54 +000097 mp_obj_iter_buf_t iter_buf;
98 mp_obj_t iterable = mp_getiter(o_in, &iter_buf);
Damiend99b0522013-12-21 18:17:45 +000099 mp_obj_t item;
Damien Georgeea8d06c2014-04-17 23:19:36 +0100100 while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
Damien Georged17926d2014-03-30 13:35:08 +0100101 if (!mp_obj_is_true(item)) {
Damiend99b0522013-12-21 18:17:45 +0000102 return mp_const_false;
Damiena3dcd9e2013-12-17 21:35:38 +0000103 }
104 }
Damiend99b0522013-12-21 18:17:45 +0000105 return mp_const_true;
Damien660365e2013-12-17 18:27:24 +0000106}
Damien George23005372014-01-13 19:39:01 +0000107MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_all_obj, mp_builtin_all);
108
Angus Grattondecf8e62024-02-27 15:32:29 +1100109static mp_obj_t mp_builtin_any(mp_obj_t o_in) {
Damien Georgeae8d8672016-01-09 23:14:54 +0000110 mp_obj_iter_buf_t iter_buf;
111 mp_obj_t iterable = mp_getiter(o_in, &iter_buf);
Damiend99b0522013-12-21 18:17:45 +0000112 mp_obj_t item;
Damien Georgeea8d06c2014-04-17 23:19:36 +0100113 while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
Damien Georged17926d2014-03-30 13:35:08 +0100114 if (mp_obj_is_true(item)) {
Damiend99b0522013-12-21 18:17:45 +0000115 return mp_const_true;
Damiena3dcd9e2013-12-17 21:35:38 +0000116 }
117 }
Damiend99b0522013-12-21 18:17:45 +0000118 return mp_const_false;
Damiena3dcd9e2013-12-17 21:35:38 +0000119}
Damien George23005372014-01-13 19:39:01 +0000120MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_any_obj, mp_builtin_any);
121
Angus Grattondecf8e62024-02-27 15:32:29 +1100122static mp_obj_t mp_builtin_bin(mp_obj_t o_in) {
Damien George897fe0c2014-04-15 22:03:55 +0100123 mp_obj_t args[] = { MP_OBJ_NEW_QSTR(MP_QSTR__brace_open__colon__hash_b_brace_close_), o_in };
Paul Sokolovskyed3b20a2015-01-04 13:26:43 +0200124 return mp_obj_str_format(MP_ARRAY_SIZE(args), args, NULL);
Damien George897fe0c2014-04-15 22:03:55 +0100125}
Damien George897fe0c2014-04-15 22:03:55 +0100126MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_bin_obj, mp_builtin_bin);
127
Angus Grattondecf8e62024-02-27 15:32:29 +1100128static mp_obj_t mp_builtin_callable(mp_obj_t o_in) {
Damiend99b0522013-12-21 18:17:45 +0000129 if (mp_obj_is_callable(o_in)) {
130 return mp_const_true;
Damiena3dcd9e2013-12-17 21:35:38 +0000131 } else {
Damiend99b0522013-12-21 18:17:45 +0000132 return mp_const_false;
Damiena3dcd9e2013-12-17 21:35:38 +0000133 }
134}
Damien George23005372014-01-13 19:39:01 +0000135MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_callable_obj, mp_builtin_callable);
136
Angus Grattondecf8e62024-02-27 15:32:29 +1100137static mp_obj_t mp_builtin_chr(mp_obj_t o_in) {
Paul Sokolovsky42a52512014-06-13 02:39:37 +0300138 #if MICROPY_PY_BUILTINS_STR_UNICODE
Damien Georgec9aa58e2014-07-31 13:41:43 +0000139 mp_uint_t c = mp_obj_get_int(o_in);
Jeff Epler9c7067d2023-11-23 11:49:57 -0600140 if (c >= 0x110000) {
Jim Mussareddef76fe2020-03-02 22:35:22 +1100141 mp_raise_ValueError(MP_ERROR_TEXT("chr() arg not in range(0x110000)"));
Damiena3dcd9e2013-12-17 21:35:38 +0000142 }
Jeff Epler9c7067d2023-11-23 11:49:57 -0600143 VSTR_FIXED(buf, 4);
144 vstr_add_char(&buf, c);
145 return mp_obj_new_str_via_qstr(buf.buf, buf.len);
Paul Sokolovsky42a52512014-06-13 02:39:37 +0300146 #else
Damien George40f3c022014-07-03 13:25:24 +0100147 mp_int_t ord = mp_obj_get_int(o_in);
Damien George16677ce2015-01-28 14:07:11 +0000148 if (0 <= ord && ord <= 0xff) {
Damien George771dfb02018-02-07 16:10:42 +1100149 uint8_t str[1] = {ord};
Damien George69661f32020-02-27 15:36:53 +1100150 return mp_obj_new_str_via_qstr((char *)str, 1);
Paul Sokolovsky42a52512014-06-13 02:39:37 +0300151 } else {
Jim Mussareddef76fe2020-03-02 22:35:22 +1100152 mp_raise_ValueError(MP_ERROR_TEXT("chr() arg not in range(256)"));
Paul Sokolovsky42a52512014-06-13 02:39:37 +0300153 }
154 #endif
Damiena3dcd9e2013-12-17 21:35:38 +0000155}
Damien George23005372014-01-13 19:39:01 +0000156MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_chr_obj, mp_builtin_chr);
157
Angus Grattondecf8e62024-02-27 15:32:29 +1100158static mp_obj_t mp_builtin_dir(size_t n_args, const mp_obj_t *args) {
Damien George4acb2452014-02-02 22:07:44 +0000159 mp_obj_t dir = mp_obj_new_list(0, NULL);
Damien George98647e82018-02-15 18:12:27 +1100160 if (n_args == 0) {
161 // Make a list of names in the local namespace
162 mp_obj_dict_t *dict = mp_locals_get();
Damien George7bd10c12017-07-04 23:44:22 +1000163 for (size_t i = 0; i < dict->map.alloc; i++) {
Damien George054dd332019-01-30 21:57:29 +1100164 if (mp_map_slot_is_filled(&dict->map, i)) {
Damien George7efc5b32014-04-05 22:36:42 +0100165 mp_obj_list_append(dir, dict->map.table[i].key);
Damien Georgebadc9d42014-03-23 00:03:11 +0000166 }
167 }
Damien George98647e82018-02-15 18:12:27 +1100168 } else { // n_args == 1
169 // Make a list of names in the given object
170 // Implemented by probing all possible qstrs with mp_load_method_maybe
171 size_t nqstr = QSTR_TOTAL();
Damien Georgeeb888032018-05-09 16:15:02 +1000172 for (size_t i = MP_QSTR_ + 1; i < nqstr; ++i) {
Damien George98647e82018-02-15 18:12:27 +1100173 mp_obj_t dest[2];
Damien George29d28c22018-05-10 23:07:19 +1000174 mp_load_method_protected(args[0], i, dest, false);
Damien George98647e82018-02-15 18:12:27 +1100175 if (dest[0] != MP_OBJ_NULL) {
Damien George3678a6b2018-05-10 23:10:46 +1000176 #if MICROPY_PY_ALL_SPECIAL_METHODS
177 // Support for __dir__: see if we can dispatch to this special method
178 // This relies on MP_QSTR__dir__ being first after MP_QSTR_
179 if (i == MP_QSTR___dir__ && dest[1] != MP_OBJ_NULL) {
180 return mp_call_method_n_kw(0, 0, dest);
181 }
182 #endif
Damien George98647e82018-02-15 18:12:27 +1100183 mp_obj_list_append(dir, MP_OBJ_NEW_QSTR(i));
Dave Hylands7281d952015-12-28 20:03:15 -0800184 }
185 }
186 }
Damien George4acb2452014-02-02 22:07:44 +0000187 return dir;
188}
Damien George4acb2452014-02-02 22:07:44 +0000189MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_dir_obj, 0, 1, mp_builtin_dir);
190
Angus Grattondecf8e62024-02-27 15:32:29 +1100191static mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) {
Damien Georgec5029bc2015-06-13 22:00:10 +0100192 return mp_binary_op(MP_BINARY_OP_DIVMOD, o1_in, o2_in);
Damiena3dcd9e2013-12-17 21:35:38 +0000193}
Damien George23005372014-01-13 19:39:01 +0000194MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_divmod_obj, mp_builtin_divmod);
195
Angus Grattondecf8e62024-02-27 15:32:29 +1100196static mp_obj_t mp_builtin_hash(mp_obj_t o_in) {
Damien Georgec2a4e4e2015-05-11 12:25:19 +0000197 // result is guaranteed to be a (small) int
198 return mp_unary_op(MP_UNARY_OP_HASH, o_in);
Damiena3dcd9e2013-12-17 21:35:38 +0000199}
Damiend99b0522013-12-21 18:17:45 +0000200MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_hash_obj, mp_builtin_hash);
201
Angus Grattondecf8e62024-02-27 15:32:29 +1100202static mp_obj_t mp_builtin_hex(mp_obj_t o_in) {
Paul Sokolovsky93f29972018-09-16 07:23:53 +0300203 #if MICROPY_PY_BUILTINS_STR_OP_MODULO
Damien Georgeb013aea2014-04-15 12:50:21 +0100204 return mp_binary_op(MP_BINARY_OP_MODULO, MP_OBJ_NEW_QSTR(MP_QSTR__percent__hash_x), o_in);
Paul Sokolovsky93f29972018-09-16 07:23:53 +0300205 #else
206 mp_obj_t args[] = { MP_OBJ_NEW_QSTR(MP_QSTR__brace_open__colon__hash_x_brace_close_), o_in };
207 return mp_obj_str_format(MP_ARRAY_SIZE(args), args, NULL);
208 #endif
Damien George58051112014-04-15 12:42:52 +0100209}
Damien George58051112014-04-15 12:42:52 +0100210MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_hex_obj, mp_builtin_hex);
211
Damien Georgebc763022017-06-01 15:32:23 +1000212#if MICROPY_PY_BUILTINS_INPUT
213
214#include "py/mphal.h"
Damien George136369d2021-07-09 14:19:15 +1000215#include "shared/readline/readline.h"
Damien Georgebc763022017-06-01 15:32:23 +1000216
217// A port can define mp_hal_readline if they want to use a custom function here
218#ifndef mp_hal_readline
219#define mp_hal_readline readline
220#endif
221
Angus Grattondecf8e62024-02-27 15:32:29 +1100222static mp_obj_t mp_builtin_input(size_t n_args, const mp_obj_t *args) {
Damien Georgebc763022017-06-01 15:32:23 +1000223 if (n_args == 1) {
224 mp_obj_print(args[0], PRINT_STR);
225 }
226 vstr_t line;
227 vstr_init(&line, 16);
228 int ret = mp_hal_readline(&line, "");
229 if (ret == CHAR_CTRL_C) {
Damien George97eca382020-02-11 13:17:41 +1100230 mp_raise_type(&mp_type_KeyboardInterrupt);
Damien Georgebc763022017-06-01 15:32:23 +1000231 }
232 if (line.len == 0 && ret == CHAR_CTRL_D) {
Damien George97eca382020-02-11 13:17:41 +1100233 mp_raise_type(&mp_type_EOFError);
Damien Georgebc763022017-06-01 15:32:23 +1000234 }
Jim Mussared8a0ee5a2022-08-22 17:08:05 +1000235 return mp_obj_new_str_from_vstr(&line);
Damien Georgebc763022017-06-01 15:32:23 +1000236}
237MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_input_obj, 0, 1, mp_builtin_input);
238
239#endif
240
Angus Grattondecf8e62024-02-27 15:32:29 +1100241static mp_obj_t mp_builtin_iter(mp_obj_t o_in) {
Damien Georgeae8d8672016-01-09 23:14:54 +0000242 return mp_getiter(o_in, NULL);
Damiena3dcd9e2013-12-17 21:35:38 +0000243}
Damiend99b0522013-12-21 18:17:45 +0000244MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_iter_obj, mp_builtin_iter);
Damiena3dcd9e2013-12-17 21:35:38 +0000245
pohmelie354e6882015-12-07 15:35:48 +0300246#if MICROPY_PY_BUILTINS_MIN_MAX
247
Angus Grattondecf8e62024-02-27 15:32:29 +1100248static mp_obj_t mp_builtin_min_max(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs, mp_uint_t op) {
Damien George7310fd42014-08-24 19:14:09 +0100249 mp_map_elem_t *key_elem = mp_map_lookup(kwargs, MP_OBJ_NEW_QSTR(MP_QSTR_key), MP_MAP_LOOKUP);
pohmeliec6ee2732015-12-07 15:45:43 +0300250 mp_map_elem_t *default_elem;
Damien George7310fd42014-08-24 19:14:09 +0100251 mp_obj_t key_fn = key_elem == NULL ? MP_OBJ_NULL : key_elem->value;
Damiena3dcd9e2013-12-17 21:35:38 +0000252 if (n_args == 1) {
253 // given an iterable
Damien Georgeae8d8672016-01-09 23:14:54 +0000254 mp_obj_iter_buf_t iter_buf;
255 mp_obj_t iterable = mp_getiter(args[0], &iter_buf);
Damien George7310fd42014-08-24 19:14:09 +0100256 mp_obj_t best_key = MP_OBJ_NULL;
257 mp_obj_t best_obj = MP_OBJ_NULL;
Damiend99b0522013-12-21 18:17:45 +0000258 mp_obj_t item;
Damien Georgeea8d06c2014-04-17 23:19:36 +0100259 while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
Damien George7310fd42014-08-24 19:14:09 +0100260 mp_obj_t key = key_fn == MP_OBJ_NULL ? item : mp_call_function_1(key_fn, item);
261 if (best_obj == MP_OBJ_NULL || (mp_binary_op(op, key, best_key) == mp_const_true)) {
262 best_key = key;
263 best_obj = item;
Damiena3dcd9e2013-12-17 21:35:38 +0000264 }
265 }
Damien George7310fd42014-08-24 19:14:09 +0100266 if (best_obj == MP_OBJ_NULL) {
pohmeliec6ee2732015-12-07 15:45:43 +0300267 default_elem = mp_map_lookup(kwargs, MP_OBJ_NEW_QSTR(MP_QSTR_default), MP_MAP_LOOKUP);
268 if (default_elem != NULL) {
269 best_obj = default_elem->value;
270 } else {
Jim Mussareddef76fe2020-03-02 22:35:22 +1100271 mp_raise_ValueError(MP_ERROR_TEXT("arg is an empty sequence"));
pohmeliec6ee2732015-12-07 15:45:43 +0300272 }
Damiena3dcd9e2013-12-17 21:35:38 +0000273 }
Damien George7310fd42014-08-24 19:14:09 +0100274 return best_obj;
Damiena3dcd9e2013-12-17 21:35:38 +0000275 } else {
276 // given many args
Damien George7310fd42014-08-24 19:14:09 +0100277 mp_obj_t best_key = MP_OBJ_NULL;
278 mp_obj_t best_obj = MP_OBJ_NULL;
Damien George7bd10c12017-07-04 23:44:22 +1000279 for (size_t i = 0; i < n_args; i++) {
Damien George7310fd42014-08-24 19:14:09 +0100280 mp_obj_t key = key_fn == MP_OBJ_NULL ? args[i] : mp_call_function_1(key_fn, args[i]);
281 if (best_obj == MP_OBJ_NULL || (mp_binary_op(op, key, best_key) == mp_const_true)) {
282 best_key = key;
283 best_obj = args[i];
Damiena3dcd9e2013-12-17 21:35:38 +0000284 }
285 }
Damien George7310fd42014-08-24 19:14:09 +0100286 return best_obj;
Damiena3dcd9e2013-12-17 21:35:38 +0000287 }
288}
289
Angus Grattondecf8e62024-02-27 15:32:29 +1100290static mp_obj_t mp_builtin_max(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
Damien George7310fd42014-08-24 19:14:09 +0100291 return mp_builtin_min_max(n_args, args, kwargs, MP_BINARY_OP_MORE);
Damiena3dcd9e2013-12-17 21:35:38 +0000292}
Damien George7310fd42014-08-24 19:14:09 +0100293MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_max_obj, 1, mp_builtin_max);
Damiena3dcd9e2013-12-17 21:35:38 +0000294
Angus Grattondecf8e62024-02-27 15:32:29 +1100295static mp_obj_t mp_builtin_min(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
Damien George7310fd42014-08-24 19:14:09 +0100296 return mp_builtin_min_max(n_args, args, kwargs, MP_BINARY_OP_LESS);
297}
298MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_min_obj, 1, mp_builtin_min);
Damien George23005372014-01-13 19:39:01 +0000299
pohmelie354e6882015-12-07 15:35:48 +0300300#endif
301
stijn42863832019-01-03 15:19:42 +0100302#if MICROPY_PY_BUILTINS_NEXT2
Angus Grattondecf8e62024-02-27 15:32:29 +1100303static mp_obj_t mp_builtin_next(size_t n_args, const mp_obj_t *args) {
stijn42863832019-01-03 15:19:42 +0100304 if (n_args == 1) {
305 mp_obj_t ret = mp_iternext_allow_raise(args[0]);
306 if (ret == MP_OBJ_STOP_ITERATION) {
Damien Georgebb001252021-06-29 17:34:34 +1000307 mp_raise_StopIteration(MP_STATE_THREAD(stop_iteration_arg));
stijn42863832019-01-03 15:19:42 +0100308 } else {
309 return ret;
310 }
311 } else {
312 mp_obj_t ret = mp_iternext(args[0]);
313 return ret == MP_OBJ_STOP_ITERATION ? args[1] : ret;
314 }
315}
316MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_next_obj, 1, 2, mp_builtin_next);
317#else
Angus Grattondecf8e62024-02-27 15:32:29 +1100318static mp_obj_t mp_builtin_next(mp_obj_t o) {
Damien Georged17926d2014-03-30 13:35:08 +0100319 mp_obj_t ret = mp_iternext_allow_raise(o);
Damien Georgeea8d06c2014-04-17 23:19:36 +0100320 if (ret == MP_OBJ_STOP_ITERATION) {
Damien Georgebb001252021-06-29 17:34:34 +1000321 mp_raise_StopIteration(MP_STATE_THREAD(stop_iteration_arg));
Damiend9d62012013-12-21 18:38:03 +0000322 } else {
323 return ret;
324 }
Damiend99b0522013-12-21 18:17:45 +0000325}
Damiend99b0522013-12-21 18:17:45 +0000326MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_next_obj, mp_builtin_next);
stijn42863832019-01-03 15:19:42 +0100327#endif
Damiend99b0522013-12-21 18:17:45 +0000328
Angus Grattondecf8e62024-02-27 15:32:29 +1100329static mp_obj_t mp_builtin_oct(mp_obj_t o_in) {
Paul Sokolovsky93f29972018-09-16 07:23:53 +0300330 #if MICROPY_PY_BUILTINS_STR_OP_MODULO
Damien George897fe0c2014-04-15 22:03:55 +0100331 return mp_binary_op(MP_BINARY_OP_MODULO, MP_OBJ_NEW_QSTR(MP_QSTR__percent__hash_o), o_in);
Paul Sokolovsky93f29972018-09-16 07:23:53 +0300332 #else
333 mp_obj_t args[] = { MP_OBJ_NEW_QSTR(MP_QSTR__brace_open__colon__hash_o_brace_close_), o_in };
334 return mp_obj_str_format(MP_ARRAY_SIZE(args), args, NULL);
335 #endif
Damien George897fe0c2014-04-15 22:03:55 +0100336}
Damien George897fe0c2014-04-15 22:03:55 +0100337MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_oct_obj, mp_builtin_oct);
338
Angus Grattondecf8e62024-02-27 15:32:29 +1100339static mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
Damien George6b341072017-03-25 19:48:18 +1100340 size_t len;
Damien George69661f32020-02-27 15:36:53 +1100341 const byte *str = (const byte *)mp_obj_str_get_data(o_in, &len);
Paul Sokolovsky42a52512014-06-13 02:39:37 +0300342 #if MICROPY_PY_BUILTINS_STR_UNICODE
Damien Georgeeee1e882019-01-30 18:49:52 +1100343 if (mp_obj_is_str(o_in)) {
Damien Georgee98ff402018-02-14 18:27:14 +1100344 len = utf8_charlen(str, len);
Damien Georged8cbbca2015-04-19 12:26:46 +0100345 if (len == 1) {
Damien Georgee98ff402018-02-14 18:27:14 +1100346 return mp_obj_new_int(utf8_get_char(str));
Damien Georged8cbbca2015-04-19 12:26:46 +0100347 }
Damien George69da74e2017-10-11 11:25:20 +1100348 } else
349 #endif
350 {
351 // a bytes object, or a str without unicode support (don't sign extend the char)
Damien Georged8cbbca2015-04-19 12:26:46 +0100352 if (len == 1) {
Damien Georgee98ff402018-02-14 18:27:14 +1100353 return MP_OBJ_NEW_SMALL_INT(str[0]);
Chris Angelico9a1a4be2014-06-04 05:28:12 +1000354 }
Damiena3dcd9e2013-12-17 21:35:38 +0000355 }
Damien George1e9a92f2014-11-06 17:36:16 +0000356
Damien Georged4b706c2021-04-22 12:13:58 +1000357 #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
Jim Mussareddef76fe2020-03-02 22:35:22 +1100358 mp_raise_TypeError(MP_ERROR_TEXT("ord expects a character"));
Jim Mussareda9a745e2019-09-26 22:52:04 +1000359 #else
360 mp_raise_msg_varg(&mp_type_TypeError,
Jim Mussareddef76fe2020-03-02 22:35:22 +1100361 MP_ERROR_TEXT("ord() expected a character, but string of length %d found"), (int)len);
Jim Mussareda9a745e2019-09-26 22:52:04 +1000362 #endif
Damiena3dcd9e2013-12-17 21:35:38 +0000363}
Damien George23005372014-01-13 19:39:01 +0000364MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_ord_obj, mp_builtin_ord);
365
Angus Grattondecf8e62024-02-27 15:32:29 +1100366static mp_obj_t mp_builtin_pow(size_t n_args, const mp_obj_t *args) {
Damiena3dcd9e2013-12-17 21:35:38 +0000367 switch (n_args) {
Damien George69661f32020-02-27 15:36:53 +1100368 case 2:
369 return mp_binary_op(MP_BINARY_OP_POWER, args[0], args[1]);
Nicko van Somerendf0117c2017-02-01 16:41:22 -0700370 default:
Damien George69661f32020-02-27 15:36:53 +1100371 #if !MICROPY_PY_BUILTINS_POW3
Jim Mussareddef76fe2020-03-02 22:35:22 +1100372 mp_raise_NotImplementedError(MP_ERROR_TEXT("3-arg pow() not supported"));
Damien George69661f32020-02-27 15:36:53 +1100373 #elif MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_MPZ
Nicko van Somerendf0117c2017-02-01 16:41:22 -0700374 return mp_binary_op(MP_BINARY_OP_MODULO, mp_binary_op(MP_BINARY_OP_POWER, args[0], args[1]), args[2]);
Damien George69661f32020-02-27 15:36:53 +1100375 #else
Nicko van Somerendf0117c2017-02-01 16:41:22 -0700376 return mp_obj_int_pow3(args[0], args[1], args[2]);
Damien George69661f32020-02-27 15:36:53 +1100377 #endif
Damiena3dcd9e2013-12-17 21:35:38 +0000378 }
379}
Damien George23005372014-01-13 19:39:01 +0000380MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_pow_obj, 2, 3, mp_builtin_pow);
381
Angus Grattondecf8e62024-02-27 15:32:29 +1100382static mp_obj_t mp_builtin_print(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
Damien George58f00d72017-12-05 12:14:57 +1100383 enum { ARG_sep, ARG_end, ARG_file };
384 static const mp_arg_t allowed_args[] = {
385 { MP_QSTR_sep, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_QSTR(MP_QSTR__space_)} },
386 { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_QSTR(MP_QSTR__0x0a_)} },
387 #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES
388 { MP_QSTR_file, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_sys_stdout_obj)} },
389 #endif
390 };
Paul Sokolovskycb66f412014-07-13 23:07:42 +0300391
Damien George58f00d72017-12-05 12:14:57 +1100392 // parse args (a union is used to reduce the amount of C stack that is needed)
393 union {
394 mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
395 size_t len[2];
396 } u;
397 mp_arg_parse_all(0, NULL, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, u.args);
398
399 #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES
Damien George582b1902018-06-20 15:57:10 +1000400 mp_get_stream_raise(u.args[ARG_file].u_obj, MP_STREAM_OP_WRITE);
Damien George58f00d72017-12-05 12:14:57 +1100401 mp_print_t print = {MP_OBJ_TO_PTR(u.args[ARG_file].u_obj), mp_stream_write_adaptor};
Paul Sokolovskycb66f412014-07-13 23:07:42 +0300402 #endif
Damien George58f00d72017-12-05 12:14:57 +1100403
404 // extract the objects first because we are going to use the other part of the union
405 mp_obj_t sep = u.args[ARG_sep].u_obj;
406 mp_obj_t end = u.args[ARG_end].u_obj;
407 const char *sep_data = mp_obj_str_get_data(sep, &u.len[0]);
408 const char *end_data = mp_obj_str_get_data(end, &u.len[1]);
409
Damien George7bd10c12017-07-04 23:44:22 +1000410 for (size_t i = 0; i < n_args; i++) {
Damiena3dcd9e2013-12-17 21:35:38 +0000411 if (i > 0) {
Tom Collinsf06d0832017-01-12 16:08:51 -0800412 #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES
Damien George58f00d72017-12-05 12:14:57 +1100413 mp_stream_write_adaptor(print.data, sep_data, u.len[0]);
Paul Sokolovskycb66f412014-07-13 23:07:42 +0300414 #else
Damien George58f00d72017-12-05 12:14:57 +1100415 mp_print_strn(&mp_plat_print, sep_data, u.len[0], 0, 0, 0);
Paul Sokolovskycb66f412014-07-13 23:07:42 +0300416 #endif
Damiena3dcd9e2013-12-17 21:35:38 +0000417 }
Tom Collinsf06d0832017-01-12 16:08:51 -0800418 #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES
Damien George58f00d72017-12-05 12:14:57 +1100419 mp_obj_print_helper(&print, pos_args[i], PRINT_STR);
Paul Sokolovskycb66f412014-07-13 23:07:42 +0300420 #else
Damien George58f00d72017-12-05 12:14:57 +1100421 mp_obj_print_helper(&mp_plat_print, pos_args[i], PRINT_STR);
Paul Sokolovskycb66f412014-07-13 23:07:42 +0300422 #endif
Damiena3dcd9e2013-12-17 21:35:38 +0000423 }
Tom Collinsf06d0832017-01-12 16:08:51 -0800424 #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES
Damien George58f00d72017-12-05 12:14:57 +1100425 mp_stream_write_adaptor(print.data, end_data, u.len[1]);
Paul Sokolovskycb66f412014-07-13 23:07:42 +0300426 #else
Damien George58f00d72017-12-05 12:14:57 +1100427 mp_print_strn(&mp_plat_print, end_data, u.len[1], 0, 0, 0);
Paul Sokolovskycb66f412014-07-13 23:07:42 +0300428 #endif
Damiend99b0522013-12-21 18:17:45 +0000429 return mp_const_none;
Damiena3dcd9e2013-12-17 21:35:38 +0000430}
Damien George48815662014-04-02 10:34:44 +0100431MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_print_obj, 0, mp_builtin_print);
Damien George23005372014-01-13 19:39:01 +0000432
Angus Grattondecf8e62024-02-27 15:32:29 +1100433static mp_obj_t mp_builtin___repl_print__(mp_obj_t o) {
Paul Sokolovsky1eca3282014-11-26 21:17:16 +0200434 if (o != mp_const_none) {
Paul Sokolovsky37300902016-10-22 01:07:07 +0300435 mp_obj_print_helper(MP_PYTHON_PRINTER, o, PRINT_REPR);
436 mp_print_str(MP_PYTHON_PRINTER, "\n");
Damien George035a0a22015-10-12 21:49:03 +0100437 #if MICROPY_CAN_OVERRIDE_BUILTINS
Paul Sokolovskyb67d0982016-04-13 00:58:17 +0300438 // Set "_" special variable
Damien George035a0a22015-10-12 21:49:03 +0100439 mp_obj_t dest[2] = {MP_OBJ_SENTINEL, o};
Jim Mussareda52cd5b2021-07-14 17:14:16 +1000440 MP_OBJ_TYPE_GET_SLOT(&mp_type_module, attr)(MP_OBJ_FROM_PTR(&mp_module_builtins), MP_QSTR__, dest);
Damien George035a0a22015-10-12 21:49:03 +0100441 #endif
Paul Sokolovsky1eca3282014-11-26 21:17:16 +0200442 }
443 return mp_const_none;
444}
445MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin___repl_print___obj, mp_builtin___repl_print__);
446
Angus Grattondecf8e62024-02-27 15:32:29 +1100447static mp_obj_t mp_builtin_repr(mp_obj_t o_in) {
Damien George0b9ee862015-01-21 19:14:25 +0000448 vstr_t vstr;
Damien George7f9d1d62015-04-09 23:56:15 +0100449 mp_print_t print;
450 vstr_init_print(&vstr, 16, &print);
451 mp_obj_print_helper(&print, o_in, PRINT_REPR);
Jim Mussared3a910b12022-08-23 18:35:37 +1000452 return mp_obj_new_str_from_utf8_vstr(&vstr);
Damien Georgee2fb2ba2014-01-15 21:40:48 +0000453}
Damien Georgee2fb2ba2014-01-15 21:40:48 +0000454MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_repr_obj, mp_builtin_repr);
455
Angus Grattondecf8e62024-02-27 15:32:29 +1100456static mp_obj_t mp_builtin_round(size_t n_args, const mp_obj_t *args) {
Paul Sokolovskyfdaac1d2015-03-30 02:20:23 +0300457 mp_obj_t o_in = args[0];
Damien Georgeeee1e882019-01-30 18:49:52 +1100458 if (mp_obj_is_int(o_in)) {
Jan Klusacekb318ebf2018-01-09 22:47:35 +0100459 if (n_args <= 1) {
460 return o_in;
461 }
462
463 #if !MICROPY_PY_BUILTINS_ROUND_INT
464 mp_raise_NotImplementedError(NULL);
465 #else
466 mp_int_t num_dig = mp_obj_get_int(args[1]);
467 if (num_dig >= 0) {
468 return o_in;
469 }
470
471 mp_obj_t mult = mp_binary_op(MP_BINARY_OP_POWER, MP_OBJ_NEW_SMALL_INT(10), MP_OBJ_NEW_SMALL_INT(-num_dig));
Damien George69661f32020-02-27 15:36:53 +1100472 mp_obj_t half_mult = mp_binary_op(MP_BINARY_OP_FLOOR_DIVIDE, mult, MP_OBJ_NEW_SMALL_INT(2));
Jan Klusacekb318ebf2018-01-09 22:47:35 +0100473 mp_obj_t modulo = mp_binary_op(MP_BINARY_OP_MODULO, o_in, mult);
474 mp_obj_t rounded = mp_binary_op(MP_BINARY_OP_SUBTRACT, o_in, modulo);
475 if (mp_obj_is_true(mp_binary_op(MP_BINARY_OP_MORE, half_mult, modulo))) {
476 return rounded;
477 } else if (mp_obj_is_true(mp_binary_op(MP_BINARY_OP_MORE, modulo, half_mult))) {
478 return mp_binary_op(MP_BINARY_OP_ADD, rounded, mult);
479 } else {
480 // round to even number
481 mp_obj_t floor = mp_binary_op(MP_BINARY_OP_FLOOR_DIVIDE, o_in, mult);
482 if (mp_obj_is_true(mp_binary_op(MP_BINARY_OP_AND, floor, MP_OBJ_NEW_SMALL_INT(1)))) {
483 return mp_binary_op(MP_BINARY_OP_ADD, rounded, mult);
484 } else {
485 return rounded;
486 }
487 }
488 #endif
Damien George1559a972014-10-31 11:28:50 +0000489 }
Damien George69661f32020-02-27 15:36:53 +1100490 #if MICROPY_PY_BUILTINS_FLOAT
Damien Georged5cf5f72017-11-22 15:51:51 +1100491 mp_float_t val = mp_obj_get_float(o_in);
Paul Sokolovskyfdaac1d2015-03-30 02:20:23 +0300492 if (n_args > 1) {
Damien Georged5cf5f72017-11-22 15:51:51 +1100493 mp_int_t num_dig = mp_obj_get_int(args[1]);
stijn70affd92020-04-13 20:56:31 +0200494 mp_float_t mult = MICROPY_FLOAT_C_FUN(pow)(10, (mp_float_t)num_dig);
Sebastian Plamauer1e8ca3a2015-07-14 14:44:31 +0200495 // TODO may lead to overflow
Damien George125eae12017-03-24 10:40:25 +1100496 mp_float_t rounded = MICROPY_FLOAT_C_FUN(nearbyint)(val * mult) / mult;
Sebastian Plamauer1e8ca3a2015-07-14 14:44:31 +0200497 return mp_obj_new_float(rounded);
Paul Sokolovskyfdaac1d2015-03-30 02:20:23 +0300498 }
Damien George125eae12017-03-24 10:40:25 +1100499 mp_float_t rounded = MICROPY_FLOAT_C_FUN(nearbyint)(val);
Damien Georgec236ebf2017-03-24 10:55:50 +1100500 return mp_obj_new_int_from_float(rounded);
Damien George69661f32020-02-27 15:36:53 +1100501 #else
Damien George1559a972014-10-31 11:28:50 +0000502 mp_int_t r = mp_obj_get_int(o_in);
Damien George1559a972014-10-31 11:28:50 +0000503 return mp_obj_new_int(r);
Damien George69661f32020-02-27 15:36:53 +1100504 #endif
Damien George1559a972014-10-31 11:28:50 +0000505}
Paul Sokolovskyfdaac1d2015-03-30 02:20:23 +0300506MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_round_obj, 1, 2, mp_builtin_round);
Damien George1559a972014-10-31 11:28:50 +0000507
Angus Grattondecf8e62024-02-27 15:32:29 +1100508static mp_obj_t mp_builtin_sum(size_t n_args, const mp_obj_t *args) {
Damiend99b0522013-12-21 18:17:45 +0000509 mp_obj_t value;
Damiena3dcd9e2013-12-17 21:35:38 +0000510 switch (n_args) {
Damien George69661f32020-02-27 15:36:53 +1100511 case 1:
512 value = MP_OBJ_NEW_SMALL_INT(0);
513 break;
514 default:
515 value = args[1];
516 break;
Damiena3dcd9e2013-12-17 21:35:38 +0000517 }
Damien Georgeae8d8672016-01-09 23:14:54 +0000518 mp_obj_iter_buf_t iter_buf;
519 mp_obj_t iterable = mp_getiter(args[0], &iter_buf);
Damiend99b0522013-12-21 18:17:45 +0000520 mp_obj_t item;
Damien Georgeea8d06c2014-04-17 23:19:36 +0100521 while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
Damien Georged17926d2014-03-30 13:35:08 +0100522 value = mp_binary_op(MP_BINARY_OP_ADD, value, item);
Damiena3dcd9e2013-12-17 21:35:38 +0000523 }
524 return value;
525}
Damien George23005372014-01-13 19:39:01 +0000526MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_sum_obj, 1, 2, mp_builtin_sum);
John R. Lenton5c768392014-01-13 05:12:50 +0000527
Angus Grattondecf8e62024-02-27 15:32:29 +1100528static mp_obj_t mp_builtin_sorted(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
Damien George20006db2014-01-18 14:10:48 +0000529 if (n_args > 1) {
Jim Mussareddef76fe2020-03-02 22:35:22 +1100530 mp_raise_TypeError(MP_ERROR_TEXT("must use keyword argument for key function"));
John R. Lenton5c768392014-01-13 05:12:50 +0000531 }
Jim Mussared94beeab2022-09-17 00:31:23 +1000532 mp_obj_t self = mp_obj_list_make_new(&mp_type_list, 1, 0, args);
Damien George20006db2014-01-18 14:10:48 +0000533 mp_obj_list_sort(1, &self, kwargs);
John R. Lenton5c768392014-01-13 05:12:50 +0000534
535 return self;
536}
John R. Lenton88cb1e62014-01-13 19:55:18 +0000537MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj, 1, mp_builtin_sorted);
Paul Sokolovsky36c44992014-01-13 19:20:46 +0200538
Paul Sokolovsky36dd19a2014-04-06 02:12:03 +0300539// See mp_load_attr() if making any changes
Damien George0f120822017-08-02 13:42:34 +1000540static inline mp_obj_t mp_load_attr_default(mp_obj_t base, qstr attr, mp_obj_t defval) {
Paul Sokolovsky36dd19a2014-04-06 02:12:03 +0300541 mp_obj_t dest[2];
542 // use load_method, raising or not raising exception
Damien George203b1072020-05-29 10:28:38 +1000543 if (defval == MP_OBJ_NULL) {
544 mp_load_method(base, attr, dest);
545 } else {
546 mp_load_method_protected(base, attr, dest, false);
547 }
Paul Sokolovsky36dd19a2014-04-06 02:12:03 +0300548 if (dest[0] == MP_OBJ_NULL) {
549 return defval;
550 } else if (dest[1] == MP_OBJ_NULL) {
551 // load_method returned just a normal attribute
552 return dest[0];
553 } else {
554 // load_method returned a method, so build a bound method object
555 return mp_obj_new_bound_meth(dest[0], dest[1]);
556 }
557}
558
Angus Grattondecf8e62024-02-27 15:32:29 +1100559static mp_obj_t mp_builtin_getattr(size_t n_args, const mp_obj_t *args) {
Paul Sokolovskybfb7d6a2014-04-05 13:33:04 +0300560 mp_obj_t defval = MP_OBJ_NULL;
561 if (n_args > 2) {
562 defval = args[2];
563 }
stijnc1832fd2015-02-14 17:36:59 +0100564 return mp_load_attr_default(args[0], mp_obj_str_get_qstr(args[1]), defval);
Paul Sokolovskye9137b92014-03-26 23:35:13 +0200565}
Paul Sokolovskybfb7d6a2014-04-05 13:33:04 +0300566MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_getattr_obj, 2, 3, mp_builtin_getattr);
Paul Sokolovskycc0af3d2014-04-06 01:00:46 +0300567
Angus Grattondecf8e62024-02-27 15:32:29 +1100568static mp_obj_t mp_builtin_setattr(mp_obj_t base, mp_obj_t attr, mp_obj_t value) {
stijnc1832fd2015-02-14 17:36:59 +0100569 mp_store_attr(base, mp_obj_str_get_qstr(attr), value);
570 return mp_const_none;
571}
572MP_DEFINE_CONST_FUN_OBJ_3(mp_builtin_setattr_obj, mp_builtin_setattr);
573
Damien George5076e5c2016-10-24 13:50:03 +1100574#if MICROPY_CPYTHON_COMPAT
Angus Grattondecf8e62024-02-27 15:32:29 +1100575static mp_obj_t mp_builtin_delattr(mp_obj_t base, mp_obj_t attr) {
Damien George5076e5c2016-10-24 13:50:03 +1100576 return mp_builtin_setattr(base, attr, MP_OBJ_NULL);
577}
578MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_delattr_obj, mp_builtin_delattr);
579#endif
580
Angus Grattondecf8e62024-02-27 15:32:29 +1100581static mp_obj_t mp_builtin_hasattr(mp_obj_t object_in, mp_obj_t attr_in) {
Damien George0e3f29c2015-11-23 15:57:00 +0000582 qstr attr = mp_obj_str_get_qstr(attr_in);
Paul Sokolovskyff306662014-05-11 19:05:42 +0300583 mp_obj_t dest[2];
Damien George52986062018-05-10 23:03:30 +1000584 mp_load_method_protected(object_in, attr, dest, false);
Paul Sokolovsky1b586f32015-10-11 12:09:43 +0300585 return mp_obj_new_bool(dest[0] != MP_OBJ_NULL);
Paul Sokolovskyff306662014-05-11 19:05:42 +0300586}
Paul Sokolovskyff306662014-05-11 19:05:42 +0300587MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_hasattr_obj, mp_builtin_hasattr);
588
Angus Grattondecf8e62024-02-27 15:32:29 +1100589static mp_obj_t mp_builtin_globals(void) {
Damien George1b0aab62016-01-03 11:53:44 +0000590 return MP_OBJ_FROM_PTR(mp_globals_get());
591}
592MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_globals_obj, mp_builtin_globals);
593
Angus Grattondecf8e62024-02-27 15:32:29 +1100594static mp_obj_t mp_builtin_locals(void) {
Damien George1b0aab62016-01-03 11:53:44 +0000595 return MP_OBJ_FROM_PTR(mp_locals_get());
596}
597MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_locals_obj, mp_builtin_locals);
598
Damien George4c03b3a2014-08-12 18:33:40 +0100599// These are defined in terms of MicroPython API functions right away
Damien Georgec7687ad2014-08-22 21:48:30 +0100600MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_id_obj, mp_obj_id);
Damien George4c03b3a2014-08-12 18:33:40 +0100601MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_len_obj, mp_obj_len);
Damien George78d702c2014-12-09 16:19:48 +0000602
Angus Grattondecf8e62024-02-27 15:32:29 +1100603static const mp_rom_map_elem_t mp_module_builtins_globals_table[] = {
Damien George93c4a6a2016-09-21 10:52:53 +1000604 { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_builtins) },
605
Damien George78d702c2014-12-09 16:19:48 +0000606 // built-in core functions
Damien Georgecbf76742015-11-27 13:38:15 +0000607 { MP_ROM_QSTR(MP_QSTR___build_class__), MP_ROM_PTR(&mp_builtin___build_class___obj) },
608 { MP_ROM_QSTR(MP_QSTR___import__), MP_ROM_PTR(&mp_builtin___import___obj) },
609 { MP_ROM_QSTR(MP_QSTR___repl_print__), MP_ROM_PTR(&mp_builtin___repl_print___obj) },
Damien George78d702c2014-12-09 16:19:48 +0000610
611 // built-in types
Damien Georgecbf76742015-11-27 13:38:15 +0000612 { MP_ROM_QSTR(MP_QSTR_bool), MP_ROM_PTR(&mp_type_bool) },
613 { MP_ROM_QSTR(MP_QSTR_bytes), MP_ROM_PTR(&mp_type_bytes) },
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300614 #if MICROPY_PY_BUILTINS_BYTEARRAY
Damien Georgecbf76742015-11-27 13:38:15 +0000615 { MP_ROM_QSTR(MP_QSTR_bytearray), MP_ROM_PTR(&mp_type_bytearray) },
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300616 #endif
617 #if MICROPY_PY_BUILTINS_COMPLEX
Damien Georgecbf76742015-11-27 13:38:15 +0000618 { MP_ROM_QSTR(MP_QSTR_complex), MP_ROM_PTR(&mp_type_complex) },
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300619 #endif
Damien Georgecbf76742015-11-27 13:38:15 +0000620 { MP_ROM_QSTR(MP_QSTR_dict), MP_ROM_PTR(&mp_type_dict) },
Paul Sokolovskye2d44e32015-04-06 23:50:37 +0300621 #if MICROPY_PY_BUILTINS_ENUMERATE
Damien Georgecbf76742015-11-27 13:38:15 +0000622 { MP_ROM_QSTR(MP_QSTR_enumerate), MP_ROM_PTR(&mp_type_enumerate) },
Paul Sokolovskye2d44e32015-04-06 23:50:37 +0300623 #endif
Paul Sokolovsky22ff3972015-08-20 01:01:56 +0300624 #if MICROPY_PY_BUILTINS_FILTER
Damien Georgecbf76742015-11-27 13:38:15 +0000625 { MP_ROM_QSTR(MP_QSTR_filter), MP_ROM_PTR(&mp_type_filter) },
Paul Sokolovsky22ff3972015-08-20 01:01:56 +0300626 #endif
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300627 #if MICROPY_PY_BUILTINS_FLOAT
Damien Georgecbf76742015-11-27 13:38:15 +0000628 { MP_ROM_QSTR(MP_QSTR_float), MP_ROM_PTR(&mp_type_float) },
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300629 #endif
630 #if MICROPY_PY_BUILTINS_SET && MICROPY_PY_BUILTINS_FROZENSET
Damien Georgecbf76742015-11-27 13:38:15 +0000631 { MP_ROM_QSTR(MP_QSTR_frozenset), MP_ROM_PTR(&mp_type_frozenset) },
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300632 #endif
Damien Georgecbf76742015-11-27 13:38:15 +0000633 { MP_ROM_QSTR(MP_QSTR_int), MP_ROM_PTR(&mp_type_int) },
634 { MP_ROM_QSTR(MP_QSTR_list), MP_ROM_PTR(&mp_type_list) },
635 { MP_ROM_QSTR(MP_QSTR_map), MP_ROM_PTR(&mp_type_map) },
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300636 #if MICROPY_PY_BUILTINS_MEMORYVIEW
Damien Georgecbf76742015-11-27 13:38:15 +0000637 { MP_ROM_QSTR(MP_QSTR_memoryview), MP_ROM_PTR(&mp_type_memoryview) },
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300638 #endif
Damien Georgecbf76742015-11-27 13:38:15 +0000639 { MP_ROM_QSTR(MP_QSTR_object), MP_ROM_PTR(&mp_type_object) },
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300640 #if MICROPY_PY_BUILTINS_PROPERTY
Damien Georgecbf76742015-11-27 13:38:15 +0000641 { MP_ROM_QSTR(MP_QSTR_property), MP_ROM_PTR(&mp_type_property) },
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300642 #endif
Damien Georgecbf76742015-11-27 13:38:15 +0000643 { MP_ROM_QSTR(MP_QSTR_range), MP_ROM_PTR(&mp_type_range) },
Paul Sokolovsky282ca092015-04-07 00:16:51 +0300644 #if MICROPY_PY_BUILTINS_REVERSED
Damien Georgecbf76742015-11-27 13:38:15 +0000645 { MP_ROM_QSTR(MP_QSTR_reversed), MP_ROM_PTR(&mp_type_reversed) },
Paul Sokolovsky282ca092015-04-07 00:16:51 +0300646 #endif
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300647 #if MICROPY_PY_BUILTINS_SET
Damien Georgecbf76742015-11-27 13:38:15 +0000648 { MP_ROM_QSTR(MP_QSTR_set), MP_ROM_PTR(&mp_type_set) },
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300649 #endif
Damien Georgebdb0d2d2016-10-22 14:30:01 +1100650 #if MICROPY_PY_BUILTINS_SLICE
651 { MP_ROM_QSTR(MP_QSTR_slice), MP_ROM_PTR(&mp_type_slice) },
652 #endif
Damien Georgecbf76742015-11-27 13:38:15 +0000653 { MP_ROM_QSTR(MP_QSTR_str), MP_ROM_PTR(&mp_type_str) },
654 { MP_ROM_QSTR(MP_QSTR_super), MP_ROM_PTR(&mp_type_super) },
655 { MP_ROM_QSTR(MP_QSTR_tuple), MP_ROM_PTR(&mp_type_tuple) },
656 { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&mp_type_type) },
657 { MP_ROM_QSTR(MP_QSTR_zip), MP_ROM_PTR(&mp_type_zip) },
Damien George78d702c2014-12-09 16:19:48 +0000658
Damien Georgecbf76742015-11-27 13:38:15 +0000659 { MP_ROM_QSTR(MP_QSTR_classmethod), MP_ROM_PTR(&mp_type_classmethod) },
660 { MP_ROM_QSTR(MP_QSTR_staticmethod), MP_ROM_PTR(&mp_type_staticmethod) },
Damien George78d702c2014-12-09 16:19:48 +0000661
662 // built-in objects
Damien Georgecbf76742015-11-27 13:38:15 +0000663 { MP_ROM_QSTR(MP_QSTR_Ellipsis), MP_ROM_PTR(&mp_const_ellipsis_obj) },
Paul Sokolovsky5ab5ac52015-05-04 19:45:53 +0300664 #if MICROPY_PY_BUILTINS_NOTIMPLEMENTED
Damien Georgecbf76742015-11-27 13:38:15 +0000665 { MP_ROM_QSTR(MP_QSTR_NotImplemented), MP_ROM_PTR(&mp_const_notimplemented_obj) },
Paul Sokolovsky5ab5ac52015-05-04 19:45:53 +0300666 #endif
Damien George78d702c2014-12-09 16:19:48 +0000667
668 // built-in user functions
Damien Georgecbf76742015-11-27 13:38:15 +0000669 { MP_ROM_QSTR(MP_QSTR_abs), MP_ROM_PTR(&mp_builtin_abs_obj) },
670 { MP_ROM_QSTR(MP_QSTR_all), MP_ROM_PTR(&mp_builtin_all_obj) },
671 { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&mp_builtin_any_obj) },
672 { MP_ROM_QSTR(MP_QSTR_bin), MP_ROM_PTR(&mp_builtin_bin_obj) },
673 { MP_ROM_QSTR(MP_QSTR_callable), MP_ROM_PTR(&mp_builtin_callable_obj) },
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300674 #if MICROPY_PY_BUILTINS_COMPILE
Damien Georgecbf76742015-11-27 13:38:15 +0000675 { MP_ROM_QSTR(MP_QSTR_compile), MP_ROM_PTR(&mp_builtin_compile_obj) },
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300676 #endif
Damien Georgecbf76742015-11-27 13:38:15 +0000677 { MP_ROM_QSTR(MP_QSTR_chr), MP_ROM_PTR(&mp_builtin_chr_obj) },
Damien George5076e5c2016-10-24 13:50:03 +1100678 #if MICROPY_CPYTHON_COMPAT
679 { MP_ROM_QSTR(MP_QSTR_delattr), MP_ROM_PTR(&mp_builtin_delattr_obj) },
680 #endif
Damien Georgecbf76742015-11-27 13:38:15 +0000681 { MP_ROM_QSTR(MP_QSTR_dir), MP_ROM_PTR(&mp_builtin_dir_obj) },
682 { MP_ROM_QSTR(MP_QSTR_divmod), MP_ROM_PTR(&mp_builtin_divmod_obj) },
Damien Georgedd5353a2015-12-18 12:35:44 +0000683 #if MICROPY_PY_BUILTINS_EVAL_EXEC
Damien Georgecbf76742015-11-27 13:38:15 +0000684 { MP_ROM_QSTR(MP_QSTR_eval), MP_ROM_PTR(&mp_builtin_eval_obj) },
685 { MP_ROM_QSTR(MP_QSTR_exec), MP_ROM_PTR(&mp_builtin_exec_obj) },
Damien Georgedd5353a2015-12-18 12:35:44 +0000686 #endif
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300687 #if MICROPY_PY_BUILTINS_EXECFILE
Damien Georgecbf76742015-11-27 13:38:15 +0000688 { MP_ROM_QSTR(MP_QSTR_execfile), MP_ROM_PTR(&mp_builtin_execfile_obj) },
Paul Sokolovsky21ffa7c2015-08-31 00:22:11 +0300689 #endif
Damien Georgecbf76742015-11-27 13:38:15 +0000690 { MP_ROM_QSTR(MP_QSTR_getattr), MP_ROM_PTR(&mp_builtin_getattr_obj) },
691 { MP_ROM_QSTR(MP_QSTR_setattr), MP_ROM_PTR(&mp_builtin_setattr_obj) },
692 { MP_ROM_QSTR(MP_QSTR_globals), MP_ROM_PTR(&mp_builtin_globals_obj) },
693 { MP_ROM_QSTR(MP_QSTR_hasattr), MP_ROM_PTR(&mp_builtin_hasattr_obj) },
694 { MP_ROM_QSTR(MP_QSTR_hash), MP_ROM_PTR(&mp_builtin_hash_obj) },
Damien George9f04dfb2017-01-21 23:17:51 +1100695 #if MICROPY_PY_BUILTINS_HELP
696 { MP_ROM_QSTR(MP_QSTR_help), MP_ROM_PTR(&mp_builtin_help_obj) },
697 #endif
Damien Georgecbf76742015-11-27 13:38:15 +0000698 { MP_ROM_QSTR(MP_QSTR_hex), MP_ROM_PTR(&mp_builtin_hex_obj) },
699 { MP_ROM_QSTR(MP_QSTR_id), MP_ROM_PTR(&mp_builtin_id_obj) },
Damien Georgebc763022017-06-01 15:32:23 +1000700 #if MICROPY_PY_BUILTINS_INPUT
701 { MP_ROM_QSTR(MP_QSTR_input), MP_ROM_PTR(&mp_builtin_input_obj) },
702 #endif
Damien Georgecbf76742015-11-27 13:38:15 +0000703 { MP_ROM_QSTR(MP_QSTR_isinstance), MP_ROM_PTR(&mp_builtin_isinstance_obj) },
704 { MP_ROM_QSTR(MP_QSTR_issubclass), MP_ROM_PTR(&mp_builtin_issubclass_obj) },
705 { MP_ROM_QSTR(MP_QSTR_iter), MP_ROM_PTR(&mp_builtin_iter_obj) },
706 { MP_ROM_QSTR(MP_QSTR_len), MP_ROM_PTR(&mp_builtin_len_obj) },
707 { MP_ROM_QSTR(MP_QSTR_locals), MP_ROM_PTR(&mp_builtin_locals_obj) },
pohmelie354e6882015-12-07 15:35:48 +0300708 #if MICROPY_PY_BUILTINS_MIN_MAX
Damien Georgecbf76742015-11-27 13:38:15 +0000709 { MP_ROM_QSTR(MP_QSTR_max), MP_ROM_PTR(&mp_builtin_max_obj) },
710 { MP_ROM_QSTR(MP_QSTR_min), MP_ROM_PTR(&mp_builtin_min_obj) },
pohmelie354e6882015-12-07 15:35:48 +0300711 #endif
Damien Georgecbf76742015-11-27 13:38:15 +0000712 { MP_ROM_QSTR(MP_QSTR_next), MP_ROM_PTR(&mp_builtin_next_obj) },
713 { MP_ROM_QSTR(MP_QSTR_oct), MP_ROM_PTR(&mp_builtin_oct_obj) },
Damien George59564662022-05-25 12:04:27 +1000714 #if MICROPY_PY_IO
715 { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mp_builtin_open_obj) },
716 #endif
Damien Georgecbf76742015-11-27 13:38:15 +0000717 { MP_ROM_QSTR(MP_QSTR_ord), MP_ROM_PTR(&mp_builtin_ord_obj) },
718 { MP_ROM_QSTR(MP_QSTR_pow), MP_ROM_PTR(&mp_builtin_pow_obj) },
719 { MP_ROM_QSTR(MP_QSTR_print), MP_ROM_PTR(&mp_builtin_print_obj) },
720 { MP_ROM_QSTR(MP_QSTR_repr), MP_ROM_PTR(&mp_builtin_repr_obj) },
721 { MP_ROM_QSTR(MP_QSTR_round), MP_ROM_PTR(&mp_builtin_round_obj) },
722 { MP_ROM_QSTR(MP_QSTR_sorted), MP_ROM_PTR(&mp_builtin_sorted_obj) },
723 { MP_ROM_QSTR(MP_QSTR_sum), MP_ROM_PTR(&mp_builtin_sum_obj) },
Damien George78d702c2014-12-09 16:19:48 +0000724
725 // built-in exceptions
Damien Georgecbf76742015-11-27 13:38:15 +0000726 { MP_ROM_QSTR(MP_QSTR_BaseException), MP_ROM_PTR(&mp_type_BaseException) },
727 { MP_ROM_QSTR(MP_QSTR_ArithmeticError), MP_ROM_PTR(&mp_type_ArithmeticError) },
728 { MP_ROM_QSTR(MP_QSTR_AssertionError), MP_ROM_PTR(&mp_type_AssertionError) },
729 { MP_ROM_QSTR(MP_QSTR_AttributeError), MP_ROM_PTR(&mp_type_AttributeError) },
730 { MP_ROM_QSTR(MP_QSTR_EOFError), MP_ROM_PTR(&mp_type_EOFError) },
731 { MP_ROM_QSTR(MP_QSTR_Exception), MP_ROM_PTR(&mp_type_Exception) },
732 { MP_ROM_QSTR(MP_QSTR_GeneratorExit), MP_ROM_PTR(&mp_type_GeneratorExit) },
733 { MP_ROM_QSTR(MP_QSTR_ImportError), MP_ROM_PTR(&mp_type_ImportError) },
734 { MP_ROM_QSTR(MP_QSTR_IndentationError), MP_ROM_PTR(&mp_type_IndentationError) },
735 { MP_ROM_QSTR(MP_QSTR_IndexError), MP_ROM_PTR(&mp_type_IndexError) },
736 { MP_ROM_QSTR(MP_QSTR_KeyboardInterrupt), MP_ROM_PTR(&mp_type_KeyboardInterrupt) },
737 { MP_ROM_QSTR(MP_QSTR_KeyError), MP_ROM_PTR(&mp_type_KeyError) },
738 { MP_ROM_QSTR(MP_QSTR_LookupError), MP_ROM_PTR(&mp_type_LookupError) },
739 { MP_ROM_QSTR(MP_QSTR_MemoryError), MP_ROM_PTR(&mp_type_MemoryError) },
740 { MP_ROM_QSTR(MP_QSTR_NameError), MP_ROM_PTR(&mp_type_NameError) },
741 { MP_ROM_QSTR(MP_QSTR_NotImplementedError), MP_ROM_PTR(&mp_type_NotImplementedError) },
742 { MP_ROM_QSTR(MP_QSTR_OSError), MP_ROM_PTR(&mp_type_OSError) },
743 { MP_ROM_QSTR(MP_QSTR_OverflowError), MP_ROM_PTR(&mp_type_OverflowError) },
744 { MP_ROM_QSTR(MP_QSTR_RuntimeError), MP_ROM_PTR(&mp_type_RuntimeError) },
pohmelie81ebba72016-01-27 23:23:11 +0300745 #if MICROPY_PY_ASYNC_AWAIT
746 { MP_ROM_QSTR(MP_QSTR_StopAsyncIteration), MP_ROM_PTR(&mp_type_StopAsyncIteration) },
747 #endif
Damien Georgecbf76742015-11-27 13:38:15 +0000748 { MP_ROM_QSTR(MP_QSTR_StopIteration), MP_ROM_PTR(&mp_type_StopIteration) },
749 { MP_ROM_QSTR(MP_QSTR_SyntaxError), MP_ROM_PTR(&mp_type_SyntaxError) },
750 { MP_ROM_QSTR(MP_QSTR_SystemExit), MP_ROM_PTR(&mp_type_SystemExit) },
751 { MP_ROM_QSTR(MP_QSTR_TypeError), MP_ROM_PTR(&mp_type_TypeError) },
Paul Sokolovsky71ebd4b2015-02-23 23:18:36 +0200752 #if MICROPY_PY_BUILTINS_STR_UNICODE
Damien Georgecbf76742015-11-27 13:38:15 +0000753 { MP_ROM_QSTR(MP_QSTR_UnicodeError), MP_ROM_PTR(&mp_type_UnicodeError) },
Paul Sokolovsky71ebd4b2015-02-23 23:18:36 +0200754 #endif
Damien Georgecbf76742015-11-27 13:38:15 +0000755 { MP_ROM_QSTR(MP_QSTR_ValueError), MP_ROM_PTR(&mp_type_ValueError) },
Damien Georgec8b60f02015-04-20 13:29:31 +0000756 #if MICROPY_EMIT_NATIVE
Damien Georgecbf76742015-11-27 13:38:15 +0000757 { MP_ROM_QSTR(MP_QSTR_ViperTypeError), MP_ROM_PTR(&mp_type_ViperTypeError) },
Damien Georgec8b60f02015-04-20 13:29:31 +0000758 #endif
Damien Georgecbf76742015-11-27 13:38:15 +0000759 { MP_ROM_QSTR(MP_QSTR_ZeroDivisionError), MP_ROM_PTR(&mp_type_ZeroDivisionError) },
Damien George78d702c2014-12-09 16:19:48 +0000760
761 // Extra builtins as defined by a port
762 MICROPY_PORT_BUILTINS
stijn22cf0942022-01-05 16:04:58 +0100763 MICROPY_PORT_EXTRA_BUILTINS
Damien George78d702c2014-12-09 16:19:48 +0000764};
765
766MP_DEFINE_CONST_DICT(mp_module_builtins_globals, mp_module_builtins_globals_table);
767
768const mp_obj_module_t mp_module_builtins = {
769 .base = { &mp_type_module },
Damien George69661f32020-02-27 15:36:53 +1100770 .globals = (mp_obj_dict_t *)&mp_module_builtins_globals,
Damien George78d702c2014-12-09 16:19:48 +0000771};
Jim Mussaredd8d3e6a2022-04-20 16:14:22 +1000772
Damien Georgeefe23ac2022-05-31 22:56:11 +1000773MP_REGISTER_MODULE(MP_QSTR_builtins, mp_module_builtins);