summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* matcher: new broken test case: bad order of checks.Kaz Kylheku2021-01-271-0/+2
| | | | | | | * tests/011/patmatch.tl: Even though bar mismatches foo, the second element @(all) is processed and tries to collect the list. This results in an error due to the list being improper.
* matcher: clean up unclear vars situaton.Kaz Kylheku2021-01-271-38/+38
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | With this commit, the new broken test case passes. The main issue is not clearly separating temporary variables in mach-guards from public variables. * share/txr/stdlib/match.tl (match-vars): Remove pure-vars and pure-var-exprs from this inheritance base, as well as the related lets method. (match-guard): Add the "pure" slots here, under new names: pure-temps and pure-temp-exprs. This renaming is for clarity. Add the lets method here, based on these new variables. Add new slots temps, representing the impure temps. There is no temp-exprs because impure temps are bound to nil and later assigned. (compiled-match get-temps): Method removed. (compiled-match get-vars): Rewritten to avoid using get-temps which doesn't exist any more. This method has a clear purpose: to all the public variables coming from the patterns themselves, whether those variables are promoted into a guard-chain for early binding or whether they are attached on the compiled-match object. (compiled-match wrap-guards): Ensure that the new temps from the guard-chain objects are bound with let. (compile-struct-match, compile-vec-match, compile-range-match, compile-dwim-predicate-match, compile-cons-structure, compile-hash-match): pure-vars rename. (compile-loop-match): We no longer bind cm.(get-temps) here. That method doesn't exist. If we are not doing @(some), we bind cm-vars: the public vars collected from cm. We need local copies of them to catch their values and accumulate them into list. In the match-guard constructor, we move the collect-gens into temps; they are not public variables. (compile-parallel-match): Drop ^(let ,pm.(get-temps) ...) from the expansion.
* matcher: add failing @(or @(and ...)) test.Kaz Kylheku2021-01-271-0/+2
| | | | | | * tests/011/patmatch.tl: It looks like there is still a problem with scoping. An inner x is assigned the correct value, leaving the outer x nil.
* matcher: vars issue with loop and parallel paterns.Kaz Kylheku2021-01-271-5/+6
| | | | | | | | | | * share/txr/stdlib/match.tl (compile-loop-match): We must use the get-vars method of a compiled-match to get a list of its vars, and not directly access the vars slot. The list of vars must include all the non-temporary variables from the guard-chain. This is important in these rules because they specially treat the guard-chain and do not integrate it into their own guard chain directly.
* matcher: add failing @(all (@or ...)) test.Kaz Kylheku2021-01-271-0/+3
| | | | | The matcher has a bug: the loop patterns are not collecting the variables from enclosed parallel patterns.
* compiler: eliminate one local in compiler source.Kaz Kylheku2021-01-271-2/+1
| | | | | | * share/txr/stdlib/compiler.tl (compiler comp-let): The eenv variable is used only in one place; the immediately next binding for fenv. Let's eliminate it.
* optimizer: syntactic sugar around rewrite.Kaz Kylheku2021-01-271-46/+44
| | | | | | | | * share/txr/stdlib/optimize.tl (rewrite-case): New macro, combining rewrite, lambda and match-case. (basic-blocks thread-jumps): Condense using rewrite-case, and unfold some of the expressions into longer lines, since everything has moved quite a bit to the left.
* optimizer: format to 80 cols.Kaz Kylheku2021-01-271-7/+20
| | | | | * share/txr/stdlib/optimize.tl (basic-blocks thread-jumps): Wrap long pattern expressions.
* compiler: get rid of vector from swtch syntax.Kaz Kylheku2021-01-261-1/+1
| | | | | | | * share/txr/stdlib/compiler.tl (comp-switch): Convert the list of labels for the switch instruction from vector to list. This ends up a vector due to contagion from the sys:switch special operator syntax.
* compiler: use consistent prefix for label gensyms.Kaz Kylheku2021-01-261-1/+1
| | | | | | * share/txr/stdlib/compiler.tl (compiler comp-lambda-impl): Use the same "l" prefix for the skip label that is used elsewhere in the compiler.
* optimizer: thread close instructions.Kaz Kylheku2021-01-261-0/+6
| | | | | | | | * share/txr/stdlib/optimize.tl (basic-blocks thread-jumps): Also thread the implicit branch performed by close instructions. If a close instruction branches to an unconditional jump, then rewrite the close to jump that jump's target.
* optimizer: thread ifq instructions also.Kaz Kylheku2021-01-261-0/+9
| | | | | | | | | * share/txr/stdlib/optimize.tl (basic-blocks thread-jumps): If an (ifq RX RY label-X) instruction branches to an (ifq RX RY label-Y) instruction, replace it with that instruction. Moreover, if (if RX RY label-X) jumps to a (jmp label-Y) instruction, also replace it with (if RX RY label-Y).
* compiler: jump-threading optimization.Kaz Kylheku2021-01-262-1/+97
| | | | | | | | * share/txr/stdlib/compiler.tl: Load the new optimize module. (compiler optimize): New method. (compile-toplevel): Pass code through optimize method. * share/txr/stdlib/optimize.tl: New file.
* matcher: allow pat/var argument: @[expr var pat]Kaz Kylheku2021-01-263-13/+60
| | | | | | | | | | | | * share/txr/stdlib/match.tl (compile-dwim-predicate-match): Drop redundant bindable check of sym, since compile-var-match checks this. Support third argument which gives a pattern or variable which captures the value from the predicate function, which might be interesting (not just true/false). * tests/011/patmatch.tl: New tests. * txr.1: Documented.
* matcher: allow @[...] predicate notation.Kaz Kylheku2021-01-252-13/+34
| | | | | | | | | * share/txr/stdlib/match.tl (compile-dwim-predicate-match): New function. (compile-match): Route dwim symbol to compile-dwim-predicate-match. * txr.1: Documented.
* doc: update definition of non-trivial pattern.Kaz Kylheku2021-01-251-1/+1
| | | | | * txr.1: Under Pattern operator hash, include range patterns wih non-trivial contents as being non-trivial.
* doc: fix .meti not wrapped in of .mono/.onom.Kaz Kylheku2021-01-252-0/+42
| | | | | | | | | | * checkman.txr (check-meti): New pattern function which simply diagnoses any .meti. This relies on the fact that .mono/.onom blocks are matched and consumed by by another rule. All valid .meti lines are consumed as part of these blocks, so any .meti that remain must be outside. * txr.1: Fix numerous occurrences of this.
* doc: really remove @(rcons) pattern operatorKaz Kylheku2021-01-251-49/+1
| | | | | | * txr.1: Fix typo under Range match. Remove the documentation for the nonexistent pattern operator @(rcons ...) that was supposed to be removed before release 249.
* lazy-sub-str: bugfix: invalid substructure sharing.Kaz Kylheku2021-01-253-1/+48
| | | | | | | | | | | | | | | | | | | | | | | | | | | This addresses a bug manifesting itself as a regression in the behavior of @(freeform), which was reported by Frank Schwidom. The sub_str operation calls lazy_subs_str for a lazy string. But lazy_sub_str again relies on sub_str for extracting part of the lazy string prefix. But sub_str can potentially return the whole object rather than a copy of a substring of it. In this case, lazy_sub_str produces a new lazy string object which shares the prefix string object with the original lazy string. This is incorrect because the lazy string data type destructively manipulates the prefix. It means that operations one one lazy string are mucking with the prefix of another lazy string. * lib.c (lazy_sub_str): When creating the new lazy string object, make a copy of the prefix string pulled from the original. We do the carefully: the copy of the prefix is made before the make_obj call which allocates the new lazy string, otherwise we create a wrong-way assignment from the perspective of generational GC. * tests/006/freeform-4.txr: New test case, from Frank. * tests/006/freeform-4.expected: Expected output of test case.
* sub-str: compat check now restores 215 behavior.Kaz Kylheku2021-01-252-3/+20
| | | | | | | | | | | * lib.c (sub_str): If compatibility is requested, with a value of 215 or less, then disable the optimization of returning the original string without making a copy. This was found to break the @(freeform) directive. That regression alerts me to the fact that I should have made this subject to compatibility; some user code could be affected. * txr.1: New compat note added, under 215.
* Version 249txr-249Kaz Kylheku2021-01-196-943/+1014
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* doc: add back discussion about (rcons ...) pattern.Kaz Kylheku2021-01-242-0/+16
| | | | | | | * txr.1: Add anote that a pattern a..b matches rcons syntax, and add examples. * tests/011/patmatch.tl: new examples from doc added as tests.
* matcher: rescind support for @(rcons ...) patterns.Kaz Kylheku2021-01-243-41/+31
| | | | | | | | | | | | | | | | | | | | | There is no longer any way to write a @(rcons ...) pattern using the range syntax, so there is no point in supporting that operator. The silly syntax @@a..@b which previously worked was actually due to a mistaken requirement in the parser. * share/txr/stdlib/match.tl (compile-range-match): Function moved closer to compile-atom-match, below compile-vec-match. The argument is now a range object containing patterns, so we pull it apart with from and to. (compile-atom-match): Pass range directly to compile-range-match; no need to construct (rcons ...) syntax. * tests/011/patmatch.tl: Add range tests from documentation and a few others. * txr.1: References to @(rcons ...) pattern scrubbed. One wrong #R pattern example corrected.
* printer: do not render @(rcons ...) in .. notation.Kaz Kylheku2021-01-241-2/+11
| | | | | | | | | | | | | | | | | | | | | | | This fixes the following print-read consistency issue. Both of these objects print as @a..@b. 1> '@(rcons a b) @a..b 2> '(rcons @a b) @a..b We want only the second case. After the this fix: 1> '(rcons @a b) @a..b 2> '@(rcons a b) @(rcons a b) * lib.c (obj_print_impl): In the sys:expr case, we check whether the head of the argument is rcons. If so, we adjust a few local variables and branch directly to the generic list case via goto to print the argument as (rcons ...) without conversion to dotdot range notation.
* printer: do some streamlining.Kaz Kylheku2021-01-241-26/+27
| | | | | | * lib.c (obj_print_impl): Capture some values into local variables to avoid repeating the type-checked accesses. Many of the cases access the first argument, and such.
* parser: fix bad precedence of @ token.Kaz Kylheku2021-01-246-1778/+1876
| | | | | | | | | | | | | | | | | | | | | | | Whereas @a..@b parses and transforms to (rcons @a @a), @(a)..@(a) goes to @(rcons a @(a)). * parser.l (grammar): Under 248 compatibility or lower, the @ character now produces the OLD_AT token. Otherwise it produces the '@' character, as before. * parser.y (OLD_AT): New token replaces the '@' at the old low precedence position. '@' is now at the highest precedence, together with OLD_DOTDOT. (We don't care about interactions between '@' and OLD_DOTDOT, because OLD_DOTDOT only exists in 185 compatibility, in which '@' is OLD_AT). (meta): The two rules have to be unfortunately duplicated for OLD_AT, since there is no BNF OR operator in Yacc. * txr.1: Compat note added. * lex.yy.c.shipped: Updated. * y.tab.c.shipped, y.tab.h.shipped: Likewise.
* build: add rule for updating .shipped material.Kaz Kylheku2021-01-241-0/+3
| | | | * Makefile (%.shipped): New pattern rule.
* matcher: bind some temporaries with let.Kaz Kylheku2021-01-231-30/+34
| | | | | | | | | | | | | | * share/txr/stdlib/match.tl (match-vars): New slots, pure-vars and pure-var-exprs. (match-vars lets): New method. (compiled-match wrap-guards): Generate an alet that binds the temporaries, and then does the assignments of the regular variables. (compile-vec-match, compile-cons-structure, compile-hash-match, compile-range-match): Use the pure-vars for match-guard temporaries that are bound and not assigned, rather than vars. (when-match, if-match): Use alet for obj-var.
* places: fix runaway recursion bug.Kaz Kylheku2021-01-231-6/+7
| | | | | | | | | | | | | | The following form fails to expand: (let (a) (set a '#1=(#1#))) This is due to macro ancestor propagation which wants to traverse the entire (set ...) form in order to indicate its macro ancestor. * share/txr/stdlib/place.tl (sys:propagate-ancestor): We check whether to-tree already has a macro ancestor, and only recurse if it doesn't.
* place: bug: call-delete-expander not in usr package.Kaz Kylheku2021-01-231-1/+1
| | | | | * lisplib.c (place_set_entries): Fix misspelling of call-delete-expander entry: stray parenthesis.
* matcher: add support for range objects.Kaz Kylheku2021-01-232-0/+122
| | | | | | | | | | | * share/txr/stdlib/match.tl (compile-atom-match): Handle range type, via transformation to rcons operator and compile-range-mach. (compile-range-match): New function. (compile-match): Hook in compile-range-match for @(rcons). (non-triv-pat-p): Handle range case. * txr.1: Documented.
* doc: fix remove double word.Kaz Kylheku2021-01-231-2/+1
| | | | | * txr.1: Under Structural Pattern Matching, fix "instance instance".
* matcher: bugfix: boostrapping chicken-egg-problem.Kaz Kylheku2021-01-221-0/+2
| | | | | | | | | | | | | | | | | The previous commit made the general pattern matcher dependent on calling non-triv-pat-p function. But that function needs the matcher to work in order to be defined. This has left the code base uncompilable. * share/txr/stdlib/match.tl (non-triv-pat-p): Precede the real definition of non-triv-pat-p with a temporary one which returns a conservative t value, which suspects all syntx to be non-trivial. This means that the real non-triv-pat-p can use match-case, because match-case's expander will be using the temporary version of the function. non-triv-pat-p won't benefit from the optimizations arising from identifying trivial patterns: but since it doesn't have any such patterns, so it makes no difference.
* matcher: match trivial patterns as atoms.Kaz Kylheku2021-01-221-7/+13
| | | | | | | | | | | | * share/txr/stdlib/match.tl (compile-atom-match): Test whether a vector is really a non-trivial pattern, or a trivial piece of datum. If it is trivial, then compile it as an atom, which is matched by a simple call to equal, which is way less code bloat, and implemented in C. (compile-match): Similarly, check whether the cons structure case is nontrivial and only then treat it as a cons pattern, otherwise compile it as an atom, which will just match it with equal.
* matcher: add optimized special case to hash pattern.Kaz Kylheku2021-01-223-4/+55
| | | | | | | | | | | | | | | | | | This change causes a key-value pattern like (@a @b) to be treated specially when @a already has a binding from a previous pattern. In this case, it behaves like the trivial key case: the value of @a is looked up to try to find a single value. If @a is not bound, then the exhaustive search takes place, using equal equality. * share/txr/stdlib/match.tl (compile-hash-match): Implement special case. (var-pat-p): New function. * tests/011/patmatch.tl: Existing test case now changes value. New test case added. * txr.1: Documented.
* matcher: fix null value ambiguity in hash match.Kaz Kylheku2021-01-221-1/+6
| | | | | | | | | | | Hash pattern matching must not assume that if gethash returns nil, the item is not found. That's just a convenience that can be coded in some situations, not in a general mechanism. * share/txr/stdlib/match.tl (compile-hash-match): Allocate a gensym that serves as a unique object. Pass this to gethash as the alt argument, and then check whether gethash has returned this value to indicate failure.
* doc: he -> the fix.Kaz Kylheku2021-01-221-1/+1
| | | | * txr.1: fix typoo under if-match.
* matcher: document hash and some fixes.Kaz Kylheku2021-01-223-7/+131
| | | | | | | | | | | | | * share/txr/stdlib/match.tl (compile-hash-match): Follow rename of is-pattern function to non-triv-pat-p. (is-pattern): Renamed to non-triv-pat-p, to follow terminology in the reference manual. A bug is fixed here: we must recognize cons patterns with operators and variables in the dotted position as non-trivial. * tests/011/patmatch.tl: New hash test case, from doc. * txr.1: Documented hash pattern operator.
* hash: hash-revget now defaults to equal.Kaz Kylheku2021-01-222-3/+16
| | | | | | | | | * hash.c (hash_revget): Default to equal, except in compatibility mode. (hash_keys_of): Also default to equal. This function is too new to bother with compatibility switching. * txr.1: Documented, with compat notes.
* matcher: existing variables in @(all) now backref.Kaz Kylheku2021-01-223-8/+37
| | | | | | | | | | | | | | | | | | This commit fixes the inadequacy that all variables occurring in a pattern under @(all ...) or @(coll ...) are blindly collated into lists, ignoring the fact that they may be previously bound variables that must back-reference and not be colleced into lists (just like in the TXR Pattern language!) * share/txr/stdlib/match.tl (compile-loop-match): Calculate the subset of variables in the pattern that have been freshly bound. Only generate the collection gensyms for those variables and only collect and nreverse those variables. * tests/011/patmatch.tl: Some test cases that backreference into an @(all). * txr.1: Documented.
* matcher: default guard-expr to t in match-guard.Kaz Kylheku2021-01-211-4/+1
| | | | | | | | | * share/txr/stdlib/match.tl (struct match-guard): guard-expr slot defaults to t, so the guard defauls open. Guards are sometimes used just for binding temporaries and not imposing any condition. (compile-parallel-match, compile-hash-match): Omit initial value of t for guard-expr.
* doc: fix wrong year in document date.Kaz Kylheku2021-01-211-1/+1
| | | | * txr.1: 2020 -> 2021.
* bugfix: several predicates return 1 instead of t.Kaz Kylheku2021-01-211-13/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Firstly, I'm fixing an odd bug here: cobjclassp returns 1 instead of t to represent true. This affects: carrayp, hashp, random-state-p, regexp and struct-type-p, all of which return 1 when the test is true. For some bizarre reason, I chose this weird solution back in 2019 because this function has some calls at init time when t is not yet available; simply returning t causes a segfault. Secondly, I'm fixing the way we deal with t at initialization time. We simply give it a temporary value of 1 until it is replaced with the real symbol. This fixes all the original problems with t being nil until initialized. Now, we cannot do this: val t = one; because one is not a constant expression due to the cast, even though one is a de-facto constant. That's probably what distraced me away from the obvious second-best solution of just assigning it at some early point in the execution. * lib.c (cobjclassp): Fix odd bug here: returning one to indicate true instead of t. (make_sym): Don't test value of t here any more. (make_package_common): Don't use lit("t") instead of t any more in the make_hash calls. (make_package): Don't test value of t here. (obj_init): t can now be initialized using the straightforward expression t = intern(lit("t"), user_package), similarly to other symbols. (init): set t to the integer 1 before making any init calls.
* matcher: first cut at @(hash ...) operator.Kaz Kylheku2021-01-211-0/+54
| | | | | | | | | * share/txr/stdlib/match.tl (compile-hash-match): New function. (compile-match): Hook in hash operator. (is-pattern): New function: uses match-case, and is used in the implementation of the hash operator. This works because the function doesn't use @(hash ...) anywhere.
* matcher: new @(coll) operator.Kaz Kylheku2021-01-213-9/+43
| | | | | | | | | | | | | * share/txr/stdlib/match.tl (compile-loop-match): Implement coll semantics. coll fails if it collects nothing, which uses common logic with all*. We just have to move the flipping of the loop-iterated-var into the match, and not do it unconditionally for every iteration. (compile-match): Hook in the coll operator. * tests/011/patmatch.tl: Test case copied from doc example. * txr.1: Documented.
* matcher: when-match incorrect body treatment.Kaz Kylheku2021-01-211-1/+1
| | | | | * share/txr/stdlib/match.tl (when-match): Replace incorrect if with when.
* matcher: @(some) and @(all) work with sequences.Kaz Kylheku2021-01-212-16/+23
| | | | | | | | | | Relax the restrictions in these operators so they work with sequences rather than specifically lists. * share/txr/stdlib/match.tl (compile-loop-match): Make the necessary adjustments so that abstract iteration is used. * txr.1: Documented.
* doc: document new check in iter-step.Kaz Kylheku2021-01-211-1/+36
| | | | | | * txr.1: Document recently introduced check against crossing over into infinite iteration on the terminator of an improper list.
* matcher: more test cases.Kaz Kylheku2021-01-211-0/+29
| | | | | | * tests/011/patmatch.tl: Add test case matching with two structures in circular relationship, and a loop around match case for various cases involving backreference.
* matcher: matcher: fix broken @(let @a @(some @a)).Kaz Kylheku2021-01-212-7/+7
| | | | | | | | | | | | * share/txr/stdlib/match.tl (compile-parallel-match): Just like what was done in compile-loop-match in the prior commit, we fix the situation here. guard1's guard-expr, in which the matching logic actually happens, becomes the main test-expr. Thus guard1 disappears and guard0 is renamed to the one and only guard. * tests/011/patmatch.tl: Added test case which is fixed by this.