Changeset 235738 in webkit
- Timestamp:
- Sep 6, 2018 9:01:05 AM (6 years ago)
- Location:
- trunk/Tools
- Files:
-
- 11 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r235734 r235738 1 2018-09-06 Myles C. Maxfield <mmaxfield@apple.com> 2 3 [WHLSL] The parser is too slow 4 https://bugs.webkit.org/show_bug.cgi?id=189014 5 6 Reviewed by Filip Pizlo. 7 8 This patch includes three changes: 9 1. Migrate from using try/catch to simply returning the WSyntaxError. This means that 10 each parser call has to check for this sentinel value. The lexer still can throw if 11 it encounters an unknown token or an unmatched "/*" token (which is rare). 12 2. After removing try/catch, making the sentinel values not inherit from Error (the 13 Error constructor was taking lots of time) 14 3. Previously, every time the parser failed (which is many times per expression) it was 15 running a regex over the entire source text to figure out where the error occurred. 16 Instead, we can preprocess the text string to find these line numbers ahead of time. 17 18 Together, these make the parser 75x faster. Parsing the standard library goes from 2.5 19 hours down to 2 minutes. Because it's now a reasonable length, this patch uncomments 20 the bulk of the standard library. 21 22 * WebGPUShadingLanguageRI/All.js: 23 * WebGPUShadingLanguageRI/Lexer.js: 24 (Lexer): 25 (Lexer.prototype.lineNumberForIndex): 26 * WebGPUShadingLanguageRI/Parse.js: 27 (fail): 28 (backtrackingScope): 29 (testScope): 30 (genericConsume): 31 (consumeEndOfTypeArgs): 32 (parseTerm): 33 (parseConstexpr): 34 (parseTypeArguments): 35 (parseType.getAddressSpace): 36 (parseType): 37 (parseTypeDef): 38 (genericParseLeft): 39 (parseCallExpression.let.parseArguments): 40 (isCallExpression): 41 (parseSuffixOperator): 42 (parsePossibleSuffix): 43 (parsePreIncrement): 44 (parsePossiblePrefix): 45 (parsePossibleTernaryConditional): 46 (parsePossibleAssignment): 47 (parsePostIncrement): 48 (parseEffectfulExpression): 49 (genericParseCommaExpression): 50 (parseEffectfulStatement): 51 (parseReturn): 52 (parseBreak): 53 (parseContinue): 54 (parseIfStatement): 55 (parseWhile): 56 (parseFor): 57 (parseDo): 58 (parseVariableDecls): 59 (parseSwitchCase): 60 (parseSwitchStatement): 61 (parseStatement): 62 (parseBlockBody): 63 (parseBlock): 64 (parseParameter): 65 (parseFuncName): 66 (parseFuncDecl): 67 (parseFuncDef): 68 (parseField): 69 (parseStructType): 70 (parseNativeFunc): 71 (parseNative): 72 (parseRestrictedFuncDef): 73 (parseEnumMember): 74 (parseEnumType): 75 (parse): 76 * WebGPUShadingLanguageRI/SPIRV.html: 77 * WebGPUShadingLanguageRI/StandardLibrary.js: 78 (let.standardLibrary): 79 * WebGPUShadingLanguageRI/Test.html: 80 * WebGPUShadingLanguageRI/Test.js: 81 (checkFail.doPrep): Deleted. 82 * WebGPUShadingLanguageRI/WLexicalError.js: Added. 83 (WLexicalError): 84 * WebGPUShadingLanguageRI/index.html: 85 1 86 2018-09-06 Xan Lopez <xan@igalia.com> 2 87 -
trunk/Tools/WebGPUShadingLanguageRI/All.js
r235635 r235738 169 169 load("VectorType.js"); 170 170 load("VisitingSet.js"); 171 load("WLexicalError.js"); 171 172 load("WSyntaxError.js"); 172 173 load("WTrapError.js"); -
trunk/Tools/WebGPUShadingLanguageRI/Lexer.js
r235096 r235738 36 36 this._index = 0; 37 37 this._stack = []; 38 39 this._lineNumbers = []; 40 let lineNumber = 1; 41 for (let i = 0; i < this._text.length; ++i) { 42 this._lineNumbers.push(lineNumber); 43 if (this._text[i] == '\n') 44 ++lineNumber; 45 } 38 46 } 39 47 … … 54 62 lineNumberForIndex(index) 55 63 { 56 let matches = this._text.substring(0, index).match(/\n/g); 57 return (matches ? matches.length : 0) + this._lineNumberOffset; 64 return this._lineNumbers[index] + this._lineNumberOffset; 58 65 } 59 66 … … 167 174 fail(error) 168 175 { 169 throw new WSyntaxError(this.originString, error); 170 } 171 172 backtrackingScope(callback) 173 { 174 let state = this.state; 175 try { 176 return callback(); 177 } catch (e) { 178 if (e instanceof WSyntaxError) { 179 this.state = state; 180 return null; 181 } 182 throw e; 183 } 184 } 185 186 testScope(callback) 187 { 188 let state = this.state; 189 try { 190 callback(); 191 return true; 192 } catch (e) { 193 if (e instanceof WSyntaxError) 194 return false; 195 throw e; 196 } finally { 197 this.state = state; 198 } 176 throw new WLexicalError(this.originString, error); 199 177 } 200 178 } -
trunk/Tools/WebGPUShadingLanguageRI/LexerToken.js
r222351 r235738 71 71 get originString() 72 72 { 73 return this.origin + ":" + (this.lineNumber + 1);73 return this.origin + ":" + this.lineNumber; 74 74 } 75 75 -
trunk/Tools/WebGPUShadingLanguageRI/Parse.js
r235533 r235738 28 28 { 29 29 let lexer = new Lexer(origin, originKind, lineNumberOffset, text); 30 30 31 31 // The hardest part of dealing with C-like languages is parsing variable declaration statements. 32 32 // Let's consider if this happens in WSL. Here are the valid statements in WSL that being with an … … 62 62 // have arbitrary expressions as the callee. The remaining two problems are solved by 63 63 // backtracking. In all other respects, this is a simple recursive descent parser. 64 64 65 function fail(error) 66 { 67 return new WSyntaxError(lexer.originString, error); 68 } 69 70 function backtrackingScope(callback) 71 { 72 let state = lexer.state; 73 let maybeError = callback(); 74 if (maybeError instanceof WSyntaxError) { 75 lexer.state = state; 76 return null; 77 } else 78 return maybeError; 79 } 80 81 function testScope(callback) 82 { 83 let state = lexer.state; 84 let maybeError = callback(); 85 lexer.state = state; 86 return !(maybeError instanceof WSyntaxError); 87 } 88 65 89 function genericConsume(callback, explanation) 66 90 { 67 91 let token = lexer.next(); 68 92 if (!token) 69 lexer.fail("Unexpected end of file");93 return fail("Unexpected end of file"); 70 94 if (!callback(token)) 71 lexer.fail("Unexpected token: " + token.text + "; expected: " + explanation);95 return fail("Unexpected token: " + token.text + "; expected: " + explanation); 72 96 return token; 73 97 } 74 98 75 99 function consume(...texts) 76 100 { 77 101 return genericConsume(token => texts.includes(token.text), texts); 78 102 } 79 103 80 104 function consumeKind(kind) 81 105 { 82 106 return genericConsume(token => token.kind == kind, kind); 83 107 } 84 108 85 109 function assertNext(...texts) 86 110 { 87 lexer.push(consume(...texts)); 88 } 89 111 let maybeError = consume(...texts); 112 if (maybeError instanceof WSyntaxError) 113 return maybeError; 114 lexer.push(maybeError); 115 } 116 90 117 function genericTest(callback) 91 118 { … … 95 122 return null; 96 123 } 97 124 98 125 function test(...texts) 99 126 { 100 127 return genericTest(token => texts.includes(token.text)); 101 128 } 102 129 103 130 function testKind(kind) 104 131 { 105 132 return genericTest(token => token.kind == kind); 106 133 } 107 134 108 135 function tryConsume(...texts) 109 136 { … … 113 140 return result; 114 141 } 115 142 116 143 function tryConsumeKind(kind) 117 144 { … … 121 148 return result; 122 149 } 123 150 124 151 function consumeEndOfTypeArgs() 125 152 { … … 127 154 if (rightShift) 128 155 lexer.push(new LexerToken(lexer, rightShift, rightShift.index, rightShift.kind, ">")); 129 else 130 consume(">"); 131 } 132 156 else { 157 let maybeError = consume(">"); 158 if (maybeError instanceof WSyntaxError) 159 return maybeError; 160 } 161 } 162 133 163 function parseTerm() 134 164 { … … 141 171 let intVersion = (+token.text) | 0; 142 172 if ("" + intVersion !== token.text) 143 lexer.fail("Integer literal is not an integer: " + token.text);173 return fail("Integer literal is not an integer: " + token.text); 144 174 return new IntLiteral(token, intVersion); 145 175 } … … 147 177 let uintVersion = token.text.substr(0, token.text.length - 1) >>> 0; 148 178 if (uintVersion + "u" !== token.text) 149 lexer.fail("Integer literal is not 32-bit unsigned integer: " + token.text);179 return fail("Integer literal is not 32-bit unsigned integer: " + token.text); 150 180 return new UintLiteral(token, uintVersion); 151 181 } … … 163 193 intVersion = intVersion >>> 0; 164 194 if (intVersion.toString(16) !== hexString) 165 lexer.fail("Hex integer literal is not an integer: " + token.text);195 return fail("Hex integer literal is not an integer: " + token.text); 166 196 if (token.kind == "intHexLiteral") 167 197 return new IntLiteral(token, intVersion); … … 179 209 return new BoolLiteral(token, token.text == "true"); 180 210 // FIXME: Need support for other literals too. 181 consume("("); 211 let maybeError = consume("("); 212 if (maybeError instanceof WSyntaxError) 213 return maybeError; 182 214 let result = parseExpression(); 183 consume(")"); 215 if (result instanceof WSyntaxError) 216 return result; 217 maybeError = consume(")"); 218 if (maybeError instanceof WSyntaxError) 219 return maybeError; 184 220 return result; 185 221 } 186 222 187 223 function parseConstexpr() 188 224 { 189 225 let token; 190 if (token = tryConsume("-")) 191 return new CallExpression(token, "operator" + token.text, [parseTerm()]); 226 if (token = tryConsume("-")) { 227 let term = parseTerm(); 228 if (term instanceof WSyntaxError) 229 return term; 230 return new CallExpression(token, "operator" + token.text, [term]); 231 } 192 232 let left = parseTerm(); 193 if (token = tryConsume(".")) 194 left = new DotExpression(token, left, consumeKind("identifier").text); 233 if (left instanceof WSyntaxError) 234 return left; 235 if (token = tryConsume(".")) { 236 let maybeError = consumeKind("identifier") 237 if (maybeError instanceof WSyntaxError) 238 return maybeError; 239 left = new DotExpression(token, left, maybeError.text); 240 } 195 241 return left; 196 242 } 197 243 198 244 function parseTypeArguments() 199 245 { … … 202 248 203 249 let result = []; 204 consume("<"); 250 let maybeError = consume("<"); 251 if (maybeError instanceof WSyntaxError) 252 return maybeError; 205 253 while (!test(">")) { 206 254 // It's possible for a constexpr or type can syntactically overlap in the single … … 215 263 // the problem that something of the form T[1][2][3]... can either be a type or a 216 264 // constexpr, and we can figure out in the checker which it is. 217 let typeRef = lexer.backtrackingScope(() => {265 let typeRef = backtrackingScope(() => { 218 266 let result = consumeKind("identifier"); 219 assertNext(",", ">", ">>"); 267 if (result instanceof WSyntaxError) 268 return result; 269 let maybeError = assertNext(",", ">", ">>"); 270 if (maybeError instanceof WSyntaxError) 271 return maybeError; 220 272 return new TypeRef(result, result.text); 221 273 }); … … 223 275 result.push(typeRef); 224 276 else { 225 let constexpr = lexer.backtrackingScope(() => {277 let constexpr = backtrackingScope(() => { 226 278 let result = parseConstexpr(); 227 assertNext(",", ">", ">>"); 279 if (result instanceof WSyntaxError) 280 return result; 281 let maybeError = assertNext(",", ">", ">>"); 282 if (maybeError instanceof WSyntaxError) 283 return maybeError; 228 284 return result; 229 285 }); 230 286 if (constexpr) 231 287 result.push(constexpr); 232 else 233 result.push(parseType()); 288 else { 289 let type = parseType(); 290 if (type instanceof WSyntaxError) 291 return type; 292 result.push(type); 293 } 234 294 } 235 295 if (!tryConsume(",")) 236 296 break; 237 297 } 238 consumeEndOfTypeArgs(); 298 maybeError = consumeEndOfTypeArgs(); 299 if (maybeError instanceof WSyntaxError) 300 return maybeError; 239 301 return result; 240 302 } 241 303 242 304 function parseType() 243 305 { … … 247 309 if (token = tryConsume(...addressSpaces)) 248 310 addressSpace = token.text; 249 311 250 312 let name = consumeKind("identifier"); 313 if (name instanceof WSyntaxError) 314 return name; 251 315 let typeArguments = parseTypeArguments(); 316 if (typeArguments instanceof WSyntaxError) 317 return typeArguments; 252 318 let type = new TypeRef(name, name.text, typeArguments); 253 319 254 320 function getAddressSpace() 255 321 { … … 257 323 if (addressSpace) 258 324 return addressSpace; 259 return consume(...addressSpaces).text; 260 } 261 325 let consumedAddressSpace = consume(...addressSpaces); 326 if (consumedAddressSpace instanceof WSyntaxError) 327 return consumedAddressSpace; 328 return consumedAddressSpace.text; 329 } 330 262 331 const typeConstructorStack = [ ]; 263 332 … … 266 335 // Likewise, the address space must be parsed before parsing continues. 267 336 const addressSpace = getAddressSpace(); 337 if (addressSpace instanceof WSyntaxError) 338 return addressSpace; 268 339 typeConstructorStack.unshift(type => new PtrType(token, addressSpace, type)); 269 340 continue; … … 272 343 if (tryConsume("]")) { 273 344 const addressSpace = getAddressSpace(); 345 if (addressSpace instanceof WSyntaxError) 346 return addressSpace; 274 347 typeConstructorStack.unshift(type => new ArrayRefType(token, addressSpace, type)); 275 348 continue; … … 277 350 278 351 const lengthExpr = parseConstexpr(); 352 if (lengthExpr instanceof WSyntaxError) 353 return lengthExpr; 279 354 typeConstructorStack.unshift(type => new ArrayType(token, type, lengthExpr)); 280 consume("]"); 355 let maybeError = consume("]"); 356 if (maybeError instanceof WSyntaxError) 357 return maybeError; 281 358 } 282 359 … … 285 362 286 363 if (addressSpace && !addressSpaceConsumed) 287 lexer.fail("Address space specified for type that does not need address space");364 return fail("Address space specified for type that does not need address space"); 288 365 289 366 return type; 290 367 } 291 368 292 369 function parseTypeDef() 293 370 { 294 371 let origin = consume("typedef"); 295 let name = consumeKind("identifier").text; 296 consume("="); 372 if (origin instanceof WSyntaxError) 373 return origin; 374 let maybeError = consumeKind("identifier"); 375 if (maybeError instanceof WSyntaxError) 376 return maybeError; 377 let name = maybeError.text; 378 maybeError = consume("="); 379 if (maybeError instanceof WSyntaxError) 380 return maybeError; 297 381 let type = parseType(); 298 consume(";"); 382 if (type instanceof WSyntaxError) 383 return type; 384 maybeError = consume(";"); 385 if (maybeError instanceof WSyntaxError) 386 return maybeError; 299 387 return new TypeDef(origin, name, type); 300 388 } 301 389 302 390 function genericParseLeft(texts, nextParser, constructor) 303 391 { 304 392 let left = nextParser(); 393 if (left instanceof WSyntaxError) 394 return left; 305 395 let token; 306 396 while (token = tryConsume(...texts)) … … 308 398 return left; 309 399 } 310 400 311 401 function parseLeftOperatorCall(texts, nextParser) 312 402 { … … 316 406 new CallExpression(token, "operator" + token.text, [left, right])); 317 407 } 318 408 319 409 function parseCallExpression() 320 410 { … … 323 413 while (!test(")")) { 324 414 let argument = parsePossibleAssignment(); 415 if (argument instanceof WSyntaxError) 416 return argument; 325 417 argumentList.push(argument); 326 418 if (!tryConsume(",")) 327 419 break; 328 420 } 329 consume(")"); 421 let maybeError = consume(")"); 422 if (maybeError instanceof WSyntaxError) 423 return maybeError; 330 424 return new CallExpression(origin, callName, argumentList); 331 425 } 332 426 333 let name = lexer.backtrackingScope(() => {427 let name = backtrackingScope(() => { 334 428 let name = consumeKind("identifier"); 335 consume("("); 429 if (name instanceof WSyntaxError) 430 return name; 431 let maybeError = consume("("); 432 if (maybeError instanceof WSyntaxError) 433 return maybeError; 336 434 return name; 337 435 }); … … 342 440 } else { 343 441 let returnType = parseType(); 344 consume("("); 442 if (returnType instanceof WSyntaxError) 443 return returnType; 444 let maybeError = consume("("); 445 if (maybeError instanceof WSyntaxError) 446 return maybeError; 345 447 let result = parseArguments(returnType.origin, "operator cast"); 346 448 result.setCastData(returnType); … … 348 450 } 349 451 } 350 452 351 453 function isCallExpression() 352 454 { 353 return lexer.testScope(() => { 354 consumeKind("identifier"); 355 consume("("); 356 }) || lexer.testScope(() => { 357 parseType(); 358 consume("("); 455 return testScope(() => { 456 let maybeError = consumeKind("identifier"); 457 if (maybeError instanceof WSyntaxError) 458 return maybeError; 459 maybeError = consume("("); 460 if (maybeError instanceof WSyntaxError) 461 return maybeError; 462 }) || testScope(() => { 463 let type = parseType(); 464 if (type instanceof WSyntaxError) 465 return type; 466 let maybeError = consume("("); 467 if (maybeError instanceof WSyntaxError) 468 return maybeError; 359 469 }); 360 470 } 361 471 362 472 function emitIncrement(token, old, extraArg) 363 473 { … … 365 475 if (extraArg) 366 476 args.push(extraArg); 367 477 368 478 let name = "operator" + token.text; 369 479 if (/=$/.test(name)) 370 480 name = RegExp.leftContext; 371 481 372 482 if (name == "operator") 373 483 throw new Error("Invalid name: " + name); 374 484 375 485 return new CallExpression(token, name, args); 376 486 } 377 487 378 488 function finishParsingPostIncrement(token, left) 379 489 { … … 383 493 return readModifyWrite; 384 494 } 385 495 386 496 function parseSuffixOperator(left, acceptableOperators) 387 497 { … … 396 506 if (token.text == "->") 397 507 left = new DereferenceExpression(token, left); 398 left = new DotExpression(token, left, consumeKind("identifier").text); 508 let maybeError = consumeKind("identifier"); 509 if (maybeError instanceof WSyntaxError) 510 return maybeError; 511 left = new DotExpression(token, left, maybeError.text); 399 512 break; 400 513 case "[": { 401 514 let index = parseExpression(); 402 consume("]"); 515 if (index instanceof WSyntaxError) 516 return index; 517 let maybeError = consume("]"); 518 if (maybeError instanceof WSyntaxError) 519 return maybeError; 403 520 left = new IndexExpression(token, left, index); 404 521 break; … … 410 527 return left; 411 528 } 412 529 413 530 function parsePossibleSuffix() 414 531 { … … 418 535 if (isCallExpression()) { 419 536 left = parseCallExpression(); 537 if (left instanceof WSyntaxError) 538 return left; 420 539 acceptableOperators = limitedOperators; 421 } else 540 } else { 422 541 left = parseTerm(); 423 542 if (left instanceof WSyntaxError) 543 return left; 544 } 545 424 546 return parseSuffixOperator(left, acceptableOperators); 425 547 } 426 548 427 549 function finishParsingPreIncrement(token, left, extraArg) 428 550 { … … 432 554 return readModifyWrite; 433 555 } 434 556 435 557 function parsePreIncrement() 436 558 { 437 559 let token = consume("++", "--"); 560 if (token instanceof WSyntaxError) 561 return token; 438 562 let left = parsePossiblePrefix(); 563 if (left instanceof WSyntaxError) 564 return left; 439 565 return finishParsingPreIncrement(token, left); 440 566 } 441 567 442 568 function parsePossiblePrefix() 443 569 { … … 445 571 if (test("++", "--")) 446 572 return parsePreIncrement(); 447 if (token = tryConsume("+", "-", "~")) 448 return new CallExpression(token, "operator" + token.text, [parsePossiblePrefix()]); 449 if (token = tryConsume("*")) 450 return new DereferenceExpression(token, parsePossiblePrefix()); 451 if (token = tryConsume("&")) 452 return new MakePtrExpression(token, parsePossiblePrefix()); 453 if (token = tryConsume("@")) 454 return new MakeArrayRefExpression(token, parsePossiblePrefix()); 455 if (token = tryConsume("!")) { 573 if (token = tryConsume("+", "-", "~")) { 574 let possiblePrefix = parsePossiblePrefix(); 575 if (possiblePrefix instanceof WSyntaxError) 576 return WSyntaxError; 577 return new CallExpression(token, "operator" + token.text, [possiblePrefix]); 578 } if (token = tryConsume("*")) { 579 let possiblePrefix = parsePossiblePrefix(); 580 if (possiblePrefix instanceof WSyntaxError) 581 return WSyntaxError; 582 return new DereferenceExpression(token, possiblePrefix); 583 } if (token = tryConsume("&")) { 584 let possiblePrefix = parsePossiblePrefix(); 585 if (possiblePrefix instanceof WSyntaxError) 586 return WSyntaxError; 587 return new MakePtrExpression(token, possiblePrefix); 588 } if (token = tryConsume("@")) { 589 let possiblePrefix = parsePossiblePrefix(); 590 if (possiblePrefix instanceof WSyntaxError) 591 return WSyntaxError; 592 return new MakeArrayRefExpression(token, possiblePrefix); 593 } if (token = tryConsume("!")) { 456 594 let remainder = parsePossiblePrefix(); 595 if (remainder instanceof WSyntaxError) 596 return remainder; 457 597 return new LogicalNot(token, new CallExpression(remainder.origin, "bool", [remainder])); 458 598 } 459 599 return parsePossibleSuffix(); 460 600 } 461 601 462 602 function parsePossibleProduct() 463 603 { 464 604 return parseLeftOperatorCall(["*", "/", "%"], parsePossiblePrefix); 465 605 } 466 606 467 607 function parsePossibleSum() 468 608 { 469 609 return parseLeftOperatorCall(["+", "-"], parsePossibleProduct); 470 610 } 471 611 472 612 function parsePossibleShift() 473 613 { 474 614 return parseLeftOperatorCall(["<<", ">>"], parsePossibleSum); 475 615 } 476 616 477 617 function parsePossibleRelationalInequality() 478 618 { 479 619 return parseLeftOperatorCall(["<", ">", "<=", ">="], parsePossibleShift); 480 620 } 481 621 482 622 function parsePossibleRelationalEquality() 483 623 { … … 491 631 }); 492 632 } 493 633 494 634 function parsePossibleBitwiseAnd() 495 635 { 496 636 return parseLeftOperatorCall(["&"], parsePossibleRelationalEquality); 497 637 } 498 638 499 639 function parsePossibleBitwiseXor() 500 640 { 501 641 return parseLeftOperatorCall(["^"], parsePossibleBitwiseAnd); 502 642 } 503 643 504 644 function parsePossibleBitwiseOr() 505 645 { 506 646 return parseLeftOperatorCall(["|"], parsePossibleBitwiseXor); 507 647 } 508 648 509 649 function parseLeftLogicalExpression(texts, nextParser) 510 650 { … … 513 653 (token, left, right) => new LogicalExpression(token, token.text, new CallExpression(left.origin, "bool", [left]), new CallExpression(right.origin, "bool", [right]))); 514 654 } 515 655 516 656 function parsePossibleLogicalAnd() 517 657 { 518 658 return parseLeftLogicalExpression(["&&"], parsePossibleBitwiseOr); 519 659 } 520 660 521 661 function parsePossibleLogicalOr() 522 662 { 523 663 return parseLeftLogicalExpression(["||"], parsePossibleLogicalAnd); 524 664 } 525 665 526 666 function parsePossibleTernaryConditional() 527 667 { 528 668 let predicate = parsePossibleLogicalOr(); 669 if (predicate instanceof WSyntaxError) 670 return predicate; 529 671 let operator = tryConsume("?"); 530 672 if (!operator) 531 673 return predicate; 532 674 let bodyExpression = parsePossibleAssignment(); 533 consume(":"); 675 if (bodyExpression instanceof WSyntaxError) 676 return bodyExpression; 677 let maybeError = consume(":"); 678 if (maybeError instanceof WSyntaxError) 679 return maybeError; 534 680 let elseExpression = parsePossibleAssignment(); 681 if (elseExpression instanceof WSyntaxError) 682 return elseExpression; 535 683 return new TernaryExpression(operator, predicate, bodyExpression, elseExpression); 536 684 } 537 685 538 686 function parsePossibleAssignment(mode) 539 687 { 540 688 let lhs = parsePossibleTernaryConditional(); 689 if (lhs instanceof WSyntaxError) 690 return lhs; 541 691 let operator = tryConsume("=", "+=", "-=", "*=", "/=", "%=", "^=", "|=", "&="); 542 692 if (!operator) { 543 693 if (mode == "required") 544 lexer.fail("Expected assignment: " + lexer._text.substring(lexer._index));694 return fail("Expected assignment: " + lexer._text.substring(lexer._index)); 545 695 return lhs; 546 696 } 547 if (operator.text == "=") 548 return new Assignment(operator, lhs, parsePossibleAssignment()); 549 return finishParsingPreIncrement(operator, lhs, parsePossibleAssignment()); 550 } 551 697 if (operator.text == "=") { 698 let innerAssignment = parsePossibleAssignment(); 699 if (innerAssignment instanceof WSyntaxError) 700 return innerAssignment; 701 return new Assignment(operator, lhs, innerAssignment); 702 } 703 let innerAssignment = parsePossibleAssignment(); 704 if (innerAssignment instanceof WSyntaxError) 705 return innerAssignment; 706 return finishParsingPreIncrement(operator, lhs, innerAssignment); 707 } 708 552 709 function parseAssignment() 553 710 { 554 711 return parsePossibleAssignment("required"); 555 712 } 556 713 557 714 function parsePostIncrement() 558 715 { 559 let left = parseSuffixOperator(parseTerm(), ".", "->", "["); 716 let term = parseTerm(); 717 if (term instanceof WSyntaxError) 718 return term; 719 let left = parseSuffixOperator(term, ".", "->", "["); 720 if (left instanceof WSyntaxError) 721 return left; 560 722 let token = consume("++", "--"); 723 if (token instanceof WSyntaxError) 724 return token; 561 725 return finishParsingPostIncrement(token, left); 562 726 } 563 727 564 728 function parseEffectfulExpression() 565 729 { 566 730 if (isCallExpression()) 567 731 return parseCallExpression(); 568 let preIncrement = lexer.backtrackingScope(parsePreIncrement);732 let preIncrement = backtrackingScope(parsePreIncrement); 569 733 if (preIncrement) 570 734 return preIncrement; 571 let postIncrement = lexer.backtrackingScope(parsePostIncrement);735 let postIncrement = backtrackingScope(parsePostIncrement); 572 736 if (postIncrement) 573 737 return postIncrement; 574 738 return parseAssignment(); 575 739 } 576 740 577 741 function genericParseCommaExpression(finalExpressionParser) 578 742 { … … 580 744 let origin = lexer.peek(); 581 745 if (!origin) 582 lexer.fail("Unexpected end of file");746 return fail("Unexpected end of file"); 583 747 for (;;) { 584 let effectfulExpression = lexer.backtrackingScope(() => { 585 parseEffectfulExpression(); 586 consume(","); 748 let effectfulExpression = backtrackingScope(() => { 749 let effectfulExpression = parseEffectfulExpression(); 750 if (effectfulExpression instanceof WSyntaxError) 751 return effectfulExpression; 752 let maybeError = consume(","); 753 if (maybeError instanceof WSyntaxError) 754 return maybeError; 755 return effectfulExpression; 587 756 }); 588 757 if (!effectfulExpression) { … … 599 768 return new CommaExpression(origin, list); 600 769 } 601 770 602 771 function parseCommaExpression() 603 772 { 604 773 return genericParseCommaExpression(parsePossibleAssignment); 605 774 } 606 775 607 776 function parseExpression() 608 777 { 609 778 return parseCommaExpression(); 610 779 } 611 780 612 781 function parseEffectfulStatement() 613 782 { 614 783 let result = genericParseCommaExpression(parseEffectfulExpression); 615 consume(";"); 784 if (result instanceof WSyntaxError) 785 return result; 786 let maybeError = consume(";"); 787 if (maybeError instanceof WSyntaxError) 788 return maybeError; 616 789 return result; 617 790 } 618 791 619 792 function parseReturn() 620 793 { 621 794 let origin = consume("return"); 795 if (origin instanceof WSyntaxError) 796 return origin; 622 797 if (tryConsume(";")) 623 798 return new Return(origin, null); 624 799 let expression = parseExpression(); 625 consume(";"); 800 if (expression instanceof WSyntaxError) 801 return expression; 802 let maybeError = consume(";"); 803 if (maybeError instanceof WSyntaxError) 804 return maybeError; 626 805 return new Return(origin, expression); 627 806 } 628 807 629 808 function parseBreak() 630 809 { 631 810 let origin = consume("break"); 632 consume(";"); 811 if (origin instanceof WSyntaxError) 812 return origin; 813 let maybeError = consume(";"); 814 if (maybeError instanceof WSyntaxError) 815 return maybeError; 633 816 return new Break(origin); 634 817 } 635 818 636 819 function parseContinue() 637 820 { 638 821 let origin = consume("continue"); 639 consume(";"); 822 if (origin instanceof WSyntaxError) 823 return origin; 824 let maybeError = consume(";"); 825 if (maybeError instanceof WSyntaxError) 826 return maybeError; 640 827 return new Continue(origin); 641 828 } … … 644 831 { 645 832 let origin = consume("if"); 646 consume("("); 833 if (origin instanceof WSyntaxError) 834 return origin; 835 let maybeError = consume("("); 836 if (maybeError instanceof WSyntaxError) 837 return maybeError; 647 838 let conditional = parseExpression(); 648 consume(")"); 839 if (conditional instanceof WSyntaxError) 840 return conditional; 841 maybeError = consume(")"); 842 if (maybeError instanceof WSyntaxError) 843 return maybeError; 649 844 let body = parseStatement(); 845 if (body instanceof WSyntaxError) 846 return body; 650 847 let elseBody; 651 if (tryConsume("else")) 848 if (tryConsume("else")) { 652 849 elseBody = parseStatement(); 850 if (elseBody instanceof WSyntaxError) 851 return elseBody; 852 } 653 853 return new IfStatement(origin, new CallExpression(conditional.origin, "bool", [conditional]), body, elseBody); 654 854 } … … 657 857 { 658 858 let origin = consume("while"); 659 consume("("); 859 if (origin instanceof WSyntaxError) 860 return origin; 861 let maybeError = consume("("); 862 if (maybeError instanceof WSyntaxError) 863 return maybeError; 660 864 let conditional = parseExpression(); 661 consume(")"); 865 if (conditional instanceof WSyntaxError) 866 return conditional; 867 maybeError = consume(")"); 868 if (maybeError instanceof WSyntaxError) 869 return maybeError; 662 870 let body = parseStatement(); 871 if (body instanceof WSyntaxError) 872 return body; 663 873 return new WhileLoop(origin, new CallExpression(conditional.origin, "bool", [conditional]), body); 664 874 } … … 667 877 { 668 878 let origin = consume("for"); 669 consume("("); 879 if (origin instanceof WSyntaxError) 880 return origin; 881 let maybeError = consume("("); 882 if (maybeError instanceof WSyntaxError) 883 return maybeError; 670 884 let initialization; 671 885 if (tryConsume(";")) 672 886 initialization = undefined; 673 887 else { 674 initialization = lexer.backtrackingScope(parseVariableDecls);675 if (!initialization) 888 initialization = backtrackingScope(parseVariableDecls); 889 if (!initialization) { 676 890 initialization = parseEffectfulStatement(); 891 if (initialization instanceof WSyntaxError) 892 return initialization; 893 } 677 894 } 678 895 let condition = tryConsume(";"); … … 681 898 else { 682 899 condition = parseExpression(); 683 consume(";"); 900 if (condition instanceof WSyntaxError) 901 return condition; 902 maybeError = consume(";"); 903 if (maybeError instanceof WSyntaxError) 904 return maybeError; 684 905 condition = new CallExpression(condition.origin, "bool", [condition]); 685 906 } … … 689 910 else { 690 911 increment = parseExpression(); 691 consume(")"); 912 if (increment instanceof WSyntaxError) 913 return increment; 914 maybeError = consume(")"); 915 if (maybeError instanceof WSyntaxError) 916 return maybeError; 692 917 } 693 918 let body = parseStatement(); 919 if (body instanceof WSyntaxError) 920 return body; 694 921 return new ForLoop(origin, initialization, condition, increment, body); 695 922 } … … 698 925 { 699 926 let origin = consume("do"); 927 if (origin instanceof WSyntaxError) 928 return origin; 700 929 let body = parseStatement(); 701 consume("while"); 702 consume("("); 930 if (body instanceof WSyntaxError) 931 return body; 932 let maybeError = consume("while"); 933 if (maybeError instanceof WSyntaxError) 934 return maybeError; 935 maybeError = consume("("); 936 if (maybeError instanceof WSyntaxError) 937 return maybeError; 703 938 let conditional = parseExpression(); 704 consume(")"); 939 if (conditional instanceof WSyntaxError) 940 return conditional; 941 maybeError = consume(")"); 942 if (maybeError instanceof WSyntaxError) 943 return maybeError; 705 944 return new DoWhileLoop(origin, body, new CallExpression(conditional.origin, "bool", [conditional])); 706 945 } 707 946 708 947 function parseVariableDecls() 709 948 { 710 949 let type = parseType(); 950 if (type instanceof WSyntaxError) 951 return type; 711 952 let list = []; 712 953 do { 713 954 let name = consumeKind("identifier"); 955 if (name instanceof WSyntaxError) 956 return name; 714 957 let initializer = tryConsume("=") ? parseExpression() : null; 958 if (initializer instanceof WSyntaxError) 959 return initializer; 715 960 list.push(new VariableDecl(name, name.text, type, initializer)); 716 } while (consume(",", ";").text == ","); 961 let maybeError = consume(",", ";"); 962 if (maybeError instanceof WSyntaxError) 963 return maybeError; 964 if (maybeError.text != ",") 965 break; 966 } while (true); 717 967 return new CommaExpression(type.origin, list); 718 968 } 719 969 720 970 function parseSwitchCase() 721 971 { 722 972 let token = consume("default", "case"); 973 if (token instanceof WSyntaxError) 974 return token; 723 975 let value; 724 if (token.text == "case") 976 if (token.text == "case") { 725 977 value = parseConstexpr(); 726 consume(":"); 978 if (value instanceof WSyntaxError) 979 return value; 980 } 981 let maybeError = consume(":"); 982 if (maybeError instanceof WSyntaxError) 983 return maybeError; 727 984 let body = parseBlockBody("}", "default", "case"); 985 if (body instanceof WSyntaxError) 986 return body; 728 987 return new SwitchCase(token, value, body); 729 988 } 730 989 731 990 function parseSwitchStatement() 732 991 { 733 992 let origin = consume("switch"); 734 consume("("); 993 if (origin instanceof WSyntaxError) 994 return origin; 995 let maybeError = consume("("); 996 if (maybeError instanceof WSyntaxError) 997 return maybeError; 735 998 let value = parseExpression(); 736 consume(")"); 737 consume("{"); 999 if (value instanceof WSyntaxError) 1000 return value; 1001 maybeError = consume(")"); 1002 if (maybeError instanceof WSyntaxError) 1003 return maybeError; 1004 maybeError = consume("{"); 1005 if (maybeError instanceof WSyntaxError) 1006 return maybeError; 738 1007 let result = new SwitchStatement(origin, value); 739 while (!tryConsume("}")) 740 result.add(parseSwitchCase()); 1008 while (!tryConsume("}")) { 1009 let switchCase = parseSwitchCase(); 1010 if (switchCase instanceof WSyntaxError) 1011 return switchCase; 1012 result.add(switchCase); 1013 } 741 1014 return result; 742 1015 } 743 1016 744 1017 function parseStatement() 745 1018 { … … 767 1040 if (token.text == "trap") { 768 1041 let origin = consume("trap"); 1042 if (origin instanceof WSyntaxError) 1043 return origin; 769 1044 consume(";"); 770 1045 return new TrapStatement(origin); … … 772 1047 if (token.text == "{") 773 1048 return parseBlock(); 774 let variableDecl = lexer.backtrackingScope(parseVariableDecls);1049 let variableDecl = backtrackingScope(parseVariableDecls); 775 1050 if (variableDecl) 776 1051 return variableDecl; 777 1052 return parseEffectfulStatement(); 778 1053 } 779 1054 780 1055 function parseBlockBody(...terminators) 781 1056 { … … 783 1058 while (!test(...terminators)) { 784 1059 let statement = parseStatement(); 1060 if (statement instanceof WSyntaxError) 1061 return statement; 785 1062 if (statement) 786 1063 block.add(statement); … … 788 1065 return block; 789 1066 } 790 1067 791 1068 function parseBlock() 792 1069 { 793 1070 let origin = consume("{"); 1071 if (origin instanceof WSyntaxError) 1072 return origin; 794 1073 let block = parseBlockBody("}"); 795 consume("}"); 1074 if (block instanceof WSyntaxError) 1075 return block; 1076 let maybeError = consume("}"); 1077 if (maybeError instanceof WSyntaxError) 1078 return maybeError; 796 1079 return block; 797 1080 } 798 1081 799 1082 function parseParameter() 800 1083 { 801 1084 let type = parseType(); 1085 if (type instanceof WSyntaxError) 1086 return type; 802 1087 let name = tryConsumeKind("identifier"); 803 1088 return new FuncParameter(type.origin, name ? name.text : null, type); 804 1089 } 805 1090 806 1091 function parseParameters() 807 1092 { 808 consume("("); 1093 let maybeError = consume("("); 1094 if (maybeError instanceof WSyntaxError) 1095 return maybeError; 809 1096 let parameters = []; 810 1097 while (!test(")")) { 811 parameters.push(parseParameter()); 1098 let parameter = parseParameter(); 1099 if (parameter instanceof WSyntaxError) 1100 return parameter; 1101 parameters.push(parameter); 812 1102 if (!tryConsume(",")) 813 1103 break; 814 1104 } 815 consume(")"); 1105 maybeError = consume(")"); 1106 if (maybeError instanceof WSyntaxError) 1107 return maybeError; 816 1108 return parameters; 817 1109 } 818 1110 819 1111 function parseFuncName() 820 1112 { 821 1113 if (tryConsume("operator")) { 822 1114 let token = consume("+", "-", "*", "/", "%", "^", "&", "|", "<", ">", "<=", ">=", "==", "++", "--", ".", "~", "<<", ">>", "["); 1115 if (token instanceof WSyntaxError) 1116 return token; 823 1117 if (token.text == "&") { 824 1118 if (tryConsume("[")) { 825 consume("]"); 1119 let maybeError = consume("]"); 1120 if (maybeError instanceof WSyntaxError) 1121 return maybeError; 826 1122 return "operator&[]"; 827 1123 } 828 if (tryConsume(".")) 829 return "operator&." + consumeKind("identifier").text; 1124 if (tryConsume(".")) { 1125 let maybeError = consumeKind("identifier"); 1126 if (maybeError instanceof WSyntaxError) 1127 return maybeError; 1128 return "operator&." + maybeError.text; 1129 } 830 1130 return "operator&"; 831 1131 } 832 1132 if (token.text == ".") { 833 let result = "operator." + consumeKind("identifier").text; 1133 let maybeError = consumeKind("identifier"); 1134 if (maybeError instanceof WSyntaxError) 1135 return maybeError; 1136 let result = "operator." + maybeError.text; 834 1137 if (tryConsume("=")) 835 1138 result += "="; … … 837 1140 } 838 1141 if (token.text == "[") { 839 consume("]"); 1142 let maybeError = consume("]"); 1143 if (maybeError instanceof WSyntaxError) 1144 return maybeError; 840 1145 let result = "operator[]"; 841 1146 if (tryConsume("=")) … … 845 1150 return "operator" + token.text; 846 1151 } 847 return consumeKind("identifier").text; 1152 let maybeError = consumeKind("identifier"); 1153 if (maybeError instanceof WSyntaxError) 1154 return maybeError; 1155 return maybeError.text; 848 1156 } 849 1157 … … 859 1167 origin = operatorToken; 860 1168 returnType = parseType(); 1169 if (returnType instanceof WSyntaxError) 1170 return returnType; 861 1171 name = "operator cast"; 862 1172 isCast = true; … … 864 1174 shaderType = tryConsume("vertex", "fragment"); 865 1175 returnType = parseType(); 1176 if (returnType instanceof WSyntaxError) 1177 return returnType; 866 1178 if (shaderType) { 867 1179 origin = shaderType; … … 870 1182 origin = returnType.origin; 871 1183 name = parseFuncName(); 1184 if (name instanceof WSyntaxError) 1185 return name; 872 1186 isCast = false; 873 1187 } 874 1188 let parameters = parseParameters(); 1189 if (parameters instanceof WSyntaxError) 1190 return parameters; 875 1191 return new Func(origin, name, returnType, parameters, isCast, shaderType); 876 1192 } 877 1193 878 1194 function parseFuncDef() 879 1195 { 880 1196 let func = parseFuncDecl(); 1197 if (func instanceof WSyntaxError) 1198 return func; 881 1199 let body = parseBlock(); 1200 if (body instanceof WSyntaxError) 1201 return body; 882 1202 return new FuncDef(func.origin, func.name, func.returnType, func.parameters, body, func.isCast, func.shaderType); 883 1203 } 884 1204 885 1205 function parseField() 886 1206 { 887 1207 let type = parseType(); 1208 if (type instanceof WSyntaxError) 1209 return type; 888 1210 let name = consumeKind("identifier"); 889 consume(";"); 1211 if (name instanceof WSyntaxError) 1212 return name; 1213 let maybeError = consume(";"); 1214 if (maybeError instanceof WSyntaxError) 1215 return maybeError; 890 1216 return new Field(name, name.text, type); 891 1217 } 892 1218 893 1219 function parseStructType() 894 1220 { 895 1221 let origin = consume("struct"); 896 let name = consumeKind("identifier").text; 897 let result = new StructType(origin, name); 898 consume("{"); 899 while (!tryConsume("}")) 900 result.add(parseField()); 1222 if (origin instanceof WSyntaxError) 1223 return origin; 1224 let name = consumeKind("identifier"); 1225 if (name instanceof WSyntaxError) 1226 return name; 1227 let result = new StructType(origin, name.text); 1228 let maybeError = consume("{"); 1229 if (maybeError instanceof WSyntaxError) 1230 return maybeError; 1231 while (!tryConsume("}")) { 1232 let field = parseField(); 1233 if (field instanceof WSyntaxError) 1234 return field; 1235 result.add(field); 1236 } 901 1237 return result; 902 1238 } 903 1239 904 1240 function parseNativeFunc() 905 1241 { 906 1242 let func = parseFuncDecl(); 907 consume(";"); 1243 if (func instanceof WSyntaxError) 1244 return func; 1245 let maybeError = consume(";"); 1246 if (maybeError instanceof WSyntaxError) 1247 return maybeError; 908 1248 return new NativeFunc(func.origin, func.name, func.returnType, func.parameters, func.isCast, func.shaderType); 909 1249 } 910 1250 911 1251 function parseNative() 912 1252 { 913 1253 let origin = consume("native"); 1254 if (origin instanceof WSyntaxError) 1255 return origin; 914 1256 if (tryConsume("typedef")) { 915 1257 let name = consumeKind("identifier"); 1258 if (name instanceof WSyntaxError) 1259 return name; 916 1260 let args = parseTypeArguments(); 917 consume(";"); 1261 if (args instanceof WSyntaxError) 1262 return args; 1263 let maybeError = consume(";"); 1264 if (maybeError instanceof WSyntaxError) 1265 return maybeError; 918 1266 return NativeType.create(origin, name.text, args); 919 1267 } 920 1268 return parseNativeFunc(); 921 1269 } 922 1270 923 1271 function parseRestrictedFuncDef() 924 1272 { 925 consume("restricted"); 1273 let maybeError = consume("restricted"); 1274 if (maybeError instanceof WSyntaxError) 1275 return maybeError; 926 1276 let result; 927 if (tryConsume("native")) 1277 if (tryConsume("native")) { 928 1278 result = parseNativeFunc(); 929 else 1279 if (result instanceof WSyntaxError) 1280 return result; 1281 } else { 930 1282 result = parseFuncDef(); 1283 if (result instanceof WSyntaxError) 1284 return result; 1285 } 931 1286 result.isRestricted = true; 932 1287 return result; 933 1288 } 934 1289 935 1290 function parseEnumMember() 936 1291 { 937 1292 let name = consumeKind("identifier"); 1293 if (name instanceof WSyntaxError) 1294 return name; 938 1295 let value = null; 939 if (tryConsume("=")) 1296 if (tryConsume("=")) { 940 1297 value = parseConstexpr(); 1298 if (value instanceof WSyntaxError) 1299 return value; 1300 } 941 1301 return new EnumMember(name, name.text, value); 942 1302 } 943 1303 944 1304 function parseEnumType() 945 1305 { 946 consume("enum"); 1306 let maybeError = consume("enum"); 1307 if (maybeError instanceof WSyntaxError) 1308 return maybeError; 947 1309 let name = consumeKind("identifier"); 1310 if (name instanceof WSyntaxError) 1311 return name; 948 1312 let baseType; 949 if (tryConsume(":")) 1313 if (tryConsume(":")) { 950 1314 baseType = parseType(); 951 else 1315 if (baseType instanceof WSyntaxError) 1316 return baseType; 1317 } else 952 1318 baseType = new TypeRef(name, "int"); 953 consume("{"); 1319 maybeError = consume("{"); 1320 if (maybeError instanceof WSyntaxError) 1321 return maybeError; 954 1322 let result = new EnumType(name, name.text, baseType); 955 1323 while (!test("}")) { 956 result.add(parseEnumMember()); 1324 let enumMember = parseEnumMember(); 1325 if (enumMember instanceof WSyntaxError) 1326 return enumMember; 1327 result.add(enumMember); 957 1328 if (!tryConsume(",")) 958 1329 break; 959 1330 } 960 consume("}"); 1331 maybeError = consume("}"); 1332 if (maybeError instanceof WSyntaxError) 1333 return maybeError; 961 1334 return result; 962 1335 } 963 1336 964 1337 for (;;) { 965 1338 let token = lexer.peek(); … … 968 1341 if (token.text == ";") 969 1342 lexer.next(); 970 else if (token.text == "typedef") 971 program.add(parseTypeDef()); 972 else if (originKind == "native" && token.text == "native") 973 program.add(parseNative()); 974 else if (originKind == "native" && token.text == "restricted") 975 program.add(parseRestrictedFuncDef()); 976 else if (token.text == "struct") 977 program.add(parseStructType()); 978 else if (token.text == "enum") 979 program.add(parseEnumType()); 980 else 981 program.add(parseFuncDef()); 1343 else if (token.text == "typedef") { 1344 let typeDef = parseTypeDef(); 1345 if (typeDef instanceof WSyntaxError) 1346 throw typeDef; 1347 program.add(typeDef); 1348 } else if (originKind == "native" && token.text == "native") { 1349 let native = parseNative(); 1350 if (native instanceof WSyntaxError) 1351 throw native; 1352 program.add(native); 1353 } else if (originKind == "native" && token.text == "restricted") { 1354 let restrictedFuncDef = parseRestrictedFuncDef(); 1355 if (restrictedFuncDef instanceof WSyntaxError) 1356 throw restrictedFuncDef; 1357 program.add(restrictedFuncDef); 1358 } else if (token.text == "struct") { 1359 let struct = parseStructType(); 1360 if (struct instanceof WSyntaxError) 1361 throw struct; 1362 program.add(struct); 1363 } else if (token.text == "enum") { 1364 let enumType = parseEnumType(); 1365 if (enumType instanceof WSyntaxError) 1366 throw enumType; 1367 program.add(enumType); 1368 } else { 1369 let funcDef = parseFuncDef(); 1370 if (funcDef instanceof WSyntaxError) 1371 throw funcDef; 1372 program.add(funcDef); 1373 } 982 1374 } 983 1375 } -
trunk/Tools/WebGPUShadingLanguageRI/SPIRV.html
r235635 r235738 152 152 <script src="VectorType.js"></script> 153 153 <script src="VisitingSet.js"></script> 154 <script src="WLexicalError.js"></script> 154 155 <script src="WSyntaxError.js"></script> 155 156 <script src="WTrapError.js"></script> -
trunk/Tools/WebGPUShadingLanguageRI/StandardLibrary.js
r235642 r235738 774 774 return result; 775 775 } 776 777 /* 776 778 777 for (let type of [`bool`, `uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { 779 778 for (let size of [2, 3, 4]) { … … 1890 1889 } 1891 1890 print(); 1892 1891 /* 1893 1892 for (let type of [`uint`, `int`]) { 1894 1893 for (let functionName of [`Add`, `And`, `Exchange`, `Max`, `Min`, `Or`, `Xor`]) { … … 1899 1898 print(); 1900 1899 */ 1901 1902 1900 for (let type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { 1903 1901 for (let length of [``, `2`, `3`, `4`]) { -
trunk/Tools/WebGPUShadingLanguageRI/Test.html
r235635 r235738 146 146 <script src="VectorType.js"></script> 147 147 <script src="VisitingSet.js"></script> 148 <script src="WLexicalError.js"></script> 148 149 <script src="WSyntaxError.js"></script> 149 150 <script src="WTrapError.js"></script> -
trunk/Tools/WebGPUShadingLanguageRI/Test.js
r235635 r235738 329 329 } 330 330 }); 331 332 tests.commentParsing = function() {333 let program = doPrep(`334 /* this comment335 runs over multiple lines */336 bool foo() { return true; }337 `);338 checkBool(program, callFunction(program, "foo", []), true);339 340 checkFail(341 () => doPrep(`342 /* this comment343 runs over multiple lines344 bool foo() { return true; }345 `),346 (e) => e instanceof WSyntaxError);347 }348 331 349 332 tests.ternaryExpression = function() { … … 7627 7610 } 7628 7611 7612 tests.commentParsing = function() { 7613 let program = doPrep(` 7614 /* this comment 7615 runs over multiple lines */ 7616 bool foo() { return true; } 7617 `); 7618 checkBool(program, callFunction(program, "foo", []), true); 7619 7620 checkFail( 7621 () => doPrep(` 7622 /* this comment 7623 runs over multiple lines 7624 bool foo() { return true; } 7625 `), 7626 (e) => e instanceof WLexicalError); 7627 } 7628 7629 7629 okToTest = true; 7630 7630 … … 7684 7684 } 7685 7685 7686 -
trunk/Tools/WebGPUShadingLanguageRI/WLexicalError.js
r235737 r235738 1 1 /* 2 * Copyright (C) 201 7Apple Inc. All rights reserved.2 * Copyright (C) 2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 25 25 "use strict"; 26 26 27 class W SyntaxError extends Error {27 class WLexicalError extends Error { 28 28 constructor(originString, message) 29 29 { 30 super(" Syntaxerror at " + originString + ": " + message);30 super("Lexical error at " + originString + ": " + message); 31 31 this.originString = originString; 32 32 this.syntaxErrorMessage = message; -
trunk/Tools/WebGPUShadingLanguageRI/WSyntaxError.js
r221393 r235738 25 25 "use strict"; 26 26 27 class WSyntaxError extends Error{27 class WSyntaxError { 28 28 constructor(originString, message) 29 29 { 30 super("Syntax error at " + originString + ": " + message);30 this.payload = "Syntax error at " + originString + ": " + message; 31 31 this.originString = originString; 32 32 this.syntaxErrorMessage = message; -
trunk/Tools/WebGPUShadingLanguageRI/index.html
r235635 r235738 146 146 <script src="VectorType.js"></script> 147 147 <script src="VisitingSet.js"></script> 148 <script src="WLexicalError.js"></script> 148 149 <script src="WSyntaxError.js"></script> 149 150 <script src="WTrapError.js"></script>
Note: See TracChangeset
for help on using the changeset viewer.