summaryrefslogtreecommitdiffstats
path: root/share
Commit message (Collapse)AuthorAgeFilesLines
* quips: four new entries.Kaz Kylheku2020-10-061-0/+4
| | | | * share/txr/stdlib/quips.tl (sys:%quips%): Add four quips.
* quips: two new entries.Kaz Kylheku2020-10-051-0/+2
| | | | * share/txr/stdlib/quips.tl (sys:%quips%): Add two quips.
* New: quip function for random humor.Kaz Kylheku2020-10-041-0/+73
| | | | | | | | | | | | Add this to your .txr_profile startup file. * lisplib.c (quips_instantiate, quips_set_entries): New static functions. (lisplib_init): Register autoloading of quip. * share/txr/stdlib/quips.tl: New file. * txr.1: Documented.
* compiler: don't use move immediate instructions.Kaz Kylheku2020-10-012-5/+0
| | | | | | | | | | | | * share/txr/stdlib/compiler.tl (comp-atom): Remove the special case for small fixnums and characters which encodes their value in a movi instruction as an immediate operand. This means that now these operands go into D registers, like all other literals. * share/txr/stdlib/vm-param.tl (%imm-width%): Remove this constant, reprensenting the maximum bit width of an immediate operand.
* vm: deprecate move-immediate instructions.Kaz Kylheku2020-10-011-0/+5
| | | | | | | | | | | | | | | | | | | The movrsi, movrmi and movrbi (move immediate {small, medium, big} to register) instructions are becoming deprecated. The reasoning is that character and fixnum operands can just go into a VM descriptor's data vector (D registers). Then they can be referenced directly without wastefully issuing an extra instruction. * genvmop.txr: Add a deprecated comment next to the enum constants of deprecated opcodes. * share/txr/stdlib/asm.tl (oc-base): Add Boolean property which indicates that an opcode is deprecated. This is a static class variable, defaulting to nil in the base class. (op-movrsi, op-movsmi, op-movrbi): Override base class deprecated property with a true value. * vmop.h: Regenerated.
* Version 243txr-243Kaz Kylheku2020-09-011-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* Version 242txr-242Kaz Kylheku2020-08-141-1/+1
| | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise.
* Version 241txr-241Kaz Kylheku2020-08-071-1/+1
| | | | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated. * protsym.c: Likewise.
* New inaddr-str and in6addr-str functions.Kaz Kylheku2020-07-241-0/+114
| | | | | | | | | | | | | | | | | * lisplib.c (sock_set_entries): Register autoload entries for inaddr-str and in6addr-str. Register prefix symbol to be interned. * share/txr/stdlib/socket.tl (sockaddr-in, sockaddr-in6): Both structs get a new member, prefix, defaulting to the respective number of bits in the address. (inaddr-str, in6addr-str): New functions. * tests/014/iaddr-str, tests/014/inaddr-str.expected, tests/014/in6addr-str.tl, tests/014/in6addr-str.expected: New files * txr.1: Documented.
* New producting each operator family.Kaz Kylheku2020-06-281-0/+75
| | | | | | | | | | | | | * lisplib.c (each_prod_instantiate, each_prod_set_entries): New static functions. (lisplib_init): Register autoload of each-prod.tl via new functions. * share/txr/stdlib/each-prod.tl: New file. * txr.1: Documented. Also, under the existing collect-each family of operators, added the equivalence to mapping with lambda to help clarify the semantics.
* Version 240txr-240Kaz Kylheku2020-06-061-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* each: fix (each ()) segfault.Kaz Kylheku2020-06-061-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The (each ()) form should infinitely loop, and the compiled version does. The interpreter crashes, when that is a top-level form. The reason is that the underlying sys:each-op operator uses an empty list of variable names as an indication to use the bindings from the parent lexical environment. And in that particular case, the let is also empty. The whole thing looks like: (let () (sys:each-op each nil)) If this is a top-level expression, then op_let receives a null environment pointer. Since it has no bindings to add, it doesn't extend the environment chain and passes a null environment pointer down to op_each, which that tries to use, because it's told to reach into it for bindings. Let's use the t symbol for that instead, so then the above would look like: ;; the t and only the t means "access parent env" (let () (sys:each-op each t)) And then, let's also fix it so that t is never used in this case when there are no vars: ;; no t, and so don't access parent env. (let () (sys:each-op each nil)) * eval.c (op_each): Get the bindings from the parent environment if vars is t, rather than when it's null. (me_each): When the symbols are not being inserted into the sys:each-op form, then insert t to indicate that, rather than nil. If the source form specifies an empty list of bindings, then insert nil, not t. * share/txr/stdlib/compiler.tl (expand-each): Get the list of variable names from the parent lexical environment when vars is t, rather than when it's null.
* Convert each-family operators to use iter-begin.Kaz Kylheku2020-06-021-4/+5
| | | | | | | | | | | | | | | | | | | With this change we can do (each ((x vec)) ...) with reasonable efficiency, because we are no longer marching through the vector with cdr, copying the suffix. * eval.c (get_iter_f): New global variable. (op_each): Obtain iterators for all the objects with iter_begin, instead of treating them as lists. Probe the iterators for termination with iter_more, get the items with iter_item instead of car and step with iter_step instead of cdr. (eval_init): gc-protect the get_iter_f function and initialize it. * share/txr/stdlib/compiler.tl (expand-each): Replace the car/cdr and null testing with iter-init, iter-more, iter-item and iter-step.
* Version 239.txr-239Kaz Kylheku2020-06-021-1/+1
| | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise.
* compiler: bugfix: missing block in dohash and each.Kaz Kylheku2020-05-311-16/+18
| | | | | | | | | | The compiler's expander for dohash, and for the each family of operators neglects to add the (block nil ...) around the forms that are expected to be in a block. * share/txr/stdlib/compiler.tl (expand-dohash, expand-each): Generate the (block nil ...) around the sys:for construct which doesn't produce one.
* Version 238.txr-238Kaz Kylheku2020-05-181-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* sort: prudently make it subject to compat valueKaz Kylheku2020-05-141-3/+3
| | | | | | | | | | | | * eval.c (eval_init): If opt_compat is 237 or less, make sort and shuffle destructive. * share/txr/stdlib/getopts.tl (opthelp): Revert previous change, restoring use of copy-list and use nsort instead of sort, so the function is not affected by the 237 compatibility being turned on. * txr.1: Add compatibility notes.
* lib: sort becomes non-destructive; nsort introduced.Kaz Kylheku2020-05-131-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I'm fixing a historic mistake copied from ANSI Lisp, which trips up language newcomers and sometimes even experienced users. The function innocently named sort will now return newly allocated structure. The function previously called sort will be available as nsort (non-consing/allocating sort). The shuffle function also becomes pure, and is accompanied by nshuffle. * eval (me_op): Continue to use destructive sort in this legacy code that is only triggered in very old compat mode. (eval_init): Registered nsort and nshuffle. * lib.c (nsort, nshuffle): New functions introduced, closely based on sort and shuffle. (sort, shuffle): Rewritten to avoid destructive behavior: work by copying the input and calling destructive counterparts. (sort_group): Continue to use destructive sort, which is safe; the structure is locally allocated. The sort_group function has pure semantics. (grade): Likewise. * lib.h (nsort, nshuffle): Declared. * share/txr/stdlib/getopts.tl (opthelp): Replace an instance of the (sort (copy-list ...)) pattern with just (sort ...). * tags.tl (toplevel): Continue to use destructive sort to sort tags before writing the tag file; the lifetime of the tags list ends when the file is written. * tests/010/seq.txr: Switch some sort calls to nsort to keep test case working. * txr.1: Documented.
* compiler: rearrange handling of callsKaz Kylheku2020-05-041-33/+37
| | | | | | | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Open up the main caseq statement for handling symbols other than just special operators. Now we handle the compiler-only special operator sys:ift here, as well as the special casing for call and apply. Function calls are handled as the fallback case here now. (compiler call-fun-form): Remove the checking for ift, and for call, apply and usr:apply. Only regular case function calls are handled here now. (compiler comp-apply-call): New method dedicated for compiling calls to the call, apply or usr:apply functions, dispatched directly out of compiler compile.
* compile: don't expand.Kaz Kylheku2020-05-031-2/+2
| | | | | | | | The compile function doesn't need to expand because the input is a function that has already been expanded. * share/txr/stdlib/compiler.tl (compile): Pass the second argument to compile-toplevel to suppress expansion.
* compiler: implement lambda lifting.Kaz Kylheku2020-05-031-1/+15
| | | | | | | | | | | | | | | | | This is what the recent load-time changes were grooming the compiler toward. When we compile a lambda, we can look at the function and variable refernces it is making. If the lambda makes no lexical function or variable references, we can lift that lambda into load time, so that it's instantiated once and then re-used out of a D register. Effectively, it becomes a top-level function. * share/txr/stdlib/compiler.tl (compiler comp-lambda-impl): New method, formed by renaming comp-lambda. (compiler comp-lambda): Turned not wrapper for comp-lambda impl which compiles the lambda, and checks for the conditions for hoisting it into load time, which is currently done by generating the sys:load-time-lit form around it and re-compiling.
* compiler: honor load-time in parts of loop.Kaz Kylheku2020-05-031-0/+1
| | | | | | | | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-for): If a for loop occurs in the top level, or inside a load-time, then we don't want to suppress the semantics of load-time for any parts of the loop that are repeatedly evaluated. The programmer may be doing that specifically to hoist those calculations out of the loop. We thus bind *load-time* to nil after compiling the initializing and test expressions. * txr.1: New paragraph in Notes for load-time, mentioning compiler treatment of loops and lambda. The language is deliberately general rather than being specifically about the for loop, because several loop constructs compile to the for loop, and that is also subject to future changes.
* compiler: top-level is in load-time.Kaz Kylheku2020-05-031-1/+2
| | | | | | * share/txr/stdlib/compiler.tl (compile-toplevel): Bind *load-time* to t, because of course initially we are in the top level, where load-time can be eliminated.
* compiler: check constantp in load-time.Kaz Kylheku2020-05-021-1/+1
| | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-load-time-lit): Don't hoist constant expressions into load-time, since they already get hoisted into a D register. Otherwise we just end up generating load-time code that moves from one D register to another.
* compiler: treat nested load-time forms.Kaz Kylheku2020-05-021-14/+19
| | | | | | | | | | | | | | | | | | | | | | | load-time forms nested in load-time forms have no special semantics; it's wasteful to separately hoist them into load time and store their value in their own D register. We must be careful: this is not true if a nested form occurs in a lambda. * share/txr/stdlib/compiler.tl (*load-time*): New special variable. (compiler comp-lambda): Bind *load-time* to nil around the compilation of the lambda, so load-time forms in the lambda are hoisted to load time, even if the lambda itself is wrapped in a load-time form. (compiler comp-load-time-lit): Bind *load-time* true around the compilation of the form. If *load-time* is already true, then skip the special load-time logic and just compile the enclosed form; the surrounding load-time compilation is taking care of the load-time hoisting. * txr.1: Document that load-time forms nested in load-time forms don't do anything, except in the lambda case.
* compiler: load-time: eliminate temp register.Kaz Kylheku2020-05-011-5/+3
| | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-load-time-lit): When compiling the load-time argument expression, indicate the allocated D register as the destination, rather than using a freshly allocated T register. Now we need an instruction to move into the D reg only if the fragment chose a different register.
* sockets: ipv6 address condensing rewrite.Kaz Kylheku2020-05-011-14/+12
| | | | | | | | | | | | | | | * share/txr/stdlib/socket.tl (sys:in6addr-condensed-text): Rewrite with regex based implementation that formats the number without condensing. This one has better semantics in that it finds the longest run of 0.0..0 to replace, rather than the leftmost. Ignoring this semantic difference, it also has better average performance on pseudo-random addresses, with similar performance on addresses with long condensable 0's. The original algorithm has a significantly poorer average case on random addresses, but better best case on condensable zeros like 1::1. The new algorithm could improve further with future work to make regexes faster.
* sockets: bug in formatting ipv6 address.Kaz Kylheku2020-05-011-11/+14
| | | | | | | | The str-in6addr and str-in6addr-net functions mishandle the zero address, rendering it as ":" instead of "::". * share/txr/stdlib/socket.tl (sys:in6addr-condensed-text): Test for the degenerate case and map it to "::" output.
* Version 237.txr-237Kaz Kylheku2020-04-261-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* compiler: avoid wasteful substitution via %bin-op%.Kaz Kylheku2020-04-201-1/+1
| | | | | | | | * share/txr/stdlib/compiler.tl (%bin-op%): Specify default value argument to relate so that arguments not found in %nary-ops% will match to nil. Otherwise the code in comp-fun-form rewrites all two-argument function calls through this relation, resulting in a bit of wasted consing.
* compiler: bugfix: constant test in 2 or 3 arg if.Kaz Kylheku2020-04-201-2/+2
| | | | | | | | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-if): The two and three argument cases assume that if the test is a constant expression, the consequent "then" should be unconditionally taken. The correct behavior is to evaluate the constant, which could yield nil. I checked which library code changes after this fix, and found that a number of (defset ...) forms are generating different, shorter code. This is due to (if ',restpar (if (consp ,restpar) ...)) in defset-expander. The intent there was to eliminate the inner if code entirely if respar is nil (there is no rest parameter); due to this bug, the code elimination didn't happen. The behavior is nevertheless correct because the code does nothing if restpar is nil.
* Version 236.txr-236Kaz Kylheku2020-04-181-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* path-testing functions: accept file descriptor.Kaz Kylheku2020-04-181-4/+3
| | | | | | | * share/txr/stdlib/path-test.tl (do-path-test): Pass all argument types to statfun, except if they are of type stat. * txr.1: Documented.
* New function: touch.Kaz Kylheku2020-04-151-0/+7
| | | | | | | | | * lisplib.c (copy_file_set_entries): Register autoload for touch. * share/txr/stdlib/copy-file.tl (touch): New function. * txr.1: Documented.
* ignwarn: handle warnings with multiple args.Kaz Kylheku2020-04-131-1/+1
| | | | | | * share/txr/stdlib/except.tl (ignwarn): Warnings have more than one argument; the handling lambda must take variable args.
* Version 235.txr-235Kaz Kylheku2020-04-121-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* path testing functions: accept stream argument.Kaz Kylheku2020-04-091-1/+4
| | | | | | | * share/txr/stdlib/path-test.tl (do-path-test): Check also for the argument being a stream, and pass to statfun. * txr.1: Documentation updated and improved.
* dump-compiled-objects: wrong self name.Kaz Kylheku2020-03-221-1/+1
| | | | | * share/txr/stdlib/compiler.tl (dump-compiled-objects): Fixed incorrect value of self variable.
* compile-file: propagate permissions for hash bang programs.Kaz Kyheku2020-03-101-1/+20
| | | | | | | | | | * share/txr/stdlib/compiler.tl (propagate-perms): New function. (compile-file-conditionally): If the source file is a hash bang script, then call propagate-perms just before closing the streams. * txr.1: Documented the permission propagation.
* Version 233.txr-233Kaz Kylheku2020-03-081-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* getopts: new feature: cumulative options.Kaz Kyheku2020-03-061-12/+46
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | An option declared as (cumul <type>) indicates that it is of type <type>, and that multiple occurrences of the option produce values that are accumulated into a list. The accumulation is in reverse order: the rightmost occurrence ends up the first in the list. * lisplib.c (getopts_set_entries): Add cumul to list of interned symbols, so that the getopts.tl code isn't mistakenly working with sys:cumul. * share/txr/stdlib/getopts.tl (opt-parsed): New slot, cumul. (opt-desc basic-type p, opt-desc list-type-p, opt-desc cumul-type-p): New methods. (opt-desc check): Rework type validity check using the new methods. (opt-parsed convert-type): Support 'cumul type by instantiating an opt-parsed object for the wrapped type, and stealing its converted argument into the current object, and setting the cumul flag. (opts add-opt, option-base add-opt): Support options that have the cumul flag set by accumulating list values. The code is different due to different amounts of encapsulation. The opts structure stores the raw opt-parsed objects, whereas option-base just takes the decoded values. (opthelp): Parse through the (cumul ...) type syntax, so cumulative options are printed in the help text the same way as if they were non-cumulative. * txr.1: Documented.
* getopts: bugfix in short option processing.Kaz Kyheku2020-03-061-6/+6
| | | | | | | | * share/txr/stdlib/getopts.tl (sys:opt-processor parse-shorts): There is a scoping mixup here with the opts argument shadowed by a same-named lexical variable, causing a referential mixup. Also fixed bad indentation.
* compiler: remove useless consp test.Kaz Kylheku2020-02-131-56/+55
| | | | | * share/txr/stdlib/compiler.tl (compiler compile): If the form isn't an atom, then consp is implied.
* copy-file.tl: mode change.Kaz Kyheku2020-02-121-0/+0
| | | | | | * share/txr/stdlib/copy-file.tl: Remove execute permissions that had been accidentally applied before this file was placed under version control.
* Version 232.txr-232Kaz Kylheku2020-02-091-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* file-place-buf: bugfix: create file if doesn't exist.Kaz Kylheku2020-02-071-1/+1
| | | | | | | * share/txr/stdlib/getput.tl (file-place-buf): Instead of "r+" mode, use the new "mb" mode which will create the file without truncating it, and open for write mode. Also, bugfix: the "b" option was missing.
* file-put-buf: new argument; also, new file-place-bufKaz Kylheku2020-02-071-1/+9
| | | | | | | | | | | | | Like file-put-buf but doesn't overwrite the file. * lisplib.c (getput_set_entries): New autoload for file-place-buf. * share/txr/stdlib/getput.tl (file-put-buf): New argument for seeking into the file. (file-place-buf): New function. * txr.1: Documented.
* file-get-buf: size limit, seek offset.Kaz Kyheku2020-02-051-12/+21
| | | | | | | | | | * share/txr/stdlib/getput.tl (sys:get-buf-common): Take two more arguments for maximum bytes to read and offset. Read loop simplified with fill-buf-adjust. (file-get-buf, command-get-buf): Take two new arguments, pass though to sys:get-buf-common. * txr.1: Documented.
* New functions chmod-rec and chown-rec.Kaz Kylheku2020-01-311-0/+29
| | | | | | | | | | | * lisplib.c (copy_file_set_entries): Add chown-rec and chmod-rec to list of symbols that trigger auto-load of copy-file.tl. * share/txr/stdlib/copy-file.tl (chmod-rec, chown-rec): Neew functions. * txr.1: Documented.
* copy-file: detect directory before opening.Kaz Kylheku2020-01-301-10/+13
| | | | | | | | * share/txr/stdlib/copy-file.tl (copy-file): Detect that from-path is a directory before attempting to open it. The issue is that the open will succeed for a directory, and only the subsequent read will fail. By that time we have opened created the target file.