Commit 13e64f06 authored by John R. Lenton's avatar John R. Lenton
Browse files

Merge remote-tracking branch 'upstream/master' into containment

parents 813edf63 34f813ee
......@@ -19,3 +19,6 @@
######################
*.swp
# Build directory
######################
build/
logo/vector-logo-2.png

88.7 KB | W: | H:

logo/vector-logo-2.png

90.5 KB | W: | H:

logo/vector-logo-2.png
logo/vector-logo-2.png
logo/vector-logo-2.png
logo/vector-logo-2.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -32,13 +32,13 @@
inkscape:window-height="1086"
id="namedview127"
showgrid="false"
inkscape:zoom="1.1668212"
inkscape:cx="347.36024"
inkscape:cy="357.11268"
inkscape:zoom="5.4082024"
inkscape:cx="367.53099"
inkscape:cy="675.33912"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="layer6" />
inkscape:current-layer="layer4" />
<defs
id="defs4">
<linearGradient
......@@ -693,6 +693,12 @@
d="m 197.35296,637.05028 26.22631,-36.06117 193.41902,1.96697 -36.06117,45.24038 -89.82511,-9.83486 7.21224,-15.08013 -43.27341,3.93395 z"
id="path5039"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffff;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
d="m 344.52579,102.27483 15.42653,-40.280383 23.99682,-15.426528 17.14059,9.427323 3.42812,11.998411 28.28197,-6.856235 14.56949,21.425734 0.85703,38.566318 -13.71247,30.85306 -21.42573,9.42732 -20.5687,-12.85544 -20.56871,8.57029 -24.98883,-23.71207 z"
id="path3253"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccc" />
</g>
<g
inkscape:groupmode="layer"
......
......@@ -1316,7 +1316,7 @@ void compile_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
void compile_assert_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
int l_end = comp_next_label(comp);
c_if_cond(comp, pns->nodes[0], true, l_end);
EMIT(load_id, MP_QSTR_AssertionError);
EMIT(load_global, MP_QSTR_AssertionError); // we load_global instead of load_id, to be consistent with CPython
if (!MP_PARSE_NODE_IS_NULL(pns->nodes[1])) {
// assertion message
compile_node(comp, pns->nodes[1]);
......
......@@ -45,10 +45,7 @@ static void emit_pass1_load_id(emit_t *emit, qstr qstr) {
bool added;
id_info_t *id = scope_find_or_add_id(emit->scope, qstr, &added);
if (added) {
if (qstr == MP_QSTR_AssertionError) {
// TODO how much of a hack is this?
id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
} else if (strcmp(qstr_str(qstr), "super") == 0 && emit->scope->kind == SCOPE_FUNCTION) {
if (strcmp(qstr_str(qstr), "super") == 0 && emit->scope->kind == SCOPE_FUNCTION) {
// special case, super is a global, and also counts as use of __class__
id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
id_info_t *id2 = scope_find_local_in_parent(emit->scope, emit->qstr___class__);
......
......@@ -8,15 +8,8 @@
#if MICROPY_ENABLE_GC
// a machine word is big enough to hold a pointer
/*
#define BYTES_PER_WORD (8)
typedef unsigned long machine_uint_t;
*/
typedef unsigned char byte;
#define BITS_PER_BYTE (8)
#define BITS_PER_WORD (BITS_PER_BYTE * BYTES_PER_WORD)
#define WORDS_PER_BLOCK (4)
#define BYTES_PER_BLOCK (WORDS_PER_BLOCK * BYTES_PER_WORD)
#define STACK_SIZE (64) // tunable; minimum is 1
......
......@@ -299,8 +299,15 @@ static void mp_lexer_next_token_into(mp_lexer_t *lex, mp_token_t *tok, bool firs
// backslash (outside string literals) must appear just before a physical newline
next_char(lex);
if (!is_physical_newline(lex)) {
// TODO SyntaxError
assert(0);
// SyntaxError: unexpected character after line continuation character
tok->src_name = lex->name;
tok->src_line = lex->line;
tok->src_column = lex->column;
tok->kind = MP_TOKEN_BAD_LINE_CONTINUATION;
vstr_reset(&lex->vstr);
tok->str = vstr_str(&lex->vstr);
tok->len = 0;
return;
} else {
next_char(lex);
}
......
......@@ -10,19 +10,20 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_INVALID,
MP_TOKEN_DEDENT_MISMATCH,
MP_TOKEN_LONELY_STRING_OPEN,
MP_TOKEN_BAD_LINE_CONTINUATION,
MP_TOKEN_NEWLINE, // 4
MP_TOKEN_INDENT, // 5
MP_TOKEN_DEDENT, // 6
MP_TOKEN_NEWLINE, // 5
MP_TOKEN_INDENT, // 6
MP_TOKEN_DEDENT, // 7
MP_TOKEN_NAME, // 7
MP_TOKEN_NAME, // 8
MP_TOKEN_NUMBER,
MP_TOKEN_STRING,
MP_TOKEN_BYTES,
MP_TOKEN_ELLIPSIS,
MP_TOKEN_KW_FALSE, // 12
MP_TOKEN_KW_FALSE, // 13
MP_TOKEN_KW_NONE,
MP_TOKEN_KW_TRUE,
MP_TOKEN_KW_AND,
......@@ -31,7 +32,7 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_KW_BREAK,
MP_TOKEN_KW_CLASS,
MP_TOKEN_KW_CONTINUE,
MP_TOKEN_KW_DEF, // 21
MP_TOKEN_KW_DEF, // 22
MP_TOKEN_KW_DEL,
MP_TOKEN_KW_ELIF,
MP_TOKEN_KW_ELSE,
......@@ -41,7 +42,7 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_KW_FROM,
MP_TOKEN_KW_GLOBAL,
MP_TOKEN_KW_IF,
MP_TOKEN_KW_IMPORT, // 31
MP_TOKEN_KW_IMPORT, // 32
MP_TOKEN_KW_IN,
MP_TOKEN_KW_IS,
MP_TOKEN_KW_LAMBDA,
......@@ -51,12 +52,12 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_KW_PASS,
MP_TOKEN_KW_RAISE,
MP_TOKEN_KW_RETURN,
MP_TOKEN_KW_TRY, // 41
MP_TOKEN_KW_TRY, // 42
MP_TOKEN_KW_WHILE,
MP_TOKEN_KW_WITH,
MP_TOKEN_KW_YIELD,
MP_TOKEN_OP_PLUS, // 45
MP_TOKEN_OP_PLUS, // 46
MP_TOKEN_OP_MINUS,
MP_TOKEN_OP_STAR,
MP_TOKEN_OP_DBL_STAR,
......@@ -66,7 +67,7 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_OP_LESS,
MP_TOKEN_OP_DBL_LESS,
MP_TOKEN_OP_MORE,
MP_TOKEN_OP_DBL_MORE, // 55
MP_TOKEN_OP_DBL_MORE, // 56
MP_TOKEN_OP_AMPERSAND,
MP_TOKEN_OP_PIPE,
MP_TOKEN_OP_CARET,
......@@ -76,7 +77,7 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_OP_DBL_EQUAL,
MP_TOKEN_OP_NOT_EQUAL,
MP_TOKEN_DEL_PAREN_OPEN, // 64
MP_TOKEN_DEL_PAREN_OPEN, // 65
MP_TOKEN_DEL_PAREN_CLOSE,
MP_TOKEN_DEL_BRACKET_OPEN,
MP_TOKEN_DEL_BRACKET_CLOSE,
......@@ -86,7 +87,7 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_DEL_COLON,
MP_TOKEN_DEL_PERIOD,
MP_TOKEN_DEL_SEMICOLON,
MP_TOKEN_DEL_AT, // 74
MP_TOKEN_DEL_AT, // 75
MP_TOKEN_DEL_EQUAL,
MP_TOKEN_DEL_PLUS_EQUAL,
MP_TOKEN_DEL_MINUS_EQUAL,
......@@ -96,7 +97,7 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_DEL_PERCENT_EQUAL,
MP_TOKEN_DEL_AMPERSAND_EQUAL,
MP_TOKEN_DEL_PIPE_EQUAL,
MP_TOKEN_DEL_CARET_EQUAL, // 84
MP_TOKEN_DEL_CARET_EQUAL, // 85
MP_TOKEN_DEL_DBL_MORE_EQUAL,
MP_TOKEN_DEL_DBL_LESS_EQUAL,
MP_TOKEN_DEL_DBL_STAR_EQUAL,
......
......@@ -132,28 +132,45 @@ void mp_set_init(mp_set_t *set, int n) {
set->table = m_new0(mp_obj_t, set->alloc);
}
mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, bool add_if_not_found) {
int hash = mp_obj_hash(index);
assert(set->alloc); /* FIXME: if alloc is ever 0 when doing a lookup, this'll fail: */
int pos = hash % set->alloc;
static void mp_set_rehash(mp_set_t *set) {
int old_alloc = set->alloc;
mp_obj_t *old_table = set->table;
set->alloc = get_doubling_prime_greater_or_equal_to(set->alloc + 1);
set->used = 0;
set->table = m_new0(mp_obj_t, set->alloc);
for (int i = 0; i < old_alloc; i++) {
if (old_table[i] != NULL) {
mp_set_lookup(set, old_table[i], true);
}
}
m_del(mp_obj_t, old_table, old_alloc);
}
mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, mp_map_lookup_kind_t lookup_kind) {
int hash;
int pos;
if (set->alloc == 0) {
if (lookup_kind & MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
mp_set_rehash(set);
} else {
return NULL;
}
}
if (lookup_kind & MP_MAP_LOOKUP_FIRST) {
hash = 0;
pos = 0;
} else {
hash = mp_obj_hash(index);;
pos = hash % set->alloc;
}
for (;;) {
mp_obj_t elem = set->table[pos];
if (elem == MP_OBJ_NULL) {
// not in table
if (add_if_not_found) {
if (lookup_kind & MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
if (set->used + 1 >= set->alloc) {
// not enough room in table, rehash it
int old_alloc = set->alloc;
mp_obj_t *old_table = set->table;
set->alloc = get_doubling_prime_greater_or_equal_to(set->alloc + 1);
set->used = 0;
set->table = m_new(mp_obj_t, set->alloc);
for (int i = 0; i < old_alloc; i++) {
if (old_table[i] != NULL) {
mp_set_lookup(set, old_table[i], true);
}
}
m_del(mp_obj_t, old_table, old_alloc);
mp_set_rehash(set);
// restart the search for the new element
pos = hash % set->alloc;
} else {
......@@ -161,11 +178,17 @@ mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, bool add_if_not_found) {
set->table[pos] = index;
return index;
}
} else if (lookup_kind & MP_MAP_LOOKUP_FIRST) {
pos++;
} else {
return MP_OBJ_NULL;
}
} else if (mp_obj_equal(elem, index)) {
} else if (lookup_kind & MP_MAP_LOOKUP_FIRST || mp_obj_equal(elem, index)) {
// found it
if (lookup_kind & MP_MAP_LOOKUP_REMOVE_IF_FOUND) {
set->used--;
set->table[pos] = NULL;
}
return elem;
} else {
// not yet found, keep searching in this table
......@@ -173,3 +196,13 @@ mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, bool add_if_not_found) {
}
}
}
void mp_set_clear(mp_set_t *set) {
set->used = 0;
machine_uint_t a = set->alloc;
set->alloc = 0;
set->table = m_renew(mp_obj_t, set->table, a, set->alloc);
for (uint i=0; i<set->alloc; i++) {
set->table[i] = NULL;
}
}
......@@ -19,9 +19,10 @@ typedef struct _mp_set_t {
} mp_set_t;
typedef enum _mp_map_lookup_kind_t {
MP_MAP_LOOKUP,
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND,
MP_MAP_LOOKUP_REMOVE_IF_FOUND,
MP_MAP_LOOKUP, // 0
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND, // 1
MP_MAP_LOOKUP_REMOVE_IF_FOUND, // 2
MP_MAP_LOOKUP_FIRST = 4,
} mp_map_lookup_kind_t;
int get_doubling_prime_greater_or_equal_to(int x);
......@@ -31,4 +32,5 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t
void mp_map_clear(mp_map_t *map);
void mp_set_init(mp_set_t *set, int n);
mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, bool add_if_not_found);
mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, mp_map_lookup_kind_t lookup_kind);
void mp_set_clear(mp_set_t *set);
......@@ -62,6 +62,18 @@
#define MICROPY_ENABLE_LEXER_UNIX (0)
#endif
// Long int implementation
#define MICROPY_LONGINT_IMPL_NONE (0)
#define MICROPY_LONGINT_IMPL_LONGLONG (1)
#ifndef MICROPY_LONGINT_IMPL
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
#endif
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
typedef long long mp_longint_impl_t;
#endif
// Whether to support float and complex types
#ifndef MICROPY_ENABLE_FLOAT
#define MICROPY_ENABLE_FLOAT (0)
......@@ -76,6 +88,11 @@
/*****************************************************************************/
/* Miscellaneous settings */
#define BITS_PER_BYTE (8)
#define BITS_PER_WORD (BITS_PER_BYTE * BYTES_PER_WORD)
// machine_int_t value with most significant bit set
#define WORD_MSBIT_HIGH (1 << (BYTES_PER_WORD * 8 - 1))
// printf format spec to use for machine_int_t and friends
#ifndef INT_FMT
#ifdef __LP64__
......
......@@ -117,6 +117,13 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t 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 {
mp_obj_base_t *o = o1;
if (o->type->binary_op != NULL) {
mp_obj_t r = o->type->binary_op(RT_COMPARE_OP_EQUAL, o1, o2);
if (r != MP_OBJ_NULL) {
return r == mp_const_true ? true : false;
}
}
// TODO: Debugging helper
printf("Equality for '%s' and '%s' types not yet implemented\n", mp_obj_get_type_str(o1), mp_obj_get_type_str(o2));
assert(0);
......@@ -231,7 +238,7 @@ uint mp_get_index(const mp_obj_type_t *type, machine_uint_t len, mp_obj_t index)
}
}
// may return NULL
// may return MP_OBJ_NULL
mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) {
mp_small_int_t len = 0;
if (MP_OBJ_IS_TYPE(o_in, &str_type)) {
......@@ -249,7 +256,7 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) {
} else if (MP_OBJ_IS_TYPE(o_in, &dict_type)) {
len = mp_obj_dict_len(o_in);
} else {
return NULL;
return MP_OBJ_NULL;
}
return MP_OBJ_NEW_SMALL_INT(len);
}
......@@ -34,6 +34,8 @@ typedef struct _mp_obj_base_t mp_obj_base_t;
// - xxxx...xx10: a qstr, bits 2 and above are the value
// - xxxx...xx00: a pointer to an mp_obj_base_t
// In SMALL_INT, next-to-highest bits is used as sign, so both must match for value in range
#define MP_OBJ_FITS_SMALL_INT(n) ((((n) ^ ((n) << 1)) & WORD_MSBIT_HIGH) == 0)
#define MP_OBJ_IS_SMALL_INT(o) ((((mp_small_int_t)(o)) & 1) != 0)
#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)
......@@ -59,6 +61,15 @@ typedef struct _mp_obj_base_t mp_obj_base_t;
#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, n_args_min, n_args_max, (mp_fun_var_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, true, 0, (~((machine_uint_t)0)), (mp_fun_kw_t)fun_name)
// These macros are used to declare and define constant staticmethond and classmethod objects
// You can put "static" in front of the definitions to make them local
#define MP_DECLARE_CONST_STATICMETHOD_OBJ(obj_name) extern const mp_obj_staticmethod_t obj_name
#define MP_DECLARE_CONST_CLASSMETHOD_OBJ(obj_name) extern const mp_obj_classmethod_t obj_name
#define MP_DEFINE_CONST_STATICMETHOD_OBJ(obj_name, fun_name) const mp_obj_staticmethod_t obj_name = {{&mp_type_staticmethod}, fun_name}
#define MP_DEFINE_CONST_CLASSMETHOD_OBJ(obj_name, fun_name) const mp_obj_classmethod_t obj_name = {{&mp_type_classmethod}, fun_name}
// Need to declare this here so we are not dependent on map.h
struct _mp_map_t;
struct _mp_map_elem_t;
......@@ -187,6 +198,8 @@ mp_obj_t mp_obj_new_none(void);
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_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_long_str(const char *s);
mp_obj_t mp_obj_new_str(qstr qstr);
#if MICROPY_ENABLE_FLOAT
mp_obj_t mp_obj_new_float(mp_float_t val);
......@@ -316,3 +329,18 @@ extern const mp_obj_type_t gen_instance_type;
extern const mp_obj_type_t module_type;
mp_obj_t mp_obj_new_module(qstr module_name);
struct _mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in);
// staticmethod and classmethod types; defined here so we can make const versions
extern const mp_obj_type_t mp_type_staticmethod;
extern const mp_obj_type_t mp_type_classmethod;
typedef struct _mp_obj_staticmethod_t {
mp_obj_base_t base;
mp_obj_t fun;
} mp_obj_staticmethod_t;
typedef struct _mp_obj_classmethod_t {
mp_obj_base_t base;
mp_obj_t fun;
} mp_obj_classmethod_t;
......@@ -145,6 +145,35 @@ static mp_obj_t dict_copy(mp_obj_t self_in) {
}
static MP_DEFINE_CONST_FUN_OBJ_1(dict_copy_obj, dict_copy);
// this is a classmethod
static mp_obj_t dict_fromkeys(int n_args, const mp_obj_t *args) {
assert(2 <= n_args && n_args <= 3);
mp_obj_t iter = rt_getiter(args[1]);
mp_obj_t len = mp_obj_len_maybe(iter);
mp_obj_t value = mp_const_none;
mp_obj_t next = NULL;
mp_obj_dict_t *self = NULL;
if (n_args > 2) {
value = args[2];
}
if (len == MP_OBJ_NULL) {
/* object's type doesn't have a __len__ slot */
self = mp_obj_new_dict(0);
} else {
self = mp_obj_new_dict(MP_OBJ_SMALL_INT_VALUE(len));
}
while ((next = rt_iternext(iter)) != mp_const_stop_iteration) {
mp_map_lookup(&self->map, next, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;
}
return self;
}
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(dict_fromkeys_fun_obj, 2, 3, dict_fromkeys);
static MP_DEFINE_CONST_CLASSMETHOD_OBJ(dict_fromkeys_obj, (const mp_obj_t)&dict_fromkeys_fun_obj);
static mp_obj_t dict_get_helper(mp_map_t *self, mp_obj_t key, mp_obj_t deflt, mp_map_lookup_kind_t lookup_kind) {
mp_map_elem_t *elem = mp_map_lookup(self, key, lookup_kind);
mp_obj_t value;
......@@ -286,23 +315,18 @@ static mp_obj_t dict_view_it_iternext(mp_obj_t self_in) {
if (next != NULL) {
switch (self->kind) {
case MP_DICT_VIEW_ITEMS:
{
mp_obj_t items[] = {next->key, next->value};
return mp_obj_new_tuple(2, items);
}
case MP_DICT_VIEW_KEYS:
{
return next->key;
}
case MP_DICT_VIEW_VALUES:
{
return next->value;
}
default:
{
assert(0); /* can't happen */
}
case MP_DICT_VIEW_ITEMS:
{
mp_obj_t items[] = {next->key, next->value};
return mp_obj_new_tuple(2, items);
}
case MP_DICT_VIEW_KEYS:
return next->key;
case MP_DICT_VIEW_VALUES:
return next->value;
default:
assert(0); /* can't happen */
return mp_const_none;
}
} else {
return mp_const_stop_iteration;
......@@ -326,7 +350,6 @@ static mp_obj_t dict_view_getiter(mp_obj_t view_in) {
return o;
}
static void dict_view_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
assert(MP_OBJ_IS_TYPE(self_in, &dict_view_type));
mp_obj_dict_view_t *self = self_in;
......@@ -370,7 +393,6 @@ mp_obj_t mp_obj_new_dict_view(mp_obj_dict_t *dict, mp_dict_view_kind_t kind) {
return o;
}
static mp_obj_t dict_view(mp_obj_t self_in, mp_dict_view_kind_t kind) {
assert(MP_OBJ_IS_TYPE(self_in, &dict_type));
mp_obj_dict_t *self = self_in;
......@@ -392,67 +414,13 @@ static mp_obj_t dict_values(mp_obj_t self_in) {
}
static MP_DEFINE_CONST_FUN_OBJ_1(dict_values_obj, dict_values);
/******************************************************************************/
/* dict metaclass */
static mp_obj_t dict_fromkeys(int n_args, const mp_obj_t *args) {
assert(2 <= n_args && n_args <= 3);
mp_obj_t iter = rt_getiter(args[1]);
mp_obj_t len = mp_obj_len_maybe(iter);
mp_obj_t value = mp_const_none;
mp_obj_t next = NULL;
mp_obj_dict_t *self = NULL;
if (n_args > 2) {
value = args[2];
}
if (len == NULL) {
/* object's type doesn't have a __len__ slot */
self = mp_obj_new_dict(0);
} else {
self = mp_obj_new_dict(MP_OBJ_SMALL_INT_VALUE(len));
}
while ((next = rt_iternext(iter)) != mp_const_stop_iteration) {
mp_map_lookup(&self->map, next, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;
}
return self;
}
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(dict_fromkeys_obj, 2, 3, dict_fromkeys);
static const mp_method_t dict_class_methods[] = {
{ "fromkeys", &dict_fromkeys_obj },
{ NULL, NULL }, // end-of-list sentinel
};
/* this should be unnecessary when inheritance works */
static void dict_class_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
print(env, "<class 'dict'>");
}
/* this should be unnecessary when inheritance works */
static mp_obj_t dict_class_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
return rt_build_map(0);
}
static const mp_obj_type_t dict_class = {
{ &mp_const_type },
"dict_class",
.print = dict_class_print,
.methods = dict_class_methods,
.call_n = dict_class_call_n,
};
/******************************************************************************/
/* dict constructors & etc */
/* dict constructors & public C API */
static const mp_method_t dict_type_methods[] = {
{ "clear", &dict_clear_obj },
{ "copy", &dict_copy_obj },
{ "fromkeys", &dict_fromkeys_obj },
{ "get", &dict_get_obj },
{ "items", &dict_items_obj },
{ "keys", &dict_keys_obj },
......@@ -465,7 +433,7 @@ static const mp_method_t dict_type_methods[] = {
};
const mp_obj_type_t dict_type = {
{ &dict_class },
{ &mp_const_type },
"dict",
.print = dict_print,
.make_new = dict_make_new,
......
......@@ -11,8 +11,16 @@
typedef struct _mp_obj_int_t {
mp_obj_base_t base;
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
mp_longint_impl_t val;
#endif
} mp_obj_int_t;
void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in);
mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in);
// This dispatcher function is expected to be independent of the implementation
// of long int
static mp_obj_t int_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
switch (n_args) {
case 0:
......@@ -20,7 +28,7 @@ static mp_obj_t int_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args)
case 1:
// TODO allow string as arg and parse it
return MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(args[0]));
return mp_obj_new_int(mp_obj_get_int(args[0]));
//case 2:
// TODO, parse with given base
......@@ -33,9 +41,41 @@ static mp_obj_t int_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *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
// 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) {
}
// This is called only for non-SMALL_INT