github.com/joomcode/cue@v0.4.4-0.20221111115225-539fe3512047/cue/testdata/cycle/compbottomnofinal.txtar (about) 1 // Issues: #667, #695, #622 2 -- in.cue -- 3 import ( 4 "strconv" 5 "regexp" 6 ) 7 8 // In these test, it is impossible to determine the existence of some arcs due 9 // to mutual dependence on becoming concrete. 10 // 11 // This tests shows the essences of when an existence check cannot be resolved. 12 minimal: { 13 a: { 14 if b.port == _|_ { 15 port: "" 16 } 17 } 18 19 b: { 20 if a.port == _|_ { 21 port: "" 22 } 23 } 24 } 25 26 small: { 27 #userHostPort: #"^(:(?P<port>\d+))?$"# 28 29 p1: { 30 #Y: regexp.FindNamedSubmatch(#userHostPort, #X.port) 31 32 #X: { 33 if #Y.port == _|_ { 34 port: "" 35 } 36 if #Y.port != _|_ { 37 port: ":" + strconv.FormatInt(#Y.port, 10) 38 } 39 } 40 } 41 42 p2: { 43 #X: { 44 if #Y.port == _|_ { 45 port: "" 46 } 47 if #Y.port != _|_ { 48 port: ":" + strconv.FormatInt(#Y.port, 10) 49 } 50 } 51 52 #Y: regexp.FindNamedSubmatch(#userHostPort, #X.port) 53 } 54 } 55 56 medium: { 57 #userHostPort: #"^(:(?P<port>\d+))?$"# 58 59 p1: { 60 #Y: regexp.FindNamedSubmatch(#userHostPort, #X.port) 61 62 Y: { 63 if #Y.port != _|_ { 64 port: strconv.Atoi(#Y.port) 65 } 66 } 67 68 #X: { 69 // Can never determine whether Y.port exists as its resolution 70 // depends on #Y becoming finalized, which, in turn, depends on #X 71 // becoming finalized. 72 if Y.port == _|_ { 73 port: "" 74 } 75 if Y.port != _|_ { 76 port: ":" + strconv.FormatInt(Y.port, 10) 77 } 78 } 79 } 80 81 p2: { 82 #Y: regexp.FindNamedSubmatch(#userHostPort, #X.port) 83 84 #X: { 85 // Can never determine whether Y.port exists as its resolution 86 // depends on #Y becoming finalized, which, in turn, depends on #X 87 // becoming finalized. 88 if Y.port == _|_ { 89 port: "" 90 } 91 if Y.port != _|_ { 92 port: ":" + strconv.FormatInt(Y.port, 10) 93 } 94 } 95 96 Y: { 97 if #Y.port != _|_ { 98 port: strconv.Atoi(#Y.port) 99 } 100 } 101 } 102 103 p3: { 104 Y: { 105 if #Y.port != _|_ { 106 port: strconv.Atoi(#Y.port) 107 } 108 } 109 110 #Y: regexp.FindNamedSubmatch(#userHostPort, #X.port) 111 112 #X: { 113 // Can never determine whether Y.port exists as its resolution 114 // depends on #Y becoming finalized, which, in turn, depends on #X 115 // becoming finalized. 116 if Y.port == _|_ { 117 port: "" 118 } 119 if Y.port != _|_ { 120 port: ":" + strconv.FormatInt(Y.port, 10) 121 } 122 } 123 } 124 125 p4: { 126 Y: { 127 if #Y.port != _|_ { 128 port: strconv.Atoi(#Y.port) 129 } 130 } 131 132 #X: { 133 // Can never determine whether Y.port exists as its resolution 134 // depends on #Y becoming finalized, which, in turn, depends on #X 135 // becoming finalized. 136 if Y.port == _|_ { 137 port: "" 138 } 139 if Y.port != _|_ { 140 port: ":" + strconv.FormatInt(Y.port, 10) 141 } 142 } 143 144 #Y: regexp.FindNamedSubmatch(#userHostPort, #X.port) 145 } 146 147 p5: { 148 #X: { 149 // Can never determine whether Y.port exists as its resolution 150 // depends on #Y becoming finalized, which, in turn, depends on #X 151 // becoming finalized. 152 if Y.port == _|_ { 153 port: "" 154 } 155 if Y.port != _|_ { 156 port: ":" + strconv.FormatInt(Y.port, 10) 157 } 158 } 159 160 #Y: regexp.FindNamedSubmatch(#userHostPort, #X.port) 161 162 Y: { 163 if #Y.port != _|_ { 164 port: strconv.Atoi(#Y.port) 165 } 166 } 167 } 168 169 p6: { 170 #X: { 171 // Can never determine whether Y.port exists as its resolution 172 // depends on #Y becoming finalized, which, in turn, depends on #X 173 // becoming finalized. 174 if Y.port == _|_ { 175 port: "" 176 } 177 if Y.port != _|_ { 178 port: ":" + strconv.FormatInt(Y.port, 10) 179 } 180 } 181 182 Y: { 183 if #Y.port != _|_ { 184 port: strconv.Atoi(#Y.port) 185 } 186 } 187 188 #Y: regexp.FindNamedSubmatch(#userHostPort, #X.port) 189 } 190 } 191 192 large: { 193 #userHostPort: #"^((?P<userinfo>[[:alnum:]]*)@)?(?P<host>[[:alnum:].]+)(:(?P<port>\d+))?$"# 194 195 p1: { 196 Y: { 197 userinfo: "user" 198 host: "example.com" 199 } 200 201 X: #X.userinfo + #X.host + #X.port 202 203 #X: { 204 if Y.userinfo == _|_ { 205 userinfo: "" 206 } 207 if Y.userinfo != _|_ { 208 userinfo: Y.userinfo + "@" 209 } 210 211 host: Y.host 212 213 if Y.port == _|_ { 214 port: "" 215 } 216 if Y.port != _|_ { 217 port: ":" + strconv.FormatInt(Y.port, 10) 218 } 219 } 220 221 Y: { 222 if #Y.userinfo != _|_ { 223 userinfo: #Y.userinfo 224 } 225 226 host: #Y.host 227 228 if #Y.port != _|_ { 229 port: strconv.Atoi(#Y.port) 230 } 231 } 232 233 #Y: regexp.FindNamedSubmatch(#userHostPort, X) 234 } 235 236 p2: { 237 X: #X.userinfo + #X.host + #X.port 238 239 Y: { 240 userinfo: "user" 241 host: "example.com" 242 } 243 244 #X: { 245 if Y.userinfo == _|_ { 246 userinfo: "" 247 } 248 if Y.userinfo != _|_ { 249 userinfo: Y.userinfo + "@" 250 } 251 252 host: Y.host 253 254 if Y.port == _|_ { 255 port: "" 256 } 257 if Y.port != _|_ { 258 port: ":" + strconv.FormatInt(Y.port, 10) 259 } 260 } 261 262 Y: { 263 if #Y.userinfo != _|_ { 264 userinfo: #Y.userinfo 265 } 266 267 host: #Y.host 268 269 if #Y.port != _|_ { 270 port: strconv.Atoi(#Y.port) 271 } 272 } 273 274 #Y: regexp.FindNamedSubmatch(#userHostPort, X) 275 } 276 277 p3: { 278 X: #X.userinfo + #X.host + #X.port 279 280 #X: { 281 if Y.userinfo == _|_ { 282 userinfo: "" 283 } 284 if Y.userinfo != _|_ { 285 userinfo: Y.userinfo + "@" 286 } 287 288 host: Y.host 289 290 if Y.port == _|_ { 291 port: "" 292 } 293 if Y.port != _|_ { 294 port: ":" + strconv.FormatInt(Y.port, 10) 295 } 296 } 297 298 Y: { 299 userinfo: "user" 300 host: "example.com" 301 } 302 303 Y: { 304 if #Y.userinfo != _|_ { 305 userinfo: #Y.userinfo 306 } 307 308 host: #Y.host 309 310 if #Y.port != _|_ { 311 port: strconv.Atoi(#Y.port) 312 } 313 } 314 315 #Y: regexp.FindNamedSubmatch(#userHostPort, X) 316 } 317 318 p4: { 319 X: #X.userinfo + #X.host + #X.port 320 321 #X: { 322 if Y.userinfo == _|_ { 323 userinfo: "" 324 } 325 if Y.userinfo != _|_ { 326 userinfo: Y.userinfo + "@" 327 } 328 329 host: Y.host 330 331 if Y.port == _|_ { 332 port: "" 333 } 334 if Y.port != _|_ { 335 port: ":" + strconv.FormatInt(Y.port, 10) 336 } 337 } 338 339 #Y: regexp.FindNamedSubmatch(#userHostPort, X) 340 341 Y: { 342 userinfo: "user" 343 host: "example.com" 344 } 345 346 Y: { 347 if #Y.userinfo != _|_ { 348 userinfo: #Y.userinfo 349 } 350 351 host: #Y.host 352 353 if #Y.port != _|_ { 354 port: strconv.Atoi(#Y.port) 355 } 356 } 357 } 358 } 359 -- out/eval -- 360 Errors: 361 large.p1.Y: cycle: field inserted by if clause that was previously evaluated by another if clause: port 362 large.p2.#Y: cycle: field was added after an if clause evaluated it: userinfo 363 large.p2.Y: cycle: field inserted by if clause that was previously evaluated by another if clause: port 364 large.p3.#Y: cycle: field was added after an if clause evaluated it: userinfo 365 large.p3.Y: cycle: field inserted by if clause that was previously evaluated by another if clause: port 366 large.p4.#Y: cycle: field was added after an if clause evaluated it: userinfo 367 medium.p1.#Y: cycle: field was added after an if clause evaluated it: port 368 medium.p2.#Y: cycle: field was added after an if clause evaluated it: port 369 medium.p3.Y: cycle: field inserted by if clause that was previously evaluated by another if clause: port 370 medium.p4.Y: cycle: field inserted by if clause that was previously evaluated by another if clause: port 371 minimal.b: cycle: field inserted by if clause that was previously evaluated by another if clause: port 372 small.p1.#Y: cycle: field was added after an if clause evaluated it: port 373 error in call to strconv.Atoi: strconv.Atoi: parsing "": invalid syntax: 374 ./in.cue:104:11 375 error in call to strconv.Atoi: strconv.Atoi: parsing "": invalid syntax: 376 ./in.cue:126:11 377 error in call to strconv.Atoi: strconv.Atoi: parsing "": invalid syntax: 378 ./in.cue:227:11 379 error in call to strconv.Atoi: strconv.Atoi: parsing "": invalid syntax: 380 ./in.cue:268:11 381 error in call to strconv.Atoi: strconv.Atoi: parsing "": invalid syntax: 382 ./in.cue:309:11 383 384 Result: 385 (_|_){ 386 // [eval] 387 minimal: (_|_){ 388 // [eval] 389 a: (struct){ 390 } 391 b: (_|_){ 392 // [eval] minimal.b: cycle: field inserted by if clause that was previously evaluated by another if clause: port 393 port: (string){ "" } 394 } 395 } 396 small: (_|_){ 397 // [eval] 398 #userHostPort: (string){ "^(:(?P<port>\\d+))?$" } 399 p1: (_|_){ 400 // [eval] 401 #Y: (_|_){ 402 // [eval] small.p1.#Y: cycle: field was added after an if clause evaluated it: port 403 port: (string){ "" } 404 } 405 #X: (#struct){ 406 port: (string){ "" } 407 } 408 } 409 p2: (struct){ 410 #X: (#struct){ 411 port: (string){ "" } 412 } 413 #Y: (_|_){ 414 // [incomplete] small.p2.#Y: undefined field: port: 415 // ./in.cue:50:50 416 port: (string){ "" } 417 } 418 } 419 } 420 medium: (_|_){ 421 // [eval] 422 #userHostPort: (string){ "^(:(?P<port>\\d+))?$" } 423 p1: (_|_){ 424 // [eval] 425 #Y: (_|_){ 426 // [eval] medium.p1.#Y: cycle: field was added after an if clause evaluated it: port 427 port: (string){ "" } 428 } 429 Y: (struct){ 430 } 431 #X: (#struct){ 432 port: (string){ "" } 433 } 434 } 435 p2: (_|_){ 436 // [eval] 437 #Y: (_|_){ 438 // [eval] medium.p2.#Y: cycle: field was added after an if clause evaluated it: port 439 port: (string){ "" } 440 } 441 #X: (#struct){ 442 port: (string){ "" } 443 } 444 Y: (struct){ 445 } 446 } 447 p3: (_|_){ 448 // [eval] 449 Y: (_|_){ 450 // [eval] medium.p3.Y: cycle: field inserted by if clause that was previously evaluated by another if clause: port 451 port: (_|_){ 452 // [eval] error in call to strconv.Atoi: strconv.Atoi: parsing "": invalid syntax: 453 // ./in.cue:104:11 454 } 455 } 456 #Y: (#struct){ 457 port: (string){ "" } 458 } 459 #X: (#struct){ 460 port: (string){ "" } 461 } 462 } 463 p4: (_|_){ 464 // [eval] 465 Y: (_|_){ 466 // [eval] medium.p4.Y: cycle: field inserted by if clause that was previously evaluated by another if clause: port 467 port: (_|_){ 468 // [eval] error in call to strconv.Atoi: strconv.Atoi: parsing "": invalid syntax: 469 // ./in.cue:126:11 470 } 471 } 472 #X: (#struct){ 473 port: (string){ "" } 474 } 475 #Y: (#struct){ 476 port: (string){ "" } 477 } 478 } 479 p5: (struct){ 480 #X: (#struct){ 481 port: (string){ "" } 482 } 483 #Y: (_|_){ 484 // [incomplete] medium.p5.#Y: undefined field: port: 485 // ./in.cue:158:50 486 port: (string){ "" } 487 } 488 Y: (struct){ 489 } 490 } 491 p6: (struct){ 492 #X: (#struct){ 493 port: (string){ "" } 494 } 495 Y: (struct){ 496 } 497 #Y: (_|_){ 498 // [incomplete] medium.p6.#Y: undefined field: port: 499 // ./in.cue:186:50 500 port: (string){ "" } 501 } 502 } 503 } 504 large: (_|_){ 505 // [eval] 506 #userHostPort: (string){ "^((?P<userinfo>[[:alnum:]]*)@)?(?P<host>[[:alnum:].]+)(:(?P<port>\\d+))?$" } 507 p1: (_|_){ 508 // [eval] 509 Y: (_|_){ 510 // [eval] large.p1.Y: cycle: field inserted by if clause that was previously evaluated by another if clause: port 511 userinfo: (string){ "user" } 512 host: (string){ "example.com" } 513 port: (_|_){ 514 // [eval] error in call to strconv.Atoi: strconv.Atoi: parsing "": invalid syntax: 515 // ./in.cue:227:11 516 } 517 } 518 X: (string){ "user@example.com" } 519 #X: (#struct){ 520 host: (string){ "example.com" } 521 userinfo: (string){ "user@" } 522 port: (string){ "" } 523 } 524 #Y: (#struct){ 525 host: (string){ "example.com" } 526 port: (string){ "" } 527 userinfo: (string){ "user" } 528 } 529 } 530 p2: (_|_){ 531 // [eval] 532 X: (string){ "user@example.com" } 533 Y: (_|_){ 534 // [eval] large.p2.Y: cycle: field inserted by if clause that was previously evaluated by another if clause: port 535 userinfo: (string){ "user" } 536 host: (string){ "example.com" } 537 port: (_|_){ 538 // [eval] error in call to strconv.Atoi: strconv.Atoi: parsing "": invalid syntax: 539 // ./in.cue:268:11 540 } 541 } 542 #X: (#struct){ 543 host: (string){ "example.com" } 544 userinfo: (string){ "user@" } 545 port: (string){ "" } 546 } 547 #Y: (_|_){ 548 // [eval] large.p2.#Y: cycle: field was added after an if clause evaluated it: userinfo 549 host: (string){ "example.com" } 550 port: (string){ "" } 551 userinfo: (string){ "user" } 552 } 553 } 554 p3: (_|_){ 555 // [eval] 556 X: (string){ "user@example.com" } 557 #X: (#struct){ 558 host: (string){ "example.com" } 559 userinfo: (string){ "user@" } 560 port: (string){ "" } 561 } 562 Y: (_|_){ 563 // [eval] large.p3.Y: cycle: field inserted by if clause that was previously evaluated by another if clause: port 564 userinfo: (string){ "user" } 565 host: (string){ "example.com" } 566 port: (_|_){ 567 // [eval] error in call to strconv.Atoi: strconv.Atoi: parsing "": invalid syntax: 568 // ./in.cue:309:11 569 } 570 } 571 #Y: (_|_){ 572 // [eval] large.p3.#Y: cycle: field was added after an if clause evaluated it: userinfo 573 host: (string){ "example.com" } 574 port: (string){ "" } 575 userinfo: (string){ "user" } 576 } 577 } 578 p4: (_|_){ 579 // [eval] 580 X: (string){ "user@example.com" } 581 #X: (#struct){ 582 host: (string){ "example.com" } 583 userinfo: (string){ "user@" } 584 port: (string){ "" } 585 } 586 #Y: (_|_){ 587 // [eval] large.p4.#Y: cycle: field was added after an if clause evaluated it: userinfo 588 host: (string){ "example.com" } 589 port: (string){ "" } 590 userinfo: (string){ "user" } 591 } 592 Y: (_|_){ 593 // [eval] 594 userinfo: (string){ "user" } 595 host: (_|_){ 596 // [eval] large.p4.#Y: cycle: field was added after an if clause evaluated it: userinfo 597 } 598 } 599 } 600 } 601 } 602 -- out/compile -- 603 --- in.cue 604 { 605 minimal: { 606 a: { 607 if (〈1;b〉.port == _|_(explicit error (_|_ literal) in source)) { 608 port: "" 609 } 610 } 611 b: { 612 if (〈1;a〉.port == _|_(explicit error (_|_ literal) in source)) { 613 port: "" 614 } 615 } 616 } 617 small: { 618 #userHostPort: "^(:(?P<port>\\d+))?$" 619 p1: { 620 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;#X〉.port) 621 #X: { 622 if (〈1;#Y〉.port == _|_(explicit error (_|_ literal) in source)) { 623 port: "" 624 } 625 if (〈1;#Y〉.port != _|_(explicit error (_|_ literal) in source)) { 626 port: (":" + 〈import;strconv〉.FormatInt(〈2;#Y〉.port, 10)) 627 } 628 } 629 } 630 p2: { 631 #X: { 632 if (〈1;#Y〉.port == _|_(explicit error (_|_ literal) in source)) { 633 port: "" 634 } 635 if (〈1;#Y〉.port != _|_(explicit error (_|_ literal) in source)) { 636 port: (":" + 〈import;strconv〉.FormatInt(〈2;#Y〉.port, 10)) 637 } 638 } 639 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;#X〉.port) 640 } 641 } 642 medium: { 643 #userHostPort: "^(:(?P<port>\\d+))?$" 644 p1: { 645 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;#X〉.port) 646 Y: { 647 if (〈1;#Y〉.port != _|_(explicit error (_|_ literal) in source)) { 648 port: 〈import;strconv〉.Atoi(〈2;#Y〉.port) 649 } 650 } 651 #X: { 652 if (〈1;Y〉.port == _|_(explicit error (_|_ literal) in source)) { 653 port: "" 654 } 655 if (〈1;Y〉.port != _|_(explicit error (_|_ literal) in source)) { 656 port: (":" + 〈import;strconv〉.FormatInt(〈2;Y〉.port, 10)) 657 } 658 } 659 } 660 p2: { 661 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;#X〉.port) 662 #X: { 663 if (〈1;Y〉.port == _|_(explicit error (_|_ literal) in source)) { 664 port: "" 665 } 666 if (〈1;Y〉.port != _|_(explicit error (_|_ literal) in source)) { 667 port: (":" + 〈import;strconv〉.FormatInt(〈2;Y〉.port, 10)) 668 } 669 } 670 Y: { 671 if (〈1;#Y〉.port != _|_(explicit error (_|_ literal) in source)) { 672 port: 〈import;strconv〉.Atoi(〈2;#Y〉.port) 673 } 674 } 675 } 676 p3: { 677 Y: { 678 if (〈1;#Y〉.port != _|_(explicit error (_|_ literal) in source)) { 679 port: 〈import;strconv〉.Atoi(〈2;#Y〉.port) 680 } 681 } 682 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;#X〉.port) 683 #X: { 684 if (〈1;Y〉.port == _|_(explicit error (_|_ literal) in source)) { 685 port: "" 686 } 687 if (〈1;Y〉.port != _|_(explicit error (_|_ literal) in source)) { 688 port: (":" + 〈import;strconv〉.FormatInt(〈2;Y〉.port, 10)) 689 } 690 } 691 } 692 p4: { 693 Y: { 694 if (〈1;#Y〉.port != _|_(explicit error (_|_ literal) in source)) { 695 port: 〈import;strconv〉.Atoi(〈2;#Y〉.port) 696 } 697 } 698 #X: { 699 if (〈1;Y〉.port == _|_(explicit error (_|_ literal) in source)) { 700 port: "" 701 } 702 if (〈1;Y〉.port != _|_(explicit error (_|_ literal) in source)) { 703 port: (":" + 〈import;strconv〉.FormatInt(〈2;Y〉.port, 10)) 704 } 705 } 706 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;#X〉.port) 707 } 708 p5: { 709 #X: { 710 if (〈1;Y〉.port == _|_(explicit error (_|_ literal) in source)) { 711 port: "" 712 } 713 if (〈1;Y〉.port != _|_(explicit error (_|_ literal) in source)) { 714 port: (":" + 〈import;strconv〉.FormatInt(〈2;Y〉.port, 10)) 715 } 716 } 717 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;#X〉.port) 718 Y: { 719 if (〈1;#Y〉.port != _|_(explicit error (_|_ literal) in source)) { 720 port: 〈import;strconv〉.Atoi(〈2;#Y〉.port) 721 } 722 } 723 } 724 p6: { 725 #X: { 726 if (〈1;Y〉.port == _|_(explicit error (_|_ literal) in source)) { 727 port: "" 728 } 729 if (〈1;Y〉.port != _|_(explicit error (_|_ literal) in source)) { 730 port: (":" + 〈import;strconv〉.FormatInt(〈2;Y〉.port, 10)) 731 } 732 } 733 Y: { 734 if (〈1;#Y〉.port != _|_(explicit error (_|_ literal) in source)) { 735 port: 〈import;strconv〉.Atoi(〈2;#Y〉.port) 736 } 737 } 738 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;#X〉.port) 739 } 740 } 741 large: { 742 #userHostPort: "^((?P<userinfo>[[:alnum:]]*)@)?(?P<host>[[:alnum:].]+)(:(?P<port>\\d+))?$" 743 p1: { 744 Y: { 745 userinfo: "user" 746 host: "example.com" 747 } 748 X: ((〈0;#X〉.userinfo + 〈0;#X〉.host) + 〈0;#X〉.port) 749 #X: { 750 if (〈1;Y〉.userinfo == _|_(explicit error (_|_ literal) in source)) { 751 userinfo: "" 752 } 753 if (〈1;Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 754 userinfo: (〈2;Y〉.userinfo + "@") 755 } 756 host: 〈1;Y〉.host 757 if (〈1;Y〉.port == _|_(explicit error (_|_ literal) in source)) { 758 port: "" 759 } 760 if (〈1;Y〉.port != _|_(explicit error (_|_ literal) in source)) { 761 port: (":" + 〈import;strconv〉.FormatInt(〈2;Y〉.port, 10)) 762 } 763 } 764 Y: { 765 if (〈1;#Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 766 userinfo: 〈2;#Y〉.userinfo 767 } 768 host: 〈1;#Y〉.host 769 if (〈1;#Y〉.port != _|_(explicit error (_|_ literal) in source)) { 770 port: 〈import;strconv〉.Atoi(〈2;#Y〉.port) 771 } 772 } 773 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;X〉) 774 } 775 p2: { 776 X: ((〈0;#X〉.userinfo + 〈0;#X〉.host) + 〈0;#X〉.port) 777 Y: { 778 userinfo: "user" 779 host: "example.com" 780 } 781 #X: { 782 if (〈1;Y〉.userinfo == _|_(explicit error (_|_ literal) in source)) { 783 userinfo: "" 784 } 785 if (〈1;Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 786 userinfo: (〈2;Y〉.userinfo + "@") 787 } 788 host: 〈1;Y〉.host 789 if (〈1;Y〉.port == _|_(explicit error (_|_ literal) in source)) { 790 port: "" 791 } 792 if (〈1;Y〉.port != _|_(explicit error (_|_ literal) in source)) { 793 port: (":" + 〈import;strconv〉.FormatInt(〈2;Y〉.port, 10)) 794 } 795 } 796 Y: { 797 if (〈1;#Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 798 userinfo: 〈2;#Y〉.userinfo 799 } 800 host: 〈1;#Y〉.host 801 if (〈1;#Y〉.port != _|_(explicit error (_|_ literal) in source)) { 802 port: 〈import;strconv〉.Atoi(〈2;#Y〉.port) 803 } 804 } 805 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;X〉) 806 } 807 p3: { 808 X: ((〈0;#X〉.userinfo + 〈0;#X〉.host) + 〈0;#X〉.port) 809 #X: { 810 if (〈1;Y〉.userinfo == _|_(explicit error (_|_ literal) in source)) { 811 userinfo: "" 812 } 813 if (〈1;Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 814 userinfo: (〈2;Y〉.userinfo + "@") 815 } 816 host: 〈1;Y〉.host 817 if (〈1;Y〉.port == _|_(explicit error (_|_ literal) in source)) { 818 port: "" 819 } 820 if (〈1;Y〉.port != _|_(explicit error (_|_ literal) in source)) { 821 port: (":" + 〈import;strconv〉.FormatInt(〈2;Y〉.port, 10)) 822 } 823 } 824 Y: { 825 userinfo: "user" 826 host: "example.com" 827 } 828 Y: { 829 if (〈1;#Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 830 userinfo: 〈2;#Y〉.userinfo 831 } 832 host: 〈1;#Y〉.host 833 if (〈1;#Y〉.port != _|_(explicit error (_|_ literal) in source)) { 834 port: 〈import;strconv〉.Atoi(〈2;#Y〉.port) 835 } 836 } 837 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;X〉) 838 } 839 p4: { 840 X: ((〈0;#X〉.userinfo + 〈0;#X〉.host) + 〈0;#X〉.port) 841 #X: { 842 if (〈1;Y〉.userinfo == _|_(explicit error (_|_ literal) in source)) { 843 userinfo: "" 844 } 845 if (〈1;Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 846 userinfo: (〈2;Y〉.userinfo + "@") 847 } 848 host: 〈1;Y〉.host 849 if (〈1;Y〉.port == _|_(explicit error (_|_ literal) in source)) { 850 port: "" 851 } 852 if (〈1;Y〉.port != _|_(explicit error (_|_ literal) in source)) { 853 port: (":" + 〈import;strconv〉.FormatInt(〈2;Y〉.port, 10)) 854 } 855 } 856 #Y: 〈import;regexp〉.FindNamedSubmatch(〈1;#userHostPort〉, 〈0;X〉) 857 Y: { 858 userinfo: "user" 859 host: "example.com" 860 } 861 Y: { 862 if (〈1;#Y〉.userinfo != _|_(explicit error (_|_ literal) in source)) { 863 userinfo: 〈2;#Y〉.userinfo 864 } 865 host: 〈1;#Y〉.host 866 if (〈1;#Y〉.port != _|_(explicit error (_|_ literal) in source)) { 867 port: 〈import;strconv〉.Atoi(〈2;#Y〉.port) 868 } 869 } 870 } 871 } 872 }