summaryrefslogtreecommitdiffstats
path: root/lib.h
Commit message (Collapse)AuthorAgeFilesLines
* Shorthand for filters which map multiple texts to a commonKaz Kylheku2011-10-251-0/+2
| | | | | | | | | | | | | | | | | replacement text. * filter.c (build_filter_from_list): Allow tuples to denote multiple keys mapping to the same value. * lib.c (do_curry_123_2, do_curry_123_1): New static functions. (curry_123_2, curry_123_1): New functions. * lib.h (curry_123_2, curry_123_1): New functions declared. * match.c (v_deffilter): Allow tuples of strings rather than just pairs. * txr.1: Updated.
* Task #11474Kaz Kylheku2011-10-221-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | * filter.c (filter_equal): Takes two filters instead of one. (lfilt_k, rfilt_k): New keyword variables. (filter_init): New keyword variables initialized. * filter.h (filter_equal): Declaration updated. (lfilt_k, rfilt_k): Declared. * lib.c (funcall4): New function. (do_curry_1234_34): New static function. (curry_1234_34): New function. (do_swap_12_21): New static function. (swap_12_21): New function. * lib.h (funcall4, curry_1234_34, swap_12_21): Declared. * match.c (dest_bind): Swap use the function argument swapping combinator when calling tree find such that the value being searched is on the left and pattern material is on the right. (v_bind): Implemented :lfilt and :rfilt. * txr.1: Documented :lfilt and :rfilt.
* Task #11474Kaz Kylheku2011-10-221-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | * filter.c (filter_equal): New function. (upcase_k, downcase_k): New keyword variables. (filter_init): New keyword variables initialized, and new upcase and downcase filters registered. * filter.h (filter_equal): Declared. * lib.c (tree_find): Takes new argument, the equality test function. (upcase_str, downcase_str): New functions. (do_curry_123_23): New static function. (curry_123_23): New function. * lib.h (tree_find): Declaration updated. (upcase_str, downcase_str, curry_123_23): Declared. * match.c (dest_bind): Updated to take equality function. Uses it and passes it down to tree_find. (v_bind): Filter feature implemented. (h_var, v_try): Add equal_f to dest_bind argument list. * txr.1: Updated to describe new filters and bind arguments.
* New features. Strling list output streams in streamKaz Kylheku2011-10-211-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | library, allow output to be captured as a list of strings representing lines (in contrast to string streams which capture a single string). The output directive can output to a variable, and next can scan over a variable. * lib.c (span_str, compl_span_str, break_str): New functions. * lib.h (span_str, compl_span_str, break_str): New functions declared. * match.c (into_k, var_k): New keyword variables. (mf_file_data): New static function. (v_next): Refactored argument handling. Added support for :var keyword. (v_output): Added support for :into keyword. * stream.c (strlist_mark, strlist_out_put_string, strlist_out_put_char): New static functions. (strlist_out_ops): New static struct. (make_strlist_output_stream, get_list_from_stream): New functions. * stream.h (make_strlist_output_stream, get_list_from_stream): New functions declared.
* * lib.c (proper_plist_to_alist, improper_plist_to_alist): NewKaz Kylheku2011-10-211-0/+2
| | | | | | | | | | | | | | functions. * lib.h (proper_plist_to_alist, improper_plist_to_alist): New functions declared. * match.c (append_k): New keyword symbol variable. (complex_open): New append argument. (v_output): Streamlined parsing of keywords. Support :append keyword. * txr.1: Output directive's keyword documentation revised.
* Task #11425.Kaz Kylheku2011-10-181-1/+3
| | | | | | | | | | | | | | | | | | | | | | | Vertical skip directive moved into function dispatched via hash table. Test suite passes. * lib.c (cptr_s): New symbol variable. (cptr_equal_op): New static function. (cptr_equal_op, cptr, cptr_get): New functions. (cptr_ops): New static structure. (obj_init): New variable initialized. * lib.h (cptr_s, cptr, cptr_get): Declared. * match.c (decline_k, same_data_k): New symbol variables. (v_match_func): New typedef. (v_skip): New function. (match_files): Check symbol in v_directive_table and dispatch the associated function if an entry exists. Skip directive handling moved to v_skip function. (syms_init): Initialize new symbol variables. (dir_tables_init): Enter v_skip into v_directive_table under skip_s symbol.
* Bug #34538Kaz Kylheku2011-10-121-9/+1
| | | | | | | | | * lib.h (wli): This macro now does the pointer displacement by 1. (auto_str, static_str): #if/#else/#endif gone. These functions just add the type tag. The + 1 logic was incorrect; it should have been + sizeof(wchar_t). But even that was not right because other code expects a wchli_t * to point to the first character, such as the string_out_put_char function.
* One more swing at this with the axe.Kaz Kylheku2011-10-091-0/+4
| | | | | | | * lib.h (wini, wref): New macros. * stream.c (string_out_put_char): Rewritten with macros to eliminate preprocessor #if test.
* * lib.h (wli, lit_noex): We need null characters on both endsKaz Kylheku2011-10-091-2/+2
| | | | | | | so that this hack is correct for null strings. When recovering the wchar_t pointer from a null literal object, we wil increment unconditionally, since it always points to a null character. We end up skipping past null terminator #1, but safely landing on #2.
* Following up to previous commit's TODO.Kaz Kylheku2011-10-091-8/+10
| | | | | | | | | | | | | | | | | | | | | | * filter.c (struct filter_par): wchar_t becomes wchli_t. * lib.h (wchli_t): New type: an incomplete structure type, so that a pointer to this type is incompatible with anything else. (wli): Macro produces const wchli_t * pointer instead of const wchar_t *. (auto_str, static_str): Accept a const wchli_t * instead of const wchar_t *, making it impossible to misuse these functions by passing in a literal. * stream.c (string_out_put_char): These type changes showed this hack to have a bug. Confronted with the need to cast from const wchar_t * to const wchli_t *, it's obvious that the conversion has to be done properly with the + 1 in the one platform case, but not the other. * txr.c (version): Type changed to const wchli_t. * txr.h (version): Declaration updated.
* Ported to Cygwin.Kaz Kylheku2011-10-091-0/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | TODO: there should be some type safety with the new wli macro so that if it is forgotten, there will be a diagnostic. * configure (lit_align): New configuration variable and configuration test. Generates LIT_ALIGN in config.h. Fixed the integer-holds-pointer test for the different output from the nm program on Cygwin. The arrays become common symbols marked C which do not show an offset attribute, only size: one less column. * filter.c (to_html_table, from_html_table): wrap wide string literals with the wli macro. This must be done from now on for all literals and initializes of arrays that are going to be directly converted to type tagged val-s. * lib.h (wli): New macro. (auto_str, static_str, litptr, lit_noex): Handle wide literals on platforms where they are aligned to only two bytes, such that we don't have two bits in the pointer. We can still add our 11 bit type tag, but then when recovering the pointer to the data, we have may have to fix up the pointer. * parser.l: Another portability issue here. Flex generates a scanner which has #include <unistd.h> in the middle, after the source file's own #includes which can introduce macros. On Cygwin, there is some hygiene problem whereby our "noreturn" macro causes the <unistd.h> header to generate bad syntax and fail to compile. Stupid Cygwin and even stupider flex! The workaround is to include <unistd.h> at the top in the flex source. * stream.c (string_out_put_char): This is one more place where the string literal handling hack spreads. * txr.c (version): Wrap string in wli.
* * lib.c (eol_s): New symbol variable.Kaz Kylheku2011-10-071-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | (obj_init): New variable initialized. * lib.h (eol_s): Declared. * match.c (match_line): Implemented horizontal skip as and new eol directive. (match_lines): Vertical skip defers to horizontal skip if there is trailing material. * txr.1: Updated. * lib.c (eol_s): New symbol variable. (obj_init): New variable initialized. * lib.h (eol_s): Declared. * match.c (match_line): Implemented horizontal skip as and new eol directive. (match_lines): Vertical skip defers to horizontal skip if there is trailing material. * txr.1: Updated.
* Extending syntax to allow for @VAR and @(...) forms insideKaz Kylheku2011-10-061-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | nested lists. This is in anticipation of future features. * lib.c (expr_s): New symbol variable. (obj_init): expr_s initialized. * lib.h (expr_s): Declared. * match.c (dest_bind): Now takes linenum. Tests for the meta-syntax denoted by the system symbols var_s and expr_s, and throws an error. (eval_form): Similar error checks added. Also, hack: do not add file and line number to an exception which begins with a '(' character; just re-throw it. This suppresses duplicate line number addition when this throw occurs across some nestings. (match_files): Updated calls to dest_bind. * parser.l (yybadtoken): Handle new token kind, METAVAR and METAPAR. (grammar): Refactoring among patterns: TOK broken into SYM and NUM, NTOK introduced, unused NUM_END removed. Rule for @( producing METAPAR in nested state. * parser.y (METAVAR, METAPAR): New tokens. (meta_expr): New nonterminal. (expr): meta_expr and META_VAR productions handled.
* Renaming the currying combinators according to new scheme.Kaz Kylheku2011-10-061-2/+5
| | | | | | | | | | * lib.c (bind2): Function renamed to curry_12_2. (bind2other): Function renamed to curry_12_1. (do_bind_2, do_bind2other): Helpers renamed likewise. (tree_find): Follows rename of bind2. * match.c (match_files): deffilter code follows bind2 rename to curry_12_2.
* * lib.c (funcall3, curry_123_2): New functions.Kaz Kylheku2011-10-061-0/+2
| | | | | | | | | | | | | | | | | | | | | | (do_curry_123_2): New static function. * lib.h (funcall3, curry_123_2): Declared. * match.c (subst_vars): Bugfix: throw error on unbound variable instead of ignoring the situation. This bug caused unbound variables in quasiliterals to be silently ignored. (eval_form): Function changed to three argument form, so that it takes a line number for reporting errors. Restructured to catch the new unbound variable exception from subst_vars, and re-throw it with a line number. Also, throws exception now instead of returning nil if itself it detets an unbound variable. Uses of eval_form no longer have to test the return value for nil, but just assume it worked. (match_lines): Currying calls to eval form updated to use curry_123_2. Test of eval return value eliminated. In function calls, eval isn't used for reducing symbol arguments to values, because it now throws in the unbound case, and it's not worth setting up a catch for this. Instead, assoc is used directly.
* * LICENSE, Makefile, configure, filter.c, filter.h, gc.c, gc.h, hash.c,Kaz Kylheku2011-10-041-1/+1
| | | | | | hash.h, lib.c, lib.h, match.c, match.h, parser.h, parser.l, parser.y, regex.c, regex.h, stream.c, stream.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h: Updated e-mail address.
* * lib.c (acons): New function.Kaz Kylheku2011-10-041-0/+1
| | | | | | | | | | | | | | | | | (set_diff): Optimize common case: list1 and list2 are the same, or list2 is substructure of list1. Situations in which this won't be the case for variable bindings are rare. * lib.h (acons): Declared. * match.c (match_line): Use acons rather than acons_new, when binding variables that we know are new (the symbol is unbound). When computing the set difference over bindings, use cons cell equality, rather than symbol equality. Symbol equality is wrong because a binding can be removed, and then a new binding can be introduced using the same symbol. This must be treated as a different binding.
* Bugfixes to the semantics of binding environments, whichKaz Kylheku2011-10-041-2/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | were broken in the face of deletions (local, forget). For some stupid reason, I had written a destructive routine for removing elements from an association list, and used it as the basis for the local and forget directives. * lib.c (eq_f, car_f): New variables. (identity_tramp, equal_tramp): Obsolete functions removed. (apply): Broken function disabled at run time. (funcall, funcall1, funcall2): Throw meaningful error instead of aborting. (alist_remove_test): New static function. (alist_remove, alist_remove1): Rewritten to be functional rather than destructive. (alist_nremove, alist_nremove1): Destructive functions, using previous implementations of alist and alist_nremove. (do_sort): Recurses directly rather than via sort. That was probably why this helper was introduced! (find, set_diff): New functions. (obj_init): gc-protect new variables eq_f and car_f, and initialize them. Initializations for equal_f and identity_f changed to use equal and identity directly, without the obsolete wrappers. * lib.h (eq_f, car_f, alist_nremove, alist_nremove1, find, set_diff): Declared. * match.c (match_line): Use set_diff to determine what bindings are new, rather than ldiff and ldiff-like logic which break when the new bindings do not share structure with the old. (match_files): Likewise.
* Implemented new last clause for collect and coll.Kaz Kylheku2011-10-031-0/+1
| | | | | | | | | | | | | | | | | | | | Bugfix in cases inside coll: was not collecting bindings. Bugfix for until inside coll: was not seeing bindings from main clause. * lib.c (ldiff): New function. * lib.h (ldiff): Declared. * match.c (match_line): Implemented last clause. Fixed cases handling by moving misplaced termination check. (match_files): Implemented last clause. * parser.y (until_last): New nonterminal symbol. (collect_clause): Refactored syntax to support until and last. (elem): Likewise. * txr.1: Updated.
* Compiles as C++ again.Kaz Kylheku2011-10-021-0/+8
| | | | | | | | | | | * lib.h (cons_set): New macro. * match.c (match_line, match_files): In collect clause handlers, move variable declarations above goto, and initialize with cons_set, instead of declaring and initializing with cons_bind. This eliminates the stupid C++ error that goto skips a variable initialization (which happens even when it can be trivially proven that the has no next use at the goto site!)
* Maintaining C++ compiling (except for two issues that willKaz Kylheku2011-10-011-1/+1
| | | | | | | | | | | | | | | | need another commit). * filter.c: Include "gc.h" for prototype of protect. (struct filter_pair): Use const wchar_t *, so we can assign literals. (html_hex_continue): Ditto. * lib.c (and): Function renamed to andf, since and is a C++ operator. * lib.h (and): Declaration renamed. * match.c (match_files): Use of and updated to andf.
* * lib.c (eof_s): New symbol variable.Kaz Kylheku2011-09-271-1/+1
| | | | | | | | | | | (obj_init): New variable initialized. * lib.h (eof_s): Declared. * match.c (match_files): New @(eof) directive explicitly matches end of data. * txr.1: Updated.
* Support &#xNNNN; hex escapes in html. Bugfix in field formatting.Kaz Kylheku2011-09-261-1/+6
| | | | | | | | | | | | | | | | | | | chr function inlined. * filter.c (trie_value_at, trie_lookup_feed_char): Handle function case. (build_filter): New parameter, compress_p. (html_hex_continue, html_hex_handler): New functions. (filter_init): Add a function-based node to the from_html trie. * lib.c (chr): Function removed. (functionp) New function. * lib.h (chr): Declaration replaced with inline function. (functionp): Declared. * match.c (format_field): Bugfix: failed to apply filter that came in as an argument.
* New feature: @(deffilter)Kaz Kylheku2011-09-261-4/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | Bugfix in @(throw) when non-symbol is thrown: exception message referred to the symbol throw rather than the erroneous object. * filter.c (build_filter_from_list, register_filter): New functions. * filter.h (register_filter): New function declared. * lib.c (deffilter_s): New variable defined. (chain): Function changed from single list argument to variable argument list to reduce the complexity of use. (do_and, and): New functions. (obj_init): deffilter_s initializatio added. * lib.h (deffilter_s, and): New declarations. (chain): Declaration updated to new function signature. (eq): Changed from macro to inline function. * match.c (do_output_line): Simplified expression involving chain. (do_output): Likewise. (match_files): Bugfix in error handling of throw. Implementation of deffilter. * txr.1: Documented deffilter.
* Trie compression. Hash table iteration.Kaz Kylheku2011-09-261-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Bugfix in typeof. * filter.c (trie_compress): New function. (trie_value_at, trie_lookup_feed_char, filter_string): Handle cons cell nodes in trie. (build_filter): Call trie_compress. * gc.c (cobj_destroy_op): Function renamed to cobj_destroy_stub_op since it doesn't do anything. (cobj_destroy_free_op): New function. * hash.c (struct hash_iter): New type. (hash_destroy): Function removed. (hash_ops): Reference to hash_destroy replaced with cobj_destroy_free_op. (hash_count, hash_iter_mark, hash_begin, hash_next): New functions. (hash_iter_ops): New static structure. * hash.h (hash_count, hash_begin, hash_next): New functions declared. * lib.c (hash_iter_s): New symbol variable. (typeof): Bugfix: TAG_LIT type tag not handled. (vecref): New function. (obj_init): Initialize hash_iter_s. * lib.h (cobj_destroy_op): Declaration renamed. (cobj_destroy_free_op, vecref): New functions declared. (hash_iter_s): New variable declared. * stream.c (string_in_ops, byte_in_ops): cobj_destroy_op renamed to cobj_destroy_stub_op.
* Filtering feature for variable substitution in output.Kaz Kylheku2011-09-251-1/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * filter.c, filter.h: New files. * Makefile (OBJS): filter.o added. * gc.c (mark_obj): Mark new alloc field of string objets. * hash.c (struct hash): New member, userdata. (hash_mark): Mark new userdata member of hash. (make_hash): Initialize userdata. (get_hash_userdata, set_hash_userdata, hashp): New functions. * hash.h (get_hash_userdata, set_hash_userdata, hashp): New functions declared. * lib.c (getplist, string_extend, cobjp): New functions. (string_own, string, string_utf8): Initialize new alloc field to nil. (mkstring, mkustring): Initialize new alloc field to actual size. (length_str): When length is computed and cached, also compute and cache alloc. (init): Call filter_init. * lib.h (string string): New member, alloc. (num_fast): Macro converted to inline function. (getplist, string_extend, cobjp): New functions declared. * match.c (match_line): Follows change of modifier s-exp syntax. (format_field): New parameter, filter. New modifier syntax parsed. Filter retrieved, and applied. (subst_vars): New parameter, filter. Filter is either applied in this function or passed to format_field, as needed. (eval_form): Pass nil to new parameter of subst_vars. (do_output_line): New parameter, filter. Passed down to subst_vars. (do_output): New parameter, filter. Passed down to do_output_line. (match_files): Pass nil filter to subst_vars in cat directive. Output directive refactored to parse keywords, extract the filter and pass down to do_output. * parser.y (regex): Generate (sys:regex regex syntax ...) instead of (regex syntax ...). (elem, expr): Updated w.r.t. regex syntax change. (var): Cases '{' IDENT regex '}' and '{' IDENT NUMBER '}' are removed. new syntax '{' IDENT exprs '}' to handle these more generally and allow for keywords. * txr.1: Updated.
* Numeric constants become real constants.Kaz Kylheku2011-09-241-1/+8
| | | | | | | | | | | | Vector code cleanup. * lib.h (zero, one, two, negone, maxint, minint): Extern declarations removed, macros introduced for these identifiers. * lib.c (zero, one, two, negone, maxint, minint): File scope definitions removed. (vector): Use vec_alloc and vec_fill enums instead of constants. (obj_init): Remove references to removed definitions.
* * LICENSE, Makefile, configure, gc.c, gc.h, hash.c, hash.h, lib.c,Kaz Kylheku2011-09-231-1/+1
| | | | | | lib.h, match.c, match.h, parser.h, parser.l, parser.y, regex.c, regex.h, stream.c, stream.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h: Updated copyright year.
* Bump copyrights to 2010.Kaz Kylheku2010-10-051-1/+1
|
* * lib.h (lazy_string): Fix incorrect comment.Kaz Kylheku2010-10-031-1/+1
| | | | | | | | * lib.c (split_str, split_str_set): It is necessary to protect input parameters against GC, because we cache their internal pointers, after which we no longer refer to the objects themselves. Moreover, we perform object allocation, and then keep using the internal pointers.
* * lib.h (split_str_sep): Declared.Kaz Kylheku2010-02-271-0/+1
| | | | | | | | | * lib.c (split_str_sep): New function. (split_str): Semantics changed; the second argument is not a set of separator characters (like in split_str_sep) but rather a separator string. Fixed bug: if the input string is empty, the output list is empty. This caused infinite looping behavior in @(freeform).
* Optimization in derivative-based regex engine.Kaz Kylheku2010-01-261-0/+2
| | | | | | | | Exponential memory consumption behavior was observed when matching the input aaaaaa.... against the regex a?a?a?a?....aaaa.... The fix is to eliminate common subexpressions from the derivative for the or operator.
* Implemented non-greedy operator.Kaz Kylheku2010-01-151-1/+1
|
* * lib.h (c_num): Remove redundant declaration.Kaz Kylheku2010-01-131-2/+1
|
* Impelement derivative-based regular expressions.Kaz Kylheku2010-01-131-1/+2
|
* Merge branch 'master' of ssh://git.sv.gnu.org/srv/git/txrKaz Kylheku2010-01-051-4/+4
|\ | | | | | | | | Conflicts: ChangeLog
| * * lib.c (make_package, find_package): Eliminate declarationKaz Kylheku2009-12-171-4/+4
| | | | | | | | | | | | | | | | in the middle of statement block. * lib.h (TAG_MASK): Becomes type cnum rather than long. (nao): Based off 1 rather than -1 to avoid left shift of negative number.
* | Implemented the regular expression ~ and & operators.Kaz Kylheku2010-01-051-1/+1
|/ | | | | | | | | | | | | | | This turns out to be easy to do in NFA land. The complement of an NFA has exactly the same number and configuration of states and transitions, except that the states have an inverted meaning; and furthermore, failed character transitions are routed to an extra state (which in this impelmentation is permanently allocated and shared by all regexes). The regex & is implemented trivially using DeMorgan's. Also, bugfix: regular expressions like A|B|C are allowed now by the syntax, rather than constituting syntax error. Previously, this would have been entered as (A|B)|C.
* * hash.c (sethash): New function.Kaz Kylheku2009-12-091-0/+1
| | | | | | | | * hash.h (sethash): Declared. * lib.c (cobj_handle): New function. * lib.h (cobj_handle): Declared.
* All COBJ operations have default implementations now;Kaz Kylheku2009-12-081-2/+9
| | | | | | no null pointer check over struct cobj_ops operations. New typechecking function for COBJ objects.
* Eliminate the void * disease. Generic pointers are of mem_t *Kaz Kylheku2009-12-041-6/+8
| | | | | from now on, which is compatible with unsigned char *. No implicit conversion to or from this type, in C or C++.
* Code cleanup. All private functions static. Private stuffKaz Kylheku2009-11-281-0/+3
| | | | in regex module not exposed in header. Etc.
* More valgrind integration. Vector objects keep displaced pointersKaz Kylheku2009-11-251-0/+3
| | | | | | | | to vector data; they point to element 0 which is actually the third element of the vector. If an object is only referenced by interior pointers, Valgrind reports it as possibly leaked. This change conditionally adds a pointer to the true start of the vector, if Valgrind support is enabled.
* Switching to keyword symbols for :args and :nothrow.Kaz Kylheku2009-11-241-3/+5
|
* Whitespace.Kaz Kylheku2009-11-241-2/+2
|
* Auto-detect what specifiers to use for inline functions.Kaz Kylheku2009-11-241-9/+9
| | | | | Allow compiler command to be set independently of full path for easier compiler switching.
* Changes to make the code portable to C++ compilers, whichKaz Kylheku2009-11-241-2/+2
| | | | can be taken advantage of for better diagnostics.
* Renaming global variables that denote symbols, such that theyKaz Kylheku2009-11-241-11/+13
| | | | have a _s suffix.
* Improving portability. It is no longer assumed that pointersKaz Kylheku2009-11-231-11/+13
| | | | | | | | can be converted to a type long and vice versa. The configure script tries to detect the appropriate type to use. Also, some run-time checking is performed in the streams module to detect which conversions specifier strings to use for printing numbers.
* Introducing symbol packages. Internal symbols are now inKaz Kylheku2009-11-211-6/+16
| | | | | | | | | | a system package instead of being hacked with the $ prefix. Keyword symbols are provided. In the matcher, evaluation is tightened up. Keywords, nil and t are not bindeable, and errors are thrown if attempts are made to bind them. Destructuring in dest_bind is strict in the number of items. String streams are exploited to print bindings to objects that are not strings or characters. Numerous bugfixes.