summaryrefslogtreecommitdiffstats
path: root/match.c
Commit message (Collapse)AuthorAgeFilesLines
* Bind variable during directive delimited match.Kaz Kylheku2017-03-221-1/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Remove useless consume_prefix call.Kaz Kylheku2017-03-221-2/+0
| | | | | | | | | * 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.
* Bugfix: missing warnings when main file is .txr.Kaz Kylheku2017-03-221-0/+3
| | | | | | | | | | | | | | | | | | | 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.
* Rename badly named default_bool_argKaz Kylheku2017-03-171-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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.
* Add in-package directive.Kaz Kylheku2017-03-131-1/+2
| | | | | | | | | | | | * 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.
* New directive: mdo.Kaz Kylheku2017-03-121-1/+2
| | | | | | | | | | | | | | | * 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.
* bugfix: @(next) in function called with match-fun.Kaz Kylheku2017-03-121-2/+6
| | | | | | | | | | | | | | | | | | | | 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-fun: report error using external name.Kaz Kylheku2017-03-121-1/+1
| | | | | * match.c (match_fun): Report self as match-fun in error message.
* match-fun: make last two args optional.Kaz Kylheku2017-03-121-1/+3
| | | | | | | | * eval.c (eval_init): Update registration of match-fun. * match.c (match_fun): Do defaulting on third and fourth arg. * txr.1: Documenation updated.
* Don't open streams or stdin on non-matching directives.Kaz Kylheku2017-03-091-22/+25
| | | | | | | | | | | | | * 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.
* Don't sweep bad data source under the rug.Kaz Kylheku2017-03-081-1/+1
| | | | | * match.c (open_data_source): If the data source isn't a string or stream, then error out.
* clean up open_data_source function.Kaz Kylheku2017-03-081-7/+5
| | | | | * match.c (open_data_source): do the spec_bind in just one place. Use first_spec consistently in the debuglf calls.
* Drop the annoying need for - for standard input.Kaz Kylheku2017-03-081-1/+9
| | | | | | | | | | | | | * 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.
* bugfix: :counter var not registered tentative.Kaz Kylheku2017-03-041-0/+4
| | | | | | | | | | | | | | | 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.
* bugfix: expand :counter property in @(collect).Kaz Kylheku2017-03-041-1/+10
| | | | | | | * 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.
* bugfix: integrate finally clause with accept.Kaz Kylheku2017-02-231-20/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* bugfix: data stream escape in accept transfers.Kaz Kylheku2017-02-201-1/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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).
* bugfix: accept allowing binding escape.Kaz Kylheku2017-02-201-0/+33
| | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Eliminate common code: pattern fun binding resolution.Kaz Kylheku2017-02-201-36/+37
| | | | | | * match.c (fun_resolve_bindings): New static function. (h_fun, v_fun): Replace common code with a call to fun_resolve_binding.
* Bugfix: h_trailer has to intercept accept.Kaz Kylheku2017-02-161-8/+26
| | | | | | | * 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.
* Support horizontal @(block), phase 2.Kaz Kylheku2017-02-151-12/+62
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Support horizontal @(block), phase 1.Kaz Kylheku2017-02-151-0/+45
| | | | | | | | | | | | 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.
* Support horizontal form of @(throw).Kaz Kylheku2017-02-131-0/+1
| | | | | | | * match.c (dir_tables_init): Wire throw_s into horizontal dispatch table via hv_trampoline. * txr.1: Documented.
* Registering tentative def must purge warning.Kaz Kylheku2017-01-251-1/+0
| | | | | | | | * 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.
* Bump copyright year to 2017.Kaz Kylheku2017-01-231-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | * 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.
* Dynamically rebind *package* in @(load).Kaz Kylheku2017-01-221-0/+1
| | | | | | | * 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.
* Dump deferred warnings in @(load).Kaz Kylheku2017-01-221-0/+4
| | | | | | * 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.
* Enable unbound warnings when expanding TXR code.Kaz Kylheku2017-01-221-4/+64
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* bugfix: expand macros in a number of directives.Kaz Kylheku2017-01-211-8/+72
| | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Consolidate unbound var errors in pattern language.Kaz Kylheku2017-01-201-33/+22
| | | | | | | | | | * 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.
* Bugfix: expand macros in collect, coll, gather.Kaz Kylheku2017-01-191-0/+52
| | | | | | | | | | | | | | | 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.
* bugfix: quasilit read/print consistency, part 2.Kaz Kylheku2016-11-261-6/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* bugfix: quasilit read/print consistency, part 1.Kaz Kylheku2016-11-261-8/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Changes to the printing framework.Kaz Kylheku2016-10-201-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Synchronize license comments with LICENSE.Kaz Kylheku2016-10-011-16/+17
| | | | | | | | | | | | | | | | | | | | * 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.
* Change criterion for *load-path*-relative loading.Kaz Kylheku2016-09-271-1/+1
| | | | | | | | | | * 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.
* Use *load-path* in load/include directive.Kaz Kylheku2016-09-261-1/+1
| | | | | | | | | | | | | | * 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.
* Overhaul of self-load-path mechanism.Kaz Kylheku2016-09-261-3/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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*.
* Separator expression in @(cat) evaluated as Lisp.Kaz Kylheku2016-06-261-1/+1
| | | | * match.c (v_cat): Use tleval_144 instead of txeval.
* Use Lisp eval for :var inits in collect and gather.Kaz Kylheku2016-06-261-1/+1
| | | | * match.c (vars_to_bindings): Use tleval_144 instead of txeval.
* Bugfix: unsafe num_fast in repeat/rep :counter code.Kaz Kylheku2016-06-171-6/+6
| | | | | | | * 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.
* Address silly uses of fixnump.Kaz Kylheku2016-06-171-26/+22
| | | | | | | | | | | | | | * 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.
* Replace most TXR eval with Lisp eval.Kaz Kylheku2016-06-141-43/+70
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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.
* Rename Lisp eval wrappers and change arg order.Kaz Kylheku2016-06-131-41/+32
| | | | | | | | | | | * 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.
* Implement :counter in collect/coll.Kaz Kylheku2016-06-091-4/+57
| | | | | | | | * 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.
* Allow @(repeat) to see variables in more places.Kaz Kylheku2016-06-041-3/+30
| | | | | | | * 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.
* @(output) evaluates destination as Lisp.Kaz Kylheku2016-06-031-1/+7
| | | | | | | | | * 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.
* Eliminating the ! $ and - file-opening hacks.Kaz Kylheku2016-05-311-10/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Fix 2011-11-17 regression.Kaz Kylheku2016-05-271-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* New feature: self-load-path symbol macro.Kaz Kylheku2016-05-181-6/+19
| | | | | | | | | | | | | | | | | | | | | * 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.