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
|
// slang-token.h
#ifndef SLANG_TOKEN_H_INCLUDED
#define SLANG_TOKEN_H_INCLUDED
#include "../core/slang-basic.h"
#include "slang-name.h"
#include "slang-source-loc.h"
namespace Slang
{
class Name;
enum class TokenType : uint8_t
{
#define TOKEN(NAME, DESC) NAME,
#include "slang-token-defs.h"
};
char const* TokenTypeToString(TokenType type);
typedef uint8_t TokenFlags;
struct TokenFlag
{
enum Enum : TokenFlags
{
AtStartOfLine = 1 << 0,
AfterWhitespace = 1 << 1,
ScrubbingNeeded = 1 << 2,
Name = 1 << 3, ///< Determines if 'name' is set or 'chars' in the charsNameUnion
};
};
class Token
{
public:
TokenType type = TokenType::Unknown;
TokenFlags flags = 0;
SourceLoc loc;
uint32_t charsCount = 0; ///< Amount of characters. Is set if name or not.
union CharsNameUnion
{
const char* chars;
Name* name;
};
CharsNameUnion charsNameUnion;
bool hasContent() const { return charsCount > 0; }
Index getContentLength() const { return charsCount; }
UnownedStringSlice getContent() const;
/// Set content
void setContent(const UnownedStringSlice& content);
Name* getName() const;
Name* getNameOrNull() const;
SourceLoc getLoc() const { return loc; }
/// Set the name
SLANG_FORCE_INLINE void setName(Name* inName);
Token() { charsNameUnion.chars = nullptr; }
Token(
TokenType inType,
const UnownedStringSlice& inContent,
SourceLoc inLoc,
TokenFlags inFlags = 0)
: flags(inFlags)
{
SLANG_ASSERT((inFlags & TokenFlag::Name) == 0);
type = inType;
charsNameUnion.chars = inContent.begin();
charsCount = uint32_t(inContent.getLength());
loc = inLoc;
}
Token(TokenType inType, Name* name, SourceLoc inLoc, TokenFlags inFlags = 0)
{
SLANG_ASSERT(name);
type = inType;
flags = inFlags | TokenFlag::Name;
charsNameUnion.name = name;
charsCount = uint32_t(name->text.getLength());
loc = inLoc;
}
};
// ---------------------------------------------------------------------------
SLANG_FORCE_INLINE UnownedStringSlice Token::getContent() const
{
return (flags & TokenFlag::Name) ? charsNameUnion.name->text.getUnownedSlice()
: UnownedStringSlice(charsNameUnion.chars, charsCount);
}
// ---------------------------------------------------------------------------
SLANG_FORCE_INLINE Name* Token::getName() const
{
return getNameOrNull();
}
// ---------------------------------------------------------------------------
SLANG_FORCE_INLINE Name* Token::getNameOrNull() const
{
return (flags & TokenFlag::Name) ? charsNameUnion.name : nullptr;
}
// ---------------------------------------------------------------------------
SLANG_FORCE_INLINE void Token::setContent(const UnownedStringSlice& content)
{
flags &= ~TokenFlag::Name;
charsNameUnion.chars = content.begin();
charsCount = uint32_t(content.getLength());
}
// ---------------------------------------------------------------------------
SLANG_FORCE_INLINE void Token::setName(Name* inName)
{
SLANG_ASSERT(inName);
flags |= TokenFlag::Name;
charsNameUnion.name = inName;
charsCount = uint32_t(inName->text.getLength());
}
} // namespace Slang
#endif
|