fix missing expansion context for prop:rename-transformer
proc
When calling a procedure that is attached as a `prop:rename-transformer` property value, make sure that any available expansion context is accessible as reflected by `(syntax-transforming?)`. Syntax parameters as rename transformers particularly rely on that information for local expansion. Thanks to Jay for the "stxparam.rktl" test. Closes #1479
This commit is contained in:
parent
d9750064b9
commit
a1a2d9c2c7
|
@ -1665,6 +1665,38 @@
|
||||||
|
|
||||||
(test '(1 2 3) dynamic-require ''uses-local-lift-values-at-expansion-time 'l)
|
(test '(1 2 3) dynamic-require ''uses-local-lift-values-at-expansion-time 'l)
|
||||||
|
|
||||||
|
;; ----------------------------------------
|
||||||
|
;; Check that a `prop:rename-transformer` procedure is called in a
|
||||||
|
;; `syntax-transforming?` mode when used as an expression
|
||||||
|
|
||||||
|
(let ([x 'one]
|
||||||
|
[bad 'bad])
|
||||||
|
(let-syntax ([also-x (let ()
|
||||||
|
(struct ax ()
|
||||||
|
#:property
|
||||||
|
prop:rename-transformer
|
||||||
|
(lambda (an-ax)
|
||||||
|
(make-will-executor)
|
||||||
|
(if (syntax-transforming?)
|
||||||
|
#'x
|
||||||
|
#'bad)))
|
||||||
|
(ax))])
|
||||||
|
(test 'one values also-x)))
|
||||||
|
|
||||||
|
(let ([x 'two]
|
||||||
|
[bad 'bad])
|
||||||
|
(let-syntax ([also-x (let ()
|
||||||
|
(struct ax ()
|
||||||
|
#:property
|
||||||
|
prop:rename-transformer
|
||||||
|
(lambda (an-ax)
|
||||||
|
(make-will-executor)
|
||||||
|
(if (syntax-transforming?)
|
||||||
|
(syntax-property #'x 'not-free-identifier=? #t)
|
||||||
|
#'bad)))
|
||||||
|
(ax))])
|
||||||
|
(test 'two values also-x)))
|
||||||
|
|
||||||
;; ----------------------------------------
|
;; ----------------------------------------
|
||||||
|
|
||||||
(report-errs)
|
(report-errs)
|
||||||
|
|
|
@ -175,6 +175,36 @@
|
||||||
(with-handlers ([exn:fail? (λ (x) (exn-message x))])
|
(with-handlers ([exn:fail? (λ (x) (exn-message x))])
|
||||||
(eval #'(syntax-parameterize ([x (make-rename-transformer #'f)]) 1)))))
|
(eval #'(syntax-parameterize ([x (make-rename-transformer #'f)]) 1)))))
|
||||||
|
|
||||||
|
;; ----------------------------------------
|
||||||
|
;; Check rename-transformer stx-param when used as an expression,
|
||||||
|
;; which involves calling the `prop:rename-transformer` is a
|
||||||
|
;; `syntax-transforming?` mode
|
||||||
|
|
||||||
|
(begin
|
||||||
|
(define-syntax (slv stx)
|
||||||
|
(syntax-case stx ()
|
||||||
|
[(_ t)
|
||||||
|
#`'#,(object-name (syntax-local-value #'t))]))
|
||||||
|
|
||||||
|
(define-syntax one (procedure-rename (λ (stx) #'1) 'one))
|
||||||
|
(define-syntax two (procedure-rename (λ (stx) #'2) 'two))
|
||||||
|
|
||||||
|
(define-syntax-parameter normal
|
||||||
|
(make-rename-transformer #'one))
|
||||||
|
(test #f eq? (slv normal) 'one)
|
||||||
|
(test #t = normal 1)
|
||||||
|
(syntax-parameterize ([normal (make-rename-transformer #'two)])
|
||||||
|
(test #f eq? (slv normal) 'two)
|
||||||
|
(test #t = normal 2))
|
||||||
|
|
||||||
|
(define-rename-transformer-parameter rt
|
||||||
|
(make-rename-transformer #'one))
|
||||||
|
(test #t eq? (slv rt) 'one)
|
||||||
|
(test #t = rt 1)
|
||||||
|
(syntax-parameterize ([rt (make-rename-transformer #'two)])
|
||||||
|
(test #t eq? (slv rt) 'two)
|
||||||
|
(test #t = rt 2)))
|
||||||
|
|
||||||
;; ----------------------------------------
|
;; ----------------------------------------
|
||||||
|
|
||||||
(report-errs)
|
(report-errs)
|
||||||
|
|
|
@ -1339,7 +1339,7 @@ set_compile (Scheme_Object *form, Scheme_Comp_Env *env, Scheme_Compile_Info *rec
|
||||||
|
|
||||||
return scheme_compile_expr(form, env, rec, drec);
|
return scheme_compile_expr(form, env, rec, drec);
|
||||||
} else if (scheme_is_rename_transformer(SCHEME_PTR_VAL(var))) {
|
} else if (scheme_is_rename_transformer(SCHEME_PTR_VAL(var))) {
|
||||||
find_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var));
|
find_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var), env);
|
||||||
SCHEME_USE_FUEL(1);
|
SCHEME_USE_FUEL(1);
|
||||||
menv = NULL;
|
menv = NULL;
|
||||||
} else
|
} else
|
||||||
|
@ -1435,7 +1435,7 @@ set_expand(Scheme_Object *orig_form, Scheme_Comp_Env *env, Scheme_Expand_Info *e
|
||||||
return scheme_expand_expr(form, env, erec, drec);
|
return scheme_expand_expr(form, env, erec, drec);
|
||||||
} else if (scheme_is_rename_transformer(SCHEME_PTR_VAL(var))) {
|
} else if (scheme_is_rename_transformer(SCHEME_PTR_VAL(var))) {
|
||||||
Scheme_Object *new_name;
|
Scheme_Object *new_name;
|
||||||
new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var));
|
new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var), env);
|
||||||
new_name = scheme_stx_track(new_name, find_name, find_name);
|
new_name = scheme_stx_track(new_name, find_name, find_name);
|
||||||
find_name = new_name;
|
find_name = new_name;
|
||||||
menv = NULL;
|
menv = NULL;
|
||||||
|
@ -3602,7 +3602,7 @@ void scheme_bind_syntaxes(const char *where, Scheme_Object *names, Scheme_Object
|
||||||
if (scheme_is_binding_rename_transformer(SCHEME_PTR_VAL(macro))) {
|
if (scheme_is_binding_rename_transformer(SCHEME_PTR_VAL(macro))) {
|
||||||
/* Rebind to the target identifier's binding */
|
/* Rebind to the target identifier's binding */
|
||||||
scheme_add_binding_copy(name,
|
scheme_add_binding_copy(name,
|
||||||
scheme_rename_transformer_id(SCHEME_PTR_VAL(macro)),
|
scheme_rename_transformer_id(SCHEME_PTR_VAL(macro), rhs_env),
|
||||||
scheme_make_integer(stx_env->genv->phase));
|
scheme_make_integer(stx_env->genv->phase));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4363,7 +4363,7 @@ Scheme_Object *scheme_check_immediate_macro(Scheme_Object *first,
|
||||||
if (scheme_is_rename_transformer(SCHEME_PTR_VAL(val))) {
|
if (scheme_is_rename_transformer(SCHEME_PTR_VAL(val))) {
|
||||||
/* It's a rename. Look up the target name and try again. */
|
/* It's a rename. Look up the target name and try again. */
|
||||||
Scheme_Object *new_name;
|
Scheme_Object *new_name;
|
||||||
new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(val));
|
new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(val), env);
|
||||||
if (!rec[drec].comp)
|
if (!rec[drec].comp)
|
||||||
new_name = scheme_stx_track(new_name, name, name);
|
new_name = scheme_stx_track(new_name, name, name);
|
||||||
name = scheme_transfer_srcloc(new_name, name);
|
name = scheme_transfer_srcloc(new_name, name);
|
||||||
|
@ -4570,7 +4570,7 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env,
|
||||||
scheme_frame_to_expansion_context_symbol(env->flags))) {
|
scheme_frame_to_expansion_context_symbol(env->flags))) {
|
||||||
/* It's a rename. Look up the target name and try again. */
|
/* It's a rename. Look up the target name and try again. */
|
||||||
Scheme_Object *new_name;
|
Scheme_Object *new_name;
|
||||||
new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var));
|
new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var), env);
|
||||||
if (!rec[drec].comp) {
|
if (!rec[drec].comp) {
|
||||||
new_name = scheme_stx_track(new_name, find_name, find_name);
|
new_name = scheme_stx_track(new_name, find_name, find_name);
|
||||||
}
|
}
|
||||||
|
@ -4701,7 +4701,7 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env,
|
||||||
scheme_frame_to_expansion_context_symbol(env->flags))) {
|
scheme_frame_to_expansion_context_symbol(env->flags))) {
|
||||||
/* It's a rename. Look up the target name and try again. */
|
/* It's a rename. Look up the target name and try again. */
|
||||||
Scheme_Object *new_name;
|
Scheme_Object *new_name;
|
||||||
new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var));
|
new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var), env);
|
||||||
if (!rec[drec].comp) {
|
if (!rec[drec].comp) {
|
||||||
new_name = scheme_stx_track(new_name, find_name, find_name);
|
new_name = scheme_stx_track(new_name, find_name, find_name);
|
||||||
}
|
}
|
||||||
|
@ -4800,7 +4800,7 @@ compile_expand_expr(Scheme_Object *form, Scheme_Comp_Env *env,
|
||||||
if (scheme_expansion_contexts_include(SCHEME_PTR_VAL(var),
|
if (scheme_expansion_contexts_include(SCHEME_PTR_VAL(var),
|
||||||
scheme_frame_to_expansion_context_symbol(env->flags))) {
|
scheme_frame_to_expansion_context_symbol(env->flags))) {
|
||||||
Scheme_Object *new_name;
|
Scheme_Object *new_name;
|
||||||
new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var));
|
new_name = scheme_rename_transformer_id(SCHEME_PTR_VAL(var), env);
|
||||||
if (!rec[drec].comp) {
|
if (!rec[drec].comp) {
|
||||||
new_name = scheme_stx_track(new_name, find_name, find_name);
|
new_name = scheme_stx_track(new_name, find_name, find_name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1623,7 +1623,7 @@ void scheme_shadow(Scheme_Env *env, Scheme_Object *n, Scheme_Object *val, int as
|
||||||
/* If the binding is a rename transformer, also install
|
/* If the binding is a rename transformer, also install
|
||||||
a mapping */
|
a mapping */
|
||||||
if (scheme_is_binding_rename_transformer(val))
|
if (scheme_is_binding_rename_transformer(val))
|
||||||
scheme_add_binding_copy(id, scheme_rename_transformer_id(val), scheme_env_phase(env));
|
scheme_add_binding_copy(id, scheme_rename_transformer_id(val, NULL), scheme_env_phase(env));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void install_one_binding_name(Scheme_Hash_Table *bt, Scheme_Object *name, Scheme_Object *id, Scheme_Env *benv)
|
static void install_one_binding_name(Scheme_Hash_Table *bt, Scheme_Object *name, Scheme_Object *id, Scheme_Env *benv)
|
||||||
|
@ -2361,7 +2361,7 @@ do_local_exp_time_value(const char *name, int argc, Scheme_Object *argv[], int r
|
||||||
|
|
||||||
v = SCHEME_PTR_VAL(v);
|
v = SCHEME_PTR_VAL(v);
|
||||||
if (scheme_is_rename_transformer(v)) {
|
if (scheme_is_rename_transformer(v)) {
|
||||||
sym = scheme_transfer_srcloc(scheme_rename_transformer_id(v), sym);
|
sym = scheme_transfer_srcloc(scheme_rename_transformer_id(v, NULL), sym);
|
||||||
renamed = 1;
|
renamed = 1;
|
||||||
menv = NULL;
|
menv = NULL;
|
||||||
SCHEME_USE_FUEL(1);
|
SCHEME_USE_FUEL(1);
|
||||||
|
@ -2984,7 +2984,7 @@ rename_transformer_target(int argc, Scheme_Object *argv[])
|
||||||
if (!scheme_is_rename_transformer(argv[0]))
|
if (!scheme_is_rename_transformer(argv[0]))
|
||||||
scheme_wrong_contract("rename-transformer-target", "rename-transformer?", 0, argc, argv);
|
scheme_wrong_contract("rename-transformer-target", "rename-transformer?", 0, argc, argv);
|
||||||
|
|
||||||
return scheme_rename_transformer_id(argv[0]);
|
return scheme_rename_transformer_id(argv[0], NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Scheme_Object *
|
static Scheme_Object *
|
||||||
|
|
|
@ -1924,7 +1924,7 @@ scheme_apply_macro(Scheme_Object *name, Scheme_Env *menv,
|
||||||
if (scheme_is_rename_transformer(rator)) {
|
if (scheme_is_rename_transformer(rator)) {
|
||||||
Scheme_Object *scope;
|
Scheme_Object *scope;
|
||||||
|
|
||||||
rator = scheme_rename_transformer_id(rator);
|
rator = scheme_rename_transformer_id(rator, env);
|
||||||
/* rator is now an identifier */
|
/* rator is now an identifier */
|
||||||
|
|
||||||
/* and it's introduced by this expression: */
|
/* and it's introduced by this expression: */
|
||||||
|
|
|
@ -6693,7 +6693,7 @@ static void eval_exptime(Scheme_Object *names, int count,
|
||||||
if (SCHEME_TRUEP(ids_for_rename_trans)
|
if (SCHEME_TRUEP(ids_for_rename_trans)
|
||||||
&& scheme_is_binding_rename_transformer(values[i])) {
|
&& scheme_is_binding_rename_transformer(values[i])) {
|
||||||
scheme_add_binding_copy(SCHEME_CAR(ids_for_rename_trans),
|
scheme_add_binding_copy(SCHEME_CAR(ids_for_rename_trans),
|
||||||
scheme_rename_transformer_id(values[i]),
|
scheme_rename_transformer_id(values[i], NULL),
|
||||||
scheme_make_integer(at_phase-1));
|
scheme_make_integer(at_phase-1));
|
||||||
}
|
}
|
||||||
scheme_add_to_table(syntax, (const char *)name, macro, 0);
|
scheme_add_to_table(syntax, (const char *)name, macro, 0);
|
||||||
|
@ -6714,7 +6714,7 @@ static void eval_exptime(Scheme_Object *names, int count,
|
||||||
if (SCHEME_TRUEP(ids_for_rename_trans)
|
if (SCHEME_TRUEP(ids_for_rename_trans)
|
||||||
&& scheme_is_binding_rename_transformer(vals)) {
|
&& scheme_is_binding_rename_transformer(vals)) {
|
||||||
scheme_add_binding_copy(SCHEME_CAR(ids_for_rename_trans),
|
scheme_add_binding_copy(SCHEME_CAR(ids_for_rename_trans),
|
||||||
scheme_rename_transformer_id(vals),
|
scheme_rename_transformer_id(vals, NULL),
|
||||||
scheme_make_integer(at_phase-1));
|
scheme_make_integer(at_phase-1));
|
||||||
}
|
}
|
||||||
scheme_add_to_table(syntax, (const char *)name, macro, 0);
|
scheme_add_to_table(syntax, (const char *)name, macro, 0);
|
||||||
|
|
|
@ -2149,6 +2149,7 @@ Scheme_Object *scheme_all_current_continuation_marks(void);
|
||||||
|
|
||||||
void scheme_about_to_move_C_stack(void);
|
void scheme_about_to_move_C_stack(void);
|
||||||
|
|
||||||
|
Scheme_Object *scheme_apply_with_dynamic_state(Scheme_Object *rator, int num_rands, Scheme_Object **rands, Scheme_Dynamic_State *dyn_state);
|
||||||
Scheme_Object *scheme_apply_multi_with_dynamic_state(Scheme_Object *rator, int num_rands, Scheme_Object **rands, Scheme_Dynamic_State *dyn_state);
|
Scheme_Object *scheme_apply_multi_with_dynamic_state(Scheme_Object *rator, int num_rands, Scheme_Object **rands, Scheme_Dynamic_State *dyn_state);
|
||||||
|
|
||||||
Scheme_Object *scheme_jump_to_continuation(Scheme_Object *obj, int num_rands, Scheme_Object **rands,
|
Scheme_Object *scheme_jump_to_continuation(Scheme_Object *obj, int num_rands, Scheme_Object **rands,
|
||||||
|
@ -3681,7 +3682,7 @@ Scheme_Object *scheme_make_marshal_shared(Scheme_Object *v);
|
||||||
|
|
||||||
int scheme_is_rename_transformer(Scheme_Object *o);
|
int scheme_is_rename_transformer(Scheme_Object *o);
|
||||||
int scheme_is_binding_rename_transformer(Scheme_Object *o);
|
int scheme_is_binding_rename_transformer(Scheme_Object *o);
|
||||||
Scheme_Object *scheme_rename_transformer_id(Scheme_Object *o);
|
Scheme_Object *scheme_rename_transformer_id(Scheme_Object *o, Scheme_Comp_Env *env);
|
||||||
int scheme_is_set_transformer(Scheme_Object *o);
|
int scheme_is_set_transformer(Scheme_Object *o);
|
||||||
Scheme_Object *scheme_set_transformer_proc(Scheme_Object *o);
|
Scheme_Object *scheme_set_transformer_proc(Scheme_Object *o);
|
||||||
|
|
||||||
|
|
|
@ -1885,7 +1885,7 @@ int scheme_is_rename_transformer(Scheme_Object *o)
|
||||||
int scheme_is_binding_rename_transformer(Scheme_Object *o)
|
int scheme_is_binding_rename_transformer(Scheme_Object *o)
|
||||||
{
|
{
|
||||||
if (scheme_is_rename_transformer(o)) {
|
if (scheme_is_rename_transformer(o)) {
|
||||||
o = scheme_rename_transformer_id(o);
|
o = scheme_rename_transformer_id(o, NULL);
|
||||||
o = scheme_stx_property(o, not_free_id_symbol, NULL);
|
o = scheme_stx_property(o, not_free_id_symbol, NULL);
|
||||||
if (o && SCHEME_TRUEP(o))
|
if (o && SCHEME_TRUEP(o))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1898,7 +1898,7 @@ static int is_stx_id(Scheme_Object *o) { return (SCHEME_STXP(o) && SCHEME_SYMBOL
|
||||||
|
|
||||||
static int is_stx_id_or_proc_1(Scheme_Object *o) { return (is_stx_id(o) || is_proc_1(o)); }
|
static int is_stx_id_or_proc_1(Scheme_Object *o) { return (is_stx_id(o) || is_proc_1(o)); }
|
||||||
|
|
||||||
Scheme_Object *scheme_rename_transformer_id(Scheme_Object *o)
|
Scheme_Object *scheme_rename_transformer_id(Scheme_Object *o, Scheme_Comp_Env *comp_env)
|
||||||
{
|
{
|
||||||
Scheme_Object *a[1];
|
Scheme_Object *a[1];
|
||||||
|
|
||||||
|
@ -1911,7 +1911,18 @@ Scheme_Object *scheme_rename_transformer_id(Scheme_Object *o)
|
||||||
a[0] = o;
|
a[0] = o;
|
||||||
/* apply a continuation barrier here to prevent a capture in
|
/* apply a continuation barrier here to prevent a capture in
|
||||||
* the property access */
|
* the property access */
|
||||||
|
if (comp_env && (scheme_current_thread->current_local_env != comp_env)) {
|
||||||
|
/* Getting identifier during an expansion context */
|
||||||
|
Scheme_Dynamic_State dyn_state;
|
||||||
|
Scheme_Env *genv = comp_env->genv;
|
||||||
|
scheme_set_dynamic_state(&dyn_state, comp_env, NULL, NULL, scheme_false,
|
||||||
|
genv, (genv->module
|
||||||
|
? (genv->link_midx ? genv->link_midx : genv->module->me->src_modidx)
|
||||||
|
: NULL));
|
||||||
|
v = scheme_apply_with_dynamic_state(v, 1, a, &dyn_state);
|
||||||
|
} else {
|
||||||
v = scheme_apply(v, 1, a);
|
v = scheme_apply(v, 1, a);
|
||||||
|
}
|
||||||
if (!is_stx_id(v)) {
|
if (!is_stx_id(v)) {
|
||||||
scheme_contract_error("prop:rename-transformer",
|
scheme_contract_error("prop:rename-transformer",
|
||||||
"contract violation for given value",
|
"contract violation for given value",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user