summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
...
* digits/digpow: wrong results for radix powers.Kaz Kylheku2019-09-061-1/+1
| | | | | | * 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.
* digits/digpow: disallow base 1.Kaz Kylheku2019-09-061-1/+1
| | | | | * arith.c (digcommon): Fix wrong test that allows base 1 to be admitted, resulting in infinitely looping behavior.
* subtypep: structs with car or length method are sequences.Kaz Kylheku2019-09-064-0/+17
| | | | | | | | | | | | | * 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.
* seq_info: bug: nil for objects with only length method.Kaz Kylheku2019-09-061-1/+1
| | | | | | * 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.
* subtypep: remove useless eq.Kaz Kylheku2019-09-061-1/+1
| | | | | | * 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.
* lib: access special methods via special slot mechanism.Kaz Kylheku2019-09-065-32/+63
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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: remove trivial static function.Kaz Kylheku2019-09-061-6/+1
| | | | | | * 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.
* structs: lazily allocate special slots array.Kaz Kylheku2019-09-041-23/+30
| | | | | | | | | | | | | | | | | | | 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.
* seq_info: remove redundant car slot lookup.Kaz Kylheku2019-09-041-2/+0
| | | | | | * lib.c (seq_info): Due to a copy-paste error maybe_slot is being accidentally called here twice for the same slot. Removing.
* structs: special slot generalization.Kaz Kylheku2019-09-041-13/+34
| | | | | | | | | | | | | | | | | | | | | | | 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.
* structs: move SLOT_CACHE_SIZE macro.Kaz Kylheku2019-09-042-2/+1
| | | | | | | | | | 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.
* type: lcons and string are subtypes of sequence.Kaz Kylheku2019-09-041-1/+1
| | | | | | | Omissions reported by user vapnik spaknik. * lib.c (subtypepe): The lcons type and string type must report as subtypes of sequence.
* list-builder: use copy-list, not copy.Kaz Kylheku2019-09-031-6/+6
| | | | | | | * 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.
* list-builder: bugfix: broken self-appending.Kaz Kylheku2019-09-031-4/+7
| | | | | | | | | | | | | | | | | | | | 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.
* New function: tailp.Kaz Kylheku2019-09-034-0/+65
| | | | | | | | | | * eval.c (eval_init): Register tailp intrinsic. * lib.c (tailp): New function. * lib.h (tailp): Declared. * txr.1: Documented.
* struct: recycle conses used for slot lookups.Kaz Kylheku2019-09-031-0/+12
| | | | | | | | | | | | 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.
* doc: fixes from vapnik spaknik.Kaz Kylheku2019-09-031-43/+80
| | | | | | | | | | | | | 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).
* doc: hyphenation of some compound words.Kaz Kylheku2019-09-031-4/+4
| | | | * txr.1: Hyphenate "heap-allocated" and "stack-allocated".
* interpreter: trivial let goes through let* case.Kaz Kylheku2019-08-311-1/+1
| | | | | | | * 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.
* interpreter: bug between let* and continuations.Kaz Kylheku2019-08-311-11/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Version 224.txr-224Kaz Kylheku2019-08-296-863/+928
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* compiler: mac params: eliminate plen variable.Kaz Kylheku2019-08-291-10/+9
| | | | | | | | * 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.
* sha256/md5: allow characters and byte values.Kaz Kylheku2019-08-292-4/+48
| | | | | | | | | * 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.
* compiler: elide nil var intializaton.Kaz Kylheku2019-08-281-2/+6
| | | | | | | | | | | | 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.
* compiler: mac params: simplify optional presence indicators.Kaz Kylheku2019-08-281-15/+21
| | | | | | | | * 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.
* compiler: mac params: late allocation for cursors.Kaz Kylheku2019-08-281-68/+69
| | | | | | | | | | | * 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.
* trace: bug: redef of traced method resurrects old.Kaz Kylheku2019-08-281-3/+3
| | | | | | | | | | | | 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.
* trace: bugfix: trace-redefine-check doesn't untrace.Kaz Kylheku2019-08-281-3/+3
| | | | | | | * 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.
* compiler: bugfix: incorrect scoping in macro param binding.Kaz Kylheku2019-08-281-65/+85
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* compiler: bugfix: colon keyword bungle in macro params.Kaz Kylheku2019-08-281-9/+7
| | | | | | | | | | | | | | | 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.
* unwind: bugfix: unhandled_ex not gc-protected.Kaz Kylheku2019-08-281-1/+3
| | | | | | | | | | | | | 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.
* compiler: relate mac bind error to right substructure.Kaz Kylheku2019-08-271-1/+1
| | | | | | | | * 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.
* compiler: for: bugfix: dangling label reference.Kaz Kylheku2019-08-261-1/+1
| | | | | | | | | | | 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.
* crypt: detect and use glibc's crypt_r.Kaz Kylheku2019-08-262-2/+39
| | | | | | | | | | * 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.
* build: bugfix: compiler opts duplicated; remove_flags broken.Kaz Kylheku2019-08-251-1/+1
| | | | | | * 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.
* sha256/md5: state-based hash: handle size_t overflow.Kaz Kylheku2019-08-241-20/+20
| | | | | | | | | | | | * 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.
* sha256/md5: hash string more efficiently.Kaz Kylheku2019-08-241-4/+12
| | | | | | * 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.
* New state-object-based sha256 and md5 digesting.Kaz Kylheku2019-08-233-0/+230
| | | | | | | | | | | | | | | * 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.
* licensing: describe RSA-MD situation.Kaz Kylheku2019-08-232-3/+15
| | | | | | | | | * 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.
* New: MD5 digest functions.Kaz Kylheku2019-08-236-19/+509
| | | | | | | | | | | | | | | | | * 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.
* New function: cptr-buf.Kaz Kylheku2019-08-214-2/+46
| | | | | | | | | | * eval.c (eval_init): Register cptr-buf intrinsic. * lib.c (cptr_buf): New function. * lib.h (cptr_buf): Declared. * txr.1: Documented.
* doc: note about cptr-obj lifetime.Kaz Kylheku2019-08-211-0/+12
| | | | | | * 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.
* New function: intern-fb.Kaz Kylheku2019-08-204-2/+37
| | | | | | | | | | | | | | | To accompany find-symbol-fb, there is intern-fb, which is like intern, but searches the fallback list. * eval.c (eval_init): Register intern-fb intrinsic. * lib.c (intern_fallback_intrinsic): New function. Does defaulting and error checks, then calls intern_fallback, just like intern_intrinsic calls intern. * lib.h (intern_fallback_intrinsic): Declared. * txr.1: Documented.
* lib: streamline interning slightly.Kaz Kylheku2019-08-204-15/+17
| | | | | | | | | | | | | | | | | | | | | We get rid of some defaulting and error checks from interning. This saves a few cycles on startup in the large number of intern calls that are performed. * eval.c (eval_init): Wire the intern intrinsic to the new intern_intrinsic function rather than intern. * lib.c (intern): Remove package lookup and error check on str argument. (intern_intrinsic): New function, which has the package lookup and error check. (intern_fallback): Remove package lookup and error check. * lib.h (intern_intrinsic): Declared. * txr.c (txr_main): Fix one instance of an intern call that relies on defaulting of the second argument, by passing cur_package.
* lexer: no leading 0 in 2-digit hex chars in diagnostic.Kaz Kylheku2019-08-201-3/+3
| | | | | | | * parser.l (grammar): Fix incorrect format strings that are supposed to show an invalid input character in hex. For instance the character 1 comes out as #\x 1 rather than #\x01.
* parser: bugfix: uninitialized ignore flag.Kaz Kylheku2019-08-201-0/+1
| | | | | | | | | | | | | | | * parser.c (parser_common_init): Initialize the ignore flag, which was until recently called circ_suppress. When the parser is invoked via parse_once or parse_once_noerror, rather than parse, the state of the flag is indeterminate. Thus this only affects the TXR Pattern Language, not TXR Lisp. As a result of this bug, which affects releases 157 through 223, if the circle notation like #1=(foo #1#) is used in Pattern Language syntax, it may not be handled properly. I discovered this bug now because there are new behaviors connected to the flag; it doesn't just affect the processing of the circle notation, but is involved in all symbol handling in the parser.
* doc: mistake in intern arg description.Kaz Kylheku2019-08-201-2/+2
| | | | | * txr.1: name must be a string, not a symbol. The optional argument must be a package, if supplied.
* new functions: find-symbol and find-symbol-fb.Kaz Kylheku2019-08-194-9/+111
| | | | | | | | | | | | | | | | | | Turns out, there is already a find_symbol in lib.c, completely unused. * eval.c (eval_init): Register find-symbol and find-symbol-fb intrinsics. * lib.c (find_symbol): Fix this hitherto unused function to do correct defaulting of the package argument and, to accept an additional argument specifying the not-found value. (find_symbol_fb): New function. * lib.c (find_symbol): Declaration updated. (find_symbol_fb): Declared. * txr.1: Documented.
* parser: #; notation shouldn't intern symbols.Kaz Kylheku2019-08-181-2/+3
| | | | | | | | | | When #; is used to ignore an object, parsing that object shouldn't cause symbols to be interned, nor errors about unknown packages. * parser.y (ifnign): New macro. (i_expr, n_expr): For SYMTOK, don't call symhlpr when parsing under ignore flag. Just yield nil as the semantic value.
* parser: rename circ_suppress flag.Kaz Kylheku2019-08-183-16/+16
| | | | | | | | | | | * parser.h (struct parser): eof flag changed to unsigned char. circ_suppress flag renamed to ignore, changed to unsigned char and relocated next to eof to compact together. * parser.c (parser_circ_ref): Follow rename. * parser.y (hash_semi_or_n_expr, hash_semi_or_i_expr, n_exprs, parse): Likewise.