| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We have these issues, which are regressions:
1> (compile-toplevel '(/ 1 0))
** expr-1:1: warning: sys:b/: constant expression (sys:b/ 1 0) throws
** /: division by zero
** during evaluation at expr-1:1 of form (sys:b/ 1 0)
1> (compile-toplevel '(let ((a 1) (b 0)) (/ a b)))
** /: division by zero
** during evaluation at expr-1:1 of form (compile-toplevel [...])
While the compiler's early pass constant folding is careful
to detect constant expressions that throw, care was not taken
in the optimizer's later constant folding which takes place
after constant values are propagated around.
After the fix:
1> (compile-toplevel '(let ((a 1) (b 0) (c t)) (if c (/ a b))))
** expr-1:1: warning: let: function sys:b/ with arguments (1 0) throws
#<sys:vm-desc: 9aceb20>
2> (compile-toplevel '(let ((a 1) (b 0) (c nil)) (if c (/ a b))))
#<sys:vm-desc: 9aef9f0>
* stdlib/compiler.tl (compiler): New slot top-form.
(compile-toplevel): Initialize the top-form slot of the
compiler. The optimizer uses this to issue a warning now.
Since the warning is based on analyzing generated code, we
cannot trace it to the code more precisely than to the top-level
form.
* stdlib/optimize.tl (basic-blocks): New slot, warned-insns.
List of instructions that have been warned about.
(basic-blocks do-peephole-block): Rearrange the constant folding
case so that as part of the pattern match condition, we include
the fact that the function will not throw when called with those
constant arguments. Only in that case do we do the optimization.
We warn in the case when the function call does throw.
A function rejected due to throwing could be processed through
this rule multiple times, under multiple peephole passes, so
for that reason we use the warned-insns list to suppress duplicate
warnings.
|
|
|
|
|
|
| |
* stdlib/compiler.tl (compiler compile): Don't store form
into me.last-form if it's an atom; it won't be useful
or error reporting.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* parser.c (read_objects_common): New static function, formed
from read_objects_from-string.
(read_objects_from_string): Now wrapper for read_objects_common.
(read_objects): New function.
* parser.h (read_objects): Declared.
* eval.c (eval_init): Register read-objects intrinsic.
* autoload.c (getput_set_entries): Add three new symbols:
file-get-objects, file-put-objects and file-append-objects.
* stdlib/getput.tl (put-objects): New system function.
(file-get-objects, file-put-objects, file-append-objects):
New functions.
* txr.1: Documented.
* tests/018/getput.tl: New file.
|
|
|
|
| |
* stdlib/quips.tl (%quips%): New one.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (compile-file-conditionally): When evaluation
of a compiled top-level form is not suppressed, there is a risk
that it can terminate non-locally, via throwing an exception or
performing a block return. The compilation of the file is then
aborted. We can do better: using an unwind-protect, we can catch
all non-local control transfers out of the form and just ignore
them. The motivation for this is that it lets us compile files
which call (return-from load ...), without requiring that it be
written as (compile-only (return-from load ...)). Other things will
work, like compiling a (load "foo") where foo doesn't exist or
aborts due to errors.
|
|
|
|
| |
* stdlib/quips.tl (%quips%): Wording change.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There used to be a hack in the Makefile whereby the
compilation of stdlib/error.tl was forced to occur earlier.
I got rid of it. Now, the issue that was solving reproduced.
A situation can occur whereby loading error.tl triggers
loading some other files, which end up performing an expansion
that needs sys:bind-mac-check: but that function has not yet
been defined because error.tl has not yet loaded that far.
The issue occurs when stdlib/place.tl is compiled before
stdlib/error.tl. The compiled place.tl has a run-time
dependency on functions in error.tl, because the compiled
version of mac-param-bind and other forms relies on a run-time
support function sys:bind-mac-check defined in stdlib/error.tl.
* stdlib/error.tl (sys:dig): This function triggers the
problem, but it's not the only cause. Here, the problem is
because the (set ...) macro is used which triggers loading the
stdlib/place module. That brings in the need for
bind-mac-params. So here we use sys:setq instead. That is not
a complete solution. The changes in eval.c are also required,
because built-in macros like whilet expand to code that uses
the (set ...) macro. Note how sys:dig uses whilet.
(sys:bind-mac-check, sys:bind-mac-error): We move these
functions above compile-warning. This addresses remaining
circularity problem. The compile-warning function uses the
catch macro which brings in stdlib/except.tl, which pulls in
stdlib/op.tl due to its use of (do ...), which pulls in
stdlib/place.tl. So if we already define sys:bind-mac-check
at that point, we are good.
* eval.c: Sweep the file for almost all places where macros
generate code that invokes (set <symbol> <value>) and replace
that with (sys:setq <symbol> <value>) to eliminate the
dependency on loading the stdlib/place.tl module.
(me_def_variable, me_gun, me_while_until_star, me_case,
me_whilet, me_mlet, me_load_for, me_pop_after_load):
In all these macro expanders, use sys:setq rather than set
in the generated code.
* tests/019/load-hook.tl: Some test cases here look for a
macro expansion containing (set ...), needing to be fixed
to look for (sys:setq ...) due to the change in eval.c.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register mref intrinsic.
* lib.[ch] (mref): New function.
* stdlib/place.tl (sys:mref1): New place.
(mref): New place macro, defined in terms
of sys:merf1, ref place and mref function.
* tests/012/seq.tl: New tests.
* txr.1: Documented.
|
|
|
|
| |
* stdlib/place.tl (dwim): Fix incorrect indentation.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The ref function is not defined in the documentation
as an accessor, but there is a ref place. Unfortunately,
deletion is broken: (del (ref x y)) does not store the
new sequence back into place x, and so it does not work
correctly for lists; if x is a list, it doesn't change.
Various accessors are defined in terms of ref, as place
macros, such as the first, second, third, ... accessors.
This fixes the bug for them also; (del (second list))
must update list.
* stdlib/place.tl (ref): Fix the delete-expander to
fetch the clobber expander of the sequence place,
and use the simple setter to put the edited sequence into
that place.
* tests/012/seq.tl: Test case, which breaks without
this fix. Test the (second ...) place also, which is defined
in terms of ref.
* txr.1: Split documentation for ref and refset, mainly
because one is an Accessor and one is a Function. Removing
some discussions about the equivalences between DWIM brackets
and ref; there are subtleties there not worth going into.
Description of refset is simplified. We mention the possibility
of del over a ref place; only in that case is the sequence
itself required to be a place.
|
|
|
|
|
|
|
|
|
|
|
| |
* autoload.c (op_set_entries): Add tap symbol as autoload
trigger for op module.
* stdlib/op.tl (tap): New macro.
* tests/012/op.tl: New test.
* txr.1: Documented.
|
|
|
|
| |
* stdlib/quips.tl (%quips%): New one.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The motivation here is that casequal brings in some optimizations
not done by match-case, like hashed lookup and jump tables.
* stdlib/match.tl (non-triv-pat-t): Move temporary definition
higher in file since it is needed earlier in the bootsrapping.
(match-case-to-casequal): New function.
(match-case): Try converting clauses to casequal with new
function. If that returns something, use that as the expansion,
otherwise perform the normal expansion.
* txr.1: Documentation revised. Existing text is wrong which
says that the clauses of a caseq, caseql or casequal are
always evaluated sequentially. Furthermore, now that
match-case and match-ecase can be transformed to casequal,
they also don't necessarily evaluate sequentially. We spell
out the conditions under which they may translate.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Defining libpng bindings, with longjmp catching, is
now possible.
* autoload.c (ffi_set_entries): Add setjmp symbol, which is
a new macro in stdlib/ffi.tl.
* ffi.c (jmp_buf_s): New symbol variable.
(mk_jmp_buf, rt_setjmp, longjmp_wrap): New functions.
(ffi_init): Initialize jmp_buf_s. Register
sys:rt-setjmp and longjmp intrinsics.
* ffi.h (jmp_buf_s): Declared.
* stdlib/ffi.h (setjmp): New macro. Rather than introducing
a new special operator, we use a run-time support function
called sys:rt-setjmp, which takes functional arguments.
* unwind.[ch] (uw_snapshot, uw_restore): New functions.
The rt_setjmp function needs these to restore our unwind
frame stack into a sane state after catching a longjmp,
which bails without unwinding it, leaving the pointers
referring to frames that no longer exist.
* tests/017/setjmp.tl,
* tests/017/setjmp.expected: New files.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
| |
* autload.c (place_set_entries): Add ensure as an autoload
trigger symbol for the place module.
* stdlib/place.tl (ensure): New macro.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The glob* function supports brace expansion, the **
pattern for matching zero or more path components,
as well as a sane sort for path names.
glob* relies on brace expansion written in Lisp;
the ** processing and sorting is done by a glob-compatible
C function called super_glob that uses glob.
* autoload.c (glob_set_entries, glob_instantiate): New static
functions.
(autoload_init): Register autoload of stdlib/glob module.
* glob.c (GLOB_XNOBRACE, GLOB_XSTAR): New macros.
(glob_wrap): Call super_glob instead of glob if GLOB_XSTAR
is present in flags. Avoid passing extension flags to glob.
(super_glob_find_inner, super_glob_rec, glob_path_cmp,
glob_str_cmp, super_glob): New static functions.
(glob_init): Register sys:glob-xstar, and glob-xnobrace.
sys:glob-xstar is used by glob* to request support for
the ** pattern from glob.
* stdlib/glob.tl: New file.
* tests/018/glob.tl: New file.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
| |
* stdlib/awk.tl (awk-state prn): Return nil in the no-argument
case instead of returning whatever put-string returns.
* tests/015/awk-misc.tl: New file.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
These remove repetitive (op ...) syntax from
the arguments of functional combinators.
* stdlib/opt.tl (opf, lopf): New macros.
* autoload.c (op_set_entries): Register opf and
lopf as autoload triggers.
* tests/012/op.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/load-args.tl (load-args-process): When compile-update-file
doesn't do anything due to the compiled file being up-to-date,
the file must be loaded, so that the effect is similar to compiling.
Otherwise subsequent files may fail to compile due to missing
definitions such as packages.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is not an easy change to make because it breaks the
validity of existing URLs in the wild which point to specific
sections of the TXR manual.
Some of my recent changes to capitalization of numerous
headings have already broken many URLs, so we might as well
bite the bullet and do this now.
The problem with the current scheme is that entire section
titles are hashed: all the words of a title, not just the
names of functions. Whenever we add a new function, macro or
variable which is documented together with related functions
in the same paragraph under the same heading, the heading
changes, and the hash changes. For instance, the hash for
the hash-map identifier is actually the hash of the string
"Function <tt>hash-map</tt>".
Under the new scheme, section titles are hashed in a more
complicated way that is robust against most edits. If a
title contains any symbols marked up with <tt>, then the
leftmost such symbol is taken as the title. Otherwise,
the whole title is mapped to lower case.
There is no longer a stdlib/doc-syms.tl file, and the
special disambiguated "D-<HEX>" codes are also gone.
Symbols are no longer associated with section hashes or
disambiguation section codes. The hash of a symbol is
a 32 bit CRC-32 checksum, expressed as S-<HEX> where
<HEX> is 8 hex digits. A section which defines symbols
has not only a <a name="..."> for its own hash but also
additional <a name="...>" elements for each of the symbols
that it defines.
If a section defines an ambiguous symbol (one that is also
defined with a different meaning in a different section),
then that symbol is not linked to either section; it is
mapped to the generated disambiguating section.
* genman.txr (dupes): Renamed to dupe-hashes for clarity.
(tagnum): Hash removed.
(direct): New hash. Tracks the assocation between sections
hashes and hashes of symbols that are defined only in
those symbols (no ambiguity) and thus the symbol hashes
can navigate directly to the sections. Serves as a
complement to the disamb hash.
(colli): There are no collisions now, so
initialize this to empty.
(hash-str): Function removed.
(hash-title): This function becomes more complicated.
If a title has at least one <tt>..</tt> item, then
that is taken in its place. Either way, the title
is transformed and enumerated against duplication and
hashed with crc32 instead of the original custom hashing
function.
(enumerate): Function removed: enumeration of titles is
done inside hash-title.
All manipulations of symhash using material from HTML now
use html-decode, so that we hash the original symbol
name like "str<" and not "str<".
When filtering the BODY, we have a new case: whenever
we see a <a name="...">, we now check the new direct
hash to see if there is a list of symbol hashes for
the given section. If so, we generate additional
<a name="..."> definitions for all the symbol hashes.
At the end of the file, the "missing from image"
processing is condensed, and the generation of the
stdlib/doc-syms.tl file is removed.
* stdlib/doc-syms.tl: Removed.
* stdlib/doc-lookup.tl: Don't load doc-syms. Use crc32
plus formatting to conver a symbol to the hash that is
used in the document and try the lookup with that.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* autoload.c (csort_set_entries): Register csort-group
as autoload trigger for stdlib/csort.tl.
* stdlib/csort.tl (csort-group): New function.
* tests/012/sort.tl: Tests for sort-group and csort-group.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In this patch we change the convention of uncapitalized words
occurring in headings such as "Special variable *foo*".
* checkman.txr (check-var, check-func): Consolidated into
a single pattern function called check-coNP. This now
enforces capitalization, and also has a giant fall-back
clause which explicitly recognizes .coNP headings that
are not specially checked by the previous rules, after
which there is an error case, so that unclassified .coNP
headings are diagnosed. A bug is fixed here in the handling
of Special Variable and Variable headings. The pattern
match was wrong, so these were not being properly recognized.
Without the error case at the end, a number of errors
occur in the document where the .desc is missing after a
Variable or Special Variable.
* txr.1: (.dir, .dirs): Fix capitalization of Directive
and Directives in headings generated by this macro.
Fix capitalization in numerous .coNP headings.
* stdlib/doc-syms.tl: Updated. Unfortunately, many symbols
change their hash value because it's based on the entire
heading.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* arith.c (tofloat_s, toint_s): New symbol variables.
(tofloat, toint): If the argument is a COBJ, handle
it via do_unary_method.
(arith_init): Initialize new symbol variables.
The functions tofloat, toint, tofloatz and tointz.
are now registered here, rather than eval_init.
* eval.c (eval_init): Remove registrations of tofloat,
toint, tofloatz and tointz.
* tests/016/ud-arith.tl: New tests.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* parser.c (listener_auto_compound_s): New symbol variable.
(repl): If *listener-auto-compound-p* is true, then evaluate
multiple forms directly as a compound expression, without
inserting progn at the head.
(parse_init): Initialize symbol variable and register
the *listener-auto-compound-p* special.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The new function use-sym-as can bring a foreign
symbol into a package under a different name,
which is not that symbol's name. This is also
featured in a new defpackage clause, :use-syms-as.
With this simple relaxation in the package system,
we don't require package local nicknames, which is
more complicated to implement and less ergonomic,
because it doesn't actually vanquish the use of
ugly package prefixes on clashing symbols.
* eval.c (eval_init): Register use-syms-as.
* lib.c (use_sym_as): New function, made out of
use_sym.
(use_sym): Now a wrapper for use_sym_as.
* lib.h (use_sym_as): Declared.
* stdlib/package.tl (defpackage): Implement :use-syms-as
clause.
* tests/012/use-as.tl: New file.
* txr.1: Documented,
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (compiler comp-fun-form): Recognize
the pattern (subtypep (typeof x) y) and rewrite it to
(typep x y).
* stdlib/match.tl (compile-struct-match): Don't generate
the (subtype (typeof x) y) pattern, but (typeof x y).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/op.tl (opip-expand): Take arguments which specify
the op and do operators to be inserted. Pass these
through the recursive calls.
(opip, oand): Pass op and do for the new arguments.
(lopip, loand): New macros like opip and oand, but
passing lop and ldo to the expander.
(lflow): New macro.
* autoload.c (op_set_entries): Add autoload entries
for lopip, loand and lflow.
* tests/012/op.tl: A few new tests.
* txr.1: Documented.
* stdlib/doc-syms.tl: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (dump-to-tlo): To ensure numbers are
externalized in such a way that they will be loaded back
exactly, we need to set a few special variables. For integers,
we want *print-base* to be 10. Numbers printed in other bases
cannot be read back correctly. Octal, hex and binary could be,
but they would need to be printed with the correct prefixes.
For floating-point values, we want to switch to the default
print format, and use flo-max-dig for the precision. That one
s not not the default value; the default is flo-dig.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The optimizer eliminates calls to pure library functions when
all their arguments are D-registers. The call is made at
compiled time and its value is inserted into the program
as a constant (in a newly allocated D register).
The bug is that we can't do this for a D register that
is linked to a load-time value, because we don't know its
value until run-time.
* stdlib/optimize.tl (basic-blocks do-peephole-block): Add
a constraint that none of the D registers can be a member
of bb.lt-dregs, which holds the list of D registers that
are used for load-time values.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/op.tl (sys:opip-single-let-p,
sys:opip-let-p): New functions.
(sys:opip-expand): Restructure from collect loop
to car/cdr recursive form, because the new let operators
in opip need access to the rest of the pipeline.
Implement let operators.
* tests/012/op.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
Discovered while experimenting with new optimizations.
* stdlib/optimize.tl (basic-blocks join-block): When we
join the following block into the current block, we must
propagate the nojoin property of the following block.
The nojoin property has to do with the last instruction
being xend. The joined block has that last instruction
and so must be nojoin.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Discovered while experimenting with new optimizations.
* stdlib/optimize.tl (basic-blocks :postinit): Pass t argument
to new parameter of basic-blocks link-graph.
(basic-blocks link-graph): New parameter indicating whether
this is the first call; if false, we reset all the links.
(basic-blocks elim-dead-code): This no longer has to reset
the links before calling link-graph. But now calls link-graph
one more time after the dead code removal so that no dead
blocks appear in the graph.
|
|
|
|
|
|
|
|
|
| |
* stdlib/place.tl (sys:get-fun-getter-setter): The check added
recently for a non-bindable sym at the top is completely
bogus, and makes it impossible to use trace for methods.
The function handles various kinds of function names that
are not symbols. The check must be done in the fallback
case, where plain symbols are handled.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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/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.
|