views:

386

answers:

3

I've written a little script to iterate across files in folders to count lines of code.

The heart of the script is this function to count lines of whitespace, comments, and code. (Note that for the moment it is tailored to C# and doesn't know about multi-line comments).

It just doesn't look very nice to me - has anyone got a cleaner version?

// from list of strings return tuple with count of (whitespace, comments, code)
let loc (arr:List<string>) = 
    let innerloc (whitesp, comment, code) (l:string) = 
        let s = l.Trim([|' ';'\t'|]) // remove leading whitespace
        match s with
        | "" -> (whitesp + 1, comment, code)        //blank lines
        | "{" -> (whitesp + 1, comment, code)       //opening blocks
        | "}" -> (whitesp + 1, comment, code)       //closing blocks
        | _ when s.StartsWith("#") -> (whitesp + 1, comment, code)  //regions
        | _ when s.StartsWith("//") -> (whitesp, comment + 1, code) //comments
        | _ -> (whitesp, comment, code + 1)

    List.fold_left innerloc (0,0,0) arr
+1  A: 

A better site for this might be refactormycode - it's tailored exactly for these questions.

Tom Ritter
No F# there yet?
Benjol
A: 

Can't see much wrong with that other than the fact you will count a single brace with trailing spaces as code instead of whitespace.

finnw
+2  A: 

I think what you have is fine, but here's some variety to mix it up. (This solution repeats your problem of ignoring trailing whitespace.)

type Line =
    | Whitespace = 0
    | Comment = 1
    | Code = 2
let Classify (l:string) =         
    let s = l.TrimStart([|' ';'\t'|])
    match s with        
    | "" | "{" | "}" -> Line.Whitespace
    | _ when s.StartsWith("#") -> Line.Whitespace
    | _ when s.StartsWith("//") -> Line.Comment
    | _ -> Line.Code
let Loc (arr:list<_>) =     
    let sums = Array.create 3 0
    arr 
    |> List.iter (fun line -> 
        let i = Classify line |> int
        sums.[i] <- sums.[i] + 1)
    sums

"Classify" as a separate entity might be useful in another context.

Brian
hmm, 'type Line' I like, 'Classify' too. Maybe I've read too much immutable stuff, but I don't much like using Arrays if I can avoid it... but I do like the way you've split the problem up into smaller bits.
Benjol