summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-03-10 10:18:59 +0800
committerJohn Hodge <tpg@mutabah.net>2016-03-10 10:18:59 +0800
commitce771e31b4cd157a87e7ec6531d625a895228ebf (patch)
tree25acbe58db5fc51e91724e7cfc6339aef49f620f /src
parent874994e677c48689036587033831af56f78797c8 (diff)
downloadmrust-ce771e31b4cd157a87e7ec6531d625a895228ebf.tar.gz
Expand - cfg!/#[cfg]/#[cfg_attr] hacked up
Diffstat (limited to 'src')
-rw-r--r--src/expand/cfg.cpp55
-rw-r--r--src/expand/mod.cpp30
-rw-r--r--src/include/synext.hpp2
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