diff options
Diffstat (limited to 'src/parse')
-rw-r--r-- | src/parse/expr.cpp | 13 | ||||
-rw-r--r-- | src/parse/lex.cpp | 16 | ||||
-rw-r--r-- | src/parse/root.cpp | 9 | ||||
-rw-r--r-- | src/parse/token.cpp | 10 |
4 files changed, 32 insertions, 16 deletions
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 6227dca4..6dd9bd75 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -119,6 +119,16 @@ ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptr<AST: Parse_Mod_Item(lex, *local_mod, mv$(item_attrs)); return ExprNodeP(); } + + if( tok.type() == TOK_MACRO && tok.str() == "macro_rules" ) + { + // Special case - create a local module if macro_rules! is seen + // - Allows correct scoping of defined macros + if( !local_mod ) { + local_mod = lex.parse_state().get_current_mod().add_anon(); + } + } + switch(tok.type()) { // Items: @@ -669,6 +679,9 @@ bool Parse_IsTokValue(eTokenType tok_type) case TOK_PAREN_OPEN: case TOK_SQUARE_OPEN: + case TOK_INTERPOLATED_PATH: + case TOK_INTERPOLATED_EXPR: + case TOK_MACRO: case TOK_PIPE: diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index caa640f9..3c4bd795 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -860,9 +860,13 @@ uint32_t Lexer::parseEscape(char enclosing) case '\n': while( ch.isspace() ) ch = this->getc(); - this->ungetc(); - if( ch == enclosing ) + if(ch == '\\' ) + return parseEscape(enclosing); + else if( ch == enclosing ) + { + this->ungetc(); return ~0; + } else return ch.v; default: @@ -1009,12 +1013,12 @@ bool Codepoint::isxdigit() const { s += (char)(0xC0 | ((cp.v >> 6) & 0x1F)); s += (char)(0x80 | ((cp.v >> 0) & 0x3F)); } - else if( cp.v <= (0x0F+1)<<(2*6) ) { + else if( cp.v < (0x0F+1)<<(2*6) ) { s += (char)(0xE0 | ((cp.v >> 12) & 0x0F)); s += (char)(0x80 | ((cp.v >> 6) & 0x3F)); s += (char)(0x80 | ((cp.v >> 0) & 0x3F)); } - else if( cp.v <= (0x07+1)<<(3*6) ) { + else if( cp.v < (0x07+1)<<(3*6) ) { s += (char)(0xF0 | ((cp.v >> 18) & 0x07)); s += (char)(0x80 | ((cp.v >> 12) & 0x3F)); s += (char)(0x80 | ((cp.v >> 6) & 0x3F)); @@ -1034,12 +1038,12 @@ bool Codepoint::isxdigit() const { os << (char)(0xC0 | ((cp.v >> 6) & 0x1F)); os << (char)(0x80 | ((cp.v >> 0) & 0x3F)); } - else if( cp.v <= (0x0F+1)<<(2*6) ) { + else if( cp.v < (0x0F+1)<<(2*6) ) { os << (char)(0xE0 | ((cp.v >> 12) & 0x0F)); os << (char)(0x80 | ((cp.v >> 6) & 0x3F)); os << (char)(0x80 | ((cp.v >> 0) & 0x3F)); } - else if( cp.v <= (0x07+1)<<(2*6) ) { + else if( cp.v < (0x07+1)<<(2*6) ) { os << (char)(0xF0 | ((cp.v >> 18) & 0x07)); os << (char)(0x80 | ((cp.v >> 12) & 0x3F)); os << (char)(0x80 | ((cp.v >> 6) & 0x3F)); diff --git a/src/parse/root.cpp b/src/parse/root.cpp index aefd5a13..d40e1f95 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -44,13 +44,13 @@ AST::MetaItem Parse_MetaItem(TokenStream& lex); void Parse_ModRoot(TokenStream& lex, AST::Module& mod, AST::MetaItems& mod_attrs); //::AST::Path Parse_Publicity(TokenStream& lex) -bool Parse_Publicity(TokenStream& lex) +bool Parse_Publicity(TokenStream& lex, bool allow_restricted=true) { Token tok; if( LOOK_AHEAD(lex) == TOK_RWORD_PUB ) { GET_TOK(tok, lex); - if( LOOK_AHEAD(lex) == TOK_PAREN_OPEN ) + if( allow_restricted && LOOK_AHEAD(lex) == TOK_PAREN_OPEN ) { auto path = AST::Path("", {}); // Restricted publicity. @@ -541,7 +541,7 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems& meta_items) SET_ATTRS(lex, item_attrs); PUTBACK(tok, lex); - bool is_pub = Parse_Publicity(lex); + bool is_pub = Parse_Publicity(lex, /*allow_restricted=*/false); // HACK: Disable `pub(restricted)` syntax in tuple structs, due to ambiguity refs.push_back( AST::TupleItem( mv$(item_attrs), is_pub, Parse_Type(lex) ) ); if( GET_TOK(tok, lex) != TOK_COMMA ) @@ -1336,7 +1336,6 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin { GET_CHECK_TOK(tok, lex, TOK_STRING); path = ::AST::Path(tok.str(), {}); - GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON); } else { PUTBACK(tok, lex); @@ -1387,7 +1386,7 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin else { PUTBACK(tok, lex); - assert(path.nodes().size() > 0); + ASSERT_BUG(lex.getPosition(), path.nodes().size() > 0, "`use` with no path"); name = path.nodes().back().name(); } diff --git a/src/parse/token.cpp b/src/parse/token.cpp index c7d11d03..05c4dbe6 100644 --- a/src/parse/token.cpp +++ b/src/parse/token.cpp @@ -289,16 +289,16 @@ struct EscapedString { case TOK_NEWLINE: return "\n"; case TOK_WHITESPACE: return " "; case TOK_COMMENT: return "/*" + m_data.as_String() + "*/"; - case TOK_INTERPOLATED_TYPE: return "/*:ty*/"; - case TOK_INTERPOLATED_PATH: return "/*:path*/"; - case TOK_INTERPOLATED_PATTERN: return "/*:pat*/"; + case TOK_INTERPOLATED_TYPE: return FMT( *reinterpret_cast<const ::TypeRef*>(m_data.as_Fragment()) ); + case TOK_INTERPOLATED_PATH: return FMT( *reinterpret_cast<const ::AST::Path*>(m_data.as_Fragment()) ); + case TOK_INTERPOLATED_PATTERN: return FMT( *reinterpret_cast<const ::AST::Pattern*>(m_data.as_Fragment()) ); + case TOK_INTERPOLATED_STMT: + case TOK_INTERPOLATED_BLOCK: case TOK_INTERPOLATED_EXPR: { ::std::stringstream ss; reinterpret_cast<const ::AST::ExprNode*>(m_data.as_Fragment())->print(ss); return ss.str(); } - case TOK_INTERPOLATED_STMT: return "/*:stmt*/"; - case TOK_INTERPOLATED_BLOCK: return "/*:block*/"; case TOK_INTERPOLATED_META: return "/*:meta*/"; case TOK_INTERPOLATED_ITEM: return "/*:item*/"; case TOK_INTERPOLATED_IDENT: return "/*:ident*/"; |