| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
| |
On newer GNU Make versions, $(wildcard ...) doesn't sort
its results, and so we compile .tlo files in an
arbitrary order. For the most part, this is fine.
However, there is a complicated circular dependency involving
the error.tl file requiring it to be compiled first.
* Makefile (STLIB_EARLY_PATS, STDLIB_EARLY_TLOS,
STDLIB_LATE_TLOS): New variables. Use these
to express a dependency which causes error.tlo
to be built first.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* vm.c (vm_execute_toplevel): Fix data vector being assigned
to the wrong display frame, leaving vm.dspl[1].vec
uninitialized. Why is that a problem? Because the VM depends
on these vectors when performing the vm_set operation: if a
frame register is stored, and the frame has an associated
vector, mut_obj is invoked on that vector. Now that there
exists the load-time operator, the d regs (which live in
dspl[1]) can be mutated. That causes mut_obj to be called
with garbage. This was all discovered during testing on PPC64.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The vm_execute function is heavily inlined by gcc, and
requires almost 500 bytes of stack space. The stack space
really adds up when the vm re-enters itself recursively.
Also, pointers to garbage can hide in areas of that bloated
stack frame that are not being used by execution paths,
adding to the spurious retention problem.
* lib.h (NOINLINE): New preprocessor symbol.
* vm.c (vm_prof, vm_frame, vm_sframe, vm_dframe, vm_end,
vm_fin, vm_call, vm_apply, vm_gcall, vm_gapply, vm_movrs,
vm_movsr, vm_movrr, vm_movrsi, vm_movsmi, vm_movrbi, vm_if,
vm_ifq, vm_ifql, vm_swtch, vm_uwprot, vm_block,
vm_no_block_err, vm_retsr, vm_retrs, vm_retrr, vm_abscsr,
vm_catch, vm_handle, vm_getsym, vm_getbind, vm_setsym,
vm_bindv, vm_close, vm_execute): Apply INLINE to functions.
|
|
|
|
|
| |
* vm.c (vm_execute_closure): Null out the vargs local
to prevent spurious retention.
|
|
|
|
|
|
|
|
|
|
| |
Whe the compiler uses t-regs as function call arguments,
they are t-regs that have no next use and can be
nulled out. We do this to prevent false retention.
* vm.c (vm_getz): New function.
(vm_call, vm_apply, vm_gcall, vm_gapply): Use vm_getz for
fetching arguments.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With the advent of compiled code, problems are exposed
in the autoloader. We can no longer rely on the reference
to a macro to load a dependent module.
Macros go away during compiling, leaving behind functions.
References to those functions have to trigger autoloading.
* lisplib.c (place_set_entries): Add new table of sys:
functions, containing sys:get-fun-getter-setter, sys:get-mb,
sys:get-vb and sys:register-simple-accessor. These seem
to be all the macro run-time-support functions in place.tl.
(struct_set_entries): Add sys:rslotset.
(yield_set_entries): Add sys:obtain-impl.
(trace_set_entries): Add sys:trace and sys:untrace.
(keyparams_set_entries): Add sys:extract-keys.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
* share/txr/stdlib/compiler.tl (compiler): Remove the nreg
slot. It is not referenced anywhere.
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
| |
* share/txr/stdlib/compiler.tl (compiler get-dreg): A let*
with just one variable in it is changed to let.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim, protsym.c: Regenerated.
|
|
|
|
|
|
|
|
| |
* txr.1: Turn the comparison with lexical closures into a
named subsection instead of Notes. Add subsection about
mutated lexical variables and continuations: how the behavior
can differ between interpreted and compiled code. Point user
to the hlet and hlet* macros.
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a dotted form like (call x ... . z) is subject to the
dot-to-apply transformation, this results in
(apply (fun call) x ... . z). The (fun call) is useless
and can be removed. Therefore, what we do is remove
occurrences of call from the original form.
* eval.c (dot_to_apply): Remove leading occurrences of call.
Since this promotes the second or subsequent form into
the operator position, we must be careful; if we are
doing a Lisp-2 form, only the first element requires
wrapping in (fun ...) when turned into an apply argument.
The second and subsequent arguments are subject to ordinary
evaluation and so if any of those becomes the operator,
it doesn't need (fun ...) wrapping.
|
|
|
|
|
|
|
|
|
| |
* eval.c (apply_intrinsic): Function removed.
(to_apf): Use applyv instead of apply_intrinsic.
* eval.h (apply_intrinsic): Declaration removed.
* vm.c (vm_gapply): Use applyv instead of apply_intrinsic.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Now (pprof (apply '+ 1 2 3 4 5 '(6 7))) shows zero
bytes consed. Previously 176 (on 32 bit). This is
the same whether the expression is compiled or
interpreted.
* eval.c (applyv): Rewritten to efficiently manipulate the
args and call generic_funcall directly. The consing
funcction apply_intrinsic_frob_args is only used when
args contains a trailing list (args->list) and is only
used on that trailing list, not the entire arg list.
Also, changing the static function to external.
* eval.h (applyv): Declared.
* vm.c (vm_apply): Use applyv instead of wastefully
converting the arguments to a consed list and going through
apply_intrinsic.
|
|
|
|
|
|
|
|
| |
The <trailing-args> argument is required in apply and iapply;
and that is documented.
* eval.c (apply_intrinsic_frob_args): Check for args being
empty and throw.
|
|
|
|
|
|
|
|
|
| |
* 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) ...)).
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
* vm.c (vm_make_closure): When a display frame is captured by
a closure and moves into the heap object, the original should
be cleared to all nil values, otherwise it can cause spurious
retention of garbage.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
* vm.c (vm_opcode, vm_oparg): Unused macros removed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The GNU Bison parser has a GPL header in the parser skeleton
which gets copied to the generated parser. The GPL asserts
that the entire file falls under the GPL (but as a special
exception, it may be used in any manner whatsoever in a
program, as long as it isn't used as the skeleton of a parser
generator). The GPL assertion is false; the file is not
entirely derived from the skeleton but contains code directly
copied from parser.y, as well as tables generated from
parser.y's original grammar. Since we are definitely not using
this as a parser skeleton for a parser generator and are thus
allowed to do whatever we want such as compiling this into
proprietary object files, I'm removing the copyright header as
a build step. You never know; someone could package up a built
directory of TXR containing a Bison-generated y.tab.c, and
then it looks like there is a GPL-ed file in the project.
* Makefile (CM): New variable, needed for interpolating
literal commas into macro calls.
(BS_LIC_FROM, BS_LIC_TO): New variables.
(y.tab.c): Filter y.tab.c to remove GPL comment.
|
|
|
|
|
|
|
|
|
|
| |
* parser.y: Move the copyright comment header into the
%{ ... %} section so that it is copied to the generated
parser, rathe than stripped away by the generator. The
problem is that Bison adds a GPL header to the file wrongly
implying that the whole thing is under the GPL (with a special
exception). Without our copyright header there, it looks
as if the whole file is from Bison.
|
|
|
|
|
|
|
|
|
|
| |
* Makefile (SH): The $(1) macro argument is substituted into
a shell '...' quote. It may contain single quotes itself,
so these have to be mapped to the famous '\'' sequence.
Currently, only one SH call has '...' syntax in it: one
in the y.tab.c rule which calls sed -e '/yyparse/d'.
That works anyway, and the quotes could be removed from
it; but let's fix the SH macro.
|
|
|
|
|
|
| |
* parser.y (parse): Note the line number before parsing.
If the error seems to be bad termination, issue an extra
message indicating the starting line number of the form.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
* share/txr/stdlib/compiler.tl (expand-bind-mac-parse-params):
Function removed.
(expand-bind-mac-params): Use mac-param-parser struct.
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
| |
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 ...) ...).
|
|
|
|
|
|
|
|
| |
* eval.c (hash_min_max): New static function.
(me_case): Check for keys being all integers or all characters
in a dense range (> 75% full). Generate code for switching
directly on the displacement of the tested value into the key
range.
|
|
|
|
|
|
|
|
| |
* Makfile (%.tlo, %.tlo2): We take advantage of Gmake's
order-only prerequisites to express this dependency. This
means that .tlo and .tlo2 files are not considered outdated
when $(PROG) is newer; it only ensures that $(PROG) cannot
be missing when a .tlo or .tlo2 must be updated.
|
|
|
|
|
|
| |
* Makefile: add .NOTPARALLEL: special target.
This Makfile doesn't support parallel builds; it relies
on left-to-right execution of prerequisites in some places.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|