G: pointer types

This commit is contained in:
Aleksey Kladov 2018-02-11 11:19:54 +03:00
parent 2389cf96dd
commit ceb94ece2a
8 changed files with 94 additions and 8 deletions

View file

@ -105,6 +105,7 @@ Grammar(
"TUPLE_TYPE", "TUPLE_TYPE",
"NEVER_TYPE", "NEVER_TYPE",
"PATH_TYPE", "PATH_TYPE",
"POINTER_TYPE",
"EXTERN_BLOCK", "EXTERN_BLOCK",
"ENUM_VARIANT", "ENUM_VARIANT",

View file

@ -4,6 +4,7 @@ pub(super) fn type_(p: &mut Parser) {
match p.current() { match p.current() {
L_PAREN => paren_or_tuple_type(p), L_PAREN => paren_or_tuple_type(p),
EXCL => never_type(p), EXCL => never_type(p),
STAR => pointer_type(p),
IDENT => path_type(p), IDENT => path_type(p),
_ => { _ => {
p.error("expected type"); 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) { fn paren_or_tuple_type(p: &mut Parser) {
assert!(p.at(L_PAREN)); assert!(p.at(L_PAREN));
let m = p.start(); let m = p.start();
@ -53,6 +58,30 @@ fn never_type(p: &mut Parser) {
m.complete(p, NEVER_TYPE); 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) { fn path_type(p: &mut Parser) {
assert!(p.at(IDENT)); assert!(p.at(IDENT));
let m = p.start(); let m = p.start();

View file

@ -103,6 +103,7 @@ pub enum SyntaxKind {
TUPLE_TYPE, TUPLE_TYPE,
NEVER_TYPE, NEVER_TYPE,
PATH_TYPE, PATH_TYPE,
POINTER_TYPE,
EXTERN_BLOCK, EXTERN_BLOCK,
ENUM_VARIANT, ENUM_VARIANT,
NAMED_FIELD, NAMED_FIELD,
@ -232,6 +233,7 @@ impl SyntaxKind {
TUPLE_TYPE => &SyntaxInfo { name: "TUPLE_TYPE" }, TUPLE_TYPE => &SyntaxInfo { name: "TUPLE_TYPE" },
NEVER_TYPE => &SyntaxInfo { name: "NEVER_TYPE" }, NEVER_TYPE => &SyntaxInfo { name: "NEVER_TYPE" },
PATH_TYPE => &SyntaxInfo { name: "PATH_TYPE" }, PATH_TYPE => &SyntaxInfo { name: "PATH_TYPE" },
POINTER_TYPE => &SyntaxInfo { name: "POINTER_TYPE" },
EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" },
ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },

View file

@ -0,0 +1 @@
type T = *();

View file

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

View file

@ -0,0 +1,2 @@
type M = *mut ();
type C = *mut ();

View file

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

View file

@ -26,21 +26,20 @@ where
F: Fn(&str) -> String, F: Fn(&str) -> String,
{ {
for path in collect_tests(paths) { for path in collect_tests(paths) {
let actual = { let input_code = read_text(&path);
let text = read_text(&path); let parse_tree = f(&input_code);
f(&text)
};
let path = path.with_extension("txt"); let path = path.with_extension("txt");
if !path.exists() { if !path.exists() {
println!("\nfile: {}", path.display()); println!("\nfile: {}", path.display());
println!("No .txt file with expected result, creating..."); println!("No .txt file with expected result, creating...\n");
file::put_text(&path, actual).unwrap(); println!("{}\n{}", input_code, parse_tree);
file::put_text(&path, parse_tree).unwrap();
panic!("No expected result") panic!("No expected result")
} }
let expected = read_text(&path); let expected = read_text(&path);
let expected = expected.as_str(); let expected = expected.as_str();
let actual = actual.as_str(); let parse_tree = parse_tree.as_str();
assert_equal_text(expected, actual, &path); assert_equal_text(expected, parse_tree, &path);
} }
} }