summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* bugfix: expand macros in a number of directives.Kaz Kylheku2017-01-214-13/+76
| | | | | | | | | | | | | | | | | | | | | | | | | 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.
* bugfix: expand dest arg of @(output).Kaz Kylheku2017-01-211-1/+12
| | | | | * parser.y (expand_form_ver): New inline function. (output_clause): If exprs are present, expand first one.
* 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.
* Expand lisp forms in @(mod) and @(modlast) args.Kaz Kylheku2017-01-191-4/+15
| | | | | | * parser.y (expand_forms_ver): New function. (repeat_parts_opt, rep_parts_opt): Expand the exprs_opt that follow MOD or MODLAST.
* Bugfix: expand macros in collect, coll, gather.Kaz Kylheku2017-01-193-16/+77
| | | | | | | | | | | | | | | 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.
* Test cases for macros in quasiliterals.Kaz Kylheku2017-01-181-0/+11
| | | | * tests/012/quasi.tl: New tests added.
* Muffle expansion warning in op macro.Kaz Kylheku2017-01-181-2/+6
| | | | | * eval.c (me_op): Install handler to intercept warnings and route them to uw_muffle_warning.
* Bugfix: macros not expanded in quasiliterals.Kaz Kylheku2017-01-181-0/+2
| | | | | | * eval.c (expand_quasi): Add all-important missing case which expands compound forms. This looks like a txr-160 regression.
* Document new diagnostic functions.Kaz Kylheku2017-01-161-0/+235
| | | | | | | | * txr.1: New section Static Error Diagnosis describing error handling and warnings. Documented functions tentative-def-exists, register-tentative-def, purge-deferred-warning, compile-defr-warning, compile-error and compile-warning
* bugfix: supertype check in make-struct-type.Kaz Kylheku2017-01-161-1/+1
| | | | | | * struct.c (make_struct_type): Fix test of incorrect variable which renders the supertype test useless, causing the type to be created with no supertype.
* defstruct: use warning for bad baseKaz Kylheku2017-01-161-4/+4
| | | | | * share/txr/stdlib/struct.tl (defstruct): Making nonexistent base type a deferrable warning.
* defstruct uses new error reporting functions.Kaz Kylheku2017-01-161-35/+32
| | | | | | | * share/txr/stdlib/struct.tl (sys:bad-slot-syntax): Takes form argument. Uses compile-error function. (defstruct): Use modified form of sys:bad-slot-syntax and compile-error instead of throw.
* defmeth uses new error reporting.Kaz Kylheku2017-01-161-6/+9
| | | | | | | * share/txr/stdlib/struct.tl (sys:defmeth): Removing checks from here. (defmeth): Add checks here with new functions which provide location info and warning deferral/supression.
* defstruct registers tentative definition.Kaz Kylheku2017-01-161-0/+1
| | | | | * share/txr/stdlib/struct.tl (defstruct): Register the struct ame as a tentative definition.
* Use tentative def mechanism for functions and vars.Kaz Kylheku2017-01-151-0/+6
| | | | | | * eval.c (do_expand): When walking a defun or defvarl, register them as tentative defs. Thus warnings are nicely supressed in code like (progn (defun foo ()) (foo)).
* Extend deferred warnings system with tentative defs.Kaz Kylheku2017-01-152-3/+21
| | | | | | | | | | | | | | | | | | | | Tentative defs record the fact that some definition has been seen at expansion time, even though that definition has not been put into effect. They suppress warnings. * unwind.c (tentative_defs): New static variable. (uw_defer_warning): Throw away the warning if it matches a tentative def. (uw_register_tentative_def, uw_tentative_def_exists): New functions. (uw_dump_deferred_warnings): Purge the tag from the list of deferred defs also. (uw_init): gc-protect tentative_defs. Register intrinsics register-tentative-def and tentative-def-exists. * unwind.h (uw_register_tentative_def, uw_tentative_def_exists): Declared.
* Dump deferred warnings in eval_intrinsic.Kaz Kylheku2017-01-152-3/+12
| | | | | | | | | | | | * eval.c (eval_intrinsic): Dump deferred warnings after expansion, unless in the middle of a load. * parser.c (read_eval_ret_last): Bind *load-recursive* around all evaluations to t, then dump warnings if prior value of *load-recursive* is nil. Thus the repl's :read feature behaves like load. (repl_warning): We can now unconditionally defer deferrable warnings here now, whether or not in a load.
* Rebind *stderr* on entry into repl.Kaz Kylheku2017-01-151-0/+4
| | | | | * parser.c (repl): Create a new dynamic env and rebind *stderr* variable to the repl's output stream.
* Functions for error reporting out of macros.Kaz Kylheku2017-01-155-0/+70
| | | | | | | | | | | | | | | | | * eval.c (eval_init): Register sys:ctx-form and sys:ctx-name intrinsics. * lisplib.c (error_set_entries, error_instantiate): New static functions. (lisplib_init): Register autoloading of error.tl via new functions. * share/txr/stdlib/error.tl: New file. * struct.c (make_struct_type): Purge deferred warnings. * unwind.c (uw_late_init): Register purge-deferred-warning intrinsic.
* bugfix: diagnose dotted form calls consistently.Kaz Kylheku2017-01-131-13/+13
| | | | | | | * eval.c (do_expand): Warn about unbound functions or non-bindable symbols in function position regardless whether the form is a dotted form that was subject to the apply transformation.
* Deferred warnings.Kaz Kylheku2017-01-136-14/+106
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Warnings about undefined functions and variables are now deferred during loading, so forward references do not generate nuisance diagnostics. * eval.c (load_recursive_s): New symbol variable. (eval_defr_warn): New static function. (op_defvarl, op_defun): Purge any deferred warning about the given function or variable not being defined. (load): Rebind the sys:*load-recursive* special var to true around the load. After the load, dump deferred warnings if the prior binding of sys:*load-recursive* is false. Discard deferred warnings in the case of termination by a nonlocal control transfer. (do_expand): Treat unbound vars and functions as deferrable warnings, specially tagged for individual purging frkm the deferred list. (eval_init): Intern sys:*load-recursive* and initialize load_recursive_s variable. * eval.h (load_recursive_s): Declared. * parse.c (repl_warning): Accept variable arguments. Check whether we are loading and if so, defer deferrable (repl): Adjustment for altered signature of repl_warning. warnings. * txr.c (txr_main): dump deferred warnings after evaluating Lisp stream. * unwind.c (deferred_warnings): New static variable. (uw_throw): When a deferrable warning is caught, suppress the usual message and add it to the deferred_warnings list. (uw_defer_warning, uw_dump_deferred_warnings, uw_dump_deferred_warnings, uw_purge_deferred_warnings): New functions. (uw_late_init): gc-protect deferred_warnings. * unwind.h (uw_defer_warning, uw_dump_deferred_warnings, uw_dump_deferred_warnings, uw_purge_deferred_warnings): New functions declared.
* Man page checker update.Kaz Kylheku2017-01-121-3/+19
| | | | | | | | | | | | | | * checkman.txr (check-func): Bugfix: neglect to scan .synb sections for two types of headings. Include accessors, methods and structs in the check. (check-cblk): Use @(last) rather than @(until) so closing .cble is consumed. Otherwise the new check for dangling .cble will report false positives. (check-spurious): New pattern function to detect dangling .syne and .cble. (main loop): Include a stand-alone .synb check for the sake of special sections like Update expander. Include check-spurious.
* doc: bad cblk and synb.Kaz Kylheku2017-01-121-9/+8
| | | | | * txr.1: Fix numerous instances of bad .cble/.cblk usage and replace one .synb/.syne with .cblk/.cble.
* doc: spurious blank line.Kaz Kylheku2017-01-121-1/+0
|
* doc: use markup in struct syntax.Kaz Kylheku2017-01-121-6/+6
| | | | | * txr.1: Use .mets in syntax block for frame, catch-frame anf handle-frame, as well as time.
* doc: bad headings.Kaz Kylheku2017-01-121-2/+2
| | | | | * txr.1: Fixed spurious comma in Methods car ... heading and no and @ in Accessors caar ...
* doc: blank line after .desc.Kaz Kylheku2017-01-121-1/+0
| | | | * txr.1: Fixed under symbol-value.
* doc: bad .IKaz Kylheku2017-01-121-1/+1
| | | | * txr.1: .I with run-on comma after quote becomes .IR.
* doc: shorten param macro memoization example.Kaz Kylheku2017-01-121-6/+1
| | | | * txr.1: Replace silly loop with idiomatic code.
* doc: formatting issue in param macros example.Kaz Kylheku2017-01-121-1/+1
| | | | * txr.1: Fix .cble that should be .cblk.
* Version 165.txr-165Kaz Kylheku2017-01-106-779/+803
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* Eliminate rejection of empty clauses.Kaz Kylheku2017-01-081-87/+27
| | | | | | * parser.y (grammar): Remove all checks which raise a syntax error if a clause is empty. These reject some correct situations, getting in the programmer's way.
* Allow last var to be omitted in whilet.Kaz Kylheku2017-01-062-3/+30
| | | | | | | * eval.c (me_whilet): insert gensym if last var is missing. Warn if init-form looks like a variable. * txr.1: Documented by copy and paste from iflet.
* Missing space in hash printed rep.Kaz Kylheku2017-01-061-0/+1
| | | | | * hash.c (hash_print_op): For hash tables that have both weak keys and weak values, print a space between the keywords.
* New Lisp feature: param list expander.Kaz Kylheku2017-01-044-6/+302
| | | | | | | | | | | | | | | | | | | | | * eval.c (pm_table): New static variable. (expand_param_macro): New static function. (expand_params): Expand parameter list macros via expand_param_macro. (eval_init): gc-protect pm_table and initialize it. Register *param-macro* variable. * lisplib.v (pmac_set_entries, pmac_instantiate): New static functions. (lisplib_init): Register autoloading of pmac.tl via new functions. * share/txr/stdlib/pmac.tl: New file. * txr.1: Notes under defun, lambds, flet/labels and defmacro about the existence of parameter macros which add to the syntax. New Parameter List Macros section. Documented *param-macro* and define-param-expander.
* Version 164.txr-164Kaz Kylheku2017-01-016-142/+175
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* bugfix: sys:setq bindable check must be warning.Kaz Kylheku2017-01-011-1/+7
| | | | | | | | | | | | | | | The problem is that during the expansion of something like (do inc @1), the place expansion will generate a (sys:setq @1 ...) form which undergoes expansion before the processing which converts @1 to a gensym. But now that throws an error during the expansion of the sys:setq form that @1 isn't a bindable symbol. Since warnings are suppressed during this expansion phase, we can make it a warning. * eval.c (not_bindable_warning): New static function. (do_expand): For the assignment special forms, throw a warning if the target isn't a bindable symbol, not an error.
* Bugfix: repeated expansion of catch unstable.Kaz Kylheku2016-12-314-18/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | It turns out we have a silly problem: catch is a special operator, which undergoes a macro-like expansion which alters its syntax, but uses the same operator symbol. We turn catch into a macro which expands to a sys:catch operator. * eval.c (sys_catch_s): New symbol variable. (expand_catch): Function now expands sys:catch forms without altering any syntax. (do_expand): Check for sys:catch rather than catch. Call expand_catch differently: it takes the form now instead of just the arguments, so it can return the original form if no expansion takes place. (eval_init): Initialize sys_catch_s variable. Change registration of op_catch to sys:catch symbol. * lisplib.c (except_set_entries): Add catch to the list of autoload symbols for except.tl. * share/txr/stdlib/except.tl (catch): New macro for transforming catch to sys:catch. * txr.1: Reclassify catch operator as a macro.
* Check for non-symbols in catch clauses.Kaz Kylheku2016-12-311-0/+2
| | | | | * eval.c (expand_catch_clause): Check added that clause sym must be a symbol.
* Bugfix: quasilit var read-print consistency.Kaz Kylheku2016-12-311-2/+9
| | | | | | | | | | | | | | The problem is that objects like `@{foo:bar} @{*xyz*}` are printing as `@foo:bar @*xyz*` without the required braces. This changes the meaning, as in @foo:bar which is @foo followed by the text :bar, or creates a syntax error, as in @*xyz*. * lib.c (out_quasi_str): When printing a var, first convert it to a string form by printing to a string stream. Then if the string form consists of anything other than letters, digits and underscores, mark it as needing braces, in addition to the existing conditions.
* Check assignment special forms at expansion time.Kaz Kylheku2016-12-291-35/+29
| | | | | | | | | | | | | | * eval.c (lispq_setq_s, setqf_s): New symbol variables. (op_defvarl, op_defsymacro, op_defmacro, op_setq, op_lisp1_setq, op_setq): Drop bindability checks. In the case of defmacro, this is already taken care of so the check is redundant. (do_expand): Add bindable check to defvar_s and cousins. In the function form fallback case, check for the various assignment operators and check their argument count and bindability of destination symbol. (eval_init): Initialize new symbol variables; register corresponding special operators using variables.
* Reintroduce lambda checks and macro param bugfix.Kaz Kylheku2016-12-291-37/+67
| | | | | | | | | | | | | | | | | | | | | | Fix nested macro parameters not being expanded properly in all cases. Diagnose uses of :env, :form and :whole in function parameter lits. * eval.c (expand_opt_params_rec, expand_params_rec): New parametr, macro_style_p, indicating destructuring macro parameter list is to be expanded. Restructure the cases in expand_opt_params_rec to fix a bug: only recursively treating a nested parameter A only when A stands alone, or without a default form as (A), failing to do so when it is (A B ...). Diagnose :env, :whole or :form inside a function parameter list. Do not process recursive parameter lists for functions; diagnose nesting as bad syntax. (expand_params): Add macro_style_p parameter. (expand_macrolet, expand_tree_cases): Pass t as argument to new parameter of expand_params. (do_expand): Pass t or nil as argument to new parameter of expand params, based on whether expanding a macro or function parameter list.
* Bugfix: optarg presence indicators may be specials.Kaz Kylheku2016-12-291-0/+7
| | | | | | | | | | | This fixes the incorrect treatment of the x-p parameter in (lambda (: (x form x-p))) when x-p is a special variable. It is being lexically bound. * eval.c (expand_opt_params_rec): When processing a (var initform) pair, check for (var initform sym). Error out if sym is not bindable. Check if it is special and if so, push it into the list of specials.
* Hoist binding and arg checking to expansion time.Kaz Kylheku2016-12-291-171/+124
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Checking for uses of non-bindable symbols in variable binding and argument lists is moved to expansion time. Also checked at expansion time are macro lambda list conventions. :env and others must have a bindable parameter, and the optional arg colon cannot occur twice. * eval.c (bind_args): Remove run-time checks that are now done at expansion time. (not_bindable_error): New function. (expand_opt_params_rec, expand_params_rec): Take form argument for reporting errors. Implement more detailed checking against non-bindable symbols, and against :env, :form and :whole having missing or unsuitable arguments. (expand_params): Take form argument for error reporting, and pass to expand_params_rec. (bind_macro_params, bindings_helper): Remove run-time checks that are now done at expansion time. (check_lambda_list): Function removed, because expand_params now does the bulk of this check. We have a regression here in that we lose the check against :env and others occurring in a function parameter list; this has to be worked into expand_params. (op_defvarl, op_defsymacro, op_defmacro, op_setq, op_lisp1_setq, op_setqf): Replace repeated code with call to not_bindable_error. However, these should be replaced by expansion-time checks anyway, and eventually will be. (expand_macrolet): Pass form to expand_params. (expand_tree_cases): Take form argument for error reporting. Pass to expand_params. (expand_tree_case): Pass form to expand_tree_cases. (me_def_variable, me_mlet): Replace repeated code with call to not_bindable_error. (expand_vars): Do bindable symbol check here, so it doesn't have to be done at the run time in bindings_helper. (me_flet_labels): Don't call check_lambda_list. Expansion of the generated lambdas will do argument list checking. (expand_catch_clause): Pass form to expand_params. (do_expand): Don't call check_lambda_list. Pass form to expand_params.
* New awk variable fw for fixed-width delimiting.Kaz Kylheku2016-12-262-0/+100
| | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-state): New slots fw, fw-prev and fw-ranges. (sys:awk-state rec-to-f): New logic to handle self.fw. (sys:awk-let): New local fw symacro. * txr.1: Documented fw.
* Add qquot optimization for ranges.Kaz Kylheku2016-12-251-0/+10
| | | | | | * eval.c (optimize_qquote_form): Check for a rcons forms. If thearguments are nothing but quoted forms, convert to literal range.
* Bugfix: incorrect quasi-quoting over #R syntax.Kaz Kylheku2016-12-252-5/+5
| | | | | | | | | | | | | | | | | | | The issue is that ^#R(,(+ 2 2) ,(+ 3 3)) produces 4..6 rather than #R(4..6). 4..6 is, of course, the syntax (rcons 4 6) which evaluates to a range. Here we want the range to which it evaluates, not the syntax. * eval.c (expand_qquote_rec): Handle the case when the qquoted_form is a range atom: expand the from and to parts, and generate a rcons expression. Though this seems to be opposite to the previous paragraph, it's the right thing. * parser.y (range): Drop the unquotes_occurs case which produces rcons syntax. Produce a range object, always. This is the source of the problem: a (rcons ...) expression was produced here which was just traversed by the qquote expander as list. It's the expander that must produce the rcons expression.
* Fix inconsistency in regex-source.Kaz Kylheku2016-12-251-2/+8
| | | | | | | | | | | | | | | | If we compile the regex expression (compound "str*"), calling regex-source on the compiled regex object yields "str*". That, of course, is treated as regex character syntax if fed back to regex-compile, and the * becomes an operator. We want the source to be (compound "str*"). This happens because the AST optimizer reduces (compound X) -> X. * regex.c (regex_compile): If the optimized expression is just a character string atom S, then for the purposes of maintaining the source code, convert it to (compound S).
* Tweak terminology in some parser error messages.Kaz Kylheku2016-12-231-3/+3
| | | | | | | | | | | | Eliminate references to a "list expression". This term specifically denotes (list ...) and not any compound expression. * parser.y (define_clause): Change "unterminated list expression" to "unterminated define directive". (output_clause): Change "unterminated list expression" to "unterminated output directive". (list): Change "list expression" to "expression".
* bugfix: dynamic env handling in parallel bindingKaz Kylheku2016-12-232-18/+86
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In the parallel binding (let ((x s) (s 0) (y s)) ...), both x and y must bind to the prior value of s, not to the new value 0. We have the bug that if s is a special variable, the initialization of y sees the new dynamic environment which contains the new value, so x gets the previous, y gets new. This commit fixes it. * eval.c (reparent_env): New static function. (bindings_helper): Separate logic into two loops, for sequential and parallel binding, so we don't have to repeatedly test this condition in the loop body, and can think separately about each case and streamline it. Nothing new happens under sequential binding; the behavior that is wrong for parallel binding is right for sequential. Under parallel binding, what we do is reset the dynamic environment to the original one prior to each evaluation of an initform. Then if the evaluation changes to a new dynamic environment (a special variable is being bound), we notice this and hook the new environment into a local stack, changing it parent pointer. At the end, we install this stack as the new dynamic env. Thus each init form is evaluated in the original dynamic env. * tests/011/special-1.tl: New tests added.