diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/grammar.ron | 5 | ||||
-rw-r--r-- | src/grammar/expressions/mod.rs | 56 | ||||
-rw-r--r-- | src/parser_api.rs | 4 | ||||
-rw-r--r-- | src/parser_impl/mod.rs | 6 | ||||
-rw-r--r-- | src/syntax_kinds/generated.rs | 14 |
5 files changed, 59 insertions, 26 deletions
diff --git a/src/grammar.ron b/src/grammar.ron index b525476c2..0620a8b8c 100644 --- a/src/grammar.ron +++ b/src/grammar.ron | |||
@@ -43,6 +43,10 @@ Grammar( | |||
43 | ["-=", "MINUSEQ"], | 43 | ["-=", "MINUSEQ"], |
44 | ["&&", "AMPAMP"], | 44 | ["&&", "AMPAMP"], |
45 | ["||", "PIPEPIPE"], | 45 | ["||", "PIPEPIPE"], |
46 | ["<<", "SHL"], | ||
47 | [">>", "SHR"], | ||
48 | ["<<=", "SHLEQ"], | ||
49 | [">>=", "SHREQ"], | ||
46 | ], | 50 | ], |
47 | keywords: [ | 51 | keywords: [ |
48 | "use", | 52 | "use", |
@@ -168,6 +172,7 @@ Grammar( | |||
168 | "REF_EXPR", | 172 | "REF_EXPR", |
169 | "DEREF_EXPR", | 173 | "DEREF_EXPR", |
170 | "NOT_EXPR", | 174 | "NOT_EXPR", |
175 | "NEG_EXPR", | ||
171 | 176 | ||
172 | "RANGE_EXPR", // just weird | 177 | "RANGE_EXPR", // just weird |
173 | "BIN_EXPR", | 178 | "BIN_EXPR", |
diff --git a/src/grammar/expressions/mod.rs b/src/grammar/expressions/mod.rs index c137fe654..5b7228146 100644 --- a/src/grammar/expressions/mod.rs +++ b/src/grammar/expressions/mod.rs | |||
@@ -3,7 +3,7 @@ mod atom; | |||
3 | use super::*; | 3 | use super::*; |
4 | pub(super) use self::atom::literal; | 4 | pub(super) use self::atom::literal; |
5 | 5 | ||
6 | const EXPR_FIRST: TokenSet = UNARY_EXPR_FIRST; | 6 | const EXPR_FIRST: TokenSet = LHS_FIRST; |
7 | 7 | ||
8 | pub(super) fn expr(p: &mut Parser) { | 8 | pub(super) fn expr(p: &mut Parser) { |
9 | let r = Restrictions { forbid_structs: false }; | 9 | let r = Restrictions { forbid_structs: false }; |
@@ -38,26 +38,6 @@ enum Op { | |||
38 | Composite(SyntaxKind, u8), | 38 | Composite(SyntaxKind, u8), |
39 | } | 39 | } |
40 | 40 | ||
41 | // test expr_binding_power | ||
42 | // fn foo() { | ||
43 | // 1 + 2 * 3 == 1 * 2 + 3; | ||
44 | // *x = 1 + 1; | ||
45 | // } | ||
46 | |||
47 | // test range_binding_power | ||
48 | // fn foo() { | ||
49 | // .. 1 + 1; | ||
50 | // .. z = 2; | ||
51 | // x = false .. 1 == 1; | ||
52 | // } | ||
53 | |||
54 | // test compound_ops | ||
55 | // fn foo() { | ||
56 | // x += 1; | ||
57 | // 1 + 1 <= 2 * 3; | ||
58 | // z -= 3 >= 0; | ||
59 | // true || true && false; | ||
60 | // } | ||
61 | fn current_op(p: &Parser) -> (u8, Op) { | 41 | fn current_op(p: &Parser) -> (u8, Op) { |
62 | if p.at_compound2(PLUS, EQ) { | 42 | if p.at_compound2(PLUS, EQ) { |
63 | return (1, Op::Composite(PLUSEQ, 2)); | 43 | return (1, Op::Composite(PLUSEQ, 2)); |
@@ -65,6 +45,12 @@ fn current_op(p: &Parser) -> (u8, Op) { | |||
65 | if p.at_compound2(MINUS, EQ) { | 45 | if p.at_compound2(MINUS, EQ) { |
66 | return (1, Op::Composite(MINUSEQ, 2)); | 46 | return (1, Op::Composite(MINUSEQ, 2)); |
67 | } | 47 | } |
48 | if p.at_compound3(L_ANGLE, L_ANGLE, EQ) { | ||
49 | return (1, Op::Composite(SHLEQ, 3)); | ||
50 | } | ||
51 | if p.at_compound3(R_ANGLE, R_ANGLE, EQ) { | ||
52 | return (1, Op::Composite(SHREQ, 3)); | ||
53 | } | ||
68 | if p.at_compound2(PIPE, PIPE) { | 54 | if p.at_compound2(PIPE, PIPE) { |
69 | return (3, Op::Composite(PIPEPIPE, 2)); | 55 | return (3, Op::Composite(PIPEPIPE, 2)); |
70 | } | 56 | } |
@@ -77,13 +63,22 @@ fn current_op(p: &Parser) -> (u8, Op) { | |||
77 | if p.at_compound2(R_ANGLE, EQ) { | 63 | if p.at_compound2(R_ANGLE, EQ) { |
78 | return (5, Op::Composite(GTEQ, 2)); | 64 | return (5, Op::Composite(GTEQ, 2)); |
79 | } | 65 | } |
66 | if p.at_compound2(L_ANGLE, L_ANGLE) { | ||
67 | return (9, Op::Composite(SHL, 2)); | ||
68 | } | ||
69 | if p.at_compound2(R_ANGLE, R_ANGLE) { | ||
70 | return (9, Op::Composite(SHR, 2)); | ||
71 | } | ||
80 | 72 | ||
81 | let bp = match p.current() { | 73 | let bp = match p.current() { |
82 | EQ => 1, | 74 | EQ => 1, |
83 | DOTDOT => 2, | 75 | DOTDOT => 2, |
84 | EQEQ | NEQ => 5, | 76 | EQEQ | NEQ => 5, |
85 | MINUS | PLUS => 6, | 77 | PIPE => 6, |
86 | STAR | SLASH => 7, | 78 | CARET => 7, |
79 | AMP => 8, | ||
80 | MINUS | PLUS => 10, | ||
81 | STAR | SLASH | PERCENT => 11, | ||
87 | _ => 0, | 82 | _ => 0, |
88 | }; | 83 | }; |
89 | (bp, Op::Simple) | 84 | (bp, Op::Simple) |
@@ -107,13 +102,13 @@ fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) { | |||
107 | p.bump_compound(kind, n); | 102 | p.bump_compound(kind, n); |
108 | } | 103 | } |
109 | } | 104 | } |
110 | lhs = bin_expr(p, r, lhs, op_bp); | 105 | lhs = bin_expr(p, r, lhs, op_bp + 1); |
111 | } | 106 | } |
112 | } | 107 | } |
113 | 108 | ||
114 | const UNARY_EXPR_FIRST: TokenSet = | 109 | const LHS_FIRST: TokenSet = |
115 | token_set_union![ | 110 | token_set_union![ |
116 | token_set![AMP, STAR, EXCL], | 111 | token_set![AMP, STAR, EXCL, DOTDOT, MINUS], |
117 | atom::ATOM_EXPR_FIRST, | 112 | atom::ATOM_EXPR_FIRST, |
118 | ]; | 113 | ]; |
119 | 114 | ||
@@ -149,6 +144,15 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> { | |||
149 | p.bump(); | 144 | p.bump(); |
150 | NOT_EXPR | 145 | NOT_EXPR |
151 | } | 146 | } |
147 | // test neg_expr | ||
148 | // fn foo() { | ||
149 | // --1; | ||
150 | // } | ||
151 | MINUS => { | ||
152 | m = p.start(); | ||
153 | p.bump(); | ||
154 | NEG_EXPR | ||
155 | } | ||
152 | DOTDOT => { | 156 | DOTDOT => { |
153 | m = p.start(); | 157 | m = p.start(); |
154 | p.bump(); | 158 | p.bump(); |
diff --git a/src/parser_api.rs b/src/parser_api.rs index fef21c5fd..c739b1321 100644 --- a/src/parser_api.rs +++ b/src/parser_api.rs | |||
@@ -62,6 +62,10 @@ impl<'t> Parser<'t> { | |||
62 | self.0.at_compound2(c1, c2) | 62 | self.0.at_compound2(c1, c2) |
63 | } | 63 | } |
64 | 64 | ||
65 | pub(crate) fn at_compound3(&self, c1: SyntaxKind, c2: SyntaxKind, c3: SyntaxKind) -> bool { | ||
66 | self.0.at_compound3(c1, c2, c3) | ||
67 | } | ||
68 | |||
65 | /// Checks if the current token is contextual keyword with text `t`. | 69 | /// Checks if the current token is contextual keyword with text `t`. |
66 | pub(crate) fn at_contextual_kw(&self, t: &str) -> bool { | 70 | pub(crate) fn at_contextual_kw(&self, t: &str) -> bool { |
67 | self.0.at_kw(t) | 71 | self.0.at_kw(t) |
diff --git a/src/parser_impl/mod.rs b/src/parser_impl/mod.rs index d640a7784..06c16cdb4 100644 --- a/src/parser_impl/mod.rs +++ b/src/parser_impl/mod.rs | |||
@@ -70,6 +70,12 @@ impl<'t> ParserImpl<'t> { | |||
70 | && self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos) | 70 | && self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos) |
71 | } | 71 | } |
72 | 72 | ||
73 | pub(super) fn at_compound3(&self, c1: SyntaxKind, c2: SyntaxKind, c3: SyntaxKind) -> bool { | ||
74 | self.inp.kind(self.pos) == c1 && self.inp.kind(self.pos + 1) == c2 && self.inp.kind(self.pos + 2) == c3 | ||
75 | && self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos) | ||
76 | && self.inp.start(self.pos + 2) == self.inp.start(self.pos + 1) + self.inp.len(self.pos + 1) | ||
77 | } | ||
78 | |||
73 | pub(super) fn nth(&self, n: u32) -> SyntaxKind { | 79 | pub(super) fn nth(&self, n: u32) -> SyntaxKind { |
74 | self.inp.kind(self.pos + n) | 80 | self.inp.kind(self.pos + n) |
75 | } | 81 | } |
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs index 005f4a9dc..db8c20004 100644 --- a/src/syntax_kinds/generated.rs +++ b/src/syntax_kinds/generated.rs | |||
@@ -46,6 +46,10 @@ pub enum SyntaxKind { | |||
46 | MINUSEQ, | 46 | MINUSEQ, |
47 | AMPAMP, | 47 | AMPAMP, |
48 | PIPEPIPE, | 48 | PIPEPIPE, |
49 | SHL, | ||
50 | SHR, | ||
51 | SHLEQ, | ||
52 | SHREQ, | ||
49 | USE_KW, | 53 | USE_KW, |
50 | FN_KW, | 54 | FN_KW, |
51 | STRUCT_KW, | 55 | STRUCT_KW, |
@@ -154,6 +158,7 @@ pub enum SyntaxKind { | |||
154 | REF_EXPR, | 158 | REF_EXPR, |
155 | DEREF_EXPR, | 159 | DEREF_EXPR, |
156 | NOT_EXPR, | 160 | NOT_EXPR, |
161 | NEG_EXPR, | ||
157 | RANGE_EXPR, | 162 | RANGE_EXPR, |
158 | BIN_EXPR, | 163 | BIN_EXPR, |
159 | EXTERN_BLOCK_EXPR, | 164 | EXTERN_BLOCK_EXPR, |
@@ -280,6 +285,10 @@ impl SyntaxKind { | |||
280 | MINUSEQ => &SyntaxInfo { name: "MINUSEQ" }, | 285 | MINUSEQ => &SyntaxInfo { name: "MINUSEQ" }, |
281 | AMPAMP => &SyntaxInfo { name: "AMPAMP" }, | 286 | AMPAMP => &SyntaxInfo { name: "AMPAMP" }, |
282 | PIPEPIPE => &SyntaxInfo { name: "PIPEPIPE" }, | 287 | PIPEPIPE => &SyntaxInfo { name: "PIPEPIPE" }, |
288 | SHL => &SyntaxInfo { name: "SHL" }, | ||
289 | SHR => &SyntaxInfo { name: "SHR" }, | ||
290 | SHLEQ => &SyntaxInfo { name: "SHLEQ" }, | ||
291 | SHREQ => &SyntaxInfo { name: "SHREQ" }, | ||
283 | USE_KW => &SyntaxInfo { name: "USE_KW" }, | 292 | USE_KW => &SyntaxInfo { name: "USE_KW" }, |
284 | FN_KW => &SyntaxInfo { name: "FN_KW" }, | 293 | FN_KW => &SyntaxInfo { name: "FN_KW" }, |
285 | STRUCT_KW => &SyntaxInfo { name: "STRUCT_KW" }, | 294 | STRUCT_KW => &SyntaxInfo { name: "STRUCT_KW" }, |
@@ -388,6 +397,7 @@ impl SyntaxKind { | |||
388 | REF_EXPR => &SyntaxInfo { name: "REF_EXPR" }, | 397 | REF_EXPR => &SyntaxInfo { name: "REF_EXPR" }, |
389 | DEREF_EXPR => &SyntaxInfo { name: "DEREF_EXPR" }, | 398 | DEREF_EXPR => &SyntaxInfo { name: "DEREF_EXPR" }, |
390 | NOT_EXPR => &SyntaxInfo { name: "NOT_EXPR" }, | 399 | NOT_EXPR => &SyntaxInfo { name: "NOT_EXPR" }, |
400 | NEG_EXPR => &SyntaxInfo { name: "NEG_EXPR" }, | ||
391 | RANGE_EXPR => &SyntaxInfo { name: "RANGE_EXPR" }, | 401 | RANGE_EXPR => &SyntaxInfo { name: "RANGE_EXPR" }, |
392 | BIN_EXPR => &SyntaxInfo { name: "BIN_EXPR" }, | 402 | BIN_EXPR => &SyntaxInfo { name: "BIN_EXPR" }, |
393 | EXTERN_BLOCK_EXPR => &SyntaxInfo { name: "EXTERN_BLOCK_EXPR" }, | 403 | EXTERN_BLOCK_EXPR => &SyntaxInfo { name: "EXTERN_BLOCK_EXPR" }, |
@@ -534,6 +544,10 @@ impl SyntaxKind { | |||
534 | MINUSEQ => "-=", | 544 | MINUSEQ => "-=", |
535 | AMPAMP => "&&", | 545 | AMPAMP => "&&", |
536 | PIPEPIPE => "||", | 546 | PIPEPIPE => "||", |
547 | SHL => "<<", | ||
548 | SHR => ">>", | ||
549 | SHLEQ => "<<=", | ||
550 | SHREQ => ">>=", | ||
537 | 551 | ||
538 | USE_KW => "use", | 552 | USE_KW => "use", |
539 | FN_KW => "fn", | 553 | FN_KW => "fn", |