[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Lines-of-Code counting for Scheme

From: Greg Troxel
Subject: Lines-of-Code counting for Scheme
Date: Fri, 19 Apr 2002 13:53:39 -0400

I've recently been keeping metrics on programming tasks in C, and want
to do that on code in Scheme as well.  For C, I'm using the usual
"Physical SLOC" definition, which removes all comments and then all
blank lines (yes, this means that coding style makes a difference).
There are a number of definitions of Logical SLOC, but they do not
agree.  So, I took a stab at Logical SLOC for Scheme (taking advantage
of the clean syntax) and declared each '(' to be a single LSLOC.
(-LSLOC seems about 50% higher than PSLOC, at least for the
SLOC-counting program.

Enclosed is sample output and code to measure LSLOC.  (Please flame me
privately if this is inappropriate for this list; given the contents
of the scripts directory it seemed close enough.)  If this is useful
for inclusion in guile, it would be an amusing example with which to
begin the copyright disclaimer process.

gdt gdt 570 ~/SE/SLOC > ./sloc-scm /usr/nguile/share/guile/1.5.6/ice-9/*.scm 
8       /usr/quist/share/guile/1.5.6/ice-9/and-let*.scm
58      /usr/quist/share/guile/1.5.6/ice-9/and-let-star.scm
122     /usr/quist/share/guile/1.5.6/ice-9/arrays.scm
4110    /usr/quist/share/guile/1.5.6/ice-9/boot-9.scm
68      /usr/quist/share/guile/1.5.6/ice-9/buffered-input.scm
523     /usr/quist/share/guile/1.5.6/ice-9/calling.scm
137     /usr/quist/share/guile/1.5.6/ice-9/channel.scm
394     /usr/quist/share/guile/1.5.6/ice-9/common-list.scm
151     /usr/quist/share/guile/1.5.6/ice-9/debug.scm
1330    /usr/quist/share/guile/1.5.6/ice-9/debugger.scm
199     /usr/quist/share/guile/1.5.6/ice-9/documentation.scm
344     /usr/quist/share/guile/1.5.6/ice-9/emacs.scm
238     /usr/quist/share/guile/1.5.6/ice-9/expect.scm
2722    /usr/quist/share/guile/1.5.6/ice-9/format.scm
437     /usr/quist/share/guile/1.5.6/ice-9/getopt-long.scm
72      /usr/quist/share/guile/1.5.6/ice-9/hcons.scm
38      /usr/quist/share/guile/1.5.6/ice-9/history.scm
82      /usr/quist/share/guile/1.5.6/ice-9/lineio.scm
91      /usr/quist/share/guile/1.5.6/ice-9/ls.scm
184     /usr/quist/share/guile/1.5.6/ice-9/mapping.scm
4889    /usr/quist/share/guile/1.5.6/ice-9/match.scm
132     /usr/quist/share/guile/1.5.6/ice-9/networking.scm
4       /usr/quist/share/guile/1.5.6/ice-9/null.scm
494     /usr/quist/share/guile/1.5.6/ice-9/optargs.scm
93      /usr/quist/share/guile/1.5.6/ice-9/poe.scm
185     /usr/quist/share/guile/1.5.6/ice-9/popen.scm
123     /usr/quist/share/guile/1.5.6/ice-9/posix.scm
489     /usr/quist/share/guile/1.5.6/ice-9/pretty-print.scm
100     /usr/quist/share/guile/1.5.6/ice-9/q.scm
151     /usr/quist/share/guile/1.5.6/ice-9/r4rs.scm
20      /usr/quist/share/guile/1.5.6/ice-9/r5rs.scm
220     /usr/quist/share/guile/1.5.6/ice-9/rdelim.scm
235     /usr/quist/share/guile/1.5.6/ice-9/readline.scm
12      /usr/quist/share/guile/1.5.6/ice-9/receive.scm
253     /usr/quist/share/guile/1.5.6/ice-9/regex.scm
230     /usr/quist/share/guile/1.5.6/ice-9/runq.scm
4       /usr/quist/share/guile/1.5.6/ice-9/rw.scm
27      /usr/quist/share/guile/1.5.6/ice-9/safe-r5rs.scm
22      /usr/quist/share/guile/1.5.6/ice-9/safe.scm
632     /usr/quist/share/guile/1.5.6/ice-9/session.scm
300     /usr/quist/share/guile/1.5.6/ice-9/slib.scm
9       /usr/quist/share/guile/1.5.6/ice-9/stack-catch.scm
206     /usr/quist/share/guile/1.5.6/ice-9/streams.scm
297     /usr/quist/share/guile/1.5.6/ice-9/string-fun.scm
226     /usr/quist/share/guile/1.5.6/ice-9/syncase.scm
71      /usr/quist/share/guile/1.5.6/ice-9/threads.scm
40      /usr/quist/share/guile/1.5.6/ice-9/time.scm
20772   TOTAL

#!/usr/bin/env guile -s
;; TODO: Change to SRFI-22 script mechanism!

;; Copyright (c) 2002 BBNT Solutions LLC
;; Gregory D. Troxel, 2002-04-19

;; Compute a complexity measure for a Scheme program (or data).  The
;; basic measure is left parentheses, which counts a define of a
;; variable to a simple value as 1.  A procedure definition is counted
;; as 2 (one for the define and one for the name and argument list)
;; plus the complexity of the statements in the procedure.  Similarly,
;; let counts 2 plus 1 for each variable let, plus the complexity of
;; initializers and the body.  This complexity measure treats lists of
;; different lengths as being of equivalent complexity, and this is
;; arguably wrong.  Thus, it may be wise to consider a complexity
;; measure which also counts each simple object.  This program has 38
;; "PSLOC" according to the usual definition on non-blank non-comment
;; clines, and 56 LSLOC according to the parentheses counting scheme.

(use-modules (ice-9 format))

;; count left-parens in an sexp as a complexity measure
(define (count-sexp s)
   ((list? s)
    (+ 1 (apply + (map count-sexp s))))
   ((vector? s)
    (count-sexp (vector->list s)))
   ;; perhaps there are other things that deserve counting
   (else 0)))

;; read from a port until eof, and return the number of left parens
(define (sloc-port p)
      ((lparens 0)
       (s (read p) (read p)))
      ((eof-object? s) lparens)
    (set! lparens (+ lparens (count-sexp s)))

;; return the number of left parens in a file
(define (sloc-file f)
      ((p (open-input-file f))
       (l (sloc-port p)))
    (close-port p)

;; print to (stdout) the number of lines in a list of files and a total
(define (sloc-files file-list)
      ((total 0))
     (lambda (f)
           ((lines (sloc-file f)))
         (set! total (+ total lines))
         (format #t "~d\t~A\n" lines f)
    (format #t "~d\tTOTAL\n" total)
(sloc-files (cdr (command-line)))

gdt gdt 571 ~/SE/SLOC > ./sloc-scm sloc-scm 
56      sloc-scm
56      TOTAL

reply via email to

[Prev in Thread] Current Thread [Next in Thread]