From ce3462ce8fed8bb86d887643479c73908fc326a3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 31 Jul 2018 20:38:36 +0300 Subject: [PATCH] struct literals --- src/grammar.ron | 2 + src/parser/grammar/expressions.rs | 39 +++++++- src/syntax_kinds/generated.rs | 4 + tests/data/parser/inline/0061_struct_lit.rs | 5 ++ tests/data/parser/inline/0061_struct_lit.txt | 94 ++++++++++++++++++++ 5 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 tests/data/parser/inline/0061_struct_lit.rs create mode 100644 tests/data/parser/inline/0061_struct_lit.txt diff --git a/src/grammar.ron b/src/grammar.ron index 6c67db73998..5642492001a 100644 --- a/src/grammar.ron +++ b/src/grammar.ron @@ -129,6 +129,8 @@ Grammar( "METHOD_CALL_EXPR", "FIELD_EXPR", "REF_EXPR", + "STRUCT_LIT", + "STRUCT_LIT_FIELD", "EXTERN_BLOCK", "ENUM_VARIANT", diff --git a/src/parser/grammar/expressions.rs b/src/parser/grammar/expressions.rs index 3956df56850..5b18e2294db 100644 --- a/src/parser/grammar/expressions.rs +++ b/src/parser/grammar/expressions.rs @@ -154,5 +154,42 @@ fn path_expr(p: &mut Parser) -> CompletedMarker { assert!(paths::is_path_start(p)); let m = p.start(); paths::expr_path(p); - m.complete(p, PATH_EXPR) + if p.at(L_CURLY) { + struct_lit(p); + m.complete(p, STRUCT_LIT) + } else { + m.complete(p, PATH_EXPR) + } +} + +// test struct_lit +// fn foo() { +// S {}; +// S { x, y: 32, }; +// S { x, y: 32, ..Default::default() }; +// } +fn struct_lit(p: &mut Parser) { + assert!(p.at(L_CURLY)); + p.bump(); + while !p.at(EOF) && !p.at(R_CURLY) { + match p.current() { + IDENT => { + let m = p.start(); + name_ref(p); + if p.eat(COLON) { + expr(p); + } + m.complete(p, STRUCT_LIT_FIELD); + }, + DOTDOT => { + p.bump(); + expr(p); + }, + _ => p.err_and_bump("expected identifier"), + } + if !p.at(R_CURLY) { + p.expect(COMMA); + } + } + p.expect(R_CURLY); } diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs index 7c9333fc51c..6557645288e 100644 --- a/src/syntax_kinds/generated.rs +++ b/src/syntax_kinds/generated.rs @@ -120,6 +120,8 @@ pub enum SyntaxKind { METHOD_CALL_EXPR, FIELD_EXPR, REF_EXPR, + STRUCT_LIT, + STRUCT_LIT_FIELD, EXTERN_BLOCK, ENUM_VARIANT, NAMED_FIELD, @@ -277,6 +279,8 @@ impl SyntaxKind { METHOD_CALL_EXPR => &SyntaxInfo { name: "METHOD_CALL_EXPR" }, FIELD_EXPR => &SyntaxInfo { name: "FIELD_EXPR" }, REF_EXPR => &SyntaxInfo { name: "REF_EXPR" }, + STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" }, + STRUCT_LIT_FIELD => &SyntaxInfo { name: "STRUCT_LIT_FIELD" }, 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/0061_struct_lit.rs b/tests/data/parser/inline/0061_struct_lit.rs new file mode 100644 index 00000000000..eb711f68a13 --- /dev/null +++ b/tests/data/parser/inline/0061_struct_lit.rs @@ -0,0 +1,5 @@ +fn foo() { + S {}; + S { x, y: 32, }; + S { x, y: 32, ..Default::default() }; +} diff --git a/tests/data/parser/inline/0061_struct_lit.txt b/tests/data/parser/inline/0061_struct_lit.txt new file mode 100644 index 00000000000..9a63d8fb2fc --- /dev/null +++ b/tests/data/parser/inline/0061_struct_lit.txt @@ -0,0 +1,94 @@ +FILE@[0; 86) + FN_ITEM@[0; 86) + FN_KW@[0; 2) + NAME@[2; 6) + WHITESPACE@[2; 3) + IDENT@[3; 6) "foo" + PARAM_LIST@[6; 9) + L_PAREN@[6; 7) + R_PAREN@[7; 8) + WHITESPACE@[8; 9) + BLOCK@[9; 86) + L_CURLY@[9; 10) + EXPR_STMT@[10; 25) + STRUCT_LIT@[10; 19) + PATH@[10; 17) + PATH_SEGMENT@[10; 17) + NAME_REF@[10; 17) + WHITESPACE@[10; 15) + IDENT@[15; 16) "S" + WHITESPACE@[16; 17) + L_CURLY@[17; 18) + R_CURLY@[18; 19) + SEMI@[19; 20) + WHITESPACE@[20; 25) + EXPR_STMT@[25; 46) + STRUCT_LIT@[25; 40) + PATH@[25; 27) + PATH_SEGMENT@[25; 27) + NAME_REF@[25; 27) + IDENT@[25; 26) "S" + WHITESPACE@[26; 27) + L_CURLY@[27; 28) + STRUCT_LIT_FIELD@[28; 30) + NAME_REF@[28; 30) + WHITESPACE@[28; 29) + IDENT@[29; 30) "x" + COMMA@[30; 31) + STRUCT_LIT_FIELD@[31; 37) + NAME_REF@[31; 33) + WHITESPACE@[31; 32) + IDENT@[32; 33) "y" + COLON@[33; 34) + LITERAL@[34; 37) + WHITESPACE@[34; 35) + INT_NUMBER@[35; 37) + COMMA@[37; 38) + WHITESPACE@[38; 39) + R_CURLY@[39; 40) + SEMI@[40; 41) + WHITESPACE@[41; 46) + EXPR_STMT@[46; 84) + STRUCT_LIT@[46; 82) + PATH@[46; 48) + PATH_SEGMENT@[46; 48) + NAME_REF@[46; 48) + IDENT@[46; 47) "S" + WHITESPACE@[47; 48) + L_CURLY@[48; 49) + STRUCT_LIT_FIELD@[49; 51) + NAME_REF@[49; 51) + WHITESPACE@[49; 50) + IDENT@[50; 51) "x" + COMMA@[51; 52) + STRUCT_LIT_FIELD@[52; 58) + NAME_REF@[52; 54) + WHITESPACE@[52; 53) + IDENT@[53; 54) "y" + COLON@[54; 55) + LITERAL@[55; 58) + WHITESPACE@[55; 56) + INT_NUMBER@[56; 58) + COMMA@[58; 59) + WHITESPACE@[59; 60) + DOTDOT@[60; 62) + CALL_EXPR@[62; 81) + PATH_EXPR@[62; 78) + PATH@[62; 78) + PATH@[62; 69) + PATH_SEGMENT@[62; 69) + NAME_REF@[62; 69) + IDENT@[62; 69) "Default" + COLONCOLON@[69; 71) + PATH_SEGMENT@[71; 78) + NAME_REF@[71; 78) + IDENT@[71; 78) "default" + ARG_LIST@[78; 81) + L_PAREN@[78; 79) + R_PAREN@[79; 80) + WHITESPACE@[80; 81) + R_CURLY@[81; 82) + SEMI@[82; 83) + WHITESPACE@[83; 84) + R_CURLY@[84; 85) + WHITESPACE@[85; 86)