| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
| |
* match.c (match_reg_var): No need to call
uw_purge_deferred_warning here any more.
* unwind.c (uw_register_tentative_def): Purge any
deferred warnings for the tag.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* LICENSE, LICENSE-CYG, METALICENSE, Makefile, args.c, args.h,
arith.c, arith.h, cadr.c, cadr.h, combi.c, combi.h, configure,
debug.c, debug.h, eval.c, eval.h, filter.c, filter.h, ftw.c,
ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h, jmp.S,
lib.c, lib.h, lisplib.c, lisplib.h, match.c, match.h,
parser.c, parser.h, parser.l, parser.y, rand.c, rand.h,
regex.c, regex.h, signal.c, signal.h, stream.c, stream.h,
struct.c, struct.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, share/txr/stdlib/awk.tl,
share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl,
share/txr/stdlib/conv.tl, share/txr/stdlib/except.tl,
share/txr/stdlib/getopts.tl, share/txr/stdlib/getput.tl,
share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl,
share/txr/stdlib/package.tl, share/txr/stdlib/path-test.tl,
share/txr/stdlib/place.tl, share/txr/stdlib/socket.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:
Add 2017 to all copyright headers and strings.
|
|
|
|
|
|
|
| |
* match.c (v_load): Re-bind the *package* variable in the
new dynamic scope to its current value, so that any
modifications to it by the loaded code are thrown away,
just like in the Lisp load function.
|
|
|
|
|
|
| |
* match.c (v_load): Bind *load-recursive* to t around
the loading, and dump deferred warnings afterward if
the previous value of *load-recursive* is nil.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With this change, Lisp expansion-time warnings are no longer
suppressed during the parsing of the TXR pattern language.
Embedded Lisp expressions can refer to TXR pattern variables,
which generates spurious warnings that must be suppressed.
Since TXR pattern variables are dynamically introduced in a
very flexible way, it's hard to do an exact job of this. We
take the crude approach that warnings are suppressed for all
pattern variables that appear anywhere in the TXR code. To do
that, we identify, at parse time, all directives which can
bind new variables, and register those variables as if they
were tentative global defs, purging all pending warnings for
them.
* match.c (binding_directive_table): New static hash table.
(match_reg_var, match_reg_params, match_reg_elem): New
functions.
(match_reg_var_rec): New static function.
(dir_tables_init): gc-protect binding_directive_table,
and populate its entries.
* match.h (into_k, named_k): Declared.
(match_reg_var, match_reg_params, match_reg_elem): Declared.
* parser.y (process_catch_exprs): New static function.
(elem): Call match_reg_elem for each basic directive,
to process the variables in that directive according to
its operator symbol. Do this for each compound form elem
and variable elem. Te horizontal @(define) eleme has
its own grammar production here, and we handle its
parameter list in that rule.
(define_clause): Handle the parameters of a vertical
@(define). It binds pattern variables, and so we must
suppress unbound warnings for those.
(catch_clauses_opt): Process the parameters bound by
@(catch) clauses.
(output_clause): Suppress warnings for the variables
nominated by any :into or :named argument.
(expand_repeat_rep_args): Suppress warnings for :counter
variable, and for :vars variables.
(parse_once): Remove the warning-muffling handler
frame set up around the yyparse call.
* txr.c (txr_main): Suppress warnings for TXR variables
defined using -D syntax on the command line. Dump
deferred warnings after parsing a .txr file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is the last round of changes on this topic, bringing
proper macro expansion to the arguments to @(skip),
@(fuzz), @(next), @(call), @(cat), @(load) and @(close).
* match.c (match_expand_keyword_args): Only process the
keyword arguments if they are followed by an argument.
Process @(next) arguments here too: :list and :string
take a Lisp expression, but :tlist and :var take an
argument which is not a Lisp expression and must be
handled properly. Also, expand any non-keyword expression.
This handles the <source> argument of @(next).
(match_expand_elem): New function.
* match.h (match_expand_elem): Declared.
* parser.h (expand_meta): Declared.
* parser.y (expand_meta): Static function becomes external.
(elem): Expand elem other than require or do using
match_expand_elem. We don't fold require and do into this
because match_expand_elem has a backward compat switch
in it that doesn't apply to these.
|
|
|
|
|
|
|
|
|
|
| |
* match.c (sem_error): Add noreturn attribute to function.
(tx_lookup_var_ubc): New static function.
(dest_set, v_next, v_flatten, v_cat, v_filter): Use new
function to for checked variable lookup.
(v_set): Pass first_spec to dest_set, since tx_lookup_var_ubc
needs to extract the directive symbol from the context
from.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In the argument lists of @(collect)/@(repeat), @(coll)/@(rep)
and @(gather), Lisp expressions can appear as arguments
to keywords or for supplying default values for variables.
These are not being macro-expanded.
* match.c (match_expand_vars): New static function.
(match_expand_keyword_args): New function.
* match.h (match_expand_keyword_args): Declared.
* parser.y (gather_clause, collect_clause, elem): Use new
function in match.c to expand the argument lists.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In this patch commit I'm addressing the issue introduced in
part 1 that expressions in @(output) blocks are still using
(sys:expr ...) wrapping, but are passed down to an evaluator
which now expects unwrapped expressions now.
As part of this change, I'm changing the representation of
@expr from (sys:expr . expr) to (sys:expr expr).
* eval.c (format_field): Adjust access to sys:expr
expression based on new representation.
(transform_op): Likewise.
* lib.c (obj_print_impl): Likewise.
* match.c (dest_bind): Likewise.
(do_txeval): Likewise.
(do_output_line): Likewise, in some compat code. Here is the
fix for the issue: when calling tx_subst_vars, we pass a list
of one element containing the expression, not wrapped in
sys:expr. Previously, we passed a one-element list containing
the sys:expr.
* parser.y (o_elem): If a list occurs in the syntax, represent
it as (sys:expr list) rather than (sys:expr . list).
(list): Do the same for @ n_expr syntax.
(expand_meta, make_expr): Harmonize with the representation
change.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The bug is that `@@@a` prints as `@@a` which
reads as a different object.
In this patch we simplify how quasiliterals are represented.
Embedded expressions are no longer (sys:expr E), just E.
Meta-numbers N and variables V are still (sys:var N).
However `@@a` and `@a` remain equivalent.
* eval.c (subst_vars): No need to look for expr_s;
just evaluate a compound form. The recursive nested
case is unnecessary and is removed.
(expand_quasi): Do nothandle expr_s; it is not
part of the quasi syntax any more.
* lib.c (out_quasi_str): Do not look for expr_s in the
quasi syntax; just print any expression with a @
the fallback case.
* match.c (tx_subst_vars): Analogous changes to those
done in subst_vars in eval.c.
* parser.y (quasi_meta_helper): Static function removed.
This was responsible for the issue due to stripping a
level of meta from expressions already having a meta
on them.
(quasi_item): In the `@` n_expr syntax case, no longer
call quasi_meta_helper. The remaining logic is simple
enough to put in line. Symbols and integers get wrapped
with (sys:var ...); other expressions are integrated
into the syntax as-is.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The print function now takes an optional boolean
for pretty printing.
The print method is also called with a third argument;
hence structures can customize both standard printing
and pretty printing.
* lib.c (obj_print): Take pretty argument, and pass it down
to obj_print_impl. This makes obj_pprint redundant.
(obj_pprint): Function removed: it was identical to obj_print
except for passing t down to obj_print_impl for the
pretty argument. These two wrappers had started small and
got bigger with identical changes done in parallel.
(pprint): New function.
(tostring, dump): Pass nil for pretty argument of obj_print.
(tostringp): Use pprint instead of obj_pprint.
* lib.h (obj_print): Declaration updated.
(obj_pprint): Declaration removed.
(print, pprint): Declared.
* eval.c (prinl): Pass nil for pretty_p argument of obj_print.
Do the stream defaulting here; obj_print doesn't do it.
(pprinl): Pass t for pretty_p argument of obj_print,
and do stream argument defaulting.
(eval_init): Register print to new print function rather
than directly to obj_print.
Register pprint to new pprint function rather than obj_pprint.
* hash.c (hash_print_op): Call obj_print_impl to print
the :equal-based keyword, rather than obj_print. Pass
down the pretty flag. All the other keywords are treated
this way; this fixes an inconsistency.
* match.c (dump_var): Call pprint instead of obj_pprint.
* stream.c (formatv): Call obj_print, with a calculated
pretty argument instead of switching between obj_pprint
and obj_print.
* struct.c (struct_inst_print): Except when in backward
compatibility mode, call the object's print method in both
pretty and regular printing mode, passing the mode as a third
argument.
* tests/012/oop.tl (defstruct animal): Support third argument
in print method. Make it optional because there are some
explicit calls which don't pass the argument.
* txr.1: Documentation updated for print method and the
print function. Revised text for some of the related
functions. Added compat notes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Makefile, args.c, args.h, arith.c, arith.h, cadr.c, cadr.h, combi.c,
combi.h, configure, debug.c, debug.h, eval.c, eval.h, filter.c,
filter.h, ftw.c, ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h,
jmp.S, lib.c, lib.h, lisplib.c, lisplib.h, match.c, match.h, parser.c,
parser.h, parser.l, parser.y, 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/except.tl, share/txr/stdlib/hash.tl,
share/txr/stdlib/ifa.tl, share/txr/stdlib/path-test.tl,
share/txr/stdlib/place.tl, share/txr/stdlib/socket.tl,
share/txr/stdlib/struct.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, 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: Revert to verbatim 2-Clause BSD.
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (load): Do not resolve all relative paths
relative to the current *load-path*, only pure
relative ones.
* match.c (v_load): Likewise.
* txr.1: Update doc for @(load)/@(include) and load function.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* match.c (v_load): Obtain parent load path from *load-path*
variable, rather than from source location info
associated with the directive. This changes the
semantics of when a @(load ...) occurs in code included
via @(include ...). That @(load ...) is processed in the
*load-path* context of the parent, rather than the
include.
* tests/011/txr-case.txr: Load txr-case.txr from the
standard library, rather than include it. Otherwise
txr-case.txr looks for txr-case.tl in tests/011.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The self-load-path symbol macro is as of now
deprecated. It simply expands to *load-path*.
*load-path* is a new special variable which is
dynamically bound to the path of a file
being loaded.
* eval.c (self_load_path_s): Global variable renamed
to load_path_s.
(sys_load): Bind *load-path* around processing of loaded file.
(me_load): Expand (load x) simply to (sys:load x *load-path*).
(set_get_symacro): Function removed.
(reg_symacro): New static function.
(eval_init): Initialize renamed load_path_s with interned
symbol having the name *load-path*. Register the *load-path*
special variable. Set up the sel-load-path symbol macro
aliasing for *load-path*.
* eval.h (self_load_path_s): Declaration renamed.
* match.c (v_load): Bind *load-path* around loading
or inclusion.
* parser.c (load_rcfile): Bind *load-path* around loading
of .txr_profile file.
* txr.c (txr_main): Bind *load-path* instead of
self-load-path symbol macro.
* txr.1: Updated documentation for @(load) directive
and load macro. Replaced documentation of self-load-path
with *load-path*.
|
|
|
|
| |
* match.c (v_cat): Use tleval_144 instead of txeval.
|
|
|
|
| |
* match.c (vars_to_bindings): Use tleval_144 instead of txeval.
|
|
|
|
|
|
|
| |
* match.c (do_output_line): Use num(i) rather than
num_fast(i), because i is not guaranteed to be in
the fixnum range. It's less than c_num(max_depth),
which could be a bignum that is in the cnum range.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* match.c (h_var): Check modifier for integerp rather
than fixnump.
(h_skip, h_coll, v_collect): Substitute zero only for nil
values of various numeric parameters, not for values that are
not fixnump.
(v_skip): Likewise, and check success for integerp rather than
fixnump. Even if the code can't handle bignums, we need to
steer into that case so it can do he right thing and throw an
exception.
(freeform_prepare): Use weaker integerp type test rather than
fixnump on arguments, for same reason as in v_skip.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* match.c (tlist_k): New keyword symbol variable.
(tleval_144): New static function.
(h_skip): evaluate min and max arguments as Lisp.
(h_coll): Evaluate all numeric keyword arguments as
Lisp: :min, :max, :gap, :times, :maxtimes, :mintimes,
:chars.
(h_call): Evaluate function expression as Lisp.
(do_output_line, do_output): Evaluate n and m parameters
in @(modlast) and @(mod) as Lisp.
(v_skip): Evaluate min and max as Lisp.
(v_fuzz): Evaluate m and n as Lisp.
(v_freeform): Evaluate arguments as Lisp.
(v_next): Support new argument, :tlist, which is like
:list, but with TXR style evaluation. From now on :list
uses Lisp evaluation, unless compatibility is set to 143
or lower. Also, evaluate the :string argument as Lisp.
(v_collect): Evaluate all numeric keyword arguments as
Lisp: :min, :max, :gap, :times, :maxtimes, :mintimes,
:lines.
(v_output): Evaluate stream in :continue or :finish
expression as Lisp.
(v_load): Evaluate load target as Lisp.
(v_close): Evaluate stream argument as Lisp.
(v_call): Evaluate function expression as Lisp.
(syms_init): Initialize tlist_k variable.
* tests/007/except-1.txr: Use :tlist instead of :list,
since argument is a TXR list expression.
* tests/010/block.txr: Likewise.
|
|
|
|
|
|
|
|
|
|
|
| |
* match.c (eval_with_bindings, eval_progn_with_bindings):
Change static function names to the shorter tleval and
tleval_progn. The first and second arguments swapped around to
match the convention used by txeval.
(dest_bind, h_coll, tx_subst_vars, do_txeval,
extract_bindings, do_output_line, do_output_line, do_output,
v_next, v_collect, v_output, v_do, v_require, v_if, h_do):
Follow rename.
|
|
|
|
|
|
|
|
| |
* match.c (h_coll, v_collect): Parse out :collect keyword
specification, using code borrowed from do_output.
Implement binding in collect loop.
* txr.1: Documented.
|
|
|
|
|
|
|
| |
* match.c (extract_vars): With these changes, if @{a b [c..d]}
appears inside a @(repeat) or @(rep), variables in the b, c
and d positions will be recognized for list iteration, not
only a.
|
|
|
|
|
|
|
|
|
| |
* match.c (v_output): Use txeval on the destination only if
compatibility is 142 or lower, or it is a meta expression
(so that @var and @(expr) still work without having to use
the compatibility option).
* txr.1: Documented and put in compatibility notes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Going forward, the "!command" and "$dir" are no longer
recognized, except with the backward-compatibility -C option.
The "-" string denoting standard input is only recognized from
the command line, not in the @(next) directive; and "-" cannot
be used in @(output) to denote standard output.
The main problem is that these are hacks which intrude into
the namespace. (What if a file is named "-", or begins with
"!" or "$"?) Secondly, they are possible security holes.
These prefixes are recognized even in computed strings, like
"@(next var)" where var contains "!command".
* Makefile (tst/tests/002/%): Run tests in this directory
with the -C 142 option in TXR_OPTS, because they use the !
mechanism.
* match.c (complex_open): New argument, from_cmdline,
indicating whether the file name came from the command
line or is internal. Function now only treats "-" as denoting
standard input, if that came from the command line.
The "!" and "$" prefixes are only recognized in compatibility
with 142 or earlier.
(v_next): Suppress old strategy of handling string sources by
pushing them to the file list to let match_files open them.
This is now done only under 142 compatibility. Instead, open
directly, produce the list, and recurse into match_files
with ready data. This is not only simpler, but also prevents
"-" from being recognized in @(next), because complex_open
is invoked directly, and the from_cmdline argument is
specified as nil.
(v_output): Don't rely on "-" denoting standard output; rather
use the stream directly, which can be passed to complex_open.
Pass nil to the new from_cmdline parameter of complex_open,
so "-" isn't recognized.
(open_data_source): Pass t for the from_cmdline parameter
of complex_open, to have "-" recognized as denoting
standard input.
* txr.1: Removed documentation referring to !, and use of -
in the @(next) and @(output) directives. Added
notes to COMPATIBILITY section.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This addresses a regression caused by commit
68ca87bc780e25dea1418019161d99727225d1ce, affecting a hundred
releases of TXR from 42 to 141.
The copy_alist call to deeply clone the variable bindings was
carelessly replaced with copy_list, to address the problem
that functions weren't able to mutate outer bindings.
However, the parameter binding code depends on the deep
cloning; it destructively manipulates bindings with the
understanding that they are copies that will be thrown away.
Test case:
@(define f0 (var))
@(end)
@(define f1 (out1 out2 var))
@ (bind out1 `a:@var`)
@ (maybe)
@ (f0 `b:@var`)
@ (end)
@ (bind out2 `a:@var`)
@(end)
@(f1 o1 o2 "z")
This program incorrectly binds o1 and o2 to different
strings, "a:z" and "a:b:z" respectively, because
the f0 pattern function call has the unwanted effect of
mutating var. Expected behavior is that both o1 and
o2 are bound to identical strings, "a:z" and "a:z".
* match.c (h_fun, v_fun): When binding arguments, extend
the environment with new bindings instead of trying to
re-use existing ones, because we do not have a copy of the
binding cells, like we used to when bindings_cp was
produced by a copy_alist call.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (self_load_path_s): New symbol variable.
(sys_load): Save, set-up and restore self-load-path
around load.
(set_get_symacro): New function.
(eval_init): Register load function using sys_load_s instead
of redundant intern.
* eval.h (set_get_symacro): Declared.
* match.c (v_load): Save, set-up and restore self-load-path
macro.
* parser.c (load_rcfile): Likewise.
* txr.c (txr_main: Set up self-load-path when opening
file.
* txr.1: Documented self-load-path.
|
|
|
|
|
|
|
|
|
|
| |
* eval.h (call_s): Declared.
* match.c (h_call, v_call): New static function.
(dir_tables_init): Register v_call in v_directive_table
under call symbol. Likewise h_call in h_directive_table.
* txr.1: Documented.
|
|
|
|
|
| |
* match.c (v_assert, h_assert): Use ~a rather than ~s
for c->curfile in assert message.
|
|
|
|
|
|
|
| |
* eval.c (sys_load): Use ~a format specifier rather than ~s
for the load path (if already known to be a string).
* match.c (v_load): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Numerous places in match.c are using assoc(sym, bindings)
logic to access a variable, which doesn't see the Lisp
globals, as we would like. For example, if foo is
defined using (defvar foo), @(set foo "A") doesn't work.
This is subject to the compatibility option.
* match.c (tx_lookup_var): New static function.
(dest_set, h_var, h_coll, h_parallel, h_fun, v_next,
v_parallel, v_gather, v_collect, v_flatten, v_cat,
v_output, v_filter, v_fun, match_filter): Use tx_lookup_var
instead of assoc for all lookups that see the full variable
scope. Only variable lists known to be locally consed up
are scanned with just assoc.
* txr.1: Documented new rules and added compatibility notes.
|