diff options
Diffstat (limited to 'src/expand/mod.cpp')
-rw-r--r-- | src/expand/mod.cpp | 324 |
1 files changed, 170 insertions, 154 deletions
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 78225a2f..b7aa6518 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -8,13 +8,14 @@ #include "macro_rules.hpp" #include "../parse/common.hpp" // For reparse from macros #include <ast/expr.hpp> - - -extern bool check_cfg(const ::AST::MetaItem& mi); +#include "cfg.hpp" ::std::map< ::std::string, ::std::unique_ptr<ExpandDecorator> > g_decorators; ::std::map< ::std::string, ::std::unique_ptr<ExpandProcMacro> > g_macros; +void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::std::function<void(const ExpandDecorator& d,const ::AST::MetaItem& a)> f); +void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Path modpath, ::AST::Module& mod); + void Register_Synext_Decorator(::std::string name, ::std::unique_ptr<ExpandDecorator> handler) { g_decorators[name] = mv$(handler); } @@ -47,7 +48,7 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::std::functi for( auto& a : attrs.m_items ) { if( a.name() == "cfg_attr" ) { - if( check_cfg(a.items().at(0)) ) { + if( check_cfg(Span(), a.items().at(0)) ) { Expand_Attr(a.items().at(1), stage, f); } } @@ -62,7 +63,7 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& } ::std::unique_ptr<TokenStream> Expand_Macro( - bool is_early, LList<const AST::Module*> modstack, ::AST::Module& mod, + bool is_early, const ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Module& mod, Span mi_span, const ::std::string& name, const ::std::string& input_ident, const TokenTree& input_tt ) { @@ -70,7 +71,7 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& { if( name == m.first && m.second->expand_early() == is_early ) { - auto e = m.second->expand(mi_span, input_ident, input_tt, mod); + auto e = m.second->expand(mi_span, crate, input_ident, input_tt, mod); return e; } } @@ -114,66 +115,72 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& // Leave valid and return an empty expression return ::std::unique_ptr<TokenStream>(); } - -void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Path item_path, AST::Expr& node) +struct CExpandExpr: + public ::AST::NodeVisitor { - struct CExpandExpr: - public ::AST::NodeVisitor + bool is_early; + ::AST::Crate& crate; + LList<const AST::Module*> modstack; + ::std::unique_ptr<::AST::ExprNode> replacement; + + CExpandExpr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> ms): + is_early(is_early), + crate(crate), + modstack(ms) { - bool is_early; - LList<const AST::Module*> modstack; - ::std::unique_ptr<::AST::ExprNode> replacement; - - CExpandExpr(bool is_early, LList<const AST::Module*> ms): - is_early(is_early), - modstack(ms) + } + + void visit(::std::unique_ptr<AST::ExprNode>& cnode) { + if(cnode.get()) + Expand_Attrs(cnode->attrs(), stage_pre(is_early), [&](const auto& d, const auto& a){ d.handle(a, this->crate, cnode); }); + if(cnode.get()) { - } - - void visit(::std::unique_ptr<AST::ExprNode>& cnode) { - if(cnode.get()) - Expand_Attrs(cnode->attrs(), stage_pre(is_early), [&](const auto& d, const auto& a){ d.handle(a, cnode); }); - if(cnode.get()) + cnode->visit(*this); + if( auto* n_mac = dynamic_cast<AST::ExprNode_Macro*>(cnode.get()) ) { - cnode->visit(*this); - if( this->replacement.get() ) { - cnode = mv$(this->replacement); - } + if( n_mac->m_name == "" ) + cnode.reset(); } - - if(cnode.get()) - Expand_Attrs(cnode->attrs(), stage_post(is_early), [&](const auto& d, const auto& a){ d.handle(a, cnode); }); - } - void visit_nodelete(const ::AST::ExprNode& parent, ::std::unique_ptr<AST::ExprNode>& cnode) { - if( cnode.get() != nullptr ) - { - this->visit(cnode); - if(cnode.get() == nullptr) - ERROR(parent.get_pos(), E0000, "#[cfg] not allowed in this position"); + if( this->replacement.get() ) { + cnode = mv$(this->replacement); } } - void visit_vector(::std::vector< ::std::unique_ptr<AST::ExprNode> >& cnodes) { - for( auto& child : cnodes ) { - this->visit(child); + + if(cnode.get()) + Expand_Attrs(cnode->attrs(), stage_post(is_early), [&](const auto& d, const auto& a){ d.handle(a, this->crate, cnode); }); + } + void visit_nodelete(const ::AST::ExprNode& parent, ::std::unique_ptr<AST::ExprNode>& cnode) { + if( cnode.get() != nullptr ) + { + this->visit(cnode); + if(cnode.get() == nullptr) + ERROR(parent.get_pos(), E0000, "#[cfg] not allowed in this position"); + } + } + void visit_vector(::std::vector< ::std::unique_ptr<AST::ExprNode> >& cnodes) { + for( auto& child : cnodes ) { + this->visit(child); + } + // Delete null children + for( auto it = cnodes.begin(); it != cnodes.end(); ) { + if( it->get() == nullptr ) { + it = cnodes.erase( it ); } - // Delete null children - for( auto it = cnodes.begin(); it != cnodes.end(); ) { - if( it->get() == nullptr ) { - it = cnodes.erase( it ); - } - else { - ++ it; - } + else { + ++ it; } } - - void visit(::AST::ExprNode_Macro& node) override { - auto ttl = Expand_Macro( - is_early, modstack, *(::AST::Module*)(modstack.m_item), - Span(node.get_pos()), - node.m_name, node.m_ident, node.m_tokens - ); - if( ttl.get() != nullptr && ttl->lookahead(0) != TOK_EOF ) + } + + void visit(::AST::ExprNode_Macro& node) override { + auto ttl = Expand_Macro( + is_early, crate, modstack, *(::AST::Module*)(modstack.m_item), + Span(node.get_pos()), + node.m_name, node.m_ident, node.m_tokens + ); + if( ttl.get() != nullptr ) + { + if( ttl->lookahead(0) != TOK_EOF ) { // Reparse as expression / item auto newexpr = Parse_Expr0(*ttl); @@ -182,98 +189,113 @@ void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> m // And schedule it to replace the previous replacement = mv$(newexpr); } + else + { + node.m_name = ""; + } } - - void visit(::AST::ExprNode_Block& node) override { - this->visit_vector(node.m_nodes); - } - void visit(::AST::ExprNode_Flow& node) override { - this->visit_nodelete(node, node.m_value); - } - void visit(::AST::ExprNode_LetBinding& node) override { - // TODO: Pattern and type - this->visit_nodelete(node, node.m_value); - } - void visit(::AST::ExprNode_Assign& node) override { - this->visit_nodelete(node, node.m_slot); - this->visit_nodelete(node, node.m_value); - } - void visit(::AST::ExprNode_CallPath& node) override { - // TODO: path? - this->visit_vector(node.m_args); - } - void visit(::AST::ExprNode_CallMethod& node) override { - this->visit_nodelete(node, node.m_val); - this->visit_vector(node.m_args); - } - void visit(::AST::ExprNode_CallObject& node) override { - this->visit_nodelete(node, node.m_val); - this->visit_vector(node.m_args); - } - void visit(::AST::ExprNode_Loop& node) override { - this->visit_nodelete(node, node.m_cond); - this->visit_nodelete(node, node.m_code); - } - void visit(::AST::ExprNode_Match& node) override { - this->visit_nodelete(node, node.m_val); - // TODO: Arms - } - void visit(::AST::ExprNode_If& node) override { - this->visit_nodelete(node, node.m_cond); - this->visit_nodelete(node, node.m_true); - this->visit_nodelete(node, node.m_false); // TODO: Can the false branch be `#[cfg]`d off? - } - void visit(::AST::ExprNode_IfLet& node) override { - // TODO: Pattern - this->visit_nodelete(node, node.m_value); - this->visit_nodelete(node, node.m_true); - this->visit_nodelete(node, node.m_false); // TODO: Can the false branch be `#[cfg]`d off? - } - void visit(::AST::ExprNode_Integer& node) override { } - void visit(::AST::ExprNode_Float& node) override { } - void visit(::AST::ExprNode_Bool& node) override { } - void visit(::AST::ExprNode_String& node) override { } - void visit(::AST::ExprNode_Closure& node) override { - // TODO: Arg patterns and types - // TODO: Return type - this->visit_nodelete(node, node.m_code); - } - void visit(::AST::ExprNode_StructLiteral& node) override { - this->visit_nodelete(node, node.m_base_value); - // TODO: Values (with #[cfg] support) - } - void visit(::AST::ExprNode_Array& node) override { - this->visit_nodelete(node, node.m_size); - this->visit_vector(node.m_values); - } - void visit(::AST::ExprNode_Tuple& node) override { - this->visit_vector(node.m_values); - } - void visit(::AST::ExprNode_NamedValue& node) override { } - void visit(::AST::ExprNode_Field& node) override { - this->visit_nodelete(node, node.m_obj); - } - void visit(::AST::ExprNode_Index& node) override { - this->visit_nodelete(node, node.m_obj); - this->visit_nodelete(node, node.m_idx); - } - void visit(::AST::ExprNode_Deref& node) override { - this->visit_nodelete(node, node.m_value); - } - void visit(::AST::ExprNode_Cast& node) override { - this->visit_nodelete(node, node.m_value); - // TODO: Type - } - void visit(::AST::ExprNode_BinOp& node) override { - this->visit_nodelete(node, node.m_left); - this->visit_nodelete(node, node.m_right); - } - void visit(::AST::ExprNode_UniOp& node) override { - this->visit_nodelete(node, node.m_value); + } + + void visit(::AST::ExprNode_Block& node) override { + // TODO! Use a proper path here + if( node.m_inner_mod ) { + Expand_Mod(is_early, crate, modstack, AST::Path(), *node.m_inner_mod); } - }; + this->visit_vector(node.m_nodes); + } + void visit(::AST::ExprNode_Flow& node) override { + this->visit_nodelete(node, node.m_value); + } + void visit(::AST::ExprNode_LetBinding& node) override { + // TODO: Pattern and type + this->visit_nodelete(node, node.m_value); + } + void visit(::AST::ExprNode_Assign& node) override { + this->visit_nodelete(node, node.m_slot); + this->visit_nodelete(node, node.m_value); + } + void visit(::AST::ExprNode_CallPath& node) override { + // TODO: path? + this->visit_vector(node.m_args); + } + void visit(::AST::ExprNode_CallMethod& node) override { + this->visit_nodelete(node, node.m_val); + this->visit_vector(node.m_args); + } + void visit(::AST::ExprNode_CallObject& node) override { + this->visit_nodelete(node, node.m_val); + this->visit_vector(node.m_args); + } + void visit(::AST::ExprNode_Loop& node) override { + this->visit_nodelete(node, node.m_cond); + this->visit_nodelete(node, node.m_code); + } + void visit(::AST::ExprNode_Match& node) override { + this->visit_nodelete(node, node.m_val); + // TODO: Arms + } + void visit(::AST::ExprNode_If& node) override { + this->visit_nodelete(node, node.m_cond); + this->visit_nodelete(node, node.m_true); + this->visit_nodelete(node, node.m_false); // TODO: Can the false branch be `#[cfg]`d off? + } + void visit(::AST::ExprNode_IfLet& node) override { + // TODO: Pattern + this->visit_nodelete(node, node.m_value); + this->visit_nodelete(node, node.m_true); + this->visit_nodelete(node, node.m_false); // TODO: Can the false branch be `#[cfg]`d off? + } + void visit(::AST::ExprNode_Integer& node) override { } + void visit(::AST::ExprNode_Float& node) override { } + void visit(::AST::ExprNode_Bool& node) override { } + void visit(::AST::ExprNode_String& node) override { } + void visit(::AST::ExprNode_Closure& node) override { + // TODO: Arg patterns and types + // TODO: Return type + this->visit_nodelete(node, node.m_code); + } + void visit(::AST::ExprNode_StructLiteral& node) override { + this->visit_nodelete(node, node.m_base_value); + // TODO: Values (with #[cfg] support) + } + void visit(::AST::ExprNode_Array& node) override { + this->visit_nodelete(node, node.m_size); + this->visit_vector(node.m_values); + } + void visit(::AST::ExprNode_Tuple& node) override { + this->visit_vector(node.m_values); + } + void visit(::AST::ExprNode_NamedValue& node) override { } + void visit(::AST::ExprNode_Field& node) override { + this->visit_nodelete(node, node.m_obj); + } + void visit(::AST::ExprNode_Index& node) override { + this->visit_nodelete(node, node.m_obj); + this->visit_nodelete(node, node.m_idx); + } + void visit(::AST::ExprNode_Deref& node) override { + this->visit_nodelete(node, node.m_value); + } + void visit(::AST::ExprNode_Cast& node) override { + this->visit_nodelete(node, node.m_value); + // TODO: Type + } + void visit(::AST::ExprNode_BinOp& node) override { + this->visit_nodelete(node, node.m_left); + this->visit_nodelete(node, node.m_right); + } + void visit(::AST::ExprNode_UniOp& node) override { + this->visit_nodelete(node, node.m_value); + } +}; - auto visitor = CExpandExpr(is_early, modstack); +void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> modstack, ::std::unique_ptr<AST::ExprNode>& node) { + auto visitor = CExpandExpr(is_early, crate, modstack); + visitor.visit(node); +} +void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Path item_path, AST::Expr& node) +{ + auto visitor = CExpandExpr(is_early, crate, modstack); node.visit_nodes(visitor); } @@ -298,7 +320,8 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo // Move out of the module to avoid invalidation if a new macro invocation is added auto mi_owned = mv$(mi); - auto ttl = Expand_Macro(is_early, modstack, mod, mi_owned.span(), mi_owned.name(), mi_owned.input_ident(), mi_owned.input_tt()); + auto ttl = Expand_Macro(is_early, crate, modstack, mod, + mi_owned.span(), mi_owned.name(), mi_owned.input_ident(), mi_owned.input_tt()); if( ! ttl.get() ) { @@ -378,14 +401,7 @@ void Expand(::AST::Crate& crate) auto modstack = LList<const ::AST::Module*>(nullptr, &crate.m_root_module); // 1. Crate attributes - for( auto& a : crate.m_attrs.m_items ) - { - for( auto& d : g_decorators ) { - if( d.first == a.name() && d.second->stage() == AttrStage::EarlyPre ) { - d.second->handle(a, crate); - } - } - } + Expand_Attrs(crate.m_attrs, AttrStage::EarlyPre, [&](const auto& d, const auto& a){ d.handle(a, crate); }); // 2. Module attributes for( auto& a : crate.m_attrs.m_items ) |