summaryrefslogtreecommitdiffstats
path: root/share
Commit message (Collapse)AuthorAgeFilesLines
...
* matcher: restructuring to fix new broken case.Kaz Kylheku2021-01-281-96/+173
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This one test case requires restructuring. The handling for the @(or ...) operator is now very different. To support @(or ...), there is now a new variant of the match-guard object called guard disjunction, which contains multiple match-guard chains. Furthermore, the separation between both guard-chain lists and compiled-match having a test expression and variables is being obliterated. For now, what we do is in a :postinit handler on compiled-match, we immediately convert the test-expr, vars and var-exprs slots into a match-guard object, which is placed into the guard-chain, and then we clear these slots. They are now vestigial only and will be removed. * tests/011/patmatch.tl: New test case which shows that (@(or foo bar) ...) does not short immediately short circuit to a failure when the corresponding element is neither foo nor bar. Matching proceeds to the right, wasting cycles and possibly causing errors. * share/txr/stdlib/match.tl (*match-var*): Move to top, above structs. There are some methods which refer to this variable now for throwing internal errors. (guard-disjunction): New object that is compatible with a match-guard, and placed into guard-lists as if it were a match-guard. This handles the bifurcation logic of an OR match. (compiled-match): New :postinit handler converts local vars, var-exprs and test-expr into a match-guard placed into the chain, and then clears these values. The compilation of code is done purely from the guard-chain. (compiled-match get-vars): This method is now complicated due to the guard-disjunction objects, and so uses a helper function called get-guard-values. (compiled-match get-var-exprs): New method accompanying get-vars to get the accompanying init expressions. (compiled-match wrap-guards): Two changes are going on here. One is that the funccion takes on more of the responsibility which was previously carried out by the callers. The callers were interpolating the test-expr and vars from a compiled-match into a piece of code, which was then passed to wrap-guards. Hence the naming: the job was just to wrap some guards. Now, wrap-guards is called just with the body forms, and does all of the work. Secondly, wrap-guards is complicated due to the handling of the guard-disjunction items. Also, there is some case handling to generate better code; we avoid generating an empty (let () ...) and (alet () ...). (compiled-match add-guard-pre, compiled-match add-guards-pre, compiled-match add-guards-post): New methods for adding guards after construction. These interfaces replace hacks of pushing new variables, tweaking the test-expr, or explicitly pushing guards onto the list. (get-guard-values): New function for iterating over a guard-chain, including match-guard and guard-disjunction items, retrieving a particular list-valued slot from each one using the fun argument, and returning a list of all those lists catenated together. (compile-struct-match, compile-vec-match, compile-range-match): Eliminate test-expr, replacing it with the harmless t. (compile-op-match): We don't try to extend the test-expr of the compiled var. Rather we add our guard expressin using the add-guard-pre interface. (compile-dwim-predicate-match): Likewise, and also, we do not calculate the test-expr for the output compiled-match from the constituent match test-exprs. We ignore those and just set the test-expr pat-match.obj-var. The constituent test-exprs have been converted to guard-chain items already, so there is no point in referring to them. (compile-predicate-match): Use add-guard-pre method to add guard instead of pushing it on list. (compile-cons-structure): Eliminate test-expr being calculated from constituent test-exprs, and just stub it out to t. (compile-require-match): Use add-guards-post to push match-guard onto compiled child mach, instead of tweaking its test-expr. (compile-let-match): Oblierate calculation of test-expr from child test-exprs, replacing with t stub. (compile-loop-match): Call wrap-guards in the new way, without generating assignments or test-expr. (compile-parallel-match): This method is removed; there are now separate compile-or-match and compile-and-match methods. (compile-or-match): New method: compiles consitituent expressions, and converts them into multiple guard-chains for a guard-disjunction object. Then wrap-guards will finish the job of emitting the or logic out of those chains. (compile-and-match): This shares some common logic with compile-or-match, but is substantially simpler. Pattern matching is implicitly AND-based: in a pattern, all the sub-patterns have to match. So there isn't much to do beyond just evaluating all the patterns against the same object. They can all be thrown into one combined flat guard chain. (compile-not-match): Adjust to new wrap-guards interface. Nothing left to do here but pass the expression t to it. (copmile-hash-mach): The post-constructon manipulations of the child compiled matches are done with the appropriate add-guards-pre. The test-expr is eliminated, replaced with t. (compile-match): Wire or and and to the new separate methods compile-or-match and compile-and-match. (when-match, if-match, match-case): Simplified due to when-match interface change. The macros depend on a lot less implementation detail now: they bind the required vars and generate the code.
* compiler: bug: append-each mutates lists.Kaz Kylheku2021-01-281-5/+7
| | | | | | | | | | | | | | | | | | * share/txr/stdlib/compiler.tl (expand-each): The algorithm for appending is completely wrong. Not only does it destructively mutate, it doesn't look like it will behave like the interpreted append-each operator, since it assumes it can rplacd the tail cons of the output list, which won't work for non-list sequence types. * share/txr/stdlib/compiler.tl (expand-each): New translation strategy: append-each each will now accumulate the values of the body expression into a list, exactly like collect-each does. Then it will apply the sys:append function to that list. This ensures the "as if" semantics (append-each behaves like the append function), and non-destructive behavior: everything is copied that needs to be, except that a list tail can share substructure.
* matcher: remove superflous test-expr in hash op.Kaz Kylheku2021-01-271-2/+0
| | | | | | | * share/txr/stdlib/match.tl (compile-hash-match): In the trivial key case, we are wastefully installing the same expression as both a guard in the guard-chain and as a test-expr. We should not be frobbing vm.test-expr.
* matcher: fix broken predicate test.Kaz Kylheku2021-01-271-1/+2
| | | | | * share/txr/stdlib/match.tl (compile-predicate-match): Promote condition from test-expr into guard-chain.
* matcher: smallest fix for broken test case found.Kaz Kylheku2021-01-271-1/+3
| | | | | | * share/txr/stdlib/match.tl (compile-atom-match): Do not express the match for the atom via test-expr. That is too late. It needs to be a guard in the guard chain.
* 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: 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.
* 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-261-5/+21
| | | | | | | | | | | | * 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-251-0/+9
| | | | | | | | | * share/txr/stdlib/match.tl (compile-dwim-predicate-match): New function. (compile-match): Route dwim symbol to compile-dwim-predicate-match. * txr.1: Documented.
* Version 249txr-249Kaz Kylheku2021-01-191-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* matcher: rescind support for @(rcons ...) patterns.Kaz Kylheku2021-01-241-19/+19
| | | | | | | | | | | | | | | | | | | | | 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.
* 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.
* matcher: add support for range objects.Kaz Kylheku2021-01-231-0/+24
| | | | | | | | | | | * 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.
* 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-221-1/+19
| | | | | | | | | | | | | | | | | | 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.
* matcher: document hash and some fixes.Kaz Kylheku2021-01-221-4/+6
| | | | | | | | | | | | | * 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.
* matcher: existing variables in @(all) now backref.Kaz Kylheku2021-01-221-5/+7
| | | | | | | | | | | | | | | | | | 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.
* 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-211-8/+10
| | | | | | | | | | | | | * 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-211-10/+16
| | | | | | | | | | 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.
* matcher: matcher: fix broken @(let @a @(some @a)).Kaz Kylheku2021-01-211-7/+5
| | | | | | | | | | | | * 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.
* matcher: fix broken @(let @a @(some @a)) test case.Kaz Kylheku2021-01-211-8/+6
| | | | | | | | | | | | | | | | | | | | | This is caused by the way the loop match compiler moves the matching logic into a guard, which causes a re-ordering of the variable assignments which interferes with backreferencing when @(some) is embedded into a @(let), and probably other situations. The issues is that the backreferencing equal tests can be reordered to occur before the assignment which sets the intial value of the backreferenced variable: cart before the horse kind of thing. * share/txr/stdlib/match.tl (compile-loop-match): Do not add the submatch into the guard sequence. Thus guard1's vars and var-exprs, move into into the main compiled-match, and guard1's guard-expr moves into guard0. Thus guard1 disappears, guard0 becomes guard. * tests/011/patmatch.tl: New test case that is also fixed, and which was not fixed by a different approach to the problem that I scrapped.
* matcher: cleaner @(let) implementation.Kaz Kylheku2021-01-211-12/+11
| | | | | | | | * share/txr/stdlib/match.tl (compile-let-match): Reimplement cleanly in terms of compiling a variable match and a pattern match against the same object and integrating the two. Also, do not reject nil as a variable name; the documentation clearly says it is allowed.
* matcher: allow variables to back-reference.Kaz Kylheku2021-01-201-54/+78
| | | | | | | | | | | | | | | | | | | | | | | | Multiple occurrences of variables unify using equal. * share/txr/stdlib/match.tl (var-list): New struct type. Used for tracking what variables have been defined. (compile-struct-match, compile-vec-match, compile-atom-match, compile-op-match, compile-cons-structure, compile-require-match, compile-let-match, compile-loop-match, compile-parallel-match, compile-not-match): Take var-match argument and pass it down. (compile-parallel-match): Take var-match argument and pass copies of it down to the compile jobs of the branches, since they do not unify. (compile-var-match, comiple-let-match, compile-op-match): Handle variables carefully: check for variable already being defined and generate a backreference instead of a new binding match. (compile-match): Take optional var-list argument, instantiating the object if it is missing, pass down to all recursive compile unctions. * txr.1: Documented.
* match-case: eliminate useless initial flag test.Kaz Kylheku2021-01-201-2/+3
| | | | | | | | | | | | * share/txr/stdlib/match.tl (match-case): The first case should not test the flag variable, the variable is false. This compiles to a useless if instruction and unreachable code. I tried writing a peephole rule against that instruction sequence in an experimental peephole optimizer, but across the entire code, it only matched in code in compiler.tl arising out of match-case, so it is better to squash this at the source. I won't commit the peephole optimizer until it comes up with something that isn't better fixed elsewhere.
* matcher: bugfix and interface change in @(require).Kaz Kylheku2021-01-201-2/+2
| | | | | | | | | | | | | | * share/txr/stdlib/match.tl (compile-require-match): The bug here is that the condition is placed before the match.test-expr, which is incorrect. The conditions can only be evaluated if match.test-expr has succeeded, because otherwise the variables are not validated to have the correctly matching value. Also, in the documentation, the synax insinuates there can be more than one expression. So let's just make it work: require takes multiple expressions and combines them with an implicit and. * txr.1: Documentation updated.
* compiler: bug in new and expansion.Kaz Kylheku2021-01-201-3/+2
| | | | | | | | | | | | | | | * /share/txr/stdlib/compiler.tl (expand-and): The case with @(true-const-p) is wrongly ordered with respect to (and @a). The problem is that @rest can match a null terminator, and then we wrongly consume the constant; i.e. (and 42) calls (expand-and ^(and)) yielding t. Also, we eliminate the (and @a @b) case, because it is redundant with respect to (and @a . @rest). We adjust the latter to just output (if ...). And, lo and behold, now the function's cases map 1:1 to the ones in reduce-or. In fact reduce-or was originally produced from expand-and. I debugged it thoroughly, but neglected to backport to expand-and.
* Version 247txr-247Kaz Kylheku2021-01-191-1/+1
| | | | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Bumped from incorrect 245 to 247. * txr.vim, tl.vim: Regenerated. * protsym.c: Regenerated.
* matcher: use mac-param-bind, not tree-bind.Kaz Kylheku2021-01-191-9/+9
| | | | | | | | | * share/txr/stdlib/match.tl (compile-struct-match, compile-predicate-match, compile-cons-structure, compile-require-match, compile-let-match, compile-loop-match, compile-parallel-match, compile-not-match, match-case): Use mac-param-bind for better error reporting against the original form when inner tree patterns don't match.
* matcher: fix broken @(some) test case.Kaz Kylheku2021-01-191-10/+14
| | | | | | | | | * share/txr/stdlib/match.tl (compile-loop-match): Introduce a new guard, and bind the pattern's variables there. The main compiled match now has an empty list of vars and var-exprs, so there is no length mismatch. The nreversing of the accumulated lists (only done in the @(and) case) is part of the test-expr now.
* matcher: fix broken test case.Kaz Kylheku2021-01-191-5/+7
| | | | | | | | | | | * share/txr/stdlib/match.tl (compile-parallel-match): The problem here is that vars in the new compiled-match being returned is not a list of the same length as var-exprs (that being empty). When this is embedded in other expressions, and the vars/var-exprs are appended together, this causes a mismatch, causing assignments to go to the wrong variables. The solution is to move the binding of all-vars into a new guard. Guards are not blindly combined by appending.
* compiler: improve code for and/or.Kaz Kylheku2021-01-181-9/+36
| | | | | | | | | | | | | | | | | | | | | Squeeze the constant and unreachable cases out of (and ...) and (or ...) forms, producing a more streamlined translation. This is the first appearance of structural pattern matching in the compiler! * share/txr/stdlib/compiler.tl (compiler compile): Handle and using new expand-and function, which translates it to if forms. Handle or via the renamed method comp-or. (compiler comp-and-or): Renamed to comp-or, since it handles only or. All the switching between or/and is eliminated. The or form is first reduced using simplify-or. We retain this function because one case in cond relies on or; or is a useful primitive because (or a b) evaluates a only once; whereas (if a a b) requires common-subexpression elimination to generate the same code as (or a b). (true-const-p, expand-and, flatten-or, reduce-or, simplify-or): New functions.
* matcher: add @(not) operator.Kaz Kylheku2021-01-181-0/+17
| | | | | | | * share/txr/stdlib/match.tl (compile-not-match): New function. (compile-match): Hook in not operator. * txr.1: Documented.
* 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.
* matcher: support loose mode for structures.Kaz Kylheku2021-01-171-20/+48
| | | | | | | | | * 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.
* matcher: add lambda-match and defun-matchKaz Kylheku2021-01-161-0/+10
| | | | | | | * 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-151-0/+34
| | | | | | | | * 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.