| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
| |
* configure: Use pointer-based test for timegm, because
-Werror=implicit-function-declaration does not work in the
gcc 4.2 used on FreeBSD 9.
* parser.l: Check for Flex 2.5.9 and earlier which don't
have yylex_destroy. Thanks to Marcus Breiing.
|
|
|
|
|
|
|
|
|
| |
/usr/bin/xpg4/sh shell. Solaris' /bin/sh does not like test
-e. Adding break to the new shell existence testing loop so we
use the first shell in the list. Solaris wants _XOPEN_SOURCE=500
to reveal certain functions. Fix breakage in the make utility
detection, and also use the $make variable everywhere instead
of make.
|
|
|
|
|
|
|
| |
We boostrap using #!/bin/sh, but try to detect a better shell
and re-execute the script with that shell. Furthermore, we now
set up the SHELL variable in config.make, so that make uses that
shell for executing build recipes.
|
|
|
|
|
|
| |
(op_dwim, dwim_locs): Removing silly logic of separately calling
eval_lisp1 on the functor, and eval_lisp1_args on its arguments, since
lisp1 evaluation treats all position the same way.
|
|
|
|
|
|
|
|
|
|
|
|
| |
it to be the cell, rather than the new value.
* eval.c (transform_op): Fix use of rplacd that uses return value.
(force): Likewise.
* lib.c (rplaca, rplacd): Return cons.
(rem_lazy_rec, obj_init): Fix use of rplacd that uses return value.
* txr.1: Documented.
|
|
|
|
|
|
|
|
| |
* eval.c (call): New static function.
(eval_args, op_call): Static functions removed.
(eval_init): call_s registered as operator rather than function.
* txr.1: Updated.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
some places. In particular, the test case
echo : | ./txr -c '@a:@a' -
breaks because of neglected LIT in do_match_line.
* arith.c (tofloat, toint): Handle LIT type in switch.
* lib.c (ref, refset, replace, update): Handle LSTR type.
* match.c (do_match_line, do_output_line): Handle LSTR and LIT
objects in switch.
|
|
|
|
| |
optional argument defaulting logic.
|
|
|
|
| |
headers.
|
|
|
|
| |
colon symbol.
|
|
|
|
| |
equivalence comparison for end test, rather than eql.
|
|
|
|
|
| |
Two objects which are equal floating-point values must be considered
eql even if they are distinct objects (not eq).
|
| |
|
|
|
|
|
| |
to 8 * HEAP_SIZE from 2 * HEAP_SIZE to reduce frequency
of garbage collections.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
GC. The issue being solved here is the accuracy of the gc_set function.
The existing impelmentation is too conservative. It has no generation
information about the memory location being stored, and so it assumes
the worst: that it is a location in the middle of a gen 1 object.
This is sub-optimal, creating unacceptable pressure against the
checkobj array and, worse, as a consequence causing unreachable gen 0
objects to be tenured into gen 1.
To solve this problem, we replace "val *" pointers with a structure
of type "loc" which keeps track of the object too, which lets us
discover the generation.
I tried another approach: using just a pointer with a bitfield
indicating the generation. This turned out to have a serious issue:
such a bitfield goes stale when the object is moved to a different
generation. The object holding the memory location is in gen 1, but the
annotated pointer still indicates gen 0. The gc_set function then
makes the wrong decision, and premature reclamation takes place.
* combi.c (perm_init_common, comb_gen_fun_common,
rcomb_gen_fun_common, rcomb_list_gen_fun): Update to new interfaces
for managing mutation.
* debug.c (debug): Update to new interfaces for managing mutation.
Avoid loc variable name.
* eval.c (env_fbind, env_fbind): Update to new interfaces
for managing mutation.
(lookup_var_l, dwim_loc): Return loc type and update to new interfaces.
(apply_frob_args, op_modplace, op_dohash, transform_op, mapcarv,
mappendv, repeat_infinite_func, repeat_times_func): Update to new
interfaces for managing mutation.
* eval.h (lookup_var_l): Declaration updated.
* filter.c (trie_add, trie_compress, trie_compress_intrinsic,
* build_filter, built_filter_from_list, filter_init): Update to new
* interfaces.
* gc.c (gc_set): Rewritten to use loc type which provides the exact
generation. We do not need the in_malloc_range hack any more, since
we have the backpointer to the object.
(gc_push): Take loc rather than raw pointer.
* gc.h (gc_set, gc_push): Declarations updated.
* hash.c (struct hash): The acons* functions use loc instead
of val * now.
(hash_equal_op, copy_hash, gethash_c, inhash, gethash_n, pushhash,
Change to how locations are passed around, for the sake of generational
GC. The issue being solved here is the accuracy of the gc_set function.
The existing impelmentation is too conservative. It has no generation
information about the memory location being stored, and so it assumes
the worst: that it is a location in the middle of a gen 1 object.
This is sub-optimal, creating unacceptable pressure against the
checkobj array and, worse, as a consequence causing unreachable gen 0
objects to be tenured into gen 1.
To solve this problem, we replace "val *" pointers with a structure
of type "loc" which keeps track of the object too, which lets us
discover the generation.
I tried another approach: using just a pointer with a bitfield
indicating the generation. This turned out to have a serious issue:
such a bitfield goes stale when the object is moved to a different
generation. The object holding the memory location is in gen 1, but the
annotated pointer still indicates gen 0. The gc_set function then
makes the wrong decision, and premature reclamation takes place.
* combi.c (perm_init_common, comb_gen_fun_common,
rcomb_gen_fun_common, rcomb_list_gen_fun): Update to new interfaces
for managing mutation.
* debug.c (debug): Update to new interfaces for managing mutation.
Avoid loc variable name.
* eval.c (env_fbind, env_fbind): Update to new interfaces
for managing mutation.
(lookup_var_l, dwim_loc): Return loc type and update to new interfaces.
(apply_frob_args, op_modplace, op_dohash, transform_op, mapcarv,
mappendv, repeat_infinite_func, repeat_times_func): Update to new
interfaces for managing mutation.
* eval.h (lookup_var_l): Declaration updated.
* filter.c (trie_add, trie_compress, trie_compress_intrinsic,
* build_filter, built_filter_from_list, filter_init): Update to new
* interfaces.
* gc.c (gc_set): Rewritten to use loc type which provides the exact
generation. We do not need the in_malloc_range hack any more, since
we have the backpointer to the object.
(gc_push): Take loc rather than raw pointer.
* gc.h (gc_set, gc_push): Declarations updated.
* hash.c (struct hash): The acons* functions use loc instead
of val * now.
(hash_equal_op, copy_hash, gethash_c, inhash, gethash_n, pushhash,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* gc.c (make_obj): If we have room in the freshobj array,
but are out of objects, then call more. Without this,
we don't take proper advantage of this nursing area.
(gc): Set the full_gc flag after doing gc, in preparation
for next time. If we know full GC is coming, we can
adjust some behaviors. Increase the threshold for calling the more()
function to be the same as in the non-generational case:
less than 3/4 of the size of a heap scavenged.
(gc_set): Now does nothing if it is known that
a full gc is coming. Also, in the checkobj array overflow
case when we invoke gc, there is no point in adding obj
to the array, since it must have been promoted to the mature
generation.
(gc_mutated): Don't bother storing the object in the
array if a full GC is coming.
|
|
|
|
|
| |
struct tm from "GMT" to "UTC", so that the time_string_utc
function will use UTC for the %Z format.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
checkobj array (via the mut macro that expands to gc_mutated).
The garbage collector assumes that checkobj has only generation 0
objects, which all exist in the freshobj array, which is subject
to a sweep. So gen 1 objects in checkobj are never cleaned up
properly: they do not have their REACHABLE flag reset, or
their generation restored to 1. To fix this, a new array for these
objects is introduced separate from checkobj.
* gc.c (MUTOBJ_VEC_SIZE): New preprocessor symbol.
(mutobj, mutobj_idx): New static array and integer.
(mark_obj): Check for REACHABLE flag before checking the full_gc
flag and generation, since those cost additional memory accesses.
(mark): Mark the objects in the new mutobj array.
(sweep): Sweep the objects in the mutobj array.
(gc): Reset mutobx_idx to zero after gc.
(gc_set): Rearrange logic. In the case that the checkobj array
is full and a gc is done to make room, there is no point in
adding to the array: the gc pass moves all babies to generation 1,
so the object that was passed into the function is no longer a baby.
(gc_mutated): Rewrite in terms of mutobj rather than checkobj,
fixing the bug.
* HACKING: Improved documentation of GC. Describe mut macro
and mutobj array.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* combi.c (perm_init_common, comb_gen_fun_common,
rcomb_gen_fun_common): Use set macro instead of plain assignment.
* hash.c (hash_grow, copy_hash, hash_update_1): Use set macro
instead of plain assignment.
* lib.c (nreverse, lazy_appendv_func, lazy_appendv,
vec_push, refset): Use set macro instead of plain assignment.
(make_package): Assign all fields of the newly created PKG
object before calling a function which can trigger GC.
* parser.y (rlset): Use set macro.
|
|
|
|
|
|
|
|
|
|
| |
in in 2014-03-12, when prof was introduced.
The attempt to fix a bug made things worse.
* lib.c (adjust_bounds): New static function.
(chk_malloc, chk_calloc, chk_realloc): Replace existing logic with
call to adjust_bounds.
(chk_malloc_gc_more): Bugfix: add missing call to adjust_bounds.
|
|
|
|
| |
* txr.vim: Regenerate.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(eval_init): Register me_quasilist as quasilist macro expander.
* lib.c (quasilist_s): New global variable.
(obj_init): quasilist_s initialized.
* lib.h (quasilist_s): Declared.
* match.c (do_txreval): Handle quasilist syntax.
* parser.l (QWLIT): New exclusive state.
Extend lexical grammar to transition to QWLIT state upon
the #` or #*` sequence which kicks off a word literal,
and in that state, piecewise lexically analyze the QLL,
mostly by borrowing rules from quasiliterals.
* parser.y (QWORDS, QWSPLICE): New tokens.
(n_exprs): Integrate splicing form of QLL syntax.
(n_expr): Integrate non-splicing form of QLL syntax.
(litchars): Propagate line number info.
(quasilit): Fix "string literal" wording in error message.
* txr.1: Introduced WLL abbreviation for word list literals,
cleaned up the text a little, and documented QLL's.
|
|
|
|
|
| |
to macro-expand the embedded forms in a quasiliteral except
when they are the very first item.
|
|
|
|
| |
types WORDS and WSPLICE.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* parser.l (WLIT): New exclusive start state.
Extend lexical grammar to transition to WLIT state upon
the #" or #*" sequence which kicks off a word literal,
and in that state, piecewise lexically analyze the literal,
mostly by borrowing rules from other literals.
* parser.y (WORDS, WSPLICE): New tokens.
(n_exprs): Integrate splicing form of word list literal syntax.
(n_expr): Integrate non-splicit for of word list literal syntax.
(litchars): Propagate line number info.
(wordslit): New grammar rule.
* txr.1: Updated.
|
|
|
|
|
|
|
|
| |
* lib.c (last): New function.
* lib.h (last): Declared.
* txr.1: Documented last.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (copy): Bugfix: handle lazy strings. Also, handle hash
tables via copy_hash.
(length): Bugifx: handle lazy strings. Also, handle hash tables
via hash_count.
(empty): New function.
* lib.h (empty): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
| |
(me_unless, me_while, m_until): New static functions.
(eval_init): Register macros unless, while and until.
* txr.1: Document unless, while and until.
|
| |
|
|
|
|
| |
2014-03-14 changes.
|
|
|
|
|
|
| |
(eval_init): Register "when" macro.
* txr.1: Documented when macro.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Here were are changing the output clause to recognize all special
clause tokens that are not used in output and turning them into
regular Lisp. So @(if a b c) in an output clause works once again,
recognized as IF exprs_opt ')' syntax, and turned into Lisp. Other
things work that didn't work before like @(and), @(or) and so forth.
* parser.y (make_expr): New static function.
(not_a_clause): New nonterminal.
(out_clause): Remove error-catching productions for match-side
clauses.
(o_elems): Now consists of a mixture of o_elems and not_a_clause's.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
within quasiliterals. This has been a problem for years.
Quasiliteral strings existed very early before TXR Lisp was introduced.
So it made sense that when @ is seen in a quasiliteral, the
lexical analyzer pushed into the SPECIAL state in which directives
are recognized, like in the pattern language. I noticed
this because there is an @(if) directive now, which prevents
`@(if ...)` from being valid.
* parser.l (QSPECIAL): New scanner state. This is a state
similar to SPECIAL that we enter into when @ is seen in a QSLIT state.
In this state we recognize constructs like braced variables, but not
certain other features like directives.
|
| |
|
|
|
|
|
|
|
|
|
| |
* arith.h (tofloat, toint): Declared.
* eval.c (eval_init): tofloat and toint registered
as intrinsics.
* txr.1: Documented.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
passing escaped arguments to Microsoft's popen and system
functions. The first argument cannot be quoted, but the
subsequent ones can. It is the quoting of the first argument
that causes the whole thing to be quoted. So we just
avoid quoting the first argument. (If it has spaces, too bad;
don't do that).
(open_process): Fix neglected optional argument handling
in Windows version of this function.
|
|
|
|
| |
* stream.c (run): Implement using _wspawnvp on MinGW.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
in the SPECIAL, NESTED and BRACED states, do not pop the state in all
three, only in SPECIAL (to terminate the @\ continuation).
* txr.1: Eliminate wrong claim that string literals do not split across lines,
which is directly contradicted two paragraphs later. Document that
quasiliterals also split.
* genvim.txr (txr_regex, txl_regex): These definitions change from "syn match"
to "syn region" so that the backslash-newline continuation can be properly
handled.
(txr_string, txr_quasilit): Correctly handle split literals.
* txr.vim: Regenerated.
|
|
|
|
|
|
| |
to be a text.
* txr.1: Documented @(empty).
|
|
|
|
|
|
|
|
| |
optional arguments. This problem can cause the symbol : to be
planted as the std_error stream, resulting in an error loop
that blows the stack.
* regex.c (regex_compile): Likewise.
|
|
|
|
|
| |
have similar functions in the MSVCRT library used by MinGW,
so if _WIN32 is defined, our functions now just wrap those.
|
|
|
|
| |
work right with arguments, though: the win command line is broken.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* rand.c (make_random_state): Do argument defaulting on seed.
Also, mix getpid() into the seed.
(random_fixnum): Bugfix: do proper defaulting on optional
agument, rather than relying on nil.
(random): Fix 2014-02-05 regression. This was totally broken,
ignoring the random state passed in and using the global
random state. This function must only use the state passed in;
there is no defaulting to the global random state.
* txr.1: Documenting that seed is optional in make-random-state.
Describing what guarantees can be expected with regard to
calls made close together temporally.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Input side for now; output later.
* parser.y (if_clause, elif_clauses_opt, else_clause_opt): New nonterminals.
(IF, ELIF, ELSE): New tokens.
(yybadtoken): Handle IF, ELIF, ELSE.
* parser.l: Recognize and return new tokens IF, ELIF and ELSE.
* txr.1: Documented.
* genvim.txr: Updated with if, elsif and else directive keywords.
* txr.vim: Regenerated
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
segmentation fault that occurs when running out of stack space,
and escape by throwing an exception.
Also, bugfix: save and restore the gc enable/disable state. Without
this, if we are ever running cod in a gc disabled state and it jumps
out, gc stays disabled.
* configure: added check for sigaltstack.
* gc.h (gc_enabled): Declaration added for existing variable.
* signal.c (is_cpu_exception): New static function.
(sig_handler): For cpu_exception type signals that pertain
to the execution of some instruction, turn on async_sig_enabled,
so that the signal is not deferred. Otherwise we will just
return without calling the user-defined handler, restart
the instruction and get into a loop. Also, disable gc around
the handler just in case. One issue is that we might be on
an alternate stack, which gc won't like.
(setup_alt_stack, teardown_alt_stack): New static functions.
(set_sig_handler): If we have sigaltstack, and are asked
to set up a SEGV handler, then set it up on the alternate
stack.
* signal.h (extended_jmp_buf): Adding new member, gc.
(extended_setjmp, extended_longjmp): use gc member
to save and restore the gc_enable state across
setjmp and longjmp.
|
|
|
|
|
|
| |
exit status.
(sh, run): New static functions.
(stream_init): sh and run registered as intrinsics.
|