diff options
author | John Hodge <tpg@mutabah.net> | 2015-03-10 15:37:02 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2015-03-10 15:37:02 +0800 |
commit | e71fccd80610bc05b0a90338b2b3beb9a0b94c22 (patch) | |
tree | 22162a90d614a200483bd0ceae629671ff798e41 /src/macros.hpp | |
parent | 65558948954daaa2aec68b76814b043bf829d608 (diff) | |
download | mrust-e71fccd80610bc05b0a90338b2b3beb9a0b94c22.tar.gz |
Rework macro handling to support correct repetitions
Diffstat (limited to 'src/macros.hpp')
-rw-r--r-- | src/macros.hpp | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/src/macros.hpp b/src/macros.hpp index 4de41782..74001cae 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -16,6 +16,7 @@ class MacroRuleEnt: Token tok;
::std::string name;
+ ::std::vector<MacroRuleEnt> subpats;
public:
MacroRuleEnt():
tok(TOK_NULL),
@@ -31,6 +32,15 @@ public: name(name)
{
}
+ MacroRuleEnt(Token tok, ::std::vector<MacroRuleEnt> subpats):
+ tok(tok),
+ subpats(subpats)
+ {
+ }
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const MacroRuleEnt& x) {
+ return os << "MacroRuleEnt( '"<<x.name<<"'" << x.tok << ", " << x.subpats << ")";
+ }
SERIALISABLE_PROTOTYPES();
};
@@ -77,6 +87,10 @@ struct MacroPatEnt: type(PAT_LOOP)
{
}
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const MacroPatEnt& mpe) {
+ return os << "MacroPatEnt( '"<<mpe.name<<"'" << mpe.tok << ", " << mpe.subpats << ")";
+ }
SERIALISABLE_PROTOTYPES();
};
@@ -95,37 +109,61 @@ public: /// A sigle 'macro_rules!' block
typedef ::std::vector<MacroRule> MacroRules;
-struct cmp_str {
- bool operator()(const char* a, const char* b) const {
- return ::std::strcmp(a, b) < 0;
- }
-};
-
class MacroExpander:
public TokenStream
{
- typedef ::std::map<const char*, TokenTree, cmp_str> t_mappings;
+public:
+ // MultiMap (layer, name) -> TokenTree
+ // - Multiple values are only allowed for layer>0
+ typedef ::std::pair<unsigned,const char*> t_mapping_key;
+
+ struct cmp_mk {
+ bool operator()(const t_mapping_key& a, const t_mapping_key& b) const {
+ return a.first < b.first || ::std::strcmp(a.second, b.second) < 0;
+ }
+ };
+ typedef ::std::multimap<t_mapping_key, TokenTree, cmp_mk> t_mappings;
+
+private:
+ const TokenTree& m_crate_path;
+ const ::std::vector<MacroRuleEnt>& m_root_contents;
const t_mappings m_mappings;
- const ::std::vector<MacroRuleEnt>& m_contents;
- size_t m_ofs;
+
+ /// Layer states : Index and Iteration
+ ::std::vector< ::std::pair<size_t,size_t> > m_offsets;
+
+ /// Cached pointer to the current layer
+ const ::std::vector<MacroRuleEnt>* m_cur_ents; // For faster lookup.
+ /// Iteration counts for each layer
+ ::std::vector<size_t> m_layer_counts;
::std::auto_ptr<TTStream> m_ttstream;
+
public:
MacroExpander(const MacroExpander& x):
+ m_crate_path(x.m_crate_path),
+ m_root_contents(x.m_root_contents),
m_mappings(x.m_mappings),
- m_contents(x.m_contents),
- m_ofs(0)
+ m_offsets({ {0,0} }),
+ m_cur_ents(&m_root_contents)
{
+ prep_counts();
}
- MacroExpander(const ::std::vector<MacroRuleEnt>& contents, t_mappings mappings):
+ MacroExpander(const ::std::vector<MacroRuleEnt>& contents, t_mappings mappings, const TokenTree& crate_path):
+ m_crate_path(crate_path),
+ m_root_contents(contents),
m_mappings(mappings),
- m_contents(contents),
- m_ofs(0)
+ m_offsets({ {0,0} }),
+ m_cur_ents(&m_root_contents)
{
+ prep_counts();
}
virtual Position getPosition() const override;
virtual Token realGetToken() override;
+private:
+ const ::std::vector<MacroRuleEnt>* getCurLayer() const;
+ void prep_counts();
};
extern void Macro_SetModule(const LList<AST::Module*>& mod);
|