Merge branch 'master' of github.com:micropython/micropython
Conflicts: py/objstr.c py/py.mk py/stream.c unix/main.c unix/socket.c
This commit is contained in:
commit
12eaccacda
@ -1,22 +1,32 @@
|
|||||||
mod = rawsocket
|
try:
|
||||||
s = mod.socket()
|
import rawsocket as _socket
|
||||||
|
except:
|
||||||
|
import _socket
|
||||||
|
|
||||||
|
|
||||||
|
s = _socket.socket()
|
||||||
|
|
||||||
if 1:
|
if 1:
|
||||||
ai = mod.getaddrinfo("google.com", 80)
|
ai = _socket.getaddrinfo("google.com", 80)
|
||||||
print("Address infos:", ai)
|
print("Address infos:", ai)
|
||||||
addr = ai[0][4]
|
addr = ai[0][4]
|
||||||
else:
|
else:
|
||||||
# Deprecated way to construct connection address
|
# Deprecated ways to construct connection address
|
||||||
addr = mod.sockaddr_in()
|
addr = _socket.sockaddr_in()
|
||||||
addr.sin_family = 2
|
addr.sin_family = 2
|
||||||
#addr.sin_addr = (0x0100 << 16) + 0x007f
|
#addr.sin_addr = (0x0100 << 16) + 0x007f
|
||||||
#addr.sin_addr = (0x7f00 << 16) + 0x0001
|
#addr.sin_addr = (0x7f00 << 16) + 0x0001
|
||||||
#addr.sin_addr = mod.inet_aton("127.0.0.1")
|
#addr.sin_addr = _socket.inet_aton("127.0.0.1")
|
||||||
addr.sin_addr = mod.gethostbyname("google.com")
|
addr.sin_addr = _socket.gethostbyname("google.com")
|
||||||
addr.sin_port = mod.htons(80)
|
addr.sin_port = _socket.htons(80)
|
||||||
|
|
||||||
print("Connect address:", addr)
|
print("Connect address:", addr)
|
||||||
s.connect(addr)
|
s.connect(addr)
|
||||||
|
|
||||||
s.write("GET / HTTP/1.0\n\n")
|
if 0:
|
||||||
print(s.readall())
|
# MicroPython rawsocket module supports file interface directly
|
||||||
|
s.write("GET / HTTP/1.0\n\n")
|
||||||
|
print(s.readall())
|
||||||
|
else:
|
||||||
|
s.send(b"GET / HTTP/1.0\n\n")
|
||||||
|
print(s.recv(4096))
|
||||||
|
@ -1,7 +1,18 @@
|
|||||||
mod = rawsocket
|
try:
|
||||||
s = mod.socket()
|
import rawsocket as socket
|
||||||
|
except:
|
||||||
|
import socket
|
||||||
|
|
||||||
ai = mod.getaddrinfo("127.0.0.1", 8080)
|
|
||||||
|
CONTENT = """\
|
||||||
|
HTTP/1.0 200 OK
|
||||||
|
|
||||||
|
Hello #{} from MicroPython!
|
||||||
|
"""
|
||||||
|
|
||||||
|
s = socket.socket()
|
||||||
|
|
||||||
|
ai = socket.getaddrinfo("127.0.0.1", 8080)
|
||||||
print("Bind address info:", ai)
|
print("Bind address info:", ai)
|
||||||
addr = ai[0][4]
|
addr = ai[0][4]
|
||||||
|
|
||||||
@ -17,12 +28,13 @@ while True:
|
|||||||
print("Client address:", client_addr)
|
print("Client address:", client_addr)
|
||||||
print("Client socket:", client_s)
|
print("Client socket:", client_s)
|
||||||
print("Request:")
|
print("Request:")
|
||||||
|
if 0:
|
||||||
|
# MicroPython rawsocket module supports file interface directly
|
||||||
print(client_s.read(4096))
|
print(client_s.read(4096))
|
||||||
#print(client_s.readall())
|
#print(client_s.readall())
|
||||||
client_s.write("""\
|
client_s.write(CONTENT.format(counter))
|
||||||
HTTP/1.0 200 OK
|
else:
|
||||||
|
print(client_s.recv(4096))
|
||||||
Hello #{} from MicroPython!
|
client_s.send(bytes(CONTENT.format(counter), "ascii"))
|
||||||
""".format(counter))
|
|
||||||
client_s.close()
|
client_s.close()
|
||||||
counter += 1
|
counter += 1
|
||||||
|
12
py/builtin.c
12
py/builtin.c
@ -350,3 +350,15 @@ static mp_obj_t mp_builtin_str(mp_obj_t o_in) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
// TODO: This should be type, this is just quick CPython compat hack
|
||||||
|
static mp_obj_t mp_builtin_bytes(uint n_args, const mp_obj_t *args) {
|
||||||
|
if (!MP_OBJ_IS_QSTR(args[0]) && !MP_OBJ_IS_TYPE(args[0], &str_type)) {
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
// Currently, MicroPython strings are mix between CPython byte and unicode
|
||||||
|
// strings. So, conversion is null so far.
|
||||||
|
return args[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_bytes_obj, 1, 3, mp_builtin_bytes);
|
||||||
|
@ -5,6 +5,7 @@ MP_DECLARE_CONST_FUN_OBJ(mp_builtin___repl_print___obj);
|
|||||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_abs_obj);
|
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_abs_obj);
|
||||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_all_obj);
|
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_all_obj);
|
||||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_any_obj);
|
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_any_obj);
|
||||||
|
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_bytes_obj); // Temporary hack
|
||||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_callable_obj);
|
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_callable_obj);
|
||||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_chr_obj);
|
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_chr_obj);
|
||||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_divmod_obj);
|
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_divmod_obj);
|
||||||
|
12
py/obj.c
12
py/obj.c
@ -28,6 +28,8 @@ 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)) {
|
if (MP_OBJ_IS_SMALL_INT(o_in)) {
|
||||||
return "int";
|
return "int";
|
||||||
|
} else if (MP_OBJ_IS_QSTR(o_in)) {
|
||||||
|
return "str";
|
||||||
} else {
|
} else {
|
||||||
mp_obj_base_t *o = o_in;
|
mp_obj_base_t *o = o_in;
|
||||||
return o->type->name;
|
return o->type->name;
|
||||||
@ -222,7 +224,9 @@ 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) {
|
qstr mp_obj_get_qstr(mp_obj_t arg) {
|
||||||
if (MP_OBJ_IS_TYPE(arg, &str_type)) {
|
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);
|
return mp_obj_str_get(arg);
|
||||||
} else {
|
} else {
|
||||||
assert(0);
|
assert(0);
|
||||||
@ -286,3 +290,9 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) {
|
|||||||
}
|
}
|
||||||
return MP_OBJ_NEW_SMALL_INT(len);
|
return MP_OBJ_NEW_SMALL_INT(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return input argument. Useful as .getiter for objects which are
|
||||||
|
// their own iterators, etc.
|
||||||
|
mp_obj_t mp_identity(mp_obj_t self) {
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
5
py/obj.h
5
py/obj.h
@ -351,6 +351,8 @@ extern const mp_obj_type_t fun_native_type;
|
|||||||
extern const mp_obj_type_t fun_bc_type;
|
extern const mp_obj_type_t fun_bc_type;
|
||||||
void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, uint *n_state, const byte **code);
|
void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, uint *n_state, const byte **code);
|
||||||
|
|
||||||
|
mp_obj_t mp_identity(mp_obj_t self);
|
||||||
|
|
||||||
// generator
|
// generator
|
||||||
extern const mp_obj_type_t gen_instance_type;
|
extern const mp_obj_type_t gen_instance_type;
|
||||||
|
|
||||||
@ -374,3 +376,6 @@ typedef struct _mp_obj_classmethod_t {
|
|||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
mp_obj_t fun;
|
mp_obj_t fun;
|
||||||
} mp_obj_classmethod_t;
|
} mp_obj_classmethod_t;
|
||||||
|
|
||||||
|
// sequence helpers
|
||||||
|
void mp_seq_multiply(const void *items, uint item_sz, uint len, uint times, void *dest);
|
||||||
|
@ -153,13 +153,8 @@ static mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
int n = MP_OBJ_SMALL_INT_VALUE(rhs);
|
int n = MP_OBJ_SMALL_INT_VALUE(rhs);
|
||||||
int len = o->len;
|
mp_obj_list_t *s = list_new(o->len * n);
|
||||||
mp_obj_list_t *s = list_new(len * n);
|
mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items);
|
||||||
mp_obj_t *dest = s->items;
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
memcpy(dest, o->items, sizeof(mp_obj_t) * len);
|
|
||||||
dest += len;
|
|
||||||
}
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
case RT_COMPARE_OP_EQUAL:
|
case RT_COMPARE_OP_EQUAL:
|
||||||
|
83
py/objstr.c
83
py/objstr.c
@ -65,9 +65,8 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
|||||||
// 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)) {
|
||||||
// TODO: This implements byte string access for single index so far
|
uint index = mp_get_index(lhs->base.type, lhs_len, rhs_in);
|
||||||
// TODO: Handle negative indexes.
|
return mp_obj_new_str(qstr_from_strn((const char*)lhs_data + index, 1));
|
||||||
return mp_obj_new_int(lhs_data[mp_obj_get_int(rhs_in)]);
|
|
||||||
#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;
|
||||||
@ -122,6 +121,16 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
|||||||
return mp_const_false;
|
return mp_const_false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case RT_BINARY_OP_MULTIPLY:
|
||||||
|
{
|
||||||
|
if (!MP_OBJ_IS_SMALL_INT(rhs_in)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
int n = MP_OBJ_SMALL_INT_VALUE(rhs_in);
|
||||||
|
char *s = m_new(char, lhs_len * n);
|
||||||
|
mp_seq_multiply(lhs_data, sizeof(*lhs_data), lhs_len, n, s);
|
||||||
|
return MP_OBJ_NEW_QSTR(qstr_from_strn_take(s, lhs_len * n, lhs_len * n));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return MP_OBJ_NULL; // op not supported
|
return MP_OBJ_NULL; // op not supported
|
||||||
@ -184,6 +193,45 @@ bad_arg:
|
|||||||
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "?str.join expecting a list of str's"));
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "?str.join expecting a list of str's"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define is_ws(c) ((c) == ' ' || (c) == '\t')
|
||||||
|
|
||||||
|
static mp_obj_t str_split(uint n_args, const mp_obj_t *args) {
|
||||||
|
int splits = -1;
|
||||||
|
mp_obj_t sep = mp_const_none;
|
||||||
|
if (n_args > 1) {
|
||||||
|
sep = args[1];
|
||||||
|
if (n_args > 2) {
|
||||||
|
splits = MP_OBJ_SMALL_INT_VALUE(args[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(sep == mp_const_none);
|
||||||
|
(void)sep; // unused; to hush compiler warning
|
||||||
|
mp_obj_t res = mp_obj_new_list(0, NULL);
|
||||||
|
const char *s = qstr_str(mp_obj_str_get(args[0]));
|
||||||
|
const char *start;
|
||||||
|
|
||||||
|
// Initial whitespace is not counted as split, so we pre-do it
|
||||||
|
while (is_ws(*s)) s++;
|
||||||
|
while (*s && splits != 0) {
|
||||||
|
start = s;
|
||||||
|
while (*s != 0 && !is_ws(*s)) s++;
|
||||||
|
rt_list_append(res, MP_OBJ_NEW_QSTR(qstr_from_strn(start, s - start)));
|
||||||
|
if (*s == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (is_ws(*s)) s++;
|
||||||
|
if (splits > 0) {
|
||||||
|
splits--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*s != 0) {
|
||||||
|
rt_list_append(res, MP_OBJ_NEW_QSTR(qstr_from_str(s)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static bool chr_in_str(const char* const str, const size_t str_len, const char c) {
|
static bool chr_in_str(const char* const str, const size_t str_len, const char c) {
|
||||||
for (size_t i = 0; i < str_len; i++) {
|
for (size_t i = 0; i < str_len; i++) {
|
||||||
if (str[i] == c) {
|
if (str[i] == c) {
|
||||||
@ -195,16 +243,8 @@ static bool chr_in_str(const char* const str, const size_t str_len, const char c
|
|||||||
|
|
||||||
static mp_obj_t str_find(uint n_args, const mp_obj_t *args) {
|
static mp_obj_t str_find(uint n_args, const mp_obj_t *args) {
|
||||||
assert(2 <= n_args && n_args <= 4);
|
assert(2 <= n_args && n_args <= 4);
|
||||||
assert(MP_OBJ_IS_TYPE(args[0], &str_type));
|
const char* haystack = qstr_str(mp_obj_str_get(args[0]));
|
||||||
if (!MP_OBJ_IS_TYPE(args[1], &str_type)) {
|
const char* needle = qstr_str(mp_obj_str_get(args[1]));
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(
|
|
||||||
MP_QSTR_TypeError,
|
|
||||||
"Can't convert '%s' object to str implicitly",
|
|
||||||
mp_obj_get_type_str(args[1])));
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* haystack = qstr_str(((mp_obj_str_t*)args[0])->qstr);
|
|
||||||
const char* needle = qstr_str(((mp_obj_str_t*)args[1])->qstr);
|
|
||||||
|
|
||||||
size_t haystack_len = strlen(haystack);
|
size_t haystack_len = strlen(haystack);
|
||||||
size_t needle_len = strlen(needle);
|
size_t needle_len = strlen(needle);
|
||||||
@ -242,14 +282,11 @@ mp_obj_t str_strip(uint n_args, const mp_obj_t *args) {
|
|||||||
if (n_args == 1) {
|
if (n_args == 1) {
|
||||||
chars_to_del = whitespace;
|
chars_to_del = whitespace;
|
||||||
} else {
|
} else {
|
||||||
assert(MP_OBJ_IS_TYPE(args[1], &str_type));
|
chars_to_del = qstr_str(mp_obj_str_get(args[1]));
|
||||||
mp_obj_str_t *chars_to_del_obj = args[1];
|
|
||||||
chars_to_del = qstr_str(chars_to_del_obj->qstr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t chars_to_del_len = strlen(chars_to_del);
|
const size_t chars_to_del_len = strlen(chars_to_del);
|
||||||
mp_obj_str_t *self = args[0];
|
const char *orig_str = qstr_str(mp_obj_str_get(args[0]));
|
||||||
const char *orig_str = qstr_str(self->qstr);
|
|
||||||
const size_t orig_str_len = strlen(orig_str);
|
const size_t orig_str_len = strlen(orig_str);
|
||||||
|
|
||||||
size_t first_good_char_pos = 0;
|
size_t first_good_char_pos = 0;
|
||||||
@ -307,12 +344,14 @@ mp_obj_t str_format(uint n_args, const mp_obj_t *args) {
|
|||||||
|
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj, 2, 4, str_find);
|
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj, 2, 4, str_find);
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_2(str_join_obj, str_join);
|
static MP_DEFINE_CONST_FUN_OBJ_2(str_join_obj, str_join);
|
||||||
|
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_split_obj, 1, 3, str_split);
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_strip_obj, 1, 2, str_strip);
|
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_strip_obj, 1, 2, str_strip);
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_VAR(str_format_obj, 1, str_format);
|
static MP_DEFINE_CONST_FUN_OBJ_VAR(str_format_obj, 1, str_format);
|
||||||
|
|
||||||
static const mp_method_t str_type_methods[] = {
|
static const mp_method_t str_type_methods[] = {
|
||||||
{ "find", &str_find_obj },
|
{ "find", &str_find_obj },
|
||||||
{ "join", &str_join_obj },
|
{ "join", &str_join_obj },
|
||||||
|
{ "split", &str_split_obj },
|
||||||
{ "strip", &str_strip_obj },
|
{ "strip", &str_strip_obj },
|
||||||
{ "format", &str_format_obj },
|
{ "format", &str_format_obj },
|
||||||
{ NULL, NULL }, // end-of-list sentinel
|
{ NULL, NULL }, // end-of-list sentinel
|
||||||
@ -335,9 +374,15 @@ mp_obj_t mp_obj_new_str(qstr qstr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
qstr mp_obj_str_get(mp_obj_t self_in) {
|
qstr mp_obj_str_get(mp_obj_t self_in) {
|
||||||
assert(MP_OBJ_IS_TYPE(self_in, &str_type));
|
if (MP_OBJ_IS_QSTR(self_in)) {
|
||||||
|
return MP_OBJ_QSTR_VALUE(self_in);
|
||||||
|
}
|
||||||
|
if (MP_OBJ_IS_TYPE(self_in, &str_type)) {
|
||||||
mp_obj_str_t *self = self_in;
|
mp_obj_str_t *self = self_in;
|
||||||
return self->qstr;
|
return self->qstr;
|
||||||
|
}
|
||||||
|
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "Can't convert '%s' object to str implicitly",
|
||||||
|
mp_obj_get_type_str(self_in)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
1
py/py.mk
1
py/py.mk
@ -97,6 +97,7 @@ PY_O_BASENAME = \
|
|||||||
objtuple.o \
|
objtuple.o \
|
||||||
objtype.o \
|
objtype.o \
|
||||||
objzip.o \
|
objzip.o \
|
||||||
|
sequence.o \
|
||||||
stream.o \
|
stream.o \
|
||||||
builtin.o \
|
builtin.o \
|
||||||
builtinimport.o \
|
builtinimport.o \
|
||||||
|
@ -40,6 +40,7 @@ Q(any)
|
|||||||
Q(array)
|
Q(array)
|
||||||
Q(bool)
|
Q(bool)
|
||||||
Q(bytearray)
|
Q(bytearray)
|
||||||
|
Q(bytes)
|
||||||
Q(callable)
|
Q(callable)
|
||||||
Q(chr)
|
Q(chr)
|
||||||
Q(complex)
|
Q(complex)
|
||||||
|
@ -130,6 +130,7 @@ void rt_init(void) {
|
|||||||
mp_map_add_qstr(&map_builtins, MP_QSTR_abs, (mp_obj_t)&mp_builtin_abs_obj);
|
mp_map_add_qstr(&map_builtins, MP_QSTR_abs, (mp_obj_t)&mp_builtin_abs_obj);
|
||||||
mp_map_add_qstr(&map_builtins, MP_QSTR_all, (mp_obj_t)&mp_builtin_all_obj);
|
mp_map_add_qstr(&map_builtins, MP_QSTR_all, (mp_obj_t)&mp_builtin_all_obj);
|
||||||
mp_map_add_qstr(&map_builtins, MP_QSTR_any, (mp_obj_t)&mp_builtin_any_obj);
|
mp_map_add_qstr(&map_builtins, MP_QSTR_any, (mp_obj_t)&mp_builtin_any_obj);
|
||||||
|
mp_map_add_qstr(&map_builtins, MP_QSTR_bytes, (mp_obj_t)&mp_builtin_bytes_obj);
|
||||||
mp_map_add_qstr(&map_builtins, MP_QSTR_callable, (mp_obj_t)&mp_builtin_callable_obj);
|
mp_map_add_qstr(&map_builtins, MP_QSTR_callable, (mp_obj_t)&mp_builtin_callable_obj);
|
||||||
mp_map_add_qstr(&map_builtins, MP_QSTR_chr, (mp_obj_t)&mp_builtin_chr_obj);
|
mp_map_add_qstr(&map_builtins, MP_QSTR_chr, (mp_obj_t)&mp_builtin_chr_obj);
|
||||||
mp_map_add_qstr(&map_builtins, MP_QSTR_divmod, (mp_obj_t)&mp_builtin_divmod_obj);
|
mp_map_add_qstr(&map_builtins, MP_QSTR_divmod, (mp_obj_t)&mp_builtin_divmod_obj);
|
||||||
|
25
py/sequence.c
Normal file
25
py/sequence.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "nlr.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "mpconfig.h"
|
||||||
|
#include "qstr.h"
|
||||||
|
#include "obj.h"
|
||||||
|
#include "map.h"
|
||||||
|
#include "runtime0.h"
|
||||||
|
#include "runtime.h"
|
||||||
|
|
||||||
|
// Helpers for sequence types
|
||||||
|
|
||||||
|
// Implements backend of sequence * integer operation. Assumes elements are
|
||||||
|
// memory-adjacent in sequence.
|
||||||
|
void mp_seq_multiply(const void *items, uint item_sz, uint len, uint times, void *dest) {
|
||||||
|
for (int i = 0; i < times; i++) {
|
||||||
|
uint copy_sz = item_sz * len;
|
||||||
|
memcpy(dest, items, copy_sz);
|
||||||
|
dest = (char*)dest + copy_sz;
|
||||||
|
}
|
||||||
|
}
|
14
py/stream.c
14
py/stream.c
@ -30,7 +30,8 @@ static mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
|
|||||||
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", error));
|
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", error));
|
||||||
} else {
|
} else {
|
||||||
// TODO don't intern this string
|
// TODO don't intern this string
|
||||||
return mp_obj_new_str(qstr_from_strn_take(buf, sz, out_sz));
|
buf = m_realloc(buf, sz, out_sz);
|
||||||
|
return mp_obj_new_str(qstr_from_strn_take(buf, out_sz, out_sz));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,9 +135,18 @@ static mp_obj_t stream_unbuffered_readline(uint n_args, const mp_obj_t *args) {
|
|||||||
}
|
}
|
||||||
// TODO don't intern this string
|
// TODO don't intern this string
|
||||||
vstr_shrink(vstr);
|
vstr_shrink(vstr);
|
||||||
return mp_obj_new_str(qstr_from_strn_take(vstr_str(vstr), vstr->alloc, vstr_len(vstr)));
|
return MP_OBJ_NEW_QSTR(qstr_from_strn_take(vstr_str(vstr), vstr->alloc, vstr_len(vstr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mp_obj_t mp_stream_unbuffered_iter(mp_obj_t self) {
|
||||||
|
mp_obj_t l_in = stream_unbuffered_readline(1, &self);
|
||||||
|
const char *l = qstr_str(MP_OBJ_QSTR_VALUE(l_in));
|
||||||
|
// TODO: \0
|
||||||
|
if (*l != 0) {
|
||||||
|
return l_in;
|
||||||
|
}
|
||||||
|
return mp_const_stop_iteration;
|
||||||
|
}
|
||||||
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_read_obj, 1, 2, stream_read);
|
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_read_obj, 1, 2, stream_read);
|
||||||
MP_DEFINE_CONST_FUN_OBJ_1(mp_stream_readall_obj, stream_readall);
|
MP_DEFINE_CONST_FUN_OBJ_1(mp_stream_readall_obj, stream_readall);
|
||||||
|
@ -2,3 +2,6 @@ extern const mp_obj_fun_native_t mp_stream_read_obj;
|
|||||||
extern const mp_obj_fun_native_t mp_stream_readall_obj;
|
extern const mp_obj_fun_native_t mp_stream_readall_obj;
|
||||||
extern const mp_obj_fun_native_t mp_stream_unbuffered_readline_obj;
|
extern const mp_obj_fun_native_t mp_stream_unbuffered_readline_obj;
|
||||||
extern const mp_obj_fun_native_t mp_stream_write_obj;
|
extern const mp_obj_fun_native_t mp_stream_write_obj;
|
||||||
|
|
||||||
|
// Iterator which uses mp_stream_unbuffered_readline_obj
|
||||||
|
mp_obj_t mp_stream_unbuffered_iter(mp_obj_t self);
|
||||||
|
@ -8,6 +8,19 @@ print(x)
|
|||||||
|
|
||||||
print('123' + "456")
|
print('123' + "456")
|
||||||
|
|
||||||
|
print('123' * 5)
|
||||||
|
|
||||||
|
print('abc'[1])
|
||||||
|
print('abc'[-1])
|
||||||
|
try:
|
||||||
|
'abc'[100]
|
||||||
|
except IndexError:
|
||||||
|
print('caught')
|
||||||
|
try:
|
||||||
|
'abc'[-4]
|
||||||
|
except IndexError:
|
||||||
|
print('caught2')
|
||||||
|
|
||||||
# iter
|
# iter
|
||||||
print(list('str'))
|
print(list('str'))
|
||||||
|
|
||||||
|
7
tests/basics/string_split.py
Normal file
7
tests/basics/string_split.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
print("a b".split())
|
||||||
|
print(" a b ".split(None))
|
||||||
|
print(" a b ".split(None, 1))
|
||||||
|
print(" a b ".split(None, 2))
|
||||||
|
print(" a b c ".split(None, 1))
|
||||||
|
print(" a b c ".split(None, 0))
|
||||||
|
print(" a b c ".split(None, -1))
|
3
tests/io/file-iter.py
Normal file
3
tests/io/file-iter.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
f = open("io/data/file1")
|
||||||
|
for l in f:
|
||||||
|
print(l)
|
@ -10,7 +10,14 @@ numpassed=0
|
|||||||
numfailed=0
|
numfailed=0
|
||||||
namefailed=
|
namefailed=
|
||||||
|
|
||||||
for infile in basics/*.py io/*.py
|
if [ $# -eq 0 ]
|
||||||
|
then
|
||||||
|
tests="basics/*.py io/*.py"
|
||||||
|
else
|
||||||
|
tests="$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
for infile in $tests
|
||||||
do
|
do
|
||||||
basename=`basename $infile .py`
|
basename=`basename $infile .py`
|
||||||
outfile=${basename}.out
|
outfile=${basename}.out
|
||||||
|
31
unix/file.c
31
unix/file.c
@ -8,6 +8,7 @@
|
|||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
#include "qstr.h"
|
#include "qstr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
|
#include "runtime.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
|
|
||||||
typedef struct _mp_obj_fdfile_t {
|
typedef struct _mp_obj_fdfile_t {
|
||||||
@ -15,6 +16,8 @@ typedef struct _mp_obj_fdfile_t {
|
|||||||
int fd;
|
int fd;
|
||||||
} mp_obj_fdfile_t;
|
} mp_obj_fdfile_t;
|
||||||
|
|
||||||
|
static const mp_obj_type_t rawfile_type;
|
||||||
|
|
||||||
static void fdfile_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
static void fdfile_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||||
mp_obj_fdfile_t *self = self_in;
|
mp_obj_fdfile_t *self = self_in;
|
||||||
print(env, "<io.FileIO %d>", self->fd);
|
print(env, "<io.FileIO %d>", self->fd);
|
||||||
@ -45,6 +48,13 @@ static mp_obj_t fdfile_close(mp_obj_t self_in) {
|
|||||||
}
|
}
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_1(fdfile_close_obj, fdfile_close);
|
static MP_DEFINE_CONST_FUN_OBJ_1(fdfile_close_obj, fdfile_close);
|
||||||
|
|
||||||
|
static mp_obj_fdfile_t *fdfile_new(int fd) {
|
||||||
|
mp_obj_fdfile_t *o = m_new_obj(mp_obj_fdfile_t);
|
||||||
|
o->base.type = &rawfile_type;
|
||||||
|
o->fd = fd;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
static mp_obj_t fdfile_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
|
static mp_obj_t fdfile_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
|
||||||
mp_obj_fdfile_t *o = m_new_obj(mp_obj_fdfile_t);
|
mp_obj_fdfile_t *o = m_new_obj(mp_obj_fdfile_t);
|
||||||
o->base.type = type_in;
|
o->base.type = type_in;
|
||||||
@ -81,11 +91,11 @@ static mp_obj_t fdfile_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
o->fd = open(fname, mode, 0644);
|
int fd = open(fname, mode, 0644);
|
||||||
if (o->fd == -1) {
|
if (fd == -1) {
|
||||||
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_OSError, "[Errno %d]", (const char *)(machine_int_t)errno));
|
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", errno));
|
||||||
}
|
}
|
||||||
return o;
|
return fdfile_new(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const mp_method_t rawfile_type_methods[] = {
|
static const mp_method_t rawfile_type_methods[] = {
|
||||||
@ -102,8 +112,8 @@ static const mp_obj_type_t rawfile_type = {
|
|||||||
"io.FileIO",
|
"io.FileIO",
|
||||||
.print = fdfile_print,
|
.print = fdfile_print,
|
||||||
.make_new = fdfile_make_new,
|
.make_new = fdfile_make_new,
|
||||||
.getiter = NULL,
|
.getiter = mp_identity,
|
||||||
.iternext = NULL,
|
.iternext = mp_stream_unbuffered_iter,
|
||||||
.stream_p = {
|
.stream_p = {
|
||||||
.read = fdfile_read,
|
.read = fdfile_read,
|
||||||
.write = fdfile_write,
|
.write = fdfile_write,
|
||||||
@ -117,3 +127,12 @@ mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args) {
|
|||||||
return fdfile_make_new((mp_obj_t)&rawfile_type, n_args, 0, args);
|
return fdfile_make_new((mp_obj_t)&rawfile_type, n_args, 0, args);
|
||||||
}
|
}
|
||||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_open_obj, 1, 2, mp_builtin_open);
|
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_open_obj, 1, 2, mp_builtin_open);
|
||||||
|
|
||||||
|
void file_init() {
|
||||||
|
rt_store_name(MP_QSTR_open, (mp_obj_t)&mp_builtin_open_obj);
|
||||||
|
|
||||||
|
mp_obj_t m_sys = mp_obj_new_module(MP_QSTR_sys);
|
||||||
|
rt_store_attr(m_sys, MP_QSTR_stdin, fdfile_new(STDIN_FILENO));
|
||||||
|
rt_store_attr(m_sys, MP_QSTR_stdout, fdfile_new(STDOUT_FILENO));
|
||||||
|
rt_store_attr(m_sys, MP_QSTR_stderr, fdfile_new(STDERR_FILENO));
|
||||||
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern const mp_obj_fun_native_t mp_builtin_open_obj;
|
extern const mp_obj_fun_native_t mp_builtin_open_obj;
|
||||||
|
void file_init();
|
||||||
void rawsocket_init();
|
void rawsocket_init();
|
||||||
|
|
||||||
static void execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bool is_repl) {
|
static void execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bool is_repl) {
|
||||||
@ -222,7 +223,8 @@ int main(int argc, char **argv) {
|
|||||||
rt_store_attr(m_sys, MP_QSTR_argv, py_argv);
|
rt_store_attr(m_sys, MP_QSTR_argv, py_argv);
|
||||||
|
|
||||||
rt_store_name(qstr_from_str("test"), test_obj_new(42));
|
rt_store_name(qstr_from_str("test"), test_obj_new(42));
|
||||||
rt_store_name(MP_QSTR_open, (mp_obj_t)&mp_builtin_open_obj);
|
|
||||||
|
file_init();
|
||||||
rawsocket_init();
|
rawsocket_init();
|
||||||
|
|
||||||
// Here is some example code to create a class and instance of that class.
|
// Here is some example code to create a class and instance of that class.
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
Q(sys)
|
Q(sys)
|
||||||
Q(argv)
|
Q(argv)
|
||||||
Q(open)
|
Q(open)
|
||||||
|
Q(stdin)
|
||||||
|
Q(stdout)
|
||||||
|
Q(stderr)
|
||||||
Q(rawsocket)
|
Q(rawsocket)
|
||||||
Q(socket)
|
Q(socket)
|
||||||
Q(sockaddr_in)
|
Q(sockaddr_in)
|
||||||
|
@ -127,6 +127,41 @@ static mp_obj_t socket_accept(mp_obj_t self_in) {
|
|||||||
}
|
}
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept);
|
static MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept);
|
||||||
|
|
||||||
|
static mp_obj_t socket_recv(uint n_args, const mp_obj_t *args) {
|
||||||
|
mp_obj_socket_t *self = args[0];
|
||||||
|
int sz = MP_OBJ_SMALL_INT_VALUE(args[1]);
|
||||||
|
int flags = 0;
|
||||||
|
|
||||||
|
if (n_args > 2) {
|
||||||
|
flags = MP_OBJ_SMALL_INT_VALUE(args[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *buf = m_new(char, sz);
|
||||||
|
int out_sz = recv(self->fd, buf, sz, flags);
|
||||||
|
RAISE_ERRNO(out_sz, errno);
|
||||||
|
|
||||||
|
buf = m_realloc(buf, sz, out_sz);
|
||||||
|
return MP_OBJ_NEW_QSTR(qstr_from_strn_take(buf, out_sz, out_sz));
|
||||||
|
}
|
||||||
|
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_recv_obj, 2, 3, socket_recv);
|
||||||
|
|
||||||
|
static mp_obj_t socket_send(uint n_args, const mp_obj_t *args) {
|
||||||
|
mp_obj_socket_t *self = args[0];
|
||||||
|
int flags = 0;
|
||||||
|
|
||||||
|
if (n_args > 2) {
|
||||||
|
flags = MP_OBJ_SMALL_INT_VALUE(args[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *buf = qstr_str(mp_obj_str_get(args[1]));
|
||||||
|
int sz = strlen(buf);
|
||||||
|
int out_sz = send(self->fd, buf, sz, flags);
|
||||||
|
RAISE_ERRNO(out_sz, errno);
|
||||||
|
|
||||||
|
return MP_OBJ_NEW_SMALL_INT((machine_int_t)out_sz);
|
||||||
|
}
|
||||||
|
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_send_obj, 2, 3, socket_send);
|
||||||
|
|
||||||
static mp_obj_t socket_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
|
static mp_obj_t socket_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
|
||||||
int family = AF_INET;
|
int family = AF_INET;
|
||||||
int type = SOCK_STREAM;
|
int type = SOCK_STREAM;
|
||||||
@ -159,6 +194,8 @@ static const mp_method_t rawsocket_type_methods[] = {
|
|||||||
{ "bind", &socket_bind_obj },
|
{ "bind", &socket_bind_obj },
|
||||||
{ "listen", &socket_listen_obj },
|
{ "listen", &socket_listen_obj },
|
||||||
{ "accept", &socket_accept_obj },
|
{ "accept", &socket_accept_obj },
|
||||||
|
{ "recv", &socket_recv_obj },
|
||||||
|
{ "send", &socket_send_obj },
|
||||||
{ "close", &socket_close_obj },
|
{ "close", &socket_close_obj },
|
||||||
#if MICROPY_SOCKET_EXTRA
|
#if MICROPY_SOCKET_EXTRA
|
||||||
{ "recv", &mp_stream_read_obj },
|
{ "recv", &mp_stream_read_obj },
|
||||||
@ -280,5 +317,4 @@ void rawsocket_init() {
|
|||||||
STORE_INT_CONST(m, SOCK_STREAM);
|
STORE_INT_CONST(m, SOCK_STREAM);
|
||||||
STORE_INT_CONST(m, SOCK_DGRAM);
|
STORE_INT_CONST(m, SOCK_DGRAM);
|
||||||
STORE_INT_CONST(m, SOCK_RAW);
|
STORE_INT_CONST(m, SOCK_RAW);
|
||||||
rt_store_name(MP_QSTR_rawsocket, m);
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user