| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (basic-blocks :postinit): Calculate the
basic block partitions more directly using partition-if,
eliminating the calculation of two sequences of indices
that have to be merged and then passed to the partition
function.
|
|
|
|
|
|
|
| |
* stdlib/place.tl (sys:get-fun-setter-getter):
Throw error if sym isn't a bindable symbol, so
that nonsense like (set (symbol-function 3) ...)
isn't allowed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a pattern variable match like @foo references a global
symbol macro, that's treated as an existing expression to
match, and not a new binding. However, local symbol macros
are not treated this way; they are invisible to variable
patterns. That is an unintended inconsistency.
* stdlib/match.tl (var-list exists): Use lexical-binding-kind
rather than lexical-var-p. This returns true for lexical
symbol macros also.
* tests/011/patmatch.tl: New test cases.
* txr.1: Documentation revised to clarify that both global
and local symbol macros are considered to be existing variable
bindings by pattern matching.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* evalc (macro_k): New keyword symbol variable.
(lexical_binding_kind, lexical_fun_binding_kind)
New functions.
(lexical_var_p): Bugfix: if the symbol is a special
variable, do not short-circuit to a nil answer.
Special variables can be shadowed by symbol macros.
The function is now defined in terms of lexical_binding_kind.
(lexical_symacro_p, lexical_macro_p): New
functions.
(lexical_fun_p): Now defined using lexical_fun_binding_kind.
(lexical_lisp1_binding): Bugfix: check for special
variables; do not report special variables as :var.
(eval_init): Initialize macro_k. Register new intrinsics:
lexical-binding-kind, lexical-fun-binding-kind,
lexical-symacro-p, lexical-macro-p.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When functions are optimized away due to constant folding,
instead of replacing them with a nil, we now compact the
table to close the gaps and renumber the references in the
code.
* stdlib/compiler.tl (compiler null-stab): Method removed.
(compiler compact-dregs): Renamed to compact-dregs-and-syms.
Now compacts the symbol table also. This is combined with
D-reg compacting because it makes just two passes through
the instruction: a pass to identify the used D registers
and symbol indices, and then another pass to edit the
instructions with the renamed D registers and renumbered
symbol indices.
(compiler optimize): Remove the call to the null-unused-data
on the basic-blocks object; nulling out D regs and symbol
table entries is no longer required. Fllow the rename of
compact-dregs to compact-dregs-and-syms which is called
the same way otherwise.
* stdlib/optimize.tl (basic-blocks null-unused-data):
No longer used method removed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We now have some constant folding in the optimizer too, not
just in the front end compiler pass. This is leaving behind
dead D registers that are not referenced in the code.
Let's compact the D register table to close the gap.
* stdlib/compiler.tl (compiler get-dreg): In this function
we no longer check that we have allocated too many D
registers. We let the counter blow past %lev-size%.
Because this creates the fighting chance that the compaction
of D regs will reduce their number to %lev-size% or less.
By doing this, we allow code to be compilable that otherwise
would not be: code that allocates too many D regs which
are then optimized away.
(compiler compact-dregs): New function. Does all the work.
(compiler optimize): Compact the D regs at optimization
level 5 or higher.
(compile-toplevel): Check for an overflowing D reg count
here, after optimization.
* stdlib/optimize.tl (basic-blocks null-unused-data):
Here, we no longer have to do anything with the D registers.
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (compiler get-dreg): Fix
indentation proble.
* stdlib/optimize.tl (basic-block fill-treg-compacting-map):
Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/path-test.tl (path-volume): Don't return
:abs for a path whose empty first component
isn't followed by any more items. Otherwise
we return :abs for a path formed by splitting
the empty string, and then calls like (rel-path "" "a")
complain about a mixture of absolute and relative.
With this change, empty paths given to rel-path
behave as if they were ".".
* tests/018/rel-path.tl: New test cases.
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (basic-blocks do-peephole-block): Extend
constant-folding case to recognize gapply as well as gcall.
We just have to take care in how we apply apply arguments
to the actual function to get the value.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Let's consider the DIM expression [a . b c]. Without
this change we get:
syms:
0: a
1: b
2: c
code:
0: 98020000 getf t2 0
1: 98030001 getf t3 1
2: 98040002 getf t4 2
3: 1C020002 apply t2 t2 t3 t4
4: 00030002
5: 00000004
6: 10000002 end t2
With this change:
syms:
0: a
1: b
2: c
code:
0: 98030001 getf t3 1
1: 98040002 getf t4 2
2: 24020002 gapply t2 0 t3 t4
3: 00030000
4: 00000004
5: 10000002 end t2
There are 17 hits for this optimization in optimize.tl
alone!
* stdlib/optimize.tl (basic-blocks do-peephole-block):
New pattern here. We recognize an instruction sequence
which begins with a (getf treg idx) and ends in
an (apply dest treg ...), without any instructions in
between accessing or redefining treg. Additionally,
the treg value must not be used after the apply,
unless the apply redefines it. In that case, we
rewrite this pattern to eliminate that initial getf
instruction, and substitute (gapply dest idsx ..)
for the apply.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There was a bug in rt_defun in that it was not calling
vm_invalidate_binding. This mean that compiled functions
were not picking up redefinitions. This bug is fixed now
because rt_defun now calls sethash on the top_fb directly,
which modifies the existing binding cell; it is not
allocating a new cell.
We put in new test cases to confirm the proper redefinition
behaviors.
The proper redefinition behavior exposes an issue in
pattern matching.
* tests/019/redef.tl: New file.
* stdlib/match.tl (transform-quote): This function's compiled
image, when deposited into a .tlo file, becomes incorrect
because (sys:hash-lit) turns into #H() syntax, which reads
back as something else. In other words (sys:hash-lit)
deosn't have print-read consistency and so doesn't
externalize. To fix this right we would need a print mode
which ensures machine readability rather than human
readability, like in Common Lisp. For now, we just break up
the pattern so that it's not a literal match. This bug was
hidden due to theredefinition issue. When match.tl is
being compiled, it defines non-triv-pat-p twice. Due to
redefinitions not kicking in properly, the first definition
of non-triv-pat-p remains in effect for some functions.
When transform-qquote is being expanded, the (sys:hash-lit)
pattern is treated as non-trivial, even though it is
is trivial, and so it is turned into pattern matching code.
The code doesn't contain a (sys:hash-lit) literal and so
the issue doesn't occur.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Like was done with the function and variable top-level
environments, we simplify the macro ones.
* eval.c (func_get_name, lookup_mac, lookup_symac,
lookup_symac_lisp1, op_defsymacro, rt_defsymacro,
rt_defmacro, op_defmacro, reg_mac, reg_symacro):
Adjust to simpler representation where the hash cell
itself is the binding cell, rather than holding a
binding cell in its cdr.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since their inception, the top_fb and top_fb hashes associated
symbols with bindings cells, causing an extra cons cell to be
allocated for each entry. I don't remember why this is. It
might have been that way so that gethash(top_fb, sym) would
return a cell when the variable exists, or else nil. This was
before we had functions like gethash_e and inhash that return
the hash cell itself. A hash cell is also a cons and can serve
as a binding just fine by itself.Let's make it so.
For now, the macro and symbol macro environments stay the
way they are; I will likely convert them also.
* eval.c (env_fbind, env_vbind, lookup_global_var, lookup_sym_lisp1,
lookup_fun, func_get_name, rt_defv, rt_defun, set_symbol_value,
reg_fun, reg_varl): Update all these functions so they treat the
hash cell from top_vb or top_fb as the binding cell, rather than
putting or expecting the cdr of that cell (i.e the hash value)
to be a binding cell.
* hash.[ch] (gethash_d): New function. Jus gethash_e without the
pesky self argument, that would only be needed for error
reporting if we pass an object that isn't a hash.
* stdlib/place.tl (sys:get-fun-getter-setter, sys:get-vb):
These two functions must be adjusted since they refer to the
top-fb and top-vb variables. sys:get-vb isn't used anywhere;
it continues to exist in order to provide run-time support
to files that were compiled with an buggy version of the
symbol-value place.
|
|
|
|
|
|
| |
* stdlib/optimize.tl (basic-blocks do-peephole-block): The
constant folding case should fire even if some of the
arguments of the call aren't D registers but T0.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (%effect-free-funs%, %effect-free%,
%functional-funs%, %functional%): Move variables
into stdlib/constfun.tl
* stdlib/constfun.tl %effect-free-funs%, %effect-free%,
%functional-funs%, %functional%): Moved here.
* stdlib/optimize.tl: Use load-for to express dependency
on constfun module; don't depend on the compiler having
loaded it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The compiler handles trivial constant folding over the
source code, as a source to source transformation.
However, there are more opportunities for constant folding
after data flow optimizations of the VM code.
Early constant folding will not fold, for instance,
(let ((a 2) (b 3)) (* a b))
but we can reduce this to an end instruction that returns
the value of a D register that holds 6. Data flow optimizations
will propagate the D registers for 2 and 3 into the gcall
instruction. We can then recognize that we have a gcall with
nothing but D register operands, calling a constant-foldable
function. We can allocate a new D register to hold the result
of that calculation and just move that D register's value
into the target register of the original gcall.
* stdlib/compiler.tl (compiler get-dreg): When allocating
a new D reg, we must invalidate the datavec slot which is
calculated from the data hash. This didn't matter before,
because until now, get-datavec was called after compilation,
at which point no new D regs will exist. That is changing;
the optimizer can allocate D regs.
(compiler null-dregs, compiler null-stab): New methods.
(compiler optimize): Pass self to constructor for basic-blocks.
basic-blocks now references back to the compiler.
At optimization level 5 or higher, constant folding can
now happen, so we call the new method in the optimizer to
null the unused data. This overwrites unused D registers
and unused parts of the symbol vector with nil.
* stdlib/optimize (basic-blocks): Boa constructor now takes
a new leftmost param, the compiler.
(basic-blocks do-peephole-block): New optimization case:
gcall instruction invoking const-foldable function, with
all arguments being dregs.
(basic-blocks null-unused-data): New method.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* configure: Detect all the new functions, with separate
tests for the unary and binary ones.
* arith.c (cbrt_s, erf_s, erfc_s, exp10_s, exp2_s,
expm1_s, gamma_s, j0_s, j1_s, lgamma_s, log1p_s, logb_s,
nearbyint_s, rint_s, significand_s, tgamma_s, y0_s, y1_s,
copysign_s, drem_s, fdim_s, fmax_s, fmin_s, hypot_s,
jn_s, ldexp_s, nextafter_s, remainder_s, scalb_s, scalbln_s,
yn_s, r_copysign_s, r_drem_s, r_fdim_s, r_fmax_s, r_fmin_s,
hypot_s, r_jn_s, r_ldexp_s, r_nextafter_s, r_remainder_s,
r_scalb_s, scalbln_s, r_yn_s): New symbol variables.
(not_available): New static function.
(cbrt_wrap, erf_wrap, erfc_wrap, exp10_wrap, exp2_wrap,
expm1_wrap, gamma_wrap, j0_wrap, j1_wrap, lgamma_wrap,
log1p_wrap, logb_wrap, nearbyint_wrap, rint_wrap,
significand_wrap, tgamma_wrap, y0_wrap, y1_wrap,
copysign_wrap, drem_wrap, fdim_wrap, fmax_wrap,
fmin_wrap, hypot_wrap, jn_wrap, ldexp_wrap,
nextafter_wrap, remainder_wrap, scalb_wrap, scalbln_wrap,
yn_wrap): New static functions.
(arith_set_entries, arith_instantiate): New static functions.
(arith_init): Initialize symbols and instantiate functions
via autoload mechanism. In a program that doesn't use the
functions, we suffer only the overhead of interning the symbols.
* lib.h (UNUSED): New macro for GCC unused attribute.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (me_load_for): An object which is not one of the
valid clause symbols is not necessarily a symbol; don't
call it one in the diagnostic.
* stdlib/struct.tl (sys:check-slot): Similarly, an object that
isn't the name of a struct slot isn't necessarily a
symbol; don't call it one.
|
|
|
|
|
|
| |
* txr.1: SHA-1 functions documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
* protsym.c: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
These functions are useful when sorting a sequence
using an expensive keyfun.
* autoload.c (csort_set_entries, csort_instantiate):
New static functions.
(autlod_init): Register autoloading of csort module
via new functions.
* stdlib/csort.tl: New file.
* tests/012/sort.tl: csort functions included in tests.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
hash-map converts a function mapping over a sequence
into a hash table.
* hash.[ch] (hash_map): New function.
* tests/010/hash.tl: Test case.
* genman.txr: The hash-map identifier introduces
a hash collision. We have to deal with that somehow now.
(colli): We put the conflicting entries into a new hash called
colli which maps them to an increment value.
(hash-title): Increment the hash code h by the amount
indicated in colli, if the title is found there.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With this change we fix the bug that the debugger commands
yield their Lisp forms rather than evaluating them.
* eval.c (eval_intrinsic): Takes one more argument,
the macro environment. This is passed into env_to_menv
as the root macro environment.
(eval_init): Update registration of eval intrinsic
to have two optional arguments.
* eval.h (eval_intrinsic): Declaration updated.
* parser.c (read_file_common, read_eval_ret_last): Pass
nil argument to new parameter of eval_intrinsic.
(repl): Pass the env parameter as the new menv
parameter of eval_intrinsic, rather than the existing
env parameter. This fixes the command dispatch in
the debugger, since the command table is consists of
symbol macros, and not variables. For instance the
backtrace command bt is a binding of the bt symbol
to the form (sys:print-backtrace), which has to be
substituted for it and executed. When that envrionment
is used as the ordinary environment, bt looks like
a variable whose value is the list (sys:backtrace).
* parser.y (elem, check_parse_time_action): Fix
eval_intrinsic calls.
* txr.c (txr_main): Likewise.
* txr.1: Documented.
* y.tab.c.shipped: Updated.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
| |
* stdlib/quips.tl (%quips%): New one.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/match.tl (match-cond): New macro.
* autoload.c (match_set_entries): match-cond triggers
autoload of match module.
* tests/011/patmatch.tl: Tests.
* txr.1: Documented.
* stdlib/doc.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
@(push) is like @(output), but feeds back into input.
Use carefully.
* parser.y (PUSH): New token.
(output_push): New nonterminal symbol.
(output_clause): Handle OUTPUT or PUSH via output_push.
Some logic moved to output_helper.
(output_helper): New function. Transforms both @(output)
and @(push) directives. Checks both for valid keywords;
push has only :filter.
* parser.l (grammar): Recognize @(push similarly to other
directives.
* lib.[ch] (push_s): New symbol variable.
* match.c (v_output_keys): Internal linkage changes to external.
(v_push): New function.
(v_parallel): We must fix the max_line algorithm not to
use an initial value of zero, because lines can go negative
thanks to @(push). We end up rejecting the pushed data.
(v_collect): We can no longer assert that the data line
number doesn't retreat.
(dir_tables_init): Register push directive in table of
vertical directives.
* match.h (append_k, continue_k, finish_k): Existing symbol
variables declared.
(v_output_keys): Declared.
* y.tab.c.shipped,
* y.tab.h.shipped,
* lex.yy.c.shipped: Updated.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.[ch] (keep_keys_if, separate_keys): New functions.
* eval.c (eval_init): keep-keys-if, separate-keys intrinsics
registered.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* autoload.c (load_args_set_entries, load_args_instantiate):
New static functions.
(autoload_init): Register new auto-loaded module "load-args".
* stdlib/load-args.tl: New file.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (clean-file): Under a log-level
of 1 or more, report clean-file removes a file.
(compile-update-file): Under a log level of 1 or more,
report when a compiled file was skipped due to being
up-to-date.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With log-level, we can obtain trace messages about
what file is being compiled and individual forms
within that file.
* autoload.c (compiler_set_entries): Intern the slot
symbol log-level.
* stdlib/compiler.tl (compile-opts): New slot, log-level.
(%warning-syms%): Add log-level to %warning-syms%.
Probably we need to rename this variable.
(compile-file-conditionally): Implement the two log
level messages.
(with-compile-opts): Allow/recognize integer option values.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This function simplifies cleaning, by allowing a file to
be cleaned to be identified in much the same way as an input
file to load or compile-file.
* autoload.c (compiler_set_entries): The clean-file symbol
is interned and becomes an autoload trigger for the
compiler module.
* stdlib/compiler.tl (clean-file): New function.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The file compiler combines compiled forms into a single
list as much as possible so that objects in the list can
share structure (e.g. merged string literals). However,
when package-manipulating forms occur, like defpackage,
it has to spit these lists, since the package manipulations
of an earlier form affect the processing of a later form,
such as whether symbols in that form are valid.
This splitting does not take care of the case that an
empty piece may result when the very last form is a package
manipulation form. A nil gets written to the .tlo file,
which the load function does not like; load thinks that since
this is not a valid list of compiled forms, it must be the
version number field of a catenated .tlo file, and proceeds
to find it an invalid, incompatible version.
* stdlib/compiler.tl (dump-to-tlo): Use partition* rather than
split*. partition* doesn't leave empty pieces.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
* protsym.c: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/expander-let.tl: New file.
* autoload.c (expander_let_set_entries, expander_let_instantiate);
New static functions.
(autoload_init): Register autoloading of above new file via
above new functions.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
| |
* stdlib/awk.tl (awk-compile-time): New slot, funs.
(awk-expander): Gather :fun clauses info funs slot.
(awk): Include a labels form which injects the functions.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (comp-fbind): When after removing unused
functions we are left with an empty list (or the list of
functions was empty to begin with), let's only emit the body
fragment without any frame wrapping. We can't just return
bfrag because that was compiled in the environment which
matches the frame. Instead of the expense of compiling the
code again, we rely on eliminate-frame to move all v registers
up one level.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This change makes it possible to use the redirection macros
like -> and ->> everywhere in the awk macro, including the
init-forms of the :let clause.
* stdlib/awk.tl (sys:awk-mac-let-outer): New macro.
(sys:awk-mac-let): Move redirection macros into
awk-mac-let-outer.
(awk): Rearrange the order of wrapping. We split the
let so the awk-retval and aws-sym are bound outermost.
Then we have the outer macros that provide the
redirection operators. Then the application-defined
lets inside of that.
* txr.1: Documented wide scope of redirection macros.
|
|
|
|
|
|
|
| |
* stdlib/awk.tl (awk-state ensure-stream): Fix missing
handling for the :apf kind symbol used by appending.
* tests/015/awk-redir.tl: New file.
|
|
|
|
|
|
|
| |
* stdlib/awk.tl (sys:awk-redir): Fix regression from April
2018. The gensym variable introduced must be parallel bound,
since it is referenced by the init expression of the other
variable. This breaks all awk redirection operators.
|
|
|
|
| |
* stdlib/quips.tl (%quips%): New entry.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The with-compile-opts macro is rewritten such that
it cad occur inside code that is being compiled, and
change compiler options for individual subexpressions.
It continues to work as before in scripted build steps
such as when calls to (compile-file ...) are wrapped
in it. However, for the time being, that now only works
in interpreted code, because with this change, when
a with-compile-opts form is compiled, it no longer
arranges for the binding of *compile-opts* to be visible
to the subforms; the binding affects the compiler's
own environment.
* stdlib/compiler.tl (with-compile-opts): Rewrite.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (compiler_let_s): New symbol variable.
(op_let): Recognize compiler-let for sequential
binding.
(do_expand): Traverse and diagnose compiler-let
form.
(eval_init): Initialize compiler_let_s and register
the interpreted version of the operator.
* stdlib/compiler.tl (compiler compile): Handle
compiler-let form.
(compiler comp-compiler-let): New method.
(no-dvbind-eval): New function.
* autoload.c (compiler-set-entries): Intern the
compiler-let symbol in the user package.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Adding a progv operator, similar to the Common Lisp one.
* eval.c (progv_s): New symbol variable.
(op_progv): New static function.
(do_expand): Recognize and traverse the progv form.
(rt_progv): New static function: run-time support
for compiled progv.
(eval_init): Initialize progv_s, and register the the
op_progv operator interpreting function.
* stdlib/compilert (compiler compile): Handle progv
operator ...
(compiler comp-progv): ... via this new method.
* tests/019/progv.tl: New file.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
| |
* stdlib/quips.tl (%quips%): New entry.
|
|
|
|
| |
* stdlib/quips.tl (%quips%): New entry.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We have a problem. If v is a dynamic variable, then
the form
(let (v)
(set (symbol-value 'v) 3))
is not behaving correctly; it's updating the top-level
value of v not the rebound one.
* eval.c (set_symbol_value): New static function.
(eval_init): Register sys:set-symbol-value intrinsic.
The top-vb variable, though no longer referenced by
the symbol-value place, because existing compiled
code depends on it.
* stdlib/place.tl (symbol-value): Rewrite the place
logic to use symbol-value to access the variable,
and set-symbol-value to update it, instead of referencing
sys:top-vb.
(sys:get-vb): This function has to stay, because it
provides run-time support for code compiled with the
buggy version of the place.
* tests/019/symbol-value.tl: New file.
|
|
|
|
|
| |
* stdlib/compiler.tl (with-compile-opts): Remove stray
character from "uncrecognized".
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* struct.tl (defstruct): When generating the lambda that
initializes slots from boa arguments, instead of we use (set
(qref obj slot) val) instead of slotset. The qref macro will
diagnose use of nonexistent slots.Thus warnings are produced
for, say:
(defstruct (point x y) nil)
where x and y have not been defined, using the imperfect
approach of the qref implementation, which is better than
nothing.
|