From a6e07200a058b8cc50902a99407e5afbcaa927b3 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 28 Oct 2016 09:29:24 +0800 Subject: Parse - Support attributes on generics, unify HRL (HRTB) parsing --- src/parse/common.hpp | 1 + src/parse/root.cpp | 86 ++++++++++++++++++++++++++++------------------------ src/parse/types.cpp | 8 +---- 3 files changed, 48 insertions(+), 47 deletions(-) diff --git a/src/parse/common.hpp b/src/parse/common.hpp index aa6e8c3d..7bf41d22 100644 --- a/src/parse/common.hpp +++ b/src/parse/common.hpp @@ -39,6 +39,7 @@ extern ::std::vector Parse_PathNodes(TokenStream& lex, eParsePath extern AST::PathParams Parse_Path_GenericList(TokenStream& lex); +extern ::std::vector< ::std::string> Parse_HRB(TokenStream& lex); extern AST::MetaItem Parse_MetaItem(TokenStream& lex); extern ::AST::MacroInvocation Parse_MacroInvocation(ProtoSpan ps, ::std::string name, TokenStream& lex); extern TypeRef Parse_Type(TokenStream& lex, bool allow_trait_list = true); diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 4da47cbe..feb5d37a 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -48,7 +48,18 @@ void Parse_ModRoot(TokenStream& lex, AST::Module& mod, AST::MetaItems& mod_attrs ::std::vector< ::std::string> lifetimes; GET_CHECK_TOK(tok, lex, TOK_LT); do { - switch(GET_TOK(tok, lex)) + GET_TOK(tok, lex); + + ::AST::MetaItems attrs; + while(tok.type() == TOK_ATTR_OPEN) + { + attrs.push_back( Parse_MetaItem(lex) ); + GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE); + GET_TOK(tok, lex); + } + (void)attrs; // TODO: Attributes on generic params + + switch(tok.type()) { case TOK_LIFETIME: lifetimes.push_back(tok.str()); @@ -68,6 +79,7 @@ void Parse_TypeBound(TokenStream& lex, AST::GenericParams& ret, TypeRef checked_ do { + ::std::vector< ::std::string> hrls; if(GET_TOK(tok, lex) == TOK_LIFETIME) { ret.add_bound(AST::GenericBound::make_TypeLifetime( { checked_type.clone(), tok.str() @@ -81,22 +93,12 @@ void Parse_TypeBound(TokenStream& lex, AST::GenericParams& ret, TypeRef checked_ else { if( tok.type() == TOK_RWORD_FOR ) { - GET_CHECK_TOK(tok, lex, TOK_LT); - do { - switch(GET_TOK(tok, lex)) - { - case TOK_LIFETIME: - lifetimes.push_back(tok.str()); - break; - default: - throw ParseError::Unexpected(lex, tok, Token(TOK_LIFETIME)); - } - } while( GET_TOK(tok, lex) == TOK_COMMA ); - CHECK_TOK(tok, TOK_GT); + hrls = Parse_HRB(lex); } else { PUTBACK(tok, lex); } + (void)hrls; // TODO: HRLs ret.add_bound( AST::GenericBound::make_IsTrait({ checked_type.clone(), mv$(lifetimes), Parse_Path(lex, PATH_GENERIC_TYPE) @@ -114,48 +116,52 @@ AST::GenericParams Parse_GenericParams(TokenStream& lex) AST::GenericParams ret; Token tok; do { - bool is_lifetime = false; if( GET_TOK(tok, lex) == TOK_GT ) { break ; } - switch( tok.type() ) + + ::AST::MetaItems attrs; + while(tok.type() == TOK_ATTR_OPEN) { - case TOK_IDENT: - break; - case TOK_LIFETIME: - is_lifetime = true; - break; - default: - // Oopsie! - throw ParseError::Unexpected(lex, tok); + attrs.push_back( Parse_MetaItem(lex) ); + GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE); + GET_TOK(tok, lex); } - ::std::string param_name = tok.str(); - if( is_lifetime ) - ret.add_lft_param( param_name ); - else - ret.add_ty_param( AST::TypeParam( param_name ) ); - auto param_ty = TypeRef(lex.getPosition(), param_name); + (void)attrs; // TODO: Attributes on generic params - if( GET_TOK(tok, lex) == TOK_COLON ) + if( tok.type() == TOK_IDENT ) { - if( is_lifetime ) + ::std::string param_name = tok.str(); + ret.add_ty_param( AST::TypeParam( param_name ) ); + + auto param_ty = TypeRef(lex.getPosition(), param_name); + if( GET_TOK(tok, lex) == TOK_COLON ) + { + Parse_TypeBound(lex, ret, param_ty); + GET_TOK(tok, lex); + } + + if( tok.type() == TOK_EQUAL ) + { + ret.ty_params().back().setDefault( Parse_Type(lex) ); + GET_TOK(tok, lex); + } + } + else if( tok.type() == TOK_LIFETIME ) + { + ::std::string param_name = tok.str(); + ret.add_lft_param( param_name ); + if( GET_TOK(tok, lex) == TOK_COLON ) { do { GET_CHECK_TOK(tok, lex, TOK_LIFETIME); ret.add_bound(AST::GenericBound::make_Lifetime( {param_name, tok.str()} )); } while( GET_TOK(tok, lex) == TOK_PLUS ); } - else - { - Parse_TypeBound(lex, ret, param_ty); - GET_TOK(tok, lex); - } } - - if( !is_lifetime && tok.type() == TOK_EQUAL ) + else { - ret.ty_params().back().setDefault( Parse_Type(lex) ); - GET_TOK(tok, lex); + throw ParseError::Unexpected(lex, tok, {TOK_IDENT, TOK_LIFETIME}); } } while( tok.type() == TOK_COMMA ); PUTBACK(tok, lex); diff --git a/src/parse/types.cpp b/src/parse/types.cpp index 4b0fe46d..fabb13bc 100644 --- a/src/parse/types.cpp +++ b/src/parse/types.cpp @@ -67,13 +67,7 @@ TypeRef Parse_Type_Int(TokenStream& lex, bool allow_trait_list) } // case TOK_RWORD_FOR: { - GET_CHECK_TOK(tok, lex, TOK_LT); - ::std::vector<::std::string> hrls; - do { - GET_CHECK_TOK(tok, lex, TOK_LIFETIME); - hrls.push_back( mv$(tok.str()) ); - } while( GET_TOK(tok, lex) == TOK_COMMA ); - CHECK_TOK(tok, TOK_GT); + auto hrls = Parse_HRB(lex); switch(LOOK_AHEAD(lex)) { case TOK_RWORD_UNSAFE: -- cgit v1.2.3