| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Via macros, atoms can sneak into a quasiliteral which then
blow up because they get treated as strings without being
converted.
Example:
(defmacro two () 2)
`@(two)xyz` -> ;; error
The expansion produces the invalid form, in which the 2
is subsequently treated as a string.
(sys:quasi 2 "xyz")
On the other hand, symbol macros don't have this problem:
(defsymacro two 2)
`@{two}xyz` -> "2xyz"
The reason is that the (sys:var two) syntax will expand to
(sys:var 2), and not 2.
The straightforward, consistent fix is to ensure that the
first case will also go to (sys:var 2).
* eval.c (expand_quasi): If the expanded form is an atom which
is not a bindable symbol, wrap it in a sys:var.
* tests/012/quasi.tl: Test cases added.
Also adding a compilation test for this file, cribbed from
patmatch.tl.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is a regression that was introduced in 191. The change in
191 was trying to prevent defsymacro from being expanded
immediately by the expander except in 190 compatibility.
Unfortunately, this caused the whole defsymacro block not to
be entered unless in 190 compatibility, otherwise taking the
common exit which returns form_ex, containing the expanded
replacement form.
* eval.c (do_expand): Split up implementation of defvarl and
defsymacro. In the defsymacro block, do not do any expanding
on entry. Absent of compatibility mode, we just do some sanity
checks and pass the entire form through. In 262 compatibility,
we do the expansion to obtain form_ex. Then all the previous
compat logic is wrapped in that block.
* tests/011/macros-3.tl: Add a test case which confirms that
symbol macros are lazily expanded. Weakness in the test suite
is how these regressions creep in.
* txr.1: Improve defsymacro documentation, spelling out
clearly that the unexpanded replacement form is associated
with the symbol. Eliminate obsolescent text suggesting that
defsymacro is evaluated at macro time.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We don't want to be unconditionally releasing deferred
warnings when error exceptions occur in evaluation or
compilation. The reason is that the error might be handled,
for instance by a speculative expansion. Then unwanted noise
occurs, because deferred warnings have been released
prematurely.
* eval.c (eval_exception): Do not call
uw_release_deferred_warnings here.
(error_trace): But do call uw_release_deferred_warnings here,
before printing anything else. We want to preserve the
behavior that when error information is actually being
printed to a stream, any deferred warnings are dumped first
because they might pertain to the error. (I may revisit
this requirement; perhaps deferred warnings rarely, if ever,
pertain to an error).
* share/txr/stdlib/error.tl (compile-error): Do not dump
deferred warnings unconditionally. Only dump them if we
are also printing the error message to stderr. Secondly, do
not output the error message at all, unless there is no
handler for the error.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register fill-vec intrinsic.
* lib.c (fill_vec): New function.
* lib.h (fill_vec): Declared.
* tests/010/vec.tl: New file.
* txr.1: Documented.
* share/txr/stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The expand function must not muffle all deferred warnings.
That causes the problem that a form like (inc var a.bar) fails
to produce a warning due to bar not being the slot of any
structure. The expand function must only muffle warnings about
undefined functions and variables.
* eval.c (muffle_unbound_warning): New static function.
(no_warn_expand): Use muffle_unbound_warning as handler,
rather than uw_muffle_warning.
* tests/012/struct.tl: Fix two test cases here which test the
expand function using a form that references a nonexistent
slot. These now generate a warning, so we use the slot name b
rather than d, which is defined.
* txr.1: Documented change to expand.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is a revert of November 2016 commit
606132c336dbeb0dd8bb851a64c97f2c11b76a85.
The commit claims that it fixes a bug, but in fact it
introduces one. There is no discussion in that commit about
what motivated it.
The commit which follows that one introduces a
naivey-implemented diagnostic for catching unbound functions
at macro-expansion time, so the likely motivation for this
wrong fix was to suppress false positives from that naive
diagnostic for recursive functions. That has long since been
replaced by a better approach.
Because of the bug, we cannot do this very useful thing: we
cannot write an inline version of a funtion as a macro first,
and then a real function which just calls that macro:
(defmacro foo (arg) ...)
(defun foo (arg) (foo arg))
The bug causes the (foo arg) call in this function not to be
expanded, due to the shadowing.
* eval.c (do_expand): When expanding defun, do not introduce
the function's name as a lexical function binding, because it
isn't one.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register put-json and put-jsonl
intrinsics.
* lib.c (out_json_str): Do not output the U+DC01 to U+DCFF
code points by masking them and using put_byte. This is
unnecessary; if we just send them as-is to the text stream,
the UTF-8 encoder does that for us.
(put_json, put_jsonl): New functions.
* lib.h (put_json, put_jsonl): Declared.
* txr.1: Documented. The bulk of tojson is moved under the
descriptions of these new functions, and elsewhere where the
document pointed to tojson for more information, it now points
to put-json. More detailed description of character treatment
is given.
* share/txr/stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): get-json intrinsic registered.
* parser.c (prime_parser): Handle prime_json.
(lisp_parse_impl): Take enum prime_parser argument
directly instead of the interactive flag.
(lisp_parse, nread, iread): Pass appropriate prime_parser
value instead of the original flag.
(get_json): New function. Like nread, but passes prime_json.
* parser.h (enum prime_parser): New constant, prime_json.
(get_json): Declared.
* parser.l (prime_scanner): Handle prime_json.
* parser.y (SECRET_ESCAPE_J): New terminal symbol.
(spec): New productions around SECRET_ESCAPE_J for parsing
JSON.
* lex.yy.c.shipped, y.tab.c.shipped, y.tab.h.shipped: Updated.
* txr.1: Documented.
* share/txr/stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): tojson intrinsic registered.
* lib.c (tojson): New function.
* lib.h (tojson): Declared.
* txr.1: Documented.
* share/txr/stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
| |
* eval.c (me_case): When we evaluate the keys of a caseq,
caseql* or casequal* construct, we must use expand_eval.
I ran into this problem trying to use constants defined
as symbol macros as keys.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (rt_defvarl): More accurate self string.
(rt_defv): New static function: like rt_defvarl but ensures
that the new variable has a binding cell, and returns that
cell instead of the hash cell.
(op_defvarl): Take advantage of rt_defv to not have to cons up
the binding cell.
(eval_init): Register sys:rt-defv intrinsic.
* parser.c (read_file_common): Compiled files are now version
7, so we must recognize them. We still load version 6 files
because rt:defvarl still exists for them.
* share/txr/stdlib/compiler.tl (expand-defvarl): Improve the
generated code in two ways. Firstly, use the new sys:rt-defv,
which returns the binding cell, so that the value can be
stored into it with rplacd without having to cons up anything.
Secondly, if there is no value expression, don't emit the
code to do the assignment.
(%tlo-ver%): Bump compiled file version to (7 0).
* txr.1: Add note about TXR 260 loading version 7 and 6.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
As of this commit, binary search trees can be iterated:
mapped over with mapcar and such.
* arith.c (poly, rpoly): rpoly won't work with trees. They
work just with vectors and lists so let's make the error
message more accurate. I noticed the self names of these two
are swapped; will fix in another commit.
* eval.c (tprint): Refactor to use iterator framework for
objects other than lists. The tree case falls into this,
so trees are supported.
* lib.h (enum seq_kind): New enum constant SEQ_TREELIKE.
(seq_iter_init_with_info): Declared.
* lib.c (seq_info): Map tree object to SEQ_TREELIKE type.
(seq_iter_get_tree, seq_iter_peek_tree): New static functions.
(seq_iter_rewind): Support rewinding tree iteration.
I think we could reuse the existing iterator here, and in the
hash case as well. I made a note to look into this.
(seq_iter_init_with_info): Internal linkage changed to
external, because tprint in eval.c uses this.
Handle SEQ_TREELIKE case here, by setting up iterator with the
two new static functions.
(seq_iter_mark): Handle SEQ_TREELIKE_CASE. Change switch
statement to exhaustively list cases.
(ldiff): Add SEQ_TREELIKE to various cases. Idea is that we
handle it like SEQ_HASH.
(nsort, sort, nshuffle, take, take_while, take_until,
drop_while, drop_until, update): Add case for SEQ_TREELIKE,
routing to error message.
(lazy_where_tree_func): New static function.
(where, sel, reject): Support trees.
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (lazy_mapcar_func): We must capture the return value
of iter_step, since we refer to it in the next statement,
expecting it to have stepped. This bug causes a behavior as if
the original list had an extra nil.
* tests/012/lazy.tl: Tests. Poor test coverage is why this
sort of thing comes up and bites us.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The lexical-var-p function wrongly reports true for locally
rebound special variables, which are not lexical.
* eval.c (special_var_p): Static function moved to avoid
forward declaration.
(lexical_var_p): Bail if sym satisfies special_var_p.
(old_lexical_var_p): New function, copy of old lexical_var_p
before this bugfix.
(eval_init): Conditionally register lexical-var-p as either
lexical_var_p or old_lexical_var_p depending on the compat
value.
* txr.1: Update documentation for lexical-var-p to clarify
that it doesn't report true for specials. Also make note that
it doesn't report true for global lexicals, and likewise that
lexical-fun-p doesn't report global functions.
Added compat note.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
mac-env-param-bind is like mac-param-bind but also allows
the value for the :env parameter to be specified.
* eval.c (op_mac_env_param_bind_s): New sy mbol variable.
(op_mac_env_param_bind): New static function.
(do_expand): Handle mac_env_param_bind_s.
(eval_init): Initialize symbol variable and register macro.
* share/txr/stdlib/compiler.tl (compiler compile): Add case
for mac-env-param-bind.
(compiler comp-mac-env-param-bind): New method.
* share/txr/stdlib/doc-syms.tl: Updated with new hashes for
tree-bind and mac-param-bind, and inclusion of
mac-env-param-bind.
* tests/012/binding.tl: New file.
* txr.1: Documented.
|
|
|
|
|
| |
* eval.c (do_expand): argument of fun is not in "operator
position"; fixed wording.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch eliminates parentheses from the error messages,
as well as a leading ./ being added to relative paths.
The word "warning: " is moved into the error message, so that
it does not appear before the location.
Example, when doing (compile-file "path/to/foo.tl").
Before patch:
warning: (./path/to/foo.tl:37): unbound function foo
After:
path/to/foo.tl:37: warning: unbound function foo
Now when I compile out of Vim, it nicely jumps to errors in
Lisp code.
* eval.c (eval_exception): Drop parentheses from error
location, add colon.
(eval_warn): Prepend "warning: " to format string.
(eval_defr_warn): Drop parentheses from location, and
prepend "warning: " to format string.
* parser.c (repl-warning): Drop "warning:" prefix.
* share/txr/stdlib/compiler.tl (open-compile-streams): Do not
do parent substitution for relative paths if the parent path
is the empty string "", to avoid inserting ./ onto relative
paths in that case.
* share/txr/stdlib/error.tl (sys:loc): Drop parentheses and
space from location.
(compile-error) Separate location with colon and space.
(compile-warning, compile-defr-warning): Likewise and add
"warning: " prefix.
* unwind.c (uw_rthrow): Drop "warning: " prefix.
(uw_warningf): Add "warning: " prefix.
(uw_dump_deferred_warnings): Drop "warning: " prefix.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
That old cat-str function is often a pain, requiring the
pieces as a list. We have a sys:fmt-join that is undocumented.
That functions is now exposed as usr:join, and documented.
Also introducing join-with that takes a separator as the
leftmost argument. Thus (op join-with "::") gives us
a function that joins pieces with :: in between.
* eval.c (eval_init): Regiser fmt_join function under join
symbol also. Register join-with.
* lib.c (join_with): New function.
(fmt_join): Now a wrapper for join_with that passes a nil
separator.
* lib.h (join_with): Declared.
* share/txr/stdlib/optimize.tl (basic-blocks join-blocks):
Rename the local function join, which now triggers a warning
about a standard function being redefined.
* txr.1: Redocumented cat-str, and documented join-with
and join.
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (dotted_form_error): Use eval_error instead of
throwing direcly, so the error message has location info and
consistent formatting.
(expand_forms, expand_forms_ss, expand_forms_lisp1): Check for
the dotting error one level above, at the cons cell. The cons
cell will have line number information attached to it for a
better error message.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The block elimination logic doesn't work for self-recursive
functions, even if they invoke no block returning, and use
only system functions that don't have anything to do with
block returns. This is because the recursive call is not
recognized, and treated as a call to an unknown function.
Let's put in a simple hack. The defun and defmacro operators
will use a new secret special operator called sys:blk instead
of block to generate the block. The compilation of sys:blk
will assume that (sys:blk name ...) is only used in a defun or
defmacro by that same name, and include name in the list of OK
functions.
So that functions created using the interpreter and then
dynamically compiled will also benefit, we add this operator
to the interpreter.
* eval.c (sys_blk_s): New symbol variable.
(op_defun): For defun and defmacro, use sys:blk for the block
for the block
(eval_init): Initialize sys_blk_s with the interned symbol
sys:blk. Register the sys:blk operator.
* share/txr/stdlib/compiler.tl (compiler compile): Recognize
the sys:blk special form and handle via comp-block.
(comp-block): If sys:blk is being compiled, then include the
block name in the list of functions that do not perform block
returns. (If this is false, other checks will fail before use
that.)
(expand-defun): Use sys:blk for defun and defmacro.
|
|
|
|
|
|
| |
* eval.c (maprodv, maprendv): These functions implement maprod
and maprend; the v suffix is just in the C code and must not be
part of the self name.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Observed wrong result:
(mapcar (lambda (. args) (list . args)) '#(1 2 3) '#(4 5 6))
-> #((1 4) nil nil)
Correct result:
-> #((1 4) (2 5) (3 6))
This is not specific to vector input; it's broken for
sequences of all types.
Functions affected are mapcar, mapf, mappend, mapdo,
maprod, maprend, maprodo.
* eval.c (map_common, prod_common): Because we reuse the args
structure across iterations, we must reinitialize the fill
and list members. These can be modified by the functionw which
is called. In particular, the arguments are applied, they may
be turned into a list (fill decrements to zero, and a list is
produced).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* METALICENSE: 2020 copyrights bumped to 2021. Added note
about SHA-256 routines from Colin Percival.
* LICENSE, LICENSE-CYG, Makefile, alloca.h, args.c, args.h,
arith.c, arith.h, buf.c, buf.h, cadr.c, cadr.h, chksum.c,
chksum.h, chksums/crc32.c, chksums/crc32.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, lex.yy.c.shipped,
lib.c, lib.h, linenoise/linenoise.c, linenoise/linenoise.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/asm.tl, share/txr/stdlib/awk.tl,
share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl,
share/txr/stdlib/compiler.tl, share/txr/stdlib/conv.tl,
share/txr/stdlib/copy-file.tl, share/txr/stdlib/debugger.tl,
share/txr/stdlib/defset.tl, share/txr/stdlib/doloop.tl,
share/txr/stdlib/each-prod.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/param.tl,
share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl,
share/txr/stdlib/pmac.tl, share/txr/stdlib/quips.tl,
share/txr/stdlib/save-exe.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/trace.tl, share/txr/stdlib/txr-case.tl,
share/txr/stdlib/type.tl, share/txr/stdlib/vm-param.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, time.c, time.h,
tree.c, tree.h, txr.1, txr.c, txr.h, unwind.c, unwind.h,
utf8.c, utf8.h, vm.c, vm.h, vmop.h, win/cleansvg.txr,
y.tab.c.shipped: Copyright year bumped to 2021.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (progn_fun, prog1_fun, prog2_fun): New static
functions.
(eval_init): Wire progn, prog1 and prog2 function bindings
to new functions.
* txr.1: Documented.
* checkman.txr (check-func): Recognize Macro/function and
Operators/functions heading.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (prog2_s): New symbol variable.
(me_prog2): New macro expander function.
(eval_init): Initialize prog2_s variable with interned
symbol.
Register prog2 macro expander.
* txr.1: Maintain the documentation for progn and prog1,
improving the wording and adding a dialect note .
Document prog2.
|
|
|
|
|
| |
* eval.c (eval_init): Use if_s, or_s, and_s instead of
wastefully calling intern.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register shuffle and nshuffle as
two-argument functions with optional argument.
* lib.c (nshuffle): Take random-state argument, defaulting to
value of random_state special variable.
(shuffle): Take random-state argument, pass down to nshuffle.
* lib.h (shuffle, nshuffle): Declarations updated.
* txr.1: Updated.
|
|
|
|
|
|
|
|
|
| |
* match.c (do_output_line, do_repeat, v_deffiler): Replace
func_n1(cdr) and func_n1(rest) with cdr_f.
* eval.c (eval_init): Replace func_n1(car) and func_n1(cdr)
with car_f and cdr_f. Should have been done in 2011 when
this was done for the registrations of car and cdr.
|
|
|
|
|
|
| |
* eval.c (map_common): Save the leftmost arg in a local
variable, and refer to that in the make_like call.
The bug here is that the args get zapped to nil.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Makefile (OBJS): Add new time.o.
* eval.c (eval_init): Registration of time functions is
removed from here; it is done in time_init now, in time.c.
* hash.c: Must #include "time.h" now.
* lib.c (time_s, time_local_s, time_utc_s, time_string_s,
time_parse_s, year_s, month_s, day_s, hour_s, min_s, sec_s,
dst_s, gmtoff_s, zone_s): Variable definitions removed.
These are now in time.c. Also declared in time.h.
(time_sec, time_sec_usec, gmtime_r, localtime_r, string_time,
time_string_local, time_string_utc, broken_time_list,
tm_to_time_struct, broken_time_struct, time_fields_local,
time_fields_utc, time_struct_local, time_struct_utc,
time_fields_to_tm, time_struct_to_tm, make_time_impl,
make_time, epoch_tm, strptime_wrap, time_parse, setenv,
unsetenv, timegm_hack, make_time_utc, time_meth,
time_string_meth, time_parse_meth, time_parse_local,
time_parse_utc): Functions removed. These are now in time.c.
(time_init): Removed, and now in time.c as an external
function.
* lib.h (time_sec, time_sec_usec, time_string_local,
time_string_utc, time_fields_local, time_fields_utc,
time_struct_local, time_struct_utc, make_time, make_time_utc,
time_parse, time_parse_local, time_parse_utc): Declarations
removed. Now in time.h.
* rand.c: Must #include "time.h" now.
* time.c: New file.
* time.h: New file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Exuberant Ctags uses the full content of one line as the key
to find a tag. A function declaration that is split into
multiple lines can have a first line which is identical to the
definition, as in:
static int add(int a,
int b);
static int add(int a,
int b)
{
return a + b;
}
Here, the search key which ctags uses for the add function is
"static int add(int a,", taken from the definition. But it's
exactly the same as a the first line of the declaration, and
that is what Vim jumps to for that tag.
A few function declarations in TXR have this issue.
* eval.c (expand_params_rec, do_eval): Make the first line of
the forward declaration different from the first line of the
definition.
* match.c (mf_all): Likewise.
* struct.c (make_struct_type_compat): Likewise.
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eva_init): Register reject intrinsic.
* lib.c (appendl): New static function.
(reject): New function.
* lib.h (reject): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Gone is the need for :vars to inform @(repeat)/@(rep) about
variable references buried in Lisp.
* eval.c (expand_with_free_refs): Change to external linkage.
* eval.h (expand_with_free_refs): Declared.
* parser.y (extract_vars): Handle sys:expr forms, which are
embedded Lisp via expand_with_free_refs to uncover their free
variables.
* txr.1: Redocumented this area.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The noreturn macro is respelled to harmonize with the
upper-case INLINE and NOINLINE.
* lib.h (noreturn): Rename to NORETURN.
* arith.c (not_number, not_integer, invalid_ops, invalid_op):
Declaration updated.
* arith.c (do_mp_error): Likewise.
* eval.c (eval_error, no_bindable_error, dotted_form_error):
Likewise.
* eval.h (eval_error): Likewise.
* lib.c (unsup_obj, callerror, wrongargs): Likewise.
* match.c (sem_error): Likewise.
* stream.c (unimpl, unimpl_put_string, unimpl_put_char,
unimpl_put_byte, unimpl_get_line, unimpl_get_char,
unimpl_get_byte, unimpl_unget_char, unimpl_unget_byte,
unimpl_put_buf, unimpl_fill_buf, unimpl_seek, unimpl_truncate,
unimpl_get_sock_family, unimpl_get_sock_type,
unimpl_get_sock_peer, unimpl_set_sock_peer): Likewise.
* struct.c (no_such_struct, no_such_slot,
no_such_static_slot): Likewise.
* unwind.h (jmp_restore, uw_throw, uw_throwf, uw_errorf,
uw_errorfv, type_mismatch): Likewise.
|
|
|
|
|
|
|
|
|
|
|
| |
* eval (eval_init): Register sspl, an argument-reversed
interface to split-str-set.
* lib.c (sspl): New function.
* lib.h (sspl): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A package is weak if it holds weak references to symbols,
meaning that if there are no references to a symbol other than
its entry in a weak package, it can be removed from the
package and reclaimed by the garbage collector.
* eval.c (eval_init): Update registrations for make-package
and sys:make-anon-package to reflect new optional argument.
* lib.c (make_package_common): New argument weak. If it is
true then both the hashes will have weak values.
(make_package, make_anon_package): New optional argument weak.
(obj_init): Add nil argument to calls to make_package. All the
standard packages are regular, not weak.
* lib.h (make_package, make_anon_package): Declarations
updated.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* arith.h (minus_s): Declared.
* eval.c (reg_symacro): Changing to external linkage.
* eval.h (macro_time_s, reg_symacro): Declared.
* parser.c (repl): Bind the *-1 to *-20 symbol macros.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register iterable intrinsic.
* lib.c (seq_iterable): New static function.
(nullify): Use seq_iterable to simplify function.
(iterable): New function.
* lib.h (iterable): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The c_num and c_unum functions now take a self argument for
identifying the calling function. This requires changes in a
large number of places.
In a few places, additional functions acquire a self
argument. The ffi module has the most extensive example of
this.
Some functions mention their name in a larger string, or have
scattered literals giving their name; with the introduction of
the self local variable, these are replaced by references to
self.
In the following changelog, the notation TS stands for "take
self argument", meaning that the functions acquires a new "val
self" argument. The notation DS means "define self": the functions
in question defines a self variable, which they pass down.
The notation PS means that the functions pass down an existing
self variable to functions that now require it.
* args.h (args_count): TS.
* arith.c (c_unum, c_num): TS.
(toint, exptv): DS.
* buf.c (buf_check_len, buf_check_alloc_size, buf_check_index,
buf_do_set_len, replace_buf, buf_put_buf, buf_put_i8,
buf_put_u8, buf_put_char, buf_put_uchar, buf_get_bytes,
buf_get_i8, buf_get_u8, buf_get_cptr,
buf_strm_get_byte_callback, buf_strm_unget_byte, buf_swap32,
str_buf, buf_int, buf_uint, int_buf, uint_buf): PS.
(make_duplicate_buf, buf_shrink, sub_buf, buf_print,
buf_pprint): DS.
* chskum.c (sha256_stream_impl, sha256_buf, crc32_buf,
md5_stream_impl, md5_buf): TS.
(chksum_ensure_buf, sha256_stream, sha256, sha256_hash,
md5_stream, md5, md5_hash): PS.
(crc32_stream): DS.
* combi.c (perm_while_fun, perm_gen_fun_common,
perm_str_gen_fun, rperm_gen_fun, comb_vec_gen_fun,
comb_str_gen_fun, rcomb_vec_gen_fun, rcomb_str_gen_fun): DS.
* diff.c (dbg_clear, dbg_set, dbg_restore): DS.
* eval.c (do_eval, gather_free_refs, maprodv, maprendv,
maprodo, do_args_apf, do_args_ipf): DS.
(op_dwim, me_op, map_common): PS.
(prod_common): TS.
* ffi.c (struct txr_ffi_type): release member TS.
(make_ffi_type_pointer): PS and release argument TS.
(ffi_varray_dynsize, ffi_array_in, ffi_array_put_common,
ffi_array_get_common, ffi_varray_in, ffi_varray_null_term): PS.
(ffi_simple_release, ffi_ptr_in_release, ffi_struct_release,
ffi_wchar_array_get, ffi_array_release_common,
ffi_array_release, ffi_varray_release): TS.
(ffi_float_put, double_put, ffi_be_i16_put, ffi_be_u16_put,
ffi_le_i16_put, ffi_le_u16_put, ffi_be_i32_put, ffi_be_u32_put,
ffi_le_i32_put, ffi_sbit_put, ffi_ubit_put, ffi_buf_d_put,
make_ffi_type_array, make_ffi_type_enum, ffi_type_compile,
make_ffi_type_desc, ffi_make_call_desc, ffi_call_wrap,
ffi_closure_dispatch_save, ffi_put_into, ffi_in, ffi_get,
ffi_put, carray_set_length, carray_blank, carray_buf,
carray_buf_sync, carray_cptr, carray_refset, carray_sub,
carray_replace, carray_uint, carray_int): PS.
(carray_vec, carray_list): DS.
* filter.c (url_encode, url_decode, base64_stream_enc_impl): DS.
* ftw.c (ftw_callback, ftw_wrap): DS.
* gc.c (mark_obj, gc_set_delta): DS.
* glob.c (glob_wrap): DS.
* hash.c (equal_hash, eql_hash, eq_hash, do_make_hash,
hash_equal, set_hash_traversal_limit, gen_hash_seed): DS.
* itypes.c (c_i8, c_u8, c_i16, c_u16, c_i32, c_u32, c_i64,
c_u64, c_short, c_ushort, c_int, c_uint, c_long, c_ulong): PS.
* lib.c (seq_iter_rewind): TS and becomes internal.
(seq_iter_init_with_info, seq_setpos, replace_str, less,
replace_vec, diff, isec, obj_print_impl): PS.
(nthcdr, equal, mkstring, mkustring, upcase_str, downcase_str,
search_str, sub_str, cat_str, scat2, scat3, fmt_join,
split_str_keep, split_str_set, trim_str, int_str, chr_int,
chr_str, chr_str_set, vector, vecref, vecref_l, list_vec,
copy_vec, sub_vec, cat_vec, lazy_str_put, lazy_str_gt,
length_str_ge, length_str_lt, length_str_le, cptr_size_hint,
cptr_int, out_lazy_str, out_quasi_str, time_string_local_time,
time_string_utc, time_fields_local_time, time_fields_utc,
time_struct_local, time_struct_utc, make_time, time_meth,
time_parse_meth): DS.
(init_str, cat_str_init, cat_str_measure, cat_str_append,
vscat, time_fields_to_tm, time_struct_to_tm, make_time_impl): TS.
* lib.h (seq_iter_rewind): Declaration removed.
(c_num, c_unum, init_str): Declarations updated.
* match.c (LOG_MISMATCH, LOG_MATCH): PS.
(h_skip, h_coll, do_output_line, do_output, v_skip, v_fuzz,
v_collect): DS.
* parser.c (parser, circ_backpatch, report_security_problem,
hist_save, repl, lino_fileno, lino_getch, lineno_getl,
lineno_gets, lineno_open): DS.
(parser_set_lineno, lisp_parse_impl): PS.
* parser.l (YY_INPUT): PS.
* rand.c (make_random_state): PS.
* regex.c (print_rec): DS.
(search_regex): PS.
* signal.c (kill_wrap, raise_wrap, get_sig_handler,
getitimer_wrap, setitimer_wrap): DS.
* socket.c (addrinfo_in, sockaddr_pack, fd_timeout,
to_connect, open_sockfd, sock_mark_connected,
sock_timeout): TS.
(getaddrinfo_wrap, dgram_set_sock_peer, sock_bind,
sock_connect, sock_listen, sock_accept, sock_shutdown,
sock_send_timeout, sock_recv_timeout, socketpair_wrap): DS.
* stream.c (generic_fill_buf, errno_to_string, stdio_truncate,
string_out_put_string, open_fileno, open_command, base_name,
dir-name): DS.
(unget_byte, put_buf, fill_buf, fill_buf_adjust,
get_line_as_buf, formatv, put_byte, test_set_indent_mode,
test_neq_set_indent_mode, set_indent_mode, set_indent,
inc_indent, set_max_length, set_max_depth, open_subprocess, run ): PS.
(fds_subst, fds_swizzle): TS.
* struct.c (make_struct_type, super, umethod_args_fun): PS.
(method_args_fun): DS.
* strudel.c (strudel_put_buf, strudel_fill_buf): DS.
* sysif.c (errno_wrap, exit_wrap, usleep_wrap, mkdir_wrap,
ensure_dir, makedev_wrap, minor_wrap, major_wrap, mknod_wrap,
mkfifo_wrap, wait_wrap, wifexited, wexitstatus, wifsignaled,
wtermsig, wcoredump, wifstopped, wstopsig, wifcontinued,
dup_wrap, close_wrap, exit_star_wrap, umask_wrap, setuid_wrap,
seteuid_wrap, setgid_wrap, setegid_wrap,
simulate_setuid_setgid, getpwuid_wrap, fnmatch_wrap,
dlopen_wrap): DS.
(chmod_wrap, do_chown, flock_pack, do_utimes, poll_wrap,
setgroups_wrap, setresuid_wrap, setresgid_wrap, getgrgid_wrap): PS.
(c_time): TS.
* sysif.h (c_time): Declaration updated.
* syslog.c (openlog_wrap, syslog_wrap): DS.
* termios.c (termios_pack): TS.
(tcgetattr_wrap, tcsetattr_wrap, tcsendbreak_wrap,
tcdrain_wrap, tcflush_wrap, tcflow_rap, encode_speeds,
decode_speeds): DS.
* txr.c (compato, array_dim, gc_delta): DS.
* unwind.c (uw_find_frames_by_mask): DS.
* vm.c (vm_make_desc): PS.
(vm_make_closure, vm_swtch): DS.
|
|
|
|
|
|
|
|
|
|
| |
maprodo is like maprod, but doesn't collect or return
anything. It's the Cartesian product analog of mapdo.
* eval.c (collect_nothing, maprodo): New static functions.
(eval_init): Register maprodo intrinsic.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
These functions convert any iterable to a list, vector or
string.
* eval.c (eval_init): Registered list-seq, vec-seq and str-seq
intrinsics.
* lib.c (list_seq, vec_seq, str_seq): New functions.
* lib.h (list_seq, vec_seq, str_seq): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The (each ()) form should infinitely loop, and the compiled
version does. The interpreter crashes, when that is a
top-level form. The reason is that the underlying sys:each-op
operator uses an empty list of variable names as an indication
to use the bindings from the parent lexical environment.
And in that particular case, the let is also empty. The
whole thing looks like:
(let () (sys:each-op each nil))
If this is a top-level expression, then op_let receives a null
environment pointer. Since it has no bindings to add, it
doesn't extend the environment chain and passes a null
environment pointer down to op_each, which that tries to use,
because it's told to reach into it for bindings.
Let's use the t symbol for that instead, so then the above
would look like:
;; the t and only the t means "access parent env"
(let () (sys:each-op each t))
And then, let's also fix it so that t is never used in this
case when there are no vars:
;; no t, and so don't access parent env.
(let () (sys:each-op each nil))
* eval.c (op_each): Get the bindings from the parent
environment if vars is t, rather than when it's null.
(me_each): When the symbols are not being inserted into the
sys:each-op form, then insert t to indicate that, rather than
nil. If the source form specifies an empty list of bindings,
then insert nil, not t.
* share/txr/stdlib/compiler.tl (expand-each): Get the list of
variable names from the parent lexical environment when vars
is t, rather than when it's null.
|
|
|
|
|
|
|
|
|
|
|
|
| |
The recent refactoring of the mapping functions to use
stack-allocated iterators has a bug. args_decl occurs inside a
loop. But args_decl uses alloca, which doesn't dispose of the
memory when the block scope terminates.
* eval.c (map_common, prod_common): Move the declaration of
args_fun outside of the loop, so that it is allocated just
once. The loop just stuffs fresh sets of values into the
arguments.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (map_common): Do not extract the arguments as a list.
Do not produce a list of iterator objects. Instead, allocate
an array of seq_iter_t objects on the stack using alloca, and
use these for walking the input lists in parallel. Do not cons
a list of the tuples coming from the lists, but rather store
the tuples into a struct args, also on the stack, and invoke
the function with that. Now, the only heap memory we allocate
is the resulting list being accumulated. In the case of mapdo,
no heap allocation takes place. However, if some of the inputs
are hashes, then hash iterators get allocated in seq_iter_init.
(mapcarv, mappendv, mapdov): Pass self argument to map_common,
needed for seq_iter_init.
|
|
|
|
|
|
| |
* eval.c (map_common): New static function.
(mapcarv, mappendv, mapdov): Now one-line wrappers
for map_common.
|
|
|
|
|
|
|
|
|
|
|
| |
The one list case of maprod reduces to mappend rather than
mapcar, so that [maprod identity '(1 2 3)] fails instead
of producing (1 2 3).
* eval.c (prod_common): Take pointer to mapping function to
use in one-list case, and use it.
(maprodv): Pass mapcarv to prod_common.
(maprendv): Pass mappendv to prod_common.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (get_iter_f): Renamed to iter_from_binding_f.
(iter_begin_f, iter_more_f, iter_item_f, iter_step_f): New
global variables.
(op_each): Follow rename of get_iter_f.
(mapcarv, mappendv, lazy_mapcar_func, lazy_mapcar,
lazy_mapcarv_func, lazy_mapcarv, mapdov, prod_common):
Convert from car/cdr/null-test iteration to iter-begin.
(eval_init): gc-protect and initialize new variables.
* lib.c (mapcar_listout, mappend, mapdo): Convert to seq_iter
iteration. List argument renamed to seq.
(mapcar): List argument renamed to seq.
* lib.h: Declarations updated with renamed arguments.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With this change we can do (each ((x vec)) ...) with
reasonable efficiency, because we are no longer marching
through the vector with cdr, copying the suffix.
* eval.c (get_iter_f): New global variable.
(op_each): Obtain iterators for all the objects with
iter_begin, instead of treating them as lists. Probe the
iterators for termination with iter_more, get the items with
iter_item instead of car and step with iter_step instead of
cdr.
(eval_init): gc-protect the get_iter_f function and initialize
it.
* share/txr/stdlib/compiler.tl (expand-each): Replace the
car/cdr and null testing with iter-init, iter-more, iter-item
and iter-step.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
iter-begin provides a paradigm for iteration that is more
compatible with lists. If the sequence is a list, then the
list itself is returned as the iterator, and the other
functions are basicaly wrappers for car/cdr and null testing.
Yet the API is defined in such a way that other objects can be
iterated with good efficiency, at the cost of allocating a new
iterator object (which can be re-used).
* eval.c (eval_init): Register iter-begin, iter-more,
iter-item, iter-step and iter-reset.
* lib.c (seq_iter_init_with_info): New static function.
(seq_iter_init): Now a thin wrapper for
seq_iter_init_with_info.
(iter_begin, iter_more, iter_item, iter_step, iter_reset): New
functions.
* lib.h (iter_begin, iter_more, iter_item, iter_step,
iter_reset): New functions.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Quasistrings compile to code that requires on the sys:fmt-join
function to glue strings together. Rewriting that function to
avoid converting its arguments from struct args * to a list.
* eval.c (fmt_join): Static function removed.
* lib.c (cat_str_measure, cat_str_append): more_p parameter
changed to int type, which better matches the C style Boolean
values it takes.
(fmt_join): New external function.
* lib.h: Declared.
* args.h (args_more_nozap, args_get_nozap): New inline
functions allowing multiple iterations over arguments without
making a copy.
|