summaryrefslogtreecommitdiffstats
path: root/eval.c
Commit message (Collapse)AuthorAgeFilesLines
...
* Different approach for specials in let/let*.Kaz Kylheku2016-12-201-36/+49
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This addresses a problem with the new scheme for handling specials. If we let specials be bound in the lexical environment and then do the swizzle into the dynamic environment using sys:with-dyn-rebinds, that only works correctly for parallel bindings (and thus also for lambda and macro parameters). For sequential bindings, it exposes the possibility that a closure is created during the sequential binding which captures a would-be special variable while it is still in the lexical stage. That closure can be thrown out of there, so the sys:with-dyn-rebinds is never reached which swizzles the variable. The new scheme is very simple. When expanding a let, we tranform (s init) to (s (sys:dvbind s init)) if s is a special variable. This new sys:dvbind operator binds s to the value of the init expression in a newly created dynamic environment, and returns the #:unbound symbol, which is received by the lexical s. Problem solved. The only thing remains is that the let special operator must save and restore the dynamic environment. There is no need for sys:with-dyn-rebinds around the body of a let, but we keep that mechanism and approach for handling specials in argument lists. * eval.c (dvbind_s): New symbol variale. (bindings_helper): Lose the env_out argument; return the new environment. No caller uses the returned bindings any more. (op_let): Call bindings_helper in initializing expression of new_env. Save the dyn_env, and restore it after evaluating the body. (op_dvbind): New static function. (expand_vars): Lose the pspecials argument. Perform the insertion of sys:dvbind. (do_expand): Simplify the let expander: expand_vars no longer outputs a list of specials and there is no need to insert with_dyn_rebinds_s. Add a case for sys:dvbind: assume it requires no expansion. (eval_init): Intern sys:dvbind, and bind it as an operator to the new op_dvbind function.
* Bugfix: sys:unbound mechanism lacks hygiene.Kaz Kylheku2016-12-201-2/+2
| | | | | | | | | | | The genvim.txr program iterates over package symbols and encounters sys:unbound. It binds that to a local variable, creating a problem due to the special hack. Let's turn sys:unbound into a gensym. * eval.c (eval_init): Protect unbound_s from gc. Initialize unbound_s with an uninterned symbol created by make_sym.
* Remove more vestiges of old specials handling.Kaz Kylheku2016-12-201-6/+0
| | | | | | | | * eval.c (struct bindings_helper_vars): Remove de member. (copy_bh_env_handler): Remove copying of dynamic environment. (bindings_helper): Remove all code dealing with de. The sequential binding will no longer introduce a dynamic environment.
* Remove vestiges of old special binding scheme.Kaz Kylheku2016-12-191-66/+17
| | | | | | | | | | | | | | | | | | | | | Removing code which handles the special function argument (sys:special ...) which can occur ahead of the other arguments, indicating the names of arguments which require special binding. Removing code which handles (sys:special init-form var) bindings in let/let*. * eval.c (env_vbind_special): Function removed. (bind_args): Do not look for special list; no such thing occurs. Use env_vbind directly rather than env_vbind special. (bind_macro_params): Likewise. (funcall_interp): Streamlined by not having to check for presence of specials list and setting up the dynamic environment frame for it. (bindings_helper): Don't look for the (sys:special initform sym) syntax among the bindings.
* Changing how binding of special variables works.Kaz Kylheku2016-12-181-60/+72
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The old way: process, at expansion time, bindings in lambda lists and all binding constructs to find special variables (symbols marked special). Replace these bindings with an annotation. Then when the interpreter performs binding, the binding helper functions process these annotations. Also, if specials occur, wrap the construct in sys:with-save-specials to set up the necessary dynamic environment frame. The new way: process, at expansion time, bindings in lambda lists and binding constructs (which have been reduced to just let and let*). If special variables occur, then wrap the body in in sys:with-dyn-rebinds which re-binds specific symbols in the dynamic namespace, copying their value from their lexical binding. The lexical bindings are then replaced with the value sys:unbound, which indicates that the value should be resolved in the dynamic environment. * eval.c (with_saved_vars_s): Symbol variable removed. (with_dyn_rebinds_s): New symbol variable. (lookup_var, lookup_sym_lisp1): If a lexical binding contains the value sys:unbound, then continue the search through the dynamic environment; ignore the remaining lexical environments. (expand_params_rec): Bugfix: neglected collect of special variable in fallback case. (expand_params): Takes body environment, and returns two values as a cons cell. The additional return value is a body that is either the original body, or else is wrapped with sys:with-dyn-rebinds. Removed is the special variable hack inserted into the syntax. (expand_macrolet, expand_tree_cases): Adjust to new expand_params interface. (op_with_saved_vars): Static function removed. (op_with_dyn_rebinds): New static function. (expand_vars): Return list of special variables via pointer argument, rather than just a Boolean which indicates that specials are present. Transformation to special representation is removed. (expand_catch_clause): Adjust to new expand_params interface. (expand_save_specials): Static function removed. (do_expand): Adjust let/let* expansion to new expand_vars interface. Generate the sys:with-dyn-rebinds wrapping around the body. Adjust the defun, lambda and mac-param-bind expanders to the new expand_params interface. Recognize sys:with-dyn-rebinds and don't expand it; all places which generate this form have to expand the internals themselves. (eval_init): Remove initialization of with_saved_var_s, and its registration as an operator. Initialize with_dyn_rebinds_s with interned symbol, and register as operator.
* Refactoring internals of for/each operators.Kaz Kylheku2016-12-181-60/+124
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | NOTE: The socket test cases do not pass under this commit: this is expected. The for and each family of operators will now be macros which expand to let/let* binding construct wrapping a lower level special operator. This is in preparation for a change to how special variable binding is implemented. This change reduces the number of special forms which bind variables. There is a single low-level operator for for loops called sys:for-op. Its syntax is a lot like the C89 for loop: (sys:for-op init-forms test step-forms body). The init-forms do not bind anything; it is just forms. There is a sys:each operator for implementing each, each*, append-each and all those operators. Its syntax is (sys:each-op type-sym optional-vars . body). The type-sym is one of each, append-each or collect-each. If optional-vars is nil, then the operator looks at the immediate lexical environment, and assumes all the bindings there are the each iteration variables and it works with those bindings, like its predecessor did. Otherwise optional-vars is a list of symbols: the operator walks the list and resolves each element to a binding. This is used in two situations: when some of the variables are special (dynamically scoped) or when the variables are bound sequentially with let* and are thus scattered in multiple levels of environment. * eval.c (for_op_s, each_op_s): New symbol variables. (get_bindings): New static function. (op_each): Now implements sys:each-op. (op_for): Now implements sys:for-op. (get_var_syms): New static function. (me_each, me_for): New static functions. (do_expand): Do not expand the each operator family under the same rule. New case handling sys:each-op is introduced due to the different syntax. The for case restructured to handle for_op_s. (eval_init): Intern sys:each-op and sys:for-op symbols. Register the corresponding operators. Move registrations of the public symbols each, each*, for, for* and all the other each variants to be macros. * tests/011/macros-2.expected: Updated with different macro expansion which is now produced for a while loop.
* Adding mismatch function.Kaz Kylheku2016-12-121-0/+1
| | | | | | | | | | * eval.c (eval_init): Register mismatch intrinsic. * lib.c (mismatch): New function. * lib.c (mismatch): Declared. * txr.1: Documented mismatch.
* Improve unbound function warning.Kaz Kylheku2016-12-121-1/+5
| | | | | | * eval.c (do_expand): Do not use the "unbound function" warning if the operator position isn't a symbol which can have a function binding.
* Method lookup doesn't throw on nonexistent slots.Kaz Kylheku2016-12-111-1/+2
| | | | | | | | | | | | * eval.c (lookup_fun): When looking up (meth ...) syntax, avoid calling static_slot with a slot argument which isn't a static slot of the given type, otherwise an exception is thrown. The situation is turned instead into a nil return which just indicates "no binding". This allows, for instance, (fboundp '(meth foo bar)) to be safe. It makes no sense for that to return nil if foo doesn't name a struct type, but to throw an error if bar isn't a static slot in foo.
* New function: endp.Kaz Kylheku2016-12-101-0/+1
| | | | | | | | | | | | | This improves compatibility with other Lisp dialects in a small way. * eval.c (eval_init): Register endp intrinsic. * lib.c (endp): New function. * lib.h (endp): Declared. * txr.1: Documented endp.
* New equot macro: expand then suppress evaluation.Kaz Kylheku2016-12-081-0/+9
| | | | | | | * eval.c (me_equot): New static function. (eval_init): Register equot intrinsic macro. * txr.1: Documented equot.
* Eliminate duplicated warning-suppressing function.Kaz Kylheku2016-11-281-6/+2
| | | | | | | | | | | | | | * eval.c (warning_continue): Static function removed. (no_warn_expand): Use uw_muffle_warning instead of removed function. * parser.y (warning_continue): Static function removed. (parse_once): Use uw_muffle_warning instead of removed function. * unwind.c (uw_muffle_warning): New function. * unwind.h (uw_muffle_warning): Declared.
* bugfix: awk macro spews warnings.Kaz Kylheku2016-11-281-1/+16
| | | | | | | | | | | | | | Rather than fix this in the awk macro, let's just have sys:expand block warnings. * eval.c (warning_continue, no_warn_expand): New static function. (eval_init): Change registration of sys:expand to point to no_warn_expand. * share/txr/stdlib/place.tl (call-update-expander, call-clobber-expander, call-delete-expander, sys:placelet-1): Remove ignwarn wrapping from sys:expand calls.
* Warn about unbound functions.Kaz Kylheku2016-11-271-1/+4
| | | | | | | | | | | | | | * eval.c (do_expand): If a compound form doesn't expand into anything, then let us check whether it calls an unbound function, and issue a warning. * share/txr/stdlib/place.tl (sys:pl-expand): Move function definition ahead of first use to suppress unbound function warning. Eventually we will have a relaxed model of deferred warning about this. (sys:placelet-1): Suppress warnings around call to sys:expand because we are expanding a body into which we inserted function calls without inserting their definitions.
* bugfix: var environment in expansion of defun.Kaz Kylheku2016-11-271-1/+4
| | | | | | | | | * eval.c (do_expand): When expanding the body of a defun we must create a function shadowing environment which indicates that the function's name is in scope. This must not be done for defmacro; a defmacro doesn't introduce a function binding, and a macros's body doesn't have that macro in scope.
* Expander warns about unbound variables.Kaz Kylheku2016-11-261-9/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (eval_exception): New static function. (eval_error): Reduced to wrapper around eval_exception. (eval_warn): New function. (me_op): Bind the rest symbol in a shadowing env to suppress watnings about unbound rest. (do_expand): Throw a warning when a bindable symbol is traversed that has no binding. (expand): Don't install atoms as last_form_expanded. * lib.c (warning_s, restart_s, continue_s): New symbol variables. (obj_init): Initialize new symbol variables. * lib.h (warning_s, restart_s, continue_s): Declared. * lisplib.c (except_set_entries): New entries for ignwarn and macro-time-ignwarn. * parser.c (repl_warning): New static function. (repl): Use repl_warning function as a handler for warning exceptions: to print their message and then continue by throwing a continue exception. * parser.y (warning_continue): New static function. (parse_once): Use warning_continue to ignore warnings. In other words, we suppress warnings from Lisp that is mixed into TXR pattern language code, because this produces too many false positives. * share/txr/stdlib/except.tl (ignwarn, macro-time-ignwarn): New macros. * share/txr/stdlib/place.tl (call-update-expander, call-clobber-expander, call-delete-expander): Ignore warnings around calls to sys:expand, because of some gensym-related false positives (we expand code into which we inserted some gensyms, without having inserted the constructs which bind them. * tests/011/macros-2.txr: Suppress unbound variable warnings from a test case. * tests/012/ifa.tl: Bind unbound x y variables in one test case. * tests/012/struct.tl: Suppress unbound variable warnings in some test cases. * uwind.c (uw_throw): If a warning is unhandled, then print its message with a "warning" prefix and then throw a continue exception. (uw_register_subtype): Eliminate the check for sub already being a subtype of sup. This allows us to officially register new types against t. (uw_late_init): Register continue exception type as a subtype of the restart type. Formally register warning type. * txr.1: Documented ignwarn.
* bugfix: quasilit read/print consistency, part 2.Kaz Kylheku2016-11-261-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In this patch commit I'm addressing the issue introduced in part 1 that expressions in @(output) blocks are still using (sys:expr ...) wrapping, but are passed down to an evaluator which now expects unwrapped expressions now. As part of this change, I'm changing the representation of @expr from (sys:expr . expr) to (sys:expr expr). * eval.c (format_field): Adjust access to sys:expr expression based on new representation. (transform_op): Likewise. * lib.c (obj_print_impl): Likewise. * match.c (dest_bind): Likewise. (do_txeval): Likewise. (do_output_line): Likewise, in some compat code. Here is the fix for the issue: when calling tx_subst_vars, we pass a list of one element containing the expression, not wrapped in sys:expr. Previously, we passed a one-element list containing the sys:expr. * parser.y (o_elem): If a list occurs in the syntax, represent it as (sys:expr list) rather than (sys:expr . list). (list): Do the same for @ n_expr syntax. (expand_meta, make_expr): Harmonize with the representation change.
* bugfix: quasilit read/print consistency, part 1.Kaz Kylheku2016-11-261-12/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The bug is that `@@@a` prints as `@@a` which reads as a different object. In this patch we simplify how quasiliterals are represented. Embedded expressions are no longer (sys:expr E), just E. Meta-numbers N and variables V are still (sys:var N). However `@@a` and `@a` remain equivalent. * eval.c (subst_vars): No need to look for expr_s; just evaluate a compound form. The recursive nested case is unnecessary and is removed. (expand_quasi): Do nothandle expr_s; it is not part of the quasi syntax any more. * lib.c (out_quasi_str): Do not look for expr_s in the quasi syntax; just print any expression with a @ the fallback case. * match.c (tx_subst_vars): Analogous changes to those done in subst_vars in eval.c. * parser.y (quasi_meta_helper): Static function removed. This was responsible for the issue due to stripping a level of meta from expressions already having a meta on them. (quasi_item): In the `@` n_expr syntax case, no longer call quasi_meta_helper. The remaining logic is simple enough to put in line. Symbols and integers get wrapped with (sys:var ...); other expressions are integrated into the syntax as-is.
* bugfix: dohash expander not making shadowing env.Kaz Kylheku2016-11-251-1/+2
| | | | | | | | * eval.c (do_expand): When a dohash special form is expanded, a macro shadowing environment must be created for the two variables that it binds and the body must be expanded in that environment, to protect the variables from symbol macros.
* bugfix: expander traversing (sys:expr ...).Kaz Kylheku2016-11-251-1/+1
| | | | | | * eval.c (do_expand): Do not expand into (sys:expr ...) expressins, the same way (sys:var ...) expressions are avoided. They are not forms.
* bugfix: op handles @rest in dot position.Kaz Kylheku2016-11-251-1/+1
| | | | | | | | | | The test case is (op list . @rest) and similar, which were expanding to a syntax containing an incorrect form like [sys:apply list sys:var rest #:rest-0123] where the sys:var rest are superfluous. * eval.c (transform_op): Missing case: the code which handles metas in the dot position must handle @rest not only @<number>.
* bugfix: don't expand @meta syntax as function call.Kaz Kylheku2016-11-241-0/+2
| | | | | | * eval.c (do_expand): If the form is (sys:var ...) then skip it without expanding. Of course, that does not preclude it form being a macro.
* bugfix: op macro using wrong expansions op.Kaz Kylheku2016-11-241-1/+3
| | | | | | * eval.c (me_op): When the operator is op, the arguments must be expanded as Lisp-1 with expand_forms_lisp1, not with the regular expand_forms.
* macro-time: interleave evaluation and expansion.Kaz Kylheku2016-11-241-2/+6
| | | | | | | | | | * eval.c (do_expand): When expanding the macro-time form, do not macro-expand it entirely and then evaluate. Rather, expand each argument form and evaluate. This way earlier forms can make global definitions which are used while macro-expanding later definitions. * txr.1: Behavior documented.
* bugfix: neglect to expand mac-param-bind forms.Kaz Kylheku2016-11-241-6/+19
| | | | | | | | | | | | | | The syntax of mac-param-bind forms isn't recognized at all in the expander, causing these forms to be incorrectly expanded as if they were function calls. * eval.c (mac_param_bind_s): New symbol variable. (do_expand): Handle mac_param_bind_s with the same block of code as tree_bind_s, adjusted to account for the small syntactic difference. (eval_init): Initialize mac_param_bind_s with interned symbol. Register operator using mac_param_bind_s to avoid redundant intern call.
* bugfix: macrolet args not included in macro env.Kaz Kylheku2016-11-241-29/+31
| | | | | | | | | | | | | | | When the function bodies of macrolets are themselves being macro-expanded, this is incorrectly being done in the original macro environment without taking into account the macrolet parameters which those bodies have in scope. Hence the parameters are not able to shadow symbol macros. * eval.c (make_var_shadowing_env): Moved above expand_macrolet so we can avoid adding a forward declaration. Otherwise unchanged. (expand_macrolet): For each macrolet function, create a shadowing environment which contains its parameters, and use that for expanding the body.
* bugfix: indicator params absent from macro envs.Kaz Kylheku2016-11-241-2/+5
| | | | | | | | | | | | | | The problem is about those Boolean parameters which indicate whether their associated optional parameters are present: in (lambda (: (opt-parm 42 opt-parm-p))), such a parameter is opt-parm-p. When parameter lists are walked by the macro expander, these parameters are not being included as shadow entries in macro-time parameter lists. Thus if opt-parm-p happens to shadow an outer symbol macro, that symbol macro will be expanded anyway. * eval.c (get_opt_param_syms): Function now lists those additional parameters.
* Move unwind intrinsics from eval.c to unwind.c.Kaz Kylheku2016-11-231-27/+1
| | | | | | | | | | | | | | | | * eval.c (reg_mac): Static function changed to extern. (me_defex, register_exception_subtypes): Static function removed here; relocated into unwind.c. (eval_init): Registrations of defex, throw, throwf, error, register-exception-subtypes and exception-subtype-p removed. * eval.h (reg_mac): Declared. * unwind.c (me_defex, register_exception_subtypes): Static function moved here. (uw_late_init): Registrations of defex, throw, throwf, error, register-exception-subtypes and exception-subtype-p moved here.
* Allow global macros to be denoted by (macro sym).Kaz Kylheku2016-11-191-14/+49
| | | | | | | | | | | | | | | | | In this patch we allow (symbol-function '(macro sym)), (defun (macro sym) (form env) ...), and (trace (macro sym)). * eval.c (macro_s): New symbol variable. (lookup_fun, func_get_name, op_defun): Support (macro sym) syntax. (builtin_reject_test): Pass through (macro sym) syntax. (eval_init); Initialize macro_s. * share/txr/stdlib/place.tl (sys:get-fun-getter-setter): Support macro place. * txr.1: Documented verything.
* Handle interpreted macros through function.Kaz Kylheku2016-11-191-29/+32
| | | | | | | | | | | | | | | | All macros are function bindings now. * eval.c (me_interp_macro): New function. Body is a copy of block from expand_macro. (op_defmacro): Hoist the me_interp_macro function into the object domain, installing the macro material as the environment. This function is the expander. (expand_macro): Assume that the binding is a function and call it. The cons case is gone. (expand_macrolet): Similar change to the one in op_defmacro: a macrolet is also a function. * txr.1: Documentation under symbol-macro updated.
* Use function rather than cptr built-in macros.Kaz Kylheku2016-11-191-51/+48
| | | | | | | | | | | * eval.c (mefun_t): Typedef removed. (expand_macro): Test whether the binding is a function, rather than C object, and call it with funcall2. (reg_mac): Take a val argument for the expander function, rather than a C function pointer, and just store that value into the binding unconverted. (eval_init): Insert a func_n2(...) call into all reg_mac calls to hoist the C functions into the object domain.
* Reproduce shared structure in sys:switch expansion.Kaz Kylheku2016-11-181-4/+36
| | | | | | | | | | | * eval.c (expand_forms_ss): New static function: like eval_forms but preserves shared substructure along the spine of the list. (expand_list_of_form_lists): Use expand_forms_ss instead of expand_forms, taking the required hash via a new parameter. (expand_switch): Instantiate the required hash table and pass down to expand_list_of_form_lists.
* Bugfix in expansion-time progn reduction.Kaz Kylheku2016-11-181-1/+1
| | | | | | | | | | | | | This was exposed by causing an issue in the multi-pass expansion strategy used in tagbody which shields macro forms from a global macro using a local macro. * eval.c (expand_progn): When calling constantp, pass the macro environment, as required, rather than nil. This was causing (go ...) forms in tagbody to be expanded in the global environment using the global go macro which unconditionally throws an error about an undefined label, rather than using the harmless local go macrolet.
* Adding a tagbody macro to the language.Kaz Kylheku2016-11-181-1/+47
| | | | | | | | | | | | | | | | | | | | | | | This is a "disciplined goto" feature of Common Lisp. This uses a new sys:switch operator, which could also be used for optimizing case and cond forms. * eval.c (switch_s): New symbol variable. (op_switch, expand_list_of_form_lists, expand_switch): New static functions. (do_expand): Hook in the expansion of the sys:switch operator. (eval_init): Initialize switch_s special variable to sys:switch symbol. Register sys:switch special op. * lisplib.c (tagbody_set_entries, tagbody_instantiate): New static functions. (lisplib_init): Register autoloading of tagbody module via new functions. * share/txr/stdlib/tagbody.tl: New file. * txr.1: Documented.
* Start of fallback package list implementation.Kaz Kylheku2016-11-161-0/+2
| | | | | | | | | | | | | | | | | | | | * eval.c (eval_init): Register package-fallback-list and set-package-fallback-list intrinsics. * lib.c (package_fallback_list, set_package_fallback_list, intern_fallback): New functions * lib.h (package_fallback_list, set_package_fallback_list, intern_fallback): Declared. * parser.y (sym_helper): Slightly restructure function so that the symbol interning is done separately in the various cases. In the unqualified symbol case, use intern_fallback to search the fallback list of the current package. * share/txr/stdlib/package.tl (defpackage): Implement :fallback clause.
* Introduce case{q,ql,qual}* macros which eval keys.Kaz Kylheku2016-11-121-3/+19
| | | | | | | | | | | | | | * eval.c (caseq_star_s, caseql_star_s, casequal_star_s): New symbol variables. (me_case): Implement new macro semantics. (eval_init): Initialize new symbol variables, and register the symbols to the me_case macro expander. * tests/sock-common.tl (local-addr): This function depends on the old broken caseql semantics which evaluate keys. Using caseql* makes it work again. * txr.1: Document case{q,ql,qual}* macros.
* Clause in case{q,ql,qual} with no forms yields nil.Kaz Kylheku2016-11-111-1/+3
| | | | | | | | * eval.c (me_case): If forms is nil, substitute the object (nil) for forms, to ensure a nil result through the expansion to a cond. * txr.1: Documented and added compat notes.
* Bugfix in case{q,ql,qual} macro expansion.Kaz Kylheku2016-11-111-6/+17
| | | | | | | | | * eval.c (me_case): The key must be quoted unconditionally whether it's an atom or list. Let's make this subject to the compatibility flag in case someone's code depends on it. * txr.1: Compat notes added.
* Streamline variable assignment operators slightly.Kaz Kylheku2016-11-111-15/+12
| | | | | | | | * eval.c (op_setq, op_lisp1_setq): Take the bindable(var) test out of the frequently executed path. We can safely do the variable lookup with any object. If the lookup fails, then we can complain that the object isn't a bindable symbol, if that is the case.
* Fix some gc-unsafe mutations found by inspection.Kaz Kylheku2016-11-101-1/+1
| | | | | | | | | | | | | | | | | | * eval.c (force): When replacing the promise by a forced value, we must use the set macro. Only the deref assignments which store symbols are safe, not the one storing ret. * lib.c (alist_nremove, alist_nremove1): We must use the set macro here instead of assigning through deref. Even though these assignments preserve the direction of the list (they just splice out nodes), it's possible that the list already contains a "wrong-way" reference (old generation to new) and that the node making this reference is appropriately marked to be processed properly in the next GC cycle. If we remove *that* node, we then cause its predecessor to point to the new generation node and that predecessor could be old generation.
* Implementing package foreign symbol concept.Kaz Kylheku2016-11-101-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (eval_init): Register new intrinsics: package-local-symbols, package-foreign-symbols, use-sym, unuse-sym, use-package, unuse-package, unintern. * gc.c (mark_obj): Mark new hidhash member of struct package. * lib.c (make_package): Initialize new hidhash member of struct package. (lookup_package): New static function. (find_package): Allow string or symbol argument. (get_package): New static function. (delete_package, package_symbols): Use get_package for flexible package argument; delete_package removes symbols from other packages via unuse_package. (package_local_symbols, package_foreign_symbols): New functions. (use_sym, unuse_sym): New functions. (resolve_package_designators): New static function. (use_package, unuse_package): New functions. (symbol_present): New static function. (intern): Revised with get_package for flexible package argument. (unintern): New function. (rehome_sym): Use get_package. Semantics revised. (obj_print_impl): Use symbol_present function to determine whether object is visible in *package* and can be printed without a prefix, rather than naive home package test. * lib.h (struct package): New member, hidhash. (package_local_symbols, package_foreign_symbols, use_sym, unuse_sym, use_package, unuse_package, unintern): Declared. * txr.1: Documentation updated. Extended section introducing the design of packages, and argument conventions. New functions described. Existing function descriptions revised, particularly rehome-sym. Missing description of delete-package added.
* Implement *package* special var; package overhaul.Kaz Kylheku2016-11-081-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (load): Rebind *package* in the local dynamic environment already established for the sake of *load-path*. By doing this we cause *package* to be restored to its prior value, which allows the loaded file to alter it. Common Lisp works this way. (eval_init): Register *package* variable, with the user package as its default value. * lib.c (package_s): New symbol variable. (intern, rehome_sym): Default the package argument to the current package, not to user_package. (get_user_package, get_system_package, get_keyword_package): Functions removed. (get_current_package): New function. (obj_print_impl): Revise symbol printing. Keyword and uninterned symbols are printed with : and #: prefixes. The remainder are printed with a package prefix if their home package isn't the current package. * lib.h (keyword_package, user_package, system_package): These macros are just straight aliases for the global variables, not going through the lookup mechanism, which was pointless. (cur_package): New macro. (package_s): Declared. (get_current_package): Declared. * lisplib.c (lisplib_try_load): Establish a local dynamic environment, and bind the *package* variable to the user package which the library modules expect. * parser.c (find_matching_syms, provide_completions): Treat unqualified symbols in the current package rather than user package. * parser.y (sym_helper): Intern unqualified symbols in the current package, not user package. * txr.1: Document that the variables user-package, system-package and keyword-package should not be modified. Document the *package* special variable, and that intern and rehome-sym default their package argument to its value. (Here we get rid of wrong references to the undocumented variable *user-package*).
* Deprecated undocumented *user-package* etc.Kaz Kylheku2016-11-081-3/+5
| | | | | | | | | | | * eval.c (eval_init): Do not register *user-package*, or *system-package* or *keyword-package* variables unless in compatibility mode. We don't document this in the compatibility notes since the variables are not documented. * tests/009/json.txr: Change use of *keyword-package* to keyword-package.
* Don't track macro origin of interned objects.Kaz Kylheku2016-11-041-1/+3
| | | | | | * eval.c (set_origin): If either form or origin isn't a heap object, or is an interned symbol, then don't record the relationship.
* Don't print distracting path in error trace.Kaz Kylheku2016-11-041-2/+2
| | | | | | * eval.c (error_trace): No need to indicate where an expansion was calculated; it is distracting information when the exception isn't happening at expansion time.
* No need to track origin of entire macrolet.Kaz Kylheku2016-11-041-4/+1
| | | | | | | | | | * eval.c (expand_macrolet): Do not call set_origin to establish a macro ancestry link between the output of the expansion and the original macrolet block. This is not necessary. What is useful and important that the individual expansions of the actual macrolets have their origins tracked to the respective subforms of the original macrolet form. That's already taken care of by expand_macro.
* Show location of expanded form in exp-time errors.Kaz Kylheku2016-11-041-3/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Old behavior: | 1> (sys:expand '(defstruct foo bar)) | ** defstruct: inheritance base bar does | not name a struct type | ** during expansion at | /usr/local/share/txr/stdlib/struct.tl:120 | of form (defstruct foo bar) New behavior: | 1> (sys:expand '(defstruct foo bar)) | ** defstruct: inheritance base bar does | not name a struct type | ** during expansion at expr-1:1 of form (defstruct foo | bar) | ** by macro code located at | /home/kaz/txr/share/txr/stdlib/struct.tl:120 * eval.c (error_trace): Show location of the form being expanded in the "during expansion" message, rather than, confusingly, the locaton of the code of its macro. Then, if the location of the macro is available, show that in a separate message whose wording makes it clear that the location of the expanding macro is being given.
* New negated equality test functions.Kaz Kylheku2016-11-011-0/+3
| | | | | | | | | * eval.c (eval_init): Register neq, neql and nequal intrinsics. * lib.h (neq, neql, nequal): New inline functions. * txr.1: Documented neq, neql and nequal
* Relax restrictions on dwim places.Kaz Kylheku2016-10-311-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | No longer require the leftmost expression in a dwim place to itself be a place, except when the expression evaluates to a list, and the list is subject to an element deletion or a range operation. * eval.c (eval_init): Register dwim-set and dwim-del with one additional argument that the C functions now take. * lib.c (dwim_set, dwim_del): Take a new place_p argument which informs these functions whether the object they are operating on came from a syntactic place. The forbidden situations are diagnosed based on this flag: modification of the subrange of a list, or deletion of a list ref. Some error messages reworded. * lib.h (dwim_set, dwim_del): Declarations updated. * share/txr/stdlib/place.tl (defplace dwim): Produce a different update, clobber and delete expansion when the obj-place form isn't a place. In the non-place case, do not assign the result of the sys:dwim-set or sys:dwim-del operation back obj-place. Furthermore, pass a Boolean flag to sys:dwim-set and sys:dwim-del indicating which situation is the case: did the object argument come from a place or non-place. * txr.1: Documentation updated.
* lambda-set method: treat [struct ...] as place.Kaz Kylheku2016-10-301-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | * eval.c (eval_init): Change registration of dwim-set to only one required argument, with the rest variadic. * lib.c (lambda_set_s): New symbol variable. (dwim_set): Change to variadic function that takes all arguments other than the object/sequence being operated on as struct args *. Rewrite to do a test on the object type first, handling hashes and structs specially. (obj_init): Initialize lambda_set_s. * share/txr/stdlib/place.tl (defplace dwim): Rewritten for more generic syntax. The only argument required is obj-place; the other arguments are treated as a variable argument list, all treated uniformly. This eliminates the special handling of the default value for hash lookups. * args.h (args_count): New inline function. * txr.1: Updated documentation for dwim operator, which neglects to mention use over objects thanks to the lambda function. Documented lambda-set.