summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* doc: document when-match, if-match and match-case.Kaz Kylheku2021-01-182-0/+132
| | | | | | * tests/011/patmatch.tl: Add match-case test. * txr.1: Document when-match, if-match and match-case.
* matcher: add tests from documentation.Kaz Kylheku2021-01-182-0/+68
| | | | | | * tests/011/patmatch.tl: New file. * tests/011/patmatch.expected: Likewise.
* mapcar: add test covering recent regression.Kaz Kylheku2021-01-181-0/+3
| | | | | * test/012/seq.tl: New test with multiple lambda arguments and variadic function.
* doc: document @(op) and predicate operator.Kaz Kylheku2021-01-181-0/+81
|
* doc: fix "he" typos.Kaz Kylheku2021-01-171-2/+2
| | | | | * txr.1: Fix "the" mistyped as "he" in the new pattern matcher documentation, as well as under call-finalizers.
* doc: document @(and)/@(or) pattern operators.Kaz Kylheku2021-01-171-0/+55
|
* matcher: fix semantics of variables in @(or)Kaz Kylheku2021-01-171-14/+19
| | | | | | | | * share/txr/stdlib/match.tl (cmopile-parallel-match): Rearrange the code and bind an all-vars local variable so that in submatch-fun we have access to the set of symbols. When compiling the @(or) operator, we use the list to null out all the variables that don't belong to the matching pattern.
* doc: document @(some) pattern operator.Kaz Kylheku2021-01-171-0/+28
|
* doc: document @(all)/@(all*) pattern operators.Kaz Kylheku2021-01-171-0/+48
|
* doc: document @(let) and @(require) pattern ops.Kaz Kylheku2021-01-171-0/+88
|
* doc: bad syntax in FFI type struct.Kaz Kylheku2021-01-171-1/+1
| | | | * txr.1: Fix << that should be <.
* doc: fix doc for @(struct ...) pattern operator.Kaz Kylheku2021-01-172-5/+5
| | | | | | | * txr.1: The operator is struct not structure. Formalize the heading as Pattern operator. * checkman.txr: Recognize the new Pattern operator heading.
* matcher: support loose mode for structures.Kaz Kylheku2021-01-172-26/+113
| | | | | | | | | * share/txr/stdlib/match.tl (compile-struct-match): Allow a pattern instead of a struct type name, in which case the object can be of any struct type which has the slots required by the pattern. * txr.1: Documented.
* doc: start of pattern matching documentation.Kaz Kylheku2021-01-161-0/+270
| | | | | * txr.1: New Structurl Pattern Matching major section with new subsections.
* matcher: add lambda-match and defun-matchKaz Kylheku2021-01-162-0/+11
| | | | | | | * lisplib.c (match_set_entries): New autoload triggers. * share/txr/stdlib/match.tl (lambda-match, defun-match): New macros.
* matcher: add if-match and match-case.Kaz Kylheku2021-01-152-1/+35
| | | | | | | | * lisplib.c (match_set_entries): Add match-case and if-match autoload trigger symbols. * share/txr/stdlib/match.tl (if-match, match-case): New macros.
* matcher: add support for @(op ...) predicate syntax.Kaz Kylheku2021-01-151-0/+6
| | | | | * share/txr/stdlib/match.tl (compile-op-match): New function. (compile-match): Route op operator to new function.
* matcher: support @(and pats ...) operator.Kaz Kylheku2021-01-151-16/+18
| | | | | | | | | | | | | | This is implemented using exactly the same code as @(or ...); the only difference is whether the and or or operator is used in the expression. * share/txr/stdlib/match.tl (compiile-or-match): Renamed to compile-or-parallel match. Some local variables are renamed to avoid being OR-specific. The operator is extracted from the pattern, and inserted into the guard expression. That one insertion is the only differnce between and and or. (compile-match): Route the or operator to the renamed function. Rout the new and operator to it also.
* matcher: remove useless code from @(some ...)Kaz Kylheku2021-01-151-8/+11
| | | | | | | | | * share/txr/stdlib/match.tl (compile-loop-match): Eliminate repeated (op eq 'some) tests by evaluating this once into the some-p variable. Do not wastefully generate the code that pushes values onto accumulation lists if we are translating the some operator; those lists are ignored. Don't generate those accumulation variables themselves at all.
* matcher: support @(or pats ..) operator.Kaz Kylheku2021-01-151-0/+17
| | | | | * share/txr/stdlib/match.tl (compile-or-match): New function. (compile-match): Route or operator to new function.
* maprod, maprend: correct self name.Kaz Kylheku2021-01-151-2/+2
| | | | | | * eval.c (maprodv, maprendv): These functions implement maprod and maprend; the v suffix is just in the C code and must not be part of the self name.
* mapcar/maprod: show-stopper bug.Kaz Kylheku2021-01-151-2/+6
| | | | | | | | | | | | | | | | | | | | | | | | Observed wrong result: (mapcar (lambda (. args) (list . args)) '#(1 2 3) '#(4 5 6)) -> #((1 4) nil nil) Correct result: -> #((1 4) (2 5) (3 6)) This is not specific to vector input; it's broken for sequences of all types. Functions affected are mapcar, mapf, mappend, mapdo, maprod, maprend, maprodo. * eval.c (map_common, prod_common): Because we reuse the args structure across iterations, we must reinitialize the fill and list members. These can be modified by the functionw which is called. In particular, the arguments are applied, they may be turned into a list (fill decrements to zero, and a list is produced).
* matcher: support @(some pat) operator.Kaz Kylheku2021-01-151-4/+8
| | | | | | | | | | | | | | | | This is the existential quantifier to accompany @(all). * share/txr/stdlib/match.tl (compile-loop-match): Check for the some symbol in a few places and adjust the output. We don't need a local binding of the patter's variables, only the temps. The values go directly to the outer binding of the variables which are not shadowed now. We also don't need the nreverse logic to set the outer variables: var-exprs is nil at the outer level. The polarity of the loop termination test is reversed: we quit the loop on the first match, as is the polarity of the return value: if the loop is aborted early t is returned instead of nil. (compile-match): Wire in the some operator.
* matcher: some renaming in all match.Kaz Kylheku2021-01-151-10/+12
| | | | | | | | | | | | This is in anticipation of using the same function to compile other patterns that involve iteration. * share/txr/stdlib/match.tl (compile-all-match): Function renamed to compile-loop-match. The successful match and loop termination variables are renamed to different symbols. Also, test for the usr:all* symbol explicitly rather than all for making the test consp. (compile-match): Follow function rename.
* matcher: use flag to eliminate block.Kaz Kylheku2021-01-151-3/+4
| | | | | | | * share/txr/stdlib/match.tl (compile-all-match): We use a flag to break out of the loop instead of (return). The loop's block is thereby later eliminated by the compiler. For this we re-purpose the same all-match-p-var symbol.
* matcher: fix semantics of empty @(all ...) match.Kaz Kylheku2021-01-152-2/+10
| | | | | | | | | | | | * lisplib.c (match_set_entries): Ensure usr:all* is interned. * share/txr/stdlib/match.tl (compile-all-match): When the operator is the existing all, we must listp as a guard, not consp, because an empty list must match vacuously by virtue of not containing any counterexample to the pattern. For situations when a vacuous empty match is not desired, we support the all* alternative operator, which uses consp. (compile-match): Wire in the all* operator.
* matcher: support @(all pat) operator.Kaz Kylheku2021-01-151-0/+37
| | | | | * share/txr/stdlib/match.tl (compile-all-match): New function. (compile-match): Hook it in.
* matcher: allow omitted variabel in predicatesKaz Kylheku2021-01-151-1/+1
| | | | | | | | | | For instance @(oddp) instead of @(oddp x) to require an element to satisfy oddp without capturing it to a variable. * share/txr/stdlib/match.tl (compile-predicate-match): Make the symbolic argument optional, defaulting to nil. A nil symbol is already treated as pseudo-variable which consumes an item without binding to a variable.
* matcher: improve error reporting.Kaz Kylheku2021-01-151-12/+16
| | | | | | | | | | | | | | So quick and dirty; you have to love special variables. * share/txr/stdlib/match.tl (*match-form*): New special variable. (compile-var-match, compile-predicate-match, compile-let-match): Use compile-error instead of error, passing the value of *match-form* as the context. (compile-match): Ditto, and eliminate unreachable case from cond form. (when-match): Capture form directly into special variable using :form *match-form*.
* matcher: factor out vars into common base.Kaz Kylheku2021-01-141-18/+18
| | | | | | | | | | | | | | | | | | | * share/txr/stdlib/match.tl (match-vars): New struct. Holds vars and expressions, and provides the method to zipper them up into the assignments. (match-guard, compiled-match): Inherit from match vars. match-guard loses temps and temp-exprs. It now has vars and var-exprs from the base and those are used instead. (compiled-match get-temps): Follow temps vars rename. (compiled-match wrap-guards): Use assignments method inherited from base instead of assignments function. (assignments): Function removed. (compile-struct-match, compile-vec-match, compile-cons-structure): Follow vars temps rename in match-guard struct. (when-mach): Use assignments method of compiled-match instead of assignments function.
* new: structural pattern matching.Kaz Kylheku2021-01-142-0/+202
| | | | | | | | * lisplib.c (match_instantiate, match_set_entries): New static functions. (lisplib_init): Register autoload using new statics. * share/txr/stdlib/match.tl: New file.
* build: support linker flags/libs separation.Kaz Kylheku2021-01-142-20/+33
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Our build system lumps all linker options together. The correct way is that linker flags are separated info flags and libs. Also, we respond to the LDFLAGS variable but ignore LDLIBS which is incorrect. Other issues are fixed. All that is fixed here. * Makefile (TXR_CFLAGS): Interpolate $(CFLAGS) last, so that options coming from CFLAGS can override previous options. (TXR_LDFLAGS): Interpolate $(LDFLAGS) last; same reason. (TXR_LDLIBS): New variable. (LINK_PROG): Put $(TXR_LDFLAGS) with the options, before the -o, and put $(TXR_LDLIBS) at the end. * configure (conf_ldlibs, platform_ldlibs): New variables. (usage text): Document platform-ldlibs and adjust documentation of platform-ldflags. (gen_config_make): Generate PLATFORM_LDLIBS and CONF_LDLIBS now needed by Makefile. (mainline): Adjusts various recipes to use conf_ldlibs instead of conf_ldflags, or in some cases both. In the case of libffi where we use pkg-config, we use the special pgk-config options to separately extract the flags and libs. We use EXTRA_LDLIBS instead of EXTRA_LDFLAGS in some conftest invocations, as necessary.
* Copyright year bump 2021.Kaz Kylheku2021-01-14128-130/+134
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * METALICENSE: 2020 copyrights bumped to 2021. Added note about SHA-256 routines from Colin Percival. * LICENSE, LICENSE-CYG, Makefile, alloca.h, args.c, args.h, arith.c, arith.h, buf.c, buf.h, cadr.c, cadr.h, chksum.c, chksum.h, chksums/crc32.c, chksums/crc32.h, combi.c, combi.h, configure, debug.c, debug.h, eval.c, eval.h, ffi.c, ffi.h, filter.c, filter.h, ftw.c, ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h, itypes.c, itypes.h, jmp.S, lex.yy.c.shipped, lib.c, lib.h, linenoise/linenoise.c, linenoise/linenoise.h, lisplib.c, lisplib.h, match.c, match.h, parser.c, parser.h, parser.l, parser.y, protsym.c, rand.c, rand.h, regex.c, regex.h, share/txr/stdlib/asm.tl, share/txr/stdlib/awk.tl, share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl, share/txr/stdlib/compiler.tl, share/txr/stdlib/conv.tl, share/txr/stdlib/copy-file.tl, share/txr/stdlib/debugger.tl, share/txr/stdlib/defset.tl, share/txr/stdlib/doloop.tl, share/txr/stdlib/each-prod.tl, share/txr/stdlib/error.tl, share/txr/stdlib/except.tl, share/txr/stdlib/ffi.tl, share/txr/stdlib/getopts.tl, share/txr/stdlib/getput.tl, share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl, share/txr/stdlib/keyparams.tl, share/txr/stdlib/op.tl, share/txr/stdlib/package.tl, share/txr/stdlib/param.tl, share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl, share/txr/stdlib/pmac.tl, share/txr/stdlib/quips.tl, share/txr/stdlib/save-exe.tl, share/txr/stdlib/socket.tl, share/txr/stdlib/stream-wrap.tl, share/txr/stdlib/struct.tl, share/txr/stdlib/tagbody.tl, share/txr/stdlib/termios.tl, share/txr/stdlib/trace.tl, share/txr/stdlib/txr-case.tl, share/txr/stdlib/type.tl, share/txr/stdlib/vm-param.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, strudel.c, strudel.h, sysif.c, sysif.h, syslog.c, syslog.h, termios.c, termios.h, time.c, time.h, tree.c, tree.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h, vm.c, vm.h, vmop.h, win/cleansvg.txr, y.tab.c.shipped: Copyright year bumped to 2021.
* vm: derive duplicated constants from Lisp origin.Kaz Kylheku2021-01-113-4/+14
| | | | | | | | | | | | | | | | | | | | | Some constnats in vm.c are hand-duplicates of ones in vm-param.tl. Let's put them in vmop.h instead, where they can be generated by the genvmop.txr script. The two new constants are anticipated for some upcoming VM work. * genvmop.txr: Generate the existing VM_LEV_BITS, VM_LEV_MASK, VM_SM_LEV_BITS and VM_SM_LEV_MASK from the Lisp constants. Also, let's add two new ones. * vm.c (VM_LEV_BITS, VM_LEV_MASK, VM_SM_LEV_BITS, VM_SM_LEV_MASK): Preprocessor symbols removed. * vmop.h (VM_LEV_BITS, VM_LEV_MASK, VM_SM_LEV_BITS, VM_SM_LEV_MASK): Preprocessor symbols generated here with identical values. (VM_MAX_LEV, VM_MAX_V_LEV): New constants.
* quips: new entriesKaz Kylheku2021-01-071-0/+2
| | | | | * share/txr/stdlib/quips.tl (sys:%quips%): East Van cross and reference to urban myth regarding Sports Illustrated cover.
* doc: stray functions in heading and syntaxKaz Kylheku2021-01-051-3/+1
| | | | | | | | * txr.1: The documentation section for makunbound also erroneously lists the fmakunbound and mmakunbound functions in the heading and syntax block. They are not documented there, but in their own section which follows and has its own heading, so these references to them must be removed.
* quips: improve one about side-effects.Kaz Kylheku2021-01-051-1/+1
| | | | * share/txr/stdlib/quips.tl (sys:%quips%): Updated.
* configure: tweak test for inline.Kaz Kylheku2021-01-041-3/+2
| | | | | | | | | | | | | | | | | | | | It seems that the Brew people are running into a problem. The configure test is detecting that "inline" can be used for declaring inline functions, but then some functions are not inlined, requiring an external definition. On GNU/Linuxes, we detect "static inline", so this doesn't reproduce. This is likely triggered by the recent change to compile as C99 (unless configuring in maintainer mode). * configure: Let's revise the set of possible definitions of INLINE that we try. Firstly, we only try "inline" if we are compiling as C++. If that fails, all the other forms of inline we try include "static". Let's not mess with anything involving "extern". Like a bare "inline", it might work in the test program but cause some sort of failure.
* progn, prog1, prog2: now also functions.Kaz Kylheku2021-01-013-8/+50
| | | | | | | | | | | | * eval.c (progn_fun, prog1_fun, prog2_fun): New static functions. (eval_init): Wire progn, prog1 and prog2 function bindings to new functions. * txr.1: Documented. * checkman.txr (check-func): Recognize Macro/function and Operators/functions heading.
* New macro: prog2Kaz Kylheku2021-01-012-5/+59
| | | | | | | | | | | | * eval.c (prog2_s): New symbol variable. (me_prog2): New macro expander function. (eval_init): Initialize prog2_s variable with interned symbol. Register prog2 macro expander. * txr.1: Maintain the documentation for progn and prog1, improving the wording and adding a dialect note . Document prog2.
* eval: use symbol vars for registering if, and or.Kaz Kylheku2021-01-011-3/+3
| | | | | * eval.c (eval_init): Use if_s, or_s, and_s instead of wastefully calling intern.
* gc: streamlining finalization-related code.Kaz Kylheku2021-01-011-4/+4
| | | | | | | | | | | | | | * gc.c (prepare_finals): Do not move unreachable objects with finalizers into generation 0 here. (call_finalizers_impl): Don't test the object for being in generation 0; that may not be true since we don't ensure that in prepare_finals now. Instead check he reachable flag of he finalization entry; that tells us that we are dealing with an object that had been found unreachable. When we re-introduce it into freshobj, we set its generation to zero. Also, don't bother with this freshobj logic if the full_gc flag has been set. That now includes not bothering to set object generations to zero.
* gc: do finalizers completely on one phase.Kaz Kylheku2021-01-012-37/+58
| | | | | | | | | | | | | | | | | | | | | | * gc.c (call_finalizers_impl): Iterate over the finalizer registrations until no more finalizers are identified, performing additional rounds, as necessary. Thus if finalizers register more finalizers that are eligible for processing according to the criteria of he current phase, those are done in the current phase. (gc_finalize): We must now carefully set the reachable flag to 1 for a new finalization entry. This was always the right thing to do and is logically correct: if an object is being passed to finalize, it is necessarily reachable. Leaving the 0 initialization would do bad things now, as follows. If any object whatsoever has a finalizer registered against it during GC-driven finalization, its finalizer will be called. This is bad if the object isn't garbage. Secondly, the object may be moved into generation 0, and put into the freshobj list. This is extremely bad if the object is reachable by generation 1 objects, which is now a wrong-way reference. * txr.1: Updated.
* Version 246txr-246Kaz Kylheku2020-12-315-266/+293
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* gc: add finalization count to objects.Kaz Kylheku2020-12-314-20/+28
| | | | | | | | | | | | | | | | | | | | | | | | With the finalization count, we don't have to scan the freshobj array for duplicates when calling finalizers. However, the limited range of the counter limits how many times we can register a finalizer against an object. * gc.c (make_obj): Reset the new fincount field to zero for a newly minted object. (call_finalizers_impl): Decrement the fincount for each object. Only run the freshobj-related logic when the count hits zero. (gc_finalize): Bump the fincount of a registered object. If the counter overflows, throw an exception. * lib.h (obj_common): Add new field fincount for the finalization count. * tree.c (tr_rebuild): Fix up dummy object initializer to accommodate the new member. * txr.1: Document that there is a limit on the number of times an object can be registered for finalization.
* gc: fix unnecessary full gc request in finalization.Kaz Kylheku2020-12-311-2/+2
| | | | | | | | | * gc.c (call_finalizers_impl): Objects are only added to freshobj if they are in the zero generation. We should skip that entire block of code if the object isn't in that generation. Not only is it wasteful to execute that code for the mature generation, but the logic falsely sets the full_gc flag whenever processing a non-gen-0 object!
* awk: tests for fconv.Kaz Kylheku2020-12-312-0/+21
| | | | | * tests/015/awk-fconv.tl, * tests/015/awk-fconv.expected: New files.
* doc: improve awk fconv documenation.Kaz Kylheku2020-12-311-0/+16
| | | | | | * txr.1: List the no-conversion - operator among the shortcuts, so it is easier to discover. Add a note that that fconv is potentially applicable to non-string fields.
* gc: bug: finalization logic causing gc assertKaz Kylheku2020-12-311-7/+17
| | | | | | | | | | | | | | | | | | | | | This problem was introduced on Feb 18, 2019 in commit 3931df5cba3d826511503ad1c0a5b84c1363765e. Explicit finalization of objects outside of GC can trigger an assertion in a later GC pass. * gc.c (call_finalizers_impl): We simply must not have duplicate entries in fresh_obj; this causes problems for sweep_one. Under Valgrind debugging, sweep_one protects the memory of processed entries, so a duplicate visit triggers bad accesses. A more serious issue is that this function can be called outside of gc, explicitly, since it is available as an API function. So that is to say, non-garbage objects can have their finalizers called ouside of GC. If this function is called explicitly, outside of GC, it can end up doing something stupid, like adding a generation 1 object into the freshobj array, triggering an assert. We address this by not doing any of that processing if GC is not taking place.
* doc: note for awk macro fconv.Kaz Kylheku2020-12-291-0/+11
| | | | * txr.1: Add usage note to the fconv macro.