Idiomdrottning’s homepage

Code-walking with call-tables

Here’s an example of call-tables.

This is from brev2scm, which walks a .brev-file and tries to figure out what dependencies are used so that the resulting .scm file doesn’t need to depend on all of brev.

This is the code-walker (also uses tree-walk-preorder):

(define (see thing)
  (aif (belongs thing)
       (seen it thing)
       #f))

(import tree)
(tree-walk-preorder
 see
 (with-input-from-file
     file-name
   read-list))

So for each node in the code that we read from file-name, we just call see which is this tiny little one-expression thing. And belongs and seen are just call-tables!

(define belongs (call-table))
(define seen (call-table*))

belongs is populated with this huge, hard-coded, thousand-line alist:

(belongs
 update:
 (alist->hash-table
  '((aand . anaphora)
    (acond . anaphora)
    (aif . anaphora)
    ...)))

When see sees something that belongs to a symbol like aand belongs to anaphora and aif also belongs to anaphora, it then stores that something under that symbol.

The two tables are each other’s inverses in that sense. When we see something we store it where it belongs, basically.

We end up with a database of everything we’ve seen that might belong somewhere, and where it belongs. A very brute-force but easy way to solve the problem.♥︎