summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-mangled-lexer.h
blob: 8436f612797d0f70098484d8689617f90525f957 (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
// slang-mangled-lexer.h
#ifndef SLANG_MANGLED_LEXER_H_INCLUDED
#define SLANG_MANGLED_LEXER_H_INCLUDED

#include "../core/slang-basic.h"
#include "../core/slang-char-util.h"
#include "slang-compiler.h"

namespace Slang
{

/* A lexer like utility class used for decoding mangled names.
Expects names to be correctly constructed - any errors will cause asserts/failures */
class MangledLexer
{
public:
    /// Reads a count at current position
    UInt readCount();

    void readGenericParam();

    void readGenericParams();

    SLANG_INLINE void readSimpleIntVal();

    String readRawStringSegment();

    void readNamedType();

    void readType();

    void readVal();

    void readGenericArg() { readVal(); }

    void readGenericArgs();

    SLANG_INLINE void readExtensionSpec();

    UnownedStringSlice readSimpleName();

    UInt readParamCount();

    /// Returns the character at the current position
    char peekChar() { return *m_cursor; }
    // Returns the current character and moves to next character.
    char nextChar() { return *m_cursor++; }

    static String unescapeString(UnownedStringSlice str);

    /// Ctor
    SLANG_FORCE_INLINE MangledLexer(const UnownedStringSlice& slice);

private:
    // Call at the beginning of a mangled name,
    // to strip off the main prefix
    void _start() { _expect("_S"); }

    SLANG_INLINE void _expect(char c);

    void _expect(char const* str)
    {
        while (char c = *str++)
            _expect(c);
    }

    char const* m_cursor = nullptr;
    char const* m_begin = nullptr;
    char const* m_end = nullptr;
};

// -------------------------------------------------------------------------- -
SLANG_FORCE_INLINE MangledLexer::MangledLexer(const UnownedStringSlice& slice)
    : m_cursor(slice.begin()), m_begin(slice.begin()), m_end(slice.end())
{
    _start();
}

// ---------------------------------------------------------------------------
SLANG_INLINE void MangledLexer::readSimpleIntVal()
{
    int c = peekChar();
    if (CharUtil::isDigit((char)c))
    {
        nextChar();
    }
    else
    {
        readVal();
    }
}

// ---------------------------------------------------------------------------
SLANG_INLINE void MangledLexer::readNamedType()
{
    // TODO: handle types with more complicated names
    readRawStringSegment();
}

// ---------------------------------------------------------------------------
SLANG_INLINE void MangledLexer::readExtensionSpec()
{
    _expect("X");
    readType();
}

// ---------------------------------------------------------------------------
SLANG_INLINE void MangledLexer::_expect(char c)
{
    if (peekChar() == c)
    {
        nextChar();
    }
    else
    {
        // ERROR!
        SLANG_UNEXPECTED("mangled name error");
    }
}

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MangledNameParser !!!!!!!!!!!!!!!!!!!!!!!!!!

struct MangledNameParser
{
    /// Tries to extract the module name from this mangled name.
    static SlangResult parseModuleName(const UnownedStringSlice& in, String& outModuleName);
};

} // namespace Slang
#endif