diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2023-11-16 00:45:49 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2023-11-16 00:45:49 -0800 |
commit | ad068f27d819465c78c574019f32a2e1d30ca5ff (patch) | |
tree | 3385e77968f5bf751ee5e0cb3dcf61c8236edfc4 /stdlib | |
parent | de166af6dff90ec0c69b5026d66195dcf00d38f7 (diff) | |
download | txr-ad068f27d819465c78c574019f32a2e1d30ca5ff.tar.gz txr-ad068f27d819465c78c574019f32a2e1d30ca5ff.tar.bz2 txr-ad068f27d819465c78c574019f32a2e1d30ca5ff.zip |
stdlib/error.tl problem rears its head.
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.
Diffstat (limited to 'stdlib')
-rw-r--r-- | stdlib/error.tl | 51 |
1 files changed, 26 insertions, 25 deletions
diff --git a/stdlib/error.tl b/stdlib/error.tl index 0e50c671..11f1d094 100644 --- a/stdlib/error.tl +++ b/stdlib/error.tl @@ -29,12 +29,37 @@ (whilet ((form (sys:ctx-form ctx)) (anc (unless (source-loc form) (macro-ancestor form)))) - (set ctx anc)) + (sys:setq ctx anc)) ctx) (defun sys:loc (ctx) (source-loc-str (sys:ctx-form ctx))) +(defun sys:bind-mac-check (ctx-form params obj req fix) + (if (and obj (atom obj)) + (compile-error ctx-form "extra element ~s not matched by params ~a" + obj params) + (let ((l (len obj))) + (iflet ((problem (cond + ((< l req) "few") + ((and fix (> l fix)) "many")))) + (if (zerop l) + (compile-error ctx-form "params ~a require arguments" params) + (compile-error ctx-form "too ~a elements in ~s for params ~a" + problem obj params)))))) + +(defun sys:bind-mac-error (ctx-form params obj too-few-p) + (cond + ((atom obj) + (compile-error ctx-form "extra element ~s not matched by params ~a" + obj params)) + ((null obj) + (compile-error ctx-form "params ~a require arguments" params)) + (t (compile-error ctx-form "too ~a elements in ~s for params ~a" + (if too-few-p "few" "many") + obj params)))) + + (defun compile-error (ctx fmt . args) (let* ((nctx (sys:dig ctx)) (loc (sys:loc nctx)) @@ -62,30 +87,6 @@ (throw 'defr-warning (fmt `@loc: warning: ~s: @fmt` name . args) tag) (continue ())))) -(defun sys:bind-mac-error (ctx-form params obj too-few-p) - (cond - ((atom obj) - (compile-error ctx-form "extra element ~s not matched by params ~a" - obj params)) - ((null obj) - (compile-error ctx-form "params ~a require arguments" params)) - (t (compile-error ctx-form "too ~a elements in ~s for params ~a" - (if too-few-p "few" "many") - obj params)))) - -(defun sys:bind-mac-check (ctx-form params obj req fix) - (if (and obj (atom obj)) - (compile-error ctx-form "extra element ~s not matched by params ~a" - obj params) - (let ((l (len obj))) - (iflet ((problem (cond - ((< l req) "few") - ((and fix (> l fix)) "many")))) - (if (zerop l) - (compile-error ctx-form "params ~a require arguments" params) - (compile-error ctx-form "too ~a elements in ~s for params ~a" - problem obj params)))))) - (defun lambda-too-many-args (form) (compile-error form "excess arguments given")) |