From ea7f97310273c28b63160ba566bbec1ec14de47f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 2 Mar 2018 17:59:12 -0700 Subject: [PATCH] expander: repairs for top-level `define-values` and `begin-for-syntax` --- pkgs/racket-test-core/tests/racket/macro.rktl | 23 ++ racket/src/expander/expand/main.rkt | 1 + racket/src/expander/expand/top.rkt | 49 ++- racket/src/racket/src/startup.inc | 368 ++++++++++++++---- 4 files changed, 367 insertions(+), 74 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/macro.rktl b/pkgs/racket-test-core/tests/racket/macro.rktl index 8b26d35674..c2f88cffc8 100644 --- a/pkgs/racket-test-core/tests/racket/macro.rktl +++ b/pkgs/racket-test-core/tests/racket/macro.rktl @@ -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)) diff --git a/racket/src/expander/expand/main.rkt b/racket/src/expander/expand/main.rkt index 4b27f439f1..2f09902248 100644 --- a/racket/src/expander/expand/main.rkt +++ b/racket/src/expander/expand/main.rkt @@ -48,6 +48,7 @@ expand/capture-lifts expand-transformer expand+eval-for-syntaxes-binding + context->transformer-context eval-for-syntaxes-binding eval-for-bindings diff --git a/racket/src/expander/expand/top.rkt b/racket/src/expander/expand/top.rkt index 3f451696d3..20ce83672b 100644 --- a/racket/src/expander/expand/top.rkt +++ b/racket/src/expander/expand/top.rkt @@ -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 diff --git a/racket/src/racket/src/startup.inc b/racket/src/racket/src/startup.inc index 25df0a6875..cbe423ce88 100644 --- a/racket/src/racket/src/startup.inc +++ b/racket/src/racket/src/startup.inc @@ -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)))))" ;