From 07849e03b7d32ff28402ddd485326e00dbe2fedd Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 25 Sep 2016 18:00:47 +0800 Subject: macro_rules! - Rough (stubbed) support for :item --- src/macro_rules/eval.cpp | 5 +++++ src/macro_rules/macro_rules.hpp | 1 + src/macro_rules/mod.cpp | 25 +++++++++++++++++++++++++ src/macro_rules/parse.cpp | 19 ++++++++++++++++++- 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); -- cgit v1.2.3