Commit 5fa93b67 authored by Damien George's avatar Damien George
Browse files

Second stage of qstr revamp: uPy str object can be qstr or not.

parent 8ae1c1be
...@@ -139,8 +139,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_callable_obj, mp_builtin_callable); ...@@ -139,8 +139,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_callable_obj, mp_builtin_callable);
static mp_obj_t mp_builtin_chr(mp_obj_t o_in) { static mp_obj_t mp_builtin_chr(mp_obj_t o_in) {
int ord = mp_obj_get_int(o_in); int ord = mp_obj_get_int(o_in);
if (0 <= ord && ord <= 0x10ffff) { if (0 <= ord && ord <= 0x10ffff) {
char str[1] = {ord}; byte str[1] = {ord};
return mp_obj_new_str(qstr_from_strn(str, 1)); return mp_obj_new_str(str, 1, true);
} else { } else {
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "chr() arg not in range(0x110000)")); nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "chr() arg not in range(0x110000)"));
} }
...@@ -258,7 +258,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_next_obj, mp_builtin_next); ...@@ -258,7 +258,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_next_obj, mp_builtin_next);
static mp_obj_t mp_builtin_ord(mp_obj_t o_in) { static mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
uint len; uint len;
const byte *str = qstr_data(mp_obj_get_qstr(o_in), &len); const byte *str = mp_obj_str_get_data(o_in, &len);
if (len == 1) { if (len == 1) {
return mp_obj_new_int(str[0]); return mp_obj_new_int(str[0]);
} else { } else {
...@@ -305,8 +305,9 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_range_obj, 1, 3, mp_builtin_range ...@@ -305,8 +305,9 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_range_obj, 1, 3, mp_builtin_range
static mp_obj_t mp_builtin_repr(mp_obj_t o_in) { static mp_obj_t mp_builtin_repr(mp_obj_t o_in) {
vstr_t *vstr = vstr_new(); vstr_t *vstr = vstr_new();
mp_obj_print_helper((void (*)(void *env, const char *fmt, ...))vstr_printf, vstr, o_in, PRINT_REPR); mp_obj_print_helper((void (*)(void *env, const char *fmt, ...))vstr_printf, vstr, o_in, PRINT_REPR);
// TODO don't intern this string mp_obj_t s = mp_obj_new_str((byte*)vstr->buf, vstr->len, false);
return mp_obj_new_str(qstr_from_strn_take(vstr->buf, vstr->alloc, vstr->len)); vstr_free(vstr);
return s;
} }
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_repr_obj, mp_builtin_repr); MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_repr_obj, mp_builtin_repr);
...@@ -345,8 +346,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj, 1, mp_builtin_sorted); ...@@ -345,8 +346,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj, 1, mp_builtin_sorted);
static mp_obj_t mp_builtin_str(mp_obj_t o_in) { static mp_obj_t mp_builtin_str(mp_obj_t o_in) {
vstr_t *vstr = vstr_new(); vstr_t *vstr = vstr_new();
mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, o_in, PRINT_STR); mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, o_in, PRINT_STR);
// TODO don't intern this string mp_obj_t s = mp_obj_new_str((byte*)vstr->buf, vstr->len, false);
return mp_obj_new_str(qstr_from_strn_take(vstr->buf, vstr->alloc, vstr->len)); vstr_free(vstr);
return s;
} }
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_str_obj, mp_builtin_str); MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_str_obj, mp_builtin_str);
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
static mp_obj_t mp_builtin_eval(mp_obj_t o_in) { static mp_obj_t mp_builtin_eval(mp_obj_t o_in) {
uint str_len; uint str_len;
const byte *str = qstr_data(mp_obj_get_qstr(o_in), &str_len); const byte *str = mp_obj_str_get_data(o_in, &str_len);
// create the lexer // create the lexer
mp_lexer_t *lex = mp_lexer_new_from_str_len("<string>", (const char*)str, str_len, 0); mp_lexer_t *lex = mp_lexer_new_from_str_len("<string>", (const char*)str, str_len, 0);
......
...@@ -29,7 +29,10 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) { ...@@ -29,7 +29,10 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
} }
*/ */
qstr mod_name = mp_obj_get_qstr(args[0]); uint mod_name_l;
const byte *mod_name_s = mp_obj_str_get_data(args[0], &mod_name_l);
qstr mod_name = qstr_from_strn((const char*)mod_name_s, mod_name_l);
mp_obj_t loaded = mp_obj_module_get(mod_name); mp_obj_t loaded = mp_obj_module_get(mod_name);
if (loaded != MP_OBJ_NULL) { if (loaded != MP_OBJ_NULL) {
return loaded; return loaded;
...@@ -43,7 +46,7 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) { ...@@ -43,7 +46,7 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
} }
// create a new module object // create a new module object
mp_obj_t module_obj = mp_obj_new_module(mp_obj_get_qstr(args[0])); mp_obj_t module_obj = mp_obj_new_module(mod_name);
// save the old context // save the old context
mp_map_t *old_locals = rt_locals_get(); mp_map_t *old_locals = rt_locals_get();
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include "runtime.h" #include "runtime.h"
#include "map.h" #include "map.h"
mp_obj_t mp_obj_get_type(mp_obj_t o_in) { mp_obj_type_t *mp_obj_get_type(mp_obj_t o_in) {
if (MP_OBJ_IS_SMALL_INT(o_in)) { if (MP_OBJ_IS_SMALL_INT(o_in)) {
return (mp_obj_t)&int_type; return (mp_obj_t)&int_type;
} else if (MP_OBJ_IS_QSTR(o_in)) { } else if (MP_OBJ_IS_QSTR(o_in)) {
...@@ -26,14 +26,7 @@ mp_obj_t mp_obj_get_type(mp_obj_t o_in) { ...@@ -26,14 +26,7 @@ mp_obj_t mp_obj_get_type(mp_obj_t o_in) {
} }
const char *mp_obj_get_type_str(mp_obj_t o_in) { const char *mp_obj_get_type_str(mp_obj_t o_in) {
if (MP_OBJ_IS_SMALL_INT(o_in)) { return mp_obj_get_type(o_in)->name;
return "int";
} else if (MP_OBJ_IS_QSTR(o_in)) {
return "str";
} else {
mp_obj_base_t *o = o_in;
return o->type->name;
}
} }
void printf_wrapper(void *env, const char *fmt, ...) { void printf_wrapper(void *env, const char *fmt, ...) {
...@@ -44,17 +37,11 @@ void printf_wrapper(void *env, const char *fmt, ...) { ...@@ -44,17 +37,11 @@ void printf_wrapper(void *env, const char *fmt, ...) {
} }
void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) { void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
if (MP_OBJ_IS_SMALL_INT(o_in)) { mp_obj_type_t *type = mp_obj_get_type(o_in);
print(env, "%d", (int)MP_OBJ_SMALL_INT_VALUE(o_in)); if (type->print != NULL) {
} else if (MP_OBJ_IS_QSTR(o_in)) { type->print(print, env, o_in, kind);
mp_obj_str_print_qstr(print, env, MP_OBJ_QSTR_VALUE(o_in), kind);
} else { } else {
mp_obj_base_t *o = o_in; print(env, "<%s>", type->name);
if (o->type->print != NULL) {
o->type->print(print, env, o_in, kind);
} else {
print(env, "<%s>", o->type->name);
}
} }
} }
...@@ -94,12 +81,10 @@ machine_int_t mp_obj_hash(mp_obj_t o_in) { ...@@ -94,12 +81,10 @@ machine_int_t mp_obj_hash(mp_obj_t o_in) {
return 1; // needs to hash to same as the integer 1, since True==1 return 1; // needs to hash to same as the integer 1, since True==1
} else if (MP_OBJ_IS_SMALL_INT(o_in)) { } else if (MP_OBJ_IS_SMALL_INT(o_in)) {
return MP_OBJ_SMALL_INT_VALUE(o_in); return MP_OBJ_SMALL_INT_VALUE(o_in);
} else if (MP_OBJ_IS_QSTR(o_in)) { } else if (MP_OBJ_IS_STR(o_in)) {
return MP_OBJ_QSTR_VALUE(o_in); return mp_obj_str_get_hash(o_in);
} else if (MP_OBJ_IS_TYPE(o_in, &none_type)) { } else if (MP_OBJ_IS_TYPE(o_in, &none_type)) {
return (machine_int_t)o_in; return (machine_int_t)o_in;
} else if (MP_OBJ_IS_TYPE(o_in, &str_type)) {
return mp_obj_str_get(o_in);
} else { } else {
assert(0); assert(0);
return 0; return 0;
...@@ -138,10 +123,8 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) { ...@@ -138,10 +123,8 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) {
} }
return false; return false;
} }
} else if (MP_OBJ_IS_QSTR(o1) || MP_OBJ_IS_QSTR(o2)) { } else if (MP_OBJ_IS_STR(o1) && MP_OBJ_IS_STR(o2)) {
return false; return mp_obj_str_equal(o1, o2);
} else if (MP_OBJ_IS_TYPE(o1, &str_type) && MP_OBJ_IS_TYPE(o2, &str_type)) {
return mp_obj_str_get(o1) == mp_obj_str_get(o2);
} else { } else {
mp_obj_base_t *o = o1; mp_obj_base_t *o = o1;
if (o->type->binary_op != NULL) { if (o->type->binary_op != NULL) {
...@@ -218,17 +201,6 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) { ...@@ -218,17 +201,6 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) {
} }
#endif #endif
qstr mp_obj_get_qstr(mp_obj_t arg) {
if (MP_OBJ_IS_QSTR(arg)) {
return MP_OBJ_QSTR_VALUE(arg);
} else if (MP_OBJ_IS_TYPE(arg, &str_type)) {
return mp_obj_str_get(arg);
} else {
assert(0);
return 0;
}
}
mp_obj_t *mp_obj_get_array_fixed_n(mp_obj_t o_in, machine_int_t n) { mp_obj_t *mp_obj_get_array_fixed_n(mp_obj_t o_in, machine_int_t n) {
if (MP_OBJ_IS_TYPE(o_in, &tuple_type) || MP_OBJ_IS_TYPE(o_in, &list_type)) { if (MP_OBJ_IS_TYPE(o_in, &tuple_type) || MP_OBJ_IS_TYPE(o_in, &list_type)) {
uint seq_len; uint seq_len;
...@@ -266,8 +238,8 @@ uint mp_get_index(const mp_obj_type_t *type, machine_uint_t len, mp_obj_t index) ...@@ -266,8 +238,8 @@ uint mp_get_index(const mp_obj_type_t *type, machine_uint_t len, mp_obj_t index)
// may return MP_OBJ_NULL // may return MP_OBJ_NULL
mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) { mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) {
mp_small_int_t len = 0; mp_small_int_t len = 0;
if (MP_OBJ_IS_TYPE(o_in, &str_type)) { if (MP_OBJ_IS_STR(o_in)) {
len = qstr_len(mp_obj_str_get(o_in)); len = mp_obj_str_get_len(o_in);
} else if (MP_OBJ_IS_TYPE(o_in, &tuple_type)) { } else if (MP_OBJ_IS_TYPE(o_in, &tuple_type)) {
uint seq_len; uint seq_len;
mp_obj_t *seq_items; mp_obj_t *seq_items;
......
...@@ -40,6 +40,7 @@ typedef struct _mp_obj_base_t mp_obj_base_t; ...@@ -40,6 +40,7 @@ typedef struct _mp_obj_base_t mp_obj_base_t;
#define MP_OBJ_IS_QSTR(o) ((((mp_small_int_t)(o)) & 3) == 2) #define MP_OBJ_IS_QSTR(o) ((((mp_small_int_t)(o)) & 3) == 2)
#define MP_OBJ_IS_OBJ(o) ((((mp_small_int_t)(o)) & 3) == 0) #define MP_OBJ_IS_OBJ(o) ((((mp_small_int_t)(o)) & 3) == 0)
#define MP_OBJ_IS_TYPE(o, t) (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t*)(o))->type == (t))) #define MP_OBJ_IS_TYPE(o, t) (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t*)(o))->type == (t)))
#define MP_OBJ_IS_STR(o) (MP_OBJ_IS_QSTR(o) || MP_OBJ_IS_TYPE(o, &str_type))
#define MP_OBJ_SMALL_INT_VALUE(o) (((mp_small_int_t)(o)) >> 1) #define MP_OBJ_SMALL_INT_VALUE(o) (((mp_small_int_t)(o)) >> 1)
#define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)(((small_int) << 1) | 1)) #define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)(((small_int) << 1) | 1))
...@@ -199,14 +200,14 @@ extern const mp_obj_t mp_const_stop_iteration; // special object indicating end ...@@ -199,14 +200,14 @@ extern const mp_obj_t mp_const_stop_iteration; // special object indicating end
// General API for objects // General API for objects
mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict); mp_obj_t mp_obj_new_type(const char *name, mp_obj_t bases_tuple, mp_obj_t locals_dict);
mp_obj_t mp_obj_new_none(void); mp_obj_t mp_obj_new_none(void);
mp_obj_t mp_obj_new_bool(bool value); mp_obj_t mp_obj_new_bool(bool value);
mp_obj_t mp_obj_new_cell(mp_obj_t obj); mp_obj_t mp_obj_new_cell(mp_obj_t obj);
mp_obj_t mp_obj_new_int(machine_int_t value); mp_obj_t mp_obj_new_int(machine_int_t value);
mp_obj_t mp_obj_new_int_from_uint(machine_uint_t value); mp_obj_t mp_obj_new_int_from_uint(machine_uint_t value);
mp_obj_t mp_obj_new_int_from_long_str(const char *s); mp_obj_t mp_obj_new_int_from_long_str(const char *s);
mp_obj_t mp_obj_new_str(qstr qstr); mp_obj_t mp_obj_new_str(const byte* data, uint len, bool make_qstr_if_not_already);
#if MICROPY_ENABLE_FLOAT #if MICROPY_ENABLE_FLOAT
mp_obj_t mp_obj_new_float(mp_float_t val); mp_obj_t mp_obj_new_float(mp_float_t val);
mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag); mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag);
...@@ -231,7 +232,7 @@ mp_obj_t mp_obj_new_slice(mp_obj_t start, mp_obj_t stop, mp_obj_t step); ...@@ -231,7 +232,7 @@ mp_obj_t mp_obj_new_slice(mp_obj_t start, mp_obj_t stop, mp_obj_t step);
mp_obj_t mp_obj_new_bound_meth(mp_obj_t meth, mp_obj_t self); mp_obj_t mp_obj_new_bound_meth(mp_obj_t meth, mp_obj_t self);
mp_obj_t mp_obj_new_module(qstr module_name); mp_obj_t mp_obj_new_module(qstr module_name);
mp_obj_t mp_obj_get_type(mp_obj_t o_in); mp_obj_type_t *mp_obj_get_type(mp_obj_t o_in);
const char *mp_obj_get_type_str(mp_obj_t o_in); const char *mp_obj_get_type_str(mp_obj_t o_in);
void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind); void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind);
...@@ -248,7 +249,7 @@ machine_int_t mp_obj_get_int(mp_obj_t arg); ...@@ -248,7 +249,7 @@ machine_int_t mp_obj_get_int(mp_obj_t arg);
mp_float_t mp_obj_get_float(mp_obj_t self_in); mp_float_t mp_obj_get_float(mp_obj_t self_in);
void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag); void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag);
#endif #endif
qstr mp_obj_get_qstr(mp_obj_t arg); //qstr mp_obj_get_qstr(mp_obj_t arg);
mp_obj_t *mp_obj_get_array_fixed_n(mp_obj_t o, machine_int_t n); mp_obj_t *mp_obj_get_array_fixed_n(mp_obj_t o, machine_int_t n);
uint mp_get_index(const mp_obj_type_t *type, machine_uint_t len, mp_obj_t index); uint mp_get_index(const mp_obj_type_t *type, machine_uint_t len, mp_obj_t index);
mp_obj_t mp_obj_len_maybe(mp_obj_t o_in); /* may return NULL */ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in); /* may return NULL */
...@@ -279,8 +280,13 @@ void mp_obj_exception_get_traceback(mp_obj_t self_in, machine_uint_t *n, machine ...@@ -279,8 +280,13 @@ void mp_obj_exception_get_traceback(mp_obj_t self_in, machine_uint_t *n, machine
// str // str
extern const mp_obj_type_t str_type; extern const mp_obj_type_t str_type;
qstr mp_obj_str_get(mp_obj_t self_in); mp_obj_t mp_obj_str_builder_start(uint len, byte **data);
void mp_obj_str_print_qstr(void (*print)(void *env, const char *fmt, ...), void *env, qstr q, mp_print_kind_t kind); mp_obj_t mp_obj_str_builder_end(mp_obj_t o_in);
bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2);
uint mp_obj_str_get_hash(mp_obj_t self_in);
uint mp_obj_str_get_len(mp_obj_t self_in);
const char *mp_obj_str_get_str(mp_obj_t self_in); // use this only if you need the string to be null terminated
const byte *mp_obj_str_get_data(mp_obj_t self_in, uint *len);
#if MICROPY_ENABLE_FLOAT #if MICROPY_ENABLE_FLOAT
// float // float
......
...@@ -167,9 +167,11 @@ static mp_obj_t array_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m ...@@ -167,9 +167,11 @@ static mp_obj_t array_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m
switch (n_args) { switch (n_args) {
case 2: case 2:
{ {
const char *code = qstr_str(mp_obj_str_get(args[0])); // TODO check args
uint l;
const byte *s = mp_obj_str_get_data(args[0], &l);
mp_obj_t initializer = args[1]; mp_obj_t initializer = args[1];
return array_construct(*code, initializer); return array_construct(*s, initializer);
} }
default: default:
......
...@@ -56,8 +56,7 @@ mp_obj_t fun_native_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_ ...@@ -56,8 +56,7 @@ mp_obj_t fun_native_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_
// TODO if n_kw==0 then don't allocate any memory for map (either pass NULL or allocate it on the heap) // TODO if n_kw==0 then don't allocate any memory for map (either pass NULL or allocate it on the heap)
mp_map_t *kw_args = mp_map_new(n_kw); mp_map_t *kw_args = mp_map_new(n_kw);
for (int i = 0; i < 2 * n_kw; i += 2) { for (int i = 0; i < 2 * n_kw; i += 2) {
qstr name = mp_obj_str_get(args[n_args + i]); mp_map_lookup(kw_args, args[n_args + i], MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = args[n_args + i + 1];
mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(name), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = args[n_args + i + 1];
} }
mp_obj_t res = ((mp_fun_kw_t)self->fun)(n_args, args, kw_args); mp_obj_t res = ((mp_fun_kw_t)self->fun)(n_args, args, kw_args);
// TODO clean up kw_args // TODO clean up kw_args
...@@ -214,9 +213,10 @@ machine_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { ...@@ -214,9 +213,10 @@ machine_uint_t convert_obj_for_inline_asm(mp_obj_t obj) {
return 0; return 0;
} else if (obj == mp_const_true) { } else if (obj == mp_const_true) {
return 1; return 1;
} else if (MP_OBJ_IS_TYPE(obj, &str_type)) { } else if (MP_OBJ_IS_STR(obj)) {
// pointer to the string (it's probably constant though!) // pointer to the string (it's probably constant though!)
return (machine_uint_t)qstr_str(mp_obj_str_get(obj)); uint l;
return (machine_uint_t)mp_obj_str_get_data(obj, &l);
#if MICROPY_ENABLE_FLOAT #if MICROPY_ENABLE_FLOAT
} else if (MP_OBJ_IS_TYPE(obj, &float_type)) { } else if (MP_OBJ_IS_TYPE(obj, &float_type)) {
// convert float to int (could also pass in float registers) // convert float to int (could also pass in float registers)
......
...@@ -20,34 +20,35 @@ static mp_obj_t int_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_ ...@@ -20,34 +20,35 @@ static mp_obj_t int_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_
return MP_OBJ_NEW_SMALL_INT(0); return MP_OBJ_NEW_SMALL_INT(0);
case 1: case 1:
if (MP_OBJ_IS_TYPE(args[0], &str_type)) { if (MP_OBJ_IS_STR(args[0])) {
// a string, parse it // a string, parse it
return MP_OBJ_NEW_SMALL_INT(strtonum(qstr_str(mp_obj_get_qstr(args[0])), 0)); uint l;
const byte *s = mp_obj_str_get_data(args[0], &l);
return MP_OBJ_NEW_SMALL_INT(strtonum((const char*)s, 0));
} else { } else {
return MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(args[0])); return MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(args[0]));
} }
case 2: case 2:
{
// should be a string, parse it // should be a string, parse it
// TODO proper error checking of argument types // TODO proper error checking of argument types
return MP_OBJ_NEW_SMALL_INT(strtonum(qstr_str(mp_obj_get_qstr(args[0])), mp_obj_get_int(args[1]))); uint l;
const byte *s = mp_obj_str_get_data(args[0], &l);
return MP_OBJ_NEW_SMALL_INT(strtonum((const char*)s, mp_obj_get_int(args[1])));
}
default: default:
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "int takes at most 2 arguments, %d given", (void*)(machine_int_t)n_args)); nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "int takes at most 2 arguments, %d given", (void*)(machine_int_t)n_args));
} }
} }
const mp_obj_type_t int_type = {
{ &mp_const_type },
"int",
.print = int_print,
.make_new = int_make_new,
.binary_op = int_binary_op,
};
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
// This is called only for non-SMALL_INT
void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
if (MP_OBJ_IS_SMALL_INT(self_in)) {
print(env, "%d", (int)MP_OBJ_SMALL_INT_VALUE(self_in));
}
} }
// This is called only for non-SMALL_INT // This is called only for non-SMALL_INT
...@@ -88,4 +89,12 @@ machine_int_t mp_obj_int_get_checked(mp_obj_t self_in) { ...@@ -88,4 +89,12 @@ machine_int_t mp_obj_int_get_checked(mp_obj_t self_in) {
return MP_OBJ_SMALL_INT_VALUE(self_in); return MP_OBJ_SMALL_INT_VALUE(self_in);
} }
#endif #endif // MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
const mp_obj_type_t int_type = {
{ &mp_const_type },
"int",
.print = int_print,
.make_new = int_make_new,
.binary_op = int_binary_op,
};
...@@ -24,8 +24,12 @@ static mp_obj_t mp_obj_new_int_from_ll(long long val); ...@@ -24,8 +24,12 @@ static mp_obj_t mp_obj_new_int_from_ll(long long val);
#endif #endif
void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_int_t *self = self_in; if (MP_OBJ_IS_SMALL_INT(self_in)) {
print(env, "%lld" SUFFIX, self->val); print(env, "%d", (int)MP_OBJ_SMALL_INT_VALUE(self_in));
} else {
mp_obj_int_t *self = self_in;
print(env, "%lld" SUFFIX, self->val);
}
} }
mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
......
...@@ -64,7 +64,7 @@ mp_obj_t mp_obj_new_module(qstr module_name) { ...@@ -64,7 +64,7 @@ mp_obj_t mp_obj_new_module(qstr module_name) {
o->name = module_name; o->name = module_name;
o->globals = mp_map_new(1); o->globals = mp_map_new(1);
el->value = o; el->value = o;
mp_map_lookup(o->globals, MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = mp_obj_new_str(module_name); mp_map_lookup(o->globals, MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = MP_OBJ_NEW_QSTR(module_name);
return o; return o;
} }
......
...@@ -14,28 +14,35 @@ ...@@ -14,28 +14,35 @@
typedef struct _mp_obj_str_t { typedef struct _mp_obj_str_t {
mp_obj_base_t base; mp_obj_base_t base;
qstr qstr; machine_uint_t hash : 16; // XXX here we assume the hash size is 16 bits (it is at the moment; see qstr.c)
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
byte data[];
} mp_obj_str_t; } mp_obj_str_t;
static mp_obj_t mp_obj_new_str_iterator(mp_obj_str_t *str, int cur); // use this macro to extract the string hash
#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; }
// use this macro to extract the string length
#define GET_STR_LEN(str_obj_in, str_len) uint str_len; if (MP_OBJ_IS_QSTR(str_obj_in)) { str_len = qstr_len(MP_OBJ_QSTR_VALUE(str_obj_in)); } else { str_len = ((mp_obj_str_t*)str_obj_in)->len; }
// use this macro to extract the string data and length
#define GET_STR_DATA_LEN(str_obj_in, str_data, str_len) const byte *str_data; uint str_len; if (MP_OBJ_IS_QSTR(str_obj_in)) { str_data = qstr_data(MP_OBJ_QSTR_VALUE(str_obj_in), &str_len); } else { str_len = ((mp_obj_str_t*)str_obj_in)->len; str_data = ((mp_obj_str_t*)str_obj_in)->data; }
static mp_obj_t mp_obj_new_str_iterator(mp_obj_t str, int cur);
/******************************************************************************/ /******************************************************************************/
/* str */ /* str */
void mp_obj_str_print_qstr(void (*print)(void *env, const char *fmt, ...), void *env, qstr q, mp_print_kind_t kind) { void str_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
GET_STR_DATA_LEN(self_in, str_data, str_len);
if (kind == PRINT_STR) { if (kind == PRINT_STR) {
print(env, "%s", qstr_str(q)); print(env, "%.*s", str_len, str_data);
} else { } else {
// TODO need to escape chars etc // TODO need to escape chars etc
print(env, "'%s'", qstr_str(q)); print(env, "'%.*s'", str_len, str_data);
} }
} }
void str_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_str_t *self = self_in;
mp_obj_str_print_qstr(print, env, self->qstr, kind);
}
// like strstr but with specified length and allows \0 bytes // like strstr but with specified length and allows \0 bytes
// TODO replace with something more efficient/standard // TODO replace with something more efficient/standard
static const byte *find_subbytes(const byte *haystack, uint hlen, const byte *needle, uint nlen) { static const byte *find_subbytes(const byte *haystack, uint hlen, const byte *needle, uint nlen) {
...@@ -57,16 +64,14 @@ static const byte *find_subbytes(const byte *haystack, uint hlen, const byte *ne ...@@ -57,16 +64,14 @@ static const byte *find_subbytes(const byte *haystack, uint hlen, const byte *ne
} }
mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
mp_obj_str_t *lhs = lhs_in; GET_STR_DATA_LEN(lhs_in, lhs_data, lhs_len);
uint lhs_len;
const byte *lhs_data = qstr_data(lhs->qstr, &lhs_len);
switch (op) { switch (op) {
case RT_BINARY_OP_SUBSCR: case RT_BINARY_OP_SUBSCR:
// TODO: need predicate to check for int-like type (bools are such for example) // TODO: need predicate to check for int-like type (bools are such for example)
// ["no", "yes"][1 == 2] is common idiom // ["no", "yes"][1 == 2] is common idiom
if (MP_OBJ_IS_SMALL_INT(rhs_in)) { if (MP_OBJ_IS_SMALL_INT(rhs_in)) {
uint index = mp_get_index(lhs->base.type, lhs_len, rhs_in); uint index = mp_get_index(mp_obj_get_type(lhs_in), lhs_len, rhs_in);
return mp_obj_new_str(qstr_from_strn((const char*)lhs_data + index, 1)); return mp_obj_new_str(lhs_data + index, 1, true);
#if MICROPY_ENABLE_SLICE #if MICROPY_ENABLE_SLICE
} else if (MP_OBJ_IS_TYPE(rhs_in, &slice_type)) { } else if (MP_OBJ_IS_TYPE(rhs_in, &slice_type)) {
machine_int_t start, stop, step; machine_int_t start, stop, step;
...@@ -89,7 +94,7 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { ...@@ -89,7 +94,7 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
} else if (stop > lhs_len) { } else if (stop > lhs_len) {
stop = lhs_len; stop = lhs_len;
} }
return mp_obj_new_str(qstr_from_strn((const char*)lhs_data + start, stop - start)); return mp_obj_new_str(lhs_data + start, stop - start, false);
#endif #endif
} else { } else {
// Message doesn't match CPython, but we don't have so much bytes as they // Message doesn't match CPython, but we don't have so much bytes as they
...@@ -99,37 +104,48 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { ...@@ -99,37 +104,48 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
case RT_BINARY_OP_ADD: case RT_BINARY_OP_ADD:
case RT_BINARY_OP_INPLACE_ADD: case RT_BINARY_OP_INPLACE_ADD:
if (MP_OBJ_IS_TYPE(rhs_in, &str_type)) { if (MP_OBJ_IS_STR(rhs_in)) {
// add 2 strings