summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--py/builtin.c15
-rw-r--r--py/builtin.h1
-rw-r--r--py/builtinimport.c1
-rw-r--r--py/builtintables.c1
-rw-r--r--py/compile.c2
-rw-r--r--py/compile.h2
-rw-r--r--py/emitglue.c25
-rw-r--r--py/emitglue.h3
-rw-r--r--py/lexer.c22
-rw-r--r--py/modstruct.c84
-rw-r--r--py/mpz.c4
-rw-r--r--py/obj.c7
-rw-r--r--py/objarray.c1
-rw-r--r--py/objbool.c10
-rw-r--r--py/objcomplex.c9
-rw-r--r--py/objfloat.c7
-rw-r--r--py/objfun.c1
-rw-r--r--py/objgenerator.c1
-rw-r--r--py/objint.c7
-rw-r--r--py/objint_longlong.c1
-rw-r--r--py/objlist.c7
-rw-r--r--py/objnamedtuple.c1
-rw-r--r--py/objproperty.c5
-rw-r--r--py/objset.c17
-rw-r--r--py/objstr.c22
-rw-r--r--py/objtuple.c8
-rw-r--r--py/objtype.c3
-rw-r--r--py/objzip.c2
-rw-r--r--py/qstrdefs.h1
-rw-r--r--py/runtime.c14
-rw-r--r--py/runtime.h2
-rw-r--r--py/sequence.c1
-rw-r--r--py/showbc.c6
-rw-r--r--py/stream.c1
-rw-r--r--py/vm.c2
-rw-r--r--tests/basics/frozenset1.py3
-rw-r--r--tests/basics/hasattr1.py29
-rw-r--r--tests/basics/int-big-and.py8
-rw-r--r--tests/basics/int-long.py12
-rw-r--r--tests/basics/string-join.py12
-rw-r--r--tests/basics/string-slice.py3
-rw-r--r--tests/basics/string_split.py2
-rw-r--r--tests/basics/struct1.py5
-rw-r--r--unix/main.c5
-rw-r--r--unix/modffi.c1
-rw-r--r--unix/modsocket.c1
-rw-r--r--unix/mpconfigport.h16
-rw-r--r--windows/mpconfigport.h2
49 files changed, 293 insertions, 106 deletions
diff --git a/.travis.yml b/.travis.yml
index f0b5b561b6..e6c12b9677 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,7 +7,7 @@ before_script:
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded
- sudo apt-get update -qq
- - sudo apt-get install -y python3.3 python3 gcc-4.7 gcc-arm-none-eabi qemu-system
+ - sudo apt-get install -y python3.3 python3 gcc-4.7 gcc-arm-none-eabi qemu-system mingw32
script:
- make -C unix CC=gcc-4.7
@@ -15,6 +15,8 @@ script:
- make -C bare-arm
- make -C qemu-arm
- make -C stmhal
+ - make -C windows CROSS_COMPILE=i586-mingw32msvc-
+
- (cd tests && MICROPY_CPYTHON3=python3.3 ./run-tests)
after_failure:
diff --git a/py/builtin.c b/py/builtin.c
index 8d5779e42c..7f0d2a4d9f 100644
--- a/py/builtin.c
+++ b/py/builtin.c
@@ -462,6 +462,21 @@ STATIC mp_obj_t mp_builtin_getattr(uint n_args, const mp_obj_t *args) {
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_getattr_obj, 2, 3, mp_builtin_getattr);
+STATIC mp_obj_t mp_builtin_hasattr(mp_obj_t object_in, mp_obj_t attr_in) {
+ assert(MP_OBJ_IS_QSTR(attr_in));
+
+ mp_obj_t dest[2];
+ // TODO: https://docs.python.org/3.3/library/functions.html?highlight=hasattr#hasattr
+ // explicitly says "This is implemented by calling getattr(object, name) and seeing
+ // whether it raises an AttributeError or not.", so we should explicitly wrap this
+ // in nlr_push and handle exception.
+ mp_load_method_maybe(object_in, MP_OBJ_QSTR_VALUE(attr_in), dest);
+
+ return MP_BOOL(dest[0] != MP_OBJ_NULL);
+}
+
+MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_hasattr_obj, mp_builtin_hasattr);
+
// These two are defined in terms of MicroPython API functions right away
MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_globals_obj, mp_globals_get);
MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_locals_obj, mp_locals_get);
diff --git a/py/builtin.h b/py/builtin.h
index baf444a208..2929c1018a 100644
--- a/py/builtin.h
+++ b/py/builtin.h
@@ -41,6 +41,7 @@ MP_DECLARE_CONST_FUN_OBJ(mp_builtin_eval_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_exec_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_getattr_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_globals_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hasattr_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hash_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hex_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_id_obj);
diff --git a/py/builtinimport.c b/py/builtinimport.c
index e6bb7586c8..e758158a64 100644
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/py/builtintables.c b/py/builtintables.c
index a1888a6e97..133c14a269 100644
--- a/py/builtintables.c
+++ b/py/builtintables.c
@@ -90,6 +90,7 @@ STATIC const mp_map_elem_t mp_builtin_object_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_exec), (mp_obj_t)&mp_builtin_exec_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_getattr), (mp_obj_t)&mp_builtin_getattr_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_globals), (mp_obj_t)&mp_builtin_globals_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_hasattr), (mp_obj_t)&mp_builtin_hasattr_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_hash), (mp_obj_t)&mp_builtin_hash_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_hex), (mp_obj_t)&mp_builtin_hex_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_id), (mp_obj_t)&mp_builtin_id_obj },
diff --git a/py/compile.c b/py/compile.c
index 36ffa928ee..cdd3a5b030 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -1147,7 +1147,7 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_
qstr attr = MP_PARSE_NODE_LEAF_ARG(name_nodes[1]);
if (attr == MP_QSTR_bytecode) {
- *emit_options = MP_EMIT_OPT_BYTE_CODE;
+ *emit_options = MP_EMIT_OPT_BYTECODE;
#if MICROPY_EMIT_NATIVE
} else if (attr == MP_QSTR_native) {
*emit_options = MP_EMIT_OPT_NATIVE_PYTHON;
diff --git a/py/compile.h b/py/compile.h
index 4606378976..52c42aff4f 100644
--- a/py/compile.h
+++ b/py/compile.h
@@ -27,7 +27,7 @@
// These must fit in 8 bits; see scope.h
enum {
MP_EMIT_OPT_NONE,
- MP_EMIT_OPT_BYTE_CODE,
+ MP_EMIT_OPT_BYTECODE,
MP_EMIT_OPT_NATIVE_PYTHON,
MP_EMIT_OPT_VIPER,
MP_EMIT_OPT_ASM_THUMB,
diff --git a/py/emitglue.c b/py/emitglue.c
index 7265a206a8..528c3bd36c 100644
--- a/py/emitglue.c
+++ b/py/emitglue.c
@@ -49,24 +49,6 @@
#define DEBUG_OP_printf(...) (void)0
#endif
-#ifdef WRITE_CODE
-FILE *fp_write_code = NULL;
-#endif
-
-void mp_emit_glue_init(void) {
-#ifdef WRITE_CODE
- fp_write_code = fopen("out-code", "wb");
-#endif
-}
-
-void mp_emit_glue_deinit(void) {
-#ifdef WRITE_CODE
- if (fp_write_code != NULL) {
- fclose(fp_write_code);
- }
-#endif
-}
-
mp_raw_code_t *mp_emit_glue_new_raw_code(void) {
mp_raw_code_t *rc = m_new0(mp_raw_code_t, 1);
rc->kind = MP_CODE_RESERVED;
@@ -123,10 +105,9 @@ void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void
DEBUG_printf("\n");
#ifdef WRITE_CODE
- if (fp_write_code != NULL) {
- fwrite(fun_data, len, 1, fp_write_code);
- fflush(fp_write_code);
- }
+ FILE *fp_write_code = fopen("out-code", "wb");
+ fwrite(fun_data, len, 1, fp_write_code);
+ fclose(fp_write_code);
#endif
#endif
}
diff --git a/py/emitglue.h b/py/emitglue.h
index 43bfb5e08a..c6cbb6283d 100644
--- a/py/emitglue.h
+++ b/py/emitglue.h
@@ -52,9 +52,6 @@ typedef struct _mp_code_t {
};
} mp_raw_code_t;
-void mp_emit_glue_init(void);
-void mp_emit_glue_deinit(void);
-
mp_raw_code_t *mp_emit_glue_new_raw_code(void);
void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, uint len, uint n_pos_args, uint n_kwonly_args, qstr *arg_names, uint scope_flags);
diff --git a/py/lexer.c b/py/lexer.c
index f736ef3030..e2dfea78c8 100644
--- a/py/lexer.c
+++ b/py/lexer.c
@@ -64,6 +64,13 @@ struct _mp_lexer_t {
mp_token_t tok_cur;
};
+// debug flag for __debug__ constant
+STATIC mp_token_kind_t mp_debug_value;
+
+void mp_set_debug(bool value) {
+ mp_debug_value = value ? MP_TOKEN_KW_TRUE : MP_TOKEN_KW_FALSE;
+}
+
// TODO replace with a call to a standard function
bool str_strn_equal(const char *str, const char *strn, int len) {
uint i = 0;
@@ -303,7 +310,7 @@ STATIC const char *tok_kw[] = {
"while",
"with",
"yield",
- NULL,
+ "__debug__",
};
STATIC int hex_digit(unichar c) {
@@ -687,9 +694,18 @@ STATIC void mp_lexer_next_token_into(mp_lexer_t *lex, mp_token_t *tok, bool firs
// check for keywords
if (tok->kind == MP_TOKEN_NAME) {
- for (int i = 0; tok_kw[i] != NULL; i++) {
+ // We check for __debug__ here and convert it to its value. This is so
+ // the parser gives a syntax error on, eg, x.__debug__. Otherwise, we
+ // need to check for this special token in many places in the compiler.
+ // TODO improve speed of these string comparisons
+ //for (int i = 0; tok_kw[i] != NULL; i++) {
+ for (int i = 0; i < ARRAY_SIZE(tok_kw); i++) {
if (str_strn_equal(tok_kw[i], tok->str, tok->len)) {
- tok->kind = MP_TOKEN_KW_FALSE + i;
+ if (i == ARRAY_SIZE(tok_kw) - 1) {
+ tok->kind = mp_debug_value;
+ } else {
+ tok->kind = MP_TOKEN_KW_FALSE + i;
+ }
break;
}
}
diff --git a/py/modstruct.c b/py/modstruct.c
index 68c5ce9baa..95a282e2ec 100644
--- a/py/modstruct.c
+++ b/py/modstruct.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -34,6 +35,7 @@
#include "objtuple.h"
#include "objstr.h"
#include "binary.h"
+#include "parsenum.h"
#if MICROPY_ENABLE_MOD_STRUCT
@@ -56,9 +58,26 @@ STATIC char get_fmt_type(const char **fmt) {
return t;
}
+STATIC machine_uint_t get_fmt_num(const char **p) {
+ const char *num = *p;
+ uint len = 1;
+ while (unichar_isdigit(*++num)) {
+ len++;
+ }
+ machine_uint_t val = (machine_uint_t)MP_OBJ_SMALL_INT_VALUE(mp_parse_num_integer(*p, len, 10));
+ *p = num;
+ return val;
+}
+
STATIC uint calcsize_items(const char *fmt) {
- // TODO
- return strlen(fmt);
+ uint cnt = 0;
+ while (*fmt) {
+ // TODO supports size spec only for "s"
+ if (!unichar_isdigit(*fmt++)) {
+ cnt++;
+ }
+ }
+ return cnt;
}
STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {
@@ -67,9 +86,23 @@ STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {
machine_uint_t size;
for (size = 0; *fmt; fmt++) {
uint align;
- int sz = mp_binary_get_size(fmt_type, *fmt, &align);
+ machine_uint_t cnt = 1;
+ if (unichar_isdigit(*fmt)) {
+ cnt = get_fmt_num(&fmt);
+ }
+ if (cnt > 1) {
+ // TODO: count spec support only for string len
+ assert(*fmt == 's');
+ }
+
+ machine_uint_t sz;
+ if (*fmt == 's') {
+ sz = cnt;
+ } else {
+ sz = (machine_uint_t)mp_binary_get_size(fmt_type, *fmt, &align);
+ }
// TODO
- assert(sz != -1);
+ assert(sz != (machine_uint_t)-1);
// Apply alignment
size = (size + align - 1) & ~(align - 1);
size += sz;
@@ -89,7 +122,22 @@ STATIC mp_obj_t struct_unpack(mp_obj_t fmt_in, mp_obj_t data_in) {
byte *p = bufinfo.buf;
for (uint i = 0; i < size; i++) {
- mp_obj_t item = mp_binary_get_val(fmt_type, *fmt++, &p);
+ machine_uint_t sz = 1;
+ if (unichar_isdigit(*fmt)) {
+ sz = get_fmt_num(&fmt);
+ }
+ if (sz > 1) {
+ // TODO: size spec support only for string len
+ assert(*fmt == 's');
+ }
+ mp_obj_t item;
+ if (*fmt == 's') {
+ item = mp_obj_new_bytes(p, sz);
+ p += sz;
+ fmt++;
+ } else {
+ item = mp_binary_get_val(fmt_type, *fmt++, &p);
+ }
res->items[i] = item;
}
return res;
@@ -106,11 +154,33 @@ STATIC mp_obj_t struct_pack(uint n_args, mp_obj_t *args) {
memset(p, 0, size);
for (uint i = 1; i < n_args; i++) {
- mp_binary_set_val(fmt_type, *fmt++, args[i], &p);
+ machine_uint_t sz = 1;
+ if (unichar_isdigit(*fmt)) {
+ sz = get_fmt_num(&fmt);
+ }
+ if (sz > 1) {
+ // TODO: size spec support only for string len
+ assert(*fmt == 's');
+ }
+
+ if (*fmt == 's') {
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[i], &bufinfo, MP_BUFFER_READ);
+ machine_uint_t to_copy = sz;
+ if (bufinfo.len < to_copy) {
+ to_copy = bufinfo.len;
+ }
+ memcpy(p, bufinfo.buf, to_copy);
+ memset(p + to_copy, 0, sz - to_copy);
+ p += sz;
+ fmt++;
+ } else {
+ mp_binary_set_val(fmt_type, *fmt++, args[i], &p);
+ }
}
return res;
}
-MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, -1, struct_pack);
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, MP_OBJ_FUN_ARGS_MAX, struct_pack);
STATIC const mp_map_elem_t mp_module_struct_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_struct) },
diff --git a/py/mpz.c b/py/mpz.c
index 8eed283f04..25c32e9a4a 100644
--- a/py/mpz.c
+++ b/py/mpz.c
@@ -213,8 +213,8 @@ STATIC uint mpn_and(mpz_dig_t *idig, const mpz_dig_t *jdig, uint jlen, const mpz
*idig = *jdig & *kdig;
}
- for (; jlen > 0; --jlen, ++idig) {
- *idig = 0;
+ // remove trailing zeros
+ for (; idig > oidig && *idig == 0; --idig) {
}
return idig - oidig;
diff --git a/py/obj.c b/py/obj.c
index e4bf7d7dfd..437346b62d 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -357,7 +357,12 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) {
} else {
mp_obj_type_t *type = mp_obj_get_type(o_in);
if (type->unary_op != NULL) {
- return type->unary_op(MP_UNARY_OP_LEN, o_in);
+ mp_obj_t val = type->unary_op(MP_UNARY_OP_LEN, o_in);
+ // TODO: Here's the case of having MP_OBJ_NOT_SUPPORTED is confusing
+ if (val == MP_OBJ_NOT_SUPPORTED) {
+ return MP_OBJ_NULL;
+ }
+ return val;
} else {
return MP_OBJ_NULL;
}
diff --git a/py/objarray.c b/py/objarray.c
index b394d77461..81ab57139a 100644
--- a/py/objarray.c
+++ b/py/objarray.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/py/objbool.c b/py/objbool.c
index 179ab76596..e31e7a2a42 100644
--- a/py/objbool.c
+++ b/py/objbool.c
@@ -49,12 +49,14 @@ STATIC void bool_print(void (*print)(void *env, const char *fmt, ...), void *env
}
STATIC mp_obj_t bool_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
- // TODO check n_kw == 0
+ mp_arg_check_num(n_args, n_kw, 0, 1, false);
switch (n_args) {
- case 0: return mp_const_false;
- case 1: if (mp_obj_is_true(args[0])) { return mp_const_true; } else { return mp_const_false; }
- default: nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "bool takes at most 1 argument, %d given", n_args));
+ case 0:
+ return mp_const_false;
+ case 1:
+ default: // must be 0 or 1
+ if (mp_obj_is_true(args[0])) { return mp_const_true; } else { return mp_const_false; }
}
}
diff --git a/py/objcomplex.c b/py/objcomplex.c
index 1caa49ede4..18e0edc519 100644
--- a/py/objcomplex.c
+++ b/py/objcomplex.c
@@ -34,6 +34,7 @@
#include "obj.h"
#include "parsenum.h"
#include "runtime0.h"
+#include "runtime.h"
#if MICROPY_ENABLE_FLOAT
@@ -74,7 +75,7 @@ STATIC void complex_print(void (*print)(void *env, const char *fmt, ...), void *
}
STATIC mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
- // TODO check n_kw == 0
+ mp_arg_check_num(n_args, n_kw, 0, 2, false);
switch (n_args) {
case 0:
@@ -94,7 +95,8 @@ STATIC mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
return mp_obj_new_complex(mp_obj_get_float(args[0]), 0);
}
- case 2: {
+ case 2:
+ default: {
mp_float_t real, imag;
if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) {
mp_obj_complex_get(args[0], &real, &imag);
@@ -112,9 +114,6 @@ STATIC mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
}
return mp_obj_new_complex(real, imag);
}
-
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "complex takes at most 2 arguments, %d given", n_args));
}
}
diff --git a/py/objfloat.c b/py/objfloat.c
index 5260fadc1c..e27942143d 100644
--- a/py/objfloat.c
+++ b/py/objfloat.c
@@ -37,6 +37,7 @@
#include "obj.h"
#include "parsenum.h"
#include "runtime0.h"
+#include "runtime.h"
#if MICROPY_ENABLE_FLOAT
@@ -66,13 +67,14 @@ STATIC void float_print(void (*print)(void *env, const char *fmt, ...), void *en
}
STATIC mp_obj_t float_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
- // TODO check n_kw == 0
+ mp_arg_check_num(n_args, n_kw, 0, 1, false);
switch (n_args) {
case 0:
return mp_obj_new_float(0);
case 1:
+ default:
if (MP_OBJ_IS_STR(args[0])) {
// a string, parse it
uint l;
@@ -85,9 +87,6 @@ STATIC mp_obj_t float_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m
// something else, try to cast it to a float
return mp_obj_new_float(mp_obj_get_float(args[0]));
}
-
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "float takes at most 1 argument, %d given", n_args));
}
}
diff --git a/py/objfun.c b/py/objfun.c
index 732009376d..7915ddad0f 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/py/objgenerator.c b/py/objgenerator.c
index fb8366bae5..de2ecdd488 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/py/objint.c b/py/objint.c
index 73b4c5d0be..d1d99a253f 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -46,7 +46,7 @@
// This dispatcher function is expected to be independent of the implementation of long int
STATIC mp_obj_t mp_obj_int_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
- // TODO check n_kw == 0
+ mp_arg_check_num(n_args, n_kw, 0, 2, false);
switch (n_args) {
case 0:
@@ -67,16 +67,13 @@ STATIC mp_obj_t mp_obj_int_make_new(mp_obj_t type_in, uint n_args, uint n_kw, co
}
case 2:
- {
+ default: {
// should be a string, parse it
// TODO proper error checking of argument types
uint l;
const char *s = mp_obj_str_get_data(args[0], &l);
return mp_parse_num_integer(s, l, mp_obj_get_int(args[1]));
}
-
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "int takes at most 2 arguments, %d given", n_args));
}
}
diff --git a/py/objint_longlong.c b/py/objint_longlong.c
index f648615a73..fe35d54a48 100644
--- a/py/objint_longlong.c
+++ b/py/objint_longlong.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/py/objlist.c b/py/objlist.c
index 9e30ebb4aa..0ef685daeb 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -69,7 +69,7 @@ STATIC mp_obj_t list_extend_from_iter(mp_obj_t list, mp_obj_t iterable) {
}
STATIC mp_obj_t list_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
- // TODO check n_kw == 0
+ mp_arg_check_num(n_args, n_kw, 0, 1, false);
switch (n_args) {
case 0:
@@ -77,15 +77,12 @@ STATIC mp_obj_t list_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp
return mp_obj_new_list(0, NULL);
case 1:
- {
+ default: {
// make list from iterable
// TODO: optimize list/tuple
mp_obj_t list = mp_obj_new_list(0, NULL);
return list_extend_from_iter(list, args[0]);
}
-
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "list takes at most 1 argument, %d given", n_args));
}
}
diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c
index 212cf131c8..a55dd643b0 100644
--- a/py/objnamedtuple.c
+++ b/py/objnamedtuple.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/py/objproperty.c b/py/objproperty.c
index 439cb9ad8a..b4f2e7d490 100644
--- a/py/objproperty.c
+++ b/py/objproperty.c
@@ -42,13 +42,10 @@ typedef struct _mp_obj_property_t {
} mp_obj_property_t;
STATIC mp_obj_t property_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
- // TODO check n_kw == 0
+ mp_arg_check_num(n_args, n_kw, 0, 4, false);
mp_obj_property_t *o = m_new_obj(mp_obj_property_t);
o->base.type = &mp_type_property;
- if (n_args >= 5) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "property takes at most 4 arguments"));
- }
if (n_args >= 4) {
// doc ignored
}
diff --git a/py/objset.c b/py/objset.c
index 4198dac18f..a6f1fe7339 100644
--- a/py/objset.c
+++ b/py/objset.c
@@ -121,15 +121,19 @@ STATIC void set_print(void (*print)(void *env, const char *fmt, ...), void *env,
STATIC mp_obj_t set_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
- // TODO check n_kw == 0
+ mp_arg_check_num(n_args, n_kw, 0, 1, false);
switch (n_args) {
- case 0:
- // return a new, empty set
- return mp_obj_new_set(0, NULL);
+ case 0: {
+ // create a new, empty set
+ mp_obj_set_t *set = mp_obj_new_set(0, NULL);
+ // set actual set/frozenset type
+ set->base.type = type_in;
+ return set;
+ }
case 1:
- {
+ default: { // can only be 0 or 1 arg
// 1 argument, an iterable from which we make a new set
mp_obj_set_t *set = mp_obj_new_set(0, NULL);
mp_obj_t iterable = mp_getiter(args[0]);
@@ -141,9 +145,6 @@ STATIC mp_obj_t set_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_
set->base.type = type_in;
return set;
}
-
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "set takes at most 1 argument, %d given", n_args));
}
}
diff --git a/py/objstr.c b/py/objstr.c
index 33bfcc3756..3a4b0b97f3 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -332,6 +333,7 @@ STATIC mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
}
STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
+ mp_obj_type_t *type = mp_obj_get_type(self_in);
GET_STR_DATA_LEN(self_in, self_data, self_len);
if (value == MP_OBJ_SENTINEL) {
// load
@@ -341,10 +343,9 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
if (!mp_seq_get_fast_slice_indexes(self_len, index, &start, &stop)) {
assert(0);
}
- return mp_obj_new_str(self_data + start, stop - start, false);
+ return str_new(type, self_data + start, stop - start);
}
#endif
- mp_obj_type_t *type = mp_obj_get_type(self_in);
uint index_val = mp_get_index(type, self_len, index, false);
if (type == &mp_type_bytes) {
return MP_OBJ_NEW_SMALL_INT((mp_small_int_t)self_data[index_val]);
@@ -357,7 +358,8 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
}
STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
- assert(MP_OBJ_IS_STR(self_in));
+ assert(is_str_or_bytes(self_in));
+ const mp_obj_type_t *self_type = mp_obj_get_type(self_in);
// get separation string
GET_STR_DATA_LEN(self_in, sep_str, sep_len);
@@ -379,8 +381,9 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
// count required length
int required_len = 0;
for (int i = 0; i < seq_len; i++) {
- if (!MP_OBJ_IS_STR(seq_items[i])) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "join expected a list of str's"));
+ if (mp_obj_get_type(seq_items[i]) != self_type) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
+ "join expects a list of str/bytes objects consistent with self object"));
}
if (i > 0) {
required_len += sep_len;
@@ -391,7 +394,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
// make joined string
byte *data;
- mp_obj_t joined_str = mp_obj_str_builder_start(mp_obj_get_type(self_in), required_len, &data);
+ mp_obj_t joined_str = mp_obj_str_builder_start(self_type, required_len, &data);
for (int i = 0; i < seq_len; i++) {
if (i > 0) {
memcpy(data, sep_str, sep_len);
@@ -409,6 +412,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
#define is_ws(c) ((c) == ' ' || (c) == '\t')
STATIC mp_obj_t str_split(uint n_args, const mp_obj_t *args) {
+ const mp_obj_type_t *self_type = mp_obj_get_type(args[0]);
machine_int_t splits = -1;
mp_obj_t sep = mp_const_none;
if (n_args > 1) {
@@ -430,7 +434,7 @@ STATIC mp_obj_t str_split(uint n_args, const mp_obj_t *args) {
while (s < top && splits != 0) {
const byte *start = s;
while (s < top && !is_ws(*s)) s++;
- mp_obj_list_append(res, mp_obj_new_str(start, s - start, false));
+ mp_obj_list_append(res, str_new(self_type, start, s - start));
if (s >= top) {
break;
}
@@ -441,7 +445,7 @@ STATIC mp_obj_t str_split(uint n_args, const mp_obj_t *args) {
}
if (s < top) {
- mp_obj_list_append(res, mp_obj_new_str(s, top - s, false));
+ mp_obj_list_append(res, str_new(self_type, s, top - s));
}
} else {
@@ -465,7 +469,7 @@ STATIC mp_obj_t str_split(uint n_args, const mp_obj_t *args) {
}
s++;
}
- mp_obj_list_append(res, mp_obj_new_str(start, s - start, false));
+ mp_obj_list_append(res, str_new(self_type, start, s - start));
if (s >= top) {
break;
}
diff --git a/py/objtuple.c b/py/objtuple.c
index 1ec75239bd..44ee95dd96 100644
--- a/py/objtuple.c
+++ b/py/objtuple.c
@@ -57,14 +57,15 @@ void mp_obj_tuple_print(void (*print)(void *env, const char *fmt, ...), void *en
}
STATIC mp_obj_t mp_obj_tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
- // TODO check n_kw == 0
+ mp_arg_check_num(n_args, n_kw, 0, 1, false);
switch (n_args) {
case 0:
// return a empty tuple
return mp_const_empty_tuple;
- case 1: {
+ case 1:
+ default: {
// 1 argument, an iterable from which we make a new tuple
if (MP_OBJ_IS_TYPE(args[0], &mp_type_tuple)) {
return args[0];
@@ -91,9 +92,6 @@ STATIC mp_obj_t mp_obj_tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw,
return tuple;
}
-
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "tuple takes at most 1 argument, %d given", n_args));
}
}
diff --git a/py/objtype.c b/py/objtype.c
index c579477db7..4827595bbe 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -540,7 +541,7 @@ STATIC void type_print(void (*print)(void *env, const char *fmt, ...), void *env
}
STATIC mp_obj_t type_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
- // TODO check n_kw == 0
+ mp_arg_check_num(n_args, n_kw, 1, 3, false);
switch (n_args) {
case 1:
diff --git a/py/objzip.c b/py/objzip.c
index 8f8946264d..97a14eb870 100644
--- a/py/objzip.c
+++ b/py/objzip.c
@@ -40,7 +40,7 @@ typedef struct _mp_obj_zip_t {
} mp_obj_zip_t;
STATIC mp_obj_t zip_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
- // TODO check n_kw == 0
+ mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false);
mp_obj_zip_t *o = m_new_obj_var(mp_obj_zip_t, mp_obj_t, n_args);
o->base.type = &mp_type_zip;
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index 13476b3be8..1679d8b39c 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -142,6 +142,7 @@ Q(float)
Q(from_bytes)
Q(getattr)
Q(globals)
+Q(hasattr)
Q(hash)
Q(hex)
Q(%#x)
diff --git a/py/runtime.c b/py/runtime.c
index a2de2d75b1..7c89ec4e2e 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -69,12 +69,13 @@ const mp_obj_module_t mp_module___main__ = {
};
void mp_init(void) {
- // call port specific initialization if any
+ // call port specific initialization if any
#ifdef MICROPY_PORT_INIT_FUNC
MICROPY_PORT_INIT_FUNC;
#endif
- mp_emit_glue_init();
+ // __debug__ enabled by default
+ mp_set_debug(true);
// init global module stuff
mp_module_init();
@@ -90,7 +91,6 @@ void mp_init(void) {
void mp_deinit(void) {
//mp_obj_dict_free(&dict_main);
mp_module_deinit();
- mp_emit_glue_deinit();
// call port specific deinitialization if any
#ifdef MICROPY_PORT_INIT_FUNC
@@ -884,9 +884,14 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) {
}
mp_obj_t mp_getiter(mp_obj_t o_in) {
+ assert(o_in);
mp_obj_type_t *type = mp_obj_get_type(o_in);
if (type->getiter != NULL) {
- return type->getiter(o_in);
+ mp_obj_t iter = type->getiter(o_in);
+ if (iter == MP_OBJ_NULL) {
+ goto not_iterable;
+ }
+ return iter;
} else {
// check for __iter__ method
mp_obj_t dest[2];
@@ -901,6 +906,7 @@ mp_obj_t mp_getiter(mp_obj_t o_in) {
return mp_obj_new_getitem_iter(dest);
} else {
// object not iterable
+not_iterable:
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not iterable", mp_obj_get_type_str(o_in)));
}
}
diff --git a/py/runtime.h b/py/runtime.h
index 910a485446..a5d6743034 100644
--- a/py/runtime.h
+++ b/py/runtime.h
@@ -54,6 +54,8 @@ typedef struct _mp_arg_t {
void mp_init(void);
void mp_deinit(void);
+void mp_set_debug(bool value); // sets the value of __debug__; see lexer.c
+
void mp_arg_check_num(uint n_args, uint n_kw, uint n_args_min, uint n_args_max, bool takes_kw);
void mp_arg_parse_all(uint n_pos, const mp_obj_t *pos, mp_map_t *kws, uint n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals);
void mp_arg_parse_all_kw_array(uint n_pos, uint n_kw, const mp_obj_t *args, uint n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals);
diff --git a/py/sequence.c b/py/sequence.c
index 91162fc099..1af2ad27ef 100644
--- a/py/sequence.c
+++ b/py/sequence.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/py/showbc.c b/py/showbc.c
index 48d5328c20..91b7572db9 100644
--- a/py/showbc.c
+++ b/py/showbc.c
@@ -404,14 +404,10 @@ void mp_bytecode_print2(const byte *ip, int len) {
printf("STORE_MAP");
break;
- /*
case MP_BC_MAP_ADD:
DECODE_UINT;
- // I think it's guaranteed by the compiler that sp[unum + 1] is a map
- rt_store_map(sp[unum + 1], sp[0], sp[1]);
- sp += 2;
+ printf("MAP_ADD " UINT_FMT, unum);
break;
- */
case MP_BC_BUILD_SET:
DECODE_UINT;
diff --git a/py/stream.c b/py/stream.c
index 9eb438b538..599582b510 100644
--- a/py/stream.c
+++ b/py/stream.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/py/vm.c b/py/vm.c
index 36e8db2032..123f520280 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -663,6 +664,7 @@ unwind_jump:
ENTRY(MP_BC_FOR_ITER):
DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward
save_sp = sp;
+ assert(TOP());
obj1 = mp_iternext_allow_raise(TOP());
if (obj1 == MP_OBJ_STOP_ITERATION) {
--sp; // pop the exhausted iterator
diff --git a/tests/basics/frozenset1.py b/tests/basics/frozenset1.py
index 02a5bf8c56..00694581f0 100644
--- a/tests/basics/frozenset1.py
+++ b/tests/basics/frozenset1.py
@@ -7,6 +7,9 @@ except NameError:
import sys
sys.exit()
+s = frozenset()
+print(s)
+
s = frozenset({1})
print(s)
diff --git a/tests/basics/hasattr1.py b/tests/basics/hasattr1.py
new file mode 100644
index 0000000000..b1c4b5ceb6
--- /dev/null
+++ b/tests/basics/hasattr1.py
@@ -0,0 +1,29 @@
+class A:
+
+ var = 132
+
+ def __init__(self):
+ self.var2 = 34
+
+ def meth(self, i):
+ return 42 + i
+
+
+a = A()
+print(hasattr(a, "var"))
+print(hasattr(a, "var2"))
+print(hasattr(a, "meth"))
+print(hasattr(a, "_none_such"))
+print(hasattr(list, "foo"))
+
+class C:
+
+ def __getattr__(self, attr):
+ if attr == "exists":
+ return attr
+ raise AttributeError
+
+c = C()
+print(hasattr(c, "exists"))
+# TODO
+#print(hasattr(c, "doesnt_exist"))
diff --git a/tests/basics/int-big-and.py b/tests/basics/int-big-and.py
new file mode 100644
index 0000000000..75fbd52884
--- /dev/null
+++ b/tests/basics/int-big-and.py
@@ -0,0 +1,8 @@
+print(0 & (1 << 80))
+print(0 & (1 << 80) == 0)
+print(bool(0 & (1 << 80)))
+
+#a = 0xfffffffffffffffffffffffffffff
+#print(a & (1 << 80))
+#print((a & (1 << 80)) >> 80)
+#print((a & (1 << 80)) >> 80 == 1)
diff --git a/tests/basics/int-long.py b/tests/basics/int-long.py
index 3567e08b2d..a22075d1f9 100644
--- a/tests/basics/int-long.py
+++ b/tests/basics/int-long.py
@@ -11,7 +11,7 @@ print(b - a)
#print(a * b)
print(a // b)
print(a % b)
-print(a & b)
+print("&", a & b)
print(a | b)
print(a ^ b)
print(a << 3)
@@ -32,7 +32,7 @@ print(a)
a |= b
print(a)
a &= b
-print(a)
+print("&=", a)
a <<= 5
print(a)
a >>= 1
@@ -44,3 +44,11 @@ b = a
a += 1
print(a)
print(b)
+
+# Bitwise ops on 64-bit
+
+a = 0x1ffffffffffffffff
+b = 0x10000000000000000
+print("&", a & b)
+print(a | b)
+print(a ^ b)
diff --git a/tests/basics/string-join.py b/tests/basics/string-join.py
index 275a804c64..49bbfc5ca0 100644
--- a/tests/basics/string-join.py
+++ b/tests/basics/string-join.py
@@ -10,3 +10,15 @@ print(''.join(''))
print(''.join('abc'))
print(','.join('abc'))
print(','.join('abc' for i in range(5)))
+
+print(b','.join([b'abc', b'123']))
+
+try:
+ print(b','.join(['abc', b'123']))
+except TypeError:
+ print("TypeError")
+
+try:
+ print(','.join([b'abc', b'123']))
+except TypeError:
+ print("TypeError")
diff --git a/tests/basics/string-slice.py b/tests/basics/string-slice.py
index 7538ae5700..89853d3437 100644
--- a/tests/basics/string-slice.py
+++ b/tests/basics/string-slice.py
@@ -30,3 +30,6 @@ print("123"[-1000000:])
# No IndexError!
print(""[1:1])
print(""[-1:-1])
+
+# bytes
+print(b"123"[0:2])
diff --git a/tests/basics/string_split.py b/tests/basics/string_split.py
index 398a115397..9ee9e5960a 100644
--- a/tests/basics/string_split.py
+++ b/tests/basics/string_split.py
@@ -26,3 +26,5 @@ print("abcabc".split("bc"))
print("abcabc".split("bc", 0))
print("abcabc".split("bc", 1))
print("abcabc".split("bc", 2))
+
+print(b"abcabc".split(b"bc", 2))
diff --git a/tests/basics/struct1.py b/tests/basics/struct1.py
index 3a05c85f0b..b114a789b5 100644
--- a/tests/basics/struct1.py
+++ b/tests/basics/struct1.py
@@ -16,3 +16,8 @@ print(struct.pack(">b", 1))
print(struct.pack("<bI", -128, 256))
print(struct.pack(">bI", -128, 256))
+
+print(struct.calcsize("100sI"))
+print(struct.calcsize("97sI"))
+print(struct.unpack("<6sH", b"foo\0\0\0\x12\x34"))
+print(struct.pack("<6sH", b"foo", 10000))
diff --git a/unix/main.c b/unix/main.c
index 5ac776fbc3..23dd4be631 100644
--- a/unix/main.c
+++ b/unix/main.c
@@ -233,7 +233,7 @@ void pre_process_options(int argc, char **argv) {
} else if (strcmp(argv[a + 1], "compile-only") == 0) {
compile_only = true;
} else if (strcmp(argv[a + 1], "emit=bytecode") == 0) {
- emit_opt = MP_EMIT_OPT_BYTE_CODE;
+ emit_opt = MP_EMIT_OPT_BYTECODE;
} else if (strcmp(argv[a + 1], "emit=native") == 0) {
emit_opt = MP_EMIT_OPT_NATIVE_PYTHON;
} else if (strcmp(argv[a + 1], "emit=viper") == 0) {
@@ -338,6 +338,9 @@ int main(int argc, char **argv) {
a += 1;
} else if (strcmp(argv[a], "-v") == 0) {
mp_verbose_flag++;
+ } else if (strcmp(argv[a], "-O") == 0) {
+ // optimisation; sets __debug__ to False
+ mp_set_debug(false);
} else {
return usage(argv);
}
diff --git a/unix/modffi.c b/unix/modffi.c
index aa26297d60..4ac9fef5aa 100644
--- a/unix/modffi.c
+++ b/unix/modffi.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/unix/modsocket.c b/unix/modsocket.c
index 72aee95eab..08d0d56b60 100644
--- a/unix/modsocket.c
+++ b/unix/modsocket.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h
index 4f347f4e02..a0a627d57e 100644
--- a/unix/mpconfigport.h
+++ b/unix/mpconfigport.h
@@ -52,9 +52,21 @@
extern const struct _mp_obj_module_t mp_module_time;
extern const struct _mp_obj_module_t mp_module_socket;
extern const struct _mp_obj_module_t mp_module_ffi;
+
+#if MICROPY_MOD_FFI
+#define MICROPY_MOD_FFI_DEF { MP_OBJ_NEW_QSTR(MP_QSTR_ffi), (mp_obj_t)&mp_module_ffi },
+#else
+#define MICROPY_MOD_FFI_DEF
+#endif
+#if MICROPY_MOD_TIME
+#define MICROPY_MOD_TIME_DEF { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&mp_module_time },
+#else
+#define MICROPY_MOD_TIME_DEF
+#endif
+
#define MICROPY_EXTRA_BUILTIN_MODULES \
- { MP_OBJ_NEW_QSTR(MP_QSTR_ffi), (mp_obj_t)&mp_module_ffi }, \
- { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&mp_module_time }, \
+ MICROPY_MOD_FFI_DEF \
+ MICROPY_MOD_TIME_DEF \
{ MP_OBJ_NEW_QSTR(MP_QSTR_microsocket), (mp_obj_t)&mp_module_socket }, \
// type definitions for the specific machine
diff --git a/windows/mpconfigport.h b/windows/mpconfigport.h
index 0a1e313cb8..974c454d39 100644
--- a/windows/mpconfigport.h
+++ b/windows/mpconfigport.h
@@ -41,6 +41,8 @@
#define MICROPY_ENABLE_LEXER_UNIX (1)
#define MICROPY_ENABLE_MOD_CMATH (1)
#define MICROPY_MOD_SYS_STDFILES (1)
+#define MICROPY_MOD_SYS_EXIT (1)
+#define MICROPY_ENABLE_FROZENSET (1)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#define MICROPY_PORT_INIT_FUNC init()