forked from graphitemaster/glsl-parser
-
Notifications
You must be signed in to change notification settings - Fork 1
/
parser.h
183 lines (151 loc) · 5.67 KB
/
parser.h
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#ifndef PARSE_HDR
#define PARSE_HDR
#include <string.h>
#include "lexer.h"
#include "ast.h"
namespace glsl {
#if __GNUC__ >= 4
# define CHECK_RETURN __attribute__((warn_unused_result))
#elif _MSC_VER >= 1700
# define CHECK_RETURN _Check_return_
#else
# define CHECK_RETURN
#endif
struct topLevel {
topLevel()
: storage(-1)
, auxiliary(-1)
, memory(0)
, precision(-1)
, interpolation(-1)
, type(0)
, initialValue(0)
, arrayOnTypeOffset(0)
, isInvariant(false)
, isPrecise(false)
, isArray(false)
{
}
int storage;
int auxiliary;
int memory;
int precision;
int interpolation;
astType *type;
astConstantExpression *initialValue;
vector<astConstantExpression*> arraySizes;
size_t arrayOnTypeOffset;
vector<astLayoutQualifier*> layoutQualifiers;
vector<astStruct*> structures;
bool isInvariant;
bool isPrecise;
bool isArray;
char *name;
};
struct parser {
~parser();
parser(const char *source, const char *fileName);
CHECK_RETURN astTU *parse(int type, bool ignoreUndefinedVariables = false);
const char *error() const;
inline bool errorOccured() { return m_errorOccured; }
void addGlobal(const char* name, int type, const char* typeName = "");
void cleanup();
protected:
enum {
kEndConditionSemicolon = 1 << 0,
kEndConditionParanthesis = 1 << 1,
kEndConditionBracket = 1 << 2,
kEndConditionColon = 1 << 3,
kEndConditionComma = 1 << 4
};
typedef int endCondition;
CHECK_RETURN bool next();
CHECK_RETURN bool parseStorage(topLevel ¤t); // const, in, out, attribute, uniform, varying, buffer, shared
CHECK_RETURN bool parseAuxiliary(topLevel ¤t); // centroid, sample, patch
CHECK_RETURN bool parseInterpolation(topLevel ¤t); // smooth, flat, noperspective
CHECK_RETURN bool parsePrecision(topLevel ¤t); // highp, mediump, lowp
CHECK_RETURN bool parseInvariant(topLevel ¤t); // invariant
CHECK_RETURN bool parsePrecise(topLevel ¤t); // precise
CHECK_RETURN bool parseMemory(topLevel ¤t); // coherent, volatile, restrict, readonly, writeonly
CHECK_RETURN bool parseLayout(topLevel ¤t);
CHECK_RETURN bool parseTopLevelItem(topLevel &level, topLevel *continuation = 0);
CHECK_RETURN bool parseTopLevel(vector<topLevel> &top);
CHECK_RETURN bool isType(int type) const;
CHECK_RETURN bool isKeyword(int keyword) const;
CHECK_RETURN bool isOperator(int oper) const;
CHECK_RETURN bool isEndCondition(endCondition condition) const;
CHECK_RETURN bool isBuiltin() const;
CHECK_RETURN bool isConstantValue(astExpression *expression) const;
CHECK_RETURN bool isConstant(astExpression *expression) const;
void fatal(const char *fmt, ...);
CHECK_RETURN astConstantExpression *evaluate(astExpression *expression);
int preprocess();
// Type parsers
astBuiltin *parseBuiltin();
astStruct *parseStruct();
CHECK_RETURN astFunction *parseFunction(const topLevel &parse);
// Call parsers
CHECK_RETURN astConstructorCall *parseConstructorCall();
CHECK_RETURN astFunctionCall *parseFunctionCall();
// Expression parsers
CHECK_RETURN astExpression *parseExpression(endCondition end);
CHECK_RETURN astExpression *parseUnary(endCondition end);
CHECK_RETURN astExpression *parseBinary(int lhsPrecedence, astExpression *lhs, endCondition condition);
CHECK_RETURN astExpression *parseUnaryPrefix(endCondition end);
CHECK_RETURN astConstantExpression *parseArraySize();
// Statement parsers
CHECK_RETURN astStatement *parseStatement();
CHECK_RETURN astSwitchStatement *parseSwitchStatement();
CHECK_RETURN astCaseLabelStatement *parseCaseLabelStatement();
CHECK_RETURN astForStatement *parseForStatement();
CHECK_RETURN astCompoundStatement *parseCompoundStatement();
CHECK_RETURN astIfStatement *parseIfStatement();
CHECK_RETURN astSimpleStatement *parseDeclarationOrExpressionStatement(endCondition condition);
CHECK_RETURN astDeclarationStatement *parseDeclarationStatement(endCondition condition);
CHECK_RETURN astExpressionStatement *parseExpressionStatement(endCondition condition);
CHECK_RETURN astContinueStatement *parseContinueStatement();
CHECK_RETURN astBreakStatement *parseBreakStatement();
CHECK_RETURN astDiscardStatement *parseDiscardStatement();
CHECK_RETURN astReturnStatement *parseReturnStatement();
CHECK_RETURN astDoStatement *parseDoStatement();
CHECK_RETURN astWhileStatement *parseWhileStatement();
astBinaryExpression *createExpression();
astType *findType(const char *identifier);
astVariable *findVariable(const char *identifier);
astType* getType(astExpression *expression);
private:
typedef vector<astVariable *> scope;
scope m_toAddGlobal;
void m_addBuiltinVariables();
astTU *m_ast;
lexer m_lexer;
token m_token;
vector<scope> m_scopes;
vector<astBuiltin*> m_builtins;
bool m_errorOccured;
char *m_error;
char *m_oom;
const char *m_fileName;
void strdel(char **what) {
if (!*what)
return;
free(*what);
*what = 0;
}
char *strnew(const char *what) {
if (!what)
return 0;
size_t length = strlen(what) + 1;
char *copy = (char*)malloc(length);
memcpy(copy, what, length);
m_strings.push_back(copy);
return copy;
}
bool strnil(const char *what) {
return !what || !*what;
}
vector<astMemory> m_memory; // Memory of AST held here
vector<char *> m_strings; // Memory of strings held here
};
}
#endif