| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
After parsing out of a stream, we attach a shadow
stream which temporarily patches the operations
to make it appear that bytes that were taken into
the lexer have been pushed back. This lets us
call an ordinary input operation after a parsing
operation to read the data immediately following the
parsed-out construct. (Almost: there is still the
issue of the parser consuming one token of lookahead
in some situations.)
* stream.h (struct strm_base): New member shadow_obj.
This is a context pointer used by the shadow stream
operations.
(generic_fill_buf): Declare previously internal
function.
* stream.c (strm_base_init): Initialize shadow_obj
to null.
(generic_fill_buf): Function changed to external linkage.
Also, reloads the ops pointer from the stream on
each loop iteration. This is because it can change;
part of the buffer may be filled by shadow_get_byte,
which can detach the shadow operations, so then
the rest of the buffer is filled by something else
like stdio_get_byte.
(generic_get_line): Reload ops in in the loop, like
in gneric_fill_buf, for the same reason.
* parser.l: Include <stddef.h> for ptrdiff_t.
(scanner_has_buffered_bytes, scanner_get_buffered_bytes):
New functions.
* parser.c (SHADOW_TAB_SIZE): New preprocessor symbol.
(shadow_tab): New static array.
(struct shadow_context, struct shadow_ungetch): New
struct types.
(lisp_parse_impl): After calling parse, call
parse_shadow_stream_attach to attach the shadow stream
context and operations onto the stream.
(shadow_detach, shadow_destroy_op, shadow_mark_op,
shadow_put_string, shadow_put_char, shadow_put_byte,
shadow_get_char_callback, shadow_get_char,
shadow_unget_char_callback, shadow_unget_char,
shadow_get_byte, shadow_unget_byte, shadow_put_buf,
shadow_close, shadow_flush, shadow_seek, shadow_truncate):
New static functions.
(shadow_ops_template): New static structure.
(customize_shad_ops): New static function.
(parser_shadow_stream_attach): New function.
(parser_free_all): New function.
* parser.h (scanner_has_buffered_bytes,
scanner_get_buffered_bytes, parser_shadow_stream_attach,
parser_free_all): Declared.
* txr.c (free_all): Call parser_free_all.
* tests/018/streams.tl: New test cases.
* lex.yy.c.shipped: Regenerated.
|
|
|
|
|
|
|
|
| |
* stream.c (tail_strategy, make_stdio_stream_common):
A recent change introduced this problem. Initialization
of h->last_op must no longer be compile-time conditional
on CONFIG_STDIO_STRICT, because it is used in non-strict
mode also.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This refactoring is required become some upcoming
hack work is going to depend on the assumption that
every stream object has a utf8_decoder_t.
* utf8.h (utf8_decoder_initializer): New macro, used when
initializing strm_base.
* stream.h: Some of the content is now hidden unless the
preprocessor symbol STREAM_IMPL is defined. This is motivated
by the fact that stream.h now depends on utf8.h.
When STREAM_IMPL is not defined, the bits that depend on
utf8.h are disabled and we don't have to touch files which
include "stream.h" which don't refer to those bits.
(struct strm_base): New member ud, of type ut8_decoder_t.
* stream.c: include "utf8.h" before "stream.h" and ensure
STREAM_IMPL is defined.
(strm_base_init): Initialize ud member of struct strm_buf
using utf8_decoder_initializer.
(struct stdio_handle, struct byte_input, struct string_out):
Remove member ud.
(stdio_switch, stdio_seek, stdio_get_char, stdio_get_byte,
stdio_unget_byte, stdio_fill_buf, tail_strategy, byte_in_get_char
string_out_byte_flush): Refer to new ud member in base.
(make_stdio_stream_common, make_string_byte_input_stream,
make_string_output_stream): No need to call utf8_decoder_init
since strm_base_init takes care of it.
* buf.c, gzio.c, hash.c, lib.c, parser.c, regex.c, socket.c,
struct.c, strudel.c, syslog.c, tree.c: Move #include "utf8.h"
above "stream.h", or in some cases add it. Define STREAM_IMPL
before #include "stream.h".
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
String byte input streams extended to provide
characer input (get-char), and any mixture of
unget-byte and unget-char. Also fill-buf
is supported.
* stream.c (struct byte_input): New ut8_decoder_t
member ud.
(struct byte_input_ungetch): New struct type.
(byte_in_get_char_callback, byte_in_get_char,
byte_in_unget_char_callback, byte_in_unget_char):
New functions.
(byte_in_ops): Wire in byte_in_get_char,
byte_in_unget_char and byte_in_unget_byte.
Also generic_fill_buf.
(make_string_byte_input_stream): Initialize the
UTF-8 decoder.
* tests/018/streams.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* utf8.[ch] (utf8_getc, utf8_ungetc): New functions
which allow the push-back buffer of the decoder to
be accessed. We can use the decoder's push-back
buffer to implement a stream's byte push-back,
so that the behavior is then consistent: invalid
bytes pushed back by the decoder are treated
uniformly with bytes pushed back using unget-char.
* stream.c (stdio_switch): Bugfix: reset the UTF8
decoder when changing direction. Without this, it
is possible that pushed back bytes in the decoder's
buffer will be read, even though write operations
moved the position. Thus stdio_switch is now defined
as a function regardless of whether CONFIG_STDIO_STRICT
is in effect.
(stdio_get_byte): If there are pushed back characters
present, throw an error. Otherwise, try to get
a byte from the UTF8 buffer's pushback first via
utf8_getc. If that produces something, just return
it. Otherwise fall back on reading from the stdio
stream.
(stdio_unget_byte): If there are pushed back characters
present, throw an error. Otherwise push back the
character using utf8_ungetc. If that reports no
space, throw an error.
(stdio_fill_buf): Take bytes from the push-back buffer
int he UTF8 decoder first, then fread the rest
from the stdio stream, if necessary.
|
|
|
|
|
|
|
|
| |
* utf8.h (utf8_decoder_t): Declare the flags member as well
as the buffer indices head, tail and back as unsigned.
Bitmask fields holding flags should be unsigned.
Regarding the indices, we perform % 8 reductions on them in
the decoder, which optimizes much better for unsigned types.
|
|
|
|
|
| |
* genvim.txr (fmt): New variable.
(txr_quat): Match optional fmt after at.
|
|
|
|
|
|
|
|
| |
* eval.c (expand_quasi): Quasiliteral sys:var items
now have a format string, which we have to propagate
to the expansion.
* tests/012/quasi.tl: New tests.
|
|
|
|
|
|
|
|
|
| |
* parser.y (quasi_item): In the @ n_expr case, we
must generate the sys:var expression if the @ is
carrying a format string, regardless of whether n_expr
is an integer or symbol.
* y.tab.c.shipped: Regenerated.
|
|
|
|
|
|
|
| |
* txr.1: The remove and keep functions are missing from their
section heading. Adding them in makes the heading overstuffed,
so breaking it up. The separate function and the two lazy
functions remove-if* and keep-if* go into their own sections.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch adds support to quasiliterals to have the inserted
items formatted via a format conversion specifier, for example
@~3,3a:abc is @abc modified by ~3,3a format conversion.
When the inserted value is a list, the conversion is distributed
over the elements individually. Otherwise it applies to the
entire item.
* eval.c (fmt_tostring, fmt_cat): Take additional format
string argument. If it isn't nil, then do the string
conversion via the fmt1 function rather than tostring.
(do_format_field): Take format string argument, and
pass down to fmt_cat.
(format_field); Take format string argument and pass down
to do_format_field.
(fmt_simple, fmt_flex): Pass nil format string argument to
fmt_tostring.
(fmt_simple_fmstr, fmt_flex_fmstr): New static functions,
like fmt_simple and fmt_flex but with format string arg.
Used as run-time support for compiler-generated quasilit code
for cases when format conversion specifier is present.
(subst_vars): Extract the new format string frome each
variable item. Pass it down to fmt_tostring, format_field
and fmt_cat.
(eval_init): Register sys:fmt-simple-fmstr and sys:flex-fmstr
intrinsics.
* eval.h (format_field): Declaration updated.
* lib.c (out_quasi_str_sym): Take format string argument.
If it is present, output it after the @, followed by
a colon, to reproduce the read notation.
(out_quasi_str): Pass down the format string, taken
from the fourth element of a sys:var item of the quasiliteral.
For simple symbolic items, pass down nil.
* match.c (tx_subst_vars): Pass nil as new argument of
format_field. The output variables of the TXR Pattern
language do not exhibit this feature.
* parser.l (FMT): New pattern for matching the format
string part.
(grammar): The rule which recognizes @ in quasiliterals
optionally scans the format notation, and turns it
into a string attached to the token's semantic value,
which is now of type val (see parser.y remarks).
* parser.y (tokens): The '@' token's %type changed
from lineno to val so it can carry the format string.
(q_var): If format string is present in the @ symbol,
then include it as the fourth element of the sys:var
form. This rule handles braced items.
(meta): We can no longer get the line number from the @
item, so we get it from n_expr.
(quasi_item): Similar to q_var change here. This handles
@ followed by unbraced items: symbols and other expressions.
* stdlib/compiler.tl (expand-quasi-mods): Take format
string argument. When the format string is present,
then generate code which uses the new alternative
run-time support functions, and passes them the format
string as an argument.
(expand-quasi-args): Extend the sys:var match to extract
the format string if it is present. Pass it down to
expand-quasi-mods.
* stdlib/match.tl (expand-quasi-match): Add an error case
diagnosing the situation when the program tries to use
a format-conversion-endowed item in a quasilit pattern.
* stream.[ch] (fmt1): New function.
* tests/012/quasi.tl: New tests.
* txr.1: Documented.
* lex.yy.c.shipped, y.tab.c.shipped: Regenerated.
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (expand-quasi-mods): Fix unidiomatic
if form which continues with a cond fallback. All
I'm doing here is flattening (if a b (cond (c d) ...))
to (cond (a b) (c d) ...).
|
|
|
|
|
|
|
|
|
|
| |
* arith.c (arg_type_error_1, arg_type_arror_2,
arg_type_error_3): New static functions.
(exptmod, isqrt, square, gcd, divides, logand,
logior, logxor, logxor_old, logtest, lognot,
logtrunc, ash, bit, bitset, logcount, width,
poly, rpoly): Use one of these three functions
to replace an ad-hoc throw.
|
|
|
|
|
|
|
|
|
| |
* stdlib/infix.tl (toplevel): New ~ operator,
prefix at level 35, tied to lognot function.
* tests/012/infix.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
| |
* arith.c (zerop, logand, logior, logxor, logtest,
lognot, logtrunc, ash, bit, bitset, logcount,
width): Add support for buffer arguments via the
new bit manipulation functions provided by the
buffer module.
* txr.1: Documented.
|
|
|
|
|
| |
* buf.c (buf_trunc): Fix self string from
buf-not to buf-trunc.
|
|
|
|
|
|
|
|
|
| |
* arith.c (logtrunc): Firstly, the correct condition
for trivially returning zero is bits <= 0, not bits < 0.
Secondly, we don't want to do this upfront. In the
case we have a struct with user-defined arithmetic,
the method must be called. It might return a different
kind of zero.
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (prepare_pattern): Do not return a zero length pattern
for an empty buffer. Callers don't deal with this properly.
Return a one byte pattern that is zero.
* test/012/buf.tl: Test case added.
* txr.1: Documented.
|
|
|
|
| |
* txr.1: Add Arithmetic Conventions of Buffer section.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The init-val parameter of make-buf and buf-set-length
is generalized to a possibly multi-byte fill pattern.
* buf.c (make_buf, buf_do_set_len): Change init-val
parameter to init-pat, and implement. We optimize the
to memset when it's a one-byte pattern.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
| |
* buf.c (prepare_pattern): New static function.
(buf_xor_pattern): Use prepare_pattern to
classify the pat parameter and prepare the
pattern.
|
|
|
|
|
|
|
|
|
|
| |
* parser.y (yybadtoken): Map the LAMBDOT token code
to the name "lambda dot" to distinguish it from
CONSDOT in error situations.
* txr.1: Change the Consing Dot section to Lambda Dot.
* y.tab.c.shipped: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Introducing a relaxation in the obj.slot.(method arg)
syntax. There can be whitespace to the right of the dot,
for splitting across multiple lines, as:
obj.
slot.
(method arg)
* parser.l (OREFDOT): Allow optional whitespace
to the right of .?
* parser.y (n_expr): Add a n_expr LAMBDOT n_expr
phrase, with same semantic rule as n_expr '.' n_expr.
We cannot add optional whitespace after . in
the lexer because that is ambiguous with LAMBDOT.
* tests/012/syntax.tl: New tewt cases.
* txr.1: Documented.
* lex.yy.c.shipped, y.tab.c.shipped: Regenerated.
|
|
|
|
|
|
| |
* ffi.c (ffi_char_array_get, ffi_zchar_array_get):
Use newly added string_utf8_from_buf rather than
utf8_dup_from_buf followed by string_own.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (str_compress, str_decompress): New functions.
(buf_init): str-compress, str-decompress intrinsics
registered.
* lib.[ch] (string_utf8_from_buf): New function.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
| |
* stdlib/hmac.tl (hmac-impl): Eliminate xor loop
by using buf-xor-pattern.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_xor_pattern): New function.
(buf_init): Register buf-xor-pattern intrinsic.
* buf.h (buf_xor_pattern): Declared.
* lib.[ch] (unsup_obj): Change function to
external linkage and declare in header.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The issue is that in a lambda-match, when we wrap
@(require) around an argument match, it becomes
a single pattern which matches the variadic arguments
as a list. As a result, the function also becomes
variadic, and a list is consed up for the match.
A nested list is worth a thousand words:
Before this change:
1> (expand '(lambda-match
(@(require (@a @b) (= 5 (+ a b))) (cons a b))))
(lambda (. #:rest0014)
(let (#:result0015)
(or (let* (a b) (let ((#:g0017 (list* #:rest0014)))
(if (consp #:g0017)
(let ((#:g0018 (car #:g0017))
(#:g0019 (cdr #:g0017)))
(sys:setq a #:g0018)
(if (consp #:g0019)
(let ((#:g0020 (car #:g0019))
(#:g0021 (cdr #:g0019)))
(sys:setq b #:g0020)
(if (equal #:g0021 '())
(if (and (= 5 (+ a b)))
(progn (sys:setq #:result0015
(cons a b))
t))))))))))
#:result0015))
After this change:
1> (expand '(lambda-match
(@(require (@a @b) (= 5 (+ a b))) (cons a b))))
(lambda (#:arg-00015
#:arg-10016)
(let (#:result0017)
(or (let* (b a) (sys:setq b #:arg-10016)
(sys:setq a #:arg-00015)
(if (and (= 5 (+ a b)))
(progn (sys:setq #:result0017
(cons a b))
t))))
#:result0017))
@(require (@a @b)) now leads to a two-argument function.
The guard condition is applied to the a and b variables
extracted from the arguments rather than a list.
* stdlib/match.tl (when-exprs-match): Macro removed.
(struct lambda-clause): New slot, require-conds.
(parse-lambda-match-clause): Recognize @(require ...)
syntax, destructure it and recurse into the argument
pattern it contains. Because the incoming syntax
includes the clause body, for the recursive call we
synthesize syntax consisting of the pattern
extracted from the @(require), coupled with the
clause body. When the recursive call gives us a
lambda-clause structure, we then add the require
guard expressions to it. So in essence the behavior
is that we parse the (@(require argpat cond ...) body)
as if it were (argpat body), and decorate the object
with the extracted conditions.
(expand-lambda-match): This now takes an env argument
due to the fact that when-exprs-match was removed.
when-exprs-match relied on its :env parameter to get
the environment, needed for compile-match. Now
expand-lambda-match directly calls compile-match,
doing all the work that when-exprs-match helper was
doing. Integrating that into expand-lambda-match
allows us to add logic to detect that the lambda-clause
structure has require conditions, and add the code
as a guard to the compiled match using add-guards-post.
(lambda-match, defun-match, :match): Pass environment
argument to expand-lambda-match.
|
|
|
|
|
|
|
|
| |
* autoload.c (trace_set_entries): Add sys:*trace-level*
symbol as autoload trigger. Compiled code which uses
the :trace parameter macro references this variable
(and some other internal trace symbols, but that one
first).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (ctx_name): Do not report just the car
of the form. If the form starts with three symbols,
list those; if two, list those.
* stdlib/compiler.tl (expand-defun): Set the
defun form as the macro ancestor of the lambda,
rather than propagating source location info.
Then diagnostics that previously refer to a
lambda will correctly refer to the defun and
thank to the above change in eval.c, include
its name.
* stdlib/pmac.t (define-param-expander):
A similar change here. We make the define-param-expander
form the macro ancestor of the lambda, so that
diagnostics agains tthe lambda will show that
form.
|
|
|
|
|
|
|
| |
* buf.c (buf_count_ones): Short-circuit loop iteration
if word or byte is zero. If the word/byte is a power
of two (1 bit set) or if it has all bits set, then
skip the bit trick.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Just add :trace to the head of the parameter list, and the
function is traced. No dynamic turning on and off though.
* autoload.c (trace_set_entries): Trigger autoload on :trace
keyword.
* stdlib/trace.tl (:trace): New parameter list expander.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
| |
* eval.c (me_flet_labels): Create a synthetic
macro ancestor form which is (labels <name>)
or (flet <name>) so the function name, location
and type of binding can be traced from the
lambda expression. This will be useful to the
:trace parameter macro that is coming.
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/error.tl (sys:dig): Do not stop tracing
the macro ancestry of a form upon finding source
location info. This can be counterproductive
because there are situations in which intermediate
forms receive the info via rlcp or rlcp_tree.
We would like to get to the form that actually
exists in that file at that line number.
|
|
|
|
|
|
| |
* autoload.c (error_set_entries): Add dig
to system package names that trigger autoload
of stdlib/error.
|
|
|
|
| |
* stdlib/quips.tl (%quips%): New one about grapheme clusters.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* autoload.c (match_set_entries): Trigger autoload on new
symbols in function namespace: each-match-case,
collect-match-cases, append-match-cases, keep-match-cases,
each-match-case-product, collect-match-case-products,
append-match-case-products, keep-match-case-products.
* stdlib/match.tl (each-match-case, collect-match-cases,
append-match-cases, keep-match-cases, each-match-case-product,
collect-match-case-products, append-match-case-products,
keep-match-case-products): New macros.
* tests/011/patmatch.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The DARG object type (dynamic args) is used in a few places.
It has no safe accessors that do type checks and is
directly accessed for efficiency. We need some modicum of
safety when is is planted into the environment of functions,
because those are mutable.
* eval.c (do_args_apf, do_args_ipf, do_callf): type check
the dargs object from the function to be DARG before
accessing it.
* struct.c (method_args_fun, umethod_args_fun): Likewise.
|
|
|
|
|
|
|
| |
* autoload.c (infix_set_entries): intern finish-infix
in the usr package, and trigger autoload on it.
* txr.1: Documented existence and purpose of finish-infix.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The problem is that (parse-infix '(x < y < z)) and
(parse-infix '(x < (< y z)) produce exactly the same
parse and will be treated the same way. But we would
like (< y z) to be left alone. The fix is to annotate
all compound terms such that finish-infix will
not recurse into them.
* stdlib/infix.tl (parse-infix): When an operand is
seen that is a compound expression X it is turned
into @X, in other words (sys:expr X).
(finish-infix): Recognize (sys:expr X) and convert
it into X without recursing into it.
* tests/012/infix.tl: Update a number of test cases.
* txr.1: Documented.
|
|
|
|
|
|
|
| |
* buf.c (int_buf): Do not multiply the buffer length by
8 as a built-in unsigned integer. Use the mul
function instead on the original Lisp integer length.
sign-extend handles bignum values for the bit width.
|
|
|
|
|
|
|
|
|
| |
* mpi/mpi.c (mp_read_signed_bin, mp_signed_bin_size,
mp_to_signed_bin): Functions removed.
* mpi/mpi.h (mp_read_signed_bin, mp_signed_bin_size,
mp_to_signed_bin): Declarations removed.
(mp_read_raw, mp_raw_size, mp_toraw): Macros removed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This fixes an exception in (int-buf #b'').
* arith.c (comp_trunc, lognot): Do not throw on negative bits,
just return zero.
(bit): Return nil if bit is negative rather than throwing.
(sign_extend): Fix instance of bad indentation. Renumber
goto labels.
Otherwise, nothing needs to be done here since bit
is where it was blowing up on a zero or negative bits value.
* txr.1: Document that logtrunc, lognot, sign-extend and bit
handle nonpositive bit widths, and negative bit positions.
|
|
|
|
|
|
|
|
|
| |
This causes assertions in uint-buf and int-buf
on an empty buffer argument.
* mpi.c (mp_read_unsigned_bin): Remove len > 0
assertion, because the code works fine for len == 0,
returning the zero mp_int produced by mp_zero.
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_binary_width): New function.
(buf_init): Register buf-binary-width intrinsic.
* buf.h (buf_binary_width): Declared.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_count_ones): New function.
(buf_init): Register buf-count-ones intrinsic.
* buf.h (buf_count_ones): Declared.
* tests/012/buf.h: New tests.
* txr.1: Documented.
|
|
|
|
|
| |
* buf.c (buf_ash): Loop must be clamped the
smaller length of the result, cnlen.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The length of a buffer is capped by the range of cnum,
which is a subrange of ucnum. A buffer can never be
so big that it can't be iterated by a
for (i = 0; i < len; i++) loop, where i and len
are of type ucnum.
* buf.c (buf_ash): In this function, we potentially
create a longer buffer than the input, and so here
it makes sense to check for the new length being
out of the range of cnum; i.e. beyond INT_PTR_MAX.
We keep the check but change the threshold.
(buf_and, buf_test, buf_or, buf_xor, buf_not):
Remove checks on existing length.
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_test): New function.
(buf_init): Register buf-test intrinsic.
* buf.h (buf_test): Declared.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_zero_p): New function.
(buf_init): Register buf-zero-p intrinsic.
* buf.h (buf_zero_p): Declared.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|