From d1d84ced588b40bdec67ee8bdb184a31d3ae9e7d Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 27 Feb 2016 10:06:54 +0800 Subject: Parse/impl - Handle macro invocations --- src/ast/ast.hpp | 72 ++++++++++++++++++++++++++++-------------------------- src/parse/root.cpp | 33 +++++++++---------------- 2 files changed, 50 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 4165b34d..2aea5ac1 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -214,6 +214,40 @@ using ItemList = ::std::vector >; typedef Item StructItem; class Crate; +class MacroInvocation: + public Serialisable +{ + MetaItems m_attrs; + ::std::string m_macro_name; + ::std::string m_ident; + TokenTree m_input; +public: + MacroInvocation() + { + } + + MacroInvocation(MetaItems attrs, ::std::string macro, ::std::string ident, TokenTree input): + m_attrs( mv$(attrs) ), + m_macro_name( mv$(macro) ), + m_ident( mv$(ident) ), + m_input( mv$(input) ) + { + } + + static ::std::unique_ptr from_deserialiser(Deserialiser& s) { + auto i = new MacroInvocation; + s.item( *i ); + return ::std::unique_ptr(i); + } + + SERIALISABLE_PROTOTYPES(); + + friend ::std::ostream& operator<<(::std::ostream& os, const MacroInvocation& x) { + os << x.m_attrs << x.m_macro_name << "! " << x.m_ident << x.m_input; + return os; + } +}; + class TypeAlias: public Serialisable { @@ -511,6 +545,7 @@ class Impl: ItemList m_types; ItemList m_functions; ItemList m_statics; + ::std::vector m_macro_invocations; ::std::vector< ::std::pair< ::std::vector, Impl > > m_concrete_impls; public: @@ -529,6 +564,9 @@ public: void add_static(bool is_public, ::std::string name, Static v) { m_statics.push_back( Item( mv$(name), mv$(v), is_public ) ); } + void add_macro_invocation( MacroInvocation inv ) { + m_macro_invocations.push_back( mv$(inv) ); + } const ImplDef& def() const { return m_def; } const ItemList& functions() const { return m_functions; } @@ -558,40 +596,6 @@ class Module; typedef void fcn_visitor_t(const AST::Crate& crate, const AST::Module& mod, Function& fcn); -class MacroInvocation: - public Serialisable -{ - MetaItems m_attrs; - ::std::string m_macro_name; - ::std::string m_ident; - TokenTree m_input; -public: - MacroInvocation() - { - } - - MacroInvocation(MetaItems attrs, ::std::string macro, ::std::string ident, TokenTree input): - m_attrs( mv$(attrs) ), - m_macro_name( mv$(macro) ), - m_ident( mv$(ident) ), - m_input( mv$(input) ) - { - } - - static ::std::unique_ptr from_deserialiser(Deserialiser& s) { - auto i = new MacroInvocation; - s.item( *i ); - return ::std::unique_ptr(i); - } - - SERIALISABLE_PROTOTYPES(); - - friend ::std::ostream& operator<<(::std::ostream& os, const MacroInvocation& x) { - os << x.m_attrs << x.m_macro_name << "! " << x.m_ident << x.m_input; - return os; - } -}; - /// Representation of a parsed (and being converted) function class Module: public Serialisable diff --git a/src/parse/root.cpp b/src/parse/root.cpp index c8fabc01..74d919c9 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -894,8 +894,18 @@ void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool i // A sequence of method implementations while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE ) { - lex.putback(tok); - Parse_Impl_Item(lex, impl); + if( tok.type() == TOK_MACRO ) + { + impl.add_macro_invocation( Parse_MacroInvocation( AST::MetaItems(), mv$(tok.str()), lex ) ); + // - Silently consume ';' after the macro + if( GET_TOK(tok, lex) != TOK_SEMICOLON ) + lex.putback(tok); + } + else + { + lex.putback(tok); + Parse_Impl_Item(lex, impl); + } } mod.add_impl( ::std::move(impl) ); @@ -930,25 +940,6 @@ 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_RWORD_TYPE: { GET_CHECK_TOK(tok, lex, TOK_IDENT); ::std::string name = tok.str(); -- cgit v1.2.3