summaryrefslogtreecommitdiffstats
path: root/lib.c
Commit message (Collapse)AuthorAgeFilesLines
...
* Another fix to print method circular printing.Kaz Kylheku2016-10-211-8/+21
| | | | | | | | | | | | | | | | | | | | | | | Continuing on the theme of the previous patch, we now properly detect the situation when the recursive call is re-introducing duplicate references to objects that have already been sent to the stream without at #<num>= label. It's too late to print those objects, so we throw an exception. * lib.c (obj_print_impl): When we print an object that doesn't have duplicates (its hash entry has a nil value), we replace that value with the : symbol to indicate that the object has already been printed. (obj_hash_merge): New function, factoring out the hash merging logic from obj_print, introduced in parent commit. Here, we detect the case that the recursive print call has submitted to us an object which was already printed without a label: because it is associated with the : symbol in the parent hash. This situation is a show-stopper so we throw. We cannot attempt to print the object in any manner because we can get into runaway recursion. (obj_print): Hash merging logic replaced with call to new static function.
* Fix circular printing across print methods.Kaz Kylheku2016-10-211-0/+10
| | | | | | | | | * lib.c (obj_print): When invoked recursively in circular printing mode, collect the nodes of the new object into a separate hash table. Then merge these entries into to the previous hash table. If the newly visited object visits objects we have already seen, suppress those entries.
* Changes to the printing framework.Kaz Kylheku2016-10-201-39/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The print function now takes an optional boolean for pretty printing. The print method is also called with a third argument; hence structures can customize both standard printing and pretty printing. * lib.c (obj_print): Take pretty argument, and pass it down to obj_print_impl. This makes obj_pprint redundant. (obj_pprint): Function removed: it was identical to obj_print except for passing t down to obj_print_impl for the pretty argument. These two wrappers had started small and got bigger with identical changes done in parallel. (pprint): New function. (tostring, dump): Pass nil for pretty argument of obj_print. (tostringp): Use pprint instead of obj_pprint. * lib.h (obj_print): Declaration updated. (obj_pprint): Declaration removed. (print, pprint): Declared. * eval.c (prinl): Pass nil for pretty_p argument of obj_print. Do the stream defaulting here; obj_print doesn't do it. (pprinl): Pass t for pretty_p argument of obj_print, and do stream argument defaulting. (eval_init): Register print to new print function rather than directly to obj_print. Register pprint to new pprint function rather than obj_pprint. * hash.c (hash_print_op): Call obj_print_impl to print the :equal-based keyword, rather than obj_print. Pass down the pretty flag. All the other keywords are treated this way; this fixes an inconsistency. * match.c (dump_var): Call pprint instead of obj_pprint. * stream.c (formatv): Call obj_print, with a calculated pretty argument instead of switching between obj_pprint and obj_print. * struct.c (struct_inst_print): Except when in backward compatibility mode, call the object's print method in both pretty and regular printing mode, passing the mode as a third argument. * tests/012/oop.tl (defstruct animal): Support third argument in print method. Make it optional because there are some explicit calls which don't pass the argument. * txr.1: Documentation updated for print method and the print function. Revised text for some of the related functions. Added compat notes.
* obj_print: use of volatile.Kaz Kylheku2016-10-201-3/+5
| | | | | | | | * lib.c (obj_print): The ret variable doesn't have to be volatile qualified, because it is never modified after setting an exception handler, and then accessed in the cleanup. On the other hand, the ctx variable is manipulated this way and must be volatile.
* Implement *print-circle* for sharing and cycles.Kaz Kylheku2016-10-201-5/+122
| | | | | | | | | | | | | | | | | | | | | | | * lib.c (obj_print_impl): On entry, ctx being non-null indicates that cycle and substructure detecting is enabled via *print-circle* for this print job. In this case, check whether this is the first request to print a multiply-referenced object, in which case we print the #<n>= label definition, or whether it is a second or additional reference, in which case we render the object as #<n>#. Special handling must also be introduced into the loop which prints list elements. At any point in a list, the rest of the list could be shared substructure or a cyclic link that must be rendered with the appropriate notation. (populate_obj_hash): New static function. Enters all objects in the substructure that are eligible for the circle notation into the hash that is stored in the print context. Any object that appears two or more times is associated with a t value. (obj_print, obj_pprint): Unless circle printing is already in effect, check *print-circle* and turn it on if necessary and prepare the context, associating it with the stream. Either way, if circle printing is enabled, call populate_obj_hash to walk the object and add its components to the hash.
* Add stream printing context.Kaz Kylheku2016-10-201-32/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is some infrastructure which will support *print-circle*. * lib.h (struct strm_ctx): Forward declared. (struct cobj_ops): Add context parameter to print function pointer. (cobj_print_op, obj_print_impl): Add context parameter to declarations. * hash.c (hash_print_op): Take context argument and pass it down in obj_print_impl calls. * lib.c (cobj_print_op, out_quasi_str): Likewise (obj_print_impl): Likewise, and also pass to COBJ print method. (obj_print, obj_pprint): Pass null pointer as context argument to obj_print_impl. * regex.c (regex_print): Take context parameter and ignore it. * socket.c (dgram_print): Likewise. * stream.h (struct strm_ctx): New struct type. (struct strm_base): New ctx member, pointer to struct strm_ctx. (stream_print_op): Add context parameter to declaration. (get_set_ctx, get_ctx): Declared. * stream.c (strm_base_init): Add null pointer to initializer. (strm_base_cleanup): Add assertion against context pointer being non-null: that indicates that some stream operation installed a context pointer and neglected to restore it to null before returning, which is bad because context will be stack allocated. (stream_print_op, stdio_stream_print, cat_stream_print): Take context parameter and ignore it. (get_set_ctx, get_ctx): New functions. * struct.c (struct_type_print): Take context parameter and ignore it. (struct_inst_print): Take context parameter and pass down to obj_print_impl.
* reduce-left bugfix: bad init val with key-func.Kaz Kylheku2016-10-181-1/+1
| | | | | * lib.c (reduce_left): init value pulled from list itself must be passed through the key function.
* Provide functions to alter range objects.Kaz Kylheku2016-10-171-0/+14
| | | | | | | | | | Ranges continue to be immutable; but a backdoor is needed for upcoming support for circular notation. * lib.c (set_from, set_to): New functions. * lib.h (set_from, set_to): Declared.
* Bugfix: sub and length on abstract sequences.Kaz Kylheku2016-10-131-1/+30
| | | | | | | | | | * lib.c (length_proper_list): New static function. (length): Use length_proper_list for objects. (sub): Call nullify on COBJ object before passing to sub_list. * tests/012/aseq.tl, tests/012/aseq.expected: New files.
* Overhaul where funtion.Kaz Kylheku2016-10-131-14/+43
| | | | | * lib.c (where): Implement faster ref-based access for vectors and strings. Support abstract sequence structs.
* Let some sequence functions work on structs.Kaz Kylheku2016-10-131-28/+32
| | | | | | * lib.c (in, sub, ref, search, rsearch, sel): These functions now accept struct objects that have the nullify, car and cdr methods.
* find-max and find-min support hashes.Kaz Kylheku2016-10-121-13/+55
| | | | | | | * lib.c (find_max): Restructured to implement separately for vectors and lists. Support hash tables. * txr.1: Document find-min and find-max for hashes.
* Support gmtoff and zone in time struct.Kaz Kylheku2016-10-121-2/+18
| | | | | | | | | | | | | | * lib.c (gmtoff_s, zone_s): New symbol variables. (tm_to_time_struct): Copy tm_gmtoff and tm_zone into Lisp struct from struct tm, if the platform has these. (time_fields_to_tm): Zero/null-out the tm_gmtoff and tm_zone fields of the target structure, if the platform has them. (time_init): Intern the gmtoff and zone symbols, initializing the gmtoff_s and zone_s variables. Add the gmtoff and zone slots to the time struct. * txr.1: Documented new slots.
* length and empty functions support ranges.Kaz Kylheku2016-10-041-0/+4
| | | | | | * lib.c (length, empty): Handle RNG in switch. * txr.1: Documented.
* Synchronize license comments with LICENSE.Kaz Kylheku2016-10-011-16/+17
| | | | | | | | | | | | | | | | | | | | * Makefile, args.c, args.h, arith.c, arith.h, cadr.c, cadr.h, combi.c, combi.h, configure, debug.c, debug.h, eval.c, eval.h, filter.c, filter.h, ftw.c, ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h, jmp.S, lib.c, lib.h, lisplib.c, lisplib.h, match.c, match.h, parser.c, parser.h, parser.l, parser.y, rand.c, rand.h, regex.c, regex.h, share/txr/stdlib/awk.tl, share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl, share/txr/stdlib/conv.tl, share/txr/stdlib/except.tl, share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl, share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl, share/txr/stdlib/socket.tl, share/txr/stdlib/struct.tl, share/txr/stdlib/termios.tl, share/txr/stdlib/txr-case.tl, share/txr/stdlib/type.tl, share/txr/stdlib/with-resources.tl, share/txr/stdlib/with-stream.tl, share/txr/stdlib/yield.tl, signal.c, signal.h, socket.c, socket.h, stream.c, stream.h, struct.c, struct.h, sysif.c, sysif.h, syslog.c, syslog.h, termios.c, termios.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h: Revert to verbatim 2-Clause BSD.
* Bugfix: out-of-range negative indices into lists.Kaz Kylheku2016-09-231-2/+5
| | | | | | | | | | | | | | | | | | We have a problem not handling negative list indices which index beyond the beginning of the list. Such accesses are just storing and retrieving the first element! * lib.c (listref): If a negative index is still negative after the length of the list is added to it, then return nil. Do not return car(list)! (listref_l): Similary, do not return car_l(list) if the index is less than zero, so that an error occurs for an out-of-range negative index. * txr.1: Update the documentation for ref to describe these indexing constraints, and also to include hashes.
* Switch regex type from sys:regex to regex.Kaz Kylheku2016-09-231-1/+1
| | | | | | | | | | | | | | | | | The sys:regex internal symbol was historically used when derivative-based regexes had a S-exp representation headed by that symbol. It had to be a private symbol. Now the regex symbol is only used as the COBJ class type for regexes; it makes no sense for it to be in the sys package. We want user code to be able to refer to this type using a public symbol. * lib.c (obj_init): Intern the regex symbol stored in regex_s in user_package. * txr.1: Include regex in the type graph in the Object Type section, and in the type list under the typeof function.
* Regexes now callable as functions.Kaz Kylheku2016-09-221-0/+16
| | | | | | | | * lib.c (generic_funcall): Add case for regexes. Handle arguments in such a way that the string is always rightmost, with a view to convenient partial application. * txr.1: Documented in multiple places.
* Bugfix in tok-str: empty-match regexes.Kaz Kylheku2016-09-161-10/+7
| | | | | | | | | | | | | | * lib.c (tok_str): Only continue the loop if the new position isn't past the end of the string. This fixes the problem of recognizing an empty token past the last character in the string. Also, advance new_pos by one if there is a zero length match. Then don't advance pos by one later in that case. This fixes the bug that we collect empty separator pieces *and* empty tokens, and also prevents empty matches before the first character of the string. Logic in tok_str is now very similar to that in split_str_keep.
* Bugfix in split-str: empty-match regexes.Kaz Kylheku2016-09-161-4/+5
| | | | | | | | | | | * lib.c (split_str_keep): In the regex case, changing to an infinite loop. The do/while is no longer needed because the if statement includes a test of the position having reached the end of the string. This is done before it is incremented by len, so we avoid wrongly keeping a separator. * txr.1: Clarified that an empty regex match behaves like an sep which is an empty string,
* split-str gains ability to keep separating pieces.Kaz Kylheku2016-09-161-1/+14
| | | | | | | | | | | | | | | * eval.c (eval_init): Register split-str to split_str_keep, with optional argument. * lib.c (split_str_keep): New function, formed from split_str, with third argument. (split_str): Reduced to wrapper around split_str_keep. Thus we don't have to update umpteen existing calls with an extra nil parameter. * lib.h (split_str_keep): Declared. * txr.1: Documented new optional argument of split-str.
* key function argument on remq, remql and remqual.Kaz Kylheku2016-09-151-6/+20
| | | | | | | | | | | | | | | | | * eval.c (weave_while): Pass third arg to remq as nil. (eval_init): Update registrations of remq, remql and remqual. * lib.c (remq, remql, remqual): Implement key function argument. * lib.h (remq, remql, remqual): Declarations updated. * sysif.c (at_exit_call): Pass third arg to remq as nil. * debug.c (debug): Pass third argument to remqual as nil. * txr.1: Documentation updated.
* New keepq, keepql and keepqual functions.Kaz Kylheku2016-09-151-0/+61
| | | | | | | | | * eval.c (eval_init): Register keepq, keepql and keepqual intrinsic functions. * lib.c (keepq, keepql, keepqual): New functions. * lib.h (keepq, keepql, keepqual): Declared.
* Fix broken keep/remove functions.Kaz Kylheku2016-09-141-19/+10
| | | | | | | | * lib.c (remq, remql, remqual, remove_if, keep_if): Bug: functions don't work correctly for strings. Anyway, the ldiff-based algorithm is ugly on vectors and strings. Patching things upp by converting input to list with tolist.
* Semantics change in trim-str function.Kaz Kylheku2016-09-111-4/+12
| | | | | | | | | * lib.c (trim_str): Trim only newlines and blanks, not carriage returns, vertical tabs and form feeds. This is subject to the compatibility option * txr.1: Doc updated and compatibility note added.
* Adding time-parse method.Kaz Kylheku2016-08-251-17/+66
| | | | | | | | | | | | | | | | | | | | * lib.c (time_parse_s): New symbol variable. (tm_to_time_struct): New static function, based on code moved out of broken_time_struct. (broken_time_struct): Bulk of code replaced with call to tm_to_time_struct. (time_struct_to_tm): New parameter, strict. Indicates whether nils in time struct are converted to zeros, or whether they trigger errors. (time_string_meth): Specify strict conversion of argument time struct to to struct tm when calling time_struct_to_tm. (time_parse_meth): New static function. (time_init): Initialize time_parse_s symbol variable; add time-parse static slot to time struct; initialize slot with new method. * txr.1: Document time-parse method.
* New time-string method on time struct.Kaz Kylheku2016-08-221-16/+52
| | | | | | | | | | | | | * lib.c (time_string_s): New symbol variable. (time_fields_to_tm, time_struct_to_tm): New static functions. (make_time_impl): Replace bunch of code with call to time_fields_to_tm. (time_string_meth): New static function. (time_init): Initialize time_string_s. Add time-string static slot to time struct. Register time-string method. * txr.1: Documented.
* Adding time-parse function: wrapper for strptime.Kaz Kylheku2016-08-221-0/+18
| | | | | | | | | | | | * configure: Test for strptime. * eval.c (eval_init): register time-parse intrinsic. * lib.c (time_parse): New function. * lib.h (time_parse): Declared. * txr.1: Documented.
* Print notation for quasi-strings and quasi-word-lists.Kaz Kylheku2016-07-201-0/+64
| | | | | | | * lib.c (out_quasi_str): New static function. (obj_print_impl): Handle sys:quasi and sys:quasilist forms, reproducing a syntax similar to their read notation.
* Replace 0 constant with nil.Kaz Kylheku2016-07-191-1/+1
| | | | | * lib.c (split_str): Fourth argument of search_regex is Lisp boolean, so nil should be used to specify false.
* Tidy up some vector object initializations.Kaz Kylheku2016-06-171-7/+7
| | | | | | | * lib.c (vector, copy_vec, sub_vec, cat_vec): Set the type field of the object sooner. Do not malloc between obtaining the object, and initializing it, because that could throw, leaving an uninitialized object in the heap space.
* New --free-all option for freeing memory on exit.Kaz Kylheku2016-06-071-3/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Although we are garbage-collected, being able to clean up on shutdown is nevertheless useful for uncovering leaks. Leaks can occur, for instance, due to neglect to free out-of-heap satellite data from objects that are reclaimed by gc. This feature is long overdue. * arith.c, arith.h (arith_free_all): New function. * gc.c, gc.h (gc_free_all): New function. * lib.c (init): Remove program name parameter and redundant initialization of progname globl variable. * lib.h (progname): Superfluous declaration removed. This is already declared in txr.h. (init): Declaration updated. * regex.c (char_set_destroy): Do not check the static allocation flag here; just destroy the object. Do check for a null pointer, though. (char_set_cobj_destroy): This cobj destructor now checks the static flag of the char set object and avoids freeing it. Thus our char set singletons are left alone by gc, but our global freeing function takes care of them. (wide_cs): New static variable moved out of wide_display_char_p to static scope. (regex_free_all): New function. * regex.h (regex_free_all): Declared. * txr.c (progname): const qualifier and initializer removed. (main): Ensure progname is always dynamically allocated, even in the argv[0] == 0 case. Do not pass progname to init; it doesn't take that argument any more. (free_all): New static function. (txr_main): Implement --free-all option. * txr.h (progname): Declaration updated.
* Handle sequence structs in length.Kaz Kylheku2016-06-061-0/+2
| | | | | * lib.c (length): In COBJ case, handle structures which have a car slot.
* Handle sequence structs in toseq.Kaz Kylheku2016-06-061-0/+4
| | | | | | * lib.c (toseq): Handle OBJP case, and implement behavior for struct objects that have a car method.
* Handle sequence better in index list case of replace.Kaz Kylheku2016-06-061-14/+9
| | | | | | | | | * lib.c (replace_list): Simplify treatment of items on entry using toseq. (replace_str, replace_vec): When a list or vector of indices is given, use the itseq result of passing items items through toseq function rather than original items, for consistency with range assignment.
* Handle structs in list collection operations.Kaz Kylheku2016-06-061-0/+10
| | | | | | | | | | | | | | | This eliminates the error which occurs when a sequence implemented as a struct is nconced or appended onto. The struct is converted to a list, and so is the object on the right hand side. As a result, more generic sequence code works on structs. * lib.c (list_collect_nconc, list_collect_append): Handle tail of type COBJ by converting to a list, storing that list back in the tail and then destructively tacking onto that the obj operand, also turned into a list.
* Use local var in list_collect_{nconc,append}.Kaz Kylheku2016-06-061-10/+12
| | | | | | | * lib.c (list_collect_nconc, list_collect_append): Capture deref(ptail) subexpression in local var and refer to that in all code where ptail isn't modified from the original value.
* Fix useless tolist over COBJ objects.Kaz Kylheku2016-06-061-1/+1
| | | | | | * lib.c (tolist): Use mapcar_listout, to avoid the conversion of the resulting list to the object's type, making this whole operation useless!
* Fix error messages in internal function scat.Kaz Kylheku2016-06-051-2/+2
| | | | | * lib.c (vscat): Replace "cat-str" and "vcat" with correct name "scat".
* Adding special function from-list.Kaz Kylheku2016-06-011-1/+9
| | | | | | | | | | * lib.c (from_list_s): New symbol variable. (make_like): Handle a COBJ. If it's a structure with a from-list method, then use it, otherwise the default handling applies of returning the list. (obj_init): Initialize from_list_s. * txr.1: Documented.
* ldiff uses equal for all non-list arguments.Kaz Kylheku2016-06-011-6/+5
| | | | | | | | | | | * lib.c (ldiff): Rather than checking specifically for strings and vectors to apply the special case behavior (comparison using equal), test specifically for lists and apply the traditional behavior. Every other object, not just strings and vectors, gets the altered behavior. * txr.1: Changed text in TXR Lisp introduction which touches on ldiff, and wording fix under ldiff.
* Methods for turning objects into sequences.Kaz Kylheku2016-06-011-2/+20
| | | | | | | | | | | | | | | | | | | | | | | | Struct objects can now define methods car, cdr and nullify. With these, they can participate in operations on sequences. * eval.h (car_s, cdr_s): Declared. * lib.c (nullify_s): New symbol variable. (car, cdr): Implement for struct objects via, respectively, their car and cdr methods. (tolist): Handle objects by mapping through identity. (nullify): Implement for objects optionally: if an object is a struct with a nullify method, use it, otherwise go through default case of just returning the object. (empty): Implement for objects that have nullify method. (obj_init): Initialize nullify_s. * struct.c (maybe_slot): New function. * struct.h (maybe_slot): Declared. * txr.1: Documented car, cdr and nullify method convention.
* Remove superfluous arg defaulting in drop functions.Kaz Kylheku2016-05-261-4/+2
| | | | | | * lib.c (drop_while, drop_until): No need to do default_arg on keyfun, since it is just passed to pos_if, which takes care of it.
* Bugfix: argument defaulting in take-until.Kaz Kylheku2016-05-261-2/+2
| | | | | | * lib.c (take_until): keyfun not defaulted in list cases. Needless defaulting of key in vector/string cases, since pos function already defaults.
* Handle integer overflow in length_list.Kaz Kylheku2016-05-181-2/+14
| | | | | | * lib.c (length_list): Count using cnum only up to INT_PTR_MAX, then switch to bignums.
* Adding termios support.Kaz Kylheku2016-05-181-0/+4
| | | | | | | | | | | | | | | | * Makefile (termios.o): New object file. * lib.c (init): Call termios_init. * lisplib.c (termios_set_entries, termios_instantiate): New functions. (lisplib_init): Register new functions in autoload table. * share/txr/stdlib/termios.tl: New file. * termios.c, termios.h: New files. * txr.1: Documented termios.
* Some streamlining in the cons recycling.Kaz Kylheku2016-05-151-10/+8
| | | | | | | | | | | * lib.c (rcyc_pop): Just assume that *plist points to a cons and access the fields directly. (rcyc_cons): Don't bother with rplacd. (rcyc_list): Don't bother with set macro. * regex.c (read_until_match): Defensive coding: locally ensure that rcyc_pop won't be called on a nil stack, which will now segfault.
* Bugfix: recycled conses play nice with gen GC.Kaz Kylheku2016-05-151-0/+3
| | | | | | | | | | * lib.c (cons): When we recycle a cons, it could be already in the mature generation. In that case, baby objects stored in its car or cdr violate the integrity of the heap. We must hint about this to the garbage collector. Test case: ./txr --gc-debug -p "(list* 'foo (zip '(a) (repeat '((gensym)))))"
* Bugfix in - and / functions.Kaz Kylheku2016-05-131-4/+4
| | | | | | | | | Improper handling of arguments in certain cases. Test case: [[flipargs -] 2 1]. Should yield -1; actual behavior is error. * lib.c (minusv, divv): Correct test for more arguments after extracting the leftmost one.
* Avoid unnecessary evaluation in argument defaulting.Kaz Kylheku2016-05-071-1/+0
| | | | | | | | * lib.h (default_arg): Inline function becomes macro, so we can avoid evaluating the default value expression when it is not needed. * lib.c (default_arg): Declaration removed.