Revamp qstrs: they now include length and hash.
Can now have null bytes in strings. Can define ROM qstrs per port using qstrdefsport.h
This commit is contained in:
parent
91d457a277
commit
55baff4c9b
19
py/builtin.c
19
py/builtin.c
@ -8,7 +8,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime0.h"
|
||||
#include "runtime.h"
|
||||
@ -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) {
|
||||
int ord = mp_obj_get_int(o_in);
|
||||
if (0 <= ord && ord <= 0x10ffff) {
|
||||
char str[2] = {ord, '\0'};
|
||||
return mp_obj_new_str(qstr_from_strn_copy(str, 1));
|
||||
char str[1] = {ord};
|
||||
return mp_obj_new_str(qstr_from_strn(str, 1));
|
||||
} else {
|
||||
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "chr() arg not in range(0x110000)"));
|
||||
}
|
||||
@ -257,11 +257,12 @@ static mp_obj_t mp_builtin_next(mp_obj_t o) {
|
||||
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) {
|
||||
const char *str = qstr_str(mp_obj_get_qstr(o_in));
|
||||
if (strlen(str) == 1) {
|
||||
uint len;
|
||||
const byte *str = qstr_data(mp_obj_get_qstr(o_in), &len);
|
||||
if (len == 1) {
|
||||
return mp_obj_new_int(str[0]);
|
||||
} else {
|
||||
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "ord() expected a character, but string of length %d found", strlen(str)));
|
||||
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "ord() expected a character, but string of length %d found", len));
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,7 +305,8 @@ 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) {
|
||||
vstr_t *vstr = vstr_new();
|
||||
mp_obj_print_helper((void (*)(void *env, const char *fmt, ...))vstr_printf, vstr, o_in, PRINT_REPR);
|
||||
return mp_obj_new_str(qstr_from_str_take(vstr->buf, vstr->alloc));
|
||||
// TODO don't intern this string
|
||||
return mp_obj_new_str(qstr_from_strn_take(vstr->buf, vstr->alloc, vstr->len));
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_repr_obj, mp_builtin_repr);
|
||||
@ -343,7 +345,8 @@ 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) {
|
||||
vstr_t *vstr = vstr_new();
|
||||
mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, o_in, PRINT_STR);
|
||||
return mp_obj_new_str(qstr_from_str_take(vstr->buf, vstr->alloc));
|
||||
// TODO don't intern this string
|
||||
return mp_obj_new_str(qstr_from_strn_take(vstr->buf, vstr->alloc, vstr->len));
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_str_obj, mp_builtin_str);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "lexerunix.h"
|
||||
#include "parse.h"
|
||||
@ -19,10 +20,11 @@
|
||||
#include "builtin.h"
|
||||
|
||||
static mp_obj_t mp_builtin_eval(mp_obj_t o_in) {
|
||||
const char *str = qstr_str(mp_obj_get_qstr(o_in));
|
||||
uint str_len;
|
||||
const byte *str = qstr_data(mp_obj_get_qstr(o_in), &str_len);
|
||||
|
||||
// create the lexer
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len("<string>", str, strlen(str), 0);
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len("<string>", (const char*)str, str_len, 0);
|
||||
|
||||
// parse the string
|
||||
qstr parse_exc_id;
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "lexerunix.h"
|
||||
#include "parse.h"
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "builtin.h"
|
||||
@ -38,8 +38,8 @@ void mp_module_micropython_init(void) {
|
||||
rt_store_name(MP_QSTR_micropython, m_mp);
|
||||
|
||||
#if MICROPY_MEM_STATS
|
||||
rt_store_attr(m_mp, qstr_from_str_static("mem_total"), (mp_obj_t)&mp_builtin_mem_total_obj);
|
||||
rt_store_attr(m_mp, qstr_from_str_static("mem_current"), (mp_obj_t)&mp_builtin_mem_current_obj);
|
||||
rt_store_attr(m_mp, qstr_from_str_static("mem_peak"), (mp_obj_t)&mp_builtin_mem_peak_obj);
|
||||
rt_store_attr(m_mp, QSTR_FROM_STR_STATIC("mem_total"), (mp_obj_t)&mp_builtin_mem_total_obj);
|
||||
rt_store_attr(m_mp, QSTR_FROM_STR_STATIC("mem_current"), (mp_obj_t)&mp_builtin_mem_current_obj);
|
||||
rt_store_attr(m_mp, QSTR_FROM_STR_STATIC("mem_peak"), (mp_obj_t)&mp_builtin_mem_peak_obj);
|
||||
#endif
|
||||
}
|
||||
|
45
py/compile.c
45
py/compile.c
@ -7,7 +7,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "parse.h"
|
||||
#include "scope.h"
|
||||
@ -273,8 +273,8 @@ static bool cpython_c_tuple_is_const(mp_parse_node_t pn) {
|
||||
}
|
||||
|
||||
static void cpython_c_print_quoted_str(vstr_t *vstr, qstr qstr, bool bytes) {
|
||||
const char *str = qstr_str(qstr);
|
||||
int len = strlen(str);
|
||||
uint len;
|
||||
const byte *str = qstr_data(qstr, &len);
|
||||
bool has_single_quote = false;
|
||||
bool has_double_quote = false;
|
||||
for (int i = 0; i < len; i++) {
|
||||
@ -1169,22 +1169,20 @@ void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q1, qstr *q2) {
|
||||
int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
|
||||
int len = n - 1;
|
||||
for (int i = 0; i < n; i++) {
|
||||
len += strlen(qstr_str(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
|
||||
len += qstr_len(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
|
||||
}
|
||||
char *str = m_new(char, len + 1);
|
||||
char *str_dest = str;
|
||||
str[0] = 0;
|
||||
byte *q_ptr;
|
||||
byte *str_dest = qstr_build_start(len, &q_ptr);
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i > 0) {
|
||||
*str_dest++ = '.';
|
||||
}
|
||||
const char *str_src = qstr_str(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
|
||||
size_t str_src_len = strlen(str_src);
|
||||
uint str_src_len;
|
||||
const byte *str_src = qstr_data(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]), &str_src_len);
|
||||
memcpy(str_dest, str_src, str_src_len);
|
||||
str_dest += str_src_len;
|
||||
}
|
||||
*str_dest = '\0';
|
||||
*q2 = qstr_from_str_take(str, len + 1);
|
||||
*q2 = qstr_build_end(q_ptr);
|
||||
EMIT(import_name, *q2);
|
||||
if (is_as) {
|
||||
for (int i = 1; i < n; i++) {
|
||||
@ -1221,7 +1219,7 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
||||
#if MICROPY_EMIT_CPYTHON
|
||||
EMIT(load_const_verbatim_str, "('*',)");
|
||||
#else
|
||||
EMIT(load_const_str, qstr_from_str_static("*"), false);
|
||||
EMIT(load_const_str, QSTR_FROM_STR_STATIC("*"), false);
|
||||
EMIT(build_tuple, 1);
|
||||
#endif
|
||||
|
||||
@ -1248,7 +1246,9 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
||||
vstr_printf(vstr, ", ");
|
||||
}
|
||||
vstr_printf(vstr, "'");
|
||||
vstr_printf(vstr, qstr_str(id2));
|
||||
uint len;
|
||||
const byte *str = qstr_data(id2, &len);
|
||||
vstr_add_strn(vstr, (const char*)str, len);
|
||||
vstr_printf(vstr, "'");
|
||||
}
|
||||
if (n == 1) {
|
||||
@ -2128,24 +2128,21 @@ void compile_atom_string(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
||||
printf("SyntaxError: cannot mix bytes and nonbytes literals\n");
|
||||
return;
|
||||
}
|
||||
const char *str = qstr_str(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
|
||||
n_bytes += strlen(str);
|
||||
n_bytes += qstr_len(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
|
||||
}
|
||||
|
||||
// allocate memory for concatenated string/bytes
|
||||
char *cat_str = m_new(char, n_bytes + 1);
|
||||
|
||||
// concatenate string/bytes
|
||||
char *s_dest = cat_str;
|
||||
byte *q_ptr;
|
||||
byte *s_dest = qstr_build_start(n_bytes, &q_ptr);
|
||||
for (int i = 0; i < n; i++) {
|
||||
const char *s = qstr_str(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
|
||||
size_t s_len = strlen(s);
|
||||
uint s_len;
|
||||
const byte *s = qstr_data(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]), &s_len);
|
||||
memcpy(s_dest, s, s_len);
|
||||
s_dest += s_len;
|
||||
}
|
||||
*s_dest = '\0';
|
||||
qstr q = qstr_build_end(q_ptr);
|
||||
|
||||
EMIT(load_const_str, qstr_from_str_take(cat_str, n_bytes + 1), string_kind == MP_PARSE_NODE_BYTES);
|
||||
EMIT(load_const_str, q, string_kind == MP_PARSE_NODE_BYTES);
|
||||
}
|
||||
|
||||
// pns needs to have 2 nodes, first is lhs of comprehension, second is PN_comp_for node
|
||||
@ -2767,7 +2764,7 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
|
||||
assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
|
||||
mp_parse_node_struct_t *pns_comp_for = (mp_parse_node_struct_t*)pns->nodes[1];
|
||||
|
||||
qstr qstr_arg = qstr_from_str_static(".0");
|
||||
qstr qstr_arg = QSTR_FROM_STR_STATIC(".0");
|
||||
if (comp->pass == PASS_1) {
|
||||
bool added;
|
||||
id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added);
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "parse.h"
|
||||
#include "scope.h"
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "parse.h"
|
||||
#include "scope.h"
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "parse.h"
|
||||
#include "scope.h"
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "parse.h"
|
||||
#include "scope.h"
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "parse.h"
|
||||
#include "scope.h"
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "parse.h"
|
||||
#include "scope.h"
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
|
||||
#define TAB_SIZE (8)
|
||||
@ -593,7 +595,7 @@ static void mp_lexer_next_token_into(mp_lexer_t *lex, mp_token_t *tok, bool firs
|
||||
mp_lexer_t *mp_lexer_new(const char *src_name, void *stream_data, mp_lexer_stream_next_char_t stream_next_char, mp_lexer_stream_close_t stream_close) {
|
||||
mp_lexer_t *lex = m_new(mp_lexer_t, 1);
|
||||
|
||||
lex->source_name = qstr_from_strn_copy(src_name, strlen(src_name));
|
||||
lex->source_name = qstr_from_str(src_name);
|
||||
lex->stream_data = stream_data;
|
||||
lex->stream_next_char = stream_next_char;
|
||||
lex->stream_close = stream_close;
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
|
||||
typedef struct _mp_lexer_str_buf_t {
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "lexerunix.h"
|
||||
|
||||
|
62
py/makeqstrdata.py
Normal file
62
py/makeqstrdata.py
Normal file
@ -0,0 +1,62 @@
|
||||
import argparse
|
||||
import re
|
||||
|
||||
# this must match the equivalent function in qstr.c
|
||||
def compute_hash(qstr):
|
||||
hash = 0
|
||||
for char in qstr:
|
||||
hash += ord(char)
|
||||
return hash & 0xffff
|
||||
|
||||
def do_work(infiles):
|
||||
# read the qstrs in from the input files
|
||||
qstrs = []
|
||||
for infile in infiles:
|
||||
with open(infile, 'rt') as f:
|
||||
line_number = 0
|
||||
for line in f:
|
||||
line_number += 1
|
||||
line = line.strip()
|
||||
|
||||
# ignore blank lines and comments
|
||||
if len(line) == 0 or line.startswith('//'):
|
||||
continue
|
||||
|
||||
# verify line is of the correct form
|
||||
match = re.match(r'Q\(([0-9A-Za-z_]+)\)$', line)
|
||||
if not match:
|
||||
print('({}:{}) bad qstr format, got {}'.format(infile, line_number, line))
|
||||
return False
|
||||
|
||||
# get the qstr value
|
||||
qstr = match.group(1)
|
||||
|
||||
# don't add duplicates
|
||||
if qstr in qstrs:
|
||||
continue
|
||||
|
||||
# add the qstr to the list
|
||||
qstrs.append(qstr)
|
||||
|
||||
# process the qstrs, printing out the generated C header file
|
||||
print('// This file was automatically generated by makeqstrdata.py')
|
||||
print()
|
||||
for qstr in qstrs:
|
||||
qhash = compute_hash(qstr)
|
||||
qlen = len(qstr)
|
||||
print('Q({}, (const byte*)"\\x{:02x}\\x{:02x}\\x{:02x}\\x{:02x}" "{}")'.format(qstr, qhash & 0xff, (qhash >> 8) & 0xff, qlen & 0xff, (qlen >> 8) & 0xff, qstr))
|
||||
|
||||
return True
|
||||
|
||||
def main():
|
||||
arg_parser = argparse.ArgumentParser(description='Process raw qstr file and output qstr data with length, hash and data bytes')
|
||||
arg_parser.add_argument('files', nargs='+', help='input file(s)')
|
||||
args = arg_parser.parse_args()
|
||||
|
||||
result = do_work(args.files)
|
||||
if not result:
|
||||
print('exiting with error code')
|
||||
exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
py/map.c
1
py/map.c
@ -4,6 +4,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime0.h"
|
||||
#include "map.h"
|
||||
|
10
py/misc.h
10
py/misc.h
@ -88,14 +88,4 @@ void vstr_printf(vstr_t *vstr, const char *fmt, ...);
|
||||
void vstr_vprintf(vstr_t *vstr, const char *fmt, va_list ap);
|
||||
#endif
|
||||
|
||||
/** unique string ***********************************************/
|
||||
|
||||
typedef unsigned int qstr;
|
||||
|
||||
void qstr_init(void);
|
||||
qstr qstr_from_str_static(const char *str);
|
||||
qstr qstr_from_str_take(char *str, int alloc_len);
|
||||
qstr qstr_from_strn_copy(const char *str, int len);
|
||||
const char* qstr_str(qstr qstr);
|
||||
|
||||
#endif // _INCLUDED_MINILIB_H
|
||||
|
13
py/mpqstr.h
13
py/mpqstr.h
@ -1,13 +0,0 @@
|
||||
// See mpqstrraw.h for a list of qstr's that are available as constants.
|
||||
// Reference them as MP_QSTR_xxxx.
|
||||
//
|
||||
// Note: it would be possible to define MP_QSTR_xxx as qstr_from_str_static("xxx")
|
||||
// for qstrs that are referenced this way, but you don't want to have them in ROM.
|
||||
|
||||
enum {
|
||||
MP_QSTR_nil = 0,
|
||||
#define Q(id) MP_QSTR_##id,
|
||||
#include "mpqstrraw.h"
|
||||
#undef Q
|
||||
MP_QSTR_number_of,
|
||||
} category_t;
|
4
py/obj.c
4
py/obj.c
@ -8,7 +8,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime0.h"
|
||||
#include "runtime.h"
|
||||
@ -268,7 +268,7 @@ 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) {
|
||||
mp_small_int_t len = 0;
|
||||
if (MP_OBJ_IS_TYPE(o_in, &str_type)) {
|
||||
len = strlen(qstr_str(mp_obj_str_get(o_in)));
|
||||
len = qstr_len(mp_obj_str_get(o_in));
|
||||
} else if (MP_OBJ_IS_TYPE(o_in, &tuple_type)) {
|
||||
uint seq_len;
|
||||
mp_obj_t *seq_items;
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "map.h"
|
||||
#include "runtime0.h"
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime0.h"
|
||||
#include "map.h"
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime0.h"
|
||||
#include "runtime.h"
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "objtuple.h"
|
||||
|
||||
@ -100,7 +100,7 @@ mp_obj_t mp_obj_new_exception_msg_varg(qstr id, const char *fmt, ...) {
|
||||
va_start(ap, fmt);
|
||||
vstr_vprintf(vstr, fmt, ap);
|
||||
va_end(ap);
|
||||
o->msg = qstr_from_str_take(vstr->buf, vstr->alloc);
|
||||
o->msg = qstr_from_strn_take(vstr->buf, vstr->alloc, vstr->len);
|
||||
}
|
||||
|
||||
return o;
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime0.h"
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "map.h"
|
||||
#include "runtime.h"
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "bc.h"
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "objint.h"
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "objint.h"
|
||||
#include "runtime0.h"
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "map.h"
|
||||
#include "runtime0.h"
|
||||
@ -259,8 +259,8 @@ mp_obj_t mp_obj_list_sort(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||
}
|
||||
mp_obj_list_t *self = args[0];
|
||||
if (self->len > 1) {
|
||||
mp_map_elem_t *keyfun = mp_map_lookup(kwargs, MP_OBJ_NEW_QSTR(qstr_from_str_static("key")), MP_MAP_LOOKUP);
|
||||
mp_map_elem_t *reverse = mp_map_lookup(kwargs, MP_OBJ_NEW_QSTR(qstr_from_str_static("reverse")), MP_MAP_LOOKUP);
|
||||
mp_map_elem_t *keyfun = mp_map_lookup(kwargs, MP_OBJ_NEW_QSTR(QSTR_FROM_STR_STATIC("key")), MP_MAP_LOOKUP);
|
||||
mp_map_elem_t *reverse = mp_map_lookup(kwargs, MP_OBJ_NEW_QSTR(QSTR_FROM_STR_STATIC("reverse")), MP_MAP_LOOKUP);
|
||||
mp_quicksort(self->items, self->items + self->len - 1,
|
||||
keyfun ? keyfun->value : NULL,
|
||||
reverse && reverse->value ? rt_is_true(reverse->value) : false);
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "map.h"
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
|
||||
typedef struct _mp_obj_none_t {
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "runtime0.h"
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime0.h"
|
||||
|
||||
|
94
py/objstr.c
94
py/objstr.c
@ -7,7 +7,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime0.h"
|
||||
#include "runtime.h"
|
||||
@ -36,9 +36,30 @@ void str_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj
|
||||
mp_obj_str_print_qstr(print, env, self->qstr, kind);
|
||||
}
|
||||
|
||||
// like strstr but with specified length and allows \0 bytes
|
||||
// TODO replace with something more efficient/standard
|
||||
static const byte *find_subbytes(const byte *haystack, uint hlen, const byte *needle, uint nlen) {
|
||||
if (hlen >= nlen) {
|
||||
for (uint i = 0; i <= hlen - nlen; i++) {
|
||||
bool found = true;
|
||||
for (uint j = 0; j < nlen; j++) {
|
||||
if (haystack[i + j] != needle[j]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
return haystack + i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
const char *lhs_str = qstr_str(lhs->qstr);
|
||||
uint lhs_len;
|
||||
const byte *lhs_data = qstr_data(lhs->qstr, &lhs_len);
|
||||
switch (op) {
|
||||
case RT_BINARY_OP_SUBSCR:
|
||||
// TODO: need predicate to check for int-like type (bools are such for example)
|
||||
@ -46,31 +67,30 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
if (MP_OBJ_IS_SMALL_INT(rhs_in)) {
|
||||
// TODO: This implements byte string access for single index so far
|
||||
// TODO: Handle negative indexes.
|
||||
return mp_obj_new_int(lhs_str[mp_obj_get_int(rhs_in)]);
|
||||
return mp_obj_new_int(lhs_data[mp_obj_get_int(rhs_in)]);
|
||||
#if MICROPY_ENABLE_SLICE
|
||||
} else if (MP_OBJ_IS_TYPE(rhs_in, &slice_type)) {
|
||||
machine_int_t start, stop, step;
|
||||
mp_obj_slice_get(rhs_in, &start, &stop, &step);
|
||||
assert(step == 1);
|
||||
int len = strlen(lhs_str);
|
||||
if (start < 0) {
|
||||
start = len + start;
|
||||
start = lhs_len + start;
|
||||
if (start < 0) {
|
||||
start = 0;
|
||||
}
|
||||
} else if (start > len) {
|
||||
start = len;
|
||||
} else if (start > lhs_len) {
|
||||
start = lhs_len;
|
||||
}
|
||||
if (stop <= 0) {
|
||||
stop = len + stop;
|
||||
stop = lhs_len + stop;
|
||||
// CPython returns empty string in such case
|
||||
if (stop < 0) {
|
||||
stop = start;
|
||||
}
|
||||
} else if (stop > len) {
|
||||
stop = len;
|
||||
} else if (stop > lhs_len) {
|
||||
stop = lhs_len;
|
||||
}
|
||||
return mp_obj_new_str(qstr_from_strn_copy(lhs_str + start, stop - start));
|
||||
return mp_obj_new_str(qstr_from_strn((const char*)lhs_data + start, stop - start));
|
||||
#endif
|
||||
} else {
|
||||
// Message doesn't match CPython, but we don't have so much bytes as they
|
||||
@ -82,24 +102,24 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
case RT_BINARY_OP_INPLACE_ADD:
|
||||
if (MP_OBJ_IS_TYPE(rhs_in, &str_type)) {
|
||||
// add 2 strings
|
||||
const char *rhs_str = qstr_str(((mp_obj_str_t*)rhs_in)->qstr);
|
||||
size_t lhs_len = strlen(lhs_str);
|
||||
size_t rhs_len = strlen(rhs_str);
|
||||
int alloc_len = lhs_len + rhs_len + 1;
|
||||
char *val = m_new(char, alloc_len);
|
||||
memcpy(val, lhs_str, lhs_len);
|
||||
memcpy(val + lhs_len, rhs_str, rhs_len);
|
||||
val[lhs_len + rhs_len] = '\0';
|
||||
return mp_obj_new_str(qstr_from_str_take(val, alloc_len));
|
||||
uint rhs_len;
|
||||
const byte *rhs_data = qstr_data(((mp_obj_str_t*)rhs_in)->qstr, &rhs_len);
|
||||
int alloc_len = lhs_len + rhs_len;
|
||||
byte *q_ptr;
|
||||
byte *val = qstr_build_start(alloc_len, &q_ptr);
|
||||
memcpy(val, lhs_data, lhs_len);
|
||||
memcpy(val + lhs_len, rhs_data, rhs_len);
|
||||
return mp_obj_new_str(qstr_build_end(q_ptr));
|
||||
}
|
||||
break;
|
||||
case RT_COMPARE_OP_IN:
|
||||
case RT_COMPARE_OP_NOT_IN:
|
||||
/* NOTE `a in b` is `b.__contains__(a)` */
|
||||
if (MP_OBJ_IS_TYPE(rhs_in, &str_type)) {
|
||||
const char *rhs_str = qstr_str(((mp_obj_str_t*)rhs_in)->qstr);
|
||||
/* FIXME \0 in strs */
|
||||
return MP_BOOL((op == RT_COMPARE_OP_IN) ^ (strstr(lhs_str, rhs_str) == NULL));
|
||||
uint rhs_len;
|
||||
const byte *rhs_data = qstr_data(((mp_obj_str_t*)rhs_in)->qstr, &rhs_len);
|
||||
return MP_BOOL((op == RT_COMPARE_OP_IN) ^ (find_subbytes(lhs_data, lhs_len, rhs_data, rhs_len) == NULL));
|
||||
return mp_const_false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -143,22 +163,22 @@ mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
|
||||
}
|
||||
|
||||
// make joined string
|
||||
char *joined_str = m_new(char, required_len + 1);
|
||||
char *s_dest = joined_str;
|
||||
byte *q_ptr;
|
||||
byte *s_dest = qstr_build_start(required_len, &q_ptr);
|
||||
for (int i = 0; i < seq_len; i++) {
|
||||
if (i > 0) {
|
||||
memcpy(s_dest, sep_str, sep_len);
|
||||
s_dest += sep_len;
|
||||
}
|
||||
const char *s2 = qstr_str(mp_obj_str_get(seq_items[i]));
|
||||
size_t s2_len = strlen(s2);
|
||||
uint s2_len;
|
||||
const byte *s2 = qstr_data(mp_obj_str_get(seq_items[i]), &s2_len);
|
||||
memcpy(s_dest, s2, s2_len);
|
||||
s_dest += s2_len;
|
||||
}
|
||||
*s_dest = '\0';
|
||||
qstr q = qstr_build_end(q_ptr);
|
||||
|
||||
// return joined string
|
||||
return mp_obj_new_str(qstr_from_str_take(joined_str, required_len + 1));
|
||||
return mp_obj_new_str(q);
|
||||
|
||||
bad_arg:
|
||||
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "?str.join expecting a list of str's"));
|
||||
@ -246,20 +266,14 @@ mp_obj_t str_strip(uint n_args, const mp_obj_t *args) {
|
||||
}
|
||||
|
||||
if (first_good_char_pos == 0 && last_good_char_pos == 0) {
|
||||
//string is all whitespace, return '\0'
|
||||
char *empty = m_new(char, 1);
|
||||
empty[0] = '\0';
|
||||
return mp_obj_new_str(qstr_from_str_take(empty, 1));
|
||||
//string is all whitespace, return ''
|
||||
return mp_obj_new_str(MP_QSTR_);
|
||||
}
|
||||
|
||||
assert(last_good_char_pos >= first_good_char_pos);
|
||||
//+1 to accomodate the last character
|
||||
size_t stripped_len = last_good_char_pos - first_good_char_pos + 1;
|
||||
//+1 to accomodate '\0'
|
||||
char *stripped_str = m_new(char, stripped_len + 1);
|
||||
memcpy(stripped_str, orig_str + first_good_char_pos, stripped_len);
|
||||
stripped_str[stripped_len] = '\0';
|
||||
return mp_obj_new_str(qstr_from_str_take(stripped_str, stripped_len + 1));
|
||||
return mp_obj_new_str(qstr_from_strn(orig_str + first_good_char_pos, stripped_len));
|
||||
}
|
||||
|
||||
mp_obj_t str_format(uint n_args, const mp_obj_t *args) {
|
||||
@ -288,7 +302,7 @@ mp_obj_t str_format(uint n_args, const mp_obj_t *args) {
|
||||
}
|
||||
}
|
||||
|
||||
return mp_obj_new_str(qstr_from_str_take(vstr->buf, vstr->alloc));
|
||||
return mp_obj_new_str(qstr_from_strn_take(vstr->buf, vstr->alloc, vstr->len));
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj, 2, 4, str_find);
|
||||
@ -339,7 +353,7 @@ mp_obj_t str_it_iternext(mp_obj_t self_in) {
|
||||
mp_obj_str_it_t *self = self_in;
|
||||
const char *str = qstr_str(self->str->qstr);
|
||||
if (self->cur < strlen(str)) {
|
||||
mp_obj_t o_out = mp_obj_new_str(qstr_from_strn_copy(str + self->cur, 1));
|
||||
mp_obj_t o_out = mp_obj_new_str(qstr_from_strn(str + self->cur, 1));
|
||||
self->cur += 1;
|
||||
return o_out;
|
||||
} else {
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime0.h"
|
||||
#include "runtime.h"
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "map.h"
|
||||
#include "runtime0.h"
|
||||
@ -166,7 +166,7 @@ static mp_obj_t class_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
if (op_name == NULL) {
|
||||
return MP_OBJ_NULL;
|
||||
}
|
||||
mp_obj_t member = mp_obj_class_lookup(lhs->base.type, qstr_from_str_static(op_name));
|
||||
mp_obj_t member = mp_obj_class_lookup(lhs->base.type, QSTR_FROM_STR_STATIC(op_name));
|
||||
if (member != MP_OBJ_NULL) {
|
||||
return rt_call_function_2(member, lhs_in, rhs_in);
|
||||
} else {
|
||||
@ -219,7 +219,7 @@ static bool class_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) {
|
||||
|
||||
bool class_store_item(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
||||
mp_obj_class_t *self = self_in;
|
||||
mp_obj_t member = mp_obj_class_lookup(self->base.type, qstr_from_str_static("__setitem__"));
|
||||
mp_obj_t member = mp_obj_class_lookup(self->base.type, QSTR_FROM_STR_STATIC("__setitem__"));
|
||||
if (member != MP_OBJ_NULL) {
|
||||
mp_obj_t args[3] = {self_in, index, value};
|
||||
rt_call_function_n_kw(member, 3, 0, args);
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
|
||||
|
12
py/parse.c
12
py/parse.c
@ -8,7 +8,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "parse.h"
|
||||
|
||||
@ -205,7 +205,7 @@ static void push_result_token(parser_t *parser, const mp_lexer_t *lex) {
|
||||
const mp_token_t *tok = mp_lexer_cur(lex);
|
||||
mp_parse_node_t pn;
|
||||
if (tok->kind == MP_TOKEN_NAME) {
|
||||
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_ID, qstr_from_strn_copy(tok->str, tok->len));
|
||||
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_ID, qstr_from_strn(tok->str, tok->len));
|
||||
} else if (tok->kind == MP_TOKEN_NUMBER) {
|
||||
bool dec = false;
|
||||
bool small_int = true;
|
||||
@ -254,16 +254,16 @@ static void push_result_token(parser_t *parser, const mp_lexer_t *lex) {
|
||||
}
|
||||
}
|
||||
if (dec) {
|
||||
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_DECIMAL, qstr_from_strn_copy(str, len));
|
||||
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_DECIMAL, qstr_from_strn(str, len));
|
||||
} else if (small_int && !overflow && MP_FIT_SMALL_INT(int_val)) {
|
||||
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, int_val);
|
||||
} else {
|
||||
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_INTEGER, qstr_from_strn_copy(str, len));
|
||||
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_INTEGER, qstr_from_strn(str, len));
|
||||
}
|
||||
} else if (tok->kind == MP_TOKEN_STRING) {
|
||||
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_STRING, qstr_from_strn_copy(tok->str, tok->len));
|
||||
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_STRING, qstr_from_strn(tok->str, tok->len));
|
||||
} else if (tok->kind == MP_TOKEN_BYTES) {
|
||||
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_BYTES, qstr_from_strn_copy(tok->str, tok->len));
|
||||
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_BYTES, qstr_from_strn(tok->str, tok->len));
|
||||
} else {
|
||||
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_TOKEN, tok->kind);
|
||||
}
|
||||
|
31
py/py.mk
31
py/py.mk
@ -25,13 +25,8 @@ endif
|
||||
|
||||
# default settings; can be overriden in main Makefile
|
||||
|
||||
ifndef PY_SRC
|
||||
PY_SRC = ../py
|
||||
endif
|
||||
|
||||
ifndef BUILD
|
||||
BUILD = build
|
||||
endif
|
||||
PY_SRC ?= ../py
|
||||
BUILD ?= build
|
||||
|
||||
# to create the build directory
|
||||
|
||||
@ -42,6 +37,10 @@ $(BUILD):
|
||||
|
||||
PY_BUILD = $(BUILD)/py.
|
||||
|
||||
# file containing qstr defs for the core Python bit
|
||||
|
||||
PY_QSTR_DEFS = $(PY_SRC)/qstrdefs.h
|
||||
|
||||
# py object files
|
||||
|
||||
PY_O_BASENAME = \
|
||||
@ -97,6 +96,7 @@ PY_O_BASENAME = \
|
||||
objstr.o \
|
||||
objtuple.o \
|
||||
objtype.o \
|
||||
objzip.o \
|
||||
stream.o \
|
||||
builtin.o \
|
||||
builtinimport.o \
|
||||
@ -105,12 +105,21 @@ PY_O_BASENAME = \
|
||||
vm.o \
|
||||
showbc.o \
|
||||
repl.o \
|
||||
objzip.o \
|
||||
|
||||
# prepend the build destination prefix to the py object files
|
||||
|
||||
PY_O = $(addprefix $(PY_BUILD), $(PY_O_BASENAME))
|
||||
|
||||
# qstr data
|
||||
|
||||
$(PY_BUILD)qstr.o: $(PY_BUILD)qstrdefs.generated.h
|
||||
|
||||
$(PY_BUILD)qstrdefs.generated.h: $(PY_QSTR_DEFS) $(QSTR_DEFS) $(PY_SRC)/makeqstrdata.py
|
||||
$(ECHO) "makeqstrdata $(PY_QSTR_DEFS) $(QSTR_DEFS)"
|
||||
$(Q)python $(PY_SRC)/makeqstrdata.py $(PY_QSTR_DEFS) $(QSTR_DEFS) > $@
|
||||
|
||||
# emitters
|
||||
|
||||
$(PY_BUILD)emitnx64.o: $(PY_SRC)/emitnative.c $(PY_SRC)/emit.h mpconfigport.h
|
||||
$(ECHO) "CC $<"
|
||||
$(Q)$(CC) $(CFLAGS) -DN_X64 -c -o $@ $<
|
||||
@ -119,11 +128,13 @@ $(PY_BUILD)emitnthumb.o: $(PY_SRC)/emitnative.c $(PY_SRC)/emit.h mpconfigport.h
|
||||
$(ECHO) "CC $<"
|
||||
$(Q)$(CC) $(CFLAGS) -DN_THUMB -c -o $@ $<
|
||||
|
||||
# general source files
|
||||
|
||||
$(PY_BUILD)%.o: $(PY_SRC)/%.S
|
||||
$(ECHO) "CC $<"
|
||||
$(Q)$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(PY_BUILD)%.o: $(PY_SRC)/%.c mpconfigport.h
|
||||
$(PY_BUILD)%.o: $(PY_SRC)/%.c mpconfigport.h $(PY_SRC)/qstr.h $(PY_QSTR_DEFS) $(QSTR_DEFS)
|
||||
$(ECHO) "CC $<"
|
||||
$(Q)$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
@ -141,5 +152,5 @@ $(PY_BUILD)vm.o: $(PY_SRC)/vm.c
|
||||
|
||||
$(PY_BUILD)parse.o: $(PY_SRC)/grammar.h
|
||||
$(PY_BUILD)compile.o: $(PY_SRC)/grammar.h
|
||||
$(PY_BUILD)/emitcpy.o: $(PY_SRC)/emit.h
|
||||
$(PY_BUILD)emitcpy.o: $(PY_SRC)/emit.h
|
||||
$(PY_BUILD)emitbc.o: $(PY_SRC)/emit.h
|
||||
|
158
py/qstr.c
158
py/qstr.c
@ -2,7 +2,8 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpqstr.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
|
||||
// NOTE: we are using linear arrays to store and search for qstr's (unique strings, interned strings)
|
||||
// ultimately we will replace this with a static hash table of some kind
|
||||
@ -15,12 +16,33 @@
|
||||
#define DEBUG_printf(args...) (void)0
|
||||
#endif
|
||||
|
||||
// A qstr is an index into the qstr pool.
|
||||
// The data for a qstr contains (hash, length, data).
|
||||
// For now we use very simple encoding, just to get the framework correct:
|
||||
// - hash is 2 bytes (simply the sum of data bytes)
|
||||
// - length is 2 bytes
|
||||
// - data follows
|
||||
// - \0 terminated (for now, so they can be printed using printf)
|
||||
|
||||
#define Q_GET_HASH(q) ((q)[0] | ((q)[1] << 8))
|
||||
#define Q_GET_ALLOC(q) (4 + Q_GET_LENGTH(q) + 1)
|
||||
#define Q_GET_LENGTH(q) ((q)[2] | ((q)[3] << 8))
|
||||
#define Q_GET_DATA(q) ((q) + 4)
|
||||
|
||||
static machine_uint_t compute_hash(const byte *data, uint len) {
|
||||
machine_uint_t hash = 0;
|
||||
for (const byte *top = data + len; data < top; data++) {
|
||||
hash += *data;
|
||||
}
|
||||
return hash & 0xffff;
|
||||
}
|
||||
|
||||
typedef struct _qstr_pool_t {
|
||||
struct _qstr_pool_t *prev;
|
||||
uint total_prev_len;
|
||||
uint alloc;
|
||||
uint len;
|
||||
const char *qstrs[];
|
||||
const byte *qstrs[];
|
||||
} qstr_pool_t;
|
||||
|
||||
const static qstr_pool_t const_pool = {
|
||||
@ -29,9 +51,11 @@ const static qstr_pool_t const_pool = {
|
||||
10, // set so that the first dynamically allocated pool is twice this size; must be <= the len (just below)
|
||||
MP_QSTR_number_of, // corresponds to number of strings in array just below
|
||||
{
|
||||
"nil", // must be first, since 0 qstr is nil
|
||||
#define Q(id) #id,
|
||||
#include "mpqstrraw.h"
|
||||
(const byte*) "\0\0\0\0", // invalid/no qstr has empty data
|
||||
(const byte*) "\0\0\0\0", // empty qstr
|
||||
#define Q(id, str) str,
|
||||
// TODO having 'build/' here is a bit of a hack, should take config variable from Makefile
|
||||
#include "build/py.qstrdefs.generated.h"
|
||||
#undef Q
|
||||
},
|
||||
};
|
||||
@ -42,8 +66,20 @@ void qstr_init(void) {
|
||||
last_pool = (qstr_pool_t*)&const_pool; // we won't modify the const_pool since it has no allocated room left
|
||||
}
|
||||
|
||||
static qstr qstr_add(const char *str) {
|
||||
DEBUG_printf("QSTR: add %s\n", str);
|
||||
static const byte *find_qstr(qstr q) {
|
||||
// search pool for this qstr
|
||||
for (qstr_pool_t *pool = last_pool; pool != NULL; pool = pool->prev) {
|
||||
if (q >= pool->total_prev_len) {
|
||||
return pool->qstrs[q - pool->total_prev_len];
|
||||
}
|
||||
}
|
||||
|
||||
// not found
|
||||
return 0;
|
||||
}
|
||||
|
||||
static qstr qstr_add(const byte *q_ptr) {
|
||||
DEBUG_printf("QSTR: add hash=%d len=%d data=%.*s\n", Q_GET_HASH(q_ptr), Q_GET_LENGTH(q_ptr), Q_GET_LENGTH(q_ptr), Q_GET_DATA(q_ptr));
|
||||
|
||||
// make sure we have room in the pool for a new qstr
|
||||
if (last_pool->len >= last_pool->alloc) {
|
||||
@ -57,55 +93,95 @@ static qstr qstr_add(const char *str) {
|
||||
}
|
||||
|
||||
// add the new qstr
|
||||
last_pool->qstrs[last_pool->len++] = str;
|
||||
last_pool->qstrs[last_pool->len++] = q_ptr;
|
||||
|
||||
// return id for the newly-added qstr
|
||||
return last_pool->total_prev_len + last_pool->len - 1;
|
||||
}
|
||||
|
||||
qstr qstr_from_str_static(const char *str) {
|
||||
static qstr qstr_find_strn(const byte *str, uint str_len) {
|
||||
// work out hash of str
|
||||
machine_uint_t str_hash = compute_hash((const byte*)str, str_len);
|
||||
|
||||
// search pools for the data
|
||||
for (qstr_pool_t *pool = last_pool; pool != NULL; pool = pool->prev) {
|
||||
for (const char **qstr = pool->qstrs, **qstr_top = pool->qstrs + pool->len; qstr < qstr_top; qstr++) {
|
||||
if (strcmp(*qstr, str) == 0) {
|
||||
return pool->total_prev_len + (qstr - pool->qstrs);
|
||||
for (const byte **q = pool->qstrs, **q_top = pool->qstrs + pool->len; q < q_top; q++) {
|
||||
if (Q_GET_HASH(*q) == str_hash && Q_GET_LENGTH(*q) == str_len && strncmp((const char*)Q_GET_DATA(*q), (const char*)str, str_len) == 0) {
|
||||
return pool->total_prev_len + (q - pool->qstrs);
|
||||
}
|
||||
}
|
||||
}
|
||||
return qstr_add(str);
|
||||
|
||||
// not found; return null qstr
|
||||
return 0;
|
||||
}
|
||||
|
||||
qstr qstr_from_str_take(char *str, int alloc_len) {
|
||||
for (qstr_pool_t *pool = last_pool; pool != NULL; pool = pool->prev) {
|
||||
for (const char **qstr = pool->qstrs, **qstr_top = pool->qstrs + pool->len; qstr < qstr_top; qstr++) {
|
||||
if (strcmp(*qstr, str) == 0) {
|
||||
m_del(char, str, alloc_len);
|
||||
return pool->total_prev_len + (qstr - pool->qstrs);
|
||||
}
|
||||
}
|
||||
qstr qstr_from_str(const char *str) {
|
||||
return qstr_from_strn(str, strlen(str));
|
||||
}
|
||||
|
||||
qstr qstr_from_strn(const char *str, uint len) {
|
||||
qstr q = qstr_find_strn((const byte*)str, len);
|
||||
if (q == 0) {
|
||||
machine_uint_t hash = compute_hash((const byte*)str, len);
|
||||
byte *q_ptr = m_new(byte, 4 + len + 1);
|
||||
q_ptr[0] = hash;
|
||||
q_ptr[1] = hash >> 8;
|
||||
q_ptr[2] = len;
|
||||
q_ptr[3] = len >> 8;
|
||||
memcpy(q_ptr + 4, str, len);
|
||||
q_ptr[4 + len] = '\0';
|
||||
q = qstr_add(q_ptr);
|
||||
}
|
||||
return qstr_add(str);
|
||||
return q;
|
||||
}
|
||||
|
||||
qstr qstr_from_strn_copy(const char *str, int len) {
|
||||
for (qstr_pool_t *pool = last_pool; pool != NULL; pool = pool->prev) {
|
||||
for (const char **qstr = pool->qstrs, **qstr_top = pool->qstrs + pool->len; qstr < qstr_top; qstr++) {
|
||||
if (strncmp(*qstr, str, len) == 0 && (*qstr)[len] == '\0') {
|
||||
return pool->total_prev_len + (qstr - pool->qstrs);
|
||||
}
|
||||
}
|
||||
qstr qstr_from_strn_take(char *str, uint alloc_len, uint len) {
|
||||
qstr q = qstr_from_strn(str, len);
|
||||
m_del(char, str, alloc_len);
|
||||
return q;
|
||||
}
|
||||
|
||||
byte *qstr_build_start(uint len, byte **q_ptr) {
|
||||
assert(len <= 65535);
|
||||
*q_ptr = m_new(byte, 4 + len + 1);
|
||||
(*q_ptr)[2] = len;
|
||||
(*q_ptr)[3] = len >> 8;
|
||||
return Q_GET_DATA(*q_ptr);
|
||||
}
|
||||
|
||||
qstr qstr_build_end(byte *q_ptr) {
|
||||
qstr q = qstr_find_strn(Q_GET_DATA(q_ptr), Q_GET_LENGTH(q_ptr));
|
||||
if (q == 0) {
|
||||
machine_uint_t len = Q_GET_LENGTH(q_ptr);
|
||||
machine_uint_t hash = compute_hash(Q_GET_DATA(q_ptr), len);
|
||||
q_ptr[0] = hash;
|
||||
q_ptr[1] = hash >> 8;
|
||||
q_ptr[4 + len] = '\0';
|
||||
q = qstr_add(q_ptr);
|
||||
} else {
|
||||
m_del(byte, q_ptr, Q_GET_ALLOC(q_ptr));
|
||||
}
|
||||
return qstr_add(strndup(str, len));
|
||||
return q;
|
||||
}
|
||||
|
||||
// convert qstr id to pointer to its string
|
||||
const char *qstr_str(qstr qstr) {
|
||||
// search
|
||||
for (qstr_pool_t *pool = last_pool; pool != NULL; pool = pool->prev) {
|
||||
if (qstr >= pool->total_prev_len) {
|
||||
return pool->qstrs[qstr - pool->total_prev_len];
|
||||
}
|
||||
}
|
||||
|
||||
// not found, return nil
|
||||
return const_pool.qstrs[0];
|
||||
machine_uint_t qstr_hash(qstr q) {
|
||||
return Q_GET_HASH(find_qstr(q));
|
||||
}
|
||||
|
||||
uint qstr_len(qstr q) {
|
||||
const byte *qd = find_qstr(q);
|
||||
return Q_GET_LENGTH(qd);
|
||||
}
|
||||
|
||||
// XXX to remove!
|
||||
const char *qstr_str(qstr q) {
|
||||
const byte *qd = find_qstr(q);
|
||||
return (const char*)Q_GET_DATA(qd);
|
||||
}
|
||||
|
||||
const byte *qstr_data(qstr q, uint *len) {
|
||||
const byte *qd = find_qstr(q);
|
||||
*len = Q_GET_LENGTH(qd);
|
||||
return Q_GET_DATA(qd);
|
||||
}
|
||||
|
35
py/qstr.h
Normal file
35
py/qstr.h
Normal file
@ -0,0 +1,35 @@
|
||||
// See qstrraw.h for a list of qstr's that are available as constants.
|
||||
// Reference them as MP_QSTR_xxxx.
|
||||
//
|
||||
// Note: it would be possible to define MP_QSTR_xxx as qstr_from_str_static("xxx")
|
||||
// for qstrs that are referenced this way, but you don't want to have them in ROM.
|
||||
|
||||
enum {
|
||||
MP_QSTR_NULL = 0, // indicates invalid/no qstr
|
||||
MP_QSTR_ = 1, // the empty qstr
|
||||
#define Q(id, str) MP_QSTR_##id,
|
||||
// TODO having 'build/py.' here is a bit of a hack, should take config variable from Makefile
|
||||
#include "build/py.qstrdefs.generated.h"
|
||||
#undef Q
|
||||
MP_QSTR_number_of,
|
||||
} category_t;
|
||||
|
||||
typedef machine_uint_t qstr;
|
||||
|
||||
#define QSTR_FROM_STR_STATIC(s) (qstr_from_strn((s), strlen(s)))
|
||||
|
||||
void qstr_init(void);
|
||||
|
||||
qstr qstr_from_str(const char *str);
|
||||
qstr qstr_from_strn(const char *str, uint len);
|
||||
//qstr qstr_from_str_static(const char *str);
|
||||
qstr qstr_from_strn_take(char *str, uint alloc_len, uint len);
|
||||
//qstr qstr_from_strn_copy(const char *str, int len);
|
||||
|
||||
byte* qstr_build_start(uint len, byte **q_ptr);
|
||||
qstr qstr_build_end(byte *q_ptr);
|
||||
|
||||
machine_uint_t qstr_hash(qstr q);
|
||||
const char* qstr_str(qstr q);
|
||||
uint qstr_len(qstr q);
|
||||
const byte* qstr_data(qstr q, uint *len);
|
@ -11,7 +11,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime0.h"
|
||||
#include "runtime.h"
|
||||
@ -154,7 +154,7 @@ void rt_init(void) {
|
||||
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
// Precreate sys module, so "import sys" didn't throw exceptions.
|
||||
mp_obj_new_module(qstr_from_str_static("sys"));
|
||||
mp_obj_new_module(QSTR_FROM_STR_STATIC("sys"));
|
||||
#endif
|
||||
|
||||
mp_module_micropython_init();
|
||||
|
13
py/scope.c
13
py/scope.c
@ -5,6 +5,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "parse.h"
|
||||
#include "scope.h"
|
||||
|
||||
@ -17,7 +18,7 @@ scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint
|
||||
scope->source_file = source_file;
|
||||
switch (kind) {
|
||||
case SCOPE_MODULE:
|
||||
scope->simple_name = qstr_from_str_static("<module>");
|
||||
scope->simple_name = QSTR_FROM_STR_STATIC("<module>");
|
||||
break;
|
||||
case SCOPE_FUNCTION:
|
||||
case SCOPE_CLASS:
|
||||
@ -25,19 +26,19 @@ scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint
|
||||
scope->simple_name = MP_PARSE_NODE_LEAF_ARG(((mp_parse_node_struct_t*)pn)->nodes[0]);
|
||||
break;
|
||||
case SCOPE_LAMBDA:
|
||||
scope->simple_name = qstr_from_str_static("<lambda>");
|
||||
scope->simple_name = QSTR_FROM_STR_STATIC("<lambda>");
|
||||
break;
|
||||
case SCOPE_LIST_COMP:
|
||||
scope->simple_name = qstr_from_str_static("<listcomp>");
|
||||
scope->simple_name = QSTR_FROM_STR_STATIC("<listcomp>");
|
||||
break;
|
||||
case SCOPE_DICT_COMP:
|
||||
scope->simple_name = qstr_from_str_static("<dictcomp>");
|
||||
scope->simple_name = QSTR_FROM_STR_STATIC("<dictcomp>");
|
||||
break;
|
||||
case SCOPE_SET_COMP:
|
||||
scope->simple_name = qstr_from_str_static("<setcomp>");
|
||||
scope->simple_name = QSTR_FROM_STR_STATIC("<setcomp>");
|
||||
break;
|
||||
case SCOPE_GEN_EXPR:
|
||||
scope->simple_name = qstr_from_str_static("<genexpr>");
|
||||
scope->simple_name = QSTR_FROM_STR_STATIC("<genexpr>");
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "bc0.h"
|
||||
|
||||
#if MICROPY_DEBUG_PRINTERS
|
||||
|
27
py/stream.c
27
py/stream.c
@ -3,7 +3,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "stream.h"
|
||||
|
||||
@ -23,15 +23,14 @@ static mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
|
||||
if (n_args == 1 || ((sz = mp_obj_get_int(args[1])) == -1)) {
|
||||
return stream_readall(args[0]);
|
||||
}
|
||||
// +1 because so far we mark end of string with \0
|
||||
char *buf = m_new(char, sz + 1);
|
||||
char *buf = m_new(char, sz);
|
||||
int error;
|
||||
machine_int_t out_sz = o->type->stream_p.read(o, buf, sz, &error);
|
||||
if (out_sz == -1) {
|
||||
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", error));
|
||||
} else {
|
||||
buf[out_sz] = 0;
|
||||
return mp_obj_new_str(qstr_from_str_take(buf, /*out_sz,*/ sz + 1));
|
||||
// TODO don't intern this string
|
||||
return mp_obj_new_str(qstr_from_strn_take(buf, sz, out_sz));
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,8 +41,8 @@ static mp_obj_t stream_write(mp_obj_t self_in, mp_obj_t arg) {
|
||||
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_OSError, "Operation not supported"));
|
||||
}
|
||||
|
||||
const char *buf = qstr_str(mp_obj_get_qstr(arg));
|
||||
machine_int_t sz = strlen(buf);
|
||||
uint sz;
|
||||
const byte *buf = qstr_data(mp_obj_get_qstr(arg), &sz);
|
||||
int error;
|
||||
machine_int_t out_sz = o->type->stream_p.write(self_in, buf, sz, &error);
|
||||
if (out_sz == -1) {
|
||||
@ -92,10 +91,9 @@ static mp_obj_t stream_readall(mp_obj_t self_in) {
|
||||
}
|
||||
}
|
||||
}
|
||||
vstr_set_size(vstr, total_size + 1); // TODO: for \0
|
||||
buf = vstr_str(vstr);
|
||||
buf[total_size] = 0;
|
||||
return mp_obj_new_str(qstr_from_str_take(buf, total_size + 1));
|
||||
// TODO don't intern this string
|
||||
vstr_set_size(vstr, total_size);
|
||||
return mp_obj_new_str(qstr_from_strn_take(vstr->buf, vstr->alloc, total_size));
|
||||
}
|
||||
|
||||
// Unbuffered, inefficient implementation of readline() for raw I/O files.
|
||||
@ -113,7 +111,7 @@ static mp_obj_t stream_unbuffered_readline(uint n_args, const mp_obj_t *args) {
|
||||
|
||||
vstr_t *vstr;
|
||||
if (max_size != -1) {
|
||||
vstr = vstr_new_size(max_size + 1); // TODO: \0
|
||||
vstr = vstr_new_size(max_size);
|
||||
} else {
|
||||
vstr = vstr_new();
|
||||
}
|
||||
@ -134,10 +132,9 @@ static mp_obj_t stream_unbuffered_readline(uint n_args, const mp_obj_t *args) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// TODO: \0
|
||||
vstr_add_byte(vstr, 0);
|
||||
// TODO don't intern this string
|
||||
vstr_shrink(vstr);
|
||||
return mp_obj_new_str(qstr_from_str_take(vstr_str(vstr), vstr_len(vstr)));
|
||||
return mp_obj_new_str(qstr_from_strn_take(vstr_str(vstr), vstr->alloc, vstr_len(vstr)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "nlr.h"
|
||||
#include "obj.h"
|
||||
|
||||
|
1
py/vm.c
1
py/vm.c
@ -7,6 +7,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "bc0.h"
|
||||
|
@ -1,6 +1,9 @@
|
||||
# define main target
|
||||
all: all2
|
||||
|
||||
# qstr definitions (must come before including py.mk)
|
||||
QSTR_DEFS = qstrdefsport.h
|
||||
|
||||
# include py core make definitions
|
||||
include ../py/py.mk
|
||||
|
||||
@ -131,7 +134,7 @@ SRC_CC3K = \
|
||||
ccspi.c \
|
||||
pybcc3k.c \
|
||||
|
||||
OBJ = $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o) $(SRC_FATFS:.c=.o) $(SRC_STM:.c=.o) $(SRC_CC3K:.c=.o)) $(PY_O)
|
||||
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o) $(SRC_FATFS:.c=.o) $(SRC_STM:.c=.o) $(SRC_CC3K:.c=.o))
|
||||
#OBJ += $(addprefix $(BUILD)/, $(SRC_STM_OTG:.c=.o))
|
||||
|
||||
all2: $(BUILD) $(BUILD)/flash.dfu
|
||||
@ -155,7 +158,7 @@ $(BUILD)/%.o: %.s
|
||||
$(ECHO) "AS $<"
|
||||
$(Q)$(AS) -o $@ $<
|
||||
|
||||
$(BUILD)/%.o: %.c
|
||||
$(BUILD)/%.o: %.c $(QSTR_DEFS)
|
||||
$(ECHO) "CC $<"
|
||||
$(Q)$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "adc.h"
|
||||
|
||||
|
12
stm/audio.c
12
stm/audio.c
@ -1,4 +1,5 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "stm32f4xx_rcc.h"
|
||||
#include "stm32f4xx_gpio.h"
|
||||
@ -7,6 +8,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "parse.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
@ -90,9 +92,9 @@ void audio_init(void) {
|
||||
// enable interrupt
|
||||
|
||||
// Python interface
|
||||
mp_obj_t m = mp_obj_new_module(qstr_from_str_static("audio"));
|
||||
rt_store_attr(m, qstr_from_str_static("dac"), rt_make_function_n(1, pyb_audio_dac));
|
||||
rt_store_attr(m, qstr_from_str_static("is_full"), rt_make_function_n(0, pyb_audio_is_full));
|
||||
rt_store_attr(m, qstr_from_str_static("fill"), rt_make_function_n(1, pyb_audio_fill));
|
||||
rt_store_name(qstr_from_str_static("audio"), m);
|
||||
mp_obj_t m = mp_obj_new_module(QSTR_FROM_STR_STATIC("audio"));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("dac"), rt_make_function_n(1, pyb_audio_dac));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("is_full"), rt_make_function_n(0, pyb_audio_is_full));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("fill"), rt_make_function_n(1, pyb_audio_fill));
|
||||
rt_store_name(QSTR_FROM_STR_STATIC("audio"), m);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "misc.h"
|
||||
#include "systick.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
|
||||
typedef enum {
|
||||
|
19
stm/lcd.c
19
stm/lcd.c
@ -4,6 +4,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "parse.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
@ -219,15 +220,15 @@ void lcd_init(void) {
|
||||
lcd_next_line = 0;
|
||||
|
||||
// Python interface
|
||||
mp_obj_t m = mp_obj_new_module(qstr_from_str_static("lcd"));
|
||||
rt_store_attr(m, qstr_from_str_static("lcd8"), rt_make_function_n(2, lcd_draw_pixel_8));
|
||||
rt_store_attr(m, qstr_from_str_static("clear"), rt_make_function_n(0, lcd_pix_clear));
|
||||
rt_store_attr(m, qstr_from_str_static("get"), rt_make_function_n(2, lcd_pix_get));
|
||||
rt_store_attr(m, qstr_from_str_static("set"), rt_make_function_n(2, lcd_pix_set));
|
||||
rt_store_attr(m, qstr_from_str_static("reset"), rt_make_function_n(2, lcd_pix_reset));
|
||||
rt_store_attr(m, qstr_from_str_static("show"), rt_make_function_n(0, lcd_pix_show));
|
||||
rt_store_attr(m, qstr_from_str_static("text"), rt_make_function_n(1, lcd_print));
|
||||
rt_store_name(qstr_from_str_static("lcd"), m);
|
||||
mp_obj_t m = mp_obj_new_module(QSTR_FROM_STR_STATIC("lcd"));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("lcd8"), rt_make_function_n(2, lcd_draw_pixel_8));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("clear"), rt_make_function_n(0, lcd_pix_clear));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("get"), rt_make_function_n(2, lcd_pix_get));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("set"), rt_make_function_n(2, lcd_pix_set));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("reset"), rt_make_function_n(2, lcd_pix_reset));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("show"), rt_make_function_n(0, lcd_pix_show));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("text"), rt_make_function_n(1, lcd_print));
|
||||
rt_store_name(QSTR_FROM_STR_STATIC("lcd"), m);
|
||||
}
|
||||
|
||||
void lcd_print_str(const char *str) {
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "led.h"
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "ff.h"
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "lexerfatfs.h"
|
||||
|
||||
|
66
stm/main.c
66
stm/main.c
@ -1,4 +1,5 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include <stm32f4xx_rcc.h>
|
||||
#include <stm32f4xx_syscfg.h>
|
||||
@ -15,7 +16,7 @@
|
||||
#include "misc.h"
|
||||
#include "ff.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "lexer.h"
|
||||
@ -677,11 +678,10 @@ void file_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, m
|
||||
mp_obj_t file_obj_read(mp_obj_t self_in, mp_obj_t arg) {
|
||||
pyb_file_obj_t *self = self_in;
|
||||
int n = mp_obj_get_int(arg);
|
||||
char *buf = m_new(char, n + 1);
|
||||
char *buf = m_new(char, n);
|
||||
UINT n_out;
|
||||
f_read(&self->fp, buf, n, &n_out);
|
||||
buf[n_out] = 0;
|
||||
return mp_obj_new_str(qstr_from_str_take(buf, n + 1));
|
||||
return mp_obj_new_str(qstr_from_strn_take(buf, n, n_out));
|
||||
}
|
||||
|
||||
mp_obj_t file_obj_write(mp_obj_t self_in, mp_obj_t arg) {
|
||||
@ -827,37 +827,37 @@ soft_reset:
|
||||
|
||||
// add some functions to the python namespace
|
||||
{
|
||||
rt_store_name(qstr_from_str_static("help"), rt_make_function_n(0, pyb_help));
|
||||
rt_store_name(MP_QSTR_help, rt_make_function_n(0, pyb_help));
|
||||
|
||||
mp_obj_t m = mp_obj_new_module(qstr_from_str_static("pyb"));
|
||||
rt_store_attr(m, qstr_from_str_static("info"), rt_make_function_n(0, pyb_info));
|
||||
rt_store_attr(m, qstr_from_str_static("sd_test"), rt_make_function_n(0, pyb_sd_test));
|
||||
rt_store_attr(m, qstr_from_str_static("stop"), rt_make_function_n(0, pyb_stop));
|
||||
rt_store_attr(m, qstr_from_str_static("standby"), rt_make_function_n(0, pyb_standby));
|
||||
rt_store_attr(m, qstr_from_str_static("source_dir"), rt_make_function_n(1, pyb_source_dir));
|
||||
rt_store_attr(m, qstr_from_str_static("main"), rt_make_function_n(1, pyb_main));
|
||||
rt_store_attr(m, qstr_from_str_static("sync"), rt_make_function_n(0, pyb_sync));
|
||||
rt_store_attr(m, qstr_from_str_static("gc"), rt_make_function_n(0, pyb_gc));
|
||||
rt_store_attr(m, qstr_from_str_static("delay"), rt_make_function_n(1, pyb_delay));
|
||||
rt_store_attr(m, qstr_from_str_static("led"), rt_make_function_n(1, pyb_led));
|
||||
rt_store_attr(m, qstr_from_str_static("switch"), (mp_obj_t)&pyb_switch_obj);
|
||||
rt_store_attr(m, qstr_from_str_static("servo"), rt_make_function_n(2, pyb_servo_set));
|
||||
rt_store_attr(m, qstr_from_str_static("pwm"), rt_make_function_n(2, pyb_pwm_set));
|
||||
rt_store_attr(m, qstr_from_str_static("accel"), (mp_obj_t)&pyb_mma_read_obj);
|
||||
rt_store_attr(m, qstr_from_str_static("mma_read"), (mp_obj_t)&pyb_mma_read_all_obj);
|
||||
rt_store_attr(m, qstr_from_str_static("mma_mode"), (mp_obj_t)&pyb_mma_write_mode_obj);
|
||||
rt_store_attr(m, qstr_from_str_static("hid"), rt_make_function_n(1, pyb_hid_send_report));
|
||||
rt_store_attr(m, qstr_from_str_static("time"), rt_make_function_n(0, pyb_rtc_read));
|
||||
rt_store_attr(m, qstr_from_str_static("rand"), rt_make_function_n(0, pyb_rng_get));
|
||||
rt_store_attr(m, qstr_from_str_static("Led"), rt_make_function_n(1, pyb_Led));
|
||||
rt_store_attr(m, qstr_from_str_static("Servo"), rt_make_function_n(1, pyb_Servo));
|
||||
rt_store_attr(m, qstr_from_str_static("I2C"), rt_make_function_n(2, pyb_I2C));
|
||||
rt_store_attr(m, qstr_from_str_static("gpio"), (mp_obj_t)&pyb_gpio_obj);
|
||||
rt_store_attr(m, qstr_from_str_static("Usart"), rt_make_function_n(2, pyb_Usart));
|
||||
rt_store_attr(m, qstr_from_str_static("ADC"), rt_make_function_n(1, pyb_ADC));
|
||||
rt_store_name(qstr_from_str_static("pyb"), m);
|
||||
mp_obj_t m = mp_obj_new_module(MP_QSTR_pyb);
|
||||
rt_store_attr(m, MP_QSTR_info, rt_make_function_n(0, pyb_info));
|
||||
rt_store_attr(m, MP_QSTR_sd_test, rt_make_function_n(0, pyb_sd_test));
|
||||
rt_store_attr(m, MP_QSTR_stop, rt_make_function_n(0, pyb_stop));
|
||||
rt_store_attr(m, MP_QSTR_standby, rt_make_function_n(0, pyb_standby));
|
||||
rt_store_attr(m, MP_QSTR_source_dir, rt_make_function_n(1, pyb_source_dir));
|
||||
rt_store_attr(m, MP_QSTR_main, rt_make_function_n(1, pyb_main));
|
||||
rt_store_attr(m, MP_QSTR_sync, rt_make_function_n(0, pyb_sync));
|
||||
rt_store_attr(m, MP_QSTR_gc, rt_make_function_n(0, pyb_gc));
|
||||
rt_store_attr(m, MP_QSTR_delay, rt_make_function_n(1, pyb_delay));
|
||||
rt_store_attr(m, MP_QSTR_led, rt_make_function_n(1, pyb_led));
|
||||
rt_store_attr(m, MP_QSTR_switch, (mp_obj_t)&pyb_switch_obj);
|
||||
rt_store_attr(m, MP_QSTR_servo, rt_make_function_n(2, pyb_servo_set));
|
||||
rt_store_attr(m, MP_QSTR_pwm, rt_make_function_n(2, pyb_pwm_set));
|
||||
rt_store_attr(m, MP_QSTR_accel, (mp_obj_t)&pyb_mma_read_obj);
|
||||
rt_store_attr(m, MP_QSTR_mma_read, (mp_obj_t)&pyb_mma_read_all_obj);
|
||||
rt_store_attr(m, MP_QSTR_mma_mode, (mp_obj_t)&pyb_mma_write_mode_obj);
|
||||
rt_store_attr(m, MP_QSTR_hid, rt_make_function_n(1, pyb_hid_send_report));
|
||||
rt_store_attr(m, MP_QSTR_time, rt_make_function_n(0, pyb_rtc_read));
|
||||
rt_store_attr(m, MP_QSTR_rand, rt_make_function_n(0, pyb_rng_get));
|
||||
rt_store_attr(m, MP_QSTR_Led, rt_make_function_n(1, pyb_Led));
|
||||
rt_store_attr(m, MP_QSTR_Servo, rt_make_function_n(1, pyb_Servo));
|
||||
rt_store_attr(m, MP_QSTR_I2C, rt_make_function_n(2, pyb_I2C));
|
||||
rt_store_attr(m, MP_QSTR_gpio, (mp_obj_t)&pyb_gpio_obj);
|
||||
rt_store_attr(m, MP_QSTR_Usart, rt_make_function_n(2, pyb_Usart));
|
||||
rt_store_attr(m, MP_QSTR_ADC, rt_make_function_n(1, pyb_ADC));
|
||||
rt_store_name(MP_QSTR_pyb, m);
|
||||
|
||||
rt_store_name(qstr_from_str_static("open"), rt_make_function_n(2, pyb_io_open));
|
||||
rt_store_name(MP_QSTR_open, rt_make_function_n(2, pyb_io_open));
|
||||
}
|
||||
|
||||
// print a message to the LCD
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "systick.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
|
@ -1,9 +1,12 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "std.h"
|
||||
#include "misc.h"
|
||||
#include "systick.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "lcd.h"
|
||||
#include "usart.h"
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include <stm32f4xx_rcc.h>
|
||||
#include <stm32f4xx_gpio.h>
|
||||
@ -12,6 +13,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "systick.h"
|
||||
|
||||
#include "nlr.h"
|
||||
@ -58,7 +60,7 @@ mp_obj_t decode_addr(unsigned char *ip, int n_bytes) {
|
||||
} else if (n_bytes == 32) {
|
||||
snprintf(data, 64, "%s", ip);
|
||||
}
|
||||
return mp_obj_new_str(qstr_from_strn_copy(data, strlen(data)));
|
||||
return mp_obj_new_str(qstr_from_strn(data, strlen(data)));
|
||||
}
|
||||
|
||||
void decode_addr_and_store(mp_obj_t object, qstr q_attr, unsigned char *ip, int n_bytes) {
|
||||
@ -78,20 +80,20 @@ mp_obj_t pyb_wlan_get_ip(void) {
|
||||
|
||||
// if it doesn't already exist, make a new empty class for NetAddress objects
|
||||
if (net_address_type == MP_OBJ_NULL) {
|
||||
net_address_type = mp_obj_new_type(qstr_from_str_static("NetAddress"), mp_const_empty_tuple, mp_obj_new_dict(0));
|
||||
net_address_type = mp_obj_new_type(QSTR_FROM_STR_STATIC("NetAddress"), mp_const_empty_tuple, mp_obj_new_dict(0));
|
||||
}
|
||||
|
||||
// make a new NetAddress object
|
||||
mp_obj_t net_addr = rt_call_function_0(net_address_type);
|
||||
|
||||
// fill the NetAddress object with data
|
||||
decode_addr_and_store(net_addr, qstr_from_str_static("ip"), &ipconfig.aucIP[0], 4);
|
||||
decode_addr_and_store(net_addr, qstr_from_str_static("subnet"), &ipconfig.aucSubnetMask[0], 4);
|
||||
decode_addr_and_store(net_addr, qstr_from_str_static("gateway"), &ipconfig.aucDefaultGateway[0], 4);
|
||||
decode_addr_and_store(net_addr, qstr_from_str_static("dhcp"), &ipconfig.aucDHCPServer[0], 4);
|
||||
decode_addr_and_store(net_addr, qstr_from_str_static("dns"), &ipconfig.aucDNSServer[0], 4);
|
||||
decode_addr_and_store(net_addr, qstr_from_str_static("mac"), &ipconfig.uaMacAddr[0], 6);
|
||||
decode_addr_and_store(net_addr, qstr_from_str_static("ssid"), &ipconfig.uaSSID[0], 32);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("ip"), &ipconfig.aucIP[0], 4);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("subnet"), &ipconfig.aucSubnetMask[0], 4);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("gateway"), &ipconfig.aucDefaultGateway[0], 4);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("dhcp"), &ipconfig.aucDHCPServer[0], 4);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("dns"), &ipconfig.aucDNSServer[0], 4);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("mac"), &ipconfig.uaMacAddr[0], 6);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("ssid"), &ipconfig.uaSSID[0], 32);
|
||||
|
||||
return net_addr;
|
||||
}
|
||||
@ -122,12 +124,12 @@ mp_obj_t pyb_wlan_http_get(mp_obj_t host_name, mp_obj_t host_path) {
|
||||
last_ip = (192 << 24) | (168 << 16) | (0 << 8) | (3);
|
||||
} else {
|
||||
if (pyb_wlan_get_host(host_name) == mp_const_none) {
|
||||
nlr_jump(mp_obj_new_exception_msg(qstr_from_str_static("WlanError"), "unknown host"));
|
||||
nlr_jump(mp_obj_new_exception_msg(QSTR_FROM_STR_STATIC("WlanError"), "unknown host"));
|
||||
}
|
||||
}
|
||||
int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (sd < 0) {
|
||||
nlr_jump(mp_obj_new_exception_msg_1_arg(qstr_from_str_static("WlanError"), "socket failed: %d", (void*)sd));
|
||||
nlr_jump(mp_obj_new_exception_msg_1_arg(QSTR_FROM_STR_STATIC("WlanError"), "socket failed: %d", (void*)sd));
|
||||
}
|
||||
//printf("socket seemed to work\n");
|
||||
//sys_tick_delay_ms(200);
|
||||
@ -138,7 +140,7 @@ mp_obj_t pyb_wlan_http_get(mp_obj_t host_name, mp_obj_t host_path) {
|
||||
remote.sin_addr.s_addr = htonl(last_ip);
|
||||
int ret = connect(sd, (sockaddr*)&remote, sizeof(sockaddr));
|
||||
if (ret != 0) {
|
||||
nlr_jump(mp_obj_new_exception_msg_1_arg(qstr_from_str_static("WlanError"), "connect failed: %d", (void*)ret));
|
||||
nlr_jump(mp_obj_new_exception_msg_1_arg(QSTR_FROM_STR_STATIC("WlanError"), "connect failed: %d", (void*)ret));
|
||||
}
|
||||
//printf("connect seemed to work\n");
|
||||
//sys_tick_delay_ms(200);
|
||||
@ -159,7 +161,7 @@ mp_obj_t pyb_wlan_http_get(mp_obj_t host_name, mp_obj_t host_path) {
|
||||
ret = send(sd, query + sent, strlen(query + sent), 0);
|
||||
//printf("sent %d bytes\n", ret);
|
||||
if (ret < 0) {
|
||||
nlr_jump(mp_obj_new_exception_msg(qstr_from_str_static("WlanError"), "send failed"));
|
||||
nlr_jump(mp_obj_new_exception_msg(QSTR_FROM_STR_STATIC("WlanError"), "send failed"));
|
||||
}
|
||||
sent += ret;
|
||||
//sys_tick_delay_ms(200);
|
||||
@ -196,12 +198,12 @@ mp_obj_t pyb_wlan_http_get(mp_obj_t host_name, mp_obj_t host_path) {
|
||||
// read data
|
||||
ret = recv(sd, buf, 64, 0);
|
||||
if (ret < 0) {
|
||||
nlr_jump(mp_obj_new_exception_msg_1_arg(qstr_from_str_static("WlanError"), "recv failed %d", (void*)ret));
|
||||
nlr_jump(mp_obj_new_exception_msg_1_arg(QSTR_FROM_STR_STATIC("WlanError"), "recv failed %d", (void*)ret));
|
||||
}
|
||||
vstr_add_strn(vstr, buf, ret);
|
||||
}
|
||||
|
||||
mp_ret = mp_obj_new_str(qstr_from_str_take(vstr->buf, vstr->alloc));
|
||||
mp_ret = mp_obj_new_str(qstr_from_strn_take(vstr->buf, vstr->alloc, vstr->len));
|
||||
}
|
||||
|
||||
closesocket(sd);
|
||||
@ -216,7 +218,7 @@ mp_obj_t pyb_wlan_serve(void) {
|
||||
sys_tick_delay_ms(500);
|
||||
if (sd < 0) {
|
||||
printf("socket fail\n");
|
||||
nlr_jump(mp_obj_new_exception_msg_1_arg(qstr_from_str_static("WlanError"), "socket failed: %d", (void*)sd));
|
||||
nlr_jump(mp_obj_new_exception_msg_1_arg(QSTR_FROM_STR_STATIC("WlanError"), "socket failed: %d", (void*)sd));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -237,7 +239,7 @@ mp_obj_t pyb_wlan_serve(void) {
|
||||
sys_tick_delay_ms(100);
|
||||
if (ret != 0) {
|
||||
printf("bind fail\n");
|
||||
nlr_jump(mp_obj_new_exception_msg_1_arg(qstr_from_str_static("WlanError"), "bind failed: %d", (void*)ret));
|
||||
nlr_jump(mp_obj_new_exception_msg_1_arg(QSTR_FROM_STR_STATIC("WlanError"), "bind failed: %d", (void*)ret));
|
||||
}
|
||||
printf("bind seemed to work\n");
|
||||
|
||||
@ -355,14 +357,14 @@ void pyb_wlan_init(void) {
|
||||
SpiInit();
|
||||
wlan_init(CC3000_UsynchCallback, sendWLFWPatch, sendDriverPatch, sendBootLoaderPatch, ReadWlanInterruptPin, WlanInterruptEnable, WlanInterruptDisable, WriteWlanPin);
|
||||
|
||||
mp_obj_t m = mp_obj_new_module(qstr_from_str_static("wlan"));
|
||||
rt_store_attr(m, qstr_from_str_static("connect"), rt_make_function_var(0, pyb_wlan_connect));
|
||||
rt_store_attr(m, qstr_from_str_static("disconnect"), rt_make_function_n(0, pyb_wlan_disconnect));
|
||||
rt_store_attr(m, qstr_from_str_static("ip"), rt_make_function_n(0, pyb_wlan_get_ip));
|
||||
rt_store_attr(m, qstr_from_str_static("get_host"), rt_make_function_n(1, pyb_wlan_get_host));
|
||||
rt_store_attr(m, qstr_from_str_static("http_get"), rt_make_function_n(2, pyb_wlan_http_get));
|
||||
rt_store_attr(m, qstr_from_str_static("serve"), rt_make_function_n(0, pyb_wlan_serve));
|
||||
rt_store_name(qstr_from_str_static("wlan"), m);
|
||||
mp_obj_t m = mp_obj_new_module(QSTR_FROM_STR_STATIC("wlan"));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("connect"), rt_make_function_var(0, pyb_wlan_connect));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("disconnect"), rt_make_function_n(0, pyb_wlan_disconnect));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("ip"), rt_make_function_n(0, pyb_wlan_get_ip));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("get_host"), rt_make_function_n(1, pyb_wlan_get_host));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("http_get"), rt_make_function_n(2, pyb_wlan_http_get));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("serve"), rt_make_function_n(0, pyb_wlan_serve));
|
||||
rt_store_name(QSTR_FROM_STR_STATIC("wlan"), m);
|
||||
}
|
||||
|
||||
void pyb_wlan_start(void) {
|
||||
|
30
stm/qstrdefsport.h
Normal file
30
stm/qstrdefsport.h
Normal file
@ -0,0 +1,30 @@
|
||||
// qstrs specific to this port
|
||||
|
||||
Q(help)
|
||||
Q(pyb)
|
||||
Q(info)
|
||||
Q(sd_test)
|
||||
Q(stop)
|
||||
Q(standby)
|
||||
Q(source_dir)
|
||||
Q(main)
|
||||
Q(sync)
|
||||
Q(gc)
|
||||
Q(delay)
|
||||
Q(led)
|
||||
Q(switch)
|
||||
Q(servo)
|
||||
Q(pwm)
|
||||
Q(accel)
|
||||
Q(mma_read)
|
||||
Q(mma_mode)
|
||||
Q(hid)
|
||||
Q(time)
|
||||
Q(rand)
|
||||
Q(Led)
|
||||
Q(Servo)
|
||||
Q(I2C)
|
||||
Q(gpio)
|
||||
Q(Usart)
|
||||
Q(ADC)
|
||||
Q(open)
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "servo.h"
|
||||
|
||||
|
@ -11,7 +11,7 @@ void *memcpy(void *dest, const void *src, size_t n);
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
void *memset(void *s, int c, size_t n);
|
||||
|
||||
int strlen(const char *str);
|
||||
//int strlen(const char *str);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
int strncmp(const char *s1, const char *s2, size_t n);
|
||||
char *strndup(const char *s, size_t n);
|
||||
|
@ -271,6 +271,7 @@ void TIM6_DAC_IRQHandler(void) {
|
||||
#include "std.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "led.h"
|
||||
// EXTI
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "misc.h"
|
||||
#include "systick.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "led.h"
|
||||
#include "flash.h"
|
||||
|
14
stm/timer.c
14
stm/timer.c
@ -1,5 +1,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "stm_misc.h"
|
||||
#include "stm32f4xx_rcc.h"
|
||||
@ -8,6 +9,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "parse.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
@ -71,12 +73,12 @@ void timer_init(void) {
|
||||
TIM_Cmd(TIM6, ENABLE);
|
||||
|
||||
// Python interface
|
||||
mp_obj_t m = mp_obj_new_module(qstr_from_str_static("timer"));
|
||||
rt_store_attr(m, qstr_from_str_static("callback"), rt_make_function_n(1, timer_py_set_callback));
|
||||
rt_store_attr(m, qstr_from_str_static("period"), rt_make_function_n(1, timer_py_set_period));
|
||||
rt_store_attr(m, qstr_from_str_static("prescaler"), rt_make_function_n(1, timer_py_set_prescaler));
|
||||
rt_store_attr(m, qstr_from_str_static("value"), rt_make_function_n(0, timer_py_get_value));
|
||||
rt_store_name(qstr_from_str_static("timer"), m);
|
||||
mp_obj_t m = mp_obj_new_module(QSTR_FROM_STR_STATIC("timer"));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("callback"), rt_make_function_n(1, timer_py_set_callback));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("period"), rt_make_function_n(1, timer_py_set_period));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("prescaler"), rt_make_function_n(1, timer_py_set_prescaler));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("value"), rt_make_function_n(0, timer_py_get_value));
|
||||
rt_store_name(QSTR_FROM_STR_STATIC("timer"), m);
|
||||
}
|
||||
|
||||
void timer_interrupt(void) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "usart.h"
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "usrsw.h"
|
||||
|
||||
|
@ -25,7 +25,7 @@ endif
|
||||
SRC_C = \
|
||||
main.c \
|
||||
|
||||
OBJ = $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) $(PY_O)
|
||||
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
LIB =
|
||||
|
||||
$(PROG): $(BUILD) $(OBJ)
|
||||
|
2
unix/.gitignore
vendored
2
unix/.gitignore
vendored
@ -1,3 +1,3 @@
|
||||
build
|
||||
py
|
||||
micropython
|
||||
*.py
|
||||
|
@ -2,6 +2,9 @@
|
||||
PROG = micropython
|
||||
all: $(PROG)
|
||||
|
||||
# qstr definitions (must come before including py.mk)
|
||||
QSTR_DEFS = qstrdefsport.h
|
||||
|
||||
# include py core make definitions
|
||||
include ../py/py.mk
|
||||
|
||||
@ -27,7 +30,7 @@ SRC_C = \
|
||||
file.c \
|
||||
socket.c \
|
||||
|
||||
OBJ = $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) $(PY_O)
|
||||
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
LIB = -lreadline
|
||||
# the following is needed for BSD
|
||||
#LIB += -ltermcap
|
||||
@ -40,7 +43,7 @@ ifndef DEBUG
|
||||
endif
|
||||
$(Q)size $(PROG)
|
||||
|
||||
$(BUILD)/%.o: %.c
|
||||
$(BUILD)/%.o: %.c $(QSTR_DEFS)
|
||||
$(ECHO) "CC $<"
|
||||
$(Q)$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "stream.h"
|
||||
|
||||
|
17
unix/main.c
17
unix/main.c
@ -6,6 +6,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "lexerunix.h"
|
||||
#include "parse.h"
|
||||
@ -216,12 +217,12 @@ int main(int argc, char **argv) {
|
||||
qstr_init();
|
||||
rt_init();
|
||||
|
||||
mp_obj_t m_sys = mp_obj_new_module(qstr_from_str_static("sys"));
|
||||
mp_obj_t m_sys = mp_obj_new_module(MP_QSTR_sys);
|
||||
mp_obj_t py_argv = mp_obj_new_list(0, NULL);
|
||||
rt_store_attr(m_sys, qstr_from_str_static("argv"), py_argv);
|
||||
rt_store_attr(m_sys, MP_QSTR_argv, py_argv);
|
||||
|
||||
rt_store_name(qstr_from_str_static("test"), test_obj_new(42));
|
||||
rt_store_name(qstr_from_str_static("open"), (mp_obj_t)&mp_builtin_open_obj);
|
||||
rt_store_name(qstr_from_str("test"), test_obj_new(42));
|
||||
rt_store_name(MP_QSTR_open, (mp_obj_t)&mp_builtin_open_obj);
|
||||
rawsocket_init();
|
||||
|
||||
// Here is some example code to create a class and instance of that class.
|
||||
@ -232,9 +233,9 @@ int main(int argc, char **argv) {
|
||||
// test_obj = TestClass()
|
||||
// test_obj.attr = 42
|
||||
mp_obj_t test_class_type, test_class_instance;
|
||||
test_class_type = mp_obj_new_type(qstr_from_str_static("TestClass"), mp_const_empty_tuple, mp_obj_new_dict(0));
|
||||
rt_store_name(qstr_from_str_static("test_obj"), test_class_instance = rt_call_function_0(test_class_type));
|
||||
rt_store_attr(test_class_instance, qstr_from_str_static("attr"), mp_obj_new_int(42));
|
||||
test_class_type = mp_obj_new_type(QSTR_FROM_STR_STATIC("TestClass"), mp_const_empty_tuple, mp_obj_new_dict(0));
|
||||
rt_store_name(QSTR_FROM_STR_STATIC("test_obj"), test_class_instance = rt_call_function_0(test_class_type));
|
||||
rt_store_attr(test_class_instance, QSTR_FROM_STR_STATIC("attr"), mp_obj_new_int(42));
|
||||
|
||||
/*
|
||||
printf("bytes:\n");
|
||||
@ -259,7 +260,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
} else {
|
||||
for (int i = a; i < argc; i++) {
|
||||
rt_list_append(py_argv, MP_OBJ_NEW_QSTR(qstr_from_strn_copy(argv[i], strlen(argv[i]))));
|
||||
rt_list_append(py_argv, MP_OBJ_NEW_QSTR(qstr_from_str(argv[i])));
|
||||
}
|
||||
do_file(argv[a]);
|
||||
break;
|
||||
|
13
unix/qstrdefsport.h
Normal file
13
unix/qstrdefsport.h
Normal file
@ -0,0 +1,13 @@
|
||||
// qstrs specific to this port
|
||||
|
||||
Q(sys)
|
||||
Q(argv)
|
||||
Q(open)
|
||||
Q(rawsocket)
|
||||
Q(socket)
|
||||
Q(sockaddr_in)
|
||||
Q(htons)
|
||||
Q(inet_aton)
|
||||
Q(gethostbyname)
|
||||
Q(getaddrinfo)
|
||||
Q(rawsocket)
|
@ -10,7 +10,7 @@
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "mpqstr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "objtuple.h"
|
||||
#include "objarray.h"
|
||||
@ -249,7 +249,7 @@ static mp_obj_t mod_socket_getaddrinfo(uint n_args, const mp_obj_t *args) {
|
||||
// "canonname will be a string representing the canonical name of the host
|
||||
// if AI_CANONNAME is part of the flags argument; else canonname will be empty." ??
|
||||
if (addr->ai_canonname) {
|
||||
t->items[3] = MP_OBJ_NEW_QSTR(qstr_from_strn_copy(addr->ai_canonname, strlen(addr->ai_canonname)));
|
||||
t->items[3] = MP_OBJ_NEW_QSTR(qstr_from_str(addr->ai_canonname));
|
||||
} else {
|
||||
t->items[3] = mp_const_none;
|
||||
}
|
||||
@ -262,23 +262,23 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_socket_getaddrinfo_obj, 2, 6, mod
|
||||
|
||||
extern mp_obj_type_t sockaddr_in_type;
|
||||
|
||||
#define STORE_INT_CONST(m, name) rt_store_attr(m, qstr_from_str_static(#name), MP_OBJ_NEW_SMALL_INT(name))
|
||||
#define STORE_INT_CONST(m, name) rt_store_attr(m, QSTR_FROM_STR_STATIC(#name), MP_OBJ_NEW_SMALL_INT(name))
|
||||
|
||||
void rawsocket_init() {
|
||||
mp_obj_t m = mp_obj_new_module(qstr_from_str_static("rawsocket"));
|
||||
rt_store_attr(m, qstr_from_str_static("socket"), (mp_obj_t)&rawsocket_type);
|
||||
mp_obj_t m = mp_obj_new_module(MP_QSTR_rawsocket);
|
||||
rt_store_attr(m, MP_QSTR_socket, (mp_obj_t)&rawsocket_type);
|
||||
#if MICROPY_SOCKET_EXTRA
|
||||
rt_store_attr(m, qstr_from_str_static("sockaddr_in"), (mp_obj_t)&sockaddr_in_type);
|
||||
rt_store_attr(m, qstr_from_str_static("htons"), (mp_obj_t)&mod_socket_htons_obj);
|
||||
rt_store_attr(m, qstr_from_str_static("inet_aton"), (mp_obj_t)&mod_socket_inet_aton_obj);
|
||||
rt_store_attr(m, qstr_from_str_static("gethostbyname"), (mp_obj_t)&mod_socket_gethostbyname_obj);
|
||||
rt_store_attr(m, MP_QSTR_sockaddr_in, (mp_obj_t)&sockaddr_in_type);
|
||||
rt_store_attr(m, MP_QSTR_htons, (mp_obj_t)&mod_socket_htons_obj);
|
||||
rt_store_attr(m, MP_QSTR_inet_aton, (mp_obj_t)&mod_socket_inet_aton_obj);
|
||||
rt_store_attr(m, MP_QSTR_gethostbyname, (mp_obj_t)&mod_socket_gethostbyname_obj);
|
||||
#endif
|
||||
rt_store_attr(m, qstr_from_str_static("getaddrinfo"), (mp_obj_t)&mod_socket_getaddrinfo_obj);
|
||||
rt_store_attr(m, MP_QSTR_getaddrinfo, (mp_obj_t)&mod_socket_getaddrinfo_obj);
|
||||
STORE_INT_CONST(m, AF_UNIX);
|
||||
STORE_INT_CONST(m, AF_INET);
|
||||
STORE_INT_CONST(m, AF_INET6);
|
||||
STORE_INT_CONST(m, SOCK_STREAM);
|
||||
STORE_INT_CONST(m, SOCK_DGRAM);
|
||||
STORE_INT_CONST(m, SOCK_RAW);
|
||||
rt_store_name(qstr_from_str_static("rawsocket"), m);
|
||||
rt_store_name(MP_QSTR_rawsocket, m);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user