Skip to content

Commit 44ca88a

Browse files
committed
refactor precedences
1 parent 2153b0f commit 44ca88a

4 files changed

Lines changed: 121 additions & 49 deletions

File tree

src/unparser.rs

Lines changed: 111 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -15,42 +15,71 @@ use rustpython_ast::{
1515
};
1616
use rustpython_ast::{Constant, Int};
1717

18+
enum Precedence {
19+
NamedExpr = 1,
20+
Tuple = 2,
21+
Yield = 3,
22+
Test = 4,
23+
Or = 5,
24+
And = 6,
25+
Not = 7,
26+
Cmp = 8,
27+
28+
Bor = 9,
29+
Bxor = 10,
30+
Band = 11,
31+
Shift = 12,
32+
Arith = 13,
33+
Term = 14,
34+
Factor = 15,
35+
Power = 16,
36+
Await = 17,
37+
Atom = 18,
38+
}
39+
40+
impl Precedence {
41+
fn value(self) -> usize {
42+
self as usize
43+
}
44+
}
45+
const EXPR_PRECEDENCE: usize = 9;
46+
1847
fn get_precedence(node: &Expr<TextRange>) -> usize {
1948
match node {
20-
Expr::NamedExpr(_) => 1,
21-
Expr::Tuple(_) => 2,
22-
Expr::Yield(_) => 3,
23-
Expr::YieldFrom(_) => 3,
24-
Expr::IfExp(_) => 4,
25-
Expr::Lambda(_) => 4,
49+
Expr::NamedExpr(_) => Precedence::NamedExpr.value(),
50+
Expr::Tuple(_) => Precedence::Tuple.value(),
51+
Expr::Yield(_) => Precedence::Yield.value(),
52+
Expr::YieldFrom(_) => Precedence::Yield.value(),
53+
Expr::IfExp(_) => Precedence::Test.value(),
54+
Expr::Lambda(_) => Precedence::Test.value(),
2655
Expr::BoolOp(data) => match data.op {
27-
BoolOp::Or => 5,
28-
BoolOp::And => 6,
56+
BoolOp::Or => Precedence::Or.value(),
57+
BoolOp::And => Precedence::And.value(),
2958
},
3059
Expr::UnaryOp(data) => match data.op {
31-
UnaryOp::Not => 7,
32-
UnaryOp::UAdd => 15,
33-
UnaryOp::USub => 15,
34-
UnaryOp::Invert => 15,
60+
UnaryOp::Not => Precedence::Not.value(),
61+
UnaryOp::UAdd => Precedence::Factor.value(),
62+
UnaryOp::USub => Precedence::Factor.value(),
63+
UnaryOp::Invert => Precedence::Factor.value(),
3564
},
36-
Expr::Compare(_) => 8,
65+
Expr::Compare(_) => Precedence::Cmp.value(),
3766
Expr::BinOp(data) => match data.op {
38-
Operator::BitOr => 9,
39-
Operator::BitXor => 10,
40-
Operator::BitAnd => 11,
41-
Operator::LShift => 12,
42-
Operator::RShift => 12,
43-
Operator::Add => 13,
44-
Operator::Sub => 13,
45-
Operator::Div => 14,
46-
Operator::FloorDiv => 14,
47-
Operator::Mult => 14,
48-
Operator::MatMult => 14,
49-
Operator::Mod => 14,
50-
Operator::Pow => 16,
67+
Operator::BitOr => Precedence::Bor.value(),
68+
Operator::BitXor => Precedence::Bxor.value(),
69+
Operator::BitAnd => Precedence::Band.value(),
70+
Operator::LShift => Precedence::Shift.value(),
71+
Operator::RShift => Precedence::Shift.value(),
72+
Operator::Add => Precedence::Arith.value(),
73+
Operator::Sub => Precedence::Arith.value(),
74+
Operator::Div => Precedence::Term.value(),
75+
Operator::FloorDiv => Precedence::Term.value(),
76+
Operator::Mult => Precedence::Term.value(),
77+
Operator::MatMult => Precedence::Term.value(),
78+
Operator::Mod => Precedence::Term.value(),
79+
Operator::Pow => Precedence::Power.value(),
5180
},
52-
Expr::Await(_) => 17,
53-
_ => 4,
81+
Expr::Await(_) => Precedence::Await.value(),
82+
_ => Precedence::Test.value(),
5483
}
5584
}
5685

