expander: repairs for top-level define-values and begin-for-syntax

This commit is contained in:
Matthew Flatt 2018-03-02 17:59:12 -07:00
parent 88b066e1b2
commit ea7f973102
4 changed files with 367 additions and 74 deletions

View File

@ -521,6 +521,29 @@
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(module local-expand-begin-for-syntax-test racket/base
(require (for-syntax racket/base)
(for-meta 2 racket/base))
(provide result)
(begin-for-syntax
(define-syntax (z stx)
(syntax-local-lift-expression #'(+ 1 2))))
(define-syntax (m stx)
#`'#,(local-expand #'(begin-for-syntax (define x 10) (z)) 'top-level null))
(define result (m)))
(let ([r (dynamic-require ''local-expand-begin-for-syntax-test 'result)])
(define lifted-id (and (list? r) (last r)))
(test `(begin-for-syntax (define-values (,lifted-id) (#%app + '1 '2)) (define-values (x) '10) ,lifted-id)
'local-expand-begin-for-syntax
r))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(module rename-transformer-tests racket/base
(require (for-syntax racket/base))

View File

@ -48,6 +48,7 @@
expand/capture-lifts
expand-transformer
expand+eval-for-syntaxes-binding
context->transformer-context
eval-for-syntaxes-binding
eval-for-bindings

View File

@ -1,5 +1,7 @@
#lang racket/base
(require "../syntax/scope.rkt"
(require "../common/struct-star.rkt"
"../syntax/syntax.rkt"
"../syntax/scope.rkt"
"../syntax/taint.rkt"
"../namespace/core.rkt"
"../syntax/match.rkt"
@ -13,6 +15,8 @@
"require.rkt"
"def-id.rkt"
"bind-top.rkt"
"lift-context.rkt"
"lift-key.rkt"
"log.rkt")
(add-core-form!
@ -24,7 +28,7 @@
(define disarmed-s (syntax-disarm s))
(define-match m s '(define-values (id ...) rhs))
(define-values (ids syms) (as-expand-time-top-level-bindings (m 'id) s ctx))
(define exp-rhs (expand (m 'rhs) (as-named-context ctx ids)))
(define exp-rhs (expand (m 'rhs) (as-named-context (as-expression-context ctx) ids)))
(if (expand-context-to-parsed? ctx)
(parsed-define-values s ids syms exp-rhs)
(rebuild
@ -37,7 +41,7 @@
(log-expand ctx 'prim-define-syntaxes)
(log-expand ctx 'prepare-env)
(unless (eq? (expand-context-context ctx) 'top-level)
(raise-syntax-error #f "not allowed in an expression position" s))
(raise-syntax-error #f "not in a definition context" s))
(define disarmed-s (syntax-disarm s))
(define-match m disarmed-s '(define-syntaxes (id ...) rhs))
(define-values (ids syms) (as-expand-time-top-level-bindings (m 'id) s ctx))
@ -51,7 +55,44 @@
(add-core-form!
'begin-for-syntax
(lambda (s ctx)
(raise-syntax-error #f "not allowed in an expression position" s)))
(unless (eq? (expand-context-context ctx) 'top-level)
(raise-syntax-error #f "not in a definition context" s))
(define-match m s '(begin-for-syntax form ...))
(log-expand ctx 'prim-begin-for-syntax)
(log-expand ctx 'prepare-env)
(define trans-ctx (context->transformer-context ctx 'top-level #:keep-stops? #t))
(define lift-ctx (make-lift-context
(make-top-level-lift trans-ctx)))
(define capture-ctx (struct*-copy expand-context trans-ctx
[lift-key #:parent root-expand-context (generate-lift-key)]
[lifts lift-ctx]))
(define all-exp-forms
(let loop ([forms (m 'form)])
(log-expand ctx 'enter-list (datum->syntax #f (m 'form) s))
(define exp-forms
(let loop ([forms forms] [accum null])
(cond
[(null? forms)
(define forms (reverse accum))
(log-expand ctx 'exit-list (datum->syntax #f forms s))
forms]
[else
(log-expand ctx 'next)
(define exp-form (expand (car forms) capture-ctx))
(loop (cdr forms) (cons exp-form accum))])))
(define lifts (get-and-clear-lifts! lift-ctx))
(cond
[(null? lifts)
exp-forms]
[else
(log-expand ctx 'module-lift-loop lifts)
(define beg (wrap-lifts-as-begin lifts #f (expand-context-phase trans-ctx)))
(define exprs (reverse (cdr (reverse (cdr (syntax-e beg))))))
(append (loop exprs) exp-forms)])))
;; We shouldn't be able to get here in to-parsed mode
(if (expand-context-to-parsed? ctx)
(parsed-begin-for-syntax s all-exp-forms)
(rebuild s (cons (m 'begin-for-syntax) all-exp-forms)))))
(add-core-form!
'#%require

View File

@ -77313,7 +77313,8 @@ static const char *startup_source =
"(values #t define-values1_1 id2_2 rhs3_1))))))"
"(let-values(((ids_50 syms_28)(as-expand-time-top-level-bindings id2_1 s_0 ctx_7)))"
"(let-values(((exp-rhs_8)"
"(let-values(((temp11_8) rhs3_0)((temp12_7)(as-named-context ctx_7 ids_50)))"
"(let-values(((temp11_8) rhs3_0)"
"((temp12_7)(as-named-context(as-expression-context ctx_7) ids_50)))"
"(expand7.1 #f #f #f #f temp11_8 temp12_7))))"
"(if(expand-context-to-parsed? ctx_7)"
"(parsed-define-values19.1 s_0 ids_50 syms_28 exp-rhs_8)"
@ -77339,7 +77340,7 @@ static const char *startup_source =
"(begin"
"(if(eq?(expand-context-context ctx_125) 'top-level)"
"(void)"
" (let-values () (raise-syntax-error$1 #f \"not allowed in an expression position\" s_872)))"
" (let-values () (raise-syntax-error$1 #f \"not in a definition context\" s_872)))"
"(values))))"
"(let-values(((disarmed-s_26)(syntax-disarm$1 s_872)))"
"(let-values(((ok?_91 define-syntaxes15_0 id16_2 rhs17_0)"
@ -77489,88 +77490,315 @@ static const char *startup_source =
"(void"
"(add-core-form!*"
" 'begin-for-syntax"
" (lambda (s_486 ctx_10) (raise-syntax-error$1 #f \"not allowed in an expression position\" s_486))))"
"(lambda(s_486 ctx_10)"
"(let-values((()"
"(begin"
"(if(eq?(expand-context-context ctx_10) 'top-level)"
"(void)"
" (let-values () (raise-syntax-error$1 #f \"not in a definition context\" s_486)))"
"(values))))"
"(let-values(((ok?_92 begin-for-syntax29_0 form30_0)"
"(let-values(((s_873) s_486))"
"(let-values(((orig-s_100) s_873))"
"(let-values(((begin-for-syntax29_1 form30_1)"
"(let-values(((s_874)(if(syntax?$1 s_873)(syntax-e$1 s_873) s_873)))"
"(if(pair? s_874)"
"(let-values(((begin-for-syntax31_0)"
"(let-values(((s_31)(car s_874))) s_31))"
"((form32_0)"
"(let-values(((s_46)(cdr s_874)))"
"(let-values(((s_147)"
"(if(syntax?$1 s_46)(syntax-e$1 s_46) s_46)))"
"(let-values(((flat-s_66)(to-syntax-list.1 s_147)))"
"(if(not flat-s_66)"
"(let-values()"
" (raise-syntax-error$1 #f \"bad syntax\" orig-s_100))"
"(let-values() flat-s_66)))))))"
"(values begin-for-syntax31_0 form32_0))"
" (raise-syntax-error$1 #f \"bad syntax\" orig-s_100)))))"
"(values #t begin-for-syntax29_1 form30_1))))))"
"(let-values((()"
"(begin"
"(let-values(((obs_171)(expand-context-observer ctx_10)))"
"(if obs_171"
"(let-values()(let-values()(call-expand-observe obs_171 'prim-begin-for-syntax)))"
"(void)))"
"(values))))"
"(let-values((()"
"(begin"
"(let-values(((obs_11)(expand-context-observer ctx_10)))"
"(if obs_11"
"(let-values()(let-values()(call-expand-observe obs_11 'prepare-env)))"
"(void)))"
"(values))))"
"(let-values(((trans-ctx_1)"
"(let-values(((ctx33_0) ctx_10)((temp34_5) 'top-level)((temp35_3) #t))"
"(context->transformer-context55.1 temp35_3 #t ctx33_0 temp34_5 #t))))"
"(let-values(((lift-ctx_7)"
"(let-values(((temp36_8)(make-top-level-lift trans-ctx_1)))"
"(make-lift-context6.1 #f #f temp36_8))))"
"(let-values(((capture-ctx_1)"
"(let-values(((v_77) trans-ctx_1))"
"(let-values(((the-struct_118) v_77))"
"(if(expand-context/outer? the-struct_118)"
"(let-values(((inner37_0)"
"(let-values(((the-struct_119)"
"(root-expand-context/outer-inner v_77)))"
"(if(expand-context/inner? the-struct_119)"
"(let-values(((lift-key38_0)(generate-lift-key))"
"((lifts39_0) lift-ctx_7))"
"(expand-context/inner2.1"
"(root-expand-context/inner-self-mpi the-struct_119)"
"(root-expand-context/inner-module-scopes the-struct_119)"
"(root-expand-context/inner-top-level-bind-scope"
" the-struct_119)"
"(root-expand-context/inner-all-scopes-stx the-struct_119)"
"(root-expand-context/inner-defined-syms the-struct_119)"
"(root-expand-context/inner-counter the-struct_119)"
" lift-key38_0"
"(expand-context/inner-to-parsed? the-struct_119)"
"(expand-context/inner-phase the-struct_119)"
"(expand-context/inner-namespace the-struct_119)"
"(expand-context/inner-just-once? the-struct_119)"
"(expand-context/inner-module-begin-k the-struct_119)"
"(expand-context/inner-allow-unbound? the-struct_119)"
"(expand-context/inner-in-local-expand? the-struct_119)"
"(expand-context/inner-stops the-struct_119)"
"(expand-context/inner-declared-submodule-names the-struct_119)"
" lifts39_0"
"(expand-context/inner-lift-envs the-struct_119)"
"(expand-context/inner-module-lifts the-struct_119)"
"(expand-context/inner-require-lifts the-struct_119)"
"(expand-context/inner-to-module-lifts the-struct_119)"
"(expand-context/inner-requires+provides the-struct_119)"
"(expand-context/inner-observer the-struct_119)"
"(expand-context/inner-for-serializable? the-struct_119)"
"(expand-context/inner-should-not-encounter-macros?"
" the-struct_119)))"
"(raise-argument-error"
" 'struct-copy"
" \"expand-context/inner?\""
" the-struct_119)))))"
"(expand-context/outer1.1"
" inner37_0"
"(root-expand-context/outer-post-expansion-scope the-struct_118)"
"(root-expand-context/outer-use-site-scopes the-struct_118)"
"(root-expand-context/outer-frame-id the-struct_118)"
"(expand-context/outer-context the-struct_118)"
"(expand-context/outer-env the-struct_118)"
"(expand-context/outer-post-expansion-scope-action the-struct_118)"
"(expand-context/outer-scopes the-struct_118)"
"(expand-context/outer-def-ctx-scopes the-struct_118)"
"(expand-context/outer-binding-layer the-struct_118)"
"(expand-context/outer-reference-records the-struct_118)"
"(expand-context/outer-only-immediate? the-struct_118)"
"(expand-context/outer-need-eventually-defined the-struct_118)"
"(expand-context/outer-current-introduction-scopes the-struct_118)"
"(expand-context/outer-name the-struct_118)))"
" (raise-argument-error 'struct-copy \"expand-context/outer?\" the-struct_118))))))"
"(let-values(((all-exp-forms_0)"
"((letrec-values(((loop_87)"
"(lambda(forms_0)"
"(begin"
" 'loop"
"(let-values((()"
"(begin"
"(let-values(((obs_16)"
"(expand-context-observer ctx_10)))"
"(if obs_16"
"(let-values()"
"(let-values()"
"(call-expand-observe"
" obs_16"
" 'enter-list"
"(datum->syntax$1 #f form30_0 s_486))))"
"(void)))"
"(values))))"
"(let-values(((exp-forms_0)"
"((letrec-values(((loop_112)"
"(lambda(forms_1 accum_1)"
"(begin"
" 'loop"
"(if(null? forms_1)"
"(let-values()"
"(let-values(((forms_2)"
"(reverse$1"
" accum_1)))"
"(begin"
"(let-values(((obs_17)"
"(expand-context-observer"
" ctx_10)))"
"(if obs_17"
"(let-values()"
"(let-values()"
"(call-expand-observe"
" obs_17"
" 'exit-list"
"(datum->syntax$1"
" #f"
" forms_2"
" s_486))))"
"(void)))"
" forms_2)))"
"(let-values()"
"(let-values((()"
"(begin"
"(let-values(((obs_172)"
"(expand-context-observer"
" ctx_10)))"
"(if obs_172"
"(let-values()"
"(let-values()"
"(call-expand-observe"
" obs_172"
" 'next)))"
"(void)))"
"(values))))"
"(let-values(((exp-form_0)"
"(let-values(((temp40_4)"
"(car"
" forms_1))"
"((capture-ctx41_0)"
" capture-ctx_1))"
"(expand7.1"
" #f"
" #f"
" #f"
" #f"
" temp40_4"
" capture-ctx41_0))))"
"(loop_112"
"(cdr forms_1)"
"(cons"
" exp-form_0"
" accum_1))))))))))"
" loop_112)"
" forms_0"
" null)))"
"(let-values(((lifts_15)(get-and-clear-lifts! lift-ctx_7)))"
"(if(null? lifts_15)"
"(let-values() exp-forms_0)"
"(let-values()"
"(let-values((()"
"(begin"
"(let-values(((obs_173)"
"(expand-context-observer"
" ctx_10)))"
"(if obs_173"
"(let-values()"
"(let-values()"
"(call-expand-observe"
" obs_173"
" 'module-lift-loop"
" lifts_15)))"
"(void)))"
"(values))))"
"(let-values(((beg_0)"
"(let-values(((lifts42_0) lifts_15)"
"((temp43_5) #f)"
"((temp44_4)"
"(expand-context-phase"
" trans-ctx_1)))"
"(wrap-lifts-as-begin16.1"
" #f"
" #f"
" #f"
" #f"
" lifts42_0"
" temp43_5"
" temp44_4))))"
"(let-values(((exprs_1)"
"(reverse$1"
"(cdr"
"(reverse$1"
"(cdr(syntax-e$1 beg_0)))))))"
"(append"
"(loop_87 exprs_1)"
" exp-forms_0)))))))))))))"
" loop_87)"
" form30_0)))"
"(if(expand-context-to-parsed? ctx_10)"
"(parsed-begin-for-syntax21.1 s_486 all-exp-forms_0)"
"(let-values(((s45_1) s_486)((temp46_4)(cons begin-for-syntax29_0 all-exp-forms_0)))"
"(rebuild5.1 #f #f s45_1 temp46_4))))))))))))))"
"(void"
"(add-core-form!*"
" '#%require"
"(lambda(s_45 ctx_18)"
"(lambda(s_33 ctx_126)"
"(let-values((()"
"(begin"
"(let-values(((obs_171)(expand-context-observer ctx_18)))"
"(if obs_171(let-values()(let-values()(call-expand-observe obs_171 'prim-require)))(void)))"
"(let-values(((obs_174)(expand-context-observer ctx_126)))"
"(if obs_174(let-values()(let-values()(call-expand-observe obs_174 'prim-require)))(void)))"
"(values))))"
"(let-values((()"
"(begin"
"(if(eq?(expand-context-context ctx_18) 'top-level)"
"(if(eq?(expand-context-context ctx_126) 'top-level)"
"(void)"
" (let-values () (raise-syntax-error$1 #f \"allowed only in a module or the top level\" s_45)))"
" (let-values () (raise-syntax-error$1 #f \"allowed only in a module or the top level\" s_33)))"
"(values))))"
"(let-values(((disarmed-s_27)(syntax-disarm$1 s_45)))"
"(let-values(((ok?_92 #%require29_0 req30_0)"
"(let-values(((s_401) disarmed-s_27))"
"(let-values(((orig-s_100) s_401))"
"(let-values(((#%require29_1 req30_1)"
"(let-values(((s_82)(if(syntax?$1 s_401)(syntax-e$1 s_401) s_401)))"
"(if(pair? s_82)"
"(let-values(((#%require31_0)(let-values(((s_46)(car s_82))) s_46))"
"((req32_0)"
"(let-values(((s_147)(cdr s_82)))"
"(let-values(((s_83)"
"(if(syntax?$1 s_147)"
"(syntax-e$1 s_147)"
" s_147)))"
"(let-values(((flat-s_66)(to-syntax-list.1 s_83)))"
"(if(not flat-s_66)"
"(let-values(((disarmed-s_27)(syntax-disarm$1 s_33)))"
"(let-values(((ok?_93 #%require47_0 req48_0)"
"(let-values(((s_195) disarmed-s_27))"
"(let-values(((orig-s_4) s_195))"
"(let-values(((#%require47_1 req48_1)"
"(let-values(((s_58)(if(syntax?$1 s_195)(syntax-e$1 s_195) s_195)))"
"(if(pair? s_58)"
"(let-values(((#%require49_0)(let-values(((s_36)(car s_58))) s_36))"
"((req50_0)"
"(let-values(((s_875)(cdr s_58)))"
"(let-values(((s_197)"
"(if(syntax?$1 s_875)"
"(syntax-e$1 s_875)"
" s_875)))"
"(let-values(((flat-s_67)(to-syntax-list.1 s_197)))"
"(if(not flat-s_67)"
"(let-values()"
"(raise-syntax-error$1"
" #f"
" \"bad syntax\""
" orig-s_100))"
"(let-values() flat-s_66)))))))"
"(values #%require31_0 req32_0))"
" (raise-syntax-error$1 #f \"bad syntax\" orig-s_100)))))"
"(values #t #%require29_1 req30_1))))))"
" (raise-syntax-error$1 #f \"bad syntax\" orig-s_4))"
"(let-values() flat-s_67)))))))"
"(values #%require49_0 req50_0))"
" (raise-syntax-error$1 #f \"bad syntax\" orig-s_4)))))"
"(values #t #%require47_1 req48_1))))))"
"(let-values(((sc_40)(new-scope 'macro)))"
"(begin"
"(let-values(((temp33_4)"
"(let-values(((temp51_4)"
"(reverse$1"
"(let-values(((lst_457) req30_0))"
"(let-values(((lst_457) req48_0))"
"(begin"
"(if(variable-reference-from-unsafe?(#%variable-reference))"
"(void)"
"(let-values()(check-list lst_457)))"
"((letrec-values(((for-loop_341)"
"(lambda(fold-var_163 lst_458)"
"(lambda(fold-var_286 lst_152)"
"(begin"
" 'for-loop"
"(if(pair? lst_458)"
"(let-values(((req_20)(unsafe-car lst_458))"
"((rest_262)(unsafe-cdr lst_458)))"
"(let-values(((fold-var_95)"
"(let-values(((fold-var_178) fold-var_163))"
"(let-values(((fold-var_179)"
"(if(pair? lst_152)"
"(let-values(((req_20)(unsafe-car lst_152))"
"((rest_262)(unsafe-cdr lst_152)))"
"(let-values(((fold-var_393)"
"(let-values(((fold-var_289) fold-var_286))"
"(let-values(((fold-var_394)"
"(let-values()"
"(cons"
"(let-values()"
"(add-scope"
" req_20"
" sc_40))"
" fold-var_178))))"
"(values fold-var_179)))))"
" fold-var_289))))"
"(values fold-var_394)))))"
"(if(not #f)"
"(for-loop_341 fold-var_95 rest_262)"
" fold-var_95)))"
" fold-var_163)))))"
"(for-loop_341 fold-var_393 rest_262)"
" fold-var_393)))"
" fold-var_286)))))"
" for-loop_341)"
" null"
" lst_457)))))"
"((s34_0) s_45)"
"((temp35_3) #f)"
"((temp36_8)(expand-context-namespace ctx_18))"
"((temp37_5)(expand-context-phase ctx_18))"
"((temp38_4)(let-values(((temp41_5) #f))(make-requires+provides8.1 #f #f temp41_5)))"
"((temp39_8) 'require)"
"((temp40_4) #t))"
"((s52_0) s_33)"
"((temp53_5) #f)"
"((temp54_6)(expand-context-namespace ctx_126))"
"((temp55_5)(expand-context-phase ctx_126))"
"((temp56_4)(let-values(((temp59_6) #f))(make-requires+provides8.1 #f #f temp59_6)))"
"((temp57_1) 'require)"
"((temp58_5) #t))"
"(parse-and-perform-requires!30.1"
" #f"
" #f"
@ -77578,7 +77806,7 @@ static const char *startup_source =
" #f"
" #f"
" #f"
" temp40_4"
" temp58_5"
" #t"
" #f"
" #f"
@ -77588,23 +77816,23 @@ static const char *startup_source =
" #f"
" #f"
" #f"
" temp35_3"
" temp53_5"
" #t"
" temp39_8"
" temp33_4"
" s34_0"
" temp36_8"
" temp37_5"
" temp38_4))"
"(if(expand-context-to-parsed? ctx_18)(parsed-require23.1 s_45) s_45))))))))))"
" temp57_1"
" temp51_4"
" s52_0"
" temp54_6"
" temp55_5"
" temp56_4))"
"(if(expand-context-to-parsed? ctx_126)(parsed-require23.1 s_33) s_33))))))))))"
"(void"
"(add-core-form!*"
" '#%provide"
"(lambda(s_503 ctx_81)"
"(lambda(s_324 ctx_127)"
"(begin"
"(let-values(((obs_17)(expand-context-observer ctx_81)))"
"(if obs_17(let-values()(let-values()(call-expand-observe obs_17 'prim-provide)))(void)))"
" (raise-syntax-error$1 #f \"not allowed outside of a module body\" s_503)))))"
"(let-values(((obs_175)(expand-context-observer ctx_127)))"
"(if obs_175(let-values()(let-values()(call-expand-observe obs_175 'prim-provide)))(void)))"
" (raise-syntax-error$1 #f \"not allowed outside of a module body\" s_324)))))"
"(define-values(ns)(make-namespace))"
"(void"
"(begin"
@ -77754,12 +77982,12 @@ static const char *startup_source =
" for-loop_10)"
" lst_17)))"
"(void))"
"(let-values(((temp33_5) '#%builtin)"
"((temp34_5)(list* '#%place-struct '#%utils '#%boot '#%expobs '#%linklet runtime-instances))"
"(let-values(((temp33_4) '#%builtin)"
"((temp34_6)(list* '#%place-struct '#%utils '#%boot '#%expobs '#%linklet runtime-instances))"
"((ns35_1) ns)"
"((temp36_9) #f))"
"(declare-reexporting-module!50.1 ns35_1 temp36_9 #t temp33_5 temp34_5))"
"(declare-reexporting-module!50.1 ns35_1 temp36_9 #t temp33_4 temp34_6))"
"(1/current-namespace ns)"
"(1/dynamic-require ''#%kernel 0)))"
"(define-values(datum->kernel-syntax)(lambda(s_873)(begin(1/datum->syntax core-stx s_873)))))"
"(define-values(datum->kernel-syntax)(lambda(s_876)(begin(1/datum->syntax core-stx s_876)))))"
;