From 967ccfbfd50e0ce0aec985bcb394e34787450f75 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 9 Oct 2016 10:27:50 +0800 Subject: AST - Remove free MacroInvocation lists --- src/ast/ast.cpp | 5 +- src/ast/ast.hpp | 9 +-- src/ast/macro.hpp | 10 +--- src/dump_as_rust.cpp | 3 + src/expand/cfg.cpp | 18 ------ src/expand/macro_rules.cpp | 37 ++++++++++++ src/expand/mod.cpp | 125 +++++++++++---------------------------- src/hir/from_ast.cpp | 7 ++- src/include/synext_decorator.hpp | 5 -- src/main.cpp | 2 + src/parse/common.hpp | 2 +- src/parse/pattern.cpp | 2 +- src/parse/root.cpp | 44 +++++++------- src/parse/types.cpp | 2 +- src/resolve/absolute.cpp | 2 +- 15 files changed, 116 insertions(+), 157 deletions(-) (limited to 'src') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 157461c1..25a1c82f 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -206,6 +206,9 @@ void Impl::add_static(bool is_public, bool is_specialisable, ::std::string name, { m_items.push_back( ImplItem { is_public, is_specialisable, mv$(name), box$( Item::make_Static(mv$(v)) ) } ); } +void Impl::add_macro_invocation(MacroInvocation item) { + m_items.push_back( ImplItem { false, false, "", box$( Item::make_MacroInv(mv$(item)) ) } ); +} bool Impl::has_named_item(const ::std::string& name) const { @@ -243,7 +246,7 @@ bool Impl::has_named_item(const ::std::string& name) const MacroInvocation MacroInvocation::clone() const { - return MacroInvocation(m_span, m_attrs.clone(), m_macro_name, m_ident, m_input.clone()); + return MacroInvocation(m_span, m_macro_name, m_ident, m_input.clone()); } diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 866dcf6e..e65ba2c2 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -416,8 +416,6 @@ private: //NamedList m_statics; public: - ::std::vector m_macro_invocations; - Impl() {} Impl(Impl&&) /*noexcept*/ = default; Impl(ImplDef def): @@ -428,9 +426,7 @@ public: void add_function(bool is_public, bool is_specialisable, ::std::string name, Function fcn); void add_type(bool is_public, bool is_specialisable, ::std::string name, TypeRef type); void add_static(bool is_public, bool is_specialisable, ::std::string name, Static v); - void add_macro_invocation( MacroInvocation inv ) { - m_macro_invocations.push_back( mv$(inv) ); - } + void add_macro_invocation( MacroInvocation inv ); const ImplDef& def() const { return m_def; } ImplDef& def() { return m_def; } @@ -491,8 +487,6 @@ class Module // Module-level items /// General items ::std::vector> m_items; - /// Macro invocations - ::std::vector m_macro_invocations; /// Impl blocks ::std::vector m_impls; @@ -576,7 +570,6 @@ public: const ::std::vector< ::std::shared_ptr >& anon_mods() const { return m_anon_modules; } - ::std::vector& macro_invs() { return m_macro_invocations; } NamedList& macros() { return m_macros; } const NamedList& macros() const { return m_macros; } const ::std::vector > macro_imports_res() const { return m_macro_import_res; } diff --git a/src/ast/macro.hpp b/src/ast/macro.hpp index e68d85ac..9ae58fb9 100644 --- a/src/ast/macro.hpp +++ b/src/ast/macro.hpp @@ -12,7 +12,6 @@ class MacroInvocation { Span m_span; - ::AST::MetaItems m_attrs; ::std::string m_macro_name; ::std::string m_ident; TokenTree m_input; @@ -26,9 +25,8 @@ public: { } - MacroInvocation(Span span, MetaItems attrs, ::std::string macro, ::std::string ident, TokenTree input): + MacroInvocation(Span span, ::std::string macro, ::std::string ident, TokenTree input): m_span( mv$(span) ), - m_attrs( mv$(attrs) ), m_macro_name( mv$(macro) ), m_ident( mv$(ident) ), m_input( mv$(input) ) @@ -42,9 +40,6 @@ public: m_ident = ""; m_input = TokenTree(); } - - ::AST::MetaItems& attrs() { return m_attrs; } - const ::AST::MetaItems& attrs() const { return m_attrs; } const Span& span() const { return m_span; } const ::std::string& name() const { return m_macro_name; } @@ -54,9 +49,6 @@ public: TokenTree& input_tt() { return m_input; } friend ::std::ostream& operator<<(::std::ostream& os, const MacroInvocation& x) { - os << x.m_attrs; - if(x.m_attrs.m_items.size() > 0) - os << " "; os << x.m_macro_name << "! " << x.m_ident << x.m_input; return os; } diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp index db44ccbc..b8443845 100644 --- a/src/dump_as_rust.cpp +++ b/src/dump_as_rust.cpp @@ -712,6 +712,9 @@ void RustPrinter::handle_module(const AST::Module& mod) (None, // Ignore, it's been deleted by #[cfg] ), + (MacroInv, + // TODO: Dump macro invocations + ), (Type, m_os << indent() << "type " << it.name << " = " << e.type() << ";\n"; ), diff --git a/src/expand/cfg.cpp b/src/expand/cfg.cpp index 5e6da051..e4b5c49c 100644 --- a/src/expand/cfg.cpp +++ b/src/expand/cfg.cpp @@ -108,24 +108,6 @@ class CCfgHandler: AttrStage stage() const override { return AttrStage::Pre; } - void handle(const Span& sp, const AST::MetaItem& mi, ::AST::Crate& crate, AST::MacroInvocation& mac) const override { - DEBUG("#[cfg] mac! - " << mi); - if( check_cfg(sp, mi) ) { - // Leave as is - } - else { - mac.clear(); - } - } - void handle(const Span& sp, const AST::MetaItem& mi, ::AST::Crate& crate, AST::UseStmt& use) const override { - DEBUG("#[cfg] use - " << mi); - if( check_cfg(sp, mi) ) { - // Leave as is - } - else { - use.path = AST::Path(); - } - } void handle(const Span& sp, const AST::MetaItem& mi, ::AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item&i) const override { TRACE_FUNCTION_FR("#[cfg] item - " << mi, (i.is_None() ? "Deleted" : "")); if( check_cfg(sp, mi) ) { diff --git a/src/expand/macro_rules.cpp b/src/expand/macro_rules.cpp index 09cf7dd7..c1d00c70 100644 --- a/src/expand/macro_rules.cpp +++ b/src/expand/macro_rules.cpp @@ -97,6 +97,41 @@ class CMacroUseHandler: }; +class CMacroExportHandler: + public ExpandDecorator +{ + AttrStage stage() const override { return AttrStage::Post; } + + void handle(const Span& sp, const AST::MetaItem& mi, ::AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item& i) const override + { + if( i.is_MacroInv() ) { + const auto& mac = i.as_MacroInv(); + if( mac.name() != "macro_rules" ) { + ERROR(sp, E0000, "#[macro_export] is only valid on macro_rules!"); + } + + //TODO(sp, "macro_export on Item MacroInv"); + } + else { + ERROR(sp, E0000, "Use of #[macro_export] on non-macro - " << i.tag_str()); + } + } +}; + +class CMacroReexportHandler: + public ExpandDecorator +{ + AttrStage stage() const override { return AttrStage::Post; } + void handle(const Span& sp, const AST::MetaItem& mi, ::AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item& i) const override + { + if( i.is_Crate() ) { + } + else { + ERROR(sp, E0000, "Use of #[macro_reexport] on non-crate - " << i.tag_str()); + } + } +}; + ::std::unique_ptr Macro_Invoke(const char* name, const MacroRules& rules, TokenTree tt, AST::Module& mod) { return Macro_InvokeRules(name, rules, mv$(tt), mod); @@ -105,4 +140,6 @@ class CMacroUseHandler: STATIC_MACRO("macro_rules", CMacroRulesExpander); STATIC_DECORATOR("macro_use", CMacroUseHandler); +STATIC_DECORATOR("macro_export", CMacroExportHandler); +STATIC_DECORATOR("macro_reexport", CMacroReexportHandler); diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 5696ccfe..7c3206dd 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -591,39 +591,10 @@ void Expand_Impl(::AST::Crate& crate, LList modstack, ::AST: Expand_Type(crate, modstack, mod, impl.def().type()); //Expand_Type(crate, modstack, mod, impl.def().trait()); - // - Macro invocation - for(unsigned int i = 0; i < impl.m_macro_invocations.size(); i ++ ) - { - auto& mi = impl.m_macro_invocations[i]; - if( mi.name() != "" ) - { - TRACE_FUNCTION_F("Macro invoke " << mi.name()); - // Move out of the module to avoid invalidation if a new macro invocation is added - auto mi_owned = mv$(mi); - - auto ttl = Expand_Macro(crate, modstack, mod, mi_owned); - - if( ! ttl.get() ) - { - // - Return ownership to the list - mod.macro_invs()[i] = mv$(mi_owned); - } - else - { - // Re-parse tt - assert(ttl.get()); - while( ttl->lookahead(0) != TOK_EOF ) - { - Parse_Impl_Item(*ttl, impl); - } - // - Any new macro invocations ends up at the end of the list and handled - } - } - } - DEBUG("> Items"); - for( auto& i : impl.items() ) + for( unsigned int idx = 0; idx < impl.items().size(); idx ++ ) { + auto& i = impl.items()[idx]; DEBUG(" - " << i.name << " :: " << i.data->attrs); // TODO: Make a path from the impl definition? Requires having the impl def resolved to be correct @@ -638,6 +609,28 @@ void Expand_Impl(::AST::Crate& crate, LList modstack, ::AST: throw ::std::runtime_error("BUG: Unknown item type in impl block"); ), (None, ), + (MacroInv, + if( e.name() != "" ) + { + TRACE_FUNCTION_F("Macro invoke " << e.name()); + // Move out of the module to avoid invalidation if a new macro invocation is added + auto mi_owned = mv$(e); + + auto ttl = Expand_Macro(crate, modstack, mod, mi_owned); + + if( ttl.get() ) + { + // Re-parse tt + while( ttl->lookahead(0) != TOK_EOF ) + { + Parse_Impl_Item(*ttl, impl); + } + // - Any new macro invocations ends up at the end of the list and handled + } + // Move back in (using the index, as the old pointr may be invalid) + impl.items()[idx].data->as_MacroInv() = mv$(mi_owned); + } + ), (Function, for(auto& arg : e.args()) { Expand_Pattern(crate, modstack, mod, arg.first); @@ -654,9 +647,14 @@ void Expand_Impl(::AST::Crate& crate, LList modstack, ::AST: ) ) - Expand_Attrs(attrs, AttrStage::Post, crate, AST::Path(), mod, *i.data); - if( i.data->attrs.m_items.size() == 0 ) - i.data->attrs = mv$(attrs); + // Run post-expansion decorators and restore attributes + { + auto& i = impl.items()[idx]; + Expand_Attrs(attrs, AttrStage::Post, crate, AST::Path(), mod, *i.data); + // TODO: How would this be populated? It got moved out? + if( i.data->attrs.m_items.size() == 0 ) + i.data->attrs = mv$(attrs); + } } Expand_Attrs(impl.def().attrs(), AttrStage::Post, crate, mod, impl.def()); @@ -690,45 +688,6 @@ void Expand_Mod(::AST::Crate& crate, LList modstack, ::AST:: } } - // TODO: Have the AST representation of a module include the definition order, - // mixing macro invocations, general items, use statements, and `impl`s - - // 1. Macros first - //for( auto& mi : mod.macro_invs() ) - for(unsigned int i = 0; i < mod.macro_invs().size(); i ++ ) - { - auto& mi = mod.macro_invs()[i]; - - if( mi.name() != "" ) - { - TRACE_FUNCTION_F("Macro invoke " << mi.name()); - // Move out of the module to avoid invalidation if a new macro invocation is added - auto mi_owned = mv$(mi); - - auto& attrs = mi_owned.attrs(); - Expand_Attrs(attrs, AttrStage::Pre, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, mi_owned); }); - - auto ttl = Expand_Macro(crate, modstack, mod, mi_owned); - - if( ! ttl.get() ) - { - Expand_Attrs(attrs, AttrStage::Post, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, mi_owned); }); - // - Return ownership to the list - mod.macro_invs()[i] = mv$(mi_owned); - } - else - { - // Re-parse tt - assert(ttl.get()); - DEBUG("-- Parsing as mod items (legacy)"); - Parse_ModRoot_Items(*ttl, mod); - // - Any new macro invocations ends up at the end of the list and handled - } - - } - } - - // 3. General items DEBUG("Items"); for( unsigned int idx = 0; idx < mod.items().size(); idx ++ ) { @@ -750,31 +709,17 @@ void Expand_Mod(::AST::Crate& crate, LList modstack, ::AST:: TRACE_FUNCTION_F("Macro invoke " << mi_owned.name()); - auto& attrs = mi_owned.attrs(); - Expand_Attrs(attrs, AttrStage::Pre, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, mi_owned); }); - auto ttl = Expand_Macro(crate, modstack, mod, mi_owned); + assert( mi_owned.name() != ""); - if( ! ttl.get() ) - { - Expand_Attrs(attrs, AttrStage::Post, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, mi_owned); }); - // - Return ownership to the list - if( mi_owned.name() == "" ) { - mod.items()[idx].data = AST::Item(); - } - else { - mod.items()[idx].data = AST::Item( mv$(mi_owned) ); - } - } - else + if( ttl.get() ) { // Re-parse tt assert(ttl.get()); DEBUG("-- Parsing as mod items"); Parse_ModRoot_Items(*ttl, mod); - // - Any new macro invocations ends up at the end of the list and handled - mod.items()[idx].data = AST::Item(); } + mod.items()[idx].data.as_MacroInv() = mv$(mi_owned); ), (Use, // No inner expand. diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index c62cc6b9..452dca5e 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1042,7 +1042,8 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H (None, ), (MacroInv, - BUG(sp, "Stray macro invocation in " << path); + // Valid. + //BUG(sp, "Stray macro invocation in " << path); ), (ExternBlock, if( e.items().size() > 0 ) @@ -1179,6 +1180,8 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat ), (None, ), + (MacroInv, + ), // TODO: Associated constants (Type, DEBUG("- type " << item.name); @@ -1236,6 +1239,8 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat ), (None, ), + (MacroInv, + ), (Function, methods.insert( ::std::make_pair(item.name, ::HIR::TypeImpl::VisImplEnt< ::HIR::Function> { item.is_pub, item.is_specialisable, LowerHIR_Function(item_path, e, type) } ) ); ) diff --git a/src/include/synext_decorator.hpp b/src/include/synext_decorator.hpp index 2be7924d..0404889f 100644 --- a/src/include/synext_decorator.hpp +++ b/src/include/synext_decorator.hpp @@ -21,14 +21,11 @@ namespace AST { class Module; class Item; - class UseStmt; class Expr; class ExprNode; struct ExprNode_Match_Arm; - class MacroInvocation; - class ImplDef; } @@ -45,8 +42,6 @@ public: virtual AttrStage stage() const = 0; virtual void handle(const Span& sp, const AST::MetaItem& mi, AST::Crate& crate) const { unexpected(sp, mi, "crate"); } - virtual void handle(const Span& sp, const AST::MetaItem& mi, AST::Crate& crate, AST::MacroInvocation& mac) const { unexpected(sp, mi, "macro invocation"); } - virtual void handle(const Span& sp, const AST::MetaItem& mi, AST::Crate& crate, AST::UseStmt& use) const { unexpected(sp, mi, "use statement"); } virtual void handle(const Span& sp, const AST::MetaItem& mi, AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item&i) const { unexpected(sp, mi, "item"); } // NOTE: To delete, set the type to `_` virtual void handle(const Span& sp, const AST::MetaItem& mi, AST::Crate& crate, const AST::Module& mod, AST::ImplDef& impl) const { unexpected(sp, mi, "impl"); } diff --git a/src/main.cpp b/src/main.cpp index cd494d6f..fbb4bfbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -450,6 +450,8 @@ ProgramParams::ProgramParams(int argc, char *argv[]) arg = argv[++i]; if( strcmp(arg, "parse") == 0 ) this->last_stage = STAGE_PARSE; + else if( strcmp(arg, "resolve") == 0 ) + this->last_stage = STAGE_RESOLVE; else { ::std::cerr << "Unknown argument to --stop-after : '" << arg << "'" << ::std::endl; exit(1); diff --git a/src/parse/common.hpp b/src/parse/common.hpp index 54f9eb16..aa6e8c3d 100644 --- a/src/parse/common.hpp +++ b/src/parse/common.hpp @@ -40,7 +40,7 @@ extern AST::PathParams Parse_Path_GenericList(TokenStream& lex); extern AST::MetaItem Parse_MetaItem(TokenStream& lex); -extern ::AST::MacroInvocation Parse_MacroInvocation(ProtoSpan ps, ::AST::MetaItems meta_items, ::std::string name, 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); extern AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable); diff --git a/src/parse/pattern.cpp b/src/parse/pattern.cpp index 7b16a10b..2b83d0f3 100644 --- a/src/parse/pattern.cpp +++ b/src/parse/pattern.cpp @@ -44,7 +44,7 @@ AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable) if( tok.type() == TOK_MACRO ) { - return AST::Pattern( AST::Pattern::TagMacro(), box$(Parse_MacroInvocation(ps, AST::MetaItems(), tok.str(), lex))); + return AST::Pattern( AST::Pattern::TagMacro(), box$(Parse_MacroInvocation(ps, tok.str(), lex))); } if( tok.type() == TOK_INTERPOLATED_PATTERN ) { diff --git a/src/parse/root.cpp b/src/parse/root.cpp index ce3c9443..e9bd4855 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -591,7 +591,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items) auto ps = lex.start_span(); if( tok.type() == TOK_MACRO ) { - auto inv = Parse_MacroInvocation( ps, AST::MetaItems(), mv$(tok.str()), lex ); + auto inv = Parse_MacroInvocation( ps, mv$(tok.str()), lex ); // - Silently consume ';' after the macro if( GET_TOK(tok, lex) != TOK_SEMICOLON ) PUTBACK(tok, lex); @@ -963,7 +963,7 @@ void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool i auto ps = lex.start_span(); if( tok.type() == TOK_MACRO ) { - impl.add_macro_invocation( Parse_MacroInvocation( ps, AST::MetaItems(), mv$(tok.str()), lex ) ); + impl.add_macro_invocation( Parse_MacroInvocation( ps, mv$(tok.str()), lex ) ); // - Silently consume ';' after the macro if( GET_TOK(tok, lex) != TOK_SEMICOLON ) PUTBACK(tok, lex); @@ -1281,7 +1281,7 @@ void Parse_Use(TokenStream& lex, ::std::functionspan, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), (NegImpl, BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());), -- cgit v1.2.3