diff options
author | Aleksey Kladov <[email protected]> | 2018-02-11 09:51:09 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-02-11 09:51:09 +0000 |
commit | 8a3f17a4e263781deac5e503ad5116ec78004618 (patch) | |
tree | 0b489b1784c572011dd9e25d6d0ba53e8a50f148 | |
parent | 2fb33b2d0d14f09ee06a42bca252dccbf57185e1 (diff) |
G: fn pointer type
-rw-r--r-- | grammar.ron | 1 | ||||
-rw-r--r-- | src/parser/grammar/items/mod.rs | 17 | ||||
-rw-r--r-- | src/parser/grammar/mod.rs | 24 | ||||
-rw-r--r-- | src/parser/grammar/types.rs | 26 | ||||
-rw-r--r-- | src/syntax_kinds.rs | 2 | ||||
-rw-r--r-- | tests/data/parser/inline/0028_fn_pointer_type.rs | 3 | ||||
-rw-r--r-- | tests/data/parser/inline/0028_fn_pointer_type.txt | 52 | ||||
-rw-r--r-- | tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs | 1 | ||||
-rw-r--r-- | tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt | 24 | ||||
-rw-r--r-- | tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs | 1 | ||||
-rw-r--r-- | tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt | 21 |
11 files changed, 155 insertions, 17 deletions
diff --git a/grammar.ron b/grammar.ron index e3010b009..d5ad59553 100644 --- a/grammar.ron +++ b/grammar.ron | |||
@@ -110,6 +110,7 @@ Grammar( | |||
110 | "SLICE_TYPE", | 110 | "SLICE_TYPE", |
111 | "REFERENCE_TYPE", | 111 | "REFERENCE_TYPE", |
112 | "PLACEHOLDER_TYPE", | 112 | "PLACEHOLDER_TYPE", |
113 | "FN_POINTER_TYPE", | ||
113 | 114 | ||
114 | "EXTERN_BLOCK", | 115 | "EXTERN_BLOCK", |
115 | "ENUM_VARIANT", | 116 | "ENUM_VARIANT", |
diff --git a/src/parser/grammar/items/mod.rs b/src/parser/grammar/items/mod.rs index b1edf2f22..18ee8af86 100644 --- a/src/parser/grammar/items/mod.rs +++ b/src/parser/grammar/items/mod.rs | |||
@@ -222,12 +222,6 @@ fn fn_item(p: &mut Parser) { | |||
222 | p.expect(L_CURLY); | 222 | p.expect(L_CURLY); |
223 | p.expect(R_CURLY); | 223 | p.expect(R_CURLY); |
224 | } | 224 | } |
225 | |||
226 | fn fn_value_parameters(p: &mut Parser) { | ||
227 | assert!(p.at(L_PAREN)); | ||
228 | p.bump(); | ||
229 | p.expect(R_PAREN); | ||
230 | } | ||
231 | } | 225 | } |
232 | 226 | ||
233 | // test type_item | 227 | // test type_item |
@@ -263,14 +257,3 @@ fn mod_item(p: &mut Parser) { | |||
263 | } | 257 | } |
264 | } | 258 | } |
265 | } | 259 | } |
266 | |||
267 | fn abi(p: &mut Parser) { | ||
268 | assert!(p.at(EXTERN_KW)); | ||
269 | let abi = p.start(); | ||
270 | p.bump(); | ||
271 | match p.current() { | ||
272 | STRING | RAW_STRING => p.bump(), | ||
273 | _ => (), | ||
274 | } | ||
275 | abi.complete(p, ABI); | ||
276 | } | ||
diff --git a/src/parser/grammar/mod.rs b/src/parser/grammar/mod.rs index abf9fe86c..5266354c1 100644 --- a/src/parser/grammar/mod.rs +++ b/src/parser/grammar/mod.rs | |||
@@ -50,6 +50,30 @@ fn alias(p: &mut Parser) -> bool { | |||
50 | true //FIXME: return false if three are errors | 50 | true //FIXME: return false if three are errors |
51 | } | 51 | } |
52 | 52 | ||
53 | fn abi(p: &mut Parser) { | ||
54 | assert!(p.at(EXTERN_KW)); | ||
55 | let abi = p.start(); | ||
56 | p.bump(); | ||
57 | match p.current() { | ||
58 | STRING | RAW_STRING => p.bump(), | ||
59 | _ => (), | ||
60 | } | ||
61 | abi.complete(p, ABI); | ||
62 | } | ||
63 | |||
64 | fn fn_value_parameters(p: &mut Parser) { | ||
65 | assert!(p.at(L_PAREN)); | ||
66 | p.bump(); | ||
67 | p.expect(R_PAREN); | ||
68 | } | ||
69 | |||
70 | fn fn_ret_type(p: &mut Parser) { | ||
71 | if p.at(THIN_ARROW) { | ||
72 | p.bump(); | ||
73 | types::type_(p); | ||
74 | } | ||
75 | } | ||
76 | |||
53 | fn name(p: &mut Parser) { | 77 | fn name(p: &mut Parser) { |
54 | if p.at(IDENT) { | 78 | if p.at(IDENT) { |
55 | let m = p.start(); | 79 | let m = p.start(); |
diff --git a/src/parser/grammar/types.rs b/src/parser/grammar/types.rs index 37b74bfe7..ea4df8639 100644 --- a/src/parser/grammar/types.rs +++ b/src/parser/grammar/types.rs | |||
@@ -8,6 +8,7 @@ pub(super) fn type_(p: &mut Parser) { | |||
8 | L_BRACK => array_or_slice_type(p), | 8 | L_BRACK => array_or_slice_type(p), |
9 | AMPERSAND => reference_type(p), | 9 | AMPERSAND => reference_type(p), |
10 | UNDERSCORE => placeholder_type(p), | 10 | UNDERSCORE => placeholder_type(p), |
11 | FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p), | ||
11 | IDENT => path_type(p), | 12 | IDENT => path_type(p), |
12 | _ => { | 13 | _ => { |
13 | p.error("expected type"); | 14 | p.error("expected type"); |
@@ -140,6 +141,31 @@ fn placeholder_type(p: &mut Parser) { | |||
140 | m.complete(p, PLACEHOLDER_TYPE); | 141 | m.complete(p, PLACEHOLDER_TYPE); |
141 | } | 142 | } |
142 | 143 | ||
144 | // test fn_pointer_type | ||
145 | // type A = fn(); | ||
146 | // type B = unsafe fn(); | ||
147 | // type C = unsafe extern "C" fn(); | ||
148 | fn fn_pointer_type(p: &mut Parser) { | ||
149 | let m = p.start(); | ||
150 | p.eat(UNSAFE_KW); | ||
151 | if p.at(EXTERN_KW) { | ||
152 | abi(p); | ||
153 | } | ||
154 | // test fn_pointer_type_missing_fn | ||
155 | // type F = unsafe (); | ||
156 | if !p.eat(FN_KW) { | ||
157 | m.abandon(p); | ||
158 | p.error("expected `fn`"); | ||
159 | return; | ||
160 | } | ||
161 | |||
162 | fn_value_parameters(p); | ||
163 | // test fn_pointer_type_with_ret | ||
164 | // type F = fn() -> (); | ||
165 | fn_ret_type(p); | ||
166 | m.complete(p, FN_POINTER_TYPE); | ||
167 | } | ||
168 | |||
143 | fn path_type(p: &mut Parser) { | 169 | fn path_type(p: &mut Parser) { |
144 | assert!(p.at(IDENT)); | 170 | assert!(p.at(IDENT)); |
145 | let m = p.start(); | 171 | let m = p.start(); |
diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs index 73539d6d4..db0f51beb 100644 --- a/src/syntax_kinds.rs +++ b/src/syntax_kinds.rs | |||
@@ -108,6 +108,7 @@ pub enum SyntaxKind { | |||
108 | SLICE_TYPE, | 108 | SLICE_TYPE, |
109 | REFERENCE_TYPE, | 109 | REFERENCE_TYPE, |
110 | PLACEHOLDER_TYPE, | 110 | PLACEHOLDER_TYPE, |
111 | FN_POINTER_TYPE, | ||
111 | EXTERN_BLOCK, | 112 | EXTERN_BLOCK, |
112 | ENUM_VARIANT, | 113 | ENUM_VARIANT, |
113 | NAMED_FIELD, | 114 | NAMED_FIELD, |
@@ -242,6 +243,7 @@ impl SyntaxKind { | |||
242 | SLICE_TYPE => &SyntaxInfo { name: "SLICE_TYPE" }, | 243 | SLICE_TYPE => &SyntaxInfo { name: "SLICE_TYPE" }, |
243 | REFERENCE_TYPE => &SyntaxInfo { name: "REFERENCE_TYPE" }, | 244 | REFERENCE_TYPE => &SyntaxInfo { name: "REFERENCE_TYPE" }, |
244 | PLACEHOLDER_TYPE => &SyntaxInfo { name: "PLACEHOLDER_TYPE" }, | 245 | PLACEHOLDER_TYPE => &SyntaxInfo { name: "PLACEHOLDER_TYPE" }, |
246 | FN_POINTER_TYPE => &SyntaxInfo { name: "FN_POINTER_TYPE" }, | ||
245 | EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, | 247 | EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, |
246 | ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, | 248 | ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, |
247 | NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, | 249 | NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, |
diff --git a/tests/data/parser/inline/0028_fn_pointer_type.rs b/tests/data/parser/inline/0028_fn_pointer_type.rs new file mode 100644 index 000000000..c9bf3bdb4 --- /dev/null +++ b/tests/data/parser/inline/0028_fn_pointer_type.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | type A = fn(); | ||
2 | type B = unsafe fn(); | ||
3 | type C = unsafe extern "C" fn(); | ||
diff --git a/tests/data/parser/inline/0028_fn_pointer_type.txt b/tests/data/parser/inline/0028_fn_pointer_type.txt new file mode 100644 index 000000000..6c62b0051 --- /dev/null +++ b/tests/data/parser/inline/0028_fn_pointer_type.txt | |||
@@ -0,0 +1,52 @@ | |||
1 | FILE@[0; 70) | ||
2 | TYPE_ITEM@[0; 15) | ||
3 | TYPE_KW@[0; 4) | ||
4 | NAME@[4; 7) | ||
5 | WHITESPACE@[4; 5) | ||
6 | IDENT@[5; 6) "A" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | FN_POINTER_TYPE@[8; 13) | ||
10 | WHITESPACE@[8; 9) | ||
11 | FN_KW@[9; 11) | ||
12 | L_PAREN@[11; 12) | ||
13 | R_PAREN@[12; 13) | ||
14 | SEMI@[13; 14) | ||
15 | WHITESPACE@[14; 15) | ||
16 | TYPE_ITEM@[15; 37) | ||
17 | TYPE_KW@[15; 19) | ||
18 | NAME@[19; 22) | ||
19 | WHITESPACE@[19; 20) | ||
20 | IDENT@[20; 21) "B" | ||
21 | WHITESPACE@[21; 22) | ||
22 | EQ@[22; 23) | ||
23 | FN_POINTER_TYPE@[23; 35) | ||
24 | WHITESPACE@[23; 24) | ||
25 | UNSAFE_KW@[24; 30) | ||
26 | WHITESPACE@[30; 31) | ||
27 | FN_KW@[31; 33) | ||
28 | L_PAREN@[33; 34) | ||
29 | R_PAREN@[34; 35) | ||
30 | SEMI@[35; 36) | ||
31 | WHITESPACE@[36; 37) | ||
32 | TYPE_ITEM@[37; 70) | ||
33 | TYPE_KW@[37; 41) | ||
34 | NAME@[41; 44) | ||
35 | WHITESPACE@[41; 42) | ||
36 | IDENT@[42; 43) "C" | ||
37 | WHITESPACE@[43; 44) | ||
38 | EQ@[44; 45) | ||
39 | FN_POINTER_TYPE@[45; 68) | ||
40 | WHITESPACE@[45; 46) | ||
41 | UNSAFE_KW@[46; 52) | ||
42 | ABI@[52; 64) | ||
43 | WHITESPACE@[52; 53) | ||
44 | EXTERN_KW@[53; 59) | ||
45 | WHITESPACE@[59; 60) | ||
46 | STRING@[60; 63) | ||
47 | WHITESPACE@[63; 64) | ||
48 | FN_KW@[64; 66) | ||
49 | L_PAREN@[66; 67) | ||
50 | R_PAREN@[67; 68) | ||
51 | SEMI@[68; 69) | ||
52 | WHITESPACE@[69; 70) | ||
diff --git a/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs b/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs new file mode 100644 index 000000000..f014914ff --- /dev/null +++ b/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs | |||
@@ -0,0 +1 @@ | |||
type F = unsafe (); | |||
diff --git a/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt b/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt new file mode 100644 index 000000000..dd6e24096 --- /dev/null +++ b/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt | |||
@@ -0,0 +1,24 @@ | |||
1 | FILE@[0; 20) | ||
2 | TYPE_ITEM@[0; 16) | ||
3 | TYPE_KW@[0; 4) | ||
4 | NAME@[4; 7) | ||
5 | WHITESPACE@[4; 5) | ||
6 | IDENT@[5; 6) "F" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | UNSAFE_KW@[9; 15) | ||
11 | err: `expected `fn`` | ||
12 | err: `expected SEMI` | ||
13 | WHITESPACE@[15; 16) | ||
14 | ERROR@[16; 17) | ||
15 | err: `expected item` | ||
16 | L_PAREN@[16; 17) | ||
17 | ERROR@[17; 18) | ||
18 | err: `expected item` | ||
19 | R_PAREN@[17; 18) | ||
20 | ERROR@[18; 20) | ||
21 | err: `expected item, found `;` | ||
22 | consider removing this semicolon` | ||
23 | SEMI@[18; 19) | ||
24 | WHITESPACE@[19; 20) | ||
diff --git a/tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs b/tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs new file mode 100644 index 000000000..e3ba5e87f --- /dev/null +++ b/tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs | |||
@@ -0,0 +1 @@ | |||
type F = fn() -> (); | |||
diff --git a/tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt b/tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt new file mode 100644 index 000000000..b41efa368 --- /dev/null +++ b/tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt | |||
@@ -0,0 +1,21 @@ | |||
1 | FILE@[0; 21) | ||
2 | TYPE_ITEM@[0; 21) | ||
3 | TYPE_KW@[0; 4) | ||
4 | NAME@[4; 7) | ||
5 | WHITESPACE@[4; 5) | ||
6 | IDENT@[5; 6) "F" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | FN_POINTER_TYPE@[8; 19) | ||
10 | WHITESPACE@[8; 9) | ||
11 | FN_KW@[9; 11) | ||
12 | L_PAREN@[11; 12) | ||
13 | R_PAREN@[12; 13) | ||
14 | WHITESPACE@[13; 14) | ||
15 | THIN_ARROW@[14; 16) | ||
16 | TUPLE_TYPE@[16; 19) | ||
17 | WHITESPACE@[16; 17) | ||
18 | L_PAREN@[17; 18) | ||
19 | R_PAREN@[18; 19) | ||
20 | SEMI@[19; 20) | ||
21 | WHITESPACE@[20; 21) | ||