| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
| |
* 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*.
|
|
|
|
|
|
|
|
|
|
|
| |
* 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!
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
| |
* share/txr/stdlib/compiler.tl (sys:env lookup-fun): Fix
swapped args in assoc call.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
| |
* share/txr/stdlib/asm.tl: block comment with copyright and
BSD license added.
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
| |
* 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 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.
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
| |
* share/txr/stdlib/asm.tl (assembler asm): Allow
instruction 0 to have a label L labeled by checking for the
range 0 <= L < N.
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
| |
* share/txr/stdlib/asm.tl (assembler): All :method definitions
and the :postinit become defmeth forms outside of the
defstruct.
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim, protsym.c: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim, protsym.c: Regenerated.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim, protsym.c: Regenerated.
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim: Regenerated.
|
|
|
|
|
| |
* share/txr/stdlib/awk.tl (sys:awk-mac-let): A few occurrences
of the deprecated set-diff function are replaced with diff.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|