Add support for rest arguments in TR plain lambda
Two caveats: * in some positions : is not accepted as a formal when used in combination with * as a formal * the quality of parse error messages for rest argument types is traded for better optional argument error messages
This commit is contained in:
parent
ad4f6e1ea1
commit
a3d818c748
|
@ -72,6 +72,7 @@ This file defines two sorts of primitives. All of them are provided into any mod
|
||||||
syntax/struct
|
syntax/struct
|
||||||
"annotate-classes.rkt"
|
"annotate-classes.rkt"
|
||||||
"../utils/tc-utils.rkt"
|
"../utils/tc-utils.rkt"
|
||||||
|
"../private/parse-classes.rkt"
|
||||||
"../private/syntax-properties.rkt"
|
"../private/syntax-properties.rkt"
|
||||||
"../types/utils.rkt"
|
"../types/utils.rkt"
|
||||||
"for-clauses.rkt"
|
"for-clauses.rkt"
|
||||||
|
@ -1169,15 +1170,20 @@ This file defines two sorts of primitives. All of them are provided into any mod
|
||||||
#:description "rest argument"
|
#:description "rest argument"
|
||||||
#:attributes (form)
|
#:attributes (form)
|
||||||
#:literals (:)
|
#:literals (:)
|
||||||
(pattern () #:attr form #'())
|
;; specifying opaque here helps produce a better error
|
||||||
|
;; message for optional argumenents, but produces worse
|
||||||
|
;; error messages for rest arguments.
|
||||||
|
#:opaque
|
||||||
(pattern rest:id #:attr form #'rest)
|
(pattern rest:id #:attr form #'rest)
|
||||||
;; FIXME: add a typed rest-arg case if a good syntax is found
|
(pattern (rest:id : type:expr :star)
|
||||||
)
|
#:attr form (type-label-property #'rest #'type)))
|
||||||
|
|
||||||
(define-syntax-class lambda-formals
|
(define-syntax-class lambda-formals
|
||||||
#:attributes (opt-property kw-property erased)
|
#:attributes (opt-property kw-property erased)
|
||||||
#:literals (:)
|
#:literals (:)
|
||||||
(pattern (mand:mand-formal ... opt:opt-formal ... . rest:rest-arg)
|
(pattern (~or (mand:mand-formal ... opt:opt-formal ... . rest:rest-arg)
|
||||||
|
(~and (mand:mand-formal ... opt:opt-formal ...)
|
||||||
|
(~bind [rest.form #'()])))
|
||||||
#:attr kw-property
|
#:attr kw-property
|
||||||
(ormap values (append (attribute mand.kw) (attribute opt.kw)))
|
(ormap values (append (attribute mand.kw) (attribute opt.kw)))
|
||||||
#:attr opt-property
|
#:attr opt-property
|
||||||
|
|
|
@ -173,10 +173,7 @@
|
||||||
[kw-type (in-list kw-args)])
|
[kw-type (in-list kw-args)])
|
||||||
(make-Keyword kw kw-type #t)))
|
(make-Keyword kw kw-type #t)))
|
||||||
(define rest-type
|
(define rest-type
|
||||||
(and rest?
|
(and rest? (last other-args)))
|
||||||
(if (equal? (last other-args) Univ)
|
|
||||||
Univ
|
|
||||||
-Bottom)))
|
|
||||||
(make-Function
|
(make-Function
|
||||||
(list (make-arr* (take other-args non-kw-argc)
|
(list (make-arr* (take other-args non-kw-argc)
|
||||||
rng
|
rng
|
||||||
|
@ -196,10 +193,7 @@
|
||||||
(define-values (mand-args opt-and-rest-args)
|
(define-values (mand-args opt-and-rest-args)
|
||||||
(split-at other-args mand-non-kw-argc))
|
(split-at other-args mand-non-kw-argc))
|
||||||
(define rest-type
|
(define rest-type
|
||||||
(and rest?
|
(and rest? (last opt-and-rest-args)))
|
||||||
(if (equal? (last opt-and-rest-args) Univ)
|
|
||||||
Univ
|
|
||||||
-Bottom)))
|
|
||||||
(define opt-types (take opt-and-rest-args opt-non-kw-argc))
|
(define opt-types (take opt-and-rest-args opt-non-kw-argc))
|
||||||
(make-Function
|
(make-Function
|
||||||
(for/list ([to-take (in-range (add1 (length opt-types)))])
|
(for/list ([to-take (in-range (add1 (length opt-types)))])
|
||||||
|
@ -301,10 +295,7 @@
|
||||||
(define-values (mand-args opt-and-rest-args)
|
(define-values (mand-args opt-and-rest-args)
|
||||||
(split-at doms mand-argc))
|
(split-at doms mand-argc))
|
||||||
(define rest-type
|
(define rest-type
|
||||||
(and rest?
|
(and rest? (last opt-and-rest-args)))
|
||||||
(if (equal? (last opt-and-rest-args) Univ)
|
|
||||||
Univ
|
|
||||||
-Bottom)))
|
|
||||||
(define opt-types (take opt-and-rest-args opt-argc))
|
(define opt-types (take opt-and-rest-args opt-argc))
|
||||||
(make-Function
|
(make-Function
|
||||||
(for/list ([to-take (in-range (add1 (length opt-types)))])
|
(for/list ([to-take (in-range (add1 (length opt-types)))])
|
||||||
|
|
|
@ -2062,13 +2062,20 @@
|
||||||
|
|
||||||
;; test lambdas with mixed type expressions, typed keywords, typed
|
;; test lambdas with mixed type expressions, typed keywords, typed
|
||||||
;; optional arguments
|
;; optional arguments
|
||||||
;; FIXME: support rest args
|
|
||||||
[tc-e (tr:lambda (x [y : String]) (string-append y "b"))
|
[tc-e (tr:lambda (x [y : String]) (string-append y "b"))
|
||||||
#:ret (ret (t:-> Univ -String -String) (-FS -top -bot))]
|
#:ret (ret (t:-> Univ -String -String) (-FS -top -bot))]
|
||||||
|
[tc-e (tr:lambda (x [y : String] . z) (string-append y "b"))
|
||||||
|
#:ret (ret (->* (list Univ -String) Univ -String) (-FS -top -bot))]
|
||||||
|
[tc-e (tr:lambda (x [y : String] . [z : String *]) (string-append y "b"))
|
||||||
|
#:ret (ret (->* (list Univ -String) -String -String) (-FS -top -bot))]
|
||||||
[tc-e (tr:lambda (x [y : String]) : String (string-append y "b"))
|
[tc-e (tr:lambda (x [y : String]) : String (string-append y "b"))
|
||||||
#:ret (ret (t:-> Univ -String -String) (-FS -top -bot))]
|
#:ret (ret (t:-> Univ -String -String) (-FS -top -bot))]
|
||||||
[tc-e (tr:lambda (x z [y : String]) (string-append y "b"))
|
[tc-e (tr:lambda (x z [y : String]) (string-append y "b"))
|
||||||
#:ret (ret (t:-> Univ Univ -String -String) (-FS -top -bot))]
|
#:ret (ret (t:-> Univ Univ -String -String) (-FS -top -bot))]
|
||||||
|
[tc-e (tr:lambda (x z [y : String] . w) (string-append y "b"))
|
||||||
|
#:ret (ret (->* (list Univ Univ -String) Univ -String) (-FS -top -bot))]
|
||||||
|
[tc-e (tr:lambda (x z [y : String] . [w : String *]) (string-append y "b"))
|
||||||
|
#:ret (ret (->* (list Univ Univ -String) -String -String) (-FS -top -bot))]
|
||||||
[tc-e (tr:lambda (x z [y : String]) : String (string-append y "b"))
|
[tc-e (tr:lambda (x z [y : String]) : String (string-append y "b"))
|
||||||
#:ret (ret (t:-> Univ Univ -String -String) (-FS -top -bot))]
|
#:ret (ret (t:-> Univ Univ -String -String) (-FS -top -bot))]
|
||||||
[tc-err (tr:lambda (x [y : String]) : Symbol (string-append y "b"))
|
[tc-err (tr:lambda (x [y : String]) : Symbol (string-append y "b"))
|
||||||
|
@ -2077,6 +2084,10 @@
|
||||||
#:msg "expected optional lambda argument"]
|
#:msg "expected optional lambda argument"]
|
||||||
[tc-e (tr:lambda (x [y : String "a"]) (string-append y "b"))
|
[tc-e (tr:lambda (x [y : String "a"]) (string-append y "b"))
|
||||||
(->opt Univ [-String] -String)]
|
(->opt Univ [-String] -String)]
|
||||||
|
[tc-e (tr:lambda (x [y : String "a"] . z) (string-append y "b"))
|
||||||
|
(->optkey Univ [-String] #:rest Univ -String)]
|
||||||
|
[tc-e (tr:lambda (x [y : String "a"] . [z : String *]) (string-append y "b"))
|
||||||
|
(->optkey Univ [-String] #:rest -String -String)]
|
||||||
[tc-e (tr:lambda (x y [z : String "a"]) (string-append z "b"))
|
[tc-e (tr:lambda (x y [z : String "a"]) (string-append z "b"))
|
||||||
(->opt Univ Univ [-String] -String)]
|
(->opt Univ Univ [-String] -String)]
|
||||||
[tc-e (tr:lambda (w x [y : String "y"] [z : String "z"]) (string-append y z))
|
[tc-e (tr:lambda (w x [y : String "y"] [z : String "z"]) (string-append y z))
|
||||||
|
@ -2086,6 +2097,10 @@
|
||||||
(->opt Univ -String [-String -String] -String)]
|
(->opt Univ -String [-String -String] -String)]
|
||||||
[tc-e (tr:lambda (x #:y [y : String]) (string-append y "b"))
|
[tc-e (tr:lambda (x #:y [y : String]) (string-append y "b"))
|
||||||
(->key Univ #:y -String #t -String)]
|
(->key Univ #:y -String #t -String)]
|
||||||
|
[tc-e (tr:lambda (x #:y [y : String] . z) (string-append y "b"))
|
||||||
|
(->optkey Univ [] #:rest Univ #:y -String #t -String)]
|
||||||
|
[tc-e (tr:lambda (x #:y [y : String] . [z : String *]) (string-append y "b"))
|
||||||
|
(->optkey Univ [] #:rest -String #:y -String #t -String)]
|
||||||
[tc-e (tr:lambda (x #:y [y : String]) : String (string-append y "b"))
|
[tc-e (tr:lambda (x #:y [y : String]) : String (string-append y "b"))
|
||||||
(->key Univ #:y -String #t -String)]
|
(->key Univ #:y -String #t -String)]
|
||||||
[tc-e (tr:lambda (x #:y [y : String "a"]) (string-append y "b"))
|
[tc-e (tr:lambda (x #:y [y : String "a"]) (string-append y "b"))
|
||||||
|
@ -2104,6 +2119,10 @@
|
||||||
(->optkey Univ [Univ] #:y -String #f -String)]
|
(->optkey Univ [Univ] #:y -String #f -String)]
|
||||||
[tc-e (tr:lambda (x #:y [y : String] [z : String "z"]) (string-append y z))
|
[tc-e (tr:lambda (x #:y [y : String] [z : String "z"]) (string-append y z))
|
||||||
(->optkey Univ [-String] #:y -String #t -String)]
|
(->optkey Univ [-String] #:y -String #t -String)]
|
||||||
|
[tc-e (tr:lambda (x #:y [y : String] [z : String "z"] . w) (string-append y z))
|
||||||
|
(->optkey Univ [-String] #:rest Univ #:y -String #t -String)]
|
||||||
|
[tc-e (tr:lambda (x #:y [y : String] [z : String "z"] . [w : String *]) (string-append y z))
|
||||||
|
(->optkey Univ [-String] #:rest -String #:y -String #t -String)]
|
||||||
[tc-e (tr:lambda (x #:y [y : String "y"] [z : String "z"]) (string-append y z))
|
[tc-e (tr:lambda (x #:y [y : String "y"] [z : String "z"]) (string-append y z))
|
||||||
(->optkey Univ [-String] #:y -String #f -String)]
|
(->optkey Univ [-String] #:y -String #f -String)]
|
||||||
[tc-e (tr:lambda (x [z : String "z"] #:y [y : String]) (string-append y z))
|
[tc-e (tr:lambda (x [z : String "z"] #:y [y : String]) (string-append y z))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user