| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lisplib.c (match_instantiate): Ensure usr:as is interned.
* share/txr/stdlib/match.tl (compile-let-match): Rename to
compile-as-match.
(compile-match): Remove handling of let symbol; route as
symbol to compile-as-match.
* tests/011/patmatch.tl: Update all uses of let to as.
* txr.1: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compiled-match get-vars): Local
function here becomes stand-alone defun, because we need it
elsewhere.
(compiled-mach wrap-guards): When processing the
guard-disjunction object to produce the or branches, we
calculate, for each branch, its own variables, and the variables
of the preceding clauses. We generate code to set the previous
variables to nil. Not all the previous variables, just those
that are not also in the current clause.
(get-vars): New function.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In the loose form of the @(struct ...) match, the struct type
is matched by a pattern. This pattern should execute before
the object is tested for the presence of the required slots
by by guard1. It should not come between testing for the
presence of slots, and then testing their contents.
* share/txr/stdlib/match.tl (compile-struct-match): Do not
lump together the type-match and slot-matches into a single
all-matches list. Emit type-match's guard before guard1,
and the slot-matches guards after. The order is
basic test (guard0), struct type pattern match (type-match),
slots-present (guard1) and then slot contents (slot-matches).
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-struct-match): make
guard0 and guard1 lists match-guard items. Replace
backquote with straight append.
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-dwim-predicate-match): In
he one-argument case, there is stray code referencing
var-match.test-expr, which blows up. This is hit by exactly
the one example in the documentation that was not added
as a test case.
* tests/011/patmatch.tl: Add test case from doc.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Elimination of unused temporaries is really the job of the
compiler, but we can do some simple things to get better code
from the matcher in the meanwhile. In list and vector matches,
@nil gets used just for placeholding. We can avoid generating
the code which binds the corresponding value to an unused
gensym.
share/txr/stdlib/match.tl (compile-var-match): When the
variable is nil, then do not generate a match-guard with
empty content. Just generate an empty guard-chain.
The higher level compiler can then check for this empty guard
chain and prune its own material away.
(compile-vec-match, compile-cons-structure): Eliminate every
gensym and its initializing expression, whose corresponding
compiled sub-match has an empty guard chain.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (non-triv-pat-p): Extend
sys:var match so (sys:var nil) is identified as trivial.
* tests/011/patmatch.tl: Add broken test case fixed by this.
This doesn't show up when @nil is used as the only match.
It also doesn't show up if @nil is used in a vector or list
in a mixture with other operators, because those other ones
identify the overall list pattern as non-trivial. None
of the occurrences of @nil in the existing test suite,
like (@nil @nil @x) tickle the bug.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compiled-match get-var-exprs):
method get-var-exprs removed. This is only used in one place,
which is going away. Actually, the value is not even used; it
is discarded.
(compiled-match get-vars): This method now passes the list of
variables thorugh uniq. The logic of get-guard-values is
pulled into a local function, since get-guard-values has only
one caller now.
(get-guard-values): Function removed.
(compile-or-match): Removing all-var-exprs variable
and all that calculation of the unique names, as well as the
extra match-guard which duplicates those names pointlessly.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (match-vars): Get rid of base,
since only match-guard would need it now.
(match-guard): Move match-vars methods and slots into this
structure.
(compiled-match): No longer inherits match-vars, so no
longer has vars and var-exprs slots. Also, slot test-expr
removed.
(compiled-match :postinit): Removed.
(compiled-match {get-vars, get-var-exprs}): Do not prepend
vars and var-exprs which no longer exist.
(compile-struct-match, compile-vec-match, compile-range-match,
compile-cons-structure, compile-let-match,
compile-hash-match): Get rid of vars, var-exprs and test-expr.
These are just causing duplicate variables to exist.
(compile-var-match): Convert necessary test-expr and vars into
match-guard object put into guard-chain.
(compile-atom-match, compile-or-match): Get rid of test-expr.
(compile-op-match, compile-predicate-match): Get rid of stray
reference to test-expr.
(compile-dwim-predicate-match): Move obj-var test into guard.
Get rid of vars, var-exprs and test-expr.
(compile-loop-match): Move vars and and test expression into
a second guard object, so there are now guard0 and guard1.
(compile-and-match): Get rid of all-var-exprs local variable
and its compuation, vars, var-exprs and test-expr.
(compile-not-match): Get rid of test-expr and empty vars.
(compile-hash-match):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (match-guard): New slot,
test-expr. This provides a bottom test, with all the variables
bound, allowing us to allocate just one match guard in a few
instances where we are allocating two. This will be important
in the upcoming refactoring.
(compiled-match :postinit): Allocate just one match-guard
with test-expr instead of a separate one with a guard-expr.
(wrap-guards): Wrap the test-expr to the code, if it is
not t.
(compile-hash-match): Reduce two match guards to one in two
instances.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-predicate-match): Promote
condition from test-expr into guard-chain.
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-dwim-predicate-match):
New function.
(compile-match): Route dwim symbol to
compile-dwim-predicate-match.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (when-match): Replace incorrect if
with when.
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-not-match): New function.
(compile-match): Hook in not operator.
* txr.1: Documented.
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
| |
* lisplib.c (match_set_entries): New autoload triggers.
* share/txr/stdlib/match.tl (lambda-match, defun-match): New
macros.
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-op-match): New function.
(compile-match): Route op operator to new function.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-or-match): New function.
(compile-match): Route or operator to new function.
|