summaryrefslogtreecommitdiff
path: root/py/compile.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2015-02-08 01:57:40 +0000
committerDamien George <damien.p.george@gmail.com>2015-02-08 01:57:40 +0000
commit7d414a1b52d193bab2c94cf56932e1eba23ba542 (patch)
tree69f6840e4f825ffc1047fe7cb0f52eba27b20d86 /py/compile.c
parent5f97aaeca4dc607a2d32e758c3ef6131ffb168a6 (diff)
py: Parse big-int/float/imag constants directly in parser.
Previous to this patch, a big-int, float or imag constant was interned (made into a qstr) and then parsed at runtime to create an object each time it was needed. This is wasteful in RAM and not efficient. Now, these constants are parsed straight away in the parser and turned into objects. This allows constants with large numbers of digits (so addresses issue #1103) and takes us a step closer to #722.
Diffstat (limited to 'py/compile.c')
-rw-r--r--py/compile.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/py/compile.c b/py/compile.c
index 7023e9c40..b82fea732 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -47,6 +47,7 @@ typedef enum {
PN_maximum_number_of,
PN_string, // special node for non-interned string
PN_bytes, // special node for non-interned bytes
+ PN_const_object, // special node for a constant, generic Python object
} pn_kind_t;
#define EMIT(fun) (comp->emit_method_table->fun(comp->emit))
@@ -174,6 +175,7 @@ STATIC mp_parse_node_t fold_constants(compiler_t *comp, mp_parse_node_t pn, mp_m
#endif
case PN_string:
case PN_bytes:
+ case PN_const_object:
return pn;
}
@@ -432,6 +434,9 @@ STATIC bool cpython_c_tuple_is_const(mp_parse_node_t pn) {
if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_bytes)) {
return true;
}
+ if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_const_object)) {
+ return true;
+ }
if (!MP_PARSE_NODE_IS_LEAF(pn)) {
return false;
}
@@ -486,6 +491,12 @@ STATIC void cpython_c_tuple_emit_const(compiler_t *comp, mp_parse_node_t pn, vst
return;
}
+ if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_const_object)) {
+ mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn;
+ mp_obj_print((mp_obj_t)pns->nodes[0], PRINT_REPR);
+ return;
+ }
+
assert(MP_PARSE_NODE_IS_LEAF(pn));
if (MP_PARSE_NODE_IS_SMALL_INT(pn)) {
vstr_printf(vstr, INT_FMT, MP_PARSE_NODE_LEAF_SMALL_INT(pn));
@@ -495,8 +506,6 @@ STATIC void cpython_c_tuple_emit_const(compiler_t *comp, mp_parse_node_t pn, vst
mp_uint_t arg = MP_PARSE_NODE_LEAF_ARG(pn);
switch (MP_PARSE_NODE_LEAF_KIND(pn)) {
case MP_PARSE_NODE_ID: assert(0);
- case MP_PARSE_NODE_INTEGER: vstr_printf(vstr, "%s", qstr_str(arg)); break;
- case MP_PARSE_NODE_DECIMAL: vstr_printf(vstr, "%s", qstr_str(arg)); break;
case MP_PARSE_NODE_STRING:
case MP_PARSE_NODE_BYTES: {
mp_uint_t len;
@@ -2159,7 +2168,8 @@ STATIC void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
// for non-REPL, evaluate then discard the expression
if ((MP_PARSE_NODE_IS_LEAF(pns->nodes[0]) && !MP_PARSE_NODE_IS_ID(pns->nodes[0]))
|| MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_string)
- || MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_bytes)) {
+ || MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_bytes)
+ || MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_const_object)) {
// do nothing with a lonely constant
} else {
compile_node(comp, pns->nodes[0]); // just an expression
@@ -2954,6 +2964,10 @@ STATIC void compile_bytes(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
}
+STATIC void compile_const_object(compiler_t *comp, mp_parse_node_struct_t *pns) {
+ EMIT_ARG(load_const_obj, (mp_obj_t)pns->nodes[0]);
+}
+
typedef void (*compile_function_t)(compiler_t*, mp_parse_node_struct_t*);
STATIC compile_function_t compile_function[] = {
#define nc NULL
@@ -2966,6 +2980,7 @@ STATIC compile_function_t compile_function[] = {
NULL,
compile_string,
compile_bytes,
+ compile_const_object,
};
STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn) {
@@ -2978,8 +2993,6 @@ STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn) {
mp_uint_t arg = MP_PARSE_NODE_LEAF_ARG(pn);
switch (MP_PARSE_NODE_LEAF_KIND(pn)) {
case MP_PARSE_NODE_ID: EMIT_ARG(load_id, arg); break;
- case MP_PARSE_NODE_INTEGER: EMIT_ARG(load_const_int, arg); break;
- case MP_PARSE_NODE_DECIMAL: EMIT_ARG(load_const_dec, arg); break;
case MP_PARSE_NODE_STRING: EMIT_ARG(load_const_str, arg, false); break;
case MP_PARSE_NODE_BYTES: EMIT_ARG(load_const_str, arg, true); break;
case MP_PARSE_NODE_TOKEN: default: