blob: b066fa544d80008e58ddde168d7eba6f228966ae [file] [log] [blame]
Paul Sokolovsky966879c2014-01-17 20:01:36 +02001#include <stdlib.h>
2#include <stdint.h>
Paul Sokolovsky966879c2014-01-17 20:01:36 +02003
4#include "nlr.h"
5#include "misc.h"
6#include "mpconfig.h"
Damien George55baff42014-01-21 21:40:13 +00007#include "qstr.h"
Paul Sokolovsky966879c2014-01-17 20:01:36 +02008#include "obj.h"
Damien George438c88d2014-02-22 19:25:23 +00009#include "mpz.h"
Paul Sokolovsky966879c2014-01-17 20:01:36 +020010#include "objint.h"
11#include "runtime0.h"
12
13#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
14
Paul Sokolovsky966879c2014-01-17 20:01:36 +020015// Python3 no longer has "l" suffix for long ints. We allow to use it
16// for debugging purpose though.
17#ifdef DEBUG
18#define SUFFIX "l"
19#else
20#define SUFFIX ""
21#endif
22
23void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
Damien George5fa93b62014-01-22 14:35:10 +000024 if (MP_OBJ_IS_SMALL_INT(self_in)) {
Damien George0379b552014-02-22 17:34:09 +000025 print(env, INT_FMT, MP_OBJ_SMALL_INT_VALUE(self_in));
Damien George5fa93b62014-01-22 14:35:10 +000026 } else {
27 mp_obj_int_t *self = self_in;
28 print(env, "%lld" SUFFIX, self->val);
29 }
Paul Sokolovsky966879c2014-01-17 20:01:36 +020030}
31
Paul Sokolovsky9b00dad2014-01-27 09:05:50 +020032mp_obj_t int_unary_op(int op, mp_obj_t o_in) {
33 mp_obj_int_t *o = o_in;
34 switch (op) {
Paul Sokolovskyc1d9bbc2014-01-30 04:37:19 +020035 case RT_UNARY_OP_BOOL: return MP_BOOL(o->val != 0);
Paul Sokolovsky9b00dad2014-01-27 09:05:50 +020036 case RT_UNARY_OP_POSITIVE: return o_in;
37 case RT_UNARY_OP_NEGATIVE: return mp_obj_new_int_from_ll(-o->val);
38 case RT_UNARY_OP_INVERT: return mp_obj_new_int_from_ll(~o->val);
39 default: return NULL; // op not supported
40 }
41}
42
Paul Sokolovsky966879c2014-01-17 20:01:36 +020043mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
Damien Georged02f6ea2014-03-20 19:31:32 +000044 long long lhs_val;
Paul Sokolovsky966879c2014-01-17 20:01:36 +020045 long long rhs_val;
46
Damien Georged02f6ea2014-03-20 19:31:32 +000047 if (MP_OBJ_IS_SMALL_INT(lhs_in)) {
48 lhs_val = MP_OBJ_SMALL_INT_VALUE(lhs_in);
49 } else if (MP_OBJ_IS_TYPE(lhs_in, &int_type)) {
50 lhs_val = ((mp_obj_int_t*)lhs_in)->val;
51 } else {
52 return MP_OBJ_NULL;
53 }
Damien Georgec4129982014-03-19 23:17:23 +000054
Damien Georged02f6ea2014-03-20 19:31:32 +000055 if (MP_OBJ_IS_SMALL_INT(rhs_in)) {
56 rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs_in);
57 } else if (MP_OBJ_IS_TYPE(rhs_in, &int_type)) {
58 rhs_val = ((mp_obj_int_t*)rhs_in)->val;
Paul Sokolovsky966879c2014-01-17 20:01:36 +020059 } else {
60 return MP_OBJ_NULL;
61 }
62
63 switch (op) {
64 case RT_BINARY_OP_ADD:
Paul Sokolovsky966879c2014-01-17 20:01:36 +020065 case RT_BINARY_OP_INPLACE_ADD:
Damien Georged02f6ea2014-03-20 19:31:32 +000066 return mp_obj_new_int_from_ll(lhs_val + rhs_val);
67 case RT_BINARY_OP_SUBTRACT:
Paul Sokolovsky966879c2014-01-17 20:01:36 +020068 case RT_BINARY_OP_INPLACE_SUBTRACT:
Damien Georged02f6ea2014-03-20 19:31:32 +000069 return mp_obj_new_int_from_ll(lhs_val - rhs_val);
70 case RT_BINARY_OP_MULTIPLY:
Paul Sokolovsky9b00dad2014-01-27 09:05:50 +020071 case RT_BINARY_OP_INPLACE_MULTIPLY:
Damien Georged02f6ea2014-03-20 19:31:32 +000072 return mp_obj_new_int_from_ll(lhs_val * rhs_val);
73 case RT_BINARY_OP_FLOOR_DIVIDE:
Paul Sokolovsky9b00dad2014-01-27 09:05:50 +020074 case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE:
Damien Georged02f6ea2014-03-20 19:31:32 +000075 return mp_obj_new_int_from_ll(lhs_val / rhs_val);
76 case RT_BINARY_OP_MODULO:
Paul Sokolovsky9b00dad2014-01-27 09:05:50 +020077 case RT_BINARY_OP_INPLACE_MODULO:
Damien Georged02f6ea2014-03-20 19:31:32 +000078 return mp_obj_new_int_from_ll(lhs_val % rhs_val);
Paul Sokolovsky966879c2014-01-17 20:01:36 +020079
80 case RT_BINARY_OP_AND:
Paul Sokolovsky9b00dad2014-01-27 09:05:50 +020081 case RT_BINARY_OP_INPLACE_AND:
Damien Georged02f6ea2014-03-20 19:31:32 +000082 return mp_obj_new_int_from_ll(lhs_val & rhs_val);
83 case RT_BINARY_OP_OR:
Paul Sokolovsky9b00dad2014-01-27 09:05:50 +020084 case RT_BINARY_OP_INPLACE_OR:
Damien Georged02f6ea2014-03-20 19:31:32 +000085 return mp_obj_new_int_from_ll(lhs_val | rhs_val);
86 case RT_BINARY_OP_XOR:
Paul Sokolovsky9b00dad2014-01-27 09:05:50 +020087 case RT_BINARY_OP_INPLACE_XOR:
Damien Georged02f6ea2014-03-20 19:31:32 +000088 return mp_obj_new_int_from_ll(lhs_val ^ rhs_val);
Paul Sokolovsky9b00dad2014-01-27 09:05:50 +020089
Paul Sokolovsky966879c2014-01-17 20:01:36 +020090 case RT_BINARY_OP_LSHIFT:
Paul Sokolovsky9b00dad2014-01-27 09:05:50 +020091 case RT_BINARY_OP_INPLACE_LSHIFT:
Damien Georged02f6ea2014-03-20 19:31:32 +000092 return mp_obj_new_int_from_ll(lhs_val << (int)rhs_val);
93 case RT_BINARY_OP_RSHIFT:
Paul Sokolovsky9b00dad2014-01-27 09:05:50 +020094 case RT_BINARY_OP_INPLACE_RSHIFT:
Damien Georged02f6ea2014-03-20 19:31:32 +000095 return mp_obj_new_int_from_ll(lhs_val >> (int)rhs_val);
Paul Sokolovsky9b00dad2014-01-27 09:05:50 +020096
Damien George9aa2a522014-02-01 23:04:09 +000097 case RT_BINARY_OP_LESS:
Damien Georged02f6ea2014-03-20 19:31:32 +000098 return MP_BOOL(lhs_val < rhs_val);
Damien George9aa2a522014-02-01 23:04:09 +000099 case RT_BINARY_OP_MORE:
Damien Georged02f6ea2014-03-20 19:31:32 +0000100 return MP_BOOL(lhs_val > rhs_val);
Damien George9aa2a522014-02-01 23:04:09 +0000101 case RT_BINARY_OP_LESS_EQUAL:
Damien Georged02f6ea2014-03-20 19:31:32 +0000102 return MP_BOOL(lhs_val <= rhs_val);
Damien George9aa2a522014-02-01 23:04:09 +0000103 case RT_BINARY_OP_MORE_EQUAL:
Damien Georged02f6ea2014-03-20 19:31:32 +0000104 return MP_BOOL(lhs_val >= rhs_val);
Damien George9aa2a522014-02-01 23:04:09 +0000105 case RT_BINARY_OP_EQUAL:
Damien Georged02f6ea2014-03-20 19:31:32 +0000106 return MP_BOOL(lhs_val == rhs_val);
Damien George9aa2a522014-02-01 23:04:09 +0000107 case RT_BINARY_OP_NOT_EQUAL:
Damien Georged02f6ea2014-03-20 19:31:32 +0000108 return MP_BOOL(lhs_val != rhs_val);
Paul Sokolovsky966879c2014-01-17 20:01:36 +0200109
110 default:
111 // op not supported
112 return MP_OBJ_NULL;
113 }
114}
115
116mp_obj_t mp_obj_new_int(machine_int_t value) {
117 if (MP_OBJ_FITS_SMALL_INT(value)) {
118 return MP_OBJ_NEW_SMALL_INT(value);
119 }
120 return mp_obj_new_int_from_ll(value);
121}
122
123mp_obj_t mp_obj_new_int_from_uint(machine_uint_t value) {
124 // SMALL_INT accepts only signed numbers, of one bit less size
125 // than word size, which totals 2 bits less for unsigned numbers.
126 if ((value & (WORD_MSBIT_HIGH | (WORD_MSBIT_HIGH >> 1))) == 0) {
127 return MP_OBJ_NEW_SMALL_INT(value);
128 }
129 return mp_obj_new_int_from_ll(value);
130}
131
132mp_obj_t mp_obj_new_int_from_ll(long long val) {
133 mp_obj_int_t *o = m_new_obj(mp_obj_int_t);
134 o->base.type = &int_type;
135 o->val = val;
136 return o;
137}
138
139mp_obj_t mp_obj_new_int_from_long_str(const char *s) {
140 long long v;
141 char *end;
142 // TODO: this doesn't handle Python hacked 0o octal syntax
143 v = strtoll(s, &end, 0);
Paul Sokolovsky4d0588d2014-02-18 00:21:11 +0200144 if (*end != 0) {
145 nlr_jump(mp_obj_new_exception_msg(&mp_type_SyntaxError, "invalid syntax for number"));
146 }
Paul Sokolovsky966879c2014-01-17 20:01:36 +0200147 mp_obj_int_t *o = m_new_obj(mp_obj_int_t);
148 o->base.type = &int_type;
149 o->val = v;
150 return o;
151}
152
Paul Sokolovskyd26b3792014-01-18 16:07:16 +0200153machine_int_t mp_obj_int_get(mp_obj_t self_in) {
154 if (MP_OBJ_IS_SMALL_INT(self_in)) {
155 return MP_OBJ_SMALL_INT_VALUE(self_in);
Damien Georgeeabdf672014-03-22 20:54:01 +0000156 } else {
157 mp_obj_int_t *self = self_in;
158 return self->val;
Paul Sokolovskyd26b3792014-01-18 16:07:16 +0200159 }
Paul Sokolovsky966879c2014-01-17 20:01:36 +0200160}
161
Paul Sokolovskyd26b3792014-01-18 16:07:16 +0200162machine_int_t mp_obj_int_get_checked(mp_obj_t self_in) {
163 // TODO: Check overflow
164 return mp_obj_int_get(self_in);
165}
166
Damien Georgeeabdf672014-03-22 20:54:01 +0000167#if MICROPY_ENABLE_FLOAT
168mp_float_t mp_obj_int_as_float(mp_obj_t self_in) {
169 if (MP_OBJ_IS_SMALL_INT(self_in)) {
170 return MP_OBJ_SMALL_INT_VALUE(self_in);
171 } else {
172 mp_obj_int_t *self = self_in;
173 return self->val;
174 }
175}
176#endif
177
Paul Sokolovsky966879c2014-01-17 20:01:36 +0200178#endif