summaryrefslogtreecommitdiffstatshomepage
path: root/py/parse.c
diff options
context:
space:
mode:
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 35f06afea6..b86b919a86 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