| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_bit): New function.
(buf_init): Register buf_bit intrinsic.
* buf.h (buf_bit): Declared.
* tests/012/buf.h: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_bitset): New function.
(buf_init): Register buf-bitset intrinsic.
* buf.h (buf_bitset): Declared.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_not, buf_trunc): New functions.
(buf_init): Register buf-not and buf-trunc intrinsics.
* buf.h (buf_not, buf_trunc): Declared.
* tests/012/buf.h: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_and, buf_or, buf_xor): New functions.
(buf_init): buf-and, buf-or and buf-xor intrinsics registered.
* buf.h (buf_and, buf_or, buf_xor): Declared.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_fash): New function.
(buf_init): buf-fash intrinsic registered.
* buf.h (buf_fash): Declared.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (err_oflow): New static function.
(buf_compress): Use err_oflow.
(buf_ash): New function.
(buf_init): Register buf-ash intrinsic.
* buf.h (buf_ash): Declared.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_put_buf): Fix incorrect argument order, contrary
to documentation and inconsistent with other buf-put-* functions.
(compat_buf_put_buf): New static function. Detects wrong
argument order and swaps.
(buf_init): Register buf-put-buf intrinsic to new
static function. Thus buf-put-buf conforms to the documentation,
but also works if called with the incorect old argument order.
* test/012/buf.tl: New tests.
* txr.1: Documentation added to clarify behaviors when put
operation is out of the range of the destination buffer.
|
|
|
|
|
|
|
|
|
| |
* eval.c (do_progf, progf): New static functions.
(eva_init): Register progf intrinsic.
* tests/012/callable.tl: New test.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.[ch] (do_juxt, juxtv): Functions removed.
* eval.c (do_callf): New static function.
Implements callf without consing up an
argument list with juxt which is then applied
to the function. It's all done with a loop
which builds args on the stack.
(callf): Rewritten to use do_callf. We have
to convert the function list to dynamic
args, but that is more compact than all the
consing done by the removed juxt implementation.
(juxt): New static function: implemented trivially
using callf and list_f.
(eval_init): Change registration from removed juxtv
to juxt. Going forward, I won't be using the v
suffix on functions. That should only be used when
two versions of a function exist: one which takes
vargs, and one which takes C variable arguments
or something else like a list. Example: format
is a variadic C function with a ... in its
argument list. formatv takes a varg and is the
main implementation. vformat takes a va_list.
Leading v is the standard C convention, like
vsprintf. trailing v is the TXR convention for
a function that takes vargs, but only if it is
an alternative to one which doesn't.
|
|
|
|
|
| |
* tests/012/infix.tl (fft): express loop condition
more succinctly as a relational compound.
|
|
|
|
|
|
|
|
|
| |
* stdlib/infix.tl (infix-expand-hook): Do not process
the interior of square bracket forms; jsut pass
them through. Of course, square brackets continue to
denote postfix array indexing.
* txr.1: Updated and revised.
|
|
|
|
|
|
| |
* sysif.c (setenv_wrap): Throw an error if setenv returns
negative, rather than sweeping the error under the carpet
and adding the variable to our hash.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It is undesirable to translate (1 fun) into (fun 1).
Only cases similar to these patterns, using list
as an example:
(1 list 2) -> (list 1 2)
(1 list 2 3) -> (list 1 2 3)
(1 list 2 + 3) -> (list 1 (+ 2 3))
(list 2 3) -> (list 2 3)
(list 2 + 3) -> (list (+ 2 3))
* stdlib/infix.tl (infix-expand-hook): Restrict the phony
infix case to three or more elements.
* txr.1: Update phony infix case 1 as requiring three
or more elements. Also add (1 list) example emphasizing
that it's not recognized.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit extends infix with a post-processing step
applied to the output of parse-infix which improves
the code, and also implements math-like semantics for
relational operators, which I'm calling superfix.
Improving the code means that expressions like a + b + c,
which turn into (+ (+ a b) c) are cleaned up into
(+ a b c). This is done for all n-ary operators.
superfix means that clumps of certain operators
behave as a compound. For instance a < b <= c
means (and (< a b) (<= b c)), where b is evaluated
only once.
Some relational operators are n-ary; for those we
generate the n-ary expression, so that
a = b = c < d becomes (and (= a b c) (< c d)).
* stdlib/infix.tl (*ifx-env*): New special variable.
We use this for communicating the macro environment
down into the new finish-infix function, without
having to pass a parameter through all the recursion.
(eq, eql, equal, neq, neql, nequal, /=, <, >, <=, >=,
less, greater, lequal, gequal): These operators
become right associative, and are merged into a single
precedence level.
(finish-infix): New function which coalesces compounds
of n-ary operations and converts the postfix chains
of relational operators into the correct translation
of superfix semantics.
(infix-expand-hook): Call finish-infix on the output
of parse-infix, taking care to bind the *ifx-env*
variable to the environment we are given.
* tests/012/infix.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
| |
* stdlib.tl (detect-infix): Do not detect a prefix
operator followed by argument, followed by anything whatsoever
as being infix. The pair must be followed by nothing, or
by a non-argument.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* config-cache-hook.tl (try-save-curent-config,
try-restore-new-config): These functions now take the
cache key as the argument again. The caller has to obtain
that. Diagnostics are not issued in these functions.
(mainline): Convert git hashes to cache keys.
If they are the same, indicate current config is
valid. Also diagnose when a configuration has not been
retrieved, recommending ./configure being run.
|
|
|
|
|
|
|
|
|
|
|
| |
* config-cache-hook.tl (hash-config-inputs): New function.
Hashes the configure script and the configure-related portions
at the end of the Makefile, starting with the conftest: targets.
We use git cat-file to get the correct versions of these files
at the specified git hash.
(try-save-current-config, try-restore-new-config): Convert
the incoming sha to a cache key.
(toplevel): Add debugging hash command.
|
|
|
|
|
|
| |
* config-cache-hook.tl (try-save-current-config,
try-restore-current-config): Preserve permissions
when copying files, so ./reconfigure remains executable.
|
|
|
|
|
|
| |
* stdlib/infix.tl (infix-expand-hook): In the phony
prefix case, require rest to be a cons, rather
than non-nil in order to invoke cdr.
|
|
|
|
|
|
|
|
| |
* config-cache-hook.tl: New file. If this is is installed
as a git post-checkout hook, it will save and restore
the configuration materials, associated with commit hash,
under a directory called .config-cache. A cache of configs
covering a wide range of commits helps with git bisecting.
|
|
|
|
|
|
|
|
|
|
| |
* test/012/infix.tl: New tests.
(*compiling*) New variable.
(unless-compiling): New macro.
One :error test elicits a warning during the compiled version
of the test that is hard to squelch, so we just remove
it from the compiled test case.
(fft): Remove unused variable i; all for loops locally bind i.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/infix.tl (infix-expand-hook): In addition to the
phony infix rule which swaps a function from second to
first place, and then transforms the arguments, if possible,
we add a case which is essentially like the above, but with
the leading argument before the function being absent:
the expression begins with a function and has two or more
arguments. If those arguments transform as infix, we take
the result as one argument. Otherwise if no transformation
takes place, we return the original expression.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* infix.tl (ifx-oper): New slot, power. When we detect a
prefix operator that is followed by a power symbol and
operand, we clone the operator and store the operand here.
(parse-infix): If the operator has the power slot, the
add-local function, add an extra node for the exponentiation
operation over the function result.
When about to add a prefix operator to the operator stack,
we check whether it is a function, and whether it is
followed by ** and an operand. If so, we clone the operator
and store the operand into the power slot then remoe
those two arguments from the rest of the input; effectively,
we recognize this as a phrase structure.
(detect-infix): We need a couple of rules here to
detect infix expressions which use function power operators.
* txr.1: Document function power operators as well
as the new auto-detection rules.
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/infix.tl (funp): New macro.
(detect-infix): Take environment argument and test with
funp rather than fboundp.
(infix-expand-hook): Pass environment to detect-infix.
Also use funp in the phony infix argument test.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/infix.tl (detect-infix): Redesign.
New algorithm looks only at the first two or three
elements. Arguments that are not operators are
only considered operands if they don't have
function bindings. This is important because sometimes
the logic is applied to the arguments in a DWIM
bracket form, like [apply / args], which we don't
want to treat as (/ apply args).
* tests/012/infix.tl: New test.
* txr.1: Redocumented.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/infix.tl (infix-expand-hook): In the phony infix
logic that swaps the first two arguments, we also try the
remaining arguments as a stand-alone expression, passing that
through the hook. If the hook recognizes and transforms them
as infix, we keep the result as one argument. Otherwise,
we just take the original arguments. I already committed
some test cases for this which are failing.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
| |
* stdlib/op.tl (sys:op-expand): Bind *expand-hook* to nil in
several places so that the unavoidable multiple expansions
we perform do not re-invoke hooks. Finally, when we
interpolate the calculated lambda-interior into the output
templates, we mark it noexpand since the material already
underwent several expansions.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (noexpand_s): New symbol variable, holding
sys:noexpand symbol.
(do_expand): When a (sys:noexpand X) form is seen, then
produce the expansion X without recursing into it; in other
words, sys:noexpand is like quote, but against expansion.
(noexpand): Static function.
(eval_init): Initialize noexpand_s. Register noexpand
as intrinsic function.
* txr.1: Document noexpand function.
|
|
|
|
|
|
|
|
| |
* tests/012/infix.tl: New tests providing some coverage
of ifx, and its phony infix also. Big test case with
FFT function.
* tests/common.tl (msstest): New macro.
|
|
|
|
|
|
|
|
|
| |
* autoload.c (autload_try): Just like we set *package* and
*package-alist* to sane values before loading, we must also
reset *expand-hook* to nil. We would not want autoloads to be
processed with some custome expansion that breaks them. This
matters in the rare case when they are being loaded from .tl
sources rather than .tlo.
|
|
|
|
|
|
|
|
|
|
| |
* parser.c (listener_auto_infix_s): New symbol variable
for *listener-auto-infix-s* special.
(repl): After potentially transforming the input line
via auto compound mode, check for auto infix mode.
If turned on, wrap the expression in ifx.
(parse_init): Initialize listener_auto_infix_s.
Register the special variable named by the symbol.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (loadv): Rebind *expand-hook* to its current
value, like we do with *package*.
* match.c (v_load): Likewise.
* stdlib/compiler.tl (compile-file-conditionally):
Likewise.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* autoload.c (hmac_set_entries, hmac_instantiate): New static
functions.
(autoload_init): Register autoload of hmac module.
* stdlib/hmac.tl: New file.
* tests/013/chksum.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* chksum.c (sha1_stream_read, sha256_stream_read,
md5_stream_read): New static function.
(sha1_stream_impl, sha256_stream_impl, md5_stream_impl):
Logic moved into new functions.
(sha1, sha256, md5): Support stream argument, via corresponding
stream_impl function, passing nil as the size to snarf the
whole stream. This could have been implemented without
the above refactoring. In other words, the _stream functions
only need to be used now when a limit on the number of
bytes must be specified.
(sha1_hash, sha256_hash, md5_hash): Support a stream
argument.
* gencksum.txr: All above chksum.c changes actually
generated from here.
* tests/013/chksum.tl: New tests.
* txr.1: Documentation updated.
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (special_operator_p): Do not return t for certain
symbols that are wired to error-throwing functions in the
table, whose purpose it is to detect certain unexpanded
syntax that is handled internally by the expander.
* txr.1: Documentation udpated in several places to clarify
that certain operators are not special operators.
Also expander-let is reclassified from Macro to Ooerator.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The expander-let mechanism wants to be more tightly integrated
into the expander than a macro. The reason is that the macro
makes an explicit call to the expander. But the expansion it
returns will be processed again by the expander.
In the tightly integrated expander-let, we can avoid this;
the expander can assume that the function which processes
expander-let completely processes it and consequently can
be tail called. All in all, since the expander is written in
C, a utility which is this close to the heart of the expander
should be implemented together with it in C.
* eval.c (expander_let_s): New symbol variable.
(expand_expander_let): New function.
(do_expand): Tail call expand_expander_let when encountering
a form headed by the expander-let symbol.
(eval_init): Initialize expander_let_s variable with interned
symbol. Also wire it into the special op table as an error
entry, similarly to macrolet and a few others.
* autoload.c (expander_let_set_entries,
expander_let_instantiate): Static functions removed.
(autoload_init): Autoload registration for expander-let module removed.
* stdlib/expander-let.tl: File removed.
Also, it should be noted that the the expander-let macro
in this file has a a tiny bug: it refers to a sys:dv-bind
symbol which should have been sys:dvbind. That means it is
evaluating the (sys:dvbind ...) forms, which means it
binds special variables twice: once in that evaluation,
and then again in progv.
|
|
|
|
|
|
|
| |
* txr.1: Add a subsection to Infix Syntax titled Precedence
Demotion Rule which describes our infix parser's enhancement
to operator precedence parsing, possibly not found
anywhere else.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/infix.tl (parse-infix): Change how we treat fn (arg ...)
and elem [arg ...] forms. These now translate to (fn (arg ...))
and [elem (arg ...)] rather than (fn arg ...) and [elem arg ...].
(detect-infix): detect certain op [arg ...] forms as infix.
(infix-expand-hook): Revise detection logic to handle bracket
expression forms, and parenthesized single terms.
The latter are needed to reduce [elem (atom)] to [elem atom].
* tests/012/infix.tl: Fix up some tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When expanding a form with macroexpand-1 or macroexpand,
and an expand hook is in effect, we must call the hook.
Otherwise macrology that relies on macroexpand or
macroexpand-1 might not work with expander-driven syntax.
I'm running into not being able to, for instance, use
the swap macro on a pair of infix expressions because
of this. macroexpand-1 must behave like the real macro
expander.
eval.c (do_macroexpand_1): After looking up whether the
form is a macro, pass it through the hook if it is
defined. If the hook transforms the code, then iterate
on this. We pass the form through the expand hook even
if it is not a macro call, and classify it based on
whether is a function call, dwim brackets form or other,
careful not to pass down special operators.
|
|
|
|
|
|
|
|
|
|
|
| |
It turns out we need this for infix.
* eval.c (do_expand): Call the expand hook for
forms headed by the dwim operator, passing that
operator symbol as the type indicator.
* txr.1: Document this and also that the
expand hook doesn't receive symbol macros.
|
|
|
|
|
|
|
|
|
|
| |
There isn't an obvious use for calling the
expander hook for symbolic forms that are
macros. (Especially while not calling it
for symbolic forms that are not macros.)
* eval.c (do_expand): Do not call the expand
hook for symbol macro forms.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* autoload.c (infix_set_entries): Intern new symbols
||, &&, !, !=, &=, |=, &&=, ||=, >>=, <<=, ~=, %=,
*=, %=, <<, >>, &, |, ~, % and //.
* stdlib/infix.tl: revise precedence of calculating
assignment operators. Add shifts, bitwise operators,
modulo, C-like synonyms for some operators,
numerous new calculating assignments.
(sys:mod-set, sys:and-set, sys:or-set, sys:logand-set,
sys:logxor-set, sys:logior-set, sys:ash-set,
sys:asr-set, sys:asr): New macros to provide
the implementation of operation combinations that
will only be available via infix.
|
|
|
|
|
|
|
|
|
| |
* autoload.c (place_set_entries): Add mul and div
symbols as autoload triggers.
* stdlib/place.tl (mul, div): New macros.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We allow the | character to be an identifier or constituent
of identifers. This is going to be immediately useful
in infix syntax to provide the C-like operators.
* parser.l (BSCHR, NSCHR, ID_END): Add | character.
* genvim.txr (glyph, iskeyword): Add | character.
* lex.yy.c.shipped,
* tl.vim,
* txr.vim: Regenerated.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
| |
* autoload.c (place_set_entries, defset_set_entries): Move the
set-mask and clear-mask symbols from def_set_entries to
place_set_entries.
* stdlib/defset.tl (set-mask, clear-mask): Functions removed from here.
* stdlib/place.tl (set-mask, clear-mask): Functions moved here.
|
|
|
|
|
|
|
| |
* tests/012/infix.tl (quadractic-roots): New function.
Add couple of tests.
* txr.1: Add quadratic-roots as example to ifx macro.
|
|
|
|
|
|
| |
* txr.1: Make it clear that whitespace is required between
atoms in infix expressions most of the time, so certain
compact notations from C-like syntax are not achieved.
|
|
|
|
| |
* txr.1: New major section Infix Syntax.
|
|
|
|
|
|
|
| |
* stdlib/infix.tl (parse-infix): We don't need to
recognize consecutive [...][...], because the
rule which reduces any element followed by [...]
does the job.
|
|
|
|
|
|
| |
* tests/012/infix.tl: New file.
* tests/012/compile.tl: Add infix to compiled tests.
|