diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2025-05-09 20:24:52 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2025-05-09 20:24:52 -0700 |
commit | 14fddd89cbb63cd6ee99810b6730992a3c8be475 (patch) | |
tree | 7947290d288f82cc5b592e1753622692879432d9 | |
parent | cc69832ceecf915971cbd09295e5bb4d39fc5de0 (diff) | |
download | txr-14fddd89cbb63cd6ee99810b6730992a3c8be475.tar.gz txr-14fddd89cbb63cd6ee99810b6730992a3c8be475.tar.bz2 txr-14fddd89cbb63cd6ee99810b6730992a3c8be475.zip |
trace: new parameter macro :trace for simple static tracing
Just add :trace to the head of the parameter list, and the
function is traced. No dynamic turning on and off though.
* autoload.c (trace_set_entries): Trigger autoload on :trace
keyword.
* stdlib/trace.tl (:trace): New parameter list expander.
* txr.1: Documented.
-rw-r--r-- | autoload.c | 4 | ||||
-rw-r--r-- | stdlib/trace.tl | 31 | ||||
-rw-r--r-- | txr.1 | 42 |
3 files changed, 76 insertions, 1 deletions
@@ -405,9 +405,13 @@ static val trace_set_entries(val fun) val name[] = { lit("trace"), lit("untrace"), nil }; + val kname[] = { + lit("trace"), nil + }; autoload_sys_set(al_fun, sys_name, fun); autoload_set(al_var, vname, fun); autoload_set(al_fun, name, fun); + autoload_key_set(al_key, kname, fun); return nil; } diff --git a/stdlib/trace.tl b/stdlib/trace.tl index 683969bc..0ee55275 100644 --- a/stdlib/trace.tl +++ b/stdlib/trace.tl @@ -25,6 +25,9 @@ ;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ;; POSSIBILITY OF SUCH DAMAGE. +(compile-only + (load-for (struct sys:param-parser-base "param"))) + (defvar *trace-output* *stdout*) (defvar sys:*trace-hash* (hash :equal-based)) @@ -122,3 +125,31 @@ (defmacro usr:untrace (. names) ^(sys:untrace ',names)) + +(define-param-expander :trace (param body menv form) + (ignore menv) + (let* ((pp (new (fun-param-parser param form))) + (args (append pp.req pp.(opt-syms) pp.rest)) + (name (let* ((anc (dig form)) + (sls (source-loc-str anc))) + (match-case anc + ((@(member @type '(flet labels macrolet)) @name) + ^(,type ,name ,sls)) + ((@(or defun defmacro) @name . @nil) + ^(,name ,sls)) + (@nil sls))))) + (with-gensyms (abandoned arglist result) + (list param + ^(let ((,abandoned t) + (sys:*trace-level* (succ sys:*trace-level*)) + (,arglist (list ,*args)) + ,result) + (unwind-protect + (progn + (sys:trace-enter ',name ,arglist) + (set ,result (progn ,*body)) + (sys:trace-leave ,result) + (set ,abandoned nil) + ,result) + (if ,abandoned + (sys:trace-leave :abandoned)))))))) @@ -86888,7 +86888,10 @@ The .code trace and .code untrace -macros control function tracing. +macros control dynamic function tracing, which allows +tracing for named functions to be turned on and off +without modifying their functions or processing their +definitions. When .code trace @@ -86969,6 +86972,43 @@ and functions return .codn nil . +.coNP Parameter List Macro @ :trace +.synb +.mets (:trace ...) +.syne +.desc +The parameter list macro +.code :trace +provides a more static form of function tracing, which cannot +be turned on and off without changing code and processing the form in which the +traced function is defined. + +When the keyword +.code :trace +is inserted as the first element of a parameter list, it triggers a parameter +list macro which transforms the function into a traced function. +The function logs information about its execution into the +.code *trace-output* +stream in the same way as functions for which tracing has been +dynamically enabled by the +.code trace +macro. + +Unlike +.codn trace , +.code :trace +may be used on anonymous functions created by the +.code lambda +operator, functions established by +.code flet +and +.codn labels , +as well as +.code macrolet +and any other constructs which translate into these which allow for +.code :trace +to be inserted into their syntax. + .SS* Dynamic Library Access .coNP Function @ dlopen |