| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
| |
* eval.c (expand_quasi): Add all-important missing
case which expands compound forms. This looks
like a txr-160 regression.
|
|
|
|
|
|
| |
* eval.c (do_expand): When walking a defun or defvarl,
register them as tentative defs. Thus warnings are nicely
supressed in code like (progn (defun foo ()) (foo)).
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_intrinsic): Dump deferred warnings after
expansion, unless in the middle of a load.
* parser.c (read_eval_ret_last): Bind *load-recursive* around
all evaluations to t, then dump warnings if prior value
of *load-recursive* is nil. Thus the repl's :read feature
behaves like load.
(repl_warning): We can now unconditionally defer deferrable
warnings here now, whether or not in a load.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register sys:ctx-form and sys:ctx-name
intrinsics.
* lisplib.c (error_set_entries, error_instantiate): New static
functions.
(lisplib_init): Register autoloading of error.tl via
new functions.
* share/txr/stdlib/error.tl: New file.
* struct.c (make_struct_type): Purge deferred warnings.
* unwind.c (uw_late_init): Register purge-deferred-warning
intrinsic.
|
|
|
|
|
|
|
| |
* eval.c (do_expand): Warn about unbound functions
or non-bindable symbols in function position
regardless whether the form is a dotted form
that was subject to the apply transformation.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Warnings about undefined functions and variables are now
deferred during loading, so forward references do not generate
nuisance diagnostics.
* eval.c (load_recursive_s): New symbol variable.
(eval_defr_warn): New static function.
(op_defvarl, op_defun): Purge any deferred warning about the
given function or variable not being defined.
(load): Rebind the sys:*load-recursive* special var to true
around the load. After the load, dump deferred warnings
if the prior binding of sys:*load-recursive* is false.
Discard deferred warnings in the case of termination by
a nonlocal control transfer.
(do_expand): Treat unbound vars and functions as deferrable
warnings, specially tagged for individual purging frkm
the deferred list.
(eval_init): Intern sys:*load-recursive* and initialize
load_recursive_s variable.
* eval.h (load_recursive_s): Declared.
* parse.c (repl_warning): Accept variable arguments.
Check whether we are loading and if so, defer deferrable
(repl): Adjustment for altered signature of repl_warning.
warnings.
* txr.c (txr_main): dump deferred warnings after
evaluating Lisp stream.
* unwind.c (deferred_warnings): New static variable.
(uw_throw): When a deferrable warning is caught,
suppress the usual message and add it to the
deferred_warnings list.
(uw_defer_warning, uw_dump_deferred_warnings,
uw_dump_deferred_warnings, uw_purge_deferred_warnings): New
functions.
(uw_late_init): gc-protect deferred_warnings.
* unwind.h (uw_defer_warning, uw_dump_deferred_warnings,
uw_dump_deferred_warnings, uw_purge_deferred_warnings): New
functions declared.
|
|
|
|
|
|
|
| |
* eval.c (me_whilet): insert gensym if last var is missing.
Warn if init-form looks like a variable.
* txr.1: Documented by copy and paste from iflet.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (pm_table): New static variable.
(expand_param_macro): New static function.
(expand_params): Expand parameter list macros via
expand_param_macro.
(eval_init): gc-protect pm_table and initialize it.
Register *param-macro* variable.
* lisplib.v (pmac_set_entries, pmac_instantiate): New static
functions.
(lisplib_init): Register autoloading of pmac.tl via new
functions.
* share/txr/stdlib/pmac.tl: New file.
* txr.1: Notes under defun, lambds, flet/labels and defmacro
about the existence of parameter macros which add to
the syntax. New Parameter List Macros section.
Documented *param-macro* and define-param-expander.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The problem is that during the expansion of something like (do
inc @1), the place expansion will generate a (sys:setq @1 ...)
form which undergoes expansion before the processing which
converts @1 to a gensym. But now that throws an error during
the expansion of the sys:setq form that @1 isn't a bindable
symbol. Since warnings are suppressed during this expansion
phase, we can make it a warning.
* eval.c (not_bindable_warning): New static function.
(do_expand): For the assignment special forms,
throw a warning if the target isn't a bindable symbol,
not an error.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It turns out we have a silly problem: catch is a special
operator, which undergoes a macro-like expansion which alters
its syntax, but uses the same operator symbol.
We turn catch into a macro which expands to a sys:catch
operator.
* eval.c (sys_catch_s): New symbol variable.
(expand_catch): Function now expands sys:catch forms
without altering any syntax.
(do_expand): Check for sys:catch rather than catch.
Call expand_catch differently: it takes the form now
instead of just the arguments, so it can return the
original form if no expansion takes place.
(eval_init): Initialize sys_catch_s variable. Change
registration of op_catch to sys:catch symbol.
* lisplib.c (except_set_entries): Add catch to the
list of autoload symbols for except.tl.
* share/txr/stdlib/except.tl (catch): New macro for
transforming catch to sys:catch.
* txr.1: Reclassify catch operator as a macro.
|
|
|
|
|
| |
* eval.c (expand_catch_clause): Check added that clause sym
must be a symbol.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (lispq_setq_s, setqf_s): New symbol variables.
(op_defvarl, op_defsymacro, op_defmacro, op_setq,
op_lisp1_setq, op_setq): Drop bindability checks.
In the case of defmacro, this is already taken care
of so the check is redundant.
(do_expand): Add bindable check to defvar_s and cousins. In
the function form fallback case, check for the various
assignment operators and check their argument count and
bindability of destination symbol.
(eval_init): Initialize new symbol variables; register
corresponding special operators using variables.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fix nested macro parameters not being expanded properly in all
cases. Diagnose uses of :env, :form and :whole in
function parameter lits.
* eval.c (expand_opt_params_rec, expand_params_rec): New
parametr, macro_style_p, indicating destructuring macro
parameter list is to be expanded. Restructure the cases in
expand_opt_params_rec to fix a bug: only recursively treating
a nested parameter A only when A stands alone, or without
a default form as (A), failing to do so when it is (A B ...).
Diagnose :env, :whole or :form inside a function parameter
list. Do not process recursive parameter lists for functions;
diagnose nesting as bad syntax.
(expand_params): Add macro_style_p parameter.
(expand_macrolet, expand_tree_cases): Pass t as argument to
new parameter of expand_params.
(do_expand): Pass t or nil as argument to new parameter
of expand params, based on whether expanding a macro
or function parameter list.
|
|
|
|
|
|
|
|
|
|
|
| |
This fixes the incorrect treatment of the x-p parameter in
(lambda (: (x form x-p))) when x-p is a special variable.
It is being lexically bound.
* eval.c (expand_opt_params_rec): When processing a (var
initform) pair, check for (var initform sym). Error out if
sym is not bindable. Check if it is special and if so,
push it into the list of specials.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Checking for uses of non-bindable symbols in
variable binding and argument lists is moved to
expansion time. Also checked at expansion time
are macro lambda list conventions. :env and others
must have a bindable parameter, and the optional
arg colon cannot occur twice.
* eval.c (bind_args): Remove run-time checks that are now done
at expansion time.
(not_bindable_error): New function.
(expand_opt_params_rec, expand_params_rec): Take form argument
for reporting errors. Implement more detailed checking against
non-bindable symbols, and against :env, :form and :whole
having missing or unsuitable arguments.
(expand_params): Take form argument for error reporting,
and pass to expand_params_rec.
(bind_macro_params, bindings_helper): Remove run-time checks
that are now done at expansion time.
(check_lambda_list): Function removed, because expand_params
now does the bulk of this check. We have a regression here
in that we lose the check against :env and others occurring
in a function parameter list; this has to be worked into
expand_params.
(op_defvarl, op_defsymacro, op_defmacro, op_setq,
op_lisp1_setq, op_setqf): Replace repeated code with call to
not_bindable_error. However, these should be replaced by
expansion-time checks anyway, and eventually will be.
(expand_macrolet): Pass form to expand_params.
(expand_tree_cases): Take form argument for error reporting.
Pass to expand_params.
(expand_tree_case): Pass form to expand_tree_cases.
(me_def_variable, me_mlet): Replace repeated code with call to
not_bindable_error.
(expand_vars): Do bindable symbol check here, so it doesn't
have to be done at the run time in bindings_helper.
(me_flet_labels): Don't call check_lambda_list.
Expansion of the generated lambdas will do argument
list checking.
(expand_catch_clause): Pass form to expand_params.
(do_expand): Don't call check_lambda_list. Pass form to
expand_params.
|
|
|
|
|
|
| |
* eval.c (optimize_qquote_form): Check for a rcons
forms. If thearguments are nothing but quoted forms,
convert to literal range.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The issue is that ^#R(,(+ 2 2) ,(+ 3 3)) produces 4..6 rather
than #R(4..6). 4..6 is, of course, the syntax (rcons 4 6)
which evaluates to a range. Here we want the range to which
it evaluates, not the syntax.
* eval.c (expand_qquote_rec): Handle the case when the
qquoted_form is a range atom: expand the from and to parts,
and generate a rcons expression. Though this seems to be
opposite to the previous paragraph, it's the right thing.
* parser.y (range): Drop the unquotes_occurs case which
produces rcons syntax. Produce a range object, always.
This is the source of the problem: a (rcons ...) expression
was produced here which was just traversed by the qquote
expander as list. It's the expander that must produce
the rcons expression.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In the parallel binding (let ((x s) (s 0) (y s)) ...),
both x and y must bind to the prior value of s,
not to the new value 0. We have the bug that if
s is a special variable, the initialization of y
sees the new dynamic environment which contains the
new value, so x gets the previous, y gets new.
This commit fixes it.
* eval.c (reparent_env): New static function.
(bindings_helper): Separate logic into two loops,
for sequential and parallel binding, so we don't
have to repeatedly test this condition in the loop
body, and can think separately about each case and
streamline it. Nothing new happens under sequential
binding; the behavior that is wrong for parallel
binding is right for sequential. Under parallel binding,
what we do is reset the dynamic environment to the
original one prior to each evaluation of an initform.
Then if the evaluation changes to a new dynamic
environment (a special variable is being bound),
we notice this and hook the new environment into
a local stack, changing it parent pointer. At the
end, we install this stack as the new dynamic env.
Thus each init form is evaluated in the original
dynamic env.
* tests/011/special-1.tl: New tests added.
|
|
|
|
|
|
|
|
| |
* eval.c (me_iflet_whenlet): Allow the last binding
to be (init-form) instead of (sym init-form), for
situations in which sym is never used.
* txr.1: Documented.
|
|
|
|
|
| |
* eval.c (do_expand): Fix outdated comment about what
forms are expanded like function calls.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This addresses a problem with the new scheme for handling
specials. If we let specials be bound in the lexical
environment and then do the swizzle into the dynamic
environment using sys:with-dyn-rebinds, that only works
correctly for parallel bindings (and thus also for lambda and
macro parameters). For sequential bindings, it exposes the
possibility that a closure is created during the sequential
binding which captures a would-be special variable while it is
still in the lexical stage. That closure can be thrown out of
there, so the sys:with-dyn-rebinds is never reached which
swizzles the variable.
The new scheme is very simple. When expanding a let, we
tranform (s init) to (s (sys:dvbind s init)) if s is a special
variable. This new sys:dvbind operator binds s to the value of
the init expression in a newly created dynamic environment,
and returns the #:unbound symbol, which is received by the
lexical s. Problem solved. The only thing remains is that the
let special operator must save and restore the dynamic
environment.
There is no need for sys:with-dyn-rebinds around the body
of a let, but we keep that mechanism and approach for handling
specials in argument lists.
* eval.c (dvbind_s): New symbol variale.
(bindings_helper): Lose the env_out argument; return the new
environment. No caller uses the returned bindings any more.
(op_let): Call bindings_helper in initializing expression of
new_env. Save the dyn_env, and restore it after evaluating
the body.
(op_dvbind): New static function.
(expand_vars): Lose the pspecials argument. Perform
the insertion of sys:dvbind.
(do_expand): Simplify the let expander: expand_vars no longer
outputs a list of specials and there is no need to insert
with_dyn_rebinds_s. Add a case for sys:dvbind: assume it
requires no expansion.
(eval_init): Intern sys:dvbind, and bind it as an operator
to the new op_dvbind function.
|
|
|
|
|
|
|
|
|
|
|
| |
The genvim.txr program iterates over package symbols
and encounters sys:unbound. It binds that to a local
variable, creating a problem due to the special hack.
Let's turn sys:unbound into a gensym.
* eval.c (eval_init): Protect unbound_s from gc.
Initialize unbound_s with an uninterned symbol
created by make_sym.
|
|
|
|
|
|
|
|
| |
* eval.c (struct bindings_helper_vars): Remove de member.
(copy_bh_env_handler): Remove copying of dynamic environment.
(bindings_helper): Remove all code dealing with de.
The sequential binding will no longer introduce a dynamic
environment.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Removing code which handles the special function
argument (sys:special ...) which can occur ahead
of the other arguments, indicating the names of
arguments which require special binding.
Removing code which handles (sys:special init-form var)
bindings in let/let*.
* eval.c (env_vbind_special): Function removed.
(bind_args): Do not look for special list; no such
thing occurs. Use env_vbind directly rather than
env_vbind special.
(bind_macro_params): Likewise.
(funcall_interp): Streamlined by not having to
check for presence of specials list and setting up
the dynamic environment frame for it.
(bindings_helper): Don't look for the (sys:special
initform sym) syntax among the bindings.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The old way: process, at expansion time, bindings in lambda
lists and all binding constructs to find special variables
(symbols marked special). Replace these bindings with
an annotation. Then when the interpreter performs binding,
the binding helper functions process these annotations.
Also, if specials occur, wrap the construct in
sys:with-save-specials to set up the necessary dynamic
environment frame.
The new way: process, at expansion time, bindings in
lambda lists and binding constructs (which have been reduced
to just let and let*). If special variables occur, then
wrap the body in in sys:with-dyn-rebinds which re-binds
specific symbols in the dynamic namespace, copying their
value from their lexical binding. The lexical bindings are
then replaced with the value sys:unbound, which indicates that
the value should be resolved in the dynamic environment.
* eval.c (with_saved_vars_s): Symbol variable removed.
(with_dyn_rebinds_s): New symbol variable.
(lookup_var, lookup_sym_lisp1): If a lexical binding contains
the value sys:unbound, then continue the search through the
dynamic environment; ignore the remaining lexical
environments.
(expand_params_rec): Bugfix: neglected collect of
special variable in fallback case.
(expand_params): Takes body environment, and returns two
values as a cons cell. The additional return value is a body
that is either the original body, or else is wrapped with
sys:with-dyn-rebinds. Removed is the special variable
hack inserted into the syntax.
(expand_macrolet, expand_tree_cases): Adjust to new
expand_params interface.
(op_with_saved_vars): Static function removed.
(op_with_dyn_rebinds): New static function.
(expand_vars): Return list of special variables via pointer
argument, rather than just a Boolean which indicates that
specials are present. Transformation to special representation
is removed.
(expand_catch_clause): Adjust to new expand_params interface.
(expand_save_specials): Static function removed.
(do_expand): Adjust let/let* expansion to new expand_vars
interface. Generate the sys:with-dyn-rebinds wrapping around
the body. Adjust the defun, lambda and mac-param-bind
expanders to the new expand_params interface.
Recognize sys:with-dyn-rebinds and don't expand it;
all places which generate this form have to expand the
internals themselves.
(eval_init): Remove initialization of with_saved_var_s,
and its registration as an operator.
Initialize with_dyn_rebinds_s with interned symbol,
and register as operator.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
NOTE: The socket test cases do not pass under this commit:
this is expected.
The for and each family of operators will now be macros which
expand to let/let* binding construct wrapping a lower level
special operator.
This is in preparation for a change to how special variable
binding is implemented.
This change reduces the number of special forms which bind
variables.
There is a single low-level operator for for loops called
sys:for-op. Its syntax is a lot like the C89 for loop:
(sys:for-op init-forms test step-forms body). The init-forms
do not bind anything; it is just forms.
There is a sys:each operator for implementing each,
each*, append-each and all those operators. Its syntax is
(sys:each-op type-sym optional-vars . body).
The type-sym is one of each, append-each or collect-each.
If optional-vars is nil, then the operator looks at the
immediate lexical environment, and assumes all the bindings
there are the each iteration variables and it works with
those bindings, like its predecessor did. Otherwise
optional-vars is a list of symbols: the operator walks the
list and resolves each element to a binding. This is
used in two situations: when some of the variables are
special (dynamically scoped) or when the variables are
bound sequentially with let* and are thus scattered in
multiple levels of environment.
* eval.c (for_op_s, each_op_s): New symbol variables.
(get_bindings): New static function.
(op_each): Now implements sys:each-op.
(op_for): Now implements sys:for-op.
(get_var_syms): New static function.
(me_each, me_for): New static functions.
(do_expand): Do not expand the each operator family under the
same rule. New case handling sys:each-op is introduced
due to the different syntax.
The for case restructured to handle for_op_s.
(eval_init): Intern sys:each-op and sys:for-op symbols.
Register the corresponding operators. Move registrations of
the public symbols each, each*, for, for* and all the other
each variants to be macros.
* tests/011/macros-2.expected: Updated with different
macro expansion which is now produced for a while
loop.
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register mismatch intrinsic.
* lib.c (mismatch): New function.
* lib.c (mismatch): Declared.
* txr.1: Documented mismatch.
|
|
|
|
|
|
| |
* eval.c (do_expand): Do not use the "unbound function"
warning if the operator position isn't a symbol which
can have a function binding.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (lookup_fun): When looking up (meth ...) syntax,
avoid calling static_slot with a slot argument which isn't
a static slot of the given type, otherwise an exception
is thrown. The situation is turned instead into a nil
return which just indicates "no binding". This allows,
for instance, (fboundp '(meth foo bar)) to be safe.
It makes no sense for that to return nil if foo
doesn't name a struct type, but to throw an error if
bar isn't a static slot in foo.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This improves compatibility with other Lisp dialects
in a small way.
* eval.c (eval_init): Register endp intrinsic.
* lib.c (endp): New function.
* lib.h (endp): Declared.
* txr.1: Documented endp.
|
|
|
|
|
|
|
| |
* eval.c (me_equot): New static function.
(eval_init): Register equot intrinsic macro.
* txr.1: Documented equot.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (warning_continue): Static function removed.
(no_warn_expand): Use uw_muffle_warning instead of
removed function.
* parser.y (warning_continue): Static function removed.
(parse_once): Use uw_muffle_warning instead of
removed function.
* unwind.c (uw_muffle_warning): New function.
* unwind.h (uw_muffle_warning): Declared.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Rather than fix this in the awk macro, let's
just have sys:expand block warnings.
* eval.c (warning_continue, no_warn_expand): New static
function.
(eval_init): Change registration of sys:expand to point
to no_warn_expand.
* share/txr/stdlib/place.tl (call-update-expander,
call-clobber-expander, call-delete-expander, sys:placelet-1):
Remove ignwarn wrapping from sys:expand calls.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (do_expand): If a compound form doesn't expand into
anything, then let us check whether it calls an unbound
function, and issue a warning.
* share/txr/stdlib/place.tl (sys:pl-expand): Move function
definition ahead of first use to suppress unbound function
warning. Eventually we will have a relaxed model of deferred
warning about this.
(sys:placelet-1): Suppress warnings around call to sys:expand
because we are expanding a body into which we inserted
function calls without inserting their definitions.
|
|
|
|
|
|
|
|
|
| |
* eval.c (do_expand): When expanding the body of a defun
we must create a function shadowing environment which
indicates that the function's name is in scope.
This must not be done for defmacro; a defmacro doesn't
introduce a function binding, and a macros's body doesn't
have that macro in scope.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_exception): New static function.
(eval_error): Reduced to wrapper around eval_exception.
(eval_warn): New function.
(me_op): Bind the rest symbol in a shadowing env to suppress
watnings about unbound rest.
(do_expand): Throw a warning when a bindable symbol is
traversed that has no binding.
(expand): Don't install atoms as last_form_expanded.
* lib.c (warning_s, restart_s, continue_s): New symbol
variables.
(obj_init): Initialize new symbol variables.
* lib.h (warning_s, restart_s, continue_s): Declared.
* lisplib.c (except_set_entries): New entries for
ignwarn and macro-time-ignwarn.
* parser.c (repl_warning): New static function.
(repl): Use repl_warning function as a handler for
warning exceptions: to print their message and then
continue by throwing a continue exception.
* parser.y (warning_continue): New static function.
(parse_once): Use warning_continue to ignore warnings.
In other words, we suppress warnings from Lisp that is
mixed into TXR pattern language code, because this
produces too many false positives.
* share/txr/stdlib/except.tl (ignwarn, macro-time-ignwarn):
New macros.
* share/txr/stdlib/place.tl (call-update-expander,
call-clobber-expander, call-delete-expander): Ignore warnings
around calls to sys:expand, because of some gensym-related
false positives (we expand code into which we inserted some
gensyms, without having inserted the constructs which
bind them.
* tests/011/macros-2.txr: Suppress unbound variable
warnings from a test case.
* tests/012/ifa.tl: Bind unbound x y variables in one
test case.
* tests/012/struct.tl: Suppress unbound variable
warnings in some test cases.
* uwind.c (uw_throw): If a warning is unhandled, then
print its message with a "warning" prefix and then
throw a continue exception.
(uw_register_subtype): Eliminate the check for sub
already being a subtype of sup. This allows us to
officially register new types against t.
(uw_late_init): Register continue exception type as a
subtype of the restart type.
Formally register warning type.
* txr.1: Documented ignwarn.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In this patch commit I'm addressing the issue introduced in
part 1 that expressions in @(output) blocks are still using
(sys:expr ...) wrapping, but are passed down to an evaluator
which now expects unwrapped expressions now.
As part of this change, I'm changing the representation of
@expr from (sys:expr . expr) to (sys:expr expr).
* eval.c (format_field): Adjust access to sys:expr
expression based on new representation.
(transform_op): Likewise.
* lib.c (obj_print_impl): Likewise.
* match.c (dest_bind): Likewise.
(do_txeval): Likewise.
(do_output_line): Likewise, in some compat code. Here is the
fix for the issue: when calling tx_subst_vars, we pass a list
of one element containing the expression, not wrapped in
sys:expr. Previously, we passed a one-element list containing
the sys:expr.
* parser.y (o_elem): If a list occurs in the syntax, represent
it as (sys:expr list) rather than (sys:expr . list).
(list): Do the same for @ n_expr syntax.
(expand_meta, make_expr): Harmonize with the representation
change.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The bug is that `@@@a` prints as `@@a` which
reads as a different object.
In this patch we simplify how quasiliterals are represented.
Embedded expressions are no longer (sys:expr E), just E.
Meta-numbers N and variables V are still (sys:var N).
However `@@a` and `@a` remain equivalent.
* eval.c (subst_vars): No need to look for expr_s;
just evaluate a compound form. The recursive nested
case is unnecessary and is removed.
(expand_quasi): Do nothandle expr_s; it is not
part of the quasi syntax any more.
* lib.c (out_quasi_str): Do not look for expr_s in the
quasi syntax; just print any expression with a @
the fallback case.
* match.c (tx_subst_vars): Analogous changes to those
done in subst_vars in eval.c.
* parser.y (quasi_meta_helper): Static function removed.
This was responsible for the issue due to stripping a
level of meta from expressions already having a meta
on them.
(quasi_item): In the `@` n_expr syntax case, no longer
call quasi_meta_helper. The remaining logic is simple
enough to put in line. Symbols and integers get wrapped
with (sys:var ...); other expressions are integrated
into the syntax as-is.
|
|
|
|
|
|
|
|
| |
* eval.c (do_expand): When a dohash special form is
expanded, a macro shadowing environment must be
created for the two variables that it binds and the
body must be expanded in that environment, to
protect the variables from symbol macros.
|
|
|
|
|
|
| |
* eval.c (do_expand): Do not expand into (sys:expr ...)
expressins, the same way (sys:var ...) expressions are
avoided. They are not forms.
|
|
|
|
|
|
|
|
|
|
| |
The test case is (op list . @rest) and similar, which were
expanding to a syntax containing an incorrect form like
[sys:apply list sys:var rest #:rest-0123] where the
sys:var rest are superfluous.
* eval.c (transform_op): Missing case: the code which handles
metas in the dot position must handle @rest not only @<number>.
|
|
|
|
|
|
| |
* eval.c (do_expand): If the form is (sys:var ...)
then skip it without expanding. Of course, that does
not preclude it form being a macro.
|
|
|
|
|
|
| |
* eval.c (me_op): When the operator is op, the arguments
must be expanded as Lisp-1 with expand_forms_lisp1, not
with the regular expand_forms.
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (do_expand): When expanding the macro-time
form, do not macro-expand it entirely and then evaluate.
Rather, expand each argument form and evaluate.
This way earlier forms can make global definitions
which are used while macro-expanding later definitions.
* txr.1: Behavior documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The syntax of mac-param-bind forms isn't recognized at all in
the expander, causing these forms to be incorrectly expanded
as if they were function calls.
* eval.c (mac_param_bind_s): New symbol variable.
(do_expand): Handle mac_param_bind_s with the same block of
code as tree_bind_s, adjusted to account for the small
syntactic difference.
(eval_init): Initialize mac_param_bind_s with interned symbol.
Register operator using mac_param_bind_s to avoid redundant
intern call.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When the function bodies of macrolets are themselves
being macro-expanded, this is incorrectly being done in
the original macro environment without taking into account
the macrolet parameters which those bodies have in scope.
Hence the parameters are not able to shadow symbol macros.
* eval.c (make_var_shadowing_env): Moved above expand_macrolet
so we can avoid adding a forward declaration. Otherwise
unchanged.
(expand_macrolet): For each macrolet function, create
a shadowing environment which contains its parameters,
and use that for expanding the body.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The problem is about those Boolean parameters which indicate
whether their associated optional parameters are present: in
(lambda (: (opt-parm 42 opt-parm-p))), such a parameter is
opt-parm-p. When parameter lists are walked by the macro
expander, these parameters are not being included as shadow
entries in macro-time parameter lists. Thus if opt-parm-p
happens to shadow an outer symbol macro, that symbol macro
will be expanded anyway.
* eval.c (get_opt_param_syms): Function now lists those
additional parameters.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (reg_mac): Static function changed to extern.
(me_defex, register_exception_subtypes): Static function
removed here; relocated into unwind.c.
(eval_init): Registrations of defex, throw, throwf, error,
register-exception-subtypes and exception-subtype-p removed.
* eval.h (reg_mac): Declared.
* unwind.c (me_defex, register_exception_subtypes): Static
function moved here.
(uw_late_init): Registrations of defex, throw, throwf, error,
register-exception-subtypes and exception-subtype-p moved
here.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In this patch we allow (symbol-function '(macro sym)),
(defun (macro sym) (form env) ...), and
(trace (macro sym)).
* eval.c (macro_s): New symbol variable.
(lookup_fun, func_get_name, op_defun): Support (macro sym)
syntax.
(builtin_reject_test): Pass through (macro sym) syntax.
(eval_init); Initialize macro_s.
* share/txr/stdlib/place.tl (sys:get-fun-getter-setter):
Support macro place.
* txr.1: Documented verything.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
All macros are function bindings now.
* eval.c (me_interp_macro): New function. Body is
a copy of block from expand_macro.
(op_defmacro): Hoist the me_interp_macro function into
the object domain, installing the macro material as the
environment. This function is the expander.
(expand_macro): Assume that the binding is a function
and call it. The cons case is gone.
(expand_macrolet): Similar change to the one in
op_defmacro: a macrolet is also a function.
* txr.1: Documentation under symbol-macro updated.
|