WIP on unhygienic / chain-able version
This commit is contained in:
parent
d69bc53905
commit
ee26ad8101
29
dotlambda/chain.rkt
Normal file
29
dotlambda/chain.rkt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(provide chain-module-begin)
|
||||||
|
|
||||||
|
(require (for-syntax racket/base
|
||||||
|
syntax/parse
|
||||||
|
debug-scopes/named-scopes/exptime))
|
||||||
|
|
||||||
|
(define-syntax continue
|
||||||
|
(syntax-parser
|
||||||
|
[(_ whole-ctx lang lang-modbeg . body)
|
||||||
|
#:with ({~literal #%plain-module-begin} . expanded-body)
|
||||||
|
(local-expand (datum->syntax #'whole-ctx
|
||||||
|
`(,#'lang-modbeg . ,#'body)
|
||||||
|
#'whole-ctx)
|
||||||
|
'module-begin
|
||||||
|
'())
|
||||||
|
(define new-scope (make-module-like-named-scope
|
||||||
|
(format "nested-lang-~a" (syntax-e #'lang))))
|
||||||
|
(new-scope #`(begin . expanded-body))]))
|
||||||
|
|
||||||
|
(define-syntax chain-module-begin
|
||||||
|
(syntax-parser
|
||||||
|
[{~and whole (_ lang . body)}
|
||||||
|
#:with lang-modbeg (datum->syntax #'lang '#%module-begin #'lang)
|
||||||
|
#:with whole-ctx (datum->syntax #'whole 'ctx #'whole)
|
||||||
|
#'(#%plain-module-begin
|
||||||
|
(require lang)
|
||||||
|
(continue whole-ctx lang lang-modbeg . body))]))
|
|
@ -5,7 +5,8 @@
|
||||||
make-#%top-interaction)
|
make-#%top-interaction)
|
||||||
|
|
||||||
(require typed/racket)
|
(require typed/racket)
|
||||||
|
(require (for-syntax debug-scopes))
|
||||||
|
|
||||||
(require racket/stxparam
|
(require racket/stxparam
|
||||||
(for-syntax racket/string
|
(for-syntax racket/string
|
||||||
racket/list
|
racket/list
|
||||||
|
@ -39,14 +40,18 @@
|
||||||
(define-syntax (make-#%module-begin stx)
|
(define-syntax (make-#%module-begin stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
;; -mrt = -make-rename-transformer
|
;; -mrt = -make-rename-transformer
|
||||||
[(_ name wrapped-#%module-begin -λ -define-syntax -mrt)
|
[(_ name wrapped-#%module-begin -λ -define-syntax -mrt -app1 -syntax)
|
||||||
#'(define-syntax (name stx2)
|
#'(define-syntax (name stx2)
|
||||||
(syntax-case stx2 ()
|
(syntax-case stx2 ()
|
||||||
[(_ . body)
|
[(_ . body)
|
||||||
(datum->syntax
|
(datum->syntax
|
||||||
stx2
|
stx2
|
||||||
`(,#'wrapped-#%module-begin
|
`(,#'wrapped-#%module-begin
|
||||||
. ,(fold-syntax (replace-dots #'-λ #'-define-syntax #'-mrt)
|
. ,(fold-syntax (replace-dots #'-λ
|
||||||
|
#'-define-syntax
|
||||||
|
#'-mrt
|
||||||
|
#'-app1
|
||||||
|
#'-syntax)
|
||||||
#'body))
|
#'body))
|
||||||
stx2
|
stx2
|
||||||
stx2)]))]))
|
stx2)]))]))
|
||||||
|
@ -54,22 +59,27 @@
|
||||||
(define-syntax (make-#%top-interaction stx)
|
(define-syntax (make-#%top-interaction stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
;; -mrt = -make-rename-transformer
|
;; -mrt = -make-rename-transformer
|
||||||
[(_ name wrapped-#%top-interaction -λ -define-syntax -mrt)
|
[(_ name wrapped-#%top-interaction -λ -define-syntax -mrt -app1 -syntax)
|
||||||
#'(define-syntax (name stx2)
|
#'(define-syntax (name stx2)
|
||||||
(syntax-case stx2 ()
|
(syntax-case stx2 ()
|
||||||
[(_ . body)
|
[(_ . body)
|
||||||
(datum->syntax
|
(datum->syntax
|
||||||
stx2
|
stx2
|
||||||
`(,#'wrapped-#%top-interaction
|
`(,#'wrapped-#%top-interaction
|
||||||
. ,(fold-syntax (replace-dots #'-λ #'-define-syntax #'-mrt)
|
. ,(fold-syntax (replace-dots #'-λ
|
||||||
|
#'-define-syntax
|
||||||
|
#'-mrt
|
||||||
|
#'-app1
|
||||||
|
#'-syntax)
|
||||||
#'body))
|
#'body))
|
||||||
stx2
|
stx2
|
||||||
stx2)]))]))
|
stx2)]))]))
|
||||||
|
|
||||||
(define-for-syntax (make-λ l args e percent? -λ -define-syntax -mrt)
|
(define-for-syntax (make-λ l args e percent?
|
||||||
|
-λ -define-syntax -mrt -app1 -syntax)
|
||||||
(define percent*
|
(define percent*
|
||||||
(if (and percent? (>= (length args) 1))
|
(if (and percent? (>= (length args) 1))
|
||||||
`{(,-define-syntax % (,-mrt #',(car args)))}
|
`{(,-define-syntax % (,-app1 ,-mrt (,-syntax ,(car args))))}
|
||||||
'{}))
|
'{}))
|
||||||
;`(letrec ([%0 (,#'λ ,args ,@percent* ,e)]) %0)
|
;`(letrec ([%0 (,#'λ ,args ,@percent* ,e)]) %0)
|
||||||
(datum->syntax l `(,-λ ,args ,@percent* ,e) l l))
|
(datum->syntax l `(,-λ ,args ,@percent* ,e) l l))
|
||||||
|
@ -106,7 +116,7 @@
|
||||||
found)
|
found)
|
||||||
|
|
||||||
(begin-for-syntax
|
(begin-for-syntax
|
||||||
(define-splicing-syntax-class (elt -λ -define-syntax -mrt)
|
(define-splicing-syntax-class (elt -λ -define-syntax -mrt -app1 -syntax)
|
||||||
(pattern {~seq {~and l {~datum λ.}} e:expr}
|
(pattern {~seq {~and l {~datum λ.}} e:expr}
|
||||||
#:with expanded
|
#:with expanded
|
||||||
(let ([args (for/list ([arg (in-range 1 (add1 (find-% #'e)))])
|
(let ([args (for/list ([arg (in-range 1 (add1 (find-% #'e)))])
|
||||||
|
@ -114,7 +124,7 @@
|
||||||
(string->symbol (format "%~a" arg))
|
(string->symbol (format "%~a" arg))
|
||||||
#'l
|
#'l
|
||||||
#'l))])
|
#'l))])
|
||||||
(make-λ #'l args #'e #t -λ -define-syntax -mrt)))
|
(make-λ #'l args #'e #t -λ -define-syntax -mrt -app1 -syntax)))
|
||||||
(pattern {~seq l:id e:expr}
|
(pattern {~seq l:id e:expr}
|
||||||
#:when (regexp-match #px"^λ([^.]+\\.)+$" (identifier→string #'l))
|
#:when (regexp-match #px"^λ([^.]+\\.)+$" (identifier→string #'l))
|
||||||
#:with expanded
|
#:with expanded
|
||||||
|
@ -122,11 +132,12 @@
|
||||||
[args (make-args #'l
|
[args (make-args #'l
|
||||||
m
|
m
|
||||||
(+ (syntax-position #'l) 1))])
|
(+ (syntax-position #'l) 1))])
|
||||||
(make-λ #'l args #'e #f -λ -define-syntax -mrt)))
|
(make-λ #'l args #'e #f -λ -define-syntax -mrt -app1 -syntax)))
|
||||||
(pattern e
|
(pattern e
|
||||||
#:with expanded #'e)))
|
#:with expanded #'e)))
|
||||||
|
|
||||||
(define-for-syntax ((replace-dots -λ -define-syntax -mrt) stx recurse)
|
(define-for-syntax ((replace-dots -λ -define-syntax -mrt -app1 -syntax)
|
||||||
|
stx recurse)
|
||||||
(syntax-parse stx
|
(syntax-parse stx
|
||||||
;; Fast path: no dots or ellipses.
|
;; Fast path: no dots or ellipses.
|
||||||
[x:id #:when (regexp-match #px"^[^.…]*$" (identifier→string #'x))
|
[x:id #:when (regexp-match #px"^[^.…]*$" (identifier→string #'x))
|
||||||
|
@ -164,7 +175,7 @@
|
||||||
#,(car identifiers))
|
#,(car identifiers))
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(#,(datum->syntax #'here '#%dotted-id stx stx) id …))))]
|
(#,(datum->syntax #'here '#%dotted-id stx stx) id …))))]
|
||||||
[{~and whole ({~var || (elt -λ -define-syntax -mrt)} …
|
[{~and whole ({~var || (elt -λ -define-syntax -mrt -app1 -syntax)} …
|
||||||
. {~and tail {~not (_ . _)}})}
|
. {~and tail {~not (_ . _)}})}
|
||||||
;; TODO: keep the stx-pairs vs stx-lists structure where possible.
|
;; TODO: keep the stx-pairs vs stx-lists structure where possible.
|
||||||
(recurse (datum->syntax #'whole
|
(recurse (datum->syntax #'whole
|
||||||
|
|
|
@ -1,18 +1,42 @@
|
||||||
#lang racket/base
|
#lang racket/base
|
||||||
|
|
||||||
(require dotlambda/implementation
|
(require dotlambda/implementation
|
||||||
(for-syntax racket/base))
|
(for-meta -10 racket/base)
|
||||||
|
(for-meta -9 racket/base)
|
||||||
|
(for-meta -8 racket/base)
|
||||||
|
(for-meta -7 racket/base)
|
||||||
|
(for-meta -6 racket/base)
|
||||||
|
(for-meta -5 racket/base)
|
||||||
|
(for-meta -4 racket/base)
|
||||||
|
(for-meta -3 racket/base)
|
||||||
|
(for-meta -2 racket/base)
|
||||||
|
(for-meta -1 racket/base)
|
||||||
|
(for-meta 0 racket/base)
|
||||||
|
(for-meta 1 racket/base)
|
||||||
|
(for-meta 2 racket/base)
|
||||||
|
(for-meta 3 racket/base)
|
||||||
|
(for-meta 4 racket/base)
|
||||||
|
(for-meta 5 racket/base)
|
||||||
|
(for-meta 6 racket/base)
|
||||||
|
(for-meta 7 racket/base)
|
||||||
|
(for-meta 8 racket/base)
|
||||||
|
(for-meta 9 racket/base)
|
||||||
|
(for-meta 10 racket/base))
|
||||||
|
|
||||||
(make-#%module-begin new-#%module-begin
|
(make-#%module-begin new-#%module-begin
|
||||||
#%module-begin
|
#%module-begin
|
||||||
λ
|
λ
|
||||||
define-syntax
|
define-syntax
|
||||||
make-rename-transformer)
|
make-rename-transformer
|
||||||
|
#%plain-app
|
||||||
|
syntax)
|
||||||
(make-#%top-interaction new-#%top-interaction
|
(make-#%top-interaction new-#%top-interaction
|
||||||
#%top-interaction
|
#%top-interaction
|
||||||
λ
|
λ
|
||||||
define-syntax
|
define-syntax
|
||||||
make-rename-transformer)
|
make-rename-transformer
|
||||||
|
#%plain-app
|
||||||
|
syntax)
|
||||||
|
|
||||||
(provide (except-out (all-from-out racket/base)
|
(provide (except-out (all-from-out racket/base)
|
||||||
#%module-begin
|
#%module-begin
|
||||||
|
|
6
dotlambda/test/test-hyper-literate-chain.rkt
Normal file
6
dotlambda/test/test-hyper-literate-chain.rkt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#lang hyper-literate (dotlambda/unhygienic . typed/racket)
|
||||||
|
@chunk[<*>
|
||||||
|
(require typed/rackunit)
|
||||||
|
(define l λ.(list % 1))
|
||||||
|
(check-equal? ((ann l (→ Any (Listof Any))) "b")
|
||||||
|
'("b" 1))]
|
5
dotlambda/test/test-typed-racket-chain.rkt
Normal file
5
dotlambda/test/test-typed-racket-chain.rkt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#lang dotlambda/unhygienic typed/racket
|
||||||
|
(require typed/rackunit)
|
||||||
|
(define l λ.(list % 1))
|
||||||
|
(check-equal? ((ann l (→ Any (Listof Any))) "b")
|
||||||
|
'("b" 1))
|
4
dotlambda/test/typed-dotlambda-phase1.rkt
Normal file
4
dotlambda/test/typed-dotlambda-phase1.rkt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#lang typed/dotlambda
|
||||||
|
(require (for-syntax racket/base))
|
||||||
|
(begin-for-syntax
|
||||||
|
λ.(+ % 1))
|
132
dotlambda/type-expander.rkt
Normal file
132
dotlambda/type-expander.rkt
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(require dotlambda/implementation
|
||||||
|
(for-meta -10 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta -9 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta -8 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta -7 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta -6 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta -5 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta -4 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta -3 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta -2 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta -1 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta 0 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta 1 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta 2 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta 3 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta 4 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta 5 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta 6 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta 7 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta 8 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta 9 (only-meta-in 0 type-expander/lang))
|
||||||
|
(for-meta 10 (only-meta-in 0 type-expander/lang))
|
||||||
|
(only-in (for-meta -10 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -9 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -8 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -7 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -6 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -5 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -4 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -3 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -2 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -1 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 0 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 1 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 2 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 3 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 4 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 5 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 6 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 7 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 8 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 9 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 10 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax]))
|
||||||
|
|
||||||
|
(make-#%module-begin new-#%module-begin
|
||||||
|
#%module-begin
|
||||||
|
λ
|
||||||
|
define-syntax
|
||||||
|
-make-rename-transformer
|
||||||
|
-#%plain-app
|
||||||
|
-syntax)
|
||||||
|
(make-#%top-interaction new-#%top-interaction
|
||||||
|
#%top-interaction
|
||||||
|
λ
|
||||||
|
define-syntax
|
||||||
|
-make-rename-transformer
|
||||||
|
-#%plain-app
|
||||||
|
-syntax)
|
||||||
|
|
||||||
|
(provide (except-out (all-from-out type-expander/lang)
|
||||||
|
#%module-begin
|
||||||
|
#%top-interaction)
|
||||||
|
(except-out (all-from-out dotlambda/implementation)
|
||||||
|
make-#%module-begin
|
||||||
|
make-#%top-interaction)
|
||||||
|
(rename-out [new-#%module-begin #%module-begin]
|
||||||
|
[new-#%top-interaction #%top-interaction]))
|
2
dotlambda/type-expander/lang/reader.rkt
Normal file
2
dotlambda/type-expander/lang/reader.rkt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
(module reader syntax/module-reader
|
||||||
|
dotlambda/unhygienic)
|
222
dotlambda/unhygienic-implementation.rkt
Normal file
222
dotlambda/unhygienic-implementation.rkt
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
#lang racket
|
||||||
|
(provide #%dotted-id
|
||||||
|
#%dot-separator
|
||||||
|
new-#%module-begin
|
||||||
|
make-#%top-interaction)
|
||||||
|
|
||||||
|
(require typed/racket
|
||||||
|
"chain.rkt")
|
||||||
|
(require (for-syntax debug-scopes))
|
||||||
|
|
||||||
|
(require racket/stxparam
|
||||||
|
(for-syntax racket/string
|
||||||
|
racket/list
|
||||||
|
syntax/parse
|
||||||
|
racket/syntax
|
||||||
|
syntax/strip-context
|
||||||
|
racket/struct
|
||||||
|
racket/function
|
||||||
|
syntax/srcloc
|
||||||
|
"private/fold.rkt"
|
||||||
|
(only-in racket/base [... …])))
|
||||||
|
|
||||||
|
(define-for-syntax identifier→string (compose symbol->string syntax-e))
|
||||||
|
|
||||||
|
(define-syntax (#%dot-separator stx)
|
||||||
|
(raise-syntax-error '#%dot-separator
|
||||||
|
"Can only be used in special contexts"
|
||||||
|
stx))
|
||||||
|
|
||||||
|
(define-syntax (~> stx)
|
||||||
|
(syntax-case stx ()
|
||||||
|
[(_ v) #'v]
|
||||||
|
[(_ v f . f*) #'(~> (f v) . f*)]))
|
||||||
|
|
||||||
|
(define-syntax-parameter #%dotted-id
|
||||||
|
(syntax-parser
|
||||||
|
#:literals (#%dot-separator)
|
||||||
|
[(_ {~seq #%dot-separator e} …) #'(λ (v) (~> v e …))]
|
||||||
|
[(_ e₀ {~seq #%dot-separator e} …) #'(~> e₀ e …)]))
|
||||||
|
|
||||||
|
(define-syntax (new-#%module-begin stx)
|
||||||
|
(syntax-parse stx
|
||||||
|
[(_ {~or lang:id (lang:id . chain₊)} . body)
|
||||||
|
(datum->syntax
|
||||||
|
stx
|
||||||
|
`(,#'chain-module-begin ,#'lang ,@(if (attribute chain₊) `(,#'chain₊) '())
|
||||||
|
. ,(fold-syntax replace-dots #'body))
|
||||||
|
stx
|
||||||
|
stx)]))
|
||||||
|
|
||||||
|
(define-syntax (make-#%top-interaction stx)
|
||||||
|
(syntax-case stx ()
|
||||||
|
[(_ name wrapped-#%top-interaction)
|
||||||
|
#'(define-syntax (name stx2)
|
||||||
|
(syntax-case stx2 ()
|
||||||
|
[(_ . body)
|
||||||
|
(datum->syntax
|
||||||
|
stx2
|
||||||
|
`(,#'wrapped-#%top-interaction
|
||||||
|
. ,(fold-syntax replace-dots
|
||||||
|
#'body))
|
||||||
|
stx2
|
||||||
|
stx2)]))]))
|
||||||
|
|
||||||
|
(define-for-syntax (make-λ l args e percent?)
|
||||||
|
(define %-loc
|
||||||
|
(build-source-location-list
|
||||||
|
(update-source-location l
|
||||||
|
#:position (let ([p (syntax-position l)])
|
||||||
|
(and p (+ p 1)))
|
||||||
|
#:column (let ([c (syntax-column l)])
|
||||||
|
(and c (+ c 1)))
|
||||||
|
#:span 1)))
|
||||||
|
(define percent*
|
||||||
|
(if (and percent? (>= (length args) 1))
|
||||||
|
#`{(define-syntax #,(datum->syntax l '% %-loc)
|
||||||
|
(#%plain-app make-rename-transformer #'#,(car args)))}
|
||||||
|
#'{}))
|
||||||
|
;`(letrec ([%0 (,#'λ ,args ,@percent* ,e)]) %0)
|
||||||
|
(define -λ
|
||||||
|
(datum->syntax #'here 'λ
|
||||||
|
(build-source-location-list
|
||||||
|
(update-source-location l #:span 1))))
|
||||||
|
(datum->syntax l #`(#,-λ #,args #,@percent* #,e) l l))
|
||||||
|
|
||||||
|
(define-for-syntax (make-args l str* pos)
|
||||||
|
(if (empty? str*)
|
||||||
|
'()
|
||||||
|
(let ()
|
||||||
|
(define str (car str*))
|
||||||
|
(define len (string-length str))
|
||||||
|
(cons (datum->syntax l
|
||||||
|
(string->symbol str)
|
||||||
|
(update-source-location l
|
||||||
|
#:position pos
|
||||||
|
#:span len)
|
||||||
|
l)
|
||||||
|
(make-args l (cdr str*) (+ pos 1 len))))))
|
||||||
|
|
||||||
|
(define-for-syntax (find-% stx)
|
||||||
|
(define found 0)
|
||||||
|
(define (found! n) (set! found (max found n)))
|
||||||
|
(fold-syntax (λ (e recurse)
|
||||||
|
(if (and (identifier? e)
|
||||||
|
(regexp-match #px"^%[1-9][0-9]*$"
|
||||||
|
(identifier→string e)))
|
||||||
|
(found! (string->number
|
||||||
|
(cadr (regexp-match #px"^%([1-9][0-9]*)$"
|
||||||
|
(identifier→string e)))))
|
||||||
|
(if (and (identifier? e)
|
||||||
|
(string=? (identifier→string e) "%"))
|
||||||
|
(found! 1)
|
||||||
|
(recurse e))))
|
||||||
|
stx)
|
||||||
|
found)
|
||||||
|
|
||||||
|
(begin-for-syntax
|
||||||
|
(define-splicing-syntax-class elt
|
||||||
|
(pattern {~seq {~and l {~datum λ.}} e:expr}
|
||||||
|
#:with expanded
|
||||||
|
(let ([args (for/list ([arg (in-range 1 (add1 (find-% #'e)))])
|
||||||
|
(datum->syntax #'l
|
||||||
|
(string->symbol (format "%~a" arg))
|
||||||
|
#'l
|
||||||
|
#'l))])
|
||||||
|
(make-λ #'l args #'e #t)))
|
||||||
|
(pattern {~seq l:id e:expr}
|
||||||
|
#:when (regexp-match #px"^λ([^.]+\\.)+$" (identifier→string #'l))
|
||||||
|
#:with expanded
|
||||||
|
(let* ([m (regexp-match* #px"[^.]+" (identifier→string #'l) 1)]
|
||||||
|
[args (make-args #'l
|
||||||
|
m
|
||||||
|
(+ (syntax-position #'l) 1))])
|
||||||
|
(make-λ #'l args #'e #f)))
|
||||||
|
(pattern e
|
||||||
|
#:with expanded #'e)))
|
||||||
|
|
||||||
|
(define-for-syntax (replace-dots stx recurse)
|
||||||
|
(syntax-parse stx
|
||||||
|
;; Fast path: no dots or ellipses.
|
||||||
|
[x:id #:when (regexp-match #px"^[^.…]*$" (identifier→string #'x))
|
||||||
|
#'x]
|
||||||
|
;; Protected identifiers, which are not altered.
|
||||||
|
[x:id #:when (regexp-match #px"^(\\.*|…|\\.\\.\\.?[+*]|…[+*]|::\\.\\.\\.)$"
|
||||||
|
(identifier→string #'x))
|
||||||
|
#'x]
|
||||||
|
;; A trailing dot is dropped and escapes the preceding identifier.
|
||||||
|
[x:id #:when (regexp-match #px"\\.$" (identifier→string #'x))
|
||||||
|
(let* ([str (identifier→string #'x)]
|
||||||
|
[unescaped (substring str 0 (sub1 (string-length str)))])
|
||||||
|
(datum->syntax stx (string->symbol unescaped) stx stx))]
|
||||||
|
[x:id #:when (regexp-match #px"[.…]"
|
||||||
|
(identifier→string #'x))
|
||||||
|
(let* ([str (symbol->string (syntax-e #'x))]
|
||||||
|
[leading-dot? (regexp-match #px"^\\." str)]
|
||||||
|
[components* (regexp-match* #px"([^.…]|\\.\\.+)+|…"
|
||||||
|
str
|
||||||
|
#:gap-select? #t)]
|
||||||
|
[components (if leading-dot?
|
||||||
|
(drop-right components* 1)
|
||||||
|
(cdr (drop-right components* 1)))]
|
||||||
|
[unescaped (map (λ (m)
|
||||||
|
(regexp-replace* #px"\\.(\\.+)" m "\\1"))
|
||||||
|
components)]
|
||||||
|
[identifiers ((to-ids stx) components
|
||||||
|
unescaped
|
||||||
|
0
|
||||||
|
leading-dot?)]
|
||||||
|
[trailing-dot? (regexp-match #px"\\.$" str)])
|
||||||
|
(define/with-syntax (id …) identifiers)
|
||||||
|
(if (= (length identifiers) 1)
|
||||||
|
(quasisyntax/loc stx
|
||||||
|
#,(car identifiers))
|
||||||
|
(quasisyntax/loc stx
|
||||||
|
(#,(datum->syntax #'here '#%dotted-id stx stx) id …))))]
|
||||||
|
[{~and whole (:elt … . {~and tail {~not (_ . _)}})}
|
||||||
|
;; TODO: keep the stx-pairs vs stx-lists structure where possible.
|
||||||
|
(recurse (datum->syntax #'whole
|
||||||
|
(syntax-e #'(expanded … . tail))
|
||||||
|
#'whole
|
||||||
|
#'whole))]
|
||||||
|
[_ (recurse stx)]))
|
||||||
|
|
||||||
|
(define-for-syntax (to-ids stx)
|
||||||
|
(define (process component* unescaped* len-before dot?)
|
||||||
|
(if (empty? component*)
|
||||||
|
'()
|
||||||
|
(let ()
|
||||||
|
(define component (car component*))
|
||||||
|
(define unescaped (car unescaped*))
|
||||||
|
(define len (string-length component))
|
||||||
|
(define len-after (+ len-before len))
|
||||||
|
(define pos (+ (syntax-position stx) len-before))
|
||||||
|
(define loc (update-source-location stx #:position pos #:span len))
|
||||||
|
(define id
|
||||||
|
(datum->syntax stx
|
||||||
|
(if dot?
|
||||||
|
'#%dot-separator
|
||||||
|
(string->symbol unescaped))
|
||||||
|
loc
|
||||||
|
stx))
|
||||||
|
(define id-p
|
||||||
|
(if dot? (syntax-property id 'dotted-original-chars unescaped) id))
|
||||||
|
(cons id-p
|
||||||
|
(process (cdr component*)
|
||||||
|
(cdr unescaped*)
|
||||||
|
len-after
|
||||||
|
(not dot?))))))
|
||||||
|
process)
|
||||||
|
|
||||||
|
(define-for-syntax (map-fold f init . l*)
|
||||||
|
(car
|
||||||
|
(apply foldl
|
||||||
|
(λ all-args
|
||||||
|
(define vs+acc (last all-args))
|
||||||
|
(define args (drop-right all-args 1))
|
||||||
|
(define new-v+new-acc (apply f (append args (list (cdr vs+acc)))))
|
||||||
|
(cons (cons (car new-v+new-acc)
|
||||||
|
(car vs+acc))
|
||||||
|
(cdr new-v+new-acc)))
|
||||||
|
(cons '() init)
|
||||||
|
l*)))
|
6
dotlambda/unhygienic.rkt
Normal file
6
dotlambda/unhygienic.rkt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#lang racket
|
||||||
|
|
||||||
|
(require dotlambda/unhygienic-implementation)
|
||||||
|
|
||||||
|
(provide (rename-out [new-#%module-begin #%module-begin]
|
||||||
|
#;[new-#%top-interaction #%top-interaction]))
|
2
dotlambda/unhygienic/lang/reader.rkt
Normal file
2
dotlambda/unhygienic/lang/reader.rkt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
(module reader syntax/module-reader
|
||||||
|
dotlambda/unhygienic)
|
|
@ -1,19 +1,126 @@
|
||||||
#lang racket/base
|
#lang racket/base
|
||||||
|
|
||||||
(require dotlambda/implementation
|
(require dotlambda/implementation
|
||||||
typed/racket/base
|
(for-meta -10 typed/racket/base)
|
||||||
(for-syntax racket/base))
|
(for-meta -9 typed/racket/base)
|
||||||
|
(for-meta -8 typed/racket/base)
|
||||||
|
(for-meta -7 typed/racket/base)
|
||||||
|
(for-meta -6 typed/racket/base)
|
||||||
|
(for-meta -5 typed/racket/base)
|
||||||
|
(for-meta -4 typed/racket/base)
|
||||||
|
(for-meta -3 typed/racket/base)
|
||||||
|
(for-meta -2 typed/racket/base)
|
||||||
|
(for-meta -1 typed/racket/base)
|
||||||
|
(for-meta 0 typed/racket/base)
|
||||||
|
(for-meta 1 typed/racket/base)
|
||||||
|
(for-meta 2 typed/racket/base)
|
||||||
|
(for-meta 3 typed/racket/base)
|
||||||
|
(for-meta 4 typed/racket/base)
|
||||||
|
(for-meta 5 typed/racket/base)
|
||||||
|
(for-meta 6 typed/racket/base)
|
||||||
|
(for-meta 7 typed/racket/base)
|
||||||
|
(for-meta 8 typed/racket/base)
|
||||||
|
(for-meta 9 typed/racket/base)
|
||||||
|
(for-meta 10 typed/racket/base)
|
||||||
|
(only-in (for-meta -10 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -9 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -8 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -7 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -6 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -5 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -4 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -3 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -2 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta -1 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 0 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 1 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 2 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 3 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 4 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 5 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 6 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 7 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 8 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 9 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax])
|
||||||
|
(only-in (for-meta 10 racket/base)
|
||||||
|
[make-rename-transformer -make-rename-transformer]
|
||||||
|
[#%plain-app -#%plain-app]
|
||||||
|
[syntax -syntax]))
|
||||||
|
|
||||||
(make-#%module-begin new-#%module-begin
|
(make-#%module-begin new-#%module-begin
|
||||||
#%module-begin
|
#%module-begin
|
||||||
λ
|
λ
|
||||||
define-syntax
|
define-syntax
|
||||||
make-rename-transformer)
|
-make-rename-transformer
|
||||||
|
-#%plain-app
|
||||||
|
-syntax)
|
||||||
(make-#%top-interaction new-#%top-interaction
|
(make-#%top-interaction new-#%top-interaction
|
||||||
#%top-interaction
|
#%top-interaction
|
||||||
λ
|
λ
|
||||||
define-syntax
|
define-syntax
|
||||||
make-rename-transformer)
|
-make-rename-transformer
|
||||||
|
-#%plain-app
|
||||||
|
-syntax)
|
||||||
|
|
||||||
(provide (except-out (all-from-out typed/racket/base)
|
(provide (except-out (all-from-out typed/racket/base)
|
||||||
#%module-begin
|
#%module-begin
|
||||||
|
|
Loading…
Reference in New Issue
Block a user