| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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/compiler.tl (compiler optimize): Call
peephole method on basic-blocks object, rather than
thread-jumps.
* share/txr/stdlib/optimize.tl (basic-blocks thread-jumps):
Rename method to peephole, since it does more than just
thread-jumps. Add some dead code elimination, and elimination
of wasteful moves.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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/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.
|
|
|
|
|
|
|
| |
* 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/compiler.tl (compiler comp-let): The eenv
variable is used only in one place; the immediately next
binding for fenv. Let's eliminate it.
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
| |
* share/txr/stdlib/optimize.tl (basic-blocks thread-jumps):
Wrap long pattern expressions.
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
| |
* 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).
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|