Skip to content

Commit 17f45d4

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 300c8bd + da8d21e commit 17f45d4

42 files changed

Lines changed: 1265 additions & 237 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

py/builtin.c

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -375,28 +375,6 @@ STATIC mp_obj_t mp_builtin_sorted(uint n_args, const mp_obj_t *args, mp_map_t *k
375375

376376
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj, 1, mp_builtin_sorted);
377377

378-
STATIC mp_obj_t mp_builtin_str(mp_obj_t o_in) {
379-
vstr_t *vstr = vstr_new();
380-
mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, o_in, PRINT_STR);
381-
mp_obj_t s = mp_obj_new_str((byte*)vstr->buf, vstr->len, false);
382-
vstr_free(vstr);
383-
return s;
384-
}
385-
386-
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_str_obj, mp_builtin_str);
387-
388-
// TODO: This should be type, this is just quick CPython compat hack
389-
STATIC mp_obj_t mp_builtin_bytes(uint n_args, const mp_obj_t *args) {
390-
if (!MP_OBJ_IS_QSTR(args[0]) && !MP_OBJ_IS_TYPE(args[0], &str_type)) {
391-
assert(0);
392-
}
393-
// Currently, MicroPython strings are mix between CPython byte and unicode
394-
// strings. So, conversion is null so far.
395-
return args[0];
396-
}
397-
398-
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_bytes_obj, 1, 3, mp_builtin_bytes);
399-
400378
STATIC mp_obj_t mp_builtin_id(mp_obj_t o_in) {
401379
return mp_obj_new_int((machine_int_t)o_in);
402380
}

py/builtinmath.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ MATH_FUN_1(fabs, fabs)
4646
MATH_FUN_1(floor, floor) //TODO: delegate to x.__floor__() if x is not a float
4747
MATH_FUN_2(fmod, fmod)
4848
//MATH_FUN_1(frexp, frexp)
49-
MATH_FUN_1(isfinite, isfinite)
50-
MATH_FUN_1(isinf, isinf)
51-
MATH_FUN_1(isnan, isnan)
49+
//MATH_FUN_1(isfinite, isfinite)
50+
//MATH_FUN_1(isinf, isinf)
51+
//MATH_FUN_1(isnan, isnan)
5252
MATH_FUN_1(trunc, trunc)
5353

5454
//TODO: factorial, fsum, frexp, ldexp, modf
@@ -83,9 +83,9 @@ STATIC const mp_map_elem_t mp_module_math_globals_table[] = {
8383
{ MP_OBJ_NEW_QSTR(MP_QSTR_floor), (mp_obj_t)&mp_math_floor_obj },
8484
{ MP_OBJ_NEW_QSTR(MP_QSTR_fmod), (mp_obj_t)&mp_math_fmod_obj },
8585
//{ MP_OBJ_NEW_QSTR(MP_QSTR_frexp), (mp_obj_t)&mp_math_frexp_obj },
86-
{ MP_OBJ_NEW_QSTR(MP_QSTR_isfinite), (mp_obj_t)&mp_math_isfinite_obj },
87-
{ MP_OBJ_NEW_QSTR(MP_QSTR_isinf), (mp_obj_t)&mp_math_isinf_obj },
88-
{ MP_OBJ_NEW_QSTR(MP_QSTR_isnan), (mp_obj_t)&mp_math_isnan_obj },
86+
//{ MP_OBJ_NEW_QSTR(MP_QSTR_isfinite), (mp_obj_t)&mp_math_isfinite_obj },
87+
//{ MP_OBJ_NEW_QSTR(MP_QSTR_isinf), (mp_obj_t)&mp_math_isinf_obj },
88+
//{ MP_OBJ_NEW_QSTR(MP_QSTR_isnan), (mp_obj_t)&mp_math_isnan_obj },
8989
{ MP_OBJ_NEW_QSTR(MP_QSTR_trunc), (mp_obj_t)&mp_math_trunc_obj },
9090
};
9191

py/objcomplex.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "mpconfig.h"
77
#include "qstr.h"
88
#include "obj.h"
9+
#include "parsenum.h"
910
#include "runtime0.h"
1011
#include "map.h"
1112

@@ -36,15 +37,20 @@ STATIC mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
3637
return mp_obj_new_complex(0, 0);
3738

