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