diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-05-15 06:40:03 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-05-15 06:40:03 -0700 |
commit | f1cb385c90eb80200c36fa2628e023958472ec39 (patch) | |
tree | 994aff54aa47dcc0feabb23eaf5b07462b6516dd | |
parent | 47dd339b4ae661aca9773560d83072d649a88919 (diff) | |
download | txr-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-- | ChangeLog | 10 | ||||
-rw-r--r-- | eval.c | 26 | ||||
-rw-r--r-- | txr.1 | 98 |
3 files changed, 122 insertions, 12 deletions
@@ -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 @@ -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)); @@ -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 ) |