3839
case 1:
39-
// TODO allow string as first arg and parse it
40-
if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) {
40+
if (MP_OBJ_IS_STR(args[0])) {
41+
// a string, parse it
42+
uint l;
43+
const char *s = mp_obj_str_get_data(args[0], &l);
44+
return mp_parse_num_decimal(s, l, true, true);
45+
} else if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) {
46+
// a complex, just return it
4147
return args[0];
4248
} else {
49+
// something else, try to cast it to a complex
4350
return mp_obj_new_complex(mp_obj_get_float(args[0]), 0);
4451
}
4552

46-
case 2:
47-
{
53+
case 2: {
4854
mp_float_t real, imag;
4955
if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) {
5056
mp_obj_complex_get(args[0], &real, &imag);

py/objfloat.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,12 @@ STATIC mp_obj_t float_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m
3939
// a string, parse it
4040
uint l;
4141
const char *s = mp_obj_str_get_data(args[0], &l);
42-
return mp_parse_num_decimal(s, l);
42+
return mp_parse_num_decimal(s, l, false, false);
4343
} else if (MP_OBJ_IS_TYPE(args[0], &mp_type_float)) {
44+
// a float, just return it
4445
return args[0];
4546
} else {
47+
// something else, try to cast it to a float
4648
return mp_obj_new_float(mp_obj_get_float(args[0]));
4749
}
4850

py/objstr.c

Lines changed: 187 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ typedef struct _mp_obj_str_t {
1414
mp_obj_base_t base;
1515
machine_uint_t hash : 16; // XXX here we assume the hash size is 16 bits (it is at the moment; see qstr.c)
1616
machine_uint_t len : 16; // len == number of bytes used in data, alloc = len + 1 because (at the moment) we also append a null byte
17-
byte data[];
17+
const byte *data;
1818
} mp_obj_str_t;
1919

20+
const mp_obj_t mp_const_empty_bytes;
21+
2022
// use this macro to extract the string hash
2123
#define GET_STR_HASH(str_obj_in, str_hash) uint str_hash; if (MP_OBJ_IS_QSTR(str_obj_in)) { str_hash = qstr_hash(MP_OBJ_QSTR_VALUE(str_obj_in)); } else { str_hash = ((mp_obj_str_t*)str_obj_in)->hash; }
2224

@@ -28,6 +30,7 @@ typedef struct _mp_obj_str_t {
2830

2931
STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str);
3032
STATIC mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str);
33+
STATIC mp_obj_t str_new(const mp_obj_type_t *type, const byte* data, uint len);
3134

3235
/******************************************************************************/
3336
/* str */
@@ -78,6 +81,109 @@ STATIC void str_print(void (*print)(void *env, const char *fmt, ...), void *env,
7881
}
7982
}
8083

