G: fn pointer type

This commit is contained in:
Aleksey Kladov 2018-02-11 12:51:09 +03:00
parent 2fb33b2d0d
commit 8a3f17a4e2
11 changed files with 155 additions and 17 deletions

View File

@ -110,6 +110,7 @@ Grammar(
"SLICE_TYPE",
"REFERENCE_TYPE",
"PLACEHOLDER_TYPE",
"FN_POINTER_TYPE",
"EXTERN_BLOCK",
"ENUM_VARIANT",

View File

@ -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);
}

View File

@ -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();

View File

@ -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();

View File

@ -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 @@ pub(crate) fn info(self) -> &'static SyntaxInfo {
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" },

View File

@ -0,0 +1,3 @@
type A = fn();
type B = unsafe fn();
type C = unsafe extern "C" fn();

View File

@ -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)

View File

@ -0,0 +1 @@
type F = unsafe ();

View File

@ -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)

View File

@ -0,0 +1 @@
type F = fn() -> ();

View File

@ -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)