forked from AcademySoftwareFoundation/MaterialX
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Syntax.h
295 lines (225 loc) · 12.1 KB
/
Syntax.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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
//
// TM & (c) 2017 Lucasfilm Entertainment Company Ltd. and Lucasfilm Ltd.
// All rights reserved. See LICENSE.txt for license.
//
#ifndef MATERIALX_SYNTAX_H
#define MATERIALX_SYNTAX_H
/// @file
/// Base class for syntax handling for shader generators
#include <MaterialXGenShader/Library.h>
#include <MaterialXCore/Definition.h>
#include <MaterialXCore/Library.h>
#include <MaterialXCore/Value.h>
namespace MaterialX
{
class Syntax;
class TypeSyntax;
class TypeDesc;
/// Shared pointer to a Syntax
using SyntaxPtr = shared_ptr<Syntax>;
/// Shared pointer to a constant Syntax
using ConstSyntaxPtr = shared_ptr<const Syntax>;
/// Shared pointer to a TypeSyntax
using TypeSyntaxPtr = shared_ptr<TypeSyntax>;
/// Map holding identifier names and a counter for
/// creating unique names from them.
using IdentifierMap = std::unordered_map<string, size_t>;
/// @class Syntax
/// Base class for syntax objects used by shader generators
/// to emit code with correct syntax for each language.
class Syntax
{
public:
/// Punctuation types
enum Punctuation
{
PARENTHESES,
CURLY_BRACKETS,
SQUARE_BRACKETS,
DOUBLE_SQUARE_BRACKETS
};
public:
virtual ~Syntax() { }
/// Register syntax handling for a data type.
/// Required to be set for all supported data types.
void registerTypeSyntax(const TypeDesc* type, TypeSyntaxPtr syntax);
/// Register names that are reserved words not to be used by a code generator when naming
/// variables and functions. Keywords, types, built-in functions etc. should be
/// added to this set. Multiple calls will add to the internal set of names.
void registerReservedWords(const StringSet& names);
/// Register a set string replacements for disallowed tokens
/// for a code generator when naming variables and functions.
/// Multiple calls will add to the internal set of tokens.
void registerInvalidTokens(const StringMap& tokens);
/// Returns a set of names that are reserved words for this language syntax.
const StringSet& getReservedWords() const { return _reservedWords; }
/// Returns a mapping from disallowed tokens to replacement strings for this language syntax.
const StringMap& getInvalidTokens() const { return _invalidTokens; }
/// Returns the type syntax object for a named type.
/// Throws an exception if a type syntax is not defined for the given type.
const TypeSyntax& getTypeSyntax(const TypeDesc* type) const;
/// Returns an array of all registered type syntax objects
const vector<TypeSyntaxPtr>& getTypeSyntaxes() const { return _typeSyntaxes; }
/// Returns a type description given a type syntax. Throws an exception
/// if the type syntax has not been registered
const TypeDesc* getTypeDescription(const TypeSyntaxPtr& typeSyntax) const;
/// Returns the name syntax of the given type
const string& getTypeName(const TypeDesc* type) const;
/// Returns the type name in an output context
string getOutputTypeName(const TypeDesc* type) const;
/// Returns a type alias for the given data type.
/// If not used returns an empty string.
const string& getTypeAlias(const TypeDesc* type) const;
/// Returns a custom type definition if needed for the given data type.
/// If not used returns an empty string.
const string& getTypeDefinition(const TypeDesc* type) const;
/// Returns the default value string for the given type
const string& getDefaultValue(const TypeDesc* type, bool uniform = false) const;
/// Returns the value string for a given type and value object
virtual string getValue(const TypeDesc* type, const Value& value, bool uniform = false) const;
/// Get syntax for a swizzled variable
virtual string getSwizzledVariable(const string& srcName, const TypeDesc* srcType, const string& channels, const TypeDesc* dstType) const;
/// Get swizzled value
virtual ValuePtr getSwizzledValue(ValuePtr value, const TypeDesc* srcType, const string& channels, const TypeDesc* dstType) const;
/// Returns a type qualifier to be used when declaring types for input variables.
/// Default implementation returns empty string and derived syntax classes should
/// override this method.
virtual const string& getInputQualifier() const { return EMPTY_STRING; };
/// Returns a type qualifier to be used when declaring types for output variables.
/// Default implementation returns empty string and derived syntax classes should
/// override this method.
virtual const string& getOutputQualifier() const { return EMPTY_STRING; };
/// Get the qualifier used when declaring constant variables.
/// Derived classes must define this method.
virtual const string& getConstantQualifier() const = 0;
/// Get the qualifier used when declaring uniform variables.
/// Default implementation returns empty string and derived syntax classes should
/// override this method.
virtual const string& getUniformQualifier() const { return EMPTY_STRING; };
/// Return the characters used for a newline.
virtual const string& getNewline() const { return NEWLINE; };
/// Return the characters used for a single indentation level.
virtual const string& getIndentation() const { return INDENTATION; };
/// Return the characters used to begin/end a string definition.
virtual const string& getStringQuote() const { return STRING_QUOTE; };
/// Return the string pattern used for a file include statement.
virtual const string& getIncludeStatement() const { return INCLUDE_STATEMENT; };
/// Return the characters used for single line comment.
virtual const string& getSingleLineComment() const { return SINGLE_LINE_COMMENT; };
/// Return the characters used to begin a multi line comments block.
virtual const string& getBeginMultiLineComment() const { return BEGIN_MULTI_LINE_COMMENT; };
/// Return the characters used to end a multi line comments block.
virtual const string& getEndMultiLineComment() const { return END_MULTI_LINE_COMMENT; };
/// Return the file extension used for source code files in this language.
virtual const string& getSourceFileExtension() const = 0;
/// Return the array suffix to use for declaring an array type.
virtual string getArrayTypeSuffix(const TypeDesc*, const Value&) const { return EMPTY_STRING; };
/// Return the array suffix to use for declaring an array variable.
virtual string getArrayVariableSuffix(const TypeDesc* type, const Value& value) const;
/// Query if given type is suppored in the syntax.
/// By default all types are assumed to be supported.
virtual bool typeSupported(const TypeDesc* type) const;
/// Modify the given name string to remove any invalid characters or tokens.
virtual void makeValidName(string& name) const;
/// Make sure the given name is a unique identifier,
/// updating it if needed to make it unique.
virtual void makeIdentifier(string& name, IdentifierMap& identifiers) const;
/// Create a unique identifier for the given variable name and type.
/// The method is used for naming variables (inputs and outputs) in generated code.
/// Derived classes can override this method to have a custom naming strategy.
/// Default implementation adds a number suffix, or increases an existing number suffix,
/// on the name string if there is a name collision.
virtual string getVariableName(const string& name, const TypeDesc* type, IdentifierMap& identifiers) const;
/// Given an input specification attempt to remap this to an enumeration which is accepted by
/// the shader generator. The enumeration may be converted to a different type than the input.
/// @param value The value string to remap.
/// @param type The type of the value to remap,
/// @param enumNames Type enumeration names
/// @param result Enumeration type and value (returned).
/// @return Return true if the remapping was successful.
virtual bool remapEnumeration(const string& value, const TypeDesc* type, const string& enumNames,
std::pair<const TypeDesc*, ValuePtr>& result) const;
/// Constants with commonly used strings.
static const string NEWLINE;
static const string SEMICOLON;
static const string COMMA;
protected:
/// Protected constructor
Syntax();
vector<TypeSyntaxPtr> _typeSyntaxes;
std::unordered_map<const TypeDesc*, size_t> _typeSyntaxByType;
StringSet _reservedWords;
StringMap _invalidTokens;
static const string INDENTATION;
static const string STRING_QUOTE;
static const string INCLUDE_STATEMENT;
static const string SINGLE_LINE_COMMENT;
static const string BEGIN_MULTI_LINE_COMMENT;
static const string END_MULTI_LINE_COMMENT;
static const std::unordered_map<char, size_t> CHANNELS_MAPPING;
};
/// @class TypeSyntax
/// Base class for syntax handling of types.
class TypeSyntax
{
public:
virtual ~TypeSyntax() { }
/// Returns the type name.
const string& getName() const { return _name; }
/// Returns a type alias if needed to define the type in the target language.
const string& getTypeAlias() const { return _typeAlias; }
/// Returns a type definition if needed to define the type in the target language.
const string& getTypeDefinition() const { return _typeDefinition; }
/// Returns the default value for this type.
const string& getDefaultValue(bool uniform) const { return uniform ? _uniformDefaultValue : _defaultValue; }
/// Returns the syntax for accessing type members if the type
/// can be swizzled.
const StringVec& getMembers() const { return _members; }
/// Returns a value formatted according to this type syntax.
/// The value is constructed from the given value object.
virtual string getValue(const Value& value, bool uniform) const = 0;
/// Returns a value formatted according to this type syntax.
/// The value is constructed from the given list of value entries
/// with one entry for each member of the type.
virtual string getValue(const StringVec& values, bool uniform) const = 0;
protected:
/// Protected constructor
TypeSyntax(const string& name, const string& defaultValue, const string& uniformDefaultValue,
const string& typeAlias, const string& typeDefinition, const StringVec& members);
string _name; // type name
string _defaultValue; // default value syntax
string _uniformDefaultValue; // default value syntax when assigned to uniforms
string _typeAlias; // type alias if needed in source code
string _typeDefinition; // custom type definition if needed in source code
StringVec _members; // syntax for member access
static const StringVec EMPTY_MEMBERS;
};
/// Specialization of TypeSyntax for scalar types.
class ScalarTypeSyntax : public TypeSyntax
{
public:
ScalarTypeSyntax(const string& name, const string& defaultValue, const string& uniformDefaultValue,
const string& typeAlias = EMPTY_STRING, const string& typeDefinition = EMPTY_STRING);
string getValue(const Value& value, bool uniform) const override;
string getValue(const StringVec& values, bool uniform) const override;
};
/// Specialization of TypeSyntax for string types.
class StringTypeSyntax : public ScalarTypeSyntax
{
public:
StringTypeSyntax(const string& name, const string& defaultValue, const string& uniformDefaultValue,
const string& typeAlias = EMPTY_STRING, const string& typeDefinition = EMPTY_STRING);
string getValue(const Value& value, bool uniform) const override;
};
/// Specialization of TypeSyntax for aggregate types.
class AggregateTypeSyntax : public TypeSyntax
{
public:
AggregateTypeSyntax(const string& name, const string& defaultValue, const string& uniformDefaultValue,
const string& typeAlias = EMPTY_STRING, const string& typeDefinition = EMPTY_STRING,
const StringVec& members = EMPTY_MEMBERS);
string getValue(const Value& value, bool uniform) const override;
string getValue(const StringVec& values, bool uniform) const override;
};
} // namespace MaterialX
#endif