summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-05-15 06:40:03 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-05-15 06:40:03 -0700
commitf1cb385c90eb80200c36fa2628e023958472ec39 (patch)
tree994aff54aa47dcc0feabb23eaf5b07462b6516dd
parent47dd339b4ae661aca9773560d83072d649a88919 (diff)
downloadtxr-f1cb385c90eb80200c36fa2628e023958472ec39.tar.gz
txr-f1cb385c90eb80200c36fa2628e023958472ec39.tar.bz2
txr-f1cb385c90eb80200c36fa2628e023958472ec39.zip
* eval.c (symbol_value): Retrieve the binding of a symbol
macro also. (boundp): Return t for symbol macros. (makunbound, fmakunbound): New functions. (eval_init): Register makunbound and fmakunbound. * txr.1: Document changes to symbol-value and boundp, and add dialect notes about the different semantics of binding.
-rw-r--r--ChangeLog10
-rw-r--r--eval.c26
-rw-r--r--txr.198
3 files changed, 122 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index a1b00fd4..77a01b0d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2015-05-15 Kaz Kylheku <kaz@kylheku.com>
+
+ * eval.c (symbol_value): Retrieve the binding of a symbol
+ macro also.
+ (boundp): Return t for symbol macros.
+ (makunbound, fmakunbound): New functions.
+ (eval_init): Register makunbound and fmakunbound.
+
+ * txr.1: Document changes to symbol-value and boundp.
+
2015-05-14 Kaz Kylheku <kaz@kylheku.com>
* lib.c (replace_list, replace_str, replace_vec): Handle
diff --git a/eval.c b/eval.c
index beecc139..8a5b84df 100644
--- a/eval.c
+++ b/eval.c
@@ -3283,7 +3283,10 @@ static val mapdov(val fun, val list_of_lists)
static val symbol_value(val sym)
{
- return cdr(lookup_var(nil, sym));
+ uses_or2;
+
+ return cdr(or2(lookup_var(nil, sym),
+ lookup_symac(nil, sym)));
}
static val symbol_function(val sym)
@@ -3296,7 +3299,7 @@ static val symbol_function(val sym)
static val boundp(val sym)
{
- return if3(lookup_var(nil, sym), t, nil);
+ return if2(lookup_var(nil, sym) || lookup_symac(nil, sym), t);
}
static val fboundp(val sym)
@@ -3305,6 +3308,23 @@ static val fboundp(val sym)
gethash(op_table, sym), t);
}
+static val makunbound(val sym)
+{
+ lisplib_try_load(sym),
+ remhash(top_vb, sym);
+ remhash(top_smb, sym);
+ remhash(special, sym);
+ return sym;
+}
+
+static val fmakunbound(val sym)
+{
+ lisplib_try_load(sym),
+ remhash(top_fb, sym);
+ remhash(top_mb, sym);
+ return sym;
+}
+
static val rangev_func(val env, val lcons)
{
cons_bind (from, to_step, env);
@@ -4370,6 +4390,8 @@ void eval_init(void)
reg_fun(intern(lit("symbol-function"), user_package), func_n1(symbol_function));
reg_fun(intern(lit("boundp"), user_package), func_n1(boundp));
reg_fun(intern(lit("fboundp"), user_package), func_n1(fboundp));
+ reg_fun(intern(lit("makunbound"), user_package), func_n1(makunbound));
+ reg_fun(intern(lit("fmakunbound"), user_package), func_n1(fmakunbound));
reg_fun(intern(lit("func-get-form"), user_package), func_n1(func_get_form));
reg_fun(intern(lit("func-get-env"), user_package), func_n1(func_get_env));
reg_fun(intern(lit("func-set-env"), user_package), func_n2(func_set_env));
diff --git a/txr.1 b/txr.1
index c5204df5..7c6328fa 100644
--- a/txr.1
+++ b/txr.1
@@ -9711,7 +9711,7 @@ Certain variables in \*(TX's library break this convention; however, they at
least have distinct prefixes, examples being example s-ifmt, log-emerg and
sig-hup.
-Example:
+.TP* "Example:"
.cblk
(defvar *x* 42) ;; *x* has a value of 42
@@ -9725,6 +9725,31 @@ Example:
(print-x) ;; *x* is 42 again and so "42" is printed
.cble
+.TP* "Dialect Note:"
+
+The terms
+.I bind
+and
+.I binding
+are used differently in \*(TL compared to ANSI Common Lisp.
+In \*(TL binding is an association between a symbol and an abstract storage
+location. The association is registered in some namespace, such as the global
+namespace or a lexical scope. That storage location, in turn, contains a
+value. In ANSI Lisp, a binding of a dynamic variable is the association between
+the symbol and a value. It is possible for a dynamic variable to exist, and
+not have a value. A value can be assigned, which creates a binding.
+In \*(TL, an assignment is an operation which transfers a value into
+a binding, not one which creates a binding.
+
+In ANSI Lisp, a dynamic variable can exist which has no value. Accessing
+the value signals a condition, but storing a value is permitted; doing so
+creates a binding. By contrast, in \*(TL a global variable cannot exist without
+a value. If a
+.code defvar
+form doesn't specify a value, and the variable doesn't exist, it is
+created with a value of
+.codn nil .
+
.SH* TXR LISP OPERATOR AND FUNCTION LIBRARY
A compound expression with a symbol as its first element, if
intended to be evaluated, denotes either an operator invocation or a function
@@ -11815,14 +11840,8 @@ operator binding is returned, and if that doesn't exist, then
.code nil
is returned.
-The
-.code symbol-value
-function retrieves the value of a global variable, if it exists,
-otherwise
-.codn nil .
-
-Note: a function binding is a function, but a macro or special operator binding
-binding isn't. The value of a macro binding is a list of the following form:
+The value of a macro binding isn't a functio object, but a list of the
+following form:
.cblk
.mets (#<environment object> < macro-parameter-list << body-form *)
@@ -11837,6 +11856,14 @@ printed representation looks like:
These details may change in future version of \*(TX.
+The
+.code symbol-value
+function retrieves the value of a either a global variable or a global
+symbol macro, whichever exists. Otherwise it returns
+.codn nil .
+
+The value of a symbol macro binding is simply the replacement form.
+
.TP* "Dialect note:"
Forms which call
.code symbol-function
@@ -11855,7 +11882,7 @@ operator defines functions.
.code boundp
returns
.code t
-if the symbol has a variable binding in the global
+if the symbol is bound as a variable or symbol macro in the global
environment, otherwise
.codn nil .
@@ -11866,6 +11893,57 @@ if the symbol has a function or macro binding in the global
environment, or if it is an operator, otherwise
.codn nil .
+.coNP Functions @ makunbound and @ fmakunbound
+.synb
+.mets (makunbound << symbol )
+.mets (fmakunbound << symbol )
+.syne
+.desc
+The function
+.code makunbound
+removes any binding for
+.meta symbol
+from the variable namespace of the global environment. If
+.meta symbol
+has no such binding, it does nothing.
+In either case, it returns
+.metn symbol .
+
+Both variables and symbol macros are bindings in the variable namespace.
+
+Additionally, if
+.meta symbol
+was previously marked as special, for instance
+by
+.codn defvar ,
+this marking is removed by
+.codn makunbound .
+
+The function
+.code fmakunbound
+removes any binding for
+.meta symbol
+from the function namespace of the global environment. If
+.meta symbol
+has no such binding, it does nothing.
+In either case, it returns
+.metn symbol .
+
+Both functions and macros are bindings in the function namespace.
+
+.TP* "Dialect Note:"
+
+The behavior of these functions differs from ANSI Common Lisp.
+The
+.code makunbound
+function in ANSI 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.
+
.coNP Function @ func-get-form
.synb
.mets (func-get-form << func )