Make :-less versions of let variants in TR

This commit is contained in:
Asumu Takikawa 2014-02-11 22:19:02 -05:00
parent a3d818c748
commit e6e3ab4e74
5 changed files with 95 additions and 19 deletions

View File

@ -2,7 +2,9 @@
(providing (libs (except scheme/base #%module-begin #%top-interaction (providing (libs (except scheme/base #%module-begin #%top-interaction
with-handlers default-continuation-prompt-tag with-handlers default-continuation-prompt-tag
define λ lambda define-struct for for*)) define λ lambda define-struct for for*
let let* let-values letrec letrec-values
let/cc let/ec))
(basics #%module-begin #%top-interaction)) (basics #%module-begin #%top-interaction))
(require typed-racket/base-env/extra-procs (require typed-racket/base-env/extra-procs

View File

@ -22,7 +22,7 @@ This file defines two sorts of primitives. All of them are provided into any mod
|# |#
(provide (except-out (all-defined-out) dtsi* dtsi/exec* let-internal: define-for-variants define-for*-variants (provide (except-out (all-defined-out) dtsi* dtsi/exec* -let-internal define-for-variants define-for*-variants
with-handlers: for/annotation for*/annotation define-for/acc:-variants base-for/flvector: base-for/vector with-handlers: for/annotation for*/annotation define-for/acc:-variants base-for/flvector: base-for/vector
-lambda -define) -lambda -define)
;; provide the contracted bindings as primitives ;; provide the contracted bindings as primitives
@ -34,6 +34,20 @@ This file defines two sorts of primitives. All of them are provided into any mod
[-lambda lambda] [-lambda lambda]
[-lambda λ] [-lambda λ]
[-define define] [-define define]
[-let let]
[-let* let*]
[-letrec letrec]
[-let-values let-values]
[-letrec-values letrec-values]
[-let/cc let/cc]
[-let/ec let/ec]
[-let let:]
[-let* let*:]
[-letrec letrec:]
[-let-values let-values:]
[-letrec-values letrec-values:]
[-let/cc let/cc:]
[-let/ec let/ec:]
[with-handlers: with-handlers] [with-handlers: with-handlers]
[define-typed-struct/exec define-struct/exec:] [define-typed-struct/exec define-struct/exec:]
[for/annotation for] [for/annotation for]
@ -434,7 +448,7 @@ This file defines two sorts of primitives. All of them are provided into any mod
[(opt-lambda: formals:opt-lambda-annotated-formals . body) [(opt-lambda: formals:opt-lambda-annotated-formals . body)
(syntax/loc stx (-lambda formals.ann-formals . body))])) (syntax/loc stx (-lambda formals.ann-formals . body))]))
(define-syntaxes (let-internal: let*: letrec:) (define-syntaxes (-let-internal -let* -letrec)
(let ([mk (lambda (form) (let ([mk (lambda (form)
(lambda (stx) (lambda (stx)
(syntax-parse stx (syntax-parse stx
@ -442,7 +456,7 @@ This file defines two sorts of primitives. All of them are provided into any mod
(quasisyntax/loc stx (#,form (bs.binding ...) . body))])))]) (quasisyntax/loc stx (#,form (bs.binding ...) . body))])))])
(values (mk #'let) (mk #'let*) (mk #'letrec)))) (values (mk #'let) (mk #'let*) (mk #'letrec))))
(define-syntaxes (let-values: let*-values: letrec-values:) (define-syntaxes (-let-values -let*-values -letrec-values)
(let ([mk (lambda (form) (let ([mk (lambda (form)
(lambda (stx) (lambda (stx)
(syntax-parse stx (syntax-parse stx
@ -450,9 +464,9 @@ This file defines two sorts of primitives. All of them are provided into any mod
(quasisyntax/loc stx (#,form (bs.binding ...) . body))])))]) (quasisyntax/loc stx (#,form (bs.binding ...) . body))])))])
(values (mk #'let-values) (mk #'let*-values) (mk #'letrec-values)))) (values (mk #'let-values) (mk #'let*-values) (mk #'letrec-values))))
(define-syntax (let: stx) (define-syntax (-let stx)
(syntax-parse stx #:literals (:) (syntax-parse stx #:literals (:)
[(let: nm:id ~! ; named let: [(-let nm:id ~! ; named let:
(~and (~seq (~optional (~seq : ret-ty)) (~and (~seq (~optional (~seq : ret-ty))
(bs:optionally-annotated-binding ...) body ...) (bs:optionally-annotated-binding ...) body ...)
(~seq rest ...))) (~seq rest ...)))
@ -461,7 +475,7 @@ This file defines two sorts of primitives. All of them are provided into any mod
#:literals (:) #:literals (:)
[(: ret-ty (bs:annotated-binding ...) . body) [(: ret-ty (bs:annotated-binding ...) . body)
(quasisyntax/loc stx (quasisyntax/loc stx
(letrec: ([nm : (bs.ty ... -> ret-ty) (-letrec ([nm : (bs.ty ... -> ret-ty)
#,(quasisyntax/loc stx #,(quasisyntax/loc stx
(lambda (bs.ann-name ...) . #,(syntax/loc stx body)))]) (lambda (bs.ann-name ...) . #,(syntax/loc stx body)))])
#,(quasisyntax/loc stx nm)))] #,(quasisyntax/loc stx nm)))]
@ -476,8 +490,8 @@ This file defines two sorts of primitives. All of them are provided into any mod
(lambda (bs.ann-name ...) . #,(syntax/loc stx body)))]) (lambda (bs.ann-name ...) . #,(syntax/loc stx body)))])
#,(quasisyntax/loc stx nm)))]) #,(quasisyntax/loc stx nm)))])
bs.rhs ...))] bs.rhs ...))]
[(let: . rest) [(-let . rest)
(syntax/loc stx (let-internal: . rest))])) (syntax/loc stx (-let-internal . rest))]))
(define-syntax (plet: stx) (define-syntax (plet: stx)
(syntax-parse stx #:literals (:) (syntax-parse stx #:literals (:)
@ -1111,15 +1125,15 @@ This file defines two sorts of primitives. All of them are provided into any mod
[(_ p:id) [(_ p:id)
(quasisyntax/loc stx #,(internal #'(declare-refinement-internal p)))])) (quasisyntax/loc stx #,(internal #'(declare-refinement-internal p)))]))
(define-syntaxes (let/cc: let/ec:) (define-syntaxes (-let/cc -let/ec)
(let () (let ()
(define ((mk l/c) stx) (define ((mk l/c) stx)
(syntax-parse stx (syntax-parse stx
[(_ (~var k (param-annotated-name (lambda (s) #`(#,s -> (U))))) . body) [(_ (~or (~var k (param-annotated-name (lambda (s) #`(#,s -> (U)))))
(~and k:id (~bind [k.ann-name #'k]))) . body)
(quasisyntax/loc stx (#,l/c k.ann-name . body))])) (quasisyntax/loc stx (#,l/c k.ann-name . body))]))
(values (mk #'let/cc) (mk #'let/ec)))) (values (mk #'let/cc) (mk #'let/ec))))
;; Syntax classes for -lambda ;; Syntax classes for -lambda
(begin-for-syntax (begin-for-syntax
(define-splicing-syntax-class kw-formal (define-splicing-syntax-class kw-formal
@ -1338,11 +1352,11 @@ This file defines two sorts of primitives. All of them are provided into any mod
(syntax-parse stx (syntax-parse stx
[(_ for: #:length n-expr:expr (clauses ...) body ...+) [(_ for: #:length n-expr:expr (clauses ...) body ...+)
(syntax/loc stx (syntax/loc stx
(let: ([n : Integer n-expr]) (-let ([n : Integer n-expr])
(cond [(n . > . 0) (cond [(n . > . 0)
(define xs (make-flvector n)) (define xs (make-flvector n))
(define: i : Nonnegative-Fixnum 0) (define: i : Nonnegative-Fixnum 0)
(let/ec: break : Void (-let/ec break : Void
(for: (clauses ...) (for: (clauses ...)
(unsafe-flvector-set! xs i (let () body ...)) (unsafe-flvector-set! xs i (let () body ...))
(set! i (unsafe-fx+ i 1)) (set! i (unsafe-fx+ i 1))
@ -1356,10 +1370,10 @@ This file defines two sorts of primitives. All of them are provided into any mod
(define xs (make-flvector 4)) (define xs (make-flvector 4))
(define i 0) (define i 0)
(for: (clauses ...) (for: (clauses ...)
(let: ([x : Float (let () body ...)]) (-let ([x : Float (let () body ...)])
(cond [(unsafe-fx= i n) (define new-n (unsafe-fx* 2 n)) (cond [(unsafe-fx= i n) (define new-n (unsafe-fx* 2 n))
(define new-xs (make-flvector new-n x)) (define new-xs (make-flvector new-n x))
(let: loop : Void ([i : Nonnegative-Fixnum 0]) (-let loop : Void ([i : Nonnegative-Fixnum 0])
(when (i . unsafe-fx< . n) (when (i . unsafe-fx< . n)
(unsafe-flvector-set! new-xs i (unsafe-flvector-ref xs i)) (unsafe-flvector-set! new-xs i (unsafe-flvector-ref xs i))
(loop (unsafe-fx+ i 1)))) (loop (unsafe-fx+ i 1))))

View File

@ -3,6 +3,8 @@
(require racket/require racket/promise (require racket/require racket/promise
(for-template (for-template
(except-in racket/base for for* with-handlers lambda λ define (except-in racket/base for for* with-handlers lambda λ define
let let* letrec letrec-values let-values
let/cc let/ec
default-continuation-prompt-tag) default-continuation-prompt-tag)
"../base-env/prims.rkt" "../base-env/prims.rkt"
(prefix-in c: (combine-in racket/contract/region racket/contract/base))) (prefix-in c: (combine-in racket/contract/region racket/contract/base)))

View File

@ -2,7 +2,9 @@
(providing (libs (except racket/base #%module-begin #%top-interaction (providing (libs (except racket/base #%module-begin #%top-interaction
with-handlers default-continuation-prompt-tag with-handlers default-continuation-prompt-tag
define λ lambda define-struct for for*)) define λ lambda define-struct for for*
let let* let-values letrec letrec-values
let/cc let/ec))
(basics #%module-begin #%top-interaction)) (basics #%module-begin #%top-interaction))
(require typed-racket/base-env/extra-procs (require typed-racket/base-env/extra-procs

View File

@ -169,6 +169,8 @@
define lambda λ) define lambda λ)
;; For tests that rely on kw/opt properties ;; For tests that rely on kw/opt properties
(prefix-in tr: (only-in (base-env prims) define lambda λ)) (prefix-in tr: (only-in (base-env prims) define lambda λ))
;; Needed for the `let-name` syntax class before
(prefix-in r: (only-in racket/base let-values))
;; Needed for constructing TR types in expected values ;; Needed for constructing TR types in expected values
(for-syntax (for-syntax
(rep type-rep filter-rep object-rep) (rep type-rep filter-rep object-rep)
@ -179,8 +181,8 @@
(begin-for-syntax (begin-for-syntax
;; More tests need to be written to use these macros. ;; More tests need to be written to use these macros.
(define-syntax-class (let-name n) (define-syntax-class (let-name n)
#:literals (let-values) #:literals (r:let-values)
(pattern (let-values ([(i:id) _] ...) . _) (pattern (r:let-values ([(i:id) _] ...) . _)
#:with x (list-ref (syntax->list #'(i ...)) n))) #:with x (list-ref (syntax->list #'(i ...)) n)))
(define-syntax-rule (get-let-name id n e) (define-syntax-rule (get-let-name id n e)
@ -2135,6 +2137,60 @@
(->key Univ #:y -String #t #:z -String #f -String)] (->key Univ #:y -String #t #:z -String #f -String)]
[tc-e (tr:lambda (x #:y [y : String "y"] #:z [z : String "z"]) (string-append y z)) [tc-e (tr:lambda (x #:y [y : String "y"] #:z [z : String "z"]) (string-append y z))
(->key Univ #:y -String #f #:z -String #f -String)] (->key Univ #:y -String #f #:z -String #f -String)]
;; test new :-less forms that allow fewer annotations
[tc-e (let ([x "foo"]) x) -String]
[tc-e (let ([x : String "foo"]) (string-append x "bar"))
-String]
[tc-e (let ([x : String "foo"] [y 'y]) (string-append x "bar"))
-String]
[tc-e (let ([y 'y] [x : String "foo"]) (string-append x "bar"))
-String]
[tc-e (let ([y 'y] [x : String "foo"]) (string-append x "bar"))
-String]
[tc-e (let* ([x "foo"]) x) -String]
[tc-e (let* ([x : String "foo"]) (string-append x "bar"))
-String]
[tc-e (let* ([x : String "foo"] [y 'y]) (string-append x "bar"))
-String]
[tc-e (let* ([y 'y] [x : String "foo"]) (string-append x "bar"))
-String]
[tc-e (let* ([y 'y] [x : String "foo"]) (string-append x "bar"))
-String]
[tc-e (letrec ([x "foo"]) x) -String]
[tc-e (letrec ([x : String "foo"]) (string-append x "bar"))
-String]
[tc-e (letrec ([x : String "foo"] [y 'y]) (string-append x "bar"))
-String]
[tc-e (letrec ([y 'y] [x : String "foo"]) (string-append x "bar"))
-String]
[tc-e (letrec ([y 'y] [x : String "foo"]) (string-append x "bar"))
-String]
[tc-e (let-values ([(x y) (values "foo" "bar")]) x) -String]
[tc-e (let-values ([(x y) (values "foo" "bar")]
[([z : String]) (values "baz")])
(string-append x y z))
-String]
[tc-e (let-values ([([x : String] [y : String]) (values "foo" "bar")])
(string-append x y))
-String]
[tc-e (letrec-values ([(x y) (values "foo" "bar")]) x)
-String]
[tc-e (letrec-values ([(x y) (values "foo" "bar")]
[([z : String]) (values "baz")])
(string-append x y z))
-String]
[tc-e (letrec-values ([([x : String] [y : String]) (values "foo" "bar")])
(string-append x y))
-String]
[tc-e (let loop ([x "x"]) x)
#:ret (ret Univ (-FS -top -bot))]
[tc-e (let loop ([x : String "x"]) x)
#:ret (ret -String (-FS -top -bot))]
[tc-e (let/cc k "foo") -String]
[tc-e (let/ec k "foo") -String]
[tc-e (let/cc k : String (k "foo")) -String]
[tc-e (let/ec k : String (k "foo")) -String]
) )
(test-suite (test-suite
"tc-literal tests" "tc-literal tests"