Skip to content

Commit 7140ad4

Browse files
authored
Merge pull request #1 from tomasr8/binop-fold
Transform complex numbers in codegen stage
2 parents 89fe067 + 4d80e43 commit 7140ad4

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

Python/codegen.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5352,9 +5352,26 @@ codegen_slice(compiler *c, expr_ty s)
53525352
#define WILDCARD_STAR_CHECK(N) \
53535353
((N)->kind == MatchStar_kind && !(N)->v.MatchStar.name)
53545354

5355+
// Expressions such as '1+2j' or '1-2j'
5356+
static inline bool is_complex_literal(expr_ty e) {
5357+
return e->kind == BinOp_kind
5358+
&& (e->v.BinOp.op == Add || e->v.BinOp.op == Sub)
5359+
&& e->v.BinOp.left->kind == Constant_kind
5360+
&& e->v.BinOp.right->kind == Constant_kind
5361+
&& (PyLong_CheckExact(e->v.BinOp.left->v.Constant.value)
5362+
|| PyFloat_CheckExact(e->v.BinOp.left->v.Constant.value))
5363+
&& PyComplex_CheckExact(e->v.BinOp.right->v.Constant.value);
5364+
}
5365+
53555366
// Limit permitted subexpressions, even if the parser & AST validator let them through
5356-
#define MATCH_VALUE_EXPR(N) \
5357-
((N)->kind == Constant_kind || (N)->kind == Attribute_kind)
5367+
static inline bool is_match_value_expr(expr_ty e) {
5368+
// The permitted expressions in a case pattern value are constants,
5369+
// attribute lookups, and complex literals. However,
5370+
// complex literals are represented as a binary add or sub in
5371+
// the AST rather than a constant, so we need to check for them
5372+
// manually here.
5373+
return e->kind == Constant_kind || e->kind == Attribute_kind || is_complex_literal(e);
5374+
}
53585375

53595376
// Allocate or resize pc->fail_pop to allow for n items to be popped on failure.
53605377
static int
@@ -6019,7 +6036,7 @@ codegen_pattern_value(compiler *c, pattern_ty p, pattern_context *pc)
60196036
{
60206037
assert(p->kind == MatchValue_kind);
60216038
expr_ty value = p->v.MatchValue.value;
6022-
if (!MATCH_VALUE_EXPR(value)) {
6039+
if (!is_match_value_expr(value)) {
60236040
const char *e = "patterns may only match literals and attribute lookups";
60246041
return _PyCompile_Error(c, LOC(p), e);
60256042
}

0 commit comments

Comments
 (0)