summaryrefslogtreecommitdiffstats
path: root/lib.c
Commit message (Collapse)AuthorAgeFilesLines
* split, split*, partition, partition*: allow neg indices.Kaz Kylheku2017-03-141-14/+46
| | | | | | | | | | * lib.c (partition_split_common): Filter the list of indices, displacing any negative values by the length of the sequence, removing any that are still negative. This is subject to compatibility. (partition_star): Likewise. * txr.1: Document, and add compat notes.
* Fix missing nao terminator in formatted printing.Kaz Kylheku2017-03-131-1/+1
| | | | | | | | | | | | | | * arith.c (trunc1, trunc, floorf, ceili): Add missing nao terminator to uw_throwf calls. * debug.c (debug): Missing nao terminator in format call. * eval.c (expand_opt_params_rec, me_equot): Missing nao terminator in eval_error call. * lib.c (use_sym): Missing nao in uw_throw call. * regex.c (reg_derivative): Missing nao in uw_throwf.
* New functions starts-with and ends-with.Kaz Kylheku2017-03-121-0/+12
| | | | | | | | | | | * eval.c (eval_init): Register starts-with and ends-with intrinsics. * lib.c (starts_with, ends_with): New functions. * lib.c (starts_with, ends_with): Declared. * txr.1: Documented.
* New rmismatch function.Kaz Kylheku2017-03-121-0/+100
| | | | | | | | | | * eval.c (eval_init): Register rmismatch intrinsic. * lib.c (rmismatch): New function. * lib.h (rmismatch): Declared. * txr.1: Documented
* uref: the a.b.c syntax extended to .a.b.cKaz Kylheku2017-03-061-1/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Now it is possible to use a leading dot on the referencing dot syntax. This is the is the "unbound reference dot". It expands to the uref macro, which denotes an unbound-reference: it produces a function which takes an object as the argument, and curries the reference implied by the remaining arguments. * eval.c (uref_s): New global symbol variable. (eval_init): Intern uref symbol and init uref_s. * eval.h (uref_s): Declared. * lib.c (simple_qref_args_p): A qref expression is now also not simple if it contains an embedded uref, meaning that it cannot be rendered into the dot notation without ambiguity. (obj_print_impl): Support printing (uref a b c) as .a.b.c. * lisplib.c (struct_set_entries): Add uref to the list of autoload triggers for struct.tl. * parser.l (DOTDOT): Consume any leading whitespace as part of recognizing the DOTDOT token. Otherwise the new rule for UREFDOT, which matches (mandatory) leading space will take precedence, causing " .." to be scanned wrong. (UREFDOT): Rule for new kind of dot token, which is preceded by mandatory whitespace, and isn't consing dot (which has mandatory trailing whitespace too, matched by an earlier rule). * parser.y (UREFDOT): New token type. (i_dot_expr, n_dot_expr): New grammar rules. (list): Handle a leading dot on the first element of a list as a special case. Things are done this way because trying to work a UREFDOT into the grammar otherwise causes intractable conflicts. (i_expr): The ^, ' and , punctuators are now followed by an i_dot_expr, so that the expression can be an unbound dot. (n_expr): Same change as in i_expr, but using n_dot_expr. Plus new UREFDOT n_expr production. * share/txr/stdlib/struct.tl (uref): New macro. * txr.1: Documented.
* remq/remove-if family: bugfixes in error message.Kaz Kylheku2017-02-221-9/+9
| | | | | | | | | | | | * lib.c (rem_impl): Take a name argument, so as to report correct function name. Also, serious fix here: we passed the address of the in function to the error message format job, rather than seq_in. (remove_if): Report as remove-if rather than remq in the error message. Also, same bug as in remq_impl: in used in place of seq_in. (remq, remql, remqual, keepq, keepql, keepqual): Pass function name as string into remq_impl.
* New internal function: vec.Kaz Kylheku2017-02-151-0/+22
| | | | | | * lib.c (vec): New function. * lib.h (vec): Declared.
* Add rassoc and rassql functions.Kaz Kylheku2017-02-111-0/+28
| | | | | | | | | | | * eval.c (eval_init): Register rassoc and rassql intrinsics. * lib.c (rassoc, rassql): New functions. * lib.h (rassoc, rassql): Declared. * txr.1: Documented rassoc and rassql, with small fixes to assql and assoc.
* Use non-hacky representation for deferrable warnings.Kaz Kylheku2017-02-101-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Deferrable warnings now get their own subtype, defr-warning. The tag is a regular argument: no funny dotted argument list. * eval.c (eval_defr_warn): Throw new style deferrable warning. (me_op, no_warn_expand): Catch defr-warning rather than warning. Use uw_muffle_warning to suppress it. (gather_free_refs): Parse new representation of deferrable warning. (expand_with_free_refs): Catch defr-warning rather than warning. * lib.c (defr_warning_s): New symbol variable defined. (obj_init): Initialize defr_warning_s. * lib.h (defr_warning_s): Declared. * share/txr/stdlib/error.tl (compile-defr-warning): Throw new-style deferrable warning. * unwind.c (uw_muffle_deferrable_warning): Function removed. (uw_throw): Bugfix: handle warnings by checking by subtype rather than exactly for the warning type. Distinguish deferrable warnings by subtype rather than argument list shape. (uw_defer_warning): Take the new style args and reconstruct the (msg . tag) representation for a deferred warning, so the other functions don't have to change. (uw_late_init): Register defr-warning as exception subtype of warning. * unwind.h (uw_muffle_deferrable_warning): Decl removed. * txr.1: Adjusted all documentation touching on the subject of the representation of deferrable warnings.
* keep/remove: reduce duplication, optimize.Kaz Kylheku2017-02-051-130/+128
| | | | | | | | | | | * lib.c (rem_impl): New static function. (remove_if): Rewritten similarly to rem_impl. (remq, remql, remqual, keepq, keepql, keepqual): Reduced to wrappers around rem_impl. (keep_if): Wrapper around remove_if with test negated. * lib.c (remq, remql, remqual, remove_if, keepq, keepql, keepqual, keep_if): Argument names adjusted.
* bugfix: incorrect keepql due to spurious statement.Kaz Kylheku2017-02-051-1/+0
| | | | * lib.c (keepql): Remove repeated list_collect_nconc call.
* bugfix: rehome_sym not removing from hidden list.Kaz Kylheku2017-02-041-0/+1
| | | | | | | | * lib.c (rehome_sym): Remove a symbol of the same name as sym from the target package's hidden symbol list. The documentation says that this is done. Basically, rehome_sym permanently brings in a symbol, so that a same-named symbol is kicked out.
* bugfix: don't print unnecessary package prefix.Kaz Kylheku2017-02-041-2/+2
| | | | | | | | * lib.c (symbol_visible): Fix wrong accesses to hash table cell: the symbol is in the cdr, not car. This bug means that any symbol which is not in the package is declared not visible and thus requires a package prefix.
* Optimize merge a little.Kaz Kylheku2017-01-291-4/+6
| | | | | * lib.c (merge): Eliminate extra call to cdr by keeping the result of cdr_l, and working with the location.
* bugfix: make list sorting stable, as documented.Kaz Kylheku2017-01-291-11/+11
| | | | | | | | | | | | * lib.c (merge): Fix unstable logic here. What we want is that when the item from list1 is *not less* than the item from list2, we take them in that order. Since all we have is a less function, we must test (less item2 item1). If this is false, then preserve the order, because when the keys are identical, the less function yields false. (sort_list): A similar change takes place here when we sort a list of length two (which is essentially an inlined case of merge).
* bugfix: read print consistency of shadowed symbols.Kaz Kylheku2017-01-291-7/+14
| | | | | | | | | | | | | | Suppose that a program-defined package is current, has usr as its :fallback, and has a :local symbol list. Then if 'usr:list is printed, it must print with the usr: package symbol because it is not visible. It is printing without the prefix. * lib.c (symbol_present): Function renamed to symbol_visible, which is much more descriptive of what its return value means. The bug in this function is that it does not stop searching when, in its search path, it encounters a symbol which has the same name as sym, but which isn't sym. But such a symbol makes sym invisible. This is now fixed.
* bugfix: take-while, take-until termination condition.Kaz Kylheku2017-01-241-2/+2
| | | | | | | * lib.c (take_while_list_fun, take_until_list_fun): We must terminate the output list when the output list is empty, and not try to apply the predicate to car(list) in that case.
* Rename proper_plist_to_alist function.Kaz Kylheku2017-01-241-1/+1
| | | | | | | * lib.c (proper_plist_to_alist): Renamed to plist_to_alist. * lib.h (proper_plist_to_alist): Declaration replaced. (plist_to_alist): Declared.
* New memp function for searching a plist.Kaz Kylheku2017-01-241-0/+9
| | | | | | | | | | * eval.c (eval_init): Register memp intrinsic. * lib.c (memp): New function. * lib.h (memp): Declared. * txr.1: Documented.
* Bump copyright year to 2017.Kaz Kylheku2017-01-231-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | * LICENSE, LICENSE-CYG, METALICENSE, Makefile, args.c, args.h, arith.c, arith.h, cadr.c, cadr.h, combi.c, combi.h, configure, debug.c, debug.h, eval.c, eval.h, filter.c, filter.h, ftw.c, ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h, jmp.S, lib.c, lib.h, lisplib.c, lisplib.h, match.c, match.h, parser.c, parser.h, parser.l, parser.y, rand.c, rand.h, regex.c, regex.h, signal.c, signal.h, stream.c, stream.h, struct.c, struct.h, sysif.c, sysif.h, syslog.c, syslog.h, termios.c, termios.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h, share/txr/stdlib/awk.tl, share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl, share/txr/stdlib/conv.tl, share/txr/stdlib/except.tl, share/txr/stdlib/getopts.tl, share/txr/stdlib/getput.tl, share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl, share/txr/stdlib/package.tl, share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl, share/txr/stdlib/socket.tl, share/txr/stdlib/struct.tl, share/txr/stdlib/tagbody.tl, share/txr/stdlib/termios.tl, share/txr/stdlib/txr-case.tl, share/txr/stdlib/type.tl, share/txr/stdlib/with-resources.tl, share/txr/stdlib/with-stream.tl, share/txr/stdlib/yield.tl: Add 2017 to all copyright headers and strings.
* Bugfix: quasilit var read-print consistency.Kaz Kylheku2016-12-311-2/+9
| | | | | | | | | | | | | | The problem is that objects like `@{foo:bar} @{*xyz*}` are printing as `@foo:bar @*xyz*` without the required braces. This changes the meaning, as in @foo:bar which is @foo followed by the text :bar, or creates a syntax error, as in @*xyz*. * lib.c (out_quasi_str): When printing a var, first convert it to a string form by printing to a string stream. Then if the string form consists of anything other than letters, digits and underscores, mark it as needing braces, in addition to the existing conditions.
* Adding mismatch function.Kaz Kylheku2016-12-121-0/+112
| | | | | | | | | | * eval.c (eval_init): Register mismatch intrinsic. * lib.c (mismatch): New function. * lib.c (mismatch): Declared. * txr.1: Documented mismatch.
* bugfix: find-max doesn't handle internal literals.Kaz Kylheku2016-12-121-1/+2
| | | | | * lib.c (find_max): Handle LIT case in switch. Also, fix nonsensical, typo-ridden error message.
* New function: endp.Kaz Kylheku2016-12-101-0/+10
| | | | | | | | | | | | | 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.
* C++ regression in printer.Kaz Kylheku2016-12-071-21/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * lib.c (obj_print_impl): The recent change for unquote-related read/print consistency introduced initializing declarations which are crossed by a label. They are not actually used past the label, so we can put in a block to delimit their scope to get rid of the compiler error. diff --git a/lib.c b/lib.c index dd599d2..1ca1790 100644 --- a/lib.c +++ b/lib.c @@ -9663,29 +9663,31 @@ val obj_print_impl(val obj, val out, val pretty, struct strm_ctx *ctx) for (iter = obj; consp(iter); iter = cdr(iter)) { val d; - val a = car(iter); - val unq = nil; - - if (a == sys_unquote_s) - unq = lit(". ,"); - else if (a == sys_splice_s) - unq = lit(". ,*"); - - if (unq) { - val d = cdr(iter); - val ad = car(d); - - if (consp(d) && !cdr(d)) { - put_string(unq, out); - if (a == sys_unquote_s && unquote_star_check(ad, pretty)) - put_char(chr(' '), out); - obj_print_impl(ad, out, pretty, ctx); - put_char(closepar, out); - break; + { + val a = car(iter); + val unq = nil; + + if (a == sys_unquote_s) + unq = lit(". ,"); + else if (a == sys_splice_s) + unq = lit(". ,*"); + + if (unq) { + val d = cdr(iter); + val ad = car(d); + + if (consp(d) && !cdr(d)) { + put_string(unq, out); + if (a == sys_unquote_s && unquote_star_check(ad, pretty)) + put_char(chr(' '), out); + obj_print_impl(ad, out, pretty, ctx); + put_char(closepar, out); + break; + } } - } - obj_print_impl(a, out, pretty, ctx); + obj_print_impl(a, out, pretty, ctx); + } finish: d = cdr(iter); if (nilp(d)) {
* bugfix: , *sym printed as ,*sym.Kaz Kylheku2016-12-061-2/+18
| | | | | | | | | | | | | | We are lacking read/print consistency in the handling of unquotes applied to symbols whose names begin with a star. * lib.c (unquote_star_check): New static function. (obj_print_impl): Use unquote_star check when printing an unquote to determine whether a space is needed so that the result doesn't read back as a ,* splice. * txr.1: Change "should" to "must": the whitespace is absolutely required in , *x*. Adding more discussion as a dialect note.
* bugfix: print unquote/splice in dot position.Kaz Kylheku2016-12-051-1/+19
| | | | | | * lib.c (obj_print_impl): Properly print objects like ^(... . ,expr) and (... . ,*expr) rather than ^(... sys:unquote expr) or ^(... sys:splice expr).
* Adding curry_1234_1 function.Kaz Kylheku2016-12-011-0/+15
| | | | | | | * lib.c (do_curry_1234_1): New static function. (curry_1234_1): New function * lib.h: (curry_1234_1): Declared.
* Don't throw when printing (sys:quasi . atom).Kaz Kylheku2016-11-271-2/+2
| | | | | | | | | | | | | | | | | | | We do not have perfect read/print consistency for quasiliterals. Programs can construct quasiliterals which cause the printer to throw exceptions, or which don't print such that the same object is read back. However, at least we can handle some trivial cases. In particular, the object (sys:quasi . #<function>) occurs in the system, as the top-level binding of the quasi operator. With this change, we can print that instead of throwing. * lib.c (obj_print_impl): Check that a quasiliteral or quasi-list-literal is a list with at least one argument. Don't print (sys:quasi) or (sys:quasi . non-nil-atom) in the notation.
* bugfix: read-print consistency for @(expr).Kaz Kylheku2016-11-271-1/+1
| | | | | | | | * lib.c (obj_print_impl): Only print (sys:expr x . rest) as @x if rest is nil, and x is a cons. Otherwise we create read-print problems: (sys:expr x y) prints as @x, concealing y. And (sys:expr sym) prints as @sym which reads as (sys:var sym).
* Expander warns about unbound variables.Kaz Kylheku2016-11-261-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Completion of fallback list implementation.Kaz Kylheku2016-11-161-1/+26
| | | | | | | | | | | | | | | | | | | | | | | | * lib.c (find_symbol): New function. (symbol_present): Search the fallback list also to determine whether the symbol is visible. * lib.h (find_symbol): Declared. * parser.y (sym_helper): Implement a new behavior for qualified symbols. Interning new symbols is only allowed for packages that have an empty fallback list. * parser.c (get_visible_syms): New static function. (find_matching_syms): Use get_visible_syms to get the list of eligible symbols. This way the fallback list of the package is included if it is the current package. * share/txr/stdlib/package.tl (defpackage): Do not insert a default (:use usr) if there is no :usr clause. Since defpackage is very new, no need for backward compatibility; the amount of code depending on this is likely zero. * txr.1: Documented fallback list feature.
* Start of fallback package list implementation.Kaz Kylheku2016-11-161-0/+53
| | | | | | | | | | | | | | | | | | | | * 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.
* Fix circular printing issue for package objects.Kaz Kylheku2016-11-101-1/+1
| | | | | | * lib.c (obj_print_impl): Print package name using ~a rather than ~s. Otherwise if the string object occurs elsewhere in the structure being printed, we have a problem.
* Handle interpreted functions in circle printing.Kaz Kylheku2016-11-101-0/+7
| | | | | | | | | | | | | | | | | | | Interpreted functions print as #<interpreted fun: name args>, thus repeating some list structure in their notation. This means we must traverse them when populating the object hash during printing, and also when backpatching after parsing. Test case: evaluate and print (let ((s '(lambda (a b c) d))) (list s (eval s))) with *print-circle* enabled. * lib.c (populate_obj_hash): Handle FUN objects of functype FINTERP. * parser.c (circ_backpatch): Likewise.
* Fix some gc-unsafe mutations found by inspection.Kaz Kylheku2016-11-101-2/+2
| | | | | | | | | | | | | | | | | | * 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.
* Check for non-package value in *package*.Kaz Kylheku2016-11-101-1/+9
| | | | | | * lib.c (get_current_package): If *package* contains nonsense, then reset it to a sane value and throw an exception.
* Implementing package foreign symbol concept.Kaz Kylheku2016-11-101-38/+238
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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.
* Check that name is stringp in some sym functions.Kaz Kylheku2016-11-081-6/+18
| | | | | * lib.c (make_sym, make_package, intern): Check that the name argument is a string.
* Implement *package* special var; package overhaul.Kaz Kylheku2016-11-081-26/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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*).
* Don't access *print-circle* in early init.Kaz Kylheku2016-11-081-1/+1
| | | | | | | | * lib.c (obj_print): Check that print_circle_s has been interned before trying to look it up as a variable. Otherwise the auto-load code will be triggered, and try to use a hash table that doesn't exist yet. This can happen when this code is called during early initialization.
* Circ print: fix recursion from print methods.Kaz Kylheku2016-11-011-12/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Two issues addressed here, both occurring when *print-circle* is enabled and an object has struct components which have a custom print method that re-enters the object printer. One issue is that the children of these components which occur just once print with spurious labels: like #3=, when no matching #3# occurs. The other bug is a wrong "unexpected duplicate object" exception caused by mismanagement of the child object's label hash table and its merging with the parent. * stream.h (struct stream_ctx): New member, obj_hash_prev. Makes the parent hash table known to populate_obj_hash, if there is a table, otherwise nil. * lib.c (populate_obj_hash): If there is a parent table, check each object in it. If it occurs, then bail. I.e. don't add objects to the child table which occur in the parent. This fixes both issues. Also, we do the unexpected duplicate object check right here now: if we traverse an object that already printed without a label (because it is not known to be duplicate), that means that a custom print method is inappropriately introducing new references to existing objects, contrary to the rules. (obj_hash_merge): The logic here is now simplified. All entries in the child table are simply moved to the parent. If anything already exists, that is an unexpected stuation indicating an internal problem, turned into a variant of the unexpected duplicate object message. * tests/012/circ.tl: New file, giving tests for the bugs. * tests/012/circ.expected: New file.
* Don't enter symbols into cycle-identifying hash.Kaz Kylheku2016-10-311-2/+7
| | | | | | | | | * lib.c (circle_print_eligible): New inline function. (obj_print_impl): Do not bother with hash lookup for interned objects that don't participate in circle notation. (populate_obj_hash): Replace open-coded test with call to circle_print_eligible.
* Relax restrictions on dwim places.Kaz Kylheku2016-10-311-9/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-19/+51
| | | | | | | | | | | | | | | | | | | | | | | | * 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.
* Same fix in tok-where as tok-str.Kaz Kylheku2016-10-261-1/+23
| | | | | | | | lib.c (tok_where) Implement new loop which suppresses empty tokens immediately matching after non-empty tokens. Old loop available under compatibility. No documentation update needed since tok-where is already documented as working like tok-str.
* Don't bother with numeq comparison in tok_where.Kaz Kylheku2016-10-261-1/+1
| | | | * lib.c (tok_where): Just compare match_end == match_start.
* Fix regression: broken tok_where.Kaz Kylheku2016-10-261-7/+10
| | | | | | * lib.c (tok_where): Check that the regex match succeeded before destructuring the result with range_bind.