summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
...
* doc: add Compilation Library section header.Kaz Kylheku2018-10-271-0/+2
| | | | | | | | * txr.1: We need a SS section for the compilation functions, otherwise they appear to be children of the preceding "Treatment of the Hash Bang Line" section. An alternative would have been to promote them to a higher section level with .coSS instead of .coNP.
* op: bugfix: sys:*op-ctx* defined too late.Kaz Kylheku2018-10-261-2/+2
| | | | | | | | * share/txr/stdlib/op.tl (sys:*op-ctx*) Move definition before the make-struct-type call which instantiates the sys:op-ctx structure type, because the variable is referenced in that expression and treated as lexical. This situation now generates a warning.
* defvar: warn about prior lexical uses.Kaz Kylheku2018-10-263-1/+11
| | | | | | | | | | | | | | | | | | | Now that the compiler has a more efficient treatment of global lexical variables, code which accesses global variables that have not yet been defined will misbehave if the intent is to for those variables to be dynamically scoped. There is such a bug in the op expander, in fact. * eval.c (me_def_variable): When defvar/defparm are expanding, they now check whether there is an outstanding unbound warning against the variable. If so, then a warning is issued that the variable was previously used lexically and is now being marked special. * unwind.c (uw_warning_exists): New function. * unwind.h (uw_warning_exists): Declared.
* compiler: use symtab caching for global lexicals.Kaz Kylheku2018-10-262-10/+17
| | | | | | | | | | | | | | | | * parser.c (read_file_common): Allow version three object files. * share/txr/stdlib/compiler.tl (compiler comp-var): If a global variable isn't special, then treat it via the getlx instruction. The symbol gets added to the symtab, and referenced by index number. (compiler comp-setq): Similarly, treat a non-special global variable using the setlx instruction. (%tlo-ver%): We bump the major version of .tlo files from 2 to 3, since old txr executables won't recognize these new instructions. However, we are backward compatible; hence read_file_common still allows version 2.
* vm/asm: new instructions getlx and setlx.Kaz Kylheku2018-10-263-4/+57
| | | | | | | | | | | | | | | | | | | | These instructions can be used for accessing cached global variable bindings through the symtab of the vm descriptor. The compiler will use these for optimizing access to global lexical variables. * share/txr/stdlib/asm.tl (op-getlx, op-setlx): New opcode classes. * vm.c (vm_stab): Take the lookup function as an argument, so this can be used for variable bindings. (vm_gcall, vm_gapply): Pass lookup_fun function to vm_stab, as well as the appropriate string for the unbound error. (vm_gettab, vm_settab): New static functions. (vm_execute): Implement GETLX and SETLX using vm_gettab and vm_settab. * vmop.h: Regenerated.
* vm: bugfix: corruption of global desc list.Kaz Kylheku2018-10-261-5/+5
| | | | | | | | | * vm.c (vm_make_desc): We must register the newly malloced descriptor structure into the free list before calling cobj, because calling cobj may trigger gc, which can blow away the object pointed to by our vtail local variable. Alternatively, we calculate vtail after doign the cobj. Obtaining vtail and using it cannot be separated by gc.
* vm: rename remaining vestiges of ftab terminology.Kaz Kylheku2018-10-261-10/+10
| | | | | | | | | * vm.c (struct vm_stent): Rename fb and fbloc members to bind and bind_loc. (vm_desc_mark, vm_stab, vm_invalidate_binding): Follow rename. A local variable in vm_stab is also renamed. The error message in this function still says "function ... not defined"; that word will be replaced by a parameter in a later commit.
* doc: return value of list-builder methods.Kaz Kylheku2018-10-251-0/+14
| | | | | | * txr.1: Document that the list-builder methods which add to the list have unspecified return values, and that the local functions set up by the build macro are the same way.
* doc: no such thing as define-parameter-macro.Kaz Kylheku2018-10-161-1/+1
| | | | | | * txr.1: Replace reference to the nonexistent define-parameter-macro with the correct define-param-expander.
* doc: shorten some POSIX awk examples.Kaz Kylheku2018-10-141-2/+2
| | | | | | * txr.1: Remove unnecessary test for the existence of a field, since the find function accepts nil. Use len instead of length.
* doc: use nequal.Kaz Kylheku2018-10-141-2/+2
| | | | | * txr.1: shorten some examples by replacing (not (equal ...)) with (nequal ...).
* awk: unwanted package prefix in error message.Kaz Kylheku2018-10-121-1/+1
| | | | | | | * share/txr/stdlib/awk.tl (sys:awk-code-move-check): A symbol in the sys: package is being used just for the English word that its name supplies, so print it using ~a so the sys: prefix doesn't appear.
* compiler: typo in error message.Kaz Kylheku2018-08-071-1/+1
| | | | | | | * share/txr/stdlib/compiler.tl (expand-quasi-mods): Fix misspelled "missing". Small repro test case to trigger the diagnostic: (compile-toplevel '`@{"" []}`) where, note, there is nothing between the square brackets.
* New function: signum.Kaz Kylheku2018-08-072-0/+47
| | | | | | | arith.c (signum): New function. (arith_init): signum intrinsic registered. * txr.1: Documented.
* doc: option processing fixes.Kaz Kylheku2018-08-021-2/+3
| | | | | * txr.1: Wording change in introductory paragraph. Error in description of Boolean options.
* feature: support for floating-point rounding control.Kaz Kylheku2018-07-263-0/+135
| | | | | | | | | | | | | | | * arith.c (flo_get_round_mode, flo_set_round_mode): New functions. (arith_init): Register global lexical variables flo-near, flo-down, flo-up and flo-zero. Register flo-get-round-mode and flo-set-round-mode intrinsic functions. * configure: Test for fesetround and fegetround variables, and the associated constants, prpoducing a HAVE_ROUNDING_CTL_H variable in config.h. * txr.1: Documented new variables and functions.
* doc: updates regarding top-level form expansion order.Kaz Kylheku2018-07-231-2/+99
| | | | | | * txr.1: The descriptions of eval, the File Compilation Model and compile-toplevel give details about the processing of top-level forms.
* tests: remove macro-time hack from man-or-boy test.Kaz Kylheku2018-07-171-1/+1
| | | | | | * tests/012/man-or-boy.tl (defun-cbn): We no longer need the macro-time expression here to force the evaluation of the defmacro form.
* compile-file: incremental expansion of top-level forms.Kaz Kylheku2018-07-171-17/+18
| | | | | | | | | | | | | | Harmonizing with the previous change to eval, the compiler should also handle those situations. * share/txr/stdlib/compiler.tl (compile-file): do not perform a full expansion on each object that it reads from the file before passing it into the top-level walk. Rather, the raw form is passed into the top-level walk. It is partially expanded with macro-expand, and this is repated at each descent of the recursion. Only forms which are not top-level forms are then fully expanded before compilation, by not passing the t argument to compile-toplevel.
* eval: handle top-level incrementally.Kaz Kylheku2018-07-171-3/+30
| | | | | | | | | | | | | | | | | | | | | | | | Like in some other Lisp dialects, evaluation of top-level forms should deal with forms like: (progn (defmacro a () 42) (a)) where the (a) will correctly reference the macro earlier in the progn. * eval.c (eval_only_s, compile_only_s): New symbol variables. (expand_eval): New static function, based on previous code of eval_intrinsic. (eval_intrinsic): Rewritten to perform incremental macroexpand, similarly to compile-file, and recurse. If a form, after macro-expansion, is a progn, eval-only or compile-only, then its constituents are individually evaluated through expand_eval as separate forms: each one is fully expanded and evaluated before the next one is processed. If the form isn't a progn, eval-only or compile-only, then it is treated as a single expansion and evaluation. (eval_init): Initialize new symbol variables and use their values in registering their respective operators.
* hash: replace hashing function for doubles.Kaz Kylheku2018-07-171-5/+8
| | | | | * hash.c (hash_double): Rewrite silly byte rotation with union aliased against ucnum array.
* random-float: new function.Kaz Kylheku2018-07-162-0/+42
| | | | | | | * rand.c (random_float): New function. (rand_init): Register random-float. * txr.1: Documented.
* opip, oand: rewrite in Lisp.Kaz Kylheku2018-07-164-215/+194
| | | | | | | | | | | | | | | | | * eval.c (opip_s, oand_s, chain_s, chand_s): Variables removed. (me_opip): Function removed. (eval_init): Initializations of removed variables removed. chain and chand symbols interned at point of function registration. * lisplib.c (op_set_entries): Add autoload entries for opip and oand. * share/txr/stdlib/op.tl (sys:opip-expand): New function. (opip, oand): New macros. * protsym.c: Regenerated.
* op: convert to Lisp trivial macros related to op.Kaz Kylheku2018-07-164-188/+165
| | | | | | | | | | | | | | | | | | | | | | | The op macro is no longer written in C, but the trivial macros ap, ip, ado, ido, ret and aret are still C. It's silly to have macros written in C, baked into the TXR executable, which just produce syntax for a complicated macro written in Lisp that must be autoloaded when that code is used. * eval.c (ap_s, apf_s, ipf_s, ret_s, aret_s): Variables removed. (me_ap, me_ip, me_ado, me_ido, me_ret_aret): Functions removed. (eval_init): Do not initialize removed variables. Remove registration for macros ap, ip, ado, ido, ret and aret. Intern the apf and ipf symbols in the same expression which registers these functions. * lisplib.c (op_set_entries): Add autoload entries for ap, ip, ado, ido, ret and aret. * share/txr/stdlib/op.tl (ap, ip, ado, ido, ret, aret): New macros. * protsym.c: Regenerated.
* compile-file: support hash bang.Kaz Kylheku2018-07-112-0/+15
| | | | | | | | | * share/txr/stdlib/compiler.tl (usr:compile-file): Check for a hash bang line in the source file. If so, propagate it to the compiled file. * txr.1: Documented existing support for hash bang in .tlo files, and the translation of hash bang from .tl to .tlo.
* doc: indentation issueKaz Kylheku2018-07-111-2/+5
| | | | | | * txr.1: Fix wrong deindentation after .RS/.RE delimited bulleted lists. A vertical space is needed in one case after a bulleted list.
* list-build: rewrite methods for semantics & efficiency.Kaz Kylheku2018-07-111-10/+28
| | | | | | | | | | | | | | | | | | The list builder needlessly copies list structure. At any given moment, the last piece of structure added to the list can remain shared. We can leave the tail pointing to that piece and copy it later in a nondestructive operation. Also, we would like (build (add 1) (pend 2)) to produce (1 . 2) rather than an errror. The implementation gives this to us in the same stroke. * share/txr/stdlib/build.tl (list-builder :postinit): Just initialize tail to be head, rather than eagerly chasing to the last cons. (list-builder add, list-builder pend, list-builder pend*, list-builder ncon, list-builder ncon*): Rewrite.
* struct: uslot and umethod: improve diagnostics.Kaz Kylheku2018-07-111-3/+3
| | | | | | | | * struct.c (uslot_fun, umethod_fun, umethod_args_fun): Use the struct_handle_for_slot function rather than struct_handle. That function includes the slot name in the diagnostic message when the object isn't a struct; the programmer knows which slot was being asked for in the non-struct object.
* compiler: bugfix: mishandled empty testKaz Kylheku2018-07-101-6/+9
| | | | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-for): Fix exception thrown when compiling (for init test step ...) when test is nil. Firstly, we must distinguish a (nil) test from (), because the latter means (t). Hence the need for the test-p Boolean. The list of frags must not contain a nil, which isn't a frag. The instruction template must not only omit generating the conditional jump when the test is absent, but also omit generating the test code (insertion of tfrag.code) in that case, because tfrag is nil.
* compiler: duplicated code when compiling switch.Kaz Kylheku2018-07-101-2/+2
| | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-ift): Fix incorrect reference to the vec function rather than the cases-vec local variable. Thus the variable shared is now correctly calculated, and switch syntax which implements fall through cases via a single block of shared code is now translated properly as one block of instructions with with multiple entry points.
* compiler: constant-fold if eql.Kaz Kylheku2018-07-091-4/+9
| | | | | | | | | | | | | | | We put the ifql opcode to use for (if (eql ...) ...) and (if (neql ...) ...) and also constant-fold the constant cases, like we do for eq. * share/txr/stdlib/compiler.tl (%test-funs-pos%): Add eql to list. (%test-funs-neg%): Add neql to list. (%test-funs-ops%): New list of corresponding opcodes. (%test-opcode%): New variable containing a relation function from equality functions to assembler opcodes. (compiler comp-ift): Don't hard code the opcode; look it up from the test function using %test-opcode%.
* compiler: bugfix in constant condition logic.Kaz Kylheku2018-07-091-1/+1
| | | | | | | | | * share/txr/stdlib/compiler.tl (%test-inv%): Fix reversed mapping; the way this is used, it is expected to map the negative tests to their positive counterparts. This didn't matter until the previous commit because before that commit, the value that was computed through this table wasn't used for anything. It is being used now.
* compiler: don't hardcode eq in if optimization.Kaz Kylheku2018-07-091-1/+1
| | | | | | | | * share/txr/stdlib/compiler.tl (copmiler comp-ift): In the case when both values being compared are constant expressions, evaluate the comparison statically using the function, rather than a hard coded eq. Right now, the only funtion handled is in fact eq.
* Version 198.txr-198Kaz Kylheku2018-07-067-1138/+1181
| | | | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated. * protsym.c: Regenerated.
* hash: use full width unsigned type for hash values.Kaz Kylheku2018-07-065-59/+51
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Throughout the hashing framework, hashes are reduced into the fixnum range, and returned as cnum. This is not necessary; only the hash-eql and hash-equal functions need to reduce hashes to fixnums. Let's make it ucnum everywhere else, using its full range (no reduction into the [0, NUM_MAX) range). * hash.c (struct hash_ops): hash_fun function pointer returns ucnum instead of cnum. (hash_double): Return unreduced ucnum. Obsolete #ifdef-s removed; the ucnum type gives us a pointer-wide unsigned integer on all platforms. (equal_hash, eql_hash): Return ucnum. Don't reduce values to fixnum range. Some of the way we combine hashes from recursive calls changes; we multiply by at most 2 not to lose too many bits. (eql_hash_op, cobj_eq_hash_op, hash_hash_op): Return ucnum. * hash.h (equal_hash): Declaration updated. * lib.c (cobj_handle_hash_op): Return value changes to ucnum. * lib.h (struct cobj_ops): Hash function pointer's return type changes. (cobj_eq_hash_op, cobj_handle_hash_op): Declarations updated. * struct.c (struct_inst_hash): Return value changes to ucnum.
* hash: C++ maintenance.Kaz Kylheku2018-07-061-2/+2
| | | | | | | | * hash.c (hash_buf): Make size parameter unsigned. This eliminates a signed/unsigned comparison error from the GNU C++ compiler. (equal_hash): Use c_unum to get the buffer length. Should that be negative, c_unum will throw.
* hashing: overhaul part 2.Kaz Kylheku2018-07-053-9/+125
| | | | | | | | | | | | | | | | | | | | | | | | | | | | In this commit we feature-complete the seeded hashing implementation. The *hash-seed* special variable is provided from which newly created hashes take their seed. The make-hash and hash-equal functions get an optional seed argument. A function called gen-hash-seed is provided for obtaining a randomized seed. * hash.c (hash_seed): New macro. (hash_seed_s): New symbol variable. (make_seeded_hash): New function, made from make_hash. (make_hash): Reduced to wrapper around make_seeded_hash. (hash-equal): Take seed argument. (gen_hash_seed): New function. (hash_init): Initialize hash_seed_s and register *hash-seed* special variable. Re-register make-hash with new optional parameter, with regard to make_seeded_hash. Re-register hash-equal with new optional parameter. Register gen-hash-seed. * hash.h (make_seeded_hash): Declared. (hash_equal): Declaration updated. * txr.1: Documented optional seed arguments of make-hash and hash-equal. Documented new *hash-seed* variable and gen-hash-seed function.
* hashing: overhaul part 1.Kaz Kylheku2018-07-046-121/+151
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Hashing of buffers and character strings is being replaced with a seedable hash, providing a tool against denial of service attacks against hash tables. This commit lays most of the groundwork: most of the internal interface changes, and a new hashing implementation. What is missing is the mechanisms to do the seeding. * hash.c (struct hash_ops): Hash operation now takes a seed argument of type ucnum. (struct hash): New member, seed. (hash_str_limit): Default value changed to INT_MAX. A short value opens the gateway to an obvious collision attack whereby strings sharing the same 128 character prefix are entered into the same hash table, which will defeat any seedings strategy. (randbox): New static array. Values come from the Kazlib hash module, but are not used in exactly the same way. (hash_c_str, hash_buf): Now take a seed argument, and are rewritten. (equal_hash): Takes a seed, and passes it to hash_c_str, hash_buf and to recursive self calls. (eql_hash_op): New static function. Adapts the eql_hash operation, which doesn't take a seed, to the new interface that calls for a seed. (obj_eq_hash_op): Take a seed; ignore it. (hash_hash_op): Take a seed, pass it down to equal_hash. (hash_eql_ops): Wire hash functiono pointer to eql_hash_op instead of eql_hash. (make_hash): For now, intialize the hash's seed to zero. (make_similar_hash): Copy original hash's seed. (gethash_c, gethash_e, remhash): Pass hash table's seed to the hashing function. (hash_equal): Pass a seed of zero to equal_hash for now; this function will soon acquire an optional parameter for the seed. * hash.h (equal_hash): Declaration updated. * lib.c (cobj_handle_hash_op): Take seed argument, pass down. * lib.h (cobj_ops): Hash operation now takes seed. (cobj_eq_hash_op, cobj_handle_hash_op): Declarations updated. * struct.c (struct_inst_hash): Take seed argument, pass down. * tests/009/json.expected: Updated, because the hash table included in this output is now printed in a different order.
* doc: block* isn't elided.Kaz Kylheku2018-06-281-0/+4
| | | | | * txr.1: Make it clear that block* is not subject to progn-conversion.
* awk: bugfix: block optimized away by compiler.Kaz Kylheku2018-06-281-1/+1
| | | | | | | | | | | This breaks the (next) awk macro, breaking awk expressions which want to short-circuit to the next record. * share/txr/stdlib/awk.tl (sys:awk-state loop): The :awk-rec block is being optimized away by the compiler because it doesn't contain any direct function calls to functions that are not in the standard library. We must use block*, which isn't subject to this optimization.
* genman: use hash function written in Lisp.Kaz Kylheku2018-06-281-2/+6
| | | | | | | | | | | Planning to support seeded hashing, so the behavior of the hashing function will change. But we need a stable hash for the section URL's in the HTML doc; so let's preserve the existing function as Lisp code. * genman.txr (hash-str): New string hashing function. This behaves like the existing hash-equal behaves on 32 bits. (hash-title): Use hash-str instead of hash-equal.
* ffi: use existing local instead of struct access.Kaz Kylheku2018-06-251-4/+4
| | | | | | * ffi.c (ffi_closure_dispatch, ffi_closure_dispatch_safe): The nargs variable holds a copy of tfcl->nparam, so use it instead of accessing tfcl->nparam again.
* vm: replace open-coded ternary with max macro.Kaz Kylheku2018-06-251-4/+6
| | | | | | * vm.c (max): New macro. (vm_call, vm_apply, vm_gcall, vm_gapply): Use max macro in calculating args allocation.
* ftw: fix broken callback mechanism.Kaz Kylheku2018-06-251-1/+3
| | | | | | | * ftw.c (max): New macro. (ftw_callback): Allocate enough args for all five arguments. This bug went undetected when this was developed. A more recently added assertion in args.c caught this.
* hash: move ops into static structure + bug found.Kaz Kylheku2018-06-221-32/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The four hash operations (hash, equal, assoc and acons) are moved out of the hash instance and into a static table of operations. This means we have to go through one more indirection when calling them, but we save some space and shorten initialization. A bug is fixed here: the copy_hash function was only copying three out of these four functions; the equal operation was left uninitialized eposing the hash equality operation to corrupt behavior. Now that function just copies the hops pointer, so all is well. * hash.c (struct hash_ops): New struct type. (hash_ops_init): New macro. (struct hash): hash_fun, equal_fun, assoc_fun and assoc_new_c fun members removed. New member hops. (hash_eql_ops, hash_equal_ops): New static structures. (hash_equal_op): Compare the hops pointers rather than just the hash_fun: if two hashes have different hops pointers, they are different, period. Indirect through ops for calling equal fun and others. (hash_hash_op): Include the hops pointer in the hash, rather than the hash_fun pointer. (hash_print_op): Test for hash type (equal based or eql based) now done by comparing the hops pointer to one of the two static structures, rather than hash_fun to one of two functions. (make_hash, make_similar_hash, copy_hash): Initialize hops; remove initializations for the four functions. (gethash_c, gethash_e, remhash): Indirect through hops to invoke hash operations. (hash_uni, hash_diff, hash_isec): Incompatible hash check based on comparing hops pointer rather than hash_fun.
* hash: fix broken equality-of-two-hashes test.Kaz Kylheku2018-06-221-2/+2
| | | | | * hash.c (hash_equal_op): Fix broken logic that is supposed to push a cell onto the pending list: rplaca should be rplacd.
* load: do not record source location for compiled files.Kaz Kylheku2018-06-211-1/+6
| | | | | | | * parser.c (read_file_common): When reading a compiled file, turn off the rec_source_loc flag in the parser, since the forms are just data, and not source code for which we need error reporting.
* vm: rename identifiers that still use ftab terminology.Kaz Kylheku2018-06-211-13/+13
| | | | | | | | | * vm.c (struct vm_desc): Rename ftsz member to stsz. (struct vm_ftent): Renamed to struct vm_stent. (vm_make_desc, vm_make_destroy, vm_desc_mark, vm_stab, vm_invalidate_binding): Rename local ftsz variable to stsz, and follow the renames of struct members and of struct vm_ftent.
* vm: release cached bindings that become unbound.Kaz Kylheku2018-06-213-0/+40
| | | | | | | | | | | | | | | | | | | | | | | | When a function binding is removed using fmakunbound, virtual machine descriptions hang on to the previously cached binding in the ftab. When the symbol is newly bound, virtual machine descriptions keep pointing to the old function. To solve this, we put the vm_desc structures into a global list and provide a function that fmakunbound calls to scrub all the VM descriptors of that binding. * eval.c (makunbound, fmakunbound): Call new vm_invalidate_binding function. * vm.c (struct vm_desc_links): New structure. (struct vm_desc): New member lnk, with links. (vmd_list): New static variable: circular list of all VM descriptors. (vm_make_desc): Insert new VM descriptor into list. (vm_desc_destroy): Remove VM descriptor from list. (vm_invalidate_binding): New function. * vm.h (vm_invalidate_binding): Declared.
* listener: fix crash in selection yanking.Kaz Kylheku2018-06-201-1/+1
| | | | | * linenoise/linenoise.c (yank_sel): Use wmalloc_fn because the size is being measured in characters rather than bytes.