| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/pmac.tl (macroexpand-params): New function,
implemented using newly exposed sys:expand-param-macro.
* autoload.c (pmac_set_entries): Trigger pmac.tl autload
on macroexpand-params symbol.
* eval.c (eval_init): Register existing expand_param_macro
function as sys:expand-param-macro.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (pct_fun_s): New symbol variable, holding
the usr:%fun% symbol.
(fun_macro_env): New static function.
(do_expand): For defun and defmacro, use fun_macro_env
to establish an environment binding the %fun% symbol
macro, and expand everything in that environment.
(eval_init): Intern the %fun% symbol, initializing
pct_fun_s, and also register a global symbol macro in
that name so that we can freely use %fun% everywhere
without worrying that the code will blow up.
E.g. a logging macro can use it to get the function name,
but still be useful in a top-level form outside of
a named function.
* stdlib/struct.tl (sys:meth-lambda): New macro.
(defstruct, defmeth): Use sys:meth-lambda as a replacement
for lambda to set up the %fun% symbol macro. In the :init
case which doesn't use a lambda, an open-coded symacrolet
does the job.
* tests/019/pct-fun.tl: New file.
* tests/019/pct-fun.expected: Likewise.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (lazy_stream_s): New symbol variable.
(lazy_streams_binding): New static variable.
(lazy_stream_register): New static function
(lazy_stream_cons): If the stream is associated with
a lazy cons, register it with lazy_stream_register.
(obj_init): gc-protect lazy_streams_binding variable.
Intern the sys:*lazy-streams* symbol.
* lib.h (lazy_streams_s): Declared.
* eval.c (eval_init): Register sys:*lazy-streams*
special variable.
* stdlib/getput.tl (close-lazy-streams): New macro.
* autoload.c (getput_set_entries): Trigger autload on
close-lazy-streams symbol.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): search-all intrinsic registered.
* lib.c (search_common): New Boolean argument all,
indicating whether all positions are to be returned.
We must handle this in the two places where empty
key and sequence are handled, and also in the main loop.
A trick is used: the found variable is now bound by
list_collect_decl, but not used for collecting unless
all is true.
(search, rsearch, contains): Pass 0 for all argument
of search_common.
(search_all): New function.
* lib.h (search_all): Declared.
* tests/012/seq.tl: New tests.
* txr.1: Documented.
* stdlib/doc-syms.tl: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The general count function, with keyfun and testfun,
is noticeably absent. Let's implement it.
* lib.[ch] (count): New function.
* eval.c (eval_init): Register count intrinsic.
* tests/012/seq.tl: Some tests for count.
* txr.1: Add count to count-if section. Revise documentation
based on pos/pos-if.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (me_for): Require at least one argument.
However, we let the init-forms continue to be optional
and document it.
* txr.1: Refer to for and for* as macros, since they have been
since 2016. The omission of the inc-form list is shown
as a second variant of the syntax. This is to avoid misleading
the reader into thinking that the the inc-form list can be
omitted while body forms are present. A spurious paragraph
reiterating that the macros establish an anonymous block is
removed. That extra text was present in the first draft written
in 2011, and maintained since.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The str function is like mkstring but allows a fill pattern
to be specified.
* eval.c (eval_init): str intrinsic registered.
* lib.[ch[ (str): New function.
* tests/015/str.tl: New file.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Instead of trying to work the new count parameter into the spl and
tok functions, it's better to make new ones.
* eval.c (eval_init): spln and tokn intrinsics registered.
* lib.[ch] (spln, tokn): New functions.
* tests/015/split.tl: New test cases.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Update registration of tok-str.
* lib.c (tok_str): New argument, count_opt. Implemented
in the compat 155 case; what the heck.
(tok): Pass nil to new parameter of tok_str.
* lib.h (tok_str): Declaration updated.
* tests/015/split.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
| |
* eval.c (error_trace): Don't mention that --backtrace can be
used to enable backtraces. This is not only a nuisance, but
appears in packaged programs which do not support such an option,
making it highly misleading.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Fix up registration of split-str to
account for new parameter.
* lib.c (split_str_keep): Implement new optional count
argument.
(spl): Pass nil value to split_str_keep for new argument.
I'd like this function to benefit from this argument also,
but the design isn't settled.
(split_str): Pass nil argument to split_str_keep.
* lib.h (split_str_keep): Declaration updated.
* tests/015/split.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (do_expand): When a function call's arguments are
expanded and produce a transformation, then if that function
call had been produced by a macro, the transformed function
call is tried again as a macro. This is necessary because
TXR Lisp allows a symbol to be both a function and macro.
When a macro-produced function call's arguments are expanded,
the macro version of that function may, as a result of the
argument transformations, have more opportunities for expansion.
* txr.1: New section outlining how macro expansion generally
works, with a special focus on this unusual new rule.
|
|
|
|
|
|
|
| |
* eval.c (load): Use path_cat and dir_name instead of ad hoc
path munging.
* match.c (v_load): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (load_search_dirs_s): New symbol variable.
(load): Initialize the name variable whose address is passed
as the third argument of open_txr_file, which is now
an in-out parameter. Pass t for the new search_dirs parameter,
so that load benefits from the searching.
(eval_init): Initialize load_search_dirs_s and register the
*load-search-dirs* special variable.
* eval.h (load_search_dirs_s): Declared.
(load_search_dirs): New macro.
* match.c (v_load): Initialize the variable passed as third argument
of open_txr_file.
* parser.c (open_txr_file): Take a new argument, search_dirs.
If this is t, it tells the function "if the path is not found,
then recurse on the *load-search-dirs* variable. Otherwise,
if the value is not t, it is a list of the remaining directories
to try. The existing parameter orig_in_resolved_out must now
point to a location which is initialized. It is assumed to hold
the original target that was passed to the load function.
The first_try_path is a the path to actually try, derived from
that one. Thus, the caller of open_txr_file gets to determine
the initial try path using its own algorithm. Then any recursive
calls that go through *load-search-dirs* will pass a first argument
which is made of the original name, combined with a search dir.
(load_rcfile): Pass pointer to initialized location as third
argument of open-txr_file, and pass a nil value for search_dirs:
no search takes place when looking for that file, which is at a
single, fixed location.
* parser.h (open_txr_file): Declaration updated.
* txr.c (sysroot_init): Initialize *load-search-dirs*.
(txr_main): Ensure third argument in all calls to open_txr_file
points to initialized variable, with the correct value,
and pass t for the search_dirs argument.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
New: load can search multiple directories.
* eval.c (load_search_dirs_s): New symbol variable.
(load): Initialize the name variable whose address is passed as
the third argument of open_txr_file, which is now an in-out
parameter. Pass t for the new search_dirs parameter, so that
load benefits from the searching.
(eval_init): Initialize load_search_dirs_s and register the
*load-search-dirs* special variable.
* eval.h (load_search_dirs_s): Declared.
(load_search_dirs): New macro.
* match.c (v_load): Initialize the variable passed as third
* argument
of open_txr_file.
* parser.c (open_txr_file): Take a new argument, search_dirs.
If this is t, it tells the function "if the path is not found,
then recurse on the *load-search-dirs* variable. Otherwise, if
the value is not t, it is a list of the remaining directories
to try. The existing parameter orig_in_resolved_out must now
point to a location which is initialized. It is assumed to hold
the original target that was passed to the load function. The
first_try_path is a the path to actually try, derived from that
one. Thus, the caller of open_txr_file gets to determine the
initial try path using its own algorithm. Then any recursive
calls that go through *load-search-dirs* will pass a first
argument which is made of the original name, combined with a
search dir.
(load_rcfile): Pass pointer to initialized location as third
argument of open-txr_file, and pass a nil value for
search_dirs: no search takes place when looking for that file,
which is at a single, fixed location.
* parser.h (open_txr_file): Declaration updated.
* txr.c (sysroot_init): Initialize *load-search-dirs*.
(txr_main): Ensure third argument in all calls to open_txr_file
points to initialized variable, with the correct value, and
pass t for the search_dirs argument.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register isecp intrinsic.
* lib.c (isecp): New function.
* lib.h (isecp): Declared.
* stdlib/compiler.tl (lambda-apply-transform,
dump-compiled-objects): Use isecp instead of isec, since the
actual intersection of symbols isn't needed, only whether it
exists.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register partition-if intrinsic.
* lib.c (partition_if_countdown_funv, partition_if_func): New
functions.
(partition_if): New function.
* lib.h (partition_if): Declared.
* tests/012/seq.tl: New test cases.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register find-max-key and find-min-key
intrinsics.
* lib.c (find_max_key, find_min_key): New functions.
* lib.h (find_max_key, find_min_key): Declared.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Makefile (OBJS): rename lisplib.o to autoload.o.
* lisplib.c: Renamed to autoload.c.
(lisplib_init_tables): Renamed to autoload_init_tables.
(lisplib_init): Renamed to autoload_init, and calls
autoload_init_tables.
(lisplib_try_load): Renamed to autoload_try.
(autoload_try_fun, autoload_try_var, autloload_try_slot,
autoload_try_struct, autoload_try_keyword): Follow rename.
* lisplib.h: Renamed to autoload.h.
(lisplib_init): Renamed to autoload_init.
* eval.c: Include autoload.h.
(eval_init): Follow rename of lisplib_init.
* gencadr.txr: include "autoload.h"
* cadr.c: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lisplib.c (lisplib_init): Follow rename, and rename
try-load-fun to autoload-try-fun.
(lisplib_try_load_fun, lisplib_try_load_var,
lisplib_try_load_fun_var, lisplib_try_load_slot,
lisplib_try_load_struct, lisplib_try_load_keyword):
Renamed from `lisplib_try_load_@kind` to `autoload_try_@kind`.
* lisplib.h (lisplib_try_load_fun, lisplib_try_load_var,
lisplib_try_load_fun_var, lisplib_try_load_slot,
lisplib_try_load_struct, lisplib_try_load_keyword):
Declarations renamed.
* eval.c (lookup_global_var, lookup_sym_lisp1, lookup_fun,
lookup_mac, lookup_symac, lookup_symac_lisp1, special_var_p,
expand_param_macro, rt_defvar, rt_defv, op_defsymacro,
rt_defsymacro, rt_defun, rt_defmacro, makunbound, fmakunbound,
mmakunbound): Follow rename.
* struct.c (make_struct_type, find_struct_type,
lookup_slot_load, lookup_static_slot_load,
lookup_static_slot_desc_load, slot_types, static_slot_types):
Follow rename.
* stdlib/place.tl (get-place-macro): Follow rename of
try-load-fun to autoload-try-fun.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lisplib.c (lisplib_init): Change sys:try-load (only used by
place.tl) to sys:try-load-fun, and register it to
(lisplib_try_load): External function becomes static.
(lisplib_try_load_fun, lisplib_try_load_var,
lisplib_try_load_fun_var, lisplib_try_load_slot,
lisplib_try_load_struct, lisplib_try_load_keyword): New
functions.
* lisplib.h (lisplib_try_load): Declaration removed.
(lisplib_try_load): External function becomes static.
(lisplib_try_load_fun, lisplib_try_load_var,
lisplib_try_load_fun_var, lisplib_try_load_slot,
lisplib_try_load_struct, lisplib_try_load_keyword): Declared.
* eval.c (lookup_global_var, lookup_var, lookup_symac,
lookup_symac_lisp1, rt_defvarl, rt_defv, op_defsymacro,
rt_defsymacro, makunbound): Use lisplip_try_load_var.
(lookup_fun, lookup_mac, rt_defun, rt_defmacro, fmakunbound,
mmakunbound): Use lisplib_try_load_fun.
(expand_param_macro): Use lisplib_try_load_keyword, which is
a catch-all namespace for anything tied to keywords.
* struct.c (make_struct_type, find_struct_type): Use
lisplib_try_load_struct.
(lookup_sloat_load, lookup_static_slot_load,
lookup_static_slot_desc_load, slot_types, static_slot_types):
Use lisplib_try_load_slot.
* stdlib/place.tl (get-place-macro): Use try-load-fun,
rather than try-load.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (me_macro_time): New static function
(do_expand): Remove handling of macro_time_s.
(eval_init): Remove special operator registration of
macro-time; add macro registration.
* txr.1: Documentation of macro-time updated, revised
and moved from the top the Macros section to be adjacent
to equot.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (load): Use null_string instead of lit("").
* lib.c (obj_init): Likewise.
* match.c (LOG_MATCH, LOG_MISMATCH, do_txeval): Likewise.
* parser.c (regex_parse, lisp_parse_impl, find_matching_syms):
Likewise.
* stream.c (do_parse_mode): Likewise.
* txr.c (sysroot_init): Likewise.
(txr_main): Replace string(L"") with null_string.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): copy-cptr intrinsic registered.
* lib.c (copy_cptr): New function.
(copy): Use copy_cptr for CPTR objects.
* lib.h (copy_cptr): Declared.
* tests/017/ffi-misc.tl: New test cases.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.[ch] (lookup_global_var_l): Remove.
* itypes.[ch] (c_schar): Likewise.
* lib.[ch] (null_list, rcyc_list, gequal, func_n6v, func_n7v,
func_n8v, do_pa_123_23, pa_123_23, orf, aconsql_new_c):
Likewise.
(obj_init): Remove references to null_list.
* mpi/mpi-config.h (MP_FOR_TXR): New preprocessor symbol,
defined as 1.
* mpi/mpi.c (mp_get_prec, mp_set_prec, mp_init_array,
mp_clear_array, mp_set_word, mp_exptmod_d, mp_cmp_d,
mp_cmp_mag, mp_cmp_int, mp_lcm, mp_xgcd, mp_invmod,
mp_char2value): Exclude using #if !MPI_FOR_TXR, rather
than remove. We don't bother excluding the declarations in the
header.
* utf8.[ch] (w_freopen): Remove.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (me_nand, me_nor, nor_fun, nand_fun): New functions.
(eval_init): Register new intrinsics.
* lib.c (nandv, norv): New functions.
* lib.h (nandv, norv): Declared.
* txr.1: Documented, along with trivial fixes to the descriptions
of and, or, andf, orf and notf.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Bugfix: the newly introduced @.expr fails in the
dotted position because ^(a . @,expr) turns
into (list 'a 'let ...).
* eval.c (is_meta_unquote): New static function.
(expand_qquote_rec): Replace existing shape test with
is_meta_unquote. We must also use this test in one more place:
whenever the cdr of a list has the meta unquote shape,
we must treat the result similarly to a dotted atom, by
converting to append format.
* tests/010/qquote.tl: Test cases to cover this.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
For better or worse, TXR Lisp has a dichotomy of
representation that @<atom> produces sys:var syntax, whereas
@<compound> produces sys:expr. This can cause an issue in
backquoting. Suppose you want to use backquote to generate
sytax like (a @b) where the b comes from a variable.
The problem is that (let ((x 'b)) ^(a @,x)) doesn't do
what you might expect: it produces (sys:expr b) rather
than (sys:var b).
This patch adds a hack into the quasiquote expander which
causes it to generate code to do what you expect.
Old behavior:
1> (expand '^(a @,x))
(list 'a (list 'sys:expr x))
New behavior:
1> (expand '^(a @,x))
(list 'a (let ((#:g0012 x))
(if (atom #:g0012)
(list 'sys:var #:g0012)
(list 'sys:expr #:g0012))))
In other words, x will be evaluted, and the based on the
type of the object which emerges, either sys:var or
sys:expr syntax is generated.
* eval.c (expand_qquote_rec): Implement the above hack.
We are careful to only do this when this exact shape occurs
in the syntax: (sys:expr (sys:unquote item)).
* tests/010/qquote.tl: New file.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
User vapnik spaknik was asking in the mailing list whether
there is an existence test for TXR pattern functions. Now
there is.
* eval.c (eval_init): Register match-fboundp intrinsic.
* match.c (match_fbound): New function.
* match.h (match_fbound): Declared.
* tests/011/txr-case.txr: New test cases.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
*LICENSE, LICENSE-CYG, METALICENSE, Makefile, alloca.h,
args.c, args.h, arith.c, arith.h, buf.c, buf.h, cadr.c,
cadr.h, chksum.c, chksum.h, chksums/crc32.c, chksums/crc32.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,
lex.yy.c.shipped, lib.c, lib.h, linenoise/linenoise.c,
linenoise/linenoise.h, lisplib.c, lisplib.h, match.c, match.h,
parser.c, parser.h, parser.l, parser.y, protsym.c, psquare.h,
rand.c, rand.h, regex.c, regex.h, signal.c, signal.h,
socket.c, socket.h, stdlib/arith-each.tl, stdlib/asm.tl,
stdlib/awk.tl, stdlib/build.tl, stdlib/cadr.tl,
stdlib/compiler.tl, stdlib/constfun.tl, stdlib/conv.tl,
stdlib/copy-file.tl, stdlib/debugger.tl, stdlib/defset.tl,
stdlib/doloop.tl, stdlib/each-prod.tl, stdlib/error.tl,
stdlib/except.tl, stdlib/ffi.tl, stdlib/getopts.tl,
stdlib/getput.tl, stdlib/hash.tl, stdlib/ifa.tl,
stdlib/keyparams.tl, stdlib/match.tl, stdlib/op.tl,
stdlib/optimize.tl, stdlib/package.tl, stdlib/param.tl,
stdlib/path-test.tl, stdlib/pic.tl, stdlib/place.tl,
stdlib/pmac.tl, stdlib/quips.tl, stdlib/save-exe.tl,
stdlib/socket.tl, stdlib/stream-wrap.tl, stdlib/struct.tl,
stdlib/tagbody.tl, stdlib/termios.tl, stdlib/trace.tl,
stdlib/txr-case.tl, stdlib/type.tl, stdlib/vm-param.tl,
stdlib/with-resources.tl, stdlib/with-stream.tl,
stdlib/yield.tl, stream.c, stream.h, struct.c, struct.h,
strudel.c, strudel.h, sysif.c, sysif.h, syslog.c, syslog.h,
termios.c, termios.h, time.c, time.h, tree.c, tree.h, txr.1,
txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h, vm.c, vm.h,
vmop.h, win/cleansvg.txr, y.tab.c.shipped: Copyright year
bumped to 2022.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It is against TXR coding conventions to use the C cast
notation. The usage creeps into the code. To find instances of
this, we must compile using GNU g++, and add -Wold-style-cast
via EXTRA_FLAGS.
* eval.c (prof_call): Use macro instead of cast.
* ffi.c (pad_retval, ffi_varray_alloc, make_ffi_type_union,
carray_dup, carray_replace, uint_carray, int_carray,
put_carray, fill_carray): Likewise.
* itypes.c (c_i64, c_u64): Likewise.
* lib.c (cyr, chk_xalloc, spilt_str_keep, vector,
cobj_register): Likewise.
* linenoise.c (record_undo): Likewise. Also, drop one
superfluous cast: wstrdup_fn returns wchar_t *.
(flash, edit_insert, edit_insert_str): Use macro instead of cast.
* mpi/mpi.c (s_mp_ispow2d): Likewise.
* parser.c (lino_getch): Likewise.
* rand.c (make_random_state, random_buf): Likewise.
* stream.c (generic_get_line, do_parse_mode): Likewise.
* struct.c (get_duplicate_supers, call_initfun_chain,
call_postinitfun_chain): Likewise.
* sysif.c (c_time): Likewise.
* tree.c (tr_insert): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The use of -ansi doesn't by itself diagnose instances of some
constructs we don't want in the project, like mixed
declarations and statements.
* configure (diag_flags): Add -Werror=declaration-after-statement.
This is C only, so filter it out for C++.
Also add -Werror=vla.
* HACKING: Update inaccurate statements about what dialect we
are using. TXR isn't pure C90: some GCC extensions are used.
We even use long long if the configure script detects it as
working, and some C99 library features.
* buf.c (replace_buf, buf_list): Fix by reordering.
* eval.c (op_dohash, op_load_time_lit): Fix by reordering.
* ffi.c (ffi_simple_release): Fix by reordering.
(align_sw_get): Fix empty macro to expand to dummy declaration
so a semicolon after it isn't interpreted as a statement.
On platforms with alignment, remove a semicolon from the macro
so that it requires one.
(ffi_i8_put, ffi_u8_put): Fix by reordering.
* gc.c (gc_init): Fix with extra braces.
* hash.c (hash_init): Fix by reordering.
* lib.c (list_collect_revappend, sub_iter, replace_str,
replace_vec, mapcar_listout, mappend, mapdo, window_map_list,
subst): Fix by reordering.
(gensym, find, rfind, pos, rpos, in, search_common): Fix by
renaming optional argument and using declaration instead of
assignment.
* linenoise/linenoise.c (edit_in_editor): Fix by reordering.
* parser.c (is_balanced_line): Fix by reordering.
* regex.c (nfa_count_one, print_rec): Fix by reordering.
* signal.c (sig_mask): Fix by reordering.
* stream.c (get_string): Fix by renaming optional argument and
using declaration instead of assignment.
* struct.c (lookup_static_slot_desc): Fix by turning mutated
variable into block local.
(umethod_args_fun): Fix by reordering.
(get_special_slot): Fix by new scope via braces.
* sysif.c (usleep_wrap): Fix by new scope via braces.
(setrlimit_wrap): Fix by new scope via braces.
* time.c (time_string_meth, time_parse_meth): Fix by reordering.
* tree.c (tr_do_delete_spec): Fix by new scope via braces.
* unwind.h (uw_block_beg): New macro which doesn't define
RESULTVAR but expects it to refers to an existing one.
(uw_block_begin): Replace do while (0) with enum trick
so that we have a declaration that requires a semicolon,
rather than a statement, allowing declarations to follow.
(uw_match_env_begin): Now opens a scope and features the
same enum trick as in uw_block_begin.
This fixes a declaration-follows-statement issue in
the v_output function in match.c.
(uw_match_env_end): Closes scope opened by uw_match_env_begin.
* unwind.c (revive_cont): Fix by introducing variable, and
using new uw_block_beg macro.
* vm.c (vm_execute_closure): Fix using combination of local
variable and reordering.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This bug affects optional parameters which either
have no default expression, or one that is nil.
For instance x in (lambda (: (x nil))) or (lambda (: x)).
When such a parameter is given the : symbol as an argument, it
is not being bound, as if it weren't there.
((lambda (: x) x) :) -> ;; error: unbound variable x
This issue is not a regression; it was introduced in the
commit which introduced the colon convention to optionals, as
well as init expressions and presence-indicating variables,
commit 68c084269581f32f0a7b859446ae2efb6c6a26c0 made in
February 2014.
This might be the first instance of an interpreter bug being
found that is not present in the compiler.
* eval.c (bind_args): The idea here was that when the argument
to an optional the colon keyword symbol, and the optional's
initform is nil, we can skip the overhead of calling eval to
get that initform's value. Unfortunately, the skip was
extended over the code which binds the parameter. Only
the eval can be skipped!
* tests/012/lambda.tl: New test cases to cover this.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register pairlis intrinsic.
* lib.c, lib.h (pairlis): New function.
* tests/012/seq.tl: New test cases.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register new intrinsics.
* lib.c, lib.h (subq, subql, subqual, subst): New functions.
* tests/012/seq.tl: New test cases.
* stdlib/optimize.tl (subst): Function removed. The new subst
drop-in replaces this one.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There are cases when maprodo returns a non-nil value, even
though it is supposed to collect nothing. This is because
though it is is collecting nothing, that nothing is sometimes
converted to an alternative return type via make_like.
* eval.c (prod_common): We allow the collect_fn function
pointer to be null, to indicate nothing is to be collected,
rather than using a stub. If collect_fn is null, we just call
the mapping function without collecting its value, and at the
end, we do not involve make_like and just return nil.
(collect_nothing): Static function removed.
(maprodo): Pass null function pointer instead of collect_nothing.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (me_case): Reduce (key) to key only if key is
an atom. Otherwise we reduce ((a b c)), which
is a single list-valued key to (a b c), which looks like
three keys. This was introduced on Oct 25, 2017 in
commit b72c9309c8d8f1af320dce616a69412510531b48,
making it a regression.
* tests/012/case.tl: New file. The last test
case fails without this bugfix. The others pass either way.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): nrot, rot intrinsics registered.
* lib.c (nrot, rot): New functions.
* lib.h (nrot, rot): Declared.
* tests/012/seq.tl: New test cases.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register tuples* intrinsic.
* lib.c (tuples_star_func): New static function.
(tuples_star): New function.
* lib.h (tuples_star): Declared.
* tests/012/seq.tl: New test cases.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
| |
Calling maprodo with one list argument would fall back on mappend
rather than mapdo.
* eval.c (maprodo): mappendv -> mapdov.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Basic idea: when we throw an exception that pertains to a
system error which has an errno code, we can stick the errno
into the memory area of the character string, into the wchar_t
that immediately follows the null terminator. We can do this
because strings track their actual allocation size.
A pair of setter/getter functions to set and retrieve this
value are provided, and all functions in the code which can
set such a code are updated to do so, simply by calling the
newly added uw_ethrowf that drop-in replaces for uw_throwf.
* lib.[ch] (string_set_code, string_get_code): New functions.
* unwind.[ch] (uw_ethrowf): New function.
* eval.c (eval_init): Register string-set-code and
string-get-code intrinsics.
* ftw.c (ftw_wrap): Switch to uw_ethrowf.
* parser.c (open_txr_file): Likewise.
* socket.c (dgram_overflow): Store the ENOBUFS error in errno,
and use uw_ethrowf instead uw_throwf.
(dgram_get_byte_callback, dgram_flush, sock_bind, to_connect,
open_sockfd, sock_connect, sock_listen, sock_accept,
sock_shutdown, sock_timeout, socketpair_wrap): Switch to
uw_ethrowf.
* stream.c (dev_null_get_fd, stdio_maybe_read_error,
stdio_maybe_error, stdio_close, pipe_close, open_directory,
open_file, open_fileno, open_tail, fds_subst,
open_subprocess, open_command, remove_path, rename_path,
tmpfile_wrap, mkdtemp_wrap, mkstemp_wrap): Switch to uw_ethrowf.
* sysif.c (mkdir_wrap, ensure_dir, chdir_wrap, getcwd_wrap,
rmdir_wrap, mknod_wrap, mkfifo_wrap, chmod_wrap, do_chown,
symlink_wrap, link_wrap, readlink_wrap, close_wrap, val
exec_wrap, stat_impl, do_utimes, pipe_wrap, poll_wrap,
getgroups_wrap, setuid_wrap, seteuid_wrap, setgid_wrap,
setegid_wrap, setgroups_wrap, getresuid_wrap, setresuid_wrap,
setresgid_wrap, crypt_wrap, uname_wrap, opendir_wrap,
getrlimit_wrap, setrlimit_wrap): Likewise.
* termios.c (tcgetattr_wrap, tcsetattr_wrap, tcsendbreak_wrap,
tcdrain_wrap, tcflush_wrap, tcflow_wrap): Likewise.
* tests/018/errno.tl: New file.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register string-finish intrinsic.
* lib.c (string_finish): New function.
* lib.h (string_finish): Declared.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A Boolean optional argument to string-extend indicates whether
this is likely the last call to string-extend, so memory can
be trimmed accordingly.
* eval.c (eval_init): Update string-extend registration.
* filter.c (trie_filter_string): Pass nil for new argument of
string_extend.
* lib.c (str_seq, replace_str,
lazy_str_force, lazy_str_force_upto): Pass nil for new
argument of string_extend.
(rem_impl, remove_if, separate): Pass t for new argument of
string_extend on last iteration, nil otherwise.
(string_extend): Implement new third argument, defaulted to
nil. Switch from chk_grow_vec to the more specific chk_wrealloc,
which simplifies the code.
* lib.h (string_extend): Declaration updated.
* parser.y (litchars): Pass t as last argument of
string_extend since we know syntactically that these
reductions finalize the string.
(restlitchar): Pass nil as the last argument of string_extend,
since we know syntactically that it isn't the last.
* regex.c (scan_until_common): Pass nil for new argument of
string_extend.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (run_load_hooks): Install the given environment as dyn_env
temporarily, and don't restore it until after calling the hooks.
Thus the specified environment is now in effect when running the
hooks. Also, pass nil to lookup_var, in the spirit of the previous
commit. The fact that load_dyn_env had to be passed to lookup_var
previously, which is an anti-pattern, tells us that this scoping rule
was a code smell. If the *load-hooks* value comes from a given
dynamic environment, then those functions should be executed in
exactly that environment.
* txr.1: Documentation updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since lookup_var(nil, ...) skips the environment and goes for dyn_env,
there is no need to pass dyn_env explicitly; it's a bit of an
anti-pattern. The argument is intended for lexical scopes.
* eval.c (eval_exception, expand_eval, load): Pass nil to lookup_var
instead of the current dynamic environment.
* match.c (v_load): Likewise.
* parser.c (txr_parse, read_eval_ret_last): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (me_push_after_load, me_pop_after_load): New static
functions.
(eval_init): Register push-after-load and pop-after-load
intrinsic macros.
* tests/019/load-hook.tl: Tests for correct expansion.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register delcons intrinsic.
* lib.[ch] (delcons): New function.
* tests/010/cons.tl: New file.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
*load-hooks* lets a .txr, .tl or .tlo file specify actions to be taken
when the loading of that file completes, whether normally or via
an exception. They are also honored by process exit.
For instance, with this, we can have a Lisp file that behaves like
a script which cleans up after itself (e.g. removing temporary files)
even if it is not run as a stand-alone program, but invoked
via (load ...). Because it's not a stand-alone program, it cannot
simply use the at-exit-call mechanism. The unwind-protect operator could
be used, but it's inconvenient because it protects a single form.
The *load-hooks* feature in effect protects all the top level forms of a
load, similarly to unwind-protect. Also, unwind-protect does not
guard against a process exit. (However, *load-hooks* does not guard
against an abnormal exit, only normal termination).
* eval.c (load_hooks_s): New symbol variable.
(run_load_hooks): New function.
(run_load_hooks_atexit): New static function.
(load): bind *load-hooks* to nil around load. Implement
the hooks processing via run_load_hooks, taking care to pass the
load-time dynamic environment that has already been undone.
(eval_init): Initialize load_hooks_s and register the *load-hooks*
variable. Register run_load_hooks_atexit with atexit, so the
current value of *load-hooks* is processed on process exit.
* eval.h (load_hooks_s, run_load_hooks): Declared.
* match.c (v_load): Similar changes as in load.
* txr.c (txr_main): Run the load hooks with run_load_hooks immediately
after processing the .txr or .tl file, before entering the listener.
* tests/019/load-hook.tl: New directory and file
* tests/load-hook.tl: New file.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
| |
* eval.c (me_ecase): Diagnose missing test form, like me_case.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Even prior to discovering the recent defect in deffi, which
was caused by a missing case in caseql, combined with poor
testing, I was already thinking about adding ecase macros.
The introduction of must-match and must-match-case also shows
my motivation. That deffi bug convinced me to take action
and implement these.
* eval.c (case_error_s) New symbol variable.
(me_ecase): New static function.
(eval_init): Register new intrinsic macros ecaseq, ecaseql,
ecasequal, ecaseq*, ecaseql* and ecasequal*.
Intern case-error and initialize case_error_s.
* txr.1: Documented. Also updated Exception Hierarchy diagram
with match-error and case-error.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Numerous macros share the same implementation
function, and their registrations make wasteful repeated func_f2 calls
to hoist that function from C to Lisp more than once. Let's go through
and condense all of them.
|