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 --- src/parser/grammar/items/mod.rs | 17 ----------------- src/parser/grammar/mod.rs | 24 ++++++++++++++++++++++++ src/parser/grammar/types.rs | 26 ++++++++++++++++++++++++++ src/syntax_kinds.rs | 2 ++ 4 files changed, 52 insertions(+), 17 deletions(-) (limited to 'src') 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" }, -- cgit v1.2.3