summaryrefslogtreecommitdiffstats
path: root/lib.c
Commit message (Collapse)AuthorAgeFilesLines
...
* New function: find-true.Kaz Kylheku2021-06-291-0/+63
| | | | | | | | | | | | | | | This is like find-if, but returns the value of the predicate function rather than the item. * eval.c (eval_init): Register find-true instrinsic. * lib.c (find_true): New function. * lib.c (find_true): Declared. * stdlib/doc-syms.tl: Updated. * txr.1: Documented.
* parser: no string allocation when scanning floats.Kaz Kylheku2021-06-241-0/+25
| | | | | | | | | | | | | | | | | | | Each time the scanner processes a floating-point token, it allocates a string object, just so it can call flo_str. The object is then garbage. Let's stop doing that. * lib.c (flo_str_utf8): New function, closely based on flo_str. Takes a char * string. * lib.h (flo_str_utf8): Declared. * parser.l (out_of_range_float): Take the token as a const char * string instead of a Lisp string, so we can just pass yytext to this function. (grammar): Use flo_str_utf8 instead flo_str, and pass yytext to out_of_range_float. * lex.yy.c.shipped: Updated.
* New: stack overflow protection.Kaz Kylheku2021-06-231-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * configure: detect getrlimit, producing HAVE_RLIMIT in config.h. * eval.c (do_eval, do_expand): Call gc_stack_check inline function to check stack pointer against limit. * gc.c (gc_stack_bottom): Static becomes extern, so inline function in gc.h can refer to it. (gc_stack_limit): New global variable. (gc_init): If we have rlimit, then probe RLIMIT_STACK. If the stack is sufficiently large, then enable the stack overflow protection, which kicks in when the stack pointer appears to be within a certain percentage of the limit. (set_stack_limit, get_stack_limit): New static functions. (gc_late_init): Register set-stack-limit and get-stack-limit intrinsics. (gc_stack_overflow): New function. * gc.h (gc_stack_bottom, gc_stack_limit, gc_stack_overflow): Declared. (gc_stack_check): New inline function. * lib.c (stack_overflow_s): New symbol variable. (obj_print_impl): Call gc_stack_check to protect recursive printing againts overflow. * lib.h (stack_overflow_s): Declared. * unwind.c (uw_init): Register stack-overflow symbol as a an exception symbol subtyped from error. (uw_unwind_to_exit_point): When dealing with an unhandled exception, turn off the stack limit, so we can print the messages without triggering it in a loop. * vm.c (vm_execute_closure, vm_funcall_common): Insert gc_stack_check to the top of the execution of every VM function. * txr.1: Documented. * share/txr/stdlib/doc-syms.tl: Updated.
* lib: use existing self variable.Kaz Kylheku2021-06-231-2/+2
| | | | | * lib.c (populate_obj_hash): Refer to self, rather than hard coding function name prefix.
* cmp_str: whitespace.Kaz Kylheku2021-06-231-37/+37
| | | | * lib.c (cmp_str): Fix incorrect indentation.
* cyr: broken on 64 bit.Kaz Kylheku2021-06-231-2/+3
| | | | * lib.c (cyr): We must use the cnum type for the mask, not int.
* c_str now takes a self argument.Kaz Kylheku2021-06-231-69/+87
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Adding a self parameter to c_str so that when a non-string occurs, the error is reported against a function. Legend: A - Pass existing self to c_str. B - Define self and pass to c_str and possibly other functions. C - Take new self parameter and pass to c_str and possibly other functions. D - Pass existing self to c_str and/or other functions. E - Define self and pass to other functions, not c_str. X - Pass nil to c_str. * buf.c (buf_strm_put_string, buf_str): B. * chksum.c (sha256_str, md5_str): C. (sha256_hash, md5_hash): D. * eval.c (load): D. * ffi.c (ffi_varray_dynsize, ffi_str_put, ffi_wstr_put, ffi_bstr_put): A. (ffi_char_array_put, ffi_wchar_array_put): C. (ffi_bchar_array_put): A. (ffi_array_put, ffi_array_out, ffi_varray_put): D. * ftw.c (ftw_wrap): A. * glob.c (glob_wrap): A. * lib.c (copy_str, length_str, coded_length,split_str_set, list_str, cmp_str, num_str, out_json_str, out_json_rec, display_width): B. (upcase_str, downcase_str, string_extend, search_str, do_match_str, do_rmatch_str, sub_str, replace_str, cat_str_append, split_str_keep, trim_str, int_str, chr_str, span_str, compl_span_str, break_str, length_str_gt, length_str_ge, length_str_lt, length_str_le, find, rfind, pos, rpos, mismatch, rmismatch): A. (c_str): Add self parameter and use in type mismatch diagnostic. If the parameter is nil, use "internal error". (flo_str): B, and correction to "flot-str" typo. (out_lazy_str, out_quasi_str, obj_print_impl): D. * lib.h (c_str): Declaration updated. * match.c (dump_var): X. (v_load): D. * parser.c (open_txr_file): C. (load_rcfile): E. (find_matching_syms, provide_atom): X. (hist_save, repl): B. * parser.h (open_txr_file): Declaration updated. * parser.y (chrlit): X. * regex.c (search_regex): A. * socket.c (getaddrinfo_wrap, sockaddr_pack): A. (dgram_put_string): B. (open_sockfd): D. (sock_connect): E. * stream.c (stdio_put_string, tail_strategy, vformat_str, open_directory, open_file, open_tail, remove_path, rename_path, tmpfile_wrap, mkdtemp_wrap, mkstemp_wrap): B. (do_parse_mode, parse_mode, make_string_byte_input_stream): B. (normalize_mode, normalize_mode_no_bin): E. (string_out_put_string, formatv, put_string, open_fileno, open_subprocess, open_command, base_name, dir_name, short_suffix, long_suffix): A. (run): D. (win_escape_cmd, win_escape_arg): X. * stream.h (parse_mode, normalize_mode, normalize_mode_no_bin): Declarations updated. * sysif.c (mkdir_wrap, do_utimes, dlopen_wrap, dlsym_wrap, dlvsym_wrap): A. (do_stat, do_lstat): C. (mkdir_nothrow_exists, ensure_dir): E. (chdir_wrap, rmdir_wrap, mkfifo_wrap, chmod_wrap, symlink_wrap, link_wrap, readlink_wrap, exec_wrap, getenv_wrap, setenv_wrap, unsetenv_wrap, getpwnam_wrap, getgrnam_wrap, crypt_wrap, fnmatch_wrap, realpath_wrap, opendir_wrap): B. (stat_impl): statfn pointer-to-function argument now takes self parameter. When calling it, we pass name. * syslog.c (openlog_wrap, syslog_wrapv): A. * time.c (time_string_local, time_string_utc, time_string_meth, time_parse_meth): A. (strptime_wrap): B. * txr.c (txr_main): D. * y.tab.c.shipped: Updated.
* lib: rmismatch tests and bugfix.Kaz Kylheku2021-06-221-1/+1
| | | | | | | * lib.c (rmismatch): when left is an empty string or vector, and right is nil: we must return -1 not zero. * tests/012/seq.tl: More rmismatch tests.
* lib: optimize mismatch, rmismatch for strings.Kaz Kylheku2021-06-221-3/+46
| | | | | | | | | | | * lib (mismatch, rmismatch): If the arguments are strings or literals, other than lazy strings, keyfun is identity, and equality is by character identity, the operation can be done with an efficient loop over the wchar_t strings. * tests/012/seq.tl: Tests for string case of mismatch, via starts-with function. Test mismatch via ends-with, and also directly for vectors and strings.
* Dubious new functions cxr/cyr.Kaz Kylheku2021-06-211-0/+69
| | | | | | | | | | | | | | * lib.c (cxr, cyr): New functions. * lib.h (cxr, cyr): Declared. * eval.c (eval_init): Intrinsics cxr and cyr registered. * tests/012/cadr.tl: New file. * txr.1: Documented. * share/txr/stdlib/doc-syms.tl: Updated.
* lib: remove useless coerce.Kaz Kylheku2021-06-211-1/+1
| | | | | * lib.c (string): chk_strdup returns the wchar_t * type already; there is no need to coerce.
* reduce-left: rewrite using seq_iter.Kaz Kylheku2021-06-091-6/+10
| | | | | | | * lib.c (reduce_left): Use sequence iteration instead of list operations. * txr.1: Add a note to the documentation.
* lib: new function, fill-vec.Kaz Kylheku2021-06-081-0/+34
| | | | | | | | | | | | | | * eval.c (eval_init): Register fill-vec intrinsic. * lib.c (fill_vec): New function. * lib.h (fill_vec): Declared. * tests/010/vec.tl: New file. * txr.1: Documented. * share/txr/stdlib/doc-syms.tl: Updated.
* lib: oversight, neglected struct literal printing.Kaz Kylheku2021-06-031-0/+3
| | | | | * lib.c (obj_print_impl): print (sys:struct-lit ...) syntax as #S(...).
* json: fix quasiquote print-read consistency issueKaz Kylheku2021-06-031-10/+24
| | | | | | | | | | | | * lib.c (out_json_rec): When printing keys that might be potentially quasiquoted symbols that look like ~abc, we must avoid the condensed {~abc:~def} style. This is because abd:~def looks like a single symbol, where abc is a package qualifier. To be safe and readable at the same time, we add spaces whenever either the key or the value are conses, indicating non-JSON syntax. Spaces are added on both sides of the colon, and also after the preceding comma, if there is a previous item.
* json: improve escaping for script tags.Kaz Kylheku2021-06-031-1/+12
| | | | | | | | | | | * lib.c (out_json_str): Strengthen the test for escaping the forward slash. It has to occur in the sequence </script rather than just </. Recognize <!-- and --> in the string, and encode them. * tests/010/json.tl: Cover this area with some tests. * txr.1: Documented.
* chr-iscntrl: recognize Unicode C0 and C1.Kaz Kylheku2021-06-011-1/+7
| | | | | | | | * lib.c (chr_iscntrl): Don't use iswcntrl; it fails to report 0x80-0x9F as control characters. A bit of hand-crafted logic does the job. * txr.1: Redocumented.
* json: turn on indentation.Kaz Kylheku2021-05-311-12/+7
| | | | | | | | * lib.c (put_json): Turn on indentation if the flat argument doesn't suppress it, and the stream is not in forced-off indentation mode. (tojson): Retarget to put_json, so we don't have to repeat this logic.
* json: fix circular printing.Kaz Kylheku2021-05-311-21/+34
| | | | | | | | | | | | | | | | | The recursive JSON printer must check for the circularity circularity-related conditions and emit #n= and #n# notations. * lib.c (circle_print_eligible): Function moved before out_json_rec to avoid a forward declaration. (check_emit_circle): New static function. This is a block of code for doing the circular logic, taken out of obj_print_impl, because we would like to use it in out_json_rec. (out_json_rec): Call check_emit_circle to emit any #n= or #n# notation. The function returns 1 if it has emitted #n#, in which a se we are done. (obj_print_impl): Replace moved block of code with call to check_emit_circle.
* json: functions put-json and put-jsonl.Kaz Kylheku2021-05-291-2/+22
| | | | | | | | | | | | | | | | | | | | | * eval.c (eval_init): Register put-json and put-jsonl intrinsics. * lib.c (out_json_str): Do not output the U+DC01 to U+DCFF code points by masking them and using put_byte. This is unnecessary; if we just send them as-is to the text stream, the UTF-8 encoder does that for us. (put_json, put_jsonl): New functions. * lib.h (put_json, put_jsonl): Declared. * txr.1: Documented. The bulk of tojson is moved under the descriptions of these new functions, and elsewhere where the document pointed to tojson for more information, it now points to put-json. More detailed description of character treatment is given. * share/txr/stdlib/doc-syms.tl: Updated.
* json: tojson must not add #J prefix.Kaz Kylheku2021-05-291-18/+6
| | | | | | | | | | | * lib.c (out_json_rec): In the CONS case, if ctx is null bail and report and invalid object. This lets us call the function with a null context. (tojson): Do not support (json ...) syntax. Instead of obj_print, pass the object directly to out_json_rec. * txr.1: Do not mention handling json macro syntax. Common leading text factored out of bulleted paragraphs section.
* json: escape slash in </ sequenceKaz Kylheku2021-05-291-0/+5
| | | | | | | | | * lib.c (out_json_str): When the < character is seen, if the lookahead character is /, output the < and a backslash to escape the /. * txr.1: Moved description of special JSON output handling under tojson, and described the above escaping there also.
* json: tojson function.Kaz Kylheku2021-05-281-0/+21
| | | | | | | | | | | | * eval.c (eval_init): tojson intrinsic registered. * lib.c (tojson): New function. * lib.h (tojson): Declared. * txr.1: Documented. * share/txr/stdlib/doc-syms.tl: Updated.
* json: indentation support for printing.Kaz Kylheku2021-05-281-5/+47
| | | | | | | | | * lib.c (out_json_rec): Save, establish and restore indentation when printing [ ] and { } notation. Enforce line breaks, and force a line break after the object if one occurred in the object. (out_json): Turn on indentation if it is off (but not if it is forced off). Restore after doing the object.
* json: printing support.Kaz Kylheku2021-05-281-0/+183
| | | | | | | | | | First cut, without line breaks or indentation. * lib.c (out_json_str, out_json_rec, out_json): New static functions. (obj_print_impl): Hook in json printing via out_json. * txr.1: Add notes about output to JSON extensions.
* window-map: broken :wrap and :reflect.Kaz Kylheku2021-05-251-11/+21
| | | | | | | | | | | * lib.c (window_map_list): Rewrite :wrap and :reflect support. The main issue with these is that they only sample items from the front of the input list and generate both flanks of the boundary from that prefix; :reflect is additionaly buggy due to applying nreverse to a sub which can return the original sequence. * tests/012/seq.tl: Some test coverage for window-map.
* lib: sys_rplacd misnamed parameter.Kaz Kylheku2021-05-141-3/+3
| | | | | * lib.c (sys_rplacd): Change parameter name from new_car to new_cdr, for obvious reasons.
* cygwin: fix broken string catenation.Kaz Kylheku2021-05-121-4/+4
| | | | | | * lib.c (cat_str, vscat, scat3, join_with): Pass onech rather than wref(onech) to cat_str_init. Reason being, cat_str_init calls wref(onech).
* tree: let tree-iter be iterable via generic iteration.Kaz Kylheku2021-05-121-0/+10
| | | | | | | | | | * lib.c (seq_iter_init_with_info): Recognize tree_iter object, and treat using tree iterator function. * tests/010/tree.tl: test case for tree subrange iteration with collect-each. * txr.1: Updated.
* tree: streamline iteration; provide high limit.Kaz Kylheku2021-05-111-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Getting rid of tree-begin-at and tree-reset-at. Now tree-begin takes two optional parameters, for specifying high and low range. * tree.c (struct tree_diter): New members, tree and highkey. We need tree due to requiring access to the less function. If the iterator has no highkey, the iterator itself is stored in that member to indicate this. (tree_iter_mark): Mark the tree and highkey. (tree_begin): Take optional lowkey and highkey arguments, initializing iterator acordingly. (tree_begin_at): Function removed. (copy_tree_iter, replace_tree_iter): Copy tree and highkey members. The latter require special handling due to the funny convention for indicating highkey absence. (tree_reset): Take optional lowkey and highkey arguments, configuring these in the iterator being reset. (tree_reset_at): Function removed. (tree_next, tree_peek): Implement highkey semantics. (sub_tree): Simplified: from and to arguments are just passed through to tree_begin, and there is no need for a separate loop which enforces the upper limit, that now being handled by the iterator itself. (tree_begin): Update registrations of tree-begin and tree-reset; remove tree-begin-at and tree-reset-at intrinsics. * tree.h (tree_begin_at, tree_reset_at): Declarations removed. (tree_begin, tree_reset): Declarations updated. * lib.c (seq_iter_rewind, seq_iter_init_with_info, where, populate_obj_hash): Default new optional arguments in tree_begin and tree_reset calls. * parser.c (circ_backpatch): Likewise. * tests/010/tree.tl: Affected cases updated. * txr.1: Documentation updated. * share/txr/stdlib/doc-syms.tl: Regenerated.
* tree: support indexing and range extraction.Kaz Kylheku2021-05-111-0/+20
| | | | | | | | | | | | | | | | | | | * lib.c (do_generic_funcall): Support tree object invocation with one or two arguments via sub and ref. (sub): Implement for trees via sub_tree. (ref): Implement for trees via tree_lookup. * tree.c (sub_tree): New function. (tree_init): Register sub-tree intrinsic. * tree.h (sub_tree): Declared. * tests/010/tree.tl: New tests. * txr.1: Documented: DWIM bracket syntax on trees, sub and ref support for trees, sub-tree function, * share/txr/stdlib/doc-syms.tl: Regenerated.
* tree: copy-tree-iter function.Kaz Kylheku2021-05-101-0/+2
| | | | | | | | | | | | | | | * lib.c (copy): Handle tree_iter_s via copy_tree_iter. * tree.c (copy_tree_iter): New function. (tree_init): copy-tree-iter intrinsic registered. * tree.h (copy_tree_iter): Declared. * tests/010/tree.tl: New test case. * txr.1: Documented. * share/txr/stdlib/doc-syms.tl: Updated.
* diff/isec: reset hash/tree iter instead making new.Kaz Kylheku2021-05-101-2/+2
| | | | | | | | | | | * lib.c (seq_iter_rewind): Use hash_reset and tree_reset to rewind the existing iterator rather than allocating a new one. * tests/010/hash.tl: New file, covering uni, diff and isec for hash tables. * tests/010/tree.tl: New tests.
* lib: remove spurious null statement.Kaz Kylheku2021-05-101-1/+1
| | | | | * lib.c (seq_getpos): Remove spurious semicolon which adds an unreachable null statement.
* lib: basic support for trees as sequences.Kaz Kylheku2021-05-091-23/+123
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As of this commit, binary search trees can be iterated: mapped over with mapcar and such. * arith.c (poly, rpoly): rpoly won't work with trees. They work just with vectors and lists so let's make the error message more accurate. I noticed the self names of these two are swapped; will fix in another commit. * eval.c (tprint): Refactor to use iterator framework for objects other than lists. The tree case falls into this, so trees are supported. * lib.h (enum seq_kind): New enum constant SEQ_TREELIKE. (seq_iter_init_with_info): Declared. * lib.c (seq_info): Map tree object to SEQ_TREELIKE type. (seq_iter_get_tree, seq_iter_peek_tree): New static functions. (seq_iter_rewind): Support rewinding tree iteration. I think we could reuse the existing iterator here, and in the hash case as well. I made a note to look into this. (seq_iter_init_with_info): Internal linkage changed to external, because tprint in eval.c uses this. Handle SEQ_TREELIKE case here, by setting up iterator with the two new static functions. (seq_iter_mark): Handle SEQ_TREELIKE_CASE. Change switch statement to exhaustively list cases. (ldiff): Add SEQ_TREELIKE to various cases. Idea is that we handle it like SEQ_HASH. (nsort, sort, nshuffle, take, take_while, take_until, drop_while, drop_until, update): Add case for SEQ_TREELIKE, routing to error message. (lazy_where_tree_func): New static function. (where, sel, reject): Support trees.
* bug: join-with segfault on character separators.Kaz Kylheku2021-05-021-1/+2
| | | | | | | * lib.c (join_with): Pass the correct onech array down to cat_str_init, rather than a null pointer. * tests/015/split.tl: New tests covering join and join-with.
* lib: document gc problem related to seq-begin.Kaz Kylheku2021-04-281-0/+20
| | | | | | | | | | | | | | | | | | | | | If seq-begin is used on an object that supports the iter-begin method, there is a gc problem. This does not seem worth fixing for the following reasons. 1. The seq-begin function is marked obsolescent. I removed its one and only internal use in the previous commit, so it won't be called unless application code uses it. 2. Objects supporting the iter-begin function are clearly developed as part of the new iteration protocol. It makes no sense to be newly developing such an object, along with new code which applies seq-begin to it. There is likely zero code in the wild which uses either of these mechanisms. * lib.c (seq_iter_get_oop, seq_iter_peek_oop, seq_iter_get_fast_oop, seq_iter_peek_fast_oop): Add comments documenting the issue.
* lib: remove internal use of seq_begin.Kaz Kylheku2021-04-281-12/+16
| | | | | | | | | | The where function is the only place where seq-begin is used internally. The seq-begin mechanism is marked obsolescent in the documentation; let's not use it internally. * lib.c (lazy_where_func, where): Convert to iter_begin. Also, use us_lcons_fun and us_func_set_env. This seems to be the only place where lcons_fun and func_set_env are used.
* seq-iter: gc issue.Kaz Kylheku2021-04-281-1/+1
| | | | | | | | * lib.c (seq_iter_mark): The default case checks the type of the wrong object. The seq_iter object is necessarily a cobjp, and necessarily not a obj_struct_p so the test is always false, and we do not call gc_mark(si->ui.iter). The check must be applied to the object being iterated.
* match-str: tests and bugfix.Kaz Kylheku2021-04-271-1/+1
| | | | | | * lib.c (do_match_str): Fix wrong return value calculation in LSTR-LSTR case. * tests/015/match-str.tl: New file.
* match-str: rewrite.Kaz Kylheku2021-04-271-19/+101
| | | | | | | | | | Rewriting the match-str function to check some cases more cleverly and use wmemcmp at the core. * lib.c (do_match_str, do_rmatch_str): New static functions. (match_str): Replaced: just dispatches one of the static helpers based on whether the pos value is negative.
* match-str: return useful position instead of t.Kaz Kylheku2021-04-261-2/+2
| | | | | | | * lib.c (match_str): The match_str function is hereby altered to return an integer instead of the symbol t in the matching case. * txr.1: Updated.
* streams: revise stream-max-len over strings.Kaz Kylheku2021-04-171-16/+19
| | | | | | | | | | | | | | | | The maximum number of characters printed from a string is too small, if it is directly taken from the stream-max-len value. We are going to multiply it by 8, and clamp the minimum characters at 24. * lib.c (max_str_chars): New inline function. (lazy_str_put, out_lazy_str, out_quasi_str): Use inline function to determine maximum number of chracters to print. Also bugfix here: decrement and test max_chr in the loop, not max_len. This bug was copy-pasted across all these functions. (obj_print_impl): Similarly revise the printing of strings. * txr.1: Documentation updated.
* debugging: disassemble vm code out of debugger.Kaz Kylheku2021-04-161-0/+13
| | | | | | | | * lib.c (dis): New function that we can call from gdb to disassemble a VM function, if we know its address. I've done this manually way too many times. * lib.h (dis): Declared.
* func-optparam-count: bugfix.Kaz Kylheku2021-04-031-1/+1
| | | | | | | * lib.c (get_param_counts): If there are no optional parameters, then the oa variable stays negative; we must turn that into a zero, otherwise we return the bogus value -1 as the number of optional arguments.
* lib: remove unnecessary braces in funcall FVM cases.Kaz Kylheku2021-03-251-25/+15
| | | | | * lib.c (funcall, funcall1, funcall2, funcall3, funcall4): Remove unnecessary braces.
* cat-str: seq_iter conversion,Kaz Kylheku2021-03-141-6/+19
| | | | | | | * lib.c (cat_str): Traverse sequences of strings efficiently using seq_iter framework. * txr.1: Document.
* lib: fix neglect to use self variable.Kaz Kylheku2021-03-141-18/+18
| | | | | | | | | | | | | | | | * arith.c (toint): Use self instead of repeating function name in diagnostic. * ftw.c (ftw_wrap): Likewise. * glib.c (glow_wrap): Likewise. * rand.c (make_random_state, random): Likewise. * lib.c (nreverse, reverse, remove_if, int_str, less, chr_str, chr_str_set, unintern, rehome_sym, in): Likewise. (vector, obj_print_impl): Pass self to helper function instead of repeating identical literal.
* lib: fix hard-coded cat-str in diagnostic.Kaz Kylheku2021-03-121-2/+2
| | | | | | * lib.c (cat_str_measure): Use the self parameter in diagnostics rather than cat-str, so errors are reported against the correct function.
* sort: bugfix: broken for vectors/strings.Kaz Kylheku2021-03-101-1/+2
| | | | | * lib.c (sort): Return the copied and sorted object object, not the original.