summaryrefslogtreecommitdiffstats
path: root/hash.c
Commit message (Collapse)AuthorAgeFilesLines
* Rename EXTRA_DEBUGGING to CONFIG_EXTRA_DEBUGGING.Kaz Kylheku2016-06-171-3/+3
| | | | | | | | * configure: Generate #define CONFIG_EXTRA_DEBUGGING 1 in config.h header, rather than EXTRA_DEBUGGING. * gc.c, gc.h, hash.c: Change references to EXTRA_DEBUGGING preprocessor symbol to CONFIG_EXTRA_DEBUGGING.
* Replace new hash limit constants with variables.Kaz Kylheku2016-05-281-11/+28
| | | | | | | | | | | | | | | | | | | * genman.txr: Call set-hash-str-limit to set a generous limit for string hashing, which restores the old hash values in the HTML document, preserving the validity of existing URLs. * hash.c (hash_str_limit, hash_rec_limit): New static variables. (HASH_STR_LIMIT, HASH_REC_LIMIT): Preprocessor symbols removed. (hash_c_str, equal_hash): Use hash_str_limit. (gethash_c, gethash, gethash_f, gethash_n, remhash, hash_equal): Use hash_rec_limit. (set_hash_str_limit, set_hash_rec_limit): New static functions. (hash_init): Register sys:set-hash-str-limit and sys:set-hash-rec-limit intrinsics.
* Move registration of hash module functions to hash.cKaz Kylheku2016-05-281-0/+41
| | | | | | | | | | | | | | | * eval.c (gethash_s): Global symbol variable removed, due to being used only in one place. (eval_init): Remove registration of make-hash, make-similar-hash, copy-hash, hash, hash-construct, hash-from-pairs, hash-list, inhash, sethash, pushhash, remhash, hash-count, get-hash-userdata, set-hash-userdata, hashp, maphash, hash-eql, hash-equal, hash-keys, hash-values, hash-pairs, hash-alist, hash-uni, hash-diff, hash-isec, hash-subset, hash-proper-subset, group-by, group-reduce, hash-update, hash-update-1, hash-revget, hash-begin, hash-next. * hash.c (hash_init): Registrations removed from eval_init moved here.
* Store hash values in hash entries.Kaz Kylheku2016-05-271-19/+86
| | | | | | | | | | | | | | | | | | | | | | | | Here, we augment the cons cells used for the hash chain assoc lists with one more field to store the hash value. This lets us grow hash tables without recalculating the hashes, and to perform hash searches with fewer equality comparisons. * hash.c (struct hash): assoc_fun and acons_new_c_fun function pointers get a new cnum hash argument. (hash_equal_op): Pass cell's hash value to assoc_fun. (hash_grow): No need to compute each hash entry's hash code; just pull it out from the cell, and mod it with the new modulus to get the chain index. (hash_assoc, hash_assql, hash_acons_new_c, hash_aconsql_new_c): New static functions. (make_hash): Store hash_assoc, hash_assql, hash_acons_new_c and hash_aconsql_new_c in place of assoc, assql, acons_new_c and aconsql_new_c. (gethash_c, gethash, gethash_f, gethash_n, remhash): Pass hash alue to assoc_fun or acons_new_c_fun. * lib.h (struct cons_hash_entry): New struct type. (union obj): New member ch.
* Reduce work done by hashing.Kaz Kylheku2016-05-271-31/+52
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Curtail traversal of objects and strings. * hash.c (struct hash): hash_fun member takes int * parameter now. (HASH_STR_LIMIT, HASH_REC_LIMIT): New macros. (hash_c_str): Hash only HASH_STR_LIMIT characters. (equal_hash): Becomes extern function. Takes pointer-to-int count argument, which is decremented. Function stops recursing and returns zero when this hits zero. (eql_hash): Also takes int * param, for compatibility with function pointer in struct hash. This parameter is not used, though. (cobj_hash_op): Take pointer-to-count parameter, but ignore it. (hash_hash_op): Take pointer-to-count parameter, decrement and check that it has not hit zero, pass down to equal hash. (hash_grow, gethash_c, gethash, gethash_f, gethash_n, remhash): Initialize a counter to HASH_REC_LIMIT and pass down to hashing function. (hash_eql): Pass down a pointer to a dummy counter to eql_hash. (hash_equal): Initialize a counter to HASH_REC_LIMIT and pass down to hash_equal. * hash.h (equal_hash): Declared. * lib.h (cobj_ops): hash member takes int * parameter. (cobj_hash_op): Declaration updated with new param. * struct.c (struct_inst_hash): Takes new int * parameter for count. Calls equal_hash instead of hash_equal, eliminating c_num calls; pointer to count is passed to equal_hash.
* Header file cleanup.Kaz Kylheku2016-01-221-1/+0
| | | | | | | * arith.c, cadr.c, debug.c, eval.c, filter.c, gencadr.txr, glob.c, hash.c, linenoise/linenoise.c, lisplib.c, match.c, parser.c, rand.c, regex.c, signal.c, stream.c, struct.c, sysif.c, syslog.c, txr.c, unwind.c, utf8.c: Remove unncessary header files.
* Copyright year bump.Kaz Kylheku2015-12-311-1/+1
| | | | | | | | | | | | | | | | | | | | | | | * LICENSE, 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, 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, share/txr/stdlib/cadr.tl, share/txr/stdlib/except.tl, share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl, share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl, share/txr/stdlib/struct.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, signal.c, signal.h, stream.c, stream.h, struct.c, struct.h, sysif.c, sysif.h, syslog.c, syslog.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h: Add 2016 copyright. * linenoise/LICENSE, linenoise/linenoise.c, linenoise/linenoise.h: Bump one principal author's copyright from 2014 to 2015. The code is based on a snapshot of 2015 upstream work.
* Bugfix: sethash doesn't return stored value.Kaz Kylheku2015-11-251-1/+1
| | | | | | | | | | | | | | | | sethash mistakenly returns a boolean which indicates that the value was newly added, rather than the documented behavior of returning the new value. * hash.c (sethash): return value rather than new_p. * share/txr/stdlib/place.tl (defplace): The defplace form now seturn the main symbol of the place being defined, rather than returning whatever the last sethash call returns. (define-place-macro): Likewise. (sys:register-simple-accessor): Likewise, so that defaccessor returns the getter function's name.
* New equality substitution.Kaz Kylheku2015-11-201-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the equal method is defined for structs, its return value is used in their place for hashing and comparison. * eval.h (eq_s, eql_s, equal_s): Declared. * hash.c (equal_hash): If a COBJ defines an equalsub function, we call it. If it returns non-nil, we take the object in its place and recurse. * lib.c (equal): Refactored to support equality substitution. (less): Support equality substitution. * lib.h (cobj_ops): New function pointer member, equalsub. Only struct instances define this, currently. (cobj_ops_init): Add null entry to initializer for equalsub. (cobj_ops_init_ex): New initialiation macro for situations when the equalsub member must be provided. * struct.c (struct struct_type): new member eqmslot. (make_struct_type): Initialize emslot to zero. (static_slot_set, static_slot_ensure): If eqmslot is -1, indicating positive knowledge that there is no equal method static slot, we must invalidate that with a zero: it is no longer known whether there is or isn't such a slot. (get_equal_method, struct_inst_equalsub): New static functions. (struct_inst_ops): Initialize the equalsub member using new cobj_ops_init_ex macro. * txr.1: Document equality substitution.
* New function: group-reduce.Kaz Kylheku2015-11-101-0/+45
| | | | | | | | | | * eval.c (eval_init): Register group-reduce intrinsic. * hash.c (group_reduce): New function. * hash.h (group_reduce): Declared. * txr.1: Documented group-reduce.
* New range type, distinct from cons cell.Kaz Kylheku2015-11-011-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (eval_init): Register intrinsic functions rcons, rangep from and to. (eval_init): Register rangep intrinsic. * gc.c (mark_obj): Traverse RNG objects. (finalize): Handle RNG in switch. * hash.c (equal_hash, eql_hash): Hashing for for RNG objects. * lib.c (range_s, rcons_s): New symbol variables. (code2type): Handle RNG type. (eql, equal): Equality for ranges. (less_tab_init): Table extended to cover RNG. (less): Semantics defined for ranges. (rcons, rangep, from, to): New functions. (obj_init): range_s and rcons_s variables initialized. (obj_print_impl): Produce #R notation for ranges. (generic_funcall, dwim_set): Recognize range objects for indexing * lib.h (enum type): New enum member, RNG. MAXTYPE redefined to RNG value. (TYPE_SHIFT): Increased to 5 since there are now 16 type codes. (struct range): New struct type. (union obj): New member rn, of type struct range. (range_s, rcons_s, rcons, rangep, from, to): Declared. (range_bind): New macro. * parser.l (grammar): New rule for recognizing the #R sequence as HASH_R token. * parser.y (HASH_R): New terminal symbol. (range): New nonterminal symbol. (n_expr): Derives the new range symbol. The n_expr DOTDOT n_expr rule produces rcons expression rather than const. * match.c (format_field): Recognize rcons syntax in fields which is now what ranges translate to. Also recognize range object. * tests/013/maze.tl (neigh): Fix code which destructures range as a cons. That can't be done any more. * txr.1: Document ranges.
* Bugfix: harden hash-next, since it is exposed.Kaz Kylheku2015-10-281-1/+4
| | | | | | | | | | | The C code doesn't call hash_next once it returns nil, so it doesn't matter that doing so will dereference a null pointer. But hash_next is now exposed as the Lisp function hash-next. * hash.c (hash_next): If the hash table in the iterator is nil, then return nil, avoiding the dereference of a null pointer.
* Stop using C library setjmp/longjmp.Kaz Kylheku2015-10-251-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | TXR is moving to custom assembly-language routines. This is mainly motivated by a very dubious thing done in the GNU C Library setjmp and longjmp in the name of security. Evidently, glibc's setjmp "mangles" certain pointer values which are stored into the jmp_buf buffer. It's been that way since 2005, evidently. This means that, firstly, all along, the use of setjmp in gc.c to get registers into a buffer so they can be scanned has not actually worked properly. More importantly, this pointer mangling in setjmp and longjmp is very hostile to a stack copying implementation of delimited continuations. The reason is that continuations contain jmp_buf buffers, which get relocated in the process of capturing and reviving a continuation. Any pointers in a jmp_buf which point into the captured stack segment have to be fixed up to point into the relocated location. Mangled pointers make this difficult, requiring hacks which are specific to glibc and the machine architecture. We might as well implement a clean, well-behaved setjmp and longjmp. * Makefile (jmp.o): New object file. (dbg/%.o, opt/%.o): New rules for .S prerequisites. * args.c, arith.c, cadr.c, combi.c, cadr.c, combi.c, debug.c, eval.c, filter.c, glob.c, hash.c, lib.c, match.c, parser.c, rand.c, regex.c, signal.c, stream.c, struct.c, sysif.c, syslog.c, txr.c, unwind.c, utf8.c: Removed <setjmp.h> include. * gc.c: Switch to struct jmp and jmp_save, instead of jmp_buf and setjmp. * jmp.S: New source file. * signal.h (struct jmp): New struct type. (jmp_save, jmp_restore): New function declarations denoting assembly language routines in jmp.S. (extended_jmp_buf): Uses struct jmp instead of setjmp. (extended_setjmp): Use jmp_save instead of setjmp. (extended_longjmp): Use jmp_restore instead of longjmp.
* Replace two-step initialization of args with macros.Kaz Kylheku2015-08-241-2/+1
| | | | | | | | | | | | | | | | | | | | | * args.h (args_init_list, args_init): Return the struct args * pointer. (args_decl_list, args_decl): New macros. * eval.c (apply, do_eval, expand_macro, op_dwim, op_catch, (mapcarl, lazy_mapcarl): Switch to new macros. * hash.c (hashl): Likewise. * lib.c (generic_funcall, lazy_appendl, maxl, minl, funcall, funcal1, funcall2, funcall3, funcall4, transpose, juxtv, do_and, do_or, do_iff, unique): Likewise. * match.c (h_fun, v_fun): Likewise. * stream.c (vformat): Likewise. * syslog.c (syslog_wrap): Likewise.
* Large scale conversion to new way of handling arguments.Kaz Kylheku2015-08-231-11/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Function arguments are now allocated on the stack using alloca, in conjunction with the struct alloc header structure. The generic_funcall and apply functions are refactored for this, as are most functions that take variadic arguments. * args.c (args_add_list, args_cons_list): Functions removed. (args_normalize, args_normalize_fill): New functions. (args_get_checked): Draw arguments from list when array runs out. (args_copy, args_copy_zap): New functions. * args.h (ARGS_MAX): Reduced to 32. (ARGS_MIN): New preprocessor symbol. (args_init): Call args_init_list. (args_add2, args_add3, args_add4): New inline functions. (args_more): Take into account list, which may hold additional arguments. (args_two_more): New inline function. (args_normalize, args_normalize_fill): Declared. (args_get_list): Normalize all arguments into one list and return it. (args_get_rest, args_at, args_atz): New inline functions. (args_get): Draw arguments from list when array runs out. (args_clear): New inline function. * arith.c (maskv): Convert to new args. * eval.c (APPLY_ARGS): Preprocessor symbol removed. (bind_args): Converted to accept struct args. (apply): Function reduced down to trivial adapter which converts a list of arguments to args, and calls the new generic_funcall. (applyv): New static function: struct args wrapper around apply_intrinsic. (iapply): Converted to struct args. (call): Static function removed. The call intrinsic function binding now goes directly to generic_funcall. (list_star_intrinsic, interp_fun): Converted to struct args. (op_catch): Adjustments for bind_args, which requires a struct args arglist. (me_op): Must use the new minl and maxl, since minv and maxv don't take lists any more. (mapcarv, mappendv, lazy_mapcarv, lazy_mappendv, mapdov, weavev, or_fun, and_fun, tf, nilf, do_retf, do_apf, do_ipf, callf, do_mapf, mapf): Converted. (mapcarl): New function, like the old mapcarv. (eval_init): call_f initialized from generic_funcall rather than call. apply registered to applyv rather than apply_intrinsic. Registrations for zip, hash_from_pairs, vec, alist-remove, alist-nremove, and throw similarly updated to new or renamed functions. * eval.h (interp_fun, mapcarv): Declarations updated. (mapcarl): Declard. * hash.c (hashv): Converted to struct args. (hashl): New function. (hash_construct): Use hashl, not hashv. (hash_from_pairs, hash_list, group_by): Converted. * hash.h (hashv, hash_construct, hash_from_pairs, hash_list, group_by): Declarations updated. (hashl): Declared. * lib.c (appendv, nconcv, lazy_appendv): Converted to struct args. (lazy_appendl): New function. (multi): Converted. (listv): New function. (nary_op, plusv, mulv, logandv, logiorv, gtv, ltv, gev, lev, numeqv, numneqv, maxv, minv): Converted. (maxl, minl): New functions, like old maxv and minv. (exptv, gcdv, lcmv, lessv, greaterv, lequalv, gequalv): Converted. (func_f0v, func_f1v, func_f2v, func_f3v, func_f4v): Converted. (func_n0v, func_n1v, func_n2v, func_n3v, func_n4v): Converted. (func_n0v, func_n1v, func_n2v, func_n3v, func_n4v): Converted. (func_n1ov, func_n2ov, func_n3ov): Converted. (generic_funcall): Converted to take struct args. (funcall, funcall1, funcall2, funcall4): Pass stack-allocated struct args as trailing arguments to variadic functions, and to generic_funcall. (do_curry_12_1_v): New struct-args-based static function, needed to implement curry_12_1_v now. (curry_12_1_v): Converted. (transposev): New function based on previous tranpose. (transpose): Now a wrapper for transposev. (do_chain, chainv, do_chand, chandv, do_juxt, juxtv, do_and, andv, do_or, orv, do_not, do_iff): Converted. (vectorv): New function. Implementation basis for vec intrinsic function. (alist_removev, alist_nremovev): New functions. (multi_sort): Switch from mapcarv to mapcarl. (unique): Converted. (uniq): Allocate struct args for calling unique. (obj_init): list_f function now based on new listv, rather than identity. * list.h (varg): New typedef. (struct func): All variadic function pointers converted to use struct args. (appendv, nconcv, lazy_appendv, multi, nary_op, plusv, minusv, mulv, gtv, ltv, gev, lev, numeqv, numneqv, maxv, minv, exptv, gcdv, lcmv, logadnv, logiorv, maskv, lessv, greaterv, lequalv, gequalv, func_f0v, func_f1v, func_f2v, func_f3v, func_f4v, func_n0v, func_n1v, func_n2v, func_n3v, func_n4v, func_n0v, func_n1v, func_n2v, func_n3v, func_n4v, func_n1ov, func_n2ov, func_n3ov, generic_funcall, chainv, chandv, juxtv, adnv, orv, unique): Declarations updated. (lazy_appendl, listv, maxl, minl, transposev, vectorv, alist_removev, alist_nremovev): Declared. * stream.c (make_catenated_stream_v): New function. (aformat): Renamed to formatv. The recognition of the nil and t streams (standard output and string) is done here now. (vformat): Follow rename of aformat to formatv. (formatv): Function removed. Nobody calls this anymore. (stream_init): make-catenated-stream re-registered to new make_catenated_stream_v function. * stream.h (formatv): Declaration updated. (make_catenated_v): Declared. * syslog.c (syslog_init): syslog registred to syslog_wrapv. (syslog_wrapv): New function based on syslog_wrap converted to struct args. (syslog_wrap): Now wrapper for syslog_wrapv. * syslog.h (syslog_wrapv): Declared. * unwind.h (uw_throwv): New function. (uw_throwfv, uw_errorfv): Converted to struct args. * unwind.h (uw_throwv): Declared. (uw_throwfv, uw_errorfv): Declarations updated.
* * hash.c (hash_revget): New function.Kaz Kylheku2015-08-041-0/+16
| | | | | | | | * hash.h (hash_revget): Declared. * eval.c (eval_init): Registered hash-revget intrinsic. * txr.1: Documented hash-revget.
* Pass pretty flag to cobj print operation.Kaz Kylheku2015-08-011-4/+4
| | | | | | | | | | | | | | | | | | | | | * hash.c (hash_print_op): Take third argument, and call cobj_print_impl rather than cobj_print. * lib.c (cobj_print_op): Take third argument. The object class is * printed with obj_print_impl. (obj_print_impl): Static function becomes extern. Passes its pretty flag argument to cobj print virtual function. * lib.h (cobj_ops): print takes third argument. (cobj_print_op): Declaration updated. (obj_print_impl): Declared. * regex.c (regex_print): Takes third argument, and ignores it. * stream.c (stream_print_op, stdio_stream_print, cat_stream_print): Take third argument, and ignore it. * stream.h (stream_print_op): Declaration updated.
* Multi-line, indented printing of structure.Kaz Kylheku2015-07-311-4/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (op_error): New static function. (macro_form_p, fboundp): Static to external. (special_operator_p): New function. (eval_init): Register macrolet and symacrolet to op_error. These are recognized and processed by expand, but we want them in the op table so they are reported by special_operator_p. * eval.h (fboundp, macro_form_p, special_operator_p): Declared. * hash.c (print_key_val): Break long lines on spaces between pairs with stream_width_check. (hash_print_op): Implement split and indented printing. * lib.c (obj_print_impl): New static function, resulting from a merge of obj_print and obj_pprint. Fixes some wrong-way recursion bugs: obj_pprint recursed into obj_print in some places. Adds support for multi-line printing of vectors and lists, with indentation using the new interfaces in streams. * stream.c (strm_base_init): Update initializer. (put_indent, indent_mode_put_string): New static functions. (put_string): Use indent_mode_put_string in either of the two indent modes. (put_char): Implement indent mode. (get_indent_mode, test_set_indent_mode, set_indent_mode, get_indent, set_indent, inc_indent, width_check): New functions. * stream.h (enum indent_mode): New. (struct strm_base): indent_on member becomes indent_mode. New members data_width and code_width. (get_indent_mode, test_set_indent_mode, set_indent_mode, get_indent, set_indent, inc_indent, width_check): Declared. * tests/009/json.expected: Updated. * tests/010/seq.expected: Likewise. * tests/011/macros-2.expected: Likewise.
* Correction to COBJ initialization pattern.Kaz Kylheku2015-07-301-2/+3
| | | | | | | | | | | | | In fact, the previosuly documented process is not correct and still leaves a corruption problem under generational GC (which has been the default for some time). * HACKING: Document flaw in the initialization pattern previously thought to be correct, and show fix. * hash.c (copy_hash): Fix instance of incorrect pattern. * regex.c (regex_compile): Likewise.
* * hash.c (hash_from_pairs, hash_list): New functions.Kaz Kylheku2015-06-241-0/+19
| | | | | | | | | * hash.h (hash_from_pairs, hash_list): Declared. * eval.c (eval_init): Registered hash-from-pairs and hash-list intrinsic. * txr.1: Documented new functions.
* Hash subset testing.Kaz Kylheku2015-06-231-0/+21
| | | | | | | | | | | * eval.c (eval_init): Register hash-subset and hash-proper-subset intrinsics. * hash.c (hash_subset, hash_proper_subset): New functions. * hash.h (hash_subset, hash_proper_subset): Declared. * txr.1: New functions documented.
* Improvements in equal hashing function.Kaz Kylheku2015-06-181-4/+9
| | | | | | | * hash.c (equal_hash): For conses and vectors, ensure that distinct permutations lead to different hash codes. This is done by accumulating the partial hash with a multiplier, rather than just adding subhashes.
* Critical bugfix for weak hashes.Kaz Kylheku2015-06-071-0/+2
| | | | | | | * hash.c (hash_mark): Hash tables which have both weak keys and values were not added to the reachable_weak_hashes list, and thus not subject to complete hash processing, leading to corruption.
* New macro-based framework for assignment places.Kaz Kylheku2015-05-061-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The operators set, inc, dec, pop and others are now macros which generate code, rather than built-in special forms that use "C magic". Moreover, new such macros are easy to write, and several new ones are already available. Moreover, new kinds of assignable places are easy to create. * place.tl: New file. * lisplib.c, lisplib.h: New files. * Makefile (OBJS): New target, lisplib.o. (GEN_HDRS): New variable. (LISP_TO_C_STRING): New recipe macro, with rule. (clean): Remove generated headers named in $(GEN_HDRS). * eval.c (dec_s, push_s, pop_s, flip_s, del_s): Variables removed. (setq_s): New variable. (lookup_var, lokup_sym_lisp_1, lookup_var_l, lookup_fun, lookup_mac, lookup_symac, lookup_symac_lisp1): Trigger the delayed loading of libraries for undefined global symbols, and re-try the lookup. (op_modplace, dwim_loc, force_l): Static functions removed. (op_setq): New static function. (eval_init): Initialize setq_s; remove initializations of removed variables; remove registrations for op_modplace; add registration for sys:setq, sys:rplaca, sys:rplacd, sys:dwim-set and sys:dwim-del intrinsics. Call lisplib_init to initialize the dynamic library loading module. * lib.c (sys_rplaca, sys_rplacd): New functions, differing in return value from rplaca and rplacd. (ref, refset): Handle hash table. (dwim_set, dwim_del): New functions. * lib.h (sys_rplaca, sys_rplacd, dwim_set, dwim_del): Declared. * genvim.txr: Include place.tl in scan. * tests/010/seq.txr: The del operator test case no longer throws at run-time but at macro-expansion time, so the test case is simply removed. * tests/010/seq.expected: Updated output. * tests/011/macros-2.txr: Reset *gensym-counter* to zero, because the textual output of the test case includes gensyms, whose numberings fluctuate with the content of the new Lisp library material. * tests/011/macros-2.expected: Updated output.
* Update copyright notices from 2014 to 2015.Kaz Kylheku2015-02-011-1/+1
| | | | | | | | | | | * arith.c, arith.h, combi.c, combi.h, debug.c, debug.h, eval.c, eval.h, filter.c, filter.h, gc.c, gc.h, hash.c, hash.h, lib.c, lib.h, match.c, match.h, parser.h, rand.c, rand.h, regex.c, regex.h, signal.c, signal.h, stream.c, stream.h, sysif.c, sysif.h, syslog.c, syslog.h, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h: Update. * LICENSE, METALICENSE: Likewise.
* Use macro to initialize cobj_ops.Kaz Kylheku2015-01-291-14/+10
| | | | | | | | | | * lib.h (cobj_ops_init): New macro. * hash.c (hash_ops, hash_iter_ops): Initialize with cobj_ops_init. * rand.c (random_state_ops): Likewise. * regex.c (char_set_obj_ops, regex_obj_ops): Likewise.
* * hash.c (hash_begin): Use coerce macro instead of raw C cast.Kaz Kylheku2014-10-251-3/+2
| | | | | | Use cobj_handle so hash argument is validated. * parser.l (YY_INPUT): Use convert macro instead of raw C cast.
* * Makefile: Removing trailing spaces.Kaz Kylheku2014-10-241-5/+5
| | | | | | | | | | (GREP_CHECK): New macro. (enforce): Rewritten using GREP_CHECK, with new checks. * arith.c, combi.c, debug.c, eval.c, filter.c, gc.c, hash.c, lib.c, * lib.h, match.c, parser.l, parser.y, rand.c, regex.c, signal.c, * signal.h, stream.c, syslog.c, txr.c, unwind.c, utf8.c: Remove trailing spaces.
* Ensure that a hash reorganization doesn't take placeKaz Kylheku2014-10-221-6/+56
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | during a traversal, which could cause items to be visited twice or skipped. * gc.c (full_gc): Changed from static to exter (full_gc): Changed to internal linkage. * gc.h (full_gc): Declared. * hash.c (struct hash): New member, usecount. (struct hash_iter): New member, next. (reachable_iters): New static variable. (hash_mark): Reset the usecount of every reachable hash table. (hash_iter_mark): Add every reachable iterator to reachable_iters list. (make_hash, make_similar_hash, copy_hash): Initialize usecount. (gethash_c): Do not call hash_grow if usecount is nonzero. (hash_begin): Initialize next field of hash_iter to null. Increment use count on hash table. (hash_next): When traversal ends, release use count, and null out the hash table reference. (do_weak_tables): New static function. (do_iters): New static function. (hash_process_weak): Weak hash processing logic moved to do_weak_tables. Also calls do_iters. * txr.1: Describe hash table traversal, and the assurances and caveats about inserting and deleting items.
* Converting cast expressions to macros that are retargettedKaz Kylheku2014-10-171-45/+45
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | to C++ style casts when compiling as C++. * lib.h (strip_qual, convert, coerce): New casting macros. (TAG_MASK, tag, type, wli_noex, auto_str, static_str, litptr, num_fast, chr, lit_noex, nil, nao): Use cast macros. * arith.c (mul, isqrt_fixnum, bit): Use cast macros. * configure (INT_PTR_MAX): Define using cast macro. * debug.c (debug_init): Use cast macro. * eval.c (do_eval, expand_macro, reg_op, reg_mac, eval_init): Use cast macros. * filter.c (filter_init): Use cast macro. * gc.c (more, mark_obj, in_heap, mark, sweep_one, unmark): Use cast macros. * hash.c (hash_double, equal_hash, eql_hash, hash_equal_op, hash_hash_op, hash_print_op, hash_mark, make_hash, make_similar_hash, copy_hash, gethash_c, gethash, gethash_f, gethash_n, remhash, hash_count, get_hash_userdata, set_hash_userdata, hash_iter_destroy, hash_iter_mark, hash_begin, hash_uni, hash_diff, hash_isec): Use cast macros. * lib.c (code2type, chk_malloc, chk_malloc_gc_more, chk_calloc, chk_realloc, chk_strdup, num, c_num, string, mkstring, mkustring, upcase_str, downcase_str, string_extend, sub_str, cat_str, trim_str, c_chr, vector, vec_set_length, copy_vec, sub_vec, cat_vec, cobj_print_op, obj_init): Likewise. * match.c (do_match_line, hv_trampoline, match_files, dir_tables_init): Likewise. * parser.l (grammar): Likewise. * parser.y (parse): Likewise. * rand.c (make_state, make_random_state, random_fixnum, random): Likewise. * regex.c (CHAR_SET_L2_LO, CHAR_SET_L2_HI, CHAR_SET_L1_LO, CHAR_SET_L1_HI, CHAR_SET_L0_LO, CHAR_SET_L0_HI, L0_full, L0_fill_range, L1_full, L1_fill_range, L1_contains, L1_free, L2_full, L2_fill_range, L2_contains, L2_free, L3_fill_range, L3_contains, L3_free, char_set_create, char_set_cobj_destroy, nfa_state_accept, nfa_state_empty, nfa_state_single, nfa_state_wild, nfa_state_set,
* * Makefile, arith.c, arith.h, combi.c, combi.h, configure, debug.c,Kaz Kylheku2014-07-231-16/+16
| | | | | | | | debug.h, eval.c, eval.h, filter.c, filter.h, gc.c, gc.h, hash.c, hash.h, lib.c, lib.h, match.c, match.h, parser.h, parser.l, parser.y, rand.c, rand.h, regex.c, regex.h, signal.c, signal.h, stream.c, stream.h, syslog.c, syslog.h, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h: Synchronize license header with LICENSE.
* * configure: Add a check, in the case that we cannot make anKaz Kylheku2014-07-221-0/+5
| | | | | | | | | | | | | | | | | executable, whether this is due to being required to use C99. For instance, the Solaris environment requires compilation using the C99 dialect if _XOPEN_SOURCE is set to 600 or higher. * debug.c: When compiling as C99, we have to obey the special C99 conventions for instantiating inline functions. * hash.c: Likewise. * lib.c: Likewise. * parser.y: Likewise. * unwind.c: Likewise.
* * hash.c (hash_construct): Nullify the pairs argument so thatKaz Kylheku2014-07-191-0/+2
| | | | | | it works correctly with an empty vector. * txr.1: Write missing documentation for hash-construct.
* Change to how locations are passed around, for the sake of generationalKaz Kylheku2014-03-291-55/+56
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | GC. The issue being solved here is the accuracy of the gc_set function. The existing impelmentation is too conservative. It has no generation information about the memory location being stored, and so it assumes the worst: that it is a location in the middle of a gen 1 object. This is sub-optimal, creating unacceptable pressure against the checkobj array and, worse, as a consequence causing unreachable gen 0 objects to be tenured into gen 1. To solve this problem, we replace "val *" pointers with a structure of type "loc" which keeps track of the object too, which lets us discover the generation. I tried another approach: using just a pointer with a bitfield indicating the generation. This turned out to have a serious issue: such a bitfield goes stale when the object is moved to a different generation. The object holding the memory location is in gen 1, but the annotated pointer still indicates gen 0. The gc_set function then makes the wrong decision, and premature reclamation takes place. * combi.c (perm_init_common, comb_gen_fun_common, rcomb_gen_fun_common, rcomb_list_gen_fun): Update to new interfaces for managing mutation. * debug.c (debug): Update to new interfaces for managing mutation. Avoid loc variable name. * eval.c (env_fbind, env_fbind): Update to new interfaces for managing mutation. (lookup_var_l, dwim_loc): Return loc type and update to new interfaces. (apply_frob_args, op_modplace, op_dohash, transform_op, mapcarv, mappendv, repeat_infinite_func, repeat_times_func): Update to new interfaces for managing mutation. * eval.h (lookup_var_l): Declaration updated. * filter.c (trie_add, trie_compress, trie_compress_intrinsic, * build_filter, built_filter_from_list, filter_init): Update to new * interfaces. * gc.c (gc_set): Rewritten to use loc type which provides the exact generation. We do not need the in_malloc_range hack any more, since we have the backpointer to the object. (gc_push): Take loc rather than raw pointer. * gc.h (gc_set, gc_push): Declarations updated. * hash.c (struct hash): The acons* functions use loc instead of val * now. (hash_equal_op, copy_hash, gethash_c, inhash, gethash_n, pushhash, Change to how locations are passed around, for the sake of generational GC. The issue being solved here is the accuracy of the gc_set function. The existing impelmentation is too conservative. It has no generation information about the memory location being stored, and so it assumes the worst: that it is a location in the middle of a gen 1 object. This is sub-optimal, creating unacceptable pressure against the checkobj array and, worse, as a consequence causing unreachable gen 0 objects to be tenured into gen 1. To solve this problem, we replace "val *" pointers with a structure of type "loc" which keeps track of the object too, which lets us discover the generation. I tried another approach: using just a pointer with a bitfield indicating the generation. This turned out to have a serious issue: such a bitfield goes stale when the object is moved to a different generation. The object holding the memory location is in gen 1, but the annotated pointer still indicates gen 0. The gc_set function then makes the wrong decision, and premature reclamation takes place. * combi.c (perm_init_common, comb_gen_fun_common, rcomb_gen_fun_common, rcomb_list_gen_fun): Update to new interfaces for managing mutation. * debug.c (debug): Update to new interfaces for managing mutation. Avoid loc variable name. * eval.c (env_fbind, env_fbind): Update to new interfaces for managing mutation. (lookup_var_l, dwim_loc): Return loc type and update to new interfaces. (apply_frob_args, op_modplace, op_dohash, transform_op, mapcarv, mappendv, repeat_infinite_func, repeat_times_func): Update to new interfaces for managing mutation. * eval.h (lookup_var_l): Declaration updated. * filter.c (trie_add, trie_compress, trie_compress_intrinsic, * build_filter, built_filter_from_list, filter_init): Update to new * interfaces. * gc.c (gc_set): Rewritten to use loc type which provides the exact generation. We do not need the in_malloc_range hack any more, since we have the backpointer to the object. (gc_push): Take loc rather than raw pointer. * gc.h (gc_set, gc_push): Declarations updated. * hash.c (struct hash): The acons* functions use loc instead of val * now. (hash_equal_op, copy_hash, gethash_c, inhash, gethash_n, pushhash,
* More generational GC fixes. One GC fix.Kaz Kylheku2014-03-271-4/+4
| | | | | | | | | | | | | | | * combi.c (perm_init_common, comb_gen_fun_common, rcomb_gen_fun_common): Use set macro instead of plain assignment. * hash.c (hash_grow, copy_hash, hash_update_1): Use set macro instead of plain assignment. * lib.c (nreverse, lazy_appendv_func, lazy_appendv, vec_push, refset): Use set macro instead of plain assignment. (make_package): Assign all fields of the newly created PKG object before calling a function which can trigger GC. * parser.y (rlset): Use set macro.
* Replacing uses of the eq function which are used only as C booleans,Kaz Kylheku2014-02-221-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | with just using the == operator. Removing cobj_equal_op since it's indistinguishable from eq. Streamlining missingp and null_or_missing_p. * eval.c (transform_op): eq to ==. (c_var_ops): cobj_equal_op to eq. * filter.c (trie_compress, trie_lookup_feed_char, filter_string_tree, html_hex_continue, html_dec_continue): eq to ==. * hash.c (hash_iter_ops): cobj_equal to eq. * lib.c (countq, getplist, getplist_f, search_str_tree, posq): eq to ==. (cobj_equal_op): Function removed. * lib.h (cobj_equal_op): Declaration removed. (missingp): Becomes a simple macro that yields a C boolean instead of t/nil val, because it's only used that way. (null_or_missing_p): Becomes inline function returning int. * match.c (v_output): eq to ==. * rand.c (random_state_ops): cobj_equal_op to eq. * regex.c (char_set_obj_ops, regex_obj_ops): cobj_equal_op to eq. (reg_derivative): Silly if3 expression replaced by null. (regexp): Redundant if2 expression wrapped around eq removed. * stream.c (null_ops, stdio_ops, tail_ops, pipe_ops, string_in_ops, byte_in_ops, string_out_ops, strlist_out_ops, dir_ops, cat_stream_ops): cobj_equal_op to eq. * syslog.c (syslog_strm_ops): cobj_equal_op to eq.
* The C function nullp is being renamed to null, and the rarelyKaz Kylheku2014-02-221-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | used global variable null which holds a symbol becomes null_s. A new macro called nilp is added that more efficiently checks whether an object is nil, producing a C boolean value rather than t or nil. Most of the uses of nullp in the codebase just become the more streamlined nilp. * debug.c (show_bindings): nullp to nilp * eval.c (lookup_var, lookup_var_l, lookup_fun, lookup_sym_lisp1, do_eval, expand_qquote, expand_quasi, expand_op): nullp to nilp. (op_modplace): nullp to null. (eval_init): Update registration of null and not from C function nullp to null. * filter.c (trie_compress, html_hex_continue): nullp to nil. (filter_string_tree): null to null_s. * hash.c (hash_next): nullp to nilp. * lib.c (null): Variable renamed to null_s. (code2type): null to null_s. (lazy_flatten_scan, chainv, lazy_str, lazy_str_force_upto, obj_print, obj_pprint): nullp to nilp. (obj_init): null to null_s; nullp to null. * lib.h (null): declaration changed to null_s. (nullp): Inline function renamed to null. (nilp): New macro. * match.c (do_match_line): nullp to nilp. * rand.c (make_random_state): Likewise. * regex.c (compile_regex): Likewise.
* * hash.c (hash_update): Avoid double cdr.Kaz Kylheku2014-02-141-2/+4
|
* * hash.c (inhash): Simplify with gethash_c.Kaz Kylheku2014-02-141-10/+5
|
* Replacing acons_new_l and aconsq_new_l interfaces with onesKaz Kylheku2014-02-141-10/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | that return the new or old cons cell rather than a pointer to its cdr field. * eval.c (transform_op): use of acons_new_l replaced with acons_new_c. * hash.c (struct hash): acons_new_l_fun member replaced with acons_new_c_fun. (make_hash, make_similar_hash): initialize acons_new_l_fun member using either acons_new_c or aconsql_new_c. (gethash_l): function becomes an inline in hash.h. (gethash_c): new function, based on gethash_l. (inhash, gethash_n): updated w.r.t struct hash change. * hash.h (gethash_c): declared. (gethash_l): becomes an inline wrapper for gethash_c. * lib.c (acons_new_l, aconsql_new_l): functions removed. (acons_new_c, aconsql_new_c): new functions. (obj_init): use gethash_c and rplacd instead of gethash_l and set. * lib.h (acons_new_l, aconsql_new_l): declarations removed. (acons_new_c, aconsql_new_c): declared.
* * hash.c (inhash): Simplify code with gethash_f.Kaz Kylheku2014-02-141-3/+2
|
* * eval.c (eval_init): Registered hash_update_1 as intrinsic.Kaz Kylheku2014-02-141-0/+19
| | | | | | | | * hash.c (hash_update_1): New function. * hash.h (hash_update_1): Declared. * txr.1: Documented hash-update-1.
* * hash.c (inhash): Rename local variable from new to new_p.Kaz Kylheku2014-02-141-3/+3
| | | | | This is consistent with usage elsewhere in the module, and more importantly, keeps our code C++.
* Different approach: optional arguments on hash-isec and hash-uni allowKaz Kylheku2014-02-141-62/+14
| | | | | | | | | | | | | | | | | | | | | for more flexible joining of data from the hash tables. * eval.c (eval_init): Remove hash_guni and hash_gisec. Change registration for hash_uni and hash_isec to three arguments with one optional. * hash.c (hash_uni): Third parameter introduced, join_func. The default behavior changes: in the two argument case, clashing keys prefer the value from hash1 rather than hash2. For this reason, we now iterate over hash2 first, then hash1. (hash_guni): Removed. (hash_isec): Third parameter introduced, join_func. (hash_gisec): Removed. * hash.h (hash_uni, hash_isec): Declarations updated. (hash_guni, hash_gisec): Delarations removed. * txr.1: Documentation updated.
* * eval.c (eval_init): Register hash_guni and hash_gisec as intrinsics.Kaz Kylheku2014-02-141-1/+60
| | | | | | | | | | | * hash.c (hash_guni, hash_gisec): New functions. (hash_isec): Bugfix: since gethash was naively used, keys in hash2 associated with the value nil were erroneously omitted from the intersection. * hash.h (hash_guni, hash_gisec): Declared. * txr.1: Documented new functions.
* * eval.c (eval_init): Register inhash as intrinsic.Kaz Kylheku2014-02-141-0/+22
| | | | | | | | | * hash.c (inhash): New function. * hash.h (inhash): Declared. * txr.1: Documented inhash. Also, added surprisingly missing documentation for gethash!
* * hash.c (struct hash): New member, equal_fun.Kaz Kylheku2014-02-121-0/+11
| | | | | | | (hash_equal_op): Short circuited logic: whenever we pull identical cells from either hash, we don't have to go through the pending lookaside list. (make_hash, make_similar_hash): Initialize new structure member.
* * hash.c (hash_equal_op, hash_hash_op): New static functions.Kaz Kylheku2014-02-121-2/+106
| | | | | | | (hash_ops): New functions registered in table of operations. * txr.1: Documentation for equal function updated to explain how two hashes are equal.
* Undoing bogus optimization, which can only work when objectsKaz Kylheku2014-02-121-39/+15
| | | | | | | | are treated as immutable. * hash.c (last_equal_key, last_equal_hash): Variables removed. (equal_hash, hash_process_weak): All references to removed variables scrubbed.
* * combi.c (comb_hash_while_fun, comb_hash_gen_fun, comb_hash): NewKaz Kylheku2014-02-111-1/+4
| | | | | | | | | | | | | static functions. (comb): Support hash tables. * hash.c (print_key_val): When values are nil, print in a more condensed way by omitting the second element. This notation is accepted as input already by the parser. (hash_insert_pair): New function. * txr.1: Description of comb updated to indicate that it works over hashes.