blob: 0aa281edd1aadc574714cc2a2b0d7db9583e2de5 [file] [log] [blame]
Damien George04b91472014-05-03 23:27:38 +01001/*
2 * This file is part of the Micro Python project, http://micropython.org/
3 *
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
Damien George660aef62014-04-02 12:22:07 +010027#include <stdlib.h>
Damien George45b43c22014-01-05 01:50:45 +000028#include <stdint.h>
Damien George45b43c22014-01-05 01:50:45 +000029#include <assert.h>
Dave Hylandsc4029e52014-04-07 11:19:51 -070030#include <string.h>
Damien George45b43c22014-01-05 01:50:45 +000031
Paul Sokolovskyf54bcbf2014-05-02 17:47:01 +030032#include "mpconfig.h"
Damien George45b43c22014-01-05 01:50:45 +000033#include "nlr.h"
34#include "misc.h"
Damien George55baff42014-01-21 21:40:13 +000035#include "qstr.h"
Damien George45b43c22014-01-05 01:50:45 +000036#include "obj.h"
Damien George20773972014-02-22 18:12:43 +000037#include "parsenum.h"
Damien Georged1e355e2014-05-28 14:51:12 +010038#include "smallint.h"
Damien George438c88d2014-02-22 19:25:23 +000039#include "mpz.h"
Paul Sokolovsky76a90f22014-01-13 22:31:01 +020040#include "objint.h"
Damien Georgea75b02e2014-08-27 09:20:30 +010041#include "objstr.h"
Damien George660aef62014-04-02 12:22:07 +010042#include "runtime0.h"
43#include "runtime.h"
Paul Sokolovsky48b35722014-01-12 17:30:48 +020044
Damien Georgefb510b32014-06-01 13:32:54 +010045#if MICROPY_PY_BUILTINS_FLOAT
Damien George6433bd92014-03-30 23:13:16 +010046#include <math.h>
47#endif
48
Damien Georgee8208a72014-04-04 15:08:23 +010049// This dispatcher function is expected to be independent of the implementation of long int
Damien Georgeecc88e92014-08-30 00:35:11 +010050STATIC mp_obj_t mp_obj_int_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
Damien Georgeee7a8802014-05-11 18:37:21 +010051 mp_arg_check_num(n_args, n_kw, 0, 2, false);
Damien George20006db2014-01-18 14:10:48 +000052
Damien George45b43c22014-01-05 01:50:45 +000053 switch (n_args) {
54 case 0:
55 return MP_OBJ_NEW_SMALL_INT(0);
56
57 case 1:
Damien George813ed3b2014-05-28 14:09:46 +010058 if (MP_OBJ_IS_INT(args[0])) {
59 // already an int (small or long), just return it
60 return args[0];
Dave Hylandsb7f7c652014-08-26 12:44:46 -070061 } else if (MP_OBJ_IS_STR_OR_BYTES(args[0])) {
Damien George5573f9f2014-01-15 22:58:39 +000062 // a string, parse it
Damien Georged182b982014-08-30 14:19:41 +010063 mp_uint_t l;
Damien George698ec212014-02-08 18:17:23 +000064 const char *s = mp_obj_str_get_data(args[0], &l);
Damien George20773972014-02-22 18:12:43 +000065 return mp_parse_num_integer(s, l, 0);
Damien Georgefb510b32014-06-01 13:32:54 +010066#if MICROPY_PY_BUILTINS_FLOAT
Damien George6433bd92014-03-30 23:13:16 +010067 } else if (MP_OBJ_IS_TYPE(args[0], &mp_type_float)) {
Paul Sokolovsky12033df2014-12-30 00:22:10 +020068 return mp_obj_new_int_from_float(mp_obj_float_get(args[0]));
Damien George6433bd92014-03-30 23:13:16 +010069#endif
Damien George5573f9f2014-01-15 22:58:39 +000070 } else {
Damien George813ed3b2014-05-28 14:09:46 +010071 // try to convert to small int (eg from bool)
Damien George5573f9f2014-01-15 22:58:39 +000072 return MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(args[0]));
73 }
Damien George45b43c22014-01-05 01:50:45 +000074
xybc178ea42014-01-14 21:39:05 +080075 case 2:
Damien Georgeee7a8802014-05-11 18:37:21 +010076 default: {
Damien George5573f9f2014-01-15 22:58:39 +000077 // should be a string, parse it
78 // TODO proper error checking of argument types
Damien Georged182b982014-08-30 14:19:41 +010079 mp_uint_t l;
Damien George698ec212014-02-08 18:17:23 +000080 const char *s = mp_obj_str_get_data(args[0], &l);
Damien George20773972014-02-22 18:12:43 +000081 return mp_parse_num_integer(s, l, mp_obj_get_int(args[1]));
Damien George5fa93b62014-01-22 14:35:10 +000082 }
Damien George45b43c22014-01-05 01:50:45 +000083 }
84}
85
Damien Georgee8208a72014-04-04 15:08:23 +010086void mp_obj_int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
Dave Hylandsc4029e52014-04-07 11:19:51 -070087 // The size of this buffer is rather arbitrary. If it's not large
88 // enough, a dynamic one will be allocated.
Damien George40f3c022014-07-03 13:25:24 +010089 char stack_buf[sizeof(mp_int_t) * 4];
Dave Hylandsc4029e52014-04-07 11:19:51 -070090 char *buf = stack_buf;
Damien George42f3de92014-10-03 17:44:14 +000091 mp_uint_t buf_size = sizeof(stack_buf);
92 mp_uint_t fmt_size;
Dave Hylandsc4029e52014-04-07 11:19:51 -070093
94 char *str = mp_obj_int_formatted(&buf, &buf_size, &fmt_size, self_in, 10, NULL, '\0', '\0');
95 print(env, "%s", str);
96
97 if (buf != stack_buf) {
98 m_free(buf, buf_size);
Damien George5fa93b62014-01-22 14:35:10 +000099 }
Damien George45b43c22014-01-05 01:50:45 +0000100}
Paul Sokolovsky48b35722014-01-12 17:30:48 +0200101
Dave Hylandsc4029e52014-04-07 11:19:51 -0700102#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
Damien George88d7bba2014-04-08 23:30:46 +0100103typedef mp_longint_impl_t fmt_int_t;
Dave Hylandsc4029e52014-04-07 11:19:51 -0700104#else
Damien George40f3c022014-07-03 13:25:24 +0100105typedef mp_int_t fmt_int_t;
Dave Hylandsc4029e52014-04-07 11:19:51 -0700106#endif
107
Damien George1c70cbf2014-08-30 00:38:16 +0100108STATIC const uint8_t log_base2_floor[] = {
Dave Hylandsc4029e52014-04-07 11:19:51 -0700109 0,
110 0, 1, 1, 2,
111 2, 2, 2, 3,
112 3, 3, 3, 3,
113 3, 3, 3, 4,
114 4, 4, 4, 4,
115 4, 4, 4, 4,
116 4, 4, 4, 4,
117 4, 4, 4, 5
118};
119
Damien George88d7bba2014-04-08 23:30:46 +0100120STATIC uint int_as_str_size_formatted(uint base, const char *prefix, char comma) {
Dave Hylandsc4029e52014-04-07 11:19:51 -0700121 if (base < 2 || base > 32) {
122 return 0;
123 }
124
125 uint num_digits = sizeof(fmt_int_t) * 8 / log_base2_floor[base] + 1;
126 uint num_commas = comma ? num_digits / 3: 0;
127 uint prefix_len = prefix ? strlen(prefix) : 0;
128 return num_digits + num_commas + prefix_len + 2; // +1 for sign, +1 for null byte
129}
130
Paul Sokolovskyd72bc272014-06-06 23:08:37 +0300131// This routine expects you to pass in a buffer and size (in *buf and *buf_size).
Dave Hylandsc4029e52014-04-07 11:19:51 -0700132// If, for some reason, this buffer is too small, then it will allocate a
133// buffer and return the allocated buffer and size in *buf and *buf_size. It
134// is the callers responsibility to free this allocated buffer.
135//
136// The resulting formatted string will be returned from this function and the
137// formatted size will be in *fmt_size.
Damien George42f3de92014-10-03 17:44:14 +0000138char *mp_obj_int_formatted(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_size, mp_const_obj_t self_in,
Dave Hylandsc4029e52014-04-07 11:19:51 -0700139 int base, const char *prefix, char base_char, char comma) {
Damien George88d7bba2014-04-08 23:30:46 +0100140 fmt_int_t num;
141 if (MP_OBJ_IS_SMALL_INT(self_in)) {
142 // A small int; get the integer value to format.
143 num = mp_obj_get_int(self_in);
144#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
145 } else if (MP_OBJ_IS_TYPE(self_in, &mp_type_int)) {
146 // Not a small int.
147#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
Damien George503d6112014-05-28 14:07:21 +0100148 const mp_obj_int_t *self = self_in;
Damien George40f3c022014-07-03 13:25:24 +0100149 // Get the value to format; mp_obj_get_int truncates to mp_int_t.
Damien George88d7bba2014-04-08 23:30:46 +0100150 num = self->val;
151#else
152 // Delegate to the implementation for the long int.
153 return mp_obj_int_formatted_impl(buf, buf_size, fmt_size, self_in, base, prefix, base_char, comma);
154#endif
155#endif
156 } else {
157 // Not an int.
Paul Sokolovskyd72bc272014-06-06 23:08:37 +0300158 **buf = '\0';
Dave Hylandsc4029e52014-04-07 11:19:51 -0700159 *fmt_size = 0;
160 return *buf;
161 }
Damien George88d7bba2014-04-08 23:30:46 +0100162
Dave Hylandsc4029e52014-04-07 11:19:51 -0700163 char sign = '\0';
164 if (num < 0) {
165 num = -num;
166 sign = '-';
167 }
168
169 uint needed_size = int_as_str_size_formatted(base, prefix, comma);
170 if (needed_size > *buf_size) {
171 *buf = m_new(char, needed_size);
172 *buf_size = needed_size;
173 }
174 char *str = *buf;
175
176 char *b = str + needed_size;
177 *(--b) = '\0';
178 char *last_comma = b;
179
180 if (num == 0) {
181 *(--b) = '0';
182 } else {
183 do {
184 int c = num % base;
185 num /= base;
186 if (c >= 10) {
187 c += base_char - 10;
188 } else {
189 c += '0';
190 }
191 *(--b) = c;
192 if (comma && num != 0 && b > str && (last_comma - b) == 3) {
193 *(--b) = comma;
194 last_comma = b;
195 }
196 }
197 while (b > str && num != 0);
198 }
199 if (prefix) {
200 size_t prefix_len = strlen(prefix);
201 char *p = b - prefix_len;
202 if (p > str) {
203 b = p;
204 while (*prefix) {
205 *p++ = *prefix++;
206 }
207 }
208 }
209 if (sign && b > str) {
210 *(--b) = sign;
211 }
212 *fmt_size = *buf + needed_size - b - 1;
213
214 return b;
215}
216
Damien George88d7bba2014-04-08 23:30:46 +0100217#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
218
Damien Georgeffe911d2014-07-24 14:21:37 +0100219mp_int_t mp_obj_int_hash(mp_obj_t self_in) {
220 return MP_OBJ_SMALL_INT_VALUE(self_in);
221}
222
Dave Hylandsc4029e52014-04-07 11:19:51 -0700223bool mp_obj_int_is_positive(mp_obj_t self_in) {
224 return mp_obj_get_int(self_in) >= 0;
225}
Dave Hylandsc4029e52014-04-07 11:19:51 -0700226
Damien George660aef62014-04-02 12:22:07 +0100227// This is called for operations on SMALL_INT that are not handled by mp_unary_op
Damien Georgeecc88e92014-08-30 00:35:11 +0100228mp_obj_t mp_obj_int_unary_op(mp_uint_t op, mp_obj_t o_in) {
Damien George6ac5dce2014-05-21 19:42:43 +0100229 return MP_OBJ_NULL; // op not supported
Paul Sokolovsky9b00dad2014-01-27 09:05:50 +0200230}
231
Damien George660aef62014-04-02 12:22:07 +0100232// This is called for operations on SMALL_INT that are not handled by mp_binary_op
Damien Georgeecc88e92014-08-30 00:35:11 +0100233mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
Damien Georgee8208a72014-04-04 15:08:23 +0100234 return mp_obj_int_binary_op_extra_cases(op, lhs_in, rhs_in);
Paul Sokolovsky48b35722014-01-12 17:30:48 +0200235}
236
237// This is called only with strings whose value doesn't fit in SMALL_INT
Damien George4abff752014-08-30 14:59:21 +0100238mp_obj_t mp_obj_new_int_from_str_len(const char **str, mp_uint_t len, bool neg, mp_uint_t base) {
Damien Georgeea13f402014-04-05 18:32:08 +0100239 nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "long int not supported in this build"));
Damien George23005372014-01-13 19:39:01 +0000240 return mp_const_none;
Paul Sokolovsky48b35722014-01-12 17:30:48 +0200241}
242
Damien George9d68e9c2014-03-12 15:38:15 +0000243// This is called when an integer larger than a SMALL_INT is needed (although val might still fit in a SMALL_INT)
244mp_obj_t mp_obj_new_int_from_ll(long long val) {
Damien Georgeea13f402014-04-05 18:32:08 +0100245 nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "small int overflow"));
Damien George9d68e9c2014-03-12 15:38:15 +0000246 return mp_const_none;
247}
248
Damien George95307432014-09-10 22:10:33 +0100249// This is called when an integer larger than a SMALL_INT is needed (although val might still fit in a SMALL_INT)
250mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) {
251 nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "small int overflow"));
252 return mp_const_none;
253}
254
Damien George40f3c022014-07-03 13:25:24 +0100255mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) {
Paul Sokolovsky48b35722014-01-12 17:30:48 +0200256 // SMALL_INT accepts only signed numbers, of one bit less size
257 // then word size, which totals 2 bits less for unsigned numbers.
258 if ((value & (WORD_MSBIT_HIGH | (WORD_MSBIT_HIGH >> 1))) == 0) {
259 return MP_OBJ_NEW_SMALL_INT(value);
260 }
Damien Georgeea13f402014-04-05 18:32:08 +0100261 nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "small int overflow"));
Damien George23005372014-01-13 19:39:01 +0000262 return mp_const_none;
Paul Sokolovsky48b35722014-01-12 17:30:48 +0200263}
264
Paul Sokolovskyf79cd6a2014-12-30 00:33:32 +0200265#if MICROPY_PY_BUILTINS_FLOAT
266mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
267 // TODO raise an exception if the int won't fit
268 mp_int_t i = MICROPY_FLOAT_C_FUN(trunc)(val);
269 return mp_obj_new_int(i);
270}
271#endif
272
Damien George40f3c022014-07-03 13:25:24 +0100273mp_obj_t mp_obj_new_int(mp_int_t value) {
Damien Georged1e355e2014-05-28 14:51:12 +0100274 if (MP_SMALL_INT_FITS(value)) {
Paul Sokolovsky48b35722014-01-12 17:30:48 +0200275 return MP_OBJ_NEW_SMALL_INT(value);
276 }
Damien Georgeea13f402014-04-05 18:32:08 +0100277 nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "small int overflow"));
Damien George23005372014-01-13 19:39:01 +0000278 return mp_const_none;
Paul Sokolovsky48b35722014-01-12 17:30:48 +0200279}
Paul Sokolovskyd26b3792014-01-18 16:07:16 +0200280
Damien Georgebe6d8be2014-12-05 23:13:52 +0000281mp_int_t mp_obj_int_get_truncated(mp_const_obj_t self_in) {
Paul Sokolovskyd26b3792014-01-18 16:07:16 +0200282 return MP_OBJ_SMALL_INT_VALUE(self_in);
283}
284
Damien George40f3c022014-07-03 13:25:24 +0100285mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) {
Paul Sokolovskyd26b3792014-01-18 16:07:16 +0200286 return MP_OBJ_SMALL_INT_VALUE(self_in);
287}
288
Damien Georgefb510b32014-06-01 13:32:54 +0100289#if MICROPY_PY_BUILTINS_FLOAT
Damien Georgeeabdf672014-03-22 20:54:01 +0000290mp_float_t mp_obj_int_as_float(mp_obj_t self_in) {
291 return MP_OBJ_SMALL_INT_VALUE(self_in);
292}
293#endif
294
Damien George5fa93b62014-01-22 14:35:10 +0000295#endif // MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
296
Damien Georgee8208a72014-04-04 15:08:23 +0100297// This dispatcher function is expected to be independent of the implementation of long int
298// It handles the extra cases for integer-like arithmetic
Damien Georgeecc88e92014-08-30 00:35:11 +0100299mp_obj_t mp_obj_int_binary_op_extra_cases(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
Damien Georgee8208a72014-04-04 15:08:23 +0100300 if (rhs_in == mp_const_false) {
301 // false acts as 0
302 return mp_binary_op(op, lhs_in, MP_OBJ_NEW_SMALL_INT(0));
303 } else if (rhs_in == mp_const_true) {
304 // true acts as 0
305 return mp_binary_op(op, lhs_in, MP_OBJ_NEW_SMALL_INT(1));
306 } else if (op == MP_BINARY_OP_MULTIPLY) {
Damien George9b7a8ee2014-08-13 13:22:24 +0100307 if (MP_OBJ_IS_STR(rhs_in) || MP_OBJ_IS_TYPE(rhs_in, &mp_type_bytes) || MP_OBJ_IS_TYPE(rhs_in, &mp_type_tuple) || MP_OBJ_IS_TYPE(rhs_in, &mp_type_list)) {
Damien Georgee8208a72014-04-04 15:08:23 +0100308 // multiply is commutative for these types, so delegate to them
309 return mp_binary_op(op, rhs_in, lhs_in);
310 }
311 }
Damien George6ac5dce2014-05-21 19:42:43 +0100312 return MP_OBJ_NULL; // op not supported
Damien Georgee8208a72014-04-04 15:08:23 +0100313}
314
Damien George5213eb32014-04-13 12:24:13 +0100315// this is a classmethod
Damien Georgeecc88e92014-08-30 00:35:11 +0100316STATIC mp_obj_t int_from_bytes(mp_uint_t n_args, const mp_obj_t *args) {
Paul Sokolovskya985b452014-04-09 00:40:58 +0300317 // TODO: Support long ints
Damien George5213eb32014-04-13 12:24:13 +0100318 // TODO: Support byteorder param (assumes 'little' at the moment)
319 // TODO: Support signed param (assumes signed=False at the moment)
320
321 // get the buffer info
Damien George57a4b4f2014-04-18 22:29:21 +0100322 mp_buffer_info_t bufinfo;
Damien Georgeb11b85a2014-04-18 22:59:24 +0100323 mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
Damien George5213eb32014-04-13 12:24:13 +0100324
325 // convert the bytes to an integer
Damien George40f3c022014-07-03 13:25:24 +0100326 mp_uint_t value = 0;
stijn01d6be42014-05-05 12:18:27 +0200327 for (const byte* buf = (const byte*)bufinfo.buf + bufinfo.len - 1; buf >= (byte*)bufinfo.buf; buf--) {
Damien Georgeb9e7ed42014-04-13 12:40:50 +0100328 value = (value << 8) | *buf;
Damien George5213eb32014-04-13 12:24:13 +0100329 }
330
331 return mp_obj_new_int_from_uint(value);
Paul Sokolovskya985b452014-04-09 00:40:58 +0300332}
333
Damien George5213eb32014-04-13 12:24:13 +0100334STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(int_from_bytes_fun_obj, 2, 3, int_from_bytes);
335STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(int_from_bytes_obj, (const mp_obj_t)&int_from_bytes_fun_obj);
Paul Sokolovskya985b452014-04-09 00:40:58 +0300336
Damien Georgeecc88e92014-08-30 00:35:11 +0100337STATIC mp_obj_t int_to_bytes(mp_uint_t n_args, const mp_obj_t *args) {
Paul Sokolovskya985b452014-04-09 00:40:58 +0300338 // TODO: Support long ints
Damien Georgefcdb2392014-10-06 13:45:34 +0000339 // TODO: Support byteorder param (assumes 'little')
340 // TODO: Support signed param (assumes signed=False)
341
342 mp_int_t val = mp_obj_int_get_checked(args[0]);
343 mp_int_t len = MP_OBJ_SMALL_INT_VALUE(args[1]);
344
345 byte *data;
Paul Sokolovskya985b452014-04-09 00:40:58 +0300346 mp_obj_t o = mp_obj_str_builder_start(&mp_type_bytes, len, &data);
347 memset(data, 0, len);
Damien Georgefcdb2392014-10-06 13:45:34 +0000348
349 if (MP_ENDIANNESS_LITTLE) {
350 memcpy(data, &val, len < sizeof(mp_int_t) ? len : sizeof(mp_int_t));
351 } else {
352 while (len--) {
353 *data++ = val;
354 val >>= 8;
355 }
356 }
357
Paul Sokolovskya985b452014-04-09 00:40:58 +0300358 return mp_obj_str_builder_end(o);
359}
Paul Sokolovskya985b452014-04-09 00:40:58 +0300360STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(int_to_bytes_obj, 2, 4, int_to_bytes);
361
362STATIC const mp_map_elem_t int_locals_dict_table[] = {
363 { MP_OBJ_NEW_QSTR(MP_QSTR_from_bytes), (mp_obj_t)&int_from_bytes_obj },
364 { MP_OBJ_NEW_QSTR(MP_QSTR_to_bytes), (mp_obj_t)&int_to_bytes_obj },
365};
366
367STATIC MP_DEFINE_CONST_DICT(int_locals_dict, int_locals_dict_table);
368
Damien George3e1a5c12014-03-29 13:43:38 +0000369const mp_obj_type_t mp_type_int = {
Damien Georgec5966122014-02-15 16:10:44 +0000370 { &mp_type_type },
Damien Georgea71c83a2014-02-15 11:34:50 +0000371 .name = MP_QSTR_int,
Damien Georgee8208a72014-04-04 15:08:23 +0100372 .print = mp_obj_int_print,
373 .make_new = mp_obj_int_make_new,
374 .unary_op = mp_obj_int_unary_op,
375 .binary_op = mp_obj_int_binary_op,
Paul Sokolovskya985b452014-04-09 00:40:58 +0300376 .locals_dict = (mp_obj_t)&int_locals_dict,
Damien George5fa93b62014-01-22 14:35:10 +0000377};