From afd9fe2cc7f43fd036837db10e71b04410fadf9a Mon Sep 17 00:00:00 2001 From: John Hodge Date: Wed, 18 Mar 2015 14:02:00 +0800 Subject: '..' pattern, fix macro arg lookup comparison function --- src/ast/pattern.hpp | 7 +++ src/common.hpp | 22 +++++++++ src/macros.cpp | 18 ++++++-- src/parse/expr.cpp | 4 +- src/parse/root.cpp | 127 ++++++++++++++++++++++++++++++++-------------------- 5 files changed, 125 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/ast/pattern.hpp b/src/ast/pattern.hpp index 7544d53c..a2f9a24b 100644 --- a/src/ast/pattern.hpp +++ b/src/ast/pattern.hpp @@ -69,6 +69,13 @@ public: m_class(ANY) {} + // Wildcard = '..', distinct from '_' + // TODO: Store wildcard as a different pattern type + struct TagWildcard {}; + Pattern(TagWildcard): + m_class(ANY) + {} + struct TagBind {}; Pattern(TagBind, ::std::string name): m_class(ANY), diff --git a/src/common.hpp b/src/common.hpp index 545a0adf..01c710b9 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -61,6 +61,12 @@ inline ::std::ostream& operator<<(::std::ostream& os, const ::std::vector& v) return os; } +template +inline ::std::ostream& operator<<(::std::ostream& os, const ::std::pair& v) { + os << "(" << v.first << ", " << v.second << ")"; + return os; +} + template inline ::std::ostream& operator<<(::std::ostream& os, const ::std::map& v) { if( v.size() > 0 ) @@ -77,6 +83,22 @@ inline ::std::ostream& operator<<(::std::ostream& os, const ::std::map& v) return os; } +template +inline ::std::ostream& operator<<(::std::ostream& os, const ::std::multimap& v) { + if( v.size() > 0 ) + { + bool is_first = true; + for( const auto& i : v ) + { + if(!is_first) + os << ", "; + is_first = false; + os << i.first << ": " << i.second; + } + } + return os; +} + } #endif diff --git a/src/macros.cpp b/src/macros.cpp index 3b6147e3..45175620 100644 --- a/src/macros.cpp +++ b/src/macros.cpp @@ -27,7 +27,13 @@ public: struct cmp_mk { bool operator()(const t_mapping_key& a, const t_mapping_key& b) const { - return a.first < b.first || ::std::strcmp(a.second, b.second) < 0; + if( a.first < b.first ) + return true; + if( a.first == b.first ) { + if( ::std::strcmp(a.second, b.second) < 0 ) + return true; + } + return false; } }; typedef ::std::multimap t_mappings; @@ -281,6 +287,10 @@ void Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, unsigned int lay //GET_CHECK_TOK(tok, lex, close); GET_CHECK_TOK(tok, lex, TOK_EOF); DEBUG( rule.m_contents.size() << " rule contents bound to " << bound_tts.size() << " values - " << name ); + for( const auto& v : bound_tts ) + { + DEBUG("- " << v.first.first << "#" << v.first.second << " = [" << v.second << "]"); + } return ::std::unique_ptr( (TokenStream*)new MacroExpander(olex, rule.m_contents, bound_tts, g_crate_path_tt) ); } catch(const ParseError::Base& e) @@ -399,9 +409,11 @@ Token MacroExpander::realGetToken() { // - Name const size_t iter_idx = m_offsets.back().second; + DEBUG("m_mappings = " << m_mappings); const auto tt_i = m_mappings.equal_range( ::std::make_pair(layer, ent.name.c_str()) ); - if( tt_i.first == tt_i.second ) - throw ParseError::Generic( FMT("Cannot find mapping name: " << ent.name << " for layer " << layer) ); + if( tt_i.first == tt_i.second ) { + throw ParseError::Generic(*this, FMT("Cannot find mapping name: " << ent.name << " for layer " << layer) ); + } size_t i = 0; for( auto it = tt_i.first; it != tt_i.second; it ++ ) diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 88bb021f..e568bcbb 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -160,6 +160,8 @@ AST::Pattern Parse_PatternReal1(TokenStream& lex) { case TOK_UNDERSCORE: return AST::Pattern( ); + case TOK_DOUBLE_DOT: + return AST::Pattern( AST::Pattern::TagWildcard() ); case TOK_AMP: DEBUG("Ref"); if( GET_TOK(tok, lex) == TOK_RWORD_MUT ) @@ -326,8 +328,6 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex) /// - use/extern/const/let ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *expect_end) { - TRACE_FUNCTION; - Token tok; if( GET_TOK(tok, lex) == TOK_LIFETIME ) diff --git a/src/parse/root.cpp b/src/parse/root.cpp index acd0e9e9..e721017a 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -607,7 +607,6 @@ AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, AST::MetaIt AST::Function Parse_FunctionDefWithCode(TokenStream& lex, ::std::string abi, AST::MetaItems attrs, bool allow_self) { - TRACE_FUNCTION; Token tok; auto ret = Parse_FunctionDef(lex, abi, ::std::move(attrs), allow_self, false); GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN); @@ -946,6 +945,9 @@ AST::MetaItem Parse_MetaItem(TokenStream& lex) } } +AST::Impl Parse_Impl(TokenStream& lex, bool is_unsafe/*=false*/); +void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl); + AST::Impl Parse_Impl(TokenStream& lex, bool is_unsafe/*=false*/) { TRACE_FUNCTION; @@ -1018,59 +1020,88 @@ AST::Impl Parse_Impl(TokenStream& lex, bool is_unsafe/*=false*/) // A sequence of method implementations while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE ) { - AST::MetaItems item_attrs; - while( tok.type() == TOK_ATTR_OPEN ) + lex.putback(tok); + Parse_Impl_Item(lex, impl); + } + + return impl; +} + +void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) +{ + Token tok; + + GET_TOK(tok, lex); + + AST::MetaItems item_attrs; + while( tok.type() == TOK_ATTR_OPEN ) + { + item_attrs.push_back( Parse_MetaItem(lex) ); + GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE); + GET_TOK(tok, lex); + } + + bool is_public = false; + if(tok.type() == TOK_RWORD_PUB) { + is_public = true; + GET_TOK(tok, lex); + } + + if(tok.type() == TOK_RWORD_UNSAFE) { + item_attrs.push_back( AST::MetaItem("#UNSAFE") ); + GET_TOK(tok, lex); + } + + ::std::string abi = "rust"; + switch(tok.type()) + { + case TOK_MACRO: { - item_attrs.push_back( Parse_MetaItem(lex) ); - GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE); - GET_TOK(tok, lex); - } - - bool is_public = false; - if(tok.type() == TOK_RWORD_PUB) { - is_public = true; - GET_TOK(tok, lex); + TokenTree tt = Parse_TT(lex, true); + if( tt.is_token() ) { + DEBUG("TT was a single token (not a sub-tree)"); + throw ParseError::Unexpected(lex, tt.tok()); + } + + auto expanded_macro = Macro_Invoke(lex, tok.str().c_str(), tt); + auto& lex = *expanded_macro; + while( GET_TOK(tok, lex) != TOK_EOF ) + { + lex.putback(tok); + Parse_Impl_Item(lex, impl); + } } - - if(tok.type() == TOK_RWORD_UNSAFE) { - item_attrs.push_back( AST::MetaItem("#UNSAFE") ); + if(GET_TOK(tok, lex) != TOK_SEMICOLON) + lex.putback(tok); + break; + case TOK_RWORD_TYPE: { + GET_CHECK_TOK(tok, lex, TOK_IDENT); + ::std::string name = tok.str(); + GET_CHECK_TOK(tok, lex, TOK_EQUAL); + impl.add_type(is_public, name, Parse_Type(lex)); + GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); + break; } + case TOK_RWORD_EXTERN: + { + abi = "C"; + if( GET_TOK(tok, lex) == TOK_STRING ) + abi = tok.str(); + else + lex.putback(tok); + GET_TOK(tok, lex); } - - ::std::string abi = "rust"; - switch(tok.type()) - { - case TOK_RWORD_TYPE: { - GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string name = tok.str(); - GET_CHECK_TOK(tok, lex, TOK_EQUAL); - impl.add_type(is_public, name, Parse_Type(lex)); - GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); - break; } - case TOK_RWORD_EXTERN: - { - abi = "C"; - if( GET_TOK(tok, lex) == TOK_STRING ) - abi = tok.str(); - else - lex.putback(tok); - - GET_TOK(tok, lex); - } - CHECK_TOK(tok, TOK_RWORD_FN); - case TOK_RWORD_FN: { - GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string name = tok.str(); - // - Self allowed, can't be prototype-form - impl.add_function(is_public, ::std::move(name), Parse_FunctionDefWithCode(lex, abi, ::std::move(item_attrs), true)); - break; } + CHECK_TOK(tok, TOK_RWORD_FN); + case TOK_RWORD_FN: { + GET_CHECK_TOK(tok, lex, TOK_IDENT); + ::std::string name = tok.str(); + // - Self allowed, can't be prototype-form + impl.add_function(is_public, ::std::move(name), Parse_FunctionDefWithCode(lex, abi, ::std::move(item_attrs), true)); + break; } - default: - throw ParseError::Unexpected(lex, tok); - } + default: + throw ParseError::Unexpected(lex, tok); } - - return impl; } void Parse_ExternBlock(TokenStream& lex, AST::Module& mod, ::std::string abi) -- cgit v1.2.3