summaryrefslogtreecommitdiff
path: root/src/ast/attrs.hpp
blob: 82cf2154cdc4f4326d0c71242ee0e25f109771b8 (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
#ifndef _AST_ATTRS_HPP_
#define _AST_ATTRS_HPP_


namespace AST {

//
class MetaItem;

class MetaItems:
    public Serialisable
{
public:
    ::std::vector<MetaItem> m_items;
    
    MetaItems() {}
    MetaItems(MetaItems&&) noexcept = default;
    MetaItems& operator=(MetaItems&&) = default;
    MetaItems(const MetaItems&) = delete;
    MetaItems(::std::vector<MetaItem> items):
        m_items( mv$(items) )
    {
    }
    
    void push_back(MetaItem i);
    
    MetaItems clone() const;
    
    MetaItem* get(const char *name);
    bool has(const char *name) {
        return get(name) != 0;
    }
    
    friend ::std::ostream& operator<<(::std::ostream& os, const MetaItems& x) {
        return os << "[" << x.m_items << "]";
    }
    
    SERIALISABLE_PROTOTYPES();
};


TAGGED_UNION(MetaItemData, None,
    (None, struct {}),
    (String, struct {
        ::std::string   val;
        }),
    (List, struct {
        ::std::vector<MetaItem> sub_items;
        })
    );

class MetaItem:
    public Serialisable
{
    ::std::string   m_name;
    MetaItemData    m_data;
public:
    MetaItem() {}
    MetaItem(::std::string name):
        m_name(name),
        m_data( MetaItemData::make_None({}) )
    {
    }
    MetaItem(::std::string name, ::std::string str_val):
        m_name(name),
        m_data( MetaItemData::make_String({mv$(str_val)}) )
    {
    }
    MetaItem(::std::string name, ::std::vector<MetaItem> items):
        m_name(name),
        m_data( MetaItemData::make_List({mv$(items)}) )
    {
    }
    
    MetaItem clone() const;
    
    void mark_used() {}
    const ::std::string& name() const { return m_name; }
    
    bool has_noarg() const { return m_data.is_None(); }
    
    bool has_string() const { return m_data.is_String(); }
    const ::std::string& string() const { return m_data.as_String().val; }
    
    bool has_sub_items() const { return m_data.is_List(); }
    const ::std::vector<MetaItem>& items() const { return m_data.as_List().sub_items; }
    //::std::vector<MetaItem>& items() { return m_data.as_List().sub_items; }
    
    friend ::std::ostream& operator<<(::std::ostream& os, const MetaItem& x) {
        os << x.m_name;
        TU_MATCH(MetaItemData, (x.m_data), (e),
        (None,
            ),
        (String,
            os << "=\"" << e.val << "\"";
            ),
        (List,
            os << "(" << e.sub_items << ")";
            )
        )
        return os;
    }
    
    SERIALISABLE_PROTOTYPES();
};

}   // namespace AST

#endif