|
566 | 566 |
|
567 | 567 |
|
568 | 568 | (define (syntax-contains-path? init-stx path) |
569 | | - (with-handlers ([exn:fail? (λ (_) #false)]) |
570 | | - (syntax-ref init-stx path) |
571 | | - #true)) |
| 569 | + (let/ec return |
| 570 | + (for/fold ([stx init-stx]) |
| 571 | + ([element (in-treelist (syntax-path-elements path))]) |
| 572 | + (define unwrapped (syntax-e stx)) |
| 573 | + (cond |
| 574 | + ; Handle improper lists - flatten them so the tail is treated as the last element |
| 575 | + [(and (pair? unwrapped) (not (list? unwrapped))) |
| 576 | + (define flattened (flatten-improper-list unwrapped)) |
| 577 | + (unless (< element (length flattened)) |
| 578 | + (return #false)) |
| 579 | + (list-ref flattened element)] |
| 580 | + ; Handle proper lists |
| 581 | + [(list? unwrapped) |
| 582 | + (unless (< element (length unwrapped)) |
| 583 | + (return #false)) |
| 584 | + (list-ref unwrapped element)] |
| 585 | + ; Handle vectors |
| 586 | + [(vector? unwrapped) |
| 587 | + (unless (< element (vector-length unwrapped)) |
| 588 | + (return #false)) |
| 589 | + (vector-ref unwrapped element)] |
| 590 | + ; Handle boxes - treat as single-element list |
| 591 | + [(box? unwrapped) |
| 592 | + (unless (zero? element) |
| 593 | + (return #false)) |
| 594 | + (unbox unwrapped)] |
| 595 | + ; Handle prefab structs - treat as list of fields |
| 596 | + [(prefab-struct? unwrapped) |
| 597 | + (define fields (struct->list unwrapped)) |
| 598 | + (unless (< element (length fields)) |
| 599 | + (return #false)) |
| 600 | + (list-ref fields element)] |
| 601 | + ; Hashes are unsupported |
| 602 | + [(hash? unwrapped) |
| 603 | + (return #false)] |
| 604 | + ; Other datums don't have children |
| 605 | + [else |
| 606 | + (return #false)])) |
| 607 | + ; Check if result would be a non-syntax component |
| 608 | + (define result-stx |
| 609 | + (for/fold ([stx init-stx]) |
| 610 | + ([element (in-treelist (syntax-path-elements path))]) |
| 611 | + (define unwrapped (syntax-e stx)) |
| 612 | + (cond |
| 613 | + [(and (pair? unwrapped) (not (list? unwrapped))) |
| 614 | + (list-ref (flatten-improper-list unwrapped) element)] |
| 615 | + [(list? unwrapped) |
| 616 | + (list-ref unwrapped element)] |
| 617 | + [(vector? unwrapped) |
| 618 | + (vector-ref unwrapped element)] |
| 619 | + [(box? unwrapped) |
| 620 | + (unbox unwrapped)] |
| 621 | + [(prefab-struct? unwrapped) |
| 622 | + (list-ref (struct->list unwrapped) element)] |
| 623 | + [else stx]))) |
| 624 | + (if (or (pair? result-stx) (empty? result-stx)) |
| 625 | + #false |
| 626 | + #true))) |
572 | 627 |
|
573 | 628 |
|
574 | 629 | (module+ test |
|
0 commit comments