Adding sequence support for mlists and more sequence xrefs

This commit is contained in:
Jay McCarthy 2010-08-12 13:33:43 -06:00
parent 383465aa06
commit 8c32de33c6
6 changed files with 67 additions and 8 deletions

View File

@ -29,6 +29,7 @@
(rename *in-range in-range)
(rename *in-naturals in-naturals)
(rename *in-list in-list)
(rename *in-mlist in-mlist)
(rename *in-vector in-vector)
(rename *in-string in-string)
(rename *in-bytes in-bytes)
@ -318,6 +319,7 @@
(define (sequence? v)
(or (do-sequence? v)
(list? v)
(mpair? v)
(vector? v)
(string? v)
(bytes? v)
@ -329,6 +331,7 @@
(cond
[(do-sequence? v) ((do-sequence-ref v 0))]
[(list? v) (:list-gen v)]
[(mpair? v) (:mlist-gen v)]
[(vector? v) (:vector-gen v 0 (vector-length v) 1)]
[(string? v) (:string-gen v 0 (string-length v) 1)]
[(bytes? v) (:bytes-gen v 0 (bytes-length v) 1)]
@ -378,9 +381,15 @@
(define (in-list l)
;; (unless (list? l) (raise-type-error 'in-list "list" l))
(make-do-sequence (lambda () (:list-gen l))))
(define (:list-gen l)
(values car cdr l pair? void void))
(define (in-mlist l)
(make-do-sequence (lambda () (:mlist-gen l))))
(define (:mlist-gen l)
(values mcar mcdr l mpair? void void))
(define (check-ranges who start stop step)
(unless (exact-nonnegative-integer? start) (raise-type-error who "exact non-negative integer" start))
@ -1073,6 +1082,31 @@
;; loop args -- ok to use unsafe-cdr, since car passed
((unsafe-cdr lst)))]]
[_ #f])))
(define-sequence-syntax *in-mlist
(lambda () #'in-mlist)
(lambda (stx)
(syntax-case stx ()
[[(id) (_ lst-expr)]
#'[(id)
(:do-in
;;outer bindings
([(lst) lst-expr])
;; outer check
(void) ; (unless (list? lst) (in-list lst))
;; loop bindings
([lst lst])
;; pos check
(not (null? lst))
;; inner bindings
([(id) (mcar lst)])
;; pre guard
#t
;; post guard
#t
;; loop args
((mcdr lst)))]]
[_ #f])))
(define-for-syntax (vector-like-gen vector?-id
unsafe-vector-length-id

View File

@ -24,6 +24,10 @@ values. The following datatypes are all dictionaries:
]
A dictionary can be used as a two-valued sequence (see
@secref["sequences"]). The associations of the dictionary serve as elements
of the sequence. See also @scheme[in-dict], @scheme[in-dict-keys], and @scheme[in-dict-values].
@note-lib[racket/dict]
@defproc[(dict? [v any/c]) boolean?]{

View File

@ -20,6 +20,10 @@ list. Instead of programming with mutable pairs and mutable lists,
data structures such as pairs, lists, and hash tables are practically
always better choices.
A @tech{mutable list} can be used as a single-valued sequence (see
@secref["sequences"]). The elements of the @tech{mutable list} serve as elements
of the sequence. See also @scheme[in-mlist].
@; ----------------------------------------
@section{Mutable Pair Constructors and Selectors}

View File

@ -2,7 +2,8 @@
@(require "mz.ss"
(for-syntax racket/base)
scribble/scheme
(for-label racket/generator))
(for-label racket/generator
racket/mpair))
@(define generator-eval
(lambda ()
@ -27,15 +28,21 @@ built-in datatypes, the sequence datatype includes the following:
@itemize[
@item{strings (see @secref["strings"])}
@item{byte strings (see @secref["bytestrings"])}
@item{lists (see @secref["pairs"])}
@item{mutable lists (see @secref["mpairs"])}
@item{vectors (see @secref["vectors"])}
@item{hash tables (see @secref["hashtables"])}
@item{strings (see @secref["strings"])}
@item{dictionaries (see @secref["dicts"])}
@item{byte strings (see @secref["bytestrings"])}
@item{sets (see @secref["sets"])}
@item{input ports (see @secref["ports"])}
@ -167,6 +174,11 @@ Returns a sequence equivalent to @scheme[lst].
@info-on-seq["pairs" "lists"]
@speed[in-list "list"]}
@defproc[(in-mlist [mlst mlist?]) sequence?]{
Returns a sequence equivalent to @scheme[mlst].
@info-on-seq["mpairs" "mutable lists"]
@speed[in-mlist "mutable list"]}
@defproc[(in-vector [vec vector?]
[start exact-nonnegative-integer? 0]
[stop (or/c exact-nonnegative-integer? #f) #f]

View File

@ -8,14 +8,16 @@ A @deftech{set} represents a set of distinct elements. For a given
set, elements are equivalent via @scheme[equal?], @scheme[eqv?], or
@scheme[eq?]. Two sets are @scheme[equal?] when they use the same
element-comparison procedure (@scheme[equal?], @scheme[eqv?], or
@scheme[eq?]) and have equivalent elements. A set can be used as a
@tech{sequence} (see @secref["sequences"]).
@scheme[eq?]) and have equivalent elements.
A set can be used as a single-valued sequence (see
@secref["sequences"]). The elements of the set serve as elements
of the sequence. See also @scheme[in-set].
Operations on sets that contain elements that are mutated are
unpredictable in much the same way that @tech{hash table} operations are
unpredictable when keys are mutated.
@note-lib[racket/set]
@defproc[(set? [v any/c]) boolean?]{

View File

@ -3,7 +3,8 @@
(Section 'for)
(require scheme/generator)
(require scheme/generator
racket/mpair)
(define-syntax (test-multi-generator stx)
(syntax-case stx ()
@ -105,6 +106,8 @@
(test-generator [(a b c)] '(a b c))
(test-generator [(a b c)] (in-list '(a b c)))
(test-generator [(a b c)] (mlist 'a 'b 'c))
(test-generator [(a b c)] (in-mlist (mlist 'a 'b 'c)))
(test-generator [(a b c)] #(a b c))
(test-generator [(a b c)] (in-vector #(a b c)))
(test-generator [(b c d)] (in-vector #(a b c d) 1))