From cf87314dde3af9468f3e24e29191412e8a2d19f7 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 18 Feb 2016 19:30:27 +1100 Subject: (semibroken) Defer macro expansion --- src/parse/expr.cpp | 40 +++++++++++---------------------- src/parse/lex.cpp | 6 +++++ src/parse/root.cpp | 59 ++++++++++++++++++++++++------------------------- src/parse/tokentree.hpp | 5 ++++- 4 files changed, 52 insertions(+), 58 deletions(-) (limited to 'src/parse') diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 5c7bfda5..47fe444a 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -1141,34 +1141,20 @@ ExprNodeP Parse_ExprVal(TokenStream& lex) } } throw ParseError::BugCheck(lex, "Array literal fell"); - case TOK_MACRO: - if( CHECK_PARSE_FLAG(lex, no_expand_macros) ) - { - ::std::string name = tok.str(); - TokenTree tt = Parse_TT(lex, true); - if( tt.is_token() ) { - throw ParseError::Unexpected(lex, tt.tok()); - } - return NEWNODE(AST::ExprNode_Macro, ::std::move(name), ::std::move(tt)); + case TOK_MACRO: { + ::std::string name = tok.str(); + ::std::string ident; + if( GET_TOK(tok, lex) == TOK_IDENT ) { + ident = mv$(tok.str()); } - else - { - TokenTree tt = Parse_TT(lex, true); - if( tt.is_token() ) { - throw ParseError::Unexpected(lex, tt.tok()); - } - ::std::string name = tok.str(); - - if( name == "format_args" ) - { - TTStream slex(tt); - return Parse_FormatArgs(slex); - } - else - { - auto expanded_macro = Macro_Invoke(lex, name, tt); - return Parse_Expr0(*expanded_macro); - } + else { + lex.putback(tok); + } + TokenTree tt = Parse_TT(lex, true); + if( tt.is_token() ) { + throw ParseError::Unexpected(lex, tt.tok()); + } + return NEWNODE(AST::ExprNode_Macro, mv$(name), mv$(ident), mv$(tt)); } default: throw ParseError::Unexpected(lex, tok); diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index a3187cda..cb97022d 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -1042,3 +1042,9 @@ Span TokenStream::end_span(ProtoSpan ps) const ); } + +SERIALISE_TYPE_A(TokenTree::, "TokenTree", { + s.item(m_tok); + s.item(m_subtrees); +}) + diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 5ba66dbc..93b360f1 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -829,25 +829,25 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) ::std::string abi = "rust"; switch(tok.type()) { - case TOK_MACRO: - { - TokenTree tt = Parse_TT(lex, true); - if( tt.is_token() ) { - DEBUG("TT was a single token (not a sub-tree)"); - throw ParseError::Unexpected(lex, tt.tok()); - } - - auto expanded_macro = Macro_Invoke(lex, tok.str().c_str(), tt); - auto& lex = *expanded_macro; - while( GET_TOK(tok, lex) != TOK_EOF ) - { - lex.putback(tok); - Parse_Impl_Item(lex, impl); - } - } - if(GET_TOK(tok, lex) != TOK_SEMICOLON) - lex.putback(tok); - break; + //case TOK_MACRO: + // { + // TokenTree tt = Parse_TT(lex, true); + // if( tt.is_token() ) { + // DEBUG("TT was a single token (not a sub-tree)"); + // throw ParseError::Unexpected(lex, tt.tok()); + // } + // + // auto expanded_macro = Macro_Invoke(lex, tok.str().c_str(), tt); + // auto& lex = *expanded_macro; + // while( GET_TOK(tok, lex) != TOK_EOF ) + // { + // lex.putback(tok); + // Parse_Impl_Item(lex, impl); + // } + // } + // if(GET_TOK(tok, lex) != TOK_SEMICOLON) + // lex.putback(tok); + // break; case TOK_RWORD_TYPE: { GET_CHECK_TOK(tok, lex, TOK_IDENT); ::std::string name = tok.str(); @@ -1308,24 +1308,23 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod, // root-level macros if( GET_TOK(tok, lex) == TOK_MACRO ) { + ::std::string name = mv$(tok.str()); // `macro_rules! ...` - if( tok.str() == "macro_rules" ) + if( name == "macro_rules" ) { Parse_MacroRules(lex, mod, mv$(meta_items)); } else { - DEBUG("Invoke macro '"< m_subtrees; @@ -38,6 +39,8 @@ public: else return os << "TokenTree([" << tt.m_subtrees << "])"; } + + SERIALISABLE_PROTOTYPES(); }; class TTStream: -- cgit v1.2.3