From 8a3f17a4e263781deac5e503ad5116ec78004618 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 11 Feb 2018 12:51:09 +0300 Subject: G: fn pointer type --- grammar.ron | 1 + src/parser/grammar/items/mod.rs | 17 ------- src/parser/grammar/mod.rs | 24 ++++++++++ src/parser/grammar/types.rs | 26 +++++++++++ src/syntax_kinds.rs | 2 + tests/data/parser/inline/0028_fn_pointer_type.rs | 3 ++ tests/data/parser/inline/0028_fn_pointer_type.txt | 52 ++++++++++++++++++++++ .../inline/0029_fn_pointer_type_missing_fn.rs | 1 + .../inline/0029_fn_pointer_type_missing_fn.txt | 24 ++++++++++ .../parser/inline/0030_fn_pointer_type_with_ret.rs | 1 + .../inline/0030_fn_pointer_type_with_ret.txt | 21 +++++++++ 11 files changed, 155 insertions(+), 17 deletions(-) create mode 100644 tests/data/parser/inline/0028_fn_pointer_type.rs create mode 100644 tests/data/parser/inline/0028_fn_pointer_type.txt create mode 100644 tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs create mode 100644 tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt create mode 100644 tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs create mode 100644 tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt diff --git a/grammar.ron b/grammar.ron index e3010b009..d5ad59553 100644 --- a/grammar.ron +++ b/grammar.ron @@ -110,6 +110,7 @@ Grammar( "SLICE_TYPE", "REFERENCE_TYPE", "PLACEHOLDER_TYPE", + "FN_POINTER_TYPE", "EXTERN_BLOCK", "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) { p.expect(L_CURLY); p.expect(R_CURLY); } - - fn fn_value_parameters(p: &mut Parser) { - assert!(p.at(L_PAREN)); - p.bump(); - p.expect(R_PAREN); - } } // test type_item @@ -263,14 +257,3 @@ fn mod_item(p: &mut Parser) { } } } - -fn abi(p: &mut Parser) { - assert!(p.at(EXTERN_KW)); - let abi = p.start(); - p.bump(); - match p.current() { - STRING | RAW_STRING => p.bump(), - _ => (), - } - abi.complete(p, ABI); -} 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 { true //FIXME: return false if three are errors } +fn abi(p: &mut Parser) { + assert!(p.at(EXTERN_KW)); + let abi = p.start(); + p.bump(); + match p.current() { + STRING | RAW_STRING => p.bump(), + _ => (), + } + abi.complete(p, ABI); +} + +fn fn_value_parameters(p: &mut Parser) { + assert!(p.at(L_PAREN)); + p.bump(); + p.expect(R_PAREN); +} + +fn fn_ret_type(p: &mut Parser) { + if p.at(THIN_ARROW) { + p.bump(); + types::type_(p); + } +} + fn name(p: &mut Parser) { if p.at(IDENT) { 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) { L_BRACK => array_or_slice_type(p), AMPERSAND => reference_type(p), UNDERSCORE => placeholder_type(p), + FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p), IDENT => path_type(p), _ => { p.error("expected type"); @@ -140,6 +141,31 @@ fn placeholder_type(p: &mut Parser) { m.complete(p, PLACEHOLDER_TYPE); } +// test fn_pointer_type +// type A = fn(); +// type B = unsafe fn(); +// type C = unsafe extern "C" fn(); +fn fn_pointer_type(p: &mut Parser) { + let m = p.start(); + p.eat(UNSAFE_KW); + if p.at(EXTERN_KW) { + abi(p); + } + // test fn_pointer_type_missing_fn + // type F = unsafe (); + if !p.eat(FN_KW) { + m.abandon(p); + p.error("expected `fn`"); + return; + } + + fn_value_parameters(p); + // test fn_pointer_type_with_ret + // type F = fn() -> (); + fn_ret_type(p); + m.complete(p, FN_POINTER_TYPE); +} + fn path_type(p: &mut Parser) { assert!(p.at(IDENT)); 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 { SLICE_TYPE, REFERENCE_TYPE, PLACEHOLDER_TYPE, + FN_POINTER_TYPE, EXTERN_BLOCK, ENUM_VARIANT, NAMED_FIELD, @@ -242,6 +243,7 @@ impl SyntaxKind { SLICE_TYPE => &SyntaxInfo { name: "SLICE_TYPE" }, REFERENCE_TYPE => &SyntaxInfo { name: "REFERENCE_TYPE" }, PLACEHOLDER_TYPE => &SyntaxInfo { name: "PLACEHOLDER_TYPE" }, + FN_POINTER_TYPE => &SyntaxInfo { name: "FN_POINTER_TYPE" }, EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, 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 @@ +type A = fn(); +type B = unsafe fn(); +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 @@ +FILE@[0; 70) + TYPE_ITEM@[0; 15) + TYPE_KW@[0; 4) + NAME@[4; 7) + WHITESPACE@[4; 5) + IDENT@[5; 6) "A" + WHITESPACE@[6; 7) + EQ@[7; 8) + FN_POINTER_TYPE@[8; 13) + WHITESPACE@[8; 9) + FN_KW@[9; 11) + L_PAREN@[11; 12) + R_PAREN@[12; 13) + SEMI@[13; 14) + WHITESPACE@[14; 15) + TYPE_ITEM@[15; 37) + TYPE_KW@[15; 19) + NAME@[19; 22) + WHITESPACE@[19; 20) + IDENT@[20; 21) "B" + WHITESPACE@[21; 22) + EQ@[22; 23) + FN_POINTER_TYPE@[23; 35) + WHITESPACE@[23; 24) + UNSAFE_KW@[24; 30) + WHITESPACE@[30; 31) + FN_KW@[31; 33) + L_PAREN@[33; 34) + R_PAREN@[34; 35) + SEMI@[35; 36) + WHITESPACE@[36; 37) + TYPE_ITEM@[37; 70) + TYPE_KW@[37; 41) + NAME@[41; 44) + WHITESPACE@[41; 42) + IDENT@[42; 43) "C" + WHITESPACE@[43; 44) + EQ@[44; 45) + FN_POINTER_TYPE@[45; 68) + WHITESPACE@[45; 46) + UNSAFE_KW@[46; 52) + ABI@[52; 64) + WHITESPACE@[52; 53) + EXTERN_KW@[53; 59) + WHITESPACE@[59; 60) + STRING@[60; 63) + WHITESPACE@[63; 64) + FN_KW@[64; 66) + L_PAREN@[66; 67) + R_PAREN@[67; 68) + SEMI@[68; 69) + 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 @@ +FILE@[0; 20) + TYPE_ITEM@[0; 16) + TYPE_KW@[0; 4) + NAME@[4; 7) + WHITESPACE@[4; 5) + IDENT@[5; 6) "F" + WHITESPACE@[6; 7) + EQ@[7; 8) + WHITESPACE@[8; 9) + UNSAFE_KW@[9; 15) + err: `expected `fn`` + err: `expected SEMI` + WHITESPACE@[15; 16) + ERROR@[16; 17) + err: `expected item` + L_PAREN@[16; 17) + ERROR@[17; 18) + err: `expected item` + R_PAREN@[17; 18) + ERROR@[18; 20) + err: `expected item, found `;` +consider removing this semicolon` + SEMI@[18; 19) + 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 @@ +FILE@[0; 21) + TYPE_ITEM@[0; 21) + TYPE_KW@[0; 4) + NAME@[4; 7) + WHITESPACE@[4; 5) + IDENT@[5; 6) "F" + WHITESPACE@[6; 7) + EQ@[7; 8) + FN_POINTER_TYPE@[8; 19) + WHITESPACE@[8; 9) + FN_KW@[9; 11) + L_PAREN@[11; 12) + R_PAREN@[12; 13) + WHITESPACE@[13; 14) + THIN_ARROW@[14; 16) + TUPLE_TYPE@[16; 19) + WHITESPACE@[16; 17) + L_PAREN@[17; 18) + R_PAREN@[18; 19) + SEMI@[19; 20) + WHITESPACE@[20; 21) -- cgit v1.2.3