(use srfi-1)
(define count-defines
(let* ((definers '(define define-macro define-constant
define-inline define-syntax))
(count-defines
(lambda (file)
(cons file
(length
(filter
(lambda (form)
(and (pair? form)
(memq (car form) definers)))
(with-input-from-file
file read-file)))))))
(lambda (files)
(let ((defines-count (map count-defines files)))
(for-each (lambda (file/defcount)
(print (car file/defcount) ": "
(cdr file/defcount)))
defines-count)
(print "Total: "
(reduce + 0 (map cdr defines-count)))))))
(let ((files (command-line-arguments)))
(if (null? files)
(exit 0)
(count-defines files)))
Exemplos de uso:
$ csi -s count-defines.scm count-defines.scm
count-defines.scm: 1
Total: 1
$ csi -s count-defines.scm spiffy/trunk/*.scm
spiffy/trunk/cgi-handler.scm: 5
spiffy/trunk/simple-directory-handler.scm: 4
spiffy/trunk/spiffy-base.scm: 70
spiffy/trunk/spiffy.scm: 1
spiffy/trunk/ssp-handler.scm: 10
spiffy/trunk/web-scheme-handler.scm: 4
Total: 94
Embora este programa não diga muita coisa de útil sobre o código que analisa, serve para mostrar um dos aspectos mais interessantes de Lisp: a possibilidade de se tratar, naturalmente, código como dados. Basicamente, a contagem de definições no toplevel consiste em ler todas as expressões de um arquivo e verificar se o
car
de cada expressão é um dos símbolos define
, define-macro
, define-constant
, define-inline
ou define-syntax
(se a expressão for um par).Este tipo de análise não é muito útil porque, pelo menos em Chicken, é possível especificar o que deve ser "visível" ou não no código compilado. Isto pode ser feito com as declarações
export
e hide
. Outros motivos são que este programa não consegue inferir as definições de toplevel que serão geradas através da expansão de macros (web-scheme, por exemplo, usa esta estratégia) e que não computa definições feitas dentro de blocos cond-expand
.
Nenhum comentário:
Postar um comentário