summaryrefslogtreecommitdiffstats
path: root/match.c
Commit message (Collapse)AuthorAgeFilesLines
* 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.
* Simple indirection on pattern functions: @(call).Kaz Kylheku2016-04-271-0/+59
| | | | | | | | | | * 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.
* Pretty print filename in assertion.Kaz Kylheku2016-04-251-2/+2
| | | | | * match.c (v_assert, h_assert): Use ~a rather than ~s for c->curfile in assert message.
* Don't quote path in load and @(load) diagnostics.Kaz Kylheku2016-04-221-5/+5
| | | | | | | * 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.
* Fix inconsistency of Lisp var visibility in TXR.Kaz Kylheku2016-04-171-29/+34
| | | | | | | | | | | | | | | | | | | 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.
* Fix internal error: bug in data stream opening logic.Kaz Kylheku2016-04-151-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | Test case: txr -c '@(bind x 1)A' name The problem here is that the specline has multiple elements, so when processing the bind, rest(specline) isn't nil. This means that control passes through to horizontal matching logic. No data source is open yet; just before that logic executes, open_data_source is called. However, open_data_source refuses because @(bind) is a directive that doesn't require data. So we end up in the internal error case, because we a data source, and no attempt was made to open one. The fix is for open_data_source to also check rest(specline). It cannot skip opening the data source just because the first_spec is a non-matching directive, according to the non_matching_directive_table. This criterion should only apply if it is the *only* directive, however. A spec line with multiple items must match a line of data; that's how the TXR language works. * match.c (open_data_source): Add a condition for classifying the directive as non-matching: it must be the only directive in the line (rest(specline) must be nil).
* Close source files after parsing.Kaz Kylheku2016-04-151-1/+6
| | | | | | | | | | | | | * eval.c (sys_load): close stream in all cases. * match.c (v_load): Likewise. * parser.c (load_rcfile): Close stream in unwind block, if open. * txr.c (txr_main): Close stream after parsing in all cases. If stream is std_input, or a string stream, close_stream does nothing.
* Merge some repeated code.Kaz Kylheku2016-03-221-31/+20
| | | | | | * match.c (maybe_next): New static function. (v_block, v_if): Replace block of code with call to maybe_next.
* New semantics for @(if) directive.Kaz Kylheku2016-03-221-0/+28
| | | | | | | | | | | | | | | * eval.h (if_s): Declared. * match.c (v_if): New static function. (dir_tables_init): Register v_if in v_directive_table under if symbol. * parser.y (IF): Token assigned to <lineno> type. (if_clause, elif_clauses_opt, else_clause_opt): New syntactic representation, understood by v_if. * txr.1: Documented if semantics more precisely, dropped the text about it being syntactic sugar for a cases with require, added compatibility note.
* Support binding in @(repeat)/@(rep) :vars.Kaz Kylheku2016-03-161-1/+16
| | | | | | | | | | | | | | | | * match.c (extract_bindings): Check for (var expr) syntax, evaluate and bind. * match.h (vars_k): Declared. * parser.y (expand_repeat_rep_args): New static function. (repeat_rep_helper): The :counter and :var arguments of repeat/rep must be macro-expanded, since there can be Lisp expressions there. This supports the new feature, but also fixes the bug of :counter (var form) not expanding form. * txr.1: Updated documentation about :vars in @(repeat).
* Bugfix and @(repeat) and @(rep).Kaz Kylheku2016-03-161-1/+1
| | | | | | | * match.c (extract_bindings): Do not destructively append to vars, because that's a piece of syntax. The return value of extract_vars is freshly allocated, though, so we can fix this by reversing the arguments.
* @(output)_destination can be a stream.Kaz Kylheku2016-03-141-21/+25
| | | | | | | | | | * match.c (complex_open): If name is a stream object, just return it. (v_output): Do not close the output stream if it came from a destination expression specifying an existing stream, and thus wasn't created inside complex_open. * txr.1: Document stream destination in output directive.
* Implement @(next nil).Kaz Kylheku2016-02-291-6/+10
| | | | | | | | * match.c (v_next): If argument to @(next) is nil, then evaluate remaining query in context with no list of files, and no data. * txr.1: Documented @(next nil).
* Add debug trace to @(require).Kaz Kylheku2016-01-221-1/+3
| | | | * match.c (v_require): Produce trace when require fails.
* Bugfix: @(require) eval not in proper env.Kaz Kylheku2016-01-221-2/+1
| | | | | | | | | I caught this when doing a @(require (boundp 'var)). * match.c (v_require): The correct evaluation was being done here, with the value discarded, followed by an incorrect evaluation in which the TXR bindings are not visible, whose value *is* then used.
* Header file cleanup.Kaz Kylheku2016-01-221-3/+0
| | | | | | | * arith.c, cadr.c, debug.c, eval.c, filter.c, gencadr.txr, glob.c, hash.c, linenoise/linenoise.c, lisplib.c, match.c, parser.c, rand.c, regex.c, signal.c, stream.c, struct.c, sysif.c, syslog.c, txr.c, unwind.c, utf8.c: Remove unncessary header files.
* New :mandatory keyword in until/last clauses.Kaz Kylheku2016-01-151-7/+36
| | | | | | | | | | | | | | | | | | | * match.c (mandatory_k): New keyword variable. (h_coll, v_gather, v_collect): Implement :mandatory logic. (syms_init): Initialize mandatory_k. * parser.l (grammar): The UNTIL and LAST tokens must be matched similarly to collect, without consuming the closing parenthesis, allowing a list of items to be parsed between the symbol and the closure, in the NESTED state. * parser.y (gather_clause, collect_clause, elem, repeat_parts_opt, rep_parts_opt): Adjust to new until/last syntax. In the matching productions, the abstract syntax changes to incorporate the options. In the output productions, we throw an error if options are present. * txr.1: Documented :mandatory for collect, coll and gather.
* Gather bugfix: support empty :vars.Kaz Kylheku2016-01-151-2/+5
| | | | | | | | * match.c (v_gather): Use getplist_f to distinguish the :vars nil case just like v_collect does. A :vars nil gather could be useful; it says none of the variables are strictly required. In any case, it is not correct to treat :vars nil as if :vars weren't there.
* Use last-form-evaled mechanism for pattern language.Kaz Kylheku2016-01-021-6/+12
| | | | | | | | | | | | | | We need this now, since file system errors aren't handled in the pattern language any more, after the complex_open refactoring. * eval.c (set_last_form_evaled): New function. * eval.h (set_last_form_evaled): Declared. * match.c (do_match_line, match_files): Save, set up and restore last_form_evaled via set_last_form_evaled function.
* Bugfix: premature open of data source.Kaz Kylheku2016-01-011-1/+1
| | | | | | | | | match.c (open_data_source): complex_open was being called before the check against opening the data source because the query starting with a non-matching directive. This is moved down into a more nested scope. This bug was found thanks to complex_open now throwing exceptions.
* Handle nothrow semantics down in complex_open.Kaz Kylheku2016-01-011-37/+12
| | | | | | | | | * match.c (file_err): Static function removed. (complex_open): New argument, nothrow. Catch exceptions derived from error only if nothrow is true. (v_output, open_data_source): Pass nothrow flag down to complex_open. Eliminate unnecessary error checking.
* Hacky struct fpip gone; complex_open returns stream.Kaz Kylheku2016-01-011-74/+26
| | | | | | | | | | | | | | | * match.c (enum fpip_close): Removed. (struct fpip, fpip_t): Removed. (complex_open): Use high level Lisp library function to return appropriate stream type, and return it directly. Exceptions are turned to a nil return to emulate old behavior. (complex_open_failed, complex_snarf, complex_stream): Static functions removed. (v_output, open_data_source): Use new interface of complex_open. complex_open_failed is just a nile check. complex_stream is a noop, and complex_snarf is just lazy_stream_cons.
* Copyright year bump.Kaz Kylheku2015-12-311-1/+1
| | | | | | | | | | | | | | | | | | | | | | | * LICENSE, 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, 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/cadr.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/struct.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, stream.c, stream.h, struct.c, struct.h, sysif.c, sysif.h, syslog.c, syslog.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h: Add 2016 copyright. * linenoise/LICENSE, linenoise/linenoise.c, linenoise/linenoise.h: Bump one principal author's copyright from 2014 to 2015. The code is based on a snapshot of 2015 upstream work.
* C++ breakage: multiple definition of name_s.Kaz Kylheku2015-12-301-2/+1
| | | | | | | | | | | | | * lib.c (name_s): Defined here now. (obj_init): name_s initialized here. * lib.h (name_s): Declared. * match.c (name_s): Definition removed. (syms_init): Initialization of name_s removed. * sysif.c (name_s): Definition removed. (sysif_init): Initialization of name_s removed.
* Shocking four-year-old bug in collect/coll.Kaz Kylheku2015-12-271-2/+7
| | | | | | | | | | | | | | | | | This originates to a commit on 2011-10-21. In that commit, I attempted to make until/last clauses have visibility to the bindings in the collect body (even though those are discarded). The problem is that the until/last clause is tried whether or not the body succeeds. When the body fails, no bindings emanate from it. In that case, the until/last clause is wrongly evaluated in an environment with no bindings whatsoever, meaning that even bindings that existed before the collect are not available to it. * match.c (h_coll, v_collect): Evaluate the last/until clause using the collect body bindings only if those bindings are not nil, otherwise use the original bindings from before entry into the collect.
* Allow @(repeat) and @(rep) to see Lisp globals.Kaz Kylheku2015-12-261-0/+11
| | | | | | | * match.c (extract_bindings): Process the final list of vars. For any variable not already on the list of output bindings, check if it has a Lisp binding, and if so, add *that* binding to the output bindings.
* TXR quasiliterals and output vars treated as Lisp.Kaz Kylheku2015-12-261-147/+69
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (format_field): Function moved here from match.c, along with the introduction of a new behavior: if a meta-expr occurs among the modifiers, its constituent expression is evaluated in its place. This allows for @{a @[expr]} which was previously not allowed in Lisp quasiliterals, but worked in TXR quasiliterals due to the treatment of @ by txeval. (subst_vars): Static function turns external, so code in match.c can call it instead of the subst_vars in that module. For that purpose, it needs to take a filter argument and process filters, like the match.c subst_vars. (op_quasi_lit): Pass nil as filter argument to subst_vars. * eval.h (format_field, subst_vars): Declared. * match.c (format_field): Function removed, moved to eval.c and slightly changed. (subst_vars): Renamed to tx_subst_vars. By default, now just a wrapper for subst_vars. In compatibility mode, invokes the old logic. (do_txeval, do_output_line): Call tx_subst_vars rather than subst_vars. * match.h (format_field): Declaration removed. * parser.y (expr): Grammar production removed: no longer referenced. (o_var): Braced variable case now parsed as n_expr, and expanded as expr by default, since this is Lisp now. In compatibility mode, expanded using expand_meta. Also SYMTOK case must be subject to expansion; an output var can now be a symbol macro. (expand_meta): Expand a quasi-literal as Lisp, except in compatibility mode. * txr.1: Bit of a documentation update. Existing doc isn't totally clear.
* Base value in :counterKaz Kylheku2015-12-231-4/+18
| | | | | | | * match.c (do_output_line, do_output): Decode (var expr) syntax as argument of :counter and implement displacement. * txr.1: Documented.
* New directives @(data) and @(name)Kaz Kylheku2015-12-221-1/+45
| | | | | | | | | | | * match.c (data_s, name_s): New symbol variables. (v_data, v_name): New static functions. (syms_init): Initialize data_s and name_s. (dir_tables_init): Register v_data and v_name as vertical directives, and enable them in horozintal context too using hv_trampoline. * txr.1: Documented.
* Allow @(line) in horizontal context.Kaz Kylheku2015-12-221-0/+1
| | | | | * match.c (dir_tables_init): Register hv_trampoline handler for line_s.
* Don't use ~d in several match debug diagnostics.Kaz Kylheku2015-12-221-2/+2
| | | | | * match.c (h_chr, v_line): Don't try to print clashing binding or object using ~d, because it might not be an integer.
* debugger: stopped at line nil of nil.Kaz Kylheku2015-12-181-4/+5
| | | | | | | | | | | | | Address some situations in which the debug_check call is given a piece of spec with no source loc information attached. * (h_var): Use rlcp when constructing new piece of spec representing a substituted variable, or a spec confined to just search for a piece of text with no trailing match. (do_match_line): Pass the whole specline to debug_check, rather than just the elem, which might just be a string with no location info attached. (match_files): Likewise.
* @(next) takes Lisp expression as source now.Kaz Kylheku2015-11-201-1/+14
| | | | | | | | | | | * match.c (v_next): Evaluate the source expression as TXR Lisp, unless it is meta-expression or meta-variable, or the compatibility option is set to 124 or lower. In those cases treat it as an expression of the TXR Pattern * txr.1: Updated documentation of @(next) and all relevant examples of @(next) everywhere. Added compatibility notes.
* @(rep) as shorthand for @(coll :vars nil).Kaz Kylheku2015-11-201-2/+11
| | | | | | | | | | | | | * match.c (h_coll): Check for rep symbol, and handle similarly to v_coll. Use symbol in error message. (dir_tables_init): Bind rep symbol to h_coll. * parser.y (elems): Don't generate rep_elem phrase structure for the sake of catching "rep outside of output"; this production now conflicts with the intent to allow this. (elem): Add various REP productions which clones of COLL. * txr.1: Documented new @(rep) usage.
* Use symbol in diagnostics in collect.Kaz Kylheku2015-11-201-9/+9
| | | | | * match.c (v_collect): Don't use hard-coded "collect" in diagnostics because the symbol can be repeat.
* Implementing *print-base* and ~d format directive.Kaz Kylheku2015-11-141-36/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * debug.c (show_bindings): Use ~d for level, so as not to be influenced by *print-base*. (debug): Use ~d for line numbers. * lib.c (gensym): Use ~d conversion specifier for formatting gensym counter into symbol name. * match.c (LOG_MISMATCH, LOG_MATCH): Use ~d for line number references. (h_skip, h_coll, h_fun, h_chr, match_line_completely, v_skip, v_fuzz, v_gather, v_collect, v_output, v_filter, v_fun, v_assert, v_load, v_line, h_assert, open_data_source): Use ~d for line refs, number of iterations, errno values. * parser.c (repl): Use ~d for prompt line numbers, numbered variables and the expr-<n> string in error messages. * parser.l (yyerrorf, source_loc_str): Use ~d for line numbers. * stream.c (print_base_s): New symbol variable. (formatv): Implement *print-base*. (stdio_maybe_read_error, stdio_maybe_error, stdio_close, pipe_close, open_directory, open_file, open_fileno, open_tail, open_process, run, remove_path): Use ~d for errno values. (stream_init): Initialize print_base_s and register *print-base* special variable. sysif.c (mkdir_wrap, ensure_dir, getcwd_wrap, mknod_wrap, chmod_wrap, symlink_wrap, link_wrap, readlink_wrap, excec_wrap, stat_impl, pipe_wrap, poll_wrap, getgroups_wrap, setuid_wrap, seteuid_wrap, setgid_wrap): Use ~d for errno values and system function results. * txr.1: Documented *print-base* and ~d conversion specifier.
* Pattern vars accessed from Lisp now dynamic.Kaz Kylheku2015-11-041-4/+29
| | | | | | | | | | | | | | | * eval.c (set_dyn_env): Static function becomes external. * eval.h (set_dyn_env): Declared. * match.c (eval_with_bindings, eval_progn_with_bindings): Evaluate Lisp code in null lexical environment. Instead install the pattern variables as dynamic, so they shadow global variables. A compatibility check for 121 or earlier provides the old behavior. * txr.1: Document scoping rules, and added compatibility notes.
* Factor out excessive uw_set_match_context calls.Kaz Kylheku2015-11-031-51/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | We only need to stash the TXR matcher's context in an environment frame when there is the possibility that Lisp code may be called, or filters which re-enter the matcher directly or through Lisp code. * match.c (eval_with_bindings, eval_progn_with_bindings): New static functions. (dest_bind): Use eval_with_bindings instead of five lines of boilerplate code. (h_chr): No need to stash context around dest_bind; lower levels take care of it. (subst_vars): Do set up match context around the body of this function, for the sake of Lisp calls and filtering in format_field. Use eval_with_bindings. (do_txeval): Remove match context environment frame setup around subst_vars. Use eval_with_bindings, too. (do_output_line): Use eval_with_bindings. (v_output): No match context environment frame around do_output. (v_do, v_require): Use eval_progn_with_bindings instead of five line boilerplate. (v_line): No match context frame around dest_bind. (h_do): Use eval_progn_with_bindings.
* New range type, distinct from cons cell.Kaz Kylheku2015-11-011-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (eval_init): Register intrinsic functions rcons, rangep from and to. (eval_init): Register rangep intrinsic. * gc.c (mark_obj): Traverse RNG objects. (finalize): Handle RNG in switch. * hash.c (equal_hash, eql_hash): Hashing for for RNG objects. * lib.c (range_s, rcons_s): New symbol variables. (code2type): Handle RNG type. (eql, equal): Equality for ranges. (less_tab_init): Table extended to cover RNG. (less): Semantics defined for ranges. (rcons, rangep, from, to): New functions. (obj_init): range_s and rcons_s variables initialized. (obj_print_impl): Produce #R notation for ranges. (generic_funcall, dwim_set): Recognize range objects for indexing * lib.h (enum type): New enum member, RNG. MAXTYPE redefined to RNG value. (TYPE_SHIFT): Increased to 5 since there are now 16 type codes. (struct range): New struct type. (union obj): New member rn, of type struct range. (range_s, rcons_s, rcons, rangep, from, to): Declared. (range_bind): New macro. * parser.l (grammar): New rule for recognizing the #R sequence as HASH_R token. * parser.y (HASH_R): New terminal symbol. (range): New nonterminal symbol. (n_expr): Derives the new range symbol. The n_expr DOTDOT n_expr rule produces rcons expression rather than const. * match.c (format_field): Recognize rcons syntax in fields which is now what ranges translate to. Also recognize range object. * tests/013/maze.tl (neigh): Fix code which destructures range as a cons. That can't be done any more. * txr.1: Document ranges.
* Stop using C library setjmp/longjmp.Kaz Kylheku2015-10-251-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | TXR is moving to custom assembly-language routines. This is mainly motivated by a very dubious thing done in the GNU C Library setjmp and longjmp in the name of security. Evidently, glibc's setjmp "mangles" certain pointer values which are stored into the jmp_buf buffer. It's been that way since 2005, evidently. This means that, firstly, all along, the use of setjmp in gc.c to get registers into a buffer so they can be scanned has not actually worked properly. More importantly, this pointer mangling in setjmp and longjmp is very hostile to a stack copying implementation of delimited continuations. The reason is that continuations contain jmp_buf buffers, which get relocated in the process of capturing and reviving a continuation. Any pointers in a jmp_buf which point into the captured stack segment have to be fixed up to point into the relocated location. Mangled pointers make this difficult, requiring hacks which are specific to glibc and the machine architecture. We might as well implement a clean, well-behaved setjmp and longjmp. * Makefile (jmp.o): New object file. (dbg/%.o, opt/%.o): New rules for .S prerequisites. * args.c, arith.c, cadr.c, combi.c, cadr.c, combi.c, debug.c, eval.c, filter.c, glob.c, hash.c, lib.c, match.c, parser.c, rand.c, regex.c, signal.c, stream.c, struct.c, sysif.c, syslog.c, txr.c, unwind.c, utf8.c: Removed <setjmp.h> include. * gc.c: Switch to struct jmp and jmp_save, instead of jmp_buf and setjmp. * jmp.S: New source file. * signal.h (struct jmp): New struct type. (jmp_save, jmp_restore): New function declarations denoting assembly language routines in jmp.S. (extended_jmp_buf): Uses struct jmp instead of setjmp. (extended_setjmp): Use jmp_save instead of setjmp. (extended_longjmp): Use jmp_restore instead of longjmp.
* Fix cascading message for unbound vars in pattern language.Kaz Kylheku2015-09-271-2/+4
| | | | | | | | | | | | | Commit 5ab2b46a on 2011-10-06 introduced a hack for suppressing redundant location informaton being tacked on to an unbound variable error (in the TXR pattern language, not TXR Lisp). This ugly hack broke along the way when uw_throw was changed so that exception arguments are always lists, because it still expects the exception object to be a string. (The breaking change took place in 55cc8493, on 2015-02-06). * match.c (do_txeval): In exception catch, exc is a list, and not a string.
* C++: don't use int constant as enum initializer.Kaz Kylheku2015-09-091-1/+1
| | | | | * match.c (complex_open): Initialize member close of fpip_t using fpip_close enum constant.
* TXR 105 regression: real-time stream not used on tty.Kaz Kylheku2015-09-071-6/+11
| | | | | | | | | | | | | | | | | When the -n option was introduced, on Mar 29, 2015, the change didn't take into account that the hacky complex_open function takes the C stdin stream directly, and not the std_input Lisp stream. After that change, only the std_input is automaticaly marked for real-time input if standard input is a tty, and not any stream later opened from stdin. * match.c (enum fpip_close): New enum member, fpip_close_stream. (struct fpip): New member s, for smuggling through a stream. (complex_open): If name is "-", then plant std_input or std_output as the s member of fpip_t, rather than planting stdin or stdout as the f member. (complex_open_failed): Check for nil stream also. (complex_snarf, complex_stream): Handle stream case.
* Go into repl after processing txr file also.Kaz Kylheku2015-09-071-5/+6
| | | | | | | | | | | * match.c (extract): Return match result as cons, rather than int termination status. * match.h (extract): Declaration updated. * txr.c (txr_main): Handle result cons. If repl mode is selected, pass bindings from car(result) to repl. Otherwise use match success indication in cdr(result) to determine termination status.
* Replace two-step initialization of args with macros.Kaz Kylheku2015-08-241-4/+2
| | | | | | | | | | | | | | | | | | | | | * args.h (args_init_list, args_init): Return the struct args * pointer. (args_decl_list, args_decl): New macros. * eval.c (apply, do_eval, expand_macro, op_dwim, op_catch, (mapcarl, lazy_mapcarl): Switch to new macros. * hash.c (hashl): Likewise. * lib.c (generic_funcall, lazy_appendl, maxl, minl, funcall, funcal1, funcall2, funcall3, funcall4, transpose, juxtv, do_and, do_or, do_iff, unique): Likewise. * match.c (h_fun, v_fun): Likewise. * stream.c (vformat): Likewise. * syslog.c (syslog_wrap): Likewise.
* Use of new args for function calls in interpreter.Kaz Kylheku2015-08-231-2/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * args.c (args_copy_to_list): New function. * args.h (ARGS_MIN): New preprocessor symbol. (args_add_list): New inline function. (args_copy_to_list): Declared. * debug.c (debug): Args in debug frame are now struct args *. Pull them out nondestructively for printing using args_copy_to_list. * eval.c (do_eval_args): Fill struct args argument list rather than returning evaluated list. Dot position evaluation is handled by installing the dot position value as args->list. (do_eval): Allocate args of at least ARGS_MAX for the call to do_eval_args. Then use generic_funcall to invoke the function rather than apply. (eval_args_lisp1): Modified similarly to do_eval_args. (eval_lisp1): New static function. (expand_macro): Construct struct args argument list for the sake of debug_frame. (op_dwim): Allocate args which are filled by eval_args_lisp1, and applied to the function/object with generic_funcall. The object expression is separately evaluated with eval_lisp1. * match.c (h_fun, v_fun): Construct struct args arglist for the sake of debug_frame call. * unwind.c (uw_push_debug): args argument becomes struct args *. * unwind.h (struct uw_debug): args member becomes struct args *. (uw_push_debug): Declaration updated. * txr.1: Update documentation about dot position argument in function calls. (list . a) now works, which previously didn't.
* Crafting a better parser-priming hack.Kaz Kylheku2015-08-121-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The method of inserting a character sequence which generates a SECRET_TOKEN_E token is being replaced with a purely token based method. Because we don't manipulate the input stream, the lexer is not involved. We don't have to flush its state and deal with the carry-over of the yy_hold_char. This comes about because recent changes expose a weakness in the old scheme. Now that a top-level expression can have the form expr.expr, it means that the Yacc parser reads one token ahead, to see whether there is a dot or something else. This lookahead token is discarded. We must re-create it when we call yyparse again. This re-creation is done by creating a custom yylex function, which can maintain pushback tokens. We can prime this array of pushback tokens to generate the SECRET_TOKEN_E, as well as to re-inject the lookahead symbol that was thrown away by the previous yyparse. To know which lookahead symbol to re-inject is simple: the scanner just keeps a copy of the most recent token that it returns to the parser. When the parser returns, that token must be the lookahead one. The tokens we keep now in the parser structure are subject to garbage collection, and so we must mark them. Since the YYSTYPE union has no type field, a new API is opened up into the garbage collector to help implement a conservative GC technique. * gc.c (gc_is_heap_obj): New function. * gc.h (gc_is_heap_obj): Declared. * match.c: Include y.tab.h. This is now needed by any module that needs to instantiate a parser_t structure, because members of type YYSTYPE occur in the structure. (parser.h can still be included without y.tab.h, but only an incomplete declaration for the parser strucure is then given, and a few functions are not declared.) * parser.c (yy_tok_mark): New static function. (parser_mark): Mark the recent token and the pushback tokens. (parser_common_init): Initialize the recent token, the pushback tokens, and the pushback stack index. (pushback_token): New static function. (prime_parser): hold_byte argument removed. Body considerably simplified. The catenated stream trick is no longer required. All we do here is set up two pushback tokens and prime the scanner, if necessary, so it is in the right start state for Lisp. * parser.l (YY_DECL): Take over definition of scanning function, renaming to yylex_impl, so we can implement yylex. (grammar): Rule which produces SECRET_ESCAPE_E token removed. (reset_scanner): Function removed. (yylex): New function. * parser.h (struct parser): Now only forward-declared unless y.tab.h has been included. New members, recent_tok, tok_pushback and tok_idx. (yyset_hold_char): Declared. (reset_scanner): Declaration removed. (yylex): Declared (if y.tab.h included). (prime_parser): Declaration updated. (prime_scanner): Declared. * Makefile: express new dependency on existence of y.tab.h of txr.o, match.o and parser.o.
* * eval.c (force): Default the new second argument of source_loc_str.Kaz Kylheku2015-08-041-4/+5
| | | | | | | | | | | | | | | | | | | (eval_error): Derive location of error from the last_form_evaled, if form doesn't have it. (eval_init): Re-register source-loc-str as binary with an optional arg. * match.c (debuglf, sem_error, file_err, typed_error): Default new argument of source_loc_str. * parser.h (source_loc_str): Declaration updated. * parser.l (source_loc_str): Take second argument which specifies alternative value if the source loc info is not found. * unwind.c (uw_throw): Simplify code thanks to source_loc_str default argument. * txr.1: Document new argument of source-loc-str.
* Hash-bang support for .tl files.Kaz Kylheku2015-07-021-1/+1
| | | | | | | | | | | | | | | | * parser.c (read_eval_stream): New boolean argument to request hash bang support. * parser.h (read_eval_stream): Declaration updated. * eval.c (sys_load): Pass new thid argument to read_eval_stream, to decline hash bang support. * match.c (v_load): Likewise. * txr.c (txr_main): Request hash bang support from read_eval_stream. Thus files referenced from the txr command line can have a #! line, which is ignored.
* @(load) and @(include) now load Lisp code.Kaz Kylheku2015-06-121-29/+36
| | | | | | | | | | | * match.c (v_load): Check txr_lisp_p flag coming out of open_txr_file and handle the Lisp case usin read_eval_stream. * parser.c (read_eval_stream, get_parser, parser_errors): New functions. * parser.h (read_eval_stream, get_parser, parser_errors): Declared.