summaryrefslogtreecommitdiffstats
path: root/share
Commit message (Collapse)AuthorAgeFilesLines
...
* vm: variadic arg closures bug 3/3.Kaz Kylheku2018-03-191-1/+1
| | | | | | | | | * share/txr/stdlib/asm.tl (op-close asm): Fix argument count check being incorrect in the variadic argument case, causing the assembler to blow up on a correct (close ...) instruction. The integer indicating the number of fixed args is one *less* than the number of arguments given to the instruction not one *more*.
* compiler: bug: inappropriate clobber in block.Kaz Kylheku2018-03-191-2/+2
| | | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-block): Don't use bfrag.oreg as the output register of block. Firstly, bfrag.oreg might be (t 0) which is read-only. Worse, bfrag.oreg could just be a variable from which the block obtains its return value; we mustn't clobber that location with block's dynamic return value. Not only mustn't but possibly we cannot: the location could be out of scope!
* compiler: bug: nil entered into data tab by block.Kaz Kylheku2018-03-191-1/+1
| | | | | | * share/txr/stdlib/compiler.tl (compiler comp-block): If the block is anonymous, just refer to (t 0) as the name; don't intern nil via get-dreg.
* compiler: use VM's function table for global calls.Kaz Kylheku2018-03-191-4/+23
| | | | | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler): New slots fidx-cntr, fidx and ftab. (compiler get-fidx, compiler get-funvec): New methods. (compiler comp-call-impl): New method. (compiler comp-call): Look up the symbol to determine whether the function lexical or global. Call comp-call-impl appropriately to generate a gcall or call. (usr:compile-toplevel): Obtain the funvec from the compiler and pass to vm-make-desc.
* asm: return original object from disassemble function.Kaz Kylheku2018-03-191-1/+2
| | | | | | | | * share/txr/stdlib/asm.tl (usr:disassemble): Return the object that was disassembled, rather than nil. This is useful in the listener: we can compile and disassemble something in one step, then have access to the compiled object via a listener variable.
* compiler: bug: lambda body uses inappropriate output reg.Kaz Kylheku2018-03-191-3/+5
| | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-lambda): The incoming oreg, which indicates where the surrounding context would like to put the closure, cannot be used for the output location of the lambda body. Because then when the closure is called, its return value will overwrite the location where the closure was placed. We must allocate a a new temporary register for this, and be sure to free it.
* compiler: bugfix: misused assoc in function lookup.Kaz Kylheku2018-03-191-1/+1
| | | | | * share/txr/stdlib/compiler.tl (sys:env lookup-fun): Fix swapped args in assoc call.
* vm: function table for faster calls.Kaz Kylheku2018-03-182-3/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The vm now supports gcall and gapply opcodes which index numerically (using an immediate integer field in the instruction word) into a table of pre-resolved global function bindings. * share/txr/stdlib/asm.tl (op-gcall, op-gapply): New opcodes. (disassemble-c-d): Take the function vector as an argument and dump it too. (usr:disassemble): Extract function vector from VM description and pass it to disassemble-c-d. * share/txr/stdlib/compiler.tl (usr:compile-toplevel): Pass empty function symbol vector to vm-make-desc; it's now a required argument. * vm.c (struct vm_desc): New members funvec and ftab. (struct vm_ftent): New struct type. (vm_make_desc): New argument, funvec. Store funvec in the descriptor. Allocate a table of vm_ftent structures equal in number of elements to the function table, and populate it with resolved bindings. (vm_desc_funvec, vm_desc_destroy): New static functions. (vm_desc_mark): Mark the captured bindings in vd->ftab. (vm_gcall, vm_gapply): New static functions. (vm_execute): Handle GCALL and GAPPLY opcodes. (vm_desc_ops): Wire vm_desc_destroy in place of cobj_destroy_free_op. (vm_init): Add argument to vm-make-desc intrinsic. Register vm-desc-funvec intrinsic. * vm.h (vm_make_desc): Declaration updated. * vmop.h: Regenerated
* compiler: change in output register protocol.Kaz Kylheku2018-03-181-108/+107
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | With this change we get better code, as well fewer situations in which tregs are manually released. There are some subtleties. Previously, a compiled fragment of code would dictate the identity of the location into which it has placed output; then the higher level compile had to work with that location. The new protocol is that the caller specifies a suggested output register to the recursive compile call. If the recursive compile requires a temporary register for the output, it uses the suggested one. If it doesn't require a temporary register, it specifies its own output (for instance a (v x y) entry in the display). The caller has to deal with the output not being in the suggested register. The binding constructs lambda and let also have to deal with the possibility that the body specifies an output which is going out of scope, rather than the suggested register, and in that case must generate a move instruction to transfer from there to the suggested register before the (end ...). * share/txr/stdlib/compiler.tl (sys:env out-of-scope): New method. (compiler compile): Restructured handling of atom forms. Function takes output register argument and passes it down to the special form compile methods. (compiler comp-atom): Bugfix: this must handle nil by returning (t 0) rather than wastefully interning nil into the data table. (quote nil) triggered this. We no longer need to allocate a temporary register in this function; we just use oreg when we need it. (compiler comp-var): Don't alloc temporary, use oreg. (compiler comp-setq): We don't have to free the temporary register from compiling the value expression. When the target is a lexical variable, we pass its location to the sub-compile, so the result is placed in the variable directly. Thus we don't have to generate an additional mov instruction any more, except if that compile wasn't able to use the suggested location. (compiler comp-block): Pass oreg to compile of block bodies. Then use whatever register that block specifies as the block output. (compiler comp-let): Binding of variables is streamlined with oreg in a manner similar to assignment in comp-setq. The body is compiled with the suggested oreg as its output. Because it may put the output in a location that is going out of scope, we have to do the scope check and insert a mov. (compiler comp-lambda): Similar changes as in comp-let. (compiler comp-progn): Just use the incoming oreg as the destination for every form. Use the actual output register of the last frag as the output register, unless there were no frags in which case the nil register is specified as the output. (compiler comp-prog1): Allocate a register for the ignored values of the second and subsequent forms. Use oreg for compiling the first form. (compiler comp-quasi): Take oreg param and pass down. (compiler comp-call): Now allocates a batch of suggested registers for each of the argument compiles, and passes each down to its corresponding argument compile. These registers are freed, and the actual output are used in generating the call. The output of the call goes into oreg; no need to allocate. (compiler comp-for): Mostly the obvious changes here. (usr:compile-toplevel): Here we need to allocate an output register for the top-level call into the compiler.
* compiler: use mac-param-bindKaz Kylheku2018-03-171-15/+15
| | | | | | | | | | | | It's better to use mac-param-bind than tree-bind because it provides diagnostics related to the form being destructured. * share/txr/stdlib/compiler.tl (compiler compile): Pass the whole form rather than (cdr form) to a number of special form handlers. (compiler comp-seq, compiler comp-block, compiler comp-let, compiler comp-lambda, compiler comp-for): Destructure arguments with mac-param-bind.
* compiler: replace invalid compound form message.Kaz Kylheku2018-03-171-1/+1
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): The message will show (car form) followed by a colon, so the wording should refer to that object rather than the entire form.
* compile-toplevel: expand with warnings.Kaz Kylheku2018-03-171-1/+1
| | | | | | | | * eval.c (eval_init): Expose raw expand function as sys:expand*, since sys:expand squelches warnings. * share/txr/stdlib/compiler.tl (usr:compile-toplevel): Use expand* instead of expand.
* compiler: compile string quasiliterals.Kaz Kylheku2018-03-171-0/+84
| | | | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Add sys:quasi case, dispatching new comp-quasi method. (compiler comp-quasi): New method. (expand-quasi-mods, expand-quasi-args, expand-quasi): New functions.
* compiler: closure bug: (dframe ...) without (end ...).Kaz Kylheku2018-03-161-0/+2
| | | | | | * share/txr/stdlib/compiler.tl (compiler comp-lambda): When we have specials we must generate an extra (end ...), to terminate the (dframe ...) that we inserted.
* compiler: fix wrong, undersized frame size in closure.Kaz Kylheku2018-03-161-3/+3
| | | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-lambda): Frame size can't be calculated from nfixed, because that doesn't account for the extra variables in optional parameters. It can't be calculated from the number of lexical variables either, because parameters that are special variables consume vXXYY frame entries without being counted as lexicals. Rather, the accurate frame size is given to us by the value of the counter in the newly created environment.
* Adding compiler.Kaz Kylheku2018-03-161-0/+402
| | | | | | | | | * lisplib.c (compiler_instantiate, compiler_set_entries): New static functions. (lisplib_init): Register auto-load for compiler via new functions. * share/txr/stdlib/compiler.tl: New file.
* asm: add copyright header.Kaz Kylheku2018-03-161-0/+26
| | | | | * share/txr/stdlib/asm.tl: block comment with copyright and BSD license added.
* asm: close opcode checks no of registers.Kaz Kylheku2018-03-151-0/+2
| | | | | | * share/txr/stdlib/asm.tl (op-close asm): Check that the list of registers has the right number of registers indicated by the previous operands.
* asm/vm: add ifq and ifql instructions.Kaz Kylheku2018-03-151-0/+17
| | | | | | | | | | * share/txr/stdlib/asm.tl (op-ifq, op-ifql): New opcode types. * vm.c (vm_ifq, vm_ifql): New static functions. (vm_execute): Handle IFQ and IFQL opcodes. * vmop.h (vm_op_t): Regenerated.
* push can safely use alet rather than rlet.Kaz Kylheku2018-03-141-1/+1
| | | | | | | | | | | push doesn't unconditionally require a temporary location for operational correctness; a temporary is used only for evaluation order. Therefore it is safe to use alet to eliminate the temporary when (after all expansion) the item is a trivial symbolic expression. * share/txr/stdlib/place.tl (push): Use alet to bind the temp which holds the new item.
* asm: block and catch need dest op constraint.Kaz Kylheku2018-03-141-2/+2
| | | | | | | * share/txr/stdlib/asm.tl (op-block, op-catch): Some operands that are destinations need to be parsed as "d", so the assembler diagnoses invalid destinations. Otherwise we don't catch the problem until VM run time.
* asm: wrong labels-outside-of-code test.Kaz Kylheku2018-03-141-1/+1
| | | | | | * share/txr/stdlib/asm.tl (assembler asm): Allow instruction 0 to have a label L labeled by checking for the range 0 <= L < N.
* asm: bugfix: correct value of (v x y) operands.Kaz Kylheku2018-03-141-1/+1
| | | | | | * share/txr/stdlib/asm.tl (parse-compound-operand): Add the forgotten increment by two to the level number of the v operand, since (v 0 n) is in the third display level.
* higher level disassemble function.Kaz Kylheku2018-03-131-2/+18
| | | | | | | | | | | | | | | | * lisplib.c (asm_set_entries): Autoload on usr:disassemble. * share/txr/stdlib/asm.tl (assembler): Drop initializer from bstr slot. Requires complex initialization for the case when the buf is supplied by the constructor caller for the sake of disassembling existing code. (assembler :postinit): Handle cases when only one of buf or bstr are set, and when both are not set, for the greatest flexibility. (disassemble-c-d, disassemble): New functions. * vm.c (vm_desc_datavec): New static function. (vm_init): Registered vm-desc-datavec intrinsic.
* asm: no package qualifiers in textual disassembly.Kaz Kylheku2018-03-131-1/+1
| | | | | | | * share/txr/stdlib/asm.tl (assembler dis-listing): Use tostringp when converting the opcode and arguments to text, so package prefixes won't be shown when the current package isn't sys.
* asm: fix nonworking setv.Kaz Kylheku2018-03-131-2/+3
| | | | | | | * share/txr/stdlib/asm.tl (parse-args): Include the type spec in the diagnostic for invalid type spec. (op-setv): Fix use of invalid type spec s, which should be rs.
* asm: move method definitions outside defstruct.Kaz Kylheku2018-03-131-150/+150
| | | | | | * share/txr/stdlib/asm.tl (assembler): All :method definitions and the :postinit become defmeth forms outside of the defstruct.
* structs: spurious hiding of usr symbol by sys symbol.Kaz Kylheku2018-03-131-3/+3
| | | | | | | | * share/txr/stdlib/struct.tl (sys:defmeth): Rename function to sys:define-method. Otherwise it hides usr:defmethod when the current package is sys. (defmeth): Refer to sys:define-method rather than sys:defmeth.
* asm: allow compound syntax reg operands.Kaz Kylheku2018-03-121-0/+15
| | | | | | | | | | | | In additon to the encoded notation like t13 and v013f, we allow forms like (t 19) and (v 1 63) which mean the same thing. These are a much more convenient representation for a compiler. * share/txr/stdlib/asm.tl (assembler parse-operand): Recognize a compound expression as an operand, and handle via parse-compound-operand function. (parse-compound-operand): New function.
* asm: support gensym labels.Kaz Kylheku2018-03-121-4/+9
| | | | | | | | | | | Remove restriction that labels are keywords; a compiler cannot pollute the keyword space to generate labels. We allow them to be uninterned symbols also. * share/txr/stdlib/asm.tl (assembler parse-args, assembler asm-one): Use is-label instead of keywordp. (is-label): New function. (op-label): Use is-label test.
* vm: introduce sframe instruction.Kaz Kylheku2018-03-121-0/+2
| | | | | | | | | | | | | | | | | | | | This is for allocating a new frame purely on the stack. The frame will not be captured by lexical closures, and so can only be used for non-shared variables and additional compiler-generated temporaries (if registers run out, for instance). * share/txr/stdlib/asm.tl (op-sframe, sframe): New opcode class and opcode. * vm.c (vm_do_frame): New static function for the common implementation of frame and sframe. (vm_frame): Now just a call with vm_do_frame, passing the flag indicating that closure capture is enabled for this environment frame. (vm_sframe): New static function. * vmop.h: Regenerated.
* New: virtual machine with assembler.Kaz Kylheku2018-03-101-0/+564
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit is the start of compiler work to make TXR Lisp execute faster. In six days of part time work, we now have a register-style virtual machine with 32 instructions, handling exceptions, unwind-protect, lexical closures, and global environment access/mutation. We have a complete assembler and disassembler for this machine. The assembler supports labels with forward referencing with backpatching, and features pseudo-ops: for instance the (mov ...) pseudo-instruction chooses one of three kinds of specific move instruction based on the operands. * Makelfile (OBJS): Add vm.o. * eval.c (lookup_sym_lisp1): Static function becomes external; the virtual machine needs to use this to support that style of lookup. * genvmop.txr: New file. This is the generator for the "vmop.h" header. * lib.c (func_vm): New function. (generic_funcall): Handle the FVM function type via new vm_execute_closure function. In the variadic case, we want to avoid the argument copying which we do for the sake of C functions that get their fixed arguments directly, and then just the trailing arguments. Thus the code is restructured a bit in order to switch twice on the function type. (init): Call vm_init. * lib.h (functype_t): New enum member FVM. (struct func): New member in the .f union: vm_desc. (func_vm): Declared. * lisplib.c (set_dlt_entries_impl): New static function, formed from set_dlt_entries. (set_dlt_entries): Reduced to wrapper for set_dlt_entries_impl, passing in the user package. (set_dlt_entries_sys): New static function: like set_dlt_entries but targetting the sys package. (asm_instantiate, asm_set_entries): New static functions. (lisplib_init): Auto-load the sys:assembler class. * share/txr/stdlib/asm.tl: New file. * vm.c, vm.h, vmop.h: New files.
* Version 190.txr-190Kaz Kylheku2018-02-181-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim, protsym.c: Regenerated.
* Copyright year bump 2018.Kaz Kylheku2018-02-1528-28/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * LICENSE, LICENSE-CYG, METALICENSE, Makefile, args.c, args.h, arith.c, arith.h, buf.c, buf.h, cadr.c, cadr.h, combi.c, combi.h, configure, debug.c, debug.h, eval.c, eval.h, ffi.c, ffi.h, filter.c, filter.h, ftw.c, ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h, itypes.c, itypes.h, jmp.S, lib.c, lib.h, lisplib.c, lisplib.h, match.c, match.h, parser.c, parser.h, parser.l, parser.y, protsym.c, rand.c, rand.h, regex.c, regex.h, share/txr/stdlib/awk.tl, share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl, share/txr/stdlib/conv.tl, share/txr/stdlib/doloop.tl, share/txr/stdlib/error.tl, share/txr/stdlib/except.tl, share/txr/stdlib/ffi.tl, share/txr/stdlib/getopts.tl, share/txr/stdlib/getput.tl, share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl, share/txr/stdlib/keyparams.tl, share/txr/stdlib/op.tl, share/txr/stdlib/package.tl, share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl, share/txr/stdlib/pmac.tl, share/txr/stdlib/socket.tl, share/txr/stdlib/stream-wrap.tl, share/txr/stdlib/struct.tl, share/txr/stdlib/tagbody.tl, share/txr/stdlib/termios.tl, share/txr/stdlib/txr-case.tl, share/txr/stdlib/type.tl, share/txr/stdlib/with-resources.tl, share/txr/stdlib/with-stream.tl, share/txr/stdlib/yield.tl, signal.c, signal.h, socket.c, socket.h, stream.c, stream.h, struct.c, struct.h, strudel.c, strudel.h, sysif.c, sysif.h, syslog.c, syslog.h, termios.c, termios.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h, win/cleansvg.txr: Extended Copyright line to 2018.
* bugfix: op module inversely depends on sys:l1-val.Kaz Kylheku2018-02-141-23/+0
| | | | | | | | | | | | | | | | | | | The problem is that the lop macro in op.tl generates code that uses sys:l1-val. That requires the place.tl module. But there is no autoload trigger for sys:l1-val. Even if there were, it wouldn't work because op.tl is lower level w.r.t. place.tl; place.tl uses op.tl. Let's just rewrite sys:l1-val and sys:l1-setq in C, so they live in the run-time core. * eval.c (sys_l1_val_s, sys_l1_setq_s): New symbol variables. (me_l1_val, me_l1_setq): New static functions. (eval_init): Intern sys:l1-setq and sys:l1-val symbols, binding these to the macro expanding functions. * share/txr/stdlib/place.tl (sys:l1-setq, sys:l1-val): Macros removed.
* Version 189.txr-189Kaz Kylheku2018-02-061-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim, protsym.c: Regenerated.
* Version 188.txr-188Kaz Kylheku2017-12-191-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim, protsym.c: Regenerated.
* awk: condense implementation of range-macros.Kaz Kylheku2017-12-151-36/+13
| | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-mac-let): Move repeated boiler-plate code from the various rng macrolets into an the implementation of the sys:rng macro they rely on. That implementation is split into two macros: sys:rng is now the name of a wrapper which adds the boiler-plate, and the bulky implementation macrolet is now called sys:rng-impl.
* New feature: structure delegate streams.Kaz Kylheku2017-12-081-0/+68
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A new kind of stream object which redirects its operations to the methods of a structure. * Makefile (OBJS): New object file, strudel.o. * lib.c (init): Call new strudel_init function. * lisplib.c (stream_wrap_set_entries, stream_wrap_instantiate): New static functions. (lisplib_init): Arrange for autloading of new stream-wrap.tl. * share/txr/stdlib/stream-wrap.tl: New file. * stream.c (put_string_s, put_char_s, put_byte_s, get_line_s, get_char_s, get_byte_s, unget_char_s, unget_byte_s, put_buf_s, fill_buf_s, flush_s, seek_s, truncate_s, get_prop_s, set_prop_s, get_error_s, get_error_str_s, clear_error_s, get_fd_s): New symbol variables. (stream_init): New symbol variables initialized. Numerous functions registered via these variables now rather than intern(...) expressions. * stream.h (put_string_s, put_char_s, put_byte_s, get_line_s, get_char_s, get_byte_s, unget_char_s, unget_byte_s, put_buf_s, fill_buf_s, flush_s, seek_s, truncate_s, get_prop_s, set_prop_s, get_error_s, get_error_str_s, clear_error_s, get_fd_s): Declared. * strudel.c, strudel.h: New files.
* trace: bugfix: spurious "previously traced" warningKaz Kylheku2017-12-081-2/+2
| | | | | | | | | | | | | | When a method is traced with (trace (meth class slot)), a spurious warning occurs. This is because the function is recorded in the trace hash first and then the hook is installed, and the hook is installed using the static-slot-ensure function which performs the trace warning check. * share/txr/stdlib/trace.tl (sys:trace): Swap the order: install the hook first, and then put the the previous function into the trace hash. Doing this in parallel with pset would also work.
* Version 187.txr-187Kaz Kylheku2017-11-171-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim: Regenerated.
* awk: replace set-diff uses with diff.Kaz Kylheku2017-11-011-4/+4
| | | | | * share/txr/stdlib/awk.tl (sys:awk-mac-let): A few occurrences of the deprecated set-diff function are replaced with diff.
* streams: allow "b" flag on open-command.Kaz Kylheku2017-10-301-2/+2
| | | | | | | | | | | | | | | | | | | Currently, using "rb" in open-command reports an error on GNU/Linux, due to popen not liking the "b" mode. On Cygwin, the "b" flag is useful with popen. * stream.c (normalize_mode_no_bin): New function. (open_command): Use normalize_mode_no_bin instead of normalize_mode to strip out the binary flag. This doesn't happen on Cygwin, though. * stream.h (normalize_mode_no_bin): Declared. * share/txr/stdlib/getput.tl (command-get-buf): Since we are getting binary data, pass the "rb" mode to open-command, now that it works. (command-put-buf): Add "b" flag to mode passed to open-command.
* awk: implement ranges right using functions.Kaz Kylheku2017-10-291-53/+111
| | | | | | | | | | | | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk%--rng, sys:awk%--rng-, sys:awk%rng+, sys:awk%-rng+, sys:awk%--rng+): New functions. (sys:awk-mac-let): Rewritten range expander. The four basic ranges rng, rng-, -rng and -rng- are handled with in-line expansion, because by doing that we avoid unnecessarily evaluating the from-expression. The remaining cases expand to function calls to the new functions, which receive the flag vector, the index position in that vector and the values of the from and to expressions. The behavior change is that that the -- forms now do the right thing: they hide all leading records that satisfy the from-expression, right to the last record of the range if necessary. * tests/015/awk-rng.expected: Updated. * txr.1: Revise semantic description the -- range types, plus minor fixes.
* New convenience I/O functions for buffers.Kaz Kylheku2017-10-271-0/+32
| | | | | | | | | | | | | * lisplib.c (getput_set_entries): New autoload entries for file-get-buf, file-put-buf, file-append-buf, command-get-buf and command-put-buf. * share/txr/stdlib/getput.tl (sys:get-buf-common): New function. (file-get-buf, file-put-buf, file-append-buf, command-get-buf, command-put-buf): New functions. * txr.1: Documented.
* awk: fix buggy handling of new -- ranges.Kaz Kylheku2017-10-271-21/+17
| | | | | | | | | | | | The problem is that when records appear in the middle of the range which again match from-expr, they get suppressed. * share/txr/stdlib/awk.tl (sys:awk-mac-let): Get rid of the flag-mid variable. It cannot work because middle is a state in its own right that cannot be inferred from the existing states (nil, t, :end) and the value of from-expr. We get rid of the flag and introduce a :mid state value.
* op/do: nice error if arguments are not provided.Kaz Kylheku2017-10-261-0/+2
| | | | | | | | * share/txr/stdlib/op.tl (sys:op-expand): Throw error if argument list is empty. We refer to the compile-error function by quote to avoid triggering the auto-load of the module which defines it, due to the circular dependency on op.
* awk: bugfix: lack of hygiene in range implementation.Kaz Kylheku2017-10-261-9/+10
| | | | | | | | | | | | | The code is using a non-hygienic variable called flag as a placelet alias. This binding is visible to range expressions. For instance (rng #/x/ flag) actually references the range expression's internal flag, rather than producing a warning about an unbound variable. * share/txr/stdlib/awk.tl (sys:awk-mac-let): Allocate a gensym for the flag. Then use ,flag throughout the code templates rather than flag to insert the gensym wherever the symbol flag previously appeared.
* awk: retrieve range flag vector once per iteration.Kaz Kylheku2017-10-251-4/+6
| | | | | | | | | | | | | | | | | | | | | This is an improvement in the code generation related to awk range expressions. Previously, on each iteration, for each range expression, the awk state structure is accessed to retrieve the flag vector, which is then kept in a lexical variable. With this change, the retrieval is done once for all the range expressions, which share the same variable to access it. * share/txr/stdlib/awk.tl (sys:awk-compile-time): New slot, rng-vec-temp. (sys:awk-mac-let): Alias the flag variable to a simplified vecref expression which accesses the vector assumed to have been retrieved and bound to the variable named by the rng-vec-temp gensym. (awk): Add one more variable binding into the scope of the ranges: the binding of the variable named by the rng-vec-temp gensym, to an expression which retrieves the rng-vec from the Awk run-time state structure.
* awk: five new range operators.Kaz Kylheku2017-10-251-12/+63
| | | | | | | | | | | | * share/txr/stdlib/awk.tl (sys;awk-mac-let): Provide the implementation for the local macros --rng, --rng-, rng+, -rng+ and --rng+. * tests/015/awk-rng.tl: New file. * tests/015/awk-rng.expected: New file. * txr.1: Documented.