| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/struct.tl (defstruct, sys:check-slot,
defmeth): Use slot rather than sys:slot as indicator in
tentative defs.
* struct.c (static_slot_s): Variable removed.
(struct_init): slot_s initialized with symbol in user package,
rather than system package. Initialization of static_slot_s
removed. Existing slot function now registered using slot_s.
(static_slot_type_reg): Remove reference to static_slot_s.
This was a dud all along; nothing publishes deferred warnings
against this symbol.
* protsym.c (protected_sym): Remove static_slot_s.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
* struct.c (struct_set_initfun, struct_set_postinitfun):
Replace incorrect direct assignments with set macro.
This manifested itself as corruption. I ran into a situation
in which the postinitfun of a struct type was prematurely
reclaimed and the heap object was re-used for something else
wreaking havoc on the postinit call when the struct was
instantiated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* args.c (args_normalize): Renamed to args_normalize_exact,
because this tries to split the arguments between an exact
array fill quantity and trailing list. Not all places using
this function actually need an exact fill, which causes
unnecessary consing when args->fill is reduced in order to
move items to args->list.
(args_normalize_least): New function. Variant of
args_normalize that can be used by functions which only
require a minimum fill.
(args_normalize_fill): Use args_normalize_least rather than
args_normalize_exact. This reduces consing in generic_funcall,
in handling variadic calls where arrayed arguments have been
supplied for trailing parameters.
* args.h (args_normalize): Renamed to args_normalize_exact.
(args_normalize_least): Declared.
(args_get_list, args_get_rest): Use args_normalize_exact.
(args_clear): Inline function removed. Was used only in one
place in generic_funcall and is no longer.
* eval.c (gather_free_refs): Use args_normalize_least.
(prod_common): Use args_normalize_exact.
* ffi.c (ffi_call_wrap): Use args_normalize_least.
* lib.c (generic_funcall): Use args_normalize_least in switch
statement that handles various callable non-function objects.
When copying args, ensure that there are ARGS_MIN.
A different strategy is used for producing the trailing args
for variadic calls, further reducing consing. Rather than
normalize the args to the fixed number, and then set
args->fill to zero so that args contains just the list, we use
args_cat_zap_from to create a copy of the args in which the
fixed ones are trimmed out. The resulting args is not
renormalized to be purely a list so no consing or list traversal
takes place. If the rebalancing is needed, the called
function will have to do it.
(dwim_set): Streamline the code that handles hashes assigned
via two or three args.
* struct.c (method_args_fun, umethod_args_fun): Use
args_normalize_exact.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If the trace module has been loaded, we can't
define methods. Repro:
1> (trace)
nil
2> (defmeth time foo (me))
** static-slot-home: #<struct-type time> has no static slot named foo
* struct.c (static_slot_ensure): Do the trace_check
after calling static_slot_ens_rec so that the slot exists.
If the slot doesn't exist, an exception occurs when
sys:trace-canonicalize-name calls static-slot-home.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* struct.c (reset_struct): Perform the post-init
actions are performed, not only the init actions.
Also, catch exceptions and call finalizers,
just like in a new structure instantiation.
* txr.1: Document the requirements for finalizers
being called by reset-struct, and clarify the issue of
possible duplicate finalization registration.
Add compat notes.
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.h (static_forward, static_def): At least the C version
of these now require a trailing semicolon.
* struct.c (struct_type_ops): Add required semicolon after
static_def.
* syslog.c (syslog_strm_ops): Add required semicolon after
static_forward and after static_def.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (seq_info, car, cdr, make_like, nullify,
generic_funcall, copy, length, empty, ref, refset, dwim_set,
dwim_del, populate_obj_hash): Use new obj_struct_p test when
we know that the object is a COBJ.
* struct.c (struct_inst_ops): Change from static to extern.
* struct.h (ob_struct_p): New inline function.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In this change, a struct type's initfun and postinitfun
become mutable. This is achieved by modeling them as
the pseudo-static-slots :initfun and :postinitfun.
Effectively these now behave as reserved names which do not
denote static slots but these special functions.
* eval.c (lookup_fun): When (meth type slot) syntax is
encountered, treat the slot names :init and :postinit
specially: retrieve these special functions instead of
accessing static slots.
* share/txr/stdlib/place.tl (sys:get-fun-getter-setter):
Similarly, when handling (meth type slot) syntax, return
the alternative getter/setter functions for the special
functions, not the static slot accessing functions.
Also, getting rid of a useless @1 here in existing code,
since (op foo @1) is equivalent to (op foo).
* share/txr/stdlib/struct.tl (sys:defmeth): Check for
the special names :init and :postinit, handling these
through the appropriate setter functions rather than
static-slot-ensure.
* struct.c (init_k, postinit_k): New keyword symbol variables.
(struct_init): Initialize init_k and postinit_k. Register
intrinsics struct-get-initfun, struct-set-initfun,
struct-get-postinitfun and struct-set-postinitfun.
* (struct_get_initfun, struct_set_initfun,
struct_get_postinitfun, struct_set_postinitfun): New
functions.
(method_name): For each struct type visited, check
whether the function is the initfun or postinitfun
and return the appropriate meth syntax if so.
* struct.h (init_k, postinit_k, struct_get_initfun,
struct_set_initfun, struct_get_postinitfun,
struct_set_postinitfun): Declared.
* txr.1: Documented. Updated description of method-name,
defmeth, and documented new functions.
|
|
|
|
|
|
|
|
| |
* struct.c (call_super_fun): Do not allow type to be a struct
instance, which is a consequence of the super function being
used. The documentation says that the argument is a type and
mentions no possibility of it being an instance. Allowing a
struct invites mistakes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* struct.c (static_slot_rewrite_rec): A simple rearrangement:
switch to postorder traversal, doing the derived structs
first, then this struct. Why does this fix a bug? Because
when the assignment *s = *to occurs for the node at the root
of the recursion, s and from point to the same object. And
so the assignment alters from, which is the search key.
When the children are then processed, the search key doesn't
match anything: it now looks like the to slot that the
children are supposed to get, and so they don't have it, of
course. So in other words the slot being rewritten is not
found in the derived types and not rewritten there as it
should be.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* struct.c (static_sot_ens_rec): This change is in the case
when a static slot is being ensured in a struct type which
already has that static slot by inheritance. In that
situation, the inheritance is severed and the struct gets its
own non-inherited slot of that name. Then all of the derived
structs are scanned. If any contain the original inherited
slot, it is updated to the new, non-inherited one. The bug
here is that we were copying the home_offs field of the
original inherited slot to the new one! This is wrong; the new
slot is not related to the original inherited one. The new
slot is a home slot and its own offset must be home_offs.
We can calculate that simply as its delta from the static slot
table base.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Renaming cobj_hash_op to cobj_eq_hash_op. This function is
only appropriate to use with COBJ objects which use
eq as their equal funtion. I've spotted one instance of an
inappropriate use which have to be addressed by a different
commit: the equal function is other than eq, but cobj_hash_op
is used for the equal hash.
* lib.h (cobj_hash_op): Declaration renamed to
cobj_eq_hash_op.
* hash.c (cobj_hash_op): Renamed to cobj_eq_hash_op.
(hash_iter_ops): Refer to renamed cobj_hash_eq_op.
* ffi.c (ffi_type_builtin_ops, ffi_type_struct_ops,
ffi_type_ptr_ops, ffi-closure_ops, ffi_call_desc_ops):
Likewise.
* lib.c (cptr_ops): Likewise.
* parser.c (parser_ops): Likewise.
* rand.c (random_state_ops): Likewise.
* regex.c (char_set_ops, regex_obj_ops): Likewise.
* socket.c (dgram_strm_ops): Likewise.
* stream.c (null_ops, stdio_ops, tail_ops, pipe_ops, dir_ops,
string_in_ops, byte_in_ops, strlist_in_ops, string_out_ops,
strlist_out_ops, cat_stream_ops, record_adapter_ops):
Likewise.
* struct.c (struct_type_ops): Likewise.
* sysif.c (cptr_dl_ops): Likewise.
* syslog.c (syslog_strm_ops): Likewise.
* unwind.c (cont_ops): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Implementing warning for the situaton when the qref, uref, usl
and umeth macro operators are asked to refer to a slot that
doesn't exist in any struct type. This won't catch errors
referencing a slot on the wrong type, but it will catch slots
that are misspelled in such a way that the typo doesn't land
on any slot.
* share/txr/stdlib/struct.tl (defstruct): Register tenative
slot definitions for all slots to nuke warnings.
(sys:check-slot): New function.
(qref, usl, umeth): Check slots with sys:check-slot.
(uref): Drop :whole argument, which is unused.
(defmeth): Register tentative definition for slot.
* struct.c (slot_s, static_slot_s): New symbol variables.
(slot_type_hash, static_slot_type_hash): New hash tables,
associating symbols with lists of struct type names
in which they are defined.
(struct_init): Initialize and gc-protect hashes.
Initialize new symbols, interning in system package.
Register new intrinsic funtions sys:slot-types and
sys:static-slot-types.
(make_struct_type): Register slots in new hashes.
(static_slot_ens_rec): Register new slow in static
slot hash.
(slot_types, static_slot_types): New functions,
registered as intrinsics.
(slot_type_reg, static_slot_type_reg): New functions.
* struct.h (print_s): Declared.
(slot_s, static_slot_s): Declared.
(slot_types, static_slot_types, slot_type_reg,
static_slot_type_reg): Declared.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When completing .prefix[TAB], .(prefix[TAB] or .[prefix[TAB],
restrict identifiers to the appropriate namespace. The former
will report only symbols from the relevant package which are
struct slots; the latter further restricts it to those which
are static slots defined as functions.
* lib.c (symbol_visible): Static function becomes extern.
* lib.h (symbol_visible): Declared.
* parser.c (find_matching_syms): par parameter is renamed
kind and can hold additional values 'S' (slots) and 'M'
(methods). New get_slot_syms function is used to fetch the
slots, as necessary, instead of the visible syms, if the
kind is 'S' or 'M'. The same loop as before (with the minor
change of recognizing 'S' and 'M' also) performs the prefix
matching.
(provide_completions): Recognize . .( and .[ prefix,
calculating the kind argument of find_matching_syms in
a new way.
* struct.c (get_slot_syms): New function.
* struct.h (get_slot_syms): Declared.
* txr.1: Add some notes about this under the description of
completion. The full rules are not given though; let the
user discover.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.h (default_bool_arg): Inline function renamed to
default_null_arg.
* eval.c (if_fun, pad, ginterate, giterate, range_star, range,
constantp, macroexpand_1, macro_form_p, expand_with_free_refs,
do_expand, eval_intrinsic, func_get_name, make_env_intrinsic):
Follow rename.
* arith.c (lognot): Likewise.
* gc.c (gc_finalize): Likewise.
* glob.c (glob_wrap): Likewise.
* hash.c (group_reduce, gethash_n): Likewise.
* lib.c (print, multi_sort, lazy_str, vector, iff, tok_str,
split_str_keep, search_str, remove_if, val): Likewise.
* match.c (match_fun): Likewise.
* parser.c (lisp_parse_impl, regex_parse): Likewise.
* rand.c (make_random_state): Likewise.
* regex.c (read_until_match, search_regex, regex_compile):
Likewise.
* socket.c (sock_accept, sock_connect): Likewise.
* stream.c (open_files_star, open_files, run, open_process,
open_tail, get_string, record_adapter): Likewise.
* struct.c (static_slot_ensure, static_slot_ens_rec,
clear_struct, make_struct_type): Likewise.
* sysif.c (exec_wrap, errno_wrap, cobj_ops_init): Likewise.
* unwind.c (uw_capture_cont, uw_find_frames_impl): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The tracing module should warn when traced functions or
methods are being redefined, and stop tracing the original
methods.
* eval.c (trace_check): New function. Calls
sys:trace-redefined-check if the trace module has been
loaded, otherwise does nothing.
(op_defun, op_defmacro): Call trace_check to have a warning
issued for a redefined traced function or macro.
* eval.h (trace_check): Declared.
* lisplib.c (trace_loaded): New global variable.
(trace_instantiate): Flip trace_loaded to t.
* lisplib.h (trace_loaded): Declared.
* share/txr/stdlib/trace.tl (sys:trace-redefine-check): New
function. Checks two situations: traced function or method
is redefined (neither old nor new is traced any longer),
and traced method is overridden (base method continues to be
traced, override is not traced).
* struct.c (static_slot_ensure): Do a trace check here,
taking care of defmeth.
|
|
|
|
|
|
|
|
|
|
|
| |
* struct.c (struct_init): Register intrinsic function
static-slot-home.
(lookup_static_slot_desc_load): New static function.
(static_slot_home): New function.
* struct.h (static_slot_home): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
| |
* struct.c (lookup_static_slot_desc, lookup_static_slot,
lookup_static_slot_load, get_equal_method): Remove stype
argument; it is only passed down through the calls and not
used at the leaf level.
(static_slot, static_slot_set, static_slot_ens_rec,
struct_inst_print, struct_inst_equalsub, method_name): Don't
pass stype to slot lookup functions that no longer take it.
|
|
|
|
|
|
|
| |
* struct.c (no_such_static_slot): New static function.
(static_slot, static_slot_set): Use no_such_static_slot
when reporting error. The struct type might have an
instance slot of that name.
|
|
|
|
|
|
|
|
| |
* struct.c (struct_inst_print): Check return value of print
method call. If it is the colon keyword, then do not return
but rather continue to the regular struct printing code.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
| |
* struct.c (struct_init): Register new functions.
(struct_from_plist, struct_from_args): New functions.
* struct.h (struct_from_plist, struct_from_args): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
| |
The symbolp test is too weak before calling lookup_slot,
because nil satisfies it, but lookup_slot dereferences
the symbol pointer to access its slot cache.
One of many test cases: parsing #S(time nil nil) segfaults.
* struct.c (slot, maybe_slot, slotset, uslot_fun, umethod_fun,
umethod_args_fun): Check that sym isn't nil before looking it
up as a slot.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* LICENSE, LICENSE-CYG, METALICENSE, Makefile, args.c, args.h,
arith.c, arith.h, cadr.c, cadr.h, combi.c, combi.h, configure,
debug.c, debug.h, eval.c, eval.h, filter.c, filter.h, ftw.c,
ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h, jmp.S,
lib.c, lib.h, lisplib.c, lisplib.h, match.c, match.h,
parser.c, parser.h, parser.l, parser.y, rand.c, rand.h,
regex.c, regex.h, signal.c, signal.h, stream.c, stream.h,
struct.c, struct.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, share/txr/stdlib/awk.tl,
share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl,
share/txr/stdlib/conv.tl, share/txr/stdlib/except.tl,
share/txr/stdlib/getopts.tl, share/txr/stdlib/getput.tl,
share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl,
share/txr/stdlib/package.tl, share/txr/stdlib/path-test.tl,
share/txr/stdlib/place.tl, share/txr/stdlib/socket.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:
Add 2017 to all copyright headers and strings.
|
|
|
|
|
|
| |
* struct.c (make_struct_type): Fix test of incorrect variable
which renders the supertype test useless, causing the type
to be created with no supertype.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register sys:ctx-form and sys:ctx-name
intrinsics.
* lisplib.c (error_set_entries, error_instantiate): New static
functions.
(lisplib_init): Register autoloading of error.tl via
new functions.
* share/txr/stdlib/error.tl: New file.
* struct.c (make_struct_type): Purge deferred warnings.
* unwind.c (uw_late_init): Register purge-deferred-warning
intrinsic.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is uncovered by compiling with g++ using
-Wold-style-cast.
* mpi/mpi.c (mp_get_intptr): Use convert macro.
Also in one of the rules producing REGCHAR.
* parser.l (num_esc): Likewise.
* struct.c (static_slot_set, static_slot_ens_rec,
get_equal_method): Use coerce macro for int to pointer
conversion.
* sysif.c (setgroups_wrap): Use convert macro.
* termios.c (termios_unpack, termios_pack): Likewise.
* txr.c (sysroot_init): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* struct.c (struct struct_inst): New bitfield member, dirty.
(struct_init): Register test-dirty, test-clear-dirty and
clear-dirty intrinsics.
(make_struct): Initialize dirty flag to 1.
(slotset): If the object is clean, then determine whether
the slot being set is an instance slot. If so, then
set the dirty flag.
(test_dirty, test_clear_dirty, clear_dirty): New functions.
* struct.h (test_dirty, test_clear_dirty, clear_dirty):
Declared.
* txr.1: Documented dirty flags concept and new functions.
|
|
|
|
|
|
|
| |
* struct.c (struct_init): Register slots intrinsic.
(slots): Pass correct name string to stype_handle.
* txr.1: Slots function documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 bug_unless statement was found to go off, indicating an
internal problem. Indeed, the store of inherited static slots
were being set to non-nil by incorrect copying in two places.
This is harmless in and of itself; it's just a way of being
tidy. If a slot's value is located elsewhere, then the local
store must be nil.
* struct.c (static_slot_home_fixup): After fetching a fresh
copy of the home type's stslot entry, clear the store to nil.
(make_struct_type): Likewise.
(struct_type_mark): Use assert for this rather than
bug_unless, because it happens in the middle of garbage
collection. Throwing an exception out of the middle of gc is a
nonstarter.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is some infrastructure which will support *print-circle*.
* lib.h (struct strm_ctx): Forward declared.
(struct cobj_ops): Add context parameter to print function
pointer.
(cobj_print_op, obj_print_impl): Add context parameter to
declarations.
* hash.c (hash_print_op): Take context argument and
pass it down in obj_print_impl calls.
* lib.c (cobj_print_op, out_quasi_str): Likewise
(obj_print_impl): Likewise, and also pass to
COBJ print method.
(obj_print, obj_pprint): Pass null pointer
as context argument to obj_print_impl.
* regex.c (regex_print): Take context parameter and ignore it.
* socket.c (dgram_print): Likewise.
* stream.h (struct strm_ctx): New struct type.
(struct strm_base): New ctx member, pointer to struct
strm_ctx.
(stream_print_op): Add context parameter to declaration.
(get_set_ctx, get_ctx): Declared.
* stream.c (strm_base_init): Add null pointer to initializer.
(strm_base_cleanup): Add assertion against context pointer
being non-null: that indicates that some stream operation
installed a context pointer and neglected to restore it to
null before returning, which is bad because context will be
stack allocated.
(stream_print_op, stdio_stream_print, cat_stream_print): Take
context parameter and ignore it.
(get_set_ctx, get_ctx): New functions.
* struct.c (struct_type_print): Take context parameter and
ignore it.
(struct_inst_print): Take context parameter and pass
down to obj_print_impl.
|
|
|
|
|
|
| |
* struct.c (slots): New function.
* struct.h (slots): Declared.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/struct.tl (umeth): accept variadic
arguments. Evaluate them using the dwim brackets
and pass to umethod. The (fun umethod) trick is
used to refer to the umethod in the function namespace
even if it is shadowed by a variable.
* struct.c (struct_init): Update registration of umethod to
reflect its new variadic argument signature.
(umethod_args_fun): New static function.
(umethod): Return a function based on umethod_fun,
as before, if there are no variadic args. Otherwise,
use umethod_args_fun which deals with them.
* struct.h (umethod): Declaration updated.
* tests/012/oop.tl: Modest testcase for umeth
with curried argument.
* tests/012/oop.expected: Updated.
* txr.1: Updated documentation of umeth and umethod.
|
|
|
|
|
|
|
| |
* struct.c (clear_struct, reset_struct): Inform the garbage
collector that the structure has been mutate, using the mut
macro. This is required for correctness because the structure
may be a mature object receiving young generation values.
|
|
|
|
|
|
|
|
|
| |
* struct.c (replace_struct): If target and source
are the same object, just do nothing and return
target.
* txr.1: Document self-assignment and return
value of replace-struct.
|
|
|
|
|
|
|
|
| |
* struct.c (static_slot_ens_rec): Neglected use of
set macro to store newval in freshly allocated slot,
which means we corrupt garbage collection if this
causes an old generation objet to point to a new
generation object.
|
|
|
|
|
|
| |
* struct.c (struct_type_mark): We must assert that
sl->store is nil if we are not marking it,
not that it is non-nil.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Makefile, args.c, args.h, arith.c, arith.h, cadr.c, cadr.h, combi.c,
combi.h, configure, debug.c, debug.h, eval.c, eval.h, filter.c,
filter.h, ftw.c, ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h,
jmp.S, lib.c, lib.h, lisplib.c, lisplib.h, match.c, match.h, parser.c,
parser.h, parser.l, parser.y, 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/except.tl, share/txr/stdlib/hash.tl,
share/txr/stdlib/ifa.tl, share/txr/stdlib/path-test.tl,
share/txr/stdlib/place.tl, share/txr/stdlib/socket.tl,
share/txr/stdlib/struct.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, 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: Revert to verbatim 2-Clause BSD.
|
|
|
|
|
| |
* struct.c (make_struct_type, static_slot_ens_rec): Throw an
error if there are too many static slots.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fixing the broken static slot handling in TXR Lisp's
"OOP structs" object system. Inherited static slots
are now shared with the base type; only static slots
explicitly defined in a derived type have a distinct
global instance in that type.
* share/txr/stdlib/struct.tl (sys:prune-nil-inits):
Function removed.
(sys:prune-missing-inits): New function. We now handle
static slot forms with missing inits specially, not
those with nil or missing inits.
(defstruct): Translate a (word name) form to (word name)
rather than (word name nil) if word is :static, because we
need this nuance for non-shared static slots, so they can
inherit the value from the base struct. For the purposes of
generating the static init function, prune away all the static
slot forms that do not have an initializer; we let those
default.
* struct.c (struct stslot): New struct for representing
a static slot.
(stslot_loc, stslot_place): New macros.
(struct struct_type): Member eqmslot changes to a pointer
to a struct stslot. The stslot dynamic array is no longer
an array of val, but an array of stslot structs.
(call_stinitfun_chain): The superclass chain of static
init functions is now called only in compatibility mode.
Otherwise only the type's own static init fun is called,
which defclass uses to initialize just the new or repeated
static slots. Inherited static slots are completely left
alone; they do not require initialization.
(static_slot_home_fixup): New static function; needed to
fix some internal pointers within the static slot arrays
if they are realloc'ed.
(make_struct_type): Considerably revised to implement
new scheme, while providing backward compatibility
switching. New slots live in the struct stslot in which
they are allocated. Inherited slots have home pointers
to within the array in the base.
(struct_type_mark): When walking the static slots,
mark only the store cells of those which live in
this array. Those that live elsewhere should have store
cells that are nil; let's assert on it.
(lookup_slot): Static slot lookup code has to retrieve
slots in the new way, indirecting through the home
pointer, which is hidden behind the stslot_loc
macro.
(lookup_static_slot_desc): New function, like
lookup_static_slot, but returning a pointer to the
struct stslot. Formed from the guts of lookup_static_slot.
(lookup_static_slot): Gutted and turned into a wrappar
around lookup_static_slot_desc.
(static_slot_set): Simple change here: add cast
because of the pointer type of eqmslot.
(static_slot_home_fixup_rec): New static function.
Fixes up the cached home in slot arrays in an entire
type hierarchy rooted at a given type, which has to be
done when its static slot has been reallocated, so all those
inherited static slot pointers in the derived types
are invalid.
(static_slot_rewrite_rec): New static function:
rewrites a particular inherited static slot in an inheritance
hierarchy to point to a different slot.
(static_slot_ens_rec): New static function: factored out
recursive logic of static_slot_ensure. Substantially rewritten
to handle new static slot scheme, plus support backward
compatibility. There is a bug fixed here: if an instance slot
is encountered in the no_error_p mode, it looks like we were
dereferencing through an invalid ptr through the
set(ptr, newval) line.
(static_slot_ensure): A wrapper now for static_slot_ens_rec.
(get_equal_method): Rework the logic related to the eqmslot
member of the struct_type structure, in terms of it being
a pointer now rather than an integer. The value -1 cast
to a pointer serves the previous -1 sentinel value which
indicates that it is confirmed (for the time being) that this
type doesn't have an equal method.
* txr.1: All documentation related to static slots updated,
and compatibility notes added.
* tests/012/oop.tl, tests/012/oop.expected: New files.
|
|
|
|
|
|
|
|
|
| |
* struct.c (call_postinitfun_chain): call base
handlers before derived ones, except in backward
compatibility mode.
* txr.1: Updated documentation of :postinit,
and added compatibility note.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Staci-blowing test case:
(defstruct foo nil bar)
(mlet ((f (lnew foo bar (not f.bar))))
(prinl f.bar))
* struct.c (lazy_struct_init): Do not flip the lazy flag to zero
here. The problem is that it's being done after the
funcall(so->slot[0]), and so the struct is still marked for
lazy initialization while that function is running.
We could detect the circularity (as done in the force function) but that
would create inflexibilities in lazy struct initialization.
(check_init_lazy_struct): Flip the lazy flag to zero in
this function before calling lazy_struct_init.
* txr.1: Document behavior of struct being freely accessible during
lazy initialization.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Struct objects can now define methods car, cdr and nullify.
With these, they can participate in operations on sequences.
* eval.h (car_s, cdr_s): Declared.
* lib.c (nullify_s): New symbol variable.
(car, cdr): Implement for struct objects via, respectively,
their car and cdr methods.
(tolist): Handle objects by mapping through identity.
(nullify): Implement for objects optionally: if an object
is a struct with a nullify method, use it, otherwise go
through default case of just returning the object.
(empty): Implement for objects that have nullify method.
(obj_init): Initialize nullify_s.
* struct.c (maybe_slot): New function.
* struct.h (maybe_slot): Declared.
* txr.1: Documented car, cdr and nullify method
convention.
|
|
|
|
|
|
|
|
|
| |
* struct.c (print_s): New symbol variable.
(struct_init): Initialize print_s.
(struct_inst_print): If pretty-printing, try to look
up object's print method and use it.
* txr.1: Documented pretty-printing via print method.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Curtail traversal of objects and strings.
* hash.c (struct hash): hash_fun member takes int *
parameter now.
(HASH_STR_LIMIT, HASH_REC_LIMIT): New macros.
(hash_c_str): Hash only HASH_STR_LIMIT characters.
(equal_hash): Becomes extern function. Takes pointer-to-int
count argument, which is decremented. Function stops
recursing and returns zero when this hits zero.
(eql_hash): Also takes int * param, for compatibility
with function pointer in struct hash. This parameter
is not used, though.
(cobj_hash_op): Take pointer-to-count parameter,
but ignore it.
(hash_hash_op): Take pointer-to-count parameter,
decrement and check that it has not hit zero,
pass down to equal hash.
(hash_grow, gethash_c, gethash, gethash_f, gethash_n,
remhash): Initialize a counter to HASH_REC_LIMIT and
pass down to hashing function.
(hash_eql): Pass down a pointer to a dummy counter
to eql_hash.
(hash_equal): Initialize a counter to HASH_REC_LIMIT
and pass down to hash_equal.
* hash.h (equal_hash): Declared.
* lib.h (cobj_ops): hash member takes int * parameter.
(cobj_hash_op): Declaration updated with new param.
* struct.c (struct_inst_hash): Takes new int * parameter
for count. Calls equal_hash instead of hash_equal,
eliminating c_num calls; pointer to count is
passed to equal_hash.
|