Skip to content

Commit 7287658

Browse files
committed
wip
1 parent 2c52f70 commit 7287658

File tree

5 files changed

+108
-88
lines changed

5 files changed

+108
-88
lines changed

typed-racket-lib/typed-racket/base-env/prims-struct.rkt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,15 @@
102102
([val (attribute prop-val)]
103103
[name (attribute prop)])
104104
(cond
105-
[(free-identifier=? name #'prop:procedure)
105+
[(or (free-identifier=? name #'prop:procedure)
106+
(free-identifier=? name #'prop:evt))
106107
(define tname (or (attribute type) st-name))
107108
(define sty-stx (if (null? type-vars)
108109
tname
109110
(quasisyntax/loc tname
110111
(#,tname #,@type-vars))))
111-
(maybe-extract-prop-proc-ty-ann sty-stx val)]
112+
(define-values (val^ ty^) (maybe-extract-prop-proc-ty-ann sty-stx val))
113+
(values val^ (assoc-struct-property-name-property ty^ name))]
112114
[else (values val #f)])))]
113115
#:attr proc-ty (if (null? proc-tys) #f
114116
proc-tys)
@@ -200,7 +202,7 @@
200202

201203

202204
;; This function tries to extract the type annotation on a lambda
203-
;; expression for prop:precedure.
205+
;; expression for prop:procedure.
204206
;;
205207
;; sty-stx: the syntax that represents a structure type. For a monomorhpic
206208
;; structure type, sty-stx is the identifier for its name. For a polymorphic

typed-racket-lib/typed-racket/private/syntax-properties.rkt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
(type-inst type-inst)
6262
(row-inst row-inst)
6363
(st-proc-ty st-proc-ty)
64+
(assoc-struct-property-name assoc-struct-property-name)
6465
(type-label type-label)
6566
(optional-non-immediate-arg optional-non-immediate-arg)
6667
(optional-immediate-arg optional-immediate-arg)

typed-racket-lib/typed-racket/rep/type-rep.rkt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -806,8 +806,11 @@
806806

807807

808808
(define/cond-contract (Struct-proc* sty)
809-
(-> Struct? (or/c #f Fun?))
810-
(define b (Struct-proc sty))
809+
(-> (or/c Poly? Struct?) (or/c #f Type?))
810+
(define sty^ (match sty
811+
[(? Struct?) sty]
812+
[(Poly: _ (? Struct? sty)) sty]))
813+
(define b (Struct-proc sty^))
811814
(and b (unbox b)))
812815

813816
(define (make-Struct* name parent flds proc poly? pred-id properties)

typed-racket-lib/typed-racket/typecheck/tc-structs.rkt

Lines changed: 97 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,6 @@
9191
(syntax-parse stx
9292
[t:typed-struct #'t.type-name]))
9393

94-
;; a simple wrapper to get proc from a polymorphic or monomorhpic structure
95-
(define/cond-contract (get-struct-proc sty)
96-
(c:-> (c:or/c Struct? Poly?) (c:or/c #f Fun?))
97-
(Struct-proc (match sty
98-
[(? Struct?) sty]
99-
[(Poly: names (? Struct? sty)) sty])))
100-
10194

10295
(define/cond-contract (tc/struct-prop-values st-tname pnames pvals)
10396
(c:-> identifier? (c:listof identifier?) (c:listof syntax?) void?)
@@ -385,7 +378,7 @@
385378
(define st-type-alias (mk-type-alias type-name tvars))
386379
(define st-type-alias-maybe-with-proc
387380
(let ([maybe-proc-ty (and (or (Poly? sty) (Struct? sty))
388-
(get-struct-proc sty))])
381+
(Struct-proc sty))])
389382
(if maybe-proc-ty (intersect st-type-alias maybe-proc-ty)
390383
st-type-alias)) )
391384

@@ -463,84 +456,107 @@
463456
(struct-names-type-name (parsed-struct-names parsed-struct))))
464457
(refine-variance! names stys tvarss))
465458

459+
460+
(define ((make-extract predicate mismatched-field-type-errors customized-proc property-lambda-rng-chck)
461+
ty-stx st-name fld-names desc)
462+
(syntax-parse ty-stx
463+
#:literals (struct-field-index)
464+
;; a field index is provided
465+
[n_:exact-nonnegative-integer
466+
(define n (syntax-e #'n_))
467+
(define max-idx (sub1 (length (struct-desc-self-fields desc))))
468+
(unless (<= n max-idx)
469+
(tc-error/fields
470+
"index too large"
471+
"index"
472+
n
473+
"maximum allowed index"
474+
max-idx
475+
#:stx ty-stx))
476+
(define ty (list-ref (struct-desc-self-fields desc) n))
477+
(unless (predicate ty)
478+
(tc-error/fields
479+
(format "field ~a is not a ~a" (syntax-e (list-ref fld-names n)) (car mismatched-field-type-errors))
480+
"expected"
481+
(cdr mismatched-field-type-errors)
482+
"given"
483+
ty
484+
#:stx ty-stx))
485+
ty]
486+
487+
;; a field name is provided (via struct-field-index)
488+
[(struct-field-index fld-nm:id)
489+
(define idx (index-of fld-names #'fld-nm
490+
free-identifier=?))
491+
;; fld-nm must be valid, because invalid field names have been reported by
492+
;; struct-field-index at this point
493+
(list-ref (struct-desc-self-fields desc) idx)]
494+
495+
[ty-stx:st-proc-ty^
496+
#:do [(define ty (parse-type #'ty-stx))]
497+
(match ty
498+
[(Fun: (list arrs ...))
499+
(make-Fun
500+
(map (lambda (arr)
501+
(Arrow-update
502+
arr
503+
dom
504+
rng
505+
(lambda (doms rng)
506+
(match (car doms)
507+
[(Name/simple: n)
508+
#:when (free-identifier=? n st-name)
509+
(void)]
510+
[(App: (Name/simple: rator) vars)
511+
#:when (free-identifier=? rator st-name)
512+
(void)]
513+
[(Univ:)
514+
(void)]
515+
[(or (Name/simple: (app syntax-e n)) n)
516+
(tc-error/fields "type mismatch in the first parameter of the function for prop:procedure"
517+
"expected" (syntax-e st-name)
518+
"got" n
519+
#:stx (st-proc-ty-property #'ty-stx))])
520+
(when property-lambda-rng-chck
521+
(property-lambda-rng-chck rng))
522+
(values (cdr doms) rng))))
523+
arrs))]
524+
[_
525+
(tc-error/fields "type mismatch"
526+
"expected"
527+
"Procedure"
528+
"given"
529+
ty
530+
#:stx #'ty-stx)])]
531+
[_
532+
(customized-proc ty-stx)]))
533+
534+
(define-syntax-rule (define-property-handling-table (name predicate msg-parts custimized-handling rng-chck) ...)
535+
(make-immutable-free-id-table (list (cons name (make-extract predicate msg-parts custimized-handling rng-chck))
536+
...)))
537+
538+
(define property-handling-table
539+
(define-property-handling-table
540+
(#'prop:procedure Fun? (cons "function" "Procedure")
541+
(lambda (ty-stx)
542+
(tc-error/stx ty-stx
543+
"expected: a nonnegative integer literal or an annotated lambda"))
544+
#f)))
545+
546+
547+
466548
;; extract the type annotation of prop:procedure value
467-
(define/cond-contract (extract-proc-ty proc-ty-stx desc fld-names st-name)
549+
(define/cond-contract (extract-proc-ty proc-ty-stx-li desc fld-names st-name)
468550
(c:-> (c:listof syntax?) struct-desc? (c:listof identifier?) identifier? Type?)
469551

470-
(unless (equal? (length proc-ty-stx) 1)
552+
553+
(unless (equal? (length proc-ty-stx-li) 1)
471554
(tc-error "prop:procedure can only have one value assigned to it"))
472555

473-
(let ([proc-ty-stx (car proc-ty-stx)])
474-
(syntax-parse proc-ty-stx
475-
#:literals (struct-field-index)
476-
;; a field index is provided
477-
[n_:exact-nonnegative-integer
478-
(define n (syntax-e #'n_))
479-
(define max-idx (sub1 (length (struct-desc-self-fields desc))))
480-
(unless (<= n max-idx)
481-
(tc-error/fields
482-
"index too large"
483-
"index"
484-
n
485-
"maximum allowed index"
486-
max-idx
487-
#:stx proc-ty-stx))
488-
(define ty (list-ref (struct-desc-self-fields desc) n))
489-
(unless (Fun? ty)
490-
(tc-error/fields
491-
(format "field ~a is not a function" (syntax-e (list-ref fld-names n)))
492-
"expected"
493-
"Procedure"
494-
"given"
495-
ty
496-
#:stx proc-ty-stx))
497-
ty]
498-
499-
;; a field name is provided (via struct-field-index)
500-
[(struct-field-index fld-nm:id)
501-
(define idx (index-of fld-names #'fld-nm
502-
free-identifier=?))
503-
;; fld-nm must be valid, because invalid field names have been reported by
504-
;; struct-field-index at this point
505-
(list-ref (struct-desc-self-fields desc) idx)]
506-
507-
[ty-stx:st-proc-ty^
508-
#:do [(define ty (parse-type #'ty-stx))]
509-
(match ty
510-
[(Fun: (list arrs ...))
511-
(make-Fun
512-
(map (lambda (arr)
513-
(Arrow-update
514-
arr
515-
dom
516-
(lambda (doms)
517-
(match (car doms)
518-
[(Name/simple: n)
519-
#:when (free-identifier=? n st-name)
520-
(void)]
521-
[(App: (Name/simple: rator) vars)
522-
#:when (free-identifier=? rator st-name)
523-
(void)]
524-
[(Univ:)
525-
(void)]
526-
[(or (Name/simple: (app syntax-e n)) n)
527-
(tc-error/fields "type mismatch in the first parameter of the function for prop:procedure"
528-
"expected" (syntax-e st-name)
529-
"got" n
530-
#:stx (st-proc-ty-property #'ty-stx))])
531-
532-
(cdr doms))))
533-
arrs))]
534-
[_
535-
(tc-error/fields "type mismatch"
536-
"expected"
537-
"Procedure"
538-
"given"
539-
ty
540-
#:stx #'ty-stx)])]
541-
[_
542-
(tc-error/stx proc-ty-stx
543-
"expected: a nonnegative integer literal or an annotated lambda")])))
556+
;; fixme for/first -> for/list
557+
(for/first ([proc-ty-stx (in-list proc-ty-stx-li)])
558+
(define property-name (assoc-struct-property-name-property proc-ty-stx))
559+
((free-id-table-ref property-handling-table property-name) proc-ty-stx st-name fld-names desc)))
544560

545561
;; check and register types for a define struct
546562
;; tc/struct : Listof[identifier] (U identifier (list identifier identifier))

typed-racket-test/succeed/struct-props.rkt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
#:property prop:custom-write
2222
(lambda ([self : foo] [p : Output-Port] [m : (U Boolean 1 0)]) : Void
2323
(displayln (+ (foo-x self) 20) p))
24-
#:property prop:evt 0
25-
2624
#:property prop:custom-print-quotable 'always)
2725

2826
(struct foobar^ foo ([y : Number])

0 commit comments

Comments
 (0)