| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
| |
* tests/010/tree.tl: New tests, broadening coverage.
* share/txr/stdlib/doc-syms.tl: Regenerated.
|
|
|
|
|
|
|
| |
* tree.c (tn_lookup): The right case is incorrectly
chasing the left pointer.
* tests/010/tree.tl: New file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The tree module doesn't observe generational GC correctness;
it assigns objects into other objects using ordinary
assignment.
* tests/010/tree.tl (tree_iter): New member, tree.
This is initialized to null for iterators on the stack.
dynamic iterator, we need this to be a back-pointer to the
dynamic iterator.
(tree_iter_init): Add parameter to initializer to set up the
back-pointer.
(set_left, set_right, set_key): Use set macro instead of
ordinary assignment.
(tn_find_next): Use set macro to add node to path.
(tn_flatten, tn_build_tree): Use set macro.
(tr_rebuild, tr_rebuild_scapegoat, tr_insert, tr_do_delete),
tr_delete): Use set macro. Take a tree argument so we can use
set macro on tr->root.
(tree_insert): Use set macro. Pass 0 to tree_iter_init
initializer macro.
(tree_delete_node): Pass tree to tr_delete.
(tree_equal_op, tree_print_op, tree_hash_op): Pass 0 to
tree_iter_init initializer macro.
(tree-begin): Rearrange construction for GC correctness: avoid
storing pointers into not-yet-reachable structure.
|
|
|
|
| |
* tests/015/match-str.tl: Tests added.
|
|
|
|
|
|
| |
* lib.c (do_match_str): Fix wrong return value calculation
in LSTR-LSTR case.
* tests/015/match-str.tl: New file.
|
|
|
|
|
| |
* tests/011/patmatch.tl: Use mtest throughout to condense the
syntax.
|
|
|
|
|
|
|
| |
* tests/011/patmatch.tl: Add variants based on existing tests
which insert an extra character at the left that is matched by
a bound variable. This tests that the remainder of the pattern
is following the offset numeric position within the string.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (expand-quasi-match): bound-p
local function must return nil if the symbol is nil.
* share/txr/stdlib/match.tl: New test cases testing that @nil
is treated as an unbound variable in the
non-consecutive-variables test. Also, making duplicates of
certain tests that start with a text match and sticking @nil
as the first element into them, so that the text match is
forced to be the second item.
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (expand-quasi-match): Calculate
npos correctly relative to current pos. Use match-str rather
than starts-with.
|
|
|
|
|
|
| |
* tests/011/patmatch.tl: More tests. All explicitly coded
cases covered, except the fall-through situations we are
not yet catching in expand-quasi-match.
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (expand-quasi-match): Add case fo
r unbound var followed by var, followed by nothing.
* tests/011/patmatch.tl: New tests.
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (expan-quasi-match): Use rest
variable consistently instead of (cdr args). Two instances of
(cdr rest) should just be rest. New case added for variable
with no modifiers followed by text being the last item.
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (expand-quasi-match): The return
value of search-str isn't a length but an absolute position.
We not only fix a bug, but lose a useless calculation.
* tests/011/patmatch.tl: New test cases for quasiliteral
patterns, starting with the most rudimentary.
Last one broke, due to the above issue.
|
|
|
|
|
|
|
|
| |
* tests/011/patmatch.tl: Wrap one test with compile-only and
eval-only so that the compiler ignores it. Add a form
at the end of the file, similarly ignored by the compiler
to compile the file. This compiles and executes all the test
cases.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-match): Pattern macro
expanders now have an environment parameter. We turn the list
of variables that have been bound so far into a fake
macro-time lexical environment, the parent of which is the
surrounding environment. The pattern macro can query this
using the lexical-var-p function to determine whether a given
variable already has a binding, either in the pattern, or
in the surrounding lexical environment.
(defmatch): Generate a two-argument lambda, and use the new
mac-env-param-bind to make the environment object available
to the user-defined expansion.
* tests/011/patmatch.tl: New test cases for this environment
mechanism, and also for defmatch itself.
* txr.1: Document role of :env under defmatch.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
mac-env-param-bind is like mac-param-bind but also allows
the value for the :env parameter to be specified.
* eval.c (op_mac_env_param_bind_s): New sy mbol variable.
(op_mac_env_param_bind): New static function.
(do_expand): Handle mac_env_param_bind_s.
(eval_init): Initialize symbol variable and register macro.
* share/txr/stdlib/compiler.tl (compiler compile): Add case
for mac-env-param-bind.
(compiler comp-mac-env-param-bind): New method.
* share/txr/stdlib/doc-syms.tl: Updated with new hashes for
tree-bind and mac-param-bind, and inclusion of
mac-env-param-bind.
* tests/012/binding.tl: New file.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/doc-syms.tl: New entry for end.
* share/txr/stdlib/match.tl (check, check-end, check-sym,
loosen, pat-len): New functions, taken from original local
functions of sme macro.
(sme): Refactored by hoisting local functions out. Some
local variable renaming.
(end): New pattern macro.
* tests/011/patmatch.tl: New test for end.
* txr.1: Documented.
|
|
|
|
|
| |
* tests/012/parse.tl: All the tests in this file blow up on
systems that don't have a full-blown character type.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* tests/014/socket-basic.tl (%iters%): Also reduce to 2000 on
OpenBSD, to avoid the default limit on UDP datagram size.
* tests/017/glob-carray.tl: Use the BSD-style struct glob-t
on OpenBSD also.
* tests/017/glob-zarray.tl: Likewise.
* tests/018/chmod.tl (os): New global variable.
(test-sticky): s-isvtx not allowed for non-root user on
OpenBSD, so we falsify this variable.
* tests/common.tl (os-symbol): Add OpenBSD case, producing
:openbsd keyword symbol.
(libc): Let's just use (dlopen nil) for any platform that isn't
Cygwin or Cygnal.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lisplib.c (match_instantiate): Intern sme symbol.
* share/txr/stdlib/doc-syms.tl: Update with sme entry.
* share/txr/stdlib/match.tl (sme): New defmatch macro.
* tests/011/patmatch.tl: New tests for sme.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/error.tl (compile-error): Print the
error message on *stderr*, like we do with warnings.
This allows the programming environment to pick up the
error message and navigate to that line accordingly.
The error message is also output by the unhandled exception
logic but with a prefix that prevents parsing by the tooling.
To avoid sending double error messages to the interactive
user, we only issue the *stderr* message if *load-recursive*
is true.
* tests/common.tl (macro-time-let): New macro. This lets us
bind special variables around the macro-expansion of the body,
which is useful when expansion-time logic reacts to values
of special variables.
* tests/012/ifa.tl: Use macro-time-let to suppress *stderr*
around the expansion of the erroneous ifa form.
We now needs this because the error situation spits out a
message on *stderr*, in addition to throwing.
|
|
|
|
| |
* tests/012/compile.tl: Simplify code with regsub.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Makefile (%.expected): New implicit rule. Whenever a test requires a
.expected file, if it is missing, we create an empty one.
This file will be treated as an intermediate by GNU Make, which means
that it will be deleted when make terminates.
* tests/012/compile.tl: Some of the .tl files no longer have
an .expected file, so we have to test for that in the
catenating logic.
* tests/008/call-2.expected,
* tests/008/no-stdin-hang.expected,
* tests/011/macros-3.expected,
* tests/011/patmatch.expected,
* tests/012/aseq.expected,
* tests/012/ashwin.expected,
* tests/012/compile.tl,
* tests/012/cont.expected,
* tests/012/defset.expected,
* tests/012/ifa.expected,
* tests/012/oop-seq.expected,
* tests/012/parse.expected,
* tests/012/quasi.expected,
* tests/012/quine.expected,
* tests/012/seq.expected,
* tests/012/struct.expected,
* tests/012/stslot.expected,
* tests/014/dgram-stream.expected,
* tests/014/in6addr-str.expected,
* tests/014/inaddr-str.expected,
* tests/014/socket-basic.expected,
* tests/015/awk-fconv.expected,
* tests/015/split.expected,
* tests/015/trim.expected,
* tests/016/arith.expected,
* tests/016/ud-arith.expected,
* tests/017/ffi-misc.expected,
* tests/018/chmod.expected: Empty file deleted.
|
|
|
|
|
|
|
|
| |
* tests/012/compile.tl (new-file): Compiles a select set of
.tl files in the same directory. The compile.expected file is
dynamically created from catenating the .expected files
corresponding to those .tl files; the output is expected to be
the same from compiling those files as from interpreting them.
|
|
|
|
|
|
|
|
|
|
| |
* parser.l (grammar): Just like we do in SREGEX, allow an
arbitrary byte in REGEX, mapping it to the DCxx range.
Do the same inside string literals of all types.
* lex.yy.c.shipped: Updated.
* tests/012/parse.tl: New tests.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The main idea in this commit is to change a behavior of the
lexer, and take advantage of it in the parser. Currently, the
lexer recognizes a {UANYN} pattern in two places. That
pattern matches a UTF-8 character. The lexeme is passed to
the decoder, which is expected to produce exactly one wide
character. If the UTF-8 is bad (for instance, a code in the
surrogate pair range U+DCxx) then the decoder will produce
multiple characters. In that case, these rules return ERRTOK
instead of a LITCHAR or REGCHAR. The idea is: why don't we
just return those characters as a TEXT token? Then we can
just incorporate that into the literal or regex.
* parser.l (grammar): If a UANYN lexeme decodes to multiple
characters instead of the expected one, then produce a
TEXT token instead of complaining about invalid UTF-8 bytes.
* parser.y (regterm): Recognize a TEXT item as a regterm,
converting its string value to a compound node in the regex
AST, so it will be correctly treated as a fixed pattern.
(chrlit): If a hash-backslash is followed by a TEXT token,
which can happen now, that is invalid; we diagnose that
as invalid UTF-8.
(quasi_item): Remove TEXT rule, because the litchars
constituent not generates TEXT.
(litchars, restlistchar): Recognize TEXT item, similarly to
regterm.
* tests/012/parse.tl: New file.
* tests/012/parse.expected: Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* utf8.c (utf8_from_buffer): Fix incorrect backtracking logic
for handling bad UTF-8 bytes. Firstly, we are not backtracking
to the correct byte. Because src is incremented at the top of
the loop, the backtrack pointer must be set to src - 1 to
point to the possibly bad byte. Secondly, when we backtrack,
we are neglecting to rewinding nbytes! Thus after
backtracking, we will not scan the entire input. Let's avoid
using nbytes, and guard the loop based on whether we hit the
end of the buffer; then we don't have any nbytes state to
backtrack.
* tests/017/ffi-misc.tl: New test case converting a three-byte
UTF-8 encoding of U+DC01: an invalid character in the
surrogate range. We test that the buffer decoder turns this
into three characters, exactly like the stream decoder.
Another test case for invalid bytes following a valid
sequence start.
|
|
|
|
|
|
|
|
|
| |
* tests/014/socket-basic.tl (%iters%): New variable.
2000 on MacOS, 5000 elsewhere.
(client, server): Use %iters% instead of hard-coded 5000.
(test): Rename to sock-test, since it clashes with the test
macro coming from common.tl, which we neeed to for the
os-symbol function.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The @(call) directive is buggy in the following ways, which
cause an indirect call to behave differently from a direct call.
It creates a new context, and so if the opening of a data
source is deferred into the indirectly called function, that
data source is lost when the indirect call terminates.
Furthermore, if a data source is already established, there
is no progress through the data: two consecutive @(call ...)
directives operate on the same data.
It also fails to implement vertical to horizontal fallback; if
a function is not vertically defined, the directive fails.
* match.c (v_call): Rewrite the core logic in the following
way: we rewrite the indirect @(call) syntax into direct call
syntax, substitute that into c->spec, and then just
call v_fun.
* tests/008/call-2.expected: New file.
* tests/008/call-2.txr: New file. Test fails before this commit
because both calls are matching against the same "A" element
of the list.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch causes TXR to treat calls to verticatl functions,
as well as the @(call) directive to be considered non-matching
directives, so that opening the data source is deferred.
This allows included .txr files to call the funtions that they
define, without the side effect of standard input being read.
* match.c (open_data_source): Function refactored to reduce
duplication. c->data is checked first, and if it is not t,
nothing is done, making the function cheaper in the frequent
case. The non_matching_dir condition changes. We now check
that the first element of the first spec is a non-nil symbol.
If it has a function binding as a vertical function, then
that is considered non_matching.
(dir_tables_init): Treat @(call) as a non-matching directive.
* Makefile (tst/tests/008/no-stdin-hang.ok): Add -n argument
for non-interactive, which will cause stdin to be read in
that test case if there is a regression in this change. If
make tests is run in a terminal, this will hang make tests.
* tests/no-stdin-hang.txr: New file.
* tests/no-stdin-hang.expected: New file.
|
|
|
|
|
|
|
|
|
|
|
| |
* match.c (v_call): This function must propagate the
next_spec_k return value, rather than return a
short-circuiting match object, which causes the parent
to immediately succeed.
* tests/008/call.txr: New test case, from Frank Schwidom.
* tests/008/call.expected: Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Until now, the obj.[fun ...] syntax has uselessly denoted
exactly the same thing as [obj.fun ...]. This latter syntax
is what should be used for that meaning.
The new meaning of obj.[fun ...] will be that it performs
method dispatch, where obj is passed to obj.fun as
the leftmost argument: obj.[fun ...] is [obj.fun obj ...],
with obj evaluated once.
* share/txr/stdlib/struct.tl (qref): Expansion change done
here, with backward compat switch.
* share/txr/stdlib/termios.tl (termios (go-raw, go-cbreak)):
Some a.[b c] turned to [a.b c] here.
* tests/012/oop.tl (animal print): Likewise.
* tests/012/struct.tl: Likewise, and some expansion tests
updated to reflect the new expansion.
* txr.1: Documentation revised in multiple places and compat
note added.
|
|
|
|
|
|
|
| |
* tests/011/patmatch.tl: New test case showing that existing
variables that don't match in an @(or) retain their values;
they do not become nil, unlike freshly bound variables in
non-matching or-clauses.
|
|
|
|
|
|
| |
* tests/011/patmatch.tl: back-referencing between the
expressions in an @(and) patter has recently been introduced,
and needs some coverage.
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-predicate-match): Always
allocate res-var as a gensym; do not use resvar. Otherwise we
will freshly bind resvar as a local, failing to back-reference.
* tests/011/patmatch.tl: Add test cases, the second of which
fails before this change.
|
|
|
|
| |
* tests/011/patmatch.tl: New test case.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
* tests/011/patmatch.tl: Predicates must also be tested
earlier, as guard conditions.
|