rep.rkt (75827B)
1 #lang racket/base 2 (require (for-template racket/base 3 syntax/parse/private/keywords 4 stxparse-info/parse/private/residual ;; keep abs. path 5 stxparse-info/parse/private/runtime) 6 racket/list 7 racket/contract/base 8 "make.rkt" 9 syntax/parse/private/minimatch 10 syntax/apply-transformer 11 syntax/private/id-table 12 syntax/stx 13 syntax/keyword 14 racket/syntax 15 racket/struct 16 "txlift.rkt" 17 syntax/parse/private/rep-attrs 18 syntax/parse/private/rep-data 19 syntax/parse/private/rep-patterns 20 syntax/parse/private/residual-ct ;; keep abs. path 21 syntax/parse/private/kws) 22 23 ;; Error reporting 24 ;; All entry points should have explicit, mandatory #:context arg 25 ;; (mandatory from outside, at least) 26 27 (provide/contract 28 [atomic-datum-stx? 29 (-> syntax? 30 boolean?)] 31 [parse-rhs 32 (->* [syntax? boolean? #:context (or/c false/c syntax?)] 33 [#:default-description (or/c #f string?)] 34 rhs?)] 35 [parse-pattern+sides 36 (-> syntax? syntax? 37 #:splicing? boolean? 38 #:decls DeclEnv/c 39 #:context syntax? 40 any)] 41 [parse-EH-variant 42 (-> syntax? DeclEnv/c boolean? 43 #:context syntax? 44 any)] 45 [parse-directive-table any/c] 46 [get-decls+defs 47 (-> list? #:context (or/c false/c syntax?) 48 (values DeclEnv/c (listof syntax?)))] 49 [create-aux-def 50 (-> DeclEntry/c 51 (values DeclEntry/c (listof syntax?)))] 52 [parse-argu 53 (-> (listof syntax?) 54 #:context syntax? 55 arguments?)] 56 [parse-kw-formals 57 (-> syntax? 58 #:context syntax? 59 arity?)] 60 [check-stxclass-header 61 (-> syntax? syntax? 62 (list/c identifier? syntax? arity?))] 63 [check-stxclass-application 64 (-> syntax? syntax? 65 (cons/c identifier? arguments?))] 66 [check-conventions-rules 67 (-> syntax? syntax? 68 (listof (list/c regexp? any/c)))] 69 [check-datum-literals-list 70 (-> syntax? syntax? 71 (listof den:datum-lit?))] 72 [check-attr-arity-list 73 (-> syntax? syntax? 74 (listof sattr?))] 75 [stxclass-colon-notation? 76 (parameter/c boolean?)] 77 [fixup-rhs 78 (-> rhs? boolean? (listof sattr?) rhs?)]) 79 80 ;; ---- 81 82 (define (atomic-datum-stx? stx) 83 (let ([datum (syntax-e stx)]) 84 (or (null? datum) 85 (boolean? datum) 86 (string? datum) 87 (number? datum) 88 (keyword? datum) 89 (bytes? datum) 90 (char? datum) 91 (regexp? datum) 92 (byte-regexp? datum)))) 93 94 (define (id-predicate kw) 95 (lambda (stx) 96 (and (identifier? stx) 97 (free-identifier=? stx kw) 98 (begin (disappeared! stx) #t)))) 99 100 (define wildcard? (id-predicate (quote-syntax _))) 101 (define epsilon? (id-predicate (quote-syntax ||))) 102 (define dots? (id-predicate (quote-syntax ...))) 103 (define plus-dots? (id-predicate (quote-syntax ...+))) 104 105 (define keywords 106 (list (quote-syntax _) 107 (quote-syntax ||) 108 (quote-syntax ...) 109 (quote-syntax ~var) 110 (quote-syntax ~datum) 111 (quote-syntax ~literal) 112 (quote-syntax ~and) 113 (quote-syntax ~or) 114 (quote-syntax ~or*) 115 (quote-syntax ~alt) 116 (quote-syntax ~not) 117 (quote-syntax ~seq) 118 (quote-syntax ~rep) 119 (quote-syntax ~once) 120 (quote-syntax ~optional) 121 (quote-syntax ~between) 122 (quote-syntax ~rest) 123 (quote-syntax ~describe) 124 (quote-syntax ~!) 125 (quote-syntax ~bind) 126 (quote-syntax ~fail) 127 (quote-syntax ~parse) 128 (quote-syntax ~do) 129 (quote-syntax ~undo) 130 (quote-syntax ...+) 131 (quote-syntax ~delimit-cut) 132 (quote-syntax ~commit) 133 (quote-syntax ~reflect) 134 (quote-syntax ~splicing-reflect) 135 (quote-syntax ~eh-var) 136 (quote-syntax ~peek) 137 (quote-syntax ~peek-not))) 138 139 (define (reserved? stx) 140 (and (identifier? stx) 141 (for/or ([kw (in-list keywords)]) 142 (free-identifier=? stx kw)))) 143 144 (define (safe-name? stx) 145 (and (identifier? stx) 146 (not (regexp-match? #rx"^~" (symbol->string (syntax-e stx)))))) 147 148 ;; cut-allowed? : (paramter/c boolean?) 149 ;; Used to detect ~cut within ~not pattern. 150 ;; (Also #:no-delimit-cut stxclass within ~not) 151 (define cut-allowed? (make-parameter #t)) 152 153 ;; A LookupConfig is one of 'no, 'try, 'yes 154 ;; 'no means don't lookup, always use dummy (no nested attrs) 155 ;; 'try means lookup, but on failure use dummy (-> nested attrs only from prev.) 156 ;; 'yes means lookup, raise error on failure 157 158 ;; stxclass-lookup-config : parameterof LookupConfig 159 (define stxclass-lookup-config (make-parameter 'yes)) 160 161 ;; stxclass-colon-notation? : (parameterof boolean) 162 ;; if #t, then x:sc notation means (~var x sc) 163 ;; otherwise, just a var 164 (define stxclass-colon-notation? (make-parameter #t)) 165 166 ;; disappeared! : (U Identifier (Stxpair Identifier Any)) -> Void 167 (define (disappeared! x) 168 (cond [(identifier? x) 169 (record-disappeared-uses (list x))] 170 [(and (stx-pair? x) (identifier? (stx-car x))) 171 (record-disappeared-uses (list (stx-car x)))] 172 [else 173 (raise-type-error 'disappeared! 174 "identifier or syntax with leading identifier" 175 x)])) 176 177 (define (propagate-disappeared! stx) 178 (cond [(and (syntax? stx) (syntax-property stx 'disappeared-use)) 179 => (lambda (xs) (record-disappeared-uses (filter identifier? (flatten xs)) #f))])) 180 181 182 ;; ============================================================ 183 ;; Entry points to pattern/rhs parsing 184 185 ;; parse-rhs : Syntax Boolean #:context Syntax #:default-description (U String #f) -> RHS 186 (define (parse-rhs stx splicing? #:context ctx #:default-description [default-description #f]) 187 (call/txlifts 188 (lambda () 189 (parameterize ((current-syntax-context ctx)) 190 (define-values (rest description transp? attributes auto-nested? colon-notation? 191 decls defs commit? delimit-cut?) 192 (parse-rhs/part1 stx splicing?)) 193 (define variants 194 (parameterize ((stxclass-lookup-config (if auto-nested? 'try 'no)) 195 (stxclass-colon-notation? colon-notation?)) 196 (parse-variants rest decls splicing?))) 197 (define sattrs 198 (or attributes 199 (filter (lambda (a) (symbol-interned? (attr-name a))) 200 (intersect-sattrss (map variant-attrs variants))))) 201 (make rhs sattrs transp? (or description #`(quote #,default-description)) variants 202 (append (get-txlifts-as-definitions) defs) 203 commit? delimit-cut?))))) 204 205 (define (parse-rhs/part1 stx splicing?) 206 (define-values (chunks rest) 207 (parse-keyword-options stx rhs-directive-table 208 #:context (current-syntax-context) 209 #:incompatible '((#:attributes #:auto-nested-attributes) 210 (#:commit #:no-delimit-cut)) 211 #:no-duplicates? #t)) 212 (define description (options-select-value chunks '#:description #:default #f)) 213 (define opaque? (and (assq '#:opaque chunks) #t)) 214 (define transparent? (not opaque?)) 215 (define auto-nested? (and (assq '#:auto-nested-attributes chunks) #t)) 216 (define colon-notation? (not (assq '#:disable-colon-notation chunks))) 217 (define commit? 218 (and (assq '#:commit chunks) #t)) 219 (define delimit-cut? 220 (not (assq '#:no-delimit-cut chunks))) 221 (define attributes (options-select-value chunks '#:attributes #:default #f)) 222 (define-values (decls defs) (get-decls+defs chunks)) 223 (values rest description transparent? attributes auto-nested? colon-notation? 224 decls defs commit? delimit-cut?)) 225 226 (define (parse-variants rest decls splicing?) 227 (define (gather-variants stx) 228 (syntax-case stx (pattern) 229 [((pattern . _) . rest) 230 (begin (disappeared! (stx-car stx)) 231 (cons (parse-variant (stx-car stx) splicing? decls) 232 (gather-variants #'rest)))] 233 [(bad-variant . rest) 234 (wrong-syntax #'bad-variant "expected syntax-class variant")] 235 [() 236 null])) 237 (gather-variants rest)) 238 239 ;; get-decls+defs : chunks boolean -> (values DeclEnv (listof syntax)) 240 (define (get-decls+defs chunks #:context [ctx (current-syntax-context)]) 241 (parameterize ((current-syntax-context ctx)) 242 (let*-values ([(decls defs1) (get-decls chunks)] 243 [(decls defs2) (decls-create-defs decls)]) 244 (values decls (append defs1 defs2))))) 245 246 ;; get-decls : chunks -> (values DeclEnv (listof syntax)) 247 (define (get-decls chunks) 248 (define lits (options-select-value chunks '#:literals #:default null)) 249 (define datum-lits (options-select-value chunks '#:datum-literals #:default null)) 250 (define litsets (options-select-value chunks '#:literal-sets #:default null)) 251 (define convs (options-select-value chunks '#:conventions #:default null)) 252 (define localconvs (options-select-value chunks '#:local-conventions #:default null)) 253 (define literals 254 (append/check-lits+litsets lits datum-lits litsets)) 255 (define-values (convs-rules convs-defs) 256 (for/fold ([convs-rules null] [convs-defs null]) 257 ([conv-entry (in-list convs)]) 258 (let* ([c (car conv-entry)] 259 [argu (cdr conv-entry)] 260 [get-parser-id (conventions-get-procedures c)] 261 [rules ((conventions-get-rules c))]) 262 (values (append rules convs-rules) 263 (cons (make-conventions-def (map cadr rules) get-parser-id argu) 264 convs-defs))))) 265 (define convention-rules (append localconvs convs-rules)) 266 (values (new-declenv literals #:conventions convention-rules) 267 (reverse convs-defs))) 268 269 ;; make-conventions-def : (listof den:delay) id Argument -> syntax 270 (define (make-conventions-def dens get-parsers-id argu) 271 (with-syntax ([(parser ...) (map den:delayed-parser dens)] 272 [get-parsers get-parsers-id] 273 [argu argu]) 274 #'(define-values (parser ...) 275 (apply values (app-argu get-parsers argu))))) 276 277 ;; decls-create-defs : DeclEnv -> (values DeclEnv (listof stx)) 278 (define (decls-create-defs decls0) 279 (define (updater key value defs) 280 (let-values ([(value newdefs) (create-aux-def value)]) 281 (values value (append newdefs defs)))) 282 (declenv-update/fold decls0 updater null)) 283 284 ;; create-aux-def : DeclEntry -> (values DeclEntry (listof stx)) 285 ;; FIXME: replace with txlift mechanism 286 (define (create-aux-def entry) 287 (match entry 288 [(? den:lit?) 289 (values entry null)] 290 [(? den:datum-lit?) 291 (values entry null)] 292 [(? den:magic-class?) 293 (values entry null)] 294 [(den:class name scname argu) 295 (with-syntax ([parser (generate-temporary scname)]) 296 (values (make den:delayed #'parser scname) 297 (list #`(define-values (parser) (curried-stxclass-parser #,scname #,argu)))))] 298 [(? den:delayed?) 299 (values entry null)])) 300 301 ;; append/check-lits+litsets : .... -> (listof (U den:lit den:datum-lit)) 302 (define (append/check-lits+litsets lits datum-lits litsets) 303 (define seen (make-bound-id-table)) 304 (define (check-id id [blame-ctx id]) 305 (if (bound-id-table-ref seen id #f) 306 (wrong-syntax blame-ctx "duplicate literal declaration: ~s" (syntax-e id)) 307 (bound-id-table-set! seen id #t)) 308 id) 309 (let* ([litsets* 310 (for/list ([entry (in-list litsets)]) 311 (let ([litset-id (first entry)] 312 [litset (second entry)] 313 [lctx (third entry)] 314 [input-phase (fourth entry)]) 315 (define (get/check-id sym) 316 (check-id (datum->syntax lctx sym) litset-id)) 317 (for/list ([lse (in-list (literalset-literals litset))]) 318 (match lse 319 [(lse:lit internal external lit-phase) 320 (let ([internal (get/check-id internal)] 321 [external (syntax-property external 'literal (gensym))]) 322 (make den:lit internal external input-phase lit-phase))] 323 [(lse:datum-lit internal external) 324 (let ([internal (get/check-id internal)]) 325 (make den:datum-lit internal external))]))))] 326 [lits* 327 (for/list ([lit (in-list lits)]) 328 (check-id (den:lit-internal lit)) 329 lit)] 330 [datum-lits* 331 (for/list ([datum-lit (in-list datum-lits)]) 332 (check-id (den:datum-lit-internal datum-lit)) 333 datum-lit)]) 334 (apply append lits* datum-lits* litsets*))) 335 336 ;; parse-variant : stx boolean DeclEnv -> RHS 337 (define (parse-variant stx splicing? decls0) 338 (syntax-case stx (pattern) 339 [(pattern p . rest) 340 (let-values ([(rest pattern defs) 341 (parse-pattern+sides #'p #'rest 342 #:simplify? #f 343 #:splicing? splicing? 344 #:decls decls0 345 #:context stx)]) 346 (disappeared! stx) 347 (unless (stx-null? rest) 348 (wrong-syntax (if (pair? rest) (car rest) rest) 349 "unexpected terms after pattern directives")) 350 (let* ([attrs (pattern-attrs pattern)] 351 [sattrs (iattrs->sattrs attrs)]) 352 (make variant stx sattrs pattern defs)))])) 353 354 ;; parse-EH-variant : Syntax DeclEnv Boolean 355 ;; -> (Listof (list EllipsisHeadPattern Syntax/EH-Alternative)) 356 (define (parse-EH-variant stx decls allow-or? #:context [ctx (current-syntax-context)]) 357 (parse*-ellipsis-head-pattern stx decls allow-or? #:context ctx)) 358 359 ;; parse-pattern+sides : stx stx <options> -> (values stx Pattern (listof stx)) 360 ;; Parses pattern, side clauses; desugars side clauses & merges with pattern 361 (define (parse-pattern+sides p-stx s-stx 362 #:splicing? splicing? 363 #:decls decls0 364 #:context ctx 365 #:simplify? [simplify? #t]) 366 (let-values ([(rest decls defs sides) 367 (parse-pattern-directives s-stx 368 #:allow-declare? #t 369 #:decls decls0 370 #:context ctx)]) 371 (let* ([pattern0 (parse-whole-pattern p-stx decls splicing? #:context ctx #:kind 'main)] 372 [pattern (combine-pattern+sides pattern0 sides splicing?)] 373 [pattern (if simplify? (simplify-pattern pattern) pattern)]) 374 (values rest pattern defs)))) 375 376 ;; parse-whole-pattern : stx DeclEnv boolean -> Pattern 377 ;; kind is either 'main or 'with, indicates what kind of pattern declare affects 378 (define (parse-whole-pattern stx decls [splicing? #f] 379 #:kind kind 380 #:context [ctx (current-syntax-context)]) 381 (parameterize ((current-syntax-context ctx)) 382 (define pattern 383 (if splicing? 384 (parse-head-pattern stx decls) 385 (parse-single-pattern stx decls))) 386 (define pvars (map attr-name (pattern-attrs pattern))) 387 (define excess-domain (declenv-domain-difference decls pvars)) 388 (when (pair? excess-domain) 389 (wrong-syntax (car excess-domain) 390 (string-append 391 "identifier in #:declare clause does not appear in pattern" 392 (case kind 393 [(main) ""] ;; ";\n this #:declare clause affects only the main pattern"] 394 [(with) ";\n this #:declare clause affects only the preceding #:with pattern"])))) 395 pattern)) 396 397 ;; combine-pattern+sides : Pattern (listof SideClause) -> Pattern 398 (define (combine-pattern+sides pattern sides splicing?) 399 (check-pattern 400 (cond [splicing? (hpat:andu (cons pattern sides))] 401 [else (pat:andu (cons pattern sides))]))) 402 403 ;; gensym* : -> UninternedSymbol 404 ;; Like gensym, but with deterministic name from compilation-local counter. 405 (define gensym*-counter 0) 406 (define (gensym*) 407 (set! gensym*-counter (add1 gensym*-counter)) 408 (string->uninterned-symbol (format "group~a" gensym*-counter))) 409 410 411 ;; ============================================================ 412 ;; Parsing patterns 413 414 ;; parse-single-pattern : stx DeclEnv -> SinglePattern 415 (define (parse-single-pattern stx decls) 416 (parse-*-pattern stx decls #f #f)) 417 418 ;; parse-head-pattern : stx DeclEnv -> HeadPattern 419 (define (parse-head-pattern stx decls) 420 (coerce-head-pattern (parse-*-pattern stx decls #t #f))) 421 422 ;; parse-action-pattern : Stx DeclEnv -> ActionPattern 423 (define (parse-action-pattern stx decls) 424 (define p (parse-*-pattern stx decls #f #t)) 425 (unless (action-pattern? p) 426 (wrong-syntax stx "expected action pattern")) 427 p) 428 429 (define ((make-not-shadowed? decls) id) 430 ;; Returns #f if id is in literals/datum-literals list. 431 ;; Conventions to not shadow pattern-form bindings, under the 432 ;; theory that conventions only apply to things already determined 433 ;; to be pattern variables. 434 (not (declenv-lookup decls id))) 435 ;; suitable as id=? argument to syntax-case* 436 (define ((make-not-shadowed-id=? decls) lit-id pat-id) 437 (and (free-identifier=? lit-id pat-id) 438 (not (declenv-lookup decls pat-id)))) 439 440 ;; parse-*-pattern : stx DeclEnv boolean boolean -> Pattern 441 (define (parse-*-pattern stx decls allow-head? allow-action?) 442 (define (recur stx) 443 (parse-*-pattern stx decls allow-head? allow-action?)) 444 (define (check-head! x) 445 (unless allow-head? 446 (wrong-syntax stx "head pattern not allowed here")) 447 x) 448 (define (check-action! x) 449 ;; Coerce to S-pattern IF only S-patterns allowed 450 (cond [allow-action? x] 451 [(not allow-head?) (action-pattern->single-pattern x)] 452 [else 453 (wrong-syntax stx "action pattern not allowed here")])) 454 (define not-shadowed? (make-not-shadowed? decls)) 455 (propagate-disappeared! stx) 456 (check-pattern 457 (syntax-case* stx (~var ~literal ~datum ~and ~or ~or* ~alt ~not ~rest ~describe 458 ~seq ~optional ~! ~bind ~fail ~parse ~do ~undo 459 ~post ~peek ~peek-not ~delimit-cut ~commit ~reflect 460 ~splicing-reflect) 461 (make-not-shadowed-id=? decls) 462 [id 463 (and (identifier? #'id) 464 (not-shadowed? #'id) 465 (pattern-expander? (syntax-local-value #'id (λ () #f)))) 466 (begin (disappeared! #'id) 467 (recur (expand-pattern (syntax-local-value #'id) stx)))] 468 [(id . rst) 469 (and (identifier? #'id) 470 (not-shadowed? #'id) 471 (pattern-expander? (syntax-local-value #'id (λ () #f)))) 472 (begin (disappeared! #'id) 473 (recur (expand-pattern (syntax-local-value #'id) stx)))] 474 [wildcard 475 (and (wildcard? #'wildcard) 476 (not-shadowed? #'wildcard)) 477 (begin (disappeared! stx) 478 (pat:any))] 479 [~! 480 (disappeared! stx) 481 (begin 482 (unless (cut-allowed?) 483 (wrong-syntax stx 484 "cut (~~!) not allowed within ~~not pattern")) 485 (check-action! 486 (action:cut)))] 487 [reserved 488 (and (reserved? #'reserved) 489 (not-shadowed? #'reserved)) 490 (wrong-syntax stx "pattern keyword not allowed here")] 491 [id 492 (identifier? #'id) 493 (parse-pat:id stx decls allow-head?)] 494 [datum 495 (atomic-datum-stx? #'datum) 496 (pat:datum (syntax->datum #'datum))] 497 [(~var . rest) 498 (disappeared! stx) 499 (parse-pat:var stx decls allow-head?)] 500 [(~datum . rest) 501 (disappeared! stx) 502 (syntax-case stx (~datum) 503 [(~datum d) 504 (pat:datum (syntax->datum #'d))] 505 [_ (wrong-syntax stx "bad ~~datum form")])] 506 [(~literal . rest) 507 (disappeared! stx) 508 (parse-pat:literal stx decls)] 509 [(~and . rest) 510 (disappeared! stx) 511 (parse-pat:and stx decls allow-head? allow-action?)] 512 [(~or . rest) 513 (disappeared! stx) 514 (parse-pat:or stx decls allow-head?)] 515 [(~or* . rest) 516 (disappeared! stx) 517 (parse-pat:or stx decls allow-head?)] 518 [(~alt . rest) 519 (wrong-syntax stx "ellipsis-head pattern allowed only before ellipsis")] 520 [(~not . rest) 521 (disappeared! stx) 522 (parse-pat:not stx decls)] 523 [(~rest . rest) 524 (disappeared! stx) 525 (parse-pat:rest stx decls)] 526 [(~describe . rest) 527 (disappeared! stx) 528 (parse-pat:describe stx decls allow-head?)] 529 [(~delimit-cut . rest) 530 (disappeared! stx) 531 (parse-pat:delimit stx decls allow-head?)] 532 [(~commit . rest) 533 (disappeared! stx) 534 (parse-pat:commit stx decls allow-head?)] 535 [(~reflect . rest) 536 (disappeared! stx) 537 (parse-pat:reflect stx decls #f)] 538 [(~seq . rest) 539 (disappeared! stx) 540 (check-head! 541 (parse-hpat:seq stx #'rest decls))] 542 [(~optional . rest) 543 (disappeared! stx) 544 (check-head! 545 (parse-hpat:optional stx decls))] 546 [(~splicing-reflect . rest) 547 (disappeared! stx) 548 (check-head! 549 (parse-pat:reflect stx decls #t))] 550 [(~bind . rest) 551 (disappeared! stx) 552 (check-action! 553 (parse-pat:bind stx decls))] 554 [(~fail . rest) 555 (disappeared! stx) 556 (check-action! 557 (parse-pat:fail stx decls))] 558 [(~post . rest) 559 (disappeared! stx) 560 (parse-pat:post stx decls allow-head? allow-action?)] 561 [(~peek . rest) 562 (disappeared! stx) 563 (check-head! 564 (parse-pat:peek stx decls))] 565 [(~peek-not . rest) 566 (disappeared! stx) 567 (check-head! 568 (parse-pat:peek-not stx decls))] 569 [(~parse . rest) 570 (disappeared! stx) 571 (check-action! 572 (parse-pat:parse stx decls))] 573 [(~do . rest) 574 (disappeared! stx) 575 (check-action! 576 (parse-pat:do stx decls))] 577 [(~undo . rest) 578 (disappeared! stx) 579 (check-action! 580 (parse-pat:undo stx decls))] 581 [(head dots . tail) 582 (and (dots? #'dots) (not-shadowed? #'dots)) 583 (begin (disappeared! #'dots) 584 (parse-pat:dots stx #'head #'tail decls))] 585 [(head plus-dots . tail) 586 (and (plus-dots? #'plus-dots) (not-shadowed? #'plus-dots)) 587 (begin (disappeared! #'plus-dots) 588 (parse-pat:plus-dots stx #'head #'tail decls))] 589 [(head . tail) 590 (let ([headp (parse-*-pattern #'head decls #t #t)] 591 [tailp (parse-single-pattern #'tail decls)]) 592 (cond [(action-pattern? headp) 593 (pat:action headp tailp)] 594 [else (pat:head (coerce-head-pattern headp) tailp)]))] 595 [#(a ...) 596 (let ([lp (parse-single-pattern (syntax/loc stx (a ...)) decls)]) 597 (pat:vector lp))] 598 [b 599 (box? (syntax-e #'b)) 600 (let ([bp (parse-single-pattern (unbox (syntax-e #'b)) decls)]) 601 (pat:box bp))] 602 [s 603 (and (struct? (syntax-e #'s)) (prefab-struct-key (syntax-e #'s))) 604 (let* ([s (syntax-e #'s)] 605 [key (prefab-struct-key s)] 606 [contents (struct->list s)]) 607 (let ([lp (parse-single-pattern (datum->syntax #f contents #'s) decls)]) 608 (pat:pstruct key lp)))]))) 609 610 ;; expand-pattern : pattern-expander Syntax -> Syntax 611 (define (expand-pattern pe stx) 612 (let ([proc (pattern-expander-proc pe)]) 613 (local-apply-transformer proc stx 'expression))) 614 615 ;; parse-ellipsis-head-pattern : stx DeclEnv -> (listof EllipsisHeadPattern) 616 (define (parse-ellipsis-head-pattern stx decls) 617 (for/list ([ehpat+hstx (in-list (parse*-ellipsis-head-pattern stx decls #t))]) 618 (car ehpat+hstx))) 619 620 ;; parse*-ellipsis-head-pattern : stx DeclEnv bool 621 ;; -> (listof (list EllipsisHeadPattern stx/eh-alternative)) 622 (define (parse*-ellipsis-head-pattern stx decls allow-or? 623 #:context [ctx (current-syntax-context)]) 624 (define (recur stx) (parse*-ellipsis-head-pattern stx decls allow-or? #:context ctx)) 625 (define (recur-cdr-list stx) 626 (unless (stx-list? stx) (wrong-syntax stx "expected sequence of patterns")) 627 (apply append (map recur (cdr (stx->list stx))))) 628 (define not-shadowed? (make-not-shadowed? decls)) 629 (propagate-disappeared! stx) 630 (syntax-case* stx (~eh-var ~or ~alt ~between ~optional ~once) 631 (make-not-shadowed-id=? decls) 632 [id 633 (and (identifier? #'id) 634 (not-shadowed? #'id) 635 (pattern-expander? (syntax-local-value #'id (lambda () #f)))) 636 (begin (disappeared! #'id) 637 (recur (expand-pattern (syntax-local-value #'id) stx)))] 638 [(id . rst) 639 (and (identifier? #'id) 640 (not-shadowed? #'id) 641 (pattern-expander? (syntax-local-value #'id (lambda () #f)))) 642 (begin (disappeared! #'id) 643 (recur (expand-pattern (syntax-local-value #'id) stx)))] 644 [(~eh-var name eh-alt-set-id) 645 (disappeared! stx) 646 (let () 647 (define prefix (name->prefix #'name ".")) 648 (define eh-alt-set (get-eh-alternative-set #'eh-alt-set-id)) 649 (for/list ([alt (in-list (eh-alternative-set-alts eh-alt-set))]) 650 (let* ([iattrs (id-pattern-attrs (eh-alternative-attrs alt) prefix)] 651 [attr-count (length iattrs)]) 652 (list (create-ehpat 653 (hpat:var/p #f (eh-alternative-parser alt) no-arguments iattrs #f 654 (scopts attr-count #f #t #f)) 655 (eh-alternative-repc alt) 656 #f) 657 (replace-eh-alternative-attrs 658 alt (iattrs->sattrs iattrs))))))] 659 [(~or . _) 660 (disappeared! stx) 661 (recur-cdr-list stx)] 662 [(~alt . _) 663 (disappeared! stx) 664 (recur-cdr-list stx)] 665 [(~optional . _) 666 (disappeared! stx) 667 (list (parse*-ehpat/optional stx decls))] 668 [(~once . _) 669 (disappeared! stx) 670 (list (parse*-ehpat/once stx decls))] 671 [(~between . _) 672 (disappeared! stx) 673 (list (parse*-ehpat/bounds stx decls))] 674 [_ 675 (let ([head (parse-head-pattern stx decls)]) 676 (list (list (create-ehpat head #f stx) stx)))])) 677 678 (define (replace-eh-alternative-attrs alt sattrs) 679 (match alt 680 [(eh-alternative repc _attrs parser) 681 (eh-alternative repc sattrs parser)])) 682 683 ;; ---------------------------------------- 684 ;; Identifiers, ~var, and stxclasses 685 686 (define (check-no-delimit-cut-in-not id delimit-cut?) 687 (unless (or delimit-cut? (cut-allowed?)) 688 (wrong-syntax id 689 (string-append "syntax class with #:no-delimit-cut option " 690 "not allowed within ~~not pattern")))) 691 692 (define (parse-pat:id id decls allow-head?) 693 (cond [(declenv-lookup decls id) 694 => (lambda (entry) (parse-pat:id/entry id allow-head? entry))] 695 [(not (safe-name? id)) 696 (wrong-syntax id "expected identifier not starting with ~~ character")] 697 [(and (stxclass-colon-notation?) (split-id id)) 698 => (match-lambda 699 [(cons name suffix) 700 (declenv-check-unbound decls name (syntax-e suffix) #:blame-declare? #t) 701 (define entry (declenv-lookup decls suffix)) 702 (cond [(or (den:lit? entry) (den:datum-lit? entry)) 703 (pat:andu (list (pat:svar name) (parse-pat:id/entry id allow-head? entry)))] 704 [else (parse-stxclass-use id allow-head? name suffix no-arguments "." #f)])])] 705 [(declenv-apply-conventions decls id) 706 => (lambda (entry) (parse-pat:id/entry id allow-head? entry))] 707 [else (pat:svar id)])) 708 709 (define (split-id id0) 710 (cond [(regexp-match #rx"^([^:]*):(.+)$" (symbol->string (syntax-e id0))) 711 => (lambda (m) 712 (define src (syntax-source id0)) 713 (define ln (syntax-line id0)) 714 (define col (syntax-column id0)) 715 (define pos (syntax-position id0)) 716 (define span (syntax-span id0)) 717 (define id-str (cadr m)) 718 (define id-len (string-length id-str)) 719 (define suffix-str (caddr m)) 720 (define suffix-len (string-length suffix-str)) 721 (define id 722 (datum->syntax id0 (string->symbol id-str) 723 (list src ln col pos id-len) 724 id0)) 725 (define suffix 726 (datum->syntax id0 (string->symbol suffix-str) 727 (list src ln (and col (+ col id-len 1)) (and pos (+ pos id-len 1)) suffix-len) 728 id0)) 729 (cons id suffix))] 730 [else #f])) 731 732 ;; parse-pat:id/entry : Identifier .... DeclEntry -> SinglePattern 733 ;; Handle when meaning of identifier pattern is given by declenv entry. 734 (define (parse-pat:id/entry id allow-head? entry) 735 (match entry 736 [(den:lit internal literal input-phase lit-phase) 737 (pat:literal literal input-phase lit-phase)] 738 [(den:datum-lit internal sym) 739 (pat:datum sym)] 740 [(den:magic-class name scname argu role) 741 (parse-stxclass-use scname allow-head? id scname argu "." role)] 742 [(den:class _n _c _a) 743 (error 'parse-pat:id 744 "(internal error) decls had leftover stxclass entry: ~s" 745 entry)] 746 [(den:delayed parser scname) 747 (parse-stxclass-use id allow-head? id scname no-arguments "." #f parser)])) 748 749 (define (parse-pat:var stx decls allow-head?) 750 (define name0 751 (syntax-case stx () 752 [(_ name . _) 753 (unless (identifier? #'name) 754 (wrong-syntax #'name "expected identifier")) 755 #'name] 756 [_ 757 (wrong-syntax stx "bad ~~var form")])) 758 (define-values (scname sc+args-stx argu pfx role) 759 (syntax-case stx () 760 [(_ _name) 761 (values #f #f null #f #f)] 762 [(_ _name sc/sc+args . rest) 763 (let-values ([(sc argu) 764 (let ([p (check-stxclass-application #'sc/sc+args stx)]) 765 (values (car p) (cdr p)))]) 766 (define chunks 767 (parse-keyword-options/eol #'rest var-pattern-directive-table 768 #:no-duplicates? #t 769 #:context stx)) 770 (define sep 771 (options-select-value chunks '#:attr-name-separator #:default #f)) 772 (define role (options-select-value chunks '#:role #:default #'#f)) 773 (values sc #'sc/sc+args argu (if sep (syntax-e sep) ".") role))] 774 [_ 775 (wrong-syntax stx "bad ~~var form")])) 776 (cond [(and (epsilon? name0) (not scname)) 777 (wrong-syntax name0 "illegal pattern variable name")] 778 [(and (wildcard? name0) (not scname)) 779 (pat:any)] 780 [scname 781 (parse-stxclass-use stx allow-head? name0 scname argu pfx role)] 782 [else ;; Just proper name 783 (pat:svar name0)])) 784 785 ;; ---- 786 787 (define (parse-stxclass-use stx allow-head? varname scname argu pfx role [parser* #f]) 788 (define config (stxclass-lookup-config)) 789 (cond [(and (memq config '(yes try)) (get-stxclass scname (eq? config 'try))) 790 => (lambda (sc) 791 (unless parser* 792 (check-stxclass-arity sc stx (length (arguments-pargs argu)) (arguments-kws argu))) 793 (parse-stxclass-use* stx allow-head? varname sc argu pfx role parser*))] 794 [else 795 (define bind (name->bind varname)) 796 (pat:fixup stx bind varname scname argu pfx role parser*)])) 797 798 ;; ---- 799 800 (define (parse-stxclass-use* stx allow-head? name sc argu pfx role parser*) 801 ;; if parser* not #f, overrides sc parser 802 (check-no-delimit-cut-in-not stx (scopts-delimit-cut? (stxclass-opts sc))) 803 (define bind (name->bind name)) 804 (define prefix (name->prefix name pfx)) 805 (define parser (or parser* (stxclass-parser sc))) 806 (define nested-attrs (id-pattern-attrs (stxclass-attrs sc) prefix)) 807 (define opts (stxclass-opts sc)) 808 (cond [(and (stxclass/s? sc) (stxclass-inline sc) (equal? argu no-arguments)) 809 (pat:integrated bind (stxclass-inline sc) (scopts-desc opts) role)] 810 [(stxclass/s? sc) 811 (pat:var/p bind parser argu nested-attrs role opts)] 812 [(stxclass/h? sc) 813 (unless allow-head? 814 (wrong-syntax stx "splicing syntax class not allowed here")) 815 (hpat:var/p bind parser argu nested-attrs role opts)])) 816 817 (define (name->prefix id pfx) 818 (cond [(wildcard? id) #f] 819 [(epsilon? id) id] 820 [else (format-id id "~a~a" (syntax-e id) pfx #:source id)])) 821 822 (define (name->bind id) 823 (cond [(wildcard? id) #f] 824 [(epsilon? id) #f] 825 [else id])) 826 827 ;; id-pattern-attrs : (listof SAttr)IdPrefix -> (listof IAttr) 828 (define (id-pattern-attrs sattrs prefix) 829 (if prefix 830 (for/list ([a (in-list sattrs)]) 831 (prefix-attr a prefix)) 832 null)) 833 834 ;; prefix-attr : SAttr identifier -> IAttr 835 (define (prefix-attr a prefix) 836 (make attr (prefix-attr-name prefix (attr-name a)) 837 (attr-depth a) 838 (attr-syntax? a))) 839 840 ;; prefix-attr-name : id symbol -> id 841 (define (prefix-attr-name prefix name) 842 (orig (format-id prefix "~a~a" (syntax-e prefix) name #:source prefix))) 843 844 (define (orig stx) 845 (syntax-property stx 'original-for-check-syntax #t)) 846 847 ;; ---------------------------------------- 848 ;; Other pattern forms 849 850 (define (parse-pat:reflect stx decls splicing?) 851 (syntax-case stx () 852 [(_ name (obj arg ...) . maybe-signature) 853 (let () 854 (unless (identifier? #'var) 855 (raise-syntax-error #f "expected identifier" stx #'name)) 856 (define attr-decls 857 (syntax-case #'maybe-signature () 858 [(#:attributes attr-decls) 859 (check-attr-arity-list #'attr-decls stx)] 860 [() null] 861 [_ (raise-syntax-error #f "bad syntax" stx)])) 862 (define prefix (name->prefix #'name ".")) 863 (define bind (name->bind #'name)) 864 (define ctor (if splicing? hpat:reflect pat:reflect)) 865 (ctor #'obj (parse-argu (syntax->list #'(arg ...))) attr-decls bind 866 (id-pattern-attrs attr-decls prefix)))])) 867 868 (define (parse-pat:literal stx decls) 869 (syntax-case stx () 870 [(_ lit . more) 871 (unless (identifier? #'lit) 872 (wrong-syntax #'lit "expected identifier")) 873 (let* ([chunks (parse-keyword-options/eol #'more phase-directive-table 874 #:no-duplicates? #t 875 #:context stx)] 876 [phase (options-select-value chunks '#:phase #:default #f)] 877 [phase (if phase (txlift phase) #'(syntax-local-phase-level))]) 878 (pat:literal #'lit phase phase))] 879 [_ 880 (wrong-syntax stx "bad ~~literal pattern")])) 881 882 (define (parse-pat:describe stx decls allow-head?) 883 (syntax-case stx () 884 [(_ . rest) 885 (let-values ([(chunks rest) 886 (parse-keyword-options #'rest describe-option-table 887 #:no-duplicates? #t 888 #:context stx)]) 889 (define transparent? (not (assq '#:opaque chunks))) 890 (define role (options-select-value chunks '#:role #:default #'#f)) 891 (syntax-case rest () 892 [(description pattern) 893 (let ([p (parse-*-pattern #'pattern decls allow-head? #f)]) 894 (if (head-pattern? p) 895 (hpat:describe p #'description transparent? role) 896 (pat:describe p #'description transparent? role)))]))])) 897 898 (define (parse-pat:delimit stx decls allow-head?) 899 (syntax-case stx () 900 [(_ pattern) 901 (let ([p (parameterize ((cut-allowed? #t)) 902 (parse-*-pattern #'pattern decls allow-head? #f))]) 903 (if (head-pattern? p) 904 (hpat:delimit p) 905 (pat:delimit p)))])) 906 907 (define (parse-pat:commit stx decls allow-head?) 908 (syntax-case stx () 909 [(_ pattern) 910 (let ([p (parameterize ((cut-allowed? #t)) 911 (parse-*-pattern #'pattern decls allow-head? #f))]) 912 (if (head-pattern? p) 913 (hpat:commit p) 914 (pat:commit p)))])) 915 916 (define (parse-pat:and stx decls allow-head? allow-action?) 917 ;; allow-action? = allowed to *return* pure action pattern; 918 ;; all ~and patterns are allowed to *contain* action patterns 919 (define patterns (parse-cdr-patterns stx decls allow-head? #t)) 920 (cond [(andmap action-pattern? patterns) 921 (cond [allow-action? 922 (action:and patterns)] 923 [allow-head? 924 (wrong-syntax stx "expected at least one head or single-term pattern")] 925 [else 926 (wrong-syntax stx "expected at least one single-term pattern")])] 927 [(memq (stxclass-lookup-config) '(no try)) 928 (pat:and/fixup stx patterns)] 929 [else (parse-pat:and/k stx patterns)])) 930 931 (define (parse-pat:and/k stx patterns) 932 ;; PRE: patterns not all action patterns 933 (cond [(ormap head-pattern? patterns) 934 ;; Check to make sure *all* are head patterns (and action patterns) 935 (for ([pattern (in-list patterns)] 936 [pattern-stx (in-list (stx->list (stx-cdr stx)))]) 937 (unless (or (action-pattern? pattern) (head-pattern? pattern)) 938 (wrong-syntax pattern-stx "single-term pattern not allowed after head pattern"))) 939 (hpat:andu patterns)] 940 [else (pat:andu patterns)])) 941 942 (define (split-prefix xs pred) 943 (let loop ([xs xs] [rprefix null]) 944 (cond [(and (pair? xs) (pred (car xs))) 945 (loop (cdr xs) (cons (car xs) rprefix))] 946 [else 947 (values (reverse rprefix) xs)]))) 948 949 (define (add-actions actions p) 950 (if (head-pattern? p) 951 (for/fold ([p p]) ([action (in-list (reverse actions))]) 952 (hpat:action action p)) 953 (for/fold ([p p]) ([action (in-list (reverse actions))]) 954 (pat:action action p)))) 955 956 (define (parse-pat:or stx decls allow-head?) 957 (define patterns (parse-cdr-patterns stx decls allow-head? #f)) 958 (cond [(null? (cdr patterns)) 959 (car patterns)] 960 [else 961 (cond [(ormap head-pattern? patterns) 962 (create-hpat:or (map coerce-head-pattern patterns))] 963 [else 964 (create-pat:or patterns)])])) 965 966 (define (parse-pat:not stx decls) 967 (syntax-case stx () 968 [(_ pattern) 969 (let ([p (parameterize ((cut-allowed? #f)) 970 (parse-single-pattern #'pattern decls))]) 971 (pat:not p))] 972 [_ 973 (wrong-syntax stx "expected a single subpattern")])) 974 975 (define (parse-hpat:seq stx list-stx decls) 976 (define pattern (parse-single-pattern list-stx decls)) 977 (unless (proper-list-pattern? pattern) 978 (wrong-syntax stx "expected proper list pattern")) 979 (hpat:seq pattern)) 980 981 (define (parse-cdr-patterns stx decls allow-head? allow-action?) 982 (unless (stx-list? stx) 983 (wrong-syntax stx "expected sequence of patterns")) 984 (let ([result 985 (for/list ([sub (in-list (cdr (stx->list stx)))]) 986 (parse-*-pattern sub decls allow-head? allow-action?))]) 987 (when (null? result) 988 (wrong-syntax stx "expected at least one pattern")) 989 result)) 990 991 (define (parse-pat:dots stx head tail decls) 992 (define headps (parse-ellipsis-head-pattern head decls)) 993 (define tailp (parse-single-pattern tail decls)) 994 (unless (pair? headps) 995 (wrong-syntax head "expected at least one pattern")) 996 (pat:dots headps tailp)) 997 998 (define (parse-pat:plus-dots stx head tail decls) 999 (define headp (parse-head-pattern head decls)) 1000 (define tailp (parse-single-pattern tail decls)) 1001 (define head/rep (create-ehpat headp (make-rep:bounds 1 +inf.0 #f #f #f) head)) 1002 (pat:dots (list head/rep) tailp)) 1003 1004 (define (parse-pat:bind stx decls) 1005 (syntax-case stx () 1006 [(_ clause ...) 1007 (let ([clauses (check-bind-clause-list #'(clause ...) stx)]) 1008 (action:and clauses))])) 1009 1010 (define (parse-pat:fail stx decls) 1011 (syntax-case stx () 1012 [(_ . rest) 1013 (let-values ([(chunks rest) 1014 (parse-keyword-options #'rest fail-directive-table 1015 #:context stx 1016 #:incompatible '((#:when #:unless)) 1017 #:no-duplicates? #t)]) 1018 (let ([condition 1019 (cond [(options-select-value chunks '#:when #:default #f) 1020 => values] 1021 [(options-select-value chunks '#:unless #:default #f) 1022 => (lambda (expr) #`(not #,expr))] 1023 [else #'#t])]) 1024 (syntax-case rest () 1025 [(message) 1026 (action:fail condition #'message)] 1027 [() 1028 (action:fail condition #''#f)] 1029 [_ 1030 (wrong-syntax stx "bad ~~fail pattern")])))])) 1031 1032 (define (parse-pat:post stx decls allow-head? allow-action?) 1033 (syntax-case stx () 1034 [(_ pattern) 1035 (let ([p (parse-*-pattern #'pattern decls allow-head? allow-action?)]) 1036 (cond [(action-pattern? p) 1037 (cond [allow-action? (action:post p)] 1038 [(not allow-head?) (pat:post (action-pattern->single-pattern p))] 1039 [else (wrong-syntax stx "action pattern not allowed here")])] 1040 [(head-pattern? p) 1041 (cond [allow-head? (hpat:post p)] 1042 [else (wrong-syntax stx "head pattern not allowed here")])] 1043 [else (pat:post p)]))])) 1044 1045 (define (parse-pat:peek stx decls) 1046 (syntax-case stx () 1047 [(_ pattern) 1048 (let ([p (parse-head-pattern #'pattern decls)]) 1049 (hpat:peek p))])) 1050 1051 (define (parse-pat:peek-not stx decls) 1052 (syntax-case stx () 1053 [(_ pattern) 1054 (let ([p (parse-head-pattern #'pattern decls)]) 1055 (hpat:peek-not p))])) 1056 1057 (define (parse-pat:parse stx decls) 1058 (syntax-case stx () 1059 [(_ pattern expr) 1060 (let ([p (parse-single-pattern #'pattern decls)]) 1061 (action:parse p #'expr))] 1062 [_ 1063 (wrong-syntax stx "bad ~~parse pattern")])) 1064 1065 (define (parse-pat:do stx decls) 1066 (syntax-case stx () 1067 [(_ stmt ...) 1068 (action:do (syntax->list #'(stmt ...)))] 1069 [_ 1070 (wrong-syntax stx "bad ~~do pattern")])) 1071 1072 (define (parse-pat:undo stx decls) 1073 (syntax-case stx () 1074 [(_ stmt ...) 1075 (action:undo (syntax->list #'(stmt ...)))] 1076 [_ 1077 (wrong-syntax stx "bad ~~undo pattern")])) 1078 1079 (define (parse-pat:rest stx decls) 1080 (syntax-case stx () 1081 [(_ pattern) 1082 (parse-single-pattern #'pattern decls)])) 1083 1084 (define (parse-hpat:optional stx decls) 1085 (define-values (head-stx head iattrs _name _tmm defaults) 1086 (parse*-optional-pattern stx decls h-optional-directive-table)) 1087 (create-hpat:or 1088 (list head 1089 (hpat:action (action:and defaults) 1090 (hpat:seq (pat:datum '())))))) 1091 1092 ;; parse*-optional-pattern : stx DeclEnv table 1093 ;; -> (values Syntax HeadPattern IAttrs Stx Stx (Listof BindClause)) 1094 (define (parse*-optional-pattern stx decls optional-directive-table) 1095 (syntax-case stx () 1096 [(_ p . options) 1097 (let* ([head (parse-head-pattern #'p decls)] 1098 [chunks 1099 (parse-keyword-options/eol #'options optional-directive-table 1100 #:no-duplicates? #t 1101 #:context stx)] 1102 [too-many-msg 1103 (options-select-value chunks '#:too-many #:default #'#f)] 1104 [name 1105 (options-select-value chunks '#:name #:default #'#f)] 1106 [defaults 1107 (options-select-value chunks '#:defaults #:default '())] 1108 [pattern-iattrs (pattern-attrs head)] 1109 [defaults-iattrs 1110 (append-iattrs (map pattern-attrs defaults))] 1111 [all-iattrs 1112 (union-iattrs (list pattern-iattrs defaults-iattrs))]) 1113 (when (eq? (stxclass-lookup-config) 'yes) 1114 ;; Only check that attrs in defaults clause agree with attrs 1115 ;; in pattern when attrs in pattern are known to be complete. 1116 (check-iattrs-subset defaults-iattrs pattern-iattrs stx)) 1117 (values #'p head all-iattrs name too-many-msg defaults))])) 1118 1119 ;; -- EH patterns 1120 ;; Only parse the rep-constraint part; don't parse the head pattern within. 1121 ;; (To support eh-alternative-sets.) 1122 1123 ;; parse*-ehpat/optional : stx DeclEnv -> (list EllipsisHeadPattern stx) 1124 (define (parse*-ehpat/optional stx decls) 1125 (define-values (head-stx head iattrs name too-many-msg defaults) 1126 (parse*-optional-pattern stx decls eh-optional-directive-table)) 1127 (list (create-ehpat head (make rep:optional name too-many-msg defaults) head-stx) 1128 head-stx)) 1129 1130 ;; parse*-ehpat/once : stx DeclEnv -> (list EllipsisHeadPattern stx) 1131 (define (parse*-ehpat/once stx decls) 1132 (syntax-case stx () 1133 [(_ p . options) 1134 (let* ([head (parse-head-pattern #'p decls)] 1135 [chunks 1136 (parse-keyword-options/eol #'options 1137 (list (list '#:too-few check-expression) 1138 (list '#:too-many check-expression) 1139 (list '#:name check-expression)) 1140 #:context stx)] 1141 [too-few-msg 1142 (options-select-value chunks '#:too-few #:default #'#f)] 1143 [too-many-msg 1144 (options-select-value chunks '#:too-many #:default #'#f)] 1145 [name 1146 (options-select-value chunks '#:name #:default #'#f)]) 1147 (list (create-ehpat head (make rep:once name too-few-msg too-many-msg) #'p) 1148 #'p))])) 1149 1150 ;; parse*-ehpat/bounds : stx DeclEnv -> (list EllipsisHeadPattern stx) 1151 (define (parse*-ehpat/bounds stx decls) 1152 (syntax-case stx () 1153 [(_ p min max . options) 1154 (let () 1155 (define head (parse-head-pattern #'p decls)) 1156 (define minN (syntax-e #'min)) 1157 (define maxN (syntax-e #'max)) 1158 (unless (exact-nonnegative-integer? minN) 1159 (wrong-syntax #'min 1160 "expected exact nonnegative integer")) 1161 (unless (or (exact-nonnegative-integer? maxN) (equal? maxN +inf.0)) 1162 (wrong-syntax #'max 1163 "expected exact nonnegative integer or +inf.0")) 1164 (when (> minN maxN) 1165 (wrong-syntax stx "minimum larger than maximum repetition constraint")) 1166 (let* ([chunks (parse-keyword-options/eol 1167 #'options 1168 (list (list '#:too-few check-expression) 1169 (list '#:too-many check-expression) 1170 (list '#:name check-expression)) 1171 #:context stx)] 1172 [too-few-msg 1173 (options-select-value chunks '#:too-few #:default #'#f)] 1174 [too-many-msg 1175 (options-select-value chunks '#:too-many #:default #'#f)] 1176 [name 1177 (options-select-value chunks '#:name #:default #'#f)]) 1178 (list (create-ehpat head 1179 (make rep:bounds #'min #'max 1180 name too-few-msg too-many-msg) 1181 #'p) 1182 #'p)))])) 1183 1184 1185 ;; ============================================================ 1186 ;; Fixup pass (also does simplify-pattern) 1187 1188 (define (fixup-rhs the-rhs head? expected-attrs) 1189 (match the-rhs 1190 [(rhs attrs tr? desc vs defs commit? delimit-cut?) 1191 (define vs* (for/list ([v (in-list vs)]) (fixup-variant v head? expected-attrs))) 1192 (rhs attrs tr? desc vs* defs commit? delimit-cut?)])) 1193 1194 (define (fixup-variant v head? expected-attrs) 1195 (match v 1196 [(variant stx sattrs p defs) 1197 (parameterize ((current-syntax-context stx)) 1198 (define p1 1199 (parameterize ((stxclass-lookup-config 'yes)) 1200 (fixup-pattern p head?))) 1201 ;; (eprintf "~v\n===>\n~v\n\n" p p1) 1202 (unless (if head? (wf-H? p1) (wf-S? p1)) 1203 (error 'fixup-variant "result is not well-formed")) 1204 (define p* (simplify-pattern p1)) 1205 ;; (eprintf "=2=>\n~v\n\n" p*) 1206 ;; Called just for error-reporting 1207 (reorder-iattrs expected-attrs (pattern-attrs p*)) 1208 (variant stx sattrs p* defs))])) 1209 1210 (define (fixup-pattern p0 head?) 1211 (define (S p) (fixup p #f)) 1212 (define (S* p) (fixup p #t)) 1213 (define (A/S p) (if (action-pattern? p) (A p) (S p))) 1214 (define (A/H p) (if (action-pattern? p) (A p) (H p))) 1215 1216 (define (A p) 1217 (match p 1218 ;; [(action:cut) 1219 ;; (action:cut)] 1220 ;; [(action:fail when msg) 1221 ;; (action:fail when msg)] 1222 ;; [(action:bind attr expr) 1223 ;; (action:bind attr expr)] 1224 [(action:and ps) 1225 (action:and (map A ps))] 1226 [(action:parse sp expr) 1227 (action:parse (S sp) expr)] 1228 ;; [(action:do stmts) 1229 ;; (action:do stmts)] 1230 ;; [(action:undo stmts) 1231 ;; (action:undo stmts)] 1232 [(action:ord sp group index) 1233 (create-ord-pattern (A sp) group index)] 1234 [(action:post sp) 1235 (create-post-pattern (A sp))] 1236 ;; ---- 1237 ;; Default: no sub-patterns, just return 1238 [p p])) 1239 (define (EH p) 1240 (match p 1241 [(ehpat iattrs hp repc check-null?) 1242 (create-ehpat (H hp) repc #f)])) 1243 1244 (define (fixup p allow-head?) 1245 (define (I p) (fixup p allow-head?)) 1246 (match p 1247 [(pat:fixup stx bind varname scname argu pfx role parser*) 1248 (parse-stxclass-use stx allow-head? varname scname argu pfx role parser*)] 1249 ;; ---- 1250 ;; [(pat:any) 1251 ;; (pat:any)] 1252 ;; [(pat:svar name) 1253 ;; (pat:svar name)] 1254 ;; [(pat:var/p name parser argu nested-attrs role opts) 1255 ;; (pat:var/p name parser argu nested-attrs role opts)] 1256 ;; [(pat:integrated name predicate desc role) 1257 ;; (pat:integrated name predicate desc role)] 1258 ;; [(pat:reflect obj argu attr-decls name nested-attrs) 1259 ;; (pat:reflect obj argu attr-decls name nested-attrs)] 1260 ;; [(pat:datum d) 1261 ;; (pat:datum d)] 1262 ;; [(pat:literal id input-phase lit-phase) 1263 ;; (pat:literal id input-phase lit-phase)] 1264 [(pat:vector sp) 1265 (pat:vector (S sp))] 1266 [(pat:box sp) 1267 (pat:box (S sp))] 1268 [(pat:pstruct key sp) 1269 (pat:pstruct key (S sp))] 1270 [(pat:not sp) 1271 (parameterize ((cut-allowed? #f)) 1272 (pat:not (S sp)))] 1273 [(pat:dots headps tailp) 1274 (pat:dots (map EH headps) (S tailp))] 1275 [(pat:head headp tailp) 1276 (pat:head (H headp) (S tailp))] 1277 ;; --- The following patterns may change if a subpattern switches to head pattern ---- 1278 [(pat:pair headp tailp) (error 'fixup-pattern "internal error: pat:pair in stage 0")] 1279 [(pat:action a sp) 1280 (let ([a (A a)] [sp (I sp)]) 1281 (if (head-pattern? sp) (hpat:action a sp) (pat:action a sp)))] 1282 [(pat:describe sp desc tr? role) 1283 (let ([sp (I sp)]) 1284 (if (head-pattern? sp) (hpat:describe sp desc tr? role) (pat:describe sp desc tr? role)))] 1285 [(pat:andu ps) 1286 (let ([ps (map A/S ps)]) 1287 (pat:andu ps))] 1288 [(pat:and/fixup stx ps) 1289 (let ([ps (for/list ([p (in-list ps)]) 1290 (cond [(action-pattern? p) (A p)] 1291 [(head-pattern? p) (H p)] 1292 [else (I p)]))]) 1293 (parse-pat:and/k stx ps))] 1294 [(pat:or _ ps _) 1295 (let ([ps (map I ps)]) 1296 (if (ormap head-pattern? ps) (create-hpat:or ps) (create-pat:or ps)))] 1297 [(pat:delimit sp) 1298 (let ([sp (parameterize ((cut-allowed? #t)) (I sp))]) 1299 (if (head-pattern? sp) (hpat:delimit sp) (pat:delimit sp)))] 1300 [(pat:commit sp) 1301 (let ([sp (parameterize ((cut-allowed? #t)) (I sp))]) 1302 (if (head-pattern? sp) (hpat:commit sp) (pat:commit sp)))] 1303 [(pat:ord sp group index) 1304 (create-ord-pattern (I sp) group index)] 1305 [(pat:post sp) 1306 (create-post-pattern (I sp))] 1307 ;; ---- 1308 ;; Default: no sub-patterns, just return 1309 [p p])) 1310 1311 (define (H p) 1312 (match p 1313 [(hpat:single sp) 1314 (let ([sp (fixup sp #t)]) 1315 (if (head-pattern? sp) sp (hpat:single sp)))] 1316 ;; [(hpat:var/p name parser argu nested-attrs role scopts) 1317 ;; (hpat:var/p name parser argu nested-attrs role scopts)] 1318 ;; [(hpat:reflect obj argu attr-decls name nested-attrs) 1319 ;; (hpat:reflect obj argu attr-decls name nested-attrs)] 1320 [(hpat:seq lp) 1321 (hpat:seq (S lp))] 1322 [(hpat:action a hp) 1323 (hpat:action (A a) (H hp))] 1324 [(hpat:describe hp desc tr? role) 1325 (hpat:describe (H hp) desc tr? role)] 1326 [(hpat:andu ps) 1327 (let ([ps (map A/H ps)]) 1328 (hpat:andu ps))] 1329 [(hpat:or _ ps _) 1330 (create-hpat:or (map H ps))] 1331 [(hpat:delimit hp) 1332 (parameterize ((cut-allowed? #t)) 1333 (hpat:delimit (H hp)))] 1334 [(hpat:commit hp) 1335 (parameterize ((cut-allowed? #t)) 1336 (hpat:commit (H hp)))] 1337 [(hpat:ord hp group index) 1338 (create-ord-pattern (H hp) group index)] 1339 [(hpat:post hp) 1340 (create-post-pattern (H hp))] 1341 [(hpat:peek hp) 1342 (hpat:peek (H hp))] 1343 [(hpat:peek-not hp) 1344 (hpat:peek-not (H hp))] 1345 [(? pattern? sp) 1346 (S* sp)] 1347 ;; ---- 1348 ;; Default: no sub-patterns, just return 1349 [p p])) 1350 1351 (if head? (H p0) (S p0))) 1352 1353 1354 ;; ============================================================ 1355 ;; Simplify pattern 1356 1357 ;;(begin (require racket/pretty) (pretty-print-columns 160)) 1358 1359 ;; simplify-pattern : *Pattern -> *Pattern 1360 (define (simplify-pattern p0) 1361 ;;(eprintf "-- simplify --\n") 1362 ;;(eprintf "~a\n" (pretty-format p0)) 1363 (define p1 (simplify:specialize-pairs p0)) 1364 ;; (eprintf "=1=>\n~a\n" (pretty-format p1)) 1365 (define p2 (simplify:normalize-and p1)) 1366 ;;(eprintf "=2=>\n~a\n" (pretty-format p2)) 1367 (define p3 (simplify:order-and p2)) 1368 ;;(eprintf "=3=>\n~a\n" (pretty-format p3)) 1369 (define p4 (simplify:add-seq-end p3)) 1370 ;;(eprintf "=4=>\n~a\n" (pretty-format p4)) 1371 p4) 1372 1373 ;; ---------------------------------------- 1374 ;; Add pair patterns 1375 1376 (define (simplify:specialize-pairs p) 1377 (define (for-pattern p) 1378 (match p 1379 [(pat:head (hpat:single headp) tailp) 1380 (pat:pair headp tailp)] 1381 [(pat:head (hpat:seq lp) tailp) 1382 (list-pattern-replace-end lp tailp)] 1383 [_ p])) 1384 (pattern-transform p for-pattern)) 1385 1386 ;; list-pattern-replace-end : ListPattern {L,S}Pattern -> {L,S}Pattern 1387 (define (list-pattern-replace-end lp endp) 1388 (let loop ([lp lp]) 1389 (match lp 1390 [(pat:datum '()) endp] 1391 [(pat:seq-end) endp] 1392 [(pat:action ap sp) (pat:action ap (loop sp))] 1393 [(pat:head hp tp) (pat:head hp (loop tp))] 1394 [(pat:dots hs tp) (pat:dots hs (loop tp))] 1395 [(pat:ord sp group index) 1396 ;; This is awkward, but it is needed to pop the ORD progress frame on success. 1397 (define sp* (list-pattern-replace-end sp (pat:seq-end))) 1398 (pat:head (hpat:ord (hpat:seq sp*) group index) endp)] 1399 [(pat:pair hp tp) (pat:pair hp (loop tp))]))) 1400 1401 ;; ---------------------------------------- 1402 ;; Normalize *:andu patterns, drop useless actions 1403 1404 (define (simplify:normalize-and p) 1405 (define (pattern->list p) 1406 (match p 1407 [(pat:any) null] 1408 [(pat:action ap sp) (append (pattern->list ap) (pattern->list sp))] 1409 [(pat:andu ps) (apply append (map pattern->list ps))] 1410 [(hpat:action ap hp) (append (pattern->list ap) (pattern->list hp))] 1411 [(hpat:andu ps) (apply append (map pattern->list ps))] 1412 [(action:and as) (apply append (map pattern->list as))] 1413 [(action:do '()) null] 1414 [(action:undo '()) null] 1415 [_ (list p)])) 1416 (define (for-pattern p) 1417 (match p 1418 [(pat:action ap sp) 1419 (pat:andu (append (pattern->list ap) (pattern->list sp)))] 1420 [(pat:andu ps) 1421 (pat:andu (apply append (map pattern->list ps)))] 1422 [(hpat:action ap hp) 1423 (hpat:andu (append (pattern->list ap) (pattern->list hp)))] 1424 [(hpat:andu ps) 1425 (hpat:andu (apply append (map pattern->list ps)))] 1426 [(action:post ap) 1427 (match (pattern->list ap) 1428 ['() (action:and '())] 1429 [(list ap*) (action:post ap*)] 1430 [as* (action:post (action:and as*))])] 1431 [_ p])) 1432 (pattern-transform p for-pattern)) 1433 1434 ;; ---------------------------------------- 1435 ;; Add *:ord and translate back to *:and, *:action 1436 1437 (define (simplify:order-and p) 1438 (define (A->S p) (if (action-pattern? p) (pat:action p (pat:any)) p)) 1439 (define (for-pattern p) 1440 (match p 1441 [(pat:andu ps0) 1442 (define ord-ps (ord-and-patterns ps0 (gensym*))) 1443 (define-values (as ps) (split-pred action-pattern? ord-ps)) 1444 (define sp* (list->single-pattern (map A->S ps))) 1445 (add-action-patterns as sp*)] 1446 [(hpat:andu ps0) 1447 (define ord-ps (ord-and-patterns ps0 (gensym*))) 1448 (define-values (as ps) (split-pred action-pattern? ord-ps)) 1449 (match ps 1450 ['() (error 'simplify:order-ands "internal error: no head pattern")] 1451 [(list hp) (add-action-patterns as hp)] 1452 [(cons hp1 hps) 1453 (define sp* (list->single-pattern (map action/head-pattern->list-pattern hps))) 1454 (define hp* (hpat:and hp1 sp*)) 1455 (add-action-patterns as hp*)])] 1456 [_ p])) 1457 (pattern-transform p for-pattern)) 1458 1459 ;; add-action-patterns : (Listof ActionPattern) *Pattern -> *Pattern 1460 (define (add-action-patterns as p) 1461 (if (pair? as) 1462 (let ([ap (list->action-pattern as)]) 1463 (cond [(single-pattern? p) (pat:action ap p)] 1464 [(head-pattern? p) (hpat:action ap p)])) 1465 p)) 1466 1467 ;; list->action-pattern : (Listof ActionPattern) -> ActionPattern 1468 (define (list->action-pattern as) 1469 (match as 1470 [(list ap) ap] 1471 [_ (action:and as)])) 1472 1473 ;; list->single-pattern : (Listof SinglePattern) -> SinglePattern 1474 (define (list->single-pattern ps) 1475 (match ps 1476 ['() (pat:any)] 1477 [(list p) p] 1478 [_ (pat:and ps)])) 1479 1480 (define (split-pred pred? xs) 1481 (let loop ([xs xs] [acc null]) 1482 (if (and (pair? xs) (pred? (car xs))) 1483 (loop (cdr xs) (cons (car xs) acc)) 1484 (values (reverse acc) xs)))) 1485 1486 ;; ---------------------------------------- 1487 ;; Add pat:seq-end to end of list-patterns in seq 1488 1489 (define (simplify:add-seq-end p) 1490 (define (for-pattern p) 1491 (match p 1492 [(hpat:seq lp) 1493 (hpat:seq (list-pattern-replace-end lp (pat:seq-end)))] 1494 [_ p])) 1495 (pattern-transform p for-pattern)) 1496 1497 ;; ============================================================ 1498 ;; Parsing pattern directives 1499 1500 ;; parse-pattern-directives : stxs(PatternDirective) <kw-args> 1501 ;; -> stx DeclEnv (listof stx) (listof SideClause) 1502 (define (parse-pattern-directives stx 1503 #:allow-declare? allow-declare? 1504 #:decls decls 1505 #:context ctx) 1506 (parameterize ((current-syntax-context ctx)) 1507 (define-values (chunks rest) 1508 (parse-keyword-options stx pattern-directive-table #:context ctx)) 1509 (define-values (decls2 chunks2) 1510 (if allow-declare? 1511 (grab-decls chunks decls) 1512 (values decls chunks))) 1513 (define sides 1514 ;; NOTE: use *original* decls 1515 ;; because decls2 has #:declares for *above* pattern 1516 (parse-pattern-sides chunks2 decls)) 1517 (define-values (decls3 defs) 1518 (decls-create-defs decls2)) 1519 (values rest decls3 defs sides))) 1520 1521 ;; parse-pattern-sides : (listof chunk) DeclEnv -> (listof SideClause) 1522 ;; Invariant: decls contains only literals bindings 1523 (define (parse-pattern-sides chunks decls) 1524 (match chunks 1525 [(cons (list '#:declare declare-stx _ _) rest) 1526 (wrong-syntax declare-stx 1527 "#:declare can only appear immediately after pattern or #:with clause")] 1528 [(cons (list '#:role role-stx _) rest) 1529 (wrong-syntax role-stx "#:role can only appear immediately after #:declare clause")] 1530 [(cons (list '#:fail-when fw-stx when-expr msg-expr) rest) 1531 (cons (create-post-pattern (action:fail when-expr msg-expr)) 1532 (parse-pattern-sides rest decls))] 1533 [(cons (list '#:fail-unless fu-stx unless-expr msg-expr) rest) 1534 (cons (create-post-pattern (action:fail #`(not #,unless-expr) msg-expr)) 1535 (parse-pattern-sides rest decls))] 1536 [(cons (list '#:when w-stx unless-expr) rest) 1537 (cons (create-post-pattern (action:fail #`(not #,unless-expr) #'#f)) 1538 (parse-pattern-sides rest decls))] 1539 [(cons (list '#:with with-stx pattern expr) rest) 1540 (let-values ([(decls2 rest) (grab-decls rest decls)]) 1541 (let-values ([(decls2a defs) (decls-create-defs decls2)]) 1542 (list* (action:do defs) 1543 (create-post-pattern 1544 (action:parse (parse-whole-pattern pattern decls2a #:kind 'with) expr)) 1545 (parse-pattern-sides rest decls))))] 1546 [(cons (list '#:attr attr-stx a expr) rest) 1547 (cons (action:bind a expr) ;; no POST wrapper, cannot fail 1548 (parse-pattern-sides rest decls))] 1549 [(cons (list '#:post post-stx pattern) rest) 1550 (cons (create-post-pattern (parse-action-pattern pattern decls)) 1551 (parse-pattern-sides rest decls))] 1552 [(cons (list '#:and and-stx pattern) rest) 1553 (cons (parse-action-pattern pattern decls) ;; no POST wrapper 1554 (parse-pattern-sides rest decls))] 1555 [(cons (list '#:do do-stx stmts) rest) 1556 (cons (action:do stmts) 1557 (parse-pattern-sides rest decls))] 1558 [(cons (list '#:undo undo-stx stmts) rest) 1559 (cons (action:undo stmts) 1560 (parse-pattern-sides rest decls))] 1561 [(cons (list '#:cut cut-stx) rest) 1562 (cons (action:cut) 1563 (parse-pattern-sides rest decls))] 1564 ['() 1565 '()])) 1566 1567 ;; grab-decls : (listof chunk) DeclEnv 1568 ;; -> (values DeclEnv (listof chunk)) 1569 (define (grab-decls chunks decls0) 1570 (define (add-decl stx role-stx decls) 1571 (let ([role 1572 (and role-stx 1573 (syntax-case role-stx () 1574 [(#:role role) #'role]))]) 1575 (syntax-case stx () 1576 [(#:declare name sc) 1577 (identifier? #'sc) 1578 (add-decl* decls #'name #'sc (parse-argu null) role)] 1579 [(#:declare name (sc expr ...)) 1580 (identifier? #'sc) 1581 (add-decl* decls #'name #'sc (parse-argu (syntax->list #'(expr ...))) role)] 1582 [(#:declare name bad-sc) 1583 (wrong-syntax #'bad-sc 1584 "expected syntax class name (possibly with parameters)")]))) 1585 (define (add-decl* decls id sc-name argu role) 1586 (declenv-put-stxclass decls id sc-name argu role)) 1587 (define (loop chunks decls) 1588 (match chunks 1589 [(cons (cons '#:declare decl-stx) 1590 (cons (cons '#:role role-stx) rest)) 1591 (loop rest (add-decl decl-stx role-stx decls))] 1592 [(cons (cons '#:declare decl-stx) rest) 1593 (loop rest (add-decl decl-stx #f decls))] 1594 [_ (values decls chunks)])) 1595 (loop chunks decls0)) 1596 1597 1598 ;; ============================================================ 1599 ;; Arguments and Arities 1600 1601 ;; parse-argu : (listof stx) -> Arguments 1602 (define (parse-argu args #:context [ctx (current-syntax-context)]) 1603 (parameterize ((current-syntax-context ctx)) 1604 (define (loop args rpargs rkws rkwargs) 1605 (cond [(null? args) 1606 (arguments (reverse rpargs) (reverse rkws) (reverse rkwargs))] 1607 [(keyword? (syntax-e (car args))) 1608 (let ([kw (syntax-e (car args))] 1609 [rest (cdr args)]) 1610 (cond [(memq kw rkws) 1611 (wrong-syntax (car args) "duplicate keyword")] 1612 [(null? rest) 1613 (wrong-syntax (car args) 1614 "missing argument expression after keyword")] 1615 #| Overzealous, perhaps? 1616 [(keyword? (syntax-e (car rest))) 1617 (wrong-syntax (car rest) "expected expression following keyword")] 1618 |# 1619 [else 1620 (loop (cdr rest) rpargs (cons kw rkws) (cons (car rest) rkwargs))]))] 1621 [else 1622 (loop (cdr args) (cons (car args) rpargs) rkws rkwargs)])) 1623 (loop args null null null))) 1624 1625 ;; parse-kw-formals : stx -> Arity 1626 (define (parse-kw-formals formals #:context [ctx (current-syntax-context)]) 1627 (parameterize ((current-syntax-context ctx)) 1628 (define id-h (make-bound-id-table)) 1629 (define kw-h (make-hasheq)) ;; keyword => 'mandatory or 'optional 1630 (define pos 0) 1631 (define opts 0) 1632 (define (add-id! id) 1633 (when (bound-id-table-ref id-h id #f) 1634 (wrong-syntax id "duplicate formal parameter" )) 1635 (bound-id-table-set! id-h id #t)) 1636 (define (loop formals) 1637 (cond [(and (stx-pair? formals) (keyword? (syntax-e (stx-car formals)))) 1638 (let* ([kw-stx (stx-car formals)] 1639 [kw (syntax-e kw-stx)] 1640 [rest (stx-cdr formals)]) 1641 (cond [(hash-ref kw-h kw #f) 1642 (wrong-syntax kw-stx "duplicate keyword")] 1643 [(stx-null? rest) 1644 (wrong-syntax kw-stx "missing formal parameter after keyword")] 1645 [else 1646 (let-values ([(formal opt?) (parse-formal (stx-car rest))]) 1647 (add-id! formal) 1648 (hash-set! kw-h kw (if opt? 'optional 'mandatory))) 1649 (loop (stx-cdr rest))]))] 1650 [(stx-pair? formals) 1651 (let-values ([(formal opt?) (parse-formal (stx-car formals))]) 1652 (when (and (positive? opts) (not opt?)) 1653 (wrong-syntax (stx-car formals) 1654 "mandatory argument may not follow optional argument")) 1655 (add-id! formal) 1656 (set! pos (add1 pos)) 1657 (when opt? (set! opts (add1 opts))) 1658 (loop (stx-cdr formals)))] 1659 [(identifier? formals) 1660 (add-id! formals) 1661 (finish #t)] 1662 [(stx-null? formals) 1663 (finish #f)] 1664 [else 1665 (wrong-syntax formals "bad argument sequence")])) 1666 (define (finish has-rest?) 1667 (arity (- pos opts) 1668 (if has-rest? +inf.0 pos) 1669 (sort (for/list ([(k v) (in-hash kw-h)] 1670 #:when (eq? v 'mandatory)) 1671 k) 1672 keyword<?) 1673 (sort (hash-map kw-h (lambda (k v) k)) 1674 keyword<?))) 1675 (loop formals))) 1676 1677 ;; parse-formal : stx -> (values id bool) 1678 (define (parse-formal formal) 1679 (syntax-case formal () 1680 [param 1681 (identifier? #'param) 1682 (values #'param #f)] 1683 [(param default) 1684 (identifier? #'param) 1685 (values #'param #t)] 1686 [_ 1687 (wrong-syntax formal 1688 "expected formal parameter with optional default")])) 1689 1690 ;; ============================================================ 1691 ;; Keyword Options & Checkers 1692 1693 ;; check-attr-arity-list : stx stx -> (listof SAttr) 1694 (define (check-attr-arity-list stx ctx) 1695 (unless (stx-list? stx) 1696 (raise-syntax-error #f "expected list of attribute declarations" ctx stx)) 1697 (let ([iattrs 1698 (for/list ([x (in-list (stx->list stx))]) 1699 (check-attr-arity x ctx))]) 1700 (iattrs->sattrs (append-iattrs (map list iattrs))))) 1701 1702 ;; check-attr-arity : stx stx -> IAttr 1703 (define (check-attr-arity stx ctx) 1704 (syntax-case stx () 1705 [attr 1706 (identifier? #'attr) 1707 (make-attr #'attr 0 #f)] 1708 [(attr depth) 1709 (begin (unless (identifier? #'attr) 1710 (raise-syntax-error #f "expected attribute name" ctx #'attr)) 1711 (unless (exact-nonnegative-integer? (syntax-e #'depth)) 1712 (raise-syntax-error #f "expected depth (nonnegative integer)" ctx #'depth)) 1713 (make-attr #'attr (syntax-e #'depth) #f))] 1714 [_ 1715 (raise-syntax-error #f "expected attribute name with optional depth declaration" ctx stx)])) 1716 1717 ;; check-literals-list : stx stx -> (listof den:lit) 1718 ;; - txlifts defs of phase expressions 1719 ;; - txlifts checks that literals are bound 1720 (define (check-literals-list stx ctx) 1721 (unless (stx-list? stx) 1722 (raise-syntax-error #f "expected literals list" ctx stx)) 1723 (for/list ([x (in-list (stx->list stx))]) 1724 (check-literal-entry x ctx))) 1725 1726 ;; check-literal-entry : stx stx -> den:lit 1727 (define (check-literal-entry stx ctx) 1728 (define (go internal external phase) 1729 (txlift #`(check-literal #,external #,phase #,ctx)) 1730 (let ([external (syntax-property external 'literal (gensym))]) 1731 (make den:lit internal external phase phase))) 1732 (syntax-case stx () 1733 [(internal external #:phase phase) 1734 (and (identifier? #'internal) (identifier? #'external)) 1735 (go #'internal #'external (txlift #'phase))] 1736 [(internal external) 1737 (and (identifier? #'internal) (identifier? #'external)) 1738 (go #'internal #'external #'(syntax-local-phase-level))] 1739 [id 1740 (identifier? #'id) 1741 (go #'id #'id #'(syntax-local-phase-level))] 1742 [_ 1743 (raise-syntax-error #f "expected literal entry" ctx stx)])) 1744 1745 ;; check-datum-literals-list : stx stx -> (listof den:datum-lit) 1746 (define (check-datum-literals-list stx ctx) 1747 (unless (stx-list? stx) 1748 (raise-syntax-error #f "expected datum-literals list" ctx stx)) 1749 (for/list ([x (in-list (stx->list stx))]) 1750 (check-datum-literal-entry x ctx))) 1751 1752 ;; check-datum-literal-entry : stx stx -> den:datum-lit 1753 (define (check-datum-literal-entry stx ctx) 1754 (syntax-case stx () 1755 [(internal external) 1756 (and (identifier? #'internal) (identifier? #'external)) 1757 (make den:datum-lit #'internal (syntax-e #'external))] 1758 [id 1759 (identifier? #'id) 1760 (make den:datum-lit #'id (syntax-e #'id))] 1761 [_ 1762 (raise-syntax-error #f "expected datum-literal entry" ctx stx)])) 1763 1764 ;; Literal sets - Import 1765 1766 ;; check-literal-sets-list : stx stx -> (listof (list id literalset stx stx)) 1767 (define (check-literal-sets-list stx ctx) 1768 (unless (stx-list? stx) 1769 (raise-syntax-error #f "expected literal-set list" ctx stx)) 1770 (for/list ([x (in-list (stx->list stx))]) 1771 (check-literal-set-entry x ctx))) 1772 1773 ;; check-literal-set-entry : stx stx -> (list id literalset stx stx) 1774 (define (check-literal-set-entry stx ctx) 1775 (define (elaborate litset-id lctx phase) 1776 (let ([litset (syntax-local-value/record litset-id literalset?)]) 1777 (unless litset 1778 (raise-syntax-error #f "expected identifier defined as a literal-set" 1779 ctx litset-id)) 1780 (list litset-id litset lctx phase))) 1781 (syntax-case stx () 1782 [(litset . more) 1783 (and (identifier? #'litset)) 1784 (let* ([chunks (parse-keyword-options/eol #'more litset-directive-table 1785 #:no-duplicates? #t 1786 #:context ctx)] 1787 [lctx (options-select-value chunks '#:at #:default #'litset)] 1788 [phase (options-select-value chunks '#:phase #:default #f)]) 1789 (elaborate #'litset lctx (if phase (txlift phase) #'(syntax-local-phase-level))))] 1790 [litset 1791 (identifier? #'litset) 1792 (elaborate #'litset #'litset #'(syntax-local-phase-level))] 1793 [_ 1794 (raise-syntax-error #f "expected literal-set entry" ctx stx)])) 1795 1796 ;; Conventions 1797 1798 ;; returns (listof (cons Conventions (listof syntax))) 1799 (define (check-conventions-list stx ctx) 1800 (unless (stx-list? stx) 1801 (raise-syntax-error #f "expected conventions list" ctx stx)) 1802 (for/list ([x (in-list (stx->list stx))]) 1803 (check-conventions x ctx))) 1804 1805 ;; returns (cons Conventions (listof syntax)) 1806 (define (check-conventions stx ctx) 1807 (define (elaborate conventions-id argu) 1808 (let ([cs (syntax-local-value/record conventions-id conventions?)]) 1809 (unless cs 1810 (raise-syntax-error #f "expected identifier defined as a conventions" 1811 ctx conventions-id)) 1812 (cons cs argu))) 1813 (syntax-case stx () 1814 [(conventions arg ...) 1815 (identifier? #'conventions) 1816 (elaborate #'conventions (parse-argu (syntax->list #'(arg ...))))] 1817 [conventions 1818 (identifier? #'conventions) 1819 (elaborate #'conventions no-arguments)] 1820 [_ 1821 (raise-syntax-error "expected conventions entry" ctx stx)])) 1822 1823 ;; returns (listof (list regexp DeclEntry)) 1824 (define (check-conventions-rules stx ctx) 1825 (unless (stx-list? stx) 1826 (raise-syntax-error #f "expected convention rule list" ctx stx)) 1827 (for/list ([x (in-list (stx->list stx))]) 1828 (check-conventions-rule x ctx))) 1829 1830 ;; returns (list regexp DeclEntry) 1831 (define (check-conventions-rule stx ctx) 1832 (define (check-conventions-pattern x blame) 1833 (cond [(symbol? x) 1834 (regexp (string-append "^" (regexp-quote (symbol->string x)) "$"))] 1835 [(regexp? x) x] 1836 [else 1837 (raise-syntax-error #f "expected identifier convention pattern" 1838 ctx blame)])) 1839 (define (check-sc-expr x rx) 1840 (let ([x (check-stxclass-application x ctx)]) 1841 (make den:class rx (car x) (cdr x)))) 1842 (syntax-case stx () 1843 [(rx sc) 1844 (let ([name-pattern (check-conventions-pattern (syntax-e #'rx) #'rx)]) 1845 (list name-pattern (check-sc-expr #'sc name-pattern)))])) 1846 1847 (define (check-stxclass-header stx ctx) 1848 (syntax-case stx () 1849 [name 1850 (identifier? #'name) 1851 (list #'name #'() no-arity)] 1852 [(name . formals) 1853 (identifier? #'name) 1854 (list #'name #'formals (parse-kw-formals #'formals #:context ctx))] 1855 [_ (raise-syntax-error #f "expected syntax class header" stx ctx)])) 1856 1857 (define (check-stxclass-application stx ctx) 1858 ;; Doesn't check "operator" is actually a stxclass 1859 (syntax-case stx () 1860 [op 1861 (identifier? #'op) 1862 (cons #'op no-arguments)] 1863 [(op arg ...) 1864 (identifier? #'op) 1865 (cons #'op (parse-argu (syntax->list #'(arg ...))))] 1866 [_ (raise-syntax-error #f "expected syntax class use" ctx stx)])) 1867 1868 ;; bind clauses 1869 (define (check-bind-clause-list stx ctx) 1870 (unless (stx-list? stx) 1871 (raise-syntax-error #f "expected sequence of bind clauses" ctx stx)) 1872 (for/list ([clause (in-list (stx->list stx))]) 1873 (check-bind-clause clause ctx))) 1874 1875 (define (check-bind-clause clause ctx) 1876 (syntax-case clause () 1877 [(attr-decl expr) 1878 (action:bind (check-attr-arity #'attr-decl ctx) #'expr)] 1879 [_ (raise-syntax-error #f "expected bind clause" ctx clause)])) 1880 1881 (define (check-stmt-list stx ctx) 1882 (syntax-case stx () 1883 [(e ...) 1884 (syntax->list #'(e ...))] 1885 [_ 1886 (raise-syntax-error #f "expected list of expressions and definitions" ctx stx)])) 1887 1888 1889 ;; ============================================================ 1890 ;; Directive tables 1891 1892 ;; common-parse-directive-table 1893 (define common-parse-directive-table 1894 (list (list '#:disable-colon-notation) 1895 (list '#:literals check-literals-list) 1896 (list '#:datum-literals check-datum-literals-list) 1897 (list '#:literal-sets check-literal-sets-list) 1898 (list '#:conventions check-conventions-list) 1899 (list '#:local-conventions check-conventions-rules))) 1900 1901 ;; parse-directive-table 1902 (define parse-directive-table 1903 (list* (list '#:context check-expression) 1904 (list '#:track-literals) 1905 common-parse-directive-table)) 1906 1907 ;; rhs-directive-table 1908 (define rhs-directive-table 1909 (list* (list '#:description check-expression) 1910 (list '#:transparent) 1911 (list '#:opaque) 1912 (list '#:attributes check-attr-arity-list) 1913 (list '#:auto-nested-attributes) 1914 (list '#:commit) 1915 (list '#:no-delimit-cut) 1916 common-parse-directive-table)) 1917 1918 ;; pattern-directive-table 1919 (define pattern-directive-table 1920 (list (list '#:declare check-identifier check-expression) 1921 (list '#:role check-expression) ;; attached to preceding #:declare 1922 (list '#:fail-when check-expression check-expression) 1923 (list '#:fail-unless check-expression check-expression) 1924 (list '#:when check-expression) 1925 (list '#:with check-expression check-expression) 1926 (list '#:attr check-attr-arity check-expression) 1927 (list '#:and check-expression) 1928 (list '#:post check-expression) 1929 (list '#:do check-stmt-list) 1930 (list '#:undo check-stmt-list) 1931 (list '#:cut))) 1932 1933 ;; fail-directive-table 1934 (define fail-directive-table 1935 (list (list '#:when check-expression) 1936 (list '#:unless check-expression))) 1937 1938 ;; describe-option-table 1939 (define describe-option-table 1940 (list (list '#:opaque) 1941 (list '#:role check-expression))) 1942 1943 ;; eh-optional-directive-table 1944 (define eh-optional-directive-table 1945 (list (list '#:too-many check-expression) 1946 (list '#:name check-expression) 1947 (list '#:defaults check-bind-clause-list))) 1948 1949 ;; h-optional-directive-table 1950 (define h-optional-directive-table 1951 (list (list '#:defaults check-bind-clause-list))) 1952 1953 ;; phase-directive-table 1954 (define phase-directive-table 1955 (list (list '#:phase check-expression))) 1956 1957 ;; litset-directive-table 1958 (define litset-directive-table 1959 (cons (list '#:at (lambda (stx ctx) stx)) 1960 phase-directive-table)) 1961 1962 ;; var-pattern-directive-table 1963 (define var-pattern-directive-table 1964 (list (list '#:attr-name-separator check-stx-string) 1965 (list '#:role check-expression)))