summaryrefslogtreecommitdiff
path: root/src/parse/token.hpp
blob: 25993b2f9969ef7674563c0d58fdb3fa2b5f8169 (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
/*
 */
#pragma once

#include <rc_string.hpp>
#include <tagged_union.hpp>
#include <serialise.hpp>
#include "../coretypes.hpp"

enum eTokenType
{
    #define _(t)    t,
    #include "eTokenType.enum.h"
    #undef _
};

class Position
{
public:
    RcString    filename;
    unsigned int    line;
    unsigned int    ofs;
    
    Position():
        filename(""),
        line(0),
        ofs(0)
    {}
    Position(RcString filename, unsigned int line, unsigned int ofs):
        filename(filename),
        line(line),
        ofs(ofs)
    {
    }
};
extern ::std::ostream& operator<<(::std::ostream& os, const Position& p);

class TypeRef;
class TokenTree;
namespace AST {
    class Pattern;
    class Path;
    class ExprNode;
    class MetaItem;
};

class InterpolatedFragment;

class Token:
    public Serialisable
{
    TAGGED_UNION(Data, None,
    (None, struct {}),
    (String, ::std::string),
    (Integer, struct {
        enum eCoreType  m_datatype;
        uint64_t    m_intval;
        }),
    (Float, struct {
        enum eCoreType  m_datatype;
        double  m_floatval;
        }),
    (Fragment, void*)
    );
    
    enum eTokenType m_type;
    Data    m_data;
    Position    m_pos;
public:
    virtual ~Token();
    Token();
    Token& operator=(Token&& t)
    {
        m_type = t.m_type;  t.m_type = TOK_NULL;
        m_data = ::std::move(t.m_data);
        m_pos = ::std::move(t.m_pos);
        return *this;
    }
    Token(Token&& t):
        m_type(t.m_type),
        m_data( ::std::move(t.m_data) ),
        m_pos( ::std::move(t.m_pos) )
    {
        t.m_type = TOK_NULL;
    }
    Token(const Token& t):
        m_type(t.m_type),
        m_data( Data::make_None({}) ),
        m_pos( t.m_pos )
    {
        assert( t.m_data.tag() != Data::TAGDEAD );
        TU_MATCH(Data, (t.m_data), (e),
        (None,  ),
        (String,    m_data = Data::make_String(e); ),
        (Integer,   m_data = Data::make_Integer(e);),
        (Float, m_data = Data::make_Float(e);),
        (Fragment, assert(!"Copied fragment");)
        )
    }
    Token clone() const;
    
    Token(enum eTokenType type);
    Token(enum eTokenType type, ::std::string str);
    Token(uint64_t val, enum eCoreType datatype);
    Token(double val, enum eCoreType datatype);
    Token(InterpolatedFragment& );

    enum eTokenType type() const { return m_type; }
    const ::std::string& str() const { return m_data.as_String(); }
    enum eCoreType  datatype() const { TU_MATCH_DEF(Data, (m_data), (e), (assert(!"Getting datatype of invalid token type");), (Integer, return e.m_datatype;), (Float, return e.m_datatype;)) }
    uint64_t intval() const { return m_data.as_Integer().m_intval; }
    double floatval() const { return m_data.as_Float().m_floatval; }
    
    TypeRef& frag_type() { assert(m_type == TOK_INTERPOLATED_TYPE); return *reinterpret_cast<TypeRef*>( m_data.as_Fragment() ); }
    AST::Path& frag_path() { assert(m_type == TOK_INTERPOLATED_PATH); return *reinterpret_cast<AST::Path*>( m_data.as_Fragment() ); }
    AST::Pattern& frag_pattern() { assert(m_type == TOK_INTERPOLATED_PATTERN); return *reinterpret_cast<AST::Pattern*>( m_data.as_Fragment() ); }
    AST::MetaItem& frag_meta() { assert(m_type == TOK_INTERPOLATED_META); return *reinterpret_cast<AST::MetaItem*>( m_data.as_Fragment() ); }
    ::std::unique_ptr<AST::ExprNode> take_frag_node();
    
    bool operator==(const Token& r) const {
        if(type() != r.type())
            return false;
        TU_MATCH(Data, (m_data, r.m_data), (e, re),
        (None, return true;),
        (String, return e == re;),
        (Integer, return e.m_datatype == re.m_datatype && e.m_intval == re.m_intval;),
        (Float, return e.m_datatype == re.m_datatype && e.m_floatval == re.m_floatval;),
        (Fragment, assert(!"Token equality on Fragment");)
        )
        throw "";
    }
    bool operator!=(const Token& r) { return !(*this == r); }

    ::std::string to_str() const;
    
    void set_pos(Position pos) { m_pos = pos; }
    const Position& get_pos() const { return m_pos; }
    
    static const char* typestr(enum eTokenType type);
    static eTokenType typefromstr(const ::std::string& s);
    
    SERIALISABLE_PROTOTYPES();

    friend ::std::ostream&  operator<<(::std::ostream& os, const Token& tok);
};
extern ::std::ostream&  operator<<(::std::ostream& os, const Token& tok);