summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* asm/vm: add ifq and ifql instructions.Kaz Kylheku2018-03-153-17/+64
| | | | | | | | | | * share/txr/stdlib/asm.tl (op-ifq, op-ifql): New opcode types. * vm.c (vm_ifq, vm_ifql): New static functions. (vm_execute): Handle IFQ and IFQL opcodes. * vmop.h (vm_op_t): Regenerated.
* structs: spurious hiding of defmeth: fix needed.Kaz Kylheku2018-03-141-1/+1
| | | | | | | | | | * eval.c (op_defun): There is a hidden reference to the sys:defmeth function here, which should have been updated in commit 0ae617f463290ff4463db2e479604808f940cc76 that renamed the function to define-method! Caught this by incidental code inspection, browsing through special forms in the context of working on the compiler.
* eval: remove eval_initing, which does nothing.Kaz Kylheku2018-03-141-11/+0
| | | | | | | | | | | None of the statements which are conditional on eval_initing are ever executed, because no code is interpreted during eval init time; all intrisinc functions are C functions defined using reg_fun. * eval.c (eval_initing): Global variable removed. (op_defun, op_defmacro, eval_init): References to eval_initing and code conditional on it are removed.
* push can safely use alet rather than rlet.Kaz Kylheku2018-03-141-1/+1
| | | | | | | | | | | push doesn't unconditionally require a temporary location for operational correctness; a temporary is used only for evaluation order. Therefore it is safe to use alet to eliminate the temporary when (after all expansion) the item is a trivial symbolic expression. * share/txr/stdlib/place.tl (push): Use alet to bind the temp which holds the new item.
* asm: block and catch need dest op constraint.Kaz Kylheku2018-03-141-2/+2
| | | | | | | * share/txr/stdlib/asm.tl (op-block, op-catch): Some operands that are destinations need to be parsed as "d", so the assembler diagnoses invalid destinations. Otherwise we don't catch the problem until VM run time.
* asm: wrong labels-outside-of-code test.Kaz Kylheku2018-03-141-1/+1
| | | | | | * share/txr/stdlib/asm.tl (assembler asm): Allow instruction 0 to have a label L labeled by checking for the range 0 <= L < N.
* vm: bugfix: handle empty data vector.Kaz Kylheku2018-03-141-1/+2
| | | | | | * vm.c (vm_make_desc): We can't call vecref_l on an empty vector, because it has no index zero. Let's use a null location in this case.
* asm: bugfix: correct value of (v x y) operands.Kaz Kylheku2018-03-141-1/+1
| | | | | | * share/txr/stdlib/asm.tl (parse-compound-operand): Add the forgotten increment by two to the level number of the v operand, since (v 0 n) is in the third display level.
* expander bug: sequential vars with no init forms.Kaz Kylheku2018-03-131-1/+2
| | | | | | | | | | | | | | | | The test case for this is (let* (a (b a))) which raises suspicion by diagnosing an "unbound variable a" error against the (b a) var-init pair. The error goes away if we make it (let* ((a nil) (b a))), a perfectly equivalent form. The diagnostic is just a symptom; the problem is that in the case when a doesn't have an initform, the (b a) var-init pair is being incorrectly expanded in an environment that hasn't been extended with the a variable. * eval.c (expand_vars): In the sequential binding situation (let*), we must extend the environment for each variable in the no-init-form case exactly as we do in the with-init-form case.
* higher level disassemble function.Kaz Kylheku2018-03-133-4/+32
| | | | | | | | | | | | | | | | * lisplib.c (asm_set_entries): Autoload on usr:disassemble. * share/txr/stdlib/asm.tl (assembler): Drop initializer from bstr slot. Requires complex initialization for the case when the buf is supplied by the constructor caller for the sake of disassembling existing code. (assembler :postinit): Handle cases when only one of buf or bstr are set, and when both are not set, for the greatest flexibility. (disassemble-c-d, disassemble): New functions. * vm.c (vm_desc_datavec): New static function. (vm_init): Registered vm-desc-datavec intrinsic.
* asm: no package qualifiers in textual disassembly.Kaz Kylheku2018-03-131-1/+1
| | | | | | | * share/txr/stdlib/asm.tl (assembler dis-listing): Use tostringp when converting the opcode and arguments to text, so package prefixes won't be shown when the current package isn't sys.
* asm: fix nonworking setv.Kaz Kylheku2018-03-131-2/+3
| | | | | | | * share/txr/stdlib/asm.tl (parse-args): Include the type spec in the diagnostic for invalid type spec. (op-setv): Fix use of invalid type spec s, which should be rs.
* regression: excess args not diagnosed.Kaz Kylheku2018-03-131-1/+1
| | | | | | | | | | | This was caused by the recent work to reduce consing in generic_funcall. * lib.c (generic_funcall): Correct test for too many arguments. Because we don't normalize the argument list to the exact number of fixed args, but to at least the fixed args, the excess args can possibly be part of the fill rather than part of the list.
* vm: rename vm-interpret-toplevel function.Kaz Kylheku2018-03-131-1/+1
| | | | | * vm.c (vm_init): Register vm_execute_toplevel as vm-execute-toplevel rather than vm-interpret-toplevel.
* asm: move method definitions outside defstruct.Kaz Kylheku2018-03-131-150/+150
| | | | | | * share/txr/stdlib/asm.tl (assembler): All :method definitions and the :postinit become defmeth forms outside of the defstruct.
* structs: spurious hiding of usr symbol by sys symbol.Kaz Kylheku2018-03-131-3/+3
| | | | | | | | * share/txr/stdlib/struct.tl (sys:defmeth): Rename function to sys:define-method. Otherwise it hides usr:defmethod when the current package is sys. (defmeth): Refer to sys:define-method rather than sys:defmeth.
* asm: allow compound syntax reg operands.Kaz Kylheku2018-03-121-0/+15
| | | | | | | | | | | | In additon to the encoded notation like t13 and v013f, we allow forms like (t 19) and (v 1 63) which mean the same thing. These are a much more convenient representation for a compiler. * share/txr/stdlib/asm.tl (assembler parse-operand): Recognize a compound expression as an operand, and handle via parse-compound-operand function. (parse-compound-operand): New function.
* asm: support gensym labels.Kaz Kylheku2018-03-121-4/+9
| | | | | | | | | | | Remove restriction that labels are keywords; a compiler cannot pollute the keyword space to generate labels. We allow them to be uninterned symbols also. * share/txr/stdlib/asm.tl (assembler parse-args, assembler asm-one): Use is-label instead of keywordp. (is-label): New function. (op-label): Use is-label test.
* vm: introduce sframe instruction.Kaz Kylheku2018-03-123-32/+48
| | | | | | | | | | | | | | | | | | | | This is for allocating a new frame purely on the stack. The frame will not be captured by lexical closures, and so can only be used for non-shared variables and additional compiler-generated temporaries (if registers run out, for instance). * share/txr/stdlib/asm.tl (op-sframe, sframe): New opcode class and opcode. * vm.c (vm_do_frame): New static function for the common implementation of frame and sframe. (vm_frame): Now just a call with vm_do_frame, passing the flag indicating that closure capture is enabled for this environment frame. (vm_sframe): New static function. * vmop.h: Regenerated.
* genvmop: fix broken script.Kaz Kylheku2018-03-121-1/+1
| | | | | | | | | | | | This broke when I moved asm.tl into the library directory and set it up for auto-load. * genvmop.txr: We must not include "asm" any more. But then there is no auto-load on any other feature of the assembler other than the class name. The @(mdo) directive comes in handy; at expansion time we can trigger auto-load by doing a lookup on the sys:assembler struct name.
* vm: use memcpy for copying environment.Kaz Kylheku2018-03-121-4/+2
| | | | | | * vm.c (vm_make_closure): When copying captured environment from stack to heap, use memcpy instead of a loop with assignments.
* unwind: better debugging of exceptions.Kaz Kylheku2018-03-121-0/+9
| | | | | | | | | | | | | | | Once upon a time when we didn't have continuable warning exceptions, it was easy to debug internal error throws in TXR: just set a breakpoint on uw_throw and catch it in the debugger. This approach became unworkable with uw_throw being executed numerous times as part of the ordinary program control flow. With this change, we get that debugging experience back. * unwind.c (uw_break_on_error): New static variable. (uw_throw): If the break-on-error variable is set and we are processing an exception derived from error, then call the breakpt function.
* New: virtual machine with assembler.Kaz Kylheku2018-03-1011-37/+1585
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit is the start of compiler work to make TXR Lisp execute faster. In six days of part time work, we now have a register-style virtual machine with 32 instructions, handling exceptions, unwind-protect, lexical closures, and global environment access/mutation. We have a complete assembler and disassembler for this machine. The assembler supports labels with forward referencing with backpatching, and features pseudo-ops: for instance the (mov ...) pseudo-instruction chooses one of three kinds of specific move instruction based on the operands. * Makelfile (OBJS): Add vm.o. * eval.c (lookup_sym_lisp1): Static function becomes external; the virtual machine needs to use this to support that style of lookup. * genvmop.txr: New file. This is the generator for the "vmop.h" header. * lib.c (func_vm): New function. (generic_funcall): Handle the FVM function type via new vm_execute_closure function. In the variadic case, we want to avoid the argument copying which we do for the sake of C functions that get their fixed arguments directly, and then just the trailing arguments. Thus the code is restructured a bit in order to switch twice on the function type. (init): Call vm_init. * lib.h (functype_t): New enum member FVM. (struct func): New member in the .f union: vm_desc. (func_vm): Declared. * lisplib.c (set_dlt_entries_impl): New static function, formed from set_dlt_entries. (set_dlt_entries): Reduced to wrapper for set_dlt_entries_impl, passing in the user package. (set_dlt_entries_sys): New static function: like set_dlt_entries but targetting the sys package. (asm_instantiate, asm_set_entries): New static functions. (lisplib_init): Auto-load the sys:assembler class. * share/txr/stdlib/asm.tl: New file. * vm.c, vm.h, vmop.h: New files.
* sys package fall back on usr.Kaz Kylheku2018-03-091-0/+2
| | | | | | | | | * lib.c (obj_init): Give the system package a fallback list consisting of one element: the user package. This will make it easier to develop some library features that have lots of internal symbols that ought to be hidden in the system package, without having to put sys: on everything. That code will just switch to the system package.
* packages: drop no-fallback-list interning restriction.Kaz Kylheku2018-03-092-44/+7
| | | | | | | | | | | | | Removing the restriction that qualified pkg:sym syntax may not cause interning to take place if pkg has a nonempty fallback list. This serves no purpose, only hindering the flexibility of the package system. * parser.y (sym_helper): When processing a qualified symbol, if the package exists, just intern it. * txr.1: Revise all text which touched on the removed rule, to remove all traces of it from the documentation.
* args: overhaul for clarity and reduced consing.Kaz Kylheku2018-03-096-34/+39
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * args.c (args_normalize): Renamed to args_normalize_exact, because this tries to split the arguments between an exact array fill quantity and trailing list. Not all places using this function actually need an exact fill, which causes unnecessary consing when args->fill is reduced in order to move items to args->list. (args_normalize_least): New function. Variant of args_normalize that can be used by functions which only require a minimum fill. (args_normalize_fill): Use args_normalize_least rather than args_normalize_exact. This reduces consing in generic_funcall, in handling variadic calls where arrayed arguments have been supplied for trailing parameters. * args.h (args_normalize): Renamed to args_normalize_exact. (args_normalize_least): Declared. (args_get_list, args_get_rest): Use args_normalize_exact. (args_clear): Inline function removed. Was used only in one place in generic_funcall and is no longer. * eval.c (gather_free_refs): Use args_normalize_least. (prod_common): Use args_normalize_exact. * ffi.c (ffi_call_wrap): Use args_normalize_least. * lib.c (generic_funcall): Use args_normalize_least in switch statement that handles various callable non-function objects. When copying args, ensure that there are ARGS_MIN. A different strategy is used for producing the trailing args for variadic calls, further reducing consing. Rather than normalize the args to the fixed number, and then set args->fill to zero so that args contains just the list, we use args_cat_zap_from to create a copy of the args in which the fixed ones are trimmed out. The resulting args is not renormalized to be purely a list so no consing or list traversal takes place. If the rebalancing is needed, the called function will have to do it. (dwim_set): Streamline the code that handles hashes assigned via two or three args. * struct.c (method_args_fun, umethod_args_fun): Use args_normalize_exact.
* bugfix: broken single-digit bignum multiplication.Kaz Kylheku2018-03-081-18/+9
| | | | | | | | | | | | * mpi/mpi.c (s_mp_mul_d): The test used for deciding whether or not the multiplication will carry, and possibly needs another digit of space, is broken. There are situations in which a carry occurs (k > 0) in spite of the test being negative. We code this the way it should have been done in the first place: resize the object when carry actually occurs. This still avoids calling s_mp_pad unless absolutely necessary, as the removed comment says. Also, in the carry case, we need not try to clamp away leading zeros.
* code review: switch case breaks.Kaz Kylheku2018-03-082-0/+4
| | | | | | | | | | * arith.c (c_unum): Add fallthrough comment. (minus): Add missing break after case that handles char minus heap object.. This luckily isn't a bug because type(anum) isn't RNG, and so when it falls through, the next case also falls through. * lib.c (car): Add missing fallthrough comment.
* New function: bignum-len.Kaz Kylheku2018-03-063-0/+46
| | | | | | | | | * arith.c (bignum_len): Wew function. (arith_init): Register bignum-len intrinsic. * arith.h (bignum_len): Declared. * txr.1: Documented.
* trace: bugfix in method redefinition check.Kaz Kylheku2018-03-011-2/+5
| | | | | | | | | | | | | | | If the trace module has been loaded, we can't define methods. Repro: 1> (trace) nil 2> (defmeth time foo (me)) ** static-slot-home: #<struct-type time> has no static slot named foo * struct.c (static_slot_ensure): Do the trace_check after calling static_slot_ens_rec so that the slot exists. If the slot doesn't exist, an exception occurs when sys:trace-canonicalize-name calls static-slot-home.
* bugfix: missing actions in reset-struct.Kaz Kylheku2018-02-282-1/+46
| | | | | | | | | | | | * struct.c (reset_struct): Perform the post-init actions are performed, not only the init actions. Also, catch exceptions and call finalizers, just like in a new structure instantiation. * txr.1: Document the requirements for finalizers being called by reset-struct, and clarify the issue of possible duplicate finalization registration. Add compat notes.
* bugfix: buf-get-* not allowing last byte of buffer.Kaz Kylheku2018-02-281-1/+1
| | | | | | | * buf.c (buf_get_bytes): Fix off-by-one test for reading past end of buffer. This prevents, e.g. a buf-get-u32 from the last four bytes of a buffer (or from a four-byte-long buffer, period).
* doc: wrong pluralizations of "function".Kaz Kylheku2018-02-271-3/+3
| | | | | | * txr.1: Fix three unrelated occurrences of the same mistake: "functions is", in reference to a single function.
* Require semicolon after static_{forward,def} macros.Kaz Kylheku2018-02-263-5/+5
| | | | | | | | | | | * lib.h (static_forward, static_def): At least the C version of these now require a trailing semicolon. * struct.c (struct_type_ops): Add required semicolon after static_def. * syslog.c (syslog_strm_ops): Add required semicolon after static_forward and after static_def.
* Version 190.txr-190Kaz Kylheku2018-02-187-1064/+1094
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim, protsym.c: Regenerated.
* New listener feature: greedy evaluation feature.Kaz Kylheku2018-02-174-2/+112
| | | | | | | | | | | | | | | | * eval.c (eval_intrinsic_noerr): New function. * eval.h (eval_intrinsic_noerr): Declared. * parser.c (listener_greedy_eval_s): New symbol variable. (repl): Implement greedy evaluation loop, enabled by the *listener-greedy-eval-p* special. (parse_init): Intern the *listener-greedy-eval-p* symbol, storing it in the listener_greedy_eval_s variable. Register the symbol as a special variable. * txr.1: Documented *listener-greedy-eval-p* variable and the greedy evaluation feature that it controls.
* Lisp load function supports .txr files.Kaz Kylheku2018-02-163-31/+108
| | | | | | | | | | | | * eval.c (load): Instead of throwing error when a .txr file is opened, process it according to sensible requirements. * match.c (v_load): Store bindings in the current environment frame before evaluating Lisp, and then update afterward. This allows .txr files loaded from Lisp to continue matching with the current bindings and extend those bindings. * txr.1: Update documentation of load.
* Eliminate always false expression.Kaz Kylheku2018-02-161-1/+1
| | | | | | * txr.c (txr_main): Since parser.errors being nonzero is handled earlier, it must be zero at the final return point and need not be tested.
* bugfix: broken expansion of sys:lisp1-setq places.Kaz Kylheku2018-02-151-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | This bug shows up as a spurious warning and incorrect expansion from a from like (do set [@1 x] y). In this situation, sys:lisp1-setq is involved in the assignment to the place denoted by @1, because of the way the do operator expands the (set [@1 x] y) expression. The @1 meta-variable is replaced by a gensym, but some intermediate expansion takes place in an environment which has no binding for the gensym, causing the place to be treated as if it were a global variable, using sys:lisp1-setq. The subsequent real expansion in the environment in which the gensym is now bound then calls upon the expansion of sys:lisp1-setq, which proceeds via the expand_lisp1_setq function. But now the variable has a lexical binding. This bug doesn't show up in ordinary expressions like (set [foo x] y) which is why it went undetected for a year. * eval.c (expand_lisp1_setq): Fix the missing symbol in the generated code for the case when the symbol has a lexical variable binding. We must emit (sys:setq <sym> <value>), not (sys:setq <new-value>).
* Copyright year bump 2018.Kaz Kylheku2018-02-15101-102/+102
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * LICENSE, LICENSE-CYG, METALICENSE, Makefile, args.c, args.h, arith.c, arith.h, buf.c, buf.h, cadr.c, cadr.h, combi.c, combi.h, configure, debug.c, debug.h, eval.c, eval.h, ffi.c, ffi.h, filter.c, filter.h, ftw.c, ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h, itypes.c, itypes.h, jmp.S, lib.c, lib.h, lisplib.c, lisplib.h, match.c, match.h, parser.c, parser.h, parser.l, parser.y, protsym.c, rand.c, rand.h, regex.c, regex.h, share/txr/stdlib/awk.tl, share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl, share/txr/stdlib/conv.tl, share/txr/stdlib/doloop.tl, share/txr/stdlib/error.tl, share/txr/stdlib/except.tl, share/txr/stdlib/ffi.tl, share/txr/stdlib/getopts.tl, share/txr/stdlib/getput.tl, share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl, share/txr/stdlib/keyparams.tl, share/txr/stdlib/op.tl, share/txr/stdlib/package.tl, share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl, share/txr/stdlib/pmac.tl, share/txr/stdlib/socket.tl, share/txr/stdlib/stream-wrap.tl, share/txr/stdlib/struct.tl, share/txr/stdlib/tagbody.tl, share/txr/stdlib/termios.tl, share/txr/stdlib/txr-case.tl, share/txr/stdlib/type.tl, share/txr/stdlib/with-resources.tl, share/txr/stdlib/with-stream.tl, share/txr/stdlib/yield.tl, signal.c, signal.h, socket.c, socket.h, stream.c, stream.h, struct.c, struct.h, strudel.c, strudel.h, sysif.c, sysif.h, syslog.c, syslog.h, termios.c, termios.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h, win/cleansvg.txr: Extended Copyright line to 2018.
* bugfix: op module inversely depends on sys:l1-val.Kaz Kylheku2018-02-142-24/+64
| | | | | | | | | | | | | | | | | | | The problem is that the lop macro in op.tl generates code that uses sys:l1-val. That requires the place.tl module. But there is no autoload trigger for sys:l1-val. Even if there were, it wouldn't work because op.tl is lower level w.r.t. place.tl; place.tl uses op.tl. Let's just rewrite sys:l1-val and sys:l1-setq in C, so they live in the run-time core. * eval.c (sys_l1_val_s, sys_l1_setq_s): New symbol variables. (me_l1_val, me_l1_setq): New static functions. (eval_init): Intern sys:l1-setq and sys:l1-val symbols, binding these to the macro expanding functions. * share/txr/stdlib/place.tl (sys:l1-setq, sys:l1-val): Macros removed.
* cleanup: harmonize lisp1-eval-related symbol variables.Kaz Kylheku2018-02-142-8/+8
| | | | | | | | | | | | | | * eval.c (sys_lisp1_value_s): Declaration moved to be collocated with lisp1_setq_s. (lisp1_setq_s): Variable renamed to sys_lisp1_setq_s to match sys_lisp1_value_s. (do_expand): Follow rename of lisp1_setq_s. (eval_init): Follow rename; collocate initialization of vars. * protsym.c (lisp1_setq_s): Manually renamed to sys_lisp1_setq_s instead of full regeneration, which we do at release time.
* doc: fix compat note 156, again.Kaz Kylheku2018-02-141-2/+4
| | | | | | * txr.1: Add missing text to compensate for text that was accidentally edited out, regarding the return value of the empty case of caseq/caseql/casequal.
* New listener variable: *listener-pprint-s*.Kaz Kylheku2018-02-122-1/+27
| | | | | | | | | | * parser.c (listener_pprint_s): New symbol variable. (repl): Check new variable after each evaluation and print accordingly. (parse_init): Initialize listener_print_s with interned symbol and register the variable. * txr.1: Document *listener-pprint-s*.
* bugfix: intern public symbols in autoload files.Kaz Kylheku2018-02-071-0/+29
| | | | | | | | | | | | | | | | | | | | | | | This commit addresses a bug of the following type: (defpackage p (:fallback usr)) (in-package p) (let ((lb (new list-builder))) lb.(add 1)) ;; problem: this add is p:add the add symbol is not on the auto-load list; it occurs as a slot of the list-builder class, but is not interned when TXR starts. Thus the (:fallback usr) doesn't pick it up. Expected behavior is that add is usr:add. * lisplib.c (intern_only): New static function. (sock_set_entries, build_set_entries, getopts_set_entries, stream_wrap_set_entries): Define additional lists of supplemenary symbols which are passed to intern_only just to be interned in the usr package without autoload registratiions. These symbols are all slots documented for public use in various structures defined by the respective modules managed by these autoload functions.
* Version 189.txr-189Kaz Kylheku2018-02-067-1006/+1041
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim, protsym.c: Regenerated.
* bugfix: don't record source loc of symbols and numbers.Kaz Kylheku2018-02-051-4/+22
| | | | | | | | | | | | | | | | | | This prevents a bug which manifests itself as a totally bogus file name and line number being reported in a diagnostic. The cause is that source loc info is recorded for an interned symbol when it is first encountered in one place in the code. Then that symbol occurs again in another place (perhaps a different file) in such a way that its source loc info is inherited into a surrounding generated form which now has incorrect source loc info: the location of the first occurrence of the symbol not of this form. Then when some error is reported against the form, the bogus source loc info is shown. * parser.y (rlviable): New static function. (rlset): Only record source loc for forms which satisfy rlviable.
* doc: write Equality Substitution section.Kaz Kylheku2018-02-051-0/+63
| | | | | | * txr.1: Several places in the document refer to a section called Equality Substitution which supposedly exists under the Structures section. As of now, it actually does!
* doc: clarify text under constantpKaz Kylheku2018-02-051-3/+3
| | | | | * txr.1: Restructure long sentence for readability, fixing awkward comma in the process.
* doc: more detail in ref/refset re: structs.Kaz Kylheku2018-01-311-5/+32
| | | | | | * txr.1: Describe fallback of ref and refset onto list-like operations if lambda/lambda-set are not supported.