summaryrefslogtreecommitdiffstats
path: root/share
Commit message (Collapse)AuthorAgeFilesLines
* 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-011-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Version 194.txr-194Kaz Kylheku2018-04-301-1/+1
| | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise.
* 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.
* 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-261-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim, protsym.c: Regenerated.
* compiler: replace "$" package hack.Kaz Kylheku2018-04-251-4/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* compiler: implement eliding of blocks.Kaz Kylheku2018-04-241-13/+48
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* compiler: compile-file/load-time integration fix.Kaz Kylheku2018-04-241-1/+1
| | | | | | | | | | | | | | | The issue is that when load-time forms are present in top-level forms, the execution of those forms destructively manipulates the data table. This is bad when we intend to write out the compiled forms into a file; we need to write them out in their freshly compiled state before these side effects took place. * share/txr/stdlib/compiler.tl (list-from-vm-desc): When serializing the compiled VM pieces to a list, make a freshly allocated shallow copy of the data vector. This could be optimized away if we know that the VM doesn't contain load-time effects.
* compiler: called function must be listed as free.Kaz Kylheku2018-04-241-4/+6
| | | | | | | | | When compiling a plain (f x) function call, the resulting frag must list f as a free function. * share/txr/stdlib/compiler.tl (comp-fun-form): Compile the call with comp-call-impl; then pushnew the symbol into the frag's ffuns set list.
* compiler: bug: return miscompiled as abscond.Kaz Kylheku2018-04-241-1/+1
| | | | | | | | | | Oops; (return x), equivalent to (return-from nil x), is being miscompiled as if it were (sys:abscond-from nil x). * share/txr/stdlib/compiler.tl (comp-return): When short-circuit-recursing into comp-return-from, put return-from into the operator position, because that function checks for that symbol.
* compiler: streamline destructuring error checks.Kaz Kylheku2018-04-232-92/+90
| | | | | | | | | | | | | * lisplib.c (error_set_entries): Add sys:bind-mac-check to autoload list for error.tl * compiler.tl (expand-bind-mac-params): For strict mode, use the new sys:bind-mac-check function to do the check and report the error. For non-strict checks, consolidate the error check by taking advantage of n-ary nature of <= function. * error.tl (sys:bind-mac-check): New function.
* New macro: load-time.Kaz Kylheku2018-04-232-4/+46
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is similar to the ANSI CL load-time-value. * eval.c (load_time_s, load_time_lit_s): New symbol variables. (op_load_time_lit, me_load_time): New static functions. (eval_init): Intern load-time symbol and sys:load-time-lit. Register the sys:load-time-lit special operator and load-time macro. * share/txr/stdlib/asm.tl (assembler parse-args): We must now allow the d registers to be the targets of a mov instruction, because load-time depends on being able to mutate the data vector, in order to turn the result of a calculation into a de facto literal. * share/txr/stdlib/compiler.tl (compiler): New member, lt-frags. (compile-in-toplevel): New macro. (compiler alloc-dreg): New method. (compiler compile): Handle sys:load-time-lit special form via comp-load-time-lit method. (compiler comp-load-time-lit): New method. (usr:compile-toplevel): Prepend the load-time assembly code fragments to the compiled assembly code. * vm.c (vm_set, vm_sm_set): Do not reject an attempt to modify the static data, since load-time now generates mov instructions targetting the d registers. * txr.1: Document load-time.
* compiler: remove unused slot.Kaz Kylheku2018-04-231-1/+0
| | | | | * share/txr/stdlib/compiler.tl (compiler): Remove the nreg slot. It is not referenced anywhere.
* compiler: better diagnostic about d-reg exhaustion.Kaz Kylheku2018-04-231-1/+1
| | | | | | | * share/txr/stdlib/compiler.t (compiler get-dreg): Replace "out of registers" message with something more pertinent. The problem is that the code has too many literals for the maximum table size.
* compiler: unnecessary let*.Kaz Kylheku2018-04-231-1/+1
| | | | | * share/txr/stdlib/compiler.tl (compiler get-dreg): A let* with just one variable in it is changed to let.
* compiler: tighter code for quasiliterals.Kaz Kylheku2018-04-211-4/+9
| | | | | | | | | | | | | | | | | | | | | | | | Give the sys:fmt-simple function argument defaulting so the generated code doesn't have to call it with all five arguments present, four of them nil being much of the time. * eval.c (fmt_simple): Default all but the first four arguments. (eval_init): Re-register sys:fmt-simple as having only one required argument. * parser.c (read_file_common): Load version 1 or 2 files. We are bumping the object file version to 2 because now when we compile files, they won't work with older TXR in which all five arguments to sys:fmt-simple are required. * share/txr/stdlib/compiler.tl (expand-quasi-mods): Generate the sys:fmt-simple call with just enough arguments to express the modifiers that were decoded. (sexpand-quasi-args): Reduce the trivial modifier-less sys:fmt-simple calls to just one argument. (%tlo-ver%): Bump major version to 2.
* awk: bug: multiple expansion in redirection macros.Kaz Kylheku2018-04-211-2/+3
| | | | | | share/txr/stdlib/awk.tl (sys:awk-redir): Put the unused gensym to use: evaluate the path expressio nonce into the gensym variable. Also move strangely place comma.
* Version 192.txr-192Kaz Kylheku2018-04-191-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim, protsym.c: Regenerated.
* new macros: hlet, hlet*.Kaz Kylheku2018-04-191-0/+28
| | | | | | | | | | * lisplib.c (yield_set_entries): Add hlet and hlet* to autoload list. * share/txr/stdlib/yield.tl (hlet-expand): New function (hlet, hlet*): New macros. * txr.1: Documented.
* asm: disassemble: three digits in t and d regs.Kaz Kylheku2018-04-191-3/+3
| | | | | | | | share/txr/stdlib/asm.tl (operand-to-sym): Print t and d registers with three digits, like is done with the index portion of v regs already. (disassemble-cdf): Print three-digit d regs in data table dump.
* compiler: don't expand top-level forms twice.Kaz Kylheku2018-04-181-4/+8
| | | | | | | | | | * share/txr/stdlib/compiler.tl (usr:compile-toplevel): Support optional parameter indicating that no expansion is required. (usr:compile-file): Call compile-toplevel with a t argument for the new expanded-p parameter, so no further expansion takes place. * txr.1: Document new optional parameter of compile-toplevel.
* compiler: bugfix: miscompiled unwind-protect.Kaz Kylheku2018-04-181-5/+3
| | | | | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-unwind-protect): The protected code must terminate with an end instruction. It cannot just branch to the skip label because then we keep executing the following unprotected code still under the unwind protect. How it works is that the protected code ends with end. Then the cleanup fragment at the cleanup offset is executed, also terminating with an end (that one we have in place). We don't need the skip label because the instruction pointer advances after executing the end instruction after the cleanup fragment.
* asm: disassembler v-reg regression.Kaz Kylheku2018-04-181-2/+2
| | | | | | | * share/txr/stdlib/asm.tl (operand-to-sym): To form v registers, we must subtract 2 from the level, not add. (operand-to-exp): Bug was propagated to this new function, too.
* compiler: de-duplicate switch.Kaz Kylheku2018-04-181-11/+18
| | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-switch): Identify duplicate cases and don't generate code for these; patch their table entries to point to one case. The case macros generate such code when the keys are integers, and multiple integer keys are associated with the same case: (caseq x ((1 2 3 4 5) ...) ((6 7) ...)).
* compiler: bump object file version.Kaz Kylheku2018-04-181-1/+1
| | | | | | | | | | | The instruction set architecture has changed due to the redimensioning of the frame display, so we must bump up the major number. * share/txr/stdlib/compiler.tl (%tlo-ver%): Change to (1 0). * parser.c (read_file_common): Refuse to load if major number isn't 1.
* asm: deal with too large d regs in getv/setv.Kaz Kylheku2018-04-172-4/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Only registers d00 through d3f can now fit into a small operand, but the setv, getv and derived instructions only take a small operand as the name. If a function accesses more than 64 dynamic variables, it can't be compiled and assembled. (Fewer, if it uses symbols for anything else.) The approach we take here is to relax the name operand in getv and setv: it can be a large or small operand. When assembling these instructions, we check the size: if the operand is large, we emit an extra mov instruction to move the operand to a register that is itself a small operand. Then we use that register as the operand. To do this, we need a dedicated assembler temporary register, like the "at" register on MIPS. We reserve t1 as the assembler temporary; the compiler must be adjusted not to use it. Future task: the following optimization is possible: the machine code can be scanned for uses of d registers. The d registers can be globally renumbered/reassigned (along with a rearrangement of the order of the datavec) such that the getv and setv instructions can use the lowest-numbered d registers, minimizing or eliminating these extra mov instructions. * share/txr/stdlib/asm.tl (operand-to-exp): New function. (op-getv, op-setv): Change name operand from rs to r, allowing a large operand. If the operand is large, emit the extra mov instruction into the temp register, and designate that register as the name for the getv/setv. * share/txr/stdlib/compiler.tl (compiler): Initialize t register counter to 2 rather than 1 so we don't allocate the assembler temporary t001. (compiler check-treg-leak): The balance check must cover a deficit of two registers now: t000 and t001.
* vm/asm: reconfiguration of display dimensions.Kaz Kylheku2018-04-172-21/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | Increasing the maximum frame width from 256 to 1024 words; and reducing the max display depth from 256 to 64 frames. Small operands use a 4:6 split: the first 64 words of the first 16 levels can be accessed with a 10 bit operand. * share/txr/stdlib/asm.tl (parse-operand): Adjust to wider syntax for registers due to more digits. The v registers are 5 hex digits now: 2 digit level, and a 3 digit offset. (with-lev-idx): New macro. (operand-to-sym): Use with-lev-idx and rename variables to lv and ix. (small-op-p, enc-op-p, small-op-to-sym): Rewrite for 4:6 small operand. * share/txr/stdlib/vm-param.tl (%lev-size%, %lev-bits%, %max-lev%): Adjust values. (%sm-lev-size%, %max-sm-lev-idx%, sm-lev-bits%): New symbol macros. * vm.c (VM_LEV_BITS, VM_LEV_MASK, VM_SM_LEV_BITS, VM_SM_LEV_MASK): Values adjusted.
* lib: error message cleanup.Kaz Kylheku2018-04-179-58/+66
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Eliminate function names from message string literals; they are interpolated via ~s from the symbol. Consistently use compile-error in macros. * share/txr/stdlib/asm.tl (asm-error): New function. (oc-base backpatch, assembler (define-label, parse-args, asm-one), bits-to-obj): Use asm-error. * share/txr/stdlib/awk.tl (awk-error): New function. (awk-state rec-to-f, awk-expander): Use awk-error. * share/txr/stdlib/conv.tl (conv): Function name out of string literal. * share/txr/stdlib/getopts.tl (getopts-error): New function. (opt-desc): Use getopts-error. * share/txr/stdlib/ifa.tl (ifa): Use compile-error; use symbol for name. (if-to-cond): Use compile-error. * share/txr/stdlib/place.tl (shift, defplace, get-mb): Use compile-error. (lset, placelet*, placelet): Use compile-error; use symbol for name. * share/txr/stdlib/socket.tl (str-inaddr, str-in6addr, str-inaddr-net-impl, str-inaddr-net, str-in6addr-net): Use symbols for function names. * share/txr/stdlib/txr-case.tl (txr-case-impl): Use compile-error and symbol for function name. * share/txr/stdlib/with-resources.tl (with-resources): Use compile-error and symbol for function name.
* vm/asm/compiler: parametrize display parameters.Kaz Kylheku2018-04-163-45/+97
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In this patch we replace some hard-coded constants related to the dimensions of the frame display, which will make it easier to experiment with changes to the configuration: to set up wider frames at the cost of max display depth. The encoding of small operands needs to be abstracted because games can be played here. A 10 bit small operand can be configured in various ways: for instance a 5:5 split would mean that the first 32 entries in the first 32 levels can be small operands. That's independent of the display configuration. * share/txr/stdlib/asm.tl: Load vm-param to get some fundamental constants. (small-op-p): New macro. (assembler parse-args, parse-compound-operand, parse-operand, operand-to-sym): Use constants. (enc-small-oip, small-op-to-sym): New macros. (op-frame asm): Use constants. Small range check problem fixed here: a frame level of 1 mustn't be allowed. (op-movrs, op-movsr, op-mov-pseudo, op-movsmi, op-movrbi, op-movi-pseudo, op-retsr, op-retrs, op-retrr, op-ret-pseudo, op-getv, op-setv): Deal with small operand via functions. (op-close): Use constants. Off-by-one problem: frame size of 256 must be allowed. * share/txr/stdlib/compiler.tl: Load vm-param to get constants. (compiler get-dreg, compiler get-funvec): Use constant for max frame size. (compiler new-env): Check for maximum levels being exceeded. (compiler comp-atom): Use constant for maximum immediate integer operand width. * share/txr/stdlib/vm-param.tl: New file. * vm.c (vm_insn_extra_dec_small): New macro. (VM_LEV_BITS, VM_LEV_MASK, VM_SM_LEV_BITS, VM_SM_LEV_MASK): New preprocessor constants. (vm_lev, vm_idx, vm_sm_lev, vm_sm_idx): New macros. (vm_get, vm_set): Use macros instead of literals. (vm_sm_get, vm_sm_set): New inline functions. (vm_movrs, vm_movsr, vm_movsmi, vm_retsr, vm_retrs, vm_abscsr, vm_get_binding, vm_bindv): Use vm_sm_get or vm_sm_set to access the display using the small operand. (vm_close): Use preprocessor symbols instead of hard-coded literals.
* compiler: lambda call to let optimization.Kaz Kylheku2018-04-152-6/+79
| | | | | | | | | | | | | | | | | | | Normalize ((lambda ...) args) to (call (lambda ...) args). Reduce (apply (lambda ...) args) and (call (lambda ...) args) to let (let (vars-inited-from-args ...) ...). * lisplib.c (error_set_entries): Autoload for new error functions lambda-too-many-args, lambda-too-few-args, lambda-short-apply-list. * share/txr/stdlib/compiler.tl (comp-fun-form): Restructure to recognize lambda and handle via comp-inline-lambda. (compiler comp-inline-lambda): New method. (lambda-apply-transform): New function. * share/txr/stdlib/error.tl (lambda-too-many-args, lambda-too-few-args, lambda-short-apply-list): New functions.
* compiler: use new parser for macro params.Kaz Kylheku2018-04-151-100/+80
| | | | | | * share/txr/stdlib/compiler.tl (expand-bind-mac-parse-params): Function removed. (expand-bind-mac-params): Use mac-param-parser struct.
* compiler: move lambda param parsing into struct.Kaz Kylheku2018-04-141-85/+116
| | | | | | | | * share/txr/stdlib/compiler.tl (param-parser-base, fun-param-parser, mac-param-parser): New structs. (compiler comp-lambda): Construct a fun-param-parser object using parameter syntax. Then just extract the parsed pieces for further processing.
* compiler: lambda: accurate determination of need-frame.Kaz Kylheku2018-04-141-3/+3
| | | | | | | | | | | | | * share/txr/stdlib/compiler.tl (comp-lambda): The local variable need-frame is supposed to indicate whether the lambda needs a frame for its arguments: i.e. whether it has any parameters. However the way it is calculated is poor: the fixed-pars list potentially includes the semicolon symbol : which separates the required parameters from optionals. Hence the parameter list syntax (:) will be treated as "needs frame", even though it denotes an empty parameter list, just like the syntax (). This slight flaw is now tightened up.
* compiler: bugfix: handle lambda call form.Kaz Kylheku2018-04-131-0/+2
| | | | | | | | | Looks like the compiler neglects to handle the syntax ((lambda (params ...) body ...) args ...). * share/txr/stdlib/compiler.tl (compiler compile): Check for a lambda expression in the car position of a form; if it's present then ((lambda ...) ...) -> (call (lambda ...) ...).
* compile-file: need endian mark in .tlo files.Kaz Kylheku2018-04-121-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | VM machine code is endian-specific: it consists of 32 bit instruction words which are 32 bit in the local byte order. Thus code assembled on a little-endian machine won't run on a big endian-machine, or vice versa: unless we identify the situation and byte-swap the code when we load it. * buf.c (buf_swap32): New function. * buf.h (buf_swap32): Declared. * parser.c (read_file_common): Decode the third element from the version: a Boolean indicating big endian, if true. If the object file's endian is opposite from our endian, then byte swap the code. * itypes.c (itypes_init): Oops, calculation of itypes_little_endian was broken due to classic C =/== typo. Luckily, nothing has used this flag so far; it's been waiting for this first use. I caught this due to testing on a PPC64 box. * share/txr/stdlib/compiler.tl (%big-endian%, %tlo-ver%): New variables. (usr:compile-file): The file version comes from %tlo-ver% now, which includes the big-endian flag.
* Version 191.txr-191Kaz Kylheku2018-04-101-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim, protsym.c: Regenerated.
* defpackage: bugfix: symbol clash.Kaz Kylheku2018-04-101-3/+3
| | | | | | | | * share/txr/stdlib/package.tl (defpackage): Now that library file are read in the sys package, this macro's name-str local variable is the same symbol as sys:name-str, the function it uses. They clash in the (op sys:name-str ...) syntax. Let's rename the local.
* compiler: implement with-compilation-unit macro.Kaz Kylheku2018-04-091-36/+46
| | | | | | | | | | | | * lisp.c (compiler_set_entries): Add with-compilation-unit to autoload symbols for compile module. * share/txr/stdlib/compiler.tl (usr:with-compilation-unit): New macro. (usr:compile-file): Use with-compilation-unit macro to dump warnings if a file is processed alone. * txr.1: Documented.
* compiler: record source loc when reading.Kaz Kylheku2018-04-091-0/+1
| | | | | | | * share/txr/stdlib/compiler.tl (usr:compile-file): Bind *rec-source-loc* to t, otherwise the read function doesn't record source loc info and we don't get warnings reported against line numbers in the processed source files.
* compiler: improve and & or.Kaz Kylheku2018-04-091-27/+30
| | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-and-or): Handle the trivial zero and one argument cases separately. In particular, the one-argument case results in better code because it eliminates a temporary register. We don't have to test for the zero-arg case any more in the general case, so it is simplified in a few cases.
* awk/struct: fix breakage under interpreted mode.Kaz Kylheku2018-04-092-8/+8
| | | | | | | | | | | | | | References to rslot must be usr:rslot because there is a sys:rslot. Some difference in loading order causes this not to be a problem when runing compiled "make tests", but if the .tlo files are removed, the awk test case fails. * share/txr/stdlib/awk.tl (sys:awk-mac-let): Replace rslot with usr:rslot. * share/txr/stdlib/struct.tl (rslot): Replace rslot symbol token with usr:rslot in definitions of rslot macro and rslot place macro.
* compiler: fix broken prog1.Kaz Kylheku2018-04-081-3/+3
| | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-prog1): The output of the frag should be fireg, not oreg. We need to move into fireg before re-frag.code is executed, because the data source in fi-frag may be clobbered by re-frag.
* trace: refer usr:catch operator rather than sys:catch.Kaz Kylheku2018-04-081-3/+3
| | | | | | * share/txr/stdlib/trace.tl (sys:trace, sys:untrace): Now that library code is being read in the sys package, catch refers to the sys:catch special form; we want the usr:catch macro here.
* trace: bugfix: redefine check mustn't throw exceptions.Kaz Kylheku2018-04-081-6/+10
| | | | | | | | | * share/txr/stdlib/trace.tl (sys:trace-canonicalize-name): Don't call static-slot-home on something that might not be a struct type symbol. Otherwise the trace module will throw whenever some lookup is performed for a non-existent method. That means that when trace is loaded, it is impossible to define a method with defun.
* compiler: fix overestimated register count.Kaz Kylheku2018-04-072-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The compiler internally allocates registers that are never inserted into code (but correctly recycled). Thus the treg bump counter overestimates the actual number of registers that a VM requires; but that's how we use it! That causes wasted stack space. What we can do to get a tightly clamped register count is simply to let the assembler report the highest-numbered treg operand that it finds in the code. (In the future we will need something better to optimize the register allocation. Why: because closures have their own VM instance with its own registers. If an overall VM uses registers t00 through t09, but a certain closure uses only t02 through t06, that closure's frame only needs to allocate seven registers.) * share/txr/stdlib/asm.tl (assembler): New slot, max-treg. (assembler parse-args): Whenever a register operand is parsed, if it is a t register, update max-treg. * share/txr/stdlib/compiler.tl (usr:compile-toplevel): When creating the vm-desc, determine the nreg parameter from the assembler's max-treg value, rather than from the compiler's treg allocation bump counter.
* new function: compile.Kaz Kylheku2018-04-071-0/+15
| | | | | | * lisplib.c (compiler_set_entries): Add compile to autoloads. * share/txr/stdlib/compiler.tl (usr:compile): New function.
* asm: support disassembly on functions.Kaz Kylheku2018-04-071-8/+19
| | | | | | | | | | * share/txr/stdlib/asm.tl (disassemble): Drop usr: prefix since symbol is interned already in usr package. Handle vm functions by obtaining their vm desc and entry point. Disassemble whole desc, then indicate entry point. The fallback case tries the object as a potential function name and recurses, so (disassemble '(meth struct slot)) and (disassemble 'name) will work.