diff options
-rw-r--r-- | src/ast/ast.hpp | 2 | ||||
-rw-r--r-- | src/expand/cfg.cpp | 24 | ||||
-rw-r--r-- | src/expand/lang_item.cpp | 22 | ||||
-rw-r--r-- | src/expand/mod.cpp | 21 | ||||
-rw-r--r-- | src/include/synext.hpp | 4 | ||||
-rw-r--r-- | src/resolve/index.cpp | 1 |
6 files changed, 70 insertions, 4 deletions
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 06ff857e..7f6a61ff 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -376,6 +376,7 @@ public: m_trait( move(trait_type) ),
m_type( move(impl_type) )
{}
+ ImplDef& operator=(ImplDef&&) = default;
// Accessors
const MetaItems& attrs() const { return m_attrs; }
@@ -413,6 +414,7 @@ public: Impl(MetaItems attrs, GenericParams params, TypeRef impl_type, Path trait_type):
m_def( move(attrs), move(params), move(trait_type), move(impl_type) )
{}
+ Impl& operator=(Impl&&) = default;
void add_function(bool is_public, ::std::string name, Function fcn);
void add_type(bool is_public, ::std::string name, TypeRef type);
diff --git a/src/expand/cfg.cpp b/src/expand/cfg.cpp index 431933f0..76f6bbc3 100644 --- a/src/expand/cfg.cpp +++ b/src/expand/cfg.cpp @@ -9,6 +9,7 @@ #include <set> ::std::map< ::std::string, ::std::string> g_cfg_values; +::std::map< ::std::string, ::std::function<bool(const ::std::string&)> > g_cfg_value_fcns; ::std::set< ::std::string > g_cfg_flags; void Cfg_SetFlag(::std::string name) { @@ -17,6 +18,9 @@ void Cfg_SetFlag(::std::string name) { void Cfg_SetValue(::std::string name, ::std::string val) { g_cfg_values.insert( ::std::make_pair(mv$(name), mv$(val)) ); } +void Cfg_SetValue(::std::string name, ::std::function<bool(const ::std::string&)> cb) { + g_cfg_value_fcns.insert( ::std::make_pair(mv$(name), mv$(cb)) ); +} bool check_cfg(Span sp, const ::AST::MetaItem& mi) { @@ -54,11 +58,16 @@ bool check_cfg(Span sp, const ::AST::MetaItem& mi) { DEBUG(""<<mi.name()<<": '"<<it->second<<"' == '"<<mi.string()<<"'"); return it->second == mi.string(); } - else + + auto it2 = g_cfg_value_fcns.find(mi.name()); + if(it2 != g_cfg_value_fcns.end() ) { - WARNING(sp, W0000, "Unknown cfg() param '" << mi.name() << "'"); - return false; + DEBUG(""<<mi.name()<<": ('"<<mi.string()<<"')?"); + return it2->second( mi.string() ); } + + WARNING(sp, W0000, "Unknown cfg() param '" << mi.name() << "'"); + return false; } else { // Flag @@ -126,6 +135,15 @@ class CCfgHandler: expr.reset(); } } + void handle(const AST::MetaItem& mi, AST::Crate& crate, const AST::Module& mod, AST::ImplDef& impl) const override { + DEBUG("#[cfg] impl - " << mi); + if( check_cfg(Span(), mi) ) { + // Leave + } + else { + impl.type() = ::TypeRef(); + } + } }; STATIC_MACRO("cfg", CCfgExpander); diff --git a/src/expand/lang_item.cpp b/src/expand/lang_item.cpp index a86cdd62..f794bb32 100644 --- a/src/expand/lang_item.cpp +++ b/src/expand/lang_item.cpp @@ -105,7 +105,7 @@ public: { TU_MATCH_DEF(::AST::Item, (i), (e), ( - TODO(Span(), "Unknown item type with #[lang] attached at " << path); + TODO(Span(), "Unknown item type with #[lang=\""<<attr<<"\"] attached at " << path); ), (Function, handle_lang_item(crate, path, attr.string(), AST::ITEM_FN); @@ -118,6 +118,26 @@ public: ) ) } + + void handle(const AST::MetaItem& mi, AST::Crate& crate, const AST::Module& mod, AST::ImplDef& impl) const override { + const ::std::string& name = mi.string(); + + if( name == "i8" ) {} + else if( name == "u8" ) {} + else if( name == "i16" ) {} + else if( name == "u16" ) {} + else if( name == "i32" ) {} + else if( name == "u32" ) {} + else if( name == "i64" ) {} + else if( name == "u64" ) {} + else if( name == "isize" ) {} + else if( name == "usize" ) {} + else if( name == "const_ptr" ) {} + else if( name == "mut_ptr" ) {} + else { + throw CompileError::Generic(FMT("Unknown lang item '" << name << "' on impl")); + } + } }; STATIC_DECORATOR("lang", Decorator_LangItem) diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index f0508698..3f0911fe 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -69,6 +69,10 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& { Expand_Attrs(attrs, stage, [&](const auto& d, const auto& a){ d.handle(a, crate, path, mod, item); }); } +void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& crate, ::AST::Module& mod, ::AST::ImplDef& impl) +{ + Expand_Attrs(attrs, stage, [&](const auto& d, const auto& a){ d.handle(a, crate, mod, impl); }); +} ::std::unique_ptr<TokenStream> Expand_Macro( bool is_early, const ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Module& mod, @@ -718,6 +722,13 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo for( auto& impl : mod.impls() ) { DEBUG("- " << impl); + + Expand_Attrs(impl.def().attrs(), stage_pre(is_early), crate, mod, impl.def()); + if( impl.def().type().is_wildcard() ) { + DEBUG("Deleted"); + continue ; + } + Expand_Type(is_early, crate, modstack, mod, impl.def().type()); //Expand_Type(is_early, crate, modstack, mod, impl.def().trait()); @@ -788,6 +799,16 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo if( i.data.attrs.m_items.size() == 0 ) i.data.attrs = mv$(attrs); } + + Expand_Attrs(impl.def().attrs(), stage_post(is_early), crate, mod, impl.def()); + } + + for( auto it = mod.impls().begin(); it != mod.impls().end(); ) + { + if( it->def().type().is_wildcard() ) + it = mod.impls().erase( it ); + else + ++ it; } for( const auto& mi: mod.macro_imports_res() ) diff --git a/src/include/synext.hpp b/src/include/synext.hpp index 4320fceb..40e3d073 100644 --- a/src/include/synext.hpp +++ b/src/include/synext.hpp @@ -25,6 +25,8 @@ namespace AST { class ExprNode_Match_Arm; class MacroInvocation; + + class ImplDef; } class TokenTree; class TokenStream; @@ -51,6 +53,8 @@ public: virtual void handle(const AST::MetaItem& mi, AST::Crate& crate) const { unexpected(mi, "crate"); } virtual void handle(const AST::MetaItem& mi, AST::Crate& crate, AST::MacroInvocation& mac) const { unexpected(mi, "macro invocation"); } virtual void handle(const AST::MetaItem& mi, AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item&i) const { unexpected(mi, "item"); } + // NOTE: To delete, set the type to `_` + virtual void handle(const AST::MetaItem& mi, AST::Crate& crate, const AST::Module& mod, AST::ImplDef& impl) const { unexpected(mi, "impl"); } // NOTE: To delete, clear the name virtual void handle(const AST::MetaItem& mi, AST::Crate& crate, ::AST::StructItem& si) const { unexpected(mi, "struct item"); } // NOTE: To delete, make the type invalid diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index 0155455d..a1892238 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -71,6 +71,7 @@ void Resolve_Index_Module_Base(AST::Module& mod) for( const auto& i : mod.items() ) { ::AST::Path p = mod.path() + i.name; + DEBUG("- p = " << p << " : " << ::AST::Item::tag_to_str(i.data.tag())); TU_MATCH(AST::Item, (i.data), (e), (None, |