summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* Version 173.txr-173Kaz Kylheku2017-03-256-148/+182
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* termios: broken go-cbreak method.Kaz Kylheku2017-03-251-1/+1
| | | | | * share/txr/stdlib/termios.tl (termios go-raw): Fix call to nonexistent method.
* Windows: improve 16x16 icon.Kaz Kylheku2017-03-242-0/+0
| | | | | | | | | | Not sharpening it, but extending the opaque white background, with some alpha fuzzing by hand. Looks better defined on window title. * win/txr.xcf: 16x16 icon layer edited. * win/txr.ico: Updated.
* Windows: shortcuts should start in user profile dir.Kaz Kylheku2017-03-241-0/+1
| | | | | | | | | | | | Noticed that the shortcuts created by NSIS are configured to start in the TXR standard library installation directory. Why is that? Because the locatio specified by the most recent SetOutPath is used for this! * inst.nsi: Before creating shortcuts, switch SetOutPath to $PROFILE, which is NSIS's variable denoting the user's profie directory, same as the Windows USERPROFILE environment variable.
* doc: cross reference call-finalizers.Kaz Kylheku2017-03-241-0/+4
| | | | | * txr.1: Under finalize function mention that finalizers can also be called using call-finalizers.
* doc: reference to nonexistent special var.Kaz Kylheku2017-03-241-2/+2
| | | | | * txr.1: Fix references to nonexistent *package-list* variable under Handlers and Sandboxing.
* Short-circuit lisp-1 expander for atoms.Kaz Kylheku2017-03-241-0/+3
| | | | | | * eval.c (expand_lisp1): if the form is an atom that is not a bindable symbol, just return it; don't wastefully call into expand which has to save and restore some context.
* bugfix: neglected unbound warnings in DWIM syntax.Kaz Kylheku2017-03-241-0/+4
| | | | | | | | | | | DWIM expressions like [a b c] are not raising expansion-time warnings about a, b, c being unbound. * eval.c (expand_lisp1): The problem is that here we just return in the case that the symbol is bindable and has no macro expansion! Before returning, we must check whether the symbol has a binding in the variable or function space. If not, raise a warning.
* trace: wrong function printed in traces.Kaz Kylheku2017-03-241-3/+4
| | | | | | | | | | | | When tracing for two or more functions is enabled in a single trace form, the the function tracing hooks print the wrong name for all but the rightmost function. * share/txr/stdlib/trace.tl (sys:trace): Fix code which assumes that the each operator binds fresh lexical variables on each iteration. Bind a fresh lexical variable lex-n which copies the current value of the loop variable n, and refer to this lexical out of the tracing lambda.
* Some basic tests for finalization.Kaz Kylheku2017-03-242-0/+105
| | | | | | * tests/012/fini.tl: New file. * tests/012/fini.expected: New file.
* Warn when a nonexistent slot is referenced.Kaz Kylheku2017-03-233-10/+89
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Implementing warning for the situaton when the qref, uref, usl and umeth macro operators are asked to refer to a slot that doesn't exist in any struct type. This won't catch errors referencing a slot on the wrong type, but it will catch slots that are misspelled in such a way that the typo doesn't land on any slot. * share/txr/stdlib/struct.tl (defstruct): Register tenative slot definitions for all slots to nuke warnings. (sys:check-slot): New function. (qref, usl, umeth): Check slots with sys:check-slot. (uref): Drop :whole argument, which is unused. (defmeth): Register tentative definition for slot. * struct.c (slot_s, static_slot_s): New symbol variables. (slot_type_hash, static_slot_type_hash): New hash tables, associating symbols with lists of struct type names in which they are defined. (struct_init): Initialize and gc-protect hashes. Initialize new symbols, interning in system package. Register new intrinsic funtions sys:slot-types and sys:static-slot-types. (make_struct_type): Register slots in new hashes. (static_slot_ens_rec): Register new slow in static slot hash. (slot_types, static_slot_types): New functions, registered as intrinsics. (slot_type_reg, static_slot_type_reg): New functions. * struct.h (print_s): Declared. (slot_s, static_slot_s): Declared. (slot_types, static_slot_types, slot_type_reg, static_slot_type_reg): Declared.
* call-finalizers: allow recursion.Kaz Kylheku2017-03-232-41/+76
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Code to invoke finalizers and remove them from the list is consolidated: both the gc and call-finalizers now use the same lower-level function. Finalizers may now themselves call-finalizers; it is no longer "unspecified behavior". This greatly improves the the TXR Lisp support for RAII, since :fini handlers of objects can call finalization on related objects. For instance a container being finalized can call the finalizers of contained objects. * gc.c (call_finalizers_impl): New function. Gathers all eligible finalizer registrations into a local list, first, removing them from the global list. Then does the calls in a second pass. Also, relative to the original functions which it replaces, this fixes an incorrect case: when the list is of length 1 and contains an eligible entry, in which case the global final_tail pointer is left aiming at a local variable! (is_reachable_final): New static function. (call_finalizers): Use call_finalizers_impl, specifying is_reachable_final as the predicate. (is_matching_final): New static function. (gc_call_finalizers): Use call_finalizers_impl, specifying is_matching_final as the predicate. * txr.1: Update documentation about call-finalizers.
* Bind variable during directive delimited match.Kaz Kylheku2017-03-222-1/+48
| | | | | | | | | | | | | | | | | | | | | | | | | | The existing behavior is: when a situation like @a@(foo) performs a search for the match for @(foo) in order to determine the extent of the text matched by variable a, the variable a is not bound. That is to say, @(foo) is tried in an environment in which a doesn't exist. The variable is only bound when the search succeeds, and then @(foo) is processed again, with the variable now available. The new behavior is that @(foo) is tested in an environment in which a is bound. The variable's value is bound to the range of text between the original position and the tested position where @(foo) is tried. This is subject to the copatibility option. * match.c (ml_bindings_specline_pos): New static function. (search_match_binding_var): New static function, variant of search_match. (h_var): In the var-delimited-by-directive case, perform the search using search_match_binding_var, unless <= 172 compatibility is requested. * txr.1: Compatibility note added.
* Remove useless consume_prefix call.Kaz Kylheku2017-03-221-2/+0
| | | | | | | | | * match.c (search_match): Calling consume_prefix from this function does nothing because it does not advance c->pos, and so it is hereby removed. This was introduced in commit fce7c87fa0099e5414607676fc73c9dfa9d7649c on 2012-02-11, at the same time when consume_prefix was introduced.
* Bugfix: missing warnings when main file is .txr.Kaz Kylheku2017-03-222-2/+5
| | | | | | | | | | | | | | | | | | | If the main file of an application is a .txr file, unbound function and variable warnings are not being generated. * match.c (v_load): For consistency with the load function in eval.c, release deferred warnings in the normal return case, if we are not a recursive load. However, this doesn't fix anything because a load or include is always recursive being invoked from a .txr file that is being loaded. The problem is in fact that the recursive flag is nil when it shouldn't be, and then the uw_unwind block obliterates the warnings. * txr.c (txr_main): We must bind *load-recursive* to t around not just the loading of Lisp, but also of TXR. Otherwise the individual loads will release warnings, raising false positives for forward references.
* listener: completion sensitive for slots and methods.Kaz Kylheku2017-03-216-12/+74
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When completing .prefix[TAB], .(prefix[TAB] or .[prefix[TAB], restrict identifiers to the appropriate namespace. The former will report only symbols from the relevant package which are struct slots; the latter further restricts it to those which are static slots defined as functions. * lib.c (symbol_visible): Static function becomes extern. * lib.h (symbol_visible): Declared. * parser.c (find_matching_syms): par parameter is renamed kind and can hold additional values 'S' (slots) and 'M' (methods). New get_slot_syms function is used to fetch the slots, as necessary, instead of the visible syms, if the kind is 'S' or 'M'. The same loop as before (with the minor change of recognizing 'S' and 'M' also) performs the prefix matching. (provide_completions): Recognize . .( and .[ prefix, calculating the kind argument of find_matching_syms in a new way. * struct.c (get_slot_syms): New function. * struct.h (get_slot_syms): Declared. * txr.1: Add some notes about this under the description of completion. The full rules are not given though; let the user discover.
* Version 172.txr-172Kaz Kylheku2017-03-196-698/+753
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* Restore package and package alist in handlers.Kaz Kylheku2017-03-183-0/+39
| | | | | | | | | | | | | | | | | | | | | | | | | | | | When setting up a handler frame, we note down the current package alist and package in the frame. Then when invoking the handler, we rebind the *package* and *package-alist* special variables. This is a needed security measure for sandboxing. Since handlers do not unwind (and therefore do not restore special variables) a handler in sandboxed code could catch an exception from non-sandboxed code that has changed *package* or *package-alist*, and take advantage of those changed values to escape from the sandbox. * unwind.c (uw_push_handler): Store current package and package-alist into new fields in the handler frame. (invoke_handler): Set up a new dynamic environment and bind *package* and *package-alist* around the handler call, to the values noted in the frame. Thus the handler executes with whatever package context was current when the handler was established. * unwind.h (struct uw_handler): New members, package and package_alist. * txr.1: Add paragraph to Exception Handling about this issue.
* Use original *packages-alist* value for auto-load.Kaz Kylheku2017-03-181-0/+1
| | | | | | | | | | | * lisplib.c (lisplib_try_load): Around the load, don't just bind *package* to the user package, but also *package-alist* to the original initialization-time list of packages. This allows auto-loading to work in sandboxed code. This has security implications: if sandboxed code can somehow trigger an error situation in an auto-load which then calls back into a handler in the sandboxed code, it then has access to the full usr and sys packages.
* Sandboxing support via *package-alist*.Kaz Kylheku2017-03-174-12/+84
| | | | | | | | | | | | | | | | | | | * eval.c (eval_init): Register *package-alist* variable, taking on the contents of the packages variable. * lib.c (package_alist_s): New symbol variable. (make_package, packagep, find_package, package_alist); Work with dynamic package alist variable via cur_package_alist_loc macro. (get_current_package_alist_loc): New function. * lib.h (cur_package_alist_loc): New macro. (packages, package_alist_s, get_current_package_alist_loc): Declared. * txr.1: Documented *package-alist* along with notes about sandboxing. Documented that the package-alist function is now obsolescent.
* Rename badly named default_bool_argKaz Kylheku2017-03-1716-65/+65
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * lib.h (default_bool_arg): Inline function renamed to default_null_arg. * eval.c (if_fun, pad, ginterate, giterate, range_star, range, constantp, macroexpand_1, macro_form_p, expand_with_free_refs, do_expand, eval_intrinsic, func_get_name, make_env_intrinsic): Follow rename. * arith.c (lognot): Likewise. * gc.c (gc_finalize): Likewise. * glob.c (glob_wrap): Likewise. * hash.c (group_reduce, gethash_n): Likewise. * lib.c (print, multi_sort, lazy_str, vector, iff, tok_str, split_str_keep, search_str, remove_if, val): Likewise. * match.c (match_fun): Likewise. * parser.c (lisp_parse_impl, regex_parse): Likewise. * rand.c (make_random_state): Likewise. * regex.c (read_until_match, search_regex, regex_compile): Likewise. * socket.c (sock_accept, sock_connect): Likewise. * stream.c (open_files_star, open_files, run, open_process, open_tail, get_string, record_adapter): Likewise. * struct.c (static_slot_ensure, static_slot_ens_rec, clear_struct, make_struct_type): Likewise. * sysif.c (exec_wrap, errno_wrap, cobj_ops_init): Likewise. * unwind.c (uw_capture_cont, uw_find_frames_impl): Likewise.
* linenoise: close descriptor before external edit.Kaz Kylheku2017-03-171-1/+6
| | | | | | | | * linenoise/linenoise.c (edit_in_editor): Close the file stream after writing out the temporary file, before launching the editor. On Windows, Notepad complains that the file is in use by another application and cannot write to it. Windows Vim treats the file as read-only in spite of good permissions.
* trace: implement redefinition checks.Kaz Kylheku2017-03-176-0/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The tracing module should warn when traced functions or methods are being redefined, and stop tracing the original methods. * eval.c (trace_check): New function. Calls sys:trace-redefined-check if the trace module has been loaded, otherwise does nothing. (op_defun, op_defmacro): Call trace_check to have a warning issued for a redefined traced function or macro. * eval.h (trace_check): Declared. * lisplib.c (trace_loaded): New global variable. (trace_instantiate): Flip trace_loaded to t. * lisplib.h (trace_loaded): Declared. * share/txr/stdlib/trace.tl (sys:trace-redefine-check): New function. Checks two situations: traced function or method is redefined (neither old nor new is traced any longer), and traced method is overridden (base method continues to be traced, override is not traced). * struct.c (static_slot_ensure): Do a trace check here, taking care of defmeth.
* trace: detect inheritance, change name and warn.Kaz Kylheku2017-03-171-10/+32
| | | | | | | | | | | | When a method is traced that is actually derived from another struct type, we convert the (meth ...) name to refer to that type and issue a warning. * share/txr/stdlib/trace.tl (sys:trace-canonicalize-name): New function. (sys:trace): Canonicalize name, and trace the canonicalized name. Warn if it is different from the original name. (sys:untrace): Likewise for untracing.
* Document opt function.Kaz Kylheku2017-03-171-0/+38
| | | | | * txr.1: Add missing description of the opt convenience function for constructing opt-desc structures.
* New function: static-slot-home.Kaz Kylheku2017-03-163-0/+61
| | | | | | | | | | | * struct.c (struct_init): Register intrinsic function static-slot-home. (lookup_static_slot_desc_load): New static function. (static_slot_home): New function. * struct.h (static_slot_home): Declared. * txr.1: Documented.
* structs: remove unused param from some functions.Kaz Kylheku2017-03-161-20/+19
| | | | | | | | | | * struct.c (lookup_static_slot_desc, lookup_static_slot, lookup_static_slot_load, get_equal_method): Remove stype argument; it is only passed down through the calls and not used at the leaf level. (static_slot, static_slot_set, static_slot_ens_rec, struct_inst_print, struct_inst_equalsub, method_name): Don't pass stype to slot lookup functions that no longer take it.
* Fix misleading "no such slot" for static slot lookup.Kaz Kylheku2017-03-161-2/+8
| | | | | | | * struct.c (no_such_static_slot): New static function. (static_slot, static_slot_set): Use no_such_static_slot when reporting error. The struct type might have an instance slot of that name.
* TXR query for cleaning Inkscape SVG.Kaz Kylheku2017-03-161-0/+41
| | | | * win/cleansvg.txr: New file.
* Seal transparent areas of 16x16 icon.Kaz Kylheku2017-03-162-0/+0
| | | | | | | | | | | | Looks more reasonable in window title bars, whose background isn't white. * win/txr.ico: Regenerated. * win/txr.xcf: New 1024x1024 layer with internal transparency filled with white and slightly wider white border. This shrunk to 16x16 replaces that icon size.
* Icon refresh.Kaz Kylheku2017-03-154-1/+106
| | | | | | | | | | | | | | | | | I lost the original vector graphic inputs that went into the icon. This is a superior re-make. Better artwork, better post-processing quality, more sizes. * Makefile (win/%.res): Add win/*.ico as a pattern prerequisite, so that the resource file is regenerated when the icon changes. * win/txr.ico: Updated icon, now in sizes 16, 32, 48, 64, 96, 128, 192 and 256. * win/txr.xcf: Updated GIMP file. * win/txr.svg: New file.
* umask: arg optional, return old value.Kaz Kylheku2017-03-151-3/+7
| | | | | | | | | | * sysif.c (umask_wrap): Return the prior value of the umask rather than the symbol t. If the argument is missing, then just return the current value without altering the umask. Unfortunately, this is implemented by temporarily changing the umask and then putting it back. (sysif_init): Change registration of umask to reflect optional argument.
* parser: support uref dot as top-level expr.Kaz Kylheku2017-03-151-0/+8
| | | | | * parser.y (hash_semi_oor_n_expr, hash_semi_or_i_expr): add grammar rules for leading dot.
* parser: factor repeated uref-related code.Kaz Kylheku2017-03-151-32/+20
| | | | | | | * parser.y (uref_helper): New static function. (list, i_dot_expr, n_expr, n_dot_expr): Replace most action code releated to unbound ref dot syntax with call to uref_helper.
* Version 171.txr-171Kaz Kylheku2017-03-146-574/+633
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* doc: typeset references to directives as code/codn.Kaz Kylheku2017-03-141-26/+74
|
* split, split*, partition, partition*: allow neg indices.Kaz Kylheku2017-03-142-16/+76
| | | | | | | | | | * lib.c (partition_split_common): Filter the list of indices, displacing any negative values by the length of the sequence, removing any that are still negative. This is subject to compatibility. (partition_star): Likewise. * txr.1: Document, and add compat notes.
* Fix missing nao terminator in formatted printing.Kaz Kylheku2017-03-135-9/+9
| | | | | | | | | | | | | | * arith.c (trunc1, trunc, floorf, ceili): Add missing nao terminator to uw_throwf calls. * debug.c (debug): Missing nao terminator in format call. * eval.c (expand_opt_params_rec, me_equot): Missing nao terminator in eval_error call. * lib.c (use_sym): Missing nao in uw_throw call. * regex.c (reg_derivative): Missing nao in uw_throwf.
* Print method can return : to decline printing.Kaz Kylheku2017-03-132-4/+19
| | | | | | | | * struct.c (struct_inst_print): Check return value of print method call. If it is the colon keyword, then do not return but rather continue to the regular struct printing code. * txr.1: Documented.
* doc: bungled text under in-package.Kaz Kylheku2017-03-131-3/+2
| | | | | * txr.1: Fix sentence fragmentation and redundant text in last paragraph under in-package.
* Add in-package directive.Kaz Kylheku2017-03-134-2/+41
| | | | | | | | | | | | * match.c (in_package_s): New symbol variable. (syms_init): Initialize in_package_s. * match.h (in_package_s): Declared. * parser.y (check_parse_time_action): Add case for in-package. Evaluate just with eval, as a case of the in-package macro. * txr.1: Documented.
* New directive: mdo.Kaz Kylheku2017-03-125-11/+66
| | | | | | | | | | | | | | | * eval.h (progn_s): Declarationa added. * match.c (mdo_s): New symbol variable. (syms_init): Initialize mdo_s. * match.h (mdo_s): Declared. * parser.y (check_for_include): Renamed to check_parse_time_action and implements mdo, not only include. (clauses_rev): Follow rename of function. * txr.1: Documented.
* New functions starts-with and ends-with.Kaz Kylheku2017-03-124-0/+63
| | | | | | | | | | | * eval.c (eval_init): Register starts-with and ends-with intrinsics. * lib.c (starts_with, ends_with): New functions. * lib.c (starts_with, ends_with): Declared. * txr.1: Documented.
* New rmismatch function.Kaz Kylheku2017-03-124-0/+132
| | | | | | | | | | * eval.c (eval_init): Register rmismatch intrinsic. * lib.c (rmismatch): New function. * lib.h (rmismatch): Declared. * txr.1: Documented
* New: struct-from-plist and struct-from-args.Kaz Kylheku2017-03-123-0/+61
| | | | | | | | | * struct.c (struct_init): Register new functions. (struct_from_plist, struct_from_args): New functions. * struct.h (struct_from_plist, struct_from_args): Declared. * txr.1: Documented.
* bugfix: @(next) in function called with match-fun.Kaz Kylheku2017-03-121-2/+6
| | | | | | | | | | | | | | | | | | | | The match-fun function must augment the input list with the current input source, because @(next) pops the first item from the files list and tries to open the second. We want it so that if we invoke (match-fun 'f arglist input '("abc")) then if the pattern function f invokes @(next), it will open "abc". * match.c (match_fun): Calculate a value for the curfile property of the match context and pass it to mf_all. If the input is a stream, we get its name. We also push this curfile onto the files list, satisfying the expectation that curfile and the first element of files refer to the same thing.
* match-fun: report error using external name.Kaz Kylheku2017-03-121-1/+1
| | | | | * match.c (match_fun): Report self as match-fun in error message.
* match-fun: make last two args optional.Kaz Kylheku2017-03-123-6/+11
| | | | | | | | * eval.c (eval_init): Update registration of match-fun. * match.c (match_fun): Do defaulting on third and fourth arg. * txr.1: Documenation updated.
* Don't open streams or stdin on non-matching directives.Kaz Kylheku2017-03-091-22/+25
| | | | | | | | | | | | | * match.c (open_data_source): The logic of not opening the data source for a non-matching directive must be applied to streams also, because the lazy list mechanism will read ahead from an underlying non-interactive stream. We must also apply it in the case when we open standard input by default. If standard input is non-interactive such that the lazy list unconditionally tries to read a line from it upon construction, we misbehave. The program could block on the read. Even if it doesn't block, the input action is an unwanted externally visible event.
* Don't sweep bad data source under the rug.Kaz Kylheku2017-03-081-1/+1
| | | | | * match.c (open_data_source): If the data source isn't a string or stream, then error out.