summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* 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.
* doc: new buildn example.Kaz Kylheku2019-08-181-0/+15
| | | | | * txr.1: Adding breadth-first traversal example showing queue capability of the list-builder.
* list-builder: inserter methods return nil.Kaz Kylheku2019-08-172-24/+44
| | | | | | | | | * share/txr/stdlib/build.tl (list-builder): Methods add, add*, pend, pend*, ncon and ncon* return nil. * txr.1: Updated documentation to state that these methods return nil, rather than an unspecified return value. Improvements in build macro documentation.
* list-builder: dequeue capabilities with del/del* operators.Kaz Kylheku2019-08-173-14/+129
| | | | | | | | | | | | | | | * lisplib.c (build_set_entries): Add buildn for autload, and intern del and del* symbols. * share/txr/stdlib/build.tl (list-builder): New methods del and del*. (sys:list-builder-flets): Generate flet for del*. (sys:build-expander): New function, consisting of expansion logic previously in build function. Macrolet added for del. (build): Call sys:build-expander. (buildn): New macro. * txr.1: Documented.
* doc: expand on load-time.Kaz Kylheku2019-08-161-0/+52
| | | | | | * txr.1: Add discussion highlighting use of load-time for effect staging, rather than value. Add rationale regarding the naming difference from ANSI CL.
* compile-file: include load-time as top-level form.Kaz Kylheku2019-08-162-5/+22
| | | | | | | | | | | | * share/txr/stdlib/compiler.tl (usr:compile-file): recognize sys:load-time-lit as a top-level form and recurse through to compiling its constituent form. We check the flag whether the syntax had already been processed by the evaluator, though that currently cannot possibly happen for a form that has just been parsed from a file by compile-file itself. * txr.1: Defintion of top-level form (from compile-file POV) updated. Documentation of load-time updated.
* seq_iter: remove pointless one-member union.Kaz Kylheku2019-08-142-9/+7
| | | | | | | | * lib.h (struct seq_iter): union ul with just one member replaced by that member itself. * lib.c (seq_iter_get_vec, seq_iter_peek_vec, seq_iter_init): refer to it->len instead of it->ul.len.
* where: bugfix: doesn't work for non-list sequence.Kaz Kylheku2019-08-141-13/+7
| | | | | | | | * lib.c (lazy_where_func, where): We have a regression here due to strangely trying to smuggle the predicate function in si->inf.obj, which cannot possibly work other than for lists whose seq iterators ignore that field. We switch to the trick of using the cdr field of the lazy cons to carry that forward.
* Version 223: ten years!txr-223Kaz Kylheku2019-08-146-687/+725
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* bugfix: line number of unbound vars not reported.Kaz Kylheku2019-08-131-2/+5
| | | | | * eval.c (expand): Do not create expansion debug frames for atomic forms, only for compound forms.
* autoload: bugfix: wire in forgotten test-set and others.Kaz Kylheku2019-08-131-0/+2
| | | | | * lisplib.c (place_set_entries): Add missing entries for test-set, test-clear, compare-swap, test-inc and test-dec.
* listener: don't flush lines when writing files.Kaz Kylheku2019-08-123-7/+19
| | | | | | | | | | | | | | | | * linenoise/linenoise.h (struct lino_os): New virtual operation, puts_file_fn: like puts_fn, but not display-oriented: doesn't check for and ignore padding characters, and doesn't flush after each line. (lino_os_init): Initializer macro updated. * linenoise/linenoise.c (edit_it_editor): Use puts_file_fn to write to temporary file. (lino_hist_save): Likewise, when writing out history. * parser.c (lino_puts_file): New static function. (linenoise_txr_binding): Add lino_puts_file to initializer to wire in the operation.
* tests: add test related to recent @(collect) change.Kaz Kylheku2019-08-124-0/+35
| | | | | | | | | | | 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.
* gc: remove #if 0 and #if 1.Kaz Kylheku2019-08-121-8/+0
| | | | | * gc.c (mark_obj): Remove material excluded by #if 1. (gc): Eliminate #if 0 block.
* @(collect): don't default vars if all required missing.Kaz Kylheku2019-08-122-60/+99
| | | | | | | | | | | | | | | | | | | | | | | | | The @(collect) directive disallows the situation when there are required vars, but some are missing (not bound by the collect body). However, the special case is allowed when none of the required variables are bound; that doesn't trigger the exception. There is a poor specification in this area: the issue is that when there are optional variables, and all variables are missing (optional and required), the optional ones are still bound to their default values. Thus, the situations is half-baked: some of the :vars are bound and some are not. This violates the all-or-nothing principle of :vars. This patch addresses the poor specification: if all variables are missing, then the optional variables are not bound to their defaults. * match.c (h_collect, h_coll): Detect the situation when at least one variable is required, and all optional variables are defaulted. In this case, don't propagate any bindings to the collected lists. * txr.1: Doc updated.
* reverse: bugfix: garbage object in error message.Kaz Kylheku2019-08-091-1/+1
| | | | | * lib.c (reverse): pointer to the C function in is being used as a value; the correct expression is seq_in.
* base-name: optionally remove suffix.Kaz Kylheku2019-08-093-5/+20
| | | | | | | | | | | | | | | | The base-name function now takes a second argument which is optional, specifying a suffix to be removed. The behavior is similar to that of the second argument of the POSIX basename command. * stream.c (base_name): Second argument added. If present, the returned value is adjusted by trimming the suffix, unless that would cause an empty string to be returned. (stream_init): Update registration of base-name intrinsic. * stream.h (base_name): Declaration updated. * txr.1: New base-name parameter documented.
* compiler: inline-lambda: optimize constant apply list.Kaz Kylheku2019-08-091-65/+75
| | | | | | | | | | | | | * share/txr/stdlib/compiler.tl (comp-inline-lambda): Pass nil to new argument of lambda-apply-transform, indicating top-level call. (lambda-apply-transform): Takes new argument indicating whether it's a recursive call. If the apply list expression is constant, then it is evaluated and treated as a list of arguments which are then turned into quoted constants individually and passed as fixed args in a recursive call. This eliminates the generation of code dealing with run-time evaluation and destructuring of the apply arguments.
* compiler: inline-lambda: optimize generated let.Kaz Kylheku2019-08-081-3/+8
| | | | | | | | | | * share/txr/stdlib/compiler.tl (lambda-apply-transform): We conditionally generate the outer let as an alet, if there are no shadowing issues. The shadowing test is very conservative: the intersection between the argument expressions and the lambda symbols must be empty. Also, we move the gensym for the apply list expression into the let*, because we need a real storage location that we can pop.
* pop: improve expansion.Kaz Kylheku2019-08-081-1/+1
| | | | | | * share/txr/stdlib/place.tl (pop): Use alet for binding the temporary rather than let, so that if (,getter) expands to a symbol, it will disappear.
* compiler: bugfix: eval order in inline lambda.Kaz Kylheku2019-08-071-52/+54
| | | | | | | | | | | | | | | * share/txr/stdlib/compiler.tl (lambda-apply-transform): The expander fails to observe left-to-right evaluation because if the trailing argument form is present, it is evaluated first, even though it is the last argument. Also, the argument evaluations are wrongly interleaved among the default expressions for optional arguments; they must be evaluated firt. We fix all this by allocating gensyms for all of the fixed argument forms, and binding these via an extra let wrapped around the output let* form. When generating the let* we refer to the gensyms instead of the original fixed arguments. This extra let needs optimizing, but it can't just be converted to an alet because of scoping issues.
* compiler: bugfix: scoping issue in inline lambda.Kaz Kylheku2019-08-071-1/+1
| | | | | | | | * share/txr/stdlib/compiler.tl (lambda-apply-transform): The gensym for binding the trailing argument expression must be bound before any of the parameters, otherwise the expression is exposed to the scope of the parameters that have been emitted so far. We use add* to put it at the front.
* expander: bugfix: spurious lambda form warning.Kaz Kylheku2019-08-071-5/+5
| | | | | | | | | | * eval.c (do_expand): In the expansion logic for function calls, after we have done the dot-to-apply transform, we must thereafter consistently refer to the new front element of the form insym, and not the original element sym. The first element may be a lambda form moved into the second position by dot-to-apply. We then falsely warn about that being in the operator position. Test case: ((lambda ()) . 3).
* compiler: inline lambda: incomplete opt param support.Kaz Kylheku2019-08-071-9/+20
| | | | | | | | | | | | | | The compilation of lambdas that are immediately called or applied is missing the support for the Boolean parameters that indicate whether optional arguments are present. * share/txr/stdlib/compiler.tl (lambda-apply-transform): Check whether the opt parameter items from the fun-param-parser object have a third element, the indicator variable, and emit the binding for it. This has to be done in all three cases: optional parameter statically present, statically missing, and dynamically determined from run-time apply list of unknown length.
* @(collect)/@(coll): streamline list accumulation code.Kaz Kylheku2019-08-071-10/+17
| | | | | | | | | * match.c (h_coll, v_collect): Revising the code for accumulating items into lists. Duplicate assoc lookups via assoc and acons_new are eliminated in favor of doing rplacd or acons. We don't call assoc to look up a binding if have_vars is false. car(binding) is called once and captured in the local vaiable sym.
* lib: don't GC-protect two non-heap objects.Kaz Kylheku2019-08-061-1/+1
| | | | | | | | | | * lib.c (obj_init): The null string literal and "nil" do not require gc protection; they cannot be reclaimed by the garbage collector, which ignores them. Don't waste two slots in the prot_stack on them. This is a remnant from ancient TXR; these variables were protected already in Version 11 from September 2009. At that time, there were no built-in string literal objects; these two objects were heap-allocated.
* compiler: remove one-argument or.Kaz Kylheku2019-08-061-1/+1
| | | | | * share/txr/stdlib/compiler.tl (usr:compile-file): Remove useless one-argument use of or operator.
* Version 222.txr-222Kaz Kylheku2019-07-305-181/+213
| | | | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated. * protsym.c: Likewise.
* ffi: bugfix: kind enum in wrong argument positions.Kaz Kylheku2019-07-301-10/+14
| | | | | | | | | | | | * ffi.c (ffi_type_compile, ffi_init_types): Fixed a number of instances of make_ffi_type_builtin being passed the type kind as the fourth rather than the third argument. The strange fluke here is that FFI_KIND_NUM is 1, so this actually made no difference in all the case in ffi_init_types! However in ffi_type_compile, it would have set the type of cptr-s to struct, and its size to 3. Anyway, we were saved from a regression by the good pre-release habit of compiling as C++!
* doc: update FFI struct/union description.Kaz Kylheku2019-07-301-6/+152
| | | | | | | * txr.1: Document existing gensym behavior of nil struct/union tags. Document new rules regarding structs/unions that have no members, redefinitions of complete and incomplete types, and semantics of self-reference.
* doc: fix wrapping save-exe exampleKaz Kylheku2019-07-291-1/+2
| | | | | | * txr.1: Use backslash escape in the save-exe example to break up long string literal, so it won't be wrapped by man at 80 columns.
* FFI: bugfix: GC-correctness of assignments.Kaz Kylheku2019-07-281-0/+11
| | | | | | | | | | | Recent work has introduced wrong-way assignments. When we compile the slots after we have created the type object, the slot types may be in a newer generation than the type object. If we are reusing an old type object, it can be older than the syntax, or the Lisp object being stored in it. * ffi.c (make_ffi_type_struct, make_ffi_type_union): add some setcheck calls to handle anti-generational assignments.
* FFI: bugfix: properly re-use existing struct type.Kaz Kylheku2019-07-281-2/+6
| | | | | | | | | This is a bug in the prior commit's change. * ffi.c (make_ffi_type_struct, make_ffi_type_union): When using an existing type, do not call cobj to make a new Lisp object for the type structure; pull the existing one out from tft->self.
* FFI: self-referential structs.Kaz Kylheku2019-07-281-90/+200
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | With this commit, FFI a struct definitions can contain references to the struct type being defined. It becomes possible to pass a (non-circular) linked list of structures to and from C foreign function. * ffi.c (ffi_kind_t): New enum. We need some tag in the txr_ffi_type struct to indicate type. (ffi_struct_tag_hash): New static variable. (struct txr_ffi_type): New members: kind and flexible. (ffi_struct_in, ffi_struct_get): Use the new flexible bit as an indicator that the struct has a flexible member, rather than the incomplete bit. (make_ffi_type_builtin): Take new argument indicating type kind, and store it in the kind member. (make_ffi_type_pointer): Initialize kind field. (ffi_memb_compile): New static function. (make_ffi_type_struct): No longer receives the list of slot names and their compiled types as arguments. The compiling is done in this function on-the-fly as the slots are initialized, using the ffi_memb_compile function helper. If a same-named struct/union type already exists, this is passed in; the function will replace that type by freeing and reallocating the member vector, clearing the existing struct type to all zero and re-initializing it from scratch. The new kind field is initialized. The incomplete flag is set initially and then updated at the end, so during the processing of the member types, the struct type is considered incomplete. If a struct has no members, it is considered incomplete now. It is flexible only if it ends in a flexible array. The struct type is added to ffi_struct_tag_hash, keyed on its tag. (make_ffi_type_union): Similar changes as in make_ffi_type_struct. (ffi_membs_compile): Function removed. (ffi_type_compile): Change to struct compilation logic. An empty struct definition now avoids creating a Lisp struct type. If a FFI struct type already exists, that one is returned, otherwise an empty one (considered incomplete) is created. A struct definition with members replaces an existing one. The new make_ffi_type_struct interface is used which simplifies things here, since we just pass down the syntax and the existing type, without having to compile the member types. Not a big change for unions: just use the new make_ffi_type_union interface, which requires the existing type, and just the syntax now, rather than compiled slots. For varrays, set the type kind to FFI_KIND_ARRAY, overriding the FFI_KIND_PTR type that is already there due to varrays being implemented as pointers. Perhaps varray should have its own kind, but for now this approach serves fine. For buffer types, set the kind to FFI_KIND_PTR, and for the bitfields, set it to FFI_KIND_NUM. (ffi_init_types): Pass an appropriately-valued kind argument in ach call to the make_ffi_type_builtin constructor. (ffi_init): GC-protect the ffi_struct_tag_hash variable, and initialize it.
* FFI: bugfix: pointer "in" ops must map null to nil.Kaz Kylheku2019-07-271-0/+8
| | | | | | | | | * ffi.c (ffi_ptr_in_in, ffi_ptr_in_d_in, ffi_ptr_out_in, ffi_ptr_out_s_in): If the memory location which holds the pointer to the C object is null, then just return nil. If we don't do this, we then crash trying to extract the object from a null pointer via the recursive tgtft->in or tgtft->get call.
* parser: give start of a bad forms even if line 1.Kaz Kylheku2019-07-261-1/+4
| | | | | | | * parser.y (parse): Emit the "while parsing form starting at line N" even if N is 1. I think the idea here was supposed to be to suppress this additional message for parses that don't advance from the starting line, so I'm fixing it that way.
* FFI: elemtype as type operator, not just macro.Kaz Kylheku2019-07-262-5/+48
| | | | | | | | * ffi.c (elemtype_s): New symbol variable. (ffi_type_compile): Handle elemtype. (ffi_init): Initialize elemtype_s. * txr.1: Document elemtype.
* FFI: document: elemsize and elemtype work on enums.Kaz Kylheku2019-07-262-10/+16
| | | | | | | | * ffi.c (ffi_elemsize, ffi_elemtype): Fix error messages to include enum among possible argument types. * txr.1: Extend documentation for ffi-elemsize and ffi-elemtype to include base integer type of enumerations.