aboutsummaryrefslogtreecommitdiff
path: root/src/grammar
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-05 14:09:25 +0100
committerAleksey Kladov <[email protected]>2018-08-05 14:09:25 +0100
commit1e1e2e83c462b7efacaa0e33812beed72a88ab5f (patch)
tree134caad399dc6a3cc4bfccf49d525e8db646a657 /src/grammar
parent5691da4c84655e0d966ac11406fa7a90bdd02643 (diff)
compound ops
Diffstat (limited to 'src/grammar')
-rw-r--r--src/grammar/expressions/mod.rs47
1 files changed, 37 insertions, 10 deletions
diff --git a/src/grammar/expressions/mod.rs b/src/grammar/expressions/mod.rs
index 15669f99d..baff0da52 100644
--- a/src/grammar/expressions/mod.rs
+++ b/src/grammar/expressions/mod.rs
@@ -33,19 +33,45 @@ struct Restrictions {
33 forbid_structs: bool 33 forbid_structs: bool
34} 34}
35 35
36enum Op {
37 Simple,
38 Composite(SyntaxKind, u8)
39}
40
36// test expr_binding_power 41// test expr_binding_power
37// fn foo() { 42// fn foo() {
38// 1 + 2 * 3 == 1 * 2 + 3; 43// 1 + 2 * 3 == 1 * 2 + 3;
39// *x = 1 + 1; 44// *x = 1 + 1;
40// } 45// }
41fn bp_of(op: SyntaxKind) -> u8 { 46
42 match op { 47// test compound_ops
48// fn foo() {
49// x += 1;
50// 1 + 1 <= 2 * 3;
51// z -= 3 >= 0;
52// }
53fn current_op(p: &Parser) -> (u8, Op) {
54 if p.at_compound2(L_ANGLE, EQ) {
55 return (2, Op::Composite(LTEQ, 2))
56 }
57 if p.at_compound2(R_ANGLE, EQ) {
58 return (2, Op::Composite(GTEQ, 2))
59 }
60 if p.at_compound2(PLUS, EQ) {
61 return (1, Op::Composite(PLUSEQ, 2))
62 }
63 if p.at_compound2(MINUS, EQ) {
64 return (1, Op::Composite(MINUSEQ, 2))
65 }
66
67 let bp = match p.current() {
43 EQ => 1, 68 EQ => 1,
44 EQEQ | NEQ => 2, 69 EQEQ | NEQ => 2,
45 MINUS | PLUS => 3, 70 MINUS | PLUS => 3,
46 STAR | SLASH => 4, 71 STAR | SLASH => 4,
47 _ => 0 72 _ => 0,
48 } 73 };
74 (bp, Op::Simple)
49} 75}
50 76
51// Parses expression with binding power of at least bp. 77// Parses expression with binding power of at least bp.
@@ -56,10 +82,16 @@ fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) {
56 }; 82 };
57 83
58 loop { 84 loop {
59 let op_bp = bp_of(p.current()); 85 let (op_bp, op) = current_op(p);
60 if op_bp < bp { 86 if op_bp < bp {
61 break; 87 break;
62 } 88 }
89 match op {
90 Op::Simple => p.bump(),
91 Op::Composite(kind, n) => {
92 p.bump_compound(kind, n);
93 },
94 }
63 lhs = bin_expr(p, r, lhs, op_bp); 95 lhs = bin_expr(p, r, lhs, op_bp);
64 } 96 }
65} 97}
@@ -254,12 +286,7 @@ fn struct_lit(p: &mut Parser) {
254} 286}
255 287
256fn bin_expr(p: &mut Parser, r: Restrictions, lhs: CompletedMarker, bp: u8) -> CompletedMarker { 288fn bin_expr(p: &mut Parser, r: Restrictions, lhs: CompletedMarker, bp: u8) -> CompletedMarker {
257 assert!(match p.current() {
258 MINUS | PLUS | STAR | SLASH | EQEQ | NEQ | EQ => true,
259 _ => false,
260 });
261 let m = lhs.precede(p); 289 let m = lhs.precede(p);
262 p.bump();
263 expr_bp(p, r, bp); 290 expr_bp(p, r, bp);
264 m.complete(p, BIN_EXPR) 291 m.complete(p, BIN_EXPR)
265} 292}