aboutsummaryrefslogtreecommitdiff
path: root/py/parse.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2020-04-07 12:23:08 +1000
committerDamien George <damien.p.george@gmail.com>2020-05-03 16:23:19 +1000
commit4ede70368722f4702320412f393a7c703cdf4276 (patch)
tree30615518e0a6d69c5bdd7e17b71816ee929348c6 /py/parse.c
parent40e92277339697159e9ae120d814b64b6d4bbf04 (diff)
py/parse: Support constant folding of power operator for integers.
Constant expression like "2 ** 3" will now be folded, and the special form "X = const(2 ** 3)" will now compile because the argument to the const is now a constant. Fixes issue #5865.
Diffstat (limited to 'py/parse.c')
-rw-r--r--py/parse.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/py/parse.c b/py/parse.c
index 35f06afea..b86b919a8 100644
--- a/py/parse.c
+++ b/py/parse.c
@@ -618,8 +618,9 @@ STATIC bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) {
mp_obj_t arg0;
if (rule_id == RULE_expr
|| rule_id == RULE_xor_expr
- || rule_id == RULE_and_expr) {
- // folding for binary ops: | ^ &
+ || rule_id == RULE_and_expr
+ || rule_id == RULE_power) {
+ // folding for binary ops: | ^ & **
mp_parse_node_t pn = peek_result(parser, num_args - 1);
if (!mp_parse_node_get_int_maybe(pn, &arg0)) {
return false;
@@ -629,8 +630,10 @@ STATIC bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) {
op = MP_BINARY_OP_OR;
} else if (rule_id == RULE_xor_expr) {
op = MP_BINARY_OP_XOR;
- } else {
+ } else if (rule_id == RULE_and_expr) {
op = MP_BINARY_OP_AND;
+ } else {
+ op = MP_BINARY_OP_POWER;
}
for (ssize_t i = num_args - 2; i >= 0; --i) {
pn = peek_result(parser, i);
@@ -638,6 +641,10 @@ STATIC bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) {
if (!mp_parse_node_get_int_maybe(pn, &arg1)) {
return false;
}
+ if (op == MP_BINARY_OP_POWER && mp_obj_int_sign(arg1) < 0) {
+ // ** can't have negative rhs
+ return false;
+ }
arg0 = mp_binary_op(op, arg0, arg1);
}
} else if (rule_id == RULE_shift_expr