From b48167dec0c1c05b463991a8db5a8db70a5ae604 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 19 May 2019 22:15:02 +0800 Subject: All - Switch to using interned (de-duplicated) RcString-s instead of std::string for paths/identifiers --- src/rc_string.cpp | 113 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 102 insertions(+), 11 deletions(-) (limited to 'src/rc_string.cpp') diff --git a/src/rc_string.cpp b/src/rc_string.cpp index 46f36923..0d7e253a 100644 --- a/src/rc_string.cpp +++ b/src/rc_string.cpp @@ -7,17 +7,18 @@ */ #include #include +#include #include RcString::RcString(const char* s, unsigned int len): - m_ptr(nullptr), - m_len(len) + m_ptr(nullptr) { if( len > 0 ) { - m_ptr = new unsigned int[1 + (len+1 + sizeof(unsigned int)-1) / sizeof(unsigned int)]; - *m_ptr = 1; - char* data_mut = reinterpret_cast(m_ptr + 1); + m_ptr = new unsigned int[2 + (len+1 + sizeof(unsigned int)-1) / sizeof(unsigned int)]; + m_ptr[0] = 1; + m_ptr[1] = len; + char* data_mut = reinterpret_cast(m_ptr + 2); for(unsigned int j = 0; j < len; j ++ ) data_mut[j] = s[j]; data_mut[len] = '\0'; @@ -36,14 +37,104 @@ RcString::~RcString() } } } +Ordering RcString::ord(const RcString& x) const +{ + if( m_ptr == x.m_ptr ) + return OrdEqual; + // Both can't be empty/null + if( m_ptr == nullptr ) + return OrdLess; + if( x.m_ptr == nullptr ) + return OrdGreater; + + assert(x.size() > 0); + assert(this->size() > 0); + + auto xp = x.c_str(); + auto tp = this->c_str(); + for(size_t i = 0; i < ::std::min(this->size(), x.size()); i ++) + { + if( *xp != *tp ) + return ::ord((unsigned)*xp, (unsigned)*tp); + xp ++; + tp ++; + } + return ::ord((unsigned)this->size(), (unsigned)x.size()); +} +Ordering RcString::ord(const std::string& x) const +{ + if( m_ptr == nullptr && x.size() == 0 ) + return OrdEqual; + // Both can't be empty/null + if( m_ptr == nullptr ) + return OrdLess; + if( x.empty() ) + return OrdGreater; + + assert(x.size() > 0); + assert(this->size() > 0); + + auto xp = x.c_str(); + auto tp = this->c_str(); + for(size_t i = 0; i < ::std::min(this->size(), x.size()); i ++) + { + if( *xp != *tp ) + return ::ord((unsigned)*xp, (unsigned)*tp); + xp ++; + tp ++; + } + return ::ord((unsigned)this->size(), (unsigned)x.size()); +} bool RcString::operator==(const char* s) const { - if( m_len == 0 ) + if( m_ptr == nullptr ) return *s == '\0'; - auto m = this->c_str(); - do { - if( *m != *s ) + const char* ts = this->c_str(); + const char* end = ts + this->size(); + // Loop while not at the end of either + while(s && ts != end) + { + if( *s != *ts ) return false; - } while( *m++ != '\0' && *s++ != '\0' ); - return true; + s ++; + ts ++; + } + // Only equal if we're at the end of both strings + return *s == '\0' && ts == end; +} + +::std::ostream& operator<<(::std::ostream& os, const RcString& x) +{ + for(size_t i = 0; i < x.size(); i ++) + { + os << x.c_str()[i]; + } + return os; +} + + +::std::set RcString_interned_strings; + +RcString RcString::new_interned(const ::std::string& s) +{ +#if 0 + auto it = RcString_interned_strings.find(s); + if( it == RcString_interned_strings.end() ) + { + it = RcString_interned_strings.insert(RcString(s)).first; + } + return *it; +#else + return *RcString_interned_strings.insert(RcString(s)).first; +#endif +} + +size_t std::hash::operator()(const RcString& s) const noexcept +{ + size_t h = 5381; + for(auto c : s) { + h = h * 33 + (unsigned)c; + } + return h; + //return hash(s.c_str(), s.size()); } -- cgit v1.2.3 From 84a9e0b722ac2b56a958720330592bc9e5ed7633 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 21 May 2019 18:58:23 +0800 Subject: rc_string - Use memcmp/strcmp (faster) --- src/include/rc_string.hpp | 16 ++++++++--- src/rc_string.cpp | 71 +++++++++++++---------------------------------- 2 files changed, 31 insertions(+), 56 deletions(-) (limited to 'src/rc_string.cpp') diff --git a/src/include/rc_string.hpp b/src/include/rc_string.hpp index 94b6d9e7..2177e614 100644 --- a/src/include/rc_string.hpp +++ b/src/include/rc_string.hpp @@ -85,7 +85,12 @@ public: return *(c_str() + size() - 1); } - Ordering ord(const RcString& s) const; + Ordering ord(const char* s, size_t l) const; + Ordering ord(const RcString& s) const { + if( m_ptr == s.m_ptr ) + return OrdEqual; + return ord(s.c_str(), s.size()); + } bool operator==(const RcString& s) const { if(s.size() != this->size()) return false; @@ -99,13 +104,16 @@ public: bool operator<(const RcString& s) const { return this->ord(s) == OrdLess; } bool operator>(const RcString& s) const { return this->ord(s) == OrdGreater; } - Ordering ord(const std::string& s) const; + Ordering ord(const std::string& s) const { return ord(s.data(), s.size()); } bool operator==(const std::string& s) const { return this->ord(s) == OrdEqual; } bool operator!=(const std::string& s) const { return this->ord(s) != OrdEqual; } bool operator<(const std::string& s) const { return this->ord(s) == OrdLess; } bool operator>(const std::string& s) const { return this->ord(s) == OrdGreater; } - bool operator==(const char* s) const; - bool operator!=(const char* s) const { return !(*this == s); } + + Ordering ord(const char* s) const; + bool operator==(const char* s) const { return this->ord(s) == OrdEqual; } + bool operator!=(const char* s) const { return this->ord(s) != OrdEqual; } + friend ::std::ostream& operator<<(::std::ostream& os, const RcString& x); friend bool operator==(const char* a, const RcString& b) { diff --git a/src/rc_string.cpp b/src/rc_string.cpp index 0d7e253a..123b4254 100644 --- a/src/rc_string.cpp +++ b/src/rc_string.cpp @@ -37,70 +37,35 @@ RcString::~RcString() } } } -Ordering RcString::ord(const RcString& x) const +Ordering RcString::ord(const char* s, size_t len) const { - if( m_ptr == x.m_ptr ) - return OrdEqual; - // Both can't be empty/null if( m_ptr == nullptr ) - return OrdLess; - if( x.m_ptr == nullptr ) + return (len == 0 ? OrdEqual : OrdLess); + if( len == 0 ) return OrdGreater; - assert(x.size() > 0); assert(this->size() > 0); + assert(len > 0); - auto xp = x.c_str(); - auto tp = this->c_str(); - for(size_t i = 0; i < ::std::min(this->size(), x.size()); i ++) - { - if( *xp != *tp ) - return ::ord((unsigned)*xp, (unsigned)*tp); - xp ++; - tp ++; - } - return ::ord((unsigned)this->size(), (unsigned)x.size()); + int cmp = memcmp(this->c_str(), s, ::std::min(len, this->size())); + if(cmp == 0) + return ::ord(this->size(), len); + return ::ord(cmp, 0); } -Ordering RcString::ord(const std::string& x) const +Ordering RcString::ord(const char* s) const { - if( m_ptr == nullptr && x.size() == 0 ) - return OrdEqual; - // Both can't be empty/null if( m_ptr == nullptr ) - return OrdLess; - if( x.empty() ) - return OrdGreater; - - assert(x.size() > 0); - assert(this->size() > 0); + return (*s == '\0' ? OrdEqual : OrdLess); - auto xp = x.c_str(); - auto tp = this->c_str(); - for(size_t i = 0; i < ::std::min(this->size(), x.size()); i ++) - { - if( *xp != *tp ) - return ::ord((unsigned)*xp, (unsigned)*tp); - xp ++; - tp ++; - } - return ::ord((unsigned)this->size(), (unsigned)x.size()); -} -bool RcString::operator==(const char* s) const -{ - if( m_ptr == nullptr ) - return *s == '\0'; - const char* ts = this->c_str(); - const char* end = ts + this->size(); - // Loop while not at the end of either - while(s && ts != end) + int cmp = strncmp(this->c_str(), s, this->size()); + if( cmp == 0 ) { - if( *s != *ts ) - return false; - s ++; - ts ++; + if( s[this->size()] == '\0' ) + return OrdEqual; + else + return OrdLess; } - // Only equal if we're at the end of both strings - return *s == '\0' && ts == end; + return ::ord(cmp, 0); } ::std::ostream& operator<<(::std::ostream& os, const RcString& x) @@ -125,12 +90,14 @@ RcString RcString::new_interned(const ::std::string& s) } return *it; #else + // TODO: interning flag, so comparisons can just be a pointer comparison return *RcString_interned_strings.insert(RcString(s)).first; #endif } size_t std::hash::operator()(const RcString& s) const noexcept { + // http://www.cse.yorku.ca/~oz/hash.html "djb2" size_t h = 5381; for(auto c : s) { h = h * 33 + (unsigned)c; -- cgit v1.2.3 From 865235c09f8e5ccf9cc7714428dc64036a9e3ea9 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 24 May 2019 22:39:06 +0800 Subject: Expand derive - Code cleanup --- src/expand/derive.cpp | 417 +++++++++++++++++++++------------------------- src/include/rc_string.hpp | 2 +- src/rc_string.cpp | 16 ++ 3 files changed, 207 insertions(+), 228 deletions(-) (limited to 'src/rc_string.cpp') diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp index 6dea3028..cc3b3cd0 100644 --- a/src/expand/derive.cpp +++ b/src/expand/derive.cpp @@ -58,20 +58,95 @@ static inline ::std::vector vec$(T v1, T v2, T v3, T v4, T v5) { tmp.push_back( mv$(v5) ); return mv$(tmp); } -static AST::Path get_path(const RcString& core_name, ::std::string c1, ::std::string c2) +static AST::Path get_path(const RcString& core_name, const char* c1, const char* c2) { return AST::Path(core_name, { AST::PathNode(RcString::new_interned(c1), {}), AST::PathNode(RcString::new_interned(c2), {}) }); } -static AST::Path get_path(const RcString& core_name, ::std::string c1, ::std::string c2, ::std::string c3) +static AST::Path get_path(const RcString& core_name, const char* c1, const char* c2, const char* c3) { return AST::Path(core_name, { AST::PathNode(RcString::new_interned(c1), {}), AST::PathNode(RcString::new_interned(c2), {}), AST::PathNode(RcString::new_interned(c3), {}) }); } - static inline AST::ExprNodeP mk_exprnodep(AST::ExprNode* en){ return AST::ExprNodeP(en); } //#define NEWNODE(type, ...) mk_exprnodep(new type(__VA_ARGS__)) #define NEWNODE(type, ...) mk_exprnodep(new AST::ExprNode_##type(__VA_ARGS__)) +static ::std::vector make_refpat_a( + const Span& sp, + ::std::vector& pats_a, + const ::std::vector& sub_types, + ::std::function cb + ) +{ + ::std::vector nodes; + for( size_t idx = 0; idx < sub_types.size(); idx ++ ) + { + auto name_a = RcString::new_interned(FMT("a" << idx)); + pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); + nodes.push_back( cb(idx, NEWNODE(NamedValue, AST::Path(name_a))) ); + } + return nodes; +} +static ::std::vector make_refpat_a( + const Span& sp, + ::std::vector< ::std::pair >& pats_a, + const ::std::vector& fields, + ::std::function cb + ) +{ + ::std::vector nodes; + size_t idx = 0; + for( const auto& fld : fields ) + { + auto name_a = RcString::new_interned(FMT("a" << fld.m_name)); + pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF)) ); + nodes.push_back( cb(idx, NEWNODE(NamedValue, AST::Path(name_a))) ); + idx ++; + } + return nodes; +} +static ::std::vector make_refpat_ab( + const Span& sp, + ::std::vector& pats_a, + ::std::vector& pats_b, + const ::std::vector& sub_types, + ::std::function cb + ) +{ + ::std::vector nodes; + for( size_t idx = 0; idx < sub_types.size(); idx ++ ) + { + auto name_a = RcString::new_interned(FMT("a" << idx)); + auto name_b = RcString::new_interned(FMT("b" << idx)); + pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); + pats_b.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_b, ::AST::PatternBinding::Type::REF) ); + nodes.push_back( cb(idx, NEWNODE(NamedValue, AST::Path(name_a)), NEWNODE(NamedValue, AST::Path(name_b))) ); + } + return nodes; +} +static ::std::vector make_refpat_ab( + const Span& sp, + ::std::vector< ::std::pair >& pats_a, + ::std::vector< ::std::pair >& pats_b, + const ::std::vector& fields, + ::std::function cb + ) +{ + ::std::vector nodes; + size_t idx = 0; + for( const auto& fld : fields ) + { + auto name_a = RcString::new_interned(FMT("a" << fld.m_name)); + auto name_b = RcString::new_interned(FMT("b" << fld.m_name)); + pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF)) ); + pats_b.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_b, ::AST::PatternBinding::Type::REF)) ); + nodes.push_back( cb(idx, NEWNODE(NamedValue, AST::Path(name_a)), NEWNODE(NamedValue, AST::Path(name_b))) ); + idx ++; + } + return nodes; +} + + struct DeriveOpts { RcString core_name; @@ -299,19 +374,18 @@ class Deriver_Debug: AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const { - const AST::Path debug_trait = AST::Path(core_name, { AST::PathNode("fmt", {}), AST::PathNode("Debug", {}) }); - TypeRef f_type(TypeRef::TagReference(), sp, AST::LifetimeRef(), true, - TypeRef(sp, AST::Path(core_name, {AST::PathNode("fmt",{}), AST::PathNode("Formatter", {})})) - ); + const AST::Path debug_trait = get_path(core_name, "fmt", "Debug"); AST::Function fcn( sp, AST::GenericParams(), ABI_RUST, false, false, false, - TypeRef(sp, AST::Path(core_name, {AST::PathNode("fmt",{}), AST::PathNode("Result",{})}) ), + TypeRef(sp, get_path(core_name, "fmt", "Result")), vec$( - ::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), sp, "self"), TypeRef(TypeRef::TagReference(), sp, AST::LifetimeRef(), false, TypeRef(sp, "Self", 0xFFFF)) ), - ::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), sp, "f"), mv$(f_type) ) + ::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), sp, "self"), + TypeRef(TypeRef::TagReference(), sp, AST::LifetimeRef(), false, TypeRef(sp, "Self", 0xFFFF)) ), + ::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), sp, "f"), + TypeRef(TypeRef::TagReference(), sp, AST::LifetimeRef(), true, TypeRef(sp, get_path(core_name, "fmt", "Formatter")) ) ) ) ); fcn.set_code( NEWNODE(Block, vec$(mv$(node))) ); @@ -346,6 +420,7 @@ public: mv$(node), AST::PathNode("debug_struct",{}), vec$( NEWNODE(String, name) ) ); + // TODO: use a block instead of chaining for( const auto& fld : e.ents ) { node = NEWNODE(CallMethod, @@ -411,55 +486,40 @@ public: ), (Tuple, ::std::vector pats_a; - AST::ExprNodeP node; - - node = NEWNODE(NamedValue, AST::Path("f")); - node = NEWNODE(CallMethod, - mv$(node), AST::PathNode("debug_tuple",{}), - vec$( NEWNODE(String, v.m_name.c_str()) ) - ); - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = RcString::new_interned(FMT("a" << idx)); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); - node = NEWNODE(CallMethod, - mv$(node), AST::PathNode("field",{}), - vec$( - NEWNODE(NamedValue, AST::Path(name_a)) - ) - ); - } - - code = NEWNODE(CallMethod, mv$(node), AST::PathNode("finish",{}), {}); + auto s_ent = NEWNODE(NamedValue, AST::Path("s")); + auto nodes = make_refpat_a(sp, pats_a, e.m_sub_types, [&](size_t idx, auto a){ + return NEWNODE(CallMethod, s_ent->clone(), AST::PathNode("field", {}), vec$( mv$(a) )); + }); + nodes.insert(nodes.begin(), NEWNODE(LetBinding, AST::Pattern(AST::Pattern::TagBind(), sp, "s"), TypeRef(sp), + NEWNODE(CallMethod, NEWNODE(NamedValue, AST::Path("f")), AST::PathNode("debug_tuple",{}), + vec$( NEWNODE(String, v.m_name.c_str()) ) + ) + )); + nodes.push_back( NEWNODE(CallMethod, mv$(s_ent), AST::PathNode("finish",{}), {}) ); + code = NEWNODE(Block, mv$(nodes)); pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), sp, base_path + v.m_name, mv$(pats_a)); ), (Struct, ::std::vector< ::std::pair > pats_a; - AST::ExprNodeP node; - node = NEWNODE(NamedValue, AST::Path("f")); - node = NEWNODE(CallMethod, - mv$(node), AST::PathNode("debug_struct",{}), - vec$( NEWNODE(String, v.m_name.c_str()) ) - ); - - for( const auto& fld : e.m_fields ) - { - auto name_a = RcString::new_interned(FMT("a" << fld.m_name)); - pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF)) ); - - node = NEWNODE(CallMethod, - mv$(node), AST::PathNode("field",{}), - vec$( - NEWNODE(String, fld.m_name.c_str()), - NEWNODE(NamedValue, AST::Path(name_a)) + auto s_ent = NEWNODE(NamedValue, AST::Path("s")); + auto nodes = make_refpat_a(sp, pats_a, e.m_fields, [&](size_t idx, auto a){ + return NEWNODE(CallMethod, s_ent->clone(), AST::PathNode("field", {}), + vec$( + NEWNODE(String, e.m_fields[idx].m_name.c_str()), + mv$(a) + ) + ); + }); + nodes.insert(nodes.begin(), NEWNODE(LetBinding, AST::Pattern(AST::Pattern::TagBind(), sp, "s"), TypeRef(sp), + NEWNODE(CallMethod, NEWNODE(NamedValue, AST::Path("f")), AST::PathNode("debug_struct",{}), + vec$( NEWNODE(String, v.m_name.c_str()) ) ) - ); - } + )); + nodes.push_back( NEWNODE(CallMethod, mv$(s_ent), AST::PathNode("finish",{}), {}) ); - code = NEWNODE(CallMethod, mv$(node), AST::PathNode("finish",{}), {}); + code = NEWNODE(Block, mv$(nodes)); pat_a = AST::Pattern(AST::Pattern::TagStruct(), sp, base_path + v.m_name, mv$(pats_a), true); ) ) @@ -487,7 +547,7 @@ class Deriver_PartialEq: { AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const { - const AST::Path trait_path(core_name, { AST::PathNode("cmp", {}), AST::PathNode("PartialEq", {}) }); + const AST::Path trait_path = get_path(core_name, "cmp", "PartialEq"); AST::Function fcn( sp, @@ -571,21 +631,12 @@ public: (Tuple, ::std::vector pats_a; ::std::vector pats_b; - ::std::vector nodes; - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = RcString::new_interned(FMT("a" << idx)); - auto name_b = RcString::new_interned(FMT("b" << idx)); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); - pats_b.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_b, ::AST::PatternBinding::Type::REF) ); - nodes.push_back(this->compare_and_ret(sp, opts.core_name, - NEWNODE(NamedValue, AST::Path(name_a)), - NEWNODE(NamedValue, AST::Path(name_b)) - )); - } + auto nodes = make_refpat_ab(sp, pats_a, pats_b, e.m_sub_types, [&](auto idx, auto a, auto b){ + return this->compare_and_ret(sp, opts.core_name, mv$(a), mv$(b)); + }); nodes.push_back( NEWNODE(Bool, true) ); + pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), sp, base_path + v.m_name, mv$(pats_a)); pat_b = AST::Pattern(AST::Pattern::TagNamedTuple(), sp, base_path + v.m_name, mv$(pats_b)); code = NEWNODE(Block, mv$(nodes)); @@ -593,21 +644,12 @@ public: (Struct, ::std::vector< ::std::pair > pats_a; ::std::vector< ::std::pair > pats_b; - ::std::vector nodes; - - for( const auto& fld : e.m_fields ) - { - auto name_a = RcString::new_interned(FMT("a" << fld.m_name)); - auto name_b = RcString::new_interned(FMT("b" << fld.m_name)); - pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF)) ); - pats_b.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_b, ::AST::PatternBinding::Type::REF)) ); - nodes.push_back(this->compare_and_ret(sp, opts.core_name, - NEWNODE(NamedValue, AST::Path(name_a)), - NEWNODE(NamedValue, AST::Path(name_b)) - )); - } + auto nodes = make_refpat_ab(sp, pats_a, pats_b, e.m_fields, [&](const auto& name, auto a, auto b){ + return this->compare_and_ret(sp, opts.core_name, mv$(a), mv$(b)); + }); nodes.push_back( NEWNODE(Bool, true) ); + pat_a = AST::Pattern(AST::Pattern::TagStruct(), sp, base_path + v.m_name, mv$(pats_a), true); pat_b = AST::Pattern(AST::Pattern::TagStruct(), sp, base_path + v.m_name, mv$(pats_b), true); code = NEWNODE(Block, mv$(nodes)); @@ -653,10 +695,10 @@ class Deriver_PartialOrd: { AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const { - const AST::Path trait_path(core_name, { AST::PathNode("cmp", {}), AST::PathNode("PartialOrd", {}) }); - const AST::Path path_ordering(core_name, { AST::PathNode("cmp", {}), AST::PathNode("Ordering", {}) }); + const AST::Path trait_path = get_path(core_name, "cmp", "PartialOrd"); + const AST::Path path_ordering = get_path(core_name, "cmp", "Ordering"); - AST::Path path_option_ordering(core_name, { AST::PathNode("option", {}), AST::PathNode("Option", {}) }); + AST::Path path_option_ordering = get_path(core_name, "option", "Option"); path_option_ordering.nodes().back().args().m_types.push_back( TypeRef(sp, path_ordering) ); AST::Function fcn( @@ -770,22 +812,12 @@ public: (Tuple, ::std::vector pats_a; ::std::vector pats_b; - ::std::vector nodes; - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = RcString::new_interned(FMT("a" << idx)); - auto name_b = RcString::new_interned(FMT("b" << idx)); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); - pats_b.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_b, ::AST::PatternBinding::Type::REF) ); - - nodes.push_back(this->make_compare_and_ret( sp, opts.core_name, - NEWNODE(Deref, NEWNODE(NamedValue, AST::Path(name_a))), - NEWNODE(Deref, NEWNODE(NamedValue, AST::Path(name_b))) - )); - } + auto nodes = make_refpat_ab(sp, pats_a, pats_b, e.m_sub_types, [&](size_t , auto a, auto b){ + return this->make_compare_and_ret(sp, opts.core_name, NEWNODE(Deref, mv$(a)), NEWNODE(Deref, mv$(b))); + }); nodes.push_back( this->make_ret_equal(opts.core_name) ); + pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), sp, base_path + v.m_name, mv$(pats_a)); pat_b = AST::Pattern(AST::Pattern::TagNamedTuple(), sp, base_path + v.m_name, mv$(pats_b)); code = NEWNODE(Block, mv$(nodes)); @@ -793,22 +825,12 @@ public: (Struct, ::std::vector< ::std::pair > pats_a; ::std::vector< ::std::pair > pats_b; - ::std::vector nodes; - - for( const auto& fld : e.m_fields ) - { - auto name_a = RcString::new_interned(FMT("a" << fld.m_name)); - auto name_b = RcString::new_interned(FMT("b" << fld.m_name)); - pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF)) ); - pats_b.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_b, ::AST::PatternBinding::Type::REF)) ); - - nodes.push_back(this->make_compare_and_ret( sp, opts.core_name, - NEWNODE(Deref, NEWNODE(NamedValue, AST::Path(name_a))), - NEWNODE(Deref, NEWNODE(NamedValue, AST::Path(name_b))) - )); - } + auto nodes = make_refpat_ab(sp, pats_a, pats_b, e.m_fields, [&](size_t /*idx*/, auto a, auto b){ + return this->make_compare_and_ret(sp, opts.core_name, NEWNODE(Deref, mv$(a)), NEWNODE(Deref, mv$(b))); + }); nodes.push_back( this->make_ret_equal(opts.core_name) ); + pat_a = AST::Pattern(AST::Pattern::TagStruct(), sp, base_path + v.m_name, mv$(pats_a), true); pat_b = AST::Pattern(AST::Pattern::TagStruct(), sp, base_path + v.m_name, mv$(pats_b), true); code = NEWNODE(Block, mv$(nodes)); @@ -863,7 +885,7 @@ class Deriver_Eq: public Deriver { AST::Path get_trait_path(const RcString& core_name) const { - return AST::Path(core_name, { AST::PathNode("cmp", {}), AST::PathNode("Eq", {}) }); + return get_path(core_name, "cmp", "Eq"); } AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const @@ -948,28 +970,18 @@ public: ), (Tuple, ::std::vector pats_a; - ::std::vector nodes; - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = RcString::new_interned(FMT("a" << idx)); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); - nodes.push_back( this->assert_is_eq(assert_method_path, NEWNODE(NamedValue, AST::Path(name_a))) ); - } + auto nodes = make_refpat_a(sp, pats_a, e.m_sub_types, [&](size_t idx, auto a){ + return this->assert_is_eq(assert_method_path, mv$(a)); + }); pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), sp, base_path + v.m_name, mv$(pats_a)); code = NEWNODE(Block, mv$(nodes)); ), (Struct, ::std::vector< ::std::pair > pats_a; - ::std::vector nodes; - - for( const auto& fld : e.m_fields ) - { - auto name_a = RcString::new_interned(FMT("a" << fld.m_name)); - pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF)) ); - nodes.push_back( this->assert_is_eq(assert_method_path, NEWNODE(NamedValue, AST::Path(name_a))) ); - } + auto nodes = make_refpat_a(sp, pats_a, e.m_fields, [&](size_t idx, auto a){ + return this->assert_is_eq(assert_method_path, mv$(a)); + }); pat_a = AST::Pattern(AST::Pattern::TagStruct(), sp, base_path + v.m_name, mv$(pats_a), true); code = NEWNODE(Block, mv$(nodes)); @@ -1012,8 +1024,8 @@ class Deriver_Ord: { AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const { - const AST::Path trait_path(core_name, { AST::PathNode("cmp", {}), AST::PathNode("Ord", {}) }); - const AST::Path path_ordering(core_name, { AST::PathNode("cmp", {}), AST::PathNode("Ordering", {}) }); + const AST::Path trait_path = get_path(core_name, "cmp", "Ord"); + const AST::Path path_ordering = get_path(core_name, "cmp", "Ordering"); AST::Function fcn( sp, @@ -1118,22 +1130,12 @@ public: (Tuple, ::std::vector pats_a; ::std::vector pats_b; - ::std::vector nodes; - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = RcString::new_interned(FMT("a" << idx)); - auto name_b = RcString::new_interned(FMT("b" << idx)); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); - pats_b.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_b, ::AST::PatternBinding::Type::REF) ); - - nodes.push_back(this->make_compare_and_ret( sp, opts.core_name, - NEWNODE(NamedValue, AST::Path(name_a)), - NEWNODE(NamedValue, AST::Path(name_b)) - )); - } + auto nodes = make_refpat_ab(sp, pats_a, pats_b, e.m_sub_types, [&](size_t, auto a, auto b){ + return this->make_compare_and_ret(sp, opts.core_name, mv$(a), mv$(b)); + }); nodes.push_back( this->make_ret_equal(opts.core_name) ); + pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), sp, base_path + v.m_name, mv$(pats_a)); pat_b = AST::Pattern(AST::Pattern::TagNamedTuple(), sp, base_path + v.m_name, mv$(pats_b)); code = NEWNODE(Block, mv$(nodes)); @@ -1141,22 +1143,12 @@ public: (Struct, ::std::vector< ::std::pair > pats_a; ::std::vector< ::std::pair > pats_b; - ::std::vector nodes; - - for( const auto& fld : e.m_fields ) - { - auto name_a = RcString::new_interned(FMT("a" << fld.m_name)); - auto name_b = RcString::new_interned(FMT("b" << fld.m_name)); - pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF)) ); - pats_b.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_b, ::AST::PatternBinding::Type::REF)) ); - - nodes.push_back(this->make_compare_and_ret( sp, opts.core_name, - NEWNODE(NamedValue, AST::Path(name_a)), - NEWNODE(NamedValue, AST::Path(name_b)) - )); - } + auto nodes = make_refpat_ab(sp, pats_a, pats_b, e.m_fields, [&](const auto& /*name*/, auto a, auto b) { + return this->make_compare_and_ret(sp, opts.core_name, mv$(a), mv$(b)); + }); nodes.push_back( this->make_ret_equal(opts.core_name) ); + pat_a = AST::Pattern(AST::Pattern::TagStruct(), sp, base_path + v.m_name, mv$(pats_a), true); pat_b = AST::Pattern(AST::Pattern::TagStruct(), sp, base_path + v.m_name, mv$(pats_b), true); code = NEWNODE(Block, mv$(nodes)); @@ -1307,14 +1299,9 @@ public: ), (Tuple, ::std::vector pats_a; - ::std::vector nodes; - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = RcString::new_interned(FMT("a" << idx)); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); - nodes.push_back( this->clone_val_direct(opts.core_name, NEWNODE(NamedValue, AST::Path(name_a))) ); - } + auto nodes = make_refpat_a(sp, pats_a, e.m_sub_types, [&](size_t , auto a) { + return this->clone_val_direct(opts.core_name, mv$(a)); + }); pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), sp, base_path + v.m_name, mv$(pats_a)); code = NEWNODE(CallPath, base_path + v.m_name, mv$(nodes)); @@ -1370,7 +1357,7 @@ private: for(auto& b : ret.def().params().bounds()) { auto& be = b.as_IsTrait(); - be.trait = AST::Path(opts.core_name, { AST::PathNode("marker", {}), AST::PathNode("Copy", {}) }); + be.trait = get_path(opts.core_name, "marker", "Copy"); } return ret; @@ -1381,7 +1368,7 @@ class Deriver_Copy: public Deriver { AST::Path get_trait_path(const RcString& core_name) const { - return AST::Path(core_name, { AST::PathNode("marker", {}), AST::PathNode("Copy", {}) }); + return get_path(core_name, "marker", "Copy"); } AST::Impl make_ret(Span sp, const RcString& core_name, const AST::GenericParams& p, const TypeRef& type, ::std::vector types_to_bound, AST::ExprNodeP node) const @@ -1416,7 +1403,7 @@ class Deriver_Default: public Deriver { AST::Path get_trait_path(const RcString& core_name) const { - return AST::Path(core_name, { AST::PathNode("default", {}), AST::PathNode("Default", {}) }); + return get_path(core_name, "default", "Default"); } AST::Path get_method_path(const RcString& core_name) const { return AST::Path(AST::Path::TagUfcs(), ::TypeRef(Span()), get_trait_path(core_name), { AST::PathNode("default", {}) } ); @@ -1491,10 +1478,10 @@ class Deriver_Hash: public Deriver { AST::Path get_trait_path(const RcString& core_name) const { - return AST::Path(core_name, { AST::PathNode("hash", {}), AST::PathNode("Hash", {}) }); + return get_path(core_name, "hash", "Hash"); } AST::Path get_trait_path_Hasher(const RcString& core_name) const { - return AST::Path(core_name, { AST::PathNode("hash", {}), AST::PathNode("Hasher", {}) }); + return get_path(core_name, "hash", "Hasher"); } AST::Path get_method_path(const RcString& core_name) const { return get_trait_path(core_name) + "hash"; @@ -1591,30 +1578,20 @@ public: ), (Tuple, ::std::vector pats_a; - ::std::vector nodes; - nodes.push_back( mv$(var_idx_hash) ); - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = RcString::new_interned(FMT("a" << idx)); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); - nodes.push_back( this->hash_val_direct(opts.core_name, NEWNODE(NamedValue, AST::Path(name_a))) ); - } + auto nodes = make_refpat_a(sp, pats_a, e.m_sub_types, [&](size_t , auto a) { + return this->hash_val_direct(opts.core_name, mv$(a)); + }); + nodes.insert(nodes.begin(), mv$(var_idx_hash)); pat_a = AST::Pattern(AST::Pattern::TagNamedTuple(), sp, base_path + v.m_name, mv$(pats_a)); code = NEWNODE(Block, mv$(nodes)); ), (Struct, ::std::vector< ::std::pair > pats_a; - ::std::vector< AST::ExprNodeP > nodes; - nodes.push_back( mv$(var_idx_hash) ); - - for( const auto& fld : e.m_fields ) - { - auto name_a = RcString::new_interned(FMT("a" << fld.m_name)); - pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF)) ); - nodes.push_back( this->hash_val_direct(opts.core_name, NEWNODE(NamedValue, AST::Path(name_a))) ); - } + auto nodes = make_refpat_a(sp, pats_a, e.m_fields, [&](size_t , auto a) { + return this->hash_val_direct(opts.core_name, mv$(a)); + }); + nodes.insert(nodes.begin(), mv$(var_idx_hash)); pat_a = AST::Pattern(AST::Pattern::TagStruct(), sp, base_path + v.m_name, mv$(pats_a), true); code = NEWNODE(Block, mv$(nodes)); @@ -1643,10 +1620,10 @@ class Deriver_RustcEncodable: { // NOTE: This emits paths like `::rustc_serialize::Encodable` - rustc and crates.io have subtly different crate names AST::Path get_trait_path() const { - return AST::Path("", { AST::PathNode("rustc_serialize", {}), AST::PathNode("Encodable", {}) }); + return get_path("", "rustc_serialize", "Encodable"); } AST::Path get_trait_path_Encoder() const { - return AST::Path("", { AST::PathNode("rustc_serialize", {}), AST::PathNode("Encoder", {}) }); + return get_path("", "rustc_serialize", "Encoder"); } AST::Path get_method_path() const { return get_trait_path() + "encode"; @@ -1656,7 +1633,7 @@ class Deriver_RustcEncodable: { const AST::Path trait_path = this->get_trait_path(); - AST::Path result_path = AST::Path(core_name, { AST::PathNode("result", {}), AST::PathNode("Result", {}) }); + AST::Path result_path = get_path(core_name, "result", "Result"); result_path.nodes()[1].args().m_types.push_back( TypeRef(TypeRef::TagUnit(), sp) ); result_path.nodes()[1].args().m_types.push_back(TypeRef( sp, AST::Path(AST::Path::TagUfcs(), TypeRef(sp, "S", 0x100|0), this->get_trait_path_Encoder(), { AST::PathNode("Error",{}) }) )); @@ -1703,7 +1680,7 @@ class Deriver_RustcEncodable: ); } AST::ExprNodeP get_val_ok(const RcString& core_name) const { - return NEWNODE(CallPath, AST::Path(core_name, {AST::PathNode("result",{}), AST::PathNode("Result",{}), AST::PathNode("Ok",{})}), vec$( NEWNODE(Tuple, {})) ); + return NEWNODE(CallPath, get_path(core_name, "result", "Result", "Ok"), vec$( NEWNODE(Tuple, {})) ); } public: @@ -1775,6 +1752,8 @@ public: base_path.nodes().back().args() = ::AST::PathParams(); ::std::vector arms; + auto s_ent = NEWNODE(NamedValue, AST::Path("s")); + for(unsigned int var_idx = 0; var_idx < enm.variants().size(); var_idx ++) { const auto& v = enm.variants()[var_idx]; @@ -1785,7 +1764,7 @@ public: (Value, code = NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum_variant", vec$( - NEWNODE(NamedValue, AST::Path("s")), + s_ent->clone(), NEWNODE(String, v.m_name.c_str()), NEWNODE(Integer, var_idx, CORETYPE_UINT), NEWNODE(Integer, 0, CORETYPE_UINT), @@ -1796,25 +1775,20 @@ public: ), (Tuple, ::std::vector pats_a; - ::std::vector nodes; - - for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) - { - auto name_a = RcString::new_interned(FMT("a" << idx)); - pats_a.push_back( ::AST::Pattern(::AST::Pattern::TagBind(), sp, name_a, ::AST::PatternBinding::Type::REF) ); - nodes.push_back( NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum_variant_arg", + auto nodes = make_refpat_a(sp, pats_a, e.m_sub_types, [&](size_t idx, auto a){ + return NEWNODE(CallPath, this->get_trait_path_Encoder() + RcString::new_interned("emit_enum_variant_arg"), vec$( - NEWNODE(NamedValue, AST::Path("s")), + s_ent->clone(), NEWNODE(Integer, idx, CORETYPE_UINT), - this->enc_closure(sp, this->enc_val_direct(NEWNODE(NamedValue, AST::Path(name_a)))) + this->enc_closure(sp, this->enc_val_direct(mv$(a))) ) - ) ); - } + ); + }); nodes.push_back( this->get_val_ok(opts.core_name) ); code = NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum_variant", vec$( - NEWNODE(NamedValue, AST::Path("s")), + s_ent->clone(), NEWNODE(String, v.m_name.c_str()), NEWNODE(Integer, var_idx, CORETYPE_UINT), NEWNODE(Integer, e.m_sub_types.size(), CORETYPE_UINT), @@ -1825,30 +1799,22 @@ public: ), (Struct, ::std::vector< ::std::pair > pats_a; - ::std::vector< AST::ExprNodeP > nodes; - - unsigned int idx = 0; - for( const auto& fld : e.m_fields ) - { - auto name_a = Ident( RcString::new_interned(FMT("a" << fld.m_name)) ); - pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), sp, Ident(name_a), ::AST::PatternBinding::Type::REF)) ); - - nodes.push_back( NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum_struct_variant_field", + auto nodes = make_refpat_a(sp, pats_a, e.m_fields, [&](size_t idx, auto a){ + return NEWNODE(CallPath, this->get_trait_path_Encoder() + RcString::new_interned("emit_enum_variant_arg"), vec$( - NEWNODE(NamedValue, AST::Path("s")), - NEWNODE(String, fld.m_name.c_str()), + s_ent->clone(), + NEWNODE(String, e.m_fields[idx].m_name.c_str()), NEWNODE(Integer, idx, CORETYPE_UINT), - this->enc_closure(sp, this->enc_val_direct(NEWNODE(NamedValue, AST::Path(name_a.name)))) + this->enc_closure(sp, this->enc_val_direct(mv$(a))) ) - ) ); - idx ++; - } + ); + }); nodes.push_back( this->get_val_ok(opts.core_name) ); pat_a = AST::Pattern(AST::Pattern::TagStruct(), sp, base_path + v.m_name, mv$(pats_a), true); code = NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum_struct_variant", vec$( - NEWNODE(NamedValue, AST::Path("s")), + s_ent->clone(), NEWNODE(String, v.m_name.c_str()), NEWNODE(Integer, var_idx, CORETYPE_UINT), NEWNODE(Integer, e.m_fields.size(), CORETYPE_UINT), @@ -1872,7 +1838,7 @@ public: ::std::string enum_name = type.m_data.as_Path().path.nodes().back().name().c_str(); auto node = NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_enum", - vec$( NEWNODE(NamedValue, AST::Path("s")), NEWNODE(String, enum_name), this->enc_closure(sp, mv$(node_match)) ) + vec$( mv$(s_ent), NEWNODE(String, enum_name), this->enc_closure(sp, mv$(node_match)) ) ); return this->make_ret(sp, opts.core_name, p, type, this->get_field_bounds(enm), mv$(node)); @@ -1884,10 +1850,10 @@ class Deriver_RustcDecodable: { // NOTE: This emits paths like `::rustc_serialize::Encodable` - rustc and crates.io have subtly different crate names AST::Path get_trait_path() const { - return AST::Path("", { AST::PathNode("rustc_serialize", {}), AST::PathNode("Decodable", {}) }); + return get_path("", "rustc_serialize", "Decodable"); } AST::Path get_trait_path_Decoder() const { - return AST::Path("", { AST::PathNode("rustc_serialize", {}), AST::PathNode("Decoder", {}) }); + return get_path("", "rustc_serialize", "Decoder"); } AST::Path get_method_path() const { return get_trait_path() + "decode"; @@ -1897,7 +1863,7 @@ class Deriver_RustcDecodable: { const AST::Path trait_path = this->get_trait_path(); - AST::Path result_path = AST::Path(core_name, { AST::PathNode(RcString::new_interned("result"), {}), AST::PathNode(RcString::new_interned("Result"), {}) }); + AST::Path result_path = get_path(core_name, "result", "Result"); result_path.nodes()[1].args().m_types.push_back( TypeRef(sp, "Self", 0xFFFF) ); result_path.nodes()[1].args().m_types.push_back( TypeRef(sp, AST::Path(AST::Path::TagUfcs(), TypeRef(sp, "D", 0x100|0), this->get_trait_path_Decoder(), { AST::PathNode("Error",{}) })) ); @@ -2039,7 +2005,6 @@ public: for( unsigned int idx = 0; idx < e.m_sub_types.size(); idx ++ ) { - auto name_a = FMT("a" << idx); args.push_back( NEWNODE(UniOp, ::AST::ExprNode_UniOp::QMARK, NEWNODE(CallPath, this->get_trait_path_Decoder() + "read_enum_variant_arg", vec$( NEWNODE(NamedValue, AST::Path("d")), @@ -2056,8 +2021,6 @@ public: unsigned int idx = 0; for( const auto& fld : e.m_fields ) { - auto name_a = FMT("a" << fld.m_name); - vals.push_back({ {}, fld.m_name, NEWNODE(UniOp, ::AST::ExprNode_UniOp::QMARK, NEWNODE(CallPath, this->get_trait_path_Decoder() + "read_enum_struct_variant_field", vec$( NEWNODE(NamedValue, AST::Path("d")), diff --git a/src/include/rc_string.hpp b/src/include/rc_string.hpp index 2177e614..0d6ab155 100644 --- a/src/include/rc_string.hpp +++ b/src/include/rc_string.hpp @@ -29,7 +29,7 @@ public: } static RcString new_interned(const ::std::string& s); - //static new_interned(const char* s); + static RcString new_interned(const char* s); RcString(const RcString& x): m_ptr(x.m_ptr) diff --git a/src/rc_string.cpp b/src/rc_string.cpp index 123b4254..38f6b15d 100644 --- a/src/rc_string.cpp +++ b/src/rc_string.cpp @@ -91,6 +91,22 @@ RcString RcString::new_interned(const ::std::string& s) return *it; #else // TODO: interning flag, so comparisons can just be a pointer comparison + // - Only want to set this flag on the cached instance + return *RcString_interned_strings.insert(RcString(s)).first; +#endif +} +RcString RcString::new_interned(const char* s) +{ +#if 0 + auto it = RcString_interned_strings.find(s); + if( it == RcString_interned_strings.end() ) + { + it = RcString_interned_strings.insert(RcString(s)).first; + } + return *it; +#else + // TODO: interning flag, so comparisons can just be a pointer comparison + // - Only want to set this flag on the cached instance return *RcString_interned_strings.insert(RcString(s)).first; #endif } -- cgit v1.2.3 From 9ce35b65e5be4ce75b3b7aabe29c432128a17279 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 26 Oct 2019 16:09:24 +0800 Subject: All - Compilation fixes on VS2015 (constructors, warnings, missing files, class/struct disagreement, ) --- src/ast/crate.cpp | 38 ++++++++++++++++++---- src/hir/from_ast.cpp | 4 +-- src/hir/hir.hpp | 16 +++++++++ src/hir/type.hpp | 9 +++++ src/hir_expand/vtable.cpp | 11 +++---- src/hir_typeck/expr_visit.cpp | 7 ++++ src/include/span.hpp | 3 +- src/macro_rules/parse.cpp | 6 ++-- src/mir/from_hir.cpp | 1 + src/mir/mir.cpp | 1 + src/mir/mir.hpp | 2 +- src/rc_string.cpp | 1 + tools/standalone_miri/hir_sim.cpp | 2 ++ tools/standalone_miri/mir.cpp | 1 + tools/standalone_miri/miri.cpp | 13 ++++---- tools/standalone_miri/value.hpp | 5 ++- tools/testrunner/main.cpp | 3 ++ vsproject/minicargo/minicargo.vcxproj | 9 +++++ vsproject/minicargo/minicargo.vcxproj.filters | 3 ++ vsproject/mrustc.vcxproj | 7 ++-- vsproject/mrustc.vcxproj.filters | 21 ++++++++---- vsproject/standalone_miri/standalone_miri.vcxproj | 9 +++-- .../standalone_miri.vcxproj.filters | 3 ++ 23 files changed, 138 insertions(+), 37 deletions(-) (limited to 'src/rc_string.cpp') diff --git a/src/ast/crate.cpp b/src/ast/crate.cpp index e788f6e0..19a19381 100644 --- a/src/ast/crate.cpp +++ b/src/ast/crate.cpp @@ -12,7 +12,12 @@ #include // HIR::Crate #include // HIR_Deserialise #include -#include +#ifdef _WIN32 +# define NOGDI // prevent ERROR from being defined +# include +#else +# include +#endif ::std::vector<::std::string> AST::g_crate_load_dirs = { }; ::std::map<::std::string, ::std::string> AST::g_crate_overrides; @@ -167,6 +172,17 @@ RcString Crate::load_extern_crate(Span sp, const RcString& name, const ::std::st path = ""; // Search for `p+"/lib"+name+"-*.rlib" (which would match e.g. libnum-0.11.rlib) +#ifdef _WIN32 + WIN32_FIND_DATA find_data; + auto mask = p + "\\*"; + HANDLE find_handle = FindFirstFile( mask.c_str(), &find_data ); + if( find_handle == INVALID_HANDLE_VALUE ) { + continue ; + } + do + { + const auto* fname = find_data.cFileName; +#else auto dp = opendir(p.c_str()); if( !dp ) { continue ; @@ -174,12 +190,15 @@ RcString Crate::load_extern_crate(Span sp, const RcString& name, const ::std::st struct dirent *ent; while( (ent = readdir(dp)) != nullptr && path == "" ) { + const auto* fname = ent->d_name; +#endif + // AND the start is "lib"+name - size_t len = strlen(ent->d_name); - if( len > (sizeof(RLIB_SUFFIX)-1) && strcmp(ent->d_name + len - (sizeof(RLIB_SUFFIX)-1), RLIB_SUFFIX) == 0 ) + size_t len = strlen(fname); + if( len > (sizeof(RLIB_SUFFIX)-1) && strcmp(fname + len - (sizeof(RLIB_SUFFIX)-1), RLIB_SUFFIX) == 0 ) { } - else if( len > (sizeof(RDYLIB_SUFFIX)-1) && strcmp(ent->d_name + len - (sizeof(RDYLIB_SUFFIX)-1), RDYLIB_SUFFIX) == 0 ) + else if( len > (sizeof(RDYLIB_SUFFIX)-1) && strcmp(fname + len - (sizeof(RDYLIB_SUFFIX)-1), RDYLIB_SUFFIX) == 0 ) { } else @@ -187,14 +206,19 @@ RcString Crate::load_extern_crate(Span sp, const RcString& name, const ::std::st continue ; } - DEBUG(ent->d_name << " vs " << name_prefix); + DEBUG(fname << " vs " << name_prefix); // Check if the entry ends with .rlib - if( strncmp(name_prefix.c_str(), ent->d_name, name_prefix.size()) != 0 ) + if( strncmp(name_prefix.c_str(), fname, name_prefix.size()) != 0 ) continue ; - paths.push_back( p + "/" + ent->d_name ); + paths.push_back( p + "/" + fname ); +#ifdef _WIN32 + } while( FindNextFile(find_handle, &find_data) ); + FindClose(find_handle); +#else } closedir(dp); +#endif if( paths.size() > 0 ) break; } diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 54644806..4cde40fc 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -31,10 +31,10 @@ const ::AST::Crate* g_ast_crate_ptr; // -------------------------------------------------------------------- HIR::LifetimeRef LowerHIR_LifetimeRef(const ::AST::LifetimeRef& r) { - return HIR::LifetimeRef { + return HIR::LifetimeRef( // TODO: names? r.binding() - }; + ); } ::HIR::GenericParams LowerHIR_GenericParams(const ::AST::GenericParams& gp, bool* self_is_sized) diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index bdfc8d0b..8b718b4f 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -323,6 +323,22 @@ public: (Named, t_struct_fields) ); + Struct(GenericParams params, Repr repr, Data data) + :m_params(mv$(params)) + ,m_repr(mv$(repr)) + ,m_data(mv$(data)) + { + } + Struct(GenericParams params, Repr repr, Data data, unsigned align, TraitMarkings tm, StructMarkings sm) + :m_params(mv$(params)) + ,m_repr(mv$(repr)) + ,m_data(mv$(data)) + ,m_forced_alignment(align) + ,m_markings(mv$(tm)) + ,m_struct_markings(mv$(sm)) + { + } + GenericParams m_params; Repr m_repr; Data m_data; diff --git a/src/hir/type.hpp b/src/hir/type.hpp index fe28deed..cbc2e94a 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -93,6 +93,15 @@ struct LifetimeRef // Values below 2^16 are parameters/static, values above are per-function region IDs allocated during region inferrence. uint32_t binding = UNKNOWN; + LifetimeRef() + :binding(UNKNOWN) + { + } + LifetimeRef(uint32_t binding) + :binding(binding) + { + } + static LifetimeRef new_static() { LifetimeRef rv; rv.binding = STATIC; diff --git a/src/hir_expand/vtable.cpp b/src/hir_expand/vtable.cpp index cd7b3413..d2afff5d 100644 --- a/src/hir_expand/vtable.cpp +++ b/src/hir_expand/vtable.cpp @@ -231,12 +231,11 @@ namespace { } } // TODO: Would like to have access to the publicity marker - auto item_path = m_new_type(true, RcString::new_interned(FMT(p.get_name() << "#vtable")), ::HIR::Struct { - mv$(args), - ::HIR::Struct::Repr::Rust, - ::HIR::Struct::Data(mv$(fields)), - {} - }); + auto item_path = m_new_type( + true, + RcString::new_interned(FMT(p.get_name() << "#vtable")), + ::HIR::Struct(mv$(args), ::HIR::Struct::Repr::Rust, ::HIR::Struct::Data(mv$(fields))) + ); tr.m_vtable_path = item_path; DEBUG("Vtable structure created - " << item_path); ::HIR::GenericPath path( mv$(item_path), mv$(params) ); diff --git a/src/hir_typeck/expr_visit.cpp b/src/hir_typeck/expr_visit.cpp index c655bc52..df27b7d7 100644 --- a/src/hir_typeck/expr_visit.cpp +++ b/src/hir_typeck/expr_visit.cpp @@ -65,6 +65,12 @@ namespace typeck { TU_ARMA(Function, e) { m_item_generics = &e.m_params; } + TU_ARMA(Constant, e) { + m_item_generics = &e.m_params; + } + TU_ARMA(Static, e) { + m_item_generics = nullptr; + } } } else if( ip.parent->ty ) @@ -91,6 +97,7 @@ namespace typeck { } TU_ARMA(StructConstant, _e) BUG(sp, ip << " is StructConstant"); TU_ARMA(StructConstructor, _e) BUG(sp, ip << " is StructConstructor"); + TU_ARMA(Import, _e) BUG(sp, ip << " is Import"); } } } diff --git a/src/include/span.hpp b/src/include/span.hpp index 68d6bfdf..51c3440c 100644 --- a/src/include/span.hpp +++ b/src/include/span.hpp @@ -29,8 +29,9 @@ struct ProtoSpan unsigned int start_line; unsigned int start_ofs; }; -struct Span +class Span { +public: ::std::shared_ptr outer_span; // Expansion target for macros RcString filename; diff --git a/src/macro_rules/parse.cpp b/src/macro_rules/parse.cpp index 97e1f8f9..43ffb097 100644 --- a/src/macro_rules/parse.cpp +++ b/src/macro_rules/parse.cpp @@ -58,7 +58,9 @@ public: switch( GET_TOK(tok, lex) ) { // TODO: Allow any reserved word - case TOK_RWORD_PUB ... TOK_RWORD_UNSIZED: + default: + if( !(TOK_RWORD_PUB <= tok.type() && tok.type() <= TOK_RWORD_UNSIZED) ) + throw ParseError::Unexpected(lex, tok); case TOK_IDENT: { auto name = tok.type() == TOK_IDENT ? tok.istr() : RcString::new_interned(FMT(tok)); GET_CHECK_TOK(tok, lex, TOK_COLON); @@ -123,8 +125,6 @@ public: throw ParseError::Unexpected(lex, tok); } break; } - default: - throw ParseError::Unexpected(lex, tok); } break; case TOK_EOF: diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 4ab1bf00..697f8141 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -19,6 +19,7 @@ #include #include #include // Target_GetSizeAndAlignOf - for `box` +#include // isdigit namespace { diff --git a/src/mir/mir.cpp b/src/mir/mir.cpp index 8e3045d6..a0def040 100644 --- a/src/mir/mir.cpp +++ b/src/mir/mir.cpp @@ -6,6 +6,7 @@ * - MIR (Middle Intermediate Representation) definitions */ #include +#include // std::min namespace MIR { ::std::ostream& operator<<(::std::ostream& os, const Constant& v) { diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp index f3d61dfa..99698134 100644 --- a/src/mir/mir.hpp +++ b/src/mir/mir.hpp @@ -655,7 +655,7 @@ public: ~EnumCachePtr(); EnumCachePtr(EnumCachePtr&& x): p(x.p) { x.p = nullptr; } EnumCachePtr& operator=(EnumCachePtr&& x) { this->~EnumCachePtr(); p = x.p; x.p = nullptr; return *this; } - operator bool() { return p; } + operator bool() { return p != nullptr; } const EnumCache& operator*() const { return *p; } const EnumCache* operator->() const { return p; } }; diff --git a/src/rc_string.cpp b/src/rc_string.cpp index 38f6b15d..260ba90a 100644 --- a/src/rc_string.cpp +++ b/src/rc_string.cpp @@ -9,6 +9,7 @@ #include #include #include +#include // std::max RcString::RcString(const char* s, unsigned int len): m_ptr(nullptr) diff --git a/tools/standalone_miri/hir_sim.cpp b/tools/standalone_miri/hir_sim.cpp index 135ea214..9d497054 100644 --- a/tools/standalone_miri/hir_sim.cpp +++ b/tools/standalone_miri/hir_sim.cpp @@ -156,6 +156,8 @@ size_t HIR::TypeRef::get_align(size_t ofs) const case RawType::USize: case RawType::ISize: return POINTER_SIZE; + case RawType::Unreachable: + LOG_BUG("Getting alignment of unreachable type"); } throw ""; } diff --git a/tools/standalone_miri/mir.cpp b/tools/standalone_miri/mir.cpp index 4a5df067..bc456ca6 100644 --- a/tools/standalone_miri/mir.cpp +++ b/tools/standalone_miri/mir.cpp @@ -9,6 +9,7 @@ #include "../../src/mir/mir.hpp" #include "hir_sim.hpp" #include +#include // std::min #if 0 namespace std { diff --git a/tools/standalone_miri/miri.cpp b/tools/standalone_miri/miri.cpp index 21c39a1e..4eadac66 100644 --- a/tools/standalone_miri/miri.cpp +++ b/tools/standalone_miri/miri.cpp @@ -5,6 +5,7 @@ * miri.cpp * - Interpreter core */ +#define _CRT_SECURE_NO_WARNINGS #include #include "module_tree.hpp" #include "value.hpp" @@ -15,13 +16,14 @@ #include "miri.hpp" // VVV FFI #include // memrchr +#include +#include #ifdef _WIN32 # define NOMINMAX # include +#else +# include #endif -#include -#include -#include #undef DEBUG unsigned ThreadState::s_next_tls_key = 1; @@ -2082,7 +2084,6 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c } else if( link_name == "GetModuleHandleW" ) { - LOG_ASSERT(args.at(0).allocation, ""); const auto& tgt_alloc = args.at(0).get_relocation(0); const void* arg0 = (tgt_alloc ? tgt_alloc.alloc().data_ptr() : nullptr); //extern void* GetModuleHandleW(const void* s); @@ -2096,7 +2097,7 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c auto ret = GetModuleHandleW(static_cast(arg0)); if(ret) { - rv = Value::new_ffiptr(FFIPointer { "GetModuleHandleW", ret, 0 }); + rv = Value::new_ffiptr(FFIPointer::new_void("GetModuleHandleW", ret)); } else { @@ -2121,7 +2122,7 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c if( ret ) { - rv = Value::new_ffiptr(FFIPointer { "GetProcAddress", ret, 0 }); + rv = Value::new_ffiptr(FFIPointer::new_void("GetProcAddress", ret)); } else { diff --git a/tools/standalone_miri/value.hpp b/tools/standalone_miri/value.hpp index a76e922b..03a21970 100644 --- a/tools/standalone_miri/value.hpp +++ b/tools/standalone_miri/value.hpp @@ -57,6 +57,9 @@ struct FFIPointer const char* tag_name; ::std::shared_ptr layout; + static FFIPointer new_void(const char* name, const void* v) { + return FFIPointer { const_cast(v), name, ::std::make_shared() }; + } static FFIPointer new_const_bytes(const char* name, const void* s, size_t size) { return FFIPointer { const_cast(s), name, ::std::make_shared(FfiLayout::new_const_bytes(size)) }; }; @@ -511,7 +514,7 @@ struct ValueRef: LOG_NOTICE("ValueRef exceeds bounds of FFI buffer - " << ofs << "+" << size << " > " << m_alloc.ffi().get_size()); } break; - default: + case RelocationPtr::Ty::Function: LOG_TODO(""); } } diff --git a/tools/testrunner/main.cpp b/tools/testrunner/main.cpp index 148fff9d..a634d87a 100644 --- a/tools/testrunner/main.cpp +++ b/tools/testrunner/main.cpp @@ -170,12 +170,15 @@ int main(int argc, const char* argv[]) return v; } +#ifdef _WIN32 +#else { struct sigaction sa = {0}; sa.sa_handler = sigalrm_handler; sigaction(SIGALRM, &sa, NULL); signal(SIGINT, sigint_handler); } +#endif ::std::vector<::std::string> skip_list; // > Filter out tests listed in an exceptions file (newline separated, supports comments) diff --git a/vsproject/minicargo/minicargo.vcxproj b/vsproject/minicargo/minicargo.vcxproj index 25ffbe03..c632cee2 100644 --- a/vsproject/minicargo/minicargo.vcxproj +++ b/vsproject/minicargo/minicargo.vcxproj @@ -75,6 +75,8 @@ Disabled true ..\..\tools\common + + $(OutDir) @@ -87,6 +89,8 @@ Disabled true ..\..\tools\common + + $(OutDir) @@ -101,6 +105,8 @@ true true ..\..\tools\common + + true @@ -117,6 +123,8 @@ true true ..\..\tools\common + + true @@ -127,6 +135,7 @@ + diff --git a/vsproject/minicargo/minicargo.vcxproj.filters b/vsproject/minicargo/minicargo.vcxproj.filters index 8fcee797..b9066a85 100644 --- a/vsproject/minicargo/minicargo.vcxproj.filters +++ b/vsproject/minicargo/minicargo.vcxproj.filters @@ -27,6 +27,9 @@ Source Files + + Source Files + diff --git a/vsproject/mrustc.vcxproj b/vsproject/mrustc.vcxproj index 13c4a23e..6cd135f4 100644 --- a/vsproject/mrustc.vcxproj +++ b/vsproject/mrustc.vcxproj @@ -157,6 +157,8 @@ + + @@ -166,6 +168,7 @@ + @@ -193,6 +196,7 @@ + @@ -204,9 +208,9 @@ + - @@ -259,7 +263,6 @@ - diff --git a/vsproject/mrustc.vcxproj.filters b/vsproject/mrustc.vcxproj.filters index 755013af..9d9dbcb4 100644 --- a/vsproject/mrustc.vcxproj.filters +++ b/vsproject/mrustc.vcxproj.filters @@ -98,9 +98,6 @@ Source Files\hir_expand - - Source Files\hir_expand - Source Files\hir_conv @@ -212,9 +209,6 @@ Source Files\trans - - Source Files\trans - Source Files\expand @@ -392,6 +386,21 @@ Source Files + + Source Files\trans + + + Source Files\trans + + + Source Files\hir_conv + + + Source Files\hir + + + Source Files\expand + diff --git a/vsproject/standalone_miri/standalone_miri.vcxproj b/vsproject/standalone_miri/standalone_miri.vcxproj index 5c235353..6b3c317c 100644 --- a/vsproject/standalone_miri/standalone_miri.vcxproj +++ b/vsproject/standalone_miri/standalone_miri.vcxproj @@ -90,7 +90,8 @@ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(SolutionDir)..\src\include;$(SolutionDir)..\tools\standalone_miri;%(AdditionalIncludeDirectories) - 4062;4061;%(TreatSpecificWarningsAsErrors) + 4062;%(TreatSpecificWarningsAsErrors) + 4061 Console @@ -106,7 +107,8 @@ _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(SolutionDir)..\src\include;$(SolutionDir)..\tools\standalone_miri;%(AdditionalIncludeDirectories) - 4062;4061;%(TreatSpecificWarningsAsErrors) + 4062;%(TreatSpecificWarningsAsErrors) + 4061 Console @@ -125,6 +127,7 @@ true $(SolutionDir)..\src\include;$(SolutionDir)..\tools\standalone_miri;%(AdditionalIncludeDirectories) 4062;%(TreatSpecificWarningsAsErrors) + 4061 Console @@ -145,6 +148,7 @@ true $(SolutionDir)..\src\include;$(SolutionDir)..\tools\standalone_miri;%(AdditionalIncludeDirectories) 4062;%(TreatSpecificWarningsAsErrors) + 4061 Console @@ -165,6 +169,7 @@ + diff --git a/vsproject/standalone_miri/standalone_miri.vcxproj.filters b/vsproject/standalone_miri/standalone_miri.vcxproj.filters index 3b25bbfb..5e7af341 100644 --- a/vsproject/standalone_miri/standalone_miri.vcxproj.filters +++ b/vsproject/standalone_miri/standalone_miri.vcxproj.filters @@ -62,5 +62,8 @@ Source Files + + Source Files + \ No newline at end of file -- cgit v1.2.3