summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-09-25 18:00:47 +0800
committerJohn Hodge <tpg@mutabah.net>2016-09-25 18:00:47 +0800
commit07849e03b7d32ff28402ddd485326e00dbe2fedd (patch)
tree000e521dfebd5c860d8bd2ed1d4cde78415847f7
parenta2fc0567c434af1d5888db4f5c82df7f1e6b970f (diff)
downloadmrust-07849e03b7d32ff28402ddd485326e00dbe2fedd.tar.gz
macro_rules! - Rough (stubbed) support for :item
-rw-r--r--src/macro_rules/eval.cpp5
-rw-r--r--src/macro_rules/macro_rules.hpp1
-rw-r--r--src/macro_rules/mod.cpp25
-rw-r--r--src/macro_rules/parse.cpp19
-rw-r--r--src/macro_rules/pattern_checks.hpp2
5 files changed, 50 insertions, 2 deletions
diff --git a/src/macro_rules/eval.cpp b/src/macro_rules/eval.cpp
index 137f28c9..f850ae95 100644
--- a/src/macro_rules/eval.cpp
+++ b/src/macro_rules/eval.cpp
@@ -433,6 +433,8 @@ bool Macro_TryPatternCap(/*const*/ TTStream& lex, MacroPatEnt::Type type)
return is_token_pat( LOOK_AHEAD(lex) );
case MacroPatEnt::PAT_META:
return LOOK_AHEAD(lex) == TOK_IDENT || LOOK_AHEAD(lex) == TOK_INTERPOLATED_META;
+ case MacroPatEnt::PAT_ITEM:
+ return is_token_item( LOOK_AHEAD(lex) );
}
BUG(lex.getPosition(), "");
}
@@ -496,6 +498,9 @@ void Macro_HandlePatternCap(TTStream& lex, unsigned int index, MacroPatEnt::Type
case MacroPatEnt::PAT_META:
bound_tts.insert( index, iterations, InterpolatedFragment( Parse_MetaItem(lex) ) );
break;
+ case MacroPatEnt::PAT_ITEM:
+ TODO(lex.getPosition(), "Parse :item");
+ break;
case MacroPatEnt::PAT_IDENT:
GET_CHECK_TOK(tok, lex, TOK_IDENT);
bound_tts.insert( index, iterations, InterpolatedFragment( TokenTree(tok) ) );
diff --git a/src/macro_rules/macro_rules.hpp b/src/macro_rules/macro_rules.hpp
index f9cbd2f2..7846f4ba 100644
--- a/src/macro_rules/macro_rules.hpp
+++ b/src/macro_rules/macro_rules.hpp
@@ -65,6 +65,7 @@ struct MacroPatEnt:
PAT_STMT,
PAT_BLOCK,
PAT_META,
+ PAT_ITEM, // :item
} type;
MacroPatEnt():
diff --git a/src/macro_rules/mod.cpp b/src/macro_rules/mod.cpp
index a1b4ed0e..4f7dad45 100644
--- a/src/macro_rules/mod.cpp
+++ b/src/macro_rules/mod.cpp
@@ -108,6 +108,27 @@ bool is_token_stmt(eTokenType tt) {
}
}
+bool is_token_item(eTokenType tt) {
+ switch( tt )
+ {
+ case TOK_RWORD_PUB:
+ case TOK_RWORD_UNSAFE:
+ case TOK_RWORD_TYPE:
+ case TOK_RWORD_CONST:
+ case TOK_RWORD_STATIC:
+ case TOK_RWORD_FN:
+ case TOK_RWORD_STRUCT:
+ case TOK_RWORD_ENUM:
+ case TOK_RWORD_TRAIT:
+ case TOK_RWORD_MOD:
+ //case TOK_RWORD_IMPL:
+ // TODO: more?
+ return true;
+ default:
+ return false;
+ }
+}
+
MacroRulesPtr::~MacroRulesPtr()
{
if(m_ptr)
@@ -133,6 +154,7 @@ void operator%(Serialiser& s, MacroPatEnt::Type c) {
_(PAT_PATH);
_(PAT_BLOCK);
_(PAT_META);
+ _(PAT_ITEM);
_(PAT_IDENT);
#undef _
}
@@ -154,6 +176,7 @@ void operator%(::Deserialiser& s, MacroPatEnt::Type& c) {
_(PAT_BLOCK);
_(PAT_META);
_(PAT_IDENT);
+ _(PAT_ITEM);
else
throw ::std::runtime_error( FMT("No conversion for '" << n << "'") );
#undef _
@@ -185,6 +208,7 @@ SERIALISE_TYPE_S(MacroPatEnt, {
case MacroPatEnt::PAT_STMT: os << "stmt"; break;
case MacroPatEnt::PAT_BLOCK: os << "block"; break;
case MacroPatEnt::PAT_META: os << "meta"; break;
+ case MacroPatEnt::PAT_ITEM: os << "item"; break;
}
break;
}
@@ -205,6 +229,7 @@ SERIALISE_TYPE_S(MacroPatEnt, {
case MacroPatEnt::PAT_STMT: os << "PAT_STMT"; break;
case MacroPatEnt::PAT_BLOCK: os << "PAT_BLOCK"; break;
case MacroPatEnt::PAT_META: os << "PAT_META"; break;
+ case MacroPatEnt::PAT_ITEM: os << "PAT_ITEM"; break;
}
return os;
}
diff --git a/src/macro_rules/parse.cpp b/src/macro_rules/parse.cpp
index f8ec73cc..e382573a 100644
--- a/src/macro_rules/parse.cpp
+++ b/src/macro_rules/parse.cpp
@@ -70,14 +70,18 @@ public:
ret.push_back( MacroPatEnt(name, idx, MacroPatEnt::PAT_PATH) );
else if( type == "expr" )
ret.push_back( MacroPatEnt(name, idx, MacroPatEnt::PAT_EXPR) );
+ else if( type == "stmt" )
+ ret.push_back( MacroPatEnt(name, idx, MacroPatEnt::PAT_STMT) );
else if( type == "ty" )
ret.push_back( MacroPatEnt(name, idx, MacroPatEnt::PAT_TYPE) );
else if( type == "meta" )
ret.push_back( MacroPatEnt(name, idx, MacroPatEnt::PAT_META) );
else if( type == "block" )
ret.push_back( MacroPatEnt(name, idx, MacroPatEnt::PAT_BLOCK) );
+ else if( type == "item" )
+ ret.push_back( MacroPatEnt(name, idx, MacroPatEnt::PAT_ITEM) );
else
- throw ParseError::Generic(lex, FMT("Unknown fragment type '" << type << "'"));
+ ERROR(lex.getPosition(), E0000, "Unknown fragment type '" << type << "'");
break; }
case TOK_PAREN_OPEN: {
auto subpat = Parse_MacroRules_Pat(lex, TOK_PAREN_OPEN, TOK_PAREN_CLOSE, names);
@@ -397,6 +401,19 @@ bool patterns_are_same(const Span& sp, const MacroPatEnt& left, const MacroPatEn
default:
ERROR(sp, E0000, "Incompatible macro fragments " << right << " used with " << left);
}
+ // Matches items
+ case MacroPatEnt::PAT_ITEM:
+ switch(left.type)
+ {
+ case MacroPatEnt::PAT_TOKEN:
+ if( is_token_item(left.tok.type()) )
+ ERROR(sp, E0000, "Incompatible macro fragments");
+ return false;
+ case MacroPatEnt::PAT_ITEM:
+ return true;
+ default:
+ ERROR(sp, E0000, "Incompatible macro fragments " << right << " used with " << left);
+ }
}
throw "";
}
diff --git a/src/macro_rules/pattern_checks.hpp b/src/macro_rules/pattern_checks.hpp
index 820a9ef4..138f11a3 100644
--- a/src/macro_rules/pattern_checks.hpp
+++ b/src/macro_rules/pattern_checks.hpp
@@ -7,4 +7,4 @@ extern bool is_token_pat(eTokenType tt);
extern bool is_token_type(eTokenType tt);
extern bool is_token_expr(eTokenType tt);
extern bool is_token_stmt(eTokenType tt);
-
+extern bool is_token_item(eTokenType tt);