| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
| |
Reported by user vapnik spaknik.
* lib.c (bracket): Don't rely on the index variable to step
through the arguments, because it only counts fixed arguments.
The args_get function doesn't increment the index beyond
args->fill; when popping arguments from args->list, index
stays unmodified.
* tests/016/arith.tl: Tests for bracket added.
|
|
|
|
|
|
|
| |
* share/txr/stdlib/build.tl (list-buider pend*): Fix typo:
apply should be append. Funny, this didn't propagate to ncon*.
* tests/012/seq.tl: Some list-builder tests via build macro.
|
|
|
|
| |
* tests/016/arith.tl: Add various digits tests.
|
|
|
|
|
|
|
|
| |
Just a few append cases with improper lists here to start with.
* tests/012/seq.tl: New file.
* tests/012/seq.expected: New file
|
|
|
|
|
| |
* Makefile (clean): If it exists, remove the temporary run.sh
that is generated by the install-tests target.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The list building framework underlying the list_collect_decl
macro has a flaw: if the current list ends in an non-nil
terminating atom, and the tail pointer isn't directly aiming
at that atom, then a subsequent operation to add an item or
append a suffix will just overwrite the atom.
The correct behavior is to execute the same logic as if the
tail pointer pointed at that atom on entry into the function:
switch on the type of the atom, and append to it, if possible,
or else throw an error.
Thus, for instance, (append '(1 2 3 . 42) '(4)) wrongly
returns (1 2 3 4), instead of producing an error. The 42
atom has disappeared.
The example (append '(1 2 . "ab") "c") -> (1 2 . "abc")
given in the man page doesn't work; it yields (1 2 . "c").
* lib.c (list_collect, list_collect_nconc,
list_collect_append, list_collect_revappend,
list_collect_nreconc): In the cases when the current tail
object is a CONS and LCONS, and we move the tail, we must
branch backwards and process the tail atom as if the tail had
been that way on entry into the function. Doing this with a
tail call would be nice, but in some of the functions, we hold
a local resource already, so we simulate a local tail call
by updating the tailobj variable and doing a backwards goto.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Rewriting be addition, pending and nconcing methods of
list-builder to avoid loops and rely on lower list processing
functions. This cleans up the semantics and error messages.
Some examples of behavioral changes:
(build (pend "abc") (add #\d)) now returns "abcd",
consistent with (append "abc" '(#\d)).
Previously it returned '(#\d).
(build (add 1) (pend 2) (pend 3)) now produces a "cannot
append to 2" error.
Previously it produced "copy: cannot copy object of type fixnum".
* share/txr/stdlib/build.tl (list-builder add): Don't use
copy-list; rather the idiom for copying a sequence in
preparation for appending to it is (append x nil). This will
blow up nicely if x is an atom other than nil. We use
this trick twice.
(list-builder add*): Simplify with append.
(pend, pend*, ncon): Rewrite.
(ncon*): Use nconc once on a combined argument list: this is
borrowed from the rewritten pend*.
* txr.1: Documentation updated with clarifications,
particularly in the area of the requirements regarding
destructive manipulation and substructure sharing.
|
|
|
|
|
|
|
| |
* arith.c (digcommon): Improved termination test in the second
loop to avoid wasteful pop when the list of powers is empty.
Use rcyc_pop to recycle these conses; they will be immediately
reused for building the output list.
|
|
|
|
|
|
| |
* arith.c (digcommon): Fix off-by-one test causing incorrect
results for radix powers like (digits 10) (digits 100) ...
and analogously in other radices. Reported by vapnik spaknik.
|
|
|
|
|
| |
* arith.c (digcommon): Fix wrong test that allows base 1 to be
admitted, resulting in infinitely looping behavior.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (subtypep): For the sequence supertype, check
whether the subtype is a structure that has a length or
car method, returning t if so.
* struct.c (get_special_slot_by_type): New function.
* struct.h (get_special_slot_by_type): Declared.
* txr.1: Add <structures with cars or length methods> to the
type hierarchy diagram.
|
|
|
|
|
|
| |
* lib.c (seq_info): Add missing else, which makes the function
return nil for objects that have a length method, but not a
car method.
|
|
|
|
|
|
| |
* lib.c (subtypep): The sub and sup parameters are compared
for equality early in the function; byt the time we get
here, we know they are not eq, so nil can be returned.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_flex_struct_in): Use get_special_slot to obtain
length method.
* lib.c (nullify_s, from_list_s, lambda_set_s): Definitions
removed from here.
(seq_info, car, cdr, rplaca, rplacd, make_like, nullify,
replace_obj, length, empty, sub, ref, refset, dwim_set): Use
get_special_slot to obtain special method from object,
rather than maybe_slot.
(obj_init): Remove initializations of nullify_s, from_list_s
and lambda_set_s from here.
* struct.c (enum special_slot): Definition removed from here.
(nullify_s, from_list_s, lambda_set_s): Definitions moved here
from lib.c.
(special_sym): New static array.
(struct_init): Initializations of nullify_s, from_list_s
and lambda_set_s moved here from lib.c.
(get_special_slot): New function.
* struct.h (lambda_set_s): Declared.
(enum special_slot): Definition moved here.
(get_special_slot): Declared.
* txr.1: Added compat note, since get_special_slot behaves
like maybe_slot under 224 compatibility.
|
|
|
|
|
|
| |
* struct.c (get_equal_method): Static function removed.
(struct_inst_equalsub): Replace one and only call to
get_equal_method with direct call to get_special_static_slot.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A type which we never ask for a special slot need not
waste space the array.
* struct.c (struct struct_type): Change spslot from array to
pointer.
(make_struct_type): Initialize spslot pointer to zero.
(struct_type_destroy): Free the dynamic array.
(invalidate_special_slot_nonexistence): Do nothing if the
spslot pointer is null.
(get_special_static_slot): Dynamically allocate the array
if the spslot pointer is null, and update that pointer,
before doing anything else. The parameter signature changes;
instead of a pointer to an element of the stslot array, we
pass the index.
(get_equal_method): Pass the index of the equal method special
slot, rather than the address of the array entry.
|
|
|
|
|
|
| |
* lib.c (seq_info): Due to a copy-paste error maybe_slot is
being accidentally called here twice for the same slot.
Removing.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This lays the groundwork for optimizing access to more special
slots. Currently the equal method is handled specially; if a
type has an equal method, then this is cached for fast access,
so we are not doing a slot lookup each time the method needs
to be called. We would like a small array of such methods,
with minimal code duplication.
* struct.c (enum special_slot): New enum.
(struct struct_type): Scalar member eqmslot replaced by
spslot array.
(make_struct_type): Initialize elements of new array to null;
don't initialize removed eqmslot member.
(invalidate_special_slot_nonexistence): New static function.
(static_slot_set, static_slot_ens_rec): Use
invalidate_special_slot_nonexistence instead of open code.
(get_static_special_slot): General function for obtaining and
caching a special slot. Based on implementation of
get_equal_method.
(get_equal_method): Rewritten as a simple call to
get_special-static_slot.
|
|
|
|
|
|
|
|
|
|
| |
Only struct.c refers to this symbol, and so only struct.c
needs to be recompiled when someone experiments with different
values.
* lib.h (SLOT_CACHE_SIZE): Macro deleted here.
* struct.c (SLOT_CACHE_SIZE): Macro moved here.
|
|
|
|
|
|
|
| |
Omissions reported by user vapnik spaknik.
* lib.c (subtypepe): The lcons type and string type must
report as subtypes of sequence.
|
|
|
|
|
|
|
| |
* share/txr/stdlib/build.tl (list-buider add,
list-builder add*, list-builder pend, list-builder pend*):
Use copy-list rather than copy. This copies terminating
atoms without complaining.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The list builder is failing on the documented example
(build
(add 1 2)
(pend (get))
(pend (get)))
-> (1 2 1 2 1 2 1 2)
wrongly constructing an infinite list.
* share/txr/stdlib/build.tl (list-builder pend): When
destructively appending the next argument, check whether
the current tail is a tail of that object. If so, copy
the object to prevent a cycle from forming.
(list-builder pend*): When appending the old head to the
catenated list, do the tail check and copy the object if
necessary to prevent the creation of a cycle.
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register tailp intrinsic.
* lib.c (tailp): New function.
* lib.h (tailp): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a slot is not found in a cache, and in other situations
the object system conses up a key in order to search a the
global slot_hash. We should be recycling these keys
for reuse via rcyc_cons. This change makes recompilation of
TXR's library (make clean-tlo; make) about 1.6% faster.
* struct.c (lookup_slot, lookup_static_slot_desc, static_slot_p):
Recycle the hash key cons cell via rcyc_cons, so it can be
reused immediately.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
TXR user vapnik spaknik has found a swath of errors in the
documentation.
* txr.1: Fixed bugs in numerous examples, copy-and-paste
errors in syntax sections, and other typos, including *stdin*
mistyped as *std-input* in many places. A new executable code
example is provided for expand-with-free-refs to calculate the
result that was previously only verbally described. Fixed
*stdin* mistyped as *std-input* (a non-existent symbol that
imitates the internal C variable).
|
|
|
|
| |
* txr.1: Hyphenate "heap-allocated" and "stack-allocated".
|
|
|
|
|
|
|
| |
* eval.c (bindings_helper): If there are no bindings or just
one binding, then go through the sequential case. Thus trivial
let is treated like let*. This avoids the continuation-related
overheads incurred in the parallel case.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This was discovered by user vapnik spaknik. If a let* form is
evaluated in a top-level expression such that the incoming
environment is null, and a continuation is captured in the
init-form of the first variable, when that continuation is
invoked, an exception is thrown: "copy-env: nil is not of type
env".
Short repro:
1> (block nil (let* ((x (yield 42)))))
** copy-env: nil is not of type env
In fact, the bug isn't that we're trying to copy nil.
the problem is we are trying to copy an environment we should
not be copying at all. In fact, for sequential binding,
there is no need for that logic at all; it's only parallel
binding which needs it, because all of the init-forms are
inserting bindings into the same environment.
* eval.c (bindings_helper): Don't bother with registering a
copy handler for sequential binding logic, because we
don't mutate environments. All of that code is moved into the
parallel case.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/compiler.tl (expand-bind-mac-params):
Remove the plen gensym. We don't need to store the form length
in a variable, because the generated length check code
references the value exactly once. Let's just propagate that
the length calculating expression into that code.
|
|
|
|
|
|
|
|
|
| |
* chksum.c (sha256_utf8_byte_callback, md5_utf8_byte_callback):
New static functions.
(sha256_hash, md5_hash): Support character and integer
objects.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Virtual machine local variables registers don't require
nil initialization. In cases when a complex variable
initializer is known to return nil, we can elide the move
instrution which moves that nil into the register.
* share/txr/stdlib/compiler.tl (null-reg): New function.
(compiler comp-let): Don't move the value of the output
register of the init fragment into the variable, if that
register is the null register t0.
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/compiler.tl (expand-bind-mac-params):
Generate better Lisp code when presence indicating variables
on optional parameters are not used. It's possible to bind the
variable directly, instead of binding to nil and assigning it.
The cases are split accordingly.
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/compiler.tl (expand-bind-mac-params):
Allocate the curs gensym only when about to recurse over a
nested parameter list, rather than unconditionally. Otherwise,
we always end up allocating one more gensym than we actually
use, for a lower nesting level that might not be there.
Don't use unwind-protect for returning the cursor variable to
the free-list; it makes no sense to be recovering that since
any exception will be abandoning this function entirely.
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a method which is traced is redefined, a warning message
is correctly issued and the trace is removed. But the removal
is done in the wrong order and ends up restoring the old
function, clobbering the new definition.
* struct.c (static_slot_ensure): Move the trace_check before
the call to static_slot_ens_rec, so installation of the new
method takes place after the trace is removed from the old
one.
|
|
|
|
|
|
|
| |
* share/txr/stdlib/trace.tl (sys:trace-redefine-check): Move
the sys:untrace call before the warning throw. That throw
doesn't return; it ends up transferring control to the
continue catch, and so the untrace is skipped.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The destructuring binder binds all of the variables in the
template to nil values and then assigns to them as it walks
the object that is being destructured. Unfortunately, this
results in incorrect treatment of init-forms, which are
evaluated in the wrong scope. They are actually evaluated in
completely the wrong scope due to the use of up:env, but the
problem can't be fixed by removing up:env.
The approach here is to generate a big let* construct that
binds the variables in sequence, rather than assigning to
them.
* share/txr/stdlib/compiler.tl (expand-bind-mac-params):
The basic structure of the code remains the same, but the
details are rewritten. Instead of emitting a body of forms, we
emit let* bindings. Because some of the logic requires
imperative statements, like stepping pointers through the
destructured object, these are mixed into the variable
initializations via progn. The local functions emit-stmt and
emit-var provide the interface for doing this. There is a bit
of trickery in the situation that an optional parameter also
has the presence-indicator variable. We must bind the
parameter in an environment in which that presence-indicator
variable is not yet visible. This is achieved by binding the
variable to a nil value, and then binding the presence
indicator to an expression which sets the variable's value as
a side effect, and yields a Boolean value that initializes the
indicator.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When the (set arg :) form is processed by a compiled version
of the set operator, it blows up with "set: arguments must be
pairs". This is because the compiled destructuring code is
wrongly trying to apply special treatment to a colon symbol
argument to an optional parameter. It is documented that such
such treatment only happens in function calls, and not in the
binding of macro parameter lists. Interpreted macro param
binding gets it right.
* share/txr/stdlib/compiler.tl (expand-bind-mac-params): Do
not treat a : element in the structure as a missing optional
argument, but as an ordinary value.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Exception info stashed into the unhandled_ex global
pseudo-frame is not protected from gc reclamation. This
allows for use-after-free errors, that can reproduce if
unwind-protect cleanup forms that go off during the processing
of an unhandled exception trigger gc. The code which deals
with unhandled exception, like error_trace, then works with
exception arguments that are now objects on the free list.
* unwind.c (uw_init): GC-protect the exception sym and
arguments stored in unhandled_ex.
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/compiler.tl (expand-bind-mac-params):
A nested destructuring error must be reported against the
local parameter list, not the top-level one. The
bind-mac-check call muts use the local par-syntax, not
the original top-level params.
|
|
|
|
|
|
|
|
|
|
|
| |
An infinite for loop in which the test is explicitly given as nil
rather than omitted fails to compile. A minimal repro test
case for this is (compile-toplevel '(for () (nil) ()))).
Spotted this while reading the compiler code.
* share/txr/stdlib/compiler.tl (compiler comp-for): Test the
test-p variable, not test, to determine whether or not to
generate the loop skip label.
|
|
|
|
|
|
|
|
|
|
| |
* configure: New test for crypt_r, depositing HAVE_CRYPT_R
preprocessor symbol in config.h.
* sysif.c: Conditionally include <crypt.h> header.
(crypt_wrap): Use crypt_r if HAVE_CRYPT_R is nonzero.
(sysif_init): Register crypt intrinsic if we HAVE_CRYPT or if
we HAVE_CRYPT_R.
|
|
|
|
|
|
| |
* Makefile (TXR_CFLAGS): Use := operator rather than += when
filtering out REMOVE_FLAGS, or else REMOVE_FLAGS are not
really removed, and we duplicate all the flags.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* chksum.c (sha256_szmax_upd, md5_szmax_upd): New static
functions, consisting of logic from sha256_buf and
md5_buf, respectively.
(sha256_buf, md5_buf): Use sha256_szmax_up and md5_szmax_upd,
respectively, to handle the unlikely possiblity of the ucnum
buffer length being larger than the range of size_t.
(sha256_hash, md5_hash): Also use the new static functions
instead of callig SHA256_update or MD5_update directly
to deal with the same issue.
|
|
|
|
|
|
| |
* chksum.c (sha256_str, md5_str): Don't construct a byte input
stream for hashing a string. Just convert whole thing to
temporary UTF-8, hash, and free.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* chksum.c (sha256_ctx_s, md5_ctx_s): New symbol variables.
(sha256_ops, md5_ops): New static structs.
(sha256_begin, sha256_hash, sha256_end, md5_begin, md5_hash,
md5_end): New functions.
(chksum_init): New symbol variables initialized; sha256-begin,
sha256-hash, sha256-end, md5-begin, md5-hash, md5-end
intrinsics registered.
* chksum.h (sha256_begin, sha256_hash, sha256_end, md5_begin,
md5_hash, md5_end): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
| |
* LICENSE: Mention MD5 component.
* METALICENSE: There are more libraries than linenoise; remove
focus on linenoise and make wording generic. Add description
of the RSA situation, whereby more permissive redistribution
terms were granted by the Feb 23, 2000 memo.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Makefile (OBJS): New object file, chksums/md5.o.
* chksum.c (sha256_ensure_buf): Renamed to chksum_ensure_buf
and made generic so MD5 code can borrow it.
(sha256_stream, sha256): Call chksum_ensure_buf instead of
sha256_ensure_buf, passing in new length and hash name
parameters.
(md5_stream_impl, md5_buf, md5_str): New static functions.
(md5_stream, md5): New functions.
(chksum_init): Register md5-stream and md5 intrinsics.
* chksum.h (md5_stream, md5): Declared.
* chksums/md5.c, chksums/md5.h: New files.
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register cptr-buf intrinsic.
* lib.c (cptr_buf): New function.
* lib.h (cptr_buf): Declared.
* txr.1: Documented.
|
|
|
|
|
|
| |
* txr.1: Include blurb about the independent lifetime of a
ctpr made by cptr-obj and the original object.
If the original is garbage collected, the ctpr is junk.
|