diff options
Diffstat (limited to 'src/expand/mod.cpp')
-rw-r--r-- | src/expand/mod.cpp | 287 |
1 files changed, 214 insertions, 73 deletions
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 5d6d3234..53358473 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -41,6 +41,12 @@ void Register_Synext_Macro_Static(MacroDef* def) { g_macros_list = def; } +void Expand_Init() +{ + // TODO: Initialise all macros here. + void Expand_init_assert(); Expand_init_assert(); +} + void ExpandDecorator::unexpected(const Span& sp, const AST::Attribute& mi, const char* loc_str) const { @@ -49,46 +55,67 @@ void ExpandDecorator::unexpected(const Span& sp, const AST::Attribute& mi, const void Expand_Attr(const Span& sp, const ::AST::Attribute& a, AttrStage stage, ::std::function<void(const Span& sp, const ExpandDecorator& d,const ::AST::Attribute& a)> f) { + bool found = false; for( auto& d : g_decorators ) { - if( d.first == a.name() ) { + if( a.name() == d.first ) { DEBUG("#[" << d.first << "] " << (int)d.second->stage() << "-" << (int)stage); if( d.second->stage() == stage ) { f(sp, *d.second, a); + // TODO: Early return? + // TODO: Annotate the attribute as having been handled } + found = true; } } + if( !found ) { + // TODO: Create no-op handlers for a whole heap of attributes + //WARNING(sp, W0000, "Unknown attribute " << a.name()); + } } -void Expand_Attrs(/*const */::AST::AttributeList& attrs, AttrStage stage, ::std::function<void(const Span& sp, const ExpandDecorator& d,const ::AST::Attribute& a)> f) +void Expand_Attrs(const ::AST::AttributeList& attrs, AttrStage stage, ::std::function<void(const Span& sp, const ExpandDecorator& d,const ::AST::Attribute& a)> f) { for( auto& a : attrs.m_items ) { + Expand_Attr(a.span(), a, stage, f); + } +} +void Expand_Attrs_CfgAttr(AST::AttributeList& attrs) +{ + for(auto it = attrs.m_items.begin(); it != attrs.m_items.end(); ) + { + auto& a = *it; if( a.name() == "cfg_attr" ) { if( check_cfg(a.span(), a.items().at(0)) ) { - // Wait? Why move? auto inner_attr = mv$(a.items().at(1)); - Expand_Attr(inner_attr.span(), inner_attr, stage, f); a = mv$(inner_attr); + ++ it; } else { + it = attrs.m_items.erase(it); } } else { - Expand_Attr(a.span(), a, stage, f); + ++ it; } } } -void Expand_Attrs(::AST::AttributeList& attrs, AttrStage stage, ::AST::Crate& crate, const ::AST::Path& path, ::AST::Module& mod, ::AST::Item& item) +void Expand_Attrs(const ::AST::AttributeList& attrs, AttrStage stage, ::AST::Crate& crate, const ::AST::Path& path, ::AST::Module& mod, ::AST::Item& item) { - Expand_Attrs(attrs, stage, [&](const auto& sp, const auto& d, const auto& a){ if(!item.is_None()) d.handle(sp, a, crate, path, mod, item); }); + Expand_Attrs(attrs, stage, [&](const auto& sp, const auto& d, const auto& a){ + if(!item.is_None()) { + // TODO: Pass attributes _after_ this attribute + d.handle(sp, a, crate, path, mod, slice<const AST::Attribute>(&a, &attrs.m_items.back() - &a + 1), item); + } + }); } -void Expand_Attrs(::AST::AttributeList& attrs, AttrStage stage, ::AST::Crate& crate, ::AST::Module& mod, ::AST::ImplDef& impl) +void Expand_Attrs(const ::AST::AttributeList& attrs, AttrStage stage, ::AST::Crate& crate, ::AST::Module& mod, ::AST::ImplDef& impl) { Expand_Attrs(attrs, stage, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, mod, impl); }); } -::std::unique_ptr<TokenStream> Expand_Macro( +::std::unique_ptr<TokenStream> Expand_Macro_Inner( const ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Module& mod, - Span mi_span, const ::std::string& name, const ::std::string& input_ident, TokenTree& input_tt + Span mi_span, const RcString& name, const RcString& input_ident, TokenTree& input_tt ) { if( name == "" ) { @@ -99,7 +126,10 @@ void Expand_Attrs(::AST::AttributeList& attrs, AttrStage stage, ::AST::Crate& c { if( name == m.first ) { - auto e = m.second->expand(mi_span, crate, input_ident, input_tt, mod); + auto e = input_ident == "" + ? m.second->expand(mi_span, crate, input_tt, mod) + : m.second->expand_ident(mi_span, crate, input_ident, input_tt, mod) + ; return e; } } @@ -144,6 +174,17 @@ void Expand_Attrs(::AST::AttributeList& attrs, AttrStage stage, ::AST::Crate& c // Error - Unknown macro name ERROR(mi_span, E0000, "Unknown macro '" << name << "'"); } +::std::unique_ptr<TokenStream> Expand_Macro( + const ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Module& mod, + Span mi_span, const RcString& name, const RcString& input_ident, TokenTree& input_tt + ) +{ + auto rv = Expand_Macro_Inner(crate, modstack, mod, mi_span, name, input_ident, input_tt); + assert(rv); + rv->parse_state().module = &mod; + rv->parse_state().crate = &crate; + return rv; +} ::std::unique_ptr<TokenStream> Expand_Macro(const ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Module& mod, ::AST::MacroInvocation& mi) { return Expand_Macro(crate, modstack, mod, mi.span(), mi.name(), mi.input_ident(), mi.input_tt()); @@ -330,6 +371,10 @@ struct CExpandExpr: LList<const AST::Module*> modstack; ::std::unique_ptr<::AST::ExprNode> replacement; + // Stack of `try { ... }` blocks (the string is the loop label for the desugaring) + ::std::vector<RcString> m_try_stack; + unsigned m_try_index = 0; + AST::ExprNode_Block* current_block = nullptr; CExpandExpr(::AST::Crate& crate, LList<const AST::Module*> ms): @@ -346,6 +391,7 @@ struct CExpandExpr: if(cnode.get()) { auto attrs = mv$(cnode->attrs()); + Expand_Attrs_CfgAttr(attrs); Expand_Attrs(attrs, AttrStage::Pre, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, this->crate, cnode); }); if(cnode.get()) cnode->attrs() = mv$(attrs); @@ -494,6 +540,7 @@ struct CExpandExpr: if( auto* node_mac = dynamic_cast<::AST::ExprNode_Macro*>(it->get()) ) { + Expand_Attrs_CfgAttr( (*it)->attrs() ); Expand_Attrs((*it)->attrs(), AttrStage::Pre, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, this->crate, *it); }); if( !it->get() ) { it = node.m_nodes.erase( it ); @@ -530,6 +577,25 @@ struct CExpandExpr: this->modstack = mv$(prev_modstack); } + void visit(::AST::ExprNode_Try& node) override { + // Desugar into + // ``` + // loop '#tryNNN { + // break '#tryNNN { ... } + // } + // ``` + // NOTE: MIR lowering and HIR typecheck need to know to skip these (OR resolve should handle naming all loop blocks) + m_try_stack.push_back(RcString::new_interned(FMT("#try" << m_try_index++))); + this->visit_nodelete(node, node.m_inner); + auto loop_name = mv$(m_try_stack.back()); + m_try_stack.pop_back(); + + auto core_crate = (crate.m_load_std == ::AST::Crate::LOAD_NONE ? "" : "core"); + auto path_Ok = ::AST::Path(core_crate, {::AST::PathNode("result"), ::AST::PathNode("Result"), ::AST::PathNode("Ok")}); + auto ok_node = ::AST::ExprNodeP(new ::AST::ExprNode_CallPath( mv$(path_Ok), ::make_vec1(mv$(node.m_inner)) )); + auto break_node = AST::ExprNodeP(new AST::ExprNode_Flow(AST::ExprNode_Flow::BREAK, loop_name, mv$(ok_node))); + this->replacement = AST::ExprNodeP(new AST::ExprNode_Loop(loop_name, mv$(break_node))); + } void visit(::AST::ExprNode_Asm& node) override { for(auto& v : node.m_output) this->visit_nodelete(node, v.value); @@ -627,6 +693,7 @@ struct CExpandExpr: this->visit_nodelete(node, node.m_val); for(auto& arm : node.m_arms) { + Expand_Attrs_CfgAttr( arm.m_attrs ); Expand_Attrs(arm.m_attrs, AttrStage::Pre , [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, arm); }); if( arm.m_patterns.size() == 0 ) continue ; @@ -673,6 +740,7 @@ struct CExpandExpr: this->visit_nodelete(node, node.m_base_value); for(auto& val : node.m_values) { + Expand_Attrs_CfgAttr(val.attrs); Expand_Attrs(val.attrs, AttrStage::Pre , [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, val); }); if( !val.value ) continue ; @@ -755,6 +823,7 @@ struct CExpandExpr: case ::AST::ExprNode_BinOp::RANGE_INC: { // NOTE: Not language items auto core_crate = (crate.m_load_std == ::AST::Crate::LOAD_NONE ? "" : "core"); + auto path_None = ::AST::Path(core_crate, { ::AST::PathNode("option"), ::AST::PathNode("Option"), ::AST::PathNode("None") }); auto path_RangeInclusive_NonEmpty = ::AST::Path(core_crate, { ::AST::PathNode("ops"), ::AST::PathNode("RangeInclusive") }); auto path_RangeToInclusive = ::AST::Path(core_crate, { ::AST::PathNode("ops"), ::AST::PathNode("RangeToInclusive") }); @@ -763,6 +832,8 @@ struct CExpandExpr: ::AST::ExprNode_StructLiteral::t_values values; values.push_back({ {}, "start", mv$(node.m_left) }); values.push_back({ {}, "end" , mv$(node.m_right) }); + if( TARGETVER_1_29 ) + values.push_back({ {}, "is_empty", ::AST::ExprNodeP(new ::AST::ExprNode_NamedValue(mv$(path_None))) }); replacement.reset( new ::AST::ExprNode_StructLiteral(mv$(path_RangeInclusive_NonEmpty), nullptr, mv$(values)) ); } else @@ -786,12 +857,19 @@ struct CExpandExpr: auto path_Err = ::AST::Path(core_crate, {::AST::PathNode("result"), ::AST::PathNode("Result"), ::AST::PathNode("Err")}); auto path_From = ::AST::Path(core_crate, {::AST::PathNode("convert"), ::AST::PathNode("From")}); path_From.nodes().back().args().m_types.push_back( ::TypeRef(node.span()) ); + // TODO: Lang item (needs lang items enumerated earlier) + //auto it = crate.m_lang_items.find("try"); + //ASSERT_BUG(node.span(), it != crate.m_lang_items.end(), "Can't find the `try` lang item"); + //auto path_Try = it->second; + auto path_Try = ::AST::Path(core_crate, {::AST::PathNode("ops"), ::AST::PathNode("Try")}); + auto path_Try_into_result = ::AST::Path(::AST::Path::TagUfcs(), ::TypeRef(node.span()), path_Try, { ::AST::PathNode("into_result") }); + auto path_Try_from_error = ::AST::Path(::AST::Path::TagUfcs(), ::TypeRef(node.span()), path_Try, { ::AST::PathNode("from_error") }); // Desugars into // ``` - // match `m_value` { + // match `Try::into_result(m_value)` { // Ok(v) => v, - // Err(e) => return Err(From::from(e)), + // Err(e) => return Try::from_error(From::from(e)), // } // ``` @@ -802,15 +880,15 @@ struct CExpandExpr: nullptr, ::AST::ExprNodeP( new ::AST::ExprNode_NamedValue( ::AST::Path(::AST::Path::TagLocal(), "v") ) ) )); - // `Err(e) => return Err(From::from(e)),` + // `Err(e) => return Try::from_error(From::from(e)),` arms.push_back(::AST::ExprNode_Match_Arm( ::make_vec1( ::AST::Pattern(::AST::Pattern::TagNamedTuple(), node.span(), path_Err, ::make_vec1( ::AST::Pattern(::AST::Pattern::TagBind(), node.span(), "e") )) ), nullptr, ::AST::ExprNodeP(new ::AST::ExprNode_Flow( - ::AST::ExprNode_Flow::RETURN, - "", + (m_try_stack.empty() ? ::AST::ExprNode_Flow::RETURN : ::AST::ExprNode_Flow::BREAK), // NOTE: uses `break 'tryblock` instead of return if in a try block. + (m_try_stack.empty() ? RcString("") : m_try_stack.back()), ::AST::ExprNodeP(new ::AST::ExprNode_CallPath( - ::AST::Path(path_Err), + ::AST::Path(path_Try_from_error), ::make_vec1( ::AST::ExprNodeP(new ::AST::ExprNode_CallPath( ::AST::Path(::AST::Path::TagUfcs(), ::TypeRef(node.span()), mv$(path_From), { ::AST::PathNode("from") }), @@ -821,7 +899,13 @@ struct CExpandExpr: )) )); - replacement.reset(new ::AST::ExprNode_Match( mv$(node.m_value), mv$(arms) )); + replacement.reset(new ::AST::ExprNode_Match( + ::AST::ExprNodeP(new AST::ExprNode_CallPath( + mv$(path_Try_into_result), + ::make_vec1( mv$(node.m_value) ) + )), + mv$(arms) + )); } } }; @@ -895,6 +979,7 @@ void Expand_BareExpr(const ::AST::Crate& crate, const AST::Module& mod, ::std::u void Expand_Impl(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Path modpath, ::AST::Module& mod, ::AST::Impl& impl) { TRACE_FUNCTION_F(impl.def()); + Expand_Attrs_CfgAttr(impl.def().attrs()); Expand_Attrs(impl.def().attrs(), AttrStage::Pre, crate, mod, impl.def()); if( impl.def().type().is_wildcard() ) { DEBUG("Deleted"); @@ -909,18 +994,19 @@ void Expand_Impl(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST: for( unsigned int idx = 0; idx < impl.items().size(); idx ++ ) { auto& i = impl.items()[idx]; - DEBUG(" - " << i.name << " :: " << i.data->attrs); + DEBUG(" - " << i.name << " :: " << i.attrs); // TODO: Make a path from the impl definition? Requires having the impl def resolved to be correct // - Does it? the namespace is essentially the same. There may be issues with wherever the path is used though //::AST::Path path = modpath + i.name; - auto attrs = mv$(i.data->attrs); + auto attrs = mv$(i.attrs); + Expand_Attrs_CfgAttr(attrs); Expand_Attrs(attrs, AttrStage::Pre, crate, AST::Path(), mod, *i.data); TU_MATCH_DEF(AST::Item, (*i.data), (e), ( - throw ::std::runtime_error("BUG: Unknown item type in impl block"); + BUG(Span(), "Unknown item type in impl block - " << i.data->tag_str()); ), (None, ), (MacroInv, @@ -970,8 +1056,8 @@ void Expand_Impl(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST: 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); + if( i.attrs.m_items.size() == 0 ) + i.attrs = mv$(attrs); } } @@ -979,6 +1065,7 @@ void Expand_Impl(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST: } void Expand_ImplDef(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Path modpath, ::AST::Module& mod, ::AST::ImplDef& impl_def) { + Expand_Attrs_CfgAttr(impl_def.attrs()); Expand_Attrs(impl_def.attrs(), AttrStage::Pre, crate, mod, impl_def); if( impl_def.type().is_wildcard() ) { DEBUG("Deleted"); @@ -1011,14 +1098,14 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST:: } } for( const auto& mi: mod.m_macro_imports ) - DEBUG("- Imports '" << mi.first << "'"); + DEBUG("- Imports '" << mi.path << "'"); } // Insert prelude if: Enabled for this module, present for the crate, and this module is not an anon if( crate.m_prelude_path != AST::Path() ) { if( mod.m_insert_prelude && ! mod.is_anon() ) { - mod.add_alias(false, ::AST::UseStmt(Span(), crate.m_prelude_path), "", {}); + mod.add_item(Span(), false, "", ::AST::UseItem { Span(), ::make_vec1(::AST::UseItem::Ent { Span(), crate.m_prelude_path, "" }) }, {}); } } @@ -1027,19 +1114,20 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST:: { auto& i = mod.items()[idx]; - DEBUG("- " << modpath << "::" << i.name << " (" << ::AST::Item::tag_to_str(i.data.tag()) << ") :: " << i.data.attrs); + DEBUG("- " << modpath << "::" << i.name << " (" << ::AST::Item::tag_to_str(i.data.tag()) << ") :: " << i.attrs); ::AST::Path path = modpath + i.name; - auto attrs = mv$(i.data.attrs); + auto attrs = mv$(i.attrs); + Expand_Attrs_CfgAttr(attrs); Expand_Attrs(attrs, AttrStage::Pre, crate, path, mod, i.data); auto dat = mv$(i.data); - TU_MATCH(::AST::Item, (dat), (e), - (None, - // Skip, nothing - ), - (MacroInv, + TU_MATCH_HDRA( (dat), {) + TU_ARMA(None, e) { + // Skip: nothing + } + TU_ARMA(MacroInv, e) { // Move out of the module to avoid invalidation if a new macro invocation is added auto mi_owned = mv$(e); @@ -1056,11 +1144,14 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST:: Parse_ModRoot_Items(*ttl, mod); } dat.as_MacroInv() = mv$(mi_owned); - ), - (Use, + } + TU_ARMA(Macro, e) { + mod.add_macro(i.is_pub, i.name, mv$(e)); + } + TU_ARMA(Use, e) { // No inner expand. - ), - (ExternBlock, + } + TU_ARMA(ExternBlock, e) { // TODO: Run expand on inner items? // HACK: Just convert inner items into outer items auto items = mv$( e.items() ); @@ -1068,32 +1159,32 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST:: { mod.items().push_back( mv$(i2) ); } - ), - (Impl, + } + TU_ARMA(Impl, e) { Expand_Impl(crate, modstack, modpath, mod, e); if( e.def().type().is_wildcard() ) { dat = AST::Item(); } - ), - (NegImpl, + } + TU_ARMA(NegImpl, e) { Expand_ImplDef(crate, modstack, modpath, mod, e); if( e.type().is_wildcard() ) { dat = AST::Item(); } - ), - (Module, + } + TU_ARMA(Module, e) { LList<const AST::Module*> sub_modstack(&modstack, &e); Expand_Mod(crate, sub_modstack, path, e); - ), - (Crate, + } + TU_ARMA(Crate, e) { // Can't recurse into an `extern crate` if(crate.m_extern_crates.count(e.name) == 0) { - e.name = crate.load_extern_crate( i.data.span, e.name ); + e.name = crate.load_extern_crate( i.span, e.name ); + } } - ), - (Struct, + TU_ARMA(Struct, e) { Expand_GenericParams(crate, modstack, mod, e.params()); TU_MATCH(AST::StructData, (e.m_data), (sd), (Unit, @@ -1101,6 +1192,7 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST:: (Struct, for(auto it = sd.ents.begin(); it != sd.ents.end(); ) { auto& si = *it; + Expand_Attrs_CfgAttr(si.m_attrs); Expand_Attrs(si.m_attrs, AttrStage::Pre, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, si); }); Expand_Type(crate, modstack, mod, si.m_type); Expand_Attrs(si.m_attrs, AttrStage::Post, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, si); }); @@ -1114,6 +1206,7 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST:: (Tuple, for(auto it = sd.ents.begin(); it != sd.ents.end(); ) { auto& si = *it; + Expand_Attrs_CfgAttr(si.m_attrs); Expand_Attrs(si.m_attrs, AttrStage::Pre, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, si); }); Expand_Type(crate, modstack, mod, si.m_type); Expand_Attrs(si.m_attrs, AttrStage::Post, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, si); }); @@ -1125,10 +1218,11 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST:: } ) ) - ), - (Enum, + } + TU_ARMA(Enum, e) { Expand_GenericParams(crate, modstack, mod, e.params()); for(auto& var : e.variants()) { + Expand_Attrs_CfgAttr(var.m_attrs); Expand_Attrs(var.m_attrs, AttrStage::Pre, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, var); }); TU_MATCH(::AST::EnumVariantData, (var.m_data), (e), (Value, @@ -1142,6 +1236,7 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST:: (Struct, for(auto it = e.m_fields.begin(); it != e.m_fields.end(); ) { auto& si = *it; + Expand_Attrs_CfgAttr(si.m_attrs); Expand_Attrs(si.m_attrs, AttrStage::Pre, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, si); }); Expand_Type(crate, modstack, mod, si.m_type); Expand_Attrs(si.m_attrs, AttrStage::Post, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, si); }); @@ -1155,11 +1250,22 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST:: ) Expand_Attrs(var.m_attrs, AttrStage::Post, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, var); }); } - ), - (Union, + // Handle cfg on variants (kinda hacky) + for(auto it = e.variants().begin(); it != e.variants().end(); ) { + if( it->m_name == "" ) { + it = e.variants().erase(it); + } + else { + ++ it; + } + } + } + TU_ARMA(Union, e) { Expand_GenericParams(crate, modstack, mod, e.m_params); - for(auto it = e.m_variants.begin(); it != e.m_variants.end(); ) { + for(auto it = e.m_variants.begin(); it != e.m_variants.end(); ) + { auto& si = *it; + Expand_Attrs_CfgAttr(si.m_attrs); Expand_Attrs(si.m_attrs, AttrStage::Pre, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, si); }); Expand_Type(crate, modstack, mod, si.m_type); Expand_Attrs(si.m_attrs, AttrStage::Post, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, si); }); @@ -1169,20 +1275,48 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST:: else ++it; } - ), - (Trait, + } + TU_ARMA(Trait, e) { Expand_GenericParams(crate, modstack, mod, e.params()); - for(auto& ti : e.items()) + auto& trait_items = e.items(); + for(size_t idx = 0; idx < trait_items.size(); idx ++) { + auto& ti = trait_items[idx]; DEBUG(" - " << ti.name << " " << ti.data.tag_str()); - auto attrs = mv$(ti.data.attrs); + auto attrs = mv$(ti.attrs); + Expand_Attrs_CfgAttr(attrs); Expand_Attrs(attrs, AttrStage::Pre, crate, AST::Path(), mod, ti.data); TU_MATCH_DEF(AST::Item, (ti.data), (e), ( - throw ::std::runtime_error("BUG: Unknown item type in impl block"); + BUG(Span(), "Unknown item type in trait block - " << ti.data.tag_str()); ), (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 + size_t insert_pos = idx+1; + while( ttl->lookahead(0) != TOK_EOF ) + { + auto i = Parse_Trait_Item(*ttl); + trait_items.insert( trait_items.begin() + insert_pos, mv$(i) ); + insert_pos ++; + } + // - Any new macro invocations ends up at the end of the list and handled + } + // Move back in (using the index, as the old pointer may be invalid) + trait_items[idx].data.as_MacroInv() = mv$(mi_owned); + } + ), (Function, Expand_GenericParams(crate, modstack, mod, e.params()); for(auto& arg : e.args()) { @@ -1201,16 +1335,20 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST:: ) ) - Expand_Attrs(attrs, AttrStage::Post, crate, AST::Path(), mod, ti.data); - if( ti.data.attrs.m_items.size() == 0 ) - ti.data.attrs = mv$(attrs); + { + auto& ti = trait_items[idx]; + + Expand_Attrs(attrs, AttrStage::Post, crate, AST::Path(), mod, ti.data); + if( ti.attrs.m_items.size() == 0 ) + ti.attrs = mv$(attrs); + } } - ), - (Type, + } + TU_ARMA(Type, e) { Expand_Type(crate, modstack, mod, e.type()); - ), + } - (Function, + TU_ARMA(Function, e) { Expand_GenericParams(crate, modstack, mod, e.params()); for(auto& arg : e.args()) { Expand_Pattern(crate, modstack, mod, arg.first, false); @@ -1218,12 +1356,12 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST:: } Expand_Type(crate, modstack, mod, e.rettype()); Expand_Expr(crate, modstack, e.code()); - ), - (Static, + } + TU_ARMA(Static, e) { Expand_Expr(crate, modstack, e.value()); Expand_Type(crate, modstack, mod, e.type()); - ) - ) + } + } Expand_Attrs(attrs, AttrStage::Post, crate, path, mod, dat); { @@ -1233,8 +1371,8 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST:: i.data = mv$(dat); } // TODO: When would this _not_ be empty? - if( i.data.attrs.m_items.size() == 0 ) - i.data.attrs = mv$(attrs); + if( i.attrs.m_items.size() == 0 ) + i.attrs = mv$(attrs); } } @@ -1285,6 +1423,7 @@ void Expand(::AST::Crate& crate) auto modstack = LList<const ::AST::Module*>(nullptr, &crate.m_root_module); // 1. Crate attributes + Expand_Attrs_CfgAttr(crate.m_attrs); Expand_Attrs(crate.m_attrs, AttrStage::Pre, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate); }); // Insert magic for libstd/libcore @@ -1297,7 +1436,7 @@ void Expand(::AST::Crate& crate) crate.m_extern_crates.at("std").with_all_macros([&](const auto& name, const auto& mac) { crate.m_root_module.add_macro_import( name, mac ); }); - crate.m_root_module.add_ext_crate(false, "std", "std", ::AST::AttributeList {}); + crate.m_root_module.add_ext_crate(Span(), /*is_pub=*/false, "std", "std", /*attrs=*/{}); break; case ::AST::Crate::LOAD_CORE: if( crate.m_prelude_path == AST::Path() ) @@ -1305,7 +1444,7 @@ void Expand(::AST::Crate& crate) crate.m_extern_crates.at("core").with_all_macros([&](const auto& name, const auto& mac) { crate.m_root_module.add_macro_import( name, mac ); }); - crate.m_root_module.add_ext_crate(false, "core", "core", ::AST::AttributeList {}); + crate.m_root_module.add_ext_crate(Span(), /*is_pub=*/false, "core", "core", /*attrs=*/{}); break; case ::AST::Crate::LOAD_NONE: break; @@ -1315,7 +1454,7 @@ void Expand(::AST::Crate& crate) for( auto& a : crate.m_attrs.m_items ) { for( auto& d : g_decorators ) { - if( d.first == a.name() && d.second->stage() == AttrStage::Pre ) { + if( a.name() == d.first && d.second->stage() == AttrStage::Pre ) { //d.second->handle(a, crate, ::AST::Path(), crate.m_root_module, crate.m_root_module); } } @@ -1324,6 +1463,8 @@ void Expand(::AST::Crate& crate) // 3. Module tree Expand_Mod(crate, modstack, ::AST::Path("",{}), crate.m_root_module); + //Expand_Attrs(crate.m_attrs, AttrStage::Post, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate); }); + // Post-process Expand_Mod_IndexAnon(crate, crate.m_root_module); } |