summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
...
* lib: string bug spotted on Solaris.Kaz Kylheku2023-06-101-1/+1
| | | | | | | | | | * lib.c (string_finish): On platforms where we do not HAVE_MALLOC_USABLE_SIZE, there is a compiler diagnostic. The code is inappropriately using the set macro and mkloc to assign the st->st.alloc member, which is just a number (cnum type), and not a val. The set macro is only needed when mutating a gc heap object to point to another gc heap object.
* New functions keep-keys-if, separate-keys.Kaz Kylheku2023-06-076-1/+208
| | | | | | | | | | | * lib.[ch] (keep_keys_if, separate_keys): New functions. * eval.c (eval_init): keep-keys-if, separate-keys intrinsics registered. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* clean-file: tests.Kaz Kylheku2023-06-052-0/+110
| | | | | | * tests/018/clean.tl: New file. * tests/018/clean.expected: New file.
* autoload: rename local variable.Kaz Kylheku2023-06-051-2/+2
| | | | | | | * autoload.c (expander_let_set_entries): The expander-let symbol is in the usr package, registered via autoload_set, so the array should be called name and not sys_name.
* New functions load-args-recurse and load-args-processKaz Kylheku2023-06-055-0/+352
| | | | | | | | | | | | * autoload.c (load_args_set_entries, load_args_instantiate): New static functions. (autoload_init): Register new auto-loaded module "load-args". * stdlib/load-args.tl: New file. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* compiler: more logging regarding compiled files.Kaz Kylheku2023-06-051-12/+23
| | | | | | | | * stdlib/compiler.tl (clean-file): Under a log-level of 1 or more, report clean-file removes a file. (compile-update-file): Under a log level of 1 or more, report when a compiled file was skipped due to being up-to-date.
* compiler: new compiler option log-levelKaz Kylheku2023-06-043-7/+38
| | | | | | | | | | | | | | | | | | With log-level, we can obtain trace messages about what file is being compiled and individual forms within that file. * autoload.c (compiler_set_entries): Intern the slot symbol log-level. * stdlib/compiler.tl (compile-opts): New slot, log-level. (%warning-syms%): Add log-level to %warning-syms%. Probably we need to rename this variable. (compile-file-conditionally): Implement the two log level messages. (with-compile-opts): Allow/recognize integer option values. * txr.1: Documented.
* compiler: new function, clean-file.Kaz Kylheku2023-06-044-1/+92
| | | | | | | | | | | | | | | | This function simplifies cleaning, by allowing a file to be cleaned to be identified in much the same way as an input file to load or compile-file. * autoload.c (compiler_set_entries): The clean-file symbol is interned and becomes an autoload trigger for the compiler module. * stdlib/compiler.tl (clean-file): New function. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* bug: compile-file can put out nil, confusing load.Kaz Kylheku2023-06-031-1/+1
| | | | | | | | | | | | | | | | | | | | The file compiler combines compiled forms into a single list as much as possible so that objects in the list can share structure (e.g. merged string literals). However, when package-manipulating forms occur, like defpackage, it has to spit these lists, since the package manipulations of an earlier form affect the processing of a later form, such as whether symbols in that form are valid. This splitting does not take care of the case that an empty piece may result when the very last form is a package manipulation form. A nil gets written to the .tlo file, which the load function does not like; load thinks that since this is not a valid list of compiled forms, it must be the version number field of a catenated .tlo file, and proceeds to find it an invalid, incompatible version. * stdlib/compiler.tl (dump-to-tlo): Use partition* rather than split*. partition* doesn't leave empty pieces.
* bug: autoload issue affecting with-compilation-unitKaz Kylheku2023-06-031-0/+5
| | | | | | | | | | | | | | | When a (with-compilation-unit ...) form is compiled, it references the value of a certain special variable that is private to the compiler. This reference is correct, but the variable's symbol is not hooked up to trigger autoload. If the compiler module has not yet been loaded, and the compiled version of a with-compilation-unit form is evaluated, it will fail due to an unbound variable error. * autoload.c (compiler_set_entries): Add the sys:*in-compilation-unit* variable name to the autoload triggers for the compiler module.
* Version 287.txr-287Kaz Kylheku2023-06-037-1179/+1263
| | | | | | | | | | | | | | * RELNOTES: Updated. * configure (txr_ver): Bumped version. * stdlib/ver.tl (lib-version): Bumped. * txr.1: Bumped version and date. * txr.vim, tl.vim: Regenerated. * protsym.c: Regenerated.
* gc: fix bad c++ casts.Kaz Kylheku2023-06-032-6/+6
| | | | | | | | | | This C++ regression snuck into in Version 286; I didn't check C++ compilation. * lib.h (container): Macro must use coerce not convert because mem_t * isn't void *. * gc.c (gc_prot_array_alloc): Likewise.
* listener: process multiple expressionsKaz Kylheku2023-06-022-19/+29
| | | | | | | | | * parser.c (repl): use read_objects_from_string, forming a progn expression which is evaluated. Check for the first expression being a listener command. * txr.1: Updated.
* doc: missing html-encode* syntax synopsis.Kaz Kylheku2023-06-021-0/+1
| | | | | * txr.1: Documentation for html-encode* neglects to mention it in the Syntax section.
* doc: defmacro doesn't define local macros.Kaz Kylheku2023-06-021-1/+1
| | | | | * txr.1: Fix text referring to "local macro defined using defmacfro", which should of course be macrolet.
* doc: nonexistent syntactic place.Kaz Kylheku2023-06-021-1/+0
| | | | | | * txr.1: The list of syntactic places mentions the list accessor twice, with different argument orders. Removing the wrong one.
* load: now passes args via *load-args*Kaz Kylheku2023-05-316-23/+82
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We can give additional arguments to load, which become arguments of the script, which it can retrieve via the *load-args* special variable. * eval.c (load_args_s): New symbol variable. (loadv): New function, taking over the implementation of load. This takes variadic arguments. Loadv binds the *load-args* variable from the list of variadic arguments. (load): Reduced to wrapper around loadv. (rt_load_for): Each clause in load for can now have arguments after the target name. If that file needs to be loaded, then the arguments are passed. (me_load_for): The macro expander for the load-for macro needs to allow for the load-arg expressions and generate code which passes them to sys:rt-load-for. They all get evaluated. (eval-init): Initialize load_args_s and register the *load-args* variable. Update registration of intrinsic function load to use loadv. * tests/019/load-ret.tl, * tests/019/load-ret/module.tl, * tests/019/load-ret/module2.tl: New files. * txr.1: Documented.
* load: now establishes a block named load.Kaz Kylheku2023-05-314-16/+67
| | | | | | | | | | | | | | | | | | | | | | Files loaded from the command line or via the load function or @(load) directive now have a block named load in scope. Thus (return-from load <expr>) may be used to abort a load when it is finished. The load function will then return the value of <expr>. * eval.c (load): Bind a load block around the whole thing and use the captured return value as the function's return value. * match.c (v_load): Bind the load block here too. Ensure that if the block return is taken, the ret variable contains next_spec_k, so that processing continues with whatever directive follows the @(load). * txr.c (txr_main): Bind the block in severl cases that load code. * txr.1: Documented.
* command line: -e takes multiple forms.Kaz Kylheku2023-05-304-15/+54
| | | | | | | | | | | | * parser.[ch] (read_objects_from_string): New function. * txr.c (help): Update description of -e, and don't describe -p as being like -e. (txr_main): Implement -e using read_objects_from_string, with progn consed to the front. Don't evaluate if it returns the error value colon_k. * txr.1: Documentation updated.
* parser: handle "fatal" conditions in flex scannerKaz Kylheku2023-05-292-174/+192
| | | | | | | | | * parser.l (YY_FATAL_ERROR): New macro. (lex_irrecovarable_error): New function. (parser_l_init): Take address of yy_fatal_error and cast to void, to suppress warning that the function is unused. * lex.yy.c.shipped: Updated.
* New macro: expander-let.Kaz Kylheku2023-05-284-0/+116
| | | | | | | | | | | | | * stdlib/expander-let.tl: New file. * autoload.c (expander_let_set_entries, expander_let_instantiate); New static functions. (autoload_init): Register autoloading of above new file via above new functions. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* doc: compiler-let syntaxKaz Kylheku2023-05-281-1/+9
| | | | | | * txr.1: the compiler-let operator has a stricter syntax than shown in the synopsis; it only allows (var init-form) pairs, not single variables.
* expander: support param macros in nested macro param lists.Kaz Kylheku2023-05-273-39/+72
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Parameter list macros work in inside macro parameter lists, like they do in function parameter lists. However, they ony work at the top level. Macro parameter lists are nested; they may contain nested parameter lists that match corresponding shapes in the argument list. This patch extends parameter list macros to work in nested macro parameter lists. * eval.c (expand_opt_params_rec, expand_params_rec): These two functions must be extended to take a body argument, and to return not just an expanded parameter list but a parameter list accompanied by a body. We do that by making them return a cons cell, whose car is the expanded parameter list and the cdr is the possibly transformed body. Additionally, these functions now call expand_param_macro on nested macro parameter lists. (expand_params): This function becomes slightly simpler as a result of the above changes. Because expand_params_rec already returns a cons cell holding a parameter list and body, we just return that as-is. * tests/011/keyparams.tl: Added some tests of this, vie the standard :key parameter list macro. A macro is tested which has a nested (:key ...) parameter list in a required parameter position as well as in an optional position. * txr.1: Documented.
* awk: new :fun clause for local functions.Kaz Kylheku2023-05-242-28/+56
| | | | | | | | * stdlib/awk.tl (awk-compile-time): New slot, funs. (awk-expander): Gather :fun clauses info funs slot. (awk): Include a labels form which injects the functions. * txr.1: Documented.
* compiler: fbind/lbind: elide unnecessary frames.Kaz Kylheku2023-05-241-9/+15
| | | | | | | | | | | * stdlib/compiler.tl (comp-fbind): When after removing unused functions we are left with an empty list (or the list of functions was empty to begin with), let's only emit the body fragment without any frame wrapping. We can't just return bfrag because that was compiled in the environment which matches the frame. Instead of the expense of compiling the code again, we rely on eliminate-frame to move all v registers up one level.
* label/flet: bug: empty case wallops symbol macros.Kaz Kylheku2023-05-242-1/+6
| | | | | | | | | | | | | | * eval.c (make_var_shadowing_env): We cannot return the original env in the empty variable case, but earnestly make a new one. This function is used by the expander when walking the lbind/fbind special from emitted by labels/flet. That form clobbers the environment via make_fun_shadowing_env, which calls make_var_shadowing_env and then destructively moves the variable bindings to the function binding slot of the environment. The manifestation is that when we have (symacrolet ((x 1)) (labels () x)), the x fails to expand; it has been wrongly moved to the function bindings area of the macro environment.
* awk: widen scope of redirection macros.Kaz Kylheku2023-05-242-39/+52
| | | | | | | | | | | | | | | | | This change makes it possible to use the redirection macros like -> and ->> everywhere in the awk macro, including the init-forms of the :let clause. * stdlib/awk.tl (sys:awk-mac-let-outer): New macro. (sys:awk-mac-let): Move redirection macros into awk-mac-let-outer. (awk): Rearrange the order of wrapping. We split the let so the awk-retval and aws-sym are bound outermost. Then we have the outer macros that provide the redirection operators. Then the application-defined lets inside of that. * txr.1: Documented wide scope of redirection macros.
* lib: fix issue uncovered by recent vm CALL insn change.Kaz Kylheku2023-05-242-7/+38
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The functions funcall1 through funcall4, when invoking a VM function, are not defending against the case when there are more arguments than the function can take. As a result, some :mass-delegate tests in tests/012/oop.tl are failing. They expect an :error result, but the calls are succeeding in spite of passing too many parameters via the delegate interface. The tests/012/lambda.tl suite should catch this, but it has unfortunate weaknesses. * lib.c (funcall1, funcall2, funcall3, funcall4): When dispatching the general VM case via vm_execute_closure, check that if the closure has fewer fixed parameters than arguments we are passing, it must be variadic, or else there is an error. * tests/012/lambda.tl (call-lambda-fixed): New function. Unlike call-lambda, which uses the apply dot syntax, this switches on the argument list shape and dispatches direct calls. These compile to the CALL instruction cases with four arguments or less which will exercise funcall, funcall1, ... funcall4. Also, adding some missing test cases that probe behavior with excess arguments.
* awk: bug: fix ->> appending redirection operator.Kaz Kylheku2023-05-232-1/+43
| | | | | | | * stdlib/awk.tl (awk-state ensure-stream): Fix missing handling for the :apf kind symbol used by appending. * tests/015/awk-redir.tl: New file.
* awk: bug: broken redirection operators.Kaz Kylheku2023-05-231-2/+2
| | | | | | | * stdlib/awk.tl (sys:awk-redir): Fix regression from April 2018. The gensym variable introduced must be parallel bound, since it is referenced by the init expression of the other variable. This breaks all awk redirection operators.
* vm: handle cases in CALL like in GCALL.Kaz Kylheku2023-05-171-14/+58
| | | | | | | | * vm.c (vm_call): Specially handle the cases of 0 to 4 arguments, avoiding the general loop and invocation of generic_funcall. This gets us about a 1% improvement in recompiling the standard libarry (touch stdlib/*.tl; make).
* quips: reference to Super Dave Osborne.Kaz Kylheku2023-05-171-0/+1
| | | | * stdlib/quips.tl (%quips%): New entry.
* with-compile-options: reimplement using compiler-letKaz Kylheku2023-05-162-26/+64
| | | | | | | | | | | | | | | | | | | The with-compile-opts macro is rewritten such that it cad occur inside code that is being compiled, and change compiler options for individual subexpressions. It continues to work as before in scripted build steps such as when calls to (compile-file ...) are wrapped in it. However, for the time being, that now only works in interpreted code, because with this change, when a with-compile-opts form is compiled, it no longer arranges for the binding of *compile-opts* to be visible to the subforms; the binding affects the compiler's own environment. * stdlib/compiler.tl (with-compile-opts): Rewrite. * txr.1: Documented.
* New special operator: compiler-letKaz Kylheku2023-05-165-3/+87
| | | | | | | | | | | | | | | | | | | | | | * eval.c (compiler_let_s): New symbol variable. (op_let): Recognize compiler-let for sequential binding. (do_expand): Traverse and diagnose compiler-let form. (eval_init): Initialize compiler_let_s and register the interpreted version of the operator. * stdlib/compiler.tl (compiler compile): Handle compiler-let form. (compiler comp-compiler-let): New method. (no-dvbind-eval): New function. * autoload.c (compiler-set-entries): Intern the compiler-let symbol in the user package. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New special operator: progvKaz Kylheku2023-05-155-1/+185
| | | | | | | | | | | | | | | | | | | | | | Adding a progv operator, similar to the Common Lisp one. * eval.c (progv_s): New symbol variable. (op_progv): New static function. (do_expand): Recognize and traverse the progv form. (rt_progv): New static function: run-time support for compiled progv. (eval_init): Initialize progv_s, and register the the op_progv operator interpreting function. * stdlib/compilert (compiler compile): Handle progv operator ... (compiler comp-progv): ... via this new method. * tests/019/progv.tl: New file. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* quips: piano-related quip.Kaz Kylheku2023-05-151-0/+1
| | | | * stdlib/quips.tl (%quips%): New entry.
* vm: bugfix: global lexicals looked up dynamically.Kaz Kylheku2023-05-153-23/+42
| | | | | | | | | | | | | | | | | | | | | | | | | The getlx and setlx VM instructions are using dynamic lookup for uncached bindings, due to using the same lookup_fun search function. They should use lookup_global_fun. That doesn't have an environment parameter though, so the type is not right. However, the VM never uses the environment parameter; it's always passing nil. We will get rid of the environment parameter in the lookup_fn callback and introduce a few wrappers. * eval.c, eval.h (lookup_global_fun, lookup_dynamic_var, lookup_dynamic_sym_lisp1): New functions. * vm.c (vm_stab_slowpath, vm_get_binding): lookup_fn argument loses environment parameter, and so we don't have to pass nil. (vm_gcall, vm_gapply): Use pass lookup_global_fun to to vm_stab. (vm_getsym, vm_getbind, vm_setsym, vm_gettab, vm_settab): lookup_fn argument loses environment parameter. (vm_execute): lookup functions replaced with the appropriate one-argument ones. GETLX and SETLX see a behavior change, due to using lookup_global_var which doesn't search the dynamic environment.
* quips: new dad joke about the meta-object protocolKaz Kylheku2023-05-141-0/+1
| | | | * stdlib/quips.tl (%quips%): New entry.
* bug: symbol-value place always global.Kaz Kylheku2023-05-143-4/+41
| | | | | | | | | | | | | | | | | | | | | | | | | | | We have a problem. If v is a dynamic variable, then the form (let (v) (set (symbol-value 'v) 3)) is not behaving correctly; it's updating the top-level value of v not the rebound one. * eval.c (set_symbol_value): New static function. (eval_init): Register sys:set-symbol-value intrinsic. The top-vb variable, though no longer referenced by the symbol-value place, because existing compiled code depends on it. * stdlib/place.tl (symbol-value): Rewrite the place logic to use symbol-value to access the variable, and set-symbol-value to update it, instead of referencing sys:top-vb. (sys:get-vb): This function has to stay, because it provides run-time support for code compiled with the buggy version of the place. * tests/019/symbol-value.tl: New file.
* fix crash if built-in variable is unbound.Kaz Kylheku2023-05-121-1/+3
| | | | | | | | | | | | | | | | | | | We use lookup_var_l in many places to look up the current dynamic value of a built-in variable such as *stdout*. Those places assume that a a valid location is returned which can be subject to a deref. If the application calls makunbound to remove such a variable, that deref will crash due to a null pointer dereference. Possible repro steps are numerous, possible for many variables. One example: (makunbound '*stdout*) (put-line) * eval.c (lookukp_var_l): If the binding is not found, do not return a nulloc, but throw an error exception.
* doc: missing verb under makunbound.Kaz Kylheku2023-05-121-1/+1
| | | | | * txr.1: Add missing "removes" verb to first sentence of description of makunbound.
* compiler: spelling error in diagnostic.Kaz Kylheku2023-05-121-1/+1
| | | | | * stdlib/compiler.tl (with-compile-opts): Remove stray character from "uncrecognized".
* ffi: fix unused variable warning.Kaz Kylheku2023-05-111-2/+2
| | | | | * ffi.c (ffi_varray_null_term_get): An i variable is initialized and incremented in a for loop, but never used.
* android: restore pointer tag in gc_free_all.Kaz Kylheku2023-05-111-0/+4
| | | | | | | | | | * gc.c (gc_free_all): Just like we do in the sweep function, we must mask back the pointer tag that we removed from the heap object's pointer, before handing the pointer to the free function. Starting in Android 11, the pointer tagging is more strict. It was not enforced previously; now our logic for stripping and restoring the tags is actualy being tested.
* android: configure SDK level via clang --target.Kaz Kylheku2023-05-111-1/+1
| | | | | | | | * configure: don't set __ANDROID_API__, but instead use --target to specify a target architecture. Some of the version checking is now done using symbol attributes; the preprocessor symbol alone doesn't tell the compiler what SDK version is being targeted.
* sysif: define passwd symbol for group stuff.Kaz Kylheku2023-05-111-1/+3
| | | | | | | | | * sysif.c (sysif_init): The passwd symbol is used by both the passwd and group structure, so we need to initialize it if either HAVE_PWUID or HAVE_GRGID is set. Certain Android SDK levels have getgrgid but not getpwuid, so it's possible to end up with HAVE_GRGID but not HAVE_PWUID, in which case passwd_s ends up nil, blowing up the make_struct_type call.
* Version 286.txr-286Kaz Kylheku2023-05-076-675/+768
| | | | | | | | | | | | * RELNOTES: Updated. * configure (txr_ver): Bumped version. * stdlib/ver.tl (lib-version): Bumped. * txr.1: Bumped version and date. * txr.vim, tl.vim: Regenerated.
* build: mergesort is in <stdlib.h> on MacOS.Kaz Kylheku2023-05-071-1/+1
| | | | | * configure: add mergesort to list of clashing identifiers to handle.
* doc: remove "comprised of" in two places.Kaz Kylheku2023-05-061-7/+7
| | | | | | | * txr.1: an instance of "comprised of" disappears in a wording improvement under "Dot Position in Function Calls". Another instance under doloop is replaced by consisting of. I don't have anything against it, but it bothers some people.
* hash: cache struct hash fields in locals in hash_mark.Kaz Kylheku2023-05-051-8/+11
| | | | | | * hash.c (hash_mark): Cache the table, vector and mask in local variables, so they don't have to be reloaded into registers when external functions are called.