summaryrefslogtreecommitdiffstats
path: root/share/txr/stdlib/match.tl
Commit message (Collapse)AuthorAgeFilesLines
* file layout: moving share/txr/stdlib to stdlib.Kaz Kylheku2021-06-241-1070/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This affects run-time also. Txr installations where the executable is not in directory ending in ${bindir} will look for stdlib rather than share/txr/stdlib, relative to the determined installation directory. * txr.c (sysroot_init): If we detect relative to the short name, or fall back on the program directory, use stdlib rather than share/txr/stdlib as the stdlib_path. * INSTALL: Update some installation notes not to refer to share/txr/stdlib but stdlib. * Makefile (STDLIB_SRCS): Refer to stdlib, not share/txr/stdlib. (clean): In unconfigured mode, remove the old share/txr/stdlib entirely. Remove .tlo files from stdlib. (install): Install lib materials from stdlib. * txr.1: Updated documentation under Deployment Directory Structure. * share/txr/stdlib/{asm,awk,build,cadr}.tl: Renamed to stdlib/{asm,awk,build,cadr}.tl. * share/txr/stdlib/{compiler,conv,copy-file,debugger}.tl: Renamed to stdlib/{compiler,conv,copy-file,debugger}.tl. * share/txr/stdlib/{defset,doc-lookup,doc-syms,doloop}.tl: Renamed to stdlib/{defset,doc-lookup,doc-syms,doloop}.tl. * share/txr/stdlib/{each-prod,error,except,ffi}.tl: Renamed to stdlib/{each-prod,error,except,ffi}.tl. * share/txr/stdlib/{getopts,getput,hash,ifa}.tl: Renamed to stdlib/{getopts,getput,hash,ifa}.tl. * share/txr/stdlib/{keyparams,match,op,optimize}.tl: Renamed to stdlib/{keyparams,match,op,optimize}.tl. * share/txr/stdlib/{package,param,path-test,pic}.tl: Renamed to stdlib/{package,param,path-test,pic}.tl. * share/txr/stdlib/{place,pmac,quips,save-exe}.tl: Renamed to stdlib/{place,pmac,quips,save-exe}.tl. * share/txr/stdlib/{socket,stream-wrap,struct,tagbody}.tl: Renamed to stdlib/{socket,stream-wrap,struct,tagbody}.tl. * share/txr/stdlib/{termios,trace,txr-case,type}.tl: Renamed to stdlib/{termios,trace,txr-case,type}.tl. * share/txr/stdlib/{ver,vm-param,with-resources,with-stream}.tl: Renamed to stdlib/{ver,vm-param,with-resources,with-stream}.tl. * share/txr/stdlib/yield.tl: Renamed to stdlib/yield.tl. * share/txr/stdlib/{txr-case,ver}.txr: Renamed to stdlib/{txr-case,ver}.txr. * gencadr.txr: Update to stdlib/place.tl. * genman.txr: Update to stdlib/cadr.tl.
* matcher: new looping macros.Kaz Kylheku2021-06-241-0/+25
| | | | | | | | | | | | | | * lisplib.c (match_set_entries): Autoload on new while-match, while-match-case and while-true-match-case symbols. * share/txr/stdlib/match.tl (while-match, while-match-case, while-true-match-case): New macros. * tests/011/patmatch.tl: Tests. * txr.1: Documented. * share/txr/stdlib/doc-syms.tl: Updated.
* matcher: remove unused gensym.Kaz Kylheku2021-06-241-1/+0
| | | | | * share/txr/stdlib/match.tl (if-match): match-p gensym is not used; remove it.
* matcher: better error handling for backquotes.Kaz Kylheku2021-06-021-5/+12
| | | | | | | * share/txr/stdlib/match.tl (transform-qquote): Handle hash error case with separate pattern. Use compile-error and *match form instead of error. Diagnose splicing unquote and nested quasiquote.
* matcher: quasiquote matching.Kaz Kylheku2021-06-021-0/+23
| | | | | | | | | | | | | | | | | | | | | | | This allows (when-match ^(,a ,b) '(1 2) (list a b)) -> (1 2) which is a nice alternative that is supported by some Lisp pattern matchers. We don't need it since we have (@a @b). The motivation is JSON matching. (when-match ^#J{"foo" : {"x" : ~val}} #J{"foo" : {"x" : "y"}} val) -> "y" * share/txr/stdlib/match.tl (compile-match): Recognize qquote case and handle via transform-qquote function. (non-triv-pat-p): Let's declare quasiquotes to be nontrivial. (transform-qquote): New function: transform quasi-quoted syntax into regular pattern matching syntax. * txr.1: Documented.
* matcher: allow hash pattern to omit values.Kaz Kylheku2021-05-241-7/+29
| | | | | | | | | | | | The @(hash ...) operator now allows key-only patterns like (42) or (@x), where x could be bound or unbound. This has separate semantics from when a value is present. * share/txr/stdlib/match.tl (compile-hash-match): Implement. * tests/011/patmatch.tl: Test. * txr.1: Document.
* matcher: fix funny comma placement.Kaz Kylheku2021-05-241-2/+2
| | | | | | * share/txr/stdlib/match.tl (compile-hash-match): Fix unquoting comma that had been strangely moved to the previous line.
* matcher: new "each-match family" of macros.Kaz Kylheku2021-05-041-0/+31
| | | | | | | | | | | | | | | | | | * lisplib.c (match_set_entries): New autoload symbols: each-match, append-matches, keep-matches, each-match-product, append-match-products, keep-match-products. * share/txr/stdlib/doc-syms.tl: Updated. * share/txr/stdlib/match.tl (each-match-expander): New function. (each-match, append-matches, keep-matches, each-match-product, append-match-products, keep-match-products): New macros. * tests/011/patmatch.tl: New tests covering each macro, far from exhaustively. * txr.1: Documented.
* matcher: quasi match incorrectly treats nil as bound.Kaz Kylheku2021-04-261-1/+1
| | | | | | | | | | | | * 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.
* matcher: use match-str instead of sub-str and str=Kaz Kylheku2021-04-261-4/+4
| | | | | | * share/txr/stdlib/match.tl (expand-quasi-match): Don't extract substrings with sub-str; use match-str to match in-place.
* matcher: bugfix in `text{rest}` case.Kaz Kylheku2021-04-261-2/+2
| | | | | | * share/txr/stdlib/match.tl (expand-quasi-match): Calculate npos correctly relative to current pos. Use match-str rather than starts-with.
* matcher: diagnose unhandled quasiliteral cases.Kaz Kylheku2021-04-261-1/+6
| | | | | | | * share/txr/stdlib/match.tl (expand-quasi-match): Close the gap in the expander by diagnosing all unhandled syntax. There is now enough useful functionality and stability to start documenting the feature.
* match: third round of quasi tests and fixes.Kaz Kylheku2021-04-251-0/+8
| | | | | | | * 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.
* matcher: use @(as) capture.Kaz Kylheku2021-04-251-4/+5
| | | | | | * share/txr/stdlib/match.tl (expand-quasi-match): Instead of accessing args with car and cadr, capture that part in the match using @(as) and refer to the variable.
* matcher: second round of quasi tests and fixes.Kaz Kylheku2021-04-251-5/+9
| | | | | | | * 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.
* matcher: first round of quasi tests and bugfix.Kaz Kylheku2021-04-251-7/+5
| | | | | | | | | | * 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.
* matcher: recognize sys:quasi in necessary places.Kaz Kylheku2021-04-251-7/+7
| | | | | | | | | | | * match.tl (compile-cons-structure): Recognize quasi in the middle of cons structure and compile appropriately. (parse-lambda-match-clause): Recognize quasi in dot position properly. (check, check-end): Treat quasi as atom pattern. (pat-len): Recognize quasi in dotted position. (non-triv-pat-p): Handle quasi case. Any quasi containing elements that are lists is nontrivial.
* matcher: turn sys:quasi defmatch into built-in.Kaz Kylheku2021-04-251-36/+44
| | | | | | | | | | | | | | | This not only gets rid of the @ from @`...`, but allows the `` empty pattern `` to work. A bug is also fixed. * share/txr/stdlib/match.tl (compile-match): Recognize list headed by sys:quasi and feed to expand-quasi-match. (sys:quasi): defmatch removed. (expand-quasi-match): Function formed from sys:quasi defmatch. Instead of :form argument, we access *match-form*, like all the other internal functions. Instead of the :env parameter, we use the vars-list object. Using that object's exists method fixed a bug: failing to check for existing variables using boundp.
* matcher: new quasiliteral matching macro.Kaz Kylheku2021-04-241-0/+109
| | | | | | | | * share/txr/stdlib/match.tl (sys:quasi): New defmatch. This is a macro for now, which makes it require the @ prefix: e.g. @`@a-@b-@c`. The plain is to integrate this into the matcher to eliminate that @ prefix. The first priority are test cases and documentation.
* matcher: defmatch: useful :env parameter.Kaz Kylheku2021-04-211-5/+9
| | | | | | | | | | | | | | | | | | | * 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.
* matcher: new pattern operator @(end)Kaz Kylheku2021-04-201-44/+52
| | | | | | | | | | | | | | | * 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.
* matcher: first pattern macro, sme.Kaz Kylheku2021-04-191-0/+45
| | | | | | | | | | | | * 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.
* defmatch: pass form to mac-param-bind.Kaz Kylheku2021-04-191-1/+1
| | | | | | | | * share/txr/stdlib/match.tl (defmatch): Pass *match-form* to mac-param-bind so that the context is available to defmatch macros via the :form parameter. * txr.1: Documented use of :form in defmatch.
* matcher: new @(scan) operator.Kaz Kylheku2021-04-181-0/+21
| | | | | | | | | | | | | | * share/txr/stdlib/match.tl (compile-scan-match): New function. (compile-match): Hook scan operator into compiler. * lisplib.c (match_set_entries): Ensure scan is interned in usr package. * txr.1: Documented. * share/txr/stdlib/doc-syms.tl: Updated with new entry for scan.
* matcher: allow user-defined patterns via defmatchKaz Kylheku2021-04-171-15/+33
| | | | | | | | | | | | | | | | | * lisplib.c (match_set_entries): Register defmatch and *match-symbol* to autoload match.tl. * share/txr/stdlib/doc-syms.tl: Updated with entries for defmatch and *match-macro*. * share/txr/stdlib/match.tl (*match-macro*): New special variable holding hash. (compile-match): Handle macros via *match-macro* hash. (defmatch): New macro. * txr.1: Documented. * tags.tl: Recognize defmatch forms.
* matcher: diagnose syntax problems in hash pattern.Kaz Kylheku2021-02-091-1/+1
| | | | | | * share/txr/stdlib/match.tl (compile-hash-match): Use mac-param-bind instead of tree-bind, like in the other functions.
* matcher: replace wrg function with reduce-right.Kaz Kylheku2021-02-091-23/+14
| | | | | | | * share/txr/stdlib/match.tl (wrap-expr): Remove wrg local function. Replace call with simple reduce-right, which doesn't require a reversal of the original list. (compiled-match): Likewise.
* matcher: wrap-guards type case to method dispatch.Kaz Kylheku2021-02-091-44/+48
| | | | | | | | * share/txr/stdlib/match.tl (match-guards wrap-expr): New method. (guard-distinction wrap-expr): New method. (compiled-match wrap-guards): Reduce type-case to wrap-expr method call.
* matcher: match-guard: use op list, and zip.Kaz Kylheku2021-02-091-2/+2
| | | | | | | | * share/txr/stdlib/match.tl (match-guard assignments): Use simpler op expression to generate a function that produces set assignments. (match-guard lets): Use zip function instead of mapcar with ret and quasiquote.
* matcher: get rid of undocumented @(range) op.Kaz Kylheku2021-02-091-5/+4
| | | | | | | | * share/txr/stdlib/match.tl (compile-match): Remove the rcons entry which was supposed to be already gone in version 250, and is no longer documented. (compile-range-match): Edit parameter name to remove misleading reference to rcons.
* matcher: fix backreferencing in predicate.Kaz Kylheku2021-02-081-1/+1
| | | | | | | | | * 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.
* matcher: exprs-syntax: process trivial matches first.Kaz Kylheku2021-02-071-12/+15
| | | | | | | * 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.
* matcher: eliminate use of flags.Kaz Kylheku2021-02-071-27/+18
| | | | | | | | | * 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.
* matcher: remove @(op ...) pattern.Kaz Kylheku2021-02-061-7/+0
| | | | | | | | | | | | | | | 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.
* matcher: redesign predicate pattern.Kaz Kylheku2021-02-061-33/+40
| | | | | | | | | | | | | | | | | | | | | | | | * 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.
* matcher: left-to-right scoping for @(and).Kaz Kylheku2021-02-061-8/+4
| | | | | | | | | | | | | | 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.
* matcher: @(as) must always bind fresh variable.Kaz Kylheku2021-02-061-1/+16
| | | | | | | | | | | | | | 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.
* matcher: clean up var match.Kaz Kylheku2021-02-051-4/+6
| | | | | | * share/txr/stdlib/match.tl (compile-var-match): Pull symbol check into the cond. In null sym case, don't call var-list.record.
* matcher: back-reference Lisp variables.Kaz Kylheku2021-02-051-9/+18
| | | | | | | | | | | | | | | | * 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.
* matcher: rearrange match order of @(with).Kaz Kylheku2021-02-051-16/+20
| | | | | | | | | | | | | | | | | 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.
* matcher: don't set flag in last case.Kaz Kylheku2021-02-051-12/+18
| | | | | | | | | | | 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.
* matcher: lambda-match: bug: wrong variable tested.Kaz Kylheku2021-02-041-1/+1
| | | | | | * 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.
* matcher: lambda-match: error diagnostics.Kaz Kylheku2021-02-041-14/+20
| | | | | | | | | * 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.
* matcher: misleading diagnostics.Kaz Kylheku2021-02-041-2/+2
| | | | | | | * 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.
* matcher: add :match parameter macro.Kaz Kylheku2021-02-041-0/+13
| | | | | | | | | | | | | 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.
* matcher: lambda-match: redoc, bugfix, test-casesKaz Kylheku2021-02-041-1/+6
| | | | | | | | | | | | | | | * 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.
* matcher: reimplementation of lambda-match.Kaz Kylheku2021-02-031-6/+98
| | | | | | | | | | | | | | | | | | | | | | 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.
* matcher: bugfix: bad hygiene in match-case.Kaz Kylheku2021-02-031-4/+6
| | | | | | | * 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.
* matcher: fix @(and/or) backreferencing issue.Kaz Kylheku2021-02-021-1/+6
| | | | | | | | * 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.
* matcher: new @(with) operator.Kaz Kylheku2021-02-011-0/+19
| | | | | | | | | | | | * 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.