diff options
author | John Hodge <tpg@mutabah.net> | 2016-03-10 10:18:59 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-03-10 10:18:59 +0800 |
commit | ce771e31b4cd157a87e7ec6531d625a895228ebf (patch) | |
tree | 25acbe58db5fc51e91724e7cfc6339aef49f620f /src | |
parent | 874994e677c48689036587033831af56f78797c8 (diff) | |
download | mrust-ce771e31b4cd157a87e7ec6531d625a895228ebf.tar.gz |
Expand - cfg!/#[cfg]/#[cfg_attr] hacked up
Diffstat (limited to 'src')
-rw-r--r-- | src/expand/cfg.cpp | 55 | ||||
-rw-r--r-- | src/expand/mod.cpp | 30 | ||||
-rw-r--r-- | src/include/synext.hpp | 2 |
3 files changed, 73 insertions, 14 deletions
diff --git a/src/expand/cfg.cpp b/src/expand/cfg.cpp index 546bb690..d178b9ae 100644 --- a/src/expand/cfg.cpp +++ b/src/expand/cfg.cpp @@ -2,6 +2,13 @@ #include <synext.hpp> #include <parse/tokentree.hpp> #include <parse/lex.hpp> +#include <parse/common.hpp> + +bool check_cfg(const ::AST::MetaItem& mi) { + // TODO: Handle cfg conditions + throw ::std::runtime_error("TODO: Handle #[cfg] or cfg! conditions"); + return true; +} class CCfgExpander: public ExpandProcMacro @@ -14,13 +21,51 @@ class CCfgExpander: ERROR(sp, E0000, "cfg! doesn't take an identifier"); } - DEBUG("cfg!()"); - - // TODO: Handle cfg!() + auto lex = TTStreamO(tt); + auto attrs = Parse_MetaItem(lex); + DEBUG("cfg!() - " << attrs); - return box$( TTStreamO(TokenTree(TOK_RWORD_FALSE)) ); + if( check_cfg(attrs) ) { + return box$( TTStreamO(TokenTree(TOK_RWORD_TRUE )) ); + } + else { + return box$( TTStreamO(TokenTree(TOK_RWORD_FALSE)) ); + } + } +}; + + +class CCfgHandler: + public ExpandDecorator +{ + AttrStage stage() const override { return AttrStage::EarlyPre; } + + + void handle(const AST::MetaItem& mi, AST::Crate& crate, AST::MacroInvocation& mac) const override { + if( check_cfg(mi) ) { + // Leave as is + } + else { + mac.clear(); + } + } + void handle(const AST::MetaItem& mi, AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item&i) const override { + if( check_cfg(mi) ) { + // Leave + } + else { + i = AST::Item::make_None({}); + } + } + void handle(const AST::MetaItem& mi, ::std::unique_ptr<AST::ExprNode>& expr) const override { + if( check_cfg(mi) ) { + // Leave + } + else { + expr.reset(); + } } }; STATIC_MACRO("cfg", CCfgExpander); -//STATIC_DECORATOR("cfg", CCfgHandler); +STATIC_DECORATOR("cfg", CCfgHandler); diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 33f982da..8eb6dd87 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -9,6 +9,9 @@ #include "../parse/common.hpp" // For reparse from macros #include <ast/expr.hpp> + +extern bool check_cfg(const ::AST::MetaItem& mi); + ::std::map< ::std::string, ::std::unique_ptr<ExpandDecorator> > g_decorators; ::std::map< ::std::string, ::std::unique_ptr<ExpandProcMacro> > g_macros; @@ -28,18 +31,29 @@ namespace { } } +void Expand_Attr(const ::AST::MetaItem& a, AttrStage stage, ::std::function<void(const ExpandDecorator& d,const ::AST::MetaItem& a)> f) +{ + for( auto& d : g_decorators ) { + if( d.first == a.name() ) { + DEBUG("#[" << d.first << "] " << (int)d.second->stage() << "-" << (int)stage); + if( d.second->stage() == stage ) { + f(*d.second, a); + } + } + } +} void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::std::function<void(const ExpandDecorator& d,const ::AST::MetaItem& a)> f) { for( auto& a : attrs.m_items ) { - for( auto& d : g_decorators ) { - if( d.first == a.name() ) { - DEBUG("#[" << d.first << "] " << (int)d.second->stage() << "-" << (int)stage); - if( d.second->stage() == stage ) { - f(*d.second, a); - } + if( a.name() == "cfg_attr" ) { + if( check_cfg(a.items().m_items.at(0)) ) { + Expand_Attr(a.items().m_items.at(1), stage, f); } } + else { + Expand_Attr(a, stage, f); + } } } void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& crate, const ::AST::Path& path, ::AST::Module& mod, ::AST::Item& item) @@ -118,7 +132,7 @@ void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> m 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); }); + Expand_Attrs(cnode->attrs(), stage_pre(is_early), [&](const auto& d, const auto& a){ d.handle(a, cnode); }); if(cnode.get()) { cnode->visit(*this); @@ -128,7 +142,7 @@ void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> m } if(cnode.get()) - Expand_Attrs(cnode->attrs(), stage_post(is_early), [&](const auto& d, const auto& a){ d.handle(a, *cnode); }); + 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 ) diff --git a/src/include/synext.hpp b/src/include/synext.hpp index cd1fc3b5..3ab594a5 100644 --- a/src/include/synext.hpp +++ b/src/include/synext.hpp @@ -44,7 +44,7 @@ public: virtual void handle(const AST::MetaItem& mi, AST::Crate& crate) const {} virtual void handle(const AST::MetaItem& mi, AST::Crate& crate, AST::MacroInvocation& mac) const {} virtual void handle(const AST::MetaItem& mi, AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item&i) const {} - virtual void handle(const AST::MetaItem& mi, AST::ExprNode& expr) const {}; + virtual void handle(const AST::MetaItem& mi, ::std::unique_ptr<AST::ExprNode>& expr) const {}; }; enum class MacroPosition |