scope-operations.scrbl (5492B)
1 #lang scribble/manual 2 @require[@for-label[scope-operations 3 racket/base]] 4 5 @title{scope-operations} 6 @author[@author+email["Suzanne Soy" "racket@suzanne.soy"]] 7 8 @defmodule[scope-operations] 9 10 @defproc[(scopes/c [v any/c]) boolean?]{ 11 Contract which recognizes a set of scopes, represented as an introducer 12 function. Equivalent to: 13 @racketblock[(->* (syntax?) 14 ([or/c 'add 'remove 'flip]) 15 syntax?)] 16 } 17 18 @defproc*[(((→scopes [stx syntax?]) scopes/c) 19 ((->scopes [stx syntax?]) scopes/c))]{ 20 Extracts the scopes present on the topmost syntax object of @racket[stx]. 21 This is equivalent to: 22 23 @racket[ 24 (make-syntax-delta-introducer (datum->syntax stx 'stx) 25 (datum->syntax #f 'zero))] 26 27 Unlike a @racket[make-syntax-delta-introducer], this procedure does not 28 expect a second argument (always creating an introducer for all the scopes 29 present on @racket[stx]), and works on syntax objects which are not 30 identifiers.} 31 32 @defproc*[(((→scopes* [stx (or/c syntax? scopes/c)]) scopes/c) 33 ((->scopes* [stx (or/c syntax? scopes/c)]) scopes/c))]{ 34 Lenient version of @racket[→scopes], which acts as a no-op when passed a set 35 of scopes, instead of raising an error.} 36 37 @defthing[empty-scopes]{ 38 The empty set of scopes, as produced by: 39 @racketblock[(→scopes (datum->syntax #f 'zero))] 40 } 41 42 @defthing[empty-scopes-syntax]{ 43 A syntax object with an empty set of scopes, as produced by: 44 @racketblock[(datum->syntax #f 'zero)] 45 } 46 47 @defproc[(scopes-add [sc1 (or/c syntax? scopes/c)] 48 [sc2 (or/c syntax? scopes/c)]) 49 scopes/c]{Set union of the given sets of scopes.} 50 51 @defproc[(scopes-remove [sc1 (or/c syntax? scopes/c)] 52 [sc2 (or/c syntax? scopes/c)]) 53 scopes/c]{Set difference of the given sets of scopes. 54 55 The resulting set of scopes contains all the scopes present in @racket[sc1] 56 which are not present in @racket[sc2].} 57 58 @defproc*[(((scopes-flip [sc1 (or/c syntax? scopes/c)] 59 [sc2 (or/c syntax? scopes/c)]) 60 scopes/c) 61 ((scopes-symmetric-difference [sc1 (or/c syntax? scopes/c)] 62 [sc2 (or/c syntax? scopes/c)]) 63 scopes/c))]{ 64 65 Flips the scopes in @racket[sc2] on the @racket[sc1] set of scopes. 66 67 The resulting set of scopes contains all the scopes present in @racket[sc1] 68 which are not present in @racket[sc2], as well as the scopes present in 69 @racket[sc2] which were not present in @racket[sc1]. 70 71 Flipping the @racket[sc2] scopes on @racket[sc1] has the same effect as 72 computing the symmetric difference of the two sets of scopes.} 73 74 @defproc[(scopes-intersect [sc1 (or/c syntax? scopes/c)] 75 [sc2 (or/c syntax? scopes/c)]) 76 scopes/c]{Set intersection of the given sets of scopes.} 77 78 79 @defproc[(single-scope? [sc (or/c syntax? scopes/c)]) boolean?]{ 80 Predicate which returns @racket[#true] iff the given set of scopes contains 81 only a single scope.} 82 83 @defproc[(zero-scopes? [sc (or/c syntax? scopes/c)]) boolean?]{ 84 Predicate which returns @racket[#true] iff the given set of scopes contains 85 no scopes (e.g. because sc has been created with 86 @racket[(datum->syntax #f 'id)]).} 87 88 @defproc[(scopes-equal? [sc1 (or/c syntax? scopes/c)] 89 [sc2 (or/c syntax? scopes/c)]) boolean?]{ 90 Predicate which returns @racket[#true] iff the two given sets of scopes contain 91 the same scopes. It is a generalised form of @racket[bound-identifier=?], which 92 also works for scopes represented as functions like the ones created by 93 @racket[make-syntax-introducer] and @racket[make-syntax-delta-introducer].} 94 95 @defproc[(scope-kind [sc (and/c (or/c syntax? scopes/c) single-scope?)]) 96 symbol?]{ 97 Returns the kind of the single scope in @racket[sc]. To my knowledge, this 98 will be one of @racket[use-site], @racket[macro], @racket[module], 99 @racket[intdef], @racket[local] or @racket[top].} 100 101 @defproc[(use-site-scope? [sc (and/c (or/c syntax? scopes/c) single-scope?)]) 102 boolean?]{A shorthand for @racket[(eq? (scope-kind sc) 'use-site)]} 103 @defproc[(macro-scope? [sc (and/c (or/c syntax? scopes/c) single-scope?)]) 104 boolean?]{A shorthand for @racket[(eq? (scope-kind sc) 'macro)]} 105 @defproc[(module-scope? [sc (and/c (or/c syntax? scopes/c) single-scope?)]) 106 boolean?]{A shorthand for @racket[(eq? (scope-kind sc) 'module)]} 107 @defproc[(intdef-scope? [sc (and/c (or/c syntax? scopes/c) single-scope?)]) 108 boolean?]{A shorthand for @racket[(eq? (scope-kind sc) 'intdef)]} 109 @defproc[(local-scope? [sc (and/c (or/c syntax? scopes/c) single-scope?)]) 110 boolean?]{A shorthand for @racket[(eq? (scope-kind sc) 'local)]} 111 @defproc[(top-scope? [sc (and/c (or/c syntax? scopes/c) single-scope?)]) 112 boolean?]{A shorthand for @racket[(eq? (scope-kind sc) 'top)]} 113 114 @defproc[(all-scopes-in? [sc1 (or/c syntax? scopes/c)] 115 [sc2 (or/c syntax? scopes/c)]) boolean?]{ 116 Predicate which returns @racket[#true] iff all the scopes contained within the 117 set of scopes @racket[sc1] are present in the set of scopes @racket[sc2].} 118 119 @defproc[(any-scope-in? [sc1 (or/c syntax? scopes/c)] 120 [sc2 (or/c syntax? scopes/c)]) boolean?]{ 121 Predicate which returns @racket[#true] iff any of the scopes contained within 122 the set of scopes @racket[sc1] are present in the set of scopes @racket[sc2].}