diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-06-08 20:40:34 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-06-08 20:40:34 -0700 |
commit | cfbf9c994f3c2cf352fe3dc3ba55df54e01bc94d (patch) | |
tree | 99f12b66af1faf928d5bdd07bf38019fc35a2020 | |
parent | f50c31c9571d96dcd6ec3880e12f0357a56bbcb6 (diff) | |
download | txr-cfbf9c994f3c2cf352fe3dc3ba55df54e01bc94d.tar.gz txr-cfbf9c994f3c2cf352fe3dc3ba55df54e01bc94d.tar.bz2 txr-cfbf9c994f3c2cf352fe3dc3ba55df54e01bc94d.zip |
Fixing semantics of makunbound.
* eval.c (unbound_s): New symbol variable.
(lookup_var): If a dynamic binding has the special sys:unbound
symbol as its value, then return nil, so the behavior
is as if there is no binding.
(makunbound): If the symbol exists in a dynamic environment,
then replace its value with sys:unbound, making it look
unbound.
(eval_init): Initialize unbound_s.
* lib.h (us_car, us_cdr): New inline functions.
* txr.1: New dialect notes under boundp.
Updated the makunbound documentation. Separated
makunbound documentation from fmakunbound and
mmakunbound. Added compatibility notes.
-rw-r--r-- | eval.c | 22 | ||||
-rw-r--r-- | lib.h | 2 | ||||
-rw-r--r-- | txr.1 | 134 |
3 files changed, 124 insertions, 34 deletions
@@ -100,7 +100,8 @@ val fbind_s, lbind_s, flet_s, labels_s; val opip_s, oand_s, chain_s, chand_s; val sys_load_s, self_load_path_s, sys_lisp1_value_s; -val special_s, whole_k, form_k, symacro_k; +val special_s, unbound_s; +val whole_k, form_k, symacro_k; val last_form_evaled, last_form_expanded; @@ -334,7 +335,7 @@ val lookup_var(val env, val sym) for (env = dyn_env; env; env = env->e.up_env) { val binding = assoc(sym, env->e.vbindings); if (binding) - return binding; + return if3(us_cdr(binding) == unbound_s, nil, binding); } return lookup_global_var(sym); @@ -3957,10 +3958,24 @@ val special_operator_p(val sym) static val makunbound(val sym) { - lisplib_try_load(sym), + val env; + + lisplib_try_load(sym); + + if (!opt_compat || opt_compat > 143) { + for (env = dyn_env; env; env = env->e.up_env) { + val binding = assoc(sym, env->e.vbindings); + if (binding) { + rplacd(binding, unbound_s); + return sym; + } + } + } + remhash(top_vb, sym); remhash(top_smb, sym); remhash(special, sym); + return sym; } @@ -4685,6 +4700,7 @@ void eval_init(void) whole_k = intern(lit("whole"), keyword_package); form_k = intern(lit("form"), keyword_package); special_s = intern(lit("special"), system_package); + unbound_s = intern(lit("unbound"), system_package); symacro_k = intern(lit("symacro"), keyword_package); prof_s = intern(lit("prof"), user_package); opip_s = intern(lit("opip"), user_package); @@ -478,6 +478,8 @@ val type_check3(val obj, int, int, int); val class_check(val cobj, val class_sym); val car(val cons); val cdr(val cons); +INLINE val us_car(val cons) { return cons->c.car; } +INLINE val us_cdr(val cons) { return cons->c.cdr; } val rplaca(val cons, val new_car); val rplacd(val cons, val new_car); val sys_rplaca(val cons, val new_car); @@ -13770,7 +13770,20 @@ if the symbol has a function binding in the global environment, otherwise it returns nil .codn nil . -.TP* "Dialect Note:" +.code mboundp +returns +.code t +if the symbol has an operator macro binding in the global environment, +otherwise +.codn nil . + +.TP* "Dialect Notes:" + +The +.code boundp +function in ANSI Common Lisp doesn't report that +global symbol macros have a binding. They are not considered +bindings. In \*(TL, they are considered bindings. The ANSI Common Lisp .code fboundp @@ -13783,12 +13796,9 @@ in Common Lisp can be obtained in \*(TL using the .cble expression. +The .code mboundp -returns -.code t -if the symbol has an operator macro binding in the global environment, -otherwise -.codn nil . +function doesn't exist in ANSI Common Lisp. .coNP Functions @, makunbound @ fmakunbound and @ mmakunbound .synb @@ -13799,24 +13809,91 @@ otherwise .desc The function .code makunbound -removes any binding for +the binding of .meta symbol -from the variable namespace of the global environment. If +from either the dynamic environment or the global symbol +macro environment. After the call to +.codn makunbound , .meta symbol -has no such binding, it does nothing. -In either case, it returns -.metn symbol . +appears to be unbound. -Both variables and symbol macros are bindings in the variable namespace. +If the +.code makunbound +call takes place in a scope in which there exists a dynamic rebinding of +.metn symbol , +the information for restoring the previous binding is not +affected by +.codn makunbound . +When that scope terminates, the previous binding will be restored. -Additionally, if +If the +.code makunbound +call takes place in a scope in which the dynamic binding for +.code symbol +is the global binding, then the global binding is removed. +When the global binding is removed, then +if .meta symbol -was previously marked as special, for instance +was previously marked as special (for instance by -.codn defvar , -this marking is removed by -.codn makunbound . +.codn defvar ) +this marking is removed. + +Otherwise if +.meta symbol +has a global symbol macro binding, that binding is removed. + +If +.meta symbol +has no apparent dynamic binding, and no global symbol macro binding, +.code makunbound +does nothing. + +In all cases, +.code makunbound +returns +.metn symbol . + +.TP* "Dialect Note:" + +The behavior of +.code makunbound +differs from its counterpart in ANSI Common Lisp. + +The +.code makunbound +function in Common Lisp only removes a value from a dynamic variable. The +dynamic variable does not cease to exist, it only ceases to have a value +(because a binding is a value). In \*(TL, the variable ceases to exist. The +binding of a variable isn't its value, it is the variable itself: the +association between a name and an abstract storage location, in some +environment. If the binding is undone, the variable disappears. + +The +.code makunbound +function in Common Lisp does not remove global symbol macros, +which are not considered to be bindings in the variable namespace. +That is to say, the Common Lisp +.code boundp +does not report true for symbol macros. +The Common Lisp +.code makunbound +also doesn't remove the special attribute from a symbol. If a variable +is introduced with +.code defvar +and then removed with +.codn makunbound , +the symbol continues to exhibit dynamic binding rather than lexical +in subsequent scopes. In \*(TL, if a global binding is removed, so +is the special attribute. + +.coNP Functions @ fmakunbound and @ mmakunbound +.synb +.mets (fmakunbound << symbol ) +.mets (mmakunbound << symbol ) +.syne +.desc The function .code fmakunbound removes any binding for @@ -13839,19 +13916,9 @@ In either case, it returns .TP* "Dialect Note:" -The behavior of these functions differs from ANSI Common Lisp. - -The -.code makunbound -function in Common Lisp only removes a value from a dynamic variable. The -dynamic variable does not cease to exist, it only ceases to have a value -(because a binding is a value). The special property from a symbol is also not -removed. In \*(TL, the variable ceases to exist. The binding -of a variable isn't its value, it is the variable itself: the association -between a name and an abstract storage location, in some environment. -If the binding is undone, the variable disappears. - -The +The behavior of +.code fmakunbound +differs from its counterpart in ANSI Common Lisp. The .code fmakunbound function in Common Lisp removes a function or macro binding, which do not coexist. @@ -43095,7 +43162,12 @@ selects the behaviors described below for version 105, but not those for 102. .IP 143 Until version 143, the .code stdlib -variable didn't include the trailing slash. +variable didn't include the trailing slash. The +.code makunbound +function semantics changed after version 143 to be more +compatible with ANSI Common Lisp. Until 143, that function removed +only the global binding, leaving the dynamic rebinding of a variable +intact. .IP 142 Until version 142, the \*(TX pattern language supported a prefix convention on data sources. Data sources beginning with the character |