84+
STATIC mp_obj_t str_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
85+
switch (n_args) {
86+
case 0:
87+
return MP_OBJ_NEW_QSTR(MP_QSTR_);
88+
89+
case 1:
90+
{
91+
vstr_t *vstr = vstr_new();
92+
mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, args[0], PRINT_STR);
93+
mp_obj_t s = mp_obj_new_str((byte*)vstr->buf, vstr->len, false);
94+
vstr_free(vstr);
95+
return s;
96+
}
97+
98+
case 2:
99+
case 3:
100+
{
101+
// TODO: validate 2nd/3rd args
102+
if (!MP_OBJ_IS_TYPE(args[0], &bytes_type)) {
103+
nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "bytes expected"));
104+
}
105+
GET_STR_DATA_LEN(args[0], str_data, str_len);
106+
GET_STR_HASH(args[0], str_hash);
107+
mp_obj_str_t *o = str_new(&str_type, NULL, str_len);
108+
o->data = str_data;
109+
o->hash = str_hash;
110+
return o;
111+
}
112+
113+
default:
114+
nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "str takes at most 3 arguments"));
115+
}
116+
}
117+
118+
STATIC mp_obj_t bytes_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
119+
if (n_args == 0) {
120+
return mp_const_empty_bytes;
121+
}
122+
123+
if (MP_OBJ_IS_STR(args[0])) {
124+
if (n_args < 2 || n_args > 3) {
125+
goto wrong_args;
126+
}
127+
GET_STR_DATA_LEN(args[0], str_data, str_len);
128+
GET_STR_HASH(args[0], str_hash);
129+
mp_obj_str_t *o = str_new(&bytes_type, NULL, str_len);
130+
o->data = str_data;
131+
o->hash = str_hash;
132+
return o;
133+
}
134+
135+
if (n_args > 1) {
136+
goto wrong_args;
137+
}
138+
139+
if (MP_OBJ_IS_SMALL_INT(args[0])) {
140+
uint len = MP_OBJ_SMALL_INT_VALUE(args[0]);
141+
byte *data;
142+
143+
mp_obj_t o = mp_obj_str_builder_start(&bytes_type, len, &data);
144+
memset(data, 0, len);
145+
return mp_obj_str_builder_end(o);
146+
}
147+
148+
int len;
149+
byte *data;
150+
vstr_t *vstr = NULL;
151+
mp_obj_t o = NULL;
152+
// Try to create array of exact len if initializer len is known
153+
mp_obj_t len_in = mp_obj_len_maybe(args[0]);
154+
if (len_in == MP_OBJ_NULL) {
155+
len = -1;
156+
vstr = vstr_new();
157+
} else {
158+
len = MP_OBJ_SMALL_INT_VALUE(len_in);
159+
o = mp_obj_str_builder_start(&bytes_type, len, &data);
160+
}
161+
162+
mp_obj_t iterable = rt_getiter(args[0]);
163+
mp_obj_t item;
164+
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
165+
if (len == -1) {
166+
vstr_add_char(vstr, MP_OBJ_SMALL_INT_VALUE(item));
167+
} else {
168+
*data++ = MP_OBJ_SMALL_INT_VALUE(item);
169+
}
170+
}
171+
172+
if (len == -1) {
173+
vstr_shrink(vstr);
174+
// TODO: Optimize, borrow buffer from vstr
175+
len = vstr_len(vstr);
176+
o = mp_obj_str_builder_start(&bytes_type, len, &data);
177+
memcpy(data, vstr_str(vstr), len);
178+
vstr_free(vstr);
179+
}
180+
181+
return mp_obj_str_builder_end(o);
182+
183+
wrong_args:
184+
nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "wrong number of arguments"));
185+
}
186+
81187
// like strstr but with specified length and allows \0 bytes
82188
// TODO replace with something more efficient/standard
83189
STATIC const byte *find_subbytes(const byte *haystack, uint hlen, const byte *needle, uint nlen) {
@@ -520,6 +626,62 @@ STATIC mp_obj_t str_count(uint n_args, const mp_obj_t *args) {
520626
return MP_OBJ_NEW_SMALL_INT(num_occurrences);
521627
}
522628

629+
STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, machine_int_t direction) {
630+
assert(MP_OBJ_IS_STR(self_in));
631+
if (!MP_OBJ_IS_STR(arg)) {
632+
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
633+
"Can't convert '%s' object to str implicitly", mp_obj_get_type_str(arg)));
634+
}
635+
636+
GET_STR_DATA_LEN(self_in, str, str_len);
637+
GET_STR_DATA_LEN(arg, sep, sep_len);
638+
639+
if (sep_len == 0) {
640+
nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "empty separator"));
641+
}
642+
643+
mp_obj_t result[] = {MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_), MP_OBJ_NEW_QSTR(MP_QSTR_)};
644+
645+
if (direction > 0) {
646+
result[0] = self_in;
647+
} else {
648+
result[2] = self_in;
649+
}
650+
651+
if (str_len >= sep_len) {
652+
machine_uint_t str_index, str_index_end;
653+
if (direction > 0) {
654+
str_index = 0;
655+
str_index_end = str_len - sep_len;
656+
} else {
657+
str_index = str_len - sep_len;
658+
str_index_end = 0;
659+
}
660+
for (;;) {
661+
if (memcmp(&str[str_index], sep, sep_len) == 0) {
662+
result[0] = mp_obj_new_str(str, str_index, false);
663+
result[1] = arg;
664+
result[2] = mp_obj_new_str(str + str_index + sep_len, str_len - str_index - sep_len, false);
665+
break;
666+
}
667+
if (str_index == str_index_end) {
668+
break;
669+
}
670+
str_index += direction;
671+
}
672+
}
673+
674+
return mp_obj_new_tuple(3, result);
675+
}
676+
677+
STATIC mp_obj_t str_partition(mp_obj_t self_in, mp_obj_t arg) {
678+
return str_partitioner(self_in, arg, 1);
679+
}
680+
681+
STATIC mp_obj_t str_rpartition(mp_obj_t self_in, mp_obj_t arg) {
682+
return str_partitioner(self_in, arg, -1);
683+
}
684+
523685
STATIC machine_int_t str_get_buffer(mp_obj_t self_in, buffer_info_t *bufinfo, int flags) {
524686
if (flags == BUFFER_READ) {
525687
GET_STR_DATA_LEN(self_in, str_data, str_len);
@@ -542,6 +704,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_strip_obj, 1, 2, str_strip);
542704
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(str_format_obj, 1, str_format);
543705
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj, 3, 4, str_replace);
544706
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj, 2, 4, str_count);
707+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_partition_obj, str_partition);
708+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_rpartition_obj, str_rpartition);
545709

