summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
...
* args: keyword extraction mechanism.Kaz Kylheku2017-12-012-0/+94
| | | | | | | | | | | | | | | | Implement a mechanism for extracting keyword arguments out of "struct args *" argument lists which avoids consing up an argument list and scanning it multiple times for multiple keywords. * args.c (args_for_each): New function. (struct args_bool_key, struct args_bool_ctx): New struct types. (args_key_check_store): New static function. (args_keys_extract_vl, args_key_extract): New functions. * args.h (args_for_each, args_keys_extract_vl, args_key_extract): Declared.
* Rewrite internal mapping function.Kaz Kylheku2017-11-301-4/+21
| | | | | | * lib.c (mapcar_listout): Rework using seq_info for efficient processing of vector-like sequences and objects that implement sequences.
* bugfix: code-walk the result of a declined macro.Kaz Kylheku2017-11-291-2/+3
| | | | | | | | | | | | | | | | When a form is a macro, but the macro declines to expand the form, the form must still be code walked; we can't just return it and be done. For instance if it is a function call, its argument expressions have to be expanded. This also causes undefined function warning to be generated properly if a macro declines, and the resulting form is a function call to a not-yet-defined function. * eval.c (do_expand): If expand_macro yields the original form, branch backwards to re-execute the whole if statement again. Use the fact that the local variable macro is now non-nil to skip the macro expansion case.
* macros: expand declined form in outer env.Kaz Kylheku2017-11-244-1/+63
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch implements a new requirement which clarifies what happens when a macro declines to expand a form. To decline expanding a form means to return the original form (same object) without returning it. The expander detects this situation with an eq comparison on the input and output. The current behavior is that no further attempts are made to expand the form. This is problematic for various reasons. In code which is expanded more than once, this can lead to the expansion being different between the expansion passes. In the first pass, a local macro M might decline to expand a form. In the second pass, the local macro definition no longer exists, and the form does get expanded by a global macro M. This kind of instability introduces a flaw into complex macros which expand their argument material more than once. The new requirement is that if a macro definition declines to expand a macro, then a search takes place through the outer lexical scopes, and global scope, for the innermost macro definition which will expand the form. The search tries every macro in turn, stopping if a macro is found which doesn't decline the expansion, or after passing the global scope. * eval.c (expand_macro): Implement new searching behavior. * txr.1: Documented the expansion declining mechanism under defmacro and macrolet. * tests/011/macros-3.tl: New file. * tests/011/macros-3.expected: New file.
* Fix quoted function name in unsupported object errors.Kaz Kylheku2017-11-231-11/+17
| | | | | | | | | * lib.c (unsup_obj): New static function. (grade, find, rfind, find_max, find_if, rfind_if, pos, rpos, pos_if, rpos_if, pos_max): Replace call to uw_throwf with call to unsup_obj. IN all these functions except grade, the ~s conversion specifier was wrongly used on the function name rather than ~a, resulting in unwanted quoting.
* New function: grade.Kaz Kylheku2017-11-234-0/+90
| | | | | | | | | | | | Inspired by APL. * eval.c (eval_init): Register grade intrinsic. * lib.c (grade): New function. * lib.h (grade): Declared. * txr.1: Documented.
* lastcons: streamline.Kaz Kylheku2017-11-221-1/+1
| | | | | * lib.c (lastcons): Don't wastefully call cdr on an object after called cdr_l; just dereference the cdr_l loc.
* bugfix: tail handles improper list.Kaz Kylheku2017-11-221-1/+1
| | | | | | | | | | | * lib.c (tail): This low-level function is used by the list accumulation routines. Because it doesn't handle improper lists, looking for a null terminator, certain things don't work, like the associativity of append. For instance (append '(1 2) #(3) 4) works but not (append (append '(1 2) #(3)) 4). Fixing tail so that it terminates on any atom, rather than failing trying to cdr through it.
* doc: re-doc append, split off append*.Kaz Kylheku2017-11-221-26/+134
| | | | | | | * txr.1: Documentation for append and nconc is rewritten. Treatment of non-list sequences is explained in detail. Description of append* is split off into its own section, because its handling of non-lists is too different.
* bugfix: two issues in mappend* and append*.Kaz Kylheku2017-11-211-29/+23
| | | | | | | | | | | | | | | | | | | | | | | Two bugs in these functions, both attributable to the lazy_appendv implementation: They destructively catenate the input lists, much like nconc, even though documented as non-destructive. If any input list is infinite, other than the last input list, that list is forced, resulting in an infinite loop. * lib.c (lazy_appendv_func): Rewritten to use a different algorithm which earnestly allocates a new lazy cons for each element of the output sequence, except for the tail part corresponding to the last list. (lazy_appendv): Set up the lazy cons according to the new representation and just return it. No searching for the tail of the nonempty list, and no destructive manipulation.
* Version 187.txr-187Kaz Kylheku2017-11-176-6/+55
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim: Regenerated.
* doc: pos-max, find-max: notes about multiple maxima.Kaz Kylheku2017-11-161-0/+25
| | | | | | * txr.1: mention that the rightmost maximum can be found by manipulating the comparison function. (Hence, this is why we don't provide rpos-max and rfind-max).
* Use fixnum indices for vector iteration.Kaz Kylheku2017-11-161-41/+51
| | | | | | | | | | | * lib.c (find, rfind, find_max, find_if, rfind_if, pos, rpos, pos_if, rpos_if, pos_max): Consistently fixnum indices for iterating over vector. In some functions, a cnum is already used, but could be out of fixnum range; we switch to using c_fixnum for extracting the length and then num_fast on the index. Some functions are converted from using a val index. In the case of rfind_if, a bug is fixed: it was using plusp, which now becomes the correct >= 0.
* pos-max: rewrite.Kaz Kylheku2017-11-161-18/+48
| | | | * lib.c (pos_max): Rewrite using seq_info.
* find-max: bugfix for zero length vectors.Kaz Kylheku2017-11-151-10/+15
| | | | | | * lib.c (find_max): Fix a regression introduced in recent work: only execute the loop when the vector isn't empty.
* pos-if, rpos-if: rewrite.Kaz Kylheku2017-11-151-25/+72
| | | | * lib.c (pos_if, rpos_if): Rewrite using seq_info.
* posq, posql, posqual, rposq, rposql, rposqual: rewriteKaz Kylheku2017-11-151-93/+30
| | | | | | | * lib.c (posq, posql, posqual, rposq, rposql, rposqual): These functions are reduced to wrappers around pos and rpos, respectively, so they generalize properly and efficiently to sequences of all kinds.
* pos, rpos: rewrite with seq_info.Kaz Kylheku2017-11-151-57/+88
| | | | | | | * lib.c (pos, rpos): Functions rewritten to use the seq_info sequence classification mechanism. The rpos function is thereby optimized to work with vectors. Both functions support vector-like struct objects now.
* rfind-if: optimized rewrite and hash support.Kaz Kylheku2017-11-152-10/+60
| | | | | | | | | | * lib.c (rfind_if): Function rewritten to use the seq_info sequence classification mechanism, for much better performance on vector-like objects. Also, supports hash tables just like find_if. * txr.1: Documentation updated regarding hash support of rfind-if.
* find-if: optimized rewrite and hash support.Kaz Kylheku2017-11-152-10/+63
| | | | | | | | | | * lib.c (find_if): Function rewritten to use the seq_info sequence classification mechanism, for much better performance on vector-like objects. Also, supports hash tables just like find_max. * txr.1: Documentation updated regarding hash support of find-if.
* find-max: tiny optimization for vectors.Kaz Kylheku2017-11-151-1/+1
| | | | | | * lib.c (find_max): The vector case must loop from index one, not zero, so as not to wastefully compare the initial max element to itself.
* doc: subtypep unspecified behaviorKaz Kylheku2017-11-141-0/+3
| | | | | * txr.1: Behavior of subtypep is not specified if either argument isn't a type.
* awk: replace set-diff uses with diff.Kaz Kylheku2017-11-011-4/+4
| | | | | * share/txr/stdlib/awk.tl (sys:awk-mac-let): A few occurrences of the deprecated set-diff function are replaced with diff.
* streams: allow "b" flag on open-command.Kaz Kylheku2017-10-303-3/+20
| | | | | | | | | | | | | | | | | | | Currently, using "rb" in open-command reports an error on GNU/Linux, due to popen not liking the "b" mode. On Cygwin, the "b" flag is useful with popen. * stream.c (normalize_mode_no_bin): New function. (open_command): Use normalize_mode_no_bin instead of normalize_mode to strip out the binary flag. This doesn't happen on Cygwin, though. * stream.h (normalize_mode_no_bin): Declared. * share/txr/stdlib/getput.tl (command-get-buf): Since we are getting binary data, pass the "rb" mode to open-command, now that it works. (command-put-buf): Add "b" flag to mode passed to open-command.
* doc: wording under eq.Kaz Kylheku2017-10-301-1/+1
| | | | | * txr.1: fix awkward wording which applies the definite article "the" to a Lisp expression.
* doc: wrong wording under put-buf.Kaz Kylheku2017-10-301-1/+1
| | | | * txr.1: Streams support put-byte, not buffers.
* genvim: % is constituent of identifiers.Kaz Kylheku2017-10-301-1/+1
| | | | * genvim.txr (iskeyword): add % character.
* awk: implement ranges right using functions.Kaz Kylheku2017-10-293-74/+133
| | | | | | | | | | | | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk%--rng, sys:awk%--rng-, sys:awk%rng+, sys:awk%-rng+, sys:awk%--rng+): New functions. (sys:awk-mac-let): Rewritten range expander. The four basic ranges rng, rng-, -rng and -rng- are handled with in-line expansion, because by doing that we avoid unnecessarily evaluating the from-expression. The remaining cases expand to function calls to the new functions, which receive the flag vector, the index position in that vector and the values of the from and to expressions. The behavior change is that that the -- forms now do the right thing: they hide all leading records that satisfy the from-expression, right to the last record of the range if necessary. * tests/015/awk-rng.expected: Updated. * txr.1: Revise semantic description the -- range types, plus minor fixes.
* New convenience I/O functions for buffers.Kaz Kylheku2017-10-273-0/+101
| | | | | | | | | | | | | * lisplib.c (getput_set_entries): New autoload entries for file-get-buf, file-put-buf, file-append-buf, command-get-buf and command-put-buf. * share/txr/stdlib/getput.tl (sys:get-buf-common): New function. (file-get-buf, file-put-buf, file-append-buf, command-get-buf, command-put-buf): New functions. * txr.1: Documented.
* awk: more range test cases.Kaz Kylheku2017-10-272-1/+7
| | | | | | * tests/015/awk-rng.tl: More rows of data. * tests/015/awk-rng.expected: Updated.
* awk: fix buggy handling of new -- ranges.Kaz Kylheku2017-10-271-21/+17
| | | | | | | | | | | | The problem is that when records appear in the middle of the range which again match from-expr, they get suppressed. * share/txr/stdlib/awk.tl (sys:awk-mac-let): Get rid of the flag-mid variable. It cannot work because middle is a state in its own right that cannot be inferred from the existing states (nil, t, :end) and the value of from-expr. We get rid of the flag and introduce a :mid state value.
* carray: check type object in several API functions.Kaz Kylheku2017-10-261-4/+4
| | | | | | | * ffi.c (carray_blank, carray_buf, carray_cptr, carray_pun): these functions should be using ffi_type_struct_checked, since they are public interfaces to which anything can be passed. Otherwise TXR can easily be crashed by misusing them.
* carray: bugfix: allow negative indexing in ref operation.Kaz Kylheku2017-10-261-0/+3
| | | | | | * ffi.c (carray_ref): If the index is negative, displace it by the length of the array. (Then if it is still negative, the function will throw.)
* doc: grammar in description of rr.Kaz Kylheku2017-10-261-1/+1
| | | | * txr.1: rr searches for "a match" not "a matches".
* doc: partition function: syntax formattingKaz Kylheku2017-10-261-1/+1
| | | | | | * txr.1: Fix bungled formatting of third argument alternatives in the syntax synopsis of the partition function.
* op/do: nice error if arguments are not provided.Kaz Kylheku2017-10-261-0/+2
| | | | | | | | * share/txr/stdlib/op.tl (sys:op-expand): Throw error if argument list is empty. We refer to the compile-error function by quote to avoid triggering the auto-load of the module which defines it, due to the circular dependency on op.
* awk: bugfix: lack of hygiene in range implementation.Kaz Kylheku2017-10-261-9/+10
| | | | | | | | | | | | | The code is using a non-hygienic variable called flag as a placelet alias. This binding is visible to range expressions. For instance (rng #/x/ flag) actually references the range expression's internal flag, rather than producing a warning about an unbound variable. * share/txr/stdlib/awk.tl (sys:awk-mac-let): Allocate a gensym for the flag. Then use ,flag throughout the code templates rather than flag to insert the gensym wherever the symbol flag previously appeared.
* awk: retrieve range flag vector once per iteration.Kaz Kylheku2017-10-251-4/+6
| | | | | | | | | | | | | | | | | | | | | This is an improvement in the code generation related to awk range expressions. Previously, on each iteration, for each range expression, the awk state structure is accessed to retrieve the flag vector, which is then kept in a lexical variable. With this change, the retrieval is done once for all the range expressions, which share the same variable to access it. * share/txr/stdlib/awk.tl (sys:awk-compile-time): New slot, rng-vec-temp. (sys:awk-mac-let): Alias the flag variable to a simplified vecref expression which accesses the vector assumed to have been retrieved and bound to the variable named by the rng-vec-temp gensym. (awk): Add one more variable binding into the scope of the ranges: the binding of the variable named by the rng-vec-temp gensym, to an expression which retrieves the rng-vec from the Awk run-time state structure.
* awk: five new range operators.Kaz Kylheku2017-10-254-59/+301
| | | | | | | | | | | | * share/txr/stdlib/awk.tl (sys;awk-mac-let): Provide the implementation for the local macros --rng, --rng-, rng+, -rng+ and --rng+. * tests/015/awk-rng.tl: New file. * tests/015/awk-rng.expected: New file. * txr.1: Documented.
* caseq, caseql, casequal: improvement in expansion.Kaz Kylheku2017-10-251-0/+3
| | | | | | | | | | * eval.c (me_case): When a list of case keys is one element long, reduce it to an atom. Then a simple equality is applied whether the item is equal to the key, rather than whether it is a member of a list containing that one key. This helps with the (t) case which is mandatory, since t is ruled out as a key.
* Makefile: further improvement of tests.Kaz Kylheku2017-10-251-32/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | The problem is that if a test is interrupted, it will not be re-run because the .ok stamp file depends only on an .out file, and that has been successfully created. We completely remove .out files from the rule tree. Quite simply, the output of a test is the .ok stamp. If that is out of date or doesn't exist, the test is run. Generation of the .out is just a side effect. * Makefile (TESTS_OK): Calculate this variable directly from the wildcard over .txr and .tl files..directly rather than from TESTS_OUT. (TESTS_OUT): Variable removed. (TXR_OPTS, TXR_ARGS): The target-specific assignments of these variables for specific tests is now done against .ok stamp file targets rather than .out targets. (TST_EXPECTED, TST_OUT): New helper variables for condensing repeated instances of some syntax. (tst/%.out): Both of these rules are turned into rules which target tst/%.ok. The .out files are just a side effect; the goal is to update the stamp. If an .out file is removed, the test won't be re-run; only if an .ok file is removed, or any of the real prerequisites change. (%.ok): This rule disappears, and its body containing the conditional stamp file touch is moved into both tst/%.ok rules.
* Makefile: fix silliness in "tests" target.Kaz Kylheku2017-10-251-10/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | Last I addressed this, I didn't get it quite right. The problem is that the .out files are being removed when a test fails, which is annoying. The whole redirection of test results to a temp file which is then renamed is silly. Now, the .out files are preserved. Whether or not a test passed depends on whether or not the .ok stamp file is created or updated, so it doesn't matter whether an .out file exists or not. Also, tests are made dependent on the executable, and on the .expected files. If the executable is newer than the test outputs, all the tests will re-run. Also, if any .expected file is touched, the corresponding test will be re-run. * Makefile (clean): Do not remove $(TESTS_TMP). (TESTS_TMP): Variable removed. (tst/%.out): In both rules that run the test and make .out files simply redirect the output directly to the .out file represented as the $@ target. This is how it was before, once upon a time. (%.ok): Do not remove the .out file represdented by $< if the test fails; it is sufficient not to create/touch the .ok stamp file.
* Makefile: improve command abbreviation.Kaz Kylheku2017-10-251-4/+8
| | | | | | | | | | | | For all build steps other than linking, print only the leftmost prerequisite of the target. * Makefile (ABBREV): The macro references $< rather than $^, and hence longer needs the $(DEP_$@) filtering. (ABBREVN): New macro, identical to previous ABBREV, modulo a whitespace fix: removal of a stray tab character. (LINK_PROG): For linking, use ABBREVN so that all the object files are shown.
* hash: optimization in remhash.Kaz Kylheku2017-10-231-4/+8
| | | | | | | | | | | | * hash.c (remhash): Walk chain to splice out to-be-removed entry using an approach similar to what is done in do_weak_tables to splice out lapsed weak entries. This eliminates one extra traversal of the chain as well as consing due to the ldiff call. We use raw pointers obtained using valptr, and direct assignment through *pchain because later cells in a chain are strictly older objects than earlier cells and so so the *pchain = cdr(*pchain) assignment cannot make a generation 1 object point to a generation 0 object.
* hash: fix broken copy_hash.Kaz Kylheku2017-10-231-1/+15
| | | | | | | | | | | | | | | | Impact assessment: this bug affects the correctness of all programs which rely on copying hash tables. Direct reliance means the use of copy-hash, or using the generic copy function on hash objects. Indirect reliance occurs through hash-diff which uses copy-hash. Nothing in TXR itself calls hash-diff. The the listener's Tab completion relies on copy-hash for package-sensitive symbol visibility calculation. Since that is an interactive feature, the impact is low. * hash.c (copy_hash_chain): New static function. (copy_hash): Use copy_hash_chain instead of copy_alist, since the pairs are hash conses and not regular conses: they have a hash value field that must be copied.
* hash: remove pointless nullify ops.Kaz Kylheku2017-10-231-4/+0
| | | | | | | * hash.c (hash_assoc, hash_assql): Remove useless nullify calls. These are copy and paste leftovers, since these functions were based on assoc and assql, which handle sequences other than lists.
* New variant of op: lop.Kaz Kylheku2017-10-193-6/+107
| | | | | | | | | | * lisplib.c (op_set_entries): Add lop to auto-load list. * share/txr/stdlib/op.tl (sys:op-expand): Recognize lop and implement its transformation. (lop) New macro. * txr.1: Documented.
* find_max: convert to use seq_info.Kaz Kylheku2017-10-131-20/+17
| | | | | | | * lib.c (find_max): Sequence classification rewritten to use seq_info. The cases are almost the same, but refer to si.obj rather than seq. Some care is taken in the list case to not hold a reference to the list head.
* rfind: rewrite to be like find.Kaz Kylheku2017-10-131-11/+48
| | | | | | * lib.c (rfind): Instead of treating the sequence as a list, classify with seq_info just like find. Basically the whole function is replaced with an altered copy of find.
* find: convert to seq_info classification.Kaz Kylheku2017-10-131-44/+36
| | | | | | | * lib.c (find): Convert switch statement to use the seq_info function to classify the sequence. For SEQ_VECLIKE, we still check whether the original object is a literal or regular string to treat it specially.