diff options
author | John Hodge <tpg@mutabah.net> | 2016-09-25 18:00:47 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-09-25 18:00:47 +0800 |
commit | 07849e03b7d32ff28402ddd485326e00dbe2fedd (patch) | |
tree | 000e521dfebd5c860d8bd2ed1d4cde78415847f7 | |
parent | a2fc0567c434af1d5888db4f5c82df7f1e6b970f (diff) | |
download | mrust-07849e03b7d32ff28402ddd485326e00dbe2fedd.tar.gz |
macro_rules! - Rough (stubbed) support for :item
-rw-r--r-- | src/macro_rules/eval.cpp | 5 | ||||
-rw-r--r-- | src/macro_rules/macro_rules.hpp | 1 | ||||
-rw-r--r-- | src/macro_rules/mod.cpp | 25 | ||||
-rw-r--r-- | src/macro_rules/parse.cpp | 19 | ||||
-rw-r--r-- | src/macro_rules/pattern_checks.hpp | 2 |
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); |