summaryrefslogtreecommitdiff
path: root/src/parse
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse')
-rw-r--r--src/parse/expr.cpp13
-rw-r--r--src/parse/lex.cpp16
-rw-r--r--src/parse/root.cpp9
-rw-r--r--src/parse/token.cpp10
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*/";