summaryrefslogtreecommitdiffstats
path: root/eval.c
Commit message (Collapse)AuthorAgeFilesLines
* Fix bugs in new quasiquote optimization.Kaz Kylheku2016-08-281-2/+4
| | | | | | | | | | | * eval.c (qquote_init): Stricter quote_form_p_f test function: reject the quote form if it isn't a proper list of two elements. (optimize_qquote_form): Extract all arguments of list forms and catenate them with mapcan, rather than assuming that they have one argument. This wrong assumption breaks ,,*(list ...) interpolation, for instance.
* Precompute functions used by quasiquote optimizer.Kaz Kylheku2016-08-281-35/+46
| | | | | | | | | | | | * eval.c (consp_f, second_f, list_form_p_f, quote_form_p_f, xform_listed_quote_f): New static variables. (qquote_init): New function. (optimize_qquote_form): Use list_form_p_f, quote_form_p_f, and second_f instead of constructing functions locally. (optimize_qquote_args): Use xform_listed_quote_f instead of locally constructed function. (eval_init): Call qquote_init. Register second function to second_f.
* Optimize quasiquote code generation.Kaz Kylheku2016-08-271-9/+98
| | | | | | | | | | | | | | | | | The surface motive here is to get better code than forms like (append (list 'a) (list 'b) ...). The ulterior motive is to suppress the memory explosion when heavily nested forms like ^^^^^^^^^^^x are expanded. This problem was uncovered by AFL (fast). * eval.c (optimize_qquote_form, optimize_qquote_args, optimize_qquote): New static functions. (expand_qquote_rec): New function. (expand_qquote): Contents moved into expand_qquote_rec. This function now optimizes the results of calling expand_qquote_rec.
* Introduce symbol variable for list*.Kaz Kylheku2016-08-271-2/+3
| | | | | | * eval.c (list_star_s): New symbol variable. (eval_init): Initialize list_star_s and use it for the list* function registration.
* Put cap on @<digits> value in op/do syntax.Kaz Kylheku2016-08-241-0/+4
| | | | | | | | | | | | | | | | The op transformer generates a lambda which has as many arguments as the highest-valued metanumber (@<digits> syntax) occurring in the form. If this is a huge integer, it obligingly tries to construct the argument list, running out of memory. In this commit, we cap the value to 1024. This issue was uncovered by the fuzzing utility AFL (fast) 2.30b. * eval.c (me_op): Throw error if max exceeds 1024, preventing the call to supplement_op_syms to actually generate an a formal parameter list of max symbols.
* Error on non-bindable sym in defvar and defparm.Kaz Kylheku2016-08-241-0/+3
| | | | | | * eval.c (me_def_variable): Check for sym not being a bindable symbol. Otherwise we might call mark_special on nil, which triggers an assertion.
* Fix bug: global lexicals marked special anyway.Kaz Kylheku2016-08-241-9/+4
| | | | | | | | | | | | | | Variables defined with defvarl or defparml are being marked special, due to a mark_special call in the macro expander which existed before they were introduced. * eval.c (me_def_variable): We have to call mark_special at macro-expansion-time for defparm and defvar, rather than arrange for it to be called later, for the same reasons that the (now incorrect) mark_special call had been introduced in do_expand function for handling defvar. (do_expand): Do not call mark_special, because the symbol being handled here is defvarl: define lexical variable.
* Check arg count when expanding defsymacro.Kaz Kylheku2016-08-241-0/+3
| | | | | | * eval.c (do_expand): Throw error if defsymacro form isn't a list of three elements, just like defparm and defparml do.
* Misleading error message in defvarl and defsymacro.Kaz Kylheku2016-08-241-2/+2
| | | | | | * eval.c (op_defvarl, op_defsymacro): Report correct symbol in not-bindable-symbol error message rather than reporting as let.
* Adding time-parse function: wrapper for strptime.Kaz Kylheku2016-08-221-0/+1
| | | | | | | | | | | | * configure: Test for strptime. * eval.c (eval_init): register time-parse intrinsic. * lib.c (time_parse): New function. * lib.h (time_parse): Declared. * txr.1: Documented.
* defsymacro must remove special marking.Kaz Kylheku2016-06-111-0/+2
| | | | | | | | | | * eval.c (op_defsymacro): Remove sym from the special hash, unless compatibility 143 or lower is requested. * txr.1: Document effects of evaluating defsymacro if a global variable of the same name exists, and the behavior in lexical scopes where sym is bound. Added compatibility notes covering the code change.
* Fixing semantics of makunbound.Kaz Kylheku2016-06-081-3/+19
| | | | | | | | | | | | | | | | | | * eval.c (unbound_s): New symbol variable. (lookup_var): If a dynamic binding has the special sys:unbound symbol as its value, then return nil, so the behavior is as if there is no binding. (makunbound): If the symbol exists in a dynamic environment, then replace its value with sys:unbound, making it look unbound. (eval_init): Initialize unbound_s. * lib.h (us_car, us_cdr): New inline functions. * txr.1: New dialect notes under boundp. Updated the makunbound documentation. Separated makunbound documentation from fmakunbound and mmakunbound. Added compatibility notes.
* Fixes in field formatting diagnostics.Kaz Kylheku2016-06-041-5/+6
| | | | | | * eval.c (format_field): Improve error messages; streamline some code, report expression value rather than expression itself for bad modifier.
* Move registration of hash module functions to hash.cKaz Kylheku2016-05-281-41/+1
| | | | | | | | | | | | | | | * eval.c (gethash_s): Global symbol variable removed, due to being used only in one place. (eval_init): Remove registration of make-hash, make-similar-hash, copy-hash, hash, hash-construct, hash-from-pairs, hash-list, inhash, sethash, pushhash, remhash, hash-count, get-hash-userdata, set-hash-userdata, hashp, maphash, hash-eql, hash-equal, hash-keys, hash-values, hash-pairs, hash-alist, hash-uni, hash-diff, hash-isec, hash-subset, hash-proper-subset, group-by, group-reduce, hash-update, hash-update-1, hash-revget, hash-begin, hash-next. * hash.c (hash_init): Registrations removed from eval_init moved here.
* Track origin across op/do expansion.Kaz Kylheku2016-05-231-0/+2
| | | | | | | | * eval.c (me_op): We tell a little lie here, by indicating that the "dwim body" is an expansion of the op operator. Of course, the entire lambda containing that body is that expansion. But in error messages, we need something useful for the user.
* Use sys_load_s symbol variable.Kaz Kylheku2016-05-181-1/+1
| | | | | | * eval.c (eval_init): Use sys_load_s variable set up earlier in the function instead of redundant call to intern.
* New feature: self-load-path symbol macro.Kaz Kylheku2016-05-181-2/+32
| | | | | | | | | | | | | | | | | | | | | * 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.
* Move PRNG-related initialization to rand.cKaz Kylheku2016-04-281-8/+0
| | | | | | | | | * eval.c (eval_init): Remove registration of make-random-state, random-state-get-vec, random-state-p, random-fixnup, random, and rand. * rand.c (rand_init): Move registrations removed from eval_init here.
* Recycle temporary list-of-lists in mapping functions.Kaz Kylheku2016-04-221-3/+9
| | | | | | | | * eval.c (mapcarv, mappendv, mapdov): When done, we can recycle the conses used for the temporary copy of the list-of-lists, whose car-s are used for iterating over the lists in paralle. This is safe because the temporary list's conses aren't shared with any other function.
* Don't quote path in load and @(load) diagnostics.Kaz Kylheku2016-04-221-1/+1
| | | | | | | * 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.
* Close source files after parsing.Kaz Kylheku2016-04-151-0/+3
| | | | | | | | | | | | | * 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.
* Fix proper-listp to proper-list-p.Kaz Kylheku2016-04-141-3/+7
| | | | | | | | | | | | | | | | | | | | This is really a gratuitous incompatibility with Common Lisp and other dialects. Let's fix it internally also, but keep the proper-listp function binding for backwards compatibility. * eval.c (dot_to_apply, me_op): Update proper_listp call to proper_list_p. (eval_init): Register proper-list-p to the same C function as proper-listp, and that C function is now called proper_list_p. * lib.c (proper_listp): Renamed to proper_list_p. * lib.h (proper_listp): Declaration updated. * parser.y (define_transform): Update proper_listp call. * txr.1: Replace all occurrences of proper-listp with proper-list-p. Add note explaining the rename situation.
* Trace expansion more in expansion-time errors.Kaz Kylheku2016-04-131-5/+32
| | | | | | * eval.c (error_trace): If an error occurs during the expansion of a form, that form may be the result of expansions. Dump those expansions.
* Bugfix: track origin for built-in macros.Kaz Kylheku2016-04-131-0/+1
| | | | | | | | | | | This fix is no longer that important, since due to the previous commit, expand now tracks expansion origins thoroughly, which hides this bug. However, expand_macro is directly called from a few other functions, like macroexpand, which don't benefit from that fix. * eval.c (expand_macro): Add forgotten set_origin call in the case when the native C expander is called.
* More thorough job of tracking expansion origins.Kaz Kylheku2016-04-131-7/+6
| | | | | | | | | | | | | This promotes better diagnostics. Simple test case: [(ret @5) 1]. * eval.c (do_expand): Manual tail recursion via backwards goto is removed; the function recurses now, and it recurses through the expand wrapper rather than by calling itself. That is needed in order to properly install the origin tracking for each expansion. (expand): Record origin for each expansion that already doesn't have one.
* Don't expand replacements of symbol macros.Kaz Kylheku2016-04-121-3/+6
| | | | | | | | | * eval.c (expand_symacrolet, do_expand): Don't expand the replacement form of a global or lexical symbol macro at the time it is bound to its symbol. This is almost certainly wrong in situations where it makes a difference. * txr.1: Noted in compatibility section.
* Better handling of dot position function calls.Kaz Kylheku2016-04-111-12/+50
| | | | | | | | | | | | | | | | | | | | | | | | | | The expander now actually produces apply forms for dot position function call and dwim forms. This allows symbol macros to work naturally. * eval.c (sys_apply_s): New symbol variable. (imp_list_to_list, dot_to_apply): New static functions. (expand_forms, expand_forms_lisp1): We now throw an error if a non-nil atom terminates a form, Except in compatibility mode with TXR 137 or less, whereby we emulate the old behavior of not expanding this atom. (do_expand): Perform the dot_to_apply transformation on the arguments of the dwim form. Perform the dot_to_apply transformation on an entire function call form. (eval_init): Initialize sys_apply_s and register sys:apply function (using the same function object that is registered under apply). * txr.1: Documented that both DWIM forms and regular function call forms work as if by a transformation to apply form, removing verbiage which separately described the DWIM handling. Documented that symbol macros work properly in dot position.
* Allow symbol macro in function call dot position.Kaz Kylheku2016-04-071-1/+5
| | | | | | | | | | * eval.c (expand_forms): If the forms list is an atom, then don't just return it. Try to expand it as a macro. If the macro produces a compound form, diagnose with an exception, otherwise return the expansion. * txr.1: Document the treatment of symbol macros in function call dot position.
* Adding rightmost item search functions.Kaz Kylheku2016-03-271-1/+14
| | | | | | | | | | | | | | | | | | * eval.c (eval_init): Registered intrinsics rmemq, rmemql, rmemqual, rmember, rmember-if, rposqual, rposql, rposq, rpos, rpos-if, rfind, rfind-if and rsearch. * lib.c (rmemq, rmemql, rmemqual, rmember, rmember-if, rposqual, rposql, rposq, rpos, rpos-if, rfind, rfind-if, rsearch): New functions. (rsearch_list): New static function. (search): Omit unreachable return statement. * lib.h (rmemq, rmemql, rmemqual, rmember, rmember-if, rposqual, rposql, rposq, rpos, rpos-if, rfind, rfind-if, rsearch): Declared. * txr.1: Documented.
* Bugfix in error location reporting across macro expansions.Kaz Kylheku2016-03-261-2/+2
| | | | | | | * eval.c (do_expand, macroexpand_1): The original form must have priority in providing source location info, over the macro. Otherwise macro bodies may get reported as locations of errors that occur in substituted code.
* Bugfix: append-each is wrongly destructive.Kaz Kylheku2016-02-291-1/+1
| | | | | * eval.c (op_each): Use list_collect_append not list_collect_nconc. Ouch!
* expand-left and nexpand-left functions.Kaz Kylheku2016-02-291-0/+35
| | | | | | | | * eval.c (expand_left, nexpand_left): New static functions. (eval_init): Registered expand-left and nexpand-left intrinsics. * txr.1: Documented.
* Header file cleanup.Kaz Kylheku2016-01-221-1/+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.
* Reduce header pollution caused by mpi.h.Kaz Kylheku2016-01-221-0/+1
| | | | | | | | | | | | | * eval.c: include <assert.h> that was previously coming via "mpi.h". * mpi/mpi.c: Includes of <stdio.h>, <ctype.h> and <assert.h> moved here. * mpi/mpi.h: Remove include of <stdio.h>, <ctype.h> and <assert.h>. Keeping <limits.h> for now; needed for CHAR_BIT. * mpi/mplogic.c: Needs <assert.h>
* New random-state-get-vec function.Kaz Kylheku2016-01-181-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | * arith.c (UINT_PTR_MAX_MP): New static variable. (biggnum_from_uintptr): New function. (in_uint_ptr_range): New static function. (c_uint_ptr_num): New function. (arith_init): Initialize UINT_PTR_MAX_MP. * arith.h (bignum_from_uintptr, c_uint_ptr_num): Declared. * eval.c (eval_init): Register random-state-get-vec. * mpi/mpi.c (mp_set_uintptr, mp_get_uintptr): New functions. (mp_set_intptr, mp_get_intptr): Expressed in terms of mp_set_uintptr and mp_get_uintptr. * mpi/mpi.h (mp_set_uintptr, mp_get_uintptr): Declared. * rand.c (make_random_state): Handle vector seed. (random_state_get_vec): New function. * rand.h (random_state_get_vec): Declared. * txr.1: Documented new feature in make-random-state and new random-state-get-vec function.
* New function, split*.Kaz Kylheku2016-01-171-0/+1
| | | | | | | | | | | | | | | | | | * eval.c (eval_init): Register split*. * lib.c (split_star_func): New static function. (partition_split_common): Take pointer-to-function argument instead of boolean. Hoist this C function into the lazy cons. (partition): Pass pointer to partition_func ito partition_split_common, intsead of a flag requesting the use of partition_func. (split): Pass apointer to split_func into partition_split_common. (split_star): New function. * lib.h (split_star): Declared. * txr.1: Documented split*.
* Fix omission: the / function becomes n-ary.Kaz Kylheku2016-01-131-1/+1
| | | | | | | | | | * eval.c (eval_init): Register / function to divv instead of divi. * lib.c (divv): New function. * lib.h (divv): Declared. * txr.1: Documented.
* bugfix: no location info for unbound var in dohash.Kaz Kylheku2016-01-131-5/+5
| | | | | | | * eval.c (do_expand): Add missing rlcp in the construction of the return value of the clause which expands a dohash. Let's make it a rlcp_tree. Test case: (dohash (a b c) d e) with c unbound.
* The identity function gets an alias: use.Kaz Kylheku2016-01-131-0/+1
| | | | | | * eval.c (eval_init): Register "use" as alias for identity. * txr.1: Documented use function.
* New internal function scat: variable arg cat_str.Kaz Kylheku2016-01-101-2/+2
| | | | | | | | | | | | | | Avoids consing up list of strings. * lib.c (vscat): New static function. (scat): New function. (lazy_str): Use scat instead of cat_str. * lib.h (scat): Declared. * eval.c (format_field): Use scat instead of cat_str. * parser.c (open_txr_file, read_eval_stream): Likewise.
* Don't record form as its own macro origin.Kaz Kylheku2016-01-091-2/+2
| | | | | | | * eval.c (set_origin): Add form != origin to the condition for recording the ancestry. (expand_macro): Use set_origin function instead of direct call to sethash.
* Revert chr-isdigit/isxdigit, provide new functions.Kaz Kylheku2016-01-041-0/+2
| | | | | | | | | | | | | | | | | | | It was a mistake to change the semantics of the return value of chr-isdigit and chr-isdigit. It breaks code like [partition-by chr-isdigit ...]. The behavior of chr-isdigit and chr-isxdigit is restored to returning t and nil. New chr-digit and chr-xdigit functions are introduced for returning the digit value or nil. * eval.c (eval_init): Register chr-digit and chr-xdigit intrinsics. * lib.c (chr_isdigit, chr_isxdigit): Restore old behavior. (chr_digit, chr_xdigit): New functions. * lib.h (chr_digit, chr_xdigit): Declared. * txr.1: Everything documented.
* Wording change in error_trace.Kaz Kylheku2016-01-021-2/+2
| | | | | * eval.c (error_trace): Change "possibly triggered by" to "during evaluation of".
* Use last-form-evaled mechanism for pattern language.Kaz Kylheku2016-01-021-0/+7
| | | | | | | | | | | | | | 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.
* 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.
* Fix regression in tab completion.Kaz Kylheku2015-12-301-1/+1
| | | | | | | | | | | Same issue as with Vim syntax highlighting. * eval.c (mboundp): Externalize static function. * eval.h (mboundp): Declared. * parser.c (find_matching_syms): Expand fboundp check to encompass mboundp and special_operator_p.
* last_form_evaled must track argument evaluation.Kaz Kylheku2015-12-291-4/+3
| | | | | | | * eval.c (do_eval): Set last_form_evaled to form before evaluating the arguments, so that any errors which are not attributed to their own sub forms (such as unbound symbols) are attributed to this form.
* Propagate macro ancestry info across macrolet.Kaz Kylheku2015-12-291-1/+4
| | | | | | | | | * eval.c (expand_macrolet): Install a macro ancestor for the expansion of the macrolet. If the original form has a macro ancestor, then use that grandparent ancestor. Otherwise use the original form itself. This way intermediate macrolets which are generated by macros are abbreviated out of ancestry traces.
* Detect loop in error_trace.Kaz Kylheku2015-12-291-0/+3
| | | | | | * eval.c (error_trace): If a form has itself as its macro ancestor, bail the loop. (This only happens in deliberately contrived pathological cases, useful for testing).
* Suppress "which is located at nil".Kaz Kylheku2015-12-291-3/+9
| | | | | * eval.c (error_trace): If info is nil, print alternative message about the location being unavailable.