| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Here we allow application code to take advantage of a trick
already used internally.
When a lazy cons cell is created, we can temporarily put
state information into its car and cdr fields.
When these fields are accessed normally, by the car and cdr
function, the lazy cons' update function will be invoked,
which will populate these fields.
If we have a way for that function to retrieve the existing
values of those fields, then the function can treat those
fields as state information: it can retrieve the values into
temporary local variables, overwrite the original values,
and then propagate the state information into the car and cdr
into the next lazy cons cell being added.
Thus lazy list generation that needs two cells of state or
less does not require the allocation of a context object.
* eval.c (eval_init): make-lazy-cons becomes a three-argument
function with two optional parameters. New functions
lcons-car and lcons-cdr are registered.
* lib.c (make_lazy_cons_pub): New function, wrapping
make_lazy_cons_car_cdr with argument defaulting.
(lcons_car, lcons_cdr): New functions.
* lib.h (make_lazy_cons_pu, lcons_car, lcons_cdr): Declared.
* txr.1: Updated doc of make-lazy-cons regarding new
arguments. Documented lcons-car and lcons-cdr.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.h (us_lcons_fun): New inline function.
(us_cons_bind): New macro.
* eval.c (lazy_mapcar_func, lazy_mapcarv_func, range_func,
range_star_func, generate_func, giterate_func, ginterate_func,
expand_right_fun, repeat_infinite_func, repeat_times_func,
pad_func): Use us_cons_bind, us_car, us_cdr, us_rplaca,
us_rplacd and us_lazy_cons_func, which skip the type check.
* lib.c (lazy_conses_func, lazy_appendv_func, rem_lazy_func,
lazy_flatten_func, lazy_flatcar_fund, tuples_func,
partition_by_func, partition_func, split_func,
split_star_func, partition_star_func, lazy_interpose_fun,
take_list_fun, take_while_list_fun, take_until_list_fun,
lazy_where_has_func): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register seq-begin, seq-next and
seq-reset.
* lib.c (seq_iter_s): New symbol variable.
(seq_iter_mark): New static function.
(seq_iter_ops): New static structure.
(seq_begin, seq_next, seq_reset): New functions.
(obj_init): Intern seq-iter symbol, used as class name for
iterators.
* lib.h (seq_iter_s, seq_begin, seq_next, seq_reset):
Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (do_expand): A wrong thing is being done here:
the macro is extended using the original parameter
syntax, that has not been processed by expand_params.
The body is then expanded using that environment.
This subtly breaks support for parameter macros in tree-bind.
They work, but there are spurious warnings about undefined
variables during expansion, and the wrong scope handling
can introduce bugs. The right thing is to derive new_menv
by pulling the parameter symbols from params_ex.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We don't want (fboundp '(lambda ...)) to be true, or
(symbol-function '(lambda ...)) to yield a function.
This also fixes funny print formatting of lambda
expressions.
* eval.c (lookup_fun): Do not recognize lambda expressions.
Also, return nil for unknown syntax; don't bother looking
it up in the hashes.
(do_eval): We now have to check for a lambda expression in the
car position to evaluate it; lookup_fun will no longer do
that.
(op_fun): The interpreted fun oprator must also check for
lambda itself.
(do_expand): A small code change is required here to avoid
spuriously warning about a lambda in the car position.
|
|
|
|
|
|
| |
* eval.c (fmakunbound, mmakunbound): Replace comma operator
with statement terminator, an unintentional stylistic
oddness. No behavior change.
|
|
|
|
|
|
|
|
|
| |
* eval.c (me_load_for): New function.
(rt_load_for): New static function.
(eval_init): Register load-for macro and sys:rt-load-for
intrinsic function.
* txr.1: Documented.
|
|
|
|
|
|
| |
* eval.c (usr_var_c): New symbol variable.
The existing var_s hold sys:var, not usr:var.
(eval_init): var symbol interned in usr package.
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (struct_s): Now defined here.
(eval_init): struct now interned here.
* eval.h (struct_s): Declared.
* ffi.c (struct_s): Definition removed.
(ffi_init) struct no longer interned here.
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register bracket intrinsic.
* lib.c (bracket): New function.
* lib.h (bracket): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
| |
* eval.c (me_pprof): Instead of emitting open code which
destructures the output of pprof and prints a diagnostic,
let's do that inside a run-time support function called
sys:rt-pprof, so (pprof x) now expands to (rt:pprof (prof x)).
(rt_pprof): New function.
(eval_init): Register sys:rt-pprof intrinsic.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The associative lists that make up the chains of a hash table
are guaranteed to be made of conses. We can use unsafe
versions of car, cdr, rplaca and rplacd to speed up hash
operations.
* eval.c (op_dohash): Use unsafe operations on hash cell.
* filter.c (trie_compress, regex_from_trie): Likewise.
* hash.c (hash_equal_op, hash_print_op, hash_mark, hash_grow,
hash_assoc, hash_assql, copy_hash_chain, gethash, inhash,
gethash_n, sethash, remhash, hash_next, maphash,
do_weak_tables, group_by, group_reduce, hash_keys_lazy,
hash_keys, hash_values_lazy, hash_values, hash_pairs_lazy,
hash_pairs, hash_alist_lazy, hash_uni, hash_diff,
hash_symdiff, hash_isec, hash_subset, hash_update,
hash_update_1, hash_revget): Likewise.
* lib.c (us_rplaca, us_rplacd): New functions.
(package_local_symbols, package_foreign_symbols, where,
populate_obj_hash, obj_hash_merge): Use unsafe operations on
hash cell
* lib.h (us_rplaca, us_rplacd): Declared.
* parser.c (circ_backpatch, get_visible_syms): Use unsafe
operations on hash cell.
* struct.c (method_name, get_slot_syms): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (env_fbind, env_vbind, reg_symacro): Use gethash_l
instead of gethash_c to eliminate repeated cdr operations
on the same cell.
* hash.c (sethash): Since new_p is never used, eliminated it
and use nulloc.
(group_reduce): Use gethash_l instead of gethash_c.
* lib.c (obj_init): Replace rplacd(gethash_c(...)) pattern
whose return value is not used with with sethash. We lose some
diagnosability here since sethash doesn't take a "self"
argument.
(obj_print_impl, obj_hash_merge): Use gethash_l instead of
gethash_c.
* parser.y (ensure_parser, parser_circ_def, get_visible_syms,
rlset): Use gethash_l instead of gethash_c.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register symdiff intrinsic.
* lib.c (symdiff): New function.
* lib.h (us_car_p, us_cdr_p): New inline functions.
(symdiff): Declared.
* txr.1: Documented, also fixing issues not related to
symdiff doc.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Also, these functions now support hashes.
* eval.c (eval_init): Register only the deprecated set-diff to
the set_diff function. The diff intrinsic is now going to the
new function named diff.
* lib.c (diff): New function.
(isec, uni): Rewritten to use seq_iter_t.
* lib.h (diff): Declared.
* txr.1: Documentation updated.
|
|
|
|
|
|
|
|
|
|
|
| |
The defvar/defparm macro expander marks symbols special only
at macro-expansion time, without actually generating code in
the macro expansion to do this. This means that the compiled
versions of defvar and defparm forms will code will neglect to
create a dynamically scoped variable!
* eval.c (me_def_variable): Add code to the output to mark the
symbol special, for defvar or defparm.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Adjust registrations of sum and prod to
be binary functions with an optional argument.
* lib.c (nary_op_keyfun, sumv, prodv): New static functions.
(sum, prod): Implement optional keyfun argument via sumv and
prodv helpers.
* lib.h (sum, prod): Declarations updated.
* txr.1: Documentation updated.
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (me_case): Replace a code generation pattern of the
(if (and x y) z) with the equivalent (and x y z). The
motivation behind this is that it effectively coaxes a
jump-threading optimization out of our simplistic compiler.
The failure cases out of a single *and* all jump past the
entire code block, whereas with the cascaded if + and we get
a double test of the same failed value threading through two
branches.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* LICENSE, LICENSE-CYG, METALICENSE, Makefile, args.c, args.h,
arith.c, arith.h, buf.c, buf.h, cadr.c, cadr.h, combi.c,
combi.h, configure, debug.c, debug.h, eval.c, eval.h, ffi.c,
ffi.h, filter.c, filter.h, ftw.h, gc.c, gc.h, glob.c, glob.h,
hash.c, hash.h, itypes.c, itypes.h, jmp.S, lib.c, lib.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/doloop.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/path-test.tl,
share/txr/stdlib/place.tl, share/txr/stdlib/pmac.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, txr.1, txr.c, txr.h,
unwind.c, unwind.h, utf8.c, utf8.h, vm.c, vm.h, vmop.h,
win/cleansvg.txr: Extended Copyright line to 2018.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The square function calulates (* x x) but is faster for bignum
integers by taking advantage of mp_sqr.
* arith.c (square): New function.
* eval.c (eval_init): Register square as intrinsic.
* lib.h (square): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* configure: Instead of generating a definition of ALLOCA_H,
generate the variable HAVE_ALLOCA_<name> with a value of 1,
where <name> is one of stdlib, alloca or malloc.
* alloca.h: New header.
* args.c, eval.c, ffi.c ffi.c, ftw.c, hash.c, lib.c, match.c,
parser.c, parser.y, regex.c, socket.c, stream.c, struct.c,
sysif.c, syslog.c, termios.c, unwind.c, vm.c: Include
"alloca.h" instead of ALLOCA_H.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The following situation can occur:
(defvar v expr) ;; expr throws!
What happens is that the internal hash table of global
variables ends up with an entry that has a nil value,
instead of the expected (v . <value>) cons cell.
The hash table entry is created when the table is probed
for the existence of v, but then is never populated
with a binding because expr throws.
The consequence then is that (boundp v) returns nil, yet
subsequent (defvar v ...) expressions think that v exists, and
refuse to define it. (defparm v ...) also fails; it relies on
(defvar ...) which fails to define the variable, and then
tries to assign to it, which throws.
* eval.c (rt_defvarl): If the hash table exists, but has a nil
value, treat that as an undefined variable. Thus, define the
variable not only if the hash cell is newly made, but also if
it already exists, with a null cdr.
|
|
|
|
|
|
|
|
|
|
| |
* arith.c (nzerop): New function.
* eval.c (eval_init): Register nzerop intrinsic.
* lib.h (nzerop): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The <dirent.h> header is included all over the place because
it is needed by a single declaration in stream.h. That
declaration is for a function that is only called within
stream.c, so we make it internal. Now only stream.c has
to include <dirent.h>.
* buf.c, debug.c, eval.c, ffi.c, filter.c, gc.c, gencadr.txr,
hash.c, lib.c, lisplib.c, match.c, parser.c, regex.c, socket.c,
struct.c, strudel.c, sysif.c, syslog.c, termios.c, txr.c,
unwind.c, vm.c: Remove #include <dirent.h>.
* cadr.c: Regenerated.
* stream.c (make_dir_stream): Make external function static.
* stream.h (make_dir_stream): Declaration updated.
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register in-range and in-range*
intrinsics.
* lib.c (in_range, in_range_star): New functions.
* lib.h (in_range, in_range_star): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
| |
* eval.c: Fix incorrect treatment of cases like
(caseql* ((a b) ...)). The check for evaluation must come
before we do the keys = car(keys) transformation. Also,
hash_keys must be updated to the evaluated keys, otherwise if
the hash table optimization is used, the table will contain
the original expressions as the keys, not their values.
|
|
|
|
| |
* eval.c (me_case): Throw error if the test form is missing.
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (me_case): When there are no keys, then it is
logically true that all keys are integer, and the hash table
logic kicks in. The minkey and maxkey variables are supposed
to be calculated as zero in that case, but the empty test is
bungled since nkeys doesn't test false when it is zero. We
end up with minkey and maxkey containing nil which get passed
to the minus function. And so, here we fix the empty test.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Reported by Guillaume le Vaillant.
* arith.c (logxor): Fix broken behavior when the arguments are
the same nonzero fixnum, or the same bignum object.
(logxor_old): New function: verbatim copy of previous logxor.
* eval.c (eval_init): Register logxor intrinsic to the broken
function if compatibility is 202 or less.
* txr.1: Compat note added.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With this patch, the compile function can handle interpreted
function objects that have captured environments.
For instance, if the following expression is evaluated
(let ((counter 0))
(labels ((bm () (bump))
(bump () (inc counter)))
(lambda () (bm))))
then a function object emerges. We can now feed this
function object to the compile function; the environment
will now be handled.
Of course, the above expression is already compileable;
compile-toplevel handles it and so does the file compiler.
This patch allows the expression to be interpreted and then
the function object to be compiled, without access to the
surrounding expression. The compiled function will contain a
compiled version of the environment, carrying compiled
versions of the captured variables and their contents.
* eval.c (env_vbindings, env_fbindings, env_next): New static
functions.
(eval_init): Register env-vbinding, env-fbindings and env-next
intrinsics.
* share/txr/stdlib/compiler.tl (sys:env-to-let): New function.
(usr:compile): Wrap the interpreted lambda terms with let
bindings carefully reconstructed from their captured
environments.
* txr.1: Documented new intrinsic functions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (deep_copy_env): New function.
(eval_init): Register copy-fun intrinsic.
* eval.h (deep_copy_env): Declared.
* lib.c (copy_fun): New function.
* lib.h (copy_fun): Declared.
* vm.c (vm_copy_closure): New function.
* vm.h (vm_copy_closure): Declared.
* txr.1: Documented copy-fun.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In this patch, the cobj_handle, cobj_ops and variants of
gethash get an additional argument to identify the caller.
Many functions are updated to pass this down.
* buf.c (buf_strm): Pass self name to cobj_handle.
* eval.c (env_fbind, env_vbind, rt_defvarl, me_case): Pass
self name to gethash_c or gethash_e.
(load): Pass self name to read_eval_stream and
read_compiled_file.
(reg_symacro): Pass situation-identifying string to gethash_c.
* ffi.c (ffi_type_struct_checked, ffi_closure_struct_checked,
ffi_call_desc_checked, uni_struct_checked):
Take self name parameter, and pass down to cobj_handle.
(ffi_get_type, ffi_get_lisp_type): Take self name and pass
down to ffi_type_struct_checked.
(union_get_ptr): Take self name and pass to
uni_struct_checked.
(ffi_union_in, ffi_union_put): Pass self name to union_get_ptr.
(ffi_type_compile): Pass self name to ffi_get_lisp_type.
(ffi_make_call_desc): Pass self name to
ffi_type_struct_checked, ffi_get_type and
ffi_call_desc_checked.
(ffi_make_closure): Pass self name to ffi_call_desc_checked.
(ffi_closure_get_fptr): Take self name, pass to
ffi_closure_struct_checked.
(ffi_typedef, ffi_size, ffi_alignof, ffi_offsetof,
ffi_arraysize, ffi_elemsize, ffi_elemtype, ffi_put_into,
ffi_put, ffi_in, ffi_get, ffi_out, make_carray): Pass self
name to ffi_closure_struct_checked.
(carray_struct_checked): Take self name, pass to cobj_handle.
(carray_set_length, carray_dup, carray_own, carray_free,
carray_type, length_carray, copy_carray, carray_ptr,
buf_carray, vec_carray, list_carray, carray_ref,
carray_refset, carray_sub, carray_replace, carray_get_common,
carray_put_common, unum_carray, num_carray, put_carray,
fill_carray): Pass self name to carray_struct_checked.
(carray_blank, carray_buf, carray_cptr): Pass self name
ffi_type_struct_checked.
(carray_pun): Pass self name to carray_struct_checked and
ffi_type_struct_checked.
(make_union): Pass self name to ffi_type_struct_checked.
(union_members, union_get, union_put, union_in, union_out):
Pass self name to uni_struct_checked.
(make_zstruct, zero_fill, put_obj, get_obj, fill_obj): Pass
self-name to ffi_type_struct_checked.
* ffi.h (ffi_closure_get_fptr, union_get_ptr): Declarations
updated.
* filter.c (trie_add): Pass self-name to gethash_l.
* hash.c (make_similar_hash, copy_hash, hash_count,
get_hash_userdata, set_hash_userdata, hash_begin, hash_next,
hash_uni, hash_diff, hash_isec): Pass self name
to cobj_handle.
(gethash_c, gethash_e): Take self name parameter and pass down
to cobj_handle.
(gethash_f): Take self parameter and pass down to gethash_e.
(gethash, inhash, gethash_n, sethash, pushhash, remhash,
clearhash, hash_update_1): Pass self name to gethash_e or gethash_c.
* hash.h (gethash_c, gethash_e, gethash_f): Declarations
updated.
(gethash_l): Take self name, and pass down to gethash_c.
* lib.c (class_check): Take self name parameter and use in
type mismatch diagnostic.
(use_sym, unuse_sym, symbol_needs_prefix, find_symbol,
intern, unintern, intern_fallback, unique, in, sel,
obj_print_impl, populate_obj_hash, obj_hash_merge): Pass self
name to gethash_f or gethash_l.
(symbol_visible, obj_init): Pass situation-identifying string
to gethash_e.
(cobj_handle, cobj_ops): Take self name parameter and pass
down to class_check.
* lib.h (class_check, cobj_handle, cobj_ops): Declarations
updated.
* match.c (v_load): Pass self name to read_compiled_file and
read_eval_stream.
* parser.c (get_parser_impl): Take self name and pass to
cobj_handle.
(ensure_parser): Pass situation-identifying string to
gethash_c.
(parser_circ_def): Pass self-name to gethash_c.
(lisp_parser_impl): Pass self name to get_parser_impl and
class_check.
(lisp_parse, nread, iread): Pass self-name to lisp_parser_impl.
(read_file_common): Take self name parameter and pass down to
get_parser_impl.
(read_eval_stream, read_compiled_file): Take self name and
pass down to read_file_common.
(load_rcfile): Pass situation-identifying string to
read_eval_streem.
(get_visible_syms): Pass situation-identifying string to
gethash_c.
(parser_errors, parser_eof): Pass self name to cobj_handle.
* parser.h (read_eval_stream, read_compiled_file):
Declarations updated.
* parser.y (rlset): Pass self name to gethash_c.
* rand.c (make_random_state, random_state_get_vec,l
random_fixnum, random_float): Pass self name to cobj_handle.
* regex.c (regex_source, regex_print, regex_run): Pass
self-name to cobj_handle.
(regex_machine_init): Take self name param and pass to
cobj_handle.
(search_regex, match_regex, match_regex_right,
regex_prefix_match, read_until_match): Pass self-name to
regex_machine_init.
* stream.c (stdio_get_fd): Pass self name to cobj_handle.
(generic_get_line): Get COBJ operations via unsafe, diret
object access rather than cobj_ops.
(set_mode_props): Get object handle via unsafe, direct object
access.
(stream_fd, sock_family, sock_type, sock_peer, set_sock_peer,
get_string_from_stream, get_list_from_stream, stream_set_prop,
stream_get_prop, close_stream, get_error, get_error_str,
clear_error, get_line, get_char, get_byte, unget_char,
unget_byte, put_buf, fill_buf, put_string, put_char, put_byte,
flush_stream, seek_stream, truncate_stream, get_indent_mode,
test_set_indent_mode, set_indent_mode, get_indent, set_indent,
inc_indent, width_check, force_break, get_set_ctx, get_ctx):
Pass self name to cobj_ops.
(make_delegate_stream): Take self name parameter, pass down to
cobj_ops.
(record_adapter): Pass self name down to make_delegate_stream.
(format): Pass self name to class_check.
* struct.c (stype_handle): Pass self name to cobj_handle.
(make_struct_type): Pass self name to class_check.
* txr.c (read_eval_stream_noerr): Take self name parameter,
pass to read_eval_stream.
(txr_main): Pass istuation-identifying string to
read_compiled_file and read_eval_stream_noerr.
* unwind.c (revive_cont): Pass self-name to cobj_handle.
* vm.c (vm_desc_struct): Take self name parameter, pass to
cobj_handle.
(vm_desc_nlevels, vm_desc_nregs, vm_desc_bytecode,
vm_desc_datavec, vm_desc_symvec, vm_execute_toplevel,
vm_execute_closure, vm_closure_entry): Pass self name to
vm_desc_struct.
(vm_closure_struct): Take self name parameter, pass to
cobj_handle.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* arith.c (flo_int): Pass down name to type_check.
* eval.c (copy_env, env_fbind, env_vbind, env_vb_to_fb,
func_get_name, lexical_var_p, lexical_fun_p,
lexical_lisp1_binding, squash_menv_deleting_range, op_upenv):
Pass relevant Lisp function name to type_check.
(lookup_global_var, lookup_sym_lisp1, lookup_fun, lookup_mac,
lookup_symac, lookup_symac_lisp1): For these widely used
functions, pass situational prefix in place of function name.
They may get a funtion name argument in the future.
* gc.c (gc_finalize): Pass function name to type_check.
* lib.c (throw_mismatch): Take function nme argument,
incorporate into mesage.
(lcons_fun, c_flo, string_extend, symbol_name, symbol_package,
get_package, package_name, func_get_form, func_get_env,
func_set_env, vec_set_length, length_vec, size_vec, list_vec,
lay_str_force, lay_str_force_upto, lazy_str_get_trailing_list,
from, too, set_from, set_to): Pass relevant Lisp function name
to type_check.
(symbol_setname, symbol_visible): Pass indication of internal
error into type_check, since this doesn't pertain to any Lisp
function being wrong.
* lib.h (throw_mismatch): Declaration updated.
(type_check): Take new parameter and pass down to
throw_mismatch.
* signal.c (set_sig_handler): Pass name down to type_check.
|
|
|
|
|
| |
* eval.c (load): Consume the first line of the input file if
it starts with hash bang.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The functions sys:expand, sys:expand* and
sys:expand-with-free-refs are now in the usr package and
documented for public use.
* eval.c (eval_init): Move registrations of the symbools
expand, expand* and expand-with-free-refs from the
system package to the user package.
* share/txr/stdlib/awk.tl (sys:awk-mac-let, awk): Uses of
sys:expand drop the sys: prefix.
* share/txr/stdlib/op.tl (sys:op-alpha-rename): Likewise.
* share/txr/stdlib/place.tl (call-upudate-expander,
call-clobber-expander, call-delete-expander, sys:placelet-1):
Likewise.
* tests/011/macros-2.txr, tests/012/struct.tl: Likewise.
* txr.1: Documented expand, expand* and expand-with-free-refs.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Now that the compiler has a more efficient treatment of global
lexical variables, code which accesses global variables that
have not yet been defined will misbehave if the intent is to
for those variables to be dynamically scoped.
There is such a bug in the op expander, in fact.
* eval.c (me_def_variable): When defvar/defparm are expanding,
they now check whether there is an outstanding unbound warning
against the variable. If so, then a warning is issued that the
variable was previously used lexically and is now being marked
special.
* unwind.c (uw_warning_exists): New function.
* unwind.h (uw_warning_exists): Declared.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Like in some other Lisp dialects, evaluation of top-level
forms should deal with forms like:
(progn (defmacro a () 42) (a))
where the (a) will correctly reference the macro earlier
in the progn.
* eval.c (eval_only_s, compile_only_s): New symbol variables.
(expand_eval): New static function, based on previous code of
eval_intrinsic.
(eval_intrinsic): Rewritten to perform incremental
macroexpand, similarly to compile-file, and recurse. If a
form, after macro-expansion, is a progn, eval-only or
compile-only, then its constituents are individually evaluated
through expand_eval as separate forms: each one is fully
expanded and evaluated before the next one is processed. If
the form isn't a progn, eval-only or compile-only, then it is
treated as a single expansion and evaluation.
(eval_init): Initialize new symbol variables and use their
values in registering their respective operators.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (opip_s, oand_s, chain_s, chand_s): Variables
removed.
(me_opip): Function removed.
(eval_init): Initializations of removed variables removed.
chain and chand symbols interned at point of function
registration.
* lisplib.c (op_set_entries): Add autoload entries for opip
and oand.
* share/txr/stdlib/op.tl (sys:opip-expand): New function.
(opip, oand): New macros.
* protsym.c: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The op macro is no longer written in C, but the trivial macros
ap, ip, ado, ido, ret and aret are still C. It's silly to
have macros written in C, baked into the TXR executable, which
just produce syntax for a complicated macro written in Lisp
that must be autoloaded when that code is used.
* eval.c (ap_s, apf_s, ipf_s, ret_s, aret_s): Variables removed.
(me_ap, me_ip, me_ado, me_ido, me_ret_aret): Functions removed.
(eval_init): Do not initialize removed variables. Remove
registration for macros ap, ip, ado, ido, ret and aret.
Intern the apf and ipf symbols in the same expression
which registers these functions.
* lisplib.c (op_set_entries): Add autoload entries for ap,
ip, ado, ido, ret and aret.
* share/txr/stdlib/op.tl (ap, ip, ado, ido, ret, aret):
New macros.
* protsym.c: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a function binding is removed using fmakunbound, virtual
machine descriptions hang on to the previously cached binding
in the ftab. When the symbol is newly bound, virtual machine
descriptions keep pointing to the old function.
To solve this, we put the vm_desc structures into a global
list and provide a function that fmakunbound calls to scrub
all the VM descriptors of that binding.
* eval.c (makunbound, fmakunbound): Call new
vm_invalidate_binding function.
* vm.c (struct vm_desc_links): New structure.
(struct vm_desc): New member lnk, with links.
(vmd_list): New static variable: circular list of all VM
descriptors.
(vm_make_desc): Insert new VM descriptor into list.
(vm_desc_destroy): Remove VM descriptor from list.
(vm_invalidate_binding): New function.
* vm.h (vm_invalidate_binding): Declared.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is in ANSI CL; potentially useful and hard to
implement efficiently in user code.
* arith.c (logcount): New function.
* eval.c (eval_init): Register logcount intrinsic.
* lib.h (logcount): Declared.
* mpi/mi.c (s_mp_count_ones): New static function.
(mp_count_ones): New function.
* mpi/mpi.h (mp_count_ones): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It looks like I neglected to treat dynamically scoped
variables in destructuring; all parameters are treated as
lexical. This is only true in interpreted code; compiled
destructuring treats dynamics properly because it generates a
let to bind all the variables which occur, and then uses
assignment to populate them.
* eval.c (bind_macro_params): Instead of env_vbind, use the
newly introduced lex_or_dyn_bind helper function.
(op_tree_bind, op_mac_param_bind): Save and restore dyn_env
around bind_macro_params and the evaluation of the associated
body. In op_defmacro, this is already done.
|
|
|
|
|
|
|
|
| |
* eval.c (lex_or_dyn_bind_seq, lex_or_dyn_bind): New static
functions.
(bind_args): Eliminate repeated code using new helper
functions. One wrong repetitions is thereby fixed also: a
a neglected check of dyn_env_made.
|
|
|
|
|
|
|
|
|
| |
* eval.c (expand_opt_params_rec, expand_params_rec): Remove
pspecials argument, and accumulation of the special
variables. The caller doesn't use this list any more.
(expand_params): Remove unused specials local variable whose
address was passed as the pspecials argument to
expand_params_rec.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In this patch we eliminate the special operator
sys:with-dyn-rebinds, and implement correct semantics for
dynamically scoped variables that occur in argument
lists.
* eval.c (with_dyn_rebinds_s): Symbol variable removed.
(bind_args): Handle special variables dynamically:
for each symbol that appears, check whether it is a special
and treat accordingly by allocating a new dynamic environment
if necessary, and binding in that environment.
This adds overhead, which is why I moved away from this
approach in the past. But now that there is a compiler,
overhead in the interpreter matters less. Correct semantics
is more important.
(expand_params): Greatly simplified for not having to wrap the
sys:with-dyn-rebinds operator around the body.
(funcall_interp): Since bind_args can now extend the dynamic
environment, it is necessary to save and restore dyn_env
around it. Another call to bind_args occurs in op_catch;
that already saves and restores dyn_env.
(op_with_dyn_rebinds): Static function removed.
(do_expand): with-dyn-rebinds-s case removed.
(eval_init): Removed interning of sys:with-dyn-rebinds
symbol and registration of special op.
* protsym.c: Regenerated.
* compiler.tl (compiler compile): Remove case which handles
sys:with-dyn-rebinds.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Change ca6199a that went into TXR 191 was over-zealous in suppressing
expand_param_rec calls for non-macro argument processing. The recursive
calls are needed in order to detect parameters that are special
variables and add them to pspecials. The upshot is that usage such as
the following broke: (lambda (*stdout*) ...) because expand_param_rec
isn't called on the *stdout* symbol and *stdout* is thus not noted as a
special variable, and thus the expander then neglects to produce
(sys:with-dyn-rebinds (*stdout*) ...) around the body of the lambda.
The new compiler introduced at the same time made this harder
to find. Why? Because the compiler ignores the
sys:with-dyn-rebinds special form; it implements its own
handling for specials in lambda and let! So compiled code is
unaffected by this regression.
* eval.c (expand_opt_params_rec): Call expand_params_rec on the
car of the optional var-init pair, whether or not expanding a macro
style parameter.
(expand_params_rec): Call expand_params_rec recursively on any parameter
that is bindable whether or not in macro mode. The two cases fold
together again, and so here we see that the recent fix d934a3e was also
a regression caused by ca6199a.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|