Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Side by Side Diff: src/sksl/SkSLIRGenerator.cpp

Issue 2143323003: Revert of SkSL performance improvements (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/sksl/SkSLIRGenerator.h ('k') | src/sksl/SkSLParser.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkSLIRGenerator.h" 8 #include "SkSLIRGenerator.h"
9 9
10 #include "limits.h" 10 #include "limits.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 fIR->popSymbolTable(); 61 fIR->popSymbolTable();
62 ASSERT(fPrevious == fIR->fSymbolTable); 62 ASSERT(fPrevious == fIR->fSymbolTable);
63 } 63 }
64 64
65 IRGenerator* fIR; 65 IRGenerator* fIR;
66 std::shared_ptr<SymbolTable> fPrevious; 66 std::shared_ptr<SymbolTable> fPrevious;
67 }; 67 };
68 68
69 IRGenerator::IRGenerator(std::shared_ptr<SymbolTable> symbolTable, 69 IRGenerator::IRGenerator(std::shared_ptr<SymbolTable> symbolTable,
70 ErrorReporter& errorReporter) 70 ErrorReporter& errorReporter)
71 : fCurrentFunction(nullptr) 71 : fSymbolTable(std::move(symbolTable))
72 , fSymbolTable(std::move(symbolTable)) 72 , fErrors(errorReporter) {
73 , fErrors(errorReporter) {} 73 }
74 74
75 void IRGenerator::pushSymbolTable() { 75 void IRGenerator::pushSymbolTable() {
76 fSymbolTable.reset(new SymbolTable(std::move(fSymbolTable), fErrors)); 76 fSymbolTable.reset(new SymbolTable(std::move(fSymbolTable), fErrors));
77 } 77 }
78 78
79 void IRGenerator::popSymbolTable() { 79 void IRGenerator::popSymbolTable() {
80 fSymbolTable = fSymbolTable->fParent; 80 fSymbolTable = fSymbolTable->fParent;
81 } 81 }
82 82
83 std::unique_ptr<Extension> IRGenerator::convertExtension(const ASTExtension& ext ension) { 83 std::unique_ptr<Extension> IRGenerator::convertExtension(const ASTExtension& ext ension) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 std::unique_ptr<Block> IRGenerator::convertBlock(const ASTBlock& block) { 116 std::unique_ptr<Block> IRGenerator::convertBlock(const ASTBlock& block) {
117 AutoSymbolTable table(this); 117 AutoSymbolTable table(this);
118 std::vector<std::unique_ptr<Statement>> statements; 118 std::vector<std::unique_ptr<Statement>> statements;
119 for (size_t i = 0; i < block.fStatements.size(); i++) { 119 for (size_t i = 0; i < block.fStatements.size(); i++) {
120 std::unique_ptr<Statement> statement = this->convertStatement(*block.fSt atements[i]); 120 std::unique_ptr<Statement> statement = this->convertStatement(*block.fSt atements[i]);
121 if (!statement) { 121 if (!statement) {
122 return nullptr; 122 return nullptr;
123 } 123 }
124 statements.push_back(std::move(statement)); 124 statements.push_back(std::move(statement));
125 } 125 }
126 return std::unique_ptr<Block>(new Block(block.fPosition, std::move(statement s), fSymbolTable)); 126 return std::unique_ptr<Block>(new Block(block.fPosition, std::move(statement s)));
127 } 127 }
128 128
129 std::unique_ptr<Statement> IRGenerator::convertVarDeclarationStatement( 129 std::unique_ptr<Statement> IRGenerator::convertVarDeclarationStatement(
130 const ASTVarDeclar ationStatement& s) { 130 const ASTVarDeclar ationStatement& s) {
131 auto decl = this->convertVarDeclaration(*s.fDeclaration, Variable::kLocal_St orage); 131 auto decl = this->convertVarDeclaration(*s.fDeclaration, Variable::kLocal_St orage);
132 if (!decl) { 132 if (!decl) {
133 return nullptr; 133 return nullptr;
134 } 134 }
135 return std::unique_ptr<Statement>(new VarDeclarationStatement(std::move(decl ))); 135 return std::unique_ptr<Statement>(new VarDeclarationStatement(std::move(decl )));
136 } 136 }
137 137
138 Modifiers IRGenerator::convertModifiers(const ASTModifiers& modifiers) { 138 Modifiers IRGenerator::convertModifiers(const ASTModifiers& modifiers) {
139 return Modifiers(modifiers); 139 return Modifiers(modifiers);
140 } 140 }
141 141
142 std::unique_ptr<VarDeclaration> IRGenerator::convertVarDeclaration(const ASTVarD eclaration& decl, 142 std::unique_ptr<VarDeclaration> IRGenerator::convertVarDeclaration(const ASTVarD eclaration& decl,
143 Variable::Sto rage storage) { 143 Variable::Sto rage storage) {
144 std::vector<const Variable*> variables; 144 std::vector<std::shared_ptr<Variable>> variables;
145 std::vector<std::vector<std::unique_ptr<Expression>>> sizes; 145 std::vector<std::vector<std::unique_ptr<Expression>>> sizes;
146 std::vector<std::unique_ptr<Expression>> values; 146 std::vector<std::unique_ptr<Expression>> values;
147 const Type* baseType = this->convertType(*decl.fType); 147 std::shared_ptr<Type> baseType = this->convertType(*decl.fType);
148 if (!baseType) { 148 if (!baseType) {
149 return nullptr; 149 return nullptr;
150 } 150 }
151 for (size_t i = 0; i < decl.fNames.size(); i++) { 151 for (size_t i = 0; i < decl.fNames.size(); i++) {
152 Modifiers modifiers = this->convertModifiers(decl.fModifiers); 152 Modifiers modifiers = this->convertModifiers(decl.fModifiers);
153 const Type* type = baseType; 153 std::shared_ptr<Type> type = baseType;
154 ASSERT(type->kind() != Type::kArray_Kind); 154 ASSERT(type->kind() != Type::kArray_Kind);
155 std::vector<std::unique_ptr<Expression>> currentVarSizes; 155 std::vector<std::unique_ptr<Expression>> currentVarSizes;
156 for (size_t j = 0; j < decl.fSizes[i].size(); j++) { 156 for (size_t j = 0; j < decl.fSizes[i].size(); j++) {
157 if (decl.fSizes[i][j]) { 157 if (decl.fSizes[i][j]) {
158 ASTExpression& rawSize = *decl.fSizes[i][j]; 158 ASTExpression& rawSize = *decl.fSizes[i][j];
159 auto size = this->coerce(this->convertExpression(rawSize), *kInt _Type); 159 auto size = this->coerce(this->convertExpression(rawSize), kInt_ Type);
160 if (!size) { 160 if (!size) {
161 return nullptr; 161 return nullptr;
162 } 162 }
163 std::string name = type->fName; 163 std::string name = type->fName;
164 uint64_t count; 164 uint64_t count;
165 if (size->fKind == Expression::kIntLiteral_Kind) { 165 if (size->fKind == Expression::kIntLiteral_Kind) {
166 count = ((IntLiteral&) *size).fValue; 166 count = ((IntLiteral&) *size).fValue;
167 if (count <= 0) { 167 if (count <= 0) {
168 fErrors.error(size->fPosition, "array size must be posit ive"); 168 fErrors.error(size->fPosition, "array size must be posit ive");
169 } 169 }
170 name += "[" + to_string(count) + "]"; 170 name += "[" + to_string(count) + "]";
171 } else { 171 } else {
172 count = -1; 172 count = -1;
173 name += "[]"; 173 name += "[]";
174 } 174 }
175 type = new Type(name, Type::kArray_Kind, *type, (int) count); 175 type = std::shared_ptr<Type>(new Type(name, Type::kArray_Kind, t ype, (int) count));
176 fSymbolTable->takeOwnership((Type*) type);
177 currentVarSizes.push_back(std::move(size)); 176 currentVarSizes.push_back(std::move(size));
178 } else { 177 } else {
179 type = new Type(type->fName + "[]", Type::kArray_Kind, *type, -1 ); 178 type = std::shared_ptr<Type>(new Type(type->fName + "[]", Type:: kArray_Kind, type,
180 fSymbolTable->takeOwnership((Type*) type); 179 -1));
181 currentVarSizes.push_back(nullptr); 180 currentVarSizes.push_back(nullptr);
182 } 181 }
183 } 182 }
184 sizes.push_back(std::move(currentVarSizes)); 183 sizes.push_back(std::move(currentVarSizes));
185 auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifi ers, decl.fNames[i], 184 auto var = std::make_shared<Variable>(decl.fPosition, modifiers, decl.fN ames[i], type,
186 *type, storage)); 185 storage);
186 variables.push_back(var);
187 std::unique_ptr<Expression> value; 187 std::unique_ptr<Expression> value;
188 if (decl.fValues[i]) { 188 if (decl.fValues[i]) {
189 value = this->convertExpression(*decl.fValues[i]); 189 value = this->convertExpression(*decl.fValues[i]);
190 if (!value) { 190 if (!value) {
191 return nullptr; 191 return nullptr;
192 } 192 }
193 value = this->coerce(std::move(value), *type); 193 value = this->coerce(std::move(value), type);
194 } 194 }
195 variables.push_back(var.get()); 195 fSymbolTable->add(var->fName, var);
196 fSymbolTable->add(decl.fNames[i], std::move(var));
197 values.push_back(std::move(value)); 196 values.push_back(std::move(value));
198 } 197 }
199 return std::unique_ptr<VarDeclaration>(new VarDeclaration(decl.fPosition, st d::move(variables), 198 return std::unique_ptr<VarDeclaration>(new VarDeclaration(decl.fPosition, st d::move(variables),
200 std::move(sizes), std::move(values))); 199 std::move(sizes), std::move(values)));
201 } 200 }
202 201
203 std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) { 202 std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) {
204 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*s.f Test), *kBool_Type); 203 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*s.f Test), kBool_Type);
205 if (!test) { 204 if (!test) {
206 return nullptr; 205 return nullptr;
207 } 206 }
208 std::unique_ptr<Statement> ifTrue = this->convertStatement(*s.fIfTrue); 207 std::unique_ptr<Statement> ifTrue = this->convertStatement(*s.fIfTrue);
209 if (!ifTrue) { 208 if (!ifTrue) {
210 return nullptr; 209 return nullptr;
211 } 210 }
212 std::unique_ptr<Statement> ifFalse; 211 std::unique_ptr<Statement> ifFalse;
213 if (s.fIfFalse) { 212 if (s.fIfFalse) {
214 ifFalse = this->convertStatement(*s.fIfFalse); 213 ifFalse = this->convertStatement(*s.fIfFalse);
215 if (!ifFalse) { 214 if (!ifFalse) {
216 return nullptr; 215 return nullptr;
217 } 216 }
218 } 217 }
219 return std::unique_ptr<Statement>(new IfStatement(s.fPosition, std::move(tes t), 218 return std::unique_ptr<Statement>(new IfStatement(s.fPosition, std::move(tes t),
220 std::move(ifTrue), std::mo ve(ifFalse))); 219 std::move(ifTrue), std::mo ve(ifFalse)));
221 } 220 }
222 221
223 std::unique_ptr<Statement> IRGenerator::convertFor(const ASTForStatement& f) { 222 std::unique_ptr<Statement> IRGenerator::convertFor(const ASTForStatement& f) {
224 AutoSymbolTable table(this); 223 AutoSymbolTable table(this);
225 std::unique_ptr<Statement> initializer = this->convertStatement(*f.fInitiali zer); 224 std::unique_ptr<Statement> initializer = this->convertStatement(*f.fInitiali zer);
226 if (!initializer) { 225 if (!initializer) {
227 return nullptr; 226 return nullptr;
228 } 227 }
229 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*f.f Test), *kBool_Type); 228 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*f.f Test), kBool_Type);
230 if (!test) { 229 if (!test) {
231 return nullptr; 230 return nullptr;
232 } 231 }
233 std::unique_ptr<Expression> next = this->convertExpression(*f.fNext); 232 std::unique_ptr<Expression> next = this->convertExpression(*f.fNext);
234 if (!next) { 233 if (!next) {
235 return nullptr; 234 return nullptr;
236 } 235 }
237 this->checkValid(*next); 236 this->checkValid(*next);
238 std::unique_ptr<Statement> statement = this->convertStatement(*f.fStatement) ; 237 std::unique_ptr<Statement> statement = this->convertStatement(*f.fStatement) ;
239 if (!statement) { 238 if (!statement) {
240 return nullptr; 239 return nullptr;
241 } 240 }
242 return std::unique_ptr<Statement>(new ForStatement(f.fPosition, std::move(in itializer), 241 return std::unique_ptr<Statement>(new ForStatement(f.fPosition, std::move(in itializer),
243 std::move(test), std::mov e(next), 242 std::move(test), std::mov e(next),
244 std::move(statement), fSy mbolTable)); 243 std::move(statement)));
245 } 244 }
246 245
247 std::unique_ptr<Statement> IRGenerator::convertWhile(const ASTWhileStatement& w) { 246 std::unique_ptr<Statement> IRGenerator::convertWhile(const ASTWhileStatement& w) {
248 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*w.f Test), *kBool_Type); 247 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*w.f Test), kBool_Type);
249 if (!test) { 248 if (!test) {
250 return nullptr; 249 return nullptr;
251 } 250 }
252 std::unique_ptr<Statement> statement = this->convertStatement(*w.fStatement) ; 251 std::unique_ptr<Statement> statement = this->convertStatement(*w.fStatement) ;
253 if (!statement) { 252 if (!statement) {
254 return nullptr; 253 return nullptr;
255 } 254 }
256 return std::unique_ptr<Statement>(new WhileStatement(w.fPosition, std::move( test), 255 return std::unique_ptr<Statement>(new WhileStatement(w.fPosition, std::move( test),
257 std::move(statement))); 256 std::move(statement)));
258 } 257 }
259 258
260 std::unique_ptr<Statement> IRGenerator::convertDo(const ASTDoStatement& d) { 259 std::unique_ptr<Statement> IRGenerator::convertDo(const ASTDoStatement& d) {
261 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*d.f Test), *kBool_Type); 260 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*d.f Test), kBool_Type);
262 if (!test) { 261 if (!test) {
263 return nullptr; 262 return nullptr;
264 } 263 }
265 std::unique_ptr<Statement> statement = this->convertStatement(*d.fStatement) ; 264 std::unique_ptr<Statement> statement = this->convertStatement(*d.fStatement) ;
266 if (!statement) { 265 if (!statement) {
267 return nullptr; 266 return nullptr;
268 } 267 }
269 return std::unique_ptr<Statement>(new DoStatement(d.fPosition, std::move(sta tement), 268 return std::unique_ptr<Statement>(new DoStatement(d.fPosition, std::move(sta tement),
270 std::move(test))); 269 std::move(test)));
271 } 270 }
272 271
273 std::unique_ptr<Statement> IRGenerator::convertExpressionStatement( 272 std::unique_ptr<Statement> IRGenerator::convertExpressionStatement(
274 const ASTExpre ssionStatement& s) { 273 const ASTExpre ssionStatement& s) {
275 std::unique_ptr<Expression> e = this->convertExpression(*s.fExpression); 274 std::unique_ptr<Expression> e = this->convertExpression(*s.fExpression);
276 if (!e) { 275 if (!e) {
277 return nullptr; 276 return nullptr;
278 } 277 }
279 this->checkValid(*e); 278 this->checkValid(*e);
280 return std::unique_ptr<Statement>(new ExpressionStatement(std::move(e))); 279 return std::unique_ptr<Statement>(new ExpressionStatement(std::move(e)));
281 } 280 }
282 281
283 std::unique_ptr<Statement> IRGenerator::convertReturn(const ASTReturnStatement& r) { 282 std::unique_ptr<Statement> IRGenerator::convertReturn(const ASTReturnStatement& r) {
284 ASSERT(fCurrentFunction); 283 ASSERT(fCurrentFunction);
285 if (r.fExpression) { 284 if (r.fExpression) {
286 std::unique_ptr<Expression> result = this->convertExpression(*r.fExpress ion); 285 std::unique_ptr<Expression> result = this->convertExpression(*r.fExpress ion);
287 if (!result) { 286 if (!result) {
288 return nullptr; 287 return nullptr;
289 } 288 }
290 if (fCurrentFunction->fReturnType == *kVoid_Type) { 289 if (fCurrentFunction->fReturnType == kVoid_Type) {
291 fErrors.error(result->fPosition, "may not return a value from a void function"); 290 fErrors.error(result->fPosition, "may not return a value from a void function");
292 } else { 291 } else {
293 result = this->coerce(std::move(result), fCurrentFunction->fReturnTy pe); 292 result = this->coerce(std::move(result), fCurrentFunction->fReturnTy pe);
294 if (!result) { 293 if (!result) {
295 return nullptr; 294 return nullptr;
296 } 295 }
297 } 296 }
298 return std::unique_ptr<Statement>(new ReturnStatement(std::move(result)) ); 297 return std::unique_ptr<Statement>(new ReturnStatement(std::move(result)) );
299 } else { 298 } else {
300 if (fCurrentFunction->fReturnType != *kVoid_Type) { 299 if (fCurrentFunction->fReturnType != kVoid_Type) {
301 fErrors.error(r.fPosition, "expected function to return '" + 300 fErrors.error(r.fPosition, "expected function to return '" +
302 fCurrentFunction->fReturnType.description () + "'"); 301 fCurrentFunction->fReturnType->descriptio n() + "'");
303 } 302 }
304 return std::unique_ptr<Statement>(new ReturnStatement(r.fPosition)); 303 return std::unique_ptr<Statement>(new ReturnStatement(r.fPosition));
305 } 304 }
306 } 305 }
307 306
308 std::unique_ptr<Statement> IRGenerator::convertBreak(const ASTBreakStatement& b) { 307 std::unique_ptr<Statement> IRGenerator::convertBreak(const ASTBreakStatement& b) {
309 return std::unique_ptr<Statement>(new BreakStatement(b.fPosition)); 308 return std::unique_ptr<Statement>(new BreakStatement(b.fPosition));
310 } 309 }
311 310
312 std::unique_ptr<Statement> IRGenerator::convertContinue(const ASTContinueStateme nt& c) { 311 std::unique_ptr<Statement> IRGenerator::convertContinue(const ASTContinueStateme nt& c) {
313 return std::unique_ptr<Statement>(new ContinueStatement(c.fPosition)); 312 return std::unique_ptr<Statement>(new ContinueStatement(c.fPosition));
314 } 313 }
315 314
316 std::unique_ptr<Statement> IRGenerator::convertDiscard(const ASTDiscardStatement & d) { 315 std::unique_ptr<Statement> IRGenerator::convertDiscard(const ASTDiscardStatement & d) {
317 return std::unique_ptr<Statement>(new DiscardStatement(d.fPosition)); 316 return std::unique_ptr<Statement>(new DiscardStatement(d.fPosition));
318 } 317 }
319 318
320 static const Type& expand_generics(const Type& type, int i) { 319 static std::shared_ptr<Type> expand_generics(std::shared_ptr<Type> type, int i) {
321 if (type.kind() == Type::kGeneric_Kind) { 320 if (type->kind() == Type::kGeneric_Kind) {
322 return *type.coercibleTypes()[i]; 321 return type->coercibleTypes()[i];
323 } 322 }
324 return type; 323 return type;
325 } 324 }
326 325
327 static void expand_generics(const FunctionDeclaration& decl, 326 static void expand_generics(FunctionDeclaration& decl,
328 std::shared_ptr<SymbolTable> symbolTable) { 327 SymbolTable& symbolTable) {
329 for (int i = 0; i < 4; i++) { 328 for (int i = 0; i < 4; i++) {
330 const Type& returnType = expand_generics(decl.fReturnType, i); 329 std::shared_ptr<Type> returnType = expand_generics(decl.fReturnType, i);
331 std::vector<const Variable*> parameters; 330 std::vector<std::shared_ptr<Variable>> arguments;
332 for (const auto& p : decl.fParameters) { 331 for (const auto& p : decl.fParameters) {
333 Variable* var = new Variable(p->fPosition, Modifiers(p->fModifiers), p->fName, 332 arguments.push_back(std::shared_ptr<Variable>(new Variable(
334 expand_generics(p->fType, i), 333 p->fPosition ,
335 Variable::kParameter_Storage); 334 Modifiers(p- >fModifiers),
336 symbolTable->takeOwnership(var); 335 p->fName,
337 parameters.push_back(var); 336 expand_gener ics(p->fType, i),
337 Variable::kP arameter_Storage)));
338 } 338 }
339 symbolTable->add(decl.fName, std::unique_ptr<FunctionDeclaration>(new Fu nctionDeclaration( 339 std::shared_ptr<FunctionDeclaration> expanded(new FunctionDeclaration(
340 decl. fPosition, 340 decl .fPosition,
341 decl. fName, 341 decl .fName,
342 std:: move(parameters), 342 std: :move(arguments),
343 std:: move(returnType)))); 343 std: :move(returnType)));
344 symbolTable.add(expanded->fName, expanded);
344 } 345 }
345 } 346 }
346 347
347 std::unique_ptr<FunctionDefinition> IRGenerator::convertFunction(const ASTFuncti on& f) { 348 std::unique_ptr<FunctionDefinition> IRGenerator::convertFunction(const ASTFuncti on& f) {
349 std::shared_ptr<SymbolTable> old = fSymbolTable;
350 AutoSymbolTable table(this);
348 bool isGeneric; 351 bool isGeneric;
349 const Type* returnType = this->convertType(*f.fReturnType); 352 std::shared_ptr<Type> returnType = this->convertType(*f.fReturnType);
350 if (!returnType) { 353 if (!returnType) {
351 return nullptr; 354 return nullptr;
352 } 355 }
353 isGeneric = returnType->kind() == Type::kGeneric_Kind; 356 isGeneric = returnType->kind() == Type::kGeneric_Kind;
354 std::vector<const Variable*> parameters; 357 std::vector<std::shared_ptr<Variable>> parameters;
355 for (const auto& param : f.fParameters) { 358 for (const auto& param : f.fParameters) {
356 const Type* type = this->convertType(*param->fType); 359 std::shared_ptr<Type> type = this->convertType(*param->fType);
357 if (!type) { 360 if (!type) {
358 return nullptr; 361 return nullptr;
359 } 362 }
360 for (int j = (int) param->fSizes.size() - 1; j >= 0; j--) { 363 for (int j = (int) param->fSizes.size() - 1; j >= 0; j--) {
361 int size = param->fSizes[j]; 364 int size = param->fSizes[j];
362 std::string name = type->name() + "[" + to_string(size) + "]"; 365 std::string name = type->name() + "[" + to_string(size) + "]";
363 Type* newType = new Type(std::move(name), Type::kArray_Kind, *type, size); 366 type = std::shared_ptr<Type>(new Type(std::move(name), Type::kArray_ Kind,
364 fSymbolTable->takeOwnership(newType); 367 std::move(type), size));
365 type = newType;
366 } 368 }
367 std::string name = param->fName; 369 std::string name = param->fName;
368 Modifiers modifiers = this->convertModifiers(param->fModifiers); 370 Modifiers modifiers = this->convertModifiers(param->fModifiers);
369 Position pos = param->fPosition; 371 Position pos = param->fPosition;
370 Variable* var = new Variable(pos, modifiers, std::move(name), *type, 372 std::shared_ptr<Variable> var = std::shared_ptr<Variable>(new Variable(
371 Variable::kParameter_Storage); 373 pos,
372 fSymbolTable->takeOwnership(var); 374 modifiers,
373 parameters.push_back(var); 375 std::move(n ame),
376 type,
377 Variable::k Parameter_Storage));
378 parameters.push_back(std::move(var));
374 isGeneric |= type->kind() == Type::kGeneric_Kind; 379 isGeneric |= type->kind() == Type::kGeneric_Kind;
375 } 380 }
376 381
377 // find existing declaration 382 // find existing declaration
378 const FunctionDeclaration* decl = nullptr; 383 std::shared_ptr<FunctionDeclaration> decl;
379 auto entry = (*fSymbolTable)[f.fName]; 384 auto entry = (*old)[f.fName];
380 if (entry) { 385 if (entry) {
381 std::vector<const FunctionDeclaration*> functions; 386 std::vector<std::shared_ptr<FunctionDeclaration>> functions;
382 switch (entry->fKind) { 387 switch (entry->fKind) {
383 case Symbol::kUnresolvedFunction_Kind: 388 case Symbol::kUnresolvedFunction_Kind:
384 functions = ((UnresolvedFunction*) entry)->fFunctions; 389 functions = std::static_pointer_cast<UnresolvedFunction>(entry)- >fFunctions;
385 break; 390 break;
386 case Symbol::kFunctionDeclaration_Kind: 391 case Symbol::kFunctionDeclaration_Kind:
387 functions.push_back((FunctionDeclaration*) entry); 392 functions.push_back(std::static_pointer_cast<FunctionDeclaration >(entry));
388 break; 393 break;
389 default: 394 default:
390 fErrors.error(f.fPosition, "symbol '" + f.fName + "' was already defined"); 395 fErrors.error(f.fPosition, "symbol '" + f.fName + "' was already defined");
391 return nullptr; 396 return nullptr;
392 } 397 }
393 for (const auto& other : functions) { 398 for (const auto& other : functions) {
394 ASSERT(other->fName == f.fName); 399 ASSERT(other->fName == f.fName);
395 if (parameters.size() == other->fParameters.size()) { 400 if (parameters.size() == other->fParameters.size()) {
396 bool match = true; 401 bool match = true;
397 for (size_t i = 0; i < parameters.size(); i++) { 402 for (size_t i = 0; i < parameters.size(); i++) {
398 if (parameters[i]->fType != other->fParameters[i]->fType) { 403 if (parameters[i]->fType != other->fParameters[i]->fType) {
399 match = false; 404 match = false;
400 break; 405 break;
401 } 406 }
402 } 407 }
403 if (match) { 408 if (match) {
404 if (*returnType != other->fReturnType) { 409 if (returnType != other->fReturnType) {
405 FunctionDeclaration newDecl(f.fPosition, f.fName, parame ters, *returnType); 410 FunctionDeclaration newDecl = FunctionDeclaration(f.fPos ition,
411 f.fNam e,
412 parame ters,
413 return Type);
406 fErrors.error(f.fPosition, "functions '" + newDecl.descr iption() + 414 fErrors.error(f.fPosition, "functions '" + newDecl.descr iption() +
407 "' and '" + other->descriptio n() + 415 "' and '" + other->descriptio n() +
408 "' differ only in return type "); 416 "' differ only in return type ");
409 return nullptr; 417 return nullptr;
410 } 418 }
411 decl = other; 419 decl = other;
412 for (size_t i = 0; i < parameters.size(); i++) { 420 for (size_t i = 0; i < parameters.size(); i++) {
413 if (parameters[i]->fModifiers != other->fParameters[i]-> fModifiers) { 421 if (parameters[i]->fModifiers != other->fParameters[i]-> fModifiers) {
414 fErrors.error(f.fPosition, "modifiers on parameter " + 422 fErrors.error(f.fPosition, "modifiers on parameter " +
415 to_string(i + 1) + " diff er between " + 423 to_string(i + 1) + " diff er between " +
416 "declaration and definiti on"); 424 "declaration and definiti on");
417 return nullptr; 425 return nullptr;
418 } 426 }
427 fSymbolTable->add(parameters[i]->fName, decl->fParameter s[i]);
419 } 428 }
420 if (other->fDefined) { 429 if (other->fDefined) {
421 fErrors.error(f.fPosition, "duplicate definition of " + 430 fErrors.error(f.fPosition, "duplicate definition of " +
422 other->description()); 431 other->description());
423 } 432 }
424 break; 433 break;
425 } 434 }
426 } 435 }
427 } 436 }
428 } 437 }
429 if (!decl) { 438 if (!decl) {
430 // couldn't find an existing declaration 439 // couldn't find an existing declaration
431 if (isGeneric) { 440 decl.reset(new FunctionDeclaration(f.fPosition, f.fName, parameters, ret urnType));
432 ASSERT(!f.fBody); 441 for (auto var : parameters) {
433 expand_generics(FunctionDeclaration(f.fPosition, f.fName, parameters , *returnType), 442 fSymbolTable->add(var->fName, var);
434 fSymbolTable);
435 } else {
436 auto newDecl = std::unique_ptr<FunctionDeclaration>(new FunctionDecl aration(
437 f.fPosition,
438 f.fName,
439 parameters,
440 *returnType));
441 decl = newDecl.get();
442 fSymbolTable->add(decl->fName, std::move(newDecl));
443 } 443 }
444 } 444 }
445 if (f.fBody) { 445 if (isGeneric) {
446 ASSERT(!fCurrentFunction); 446 ASSERT(!f.fBody);
447 fCurrentFunction = decl; 447 expand_generics(*decl, *old);
448 decl->fDefined = true; 448 } else {
449 std::shared_ptr<SymbolTable> old = fSymbolTable; 449 old->add(decl->fName, decl);
450 AutoSymbolTable table(this); 450 if (f.fBody) {
451 for (size_t i = 0; i < parameters.size(); i++) { 451 ASSERT(!fCurrentFunction);
452 fSymbolTable->addWithoutOwnership(parameters[i]->fName, decl->fParam eters[i]); 452 fCurrentFunction = decl;
453 decl->fDefined = true;
454 std::unique_ptr<Block> body = this->convertBlock(*f.fBody);
455 fCurrentFunction = nullptr;
456 if (!body) {
457 return nullptr;
458 }
459 return std::unique_ptr<FunctionDefinition>(new FunctionDefinition(f. fPosition, decl,
460 st d::move(body)));
453 } 461 }
454 std::unique_ptr<Block> body = this->convertBlock(*f.fBody);
455 fCurrentFunction = nullptr;
456 if (!body) {
457 return nullptr;
458 }
459 return std::unique_ptr<FunctionDefinition>(new FunctionDefinition(f.fPos ition, *decl,
460 std::m ove(body)));
461 } 462 }
462 return nullptr; 463 return nullptr;
463 } 464 }
464 465
465 std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTInte rfaceBlock& intf) { 466 std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTInte rfaceBlock& intf) {
466 std::shared_ptr<SymbolTable> old = fSymbolTable; 467 std::shared_ptr<SymbolTable> old = fSymbolTable;
467 AutoSymbolTable table(this); 468 AutoSymbolTable table(this);
468 Modifiers mods = this->convertModifiers(intf.fModifiers); 469 Modifiers mods = this->convertModifiers(intf.fModifiers);
469 std::vector<Type::Field> fields; 470 std::vector<Type::Field> fields;
470 for (size_t i = 0; i < intf.fDeclarations.size(); i++) { 471 for (size_t i = 0; i < intf.fDeclarations.size(); i++) {
471 std::unique_ptr<VarDeclaration> decl = this->convertVarDeclaration( 472 std::unique_ptr<VarDeclaration> decl = this->convertVarDeclaration(
472 *intf.f Declarations[i], 473 *intf.f Declarations[i],
473 Variabl e::kGlobal_Storage); 474 Variabl e::kGlobal_Storage);
474 for (size_t j = 0; j < decl->fVars.size(); j++) { 475 for (size_t j = 0; j < decl->fVars.size(); j++) {
475 fields.push_back(Type::Field(decl->fVars[j]->fModifiers, decl->fVars [j]->fName, 476 fields.push_back(Type::Field(decl->fVars[j]->fModifiers, decl->fVars [j]->fName,
476 decl->fVars[j]->fType)); 477 decl->fVars[j]->fType));
477 if (decl->fValues[j]) { 478 if (decl->fValues[j]) {
478 fErrors.error(decl->fPosition, 479 fErrors.error(decl->fPosition,
479 "initializers are not permitted on interface block fields"); 480 "initializers are not permitted on interface block fields");
480 } 481 }
481 if (decl->fVars[j]->fModifiers.fFlags & (Modifiers::kIn_Flag | 482 if (decl->fVars[j]->fModifiers.fFlags & (Modifiers::kIn_Flag |
482 Modifiers::kOut_Flag | 483 Modifiers::kOut_Flag |
483 Modifiers::kUniform_Flag | 484 Modifiers::kUniform_Flag |
484 Modifiers::kConst_Flag)) { 485 Modifiers::kConst_Flag)) {
485 fErrors.error(decl->fPosition, 486 fErrors.error(decl->fPosition,
486 "interface block fields may not have storage quali fiers"); 487 "interface block fields may not have storage quali fiers");
487 } 488 }
488 } 489 }
489 } 490 }
490 Type* type = new Type(intf.fInterfaceName, fields); 491 std::shared_ptr<Type> type = std::shared_ptr<Type>(new Type(intf.fInterfaceN ame, fields));
491 fSymbolTable->takeOwnership(type);
492 std::string name = intf.fValueName.length() > 0 ? intf.fValueName : intf.fIn terfaceName; 492 std::string name = intf.fValueName.length() > 0 ? intf.fValueName : intf.fIn terfaceName;
493 Variable* var = new Variable(intf.fPosition, mods, name, *type, Variable::kG lobal_Storage); 493 std::shared_ptr<Variable> var = std::shared_ptr<Variable>(new Variable(intf. fPosition, mods,
494 fSymbolTable->takeOwnership(var); 494 name, type,
495 Variable::kGloba l_Storage));
495 if (intf.fValueName.length()) { 496 if (intf.fValueName.length()) {
496 old->addWithoutOwnership(intf.fValueName, var); 497 old->add(intf.fValueName, var);
498
497 } else { 499 } else {
498 for (size_t i = 0; i < fields.size(); i++) { 500 for (size_t i = 0; i < fields.size(); i++) {
499 old->add(fields[i].fName, std::unique_ptr<Field>(new Field(intf.fPos ition, *var, 501 std::shared_ptr<Field> field = std::shared_ptr<Field>(new Field(intf .fPosition, var,
500 (int) i)) ); 502 (int ) i));
503 old->add(fields[i].fName, field);
501 } 504 }
502 } 505 }
503 return std::unique_ptr<InterfaceBlock>(new InterfaceBlock(intf.fPosition, *v ar, fSymbolTable)); 506 return std::unique_ptr<InterfaceBlock>(new InterfaceBlock(intf.fPosition, va r));
504 } 507 }
505 508
506 const Type* IRGenerator::convertType(const ASTType& type) { 509 std::shared_ptr<Type> IRGenerator::convertType(const ASTType& type) {
507 const Symbol* result = (*fSymbolTable)[type.fName]; 510 std::shared_ptr<Symbol> result = (*fSymbolTable)[type.fName];
508 if (result && result->fKind == Symbol::kType_Kind) { 511 if (result && result->fKind == Symbol::kType_Kind) {
509 return (const Type*) result; 512 return std::static_pointer_cast<Type>(result);
510 } 513 }
511 fErrors.error(type.fPosition, "unknown type '" + type.fName + "'"); 514 fErrors.error(type.fPosition, "unknown type '" + type.fName + "'");
512 return nullptr; 515 return nullptr;
513 } 516 }
514 517
515 std::unique_ptr<Expression> IRGenerator::convertExpression(const ASTExpression& expr) { 518 std::unique_ptr<Expression> IRGenerator::convertExpression(const ASTExpression& expr) {
516 switch (expr.fKind) { 519 switch (expr.fKind) {
517 case ASTExpression::kIdentifier_Kind: 520 case ASTExpression::kIdentifier_Kind:
518 return this->convertIdentifier((ASTIdentifier&) expr); 521 return this->convertIdentifier((ASTIdentifier&) expr);
519 case ASTExpression::kBool_Kind: 522 case ASTExpression::kBool_Kind:
(...skipping 12 matching lines...) Expand all
532 case ASTExpression::kSuffix_Kind: 535 case ASTExpression::kSuffix_Kind:
533 return this->convertSuffixExpression((ASTSuffixExpression&) expr); 536 return this->convertSuffixExpression((ASTSuffixExpression&) expr);
534 case ASTExpression::kTernary_Kind: 537 case ASTExpression::kTernary_Kind:
535 return this->convertTernaryExpression((ASTTernaryExpression&) expr); 538 return this->convertTernaryExpression((ASTTernaryExpression&) expr);
536 default: 539 default:
537 ABORT("unsupported expression type: %d\n", expr.fKind); 540 ABORT("unsupported expression type: %d\n", expr.fKind);
538 } 541 }
539 } 542 }
540 543
541 std::unique_ptr<Expression> IRGenerator::convertIdentifier(const ASTIdentifier& identifier) { 544 std::unique_ptr<Expression> IRGenerator::convertIdentifier(const ASTIdentifier& identifier) {
542 const Symbol* result = (*fSymbolTable)[identifier.fText]; 545 std::shared_ptr<Symbol> result = (*fSymbolTable)[identifier.fText];
543 if (!result) { 546 if (!result) {
544 fErrors.error(identifier.fPosition, "unknown identifier '" + identifier. fText + "'"); 547 fErrors.error(identifier.fPosition, "unknown identifier '" + identifier. fText + "'");
545 return nullptr; 548 return nullptr;
546 } 549 }
547 switch (result->fKind) { 550 switch (result->fKind) {
548 case Symbol::kFunctionDeclaration_Kind: { 551 case Symbol::kFunctionDeclaration_Kind: {
549 std::vector<const FunctionDeclaration*> f = { 552 std::vector<std::shared_ptr<FunctionDeclaration>> f = {
550 (const FunctionDeclaration*) result 553 std::static_pointer_cast<FunctionDeclaration>(result)
551 }; 554 };
552 return std::unique_ptr<FunctionReference>(new FunctionReference(iden tifier.fPosition, 555 return std::unique_ptr<FunctionReference>(new FunctionReference(iden tifier.fPosition,
553 f)); 556 std: :move(f)));
554 } 557 }
555 case Symbol::kUnresolvedFunction_Kind: { 558 case Symbol::kUnresolvedFunction_Kind: {
556 const UnresolvedFunction* f = (const UnresolvedFunction*) result; 559 auto f = std::static_pointer_cast<UnresolvedFunction>(result);
557 return std::unique_ptr<FunctionReference>(new FunctionReference(iden tifier.fPosition, 560 return std::unique_ptr<FunctionReference>(new FunctionReference(iden tifier.fPosition,
558 f->f Functions)); 561 f->f Functions));
559 } 562 }
560 case Symbol::kVariable_Kind: { 563 case Symbol::kVariable_Kind: {
561 const Variable* var = (const Variable*) result; 564 std::shared_ptr<Variable> var = std::static_pointer_cast<Variable>(r esult);
562 this->markReadFrom(*var); 565 this->markReadFrom(var);
563 return std::unique_ptr<VariableReference>(new VariableReference(iden tifier.fPosition, 566 return std::unique_ptr<VariableReference>(new VariableReference(iden tifier.fPosition,
564 *var )); 567 std: :move(var)));
565 } 568 }
566 case Symbol::kField_Kind: { 569 case Symbol::kField_Kind: {
567 const Field* field = (const Field*) result; 570 std::shared_ptr<Field> field = std::static_pointer_cast<Field>(resul t);
568 VariableReference* base = new VariableReference(identifier.fPosition , field->fOwner); 571 VariableReference* base = new VariableReference(identifier.fPosition , field->fOwner);
569 return std::unique_ptr<Expression>(new FieldAccess(std::unique_ptr<E xpression>(base), 572 return std::unique_ptr<Expression>(new FieldAccess(std::unique_ptr<E xpression>(base),
570 field->fFieldInde x)); 573 field->fFieldInde x));
571 } 574 }
572 case Symbol::kType_Kind: { 575 case Symbol::kType_Kind: {
573 const Type* t = (const Type*) result; 576 auto t = std::static_pointer_cast<Type>(result);
574 return std::unique_ptr<TypeReference>(new TypeReference(identifier.f Position, 577 return std::unique_ptr<TypeReference>(new TypeReference(identifier.f Position,
575 *t)); 578 std::move(t) ));
576 } 579 }
577 default: 580 default:
578 ABORT("unsupported symbol type %d\n", result->fKind); 581 ABORT("unsupported symbol type %d\n", result->fKind);
579 } 582 }
580 583
581 } 584 }
582 585
583 std::unique_ptr<Expression> IRGenerator::coerce(std::unique_ptr<Expression> expr , 586 std::unique_ptr<Expression> IRGenerator::coerce(std::unique_ptr<Expression> expr ,
584 const Type& type) { 587 std::shared_ptr<Type> type) {
585 if (!expr) { 588 if (!expr) {
586 return nullptr; 589 return nullptr;
587 } 590 }
588 if (expr->fType == type) { 591 if (*expr->fType == *type) {
589 return expr; 592 return expr;
590 } 593 }
591 this->checkValid(*expr); 594 this->checkValid(*expr);
592 if (expr->fType == *kInvalid_Type) { 595 if (*expr->fType == *kInvalid_Type) {
593 return nullptr; 596 return nullptr;
594 } 597 }
595 if (!expr->fType.canCoerceTo(type)) { 598 if (!expr->fType->canCoerceTo(type)) {
596 fErrors.error(expr->fPosition, "expected '" + type.description() + "', b ut found '" + 599 fErrors.error(expr->fPosition, "expected '" + type->description() + "', but found '" +
597 expr->fType.description() + "'"); 600 expr->fType->description() + "'");
598 return nullptr; 601 return nullptr;
599 } 602 }
600 if (type.kind() == Type::kScalar_Kind) { 603 if (type->kind() == Type::kScalar_Kind) {
601 std::vector<std::unique_ptr<Expression>> args; 604 std::vector<std::unique_ptr<Expression>> args;
602 args.push_back(std::move(expr)); 605 args.push_back(std::move(expr));
603 ASTIdentifier id(Position(), type.description()); 606 ASTIdentifier id(Position(), type->description());
604 std::unique_ptr<Expression> ctor = this->convertIdentifier(id); 607 std::unique_ptr<Expression> ctor = this->convertIdentifier(id);
605 ASSERT(ctor); 608 ASSERT(ctor);
606 return this->call(Position(), std::move(ctor), std::move(args)); 609 return this->call(Position(), std::move(ctor), std::move(args));
607 } 610 }
608 ABORT("cannot coerce %s to %s", expr->fType.description().c_str(), 611 ABORT("cannot coerce %s to %s", expr->fType->description().c_str(),
609 type.description().c_str()); 612 type->description().c_str());
610 } 613 }
611 614
612 /** 615 /**
613 * Determines the operand and result types of a binary expression. Returns true if the expression is 616 * Determines the operand and result types of a binary expression. Returns true if the expression is
614 * legal, false otherwise. If false, the values of the out parameters are undefi ned. 617 * legal, false otherwise. If false, the values of the out parameters are undefi ned.
615 */ 618 */
616 static bool determine_binary_type(Token::Kind op, const Type& left, const Type& right, 619 static bool determine_binary_type(Token::Kind op, std::shared_ptr<Type> left,
617 const Type** outLeftType, 620 std::shared_ptr<Type> right,
618 const Type** outRightType, 621 std::shared_ptr<Type>* outLeftType,
619 const Type** outResultType, 622 std::shared_ptr<Type>* outRightType,
623 std::shared_ptr<Type>* outResultType,
620 bool tryFlipped) { 624 bool tryFlipped) {
621 bool isLogical; 625 bool isLogical;
622 switch (op) { 626 switch (op) {
623 case Token::EQEQ: // fall through 627 case Token::EQEQ: // fall through
624 case Token::NEQ: // fall through 628 case Token::NEQ: // fall through
625 case Token::LT: // fall through 629 case Token::LT: // fall through
626 case Token::GT: // fall through 630 case Token::GT: // fall through
627 case Token::LTEQ: // fall through 631 case Token::LTEQ: // fall through
628 case Token::GTEQ: 632 case Token::GTEQ:
629 isLogical = true; 633 isLogical = true;
630 break; 634 break;
631 case Token::LOGICALOR: // fall through 635 case Token::LOGICALOR: // fall through
632 case Token::LOGICALAND: // fall through 636 case Token::LOGICALAND: // fall through
633 case Token::LOGICALXOR: // fall through 637 case Token::LOGICALXOR: // fall through
634 case Token::LOGICALOREQ: // fall through 638 case Token::LOGICALOREQ: // fall through
635 case Token::LOGICALANDEQ: // fall through 639 case Token::LOGICALANDEQ: // fall through
636 case Token::LOGICALXOREQ: 640 case Token::LOGICALXOREQ:
637 *outLeftType = kBool_Type; 641 *outLeftType = kBool_Type;
638 *outRightType = kBool_Type; 642 *outRightType = kBool_Type;
639 *outResultType = kBool_Type; 643 *outResultType = kBool_Type;
640 return left.canCoerceTo(*kBool_Type) && right.canCoerceTo(*kBool_Typ e); 644 return left->canCoerceTo(kBool_Type) && right->canCoerceTo(kBool_Typ e);
641 case Token::STAR: // fall through 645 case Token::STAR: // fall through
642 case Token::STAREQ: 646 case Token::STAREQ:
643 // FIXME need to handle non-square matrices 647 // FIXME need to handle non-square matrices
644 if (left.kind() == Type::kMatrix_Kind && right.kind() == Type::kVect or_Kind) { 648 if (left->kind() == Type::kMatrix_Kind && right->kind() == Type::kVe ctor_Kind) {
645 *outLeftType = &left; 649 *outLeftType = left;
646 *outRightType = &right; 650 *outRightType = right;
647 *outResultType = &right; 651 *outResultType = right;
648 return left.rows() == right.columns(); 652 return left->rows() == right->columns();
649 } 653 }
650 if (left.kind() == Type::kVector_Kind && right.kind() == Type::kMatr ix_Kind) { 654 if (left->kind() == Type::kVector_Kind && right->kind() == Type::kMa trix_Kind) {
651 *outLeftType = &left; 655 *outLeftType = left;
652 *outRightType = &right; 656 *outRightType = right;
653 *outResultType = &left; 657 *outResultType = left;
654 return left.columns() == right.columns(); 658 return left->columns() == right->columns();
655 } 659 }
656 // fall through 660 // fall through
657 default: 661 default:
658 isLogical = false; 662 isLogical = false;
659 } 663 }
660 // FIXME: need to disallow illegal operations like vec3 > vec3. Also do not currently have 664 // FIXME: need to disallow illegal operations like vec3 > vec3. Also do not currently have
661 // full support for numbers other than float. 665 // full support for numbers other than float.
662 if (left == right) { 666 if (left == right) {
663 *outLeftType = &left; 667 *outLeftType = left;
664 *outRightType = &left; 668 *outRightType = left;
665 if (isLogical) { 669 if (isLogical) {
666 *outResultType = kBool_Type; 670 *outResultType = kBool_Type;
667 } else { 671 } else {
668 *outResultType = &left; 672 *outResultType = left;
669 } 673 }
670 return true; 674 return true;
671 } 675 }
672 // FIXME: incorrect for shift operations 676 // FIXME: incorrect for shift operations
673 if (left.canCoerceTo(right)) { 677 if (left->canCoerceTo(right)) {
674 *outLeftType = &right; 678 *outLeftType = right;
675 *outRightType = &right; 679 *outRightType = right;
676 if (isLogical) { 680 if (isLogical) {
677 *outResultType = kBool_Type; 681 *outResultType = kBool_Type;
678 } else { 682 } else {
679 *outResultType = &right; 683 *outResultType = right;
680 } 684 }
681 return true; 685 return true;
682 } 686 }
683 if ((left.kind() == Type::kVector_Kind || left.kind() == Type::kMatrix_Kind) && 687 if ((left->kind() == Type::kVector_Kind || left->kind() == Type::kMatrix_Kin d) &&
684 (right.kind() == Type::kScalar_Kind)) { 688 (right->kind() == Type::kScalar_Kind)) {
685 if (determine_binary_type(op, left.componentType(), right, outLeftType, outRightType, 689 if (determine_binary_type(op, left->componentType(), right, outLeftType, outRightType,
686 outResultType, false)) { 690 outResultType, false)) {
687 *outLeftType = &(*outLeftType)->toCompound(left.columns(), left.rows ()); 691 *outLeftType = (*outLeftType)->toCompound(left->columns(), left->row s());
688 if (!isLogical) { 692 if (!isLogical) {
689 *outResultType = &(*outResultType)->toCompound(left.columns(), l eft.rows()); 693 *outResultType = (*outResultType)->toCompound(left->columns(), l eft->rows());
690 } 694 }
691 return true; 695 return true;
692 } 696 }
693 return false; 697 return false;
694 } 698 }
695 if (tryFlipped) { 699 if (tryFlipped) {
696 return determine_binary_type(op, right, left, outRightType, outLeftType, outResultType, 700 return determine_binary_type(op, right, left, outRightType, outLeftType, outResultType,
697 false); 701 false);
698 } 702 }
699 return false; 703 return false;
700 } 704 }
701 705
702 std::unique_ptr<Expression> IRGenerator::convertBinaryExpression( 706 std::unique_ptr<Expression> IRGenerator::convertBinaryExpression(
703 const ASTBinaryExpre ssion& expression) { 707 const ASTBinaryExpre ssion& expression) {
704 std::unique_ptr<Expression> left = this->convertExpression(*expression.fLeft ); 708 std::unique_ptr<Expression> left = this->convertExpression(*expression.fLeft );
705 if (!left) { 709 if (!left) {
706 return nullptr; 710 return nullptr;
707 } 711 }
708 std::unique_ptr<Expression> right = this->convertExpression(*expression.fRig ht); 712 std::unique_ptr<Expression> right = this->convertExpression(*expression.fRig ht);
709 if (!right) { 713 if (!right) {
710 return nullptr; 714 return nullptr;
711 } 715 }
712 const Type* leftType; 716 std::shared_ptr<Type> leftType;
713 const Type* rightType; 717 std::shared_ptr<Type> rightType;
714 const Type* resultType; 718 std::shared_ptr<Type> resultType;
715 if (!determine_binary_type(expression.fOperator, left->fType, right->fType, &leftType, 719 if (!determine_binary_type(expression.fOperator, left->fType, right->fType, &leftType,
716 &rightType, &resultType, true)) { 720 &rightType, &resultType, true)) {
717 fErrors.error(expression.fPosition, "type mismatch: '" + 721 fErrors.error(expression.fPosition, "type mismatch: '" +
718 Token::OperatorName(expression.fOper ator) + 722 Token::OperatorName(expression.fOper ator) +
719 "' cannot operate on '" + left->fTyp e.fName + 723 "' cannot operate on '" + left->fTyp e->fName +
720 "', '" + right->fType.fName + "'"); 724 "', '" + right->fType->fName + "'");
721 return nullptr; 725 return nullptr;
722 } 726 }
723 switch (expression.fOperator) { 727 switch (expression.fOperator) {
724 case Token::EQ: // fall through 728 case Token::EQ: // fall through
725 case Token::PLUSEQ: // fall through 729 case Token::PLUSEQ: // fall through
726 case Token::MINUSEQ: // fall through 730 case Token::MINUSEQ: // fall through
727 case Token::STAREQ: // fall through 731 case Token::STAREQ: // fall through
728 case Token::SLASHEQ: // fall through 732 case Token::SLASHEQ: // fall through
729 case Token::PERCENTEQ: // fall through 733 case Token::PERCENTEQ: // fall through
730 case Token::SHLEQ: // fall through 734 case Token::SHLEQ: // fall through
731 case Token::SHREQ: // fall through 735 case Token::SHREQ: // fall through
732 case Token::BITWISEOREQ: // fall through 736 case Token::BITWISEOREQ: // fall through
733 case Token::BITWISEXOREQ: // fall through 737 case Token::BITWISEXOREQ: // fall through
734 case Token::BITWISEANDEQ: // fall through 738 case Token::BITWISEANDEQ: // fall through
735 case Token::LOGICALOREQ: // fall through 739 case Token::LOGICALOREQ: // fall through
736 case Token::LOGICALXOREQ: // fall through 740 case Token::LOGICALXOREQ: // fall through
737 case Token::LOGICALANDEQ: 741 case Token::LOGICALANDEQ:
738 this->markWrittenTo(*left); 742 this->markWrittenTo(*left);
739 default: 743 default:
740 break; 744 break;
741 } 745 }
742 return std::unique_ptr<Expression>(new BinaryExpression(expression.fPosition , 746 return std::unique_ptr<Expression>(new BinaryExpression(expression.fPosition ,
743 this->coerce(std::mo ve(left), 747 this->coerce(std::mo ve(left), leftType),
744 *leftTy pe),
745 expression.fOperator , 748 expression.fOperator ,
746 this->coerce(std::mo ve(right), 749 this->coerce(std::mo ve(right),
747 *rightT ype), 750 rightTy pe),
748 *resultType)); 751 resultType));
749 } 752 }
750 753
751 std::unique_ptr<Expression> IRGenerator::convertTernaryExpression( 754 std::unique_ptr<Expression> IRGenerator::convertTernaryExpression(
752 const ASTTernaryExpre ssion& expression) { 755 const ASTTernaryExpre ssion& expression) {
753 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*exp ression.fTest), 756 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*exp ression.fTest),
754 *kBool_Type); 757 kBool_Type);
755 if (!test) { 758 if (!test) {
756 return nullptr; 759 return nullptr;
757 } 760 }
758 std::unique_ptr<Expression> ifTrue = this->convertExpression(*expression.fIf True); 761 std::unique_ptr<Expression> ifTrue = this->convertExpression(*expression.fIf True);
759 if (!ifTrue) { 762 if (!ifTrue) {
760 return nullptr; 763 return nullptr;
761 } 764 }
762 std::unique_ptr<Expression> ifFalse = this->convertExpression(*expression.fI fFalse); 765 std::unique_ptr<Expression> ifFalse = this->convertExpression(*expression.fI fFalse);
763 if (!ifFalse) { 766 if (!ifFalse) {
764 return nullptr; 767 return nullptr;
765 } 768 }
766 const Type* trueType; 769 std::shared_ptr<Type> trueType;
767 const Type* falseType; 770 std::shared_ptr<Type> falseType;
768 const Type* resultType; 771 std::shared_ptr<Type> resultType;
769 if (!determine_binary_type(Token::EQEQ, ifTrue->fType, ifFalse->fType, &true Type, 772 if (!determine_binary_type(Token::EQEQ, ifTrue->fType, ifFalse->fType, &true Type,
770 &falseType, &resultType, true)) { 773 &falseType, &resultType, true)) {
771 fErrors.error(expression.fPosition, "ternary operator result mismatch: ' " + 774 fErrors.error(expression.fPosition, "ternary operator result mismatch: ' " +
772 ifTrue->fType.fName + "', '" + 775 ifTrue->fType->fName + "', '" +
773 ifFalse->fType.fName + "'"); 776 ifFalse->fType->fName + "'");
774 return nullptr; 777 return nullptr;
775 } 778 }
776 ASSERT(trueType == falseType); 779 ASSERT(trueType == falseType);
777 ifTrue = this->coerce(std::move(ifTrue), *trueType); 780 ifTrue = this->coerce(std::move(ifTrue), trueType);
778 ifFalse = this->coerce(std::move(ifFalse), *falseType); 781 ifFalse = this->coerce(std::move(ifFalse), falseType);
779 return std::unique_ptr<Expression>(new TernaryExpression(expression.fPositio n, 782 return std::unique_ptr<Expression>(new TernaryExpression(expression.fPositio n,
780 std::move(test), 783 std::move(test),
781 std::move(ifTrue), 784 std::move(ifTrue),
782 std::move(ifFalse)) ); 785 std::move(ifFalse)) );
783 } 786 }
784 787
785 std::unique_ptr<Expression> IRGenerator::call(Position position, 788 std::unique_ptr<Expression> IRGenerator::call(
786 const FunctionDeclaration& functio n, 789 Position position,
787 std::vector<std::unique_ptr<Expres sion>> arguments) { 790 std::shared_ptr<FunctionDeclaration> fu nction,
788 if (function.fParameters.size() != arguments.size()) { 791 std::vector<std::unique_ptr<Expression> > arguments) {
789 std::string msg = "call to '" + function.fName + "' expected " + 792 if (function->fParameters.size() != arguments.size()) {
790 to_string(function.fParameters.size()) + 793 std::string msg = "call to '" + function->fName + "' expected " +
794 to_string(function->fParameters.size()) +
791 " argument"; 795 " argument";
792 if (function.fParameters.size() != 1) { 796 if (function->fParameters.size() != 1) {
793 msg += "s"; 797 msg += "s";
794 } 798 }
795 msg += ", but found " + to_string(arguments.size()); 799 msg += ", but found " + to_string(arguments.size());
796 fErrors.error(position, msg); 800 fErrors.error(position, msg);
797 return nullptr; 801 return nullptr;
798 } 802 }
799 for (size_t i = 0; i < arguments.size(); i++) { 803 for (size_t i = 0; i < arguments.size(); i++) {
800 arguments[i] = this->coerce(std::move(arguments[i]), function.fParameter s[i]->fType); 804 arguments[i] = this->coerce(std::move(arguments[i]), function->fParamete rs[i]->fType);
801 if (arguments[i] && (function.fParameters[i]->fModifiers.fFlags & Modifi ers::kOut_Flag)) { 805 if (arguments[i] && (function->fParameters[i]->fModifiers.fFlags & Modif iers::kOut_Flag)) {
802 this->markWrittenTo(*arguments[i]); 806 this->markWrittenTo(*arguments[i]);
803 } 807 }
804 } 808 }
805 return std::unique_ptr<FunctionCall>(new FunctionCall(position, function, 809 return std::unique_ptr<FunctionCall>(new FunctionCall(position, std::move(fu nction),
806 std::move(arguments))) ; 810 std::move(arguments))) ;
807 } 811 }
808 812
809 /** 813 /**
810 * Determines the cost of coercing the arguments of a function to the required t ypes. Returns true 814 * Determines the cost of coercing the arguments of a function to the required t ypes. Returns true
811 * if the cost could be computed, false if the call is not valid. Cost has no pa rticular meaning 815 * if the cost could be computed, false if the call is not valid. Cost has no pa rticular meaning
812 * other than "lower costs are preferred". 816 * other than "lower costs are preferred".
813 */ 817 */
814 bool IRGenerator::determineCallCost(const FunctionDeclaration& function, 818 bool IRGenerator::determineCallCost(std::shared_ptr<FunctionDeclaration> functio n,
815 const std::vector<std::unique_ptr<Expression >>& arguments, 819 const std::vector<std::unique_ptr<Expression >>& arguments,
816 int* outCost) { 820 int* outCost) {
817 if (function.fParameters.size() != arguments.size()) { 821 if (function->fParameters.size() != arguments.size()) {
818 return false; 822 return false;
819 } 823 }
820 int total = 0; 824 int total = 0;
821 for (size_t i = 0; i < arguments.size(); i++) { 825 for (size_t i = 0; i < arguments.size(); i++) {
822 int cost; 826 int cost;
823 if (arguments[i]->fType.determineCoercionCost(function.fParameters[i]->f Type, &cost)) { 827 if (arguments[i]->fType->determineCoercionCost(function->fParameters[i]- >fType, &cost)) {
824 total += cost; 828 total += cost;
825 } else { 829 } else {
826 return false; 830 return false;
827 } 831 }
828 } 832 }
829 *outCost = total; 833 *outCost = total;
830 return true; 834 return true;
831 } 835 }
832 836
833 std::unique_ptr<Expression> IRGenerator::call(Position position, 837 std::unique_ptr<Expression> IRGenerator::call(Position position,
834 std::unique_ptr<Expression> functi onValue, 838 std::unique_ptr<Expression> functi onValue,
835 std::vector<std::unique_ptr<Expres sion>> arguments) { 839 std::vector<std::unique_ptr<Expres sion>> arguments) {
836 if (functionValue->fKind == Expression::kTypeReference_Kind) { 840 if (functionValue->fKind == Expression::kTypeReference_Kind) {
837 return this->convertConstructor(position, 841 return this->convertConstructor(position,
838 ((TypeReference&) *functionValue).fValue , 842 ((TypeReference&) *functionValue).fValue ,
839 std::move(arguments)); 843 std::move(arguments));
840 } 844 }
841 if (functionValue->fKind != Expression::kFunctionReference_Kind) { 845 if (functionValue->fKind != Expression::kFunctionReference_Kind) {
842 fErrors.error(position, "'" + functionValue->description() + "' is not a function"); 846 fErrors.error(position, "'" + functionValue->description() + "' is not a function");
843 return nullptr; 847 return nullptr;
844 } 848 }
845 FunctionReference* ref = (FunctionReference*) functionValue.get(); 849 FunctionReference* ref = (FunctionReference*) functionValue.get();
846 int bestCost = INT_MAX; 850 int bestCost = INT_MAX;
847 const FunctionDeclaration* best = nullptr; 851 std::shared_ptr<FunctionDeclaration> best;
848 if (ref->fFunctions.size() > 1) { 852 if (ref->fFunctions.size() > 1) {
849 for (const auto& f : ref->fFunctions) { 853 for (const auto& f : ref->fFunctions) {
850 int cost; 854 int cost;
851 if (this->determineCallCost(*f, arguments, &cost) && cost < bestCost ) { 855 if (this->determineCallCost(f, arguments, &cost) && cost < bestCost) {
852 bestCost = cost; 856 bestCost = cost;
853 best = f; 857 best = f;
854 } 858 }
855 } 859 }
856 if (best) { 860 if (best) {
857 return this->call(position, *best, std::move(arguments)); 861 return this->call(position, std::move(best), std::move(arguments));
858 } 862 }
859 std::string msg = "no match for " + ref->fFunctions[0]->fName + "("; 863 std::string msg = "no match for " + ref->fFunctions[0]->fName + "(";
860 std::string separator = ""; 864 std::string separator = "";
861 for (size_t i = 0; i < arguments.size(); i++) { 865 for (size_t i = 0; i < arguments.size(); i++) {
862 msg += separator; 866 msg += separator;
863 separator = ", "; 867 separator = ", ";
864 msg += arguments[i]->fType.description(); 868 msg += arguments[i]->fType->description();
865 } 869 }
866 msg += ")"; 870 msg += ")";
867 fErrors.error(position, msg); 871 fErrors.error(position, msg);
868 return nullptr; 872 return nullptr;
869 } 873 }
870 return this->call(position, *ref->fFunctions[0], std::move(arguments)); 874 return this->call(position, ref->fFunctions[0], std::move(arguments));
871 } 875 }
872 876
873 std::unique_ptr<Expression> IRGenerator::convertConstructor( 877 std::unique_ptr<Expression> IRGenerator::convertConstructor(
874 Position position, 878 Position position,
875 const Type& type, 879 std::shared_ptr<Type> type,
876 std::vector<std::unique_ptr< Expression>> args) { 880 std::vector<std::unique_ptr< Expression>> args) {
877 // FIXME: add support for structs and arrays 881 // FIXME: add support for structs and arrays
878 Type::Kind kind = type.kind(); 882 Type::Kind kind = type->kind();
879 if (!type.isNumber() && kind != Type::kVector_Kind && kind != Type::kMatrix_ Kind) { 883 if (!type->isNumber() && kind != Type::kVector_Kind && kind != Type::kMatrix _Kind) {
880 fErrors.error(position, "cannot construct '" + type.description() + "'") ; 884 fErrors.error(position, "cannot construct '" + type->description() + "'" );
881 return nullptr; 885 return nullptr;
882 } 886 }
883 if (type == *kFloat_Type && args.size() == 1 && 887 if (type == kFloat_Type && args.size() == 1 &&
884 args[0]->fKind == Expression::kIntLiteral_Kind) { 888 args[0]->fKind == Expression::kIntLiteral_Kind) {
885 int64_t value = ((IntLiteral&) *args[0]).fValue; 889 int64_t value = ((IntLiteral&) *args[0]).fValue;
886 return std::unique_ptr<Expression>(new FloatLiteral(position, (double) v alue)); 890 return std::unique_ptr<Expression>(new FloatLiteral(position, (double) v alue));
887 } 891 }
888 if (args.size() == 1 && args[0]->fType == type) { 892 if (args.size() == 1 && args[0]->fType == type) {
889 // argument is already the right type, just return it 893 // argument is already the right type, just return it
890 return std::move(args[0]); 894 return std::move(args[0]);
891 } 895 }
892 if (type.isNumber()) { 896 if (type->isNumber()) {
893 if (args.size() != 1) { 897 if (args.size() != 1) {
894 fErrors.error(position, "invalid arguments to '" + type.description( ) + 898 fErrors.error(position, "invalid arguments to '" + type->description () +
895 "' constructor, (expected exactly 1 argument , but found " + 899 "' constructor, (expected exactly 1 argument , but found " +
896 to_string(args.size()) + ")"); 900 to_string(args.size()) + ")");
897 } 901 }
898 if (args[0]->fType == *kBool_Type) { 902 if (args[0]->fType == kBool_Type) {
899 std::unique_ptr<IntLiteral> zero(new IntLiteral(position, 0)); 903 std::unique_ptr<IntLiteral> zero(new IntLiteral(position, 0));
900 std::unique_ptr<IntLiteral> one(new IntLiteral(position, 1)); 904 std::unique_ptr<IntLiteral> one(new IntLiteral(position, 1));
901 return std::unique_ptr<Expression>( 905 return std::unique_ptr<Expression>(
902 new TernaryExpression(position, std::mo ve(args[0]), 906 new TernaryExpression(position, std::mo ve(args[0]),
903 this->coerce(std: :move(one), type), 907 this->coerce(std: :move(one), type),
904 this->coerce(std: :move(zero), 908 this->coerce(std: :move(zero),
905 type ))); 909 type )));
906 } else if (!args[0]->fType.isNumber()) { 910 } else if (!args[0]->fType->isNumber()) {
907 fErrors.error(position, "invalid argument to '" + type.description() + 911 fErrors.error(position, "invalid argument to '" + type->description( ) +
908 "' constructor (expected a number or bool, b ut found '" + 912 "' constructor (expected a number or bool, b ut found '" +
909 args[0]->fType.description() + "')"); 913 args[0]->fType->description() + "')");
910 } 914 }
911 } else { 915 } else {
912 ASSERT(kind == Type::kVector_Kind || kind == Type::kMatrix_Kind); 916 ASSERT(kind == Type::kVector_Kind || kind == Type::kMatrix_Kind);
913 int actual = 0; 917 int actual = 0;
914 for (size_t i = 0; i < args.size(); i++) { 918 for (size_t i = 0; i < args.size(); i++) {
915 if (args[i]->fType.kind() == Type::kVector_Kind || 919 if (args[i]->fType->kind() == Type::kVector_Kind ||
916 args[i]->fType.kind() == Type::kMatrix_Kind) { 920 args[i]->fType->kind() == Type::kMatrix_Kind) {
917 int columns = args[i]->fType.columns(); 921 int columns = args[i]->fType->columns();
918 int rows = args[i]->fType.rows(); 922 int rows = args[i]->fType->rows();
919 args[i] = this->coerce(std::move(args[i]), 923 args[i] = this->coerce(std::move(args[i]),
920 type.componentType().toCompound(columns, rows)); 924 type->componentType()->toCompound(columns , rows));
921 actual += args[i]->fType.rows() * args[i]->fType.columns(); 925 actual += args[i]->fType->rows() * args[i]->fType->columns();
922 } else if (args[i]->fType.kind() == Type::kScalar_Kind) { 926 } else if (args[i]->fType->kind() == Type::kScalar_Kind) {
923 actual += 1; 927 actual += 1;
924 if (type.kind() != Type::kScalar_Kind) { 928 if (type->kind() != Type::kScalar_Kind) {
925 args[i] = this->coerce(std::move(args[i]), type.componentTyp e()); 929 args[i] = this->coerce(std::move(args[i]), type->componentTy pe());
926 } 930 }
927 } else { 931 } else {
928 fErrors.error(position, "'" + args[i]->fType.description() + "' is not a valid " 932 fErrors.error(position, "'" + args[i]->fType->description() + "' is not a valid "
929 "parameter to '" + type.description() + "' constructor"); 933 "parameter to '" + type->description() + "' constructor");
930 return nullptr; 934 return nullptr;
931 } 935 }
932 } 936 }
933 int min = type.rows() * type.columns(); 937 int min = type->rows() * type->columns();
934 int max = type.columns() > 1 ? INT_MAX : min; 938 int max = type->columns() > 1 ? INT_MAX : min;
935 if ((actual < min || actual > max) && 939 if ((actual < min || actual > max) &&
936 !((kind == Type::kVector_Kind || kind == Type::kMatrix_Kind) && (act ual == 1))) { 940 !((kind == Type::kVector_Kind || kind == Type::kMatrix_Kind) && (act ual == 1))) {
937 fErrors.error(position, "invalid arguments to '" + type.description( ) + 941 fErrors.error(position, "invalid arguments to '" + type->description () +
938 "' constructor (expected " + to_string(min) + " scalar" + 942 "' constructor (expected " + to_string(min) + " scalar" +
939 (min == 1 ? "" : "s") + ", but found " + to_ string(actual) + 943 (min == 1 ? "" : "s") + ", but found " + to_ string(actual) +
940 ")"); 944 ")");
941 return nullptr; 945 return nullptr;
942 } 946 }
943 } 947 }
944 return std::unique_ptr<Expression>(new Constructor(position, std::move(type) , std::move(args))); 948 return std::unique_ptr<Expression>(new Constructor(position, std::move(type) , std::move(args)));
945 } 949 }
946 950
947 std::unique_ptr<Expression> IRGenerator::convertPrefixExpression( 951 std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(
948 const ASTPrefixExpre ssion& expression) { 952 const ASTPrefixExpre ssion& expression) {
949 std::unique_ptr<Expression> base = this->convertExpression(*expression.fOper and); 953 std::unique_ptr<Expression> base = this->convertExpression(*expression.fOper and);
950 if (!base) { 954 if (!base) {
951 return nullptr; 955 return nullptr;
952 } 956 }
953 switch (expression.fOperator) { 957 switch (expression.fOperator) {
954 case Token::PLUS: 958 case Token::PLUS:
955 if (!base->fType.isNumber() && base->fType.kind() != Type::kVector_K ind) { 959 if (!base->fType->isNumber() && base->fType->kind() != Type::kVector _Kind) {
956 fErrors.error(expression.fPosition, 960 fErrors.error(expression.fPosition,
957 "'+' cannot operate on '" + base->fType.descriptio n() + "'"); 961 "'+' cannot operate on '" + base->fType->descripti on() + "'");
958 return nullptr; 962 return nullptr;
959 } 963 }
960 return base; 964 return base;
961 case Token::MINUS: 965 case Token::MINUS:
962 if (!base->fType.isNumber() && base->fType.kind() != Type::kVector_K ind) { 966 if (!base->fType->isNumber() && base->fType->kind() != Type::kVector _Kind) {
963 fErrors.error(expression.fPosition, 967 fErrors.error(expression.fPosition,
964 "'-' cannot operate on '" + base->fType.descriptio n() + "'"); 968 "'-' cannot operate on '" + base->fType->descripti on() + "'");
965 return nullptr; 969 return nullptr;
966 } 970 }
967 if (base->fKind == Expression::kIntLiteral_Kind) { 971 if (base->fKind == Expression::kIntLiteral_Kind) {
968 return std::unique_ptr<Expression>(new IntLiteral(base->fPositio n, 972 return std::unique_ptr<Expression>(new IntLiteral(base->fPositio n,
969 -((IntLiteral& ) *base).fValue)); 973 -((IntLiteral& ) *base).fValue));
970 } 974 }
971 if (base->fKind == Expression::kFloatLiteral_Kind) { 975 if (base->fKind == Expression::kFloatLiteral_Kind) {
972 double value = -((FloatLiteral&) *base).fValue; 976 double value = -((FloatLiteral&) *base).fValue;
973 return std::unique_ptr<Expression>(new FloatLiteral(base->fPosit ion, value)); 977 return std::unique_ptr<Expression>(new FloatLiteral(base->fPosit ion, value));
974 } 978 }
975 return std::unique_ptr<Expression>(new PrefixExpression(Token::MINUS , std::move(base))); 979 return std::unique_ptr<Expression>(new PrefixExpression(Token::MINUS , std::move(base)));
976 case Token::PLUSPLUS: 980 case Token::PLUSPLUS:
977 if (!base->fType.isNumber()) { 981 if (!base->fType->isNumber()) {
978 fErrors.error(expression.fPosition, 982 fErrors.error(expression.fPosition,
979 "'" + Token::OperatorName(expression.fOperator) + 983 "'" + Token::OperatorName(expression.fOperator) +
980 "' cannot operate on '" + base->fType.description( ) + "'"); 984 "' cannot operate on '" + base->fType->description () + "'");
981 return nullptr; 985 return nullptr;
982 } 986 }
983 this->markWrittenTo(*base); 987 this->markWrittenTo(*base);
984 break; 988 break;
985 case Token::MINUSMINUS: 989 case Token::MINUSMINUS:
986 if (!base->fType.isNumber()) { 990 if (!base->fType->isNumber()) {
987 fErrors.error(expression.fPosition, 991 fErrors.error(expression.fPosition,
988 "'" + Token::OperatorName(expression.fOperator) + 992 "'" + Token::OperatorName(expression.fOperator) +
989 "' cannot operate on '" + base->fType.description( ) + "'"); 993 "' cannot operate on '" + base->fType->description () + "'");
990 return nullptr; 994 return nullptr;
991 } 995 }
992 this->markWrittenTo(*base); 996 this->markWrittenTo(*base);
993 break; 997 break;
994 case Token::NOT: 998 case Token::NOT:
995 if (base->fType != *kBool_Type) { 999 if (base->fType != kBool_Type) {
996 fErrors.error(expression.fPosition, 1000 fErrors.error(expression.fPosition,
997 "'" + Token::OperatorName(expression.fOperator) + 1001 "'" + Token::OperatorName(expression.fOperator) +
998 "' cannot operate on '" + base->fType.description( ) + "'"); 1002 "' cannot operate on '" + base->fType->description () + "'");
999 return nullptr; 1003 return nullptr;
1000 } 1004 }
1001 break; 1005 break;
1002 default: 1006 default:
1003 ABORT("unsupported prefix operator\n"); 1007 ABORT("unsupported prefix operator\n");
1004 } 1008 }
1005 return std::unique_ptr<Expression>(new PrefixExpression(expression.fOperator , 1009 return std::unique_ptr<Expression>(new PrefixExpression(expression.fOperator ,
1006 std::move(base))); 1010 std::move(base)));
1007 } 1011 }
1008 1012
1009 std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression > base, 1013 std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression > base,
1010 const ASTExpression& index ) { 1014 const ASTExpression& index ) {
1011 if (base->fType.kind() != Type::kArray_Kind && base->fType.kind() != Type::k Matrix_Kind) { 1015 if (base->fType->kind() != Type::kArray_Kind && base->fType->kind() != Type: :kMatrix_Kind) {
1012 fErrors.error(base->fPosition, "expected array, but found '" + base->fTy pe.description() + 1016 fErrors.error(base->fPosition, "expected array, but found '" + base->fTy pe->description() +
1013 "'"); 1017 "'");
1014 return nullptr; 1018 return nullptr;
1015 } 1019 }
1016 std::unique_ptr<Expression> converted = this->convertExpression(index); 1020 std::unique_ptr<Expression> converted = this->convertExpression(index);
1017 if (!converted) { 1021 if (!converted) {
1018 return nullptr; 1022 return nullptr;
1019 } 1023 }
1020 converted = this->coerce(std::move(converted), *kInt_Type); 1024 converted = this->coerce(std::move(converted), kInt_Type);
1021 if (!converted) { 1025 if (!converted) {
1022 return nullptr; 1026 return nullptr;
1023 } 1027 }
1024 return std::unique_ptr<Expression>(new IndexExpression(std::move(base), std: :move(converted))); 1028 return std::unique_ptr<Expression>(new IndexExpression(std::move(base), std: :move(converted)));
1025 } 1029 }
1026 1030
1027 std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression > base, 1031 std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression > base,
1028 const std::string& field) { 1032 const std::string& field) {
1029 auto fields = base->fType.fields(); 1033 auto fields = base->fType->fields();
1030 for (size_t i = 0; i < fields.size(); i++) { 1034 for (size_t i = 0; i < fields.size(); i++) {
1031 if (fields[i].fName == field) { 1035 if (fields[i].fName == field) {
1032 return std::unique_ptr<Expression>(new FieldAccess(std::move(base), (int) i)); 1036 return std::unique_ptr<Expression>(new FieldAccess(std::move(base), (int) i));
1033 } 1037 }
1034 } 1038 }
1035 fErrors.error(base->fPosition, "type '" + base->fType.description() + "' doe s not have a " 1039 fErrors.error(base->fPosition, "type '" + base->fType->description() + "' do es not have a "
1036 "field named '" + field + ""); 1040 "field named '" + field + "");
1037 return nullptr; 1041 return nullptr;
1038 } 1042 }
1039 1043
1040 std::unique_ptr<Expression> IRGenerator::convertSwizzle(std::unique_ptr<Expressi on> base, 1044 std::unique_ptr<Expression> IRGenerator::convertSwizzle(std::unique_ptr<Expressi on> base,
1041 const std::string& field s) { 1045 const std::string& field s) {
1042 if (base->fType.kind() != Type::kVector_Kind) { 1046 if (base->fType->kind() != Type::kVector_Kind) {
1043 fErrors.error(base->fPosition, "cannot swizzle type '" + base->fType.des cription() + "'"); 1047 fErrors.error(base->fPosition, "cannot swizzle type '" + base->fType->de scription() + "'");
1044 return nullptr; 1048 return nullptr;
1045 } 1049 }
1046 std::vector<int> swizzleComponents; 1050 std::vector<int> swizzleComponents;
1047 for (char c : fields) { 1051 for (char c : fields) {
1048 switch (c) { 1052 switch (c) {
1049 case 'x': // fall through 1053 case 'x': // fall through
1050 case 'r': // fall through 1054 case 'r': // fall through
1051 case 's': 1055 case 's':
1052 swizzleComponents.push_back(0); 1056 swizzleComponents.push_back(0);
1053 break; 1057 break;
1054 case 'y': // fall through 1058 case 'y': // fall through
1055 case 'g': // fall through 1059 case 'g': // fall through
1056 case 't': 1060 case 't':
1057 if (base->fType.columns() >= 2) { 1061 if (base->fType->columns() >= 2) {
1058 swizzleComponents.push_back(1); 1062 swizzleComponents.push_back(1);
1059 break; 1063 break;
1060 } 1064 }
1061 // fall through 1065 // fall through
1062 case 'z': // fall through 1066 case 'z': // fall through
1063 case 'b': // fall through 1067 case 'b': // fall through
1064 case 'p': 1068 case 'p':
1065 if (base->fType.columns() >= 3) { 1069 if (base->fType->columns() >= 3) {
1066 swizzleComponents.push_back(2); 1070 swizzleComponents.push_back(2);
1067 break; 1071 break;
1068 } 1072 }
1069 // fall through 1073 // fall through
1070 case 'w': // fall through 1074 case 'w': // fall through
1071 case 'a': // fall through 1075 case 'a': // fall through
1072 case 'q': 1076 case 'q':
1073 if (base->fType.columns() >= 4) { 1077 if (base->fType->columns() >= 4) {
1074 swizzleComponents.push_back(3); 1078 swizzleComponents.push_back(3);
1075 break; 1079 break;
1076 } 1080 }
1077 // fall through 1081 // fall through
1078 default: 1082 default:
1079 fErrors.error(base->fPosition, "invalid swizzle component '" + s td::string(1, c) + 1083 fErrors.error(base->fPosition, "invalid swizzle component '" + s td::string(1, c) +
1080 "'"); 1084 "'");
1081 return nullptr; 1085 return nullptr;
1082 } 1086 }
1083 } 1087 }
(...skipping 22 matching lines...) Expand all
1106 std::unique_ptr<Expression> converted = 1110 std::unique_ptr<Expression> converted =
1107 this->convertExpression(*(*rawArguments)[i]); 1111 this->convertExpression(*(*rawArguments)[i]);
1108 if (!converted) { 1112 if (!converted) {
1109 return nullptr; 1113 return nullptr;
1110 } 1114 }
1111 arguments.push_back(std::move(converted)); 1115 arguments.push_back(std::move(converted));
1112 } 1116 }
1113 return this->call(expression.fPosition, std::move(base), std::move(a rguments)); 1117 return this->call(expression.fPosition, std::move(base), std::move(a rguments));
1114 } 1118 }
1115 case ASTSuffix::kField_Kind: { 1119 case ASTSuffix::kField_Kind: {
1116 switch (base->fType.kind()) { 1120 switch (base->fType->kind()) {
1117 case Type::kVector_Kind: 1121 case Type::kVector_Kind:
1118 return this->convertSwizzle(std::move(base), 1122 return this->convertSwizzle(std::move(base),
1119 ((ASTFieldSuffix&) *expression.f Suffix).fField); 1123 ((ASTFieldSuffix&) *expression.f Suffix).fField);
1120 case Type::kStruct_Kind: 1124 case Type::kStruct_Kind:
1121 return this->convertField(std::move(base), 1125 return this->convertField(std::move(base),
1122 ((ASTFieldSuffix&) *expression.fSu ffix).fField); 1126 ((ASTFieldSuffix&) *expression.fSu ffix).fField);
1123 default: 1127 default:
1124 fErrors.error(base->fPosition, "cannot swizzle value of type '" + 1128 fErrors.error(base->fPosition, "cannot swizzle value of type '" +
1125 base->fType.description() + " '"); 1129 base->fType->description() + "'");
1126 return nullptr; 1130 return nullptr;
1127 } 1131 }
1128 } 1132 }
1129 case ASTSuffix::kPostIncrement_Kind: 1133 case ASTSuffix::kPostIncrement_Kind:
1130 if (!base->fType.isNumber()) { 1134 if (!base->fType->isNumber()) {
1131 fErrors.error(expression.fPosition, 1135 fErrors.error(expression.fPosition,
1132 "'++' cannot operate on '" + base->fType.descripti on() + "'"); 1136 "'++' cannot operate on '" + base->fType->descript ion() + "'");
1133 return nullptr; 1137 return nullptr;
1134 } 1138 }
1135 this->markWrittenTo(*base); 1139 this->markWrittenTo(*base);
1136 return std::unique_ptr<Expression>(new PostfixExpression(std::move(b ase), 1140 return std::unique_ptr<Expression>(new PostfixExpression(std::move(b ase),
1137 Token::PLUS PLUS)); 1141 Token::PLUS PLUS));
1138 case ASTSuffix::kPostDecrement_Kind: 1142 case ASTSuffix::kPostDecrement_Kind:
1139 if (!base->fType.isNumber()) { 1143 if (!base->fType->isNumber()) {
1140 fErrors.error(expression.fPosition, 1144 fErrors.error(expression.fPosition,
1141 "'--' cannot operate on '" + base->fType.descripti on() + "'"); 1145 "'--' cannot operate on '" + base->fType->descript ion() + "'");
1142 return nullptr; 1146 return nullptr;
1143 } 1147 }
1144 this->markWrittenTo(*base); 1148 this->markWrittenTo(*base);
1145 return std::unique_ptr<Expression>(new PostfixExpression(std::move(b ase), 1149 return std::unique_ptr<Expression>(new PostfixExpression(std::move(b ase),
1146 Token::MINU SMINUS)); 1150 Token::MINU SMINUS));
1147 default: 1151 default:
1148 ABORT("unsupported suffix operator"); 1152 ABORT("unsupported suffix operator");
1149 } 1153 }
1150 } 1154 }
1151 1155
1152 void IRGenerator::checkValid(const Expression& expr) { 1156 void IRGenerator::checkValid(const Expression& expr) {
1153 switch (expr.fKind) { 1157 switch (expr.fKind) {
1154 case Expression::kFunctionReference_Kind: 1158 case Expression::kFunctionReference_Kind:
1155 fErrors.error(expr.fPosition, "expected '(' to begin function call") ; 1159 fErrors.error(expr.fPosition, "expected '(' to begin function call") ;
1156 break; 1160 break;
1157 case Expression::kTypeReference_Kind: 1161 case Expression::kTypeReference_Kind:
1158 fErrors.error(expr.fPosition, "expected '(' to begin constructor inv ocation"); 1162 fErrors.error(expr.fPosition, "expected '(' to begin constructor inv ocation");
1159 break; 1163 break;
1160 default: 1164 default:
1161 ASSERT(expr.fType != *kInvalid_Type); 1165 ASSERT(expr.fType != kInvalid_Type);
1162 break; 1166 break;
1163 } 1167 }
1164 } 1168 }
1165 1169
1166 void IRGenerator::markReadFrom(const Variable& var) { 1170 void IRGenerator::markReadFrom(std::shared_ptr<Variable> var) {
1167 var.fIsReadFrom = true; 1171 var->fIsReadFrom = true;
1168 } 1172 }
1169 1173
1170 static bool has_duplicates(const Swizzle& swizzle) { 1174 static bool has_duplicates(const Swizzle& swizzle) {
1171 int bits = 0; 1175 int bits = 0;
1172 for (int idx : swizzle.fComponents) { 1176 for (int idx : swizzle.fComponents) {
1173 ASSERT(idx >= 0 && idx <= 3); 1177 ASSERT(idx >= 0 && idx <= 3);
1174 int bit = 1 << idx; 1178 int bit = 1 << idx;
1175 if (bits & bit) { 1179 if (bits & bit) {
1176 return true; 1180 return true;
1177 } 1181 }
1178 bits |= bit; 1182 bits |= bit;
1179 } 1183 }
1180 return false; 1184 return false;
1181 } 1185 }
1182 1186
1183 void IRGenerator::markWrittenTo(const Expression& expr) { 1187 void IRGenerator::markWrittenTo(const Expression& expr) {
1184 switch (expr.fKind) { 1188 switch (expr.fKind) {
1185 case Expression::kVariableReference_Kind: { 1189 case Expression::kVariableReference_Kind: {
1186 const Variable& var = ((VariableReference&) expr).fVariable; 1190 const Variable& var = *((VariableReference&) expr).fVariable;
1187 if (var.fModifiers.fFlags & (Modifiers::kConst_Flag | Modifiers::kUn iform_Flag)) { 1191 if (var.fModifiers.fFlags & (Modifiers::kConst_Flag | Modifiers::kUn iform_Flag)) {
1188 fErrors.error(expr.fPosition, 1192 fErrors.error(expr.fPosition,
1189 "cannot modify immutable variable '" + var.fName + "'"); 1193 "cannot modify immutable variable '" + var.fName + "'");
1190 } 1194 }
1191 var.fIsWrittenTo = true; 1195 var.fIsWrittenTo = true;
1192 break; 1196 break;
1193 } 1197 }
1194 case Expression::kFieldAccess_Kind: 1198 case Expression::kFieldAccess_Kind:
1195 this->markWrittenTo(*((FieldAccess&) expr).fBase); 1199 this->markWrittenTo(*((FieldAccess&) expr).fBase);
1196 break; 1200 break;
1197 case Expression::kSwizzle_Kind: 1201 case Expression::kSwizzle_Kind:
1198 if (has_duplicates((Swizzle&) expr)) { 1202 if (has_duplicates((Swizzle&) expr)) {
1199 fErrors.error(expr.fPosition, 1203 fErrors.error(expr.fPosition,
1200 "cannot write to the same swizzle field more than once"); 1204 "cannot write to the same swizzle field more than once");
1201 } 1205 }
1202 this->markWrittenTo(*((Swizzle&) expr).fBase); 1206 this->markWrittenTo(*((Swizzle&) expr).fBase);
1203 break; 1207 break;
1204 case Expression::kIndex_Kind: 1208 case Expression::kIndex_Kind:
1205 this->markWrittenTo(*((IndexExpression&) expr).fBase); 1209 this->markWrittenTo(*((IndexExpression&) expr).fBase);
1206 break; 1210 break;
1207 default: 1211 default:
1208 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio n() + "'"); 1212 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio n() + "'");
1209 break; 1213 break;
1210 } 1214 }
1211 } 1215 }
1212 1216
1213 } 1217 }
OLDNEW
« no previous file with comments | « src/sksl/SkSLIRGenerator.h ('k') | src/sksl/SkSLParser.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698