| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This refactoring is needed for fixing the off-by-one
line number bug when the hash bang line is processed.
* eval.c (load): Don't define parser locally; ensure there is
one in the stream and use it.
* match.c (v_load): Likewise.
* parser.c (get_parser_impl): Renamed to parser_get_impl and
changed from internal to external linkage.
(ensure_parser): Changed to external linkage.
(lisp_parser_impl, read_file_common): Follow rename of
get_parser_impl.
* parser.h (parse_once): Declaration updated.
(parser_get_impl, ensure_parser): Declared.
* parser.y (parse_once): Take self parameter; drop parser
parameter. Ensure a parser to the stream, rather than
declaring one locally. Don't clean up the parser when
done, just let the stream clean it up.
* txr.c (parse_once_noerr): Parser argument is dropped and
not passed to parse_once. Program name is passed as self
argument to parse_once.
(txr_main): When parsing the TXR pattern query, don't define a
parser locally; ensure there is one in the stream and use it,
like in load and v_load.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* debug.c (debug_depth, debug_quit_s): Variables removed.
(step_mode, next_depth, breakpoints, last_command, cols):
Static variables removed.
(debug_check): C99 inline instantiation removed.
(help, show_bindings): Static functions removed.
(debug): Function removed.
(debug_set_state): Now takes one int argument, returns int.
It's anticipated that the new debug system will have a
simple on-off switch; there won't be a debug_depth hack.
(debug_restore_state): Function removed.
(debug_init): Emptied.
* debug.h (debug_depth, debug_state_t): Declarations removed.
(debug_enter, debug_leave, debug_return): Macros removed.
(debug_check): Inline function removed.
(debug_set_state): Declaration updated.
(debug_restore_state): Declaration removed.
(debug_frame, debug_end): Macros removed.
* eval.c (do_eval, me_interp_macro): Debugging support scrubbed.
* lisplib.c (lisplib_try_load): Adapt to debug_set_state
interface change.
* match.c (h_fun, do_match_line, v_fun, match_files,
match_fun): Debugging support scrubbed.
* parser.y (parse_once): Adapt to debug_set_state interface
change.
* protsym.c: Regenerated.
* signal.h (debug_depth): Declaration removed.
(EJ_DBG_MEMB, EJ_DBG_SAVE, EJ_DBG_REST): Macros removed.
(EJ_OPT_MEMB, EJ_OPT_SAVE, EJ_OPT_REST): Reduced to
unconditionally empty definitions for future use.
* unwind.c (uw_push_debug): Function removed.
* unwind.h (uw_frtype_t): UW_DBG enum member removed.
(struct uw_debug): struct declaration removed.
(union uw_frame): db member removed.
(uw_push_debug): Declaration removed.
* txr.1: Debugger doc removed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Unwind frames of type ENV exist for the sake of the pattern
language. Let's rename them accordingly.
* match.c (tleval, tleval_progn, h_fun, tx_subst_vars, v_bind,
v_output, v_filter, v_fun): Occurrences of the macros
uw_env_begin and uw_env_end are renamed.
* unwind.c (uw_env_stack): Renamed to uw_menv_stack.
(uw_unwind_to_exit_point, uw_abscond_to_exit_point,
uw_find_env, uw_pop_frame, revive_cont): Follow
rename of UW_ENV to UW_MENV and uw_env_stack to uw_menv_stack.
(uw_push_env): Renamed to uw_push_match_env, and updated to
follow renames.
* unwind.h (enum uw_frtype, uw_frtype_t): UW_ENV renamed
to UW_MENV.
(uw_push_env): Renamed to uw_push_match_env.
(uw_env_begin, uw_env_end): Renamed to uw_match_env_begin an
uw_match_env_end.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In an @(output), if we reference a variable bound to a lazy
list, and the generation of that logic references TXR pattern
variables, things break: the lazy list's code doesn't see
the binding. This is because the lazy list is forced by some
logic that doesn't establish the proper environment for
that evaluation. Inside a @(repeat), the do_output function
measures the lengths of lists emanating from variables,
and that has the effect of forcing the lazy lists.
* match.c (v_output): Just set up the dynamic environment
around the entire function, so that any Lisp evaluation that
occurs is happening as if it were via tleval.
|
|
|
|
|
|
|
|
|
| |
* arith.h (mod_s, bit_s): Add extern declarations.
* ffi.c (bit_s): Remove definition.
* match.c (mod_s): Remove definition. Include "arith.h" to
obtain declaration of mod_s.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This addresses the following issue. Suppose the query
is something like this:
@abc
@(nonexistent)
and there is one line of data. In this case, there is no error
about a nonexistent function. The function lookup fails in
vertical mode, so horizontal mode fallback takes place. But
that just concludes that there is no data, and reports a
failed match. But the programmer might have intended to invoke
some function or directive that doesn't need to match
anything, but rather has an important effect.
In this patch we fix that. As part of the change, we disallow
functions from shadowing horizontal directives.
* match.c (match_files): Do not look up sys:var and sys:text
through the directive table, but check for these. If the
directive is not found in the vertical table, check the
horizontal table; if found there, don't try it as a function
but go to horizontal processing. Then if the function lookup
fails, we diagnose a failed lookup; don't fall through to
horizontal processing.
|
|
|
|
|
|
| |
* match.c (match_files): Change pointless two-step
initialization of a variable by assignment into straight
initialization.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We would like @(next (open-directory "nonexistent") :nothrow)
to act as a failed match, rather than for the exception to
propagate (and likely terminate TXR). The problem is that
only file sources are treated with :nothrow.
* match.c (tleval_nothrow, tleval_144_nothrow): New static
functions.
(v_next_impl): Use tleval_nothrow for all Lisp evaluation. If
nothrow is requested and Lisp evaluation returns the colon
symbol (which tleval_nothrow produces in the case of an
exception), then treat the situation as a failed match.
|
|
|
|
|
|
|
|
| |
* match.c (v_next_impl): The check against the presence of
multiple of source-specifying keyword options must also
consider the base source as part of the mutual exclusion,
so that syntax like @(next "file" :string "str") is also
ruled out.
|
|
|
|
|
|
|
|
|
|
| |
* match.c (v_next_impl): Contrary to the documentation and to
"classic" TXR behavior exhibited in compatibility mode,
when @(next "file" :nothrow) fails to open "file", it treats
the situation as a cue to read from standard input, rather
than to treat the situation as a failed match. This is because
complex_open returns nil, and when that is passed to
lazy_stream_cons, that function defaults to standard input.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* LICENSE, LICENSE-CYG, METALICENSE, Makefile, args.c, args.h,
arith.c, arith.h, buf.c, buf.h, cadr.c, cadr.h, combi.c,
combi.h, configure, debug.c, debug.h, eval.c, eval.h, ffi.c,
ffi.h, filter.c, filter.h, ftw.h, gc.c, gc.h, glob.c, glob.h,
hash.c, hash.h, itypes.c, itypes.h, jmp.S, lib.c, lib.h,
lisplib.c, lisplib.h, match.c, match.h, parser.c, parser.h,
parser.l, parser.y, protsym.c, rand.c, rand.h, regex.c,
regex.h, share/txr/stdlib/asm.tl, share/txr/stdlib/awk.tl,
share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl,
share/txr/stdlib/compiler.tl, share/txr/stdlib/conv.tl,
share/txr/stdlib/doloop.tl, share/txr/stdlib/error.tl,
share/txr/stdlib/except.tl, share/txr/stdlib/ffi.tl,
share/txr/stdlib/getopts.tl, share/txr/stdlib/getput.tl,
share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl,
share/txr/stdlib/keyparams.tl, share/txr/stdlib/op.tl,
share/txr/stdlib/package.tl, share/txr/stdlib/path-test.tl,
share/txr/stdlib/place.tl, share/txr/stdlib/pmac.tl,
share/txr/stdlib/socket.tl, share/txr/stdlib/stream-wrap.tl,
share/txr/stdlib/struct.tl, share/txr/stdlib/tagbody.tl,
share/txr/stdlib/termios.tl, share/txr/stdlib/trace.tl,
share/txr/stdlib/txr-case.tl, share/txr/stdlib/type.tl,
share/txr/stdlib/vm-param.tl, share/txr/stdlib/with-resources.tl,
share/txr/stdlib/with-stream.tl, share/txr/stdlib/yield.tl,
signal.c, signal.h, socket.c, socket.h, stream.c, stream.h,
struct.c, struct.h, strudel.c, strudel.h, sysif.c, sysif.h,
syslog.c, syslog.h, termios.c, termios.h, txr.1, txr.c, txr.h,
unwind.c, unwind.h, utf8.c, utf8.h, vm.c, vm.h, vmop.h,
win/cleansvg.txr: Extended Copyright line to 2018.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* configure: Instead of generating a definition of ALLOCA_H,
generate the variable HAVE_ALLOCA_<name> with a value of 1,
where <name> is one of stdlib, alloca or malloc.
* alloca.h: New header.
* args.c, eval.c, ffi.c ffi.c, ftw.c, hash.c, lib.c, match.c,
parser.c, parser.y, regex.c, socket.c, stream.c, struct.c,
sysif.c, syslog.c, termios.c, unwind.c, vm.c: Include
"alloca.h" instead of ALLOCA_H.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The <dirent.h> header is included all over the place because
it is needed by a single declaration in stream.h. That
declaration is for a function that is only called within
stream.c, so we make it internal. Now only stream.c has
to include <dirent.h>.
* buf.c, debug.c, eval.c, ffi.c, filter.c, gc.c, gencadr.txr,
hash.c, lib.c, lisplib.c, match.c, parser.c, regex.c, socket.c,
struct.c, strudel.c, sysif.c, syslog.c, termios.c, txr.c,
unwind.c, vm.c: Remove #include <dirent.h>.
* cadr.c: Regenerated.
* stream.c (make_dir_stream): Make external function static.
* stream.h (make_dir_stream): Declaration updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In this patch, the cobj_handle, cobj_ops and variants of
gethash get an additional argument to identify the caller.
Many functions are updated to pass this down.
* buf.c (buf_strm): Pass self name to cobj_handle.
* eval.c (env_fbind, env_vbind, rt_defvarl, me_case): Pass
self name to gethash_c or gethash_e.
(load): Pass self name to read_eval_stream and
read_compiled_file.
(reg_symacro): Pass situation-identifying string to gethash_c.
* ffi.c (ffi_type_struct_checked, ffi_closure_struct_checked,
ffi_call_desc_checked, uni_struct_checked):
Take self name parameter, and pass down to cobj_handle.
(ffi_get_type, ffi_get_lisp_type): Take self name and pass
down to ffi_type_struct_checked.
(union_get_ptr): Take self name and pass to
uni_struct_checked.
(ffi_union_in, ffi_union_put): Pass self name to union_get_ptr.
(ffi_type_compile): Pass self name to ffi_get_lisp_type.
(ffi_make_call_desc): Pass self name to
ffi_type_struct_checked, ffi_get_type and
ffi_call_desc_checked.
(ffi_make_closure): Pass self name to ffi_call_desc_checked.
(ffi_closure_get_fptr): Take self name, pass to
ffi_closure_struct_checked.
(ffi_typedef, ffi_size, ffi_alignof, ffi_offsetof,
ffi_arraysize, ffi_elemsize, ffi_elemtype, ffi_put_into,
ffi_put, ffi_in, ffi_get, ffi_out, make_carray): Pass self
name to ffi_closure_struct_checked.
(carray_struct_checked): Take self name, pass to cobj_handle.
(carray_set_length, carray_dup, carray_own, carray_free,
carray_type, length_carray, copy_carray, carray_ptr,
buf_carray, vec_carray, list_carray, carray_ref,
carray_refset, carray_sub, carray_replace, carray_get_common,
carray_put_common, unum_carray, num_carray, put_carray,
fill_carray): Pass self name to carray_struct_checked.
(carray_blank, carray_buf, carray_cptr): Pass self name
ffi_type_struct_checked.
(carray_pun): Pass self name to carray_struct_checked and
ffi_type_struct_checked.
(make_union): Pass self name to ffi_type_struct_checked.
(union_members, union_get, union_put, union_in, union_out):
Pass self name to uni_struct_checked.
(make_zstruct, zero_fill, put_obj, get_obj, fill_obj): Pass
self-name to ffi_type_struct_checked.
* ffi.h (ffi_closure_get_fptr, union_get_ptr): Declarations
updated.
* filter.c (trie_add): Pass self-name to gethash_l.
* hash.c (make_similar_hash, copy_hash, hash_count,
get_hash_userdata, set_hash_userdata, hash_begin, hash_next,
hash_uni, hash_diff, hash_isec): Pass self name
to cobj_handle.
(gethash_c, gethash_e): Take self name parameter and pass down
to cobj_handle.
(gethash_f): Take self parameter and pass down to gethash_e.
(gethash, inhash, gethash_n, sethash, pushhash, remhash,
clearhash, hash_update_1): Pass self name to gethash_e or gethash_c.
* hash.h (gethash_c, gethash_e, gethash_f): Declarations
updated.
(gethash_l): Take self name, and pass down to gethash_c.
* lib.c (class_check): Take self name parameter and use in
type mismatch diagnostic.
(use_sym, unuse_sym, symbol_needs_prefix, find_symbol,
intern, unintern, intern_fallback, unique, in, sel,
obj_print_impl, populate_obj_hash, obj_hash_merge): Pass self
name to gethash_f or gethash_l.
(symbol_visible, obj_init): Pass situation-identifying string
to gethash_e.
(cobj_handle, cobj_ops): Take self name parameter and pass
down to class_check.
* lib.h (class_check, cobj_handle, cobj_ops): Declarations
updated.
* match.c (v_load): Pass self name to read_compiled_file and
read_eval_stream.
* parser.c (get_parser_impl): Take self name and pass to
cobj_handle.
(ensure_parser): Pass situation-identifying string to
gethash_c.
(parser_circ_def): Pass self-name to gethash_c.
(lisp_parser_impl): Pass self name to get_parser_impl and
class_check.
(lisp_parse, nread, iread): Pass self-name to lisp_parser_impl.
(read_file_common): Take self name parameter and pass down to
get_parser_impl.
(read_eval_stream, read_compiled_file): Take self name and
pass down to read_file_common.
(load_rcfile): Pass situation-identifying string to
read_eval_streem.
(get_visible_syms): Pass situation-identifying string to
gethash_c.
(parser_errors, parser_eof): Pass self name to cobj_handle.
* parser.h (read_eval_stream, read_compiled_file):
Declarations updated.
* parser.y (rlset): Pass self name to gethash_c.
* rand.c (make_random_state, random_state_get_vec,l
random_fixnum, random_float): Pass self name to cobj_handle.
* regex.c (regex_source, regex_print, regex_run): Pass
self-name to cobj_handle.
(regex_machine_init): Take self name param and pass to
cobj_handle.
(search_regex, match_regex, match_regex_right,
regex_prefix_match, read_until_match): Pass self-name to
regex_machine_init.
* stream.c (stdio_get_fd): Pass self name to cobj_handle.
(generic_get_line): Get COBJ operations via unsafe, diret
object access rather than cobj_ops.
(set_mode_props): Get object handle via unsafe, direct object
access.
(stream_fd, sock_family, sock_type, sock_peer, set_sock_peer,
get_string_from_stream, get_list_from_stream, stream_set_prop,
stream_get_prop, close_stream, get_error, get_error_str,
clear_error, get_line, get_char, get_byte, unget_char,
unget_byte, put_buf, fill_buf, put_string, put_char, put_byte,
flush_stream, seek_stream, truncate_stream, get_indent_mode,
test_set_indent_mode, set_indent_mode, get_indent, set_indent,
inc_indent, width_check, force_break, get_set_ctx, get_ctx):
Pass self name to cobj_ops.
(make_delegate_stream): Take self name parameter, pass down to
cobj_ops.
(record_adapter): Pass self name down to make_delegate_stream.
(format): Pass self name to class_check.
* struct.c (stype_handle): Pass self name to cobj_handle.
(make_struct_type): Pass self name to class_check.
* txr.c (read_eval_stream_noerr): Take self name parameter,
pass to read_eval_stream.
(txr_main): Pass istuation-identifying string to
read_compiled_file and read_eval_stream_noerr.
* unwind.c (revive_cont): Pass self-name to cobj_handle.
* vm.c (vm_desc_struct): Take self name parameter, pass to
cobj_handle.
(vm_desc_nlevels, vm_desc_nregs, vm_desc_bytecode,
vm_desc_datavec, vm_desc_symvec, vm_execute_toplevel,
vm_execute_closure, vm_closure_entry): Pass self name to
vm_desc_struct.
(vm_closure_struct): Take self name parameter, pass to
cobj_handle.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In the @{var mod} syntax in the pattern language, allow mod to
be a variable which contains a regex or integer, not just an
integer or regex literal.
* match.c (h_var): Check for modifier being a variable, and
resolve it.
* parser.y (modifiers): Allow a SYMTOK phrase.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* match.c (else_s, elif_s): New symbol variables.
(syms_init): Initialize new variable with interned symbols.
* match.h (else_s, elif_s): Declared.
* parser.y (not_a_clause): Refer to if_s, else_s and elif_s,
which are symbols in the usr package, instead of intering
symbols in whatever package is current.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (load): If open_txr_file indicates compiled file by
setting txr_lisp_p to character #\o, use read_compiled_file.
* match.c (v_load): Likewise.
* parser.c (open_txr_file): Recognize the .tlo suffix, and
also try to open a .tlo version of an unsuffixed file before
trying it as .tl. Indicate a .tlo file by setting txr_lisp_p
to the character #\o rather than t.
(read_file_common): New static function, made from contents of
read_eval_stream. Will either evaluate forms or load compiled
code by instantiating virtual machine descriptions and
performing their top-level execution.
(read_eval_stream): Now a wrapper for read_file_common.
(read_compiled_file): New function.
* parser.h (read_compiled_file): Declared.
* txr.c (help): List new --compiled option.
(txr_main): If --compiled is specified, set txr_lisp_p to #\o
to load as compiled code. Update error message that -c is
not compatible with --lisp or --compiled.
If txr_lisp_p is #\o, then use read_compiled_file.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (load): Instead of throwing error when a .txr file
is opened, process it according to sensible requirements.
* match.c (v_load): Store bindings in the current environment
frame before evaluating Lisp, and then update afterward.
This allows .txr files loaded from Lisp to continue matching
with the current bindings and extend those bindings.
* txr.1: Update documentation of load.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* LICENSE, LICENSE-CYG, METALICENSE, Makefile, args.c, args.h,
arith.c, arith.h, buf.c, buf.h, cadr.c, cadr.h, combi.c,
combi.h, configure, debug.c, debug.h, eval.c, eval.h, ffi.c,
ffi.h, filter.c, filter.h, ftw.c, ftw.h, gc.c, gc.h, glob.c,
glob.h, hash.c, hash.h, itypes.c, itypes.h, jmp.S, lib.c,
lib.h, lisplib.c, lisplib.h, match.c, match.h, parser.c,
parser.h, parser.l, parser.y, protsym.c, rand.c, rand.h,
regex.c, regex.h, share/txr/stdlib/awk.tl,
share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl,
share/txr/stdlib/conv.tl, share/txr/stdlib/doloop.tl,
share/txr/stdlib/error.tl, share/txr/stdlib/except.tl,
share/txr/stdlib/ffi.tl, share/txr/stdlib/getopts.tl,
share/txr/stdlib/getput.tl, share/txr/stdlib/hash.tl,
share/txr/stdlib/ifa.tl, share/txr/stdlib/keyparams.tl,
share/txr/stdlib/op.tl, share/txr/stdlib/package.tl,
share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl,
share/txr/stdlib/pmac.tl, share/txr/stdlib/socket.tl,
share/txr/stdlib/stream-wrap.tl, share/txr/stdlib/struct.tl,
share/txr/stdlib/tagbody.tl, share/txr/stdlib/termios.tl,
share/txr/stdlib/txr-case.tl, share/txr/stdlib/type.tl,
share/txr/stdlib/with-resources.tl,
share/txr/stdlib/with-stream.tl, share/txr/stdlib/yield.tl,
signal.c, signal.h, socket.c, socket.h, stream.c, stream.h,
struct.c, struct.h, strudel.c, strudel.h, sysif.c, sysif.h,
syslog.c, syslog.h, termios.c, termios.h, txr.1, txr.c, txr.h,
unwind.c, unwind.h, utf8.c, utf8.h, win/cleansvg.txr:
Extended Copyright line to 2018.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This reduces the proliferation of car_l and cdr_l.
With this change, nreverse should work on chains of
objects that implement rplacd.
* combi.c (comb_gen_fun_common, rcomb_gen_fun_common): Use
rplaca.
* eval.c (mappendv, mapdov): Likewise
* hash.c (hash_equal_op): Likewise.
* lib.c (nreverse, acons_new, aconsql_new, sort_list): Use
rplaca and rplacd.
* match.c (dest_set, v_gather, v_collect, v_flatten, v_cat,
v_output, v_filter): Likewise
* parser.c (ensure_parser): Use sys_rplacd.
* unwind.c (uw_register_subtype): Use rplacd.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There is an inconsistency in @(bind) in that
given @(bind x y) where x is a variable, both
directions are tried for a string tree match.
x could be tree of strings and y a string atom,
or vice versa. But if x is just an atom, or
a Lisp evaluation, then only one direction is
tried. @(bind @(list "a" "b") "a") succeeds,
but @(bind "a" @(list "a" "b")) fails.
* match.c (dest_bind): Test both directions
in the scalar and Lisp evaluated cases of the
left hand side. Subject to compatibility,
just in case.
* txr.1: Compat note added.
|
|
|
|
|
|
|
|
| |
* match.c (match_reg_var): The uw_tentative_def_exists
check is being made against a symbol rather than the
tag. This check will always fail. There is no ill consequence.
Just that uw_register_tentative_def will be called
redundantly when it doesn't have to be.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is for those situations when multiple lists are being
collected, and must all be bound even if empty. Yet, the
lists are independent rather than parallel, so the discipline
of :vars is too rigid.
* match.c (lists_k): New keyword symbol variable.
(h_coll, v_collect): Extract :lists argument as local variable
lists, validate that :lists is not used on @(repeat)/@(rep)
and implement logic.
(match_expand_keyword_args): Treat expansion of :lists
the same way as :vars.
(syms_init): Initialize lists_k.
* match.c (lists_k): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
| |
* match.c (h_trailer): Prevent LOG_MATCH call from
being evaluated in failed case, when the position is nil.
This situation triggers an exception, because LOG_MATCH
prints the position as an integer using ~d.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The hash bang mechanism is handled in one place,
and disentangled from all parsing logic.
It is also endowed with special powers.
* eval.c (load): Pass one less argument to read_eval_stream.
* match.c (v_load): Likewise.
* parser.c (read_eval_stream): hash_bang_support Boolean
argument removed. Hash bang logic removed.
(load_rcfile): Pass only two arguments to read_eval_stream.
* parser.h (read_eval_stream): Declaration updated.
* txr.c (remove_hash_bang_line): Function removed.
(check_hash_bang): New static function.
(txr_main): Recognize the script file name while still
inside the argument processing loop. Open the file,
and check for a hash bang line, doing the special
processing which can generate more arguments from material
after a null byte in the hash bang line. The parse_stream
variable is now initialized to nil and doubles as a Boolean
indicating whether a stream has been opened. After the
loop, we remove the script file from the arguments, if we
have an open stream and the spec_file_str matches.
read_eval_stream is called only with two arguments.
* txr.1: Revised existing documentation and described
new features.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When TXR pattern language code is canned in the context of
an alternative *package* which uses the usr package,
the scanner will throw false errors on @(end) and @(single).
This is because these symbols don't exist in the usr
package and will get interned in the current package.
The scanner will then complain that they are not in the
usr package.
* match.c (syms_init): Intern end and single in the
usr package, but don't store the return value in any
variable.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The @{a [3]} syntax in quasiliterals and @(output) now
indexes into the original object a if it is any sequence
kind, not specifically a list. Otherwise it indexes into
its string representation.
* eval.c (format_field): Combine the elements of the
object with the separator if it is any sequence type other
than a string. Subject to compat option.
(subst_vars): Avoid converting any kind of sequence to
string, rather than just lists. After any field formatting
is applied, if the object is any sequence (not just alist),
combine the elements with a space. All subect to compat
option.
* match.c (tx_subst_vars): Same treatment as subst_vars.
* txr.1: Compatibility notes added.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The existing behavior is: when a situation like @a@(foo)
performs a search for the match for @(foo) in order to
determine the extent of the text matched by variable a, the
variable a is not bound. That is to say, @(foo) is tried in an
environment in which a doesn't exist. The variable is only
bound when the search succeeds, and then @(foo) is processed
again, with the variable now available.
The new behavior is that @(foo) is tested in an environment
in which a is bound. The variable's value is bound to the
range of text between the original position and the tested
position where @(foo) is tried.
This is subject to the copatibility option.
* match.c (ml_bindings_specline_pos): New static function.
(search_match_binding_var): New static function, variant of
search_match.
(h_var): In the var-delimited-by-directive case, perform
the search using search_match_binding_var, unless <= 172
compatibility is requested.
* txr.1: Compatibility note added.
|
|
|
|
|
|
|
|
|
| |
* match.c (search_match): Calling consume_prefix from this
function does nothing because it does not advance c->pos,
and so it is hereby removed. This was introduced in commit
fce7c87fa0099e5414607676fc73c9dfa9d7649c
on 2012-02-11, at the same time when consume_prefix
was introduced.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If the main file of an application is a .txr file, unbound
function and variable warnings are not being generated.
* match.c (v_load): For consistency with the load
function in eval.c, release deferred warnings in the normal
return case, if we are not a recursive load. However, this
doesn't fix anything because a load or include is always
recursive being invoked from a .txr file that is being loaded.
The problem is in fact that the recursive flag is nil
when it shouldn't be, and then the uw_unwind block
obliterates the warnings.
* txr.c (txr_main): We must bind *load-recursive* to t
around not just the loading of Lisp, but also of TXR.
Otherwise the individual loads will release warnings,
raising false positives for forward references.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.h (default_bool_arg): Inline function renamed to
default_null_arg.
* eval.c (if_fun, pad, ginterate, giterate, range_star, range,
constantp, macroexpand_1, macro_form_p, expand_with_free_refs,
do_expand, eval_intrinsic, func_get_name, make_env_intrinsic):
Follow rename.
* arith.c (lognot): Likewise.
* gc.c (gc_finalize): Likewise.
* glob.c (glob_wrap): Likewise.
* hash.c (group_reduce, gethash_n): Likewise.
* lib.c (print, multi_sort, lazy_str, vector, iff, tok_str,
split_str_keep, search_str, remove_if, val): Likewise.
* match.c (match_fun): Likewise.
* parser.c (lisp_parse_impl, regex_parse): Likewise.
* rand.c (make_random_state): Likewise.
* regex.c (read_until_match, search_regex, regex_compile):
Likewise.
* socket.c (sock_accept, sock_connect): Likewise.
* stream.c (open_files_star, open_files, run, open_process,
open_tail, get_string, record_adapter): Likewise.
* struct.c (static_slot_ensure, static_slot_ens_rec,
clear_struct, make_struct_type): Likewise.
* sysif.c (exec_wrap, errno_wrap, cobj_ops_init): Likewise.
* unwind.c (uw_capture_cont, uw_find_frames_impl): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* match.c (in_package_s): New symbol variable.
(syms_init): Initialize in_package_s.
* match.h (in_package_s): Declared.
* parser.y (check_parse_time_action): Add case for in-package.
Evaluate just with eval, as a case of the in-package macro.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.h (progn_s): Declarationa added.
* match.c (mdo_s): New symbol variable.
(syms_init): Initialize mdo_s.
* match.h (mdo_s): Declared.
* parser.y (check_for_include): Renamed to check_parse_time_action
and implements mdo, not only include.
(clauses_rev): Follow rename of function.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The match-fun function must augment the input list
with the current input source, because @(next)
pops the first item from the files list and tries
to open the second.
We want it so that if we invoke
(match-fun 'f arglist input '("abc"))
then if the pattern function f invokes @(next),
it will open "abc".
* match.c (match_fun): Calculate a value for the curfile
property of the match context and pass it to mf_all. If the
input is a stream, we get its name. We also push this curfile
onto the files list, satisfying the expectation that curfile
and the first element of files refer to the same thing.
|
|
|
|
|
| |
* match.c (match_fun): Report self as match-fun
in error message.
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Update registration of match-fun.
* match.c (match_fun): Do defaulting on third and fourth arg.
* txr.1: Documenation updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* match.c (open_data_source): The logic of not opening
the data source for a non-matching directive must be applied
to streams also, because the lazy list mechanism will read
ahead from an underlying non-interactive stream. We must
also apply it in the case when we open standard input by
default. If standard input is non-interactive such that the
lazy list unconditionally tries to read a line from it
upon construction, we misbehave. The program could block
on the read. Even if it doesn't block, the input action is
an unwanted externally visible event.
|
|
|
|
|
| |
* match.c (open_data_source): If the data source isn't
a string or stream, then error out.
|
|
|
|
|
| |
* match.c (open_data_source): do the spec_bind in just one place.
Use first_spec consistently in the debuglf calls.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* match.c (open_data_source): If there is nothing
in the files array and data is t (indicating a request
to open a data source), then use standard input.
Subject to the compatibility option.
* Makefile (txr-manpage.html): Drop use of
the txr - argument in rule recipe.
* txr.1: Document that - isn't necessary.
Added to compatibility notes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This test case suffers a spurious unbound variable warning:
@(collect :counter x)
@(bind y @x)
@(end)
* match.c (match_expand_keyword_args): Register the :counter
variable as a tentative definition with match_reg_var.
We don't do this for :vars because they are not newly
introduced: the :vars construct doesn't bind. The :counter
feature is the only keyword feature in collect which binds
a new variable.
|
|
|
|
|
|
|
| |
* match.c (match_expand_keyword_args): counter is wrongly
lumped with things like :times here, which fails to handle
the syntax with an initialized like :counter (a (+ 2 2)).
We move it to a separate case.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The test case for this issue is:
@(next :list '#"the quick brown fox jumped")
@(block b)
@(try)
@the
@(accept b)
@(finally)
@quick
@(end)
@(end)
Inside the try-protected clause, we bind the variable the to
the string "the". Then we initiate an accept whose exit point
is the block b. There are two problems: the finally clause
executes against the input stream beginning with "the", even
though "the" was consumed in the protected block. Secondly,
the binding captures by finally is thrown away; the accept
control transfer continues and only one variable emerges from
the block: the variable the.
In this patch we obtain a different behavior. The processing
of the finally clause detects that an accept transfer is
passing through.
The clause is executed against the input stream that is being
communicated by the accept, in this case the stream which
beings with the second line "quick", so the quick variable
gets bound to this string.
Secondly, the bindings being communicated by the accept are
hijacked and replaced with the new environment captured by the
finally clause. Thus, in this case, the quick variable emerges
out of the block.
Lastly, if the finally block fails to match, the accept
transfer is converted to a @(fail) transfer and continues to
the block.
* match.c (v_take_accept): New static function.
(v_block); Use v_take_accept function to update the
match_files_ctx state from a caught accept. That is
to say, the code to do this moves into that function,
and is just called. This way we can share that logic with
the finally processing in v_try.
(v_try): Detect an accept transfer by checking the
exit point. If one is going on, then accept the input and
bindings into the current context and process the clause
in that context. Afterward, update the accept result
object with the new position and bindings or convert to
a failure.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This fixes a bug in the same category as the parent commit.
The issue of concern here is that if an @(accept) control
transfer terminates a @(next) directive, the data stream to
which the @(next) directive switched escapes out of that
scope. Example:
@(block b)
@(next :list '("line"))
@(accept b)
@(end)
@var
Here, var captures "line" because the stream set up by @(next)
is carried by the @(accept) to the destination block, and then
taken as the current data source going forward. The
overwhelmingly preferrable behavior is for the accept to honor
the input source controlling dynamic scope of the @(next)
directive. When the control transfer crosses a @(next)
boundary by terminating a next directive, the transfer's data
must be replaced by the original data stream just prior the
@(next). However, the bindings are carried through untouched.
This is basically opposite to pattern function invocations.
Pattern functions freely advance the data position in the same
stream, but carefully control what bindings emerge. Whereas
@(next) carefully scopes the input source, but freely allows
bindings to emerge. The @(accept) control transfers must be
in accord with these behaviors. And, in the existing case of
@(trailer) which properly interacts with accept, the same
holds. That directive allows bindings to escape but prevents
the advancement of the input within the current stream. If it
is terminated by @(accept), these hold.
* match.c (v_next_impl): New static function, identical
to previous v_next.
(v_next): Reduced to wrapper around v_next_impl which
intercepts @(accept) control transfers and fixes up their
data position to match the position coming into the @(next).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The issue is that if @(accept) traverses a pattern function
call boundary, the rules for resolving bindings when
terminating a function are being ignored. For instance,
this test case ends with a and x being bound to "y"
and "x":
@(define fun (a))
@(bind x "x")
@(accept a)
@(end)
@(block a)
@(fun "y")
@(end)
the right behavior is that there are no bindings at all.
When the accept control transfer terminates (fun "y"),
binding resolution must take place as if the function
terminated normally. This resolution, in this particular
case, suppresses the a and x bindings which are local,
so that the test case terminates with no bindings.
* match.c (fun_intercept_accept): New static function.
(h_fun, v_fun): Set up an unwind handler which calls
fun_intercept_accept to catch accepts and fix-up
their bindings.
|
|
|
|
|
|
| |
* match.c (fun_resolve_bindings): New static function.
(h_fun, v_fun): Replace common code with a call to
fun_resolve_binding.
|
|
|
|
|
|
|
| |
* match.c (h_trailer): Add the unwind handling for intercepting
the block return driven by @(accept) and fixing up the position, so the
semantics of trailer isn't violated, similarly to how it is done in
v_trailer.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Accepts produce a return value which is a vector object
carrying both vertical (data pointer + line number)
and horizontal context (position within line).
Both a vertical and horizontal @(block) construct look
at this and behave in some intelligent way.
* match.c (match_line_ctx): New member, data. Thus,
horizontal contexts now know the vertical list from whcih they
are derived.
(ml_all): Take data argument, and initialize new member.
(h_block): If a vector object emerges from the block, that
means the block terminated due to an accept. If the accept
is from a different line, or from vertical context, then
just keep whatever horizontal position is current in the
horizontal context. (We have no way of knowing how far we
advanced between the start of the block and the elem which
triggered the accept.) If the accept is from the same line
then advance to the indicated position.
(h_accept_fail): Produce a three-element vector object for the
accept long return value. This carries the bindings, the
vertical-style result value, and the horizontal position.
(freeform_prepare): Update ml_all call to include c->data.
(v_block): Like in h_block, handle a vector result value.
An accept emanating from horizontal context for the current
line causes the vertical context to advance to the next line.
Horizontal accept from a different line doesn't advance the
data. Accept from a vertical context behaves as before.
(v_accept_fail): Produce vector object for accept.
(v_trailer): When intercepting accept, patch new vector
representation of accept value.
(match_files): Pass c.data to ml_all.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Unresolved issue: horizontal @(accept) terminating in a
vertical @(block) or horizontal @(block) in a different line,
or vertical @(accept) caught in horizontal context.
* match.c (h_block, h_accept_fail): New functions.
(dir_tables_init): Register horizontal @(block),
@(accept) and @(fail).
* parser.y (elem): Support BLOCK syntax.
|
|
|
|
|
|
|
| |
* match.c (dir_tables_init): Wire throw_s into horizontal
dispatch table via hv_trampoline.
* txr.1: Documented.
|