@@ -66,7 +95,7 @@ impl Unparser {
6695
Unparser {
6796
in_try_star: false,
6897
indent: 0,
69-
precedence_level: 0,
98+
precedence_level: Precedence::Test.value(),
7099
source: String::new(),
71100
}
72101
}
@@ -96,8 +125,7 @@ impl Unparser {
96125
where
97126
F: FnOnce(&mut Self),
98127
{
99-
self.precedence_level = get_precedence(node);
100-
let should_delimit = get_precedence(node) > self.precedence_level;
128+
let should_delimit = self.precedence_level > get_precedence(node);
101129
if should_delimit {
102130
self.write_str("(");
103131
}
@@ -107,6 +135,26 @@ impl Unparser {
107135
}
108136
}
109137

138+
fn with_precedence<F>(&mut self, prec: Precedence, f: F)
139+
where
140+
F: FnOnce(&mut Self),
141+
{
142+
let prev_prec = self.precedence_level;
143+
self.precedence_level = prec.value();
144+
f(self);
145+
self.precedence_level = prev_prec;
146+
}
147+
148+
fn with_precedence_num<F>(&mut self, prec: usize, f: F)
149+
where
150+
F: FnOnce(&mut Self),
151+
{
152+
let prev_prec = self.precedence_level;
153+
self.precedence_level = prec;
154+
f(self);
155+
self.precedence_level = prev_prec;
156+
}
157+
110158
pub fn unparse_stmt(&mut self, node: &Stmt<TextRange>) {
111159
match node {
112160
Stmt::FunctionDef(data) => self.unparse_stmt_function_def(data),
@@ -228,7 +276,7 @@ impl Unparser {
228276
self.unparse_expr(decorator);
229277
}
230278

231-
self.fill("class");
279+
self.fill("class ");
232280
self.write_str(&node.name);
233281

234282
if node.type_params.len() > 0 {
@@ -291,7 +339,10 @@ impl Unparser {
291339
let mut targets_iter = node.targets.iter().peekable();
292340
self.fill("");
293341
while let Some(target) = targets_iter.next() {
294-
self.unparse_expr(target);
342+
self.with_precedence(Precedence::Tuple, |prec_self| {
343+
prec_self.unparse_expr(target);
344+
});
345+
295346
if targets_iter.peek().is_some() {
296347
self.write_str(", ");
297348
}
@@ -610,7 +661,9 @@ impl Unparser {
610661
}
611662
fn unparse_stmt_expr(&mut self, node: &StmtExpr<TextRange>) {
612663
self.fill("");
613-
self.unparse_expr(&node.value);
664+
self.with_precedence(Precedence::Yield, |block_self| {
665+
block_self.unparse_expr(&node.value);
666+
});
614667
}
615668

616669
pub fn unparse_expr(&mut self, node: &Expr<TextRange>) {
@@ -646,34 +699,35 @@ impl Unparser {
646699
}
647700

648701
fn unparse_expr_bool_op(&mut self, node: &ExprBoolOp<TextRange>) {
649-
let prev_precedence_level = self.precedence_level;
702+
let enum_member = Expr::BoolOp(node.to_owned());
703+
let mut operator_precedence = get_precedence(&enum_member);
650704
let operator = match node.op {
651705
BoolOp::And => " and ",
652706
BoolOp::Or => " or ",
653707
};
654708

655-
let enum_member = Expr::BoolOp(node.to_owned());
656-
657709
let mut values_iter = node.values.iter().peekable();
658710
self.delimit_precedence(&enum_member, |block_self| {
659711
while let Some(expr) = values_iter.next() {
660-
block_self.precedence_level += 1;
661-
block_self.unparse_expr(expr);
712+
operator_precedence += 1;
713+
block_self.with_precedence_num(operator_precedence, |prec_self| {
714+
prec_self.unparse_expr(expr);
715+
});
662716
if values_iter.peek().is_some() {
663-
block_self.write_str(&operator);
717+
block_self.write_str(operator);
664718
}
665719
}
666720
});
667-
668-
self.precedence_level = prev_precedence_level;
669721
}
670722

671723
fn unparse_expr_named_expr(&mut self, node: &ExprNamedExpr<TextRange>) {
672724
let enum_member = Expr::NamedExpr(node.to_owned());
673725
self.delimit_precedence(&enum_member, |block_self| {
674-
block_self.unparse_expr(&node.target);
675-
block_self.write_str(" := ");
676-
block_self.unparse_expr(&node.value);
726+
block_self.with_precedence(Precedence::Atom, |prec_self| {
727+
prec_self.unparse_expr(&node.target);
728+
prec_self.write_str(" := ");
729+
prec_self.unparse_expr(&node.value);
730+
});
677731
})
678732
}
679733

@@ -807,7 +861,9 @@ impl Unparser {
807861
let enum_member = Expr::Await(node.to_owned());
808862
self.delimit_precedence(&enum_member, |block_self| {
809863
block_self.write_str("await ");
810-
block_self.unparse_expr(&node.value);
864+
block_self.with_precedence(Precedence::Atom, |prec_self| {
865+
prec_self.unparse_expr(&node.value);
866+
});
811867
})
812868
}
813869

@@ -817,7 +873,9 @@ impl Unparser {
817873
block_self.write_str("yield");
818874
if let Some(expr) = &node.value {
819875
block_self.write_str(" ");
820-
block_self.unparse_expr(expr);
876+
block_self.with_precedence(Precedence::Atom, |prec_self| {
877+
prec_self.unparse_expr(expr);
878+
});
821879
}
822880
})
823881
}
@@ -827,7 +885,9 @@ impl Unparser {
827885
self.delimit_precedence(&enum_member, |block_self| {
828886
block_self.write_str("yield from ");
829887

830-
block_self.unparse_expr(&node.value);
888+
block_self.with_precedence(Precedence::Atom, |prec_self| {
889+
prec_self.unparse_expr(&node.value);
890+
});
831891
})
832892
}
833893

@@ -894,7 +954,9 @@ impl Unparser {
894954

895955
fn unparse_expr_joined_str(&mut self, node: &ExprJoinedStr<TextRange>) {
896956
self.write_str("f");
897-
957+
if node.values.len() == 0 {
958+
self.write_str("\"\"");
959+
}
898960
for (index, expr) in node.values.iter().enumerate() {
899961
let mut inner_unparser = Unparser::new();
900962
inner_unparser.unparse_expr(expr);

test_files/boolop.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
True or False
2+
False and True
3+
True and False or False and True
4+
(True and False) or (False and True)
5+
True and (False or False) and True
6+
True or False and False or True
7+
(True or False) and (False or True)
8+
True or (False and False) or True

test_files/simple_f_string.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
world = "World"
2+
empty_f_string = f"" # noqa: F541
23
if __name__ == "__main__":
34
print(f"Hello {world}!")

test_files/simple_walrus.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
abc = (my_var := "Hello world")

0 commit comments

Comments
 (0)