summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
Diffstat (limited to 'py')
-rw-r--r--py/builtin.h1
-rw-r--r--py/builtintables.c3
-rw-r--r--py/mpconfig.h4
-rw-r--r--py/obj.h3
-rw-r--r--py/objbool.c14
-rw-r--r--py/objdict.c7
-rw-r--r--py/objlist.c5
-rw-r--r--py/objnone.c6
-rw-r--r--py/objstr.c32
-rw-r--r--py/objstrunicode.c36
-rw-r--r--py/objtuple.c19
-rw-r--r--py/py.mk1
-rw-r--r--py/qstrdefs.h5
13 files changed, 123 insertions, 13 deletions
diff --git a/py/builtin.h b/py/builtin.h
index 1bb61f6ebc..9c8b2b9be2 100644
--- a/py/builtin.h
+++ b/py/builtin.h
@@ -89,3 +89,4 @@ extern struct _dummy_t mp_sys_stderr_obj;
// extmod modules
extern const mp_obj_module_t mp_module_uctypes;
extern const mp_obj_module_t mp_module_zlibd;
+extern const mp_obj_module_t mp_module_ujson;
diff --git a/py/builtintables.c b/py/builtintables.c
index 08b6b16493..391077d434 100644
--- a/py/builtintables.c
+++ b/py/builtintables.c
@@ -200,6 +200,9 @@ STATIC const mp_map_elem_t mp_builtin_module_table[] = {
#if MICROPY_PY_ZLIBD
{ MP_OBJ_NEW_QSTR(MP_QSTR_zlibd), (mp_obj_t)&mp_module_zlibd },
#endif
+#if MICROPY_PY_UJSON
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ujson), (mp_obj_t)&mp_module_ujson },
+#endif
// extra builtin modules as defined by a port
MICROPY_PORT_BUILTIN_MODULES
diff --git a/py/mpconfig.h b/py/mpconfig.h
index adbcb0eb71..cf85533395 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -390,6 +390,10 @@ typedef double mp_float_t;
#define MICROPY_PY_ZLIBD (0)
#endif
+#ifndef MICROPY_PY_UJSON
+#define MICROPY_PY_UJSON (0)
+#endif
+
/*****************************************************************************/
/* Hooks for a port to add builtins */
diff --git a/py/obj.h b/py/obj.h
index c7745dc9eb..9fee0413ae 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -187,7 +187,8 @@ typedef enum {
PRINT_STR = 0,
PRINT_REPR = 1,
PRINT_EXC = 2, // Special format for printing exception in unhandled exception message
- PRINT_EXC_SUBCLASS = 4, // Internal flag for printing exception subclasses
+ PRINT_JSON = 3,
+ PRINT_EXC_SUBCLASS = 0x80, // Internal flag for printing exception subclasses
} mp_print_kind_t;
typedef void (*mp_print_fun_t)(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o, mp_print_kind_t kind);
diff --git a/py/objbool.c b/py/objbool.c
index dbe84d92e2..e6b5230f74 100644
--- a/py/objbool.c
+++ b/py/objbool.c
@@ -41,10 +41,18 @@ typedef struct _mp_obj_bool_t {
STATIC void bool_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_bool_t *self = self_in;
- if (self->value) {
- print(env, "True");
+ if (MICROPY_PY_UJSON && kind == PRINT_JSON) {
+ if (self->value) {
+ print(env, "true");
+ } else {
+ print(env, "false");
+ }
} else {
- print(env, "False");
+ if (self->value) {
+ print(env, "True");
+ } else {
+ print(env, "False");
+ }
}
}
diff --git a/py/objdict.c b/py/objdict.c
index a378bf6db8..a624320427 100644
--- a/py/objdict.c
+++ b/py/objdict.c
@@ -60,6 +60,9 @@ STATIC mp_map_elem_t *dict_iter_next(mp_obj_dict_t *dict, mp_uint_t *cur) {
STATIC void dict_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_dict_t *self = self_in;
bool first = true;
+ if (!(MICROPY_PY_UJSON && kind == PRINT_JSON)) {
+ kind = PRINT_REPR;
+ }
print(env, "{");
mp_uint_t cur = 0;
mp_map_elem_t *next = NULL;
@@ -68,9 +71,9 @@ STATIC void dict_print(void (*print)(void *env, const char *fmt, ...), void *env
print(env, ", ");
}
first = false;
- mp_obj_print_helper(print, env, next->key, PRINT_REPR);
+ mp_obj_print_helper(print, env, next->key, kind);
print(env, ": ");
- mp_obj_print_helper(print, env, next->value, PRINT_REPR);
+ mp_obj_print_helper(print, env, next->value, kind);
}
print(env, "}");
}
diff --git a/py/objlist.c b/py/objlist.c
index 59390f371f..789a1600d3 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -49,12 +49,15 @@ STATIC mp_obj_t list_pop(mp_uint_t n_args, const mp_obj_t *args);
STATIC void list_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
mp_obj_list_t *o = o_in;
+ if (!(MICROPY_PY_UJSON && kind == PRINT_JSON)) {
+ kind = PRINT_REPR;
+ }
print(env, "[");
for (mp_uint_t i = 0; i < o->len; i++) {
if (i > 0) {
print(env, ", ");
}
- mp_obj_print_helper(print, env, o->items[i], PRINT_REPR);
+ mp_obj_print_helper(print, env, o->items[i], kind);
}
print(env, "]");
}
diff --git a/py/objnone.c b/py/objnone.c
index a8d6071435..01536dcb34 100644
--- a/py/objnone.c
+++ b/py/objnone.c
@@ -38,7 +38,11 @@ typedef struct _mp_obj_none_t {
} mp_obj_none_t;
STATIC void none_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
- print(env, "None");
+ if (MICROPY_PY_UJSON && kind == PRINT_JSON) {
+ print(env, "null");
+ } else {
+ print(env, "None");
+ }
}
STATIC mp_obj_t none_unary_op(mp_uint_t op, mp_obj_t o_in) {
diff --git a/py/objstr.c b/py/objstr.c
index b2afcdc98e..130af8a6af 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -92,9 +92,41 @@ void mp_str_print_quoted(void (*print)(void *env, const char *fmt, ...), void *e
print(env, "%c", quote_char);
}
+#if MICROPY_PY_UJSON
+STATIC void str_print_json(void (*print)(void *env, const char *fmt, ...), void *env, const byte *str_data, mp_uint_t str_len) {
+ print(env, "\"");
+ for (const byte *s = str_data, *top = str_data + str_len; s < top; s++) {
+ if (*s == '"' || *s == '\\' || *s == '/') {
+ print(env, "\\%c", *s);
+ } else if (32 <= *s && *s <= 126) {
+ print(env, "%c", *s);
+ } else if (*s == '\b') {
+ print(env, "\\b");
+ } else if (*s == '\f') {
+ print(env, "\\f");
+ } else if (*s == '\n') {
+ print(env, "\\n");
+ } else if (*s == '\r') {
+ print(env, "\\r");
+ } else if (*s == '\t') {
+ print(env, "\\t");
+ } else {
+ print(env, "\\u%04x", *s);
+ }
+ }
+ print(env, "\"");
+}
+#endif
+
STATIC void str_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
GET_STR_DATA_LEN(self_in, str_data, str_len);
bool is_bytes = MP_OBJ_IS_TYPE(self_in, &mp_type_bytes);
+ #if MICROPY_PY_UJSON
+ if (kind == PRINT_JSON) {
+ str_print_json(print, env, str_data, str_len);
+ return;
+ }
+ #endif
if (kind == PRINT_STR && !is_bytes) {
print(env, "%.*s", str_len, str_data);
} else {
diff --git a/py/objstrunicode.c b/py/objstrunicode.c
index 8231eb9b16..0ee7f1dc9a 100644
--- a/py/objstrunicode.c
+++ b/py/objstrunicode.c
@@ -91,8 +91,44 @@ STATIC void uni_print_quoted(void (*print)(void *env, const char *fmt, ...), voi
print(env, "%c", quote_char);
}
+#if MICROPY_PY_UJSON
+STATIC void uni_print_json(void (*print)(void *env, const char *fmt, ...), void *env, const byte *str_data, uint str_len) {
+ print(env, "\"");
+ const byte *s = str_data, *top = str_data + str_len;
+ while (s < top) {
+ unichar ch;
+ ch = utf8_get_char(s);
+ s = utf8_next_char(s);
+ if (ch == '"' || ch == '\\' || ch == '/') {
+ print(env, "\\%c", ch);
+ } else if (32 <= ch && ch <= 126) {
+ print(env, "%c", ch);
+ } else if (*s == '\b') {
+ print(env, "\\b");
+ } else if (*s == '\f') {
+ print(env, "\\f");
+ } else if (*s == '\n') {
+ print(env, "\\n");
+ } else if (*s == '\r') {
+ print(env, "\\r");
+ } else if (*s == '\t') {
+ print(env, "\\t");
+ } else {
+ print(env, "\\u%04x", ch);
+ }
+ }
+ print(env, "\"");
+}
+#endif
+
STATIC void uni_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
GET_STR_DATA_LEN(self_in, str_data, str_len);
+ #if MICROPY_PY_UJSON
+ if (kind == PRINT_JSON) {
+ uni_print_json(print, env, str_data, str_len);
+ return;
+ }
+ #endif
if (kind == PRINT_STR) {
print(env, "%.*s", str_len, str_data);
} else {
diff --git a/py/objtuple.c b/py/objtuple.c
index 6abe7d2c64..2793e4838d 100644
--- a/py/objtuple.c
+++ b/py/objtuple.c
@@ -43,17 +43,26 @@ STATIC mp_obj_t mp_obj_new_tuple_iterator(mp_obj_tuple_t *tuple, mp_uint_t cur);
void mp_obj_tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
mp_obj_tuple_t *o = o_in;
- print(env, "(");
+ if (MICROPY_PY_UJSON && kind == PRINT_JSON) {
+ print(env, "[");
+ } else {
+ print(env, "(");
+ kind = PRINT_REPR;
+ }
for (mp_uint_t i = 0; i < o->len; i++) {
if (i > 0) {
print(env, ", ");
}
- mp_obj_print_helper(print, env, o->items[i], PRINT_REPR);
+ mp_obj_print_helper(print, env, o->items[i], kind);
}
- if (o->len == 1) {
- print(env, ",");
+ if (MICROPY_PY_UJSON && kind == PRINT_JSON) {
+ print(env, "]");
+ } else {
+ if (o->len == 1) {
+ print(env, ",");
+ }
+ print(env, ")");
}
- print(env, ")");
}
STATIC mp_obj_t mp_obj_tuple_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
diff --git a/py/py.mk b/py/py.mk
index e2288d3821..fb59b89729 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -112,6 +112,7 @@ PY_O_BASENAME = \
pfenv_printf.o \
../extmod/moductypes.o \
../extmod/modzlibd.o \
+ ../extmod/modujson.o \
# prepend the build destination prefix to the py object files
PY_O = $(addprefix $(PY_BUILD)/, $(PY_O_BASENAME))
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index d41029a1fa..41ffa1d201 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -463,3 +463,8 @@ Q(deleter)
Q(zlibd)
Q(decompress)
#endif
+
+#if MICROPY_PY_UJSON
+Q(ujson)
+Q(dumps)
+#endif