| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
| |
* txr.1: It's a developer surprise that (flow x) returns
nil rather than x; which is due to the documented behavior
of chain, when it has no arguments. Let's add cautionary
notes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date. Also mention that separator
commas in integer tokens are new in 283 and have a different
interpretation in older versions.
* txr.vim, tl.vim: Regenerated.
* protsym.c: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The reason is that args_decl_list places struct args
inside a larger struct, where it is followed by another
member. A struct with a flexible array being other than
the last member of another struct is a GNU extension,
which generates warnings on newer GCC versions.
* args.h (struct args): Define arg as array of [1]
rather than [FLEX_ARRAY].
(ARGS_ABS_MIN): Unconditionally define as 1.
(args_decl_list): Subtract 1 from N because we get
one element from struct args. This macro should have
subtracted the FLEX_ARRAY value.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* args.h (args_decl_list): This macro now handles only
constant values of N. It declares an anonyous container
struct type which juxtaposes the struc args header
with exactly N values. This is simply defined as a local
variable without alloca.
(args_decl_constsize): Like args_decl, but requiring a
constant N; implemented via args_decl_list.
(args_decl_list_dyn): New name for the old args_decl_list
which calls alloca. No places in the code depend on this
at all, except the definition of args_decl.
(args_decl): Retargeted to args_decl_list_dyn.
There is some inconsistency in the macro naming in that
args_decl_constsize depends on args_decl_list, and
args_decl depends on arg_decl_list_dyn. This was done
to minimize diffs. Most direct uses of args_decl_list
have a constant size, but a large number of args_decl
uses do not have a constant size.
* eval.c (op_catch): Use args_decl_constsize.
* ffi.c (ffi_struct_in, ffi_struct_get, union_out):
Likewise.
* ftw.c (ftw_callback): Likewise.
* lib.c (funcall, funcall1, funcall2, funcall3,
funcall4, uniq, relate): Likewise.
* socket.c (sockaddr_in_unpack, sockaddr_in6_unpack,
sockaddr_un_unpack):
Likewise.
* stream.c (formatv): Likewise.
* struct.c (struct_from_plist, struct_from_args,
make_struct_lit): Likewise.
* sysif.c (termios_unpack): Likewise.
* time.c (broken_time_struct): Likewise.
|
|
|
|
|
|
|
| |
* lib.c (funcall, funcall1, funcall2, funcall3,
funcall4): Handle FVM case separately, regardless
of the f.variadic flag. If the VM function is
variadic, the call can still use the special cases.
|
|
|
|
|
|
| |
* lib.c (funcall, funcall1, funcall2, funcall3,
funcall4): Handle some situations when the function
is a built-in with optional args.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (funcall, funcall1, funcall2, funcall3, funcall4):
Do not go through the generic_funcall slow path just
because the target function has optional arguments.
It's possible that the call is supplying all of the
required arguments. Let's try it like that and then
if it doesn't work and there are optionals, check again
and go the generic_funcall route. This might not be
an overall improvement by itself, if we end up going
to generic_funcall in more cases than not. However, this
change paves the way for more changes: handling some cases
of optargs in these helpers.
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/struct.tl (macroexpand-struct-clause): New function.
* autoload.c (struct_set_entries): Autoload struct module
on macroexpand-struct-clause.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/match.tl (macroexpand-match): New function.
* autoload.c (match_set_entries): Autoload match
module on macroexpand-match.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/place.tl (sys:pl-expand): Function renamed to
macroexpand-place; env parameter becomes optional.
(macroexpand-1-place): New function.
(place-form-p, call-update-expander, call-clobber-expander,
call-delete-expander): Follow rename.
* autoload.c (place_set_entries): Register symbols
macroexpand-place and macroexpand-1-place for autoload.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/pmac.tl (macroexpand-params): New function,
implemented using newly exposed sys:expand-param-macro.
* autoload.c (pmac_set_entries): Trigger pmac.tl autload
on macroexpand-params symbol.
* eval.c (eval_init): Register existing expand_param_macro
function as sys:expand-param-macro.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
| |
* txr.1: Fix formatting issue with .IP headings; add more
examples showing (. arg) notation, use of : argument for
requesting defaulting, and demonstration of presence-indicating
variables.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/struct.tl (:delegate): Handle the two-element
form of the optional parameter, which specifies the
usual initializing expression for the default value.
This is just passed through as-is to the generated
method. Diagnose if the three-element form occurs.
* tests/012/oop.tl: Some new tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stream.c (standard_k, print_json_format_s):
New symbol variables.
(stream_init): New variables initialized.
* stream.h (enum json_fmt): New enum.
(standard_k, print_json_format_s): Declared.
* lib.c (out_json_rec): Take enum json_fmt param,
and pass it recursively. Printing for vector and
dictionaries reacts to argument value.
(out_json, put_json): Examine value of special
var *print-json-format* and calculate enum json_fmt
value from this. Pass to out_json_rec.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
| |
* stream.c (inc_indent_abs): New function.
(stream_init): inc-init-abs intrinsic registered.
* stream.h (inc_indent_abs): Declared.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The following situation is observed in the listener.
1> (put-json #H(() (a 1)))
{** print: invalid object a in JSON
** during evaluation at expr-1:1 of form (put-json #H(() (a 1)))
1>
1>
An indent established in the aborted JSON print job
has been left in the stream.
* lib.c (put_json): Save the indent value also, not
only the mode. Restore the indent mode and value
on unwinding, not just on a normal exit from out_json_rec,
similiarly to what obj_print does.
|
|
|
|
| |
* stdlib/quips.tl (%quips%): New entry.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Research indicates that this is something useful in
languages that abuse strings for implementing symbols.
We have interned symbols.
* lib.h (struct string): Remove hash member.
* lib.c (string_own, string, string_utf8, mkustring,
string_extend, replace_str, chr_str_set): Remove
all initializations and updates of the removed
hash member.
* hash.c (equal_hash): Do not cache string hash value.
|
|
|
|
| |
* txr.1: Revise text, fixing a grammar error.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This relates to the November 2021 commit
9108e9f8f4434fb29200b08a4b576df47c407c01:
hash: 64 bit string and buffer hashing and seeds.
In the hash constructor, a 32 bit cast was left
behind, needlessly reducing the seed value to 32
bits on 64 bit platforms.
* hash.c (do_make_hash): Don't convert the ucnum
value to u32_t; just store it.
|
|
|
|
|
|
| |
* txr.1: Document that hash-eql and hash-equal
return a value in the range fixnum-min to
fixnum-max.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
On platforms which have the malloc_usable_size function,
we don't have to store the allocated size of an object;
malloc provides us the allocated size (which may be larger
than we requested). Here we take advantage of this for
strings. And since we don't have to store the string
allocated size any more, we use that field for something
else: storing the hash code (for seed zero). This can speed
up some hashing operations.
* configure (have_malloc_usable_size): New variable.
Configure test for have_malloc_usable size. We have to
try several header files, too. We set the configure
variable HAVE_MALLOC_USABLE_SIZE, and possibly
HAVE_MALLOC_H or HAVE_MALLOC_NP_H.
* lib.h (struct string): If HAVE_MALLOC_USABLE_SIZE
is true, we define a member called hash insetad of
alloc. Also, we change alloc to cnum.
* lib.c: Include <malloc_np.h> if HAVE_MALLOC_NP_H
is defined.
(string_own, string, string_utf8, mkstring, mkustring,
init_str, string_extend, string_finish, string_set_code,
string_get_code, length_str, replace_str, chr_str_set):
Fix code for both cases. On platforms with malloc_usable_size,
we have the allocated size from malloc, so we don't have to
retrieve it from the object or store it. Any operations which
mutate the string must reset the hash field to zero; zero
means "hash has not been calculated".
* hash.c (equal_hash): Just retrive a string's hash value, if
it is nonzero, otherwise calculate, cache it and return it.
* gc.c (mark_obj): The alloc member of struct string is a
machine integer now; no need to mark it.
|
|
|
|
|
|
|
| |
* txr.1: Syntax markup for file-get-buf, :mass-delegate
and file-open options contains an extra space. This causes
the syntax not to be correctly processed for the HTML
version. nroff-based man page rendering and pdf are fine.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* parser.l (remove_char): New static function.
(DIGSEP, XDIGSEP, NUMSEP, FLOSEP, XNUMSEP, ONUMSEP,
BNUMSEP, ONUM, BNUM): New named lex patterns.
(FLODOT): Use DIGSEP instead of DIG.
(ONUM): Use ODIG instead of [0-7].
(BNUM): Use BDIG instead of [0-1].
(grammar): New rule for producing NUMBER from decimal
token with commas based on BNUMSEP instead of BNUM.
This is a copy and paste so that the BNUM rule doesn't
deal with the comma removal, not to slow it down.
For the octal, binary and hex, we just switch to
BNUMSEP, ONUMSEP and XNUMSEP, so they all go through
one case.
Floating point numbers are also handled with a copy
pasted case using FLOSEP.
* tests/012/syntax.tl: New test cases.
* txr.1: Documented.
* genvim.txr (alpha-noe, digsep, hexsep, octsep, binsep): New
variables.
(txr_pnum, txr_xnum, txr_onum, txr_bnum, txr_num): Integrate
separating commas. Some bugs fixed in txr_num, some simplifications,
better txr_badnum pattern.
* lex.yy.c.shipped: Updated.
|
|
|
|
| |
* tets/012/oop-dsc.tl: New file.
|
|
|
|
|
|
|
|
| |
* stdlib/struct.tl (defstruct): Don't generate a separate finalizer
registration for each :fini or :postfini; roll them into a single
lambda in the correct order. Their object argument turns into a
let block around each piece of code to bind that argument, like
had been done for :init and :postinit.
|
|
|
|
|
|
|
|
| |
* stdlib/struct.tl (defstruct): When an :init, :fini,
:postinit or :postfini has an empty body, do not push
it onto its corresponding list. Then later we don't
have to check for empty items when generating the code;
we know only non-empty items are on the lists.
|
|
|
|
|
|
|
| |
* stdlib/struct.tl (define-struct-clause): Disallow
the :postfini keyword as clause name.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The motivation is that struct clause macros defined
using define-struct-clause may want to introduce
their own initializers and finalizers for the specific
stuff they add to the struct. The uniqueness restrictions
on these initializing and finalizing clauses makes
it impossible to use two clause macros which both want
to inject a definition of the same initializer or finalizer
type.
* stdlib/struct.tl (defstruct): Don't enforce that there
be at most one clause in the category of :init,
:postinit, :fini or :postini. Multiple are allowed.
They all execute left-to-right except for :fini.
* tests/012/fini.tl: New tests.
* tests/012/fini.expected: Updated.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (pct_fun_s): New symbol variable, holding
the usr:%fun% symbol.
(fun_macro_env): New static function.
(do_expand): For defun and defmacro, use fun_macro_env
to establish an environment binding the %fun% symbol
macro, and expand everything in that environment.
(eval_init): Intern the %fun% symbol, initializing
pct_fun_s, and also register a global symbol macro in
that name so that we can freely use %fun% everywhere
without worrying that the code will blow up.
E.g. a logging macro can use it to get the function name,
but still be useful in a top-level form outside of
a named function.
* stdlib/struct.tl (sys:meth-lambda): New macro.
(defstruct, defmeth): Use sys:meth-lambda as a replacement
for lambda to set up the %fun% symbol macro. In the :init
case which doesn't use a lambda, an open-coded symacrolet
does the job.
* tests/019/pct-fun.tl: New file.
* tests/019/pct-fun.expected: Likewise.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* socket.c (sock_set_entries): Intern str-addr symbol.
There is no autoload on this because the struct types of
which this is a method don't exist if the socket
module has not been loaded.
* stdlib/socket.tl ((sockaddr-in str-addr), (sockaddr-in6
str-addr), (sockaddr-un str-addr)): New methods.
* tests/014/str-addr.tl: New file. This provides
coverage not just for the str-addr method, but the
hitherto untested address to text functions.
This is why the bug was found, that was addressed
in the previous commit. The test case which produces
"8000::1" was actually producing "800:1".
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/socket.c (sys:in6addr-condensed-text): The
regular expression used in calculating zr is incorrect;
the zero in it can match the trailing zero of
a nonzero quad, when the intent is only to match
zero quads. Hack: we represent zero quads by the
character Z and use that for the matching and removal
of the longest range of zero quads. Then we filter
the Z back to 0.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This function "intelligently" constructs an
address object of the right type from a string.
* socket.c (sock_set_entries): Autoload socket.tl
on sockaddr-str function being accessed.
* stdlib/socket.tl (sockaddr-str): New function.
* tests/014/sockaddr-str.tl: New file.
* txr.1: Documented.
* stdlib.doc-syms.tl: Updated.
|
|
|
|
|
| |
* txr.1: describe equote as occuping a semantic midpoint
between full and quoting, rather than being "mongrel".
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The :postfini clause registers a finalizer that runs in the
ordinary order: after previously registered ones. This has
the effect of allowing a derived structure to run clean-up
actions after those of inherited structures. Either order
can be useful because the dependencies between base and
derived can go in either direction. It's a huge mistake in
C++ that it supports only derived-first destructor invocation
order.
* stdlib/struct.tl (defstruct): Recognize and translate
:postfini clause. It's exactly like :fini but omits the
t parameter in the finalize call, registering in the
natural order.
* tests/012/fini.tl (derived): Add :postfini handler.
* tests/012/fini.expected: Updated to reflect the messages
coming from the postfini handler, which are happening
in the correct order.
* txr.1: Documented.
|
|
|
|
|
|
| |
* ffi.c (make_ffi_type_struct): Change uint to unsigned.
This is a typo, but a uint type is coming from somewhere.
I discovered this in an environment where there is no uint.
|
|
|
|
|
|
|
| |
* configure: when the compiler is not found to be sane, we
used to print the errors. But in a 2014 commit, the stray
line "conftest && true" was left behind, whose termination
status is false, and which thus causes an exit.
|
|
|
|
|
|
|
|
|
| |
* configure: the reconfigure script is generated twice; once
before going through the configuration, with a notice
indicating configuration did not complete, and then again
after configuration. The first instance is missing the "$@"
argument, preventing ./reconfigure being used with arguments
after an interrupted configure run.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We strip Android's pointer tag from our heap
pointer while we own it, then put it back at
free time.
* configure (android_target): New variable.
Set this to y in the test where we detect Android.
When setting CONFIG_NAN_BOXING, also set
CONFIG_NAN_BOXING_STRIP_TAG if on Android.
* gc.c (struct heap): New member, tag.
(more): When tag stripping is enabled, clear the
top 16 bits of the pointer coming from malloc,
and keep those bits in heap->tag. This gets rid
of Android's tag.
(sweep): When releasing a heap block with free,
we must put the tag back into the pointer, from
heap->tag.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
| |
* configure: automatically select NaN boxing
on 64 bit platforms.
|
|
|
|
|
|
|
|
|
|
| |
gcc 12.2.0, targetting RISC-V, emitted a warning for
the c_f function that the &u expression uses an
uninitialized u, even though u is declared with an
initializer. Code builds otherwise and tests pass.
* lib.h (c_f): Also suppress and re-enable
the -Wuninitialized option.
|
|
|
|
|
|
|
| |
* txr.1: In the Numbers section, talk about fixnum and
bignum, and the boxed/unboxed terminology, as well as
the possibility that floating-point may be unboxed,
and how to detect that.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Older GCC 4.x versions do not support diagnostic pragmas
in functions and don't have push pragmas for diagnostics.
* arith.c (flo): Put the diagnostic disabling pragma stuff
outside of the function. Instead saving and restoring
the status with push and pop, we just disable the aliasing
warning and re-instate it as a warning.
* lib.h (c_f): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (seq_iter_get_range_bignum): Static function
renamed to seq_iter_get_range_number because it
in fact generalizes to numbers.
(seq_iter_peek_range_bignum): Renamed to
seq_iter_peek_range_number.
(seq_iter_get_rev_range_bignum): Renamed to
seq_iter_get_rev_range_number.
(seq_iter_peek_rev_range_bignum): Renamed to
seq_iter_peek_rev_range_number.
(si_range_bignum_ops): Renamed to si_range_number_ops.
(si_rev_range_bignum_ops): Renamed to
si_rev_range_number_ops.
(seq_iter_init_with_info): Handle ranges where
the from value is floating-point.
Also, if the from-value is bignum that fits into
cnum range, we now try to handle that as a cnum
range.
* tests/012/iter.tl: New tests.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The bad situation reproduced as a miscompilation of some prof
forms at *opt-level* 5 or above.
The basic idea is that there is a situation like this
prof t2
... profiled code here producing value in t8
mov t2 t8
end t2
end t2
The code block produces a value in t8, which is copied into
t2, and executes the end instruction. This instruction does not
fall through to the next one but passes control back to the
prof instruction. The prof instruction then stores the result
value, which came from t2, back into the t2 register and
resumes the program at the end t2.
The first bad thing that happens is that the end instructions
get merged together into one basic block. The optimizer then
treats them without regard for the prof instruction, as if
they were a linear sequence. It looks like the register move
mov t2 t8
is wasteful and so it eliminates it, rewriting the end instruction
to:
end t8
end t8
Of course, the second instruction is now wrong because prof is
still producing the result in t2.
To fix this without changing the instruction set, I'm introducing
another pseudo-op that represents end, called xend. This is
similar to jend, except that jend is regarded as an unconditional
branch whereas xend isn't. The special thing about xend is
that a basic block in which it occcurs is marked as non-joinable.
It will not be joined with the following basic block.
* stdlib/asm.tl (xend): New alias opcode for end.
* stdlib/compiler.tl (comp-prof): Use xend to end prof fragment,
rather than plain end.
* stdlib/optimize.tl (basic-block): New slot, nojoin.
If true, block cannot be joined with next one.
(basic-blocks jump-ops): Add xend to list of jump ops,
so that a basic block will terminate on xend.
(basic-blocks link-graph): Set the nojoin flag on a
basic block which contains (and thus ends with) xend.
(basic-blocks local-liveness): Add xend to the case
in def-ref that handles end.
(basic-blocks (peephole, join-blocks)): Refuse to join
blocks marked nojoin.
* tests/019/comp-bugs.tl: New file with miscompiled
test case that was returning 42 instead of (42 0 0 0)
as a result of the wrong register's value being returned.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The scoping is not behind handled correctly for optional
variables. The init-forms are being evaluated in a scope
in which all the variables are already visible, instead
of sequentially. Thus, for instance, variable rebinding
doesn't work, as in (lambda (: (x x)) ...). When the
argument is missing, x ends up with the value : because
the expression refers to the new x, rather than the
outer x.
* stdlib/compiler.tl (compiler comp-lambda-impl):
Perform the compilation of the init-forms earlier.
Use the same new trick that is used for let*:
the target for the code fragment is a locaton obtained
from get-loc, which is then attached to a variable
afterward. The spec-sub helper is extended with a loc
parameter to help with this case.
* tests/012/lambda.tl: New test case that fails without
this fix.
|
|
|
|
|
|
|
|
|
| |
* Makefile (COMPILE_TL): Before we invoke txr --compile,
let's make sure there isn't a .tmp file left over by
a previous failed compile job. Otherwise --compile
will consider that to be an up-to-date compiled file
due to its newer timestamp relative to the .tl file,
and we end up renaming that to .tlo.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (env rename-var): Method removed.
(compiler comp-let): Instead of initially creating
a let* variable as a gensym, and then renaming it
after compiling the init expression, we now just
obtain the location not bound to a variable, use the
location when compiling the init form, and bind
the location to a variable right after. This is
cleaner since the only thing we are mutating now is
the environment, and we are not wastefully allocating
a gensym. The real motivation is that this is building
up to a bugfix in compiling optional variables in
lambda: stay tuned!
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (env get-loc): New method for
allocating v-reg, split out of extend-var and
extend-var*. Now there is a check for the v-cntr
overflow.
(env (extend-var, extend-var*)): Taken an optional
loc parameter, so the caller can optionally allocate
a v-reg location using get-loc, and then specify
that location when creating a variable. If the
argument is omitted, use get-loc.
|