546710
STATIC const mp_method_t str_type_methods[] = {
547711
{ "find", &str_find_obj },
@@ -552,13 +716,16 @@ STATIC const mp_method_t str_type_methods[] = {
552716
{ "format", &str_format_obj },
553717
{ "replace", &str_replace_obj },
554718
{ "count", &str_count_obj },
719+
{ "partition", &str_partition_obj },
720+
{ "rpartition", &str_rpartition_obj },
555721
{ NULL, NULL }, // end-of-list sentinel
556722
};
557723

558724
const mp_obj_type_t str_type = {
559725
{ &mp_type_type },
560726
.name = MP_QSTR_str,
561727
.print = str_print,
728+
.make_new = str_make_new,
562729
.binary_op = str_binary_op,
563730
.getiter = mp_obj_new_str_iterator,
564731
.methods = str_type_methods,
@@ -570,34 +737,45 @@ const mp_obj_type_t bytes_type = {
570737
{ &mp_type_type },
571738
.name = MP_QSTR_bytes,
572739
.print = str_print,
740+
.make_new = bytes_make_new,
573741
.binary_op = str_binary_op,
574742
.getiter = mp_obj_new_bytes_iterator,
575743
.methods = str_type_methods,
576744
};
577745

746+
// the zero-length bytes
747+
STATIC const mp_obj_str_t empty_bytes_obj = {{&bytes_type}, 0, 0, NULL};
748+
const mp_obj_t mp_const_empty_bytes = (mp_obj_t)&empty_bytes_obj;
749+
578750
mp_obj_t mp_obj_str_builder_start(const mp_obj_type_t *type, uint len, byte **data) {
579-
mp_obj_str_t *o = m_new_obj_var(mp_obj_str_t, byte, len + 1);
751+
mp_obj_str_t *o = m_new_obj(mp_obj_str_t);
580752
o->base.type = type;
581753
o->len = len;
582-
*data = o->data;
754+
byte *p = m_new(byte, len + 1);
755+
o->data = p;
756+
*data = p;
583757
return o;
584758
}
585759

586760
mp_obj_t mp_obj_str_builder_end(mp_obj_t o_in) {
587-
assert(MP_OBJ_IS_STR(o_in));
588761
mp_obj_str_t *o = o_in;
589762
o->hash = qstr_compute_hash(o->data, o->len);
590-
o->data[o->len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings
763+
byte *p = (byte*)o->data;
764+
p[o->len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings
591765
return o;
592766
}
593767

594768
STATIC mp_obj_t str_new(const mp_obj_type_t *type, const byte* data, uint len) {
595-
mp_obj_str_t *o = m_new_obj_var(mp_obj_str_t, byte, len + 1);
769+
mp_obj_str_t *o = m_new_obj(mp_obj_str_t);
596770
o->base.type = type;
597-
o->hash = qstr_compute_hash(data, len);
598771
o->len = len;
599-
memcpy(o->data, data, len * sizeof(byte));
600-
o->data[len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings
772+
if (data) {
773+
o->hash = qstr_compute_hash(data, len);
774+
byte *p = m_new(byte, len + 1);
775+
o->data = p;
776+
memcpy(p, data, len * sizeof(byte));
777+
p[len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings
778+
}
601779
return o;
602780
}
603781

0 commit comments

Comments
 (0)