summaryrefslogtreecommitdiffstats
path: root/share
Commit message (Collapse)AuthorAgeFilesLines
...
* compiler: bugfix: scope of init-forms in lambda.Kaz Kylheku2018-03-311-1/+1
| | | | | | * share/txr/stdlib/compiler.tl (comp-lambda): The init-forms for optional parameters in a lambda must be compiled in the environment in which prior arguments are visible.
* compiler: change message for uhandled special op.Kaz Kylheku2018-03-291-1/+1
| | | | | | | * share/txr/stdlib/compiler.tl (compiler compile): All special forms are handled, so "not handled yet" wording is inappropriate. Going forward, no special form will be added without compiler support.
* compiler: improve register use when compiling calls.Kaz Kylheku2018-03-291-6/+11
| | | | | | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-call-impl): Instead of allocating N temporary registers for N arguments, some (or even none) of which may actually be used, we do this one argument at a time: allocate just one register, compile the argument expression, and then free the register immediately if that fragment specifies its own output location instead of the register. Otherwise keep the register and push it on a stack. This strategy lowers maximum register use. Also, since we are pushing the used registers on a stack, when we call free-tregs, they get liberated in reverse order of allocation, which keeps things tidy.
* compiler: enforce register balance.Kaz Kylheku2018-03-291-0/+7
| | | | | | | * share/txr/stdlib/compiler.tl (compiler check-treg-leak): New method. (usr:compile-toplevel): Free the top-level output register, then call check-treg-leak to verify all were returned.
* compiler: incorrect null destructuring pattern.Kaz Kylheku2018-03-291-2/+2
| | | | | | | * share/txr/stdlib/compiler.tl (expand-bind-mac-params): The listp function identifies a recursive parameter, not consp, because nil is an empty pattern, and not a variable name, in macro-style parameter lists.
* compiler: special case if + eq combo.Kaz Kylheku2018-03-281-6/+58
| | | | | | | | | | | | | | | | | We use the ifq instruction for compiling (if (eq x y) ...) and (if (neq x y ...) rather than emitting a call to eq or neq. * share/txr/stdlib/compiler.tl (%test-funs-pos%, %test-funs-neg%, %test-funs%, %test-inv%): New global %variables. (comp-if): Recognize when test expression is one of the tests in %test-funs% and transform into (sys:ift ...) syntax. Also, minor unrelated change here: (if test) optimized away to nil if test is a constant expression. (compiler comp-ift): New method. (compiler comp-fun-form): Recognize sys:ift in operator position; hand off to comp-ift.
* compiler: pass whole form to comp-fun-form.Kaz Kylheku2018-03-281-19/+20
| | | | | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Pass form to comp-fun-form rather than sym and (cdr form). (compile comp-fun-form): Take just a form argument. Internally destructure to sym and args with tree-bind. This will allow some special cases added in the future to have access to the original form.
* compiler: replace cond implementation.Kaz Kylheku2018-03-281-67/+10
| | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-cond): Replace pointlessly verbose cond implementation compact implementation that rewrites cond to combinations of if, progn and smaller cond. This generates pretty much the same code, and will automatically benefit from special case translations applied in if.
* compiler: move some lookup tables out of compiler struct.Kaz Kylheku2018-03-281-5/+7
| | | | | | | | * share/txr/stdlib/compiler.tl (compiler): Remove gcallop and callop static members. (%gcall-op%, %call-op%): New global variables. (compiler comp-fun-form): Use new globals instead of old static members.
* compiler: if: remove spurious instruction.Kaz Kylheku2018-03-281-2/+1
| | | | | | * share/txr/stdlib/compiler.tl (compiler comp-if): Remove a trailing maybe-mov from the instruction template that serves no purpose and can potentially generate an instruction.
* asm: use capital hex for dregs.Kaz Kylheku2018-03-281-1/+1
| | | | | | * share/txr/stdlib/asm.tl (disassemble-c-d): When printing the data table, use capital hexadecimal for the dregs, consistent with the instruction listing.
* compiler: bugfix in let.Kaz Kylheku2018-03-271-1/+2
| | | | | | | | | | | | | | | | | | | | | Very similar issue to the sys:fbind issue fixed some commits ago. When we are setting up parallel bindings, we don't want to compile initforms in the original env, because then they get the same frame level as the new env we are compiling. Thus (let ((x (let (...)))) ...) is mistranslated. Both lets, have environments which are siblings of the same parent env, which puts them on the same level. But their lifetimes at run-time are nested, so they cannot share the same level. The VM caught this since frame instructions declare their absolute level and it must be one higher than the current level. (I had the foresight to predict this might be a source of problems and put in the checks.) * share/txr/stdlib/compiler.tl (compiler comp-let): Same trick as in sys:fbind case: set up an empty environment above the initforms, so when an initform creates an environment, it is a granddaughter of env, and thus a niece rather than sister of of nenv, consequenty one frame level higher.
* compiler: don't wastefully enter into dreg table.Kaz Kylheku2018-03-271-0/+1
| | | | | | * share/txr/stdlib/compiler.tl (compiler get-dreg): If the input atom is nil, return the t0 register that always holds nil.
* compiler: diagnose exhaustion of dregs.Kaz Kylheku2018-03-271-4/+6
| | | | | * share/txr/stdlib/compiler.tl (compiler get-dreg): Restructure code. Don't increment dreg-cntr past 255.
* compiler: use counter instead of preallocating tregs.Kaz Kylheku2018-03-271-7/+7
| | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler): new slot, treg-cntr; slot nregs removed; tregs stack initialized to empty list. (compiler alloc-treg): Take from stack if possible, otherwise create new treg using counter, up to 255. (usr:compile-toplevel): Referenceco.treg-cntr for register count, rather than removed co.nreg.
* compiler: bugfix: register double free.Kaz Kylheku2018-03-271-1/+2
| | | | | | * share/txr/stdlib/compiler.tl (compiler comp-progn): Since oreg-discard is conditionally allocated, it must be only be freed if it had been allocated.
* compiler: implement prof special op.Kaz Kylheku2018-03-271-0/+10
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Handle prof via comp-prof method. (comp-prof): New method.
* vm/asm: new prof instruction.Kaz Kylheku2018-03-271-0/+2
| | | | | | | | | | * share/txr/stdlib/asm.tl (prof): New opcode. (op-prof): New opcode class. * vm.c (vm_prof_callback, vm_prof): New static functions. (vm_execute): Handle PROF opcode via vm_prof. * vmop.h: Regenerated.
* compiler: implement sys:switch special op.Kaz Kylheku2018-03-271-0/+32
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Handle sys:switch via comp-switch method. (comp-switch): New method.
* compiler: bugfix in sys:fbind op.Kaz Kylheku2018-03-271-1/+2
| | | | | | | | | | | | When a (flet ...) form is compiled, the function arguments of the lambda are being bound in the same frame and clashing against the variables being bound by the construct. * share/txr/stdlib/compiler.tl (compiler comp-fbind): For the non-recursive case, insert the dummy empty environment eenv, and compile the forms in that environment. This raises them up to the appropriate display level without affecting what is visible in their scope.
* compiler: recognize call and apply forms.Kaz Kylheku2018-03-271-11/+23
| | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler): New slots, gcallop and callop. (compiler comp-fun-form): Restructured to handle apply and call forms, turning them into better code, exploiting the call, gcall, apply and gapply instructions. (compiler comp-call): Take opcode argument so apply calls can be handled.
* regression: fix broken tagbody.Kaz Kylheku2018-03-261-19/+5
| | | | | | | | | | | | | | | | | | | | | | | | | commit 87caead8269055b4791de53be0e03afab01f1dd4, subject "macros: expand declined form in outer env" broke tagbody. The tagbody implementation uses a dubious trick of setting up local macros which return the original form, as a way of prevening an outer scoped macro from expanding the form. The above commit specifically changes the behavior in such a way that this strategy is nullified. However, the macro fallback feature introduced by the above commit is exactly what tagbody needs! * share/txr/stdlib/tagbody.tl (tagbody): Simplify the treatment of (go label) thanks to new behavior in macro expander. We no longer need an extra sys:expand pass to allow inner tagbodies to expand their go forms, and intercept any unexpanded ones. We have a simple go macrolet which performs the expansiion when the label is recognized, or else returns the form to decline expansion. The macro expander will then fall back by trying the macro in the next outer scope. Thus, every (go label) is resolved in the tagbody to which label belongs, or else lands into the top-level go macro which diagnoses undefined labels.
* compiler: implement sys:catch special op.Kaz Kylheku2018-03-261-0/+46
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Handle sys:catch via comp-catch method. (comp-catch): New method.
* vm/asm: new swtch instruction.Kaz Kylheku2018-03-261-0/+40
| | | | | | | | | | | | | * share/txr/stdlib/asm.tl (backpatch-low16, backpatch-high16): New struct types. (%backpatch-low16%, %backpatch-high16%): New global variables. (swtch): New opcode. (op-swtch): New opcode class. * vm.c (vm_swtch): New static function. (vm_execute): Handle SWTCH opcode via vm_swtch. * vmop.h: Regenerated.
* compiler: implement handler-bind special op.Kaz Kylheku2018-03-261-0/+14
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Handle defmacro via comp-handler-bind method. (comp-handler-bind): New method.
* compiler/vm: implement sys:abscond-from special form.Kaz Kylheku2018-03-262-2/+5
| | | | | | | | | | | | | | | * share/txr/stdlib/asm.tl (abscsr): New instruction. (op-abscsr): New opcode class, derived from op-retsr. * share/txr/stdlib/compiler.tl: Handle sys:abscond-from via comp-return-from method. (compiler comp-return-from): Handle sys:abscond-from by switching to abscsr opcode instead of ret pseudo-op. * vm.c (vm_abscsr): New static function. (vm_execute): Dispatch ABSCSR opcode. * vmop.h: Regenerated.
* compiler: implement block* special form.Kaz Kylheku2018-03-261-3/+6
| | | | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Route block* to same helper method as block. (compiler comp-block): Handle block* also by compiling the name form and using the resulting value as the name operand in the block instruction.
* compiler: implement defsymacro special op.Kaz Kylheku2018-03-251-0/+5
| | | | | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Handle defsymacro via expand-defsymacro expander. (expand-defsymacro): New function. * eval.c (rt_defsymacro): New static function. (eval_init): register sys:rt-defsymacro intrinsic.
* compiler: implement defmacro special op.Kaz Kylheku2018-03-251-0/+14
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Handle defmacro via expand-defmacro expander. (expand-defmacro): New function.
* compiler: implement defun special op.Kaz Kylheku2018-03-251-0/+20
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Handle defun via expand-defun expander. (expand-defun): New function.
* compiler: implement defvarl special op.Kaz Kylheku2018-03-251-0/+9
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Handle defvarl via expand-defvarl expander. (expand-defvarl): New function.
* compiler: implement sys:setqf special op.Kaz Kylheku2018-03-241-0/+17
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Handle sys:setqf via comp-setqf. (compiler comp-setqf): New method.
* compiler: setq bug: wrong return for globals.Kaz Kylheku2018-03-251-2/+2
| | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-setq): The output register of the returned frag must be that of the value calculating frag, not vloc, because in the dynamic variable case, vloc holds the d-reg with the variable's name, not the v-reg that receives its value. (compiler compl-lisp1-setq): Fix same bug which got propagated by copy-and-paste coding.
* compiler: implement sys:lisp1-setq special op.Kaz Kylheku2018-03-241-0/+17
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Handle sys:lisp1-setq via comp-lisp1-setq. (compiler comp-lisp1-setq): New method.
* compiler: implement dwim special op.Kaz Kylheku2018-03-241-0/+7
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Handle dwim case via comp-dwim. (compiler comp-dwim): New method.
* compiler: implement sys:lisp1-value special formKaz Kylheku2018-03-241-3/+31
| | | | | | | | | | | | * share/txr/stdlib/compiler.tl (vbinding, fbinding): New structs subtyping binding. (sys:env lookup-lisp1): New method. (sys:env extend-var, sys:env extend-var*, sys:env extend-fun): Instantiate a vbinding or fbinding as appropriate. This lets us tell whether we have a function or variable binding after doing a successful lookup-lisp1. (compiler compile): Add sys:lisp1-value case. (compiler comp-lisp1-value): New method.
* compiler: specially compile (call ...) forms.Kaz Kylheku2018-03-241-1/+13
| | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-fun-form): Add a caseq form to handle certain top-level functions specially. Add a case for the call function, handled by comp-call. (compiler comp-call): New method.
* compiler: rename comp-call.Kaz Kylheku2018-03-241-2/+2
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Call comp-fun-form instead of comp-call. (compiler comp-call): Rename to comp-fun-form.
* compiler: implement fun special formKaz Kylheku2018-03-241-0/+8
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Route fun to comp-fun. (compiler comp-fun): New method.
* compiler: add fbind and lbind special formsKaz Kylheku2018-03-241-0/+32
| | | | | | | | This supports labels and flet. * share/txr/stdlib/compiler.tl (compiler compile): Route fbind and lbind to comp-fbind method. (compiler comp-fbind): New method.
* compiler: fix wrong frame level in lexical functions.Kaz Kylheku2018-03-241-1/+1
| | | | | | * share/txr/stdlib/compiler.tl (sys:env extend-fun): The v register's level is two less than the frame level. Add missing ppred call; extend-var has it already.
* compiler: fix lexical function call.Kaz Kylheku2018-03-241-2/+2
| | | | | * share/txr/stdlib/compiler.tl (compiler comp-call): Pass the location, not the binding itself, to comp-call-impl.
* compiler: implement unwind-protect.Kaz Kylheku2018-03-241-0/+25
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Wire in unwind-protect case via comp-unwind-protect method. (compiler comp-unwind-protect): New method.
* compiler: implement mac-param-bind.Kaz Kylheku2018-03-241-0/+12
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Wire in tree-bind case via comp-mac-param-bind method. (compiler comp-mac-param-bind): New method.
* compiler: hoist quoting out of bind expander.Kaz Kylheku2018-03-231-8/+12
| | | | | | | | | | | * share/txr/stdlib/compiler.tl (expand-bind-mac-params): Take the context form and error forms as separate arguments instead of calculating one from the other. Moreover, they are no longer assumed to be objects to be quoted and inserted but rather expressions to be substituted into the code directly. This gives the caller flexibility to make them calculated. (compiler comp-tree-bind, compiler comp-tree-case): Make the compensating adjustments to preserve the behavior.
* asm: report instruction count in disassembly.Kaz Kylheku2018-03-231-2/+7
| | | | | | * share/txr/stdlib/asm.tl (assembler dis-listing): Return the number of instructions that were traversed. (disassemble-c-d): Print count after instruction listing.
* tree-bind et al: don't retain full form for errors.Kaz Kylheku2018-03-231-2/+3
| | | | | | | | | * share/txr/stdlib/compiler.tl (expand-bind-mac-params): We don't need the full form for error reporting, because only the leading symbol is reported in diagnostics. We do need the full form if the :form parameter is used. If :form is not used, then a compiled function need not carry the entire form in its data table.
* compiler: avoid using var symbol.Kaz Kylheku2018-03-231-5/+5
| | | | | | | | | var is sys:var when we're working in the system package. This sometimes confuses the code walker, because (sys:var X) is the implementation of the @X notation. * share/txr/stdlib/compiler.tl (expand-bind-mac-params): Use sym instead of var.
* compiler: constant-optimize prog1Kaz Kylheku2018-03-231-1/+2
| | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-prog1): prog1 already uses progn. When using progn, though, it should append the nil form to the tail, otherwise progn will spare the last from from being eliminated, leaving an unused constant in the data table.
* compiler: basic optimization in progn.Kaz Kylheku2018-03-231-2/+6
| | | | | | * share/txr/stdlib/compiler.tl (compiler comp-progn): Eliminate any form which is a constant or a symbol, unless it appears in the last position.