| 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
|
|
|
|
|
|
|
|
|
|
|
| |
This test will misbehave on TXR without the previous fix;
it will not collect columns of data which keep the
corresponding rows items together.
* tests/002/variant, tests/002/variant.expected,
tests/002/variant.txr: New files.
* Makefile (TXR_ARGS, TXR_OPTS): Override for new test.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* tests/001/query-5.txr: New file.
* tests/001/query-5.expected: New file.
* Makefile (tst/tests/001/query-5.ok): Pass -B to txr for this
new test.
* tests/017/glob-carray.expected: Updated, because the glob
test globs over the contents of tests/001 directory.
* tests/017/glob-zarray.expected: Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Users of defset no longer have to ensure that in the store
form, the symbol which gives the new value to be stored is
inserted only once.
* share/txr/stdlib/defset.tl (defset-expander): Transform the
store form by inserting a temporary variable using alet.
(sub-list, sub-vec, sub-str): These place forms no longer
require a local gensym.
* txr.1: Updated doc.
* tests/012/defset.tl: The expected output for the inc case
now incorporates a gensym that comes from the compiled
defset macro. Since we can't control that by means of the
gensym counter, we resort to extracting it from the expansion
itself, then check the test case against a template which
incorporates that gensym. We check that the extracted item
really is a gensym: it's a symbol with no home package whose
name starts with "g".
|
|
|
|
|
|
| |
* tests/012/defset.tl: New file.
* tests/012/defset.expected: New file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* arith.c (r_ceil_s, r_round_s): New symbol variables.
(ceildiv, roundiv): Route binary cases involving struts
directly to binary methods so the object is responsible for
the complete implementation.
(arith_init): Initialize r_ceil_s and r_round_s.
* tests/016/ud-arith.tl (numbase): Binary methods added for
ceil and round. Test cases added.
* txr.1: Descriptions for binary ceil and round methods added;
Notes about non-existence of binary methods removed from unary
ceil and round removed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* tests/016/ud-arith.expected b/tests/016/ud-arith.tl:
New file.
* tests/016/ud-arith.expected b/tests/016/ud-arith.expected:
New file.
* arith.c (divi): Bugfix: wrong argument tested for being
a COBJ.
(logtrunc): Fix incorrect method call: calling r-logtrunc-s
for the object-in-left-position case.
(sign_extend): Fix semantics not following documentation:
dispatch method with original arguments.
(divv): When there is just one argument, take advantage of the
hitherto unused unary case of divi rather than giving it both
arguments. The object dispatch is in that unary case, so we
need it now.
(arith_init): Fix wrong name of r_lognot_s symbol.
* txr.1: Fix atan2 being documented as atan.
Fix misspelling of r-lognot as lognot-r.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The functions sys:expand, sys:expand* and
sys:expand-with-free-refs are now in the usr package and
documented for public use.
* eval.c (eval_init): Move registrations of the symbools
expand, expand* and expand-with-free-refs from the
system package to the user package.
* share/txr/stdlib/awk.tl (sys:awk-mac-let, awk): Uses of
sys:expand drop the sys: prefix.
* share/txr/stdlib/op.tl (sys:op-alpha-rename): Likewise.
* share/txr/stdlib/place.tl (call-upudate-expander,
call-clobber-expander, call-delete-expander, sys:placelet-1):
Likewise.
* tests/011/macros-2.txr, tests/012/struct.tl: Likewise.
* txr.1: Documented expand, expand* and expand-with-free-refs.
|
|
|
|
|
|
| |
* tests/012/man-or-boy.tl (defun-cbn): We no longer need the
macro-time expression here to force the evaluation of the
defmacro form.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Hashing of buffers and character strings is being replaced
with a seedable hash, providing a tool against denial of
service attacks against hash tables.
This commit lays most of the groundwork: most of the internal
interface changes, and a new hashing implementation. What is
missing is the mechanisms to do the seeding.
* hash.c (struct hash_ops): Hash operation now takes a seed
argument of type ucnum.
(struct hash): New member, seed.
(hash_str_limit): Default value changed to INT_MAX.
A short value opens the gateway to an obvious collision attack
whereby strings sharing the same 128 character prefix are
entered into the same hash table, which will defeat any
seedings strategy.
(randbox): New static array. Values come from the Kazlib hash
module, but are not used in exactly the same way.
(hash_c_str, hash_buf): Now take a seed argument, and are
rewritten.
(equal_hash): Takes a seed, and passes it to hash_c_str,
hash_buf and to recursive self calls.
(eql_hash_op): New static function. Adapts the eql_hash
operation, which doesn't take a seed, to the new interface
that calls for a seed.
(obj_eq_hash_op): Take a seed; ignore it.
(hash_hash_op): Take a seed, pass it down to equal_hash.
(hash_eql_ops): Wire hash functiono pointer to eql_hash_op
instead of eql_hash.
(make_hash): For now, intialize the hash's seed to zero.
(make_similar_hash): Copy original hash's seed.
(gethash_c, gethash_e, remhash): Pass hash table's seed to
the hashing function.
(hash_equal): Pass a seed of zero to equal_hash for now;
this function will soon acquire an optional parameter for the
seed.
* hash.h (equal_hash): Declaration updated.
* lib.c (cobj_handle_hash_op): Take seed argument, pass down.
* lib.h (cobj_ops): Hash operation now takes seed.
(cobj_eq_hash_op, cobj_handle_hash_op): Declarations updated.
* struct.c (struct_inst_hash): Take seed argument, pass down.
* tests/009/json.expected: Updated, because the hash table
included in this output is now printed in a different order.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There is an issue with the printer in that it produces
output whereby objects continue on the same line after
a multi-line object, e.g:
(foo (foobly bar
xyzzy quux) (oops same
line))
rather than:
(foo (foobly bar
xyzzy quux)
(oops same line))
There is a simple fix for this: set a flag to force
a line break on the next width-check operation whenever
an object has been broken into multiple lines.
width-check can return a Boolean indication whether
it generated a line break, and so aggregate object
printing routines can tell whether their object
has been broken into lines, and set the flag.
* stream.h (struct strm_base): New member, force_break.
(force_break): Declared.
* stream.c (strm_base_init): Extent initializer to cover
force_break flag.
(put_string, put_char): Clear the force_break flag whenever
we hit column zero.
(width_check): If indent mode is on, and force_break is
true, generate a break. Clear force_break.
(force_break): New function.
(stream_init): Register force-break intrinsic.
* buf.c (buf_print): Set the force break flag if the buffer
was broken into multiple lines.
* hash.c (hash_print_op): Set the force break flag if the
hash was broken into multiple lines.
* lib.c (obj_print_impl): Same logic for lists.
* struct.c (struct_inst_print): Same logic for structs.
* tests/009/json.expected, tests/011/macros-2.expected,
tests/012/struct.tl, tests/017/glob-zarray.expected:
Update expected textual output to reflect new formatting.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (do_expand): When a defmacro or defsymacro form is
traversed, do not evaluate it, except in backward
compatibility mode. Unfortunately, this breaks some code.
* tests/011/macros-1.txr: A defmacro form has to be wrapped in
macro-time.
* tests/011/macros-2.txr: Likewise.
* tests/011/mandel.txr: Likewise.
* tests/012/man-or-boy.tl (defun-cbn): This macro generates a
progn which which expects that a defmacro form will come into
effect for the subsequent lambda in the same form. We must
wrap it in macro-time to make this happen now.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (replace_obj): New static function.
(sub): Handle struct case via lambda method.
(replace): Handle struct case via replace_obj.
* txr.1: Documented.
* tests/012/aseq.tl (add): The lambda method now has to handle
a range argument. One test case uses the last function, which
for non-lists relies on sub, which now calls the lambda method
if the object has one.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
TXR 188 makes a slight mess of the #H notation. An :eql-based
hash table prints as #H(() ...), but when that notation is
read, it produces an :equal-based hash table. No aspect of
this situation was intended; the intent was that the notation
stays the same as before, and just the hash function changes
to make :equal-based the default. Let's just go with this
and have #H(() ...) denote :equal-based tables.
* hash.c (hash_print_op): Print an :eql-based for eql-based
hash tables, and nothing for equal-based ones. In
compatibility mode with 188 and older, reproduce the old
behavior, rendering equal-based tables with :equal-based and
the absence of a symbol for eql-based.
* txr.1: Updated places that touch on :equal-based and
added compatibility notes.
* tests/009/json.expected: updated, since equal-based hash
tables now print without :equal-based keyword.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch implements a new requirement which clarifies what
happens when a macro declines to expand a form.
To decline expanding a form means to return the original form
(same object) without returning it. The expander detects this
situation with an eq comparison on the input and output.
The current behavior is that no further attempts are made to
expand the form. This is problematic for various reasons. In
code which is expanded more than once, this can lead to the
expansion being different between the expansion passes. In
the first pass, a local macro M might decline to expand a
form. In the second pass, the local macro definition no longer
exists, and the form does get expanded by a global macro M.
This kind of instability introduces a flaw into complex macros
which expand their argument material more than once.
The new requirement is that if a macro definition declines to
expand a macro, then a search takes place through the outer
lexical scopes, and global scope, for the innermost macro
definition which will expand the form. The search tries every
macro in turn, stopping if a macro is found which doesn't
decline the expansion, or after passing the global scope.
* eval.c (expand_macro): Implement new searching behavior.
* txr.1: Documented the expansion declining mechanism
under defmacro and macrolet.
* tests/011/macros-3.tl: New file.
* tests/011/macros-3.expected: New file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
| |
* tests/015/awk-rng.tl: More rows of data.
* tests/015/awk-rng.expected: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
| |
The tests fail as of this commit.
* tests/012/quine.expected: New file.
* tests/012/quine.tl: New file.
|
|
|
|
|
|
| |
* tests/012/stslot.expected: New file.
* tests/012/stslot.tl: New file. b/tests/012/stslot.tl
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (ref, refset): Check for lambda and lambda-set,
respectively, and use it.
* txr.1: Documented.
* tests/012/aseq.tl (add lambda): Fix previously unused
broken method which now causes test to go into infinite
recursion.
|
|
|
|
|
|
|
|
|
| |
* tests/017/glob-carray.tl (glob-t): Restructure
to case statement. Add padding to struct based on
looking at the glibc definition. Add FFI definition
based on Cygwin header.
* tests/017/glob-zarray.tl (glob-t): Likewise.
|
|
|
|
|
|
|
|
|
| |
* tests/017/glob-carray.tl (glob-t): Initialize reserve
member to 0. Since it doesn't exist on Darwin, it will
stay nil, and change the the test output. A Darwin variant
of the corresponding FFI type is provided.
* tests/017/glob-zarray.tl (glob-t): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The realpath function is called using FFI. One approach
passes a null pointer, so that the function dynamically
allocates. The return value is str-d, causing FFI to take
ownership of the pointer, freeing it. The other approach
is to pass a pointer to a large null-terminated character
array, marked for ownership transfer to the function. FFI
allocates it and puts the argument into it, which is just
a dummy empty string. The function fills that buffer and
returns it. The return is captured as a str-d, so FFI takes
ownership back, and frees the buffer.
* tests/017/realpath.tl: New function.
* tests/017/realpath.expected: Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
One approach captures the paths as a carray of
strings, and explicitly frees it with globfree.
The other approach uses a zarray, taking advantage
of null termination. globfree is elided because TXR FFI
does the freeing; the types used declare to it that it
is taking ownership of a dynamically allocated vector of
dynamically allocated strings, and so it performs the
equivalent of globfree.
* tests/017/glob-carray.expected: New file.
* tests/017/glob-carray.tl: Likewise.
* tests/017/glob-zarray.expected: Likewise.
* tests/017/glob-zarray.tl: Likewise.
|
|
|
|
|
|
|
|
|
|
|
| |
* tests/017/qsort.expected: New file.
* tests/017/qsort.tl: New file.
* tests/common.tl (libc): New function.
* Makefile (tst/tests/017/%): Clear TXR_DBG_OPTS so the GC
stress test isn't applied to tests in this directory.
|
|
|
|
|
|
|
|
|
|
| |
* tests/common.tl (osname): Function based on calling
shell command removed.
(os-symbol): New symbol-returning function based on
uname system call.
* tests/014/dgram-stream.tl (dgram-test): Use os-symbol
function rather than osname.
|
|
|
|
|
|
| |
* tests/012/fini.tl: New file.
* tests/012/fini.expected: New file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (op_catch): The sys:catch operator now passes the
exception symbol as the first argument of each clause.
This means the catch macro must be adjusted.
* share/txr/stdlib/except.tl (catch): Macro now inserts
a gensym dummy first argument into each clause to take the
symbol passed by the sys:catch operator.
(catch*): New macro, which is identical to the previous
catch macro, and thus exposes the symbol passed as the
first argument.
* txr.1: Documented catch*.
* tests/012/struct.tl: Some gensym numbers need adjusting
in one test case.
|
|
|
|
|
|
|
|
|
| |
* tests/008/filtenv.txr (f): Don't just copy the input
to the output but transform it by upcase-str. Otherwise
the test will pass even if the :filter syntax is not
processed at all!
* tests/08/filtenv.expected: Updated.
|
|
|
|
| |
* tests/012/quasi.tl: New tests added.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In the parallel binding (let ((x s) (s 0) (y s)) ...),
both x and y must bind to the prior value of s,
not to the new value 0. We have the bug that if
s is a special variable, the initialization of y
sees the new dynamic environment which contains the
new value, so x gets the previous, y gets new.
This commit fixes it.
* eval.c (reparent_env): New static function.
(bindings_helper): Separate logic into two loops,
for sequential and parallel binding, so we don't
have to repeatedly test this condition in the loop
body, and can think separately about each case and
streamline it. Nothing new happens under sequential
binding; the behavior that is wrong for parallel
binding is right for sequential. Under parallel binding,
what we do is reset the dynamic environment to the
original one prior to each evaluation of an initform.
Then if the evaluation changes to a new dynamic
environment (a special variable is being bound),
we notice this and hook the new environment into
a local stack, changing it parent pointer. At the
end, we install this stack as the new dynamic env.
Thus each init form is evaluated in the original
dynamic env.
* tests/011/special-1.tl: New tests added.
|
|
|
|
|
| |
* tests/011/special-1.tl (with-output-to-string): macro
removed; with-out-string-stream used.
|
|
|
|
|
| |
* tests/011/special-1.txr: Renamed to
tests/011/special-1.tl and @(do ...) removed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
NOTE: The socket test cases do not pass under this commit:
this is expected.
The for and each family of operators will now be macros which
expand to let/let* binding construct wrapping a lower level
special operator.
This is in preparation for a change to how special variable
binding is implemented.
This change reduces the number of special forms which bind
variables.
There is a single low-level operator for for loops called
sys:for-op. Its syntax is a lot like the C89 for loop:
(sys:for-op init-forms test step-forms body). The init-forms
do not bind anything; it is just forms.
There is a sys:each operator for implementing each,
each*, append-each and all those operators. Its syntax is
(sys:each-op type-sym optional-vars . body).
The type-sym is one of each, append-each or collect-each.
If optional-vars is nil, then the operator looks at the
immediate lexical environment, and assumes all the bindings
there are the each iteration variables and it works with
those bindings, like its predecessor did. Otherwise
optional-vars is a list of symbols: the operator walks the
list and resolves each element to a binding. This is
used in two situations: when some of the variables are
special (dynamically scoped) or when the variables are
bound sequentially with let* and are thus scattered in
multiple levels of environment.
* eval.c (for_op_s, each_op_s): New symbol variables.
(get_bindings): New static function.
(op_each): Now implements sys:each-op.
(op_for): Now implements sys:for-op.
(get_var_syms): New static function.
(me_each, me_for): New static functions.
(do_expand): Do not expand the each operator family under the
same rule. New case handling sys:each-op is introduced
due to the different syntax.
The for case restructured to handle for_op_s.
(eval_init): Intern sys:each-op and sys:for-op symbols.
Register the corresponding operators. Move registrations of
the public symbols each, each*, for, for* and all the other
each variants to be macros.
* tests/011/macros-2.expected: Updated with different
macro expansion which is now produced for a while
loop.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Contrary to the documentation, handle doesn't in fact have the
same syntax as catch. It passes the exception symbol to
clauses as the leftmost argument, followed by the exception
arguments, whereas catch passes only the exception arguments.
* share/txr/stdlib/except.tl (handle): Do not pass the
exception sybmol as the leftmost argument, unless operating
in TXR 161 or earlier compatibility.
* tests/012/except.tl: drop exception symbol argument from
handle clause.
* txr.1: Compatibility note added.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_exception): New static function.
(eval_error): Reduced to wrapper around eval_exception.
(eval_warn): New function.
(me_op): Bind the rest symbol in a shadowing env to suppress
watnings about unbound rest.
(do_expand): Throw a warning when a bindable symbol is
traversed that has no binding.
(expand): Don't install atoms as last_form_expanded.
* lib.c (warning_s, restart_s, continue_s): New symbol
variables.
(obj_init): Initialize new symbol variables.
* lib.h (warning_s, restart_s, continue_s): Declared.
* lisplib.c (except_set_entries): New entries for
ignwarn and macro-time-ignwarn.
* parser.c (repl_warning): New static function.
(repl): Use repl_warning function as a handler for
warning exceptions: to print their message and then
continue by throwing a continue exception.
* parser.y (warning_continue): New static function.
(parse_once): Use warning_continue to ignore warnings.
In other words, we suppress warnings from Lisp that is
mixed into TXR pattern language code, because this
produces too many false positives.
* share/txr/stdlib/except.tl (ignwarn, macro-time-ignwarn):
New macros.
* share/txr/stdlib/place.tl (call-update-expander,
call-clobber-expander, call-delete-expander): Ignore warnings
around calls to sys:expand, because of some gensym-related
false positives (we expand code into which we inserted some
gensyms, without having inserted the constructs which
bind them.
* tests/011/macros-2.txr: Suppress unbound variable
warnings from a test case.
* tests/012/ifa.tl: Bind unbound x y variables in one
test case.
* tests/012/struct.tl: Suppress unbound variable
warnings in some test cases.
* uwind.c (uw_throw): If a warning is unhandled, then
print its message with a "warning" prefix and then
throw a continue exception.
(uw_register_subtype): Eliminate the check for sub
already being a subtype of sup. This allows us to
officially register new types against t.
(uw_late_init): Register continue exception type as a
subtype of the restart type.
Formally register warning type.
* txr.1: Documented ignwarn.
|
|
|
|
|
|
|
|
|
| |
* Makefile (TXR_DBG_OPTS): Suppress for new directory
tests/016.
* tests/016/arith.tl: New file.
* tests/016/arith.expected: New file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (caseq_star_s, caseql_star_s, casequal_star_s):
New symbol variables.
(me_case): Implement new macro semantics.
(eval_init): Initialize new symbol variables, and
register the symbols to the me_case macro expander.
* tests/sock-common.tl (local-addr): This function
depends on the old broken caseql semantics which
evaluate keys. Using caseql* makes it work again.
* txr.1: Document case{q,ql,qual}* macros.
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Do not register *user-package*,
or *system-package* or *keyword-package* variables
unless in compatibility mode. We don't document this
in the compatibility notes since the variables are not
documented.
* tests/009/json.txr: Change use of *keyword-package*
to keyword-package.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Two issues addressed here, both occurring when *print-circle*
is enabled and an object has struct components which have a
custom print method that re-enters the object printer.
One issue is that the children of these components which occur
just once print with spurious labels: like #3=, when no
matching #3# occurs. The other bug is a wrong "unexpected
duplicate object" exception caused by mismanagement of the
child object's label hash table and its merging with the parent.
* stream.h (struct stream_ctx): New member, obj_hash_prev.
Makes the parent hash table known to populate_obj_hash,
if there is a table, otherwise nil.
* lib.c (populate_obj_hash): If there is a parent table, check
each object in it. If it occurs, then bail. I.e. don't add
objects to the child table which occur in the parent. This
fixes both issues. Also, we do the unexpected duplicate object
check right here now: if we traverse an object that already
printed without a label (because it is not known to be
duplicate), that means that a custom print method is
inappropriately introducing new references to existing
objects, contrary to the rules. (obj_hash_merge): The logic
here is now simplified. All entries in the child table are
simply moved to the parent. If anything already exists, that
is an unexpected stuation indicating an internal problem,
turned into a variant of the unexpected duplicate object
message.
* tests/012/circ.tl: New file, giving tests for the bugs.
* tests/012/circ.expected: New file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The problem is that when the regular expression
is capable of matching empty strings, tok-str
will extract an empty token immediately following
a non-empty token. For instance (tok-str "a,b" /[^,]*/)
extracts ("a" "" "b") instead of just ("a" "b").
This is a poor behavior and the way to fix it is to
impose a rule that an empty token must not be extracted
immediately at the ending position of a previous token.
Only a non-empty token can be consecutive to a token.
* lib.c (tok_str): Rewrite the logic of the loop,
using the prev_empty flag to suppress empty tokens
which immediately follow non-empty tokens. The
addition of 1 to the position when the token is empty
to skip a character is done at the bottom of the loop
and a new last_end variable keeps track of the end position
of the last extracted token for the purposes of extracting
the keep-between area if keep_sep is true. The old loop
is preserved intact and enabled by compatibility.
* tests/015/split.tl: Multiple empty-regex test cases for
tok-str updated.
* txr.1: Updated tok-str documentation and also added
a note between the conditions under which split-str and
tok-str, invoked with keep-sep true, produce equivalent
output. Added compatibility notes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Turns out that there is missing support for quasiquoting
over structs. Code analogous to the way vector and hash
literals are handled is missing for structs.
* eval.c (expand_qquote_rec): Handle struct_lit_s forms
specially, like hash_lit_s and vector_lit_s.
commit 1e5bc5708d5763f20a7774f9348e825304a51adc
* struct.c (make_struct_lit_s): New symbol variable.
(struct_init): Store interned sys:make-struct-lit symbol
into make_struct_lit_s, and use that to register the
function.
* struct.h (make_struct_lit_s): Declared.
* tests/012/struct.tl: Update struct literal quasiquote
test cases to reflect fixed behavior.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The print function now takes an optional boolean
for pretty printing.
The print method is also called with a third argument;
hence structures can customize both standard printing
and pretty printing.
* lib.c (obj_print): Take pretty argument, and pass it down
to obj_print_impl. This makes obj_pprint redundant.
(obj_pprint): Function removed: it was identical to obj_print
except for passing t down to obj_print_impl for the
pretty argument. These two wrappers had started small and
got bigger with identical changes done in parallel.
(pprint): New function.
(tostring, dump): Pass nil for pretty argument of obj_print.
(tostringp): Use pprint instead of obj_pprint.
* lib.h (obj_print): Declaration updated.
(obj_pprint): Declaration removed.
(print, pprint): Declared.
* eval.c (prinl): Pass nil for pretty_p argument of obj_print.
Do the stream defaulting here; obj_print doesn't do it.
(pprinl): Pass t for pretty_p argument of obj_print,
and do stream argument defaulting.
(eval_init): Register print to new print function rather
than directly to obj_print.
Register pprint to new pprint function rather than obj_pprint.
* hash.c (hash_print_op): Call obj_print_impl to print
the :equal-based keyword, rather than obj_print. Pass
down the pretty flag. All the other keywords are treated
this way; this fixes an inconsistency.
* match.c (dump_var): Call pprint instead of obj_pprint.
* stream.c (formatv): Call obj_print, with a calculated
pretty argument instead of switching between obj_pprint
and obj_print.
* struct.c (struct_inst_print): Except when in backward
compatibility mode, call the object's print method in both
pretty and regular printing mode, passing the mode as a third
argument.
* tests/012/oop.tl (defstruct animal): Support third argument
in print method. Make it optional because there are some
explicit calls which don't pass the argument.
* txr.1: Documentation updated for print method and the
print function. Revised text for some of the related
functions. Added compat notes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The semantics of how struct literals come to life is poorly
designed: namely, the slot-value pairs in the struct literal
are used as the plist argument in a call to make-struct.
This is wrong because the implied initializations are then
clobbered by the structure type's :init and :postinit
handlers, resulting in an object with slot values that don't
match what is in the literal. When you add circular syntax
to the mix, things get worse. Slots may be initialized with
(sys:circ-ref ...) expressions corresponding to #<n># syntax.
These expressions then get clobbered by the constructor
actions before the circ_backpatch processes the syntax.
* parser.y (struct): Use make_struct_lit rather than
make_struct to instantiate struct object.
* struct.tl (sys:struct-lit): Expand to a form which calls
sys:make-struct-lit, rather than make-struct.
* struct.c (struct_init): Register new make_struct_lit
function as sys:make-struct-lit intrinsic.
(make_struct_lit): New function.
* struct.h (make_struct_lit): Declared.
* tests/012/struct.tl: struct literal expansion test case
updated.
* txr.1: Updated documentation of struct literals.
Added compat notes.
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (length_proper_list): New static function.
(length): Use length_proper_list for objects.
(sub): Call nullify on COBJ object before passing
to sub_list.
* tests/012/aseq.tl, tests/012/aseq.expected:
New files.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/struct.tl (meth): Take trailing arguments
and pass them down to method, which now accepts them.
* struct.c (struct_init): Register method intrinsic to the
function method_args instead of the method function.
(method_args_fun): New static function.
(method_args): New function. Behaves like method
function if args is empty, otherwise creates a function
by means of method_args_fun.
* struct.h (method_args_fun): Declared.
* tests/012/oop.tl: New test case.
* tests/012/oop.expected: Updated.
* txr.1: Documented new features in method and
meth, revising the documentation in the process.
|