From 2389cf96dd07d8c94da349b10f6f2b750707dfd9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 11 Feb 2018 11:01:00 +0300 Subject: G: Never type --- src/parser/grammar/items/consts.rs | 2 +- src/parser/grammar/items/mod.rs | 2 +- src/parser/grammar/items/structs.rs | 4 ++-- src/parser/grammar/type_params.rs | 2 +- src/parser/grammar/types.rs | 18 ++++++++++++++---- tests/data/parser/inline/0020_never_type.rs | 1 + tests/data/parser/inline/0020_never_type.txt | 13 +++++++++++++ 7 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 tests/data/parser/inline/0020_never_type.rs create mode 100644 tests/data/parser/inline/0020_never_type.txt diff --git a/src/parser/grammar/items/consts.rs b/src/parser/grammar/items/consts.rs index 5f3cf58c2..d6c3753b3 100644 --- a/src/parser/grammar/items/consts.rs +++ b/src/parser/grammar/items/consts.rs @@ -14,7 +14,7 @@ fn const_or_static(p: &mut Parser, kw: SyntaxKind) { p.eat(MUT_KW); // TODO: validator to forbid const mut name(p); p.expect(COLON); - types::ty(p); + types::type_(p); p.expect(EQ); expressions::expr(p); p.expect(SEMI); diff --git a/src/parser/grammar/items/mod.rs b/src/parser/grammar/items/mod.rs index f1776e0e2..b1edf2f22 100644 --- a/src/parser/grammar/items/mod.rs +++ b/src/parser/grammar/items/mod.rs @@ -247,7 +247,7 @@ fn type_item(p: &mut Parser) { type_params::where_clause(p); p.expect(EQ); - types::ty(p); + types::type_(p); p.expect(SEMI); } diff --git a/src/parser/grammar/items/structs.rs b/src/parser/grammar/items/structs.rs index ad18fd270..c72b50808 100644 --- a/src/parser/grammar/items/structs.rs +++ b/src/parser/grammar/items/structs.rs @@ -89,7 +89,7 @@ fn named_fields(p: &mut Parser) { if p.at(IDENT) { name(p); p.expect(COLON); - types::ty(p); + types::type_(p); field.complete(p, NAMED_FIELD); } else { field.abandon(p); @@ -105,7 +105,7 @@ fn pos_fields(p: &mut Parser) { while !p.at(R_PAREN) && !p.at(EOF) { let pos_field = p.start(); visibility(p); - types::ty(p); + types::type_(p); pos_field.complete(p, POS_FIELD); if !p.at(R_PAREN) { diff --git a/src/parser/grammar/type_params.rs b/src/parser/grammar/type_params.rs index 2462b260e..9ea08a55c 100644 --- a/src/parser/grammar/type_params.rs +++ b/src/parser/grammar/type_params.rs @@ -62,7 +62,7 @@ pub(super) fn list(p: &mut Parser) { } } if p.at(EQ) { - types::ty(p) + types::type_(p) } m.complete(p, TYPE_PARAM); } diff --git a/src/parser/grammar/types.rs b/src/parser/grammar/types.rs index 71801d8ef..2ae583bd1 100644 --- a/src/parser/grammar/types.rs +++ b/src/parser/grammar/types.rs @@ -1,8 +1,9 @@ use super::*; -pub(super) fn ty(p: &mut Parser) { +pub(super) fn type_(p: &mut Parser) { match p.current() { - L_PAREN => paren_or_tuple_ty(p), + L_PAREN => paren_or_tuple_type(p), + EXCL => never_type(p), IDENT => path_type(p), _ => { p.error("expected type"); @@ -10,7 +11,7 @@ pub(super) fn ty(p: &mut Parser) { } } -fn paren_or_tuple_ty(p: &mut Parser) { +fn paren_or_tuple_type(p: &mut Parser) { assert!(p.at(L_PAREN)); let m = p.start(); p.bump(); @@ -18,7 +19,7 @@ fn paren_or_tuple_ty(p: &mut Parser) { let mut trailing_comma: bool = false; while !p.at(EOF) && !p.at(R_PAREN) { n_types += 1; - ty(p); + type_(p); if p.eat(COMMA) { trailing_comma = true; } else { @@ -43,6 +44,15 @@ fn paren_or_tuple_ty(p: &mut Parser) { m.complete(p, kind); } +// test never_type +// type Never = !; +fn never_type(p: &mut Parser) { + assert!(p.at(EXCL)); + let m = p.start(); + p.bump(); + m.complete(p, NEVER_TYPE); +} + fn path_type(p: &mut Parser) { assert!(p.at(IDENT)); let m = p.start(); diff --git a/tests/data/parser/inline/0020_never_type.rs b/tests/data/parser/inline/0020_never_type.rs new file mode 100644 index 000000000..de399fcf4 --- /dev/null +++ b/tests/data/parser/inline/0020_never_type.rs @@ -0,0 +1 @@ +type Never = !; diff --git a/tests/data/parser/inline/0020_never_type.txt b/tests/data/parser/inline/0020_never_type.txt new file mode 100644 index 000000000..935f33459 --- /dev/null +++ b/tests/data/parser/inline/0020_never_type.txt @@ -0,0 +1,13 @@ +FILE@[0; 16) + TYPE_ITEM@[0; 16) + TYPE_KW@[0; 4) + NAME@[4; 11) + WHITESPACE@[4; 5) + IDENT@[5; 10) "Never" + WHITESPACE@[10; 11) + EQ@[11; 12) + NEVER_TYPE@[12; 14) + WHITESPACE@[12; 13) + EXCL@[13; 14) + SEMI@[14; 15) + WHITESPACE@[15; 16) -- cgit v1.2.3 From ceb94ece2aa6a1b54063c582663fff4c1937d989 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 11 Feb 2018 11:19:54 +0300 Subject: G: pointer types --- grammar.ron | 1 + src/parser/grammar/types.rs | 29 ++++++++++++++++++ src/syntax_kinds.rs | 2 ++ .../inline/0021_pointer_type_no_mutability.rs | 1 + .../inline/0021_pointer_type_no_mutability.txt | 17 +++++++++++ tests/data/parser/inline/0022_pointer_type_mut.rs | 2 ++ tests/data/parser/inline/0022_pointer_type_mut.txt | 35 ++++++++++++++++++++++ tests/testutils/src/lib.rs | 15 +++++----- 8 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 tests/data/parser/inline/0021_pointer_type_no_mutability.rs create mode 100644 tests/data/parser/inline/0021_pointer_type_no_mutability.txt create mode 100644 tests/data/parser/inline/0022_pointer_type_mut.rs create mode 100644 tests/data/parser/inline/0022_pointer_type_mut.txt diff --git a/grammar.ron b/grammar.ron index 41d48f7b2..b43b58f02 100644 --- a/grammar.ron +++ b/grammar.ron @@ -105,6 +105,7 @@ Grammar( "TUPLE_TYPE", "NEVER_TYPE", "PATH_TYPE", + "POINTER_TYPE", "EXTERN_BLOCK", "ENUM_VARIANT", diff --git a/src/parser/grammar/types.rs b/src/parser/grammar/types.rs index 2ae583bd1..ceadf5f96 100644 --- a/src/parser/grammar/types.rs +++ b/src/parser/grammar/types.rs @@ -4,6 +4,7 @@ pub(super) fn type_(p: &mut Parser) { match p.current() { L_PAREN => paren_or_tuple_type(p), EXCL => never_type(p), + STAR => pointer_type(p), IDENT => path_type(p), _ => { p.error("expected type"); @@ -11,6 +12,10 @@ pub(super) fn type_(p: &mut Parser) { } } +fn type_no_plus(p: &mut Parser) { + type_(p); +} + fn paren_or_tuple_type(p: &mut Parser) { assert!(p.at(L_PAREN)); let m = p.start(); @@ -53,6 +58,30 @@ fn never_type(p: &mut Parser) { m.complete(p, NEVER_TYPE); } +fn pointer_type(p: &mut Parser) { + assert!(p.at(STAR)); + let m = p.start(); + p.bump(); + + match p.current() { + // test pointer_type_mut + // type M = *mut (); + // type C = *mut (); + MUT_KW | CONST_KW => p.bump(), + _ => { + // test pointer_type_no_mutability + // type T = *(); + p.error( + "expected mut or const in raw pointer type \ + (use `*mut T` or `*const T` as appropriate)" + ); + } + }; + + type_no_plus(p); + m.complete(p, 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 630d3d2a5..181dcc63b 100644 --- a/src/syntax_kinds.rs +++ b/src/syntax_kinds.rs @@ -103,6 +103,7 @@ pub enum SyntaxKind { TUPLE_TYPE, NEVER_TYPE, PATH_TYPE, + POINTER_TYPE, EXTERN_BLOCK, ENUM_VARIANT, NAMED_FIELD, @@ -232,6 +233,7 @@ impl SyntaxKind { TUPLE_TYPE => &SyntaxInfo { name: "TUPLE_TYPE" }, NEVER_TYPE => &SyntaxInfo { name: "NEVER_TYPE" }, PATH_TYPE => &SyntaxInfo { name: "PATH_TYPE" }, + POINTER_TYPE => &SyntaxInfo { name: "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/0021_pointer_type_no_mutability.rs b/tests/data/parser/inline/0021_pointer_type_no_mutability.rs new file mode 100644 index 000000000..fae705131 --- /dev/null +++ b/tests/data/parser/inline/0021_pointer_type_no_mutability.rs @@ -0,0 +1 @@ +type T = *(); diff --git a/tests/data/parser/inline/0021_pointer_type_no_mutability.txt b/tests/data/parser/inline/0021_pointer_type_no_mutability.txt new file mode 100644 index 000000000..f7720a712 --- /dev/null +++ b/tests/data/parser/inline/0021_pointer_type_no_mutability.txt @@ -0,0 +1,17 @@ +FILE@[0; 14) + TYPE_ITEM@[0; 14) + TYPE_KW@[0; 4) + NAME@[4; 7) + WHITESPACE@[4; 5) + IDENT@[5; 6) "T" + WHITESPACE@[6; 7) + EQ@[7; 8) + POINTER_TYPE@[8; 12) + WHITESPACE@[8; 9) + STAR@[9; 10) + err: `expected mut or const in raw pointer type (use `*mut T` or `*const T` as appropriate)` + TUPLE_TYPE@[10; 12) + L_PAREN@[10; 11) + R_PAREN@[11; 12) + SEMI@[12; 13) + WHITESPACE@[13; 14) diff --git a/tests/data/parser/inline/0022_pointer_type_mut.rs b/tests/data/parser/inline/0022_pointer_type_mut.rs new file mode 100644 index 000000000..04b2bb9ba --- /dev/null +++ b/tests/data/parser/inline/0022_pointer_type_mut.rs @@ -0,0 +1,2 @@ +type M = *mut (); +type C = *mut (); diff --git a/tests/data/parser/inline/0022_pointer_type_mut.txt b/tests/data/parser/inline/0022_pointer_type_mut.txt new file mode 100644 index 000000000..c3ab2b887 --- /dev/null +++ b/tests/data/parser/inline/0022_pointer_type_mut.txt @@ -0,0 +1,35 @@ +FILE@[0; 36) + TYPE_ITEM@[0; 18) + TYPE_KW@[0; 4) + NAME@[4; 7) + WHITESPACE@[4; 5) + IDENT@[5; 6) "M" + WHITESPACE@[6; 7) + EQ@[7; 8) + POINTER_TYPE@[8; 16) + WHITESPACE@[8; 9) + STAR@[9; 10) + MUT_KW@[10; 13) + TUPLE_TYPE@[13; 16) + WHITESPACE@[13; 14) + L_PAREN@[14; 15) + R_PAREN@[15; 16) + SEMI@[16; 17) + WHITESPACE@[17; 18) + TYPE_ITEM@[18; 36) + TYPE_KW@[18; 22) + NAME@[22; 25) + WHITESPACE@[22; 23) + IDENT@[23; 24) "C" + WHITESPACE@[24; 25) + EQ@[25; 26) + POINTER_TYPE@[26; 34) + WHITESPACE@[26; 27) + STAR@[27; 28) + MUT_KW@[28; 31) + TUPLE_TYPE@[31; 34) + WHITESPACE@[31; 32) + L_PAREN@[32; 33) + R_PAREN@[33; 34) + SEMI@[34; 35) + WHITESPACE@[35; 36) diff --git a/tests/testutils/src/lib.rs b/tests/testutils/src/lib.rs index b50e70849..ae1dea810 100644 --- a/tests/testutils/src/lib.rs +++ b/tests/testutils/src/lib.rs @@ -26,21 +26,20 @@ where F: Fn(&str) -> String, { for path in collect_tests(paths) { - let actual = { - let text = read_text(&path); - f(&text) - }; + let input_code = read_text(&path); + let parse_tree = f(&input_code); let path = path.with_extension("txt"); if !path.exists() { println!("\nfile: {}", path.display()); - println!("No .txt file with expected result, creating..."); - file::put_text(&path, actual).unwrap(); + println!("No .txt file with expected result, creating...\n"); + println!("{}\n{}", input_code, parse_tree); + file::put_text(&path, parse_tree).unwrap(); panic!("No expected result") } let expected = read_text(&path); let expected = expected.as_str(); - let actual = actual.as_str(); - assert_equal_text(expected, actual, &path); + let parse_tree = parse_tree.as_str(); + assert_equal_text(expected, parse_tree, &path); } } -- cgit v1.2.3 From 555c4ae37560493fd901aad41951ad1664043459 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 11 Feb 2018 11:37:08 +0300 Subject: G: slice & array types --- grammar.ron | 2 ++ src/parser/grammar/types.rs | 33 ++++++++++++++++++++++ src/syntax_kinds.rs | 4 +++ .../parser/inline/0023_array_type_missing_semi.rs | 1 + .../parser/inline/0023_array_type_missing_semi.txt | 28 ++++++++++++++++++ tests/data/parser/inline/0024_array_type.rs | 1 + tests/data/parser/inline/0024_array_type.txt | 21 ++++++++++++++ tests/data/parser/inline/0025_slice_type.rs | 1 + tests/data/parser/inline/0025_slice_type.txt | 17 +++++++++++ 9 files changed, 108 insertions(+) create mode 100644 tests/data/parser/inline/0023_array_type_missing_semi.rs create mode 100644 tests/data/parser/inline/0023_array_type_missing_semi.txt create mode 100644 tests/data/parser/inline/0024_array_type.rs create mode 100644 tests/data/parser/inline/0024_array_type.txt create mode 100644 tests/data/parser/inline/0025_slice_type.rs create mode 100644 tests/data/parser/inline/0025_slice_type.txt diff --git a/grammar.ron b/grammar.ron index b43b58f02..bc7dd7c55 100644 --- a/grammar.ron +++ b/grammar.ron @@ -106,6 +106,8 @@ Grammar( "NEVER_TYPE", "PATH_TYPE", "POINTER_TYPE", + "ARRAY_TYPE", + "SLICE_TYPE", "EXTERN_BLOCK", "ENUM_VARIANT", diff --git a/src/parser/grammar/types.rs b/src/parser/grammar/types.rs index ceadf5f96..4eb333b54 100644 --- a/src/parser/grammar/types.rs +++ b/src/parser/grammar/types.rs @@ -5,6 +5,7 @@ pub(super) fn type_(p: &mut Parser) { L_PAREN => paren_or_tuple_type(p), EXCL => never_type(p), STAR => pointer_type(p), + L_BRACK => array_or_slice_type(p), IDENT => path_type(p), _ => { p.error("expected type"); @@ -82,6 +83,38 @@ fn pointer_type(p: &mut Parser) { m.complete(p, POINTER_TYPE); } +fn array_or_slice_type(p: &mut Parser) { + assert!(p.at(L_BRACK)); + let m = p.start(); + p.bump(); + + type_(p); + let kind = match p.current() { + // test slice_type + // type T = [()]; + R_BRACK => { + p.bump(); + SLICE_TYPE + }, + + // test array_type + // type T = [(); 92]; + SEMI => { + p.bump(); + expressions::expr(p); + p.expect(R_BRACK); + ARRAY_TYPE + } + // test array_type_missing_semi + // type T = [() 92]; + _ => { + p.error("expected `;` or `]`"); + SLICE_TYPE + } + }; + m.complete(p, kind); +} + 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 181dcc63b..54200f2d1 100644 --- a/src/syntax_kinds.rs +++ b/src/syntax_kinds.rs @@ -104,6 +104,8 @@ pub enum SyntaxKind { NEVER_TYPE, PATH_TYPE, POINTER_TYPE, + ARRAY_TYPE, + SLICE_TYPE, EXTERN_BLOCK, ENUM_VARIANT, NAMED_FIELD, @@ -234,6 +236,8 @@ impl SyntaxKind { NEVER_TYPE => &SyntaxInfo { name: "NEVER_TYPE" }, PATH_TYPE => &SyntaxInfo { name: "PATH_TYPE" }, POINTER_TYPE => &SyntaxInfo { name: "POINTER_TYPE" }, + ARRAY_TYPE => &SyntaxInfo { name: "ARRAY_TYPE" }, + SLICE_TYPE => &SyntaxInfo { name: "SLICE_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/0023_array_type_missing_semi.rs b/tests/data/parser/inline/0023_array_type_missing_semi.rs new file mode 100644 index 000000000..a94851443 --- /dev/null +++ b/tests/data/parser/inline/0023_array_type_missing_semi.rs @@ -0,0 +1 @@ +type T = [() 92]; diff --git a/tests/data/parser/inline/0023_array_type_missing_semi.txt b/tests/data/parser/inline/0023_array_type_missing_semi.txt new file mode 100644 index 000000000..bb30a2a2a --- /dev/null +++ b/tests/data/parser/inline/0023_array_type_missing_semi.txt @@ -0,0 +1,28 @@ +FILE@[0; 18) + TYPE_ITEM@[0; 13) + TYPE_KW@[0; 4) + NAME@[4; 7) + WHITESPACE@[4; 5) + IDENT@[5; 6) "T" + WHITESPACE@[6; 7) + EQ@[7; 8) + SLICE_TYPE@[8; 13) + WHITESPACE@[8; 9) + L_BRACK@[9; 10) + TUPLE_TYPE@[10; 13) + L_PAREN@[10; 11) + R_PAREN@[11; 12) + WHITESPACE@[12; 13) + err: `expected `;` or `]`` + err: `expected SEMI` + ERROR@[13; 15) + err: `expected item` + INT_NUMBER@[13; 15) + ERROR@[15; 16) + err: `expected item` + R_BRACK@[15; 16) + ERROR@[16; 18) + err: `expected item, found `;` +consider removing this semicolon` + SEMI@[16; 17) + WHITESPACE@[17; 18) diff --git a/tests/data/parser/inline/0024_array_type.rs b/tests/data/parser/inline/0024_array_type.rs new file mode 100644 index 000000000..27eb22f22 --- /dev/null +++ b/tests/data/parser/inline/0024_array_type.rs @@ -0,0 +1 @@ +type T = [(); 92]; diff --git a/tests/data/parser/inline/0024_array_type.txt b/tests/data/parser/inline/0024_array_type.txt new file mode 100644 index 000000000..970734a19 --- /dev/null +++ b/tests/data/parser/inline/0024_array_type.txt @@ -0,0 +1,21 @@ +FILE@[0; 19) + TYPE_ITEM@[0; 19) + TYPE_KW@[0; 4) + NAME@[4; 7) + WHITESPACE@[4; 5) + IDENT@[5; 6) "T" + WHITESPACE@[6; 7) + EQ@[7; 8) + ARRAY_TYPE@[8; 17) + WHITESPACE@[8; 9) + L_BRACK@[9; 10) + TUPLE_TYPE@[10; 12) + L_PAREN@[10; 11) + R_PAREN@[11; 12) + SEMI@[12; 13) + LITERAL@[13; 16) + WHITESPACE@[13; 14) + INT_NUMBER@[14; 16) + R_BRACK@[16; 17) + SEMI@[17; 18) + WHITESPACE@[18; 19) diff --git a/tests/data/parser/inline/0025_slice_type.rs b/tests/data/parser/inline/0025_slice_type.rs new file mode 100644 index 000000000..4da1af827 --- /dev/null +++ b/tests/data/parser/inline/0025_slice_type.rs @@ -0,0 +1 @@ +type T = [()]; diff --git a/tests/data/parser/inline/0025_slice_type.txt b/tests/data/parser/inline/0025_slice_type.txt new file mode 100644 index 000000000..22938e5e1 --- /dev/null +++ b/tests/data/parser/inline/0025_slice_type.txt @@ -0,0 +1,17 @@ +FILE@[0; 15) + TYPE_ITEM@[0; 15) + TYPE_KW@[0; 4) + NAME@[4; 7) + WHITESPACE@[4; 5) + IDENT@[5; 6) "T" + WHITESPACE@[6; 7) + EQ@[7; 8) + SLICE_TYPE@[8; 13) + WHITESPACE@[8; 9) + L_BRACK@[9; 10) + TUPLE_TYPE@[10; 12) + L_PAREN@[10; 11) + R_PAREN@[11; 12) + R_BRACK@[12; 13) + SEMI@[13; 14) + WHITESPACE@[14; 15) -- cgit v1.2.3 From eb4c05d572ff0c4e92452232d6591d7a2796e785 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 11 Feb 2018 11:54:09 +0300 Subject: G: reference types --- grammar.ron | 1 + src/parser/grammar/types.rs | 15 +++++++ src/syntax_kinds.rs | 2 + tests/data/parser/inline/0026_reference_type;.rs | 3 ++ tests/data/parser/inline/0026_reference_type;.txt | 50 +++++++++++++++++++++++ 5 files changed, 71 insertions(+) create mode 100644 tests/data/parser/inline/0026_reference_type;.rs create mode 100644 tests/data/parser/inline/0026_reference_type;.txt diff --git a/grammar.ron b/grammar.ron index bc7dd7c55..0905c282a 100644 --- a/grammar.ron +++ b/grammar.ron @@ -108,6 +108,7 @@ Grammar( "POINTER_TYPE", "ARRAY_TYPE", "SLICE_TYPE", + "REFERENCE_TYPE", "EXTERN_BLOCK", "ENUM_VARIANT", diff --git a/src/parser/grammar/types.rs b/src/parser/grammar/types.rs index 4eb333b54..003341db5 100644 --- a/src/parser/grammar/types.rs +++ b/src/parser/grammar/types.rs @@ -6,6 +6,7 @@ pub(super) fn type_(p: &mut Parser) { EXCL => never_type(p), STAR => pointer_type(p), L_BRACK => array_or_slice_type(p), + AMPERSAND => reference_type(p), IDENT => path_type(p), _ => { p.error("expected type"); @@ -115,6 +116,20 @@ fn array_or_slice_type(p: &mut Parser) { m.complete(p, kind); } +// test reference_type; +// type A = &(); +// type B = &'static (); +// type C = &mut (); +fn reference_type(p: &mut Parser) { + assert!(p.at(AMPERSAND)); + let m = p.start(); + p.bump(); + p.eat(LIFETIME); + p.eat(MUT_KW); + type_no_plus(p); + m.complete(p, REFERENCE_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 54200f2d1..597550a32 100644 --- a/src/syntax_kinds.rs +++ b/src/syntax_kinds.rs @@ -106,6 +106,7 @@ pub enum SyntaxKind { POINTER_TYPE, ARRAY_TYPE, SLICE_TYPE, + REFERENCE_TYPE, EXTERN_BLOCK, ENUM_VARIANT, NAMED_FIELD, @@ -238,6 +239,7 @@ impl SyntaxKind { POINTER_TYPE => &SyntaxInfo { name: "POINTER_TYPE" }, ARRAY_TYPE => &SyntaxInfo { name: "ARRAY_TYPE" }, SLICE_TYPE => &SyntaxInfo { name: "SLICE_TYPE" }, + REFERENCE_TYPE => &SyntaxInfo { name: "REFERENCE_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/0026_reference_type;.rs b/tests/data/parser/inline/0026_reference_type;.rs new file mode 100644 index 000000000..3ac0badab --- /dev/null +++ b/tests/data/parser/inline/0026_reference_type;.rs @@ -0,0 +1,3 @@ +type A = &(); +type B = &'static (); +type C = &mut (); diff --git a/tests/data/parser/inline/0026_reference_type;.txt b/tests/data/parser/inline/0026_reference_type;.txt new file mode 100644 index 000000000..665c021e1 --- /dev/null +++ b/tests/data/parser/inline/0026_reference_type;.txt @@ -0,0 +1,50 @@ +FILE@[0; 54) + TYPE_ITEM@[0; 14) + TYPE_KW@[0; 4) + NAME@[4; 7) + WHITESPACE@[4; 5) + IDENT@[5; 6) "A" + WHITESPACE@[6; 7) + EQ@[7; 8) + REFERENCE_TYPE@[8; 12) + WHITESPACE@[8; 9) + AMPERSAND@[9; 10) + TUPLE_TYPE@[10; 12) + L_PAREN@[10; 11) + R_PAREN@[11; 12) + SEMI@[12; 13) + WHITESPACE@[13; 14) + TYPE_ITEM@[14; 36) + TYPE_KW@[14; 18) + NAME@[18; 21) + WHITESPACE@[18; 19) + IDENT@[19; 20) "B" + WHITESPACE@[20; 21) + EQ@[21; 22) + REFERENCE_TYPE@[22; 34) + WHITESPACE@[22; 23) + AMPERSAND@[23; 24) + LIFETIME@[24; 31) "'static" + TUPLE_TYPE@[31; 34) + WHITESPACE@[31; 32) + L_PAREN@[32; 33) + R_PAREN@[33; 34) + SEMI@[34; 35) + WHITESPACE@[35; 36) + TYPE_ITEM@[36; 54) + TYPE_KW@[36; 40) + NAME@[40; 43) + WHITESPACE@[40; 41) + IDENT@[41; 42) "C" + WHITESPACE@[42; 43) + EQ@[43; 44) + REFERENCE_TYPE@[44; 52) + WHITESPACE@[44; 45) + AMPERSAND@[45; 46) + MUT_KW@[46; 49) + TUPLE_TYPE@[49; 52) + WHITESPACE@[49; 50) + L_PAREN@[50; 51) + R_PAREN@[51; 52) + SEMI@[52; 53) + WHITESPACE@[53; 54) -- cgit v1.2.3 From 2fb33b2d0d14f09ee06a42bca252dccbf57185e1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 11 Feb 2018 11:57:05 +0300 Subject: G: placeholder types --- grammar.ron | 1 + src/parser/grammar/types.rs | 10 ++++++++++ src/syntax_kinds.rs | 2 ++ tests/data/parser/inline/0027_placeholder_type.rs | 1 + tests/data/parser/inline/0027_placeholder_type.txt | 13 +++++++++++++ 5 files changed, 27 insertions(+) create mode 100644 tests/data/parser/inline/0027_placeholder_type.rs create mode 100644 tests/data/parser/inline/0027_placeholder_type.txt diff --git a/grammar.ron b/grammar.ron index 0905c282a..e3010b009 100644 --- a/grammar.ron +++ b/grammar.ron @@ -109,6 +109,7 @@ Grammar( "ARRAY_TYPE", "SLICE_TYPE", "REFERENCE_TYPE", + "PLACEHOLDER_TYPE", "EXTERN_BLOCK", "ENUM_VARIANT", diff --git a/src/parser/grammar/types.rs b/src/parser/grammar/types.rs index 003341db5..37b74bfe7 100644 --- a/src/parser/grammar/types.rs +++ b/src/parser/grammar/types.rs @@ -7,6 +7,7 @@ pub(super) fn type_(p: &mut Parser) { STAR => pointer_type(p), L_BRACK => array_or_slice_type(p), AMPERSAND => reference_type(p), + UNDERSCORE => placeholder_type(p), IDENT => path_type(p), _ => { p.error("expected type"); @@ -130,6 +131,15 @@ fn reference_type(p: &mut Parser) { m.complete(p, REFERENCE_TYPE); } +// test placeholder_type +// type Placeholder = _; +fn placeholder_type(p: &mut Parser) { + assert!(p.at(UNDERSCORE)); + let m = p.start(); + p.bump(); + m.complete(p, PLACEHOLDER_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 597550a32..73539d6d4 100644 --- a/src/syntax_kinds.rs +++ b/src/syntax_kinds.rs @@ -107,6 +107,7 @@ pub enum SyntaxKind { ARRAY_TYPE, SLICE_TYPE, REFERENCE_TYPE, + PLACEHOLDER_TYPE, EXTERN_BLOCK, ENUM_VARIANT, NAMED_FIELD, @@ -240,6 +241,7 @@ impl SyntaxKind { ARRAY_TYPE => &SyntaxInfo { name: "ARRAY_TYPE" }, SLICE_TYPE => &SyntaxInfo { name: "SLICE_TYPE" }, REFERENCE_TYPE => &SyntaxInfo { name: "REFERENCE_TYPE" }, + PLACEHOLDER_TYPE => &SyntaxInfo { name: "PLACEHOLDER_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/0027_placeholder_type.rs b/tests/data/parser/inline/0027_placeholder_type.rs new file mode 100644 index 000000000..7952dbd57 --- /dev/null +++ b/tests/data/parser/inline/0027_placeholder_type.rs @@ -0,0 +1 @@ +type Placeholder = _; diff --git a/tests/data/parser/inline/0027_placeholder_type.txt b/tests/data/parser/inline/0027_placeholder_type.txt new file mode 100644 index 000000000..ab848836c --- /dev/null +++ b/tests/data/parser/inline/0027_placeholder_type.txt @@ -0,0 +1,13 @@ +FILE@[0; 22) + TYPE_ITEM@[0; 22) + TYPE_KW@[0; 4) + NAME@[4; 17) + WHITESPACE@[4; 5) + IDENT@[5; 16) "Placeholder" + WHITESPACE@[16; 17) + EQ@[17; 18) + PLACEHOLDER_TYPE@[18; 20) + WHITESPACE@[18; 19) + UNDERSCORE@[19; 20) + SEMI@[20; 21) + WHITESPACE@[21; 22) -- cgit v1.2.3 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 From 96437b050f2743fef2e37eaab7259f2f98f9b473 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 11 Feb 2018 12:58:12 +0300 Subject: Formatting --- src/parser/grammar/types.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parser/grammar/types.rs b/src/parser/grammar/types.rs index ea4df8639..a4967a00a 100644 --- a/src/parser/grammar/types.rs +++ b/src/parser/grammar/types.rs @@ -77,7 +77,7 @@ fn pointer_type(p: &mut Parser) { // type T = *(); p.error( "expected mut or const in raw pointer type \ - (use `*mut T` or `*const T` as appropriate)" + (use `*mut T` or `*const T` as appropriate)", ); } }; @@ -98,7 +98,7 @@ fn array_or_slice_type(p: &mut Parser) { R_BRACK => { p.bump(); SLICE_TYPE - }, + } // test array_type // type T = [(); 92]; -- cgit v1.2.3