Add `struct:'
This commit is contained in:
parent
b286673c69
commit
6e1954d79b
7
collects/tests/typed-scheme/succeed/racket-struct.rkt
Normal file
7
collects/tests/typed-scheme/succeed/racket-struct.rkt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#lang typed/racket
|
||||||
|
|
||||||
|
(struct: x ([y : Number]))
|
||||||
|
|
||||||
|
(x 1)
|
||||||
|
(x-y (x 7))
|
||||||
|
(ann x? (Any -> Boolean : x))
|
|
@ -26,6 +26,7 @@ This file defines two sorts of primitives. All of them are provided into any mod
|
||||||
[define-typed-struct/exec define-struct/exec:]))
|
[define-typed-struct/exec define-struct/exec:]))
|
||||||
|
|
||||||
(require "../utils/utils.rkt"
|
(require "../utils/utils.rkt"
|
||||||
|
racket/base
|
||||||
(for-syntax
|
(for-syntax
|
||||||
syntax/parse
|
syntax/parse
|
||||||
syntax/private/util
|
syntax/private/util
|
||||||
|
@ -296,7 +297,8 @@ This file defines two sorts of primitives. All of them are provided into any mod
|
||||||
(define-typed-struct-internal (vars ...)
|
(define-typed-struct-internal (vars ...)
|
||||||
#,(syntax-property #'nm 'struct-info (attribute nm.value)) . rest)))]))
|
#,(syntax-property #'nm 'struct-info (attribute nm.value)) . rest)))]))
|
||||||
|
|
||||||
(define-syntax (define-typed-struct stx)
|
(define-syntaxes (define-typed-struct struct:)
|
||||||
|
(let ()
|
||||||
(define-syntax-class fld-spec
|
(define-syntax-class fld-spec
|
||||||
#:literals (:)
|
#:literals (:)
|
||||||
#:description "[field-name : type]"
|
#:description "[field-name : type]"
|
||||||
|
@ -307,11 +309,22 @@ This file defines two sorts of primitives. All of them are provided into any mod
|
||||||
(pattern (name:id super:id))
|
(pattern (name:id super:id))
|
||||||
(pattern name:id
|
(pattern name:id
|
||||||
#:with super #f))
|
#:with super #f))
|
||||||
|
(define-splicing-syntax-class struct-name/new
|
||||||
|
#:description "struct name (with optional super-struct name)"
|
||||||
|
(pattern (~seq name:id super:id)
|
||||||
|
#:attr old-spec #'(name super)
|
||||||
|
#:with new-spec #'(name super))
|
||||||
|
(pattern name:id
|
||||||
|
#:with super #f
|
||||||
|
#:attr old-spec #'name
|
||||||
|
#:with new-spec #'(name)))
|
||||||
|
(define (mutable? opts)
|
||||||
|
(if (memq '#:mutable (syntax->datum opts)) '(#:mutable) '()))
|
||||||
|
(values
|
||||||
|
(lambda (stx)
|
||||||
(syntax-parse stx
|
(syntax-parse stx
|
||||||
[(_ nm:struct-name (fs:fld-spec ...) . opts)
|
[(_ nm:struct-name (fs:fld-spec ...) . opts)
|
||||||
(let ([mutable (if (memq '#:mutable (syntax->datum #'opts))
|
(let ([mutable (mutable? #'opts)])
|
||||||
'(#:mutable)
|
|
||||||
'())])
|
|
||||||
(with-syntax ([d-s (syntax-property (syntax/loc stx (define-struct nm (fs.fld ...) . opts))
|
(with-syntax ([d-s (syntax-property (syntax/loc stx (define-struct nm (fs.fld ...) . opts))
|
||||||
'typechecker:ignore #t)]
|
'typechecker:ignore #t)]
|
||||||
[dtsi (quasisyntax/loc stx (dtsi* () nm (fs ...) #,@mutable))])
|
[dtsi (quasisyntax/loc stx (dtsi* () nm (fs ...) #,@mutable))])
|
||||||
|
@ -321,6 +334,27 @@ This file defines two sorts of primitives. All of them are provided into any mod
|
||||||
'typechecker:ignore #t)]
|
'typechecker:ignore #t)]
|
||||||
[dtsi (syntax/loc stx (dtsi* (vars ...) nm (fs ...)))])
|
[dtsi (syntax/loc stx (dtsi* (vars ...) nm (fs ...)))])
|
||||||
#'(begin d-s dtsi))]))
|
#'(begin d-s dtsi))]))
|
||||||
|
(lambda (stx)
|
||||||
|
(syntax-parse stx
|
||||||
|
[(_ nm:struct-name/new (fs:fld-spec ...) . opts)
|
||||||
|
(let ([mutable (mutable? #'opts)]
|
||||||
|
[cname (datum->syntax #f (syntax-e #'nm.name))])
|
||||||
|
(with-syntax ([d-s (syntax-property (quasisyntax/loc stx
|
||||||
|
(struct #,@(attribute nm.new-spec) (fs.fld ...)
|
||||||
|
#:extra-constructor-name #,cname
|
||||||
|
. opts))
|
||||||
|
'typechecker:ignore #t)]
|
||||||
|
[dtsi (quasisyntax/loc stx (dtsi* () nm.old-spec (fs ...) #:maker #,cname #,@mutable))])
|
||||||
|
#'(begin d-s dtsi)))]
|
||||||
|
[(_ (vars:id ...) nm:struct-name/new (fs:fld-spec ...) . opts)
|
||||||
|
(let ([cname (datum->syntax #f (syntax-e #'nm.name))])
|
||||||
|
(with-syntax ([d-s (syntax-property (quasisyntax/loc stx
|
||||||
|
(struct #,@(attribute nm.new-spec) (fs.fld ...)
|
||||||
|
#:extra-constructor-name #,cname
|
||||||
|
. opts))
|
||||||
|
'typechecker:ignore #t)]
|
||||||
|
[dtsi (quasisyntax/loc stx (dtsi* (vars ...) nm.old-spec (fs ...) #:maker #,cname))])
|
||||||
|
#'(begin d-s dtsi)))])))))
|
||||||
|
|
||||||
(define-syntax (require-typed-struct stx)
|
(define-syntax (require-typed-struct stx)
|
||||||
(syntax-parse stx #:literals (:)
|
(syntax-parse stx #:literals (:)
|
||||||
|
@ -347,8 +381,7 @@ This file defines two sorts of primitives. All of them are provided into any mod
|
||||||
[(_ (nm parent) ([fld : ty] ...) lib)
|
[(_ (nm parent) ([fld : ty] ...) lib)
|
||||||
(and (identifier? #'nm) (identifier? #'parent))
|
(and (identifier? #'nm) (identifier? #'parent))
|
||||||
(with-syntax* ([(struct-info maker pred sel ...) (build-struct-names #'nm (syntax->list #'(fld ...)) #f #t)]
|
(with-syntax* ([(struct-info maker pred sel ...) (build-struct-names #'nm (syntax->list #'(fld ...)) #f #t)]
|
||||||
[(mut ...) (map (lambda _ #'#f) (syntax->list #'(sel ...)))]
|
[(mut ...) (map (lambda _ #'#f) (syntax->list #'(sel ...)))])
|
||||||
#;[(parent-tys ...) (Struct-flds (parse-type #'parent))])
|
|
||||||
#`(begin
|
#`(begin
|
||||||
(require (only-in lib struct-info))
|
(require (only-in lib struct-info))
|
||||||
(define-syntax nm (make-struct-info
|
(define-syntax nm (make-struct-info
|
||||||
|
|
|
@ -367,14 +367,26 @@ types. In most cases, use of @racket[:] is preferred to use of @racket[define:]
|
||||||
|
|
||||||
@subsection{Structure Definitions}
|
@subsection{Structure Definitions}
|
||||||
@defform/subs[
|
@defform/subs[
|
||||||
(define-struct: maybe-type-vars name-spec ([f : t] ...))
|
(struct: maybe-type-vars name-spec ([f : t] ...) options ...)
|
||||||
([maybe-type-vars code:blank (v ...)]
|
([maybe-type-vars code:blank (v ...)]
|
||||||
[name-spec name (name parent)])]{
|
[name-spec name (code:line name parent)]
|
||||||
|
[options #:transparent #:mutable])]{
|
||||||
Defines a @rtech{structure} with the name @racket[name], where the
|
Defines a @rtech{structure} with the name @racket[name], where the
|
||||||
fields @racket[f] have types @racket[t]. When @racket[parent], the
|
fields @racket[f] have types @racket[t], similar to the behavior of @racket[struct].
|
||||||
|
When @racket[parent] is present, the
|
||||||
structure is a substructure of @racket[parent]. When
|
structure is a substructure of @racket[parent]. When
|
||||||
@racket[maybe-type-vars] is present, the structure is polymorphic in the type
|
@racket[maybe-type-vars] is present, the structure is polymorphic in the type
|
||||||
variables @racket[v].}
|
variables @racket[v].
|
||||||
|
|
||||||
|
Options provided have the same meaning as for the @racket[struct] form.}
|
||||||
|
|
||||||
|
|
||||||
|
@defform/subs[
|
||||||
|
(define-struct: maybe-type-vars name-spec ([f : t] ...) options ...)
|
||||||
|
([maybe-type-vars code:blank (v ...)]
|
||||||
|
[name-spec name (name parent)]
|
||||||
|
[options #:transparent #:mutable])]{Legacy version of @racket[struct:],
|
||||||
|
corresponding to @racket[define-struct].}
|
||||||
|
|
||||||
@defform/subs[
|
@defform/subs[
|
||||||
(define-struct/exec: name-spec ([f : t] ...) [e : proc-t])
|
(define-struct/exec: name-spec ([f : t] ...) [e : proc-t])
|
||||||
|
|
|
@ -173,7 +173,7 @@
|
||||||
|
|
||||||
;; check and register types for a polymorphic define struct
|
;; check and register types for a polymorphic define struct
|
||||||
;; tc/poly-struct : Listof[identifier] (U identifier (list identifier identifier)) Listof[identifier] Listof[syntax] -> void
|
;; tc/poly-struct : Listof[identifier] (U identifier (list identifier identifier)) Listof[identifier] Listof[syntax] -> void
|
||||||
(define (tc/poly-struct vars nm/par flds tys)
|
(define (tc/poly-struct vars nm/par flds tys #:maker [maker #f])
|
||||||
;; parent field types can't actually be determined here
|
;; parent field types can't actually be determined here
|
||||||
(define-values (nm parent-name parent name name-tvar) (parse-parent nm/par))
|
(define-values (nm parent-name parent name name-tvar) (parse-parent nm/par))
|
||||||
;; create type variables for the new type parameters
|
;; create type variables for the new type parameters
|
||||||
|
@ -197,6 +197,7 @@
|
||||||
;; that the outside world will see
|
;; that the outside world will see
|
||||||
;; then register them
|
;; then register them
|
||||||
(mk/register-sty nm flds parent-name parent-field-types types
|
(mk/register-sty nm flds parent-name parent-field-types types
|
||||||
|
#:maker maker
|
||||||
;; wrap everything in the approriate forall
|
;; wrap everything in the approriate forall
|
||||||
#:wrapper (λ (t) (make-Poly tvars t))
|
#:wrapper (λ (t) (make-Poly tvars t))
|
||||||
#:type-wrapper (λ (t) (make-App t new-tvars #f))
|
#:type-wrapper (λ (t) (make-App t new-tvars #f))
|
||||||
|
|
|
@ -94,6 +94,16 @@
|
||||||
(#%plain-app values)))
|
(#%plain-app values)))
|
||||||
(tc/struct #'nm (syntax->list #'(fld ...)) (syntax->list #'(ty ...))
|
(tc/struct #'nm (syntax->list #'(fld ...)) (syntax->list #'(ty ...))
|
||||||
#:maker #'m #:constructor-return #'t)]
|
#:maker #'m #:constructor-return #'t)]
|
||||||
|
[(define-values () (begin (quote-syntax (define-typed-struct-internal nm ([fld : ty] ...)
|
||||||
|
#:maker m))
|
||||||
|
(#%plain-app values)))
|
||||||
|
(tc/struct #'nm (syntax->list #'(fld ...)) (syntax->list #'(ty ...))
|
||||||
|
#:maker #'m)]
|
||||||
|
[(define-values () (begin (quote-syntax (define-typed-struct-internal (vars ...) nm ([fld : ty] ...)
|
||||||
|
#:maker m))
|
||||||
|
(#%plain-app values)))
|
||||||
|
(tc/poly-struct (syntax->list #'(vars ...)) #'nm (syntax->list #'(fld ...)) (syntax->list #'(ty ...))
|
||||||
|
#:maker #'m)]
|
||||||
[(define-values () (begin (quote-syntax (define-typed-struct-internal nm ([fld : ty] ...) #:type-only))
|
[(define-values () (begin (quote-syntax (define-typed-struct-internal nm ([fld : ty] ...) #:type-only))
|
||||||
(#%plain-app values)))
|
(#%plain-app values)))
|
||||||
(tc/struct #'nm (syntax->list #'(fld ...)) (syntax->list #'(ty ...)) #:type-only #t)]
|
(tc/struct #'nm (syntax->list #'(fld ...)) (syntax->list #'(ty ...)) #:type-only #t)]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user