summaryrefslogtreecommitdiff
path: root/src/macro_rules/macro_rules.hpp
blob: 65822fa54469130564c74c1ae506d9c1aabd9c26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#ifndef MACROS_HPP_INCLUDED
#define MACROS_HPP_INCLUDED

#include "parse/lex.hpp"
#include "parse/tokentree.hpp"
#include <common.hpp>
#include <map>
#include <memory>
#include <cstring>
#include "macro_rules_ptr.hpp"

class MacroExpander;

class MacroRuleEnt:
    public Serialisable
{
    friend class MacroExpander;

    Token   tok;
    ::std::string   name;
    ::std::vector<MacroRuleEnt> subpats;
public:
    MacroRuleEnt():
        tok(TOK_NULL),
        name("")
    {
    }
    MacroRuleEnt(Token tok):
        tok( mv$(tok) ),
        name("")
    {
    }
    MacroRuleEnt(::std::string name):
        name( mv$(name) )
    {
    }
    MacroRuleEnt(Token tok, ::std::vector<MacroRuleEnt> subpats):
        tok( mv$(tok) ),
        subpats( mv$(subpats) )
    {
    }

    friend ::std::ostream& operator<<(::std::ostream& os, const MacroRuleEnt& x);

    SERIALISABLE_PROTOTYPES();
};
struct MacroPatEnt:
    public Serialisable
{
    ::std::string   name;
    unsigned int    name_index;
    Token   tok;
    
    ::std::vector<MacroPatEnt>  subpats;
    
    enum Type {
        PAT_TOKEN,  // A token
        PAT_LOOP,   // $() Enables use of subpats
        
        PAT_TT, // :tt
        PAT_PAT,    // :pat
        PAT_IDENT,
        PAT_PATH,
        PAT_TYPE,
        PAT_EXPR,
        PAT_STMT,
        PAT_BLOCK,
        PAT_META,
    } type;

    MacroPatEnt():
        tok(TOK_NULL),
        type(PAT_TOKEN)
    {
    }
    MacroPatEnt(Token tok):
        tok( mv$(tok) ),
        type(PAT_TOKEN)
    {
    }
    
    MacroPatEnt(::std::string name, unsigned int name_index, Type type):
        name( mv$(name) ),
        name_index( name_index ),
        tok(),
        type(type)
    {
    }
    
    MacroPatEnt(Token sep, bool need_once, ::std::vector<MacroPatEnt> ents):
        name( need_once ? "+" : "*" ),
        tok( mv$(sep) ),
        subpats( move(ents) ),
        type(PAT_LOOP)
    {
    }

    friend ::std::ostream& operator<<(::std::ostream& os, const MacroPatEnt& x);
    
    SERIALISABLE_PROTOTYPES();
};

struct MacroRulesPatFrag:
    public Serialisable
{
    ::std::vector<MacroPatEnt>  m_pats_ents;
    unsigned int    m_pattern_end;
    ::std::vector< MacroRulesPatFrag >  m_next_frags;
    
    MacroRulesPatFrag():
        m_pattern_end(~0)
    {}
    
    SERIALISABLE_PROTOTYPES();
};

/// An arm within a macro_rules! blcok
struct MacroRulesArm:
    public Serialisable
{
    ::std::vector< ::std::string>   m_param_names;
    ::std::vector<MacroRuleEnt> m_contents;
    
    MacroRulesArm()
    {}
    MacroRulesArm(::std::vector<MacroRuleEnt> contents):
        m_contents( mv$(contents) )
    {}
    
    SERIALISABLE_PROTOTYPES();
};

/// A sigle 'macro_rules!' block
class MacroRules:
    public Serialisable
{
public:
    bool m_exported;
    MacroRulesPatFrag  m_pattern;
    ::std::vector<MacroRulesArm>  m_rules;
    
    MacroRules()
    {
    }
    virtual ~MacroRules();
    
    SERIALISABLE_PROTOTYPES();
};

extern ::std::unique_ptr<TokenStream>   Macro_InvokeRules(const char *name, const MacroRules& rules, const TokenTree& input);
extern MacroRulesPtr    Parse_MacroRules(TokenStream& lex);

#endif // MACROS_HPP_INCLUDED