From 3a4d71443bfcdbba1d14c3d6c7088eaf24e479b8 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 22 May 2015 22:39:37 +0800 Subject: Restructure macro expansion to correctly fit rustc's model --- src/parse/expr.cpp | 9 +++++++++ src/parse/root.cpp | 11 ++++++++++- src/parse/tokentree.hpp | 1 + src/parse/types.cpp | 37 ++++++++++++++++++++++++++++--------- 4 files changed, 48 insertions(+), 10 deletions(-) (limited to 'src/parse') diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index b9a3d003..12aa3d3a 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -640,6 +640,7 @@ bool Parse_IsTokValue(eTokenType tok_type) case TOK_MACRO: + case TOK_PIPE: case TOK_EXCLAM: case TOK_DASH: case TOK_STAR: @@ -1297,3 +1298,11 @@ TokenTree Parse_TT_Block(TokenStream& lex) throw ParseError::Todo("Parse_TT_Block"); } +TokenTree Parse_TT_Meta(TokenStream& lex) +{ + TRACE_FUNCTION; + TTLexer wlex(lex); + SET_PARSE_FLAG(wlex, no_expand_macros); + Parse_MetaItem(wlex); + return wlex.get_output(); +} diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 15268ce9..eeeafb0e 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -395,6 +395,13 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems meta_items) break; } CHECK_TOK(tok, TOK_PAREN_CLOSE); + + if(LOOK_AHEAD(lex) == TOK_RWORD_WHERE) + { + GET_TOK(tok, lex); + Parse_WhereClause(lex, params); + } + // TODO: Where block GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); if( refs.size() == 0 ) throw ParseError::Generic(lex, "Use 'struct Name;' instead of 'struct Name();' ... ning-nong"); @@ -1008,8 +1015,10 @@ void Parse_Use(TokenStream& lex, ::std::function ret.push_back( MacroPatEnt(name, MacroPatEnt::PAT_EXPR) ); else if( type == "ty" ) ret.push_back( MacroPatEnt(name, MacroPatEnt::PAT_TYPE) ); + else if( type == "meta" ) + ret.push_back( MacroPatEnt(name, MacroPatEnt::PAT_META) ); else - throw ParseError::Generic(FMT("Unknown fragment type " << type)); + throw ParseError::Generic(lex, FMT("Unknown fragment type " << type)); break; } case TOK_PAREN_OPEN: if( allow_sub ) diff --git a/src/parse/tokentree.hpp b/src/parse/tokentree.hpp index 34418340..cde35c8c 100644 --- a/src/parse/tokentree.hpp +++ b/src/parse/tokentree.hpp @@ -65,5 +65,6 @@ extern TokenTree Parse_TT_Type(TokenStream& lex); extern TokenTree Parse_TT_Stmt(TokenStream& lex); extern TokenTree Parse_TT_Block(TokenStream& lex); extern TokenTree Parse_TT_Path(TokenStream& lex, bool mode_expr); +extern TokenTree Parse_TT_Meta(TokenStream& lex); #endif // TOKENTREE_HPP_INCLUDED diff --git a/src/parse/types.cpp b/src/parse/types.cpp index 2070a0d2..95076e29 100644 --- a/src/parse/types.cpp +++ b/src/parse/types.cpp @@ -35,7 +35,7 @@ static const struct { // === PROTOTYPES === TypeRef Parse_Type(TokenStream& lex); -TypeRef Parse_Type_Fn(TokenStream& lex, ::std::string abi); +TypeRef Parse_Type_Fn(TokenStream& lex); // === CODE === TypeRef Parse_Type(TokenStream& lex) @@ -52,16 +52,18 @@ TypeRef Parse_Type(TokenStream& lex) // '_' = Wildcard (type inferrence variable) case TOK_UNDERSCORE: return TypeRef(); + // 'unsafe' - An unsafe function type + case TOK_RWORD_UNSAFE: + lex.putback(tok); + return Parse_Type_Fn(lex); // 'extern' - A function type with an ABI - case TOK_RWORD_EXTERN: { - GET_CHECK_TOK(tok, lex, TOK_STRING); - ::std::string abi = tok.str(); - GET_CHECK_TOK(tok, lex, TOK_RWORD_FN); - return Parse_Type_Fn(lex, abi); - } + case TOK_RWORD_EXTERN: + lex.putback(tok); + return Parse_Type_Fn(lex); // 'fn' - Rust function case TOK_RWORD_FN: - return Parse_Type_Fn(lex, ""); + lex.putback(tok); + return Parse_Type_Fn(lex); // '<' - An associated type cast case TOK_LT: lex.putback(tok); @@ -222,11 +224,28 @@ TypeRef Parse_Type(TokenStream& lex) throw ParseError::BugCheck("Reached end of Parse_Type"); } -TypeRef Parse_Type_Fn(TokenStream& lex, ::std::string abi) +TypeRef Parse_Type_Fn(TokenStream& lex) { TRACE_FUNCTION; Token tok; + ::std::string abi = ""; + + GET_TOK(tok, lex); + + if( tok.type() == TOK_RWORD_UNSAFE ) + { + // TODO: Unsafe functions in types + GET_TOK(tok, lex); + } + if( tok.type() == TOK_RWORD_EXTERN ) + { + GET_CHECK_TOK(tok, lex, TOK_STRING); + abi = tok.str(); + GET_TOK(tok, lex); + } + CHECK_TOK(tok, TOK_RWORD_FN); + ::std::vector args; GET_CHECK_TOK(tok, lex, TOK_PAREN_OPEN); while( LOOK_AHEAD(lex) != TOK_PAREN_CLOSE ) -- cgit v1.2.3