summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* arith: switch sum and prod to seq_iter.Kaz Kylheku2021-06-093-34/+72
| | | | | | | | | | | | | | * arith.c (nary_op_keyfun): Static function removed. (nary_op_seq, nary_op_seq_keyfun): New static functions. (sumv, prodv): Static functions removed. (sum, prod): Reimplement using nary_op_seq and nary_op_seq_keyfun. Conversion of sequence to list smuggled via args is gone. * tests/016/arith.tl: new sum and prod tests. * txr.1: Note about sum and prod taking an iterable sequence added.
* reduce-left: rewrite using seq_iter.Kaz Kylheku2021-06-093-6/+32
| | | | | | | * lib.c (reduce_left): Use sequence iteration instead of list operations. * txr.1: Add a note to the documentation.
* parser: bug #; and #S don't play.Kaz Kylheku2021-06-091-6/+15
| | | | | | | | | When #; is used to comment out syntax containing #S, an attempt is made to instantiate a structure using nil as the type, and an exception occurs. * parser.y (hash, struct, tree): Check for parser->ignore and produce nil instead of making any of these objects.
* ffi: bug: always using ffi_prep_cif_var.Kaz Kylheku2021-06-093-7/+10
| | | | | | | | | | | | | | | * share/txr/stdlib/ffi.c (deffi): Fix misnamed variable. The second value coming from sys:analyze-argtypes is the number of fixed arguments, not the number of variadic arguments. Furthermore, if this number is equal to nargs, we were supposed to have been passing nil instead to ffi-make-call-desc, which indicates the ordinary non-variadic function. We were always always passing a non-nil value, so always requesting variadic. That is fixed now thanks to the change to ffi_make_call_desc. * ffi.c (ffi_make_call_desc): Register the function as variadic if either nfixed is specified as nil, or if it is equal to ntotal. * txr.1: Document the convention change for ffi-make-call-desc.
* ffi: earnest implementation of FFI struct elements.Kaz Kylheku2021-06-091-23/+72
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit tries to address a flaw in our use of libffi. When we construct a structure type, we do not fill in the "elements" array of the libffi type to describe every element. Instead we calculate the size and alignment ourselves. This breaks when passing small structures by value on some platforms. There are some areas where we are still winging it. We allow passing of arrays by value, which are simulated using FFI structure types. To allocate the descriptor earnestly for such an object means allocating an array of ffi_type pointers as large as the array, which is wasteful. So we cap it to 20. This 20 comes form the idea that anything bigger than a 16 byte structure is passed on the stack rather than in registers. For unions, we choose the largest member and inform libffi of its type. * ffi.c (struct txr_ffi_type): elements member changes to from array of 1 to pointer. (ffi_type_struct_destroy_op): Consolidate HAVE_LIBFFI code. Don't bother setting tft->ft->elements to null. Free tft->elements. (ffi_struct_clone): Clone the elements array. (ffi_union_clonse): New static function. Unions need their own clone function now because their elements array has a size not related to the number of members. It contains two pointers, including the null terminating one. (make_ffi_type_struct): Allocate the elements array, and fill it. We wing it around bitfields, which libffi doesn't support. This will be revisited, but it's likely a bad idea to be passing bitfield-endowed structures by value. (make_ffi_type_union): Allocate the elements array to a fixed size of two pointers. Fill it in with the largest member's type. (ffi_array_clone): Clone the elements array, which is up two 20 pointers plus a null terminator. (make_ffi_type_array): Allocate the elements array up to 20 elements plus null pointer, and fill it with repetitions of the element libffi type.
* ffi: fix leak on struct/union redefinition.Kaz Kylheku2021-06-091-0/+6
| | | | | | | * ffi.c (make_ffi_type_struct, make_ffi_type_union): When we are replacing the existing type, if HAVE_FFI is true, we must free the tft->ft object before clobbering the tft with zeros.
* ffi: leak fix on !HAVE_FFI builds.Kaz Kylheku2021-06-091-2/+18
| | | | | | | | | | The ffi_type_struct_destroy_op only frees tft->ft if HAVE_FFI is true. But the object is allocated in several places without regard for HAVE_FFI. * ffi.c (ffi_struct_clone, make_ffi_type_struct, make_ffi_type_union, ffi_array_clone, make_ffi_type_array): Do not allocate a ffi_type object if HAVE_FFI is false.
* tags: recognize deffi-struct.Kaz Kylheku2021-06-081-1/+1
| | | | | * tags.tl (process-form): Recognize deffi-struct together with defstruct.
* tags: handle literals for undefined structures.Kaz Kylheku2021-06-081-0/+1
| | | | | * tags.tl: bind *read-unknown-structs* to t around the file walk.
* parser: new *read-unknown-structs* variable.Kaz Kylheku2021-06-086-283/+310
| | | | | | | | | | | | | | | | | | | | | * parser.c (read_unknown_structs_s): New symbol variable. (parser_common_init): Initialize read_unknown_structs flag member of the parser structure from the new special variable. (parse_init): Initialize read_unknown_struct_s variable. Register the *read-unknown-structs* dynamic variable. * parser.h (struct parser): New member, read_unknown_structs. (read_unknown_structs_s): Declared. * parser.y (struct): Generate the struct literal syntax not only for quasiquoted structures, but for structures with an unknown type name, if the read_unkonwn_structs flag is set. * txr.1: Documented. * share/txr/stdlib/doc-syms.tl: Regenerated. * y.tab.c.shipped: Regenerated.
* lib: new function, fill-vec.Kaz Kylheku2021-06-086-0/+157
| | | | | | | | | | | | | | * eval.c (eval_init): Register fill-vec intrinsic. * lib.c (fill_vec): New function. * lib.h (fill_vec): Declared. * tests/010/vec.tl: New file. * txr.1: Documented. * share/txr/stdlib/doc-syms.tl: Updated.
* ffi: new macros deffi-struct and deffi-union.Kaz Kylheku2021-06-084-1/+40
| | | | | | | | | | | | * lisplib.c (ffi_set_entries): Autoload for deffi-struct and deffi-union symbols. * share/txr/stdlib/ffi.tl (deffi-struct, deffi-union): New macros. * txr.1: Documented. * share/txr/stdlib/doc-syms.tl: Updated.
* expander: expand must only ignores unbound warnings.Kaz Kylheku2021-06-073-6/+38
| | | | | | | | | | | | | | | | | | | The expand function must not muffle all deferred warnings. That causes the problem that a form like (inc var a.bar) fails to produce a warning due to bar not being the slot of any structure. The expand function must only muffle warnings about undefined functions and variables. * eval.c (muffle_unbound_warning): New static function. (no_warn_expand): Use muffle_unbound_warning as handler, rather than uw_muffle_warning. * tests/012/struct.tl: Fix two test cases here which test the expand function using a form that references a nonexistent slot. These now generate a warning, so we use the slot name b rather than d, which is defined. * txr.1: Documented change to expand.
* args: correction in assertion.Kaz Kylheku2021-06-071-1/+1
| | | | | | | * args.c (args_normalize_least): The bug_unless here should be checking that minfill is not beyond argc->argc. That's the situation that would cause the loop to overflow the fixed argument argument storage in args indicated by args->argc.
* ffi: allow conversion of carray objects under cptr.Kaz Kylheku2021-06-062-4/+41
| | | | | | | | | | | | | | * ffi.c (ffi_cptr_put): If the object is not a cptr, try it as a carray. This requires the tft to have an eltype, requiring a change in ffi_type_compile. (ffi_type_compile): When compiling a parametrized cptr object, we now look up the type symbol as a FFI type, and store the result as the tft->eltype. If the symbol is not an FFI type, then this lookup returns nil. If the eltype is non-nil, then there is the possibility it can match the element type of a carray. * txr.1: Documented.
* ffi: allow nil object to convert under closure type.Kaz Kylheku2021-06-062-4/+31
| | | | | | | | * ffi.c (ffi_closure_put): Only diagnose a bad object if it's not nil, otherwise let the null value of p through. This is useful because there are sometimes C interfaces which take an optional function pointer, whereby a null value indicates that the pointer is not specified.
* ffi: add space in ffi-call-desc's printed rep.Kaz Kylheku2021-06-061-1/+1
| | | | | * ffi.c (ffi_call_desc_print_op): Print a space between the class symbol and name so they are not run together.
* dlsym: improve diagnostic.Kaz Kylheku2021-06-051-1/+2
| | | | | | | * sysif.c (dlsym_error): Show the library object and symbol even when the system has a diagnotic. On Cygwin/Cygnal there is a generic "No such process" error that doesn't mention the library or symbol.
* matcher: doc fix, quasiquote examples, new test.Kaz Kylheku2021-06-042-1/+42
| | | | | | | * tests/011/patmatch.tl: New test case. * txr.1: Heading fix: Quasiquote matching notation, not quasiliteral. Examples of quasiquote notation added.
* bugfix: do not expand defun body with name in scope.Kaz Kylheku2021-06-041-4/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is a revert of November 2016 commit 606132c336dbeb0dd8bb851a64c97f2c11b76a85. The commit claims that it fixes a bug, but in fact it introduces one. There is no discussion in that commit about what motivated it. The commit which follows that one introduces a naivey-implemented diagnostic for catching unbound functions at macro-expansion time, so the likely motivation for this wrong fix was to suppress false positives from that naive diagnostic for recursive functions. That has long since been replaced by a better approach. Because of the bug, we cannot do this very useful thing: we cannot write an inline version of a funtion as a macro first, and then a real function which just calls that macro: (defmacro foo (arg) ...) (defun foo (arg) (foo arg)) The bug causes the (foo arg) call in this function not to be expanded, due to the shadowing. * eval.c (do_expand): When expanding defun, do not introduce the function's name as a lexical function binding, because it isn't one.
* FFI: big improvement in bad call diagnosis.Kaz Kylheku2021-06-044-14/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | FFI has the problem that when things go wrong in calls, or in specifications of functions, the diagnostics refer to an internal function like ffi-call or ffi-make-call-desc, which is not helpful in identifying the error. We want the diagnostics to refer to the foreign function, or foreignb callback wrapper, to which the problem pertains. The approach taken is to stick the name symbol into the ffi-call-desc object. Functions which work with a ffi-call-desc can pull out the name and use it for reporting. * ffi.c (struct txr_ffi_call_desc): Add name member. (ffi_call_desc_print_op): Include name in printed representation. (ffi_desc_mark_op): Mark the name. (ffi_make_call_desc): Take new argument to specify the name, storing it into the structure. If it is specified,then use that name for reporting errors, otherwise stick with ffi-make-call-desc. (ffi_call_wrap, ffi_closure_dispatch, ffi_closure_dispatch_safe, ffi_make_closure): Use the name from the call descriptor, or else the function's own name if that is nil. (ffi_init): Update registration of ffi-make-call-desc intrinsic to five arguments with four required. * ffi.h (ffi_make_call_desc): Declaration updated. * share/txr/stdlib/ffi.tl (deffi, deffi-cb-expander): Pass the name symbol down to ffi-make-call-desc. * txr.1: Documented.
* lib: oversight, neglected struct literal printing.Kaz Kylheku2021-06-031-0/+3
| | | | | * lib.c (obj_print_impl): print (sys:struct-lit ...) syntax as #S(...).
* json: fix quasiquote print-read consistency issueKaz Kylheku2021-06-031-10/+24
| | | | | | | | | | | | * lib.c (out_json_rec): When printing keys that might be potentially quasiquoted symbols that look like ~abc, we must avoid the condensed {~abc:~def} style. This is because abd:~def looks like a single symbol, where abc is a package qualifier. To be safe and readable at the same time, we add spaces whenever either the key or the value are conses, indicating non-JSON syntax. Spaces are added on both sides of the colon, and also after the preceding comma, if there is a previous item.
* json: pattern matching test cases and bugfix.Kaz Kylheku2021-06-033-257/+276
| | | | | | | | | | | | | * parser.y (json_val): We must nreverse the json_pairs which were pushed in right to left order. This didn't matter for constructing hashes so it was left out, but under quasiquoting the order matters: it determines the order of evaluation and of pattern matching. * tests/011/patmatch.tl: New quasiquoting pattern matching cases, including JSON. * y.tab.c.shipped: Regenerated.
* quips: new one.Kaz Kylheku2021-06-031-0/+1
| | | | * share/txr/stdlib/quips.tl (sys:%quips%): New entry.
* json: improve escaping for script tags.Kaz Kylheku2021-06-033-14/+58
| | | | | | | | | | | * lib.c (out_json_str): Strengthen the test for escaping the forward slash. It has to occur in the sequence </script rather than just </. Recognize <!-- and --> in the string, and encode them. * tests/010/json.tl: Cover this area with some tests. * txr.1: Documented.
* matcher: better error handling for backquotes.Kaz Kylheku2021-06-022-6/+20
| | | | | | | * share/txr/stdlib/match.tl (transform-qquote): Handle hash error case with separate pattern. Use compile-error and *match form instead of error. Diagnose splicing unquote and nested quasiquote.
* matcher: quasiquote matching.Kaz Kylheku2021-06-022-10/+148
| | | | | | | | | | | | | | | | | | | | | | | This allows (when-match ^(,a ,b) '(1 2) (list a b)) -> (1 2) which is a nice alternative that is supported by some Lisp pattern matchers. We don't need it since we have (@a @b). The motivation is JSON matching. (when-match ^#J{"foo" : {"x" : ~val}} #J{"foo" : {"x" : "y"}} val) -> "y" * share/txr/stdlib/match.tl (compile-match): Recognize qquote case and handle via transform-qquote function. (non-triv-pat-p): Let's declare quasiquotes to be nontrivial. (transform-qquote): New function: transform quasi-quoted syntax into regular pattern matching syntax. * txr.1: Documented.
* json: fix two test cases for Windows.Kaz Kylheku2021-06-021-2/+5
| | | | | | | | | | | | * tests/010/json.tl: on Windows characters are limited to the BMP range 0 to #\xFFFF. The character escape \x10437 is out of range, and so throws an error, simply from that syntax being read. The two test cases which use this character are clumped into their own test form, which is executed conditionally on wide characters being more than two bytes. Because the expression is still parsed on Windows, we read the troublesome character from a string at run-time, and interpolate it.
* solaris: unbundle mkstemp and mkdtemp.Kaz Kylheku2021-06-022-5/+30
| | | | | | | | | | | | | * configure: Solaris 10 doesn't have mkdtemp, so we detect it separately from mkstemp, which Solaris 10 does have, producing HAVE_MKSTEMP and MAKE_MKDTEMP config.h symbols. * stream.c (mkdtemp_wrap): Separately surround with #if HAVE_MKDTEMP. (mkstemp_wrap): Reduce scope of #if HAVE_MKSTEMP only around this function. Bugfix here: in the #else case of #if HAVE_MKSTEMPS, we are calling the mkstemps function instead of mkstemp.
* bug: doc function not working in Windows port.Kaz Kylheku2021-06-021-1/+1
| | | | | * share/txr/stdlib/doc-lookup.tl (open-url): Handle :cygnal together with :cygwin.
* Version 261txr-261Kaz Kylheku2021-06-017-791/+892
| | | | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Bumped. * txr.vim, tl.vim: Regenerated. * protsym.c: Likewise.
* doc: rearrangement in Data Interchange SupportKaz Kylheku2021-06-011-34/+34
| | | | | * txr.1: Move the json macro description to the beginning of the section.
* doc: put-json: numbering, include U+007F.Kaz Kylheku2021-06-011-4/+4
| | | | | * txr.1: Fix duplicate 4. bullet; mention the that control character U+007F is rendered as an escape also.
* Pre-release C++ upkeep.Kaz Kylheku2021-06-012-5/+5
| | | | | | | | * stream.c (mkdtemp_wrap): Rename template argument to prefix, because template is a C++ keyword. (mkstemp_wrap): Rename local variable from template to templ. * stream.h (mkdtemp_wrap): Rename template argument.
* vim: handle more kinds of unquotes in JSON.Kaz Kylheku2021-06-011-2/+4
| | | | | | * genvim.txr (list): Add txr_junqbkt: unquoted bracket. (txr_junqlist): Support optional # for vector syntax. (txr_junqbkt): New region for unquoted bracket expressions.
* vim: improve JSON highlighting.Kaz Kylheku2021-06-011-11/+23
| | | | | | | | | | | | | | | | | | * genvim.txr (ws, jlist, jsonkw, jerr, jpunc, jesc, juesc, jnum): New variables. (txr_circ): Move down; this somehow clashes with JSON regions beginning with #, so that even if we include txr_circ in JSON regions, it doesn't work properly. (txr_jerr, txr_jpunc, txr_jesc, txr_juesc, txr_jnum): Define using variables. (txr_jkeyword): Switch to regex match instead of keyword. Vim 8.0 does not recognize keywords when they are glued to #J, as in #Jtrue, even though #J is excluded from the region. (txr_jatom): New region. (txr_jarray, txr_jhash): Define using jlist variable for contained items. (txr_jarray_in, txr_jhash_in): New regions for the inner parts without the #J.
* chr-iscntrl: recognize Unicode C0 and C1.Kaz Kylheku2021-06-012-4/+13
| | | | | | | | * lib.c (chr_iscntrl): Don't use iswcntrl; it fails to report 0x80-0x9F as control characters. A bit of hand-crafted logic does the job. * txr.1: Redocumented.
* build: improved mechanism for copying .shipped files.Kaz Kylheku2021-06-011-3/+9
| | | | | | | | | | | * Makefile (SHIPPED): New variable, holds names of files that get copied to a .shipped suffix and commited to the repo. (ABBREV3SH): New macro, version of ABBREV3 that doesn't assume it is expanding an entire recipe line, and thus can be embedded into shell commands. (%.shipped): Rule removed. (shipped): New rule that prints what it is copying. Non-maintainer version of rule errors out.
* build: produce output when copying .shipped files.Kaz Kylheku2021-06-011-0/+1
| | | | | | | | | * Makefile (%.shipped): Call the ABBREV macro to produce output when "make *.shipped" is invoked, otherwise unless VERBOSE=1 is used, it works silently. This is only in maintainer mode. The rule in regular mode has the ABBREV call. (But should we have that rule at all outside of maintainer mode?)
* sysif: utimes: internal naming cleanup.Kaz Kylheku2021-06-011-4/+4
| | | | | | | * sysif.c (wrap_utimes, wrap_lutimes): Rename static functions to utimes_wrap and lutimes_wrap, the convention used everwhere for wrappers of library functions. (sysif_init): Follow rename.
* json: turn on indentation.Kaz Kylheku2021-05-311-12/+7
| | | | | | | | * lib.c (put_json): Turn on indentation if the flat argument doesn't suppress it, and the stream is not in forced-off indentation mode. (tojson): Retarget to put_json, so we don't have to repeat this logic.
* json: wrap up: test cases, fixes, tweaks.Kaz Kylheku2021-05-315-23/+169
| | | | | | | | | | | | | | | | | | | | | * /share/txr/stdlib/getput.tl (get-jsons): If the s parameter is a string, convert it to a byte input stream so that. (put-jsons): Add missing t return value. (file-put-json, file-append-json, file-put-jsons, file-append-jsons, command-put-jsons, command-put-jsons): Add missing object argument to all these functions, and a missing "w" open-file mode to several of them. * stream.c (mkstemp_wrap): Calculate length of suff the defaulted argument, not the raw suffix argument. * test/010/json.tl: New file, providing tests that touch every area of the new JSON functionality. * tests/common.tl (mstest, with-temp-file): New macros. * txr.1: Document that get-jsons takes a source which could be a string.
* parser: gc bug in token.Kaz Kylheku2021-05-312-0/+3
| | | | | | | | | | | | | | The parser maintains some token objects for one parse job to the next in the tok_pushback and recent_tok arrays. When the recent_tok is assigned into the parser, it could be a wrong-way assignment: the parser is a gen 1 object, yet the token's semantic value of type val is a gen 0. * parser.c (lisp_parse_impl, txr_parse): Before re-enabling gc, indicate that the parser object may have been mutated by a wrong-way assignment using the mut macro. * txr.c (txr_main): Likewise.
* json: fix unquote parsing issue in quasiquotes.Kaz Kylheku2021-05-312-3304/+3428
| | | | | | | | | | | | | | | | | | | | | The big comment I added above end_of_json_unquote summarizes the issue. This issue has been uncovered by some test cases in a JSON test suite, not yet committed. * parser.l <JMARKER>: New start condition. Used as a reliable marker in the start condition stack, based on which end_of_json_quasiquote can intelligently fix-up the stack. (JSON): In the transitions to the quasiquote scanning NESTED state, push the JMARKER start condition before NESTED. (JMARKER): The lexer should never read input in the JMARKER state. If we don't put in a rule to catch this, if that ever happens, the lexer will just copy the source code to standard output. I ran into this during debugging. (end_of_json_unquote): Rewrite the start condition stack intelligently based on what the Lisp lookahead token has done to it, so parsing can smoothly continue. * lex.yy.c.shipped: Regenerated.
* json: fix circular printing.Kaz Kylheku2021-05-311-21/+34
| | | | | | | | | | | | | | | | | The recursive JSON printer must check for the circularity circularity-related conditions and emit #n= and #n# notations. * lib.c (circle_print_eligible): Function moved before out_json_rec to avoid a forward declaration. (check_emit_circle): New static function. This is a block of code for doing the circular logic, taken out of obj_print_impl, because we would like to use it in out_json_rec. (out_json_rec): Call check_emit_circle to emit any #n= or #n# notation. The function returns 1 if it has emitted #n#, in which a se we are done. (obj_print_impl): Replace moved block of code with call to check_emit_circle.
* New: mkdtemp and mkstemp functions.Kaz Kylheku2021-05-315-0/+165
| | | | | | | | | | | | | | | | * configure: check for mkstemp and mkdtemp. * stream.c (stdio_set_prop): Implement setting the :name property. We need this in mkstemp_wrap in order to punch in the temporary name, so that the application can retrieve it. (mkdtemp_wrap, mkstemp_wrap): New functions. (stream_init): Register mkdtemp and mkstemp intrinsics. * stream.h (mkdtemp_wrap, mkstemp_wrap): Declared. * txr.1: Documented. * share/txr/stdlib/doc-syms.tl: Updated.
* New function: tmpfile.Kaz Kylheku2021-05-314-0/+40
| | | | | | | | | | | * stream.c (tmpfile_wrap): New static function. (stream_init): Register tmpfile intrinsic. * stream.h (tmpfile_wrap): Declared. * txr.1: Documented. * share/txr/stdlib/doc-syms.tl: Updated.
* doc: document all json I/O convenience routines.Kaz Kylheku2021-05-302-86/+339
| | | | | | | | | * txr.1: Documented file-get-json, file-put-json, file-append-json, file-get-jsons, file-put-jsons, file-append-jsons, command-get-json, command-put-json, command-get-jsons, command-put-jsons. * share/txr/stdlib/doc-syms.tl: Updated.
* doc: put-json and put-jsonl return the object.Kaz Kylheku2021-05-301-0/+7
| | | | * txr.1: Document return value of put-json and put-jsonl.