LispPad

Lightweight Scheme Development on macOS

LispKit Debug

Library (lispkit debug) provides utilities for debugging code. Available are procedures for measuring execution latencies, for tracing procedure calls, for expanding macros, for disassembling code, as well as for inspecting the execution environment.

Timing execution

(time expr)     [syntax]

time compiles expr and executes it. The form displays the time it took to execute expr as a side-effect. It returns the result of executing expr.

(time-values expr)     [syntax]

time-values executes expr. If expr evaluates to n values x1, ..., xn, time-values returns n + 1 values t, x1, ..., xn where t is the time it takes to evaluate expr.

Tracing procedure calls

(trace-calls)     [procedure]
(trace-calls level)

This function is used to enable/disable call tracing. When call tracing is enabled, all function calls that are executed by the virtual machine are being printed to the console. Call tracing operates at three levels:

  • 0: Call tracing is switched off
  • 1: Call tracing is enabled only for procedures for which it is enabled (via function set-procedure-trace!)
  • 2: Call tracing is switched on for all procedures (independent of procedure-level tracing being enabled or disabled)

(trace-calls n) will set call tracing to level n. If the level is ommitted, trace-calls will return the current call tracing level.

For instance, if call tracing is enabled via (trace-calls 2), executing (fib 3) will print the following call trace.


> (define (fib n)
    (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2)))))
> (trace-calls 2)
> (fib 2)
  ↪︎ (fib 2) in 
    ⟶ (< 2 2) in fib
    ⟵ #f from <
    ⟶ (- 2 1) in fib
    ⟵ 1 from -
    ⟶ (fib 1) in fib
      ⟶ (< 1 2) in fib
      ⟵ #t from < in fib
    ⟵ 1 from fib in fib
    ⟶ (- 2 2) in fib
    ⟵ 0 from -
    ⟶ (fib 0) in fib
      ⟶ (< 0 2) in fib
      ⟵ #t from < in fib
    ⟵ 0 from fib in fib
  ↪︎ (+ 1 0) in fib
  ⟵ 1 from fib
1

Function invocations are prefixed with , or if it's a tail call. The value returned by a function call is prefixed with .

(procedure-trace? proc)     [procedure]

Returns #f if procedure-level call tracing is disabled for proc, #t otherwise.

(set-procedure-trace! proc trace?)     [procedure]

Enables procedure-level call tracing for procedure proc if trace? is set to #t. It disables call tracing for proc if trace? is #f.

Macro expansion

(quote-expanded expr)     [syntax]

quote-expanded is syntax for macro-expanding expression expr in the current syntactical environment. Macro-expansion is applied consecutively as long as the top-level can be expanded further.


(quote-expanded (assert (+ 1 2)))
⇒  (if (not (+ 1 2))
       (assertion (quote (+ 1 2))))

(quote-expanded-1 expr)     [syntax]

quote-expanded-1 is syntax for macro-expanding expression expr in the current syntactical environment. Macro-expansion is applied at most once, even if the top-level can be expanded further.


(quote-expanded-1 (for x in '(1 2 3) (display x)))
⇒  (dolist (x (quote (1 2 3))) (display x))

(macroexpand expr)     [procedure]
(macroexpand expr env)

Procedure macroexpand applies macro-expansion to the expression expr in the environment env as long as the expression on its top-level can be expanded further. If env is not provided, the current interaction environment is used.


(macroexpand
  '(dotimes (x (+ 2 2)) (display x) (newline)))
⇒  (do ((maxvar (+ 2 2))
        (x 0 (fx1+ x)))
       ((fx>= x maxvar))
     (display x)
     (newline))

(macroexpand-1 expr)     [procedure]
(macroexpand-1 expr env)

Procedure macroexpand-1 applies macro-expansion to the expression expr in the environment env at most once. The resulting expression might therefore only be partially expanded at the top-level. If env is not provided, the current interaction environment is used.


(macroexpand-1 '(for x in '(1 2 3) (display x)))
⇒  (dolist (x (quote (1 2 3))) (display x))
(macroexpand-1
  (macroexpand-1
    '(for x in '(1 2 3) (display x))))
⇒  (let ((x (quote ()))
         (ys (quote (1 2 3))))
     (if (null? ys)
         (void)
         (do ((xs ys (cdr xs)))
             ((null? xs))
           (set! x (car xs))
           (display x))))

Disassembling code

(compile expr)     [procedure]

Compiles expression expr and displays the disassembled code. This is what is being printed when executing (compile '(do ((i 0 (fx1+ i)))((fx> i 10))(display i)(newline))):


CONSTANTS:
    0: #
    1: #
INSTRUCTIONS:
    0: alloc 1
    1: push_fixnum 0
    2: make_local_variable 0
    3: push_local_value 0
    4: push_fixnum 10
    5: fx_gt
    6: branch_if 14                    ;; jump to 20
    7: make_frame
    8: push_constant 0                 ;; #
    9: push_local_value 0
   10: call 1
   11: pop
   12: make_frame
   13: push_constant 1                 ;; #
   14: call 0
   15: pop
   16: push_local_value 0
   17: fx_inc
   18: set_local_value 0
   19: branch -16                      ;; jump to 3
   20: push_void
   21: reset 0, 1
   22: return

(disassemble proc)     [procedure]

Disassembles procedure proc and prints out the code. This is what is being printed when executing (disassemble caddr):


CONSTANTS:
INSTRUCTIONS:
    0: assert_arg_count 1
    1: push_global 426
    2: make_frame
    3: push_global 431
    4: push_local 0
    5: call 1
    6: tail_call 1

Execution environment

(gc)     [procedure]

Force garbage collection to be performed.

(available-symbols)     [procedure]

Returns a list of all symbols that have been used so far.

(loaded-libraries)     [procedure]

Returns a list of all libraries that have been loaded so far.


> (loaded-libraries)
((lispkit draw) (lispkit base) (lispkit port) (lispkit control) (lispkit type) (lispkit list)
 (lispkit string) (lispkit math) (lispkit date-time) (lispkit dynamic) (lispkit char-set)
 (lispkit bytevector) (lispkit char) (lispkit vector) (lispkit regexp) (lispkit record)
 (lispkit hashtable) (lispkit system) (lispkit core) (lispkit gvector) (lispkit box))

(loaded-sources)     [procedure]

Returns a list of all sources that have been loaded.

(environment-info)     [procedure]

Prints out debug information about the current execution environment (mostly relevant for developing LispKit).