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


namespace AST {

//
class MetaItem;

class MetaItems
{
public:
    Span    m_span;
    ::std::vector<MetaItem> m_items;

    virtual ~MetaItems();
    MetaItems() {}
    MetaItems(MetaItems&&) = default;
    MetaItems& operator=(MetaItems&&) = default;
    MetaItems(const MetaItems&) = delete;
    MetaItems(Span sp, ::std::vector<MetaItem> items):
        m_span( mv$(sp) ),
        m_items( mv$(items) )
    {
    }

    void push_back(MetaItem i);

    MetaItems clone() const;

    MetaItem* get(const char *name) { return const_cast<MetaItem*>( const_cast<const MetaItems*>(this)->get(name)); }
    const MetaItem* get(const char *name) const;
    bool has(const char *name) const {
        return get(name) != 0;
    }

    friend ::std::ostream& operator<<(::std::ostream& os, const MetaItems& x) {
        return os << "[" << x.m_items << "]";
    }
};


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

class MetaItem
{
    ::std::string   m_name;
    MetaItemData    m_data;
public:
    virtual ~MetaItem();
    MetaItem() {}
    MetaItem(MetaItem&& ) = default;
    MetaItem& operator=(MetaItem&& ) = default;
    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;
    }
};

}   // namespace AST

#endif