summaryrefslogtreecommitdiffstats
path: root/eval.c
Commit message (Collapse)AuthorAgeFilesLines
* listener: new *-1, *-2 ... *-20 macros.Kaz Kylheku2020-07-111-1/+1
| | | | | | | | | | | | * arith.h (minus_s): Declared. * eval.c (reg_symacro): Changing to external linkage. * eval.h (macro_time_s, reg_symacro): Declared. * parser.c (repl): Bind the *-1 to *-20 symbol macros. * txr.1: Documented.
* New function: iterable.Kaz Kylheku2020-07-021-0/+1
| | | | | | | | | | | | * eval.c (eval_init): Register iterable intrinsic. * lib.c (seq_iterable): New static function. (nullify): Use seq_iterable to simplify function. (iterable): New function. * lib.h (iterable): Declared. * txr.1: Documented.
* c_num: now takes self argument.Kaz Kylheku2020-06-291-12/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The c_num and c_unum functions now take a self argument for identifying the calling function. This requires changes in a large number of places. In a few places, additional functions acquire a self argument. The ffi module has the most extensive example of this. Some functions mention their name in a larger string, or have scattered literals giving their name; with the introduction of the self local variable, these are replaced by references to self. In the following changelog, the notation TS stands for "take self argument", meaning that the functions acquires a new "val self" argument. The notation DS means "define self": the functions in question defines a self variable, which they pass down. The notation PS means that the functions pass down an existing self variable to functions that now require it. * args.h (args_count): TS. * arith.c (c_unum, c_num): TS. (toint, exptv): DS. * buf.c (buf_check_len, buf_check_alloc_size, buf_check_index, buf_do_set_len, replace_buf, buf_put_buf, buf_put_i8, buf_put_u8, buf_put_char, buf_put_uchar, buf_get_bytes, buf_get_i8, buf_get_u8, buf_get_cptr, buf_strm_get_byte_callback, buf_strm_unget_byte, buf_swap32, str_buf, buf_int, buf_uint, int_buf, uint_buf): PS. (make_duplicate_buf, buf_shrink, sub_buf, buf_print, buf_pprint): DS. * chskum.c (sha256_stream_impl, sha256_buf, crc32_buf, md5_stream_impl, md5_buf): TS. (chksum_ensure_buf, sha256_stream, sha256, sha256_hash, md5_stream, md5, md5_hash): PS. (crc32_stream): DS. * combi.c (perm_while_fun, perm_gen_fun_common, perm_str_gen_fun, rperm_gen_fun, comb_vec_gen_fun, comb_str_gen_fun, rcomb_vec_gen_fun, rcomb_str_gen_fun): DS. * diff.c (dbg_clear, dbg_set, dbg_restore): DS. * eval.c (do_eval, gather_free_refs, maprodv, maprendv, maprodo, do_args_apf, do_args_ipf): DS. (op_dwim, me_op, map_common): PS. (prod_common): TS. * ffi.c (struct txr_ffi_type): release member TS. (make_ffi_type_pointer): PS and release argument TS. (ffi_varray_dynsize, ffi_array_in, ffi_array_put_common, ffi_array_get_common, ffi_varray_in, ffi_varray_null_term): PS. (ffi_simple_release, ffi_ptr_in_release, ffi_struct_release, ffi_wchar_array_get, ffi_array_release_common, ffi_array_release, ffi_varray_release): TS. (ffi_float_put, double_put, ffi_be_i16_put, ffi_be_u16_put, ffi_le_i16_put, ffi_le_u16_put, ffi_be_i32_put, ffi_be_u32_put, ffi_le_i32_put, ffi_sbit_put, ffi_ubit_put, ffi_buf_d_put, make_ffi_type_array, make_ffi_type_enum, ffi_type_compile, make_ffi_type_desc, ffi_make_call_desc, ffi_call_wrap, ffi_closure_dispatch_save, ffi_put_into, ffi_in, ffi_get, ffi_put, carray_set_length, carray_blank, carray_buf, carray_buf_sync, carray_cptr, carray_refset, carray_sub, carray_replace, carray_uint, carray_int): PS. (carray_vec, carray_list): DS. * filter.c (url_encode, url_decode, base64_stream_enc_impl): DS. * ftw.c (ftw_callback, ftw_wrap): DS. * gc.c (mark_obj, gc_set_delta): DS. * glob.c (glob_wrap): DS. * hash.c (equal_hash, eql_hash, eq_hash, do_make_hash, hash_equal, set_hash_traversal_limit, gen_hash_seed): DS. * itypes.c (c_i8, c_u8, c_i16, c_u16, c_i32, c_u32, c_i64, c_u64, c_short, c_ushort, c_int, c_uint, c_long, c_ulong): PS. * lib.c (seq_iter_rewind): TS and becomes internal. (seq_iter_init_with_info, seq_setpos, replace_str, less, replace_vec, diff, isec, obj_print_impl): PS. (nthcdr, equal, mkstring, mkustring, upcase_str, downcase_str, search_str, sub_str, cat_str, scat2, scat3, fmt_join, split_str_keep, split_str_set, trim_str, int_str, chr_int, chr_str, chr_str_set, vector, vecref, vecref_l, list_vec, copy_vec, sub_vec, cat_vec, lazy_str_put, lazy_str_gt, length_str_ge, length_str_lt, length_str_le, cptr_size_hint, cptr_int, out_lazy_str, out_quasi_str, time_string_local_time, time_string_utc, time_fields_local_time, time_fields_utc, time_struct_local, time_struct_utc, make_time, time_meth, time_parse_meth): DS. (init_str, cat_str_init, cat_str_measure, cat_str_append, vscat, time_fields_to_tm, time_struct_to_tm, make_time_impl): TS. * lib.h (seq_iter_rewind): Declaration removed. (c_num, c_unum, init_str): Declarations updated. * match.c (LOG_MISMATCH, LOG_MATCH): PS. (h_skip, h_coll, do_output_line, do_output, v_skip, v_fuzz, v_collect): DS. * parser.c (parser, circ_backpatch, report_security_problem, hist_save, repl, lino_fileno, lino_getch, lineno_getl, lineno_gets, lineno_open): DS. (parser_set_lineno, lisp_parse_impl): PS. * parser.l (YY_INPUT): PS. * rand.c (make_random_state): PS. * regex.c (print_rec): DS. (search_regex): PS. * signal.c (kill_wrap, raise_wrap, get_sig_handler, getitimer_wrap, setitimer_wrap): DS. * socket.c (addrinfo_in, sockaddr_pack, fd_timeout, to_connect, open_sockfd, sock_mark_connected, sock_timeout): TS. (getaddrinfo_wrap, dgram_set_sock_peer, sock_bind, sock_connect, sock_listen, sock_accept, sock_shutdown, sock_send_timeout, sock_recv_timeout, socketpair_wrap): DS. * stream.c (generic_fill_buf, errno_to_string, stdio_truncate, string_out_put_string, open_fileno, open_command, base_name, dir-name): DS. (unget_byte, put_buf, fill_buf, fill_buf_adjust, get_line_as_buf, formatv, put_byte, test_set_indent_mode, test_neq_set_indent_mode, set_indent_mode, set_indent, inc_indent, set_max_length, set_max_depth, open_subprocess, run ): PS. (fds_subst, fds_swizzle): TS. * struct.c (make_struct_type, super, umethod_args_fun): PS. (method_args_fun): DS. * strudel.c (strudel_put_buf, strudel_fill_buf): DS. * sysif.c (errno_wrap, exit_wrap, usleep_wrap, mkdir_wrap, ensure_dir, makedev_wrap, minor_wrap, major_wrap, mknod_wrap, mkfifo_wrap, wait_wrap, wifexited, wexitstatus, wifsignaled, wtermsig, wcoredump, wifstopped, wstopsig, wifcontinued, dup_wrap, close_wrap, exit_star_wrap, umask_wrap, setuid_wrap, seteuid_wrap, setgid_wrap, setegid_wrap, simulate_setuid_setgid, getpwuid_wrap, fnmatch_wrap, dlopen_wrap): DS. (chmod_wrap, do_chown, flock_pack, do_utimes, poll_wrap, setgroups_wrap, setresuid_wrap, setresgid_wrap, getgrgid_wrap): PS. (c_time): TS. * sysif.h (c_time): Declaration updated. * syslog.c (openlog_wrap, syslog_wrap): DS. * termios.c (termios_pack): TS. (tcgetattr_wrap, tcsetattr_wrap, tcsendbreak_wrap, tcdrain_wrap, tcflush_wrap, tcflow_rap, encode_speeds, decode_speeds): DS. * txr.c (compato, array_dim, gc_delta): DS. * unwind.c (uw_find_frames_by_mask): DS. * vm.c (vm_make_desc): PS. (vm_make_closure, vm_swtch): DS.
* New function: maprodo.Kaz Kylheku2020-06-281-0/+12
| | | | | | | | | | maprodo is like maprod, but doesn't collect or return anything. It's the Cartesian product analog of mapdo. * eval.c (collect_nothing, maprodo): New static functions. (eval_init): Register maprodo intrinsic. * txr.1: Documented.
* New functions: list-seq, ved-seq and str-seq.Kaz Kylheku2020-06-281-0/+3
| | | | | | | | | | | | | | These functions convert any iterable to a list, vector or string. * eval.c (eval_init): Registered list-seq, vec-seq and str-seq intrinsics. * lib.c (list_seq, vec_seq, str_seq): New functions. * lib.h (list_seq, vec_seq, str_seq): Declared. * txr.1: Documented.
* each: fix (each ()) segfault.Kaz Kylheku2020-06-061-4/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The (each ()) form should infinitely loop, and the compiled version does. The interpreter crashes, when that is a top-level form. The reason is that the underlying sys:each-op operator uses an empty list of variable names as an indication to use the bindings from the parent lexical environment. And in that particular case, the let is also empty. The whole thing looks like: (let () (sys:each-op each nil)) If this is a top-level expression, then op_let receives a null environment pointer. Since it has no bindings to add, it doesn't extend the environment chain and passes a null environment pointer down to op_each, which that tries to use, because it's told to reach into it for bindings. Let's use the t symbol for that instead, so then the above would look like: ;; the t and only the t means "access parent env" (let () (sys:each-op each t)) And then, let's also fix it so that t is never used in this case when there are no vars: ;; no t, and so don't access parent env. (let () (sys:each-op each nil)) * eval.c (op_each): Get the bindings from the parent environment if vars is t, rather than when it's null. (me_each): When the symbols are not being inserted into the sys:each-op form, then insert t to indicate that, rather than nil. If the source form specifies an empty list of bindings, then insert nil, not t. * share/txr/stdlib/compiler.tl (expand-each): Get the list of variable names from the parent lexical environment when vars is t, rather than when it's null.
* mapcar/maprod: fix stack overflow regression.Kaz Kylheku2020-06-051-6/+5
| | | | | | | | | | | | The recent refactoring of the mapping functions to use stack-allocated iterators has a bug. args_decl occurs inside a loop. But args_decl uses alloca, which doesn't dispose of the memory when the block scope terminates. * eval.c (map_common, prod_common): Move the declaration of args_fun outside of the loop, so that it is allocated just once. The loop just stuffs fresh sets of values into the arguments.
* mapping: rewrite loop using seq_info and args.Kaz Kylheku2020-06-041-19/+27
| | | | | | | | | | | | | | | * eval.c (map_common): Do not extract the arguments as a list. Do not produce a list of iterator objects. Instead, allocate an array of seq_iter_t objects on the stack using alloca, and use these for walking the input lists in parallel. Do not cons a list of the tuples coming from the lists, but rather store the tuples into a struct args, also on the stack, and invoke the function with that. Now, the only heap memory we allocate is the resulting list being accumulated. In the case of mapdo, no heap allocation takes place. However, if some of the inputs are hashes, then hash iterators get allocated in seq_iter_init. (mapcarv, mappendv, mapdov): Pass self argument to map_common, needed for seq_iter_init.
* mapcar, mappend, mapdo: merge implementations.Kaz Kylheku2020-06-041-60/+20
| | | | | | * eval.c (map_common): New static function. (mapcarv, mappendv, mapdov): Now one-line wrappers for map_common.
* maprod: bugfix: not reducing to mapcar.Kaz Kylheku2020-06-041-5/+6
| | | | | | | | | | | The one list case of maprod reduces to mappend rather than mapcar, so that [maprod identity '(1 2 3)] fails instead of producing (1 2 3). * eval.c (prod_common): Take pointer to mapping function to use in one-list case, and use it. (maprodv): Pass mapcarv to prod_common. (maprendv): Pass mappendv to prod_common.
* Convert mapping functions to new iterators.Kaz Kylheku2020-06-031-57/+63
| | | | | | | | | | | | | | | | | * eval.c (get_iter_f): Renamed to iter_from_binding_f. (iter_begin_f, iter_more_f, iter_item_f, iter_step_f): New global variables. (op_each): Follow rename of get_iter_f. (mapcarv, mappendv, lazy_mapcar_func, lazy_mapcar, lazy_mapcarv_func, lazy_mapcarv, mapdov, prod_common): Convert from car/cdr/null-test iteration to iter-begin. (eval_init): gc-protect and initialize new variables. * lib.c (mapcar_listout, mappend, mapdo): Convert to seq_iter iteration. List argument renamed to seq. (mapcar): List argument renamed to seq. * lib.h: Declarations updated with renamed arguments.
* Convert each-family operators to use iter-begin.Kaz Kylheku2020-06-021-10/+11
| | | | | | | | | | | | | | | | | | | With this change we can do (each ((x vec)) ...) with reasonable efficiency, because we are no longer marching through the vector with cdr, copying the suffix. * eval.c (get_iter_f): New global variable. (op_each): Obtain iterators for all the objects with iter_begin, instead of treating them as lists. Probe the iterators for termination with iter_more, get the items with iter_item instead of car and step with iter_step instead of cdr. (eval_init): gc-protect the get_iter_f function and initialize it. * share/txr/stdlib/compiler.tl (expand-each): Replace the car/cdr and null testing with iter-init, iter-more, iter-item and iter-step.
* New style iteration functions.Kaz Kylheku2020-06-021-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | iter-begin provides a paradigm for iteration that is more compatible with lists. If the sequence is a list, then the list itself is returned as the iterator, and the other functions are basicaly wrappers for car/cdr and null testing. Yet the API is defined in such a way that other objects can be iterated with good efficiency, at the cost of allocating a new iterator object (which can be re-used). * eval.c (eval_init): Register iter-begin, iter-more, iter-item, iter-step and iter-reset. * lib.c (seq_iter_init_with_info): New static function. (seq_iter_init): Now a thin wrapper for seq_iter_init_with_info. (iter_begin, iter_more, iter_item, iter_step, iter_reset): New functions. * lib.h (iter_begin, iter_more, iter_item, iter_step, iter_reset): New functions. * txr.1: Documented.
* quasistrings: reduce consing.Kaz Kylheku2020-05-301-5/+0
| | | | | | | | | | | | | | | | | | | Quasistrings compile to code that requires on the sys:fmt-join function to glue strings together. Rewriting that function to avoid converting its arguments from struct args * to a list. * eval.c (fmt_join): Static function removed. * lib.c (cat_str_measure, cat_str_append): more_p parameter changed to int type, which better matches the C style Boolean values it takes. (fmt_join): New external function. * lib.h: Declared. * args.h (args_more_nozap, args_get_nozap): New inline functions allowing multiple iterations over arguments without making a copy.
* New assert macro.Kaz Kylheku2020-05-181-0/+45
| | | | | | | | | | | | * eval.c (rt_assert_fail, me_assert): New static functions. (eval_init): assert macro and sys:rt-assert-fail function registered. * lib.c (func_n4ov): New function. * lib.h (func_n4ov): Declared. * txr.1: Documented.
* sort: prudently make it subject to compat valueKaz Kylheku2020-05-141-2/+4
| | | | | | | | | | | | * eval.c (eval_init): If opt_compat is 237 or less, make sort and shuffle destructive. * share/txr/stdlib/getopts.tl (opthelp): Revert previous change, restoring use of copy-list and use nsort instead of sort, so the function is not affected by the 237 compatibility being turned on. * txr.1: Add compatibility notes.
* lib: sort becomes non-destructive; nsort introduced.Kaz Kylheku2020-05-131-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* symbol-function: bugfix: expand lambda expression.Kaz Kylheku2020-05-031-1/+1
| | | | | | | * eval.c (lookup_fun): A lambda expression must be expanded before being turned into a function. * txr.1: Documented.
* load: release warnings before throwing exception.Kaz Kylheku2020-04-141-3/+4
| | | | | | | | | | | | * eval.c (load): When we parse TXR code, let's not release warnings unconditionally. Let's do that when throwing an exception though due to parse errors. If the load is not recursed it will release warnings at the bottom of the function. * match.c (v_load): Consistently with load, release deferred warnings if throwing exception due to the parse having failed.
* bugfix: definitions must trigger autoload.Kaz Kylheku2020-04-131-1/+6
| | | | | | | | | | | | | | When a function, macro, variale, symbol macro or struct is being defined, we must trigger any auto-load for that symbol. If the definition is redefining a library symbol, then if the autoload is later triggered, it will surprisingly reinstate the library definition. * eval.c (rt_defvarl, op_defsymacro, rt_defsymacro, rt_defun, rt_defmacro): Insert calls to lisplib_try_load against the symbol being defined. * struct.c (make_struct_type): Likewise.
* exceptions: use uw_rthrow for non-error exceptions.Kaz Kylheku2020-04-071-6/+6
| | | | | | | | | | | | | | | | | | | * eval.c (eval_exception): This function is shared by warnings and errors. Use uw_throw. The eval_error caller already has an abort() after its eval_exception call, which makes that code path continue to be equivalent to uw_throw. The behavior changes for the other caller, eval_warn, which will now return if the warning is not handled. (eval_defr_warn, gather_free_refs, gather_free_refs_nw): Throw non-error exception with uw_rthrow. * match.c (v_throw, v_assert, h_assert): Use uw_rthrow for these directives, just like the throw function. * parser.c (repl_intr, repl_warning): Use uw_rthrow. * unwind.c (uw_muffle_warning, uw_release_deferred_warnings): Likewise.
* warning cleanup: remove unused parameters.Kaz Kylheku2020-04-051-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-3/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 function: txr-parse.Kaz Kylheku2020-04-021-0/+1
| | | | | | | | | | | | txr-parse provides a way for Lisp code to programmatically parse the TXR language and obtain the Lisp represenation. This has hitherto not been available. * eval.c (eval_init): Register txr-parse intrinsic. * parser.c (txr_parse): New function. * parser.h (txr_parse): Declared.
* New contains function: near alias of search.Kaz Kylheku2020-03-231-0/+1
| | | | | | | | | | | | 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.
* apf and ipf: take arguments that are inserted.Kaz Kylheku2020-03-221-7/+40
| | | | | | | | | | | | | | The apf and ipf functions now take arguments in addition to the function that is being wrapped. If specified, these arguments are inserted to the left the applied arguments. * eval.c (do_args_apf, do_args_ipf): New static functions. (apf, ipf): Use do_args_apf and do_args_ipf, respectively, for handling the case when arguments are present. Passing the stored arguments is done with the help of the new DARG type, instead of consing up a list. * txr.1: Documented new arguments of apf and ipf.
* internals: rename misnamed curry_* functions.Kaz Kyheku2020-03-171-9/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* New function: assq and rassq.Kaz Kyheku2020-02-241-0/+2
| | | | | | | | | | | | | | | | | | | | | 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/+3
| | | | | | | | | | * 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.
* packages: no default argument in several functions.Kaz Kyheku2020-01-291-3/+3
| | | | | | | * eval.c (eval_init): bugfix: for the functions package-symbols, package-local-symbols and package-foreign-symbols, make the package parameter optional, as is specified in the documentation.
* New function: merge-delete-package.Kaz Kyheku2020-01-291-0/+1
| | | | | | | | | | | | | | | | | | | | | 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/+1
| | | | | | | | * eval.c (eval_init): Register coded-length intrinsic. * lib.c (coded_length): New function. * lib.h (coded_length): Declared.
* builtin redefinition: better diagnostic message.Kaz Kylheku2020-01-061-6/+10
| | | | | | | | | | | | | | | | | | | The motivation here is that if we define, say, a macro whose name is the same as a built-in function, we get a warning which misleadingly uses the word "redefining". * eval.c (builtin_reject_test): Add a new parameter which indicates what kind of binding is being defined. This has the same values as the builtin hash. If the builtin hash reports that the symbol is a builtin, we can issue one of two diagnostic messages based on whether the one being defined is of the same kind or noto. (expand_macrolet): Pass the defmacro symbol to builtin_reject_test, since macros are being defined. (expand_fbind_vars): Pass the defun symbol symbol to builtin_reject_test. (do_expand): In the defun/defmacro case, pass the operator in question to builtin_reject_test.
* 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.
* eval: bugfix: expansion wrongly always in null env.Kaz Kylheku2019-11-181-5/+34
| | | | | | | | | | | | | | | | | | | | | | The eval function uses a null macro environment for expanding a form, even when it's given an environment object. This causes spurious warnings about unbound variables/functions. For instance: (let ((env (make-env '((x . 42)) nil nil))) (eval '(+ x x) env)) ;; warning: unbound variable x To fix this, we have to create a macro version of the incoming environment and expand with that. * eval.c (env_to_menv): Take an evaluation environment chain and convert it to a (flattened) macro environment. (expand_eval): Take a macro environment parameter and use that for expanding the form to be evaluated, rather than nil. (eval_intrinsic): Calculate a macro environment corresponding to the given evaluation environment. Use that for the macroexpand call, and also pass it down to expand_eval to be used for the full expansion.
* lib: use stack-allocated hash iterators everywhere.Kaz Kylheku2019-11-011-2/+5
| | | | | | | | | | | | | | | | | * 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.
* expander: bogus undefined warnings from lisp1 values.Kaz Kylheku2019-10-301-8/+5
| | | | | | | | | | | | | Issue: (sys:lisp1-value x) throws a warning even if x is a predefined library function. This is caused by naively using expand to attempt to expand it as a symbol macro. * eval.c (expand_lisp1_value): Use expand_lisp1 instead of expand, just like expand_forms_lisp1. Because I didn't notice this problem when adding those two functions, expand_lisp1 is farther down the file and we need a forward declaration. (expand_lisp1_setq): Likewise, and eliminate the unbound variable check which is done by expand_lisp1.
* expander: allow TTY interrupt.Kaz Kylheku2019-10-281-0/+2
| | | | | * eval.c (expand): Call sig_check_fast so that if the expander gets into some kind of loop, it is interruptible.
* New function: identity*Kaz Kylheku2019-10-281-0/+1
| | | | | | | | | | | | | | | 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.
* functions: provide accessors for basic properties.Kaz Kylheku2019-10-181-0/+3
| | | | | | | | | | | | | | * 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.
* New function: copy-tree.Kaz Kylheku2019-10-161-0/+1
| | | | | | | | | | * eval.c (eval_init): Register copy-tree intrinsic. * lib.c (copy_tree): New function. * lib.h (copy_tree): Declared. * txr.1: Documented.
* eval: bugfix: don't pass eval env to macroexpand.Kaz Kylheku2019-10-131-1/+1
| | | | | | | * eval.c (eval_intrinsic): macroexpand must be called with the nil environment. If we had a macro env parameter, we could pass that. In any case, we mustn't pass an eval environment to the expander.
* expander: origin_hash must be eq-based.Kaz Kylheku2019-10-111-1/+1
| | | | | | | * eval.c (eval_init): Initialize origin_hash as eq-based hash table, not eql-based. The main culprit are range #R(x y) objects. eql equality recurses over these, and if it encounters a circular one like #R(#1# #1#), it crashes.
* tree: allow quasiquoting into #T syntax.Kaz Kylheku2019-09-281-1/+7
| | | | | | | | | | | | | | | | | * eval.c (tree_lit_s, tree_construct_s): New symbol variables. (expand_qquote_rec): Handle sys:tree-lit syntax generated by quasi-quoted #T notaton by expanding and converting to sys:tree-constuct call. (eval_init): Initialize tree_lit_s and tree_construct_s. * eval.h (tree_lit_s, tree_construct_s): Declared. * parser.y (tree): Produce sys:tree-lit syntax when #T is quasi-quoted, and unquotes occur inside it. * tree.c (tree_construct_fname, tree_construct): New static functions. (tree_init): Register sys:tree-construct intrinsic function.
* symbol-function: support lambda expressions.Kaz Kylheku2019-09-271-7/+3
| | | | | | | | | | | | | | | | | * eval.c (lookup_fun): Check for a lambda expression and return a faked binding containing the interpreted function. (do_eval, op_fun): Remove checks for lambda that are now being done in lookup_fun. In many other places where lookup_fun is used, we still need lambda checks, like in the expander. * share/txr/stdlib/place.tl (sys:get-fun-getter-setter): Take form argument. Diagnose assignments to lambda, and to unknown function place syntax. (defplace symbol-function): Pass sys:*pl-form* to sys:get-fun-getter-setter as form argument. * txr.1: fboundp and symbol-function doc updated.
* fun operator: don't cons binding when handling lambda.Kaz Kylheku2019-09-261-4/+4
| | | | | | * eval.c (op_fun): Don't cons up a fake fbinding when processing lambda; just return result of func_interp. Test for null fbinding consolidated, too.
* lookup_fun: eliminate recursion.Kaz Kylheku2019-09-261-24/+24
| | | | | | | | * eval.c (lookup_fun); Use iteration to search the nested environments. Put this code ahead of the global search so we fall back on it. Also, let's check for a compound function name first, so we don't search the environments for this.
* func-get-name: fix bogus return for nil argument.Kaz Kylheku2019-09-261-10/+15
| | | | | | | | | | | | * eval.c (func_get_name): when func_get_name has a nil function argument and nil env, it falls back on method_name, which naively searches its space and finds some static slots with a nil value which is then returned as a method name. Let's put in a type check that the argument must be a function. Also, let's drop the recursion in the nested environment search and switch to iteration, so we don't do these wasteful sanity checks on multiple re-entries of the function.
* New data structure: binary search trees.Kaz Kylheku2019-09-251-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Adding binary search trees based on the new tnode cell. The scapegoat algorithm is used, which requires no additional storage in a cell. In the future we may go to something else, like red-black trees, and carve out a bit in the tag field of the cell for the red/black color. Tree cells store only single key objects, not key/value pairs. However, which part of the key object is compared is determined by a custom key function stored in the tree container. For instance, tree nodes can be cons cells, and car can be used as the key function; the cdr then stores an associated value. Trees have a printed notation #T(<props> <key>*) where <props> is a list of up to three items: <props> ::= ([<key-fn> [<less-fn> [<equal-fn>]]]) key-fn, less-fn and equal-fn are function names. If they are missing or nil, they default, respectively, to identity, less and equal. For security, the printed notation is machine-readable only if these options are symbols, not lambda expressions. Furthermore, the symbols must be listed in the special variable *tree-fun-whitelist*. * eval.c (less_s): New symbol variable. (eval_init): Initialize less_s. * eval.h (less_s): Declard. * parser.h (grammar): New #T token recognized, mapped to HASH_T. * parser.y (HASH_T): New terminal symbol. (tree): New non-terminal symbol. (i_expr, n_expr): Add tree to productions. (fname_helper): New static function. (yybadtoken): Map HASH_T to "#T". * protsym.c: Tweaked accidentally; remove. * tree.c (TREE_DEPTH_MAX): New macro. (struct tree): New struct type. (enum tree_iter_state): New enumeration. (struct tree_iter): New struct type. (tree_iter_init): New macro. (tree_s, tree_fun_whitelist_s): New symbol variables. (tn_size, tn_size_one_child, tn_lookup, tn_find_next, tn_flatten, tn_build_tree, tr_rebuild, tr_find_rebuild_scapegoat, tr_insert, tr_lookup, tr_do_delete, tr_delete, tree_insert_node, tree_insert, tree_lookup_node, tree_lookup, tree_delete, tree_root, tree_equal_op, tree_print_op, tree_mark, tree_hash_op): New static functions. (tree_ops): New static struct. (tree): New function. (tree_init): Initialize tree_s and tree_fun_whitelist_s symbol variables. Register intrinsic functions tree, tree-insert-node, tree-insert, tree-lookup-node, tree-lookup, tree-delete, tree-root. Register special variable *tree-fun-whitelist*. * tree.h (tree_s, tree_fun_whitelist_s, tree): Declared. (tree_fun_whitelist): New macro.
* New data type: tnode.Kaz Kylheku2019-09-221-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.