| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
| |
* tests/011/patmatch.tl: New test case.
|
|
|
|
|
| |
* share/txr/stdlib/optimize.tl (basic-blocks peephole): Use or
pattern to look for dframe as well as frame.
|
|
|
|
|
|
| |
* txr.1: Document that multi-sort takes a single function
in place of a list of one function. This has been a feature of
the implementation from the beginning.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If an (if reg label0) target branches due to reg being nil,
and the target of the branch is another branch instrution
of the form (ifq reg nil label1), we know that that branch is
not taken: the code following that instruction is executed.
THus can jump right to that code.
(if reg label0) (if reg xlabel)
... ...
label0 label0
(ifq reg nil label1) --> (ifq reg nil label1)
... xlabel
...
* share/txr/stdlib/optimize.tl (basic-blocks peephole): New
sub-case under (jmp @reg @jlabel).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
These optimizations have to do with moving a (frame x y)
instruction past the next instruction. The goal is to move the
frame past a conditional branch, under the right
circumstances, so that the frame is eliminated when the branch
is taken.
* share/txr/stdlib/optimize.tl (basic-blocks (cut-block,
next-block)): New methods.
(basic-block peephole): Add two patterns: one to move a frame
past a mov, call or gcall. Another more complicated one to
move it past an if which jumps to an end.
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-exprs-match): Sort the
expressions and patterns so trivial matches are processed
first. The original order is used for evaluating the
expressions.
|
|
|
|
|
|
|
| |
* lib.c (multi_sort): If any of the input lists is empty, then
there is an empty list of tuples to sort, producing a an
empty list that doesn't transpose back to a list of empty
lists. We code this as a special case.
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (if-match, match-case,
lambda-match): Instead of returning the result from the
case(s), which gets stored in a result variable, and setting a
flag to t, set the result variable inside the case, and return
t. This eliminates the flag. In match-case and lambda-match,
the cases can then be combined into an or form.
|
|
|
|
|
| |
* txr.1: The @avar variable may be in the dot position of the
form, denoting application.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
All he typical uses of this are better served by the new
predicate match. If op is really needed, it can be used with
the DWIM form of the predicate, as in @[(op ...) ...].
* share/txr/stdlib/match.tl (compile-op-match): Function
removed.
(compile-match): Remove op case.
* tests/011/patmatch.tl: Keep op test cases by converting them
to predicate test cases.
* txr.1: Documentation removed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-dwim-predicate-match):
Function removed. There is no more special @(dwim ...)
or @[...] pattern.
(compile-predicate-match): Function rewritten, providing
different syntax and semantics.
(compile-match): dwim dispatch removed.
(non-triv-pat-p): Replaced @(op ...) calls with new-style
predicate syntax.
(var-pat-p): Likewise, and upgraded one instance of old-style
predicate syntax to new.
* share/txr/stdlib/compiler.tl (reduce-or): Adjust predicate
pattern to new style.
* share/txr/stdlib/optimize.tl (dedup-labels): Likewise.
* tests/011/patmatch.tl: All test cases with predicate syntax
are updated to new style. One test case removed; some added.
* txr.1: Predicate patterns re-documented. All examples
involving predicate patterns updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
And binds left to right now; only or is parallel.
* share/txr/stdlib/match.tl (compile-and-mach): Do not compile
the patterns with copies of the var list, but with he one and
only incoming var-list. Consequently, there are not var lists
to merge. par-pat parameter renamed to and-pat.
* txr.1: Improve and/or documentation, clarifying scope
rules. Also, clarify that variables in non-matching patterns
of an or are no set to nil, if they are existing bindings from
before the or.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It is documented that as binds a new variable. Furthermore, it
used to be called let. Yet, it back-references. Let's fix it.
* share/txr/stdlib/match.tl (compile-new-var-match): New
function: like compile-var-match but binds new variable, as if
back-referencing didn't exist.
(compile-as-match): Use compile-new-var-match.
* txr.1: Improve as documentation. Clarify that it binds a
fresh variable, and that pattern is processed in its scope.
Include an example with circular structure.
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-var-match): Pull symbol
check into the cond. In null sym case, don't call
var-list.record.
|
|
|
|
|
|
| |
* share/txr/stdlib/optimize.tl (basic-blocks peephole): Get
rid of @(op ...) and @(require ...) operators in favor of
direct backreferencing.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (struct var-list): New slot, menv.
(var-list exists): Method now falls back on lexical scope and
dynamic variables.
(get-var-list): New function.
(when-match, if-match, match-case, when-exprs-match): Capture
macro environment and use get-vars-list to convert to a vars
object which carries it as the menv slot. With this, the
compiler framework has access to the lexical environment.
* tests/011/patmatch.tl: Test cases of back-referencing with
Lisp lexicals.
* txr.1: Documented.
|
|
|
|
|
|
|
| |
* share/txr/stdlib/optimize.tl (basic-blocks peephole):
Rewrite the recently added jump hreading optimization as a
single pattern, doing the matching into the other basic
block through the hash table using @(with ...).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The @(with side-pat expr main-pat) syntax becomes
@(with main-pat side-pat expr), which is more useful.
Also, the main-pat can be omitted.
* share/txr/stdlib/match.tl (compile-with-match): Recognize
two forms of the syntax: two argument form with main-pat
omitted and the full form. In the full form, main-pat is
on the left now and processed first, so we have to rearrange
the compilation and integration order.
* tests/011/patmatch.tl: Existing tests updated. Two-argument
test added.
* txr.1: Updated.
|
|
|
|
|
|
|
|
|
|
|
| |
The last case in a match-case or lambda-match does not need to
set the matched flag, since nothing tests it.
* share/txr/stdlib/match.tl (match-case): Rename some local
variables for consistency with lambda-match. Change the
counter from 1, so we can then compare the index of the last
case to the length and avoid emitting the set.
(expand-lambda-match): Same optimization.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This opportunity now exists due to the previous commit which
eliminates discarded register moves.
The idea is to recognize code like
if Txxx label0
jmp label1 ;; jump if Txx is not nil
label1:
if Txxx ... ;; Txxx is not nil
jmp label2 ;; jump taken
and rewrite the jmp in the first block to:
if Txxx label0
jmp label2
The leading if Txx label0 is then susceptible to further
threading via label0, as before.
Before the previous compiler commit, there were dead register
moves between the if and jmp that would be too complicated to
analyze in the peephole.
The motivation is that this pattern occurs in match-case
and lambda-match due to the way the cases update a matched-p
variable which is used to skip subsequent cases:
case0
(unless matched-p
case1) ;; sets matched-p if it matches
(unless matched-p)
case2) ;; sets matched-p if it matches
...
and so on. Those successive matched-p tests now thread; if matched-p
is true, the control flow will short-circuit past the
subsequent tests.
* share/txr/stdlib/optimize.tl (basic-blocks peephole): Add
new case for recognizing aforementioned pattern.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When compiling the procedural special forms prog and prog1,
there are subforms whose values are discarded. The
compilation of those forms still requires an output register,
which is passed down. In certain cases, wasteful moves of data
into that register are generated, which we can eliminate.
* share/txr/stdlib/compiler.tl (struct compiler): New slot,
discards. Holds t-registers that are marked as discard.
(compiler alloc-discard-treg): New method.
(compiler free-treg): Remove freed treg from discard list.
(compiler maybe-alloc-treg): If the given register is a
discard, we must allocate.
(compiler maybe-mov): New method, replacing maybe-mov function.
(compiler comp-if): Replace maybe-mov function calls with method.
In the (if test then) case, avoid referencing oreg register
after a maybe-mov since it may be a discard such that the
maybe-mov produced no code; reference the original register.
(comp-progn): Allocate oreg-discard with alloc-discard-treg
method instead of alloc-treg.
(comp-prog1): Same thing with igreg.
(comp-for): For compiling the test expression, use the same
output register as what was used for the init block. Do not
borrow oreg for this, which may be a discard that will be
removed by the maybe-mov.
(compiler (comp-setq, comp-ift, comp-switch, comp-block,
comp-catch, comp-let, comp-fbind, comp-lambda-impl, comp-or,
comp-tree-case, comp-load-time-lit): Replace maybe-mov
function calls with method.
(maybe-mov): Function removed, replaced by method.
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (expand-lambda-match): The
matched-p-temp variable must be tested for each clause, not
result-temp. The result of a matching clause could be nil.
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (when-exprs-match): Bind
the *match-form* special to macro form.
(lambda-match, defun-match, :match): Likewise.
(expand-lambda-match): Set the macro ancestor for the
when-exprs-match form to the be clause syntax it was derived
from.
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-var-match,
compile-predicate-match): Replace "is not a symbol" with "is
not a bindable symbol". I had this message come up claiming
that a :keyword is not a symbol.
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/error.tl (sys:dig): New function. If the
form has no source location, but has macro ancestry, thens
try to search through that.
(sys:loc): Don't bother with the conditional; source-loc-str
always returns something. When there is no source location
there is a "source loc n/a" string.
(compile-error, compile-warning, compile-defr-warning): Use
sys:dig to take advanage of macro ancestry information.
|
|
|
|
| |
* txr.1: pluralize identifier in syntax section.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With this, we can do matching anywhere we are able to specify
a function parameter list and a body, and we can specify
ordinary arguments, which are inserted to the left of the
implicit match. Plus, it specialy integrates with :key.
* lisplib.c (match_set_entries): Autoload on :match.
* share/txr/stdlib/match.tl (:match): New parameter macro.
* txr.1: Documented.
|
|
|
|
|
|
| |
* txr.1: Document return value convention of parameter list
transformers, without which it can only be deduced from
the example.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (expand-lambda-match): In a case
that takes the maximum number of fixed args and no dotted
pattern, in a function that is variadic, we must assert that
the rest parameter is nil: there are no additional arguments.
In the lambda args, we must generate the colon that separates
the optional arguments.
* tests/011/patmatch.tl: basic test cases for lambda-match
and defun-match.
* txr.1: lambda-match and defun-match redocumented, with
examples.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch replaces the argument-list-based lambda match with
one that matches fixed arguments without consing. Instead of
generating a variadic function with zero fixed arguments, it
generates a function with required, optional and rest argument
based on considering the arity of all the matches.
* share/txr/stdlib/match.tl (compile-exprs-match): New
function.
(compile-match): Wire a new pattern operator called sys:exprs,
for internal use. This matches a list-like pattern against the
values of multiple expressions, rather than a single
expression.
(when-exprs-mach): New internal macro for matching a sequence
of patterns against a sequence of expressions of the same
arity.
(lambda-clause): New structure.
(parse-lambda-match-clause, expand-lambda-match): New functions.
(lambda-match, defun-match): Redefine using
expand-lambda-match.
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (match-case): Use a gensym for
evaluating the obj expression, rather than passing that
expression itself into the sub-compile jobs, where it is
subject to multiple evaluation.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (seq_info): Streamline code. Initialize ret.kind to
SEQ_NOTSEQ to avoid repeating that in multiple else clauses.
Make sure that if the nullify method returns nil, we also
return in that case, and don't call get_special_slot on nil.
(rplaca, rplacd): Change the default case to COBJ, so that the
obj_struct_p inline can be used instead of structp.
Put the default: label on the error case which the struct
check falls through to; NIL now goes there.
(sub): Use obj_struct_p, not structp, in a case where we
already know we have a COBJ.
|
|
|
|
|
|
|
| |
* lib.c (seq_iterable): In the COBJ case, we must check
whether the object is a structure before accessing
get_special_slot. For instance (nullify #/a/) crashes
because a regex is a COBJ but not a struct.
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (var-list merge): New method.
(compile-or-match, compile-and-match): After compiling the
sub-patterns, merge all of their new variables produced in
their isolated var-list copies back into var-list, so they are
visible to subsequent compilation.
|
|
|
|
|
|
|
|
|
|
| |
* tests/011/patmatch.tl: New test cases that break. The (copy
var-list) logic in the handling of and and or is incomplete.
The bifurcated vars must be merged together into the original
vars. Without this, it looks as if the operator didn't bind
any variables, and they can be repeated again without
backreferencing. In the broken examples, variable a is taking
on the value 2 instead of mismatching the previous value of 1.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lisplib.c (match_instantiate): Ensure usr:with is interned.
* share/txr/stdlib/match.tl (compile-with-match): New
function.
(compile-match): Wire in with operator.
* tests/011/patmatch.tl: Test cases.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
| |
* tests/011/patmatch.tl: New test case showing that @(or)
no longer nulls out the variables from previous clauses like
it used to. (2 2 nil) is returned, showing a is not set to
nil when b matches.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
* txr.1: Fix use of nonexistent odd function which should be
oddp. The same example occurs in the test suite, but without
this error. Also fix indentation in this and the two related
examples above.
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
| |
* txr.1: The de-sugared (rcons @a @b) example is missing a
quote on the object, and so returns nil and not (1 2).
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
| |
* lib.c (delete_package): This is the only user of
alist_remove1. It can use remqual with a car_f key, which is
more efficient.
(alist_remove1): Function removed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Makefile (tst/tests/000/binding.ok): Pass -B to txr for this
new test.
* match.c (v_rebind): Fix gaping copy-and-paste bug here,
which causes rebind to take on the behavior of local/forget;
it takes all symbols that appear as its arguments from the
environment and produces an environment in which they
don't exist. What we want is to remove the left
variables from the environment, and since that is a nested
pattern, the right way to do that is to flatten it.
Bug reported by Frank Schwidom.
* tests/000/binding.txr: New file.
* tests/000/binding.expected: New file.
* txr.1: Improve documentation of @(rebind), also making
improvements in @(set) documentation.
|
|
|
|
|
|
| |
* txr.1: Fix issues in the formatting of the index-list, index
and function arguments of partition, partition*, split and
split* functions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|