summaryrefslogtreecommitdiffstats
path: root/share
Commit message (Collapse)AuthorAgeFilesLines
...
* compiler: use fixed-point macro for reduce-lisp.Kaz Kylheku2021-02-181-27/+32
| | | | | | * share/txr/stdlib/compiler.tl (fixed-point): New macro. (reduce-lisp): Hide irrelevant iteration details by using fixed-point macro.
* compiler: reduce (not (eq ...)) and related exprs.Kaz Kylheku2021-02-181-0/+3
| | | | | * share/txr/stdlib/compiler.tl (compiler comp-fun-form): Reduce negated eq, eql, equal to neq, neql, nequal.
* compiler: strength reduction of nequal.Kaz Kylheku2021-02-181-4/+6
| | | | | * share/txr/stdlib/compiler.tl (compiler comp-if): Support reduction of nequal in the same way as equal.
* compiler: reduce (list* x) to x.Kaz Kylheku2021-02-181-1/+1
| | | | | | | * share/txr/stdlib/compiler.tl (reduce-lisp): Add one more reduction case. There is a "hit" for this somewhere, because even though this adds code, overall 200 bytes are saved over the entire library.
* compiler: add list construction optimizations.Kaz Kylheku2021-02-171-0/+35
| | | | | | | | | | | | The raw size of the library compiled files shrinks by over 2% from this optimization, not to mention that some list construction code is faster. * share/txr/stdlib/compiler.tl (compiler comp-fun-form): Reduce common list construction primitives via reduce-lisp function which algebraically transforms to a form with fewer function calls. (reduce-lisp): New function.
* compiler: condense if with pattern matching.Kaz Kylheku2021-02-171-59/+47
| | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-if): Remove the pointless cases which check for test being nil, since that is subsumed under constantp. Move all the constantp cases up, making them match-case clauses. The handling of %test-funs% in several places becomes a single pattern case. The remaining cases don't have any more sub-cases to test, so the cond forms are gone.
* compiler: strength reduction of equal.Kaz Kylheku2021-02-171-6/+29
| | | | | | | | | | | | | | | Here, we look for (equal x y) expressions that can be reduced to (eql x y) or (eq x y) and compiled that way. Also, we look for (if (equal x y) ...) expressions that can be turned into (if (eql x y) ...) or (if (eq x y) ...) which then compile into ifq or ifql instructions. * share/txr/stdlib/compiler.tl (compiler comp-if): Convert tree-case into match case, and then handle the (if (equal ...)) pattern. (comp-fun-form): Add recognition for (equal x y) expressions, and reduce their strength, if possible. (eq-comparable, eql-comparable): New functions.
* compiler: fix jump-threading regression.Kaz Kylheku2021-02-171-48/+48
| | | | | | | | | | * share/txr/stdlib/optimize.tl (basic-blocks thread-jumps-block): We want a set here, not a pset, otherwise we are processing the old-instruction again rather than iterating. This breaks jump threading where multiple iterations are required to get to the ultimate target. It showed up as a difference in the compiled image of the sys:compile-match function.
* compiler: use pattern matching for function formKaz Kylheku2021-02-171-11/+7
| | | | | * share/txr/stdlib/compiler.tl (compiler comp-fun-form): Rewritten more compactly and extensibly using match-case.
* compiler: separate jump threading from peepholeKaz Kylheku2021-02-172-51/+65
| | | | | | | | | | | | | | | Jump threading just needs to looks at the last instruction in a basic blocks now; it's a waste of cycles to be pattern matching on jump intruction patterns while peephole scanning. * share/txr/stdlib/compiler.tl (compiler optimize): Invoke new thread-jumps after peephole. * share/txr/stdlib/optimize.tl (basic-blocks thread-jumps-block): New method. (basic-blocks peephole-block): Remove jump-threading cases; they are in thread-jumps block. (basic-blocks thread-jumps): New method.
* compiler: remove unreachable optimization.Kaz Kylheku2021-02-161-7/+0
| | | | | | | | * share/txr/stdlib/optimize.tl (basic-blocks peephole-block): Remove the special optimization involving an unconditional jump followed by an if, to a block which tests the same register with another if. This optimization can't match because a jmp and if cannot be in a basic block together.
* compiler: re-scan block altered by frame-move.Kaz Kylheku2021-02-151-0/+1
| | | | | | | | | | | * share/txr/stdlib/optimize.tl (basic-blocks peephole-block): If we move a frame instruction past a jump into the next block, we must add that block's label to the rescan list. There may be an opportunity to propagate the frame instruction deeper into that block. I'm not seeing a difference from this change in the compilation of the standard library, which indicates that this is happening by fluke; the alteration of that block is happening before it has been visited.
* compiler: close instructions terminate basic block.Kaz Kylheku2021-02-151-1/+1
| | | | | | | | * share/txr/stdlib/optimize.tl (struct basic-blocks): Include the close instruction in the set which terminate a basic block. A close is an unconditional jump; execution never continues after a close instruction, but goes unconditionally to a branch target.
* compiler: peephole newly added blocks.Kaz Kylheku2021-02-151-90/+100
| | | | | | | | | | | | | | | | If cut-block is called during peephole optimization, it can introduce blocks that can be missed, in which there might be some opportunity for peephole reduction. Let's keep track of newly added blocks in a re-scan list. * share/txr/stdlib/optimize.tl (struct basic-blocks): New slot, rescan. (basic-blocks cut-block): Add new block's label to rescan list. (basic-blocks peephole-block): New method, formed out of the bulk of basic-blocks peephole. (basic-blocks peephole): After processing the blocks from the hash table, iterate on the rescan list.
* compiler: basic blocks replace extended basic blocks.Kaz Kylheku2021-02-151-12/+27
| | | | | | | | | | | | | | | | * share/txr/stdlib/optimize.tl (struct basic-blocks): jump-ops, new static member. (basic-blocks :postinit): Cut the code into basic blocks rather than extended basic blocks. This means that the insruction which follows every jumping instructions is now a block leader. Every block needs a label, so we add them. (basic-blocks peephole): The optimization which slides a frame instruction past a jump must be refactored to move the frame instruction into the next block. Firstly, moving anything past a jump instruction is no longer allowed, because the result is no longer a basic block. Secondly, doing so prevents further frame movements, because the block no longer has any instructions after the jump over which the frame can be moved.
* asm/vm/compiler: introduce jend pseudo-instruction.Kaz Kylheku2021-02-142-5/+10
| | | | | | | | | | | | | | | | | | | | | | The jend pseudo-instruction is a simple alias for end. It indicates a jumping end: an end that does not fall through to the next instruction but could go somewhere else. This is for "future correctness" as well as clarity. The difference is important in analysis of code into basic blocks. Currently this won't make a difference because all the jend instructions except for the one at the end of compiled top-level form are followed by a label which kicks off a basic block anyway. * share/txr/stdlib/asm.tl (defopcode-alias): New macro. (jend): New opcode, defined as alias for end. * share/txr/stdlib/compiler.tl (comp-unwind-protect, comp-lambda-impl, compile-toplevel): Use jend instruction for a jumping end: the one after the protected code block of a uwprot, the one at the end of a function, and the one at the end of a top-level form.
* vm/asm: housecleaning: remove deprecated opcodes.Kaz Kylheku2021-02-141-46/+1
| | | | | | | | | | | | | | | | | | Since we have are breaking binary compatibility in the upcoming TXR 252, we might as well take the opportunity to remove deprecated opcodes that the compiler doesn't use. * share/txr/stdlib/asm.tl (op-fin): Opcode removed. (op-pprof): Derive directly from op-end rather than op-fin. (op-movrsi, op-movsmi, op-movrbi, op-movi-pseudo): Opcodes removed. * vm.c (vm_fin, vm_movrsi, vm_movsmi, vm_movrbi): Functions removed. (vm_execute): FIN, MOVRSI, MOVSMI, MOVRBI cases removed. * vmop.h: Regenerated. (vm_op_t): Enum members FIN, MOVRSI, MOVSMI, MOVRBI removed.
* compiler: eliminate block from recursive functions.Kaz Kylheku2021-02-121-7/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The block elimination logic doesn't work for self-recursive functions, even if they invoke no block returning, and use only system functions that don't have anything to do with block returns. This is because the recursive call is not recognized, and treated as a call to an unknown function. Let's put in a simple hack. The defun and defmacro operators will use a new secret special operator called sys:blk instead of block to generate the block. The compilation of sys:blk will assume that (sys:blk name ...) is only used in a defun or defmacro by that same name, and include name in the list of OK functions. So that functions created using the interpreter and then dynamically compiled will also benefit, we add this operator to the interpreter. * eval.c (sys_blk_s): New symbol variable. (op_defun): For defun and defmacro, use sys:blk for the block for the block (eval_init): Initialize sys_blk_s with the interned symbol sys:blk. Register the sys:blk operator. * share/txr/stdlib/compiler.tl (compiler compile): Recognize the sys:blk special form and handle via comp-block. (comp-block): If sys:blk is being compiled, then include the block name in the list of functions that do not perform block returns. (If this is false, other checks will fail before use that.) (expand-defun): Use sys:blk for defun and defmacro.
* compiler/vm: more compact frame size for closures.Kaz Kylheku2021-02-112-121/+143
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Closures do not share t-registers with surrounding code; they do not store a value into such a register that code outside the closure would read and vice versa. When compiling closures, we can can temporarily reset the compiler's t-register allocator machinery to get low t-register values. Then, when executing the closure, we reserve space just for the registers it needs, not based off the containing vm description. Here we make a backwards-incompatible change. The VM close instruction needs an extra parameter indicating the number of t-regisers. This is stored into the closure and used for allocating the frame when it is dispatched. * parser.c (read_file_common): We read nothing but version 6 tlo files now. * share/txr/stdlib/asm.tl (op-close asm): Parse new ntreg argument from close syntax, and put it out as an extra word. Here is where we pay for this improvement in extra code size. (op-close dis): Extract the new argument from the machine code and add it to the disassembled format. * share/txr/stdlib/compiler.tl (compile-in-toplevel): Save and restore the t-reg discards list also. Don't bother with a gensym for the compiler; the argument is always a symbol, which we can use unhygienically like in with-var-spy. (compile-with-fresh-tregs): New macro based on compile-in-toplevel: almost the same but doesn't reset the level. (comp-lambda-impl): Use compile-with-fresh-tregs to compile the entire closure with a minimized register set. Place the treg-cntr into the closure instruction to indicate the number of registers the closure requires. * vm.c (struct vm): New member, nreg. (vm_make_closure): New parameter, nreg, stored into the closure. (vm_close): Extract a third opcode word, and pull the nreg value from the bottom half. Pass this to vm_make_closure. (vm_execute_closure, vm_funcall_common): Calculate frame size based on the closur's nreg rather than the VM description's. * txr.1: Document that the upcoming version 252 produces version 6.0 object files and only loads version 6.
* compiler: frame-eliminating optimization.Kaz Kylheku2021-02-111-149/+260
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This optimization identifies let blocks whose variables are not captured by closures. The variables are relocated to registers and the frame M N ... end reg wrapping is removed. * parser.c (read_file_common): Load version 6 files. We remain backwards-compatible. * share/txr/stdlib/compiler.tl (var-spy, capture-var-spy): New structure types. (struct compiler): New slot, var-spies. (with-var-spy): New macro. (compiler (alloc-new-treg, unalloc-reg-count, push-var-spy, pop-var-spy)): New methods. (compiler (comp-atom, compt-setq, comp-list-setq, comp-lisp1-value)): Inform the spies in the spy notification stack about assignments and accesses. (compiler eliminate-frame): New method. (compiler comp-let): Use spies to determine which variables from this frame are captured, and if none are, then use eliminate-frame to rename all the variables to t-registers and drop the frame setup/teardown. (compiler comp-lambda): Set up a capture-var-spy which intercepts accesses and assignments within a lambda, and informs other spies about the captures. (%tlo-ver%): Bump compiled file version to to (6 0), because of some behavioral changes necessary in the VM. We might revert this if the issues are solved differently. * vm.c (vm_getz): Do not null out T registers. (vm_execute_toplevel, vm_execute_closure): Use zalloca to allocate the register part of the frame, so T registers are initialized to nil.
* compiler: use rewrite-case in dedup-labels.Kaz Kylheku2021-02-101-8/+6
| | | | | | | * share/txr/stdlib/optimize.tl (dedup-labels): Use rewrite-case macro defined in the same file instead of rewrite/lambda/match-case. Also change two-argument list* to cons.
* compiler: bug: trivial unwind-protect return valueKaz Kylheku2021-02-101-1/+1
| | | | | | | | | | | | | Bad test case: (unwind-protect 42 1 2 3) -> 3 ;; should be 42 * share/txr/stdlib/compiler.tl (compile comp-unwind-protect): In the case when the protected code compiles to zero code, because it is a simple variable or constant, the code that we return must still nominate the that fragment's output register as its output, and not the output register of the cleanup 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.
* compiler: rename variable in optimizer code.Kaz Kylheku2021-02-091-2/+2
| | | | | | * share/txr/stdlib/optimize.tl (basic-blocks peephole): Rename jlabel3 variable to jlabel2, so it is in sequence after jlabel0 and jlabel1.
* struct: changing meaning of obj.[fun ...] syntax.Kaz Kylheku2021-02-092-6/+16
| | | | | | | | | | | | | | | | | | | | | | | | | 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.
* 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.
* Version 251txr-251Kaz Kylheku2021-02-081-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Re-synced to 251. * txr.vim, tl.vim: Regenerated.
* 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.
* compiler: frame optimizations apply to dframe too.Kaz Kylheku2021-02-081-2/+2
| | | | | * share/txr/stdlib/optimize.tl (basic-blocks peephole): Use or pattern to look for dframe as well as frame.
* compiler: jump skid optimization.Kaz Kylheku2021-02-071-0/+8
| | | | | | | | | | | | | | | | | | 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).
* compiler: frame reduction optimizations.Kaz Kylheku2021-02-071-1/+36
| | | | | | | | | | | | | | 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.
* 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-063-35/+42
| | | | | | | | | | | | | | | | | | | | | | | | * 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.
* compiler: take advantage of new scoping in optimizer.Kaz Kylheku2021-02-051-14/+14
| | | | | | * share/txr/stdlib/optimize.tl (basic-blocks peephole): Get rid of @(op ...) and @(require ...) operators in favor of direct backreferencing.
* 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.
* compiler: rewrite one peephole patern using @(with ...).Kaz Kylheku2021-02-051-8/+6
| | | | | | | * 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 ...).
* 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.
* compiler: new jump threading optimization case.Kaz Kylheku2021-02-051-0/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* compiler: optimize away discard register.Kaz Kylheku2021-02-051-33/+41
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* 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.