summaryrefslogtreecommitdiffstats
path: root/lib.c
Commit message (Collapse)AuthorAgeFilesLines
* lib: sort becomes non-destructive; nsort introduced.Kaz Kylheku2020-05-131-7/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I'm fixing a historic mistake copied from ANSI Lisp, which trips up language newcomers and sometimes even experienced users. The function innocently named sort will now return newly allocated structure. The function previously called sort will be available as nsort (non-consing/allocating sort). The shuffle function also becomes pure, and is accompanied by nshuffle. * eval (me_op): Continue to use destructive sort in this legacy code that is only triggered in very old compat mode. (eval_init): Registered nsort and nshuffle. * lib.c (nsort, nshuffle): New functions introduced, closely based on sort and shuffle. (sort, shuffle): Rewritten to avoid destructive behavior: work by copying the input and calling destructive counterparts. (sort_group): Continue to use destructive sort, which is safe; the structure is locally allocated. The sort_group function has pure semantics. (grade): Likewise. * lib.h (nsort, nshuffle): Declared. * share/txr/stdlib/getopts.tl (opthelp): Replace an instance of the (sort (copy-list ...)) pattern with just (sort ...). * tags.tl (toplevel): Continue to use destructive sort to sort tags before writing the tag file; the lifetime of the tags list ends when the file is written. * tests/010/seq.txr: Switch some sort calls to nsort to keep test case working. * txr.1: Documented.
* lib: use seq-info for sort and shuffle.Kaz Kylheku2020-05-131-19/+25
| | | | | | | | * lib.c (sort, shuffle): Switch to seq_info. For consistency with sort, shuffle now handles hashes in the same peculiar way. * txr.1: Document hash behavior for sort and shuffle.
* funcall: fight spurious retention.Kaz Kylheku2020-05-051-4/+4
| | | | | * lib.c (funcall1, funcall2, funcall3, funcall4): Add forgotten argument zaps in the case that routes to generic_funcall.
* lib: convert counting and predicate quantifying to seq_info.Kaz Kylheku2020-05-051-65/+88
| | | | | | * lib.c (countqual, countql, countq, count_if, some_satisfy, all_satisfy, none_satisfy): Convert from list iteration to seq_info.
* lib/buf: use unsigned integers around allocations.Kaz Kylheku2020-04-251-3/+3
| | | | | | | | | | * buf.c (buf_shrink): Convert len to alloc size using c_unum, which will reject negative values that will implicitly convert to a wrong/huge size. * lib.c (upcase_str, downcase_str): Similar reasoning. (sub_vec): nelem is a size_t, so use unum on it, rather than num.
* printer: add package prefix on symbols with zero-length name.Kaz Kylheku2020-04-221-0/+3
| | | | | | * lib.c (symbol_needs_prefix): If the name is an empty string, the symbol needs a prefix. Otherwise it disappears in the output.
* seq_info: bugfix: uninitialized type field.Kaz Kylheku2020-04-201-1/+1
| | | | | | | | | | | * lib.c (seq_info): Ensure the type field in the returned structure is inintialized. We are neglecting this when the type is COBJ, initializing only the kind field. This makes the in function behave unreliably over arguments that are hash tables, or vector-like sequences (objects with a length function or the carray type). Several other functions will behave unreliably for vector-like sequences: reverse, find, rfind, pos, rpos and tprint.
* warning cleanup: GNU C++ initializer warnings.Kaz Kylheku2020-04-061-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | This is the eight and final round of an effort to enable GCC's -Wextra option. The C++ compiler, with -Wextra, doesn't like C's universal struct initializer { 0 }, individually complaining about all the remaining members not being initialized. What works in C++ is the { } initializer. Conditional definition to the rescue. * lib.h (all_zero_init): New macro which expands to { } under C++, and { 0 } under C. * lib.c (make_time_impl, epoch_tm, time_string_meth, time_parse_meth): Use all_zero_init. * parser.c (prime_parser): Likewise. * socket.c (sock_mark_connected): Likewise. * sysif.c (fcntl_wrap): Likewise. * termios.c (encode_speeds, decode_speeds): Likewise. * configure (diag_flags): Add -Wextra.
* warning cleanup: suspicious switch fallthrough cases.Kaz Kylheku2020-04-051-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is the seventh round of an effort to enable GCC's -Wextra option. Warnings about switch fallthrough situations are addressed. GCC now has a diagnostic for this that is enabled by -Wextra in such a way that if a fallthrough comment is present, the diagnostic is suppressed. In much of the code, we have such a comment. It's missing in a few places, or misplaced. There are also some real bugs. * hash.c (hash_buf): Add fallthrough comments to intentional fallthrough cases. (hash_hash_op): bugfix: add break statement. The 32 and 64 bit cases are independent (at compile time). * lib.c (cdr, nullify, list_collect, empty): Add fallthrough comment. (int_str): Add missing break. This has not caused a bug though because setting the octzero flag in the zerox case is harmless to the logic which follows. * linenoise.c (edit): Move misplaced fallthrough. * sysif.c (fcntl_wrap): Bugfix: add missing break, without which errno is tampered to hold EINVAL, in spite of a successful F_SETLK, F_SETLKW or F_GETLK operation. * unwind.h (jmp_restore): Declare noreturn, so that GCC does not issue a false positive warning about a fallthrough in uw_unwind_to_exit_point. * utf8.c (utf8_from_buf, utf8_decode): Move a fallthrough comment outside of preprocessing, so it is properly processed by GCC's diagnostic.
* warning cleanup: missing member initializers.Kaz Kylheku2020-04-051-7/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is the sixth round of an effort to enable GCC's -Wextra option. Warnings about uninitialized members are addressed. I am not happy with what had to be done in linenoise.c. We just need a dummy circular list node for the lino_list, which we achieved with a dummy all zero struture, with statially initialized next and prev pointers. There are way too many members to initialize, including one that has struct termios type containing a nonportable set of members. On the plus size, the lino_list structure now moves into the BSS section, reducing the executable size slightly. * lib.c (cptr_ops): Initialize using cobj_ops_init, which has all the initializers already, and should have been used for this in the first place. * linenoise/linenoise.c (lino_list): Remove initializer, which eliminates the warning about some members not being initialized. (lino_init): Initialize the next and prev pointers here. * parser.c (parser_ops): Initialize with cobj_ops_init. * stream.h (stdio_mode_init_blank, stdio_mode_init_r, stdio_mode_init_rpb): Add initializer corresponding to redir array member of struct stdio_mode. * sysif.c (cptr_dl_ops): Use cobj_ops_init. * tree.c (tree_iter_init): Add initializer for the path array member of struct tree_iter. (tr_rebuild): Initialize all fields of the dummy object. Since it's a union, we just have to deal with the any member. There are two layouts for the obj_common fields based on whether CONFIG_GEN_GC is enabled. This is ugly, but occurs in one place only.
* warning cleanup: signed/unsigned in ternaries.Kaz Kylheku2020-04-051-2/+2
| | | | | | | | | | | | | | | | | | | | | This is the third round of an effort to enable GCC's -Wextra option. Instances of signed/unsigned mismatch between the branches of ternary conditionals are addressed. * ffi.c (pad_retval): Add cast into the consequent of the conditional so it yields size_t, like the alternative. * lib.c (split_str_keep): Likewise. (vector): Cast -1 to ucnum so it has the same type as the alloc_plus opposite to it. * parser.c (lino_getch): Add a cast to wint_t to match return value and opposite WEOF operand. * stream.c (generic_get_line): Likewise. * sysif.c (c_time): Convert both consequent and alternative to time_t to silence warning.
* warning cleanup: remove unused parameters.Kaz Kylheku2020-04-051-9/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is the second round of an effort to enable GCC's -Wextra option. All function parameters that are unused and are removable are removed. They are eliminated from the function defintions, declarations, callers, and any related function pointer variables or structure members. * arith.c (nary_simple_op): Remove unused self parameter. See lib.c: maxv, minv. * chksum.c (crc32_buf, crc32_str): Remove unused self parameter. (crc32): Don't pass self to the above functions. * eval.c (copy_env_handler, copy_bh_env_handler): Remove unused parent parameter. See unwind.c. (supplement_op_syms): Remove unused max parameter. (me_op): Don't pass max to supplement_op_syms. * lib.c (seq_iter_rewind): Remove unused self parameter. (lazy_flatten_func): Remove unused env parameter. (lazy_flatten): Use func_n1 to create non-environment-carrying funtion out of lazy_flatten_func. (maxv, minv): Don't pass self parameter to nary_simple_op. (middle_pivot): Remove unused lessfun param. (quicksort): Don't pass lessfun to middle_pivot. (diff, isec): Don't pass self to seq_iter_rewind. * lib.h (seq_iter_rewind, nary_simple_op): Declarations updated. * struct.c (get_super_slots): Remove unused self parameteer. (make_struct_type): Don't pass self to get_super_slots. * sysif.c (flock_unpack): Remove unused self parameter. (fcntl_wrap): Don't pass self to flock_unpack. * unwind.c (uw_push_cont_copy): Remove parent parameter from function pointer parameter. See eval.c: copy_env_handler. (call_copy_handlers): Remove parent parameter and don't pass that argument to the indirect call via pointer to the copy handler function. (revive_cont, capture_cont): Don't pass 0 value to removed parent parameter of call_copy_handlers. * unwind.h (struct uw_cont_copy): Function pointer member copy loses parent parameter. (uw_push_cont_copy): Declaration updated.
* warning cleanup: add casts for unused parameters.Kaz Kylheku2020-04-051-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is the first round of an effort to enable GCC's -Wextra option. All function parameters that are unused an that we cannot eliminate are treated with a cast to void in the function body. * args.c (args_key_check_store): Cast unused param to void. * combi.c (perm_list_gen_fill): Likewise. * eval.c (op_error, op_meta_error, op_quote op_qquote_error, op_unquote_error, op_load_time_lit, me_each, me_for, me_quasilist, me_flet_labels, hash_min_max, me_ignerr, me_whilet, me_iflet_whenlet, me_dotimes, me_mlet, me_load_time, me_load_for): Likewise. * ffi.c (ffi_void_put, ffi_fixed_dynsize, *ffi_fixed_alloc, ffi_noop_free, ffi_void_get, ffi_simple_release, ffi_i8_put, ffi_i8_get, ffi_u8_put, ffi_u8_get, ffi_i16_put, ffi_i16_get, ffi_u16_put, ffi_u16_get, ffi_i32_put, ffi_i32_get, ffi_u32_put, ffi_u32_get, ffi_i64_put, ffi_i64_get, ffi_u64_put, ffi_u64_get, ffi_char_put, ffi_char_get, ffi_uchar_put, ffi_uchar_get, ffi_bchar_get, ffi_short_put, ffi_short_get, ffi_ushort_put, ffi_ushort_get, ffi_int_put, ffi_int_get, ffi_uint_put, ffi_uint_get, ffi_long_put, ffi_long_get, ffi_ulong_put, ffi_ulong_get, ffi_float_put, ffi_float_get, ffi_double_put, ffi_double_get, ffi_val_put, ffi_val_get, ffi_be_i16_put, ffi_be_i16_get, ffi_be_u16_put, ffi_be_u16_get, ffi_le_i16_put, ffi_le_i16_get, ffi_le_u16_put, ffi_le_u16_get, ffi_be_i32_put, ffi_be_i32_get, ffi_be_u32_put, ffi_be_u32_get, ffi_le_i32_put, ffi_le_i32_get, ffi_le_u32_put, ffi_le_u32_get, ffi_be_i64_put, ffi_be_i64_get, ffi_be_u64_put, ffi_be_u64_get, ffi_le_i64_put, ffi_le_i64_get, ffi_le_u64_put, ffi_le_u64_get, ffi_wchar_put, ffi_wchar_get, ffi_sbit_get, ffi_ubit_get, ffi_cptr_get, ffi_str_in, ffi_str_put, ffi_str_get, ffi_str_d_get, ffi_wstr_in, ffi_wstr_get, ffi_wstr_put, ffi_wstr_d_get, ffi_bstr_in, ffi_bstr_put, ffi_bstr_get, ffi_bstr_d_get, ffi_buf_in, ffi_buf_put, ffi_buf_get, ffi_buf_d_in, ffi_buf_d_put, ffi_buf_d_get, ffi_closure_put, ffi_ptr_in_in, ffi_ptr_in_d_in, ffi_ptr_in_out, ffi_ptr_out_in, ffi_ptr_out_out, ffi_ptr_out_null_put, ffi_ptr_out_s_in, ffi_flex_struct_in, ffi_carray_get, ffi_union_get, make_ffi_type_builtin, make_ffi_type_array, ffi_closure_dispatch, ffi_closure_dispatch_safe): Likewise. * gc.c (cobj_destroy_stub_op, cobj_destroy_free_op, cobj_mark_op): Likewise. * lib.c (seq_iter_get_nil, seq_iter_peek_nil): Likewise. * linenoise/linenoise.c (sigwinch_handler): Likewise. * parser.c (repl_intr, read_eval_ret_last, repl_warning, is_balanced_line): Likewise. * parser.y (yydebug_onoff): Likewise. * socket.c (dgram_close): Likewise. * stream.c (unimpl_put_string, unimpl_put_char, unimpl_put_byte, unimpl_unget_char, unimpl_unget_byte, unimpl_put_buf, unimpl_fill_buf, unimpl_seek, unimpl_truncate, unimpl_set_sock_peer, null_put_string, null_put_char, null_put_byte, null_get_line, null_get_char, null_get_byte, null_close, null_flush, null_seek, null_set_prop, null_get_error, null_get_error_str, null_clear_error, null_get_fd, dir_close): Likewise. * struct.c (struct_type_print): Likewise. * unwind.c (me_defex): Likewise.
* New contains function: near alias of search.Kaz Kylheku2020-03-231-0/+5
| | | | | | | | | | | | Harmonizes with starts-with and ends-with. * eval.c (eval_init): Register contains intrinsic. * lib.c (contains): New function. * lib.h (contains): Delared. * txr.1: Documented.
* New type args with DARG type code.Kaz Kylheku2020-03-221-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | An object of args type captures into the heap the "struct args" argument list that normally appears only on the stack. Such an object also has space for a car and cdr field, which can come in handy. * args.c (dyn_args): New function: hoist a struct args * into an args heap object. * args.h (dyn_args): Declared. * gc.c (finalize, mark_obj): Handle DARGS type code. * hash.c (equal_hash): Handle DARG via eq equivalence. * lib.c (args_s): New symbol variable. (code2type): Map DARG to args symbol. (equal): Handle DARG type, using eq equivalence for now. (obj_init): Initialize args_s with interned symbol. * lib.h (enum type, type_t): New type code, DARG. (struct dyn_args): New struct. (union obj): New member, a of type struct dyn_args. * txr.1: Documented args type under typeof.
* internals: rename misnamed curry_* functions.Kaz Kyheku2020-03-171-34/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The various curry_xx_yy functions perform partial application, not currying. The curry prefix is being renamed to pa (partially apply). * lib.c (remq_lazy, remql_lazy, remqual_lazy, tree_Find): Updated. (do_curry_12_1, do_curry_12_1_v, do_curry_12_2, do_curry_123_1, do_curry_123_23, do_curry_123_2, do_curry_123_3, do_curry_1234_1, do_curry_1234_34): Renamed to do_pa_12_1, do_pa_12_1_v, do_pa_12_2, do_pa_123_1, do_pa_123_23, do_pa_123_2, do_pa_123_3, do_pa_1234_1, do_pa_1234_34. (curry_12_1, curry_12_1_v, curry_12_2, curry_123_1, curry_123_23, curry_123_2, curry_123_3, curry_1234_1, curry_1234_34): Renamed to pa_12_1, pa_12_1_v, pa_12_2, pa_123_1, pa_123_23, pa_123_2, pa_123_3, pa_1234_1, pa_1234_34. (transposev, do_juxt): Updated. * lib.h: Declarations renamed. * eval.c (subst_vars, qquote_init, expand_catch, weavev): Updated. * filter.c (get_filter, build_filter_from_list, filter_string_tree, filter_init): Updated. * match.c (tx_subst_vars, do_txeval, v_freeform, v_bind, v_throw, v_deffilter, v_assert, h_assert): Updated. * parser.y (gather_clause): Updated. * regex.c (regex_range_full_fun, regex_range_left_fun, regex_range_right_fun, regex_range_search_fun): Updated. * stream.c (open_files, open_files_star): Updated. * txr.c (txr_main): Updated. * unwind.c (me_defex): Updated.
* strings: bugfix: broken inequality comparisons.Kaz Kylheku2020-03-071-1/+4
| | | | | | | | | | | | | | | | | | | | | Inequality comparisons of strings and symbols are broken due to assuming that cmp_str returns -1 or 1. cmp_str uses the C library function wscsmp, and is exposed as the Lisp function cmp-str. That is correctly documented as returning a negative or positive value. But a few function in lib.c assume otherwise. On newer glibc's, at least on x86, it seems that wcscmp does return 1, 0 or -1 consistently; perhaps the newer optimized assembly routines are ensuring this. It shows up on older glibc installations where the C version just returns the difference between the mismatching characters. * lib.c (cmp_str): Now returns -1, 0 or 1. * txr.1: Specify the stronger requirements on the cmp-str return value, adding a note that older versions conform to a weaker requirement.
* less: fix broken semantics for symbols.Kaz Kyheku2020-03-041-1/+20
| | | | | | | | | | | | | | | | | | | | | | | If a and b are symbols, then it's possible for (equal a b), (less a b) and (less b a) to all yield false, which makes no sense. This happens in the case when a and b are distinct symbols (thus not equal), and have the same name (so the stringwise comparison finds them to be equal and hence neither less than the other). * lib.c (less): Implement more complicated requirements for comparing symbols. If two distinct symbols have the same name, then one must be less than the other, and we use other information to determine this. If at least one of them has a home package, then we go by comparing packages: package names are compared as strings, and a missing package is less than a present package. If both same-named symbols have no package, then they are compared as pointers. * txr.1: Documented the properties of less as an antisymmetric, antireflexive and transitive relation. Documented the relationship with equal. Documented the treatment of symbols. Cleaned up some wording.
* New function: assq and rassq.Kaz Kyheku2020-02-241-0/+28
| | | | | | | | | | | | | | | | | | | | | TXR Lisp is henceforth a dialect in which (cdr (assq key a-list)) works exactly as shown, without substitution of assql or assoc. * eval.c (eval_init): Register assq and rassq intrinsics. * lib.c (assq, rassq): New functions. * lib.h (assq, rassq): Declared. * txr.1: Documented. * tests/012/ashwin.tl: New file. * tests/012/ashwin.expected: New file.
* New functions: meq, meql and mequal.Kaz Kylheku2020-02-221-0/+27
| | | | | | | | | | * eval.c (eval_init): Register meq, meql an mequal intrinsics. * lib.c (meq, meql, mequal): New functions. * lib.h (meq, meql, mequal): Declared. * txr.1: Documented.
* c_str: don't allow symbols.Kaz Kyheku2020-01-311-2/+4
| | | | | | | | | | | | | | | | | | | | | | | On 2009-10-02, prior to TXR 014, I made a change to the c_str function to allow symbolic arguments, so that c_str(sym) could be used in the code base instead of c_str(symbol_name(sym)). This was a bad idea, and is allowing numerous functions that operate on strings to accept symbols also. That behavior is not documented and not consistently supported. Ironically, I completely forgot about this and have been consistently using symbol_name(sym) anyway. Let us remove this. Compat support is required because this will break user code that accidentally depends on this undocumented behavior. * lib.c (c_str): If the object is type SYM, only return the symbol_name if compatibility with 231 or older is requested, otherwise fall through to the error case. * match.c (dump_var): Fix one case where a symbol is passed directly to put_string. This fails one of the test cases. More testing is required to see if any other such cases occur. * txr.1: New entry in the compatibility notes.
* New function: merge-delete-package.Kaz Kyheku2020-01-291-0/+19
| | | | | | | | | | | | | | | | | | | | | This is a useful function which supports the use of temporary packages over the scope of file compilation units. A file can be read under a temporary package which provides usefully customized symbol visibility consisting of an arrangement of symbols from various other packages. Then, in a single operation, thanks to this new function, that packag can be deleted and all of its local symbols (those having been newly interned over the course of the file) are transferred to some other, more permanent package. * eval.c (eval_init): merge-delete-package intrinsic registered. * lib.c (merge_delete_package): New function. * lib.h (merge_delete_package): Declared. * txr.1: Documented.
* New function: coded-length.Kaz Kylheku2020-01-181-0/+5
| | | | | | | | * eval.c (eval_init): Register coded-length intrinsic. * lib.c (coded_length): New function. * lib.h (coded_length): Declared.
* Copyright year bump 2020.Kaz Kylheku2019-12-311-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * LICENSE, LICENSE-CYG, METALICENSE, Makefile, alloca.h, args.c, args.h, arith.c, arith.h, buf.c, buf.h, cadr.c, cadr.h, chksum.c, chksum.h, chksums/crc32.c, chksums/crc32.h, combi.c, combi.h, configure, debug.c, debug.h, eval.c, eval.h, ffi.c, ffi.h, filter.c, filter.h, ftw.c, ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h, itypes.c, itypes.h, jmp.S, lib.c, lib.h, linenoise/linenoise.c, linenoise/linenoise.h, lisplib.c, lisplib.h, match.c, match.h, parser.c, parser.h, parser.l, parser.y, protsym.c, rand.c, rand.h, regex.c, regex.h, share/txr/stdlib/asm.tl, share/txr/stdlib/awk.tl, share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl, share/txr/stdlib/compiler.tl, share/txr/stdlib/conv.tl, share/txr/stdlib/debugger.tl, share/txr/stdlib/defset.tl, share/txr/stdlib/doloop.tl, share/txr/stdlib/error.tl, share/txr/stdlib/except.tl, share/txr/stdlib/ffi.tl, share/txr/stdlib/getopts.tl, share/txr/stdlib/getput.tl, share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl, share/txr/stdlib/keyparams.tl, share/txr/stdlib/op.tl, share/txr/stdlib/package.tl, share/txr/stdlib/param.tl, share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl, share/txr/stdlib/pmac.tl, share/txr/stdlib/save-exe.tl, share/txr/stdlib/socket.tl, share/txr/stdlib/stream-wrap.tl, share/txr/stdlib/struct.tl, share/txr/stdlib/tagbody.tl, share/txr/stdlib/termios.tl, share/txr/stdlib/trace.tl, share/txr/stdlib/txr-case.tl, share/txr/stdlib/type.tl, share/txr/stdlib/vm-param.tl, share/txr/stdlib/with-resources.tl, share/txr/stdlib/with-stream.tl, share/txr/stdlib/yield.tl, signal.c, signal.h, socket.c, socket.h, stream.c, stream.h, struct.c, struct.h, strudel.c, strudel.h, sysif.c, sysif.h, syslog.c, syslog.h, termios.c, termios.h, tree.c, tree.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h, vm.c, vm.h, vmop.h, win/cleansvg.txr: Extended copyright notices to 2020.
* OOP: implementing multiple inheritance.Kaz Kylheku2019-12-111-8/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Multiple inheritance is too useful to ignore any longer. * lib.c (subtypep): Perform subtypep calculation between two struct types via the new struct_subtype_p function. It's too complicated now to do with ad hoc code outside of struct.c. * share/txr/stdlib/struct.tl (defstruct): This macro now needs to deal with the super argument being possibly a list of base types instead of a single one. * strut.c (struct struct_type): Member super and super_handle are removed. New member nsupers, supers, and sus. (struct_init): The super function re-registered; it has an optional argument. (call_stinitfun_chain): The compat code here must now access the supertype differently. We don't bother dealing with multiple inheritance in the compat case; programs requesting compatibility with TXR 151 shoudn't be trying to use multiple inheritance. (get_struct_handles, count_super_stslots, get_super_slots, find_super_for_slot): New static functions, to off-load some new complexity from make_struct_type. (make_struct_type): Handle the increased complexity due to multiple inheritance. (super): Takes an additional argument now, to request which supertype to retrieve. Defaults to zero: the first one. (struct_type_destroy): Free the sus array. (struct_type_mark): Mark the supers slot. (call_initfun_chain): Call init functions of all bases, in right-to-left order. (call_postinitfun_chain): Likewise for postinit functions. (call_super_method, call_super_fun, super_method): Use the first base as the supertype. This requirement feels bad; it needs to be revisited. (do_struct_subtype_p): New static function. (struct_subtype_p): New function. (ancestor_with_static_slot): New static function. (method_name): Revised for multiple inheritance; now relies on ancestor_with_static_slot to find the original ancestor that has brought in a method, so we can use that type in the method name. * struct.h (super): Declaration updated. (struct_subtype_p): Declared. * tests/012/oop-mi.expected: New file. * tests/012/oop-mi.tl: New test cases. * txr.1: Revised in order to document multiple inheritance.
* intern-fb: bugfix: optional argument handling.Kaz Kylheku2019-11-281-1/+1
| | | | | | | | | * lib.c (intern_fallback_intrinsic): The missing_ok parameter of get_package must be given a true argument, because package_in is optional. When it is missing, it is represented by the colon symbol, and if missing_ok is false, then get_package treats this colon symbol as the package name "" (the name of that symbol).
* intern-fb: use correct name in diagnostics.Kaz Kylheku2019-11-281-2/+2
| | | | | * lib.c (intern_fallback, intern_fallback_intrinsic): Use intern-fb name, not intern-fallback.
* buffers: support list operations.Kaz Kylheku2019-11-201-0/+18
| | | | | * lib.c (car, cdr, rplaca, rplacd, make_like): Handle BUF type.
* identity*: fix wrong argument index type.Kaz Kylheku2019-11-181-1/+1
| | | | | * lib.c (identity_star): The args_more function requires an index which is a cnum, not int.
* syntax: new .? operator for null-safe object access.Kaz Kylheku2019-11-051-12/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | * lib.c (obj_print_impl): Render the new syntactic conventions introduced in qref/uref back into the .? syntax. The printers for qref and uref are united into a single implementation to reduce code proliferation. * parser.l (grammar): Produce new tokens OREFDOT and UOREFDOT. * parser.y (OREFDOT, UREFDOT): New terminal symbols. (n_expr): Handle .? syntax via the new OREFDOT and UOREFDOT token via qref_helper and uoref_helper. Logic for the existing referencing dot is moved into the new qref_helper function. (n_dot_expr): Handle .? syntax via uoref_helper. (uoref_helper, qref_helper): New static functions. * share/txr/stdlib/struct.tl (qref): Handle the new case when the expression which gives the object is (t expr). Handle the new case when the first argument after the object has this form, and is followed by more arguments. Both these cases emit the right conditional code. (uref): Handle the leading .? syntax indicated by a leading t by generating a lambda which checks its argument for nil. Transformations to qref handle the other cases. * txr.1: Documentation updated in several places.
* lib: use stack-allocated hash iterators everywhere.Kaz Kylheku2019-11-011-15/+25
| | | | | | | | | | | | | | | | | * eval.c (op_dohash): Use hash_iter instead of consing up heap-allocated hash iterator. * filter.c (trie_compress, regex_from_trie): Likewise. * hash.c (hash_equal_op, hash_hash_op, hash_print_op): Likewise. * lib.c (package_local_symbols, package_foreign_symbols, find_max, find_if, rfind_if, populate_obj_hash): Likewise. * parser.c (circ_backpatch, get_visible_syms): Likewise. * struct.c (method_name, get_slot_syms): Likewise.
* lib: don't assume time_t is signed.Kaz Kylheku2019-10-311-10/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | We introduce the function c_time to convert a Lisp integer to time_t, and num_time to do the reverse conversion. The FFI type time-t already does this right. (See registration of time-t in ffi_init_extra_types). * hash.c (gen_hash_seed): The first value out of time_sec_usec corresponds to a time_t value. We now convert this to C number using c_time rather than c_num. Also, while we are touching this code, the microseconds value can convert directly to ucnum with c_unum. * lib.c (time_sec_usec): Use num_time for seconds. (time_string_local, time_string_utc, time_fields_local, time_fields_utc, time_struct_local, time_struct_utc): Use c_time. (make_time_impl, time_parse_utc): Use num_time instead of num. * signal.h (getitimer_wrap, setitimer_wrap): Convert tv_sec members of struct timeval using c_time and num_time. * sysif.c (c_time, num_time): New functions. (stat_to_struct): Convert st_atime, st_mtime and st_ctime to Lisp using num_time instead of num. * sysif.c (c_time, num_time): Declared.
* New function: identity*Kaz Kylheku2019-10-281-2/+13
| | | | | | | | | | | | | | | An version of identity with lax argument conventions. * eval.c (eval_init): Register identity* intrinsic. * lib.c (identity_star_f): New symbol variable. (identity_star): New function. (obj_init): gc-protect identity_star_f variable, and initialize it. * lib.h (identity_star_f): Declared. * txr.1: Documented.
* configure: memalign fixes.Kaz Kylheku2019-10-251-1/+1
| | | | | | | | | | | | | | | | | | | | | This fixes build problems on Mac OS and Solaris due to the introduction of the use of memalign. * configure: After detecting that __EXTENSIONS__ is required on Solaris and adding that to lang_flags, we must call gen_config_make so that it becomes available to subsequent configure tests. On Solaris, memalign is just in <stdlib.h>, so let's test for that first, then test for a memalign in <malloc.h>, and in that case add HAVE_MALLOC_H into config.h. Also, fixing two bugs here. Firstly, the memalign test used inverted logic, causing HAVE_MEMALIGN to be defined on platforms that don't have it. Secondly, the dummy while loop that is just supposed to be a control structure for forward breaks turned infinite due to a missing break at the bottom. * lib.c: if HAVE_MALLOC_H is defined and nonzero, then include <malloc.h>.
* fixparam: signed/unsigned warning from GNU C++.Kaz Kylheku2019-10-251-1/+1
| | | | | | | * lib.h (FIXPARAM_MAX): Switch constant to signed type. * lib.c (func_vm): Use num instead of unum on FIXPARAM_MAX, since we are making it signed.
* parser: use faster, unsafe nreverse.Kaz Kylheku2019-10-251-0/+14
| | | | | | | | | | * lib.c (us_nreverse): New function. * lib.h (us_nreverse): Declared. * parser.y (clauses_opt, n_exprs, r_exprs): Use us_nreverse instead of nreverse to rorder lists built in reverse into final shape.
* functions: provide accessors for basic properties.Kaz Kylheku2019-10-181-0/+63
| | | | | | | | | | | | | | * eval.c (eval_init): Register intrinsic functions fun-fixparam-count, fun-optparam-count, fun-variadic. * lib.c (get_param_counts): New static function. (fun_fixparam_count, fun_optparam_count, fun_variadic): New functions. * lib.h (fun_fixparam_count, fun_optparam_count, fun_variadic): Declared. * txr.1: Documented.
* vm: prevent overflow of fixparam field in function.Kaz Kylheku2019-10-171-9/+17
| | | | | | | | | | | | | Functions can only have 127 fixed parameters; some code ignores this when assigning to the bitfield. * lib.h (FIXPARAM_BITS, FIXPARAM_MAX): New preprocessor symbols. (struct func): Use FIXPARAM_BITS for defining fixparam and optargs bitfields instead of hard-coded 7. * lib.c (func_vm): Sanity check the fixparam and reqags parameters: 0 <= reqargs <= fixparam <= FIXPARAM_MAX.
* New function: copy-tree.Kaz Kylheku2019-10-161-0/+15
| | | | | | | | | | * eval.c (eval_init): Register copy-tree intrinsic. * lib.c (copy_tree): New function. * lib.h (copy_tree): Declared. * txr.1: Documented.
* copy-alist: no mapcar.Kaz Kylheku2019-10-161-1/+4
| | | | | * lib.c (copy_alist): Rewrite using list_collect iteration. endp is used for detecting improper list.
* copy-cons: more efficient; copies lconses.Kaz Kylheku2019-10-161-2/+12
| | | | | | | | | * lib.c (copy_cons): Rewrite to copy the object in a more low-level way, rather than going through the accessors and constructors. Now copies LCONS as LCONS, including its update function. * txr.1: copy-cons re-documented.
* tree: copy-search-tree function.Kaz Kylheku2019-10-161-0/+2
| | | | | | | | | | | | | * lib.c (copy): Handle tree objects via copy_search_tree. * tree.c (deep_copy_tnode): New static function. (copy_search_tree): New function. (tree_init): copy-search-tree intrinsic registered. * tree.h (copy_search_tree): Declared. * txr.1: Documented copy-search-tree, and copy function's use thereof.
* tree: introduce copy-tnode.Kaz Kylheku2019-10-161-0/+2
| | | | | | | | | | | | * lib.c (copy): Handle TNOD casee via copy_tnode. * tree.c (copy_tnode): New function. (tree_init): copy-tnode intrinsic registered. * tree.h (copy_tnode): Declared. * txr.1: copy function documented as handling tnode type via copy-tnode. That function is documented.
* lib: middle_pivot: whitespace fix.Kaz Kylheku2019-10-151-4/+4
| | | | * lib.c (middle_pivot): Fix non-conforming indentation.
* printer: obj_hash must be eq-based.Kaz Kylheku2019-10-111-2/+2
| | | | | | | | | The printer must use an eq-based hash table for detecting circularity, otherwise it blows up on circular range objects. * lib.c (obj_print): instantiate ctx->obj_hash as an eq-based hash table, not eql-based.
* sort: remove obsolete comments.Kaz Kylheku2019-10-081-10/+1
| | | | | | * lib.c (sort_list, sort): Remove comments about dangerous mutation; these pertain to some explicit logic which existed in previous versions of the code to handle those situations.
* tree: circular notation support.Kaz Kylheku2019-10-071-0/+5
| | | | | | * lib.c (populate_obj_hash): Handle tree object. * parser.c (circ_backpatch): Likewise.
* safety: fix type tests that code can subvert.Kaz Kylheku2019-09-301-2/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch fixes numerous instances of a safety hole which involves the type of a COBJ object being tested to be of a given class using logic that can be subverted by the definition of a like-named struct. Specifically logic like (typeof(obj) == hash_s) is broken, because if a struct type called hash is defined, then the test will yield true for instances of that struct type. Those instances can then be passed into code that only works on COBJ hashes, and relies on this test to reject invalid objects. * ffi.c (make_carray): Replace fragile test with strong one, using new cobjclassp function. * hash.c (hashp): Likewise. * lib.c (class_check): The expression used here for the type test moves into the new function cobjclassp and so is replaced by a call to that function. (cobjclassp): New function. * lib.h (cobjclassp): Declared. * rand.c (random_state_p): Replace fragile test using cobjclassp. * regex.c (char_set_compile): Replace fragile typeof tests for character type with is_chr. (reg_derivative, regexp): Replace fragile test with cobjclassp. * struct.c (struct_type_p): Replace fragile test with cobjclassp.
* Use put_char for single character output.Kaz Kylheku2019-09-261-3/+3
| | | | | | | * hash.c (hash_print_op): Replace length 1 put_string calls with put_char. * lib.c (obj_print_impl): Likewise.
* New data type: tnode.Kaz Kylheku2019-09-221-1/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Binary search tree nodes are being added as a basic heap data type. The C type tag is TNOD, and the Lisp type is tnode. Binary search tree nodes have three elements: a key, a left child and a right child. The printed notation is #N(key left right). Quasiquoting is supported: ^#N(,foo ,bar) but not splicing. Because tnodes have three elements, they they fit into TXR's four-word heap cell, not requiring any additional memory allocation. These nodes are going to be the basis for a binary search tree container, which will use the scapegoat tree algorithm for maintaining balance. * tree.c, tree.h: New files. * Makefile (OBJS): Adding tree.o. * eval.c (expand_qquote_rec): Recurse through tnode cells, so unquotes work inside #N syntax. * gc.c (finalize): Add TNOD to no-op case in switch; tnodes don't require finalization. (mark_obj): Traverse tnode cell. * hash.c (equal_hash): Add TNOD case. * lib.c (tnode_s): New symbol variable. (seq_kind_tab): New entry for TNOD, mapping to SEQ_NOTSEQ. (code2type, equal): Handle TNOD. (obj_init): Initialize tnode_s variable. (obj_print_impl, populate_obj_hash): Handle TNOD. (init): Call tree_init function in tree.c. * lib.h (enum type, type_t): New enumeration TNOD. (struct tnod): New struct type. (union obj, obj_t): New union member tn of type struct tnod. (tnode_s): Declard. * parserc.c (circ_backpatch): Handle TNOD, so circular notation works through tnode cells. * parser.l (grammar): Recognize #N prefix, mapping to HASH_N token. * parser.y (HASH_N): New grammar terminal symbol. (tnode): New nonterminal symbol. (i_expr, n_expr): Add tnode cases to productions. (yybadtoken): Map HASH_N to "#N" string.