summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* compiler/vm: renaming funvec.Kaz Kylheku2018-05-253-41/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | The virtual machine's funvec will be used for global lexical variables also, so it is being renamed to symvec. Related structure members, functions and variables are also renamed. * share/txr/stdlib/asm.tl (disassemble): Print the table heading as syms: rather than funs:. Follow the rename of vm-desc-funvec to vm-desc-symvec. * share/txr/stdlib/compiler.tl (compiler): Slots fidx-cntr fidx and ftab are renamed to sidx-cntr, sidx and stab, resp. (compiler get-fidx): Renamed to get-sidx. (compiler get-funvec): Renamed to get-symvec. (compiler comp-setqf, compiler comp-catch, compiler comp-fun-form, usr:compile-toplevel): Follow rename. (list-from-vm-desc): Follow rename of sys:vm-desc-funvec. * vm.c (strut vm_desc): Members funvec and ftab renamed to symvec and stab. (vm_make_desc): Parameters and local variables renamed. Follow rename of struct members. (vm_desc_funvec): Renamed to vm_desc_symvec. (vm_desc_destroy, vm_desc_mark): Follow rename struct members. (vm_ftab): Renamed to vm_stab. (vm_gcall, vm_gapply): Follow rename of vm_ftab. (vm_init): Register renamed vm_desc_symvec function as sys:vm-desc-symvec.
* compiler: fix wrong free symbol calculations.Kaz Kylheku2018-05-251-10/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Calculation of free symbols emanating out of let, let*, flet and labels is wrong, not taking into account the differences, respectively between let and let*, and between flet and labels. Compilation of lambda also has the same problem; variable references in initforms are considered free without regard for shadowing by earlier parameters. Another issue is the incorrect handling of special variables: special variable references are incorrectly being considered free in scopes where they are bound. * share/txr/stdlib/compiler.tl (compiler comp-let): For sequential bindings (let*), we must cull the prior variables from the list of free vars emanating out of each init form; these references do not emanate out of the binding construct. We pull the prior vars list out of the environment before binding the current variable so that it is not included in the list. Both special and lexical variables must be considered reference-capturing. (compiler comp-fbind): If compiling a recursive binding, cull the newly bound functions from the free references emanating from the local function bodies. A bug is fixed here that we were not referring to the correct list of symbols and so not taking into account the function references inside the local functions themselves at all. (compile comp-lambda): Build a correct list of free vars in relation to the initforms of optional parameters, taking account the scope, and that special variables capture references.
* doc: wrong eval-only description.Kaz Kylheku2018-05-251-4/+4
| | | | * txr.1: Revise incorrect semantic description of eval-only.
* doc: issues under Awk.Kaz Kylheku2018-05-251-1/+2
| | | | * txr.1: Wrong article "an local" and missing .codn line.
* Replace informality in command line help.Kaz Kylheku2018-05-241-1/+1
| | | | | | | * txr.1 (help): Someone reading the help text doesn't necessarily know that --help produced it; it can be read by someone in contexts where that same person didn't just obtain it by running txr --help.
* doc: document the --compiled option.Kaz Kylheku2018-05-241-20/+26
| | | | | * txr.1: Fold --compiled with --lisp into the same description.
* awk: bugfix: autoload on sys:awk-state.Kaz Kylheku2018-05-231-0/+4
| | | | | | | | | | | | The problem is that compiled code which uses the awk macro won't load because it invokes make-struct for the unknown sys:awk-state type. Interpreted code doesn't have the problem because it has to expand the awk macro from scratch to generate the make-struct call, and the awk macro triggers the autoload. * lisplib.c (awk_set_entries): Add sys:awk-state to autoload list for awk.tl.
* compiler: elide unused lexical functions.Kaz Kylheku2018-05-231-8/+16
| | | | | | | | | | This makes certain macros cheaper: macros which wrap code with numerous local functions, not all of which are expected to be used. * share/txr/stdlib/compiler.tl (compiler comp-fbind): Detect functions that are completely unused, and eliminate their code.
* compiler: streamline marking bindings used.Kaz Kylheku2018-05-231-19/+30
| | | | | | | | | | | | | | | NB: Accesses to lexical variables are not all marked used yet. * share/txr/stdlib/compiler.tl (binding): New slot, used. (sys:env lookup-var, sys:env lookup-fun, sys:env lookup-lisp1, sys:env lookup-block): Support optional Boolean argument which, if true, causes the lookup to mark the binding used. (compiler comp-return-from): Pass t to lookup-block, and remove code to mark used. (compiler comp-fun, compiler comp-fun-form): Pass t to lookup-fun to mark function used. (compiler comp-lisp1-value): Pass t to lookup-lisp1 to mark function used.
* txr: support variable in postive match.Kaz Kylheku2018-05-223-0/+27
| | | | | | | | | | | | | In the @{var mod} syntax in the pattern language, allow mod to be a variable which contains a regex or integer, not just an integer or regex literal. * match.c (h_var): Check for modifier being a variable, and resolve it. * parser.y (modifiers): Allow a SYMTOK phrase. * txr.1: Documented.
* logcount: new function.Kaz Kylheku2018-05-186-0/+121
| | | | | | | | | | | | | | | | | | This is in ANSI CL; potentially useful and hard to implement efficiently in user code. * arith.c (logcount): New function. * eval.c (eval_init): Register logcount intrinsic. * lib.h (logcount): Declared. * mpi/mi.c (s_mp_count_ones): New static function. (mp_count_ones): New function. * mpi/mpi.h (mp_count_ones): Declared. * txr.1: Documented.
* width: misleading error message.Kaz Kylheku2018-05-181-1/+1
| | | | | * arith.c (width): Fix incorrect name in type error diagnostic. There is no such function as integer-length.
* Version 196.txr-196Kaz Kylheku2018-05-186-142/+160
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* listener: Cygnal fix.Kaz Kylheku2018-05-181-1/+23
| | | | | | | | | | | | | | | | The standard input and output streams are in text mode on Cygnal, which interferes with the listener, because it draws input from streams. Let's hack it by Cygwin-specific code in linenoise. * linenoise/linenoise.c (struct lino_state): New members orig_imode and orig_omode, on Cygwin/Cygnal only. (enable_raw_mode): As part of enabling raw mode, use the Cygwin setmode function to put both descriptors in binary mode, saving their previous mode. (disable_raw_mode): Revert the previous mode of both descriptors, in reverse order in case they are the same descriptor.
* listener: Cygwin fix.Kaz Kylheku2018-05-183-14/+23
| | | | | | | | | | | | | | | | | | | | | | | | We cannot pass raw C wide literals to static_str; this breaks on platforms where wchar_t is two bytes and strings are aligned to only two byte boundaries. That's why TXR has the wli() macro. We don't want to introduce the wli() macro into linenoise, so the two choices are: duplicate the incoming mode strings into dynamic storage with string(), or pass some enum to specify file mode and locally convert to static mode string. Let's go with the latter. * linenoise.c (edit_in_editor, lino_hist_save): Use enum constant for file mode instead of mode string. * linenoise.h (enum lino_file_mode, line_file_mode_t): New enum. (struct lino_os): File opening functions use lino_file_mode_t instead of mode string. * parser.c (lino_mode_str): New static array. (lino_open, lino_open8, lino_fdopen): Take enum mode instead of string. Convert to literal through lino_mode_str table, and pass that literal to static_str.
* C++ fixes related to recent Unicode work.Kaz Kylheku2018-05-182-4/+4
| | | | | | | * lib.c (chk_wrealloc): convert needs to be a coerce. * parser.l (grammar): Use yyg instead of yyscanner; the latter is the same pointer but of void * type.
* random: reject negative bignum modulus.Kaz Kylheku2018-05-161-2/+2
| | | | | * rand.c (random): Function now rejects negative bignums, not only negative fixnums.
* linenoise: switch to wide characters, support Unicode.Kaz Kylheku2015-09-226-423/+607
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * lib.c (chk_wrealloc): New function. * lib.h (mem_t): Wrap with ifndef block. (MEM_T_DEFINED): New preprocessor symbol. (chk_wrealloc): Declared. * linenoise/linenoise.c (LINENOISE_MAX_DISP): Adjust to a reasonable value; just twice the number of abstract characters. The 8 factor had been chosen to cover the worst case that every character is mapped to a tab. (struct lino_state): Almost everything char typed turns to wchar_t. The TTY isn't referenced with Unix file descriptors, ifd and ofd, but abstract stream handles tty_ifs and tty_ofs. The ifs member isn't required any more since plain mode is handled via the tty_ifs stream. (mem_t): Declaration removed; now in linenoise.h. (chk_malloc, chk_realloc, chk_strdup_utf8): Declarations removed. (lino_os): New static structure. (nelem): New macro. (wcsnprintf): New static function. (enable_raw_mode, disable_raw_mode): Get Unix FD from stream using lino_os interface. (get_cursor_position, get_columns, handle_resize, record_undo, remove_noop_undo, restore_undo, undo_renumber_hist_idx, compare_completions, complete_line, lino_add_completion, next_hist_match, history_search, show_help, struct abuf, ab_append, ab_free, sync_data_to_buf, refresh_singleline, screen_rows, col_offset_in_str, refresh_multiline, scan_match_rev, scan_match_fwd, scan_fwd, find_nearest_paren, usec_delay, flash, yank_sel, delete_sel, edit_insert, edit_insert_str, edit_move_eol, edit_history_next, edit_delete, edit_backspace, edit_delete_prev_all, edit_delete_to_eol, edit_delete_line, edit_in_editor, edit, linenoise, lino_make, lino_cleanup. lino_free, free_hist, lino_hist_add, lino_hist_save, lino_set_result): Revised using streams, wide chars and lino_os interface. (lino_init): New function. * linenoise/linenoise.h (LINO_PAD_CHAR): New preprocessor symbol. (mem_t): Defined here. (MEM_T_DEFINED): New preprocessor symbol. (struct lino_os, lino_os_t): New structure. (lino_os_init): New macro. (struct lino_completions, lino_compl_cb_t, lino_atom_cb_t, lino_enter_cb_t): Switch to wchar_t. (lino_init): New function. (lino_add_completion, lino_make, linenoise, lino_hist_add, lino_hist_save, lino_hist_load, lino_set_result) * parser.c (find_matching_syms, provide_completions, provide_atom, is_balanced_line, repl): Adapt to wide character linenoise. (lino_fileno, lino_puts, lino_getch, lino_getl, lino_gets, lino_feof, lino_open, lino_open8, lino_fdopen, lino_close): New static functions. (linenoise_txr_binding): New static structure. (parse_init): Call lino_init, passing OS binding. * txr.1: Update text about the listener's limitations.
* Allow Unicode characters in identifiers.Kaz Kylheku2018-05-112-6/+59
| | | | | | | | | | * parser.l (unicode_ident): New static function. (BSCHR, NSCHR): Include UONLY match. (grammar): Use unicode_ident function to validate tokens obtained from BTOK and NTOK. * txr.1: Documented changing definition of bident and lident.
* lexer: eliminate regex alias used in one place.Kaz Kylheku2018-05-111-3/+2
| | | | | | | * parser.l (SYM, TOK): These are just aliases for the same pattern. SYM is referenced only in one place; TOK in multiple places, so let's remove SYM and replace that one reference by TOK.
* doc: fix of of.Kaz Kylheku2018-05-071-2/+2
| | | | * txr.1: Two occurrences of "of of" are corrected.
* doc: compiler sections: grammar, awkward wording.Kaz Kylheku2018-05-071-16/+16
| | | | | * txr.1: Overhaul after a proof-reading of the new LISP COMPILATION section.
* compiler: warn on misleading references in load-time.Kaz Kylheku2018-05-071-0/+9
| | | | | | | | | | | | | | | If code does something like this, we produce a warning: (let ((var 42)) (load-time (+ var 3))) A load-time form occurs in an empty lexical environment, so this code appears right but actually cannot work; the appearance is a mere trompe d'oeil. * share/txr/stdlib/compiler.tl (misleading-ref-check): New function. (compiler comp-load-time-lit): Apply misleading-ref-check.
* Version 195.txr-195Kaz Kylheku2018-05-046-122/+139
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* More reasonable fallback for self path.Kaz Kylheku2018-05-042-11/+5
| | | | | | | | | | | | | | | | * Makefile (opt/txr.o, dbg/txr.o): Set up TXR_REL_PATH preprocessor symbol on command line which specifies the hard installation path derived from the configure prefix. * txr.c (get_self_path): The fallback implementation simply returns TXR_REL_PATH. This will work if in fact the executable is installed at that path. What it means is that the build of TXR which uses this fallback get_self_path will not support relocation: the installation cannot be moved to another directory, yet still find its supporting files. This is better than what we are replacing: not working even in the original installation directory, if not invoked by an absolute path.
* bugfix: correcly obtain self path on Solaris.Kaz Kylheku2018-05-044-1/+30
| | | | | | | | | | | | * configure: Add detection for getexecname. * sysif.c (getcwd_wrap): Change static function to external. * sysif.h (getcwd_wrap): Declared. * txr.c (get_self_path): New implementation for Solaris using getexecname, which requires us to prepend the current directory name if the result is a relative path.
* Mac-OS: replace nonworking method of getting self-path.Kaz Kylheku2018-05-041-0/+13
| | | | | | | | | TXR's fall-back method of getting the executable's own path is broken in the Mac-OS port, which means that TXR doesn't work when invoked via PATH search. Mac-OS-specific code is required. * txr.c (get_self_path): New variant for Darwin, using the platform-specific function _NSGetExecutablePath.
* bugfix: interpreted destructuring doesn't do specials.Kaz Kylheku2018-05-031-8/+18
| | | | | | | | | | | | | | | It looks like I neglected to treat dynamically scoped variables in destructuring; all parameters are treated as lexical. This is only true in interpreted code; compiled destructuring treats dynamics properly because it generates a let to bind all the variables which occur, and then uses assignment to populate them. * eval.c (bind_macro_params): Instead of env_vbind, use the newly introduced lex_or_dyn_bind helper function. (op_tree_bind, op_mac_param_bind): Save and restore dyn_env around bind_macro_params and the evaluation of the associated body. In op_defmacro, this is already done.
* bind_args refactoring.Kaz Kylheku2018-05-031-77/+45
| | | | | | | | * eval.c (lex_or_dyn_bind_seq, lex_or_dyn_bind): New static functions. (bind_args): Eliminate repeated code using new helper functions. One wrong repetitions is thereby fixed also: a a neglected check of dyn_env_made.
* doc: break up long syntax.Kaz Kylheku2018-05-021-9/+14
| | | | | | | | * txr.1: The syntax synopses for the following functions and macros are too long and are awkwardly wrapped by man under 80 columns: make-time, make-time-utc, make-env, call-update-expander, call-clobber-expander and txr-if. Breaking up and shortening some identifiers.
* doc: fix recurring syntax formatting error.Kaz Kylheku2018-05-021-12/+12
| | | | | | * txr.1: I spotted a problem in the syntax synopsis of remq, remql and remqual. The same mistake was made in a few other places. remq* also had an error, though different.
* expander: remove pspecials from param expansionKaz Kylheku2018-05-011-29/+11
| | | | | | | | | * eval.c (expand_opt_params_rec, expand_params_rec): Remove pspecials argument, and accumulation of the special variables. The caller doesn't use this list any more. (expand_params): Remove unused specials local variable whose address was passed as the pspecials argument to expand_params_rec.
* compiler: correct semantics of special var args.Kaz Kylheku2018-05-011-7/+15
| | | | | | | | | | | | | | | | | | | The same, correct semantics for special variables in function arguments get implemented in the compiler. * share/txr/stdlib/compiler.tl (compiler comp-lambda): We stick with the strategy that each parameter which is a special variable is aliased by an anonymous lexical variable. The difference is that we bind the underlying special variable from the hidden lexical's value as early as possible. The overall processing is rearranged. On entry into the function, if any of the required arguments are specials, their values are immediately bound to the special variables in a new environment. Then the optional arguments are processed, and they bind specials in the dynamic environment also. Previously, the specials were bound in one fell swoop after processing the optionals, leading to the same incorrect semantics that the interpreter code had.
* interpreter: correct semantics of special var args.Kaz Kylheku2018-05-013-60/+92
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In this patch we eliminate the special operator sys:with-dyn-rebinds, and implement correct semantics for dynamically scoped variables that occur in argument lists. * eval.c (with_dyn_rebinds_s): Symbol variable removed. (bind_args): Handle special variables dynamically: for each symbol that appears, check whether it is a special and treat accordingly by allocating a new dynamic environment if necessary, and binding in that environment. This adds overhead, which is why I moved away from this approach in the past. But now that there is a compiler, overhead in the interpreter matters less. Correct semantics is more important. (expand_params): Greatly simplified for not having to wrap the sys:with-dyn-rebinds operator around the body. (funcall_interp): Since bind_args can now extend the dynamic environment, it is necessary to save and restore dyn_env around it. Another call to bind_args occurs in op_catch; that already saves and restores dyn_env. (op_with_dyn_rebinds): Static function removed. (do_expand): with-dyn-rebinds-s case removed. (eval_init): Removed interning of sys:with-dyn-rebinds symbol and registration of special op. * protsym.c: Regenerated. * compiler.tl (compiler compile): Remove case which handles sys:with-dyn-rebinds.
* expander: regression in param list treatment.Kaz Kylheku2018-04-301-8/+5
| | | | | | | | | | | | | | | | | | | | | | | | | Change ca6199a that went into TXR 191 was over-zealous in suppressing expand_param_rec calls for non-macro argument processing. The recursive calls are needed in order to detect parameters that are special variables and add them to pspecials. The upshot is that usage such as the following broke: (lambda (*stdout*) ...) because expand_param_rec isn't called on the *stdout* symbol and *stdout* is thus not noted as a special variable, and thus the expander then neglects to produce (sys:with-dyn-rebinds (*stdout*) ...) around the body of the lambda. The new compiler introduced at the same time made this harder to find. Why? Because the compiler ignores the sys:with-dyn-rebinds special form; it implements its own handling for specials in lambda and let! So compiled code is unaffected by this regression. * eval.c (expand_opt_params_rec): Call expand_params_rec on the car of the optional var-init pair, whether or not expanding a macro style parameter. (expand_params_rec): Call expand_params_rec recursively on any parameter that is bindable whether or not in macro mode. The two cases fold together again, and so here we see that the recent fix d934a3e was also a regression caused by ca6199a.
* Version 194.txr-194Kaz Kylheku2018-04-304-3/+22
| | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise.
* Makefile: use order-only between early and late tlo-s.Kaz Kylheku2018-04-291-1/+1
| | | | | | | | | * Makefile: make STDLIB_EARLY_TLOS order-only prerequisites of STDLIB_LATE_TLOS, rather than conventional prerequisites. This means that the early tlo-s are built or rebuilt before the late ones, but there is no other dependency expressed: an update of early tlo-s doesn't force late tlo-s to be out-of-date and updated also.
* compiler: improve wording of destructuring errors.Kaz Kylheku2018-04-291-10/+16
| | | | | | | * share/txr/stdlib/error.tl (sys:bind-mac-error, sys:bind-mac-check): Improve error messages with better wording. Use ~a for rendering parameter syntax so sys: package prefixes don't appear.
* bugfix: include most negative two's in cnum range.Kaz Kylheku2018-04-292-3/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The INT_PTR_MIN value isn't the smallest value actually representable in cnum, because it is just the additive inverse of INT_PTR_MAX. In two's complement, the INT_PTR_MIN-1 value is still representable. But we are excluding it. If a Lisp integer has the value INT_PTR_MIN-1, the c_num function will fail to convert it to a cnum. This situation occurs in FFI, where code may expect that the Lisp value #x-80000000 can convert to an external 32 bit integer type. This will be done by way of a conversion to cnum first via c_num (see ffi_i32_put for instance, which calls c_i32 which relies on c_num). * arith.c (INT_PTR_MAX_SUCC_MP): New static variable. This holds a bignum equivalent to INT_PTR_MAX + 1. (in_int_ptr_range): We now check whether the value against the range [-(INT_PTR_MAX + 1), (INT_PTR_MAX + 1)] and then check all possible return values. The MP_LT case is clearly in range, and MP_GT is out of the range. The interesting situation is MP_EQ: in that case we just test the sign to see whether we are looking at -(INT_PTR_MAX + 1). (int_flo): INT_PTR_MIN is referenced in this function, so we use INT_PTR_MIN - 1 instead. This allows that value to be handled via the simple bignum(n) case. (arith_init): Initialize INT_PTR_MAX_SUCC_MP. We cannot initialize it to INT_PTR_MAX + 1 directly because that expression overflows: insted we use INT_PTR_MIN - 1 and then flip the resulting bignum's sign. (arith_free_all): Call mp_clear on the new variable to release its digit buffer. * ffi.c (make_ffi_type_enum): Use INT_PTR_MIN - 1 as the initial value of the highest variable, to accurately calculate the range of the enum values if they contain INT_PTR_MIN - 1.
* compiler/assembler: bugfix: bignums can't be immediate ops.Kaz Kylheku2018-04-292-2/+2
| | | | | | | | | | | | | | | | | * share/txr/stdlib/asm.tl (assembler immediate-fits-type): Do not include bignum types as candidates for immediate operand. We take the sys:bits representation of the object, and that of course is a pointer. This case actually happens on 32 bit platforms because the value that is one less than the most negative fixnum still fits into the fixnum representational range, due to the way two's complement works, but is actually a bignum. Concretely, the value #x-20000000 is a bignum, but its width is 29, which falsely suggests that its representation can fit into 32 bits as a literal. * share/txr/stdlib/compiler.tl (compiler comp-atom): Test for fixnum here rather than integerp, so in the above discussed case, we don't generate a movi instruction.
* asm: improve bad immediate diagnostic.Kaz Kylheku2018-04-281-1/+1
| | | | | * share/txr/stdlib/asm.tl (bits-to-obj): Show the bad immediate operand in hex.
* compiler: bugfix: wrong immediate op width calculation.Kaz Kylheku2018-04-281-1/+1
| | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-atom): The calculation which determines whether an integer operand fits into an immediate move instruction is incorrect. The width function doesn't include a sign bit, so that must be counted. Also, the immediate operand includes a two bit type tag: thus we are off by three.
* Version 193.txr-193Kaz Kylheku2018-04-267-594/+635
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim, protsym.c: Regenerated.
* build: fix failure due to .tlo compilation order.Kaz Kylheku2018-04-261-0/+6
| | | | | | | | | | | | | On newer GNU Make versions, $(wildcard ...) doesn't sort its results, and so we compile .tlo files in an arbitrary order. For the most part, this is fine. However, there is a complicated circular dependency involving the error.tl file requiring it to be compiled first. * Makefile (STLIB_EARLY_PATS, STDLIB_EARLY_TLOS, STDLIB_LATE_TLOS): New variables. Use these to express a dependency which causes error.tlo to be built first.
* vm: heap corruption bug.Kaz Kylheku2018-04-251-1/+1
| | | | | | | | | | | | * vm.c (vm_execute_toplevel): Fix data vector being assigned to the wrong display frame, leaving vm.dspl[1].vec uninitialized. Why is that a problem? Because the VM depends on these vectors when performing the vm_set operation: if a frame register is stored, and the frame has an associated vector, mut_obj is invoked on that vector. Now that there exists the load-time operator, the d regs (which live in dspl[1]) can be mutated. That causes mut_obj to be called with garbage. This was all discovered during testing on PPC64.
* compiler: replace "$" package hack.Kaz Kylheku2018-04-254-12/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | When compile-file writes emits the file, it does so with *package* bound to a temporary package named "$" so that all the symbols get fully qualified. Problem is, this is a valid package name and is added to the package list. While the package exists, symbols such as $:a could be interned. If such symbols occur in code being compiled, they get emitted using unqualified names. Let's introduce an internal interface for making an anonymous package which isn't on the list of package, and which has a name that results in bad syntax if it occurs in print. * eval.c (eval_init): Register sys:make-anon-package intrinsic. * lib.c (make_package_common): New static function. (make_package): Package construction and initialization code moved into make_package_common. (make_anon_package): New function. * lib.h (make_anon_package): Declared. * share/txr/stdlib/compiler.tl (usr:compile-file): When writing out translation, bind *package* to anonymous package from sys:make-anon-package.
* vm: de-inline opcode dispatch.Kaz Kylheku2018-04-252-41/+43
| | | | | | | | | | | | | | | | | | | The vm_execute function is heavily inlined by gcc, and requires almost 500 bytes of stack space. The stack space really adds up when the vm re-enters itself recursively. Also, pointers to garbage can hide in areas of that bloated stack frame that are not being used by execution paths, adding to the spurious retention problem. * lib.h (NOINLINE): New preprocessor symbol. * vm.c (vm_prof, vm_frame, vm_sframe, vm_dframe, vm_end, vm_fin, vm_call, vm_apply, vm_gcall, vm_gapply, vm_movrs, vm_movsr, vm_movrr, vm_movrsi, vm_movsmi, vm_movrbi, vm_if, vm_ifq, vm_ifql, vm_swtch, vm_uwprot, vm_block, vm_no_block_err, vm_retsr, vm_retrs, vm_retrr, vm_abscsr, vm_catch, vm_handle, vm_getsym, vm_getbind, vm_setsym, vm_bindv, vm_close, vm_execute): Apply INLINE to functions.
* vm: null out variable arg list.Kaz Kylheku2018-04-251-1/+1
| | | | | * vm.c (vm_execute_closure): Null out the vargs local to prevent spurious retention.
* vm: destroy t-reg values used as call args.Kaz Kylheku2018-04-241-17/+25
| | | | | | | | | | Whe the compiler uses t-regs as function call arguments, they are t-regs that have no next use and can be nulled out. We do this to prevent false retention. * vm.c (vm_getz): New function. (vm_call, vm_apply, vm_gcall, vm_gapply): Use vm_getz for fetching arguments.
* compiler: implement eliding of blocks.Kaz Kylheku2018-04-242-13/+139
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It is time-wasting to have a block in every function. In this patch we have the compiler eliminate blocks if it is obvious that they will not be the targets of any exits or continuation captures through any direct function calls. If a block contains only calls to library functions, and doesn't call certain functions, then it is removed. It is possible for this removal to be strictly wrong and different from interpreted code. This is true if the code enclosed in a block invokes a function indirectly or via a quoted symbol, and that function tries to return from the block or capture a continuation using that block as a prompt. Such a call doesn't prevent the block from being removed. For instance, this won't work in compiled code any more: (defun tricky (fun) (call fun)) (tricky (lambda () (return-from tricky 42))) The call function is considered safe; the (call fun) form doesn't prevent the block inside the tricky function from being removed. * share/txr/stdlib/compiler.tl (blockinfo): New struct. (env): New slot, bb. (env lookup-block, env extend-block): New methods. (%block-using-funs%): New global variable. (compiler comp-block): Implement the elision of the block based on what free functions are referenced in the body, and whether the block is referenced lexically. Also, bind the block in the environment using the bb member in the env structure. (comp-return-from): Lookup the block lexically and mark it as used. (system-symbol-p): New function. * txr.1: Document the rules for elision of blocks.