Skip to content

Instantly share code, notes, and snippets.

@Lysxia
Created September 22, 2023 14:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lysxia/3ac74b77d992adb20c13cdbe56eb5cec to your computer and use it in GitHub Desktop.
Save Lysxia/3ac74b77d992adb20c13cdbe56eb5cec to your computer and use it in GitHub Desktop.
{- counter.hs: count comments and lines of code in .lagda.md files.
Usage:
cat src/*.lagda.md|runghc counter.hs
Counting method:
Triple backticks either start or end a code block.
Triple backtick lines are not counted.
Code lines starting with `--` are counted as comments
-}
{-# LANGUAGE BangPatterns #-}
import Control.Exception (throw, try)
import Data.Char (isSpace)
import System.IO.Error (isEOFError)
main :: IO ()
main = do
putStrLn "Ignoring spaces"
(comments, code) <- counter
putStrLn ("Comments: " ++ show comments)
putStrLn ("Code: " ++ show code)
data Mode = Comments | Code
flipMode :: Mode -> Mode
flipMode Comments = Code
flipMode Code = Comments
counter :: IO (Int, Int)
counter = count Comments 0 0
where
count !mode !comments !code = do
i <- try getLine
case i of
Left e | isEOFError e ->
case mode of
Comments -> pure (comments, code)
Code -> putStrLn "WARNING: Malformed input, unterminated code block" >> pure (comments, code)
Left e -> throw e
Right line
| all isSpace line -> count mode comments code
| isComment line -> count mode (comments + 1) code
| isThreeBackticks line -> count (flipMode mode) comments code
| Comments <- mode -> count mode (comments + 1) code
| otherwise -> count mode comments (code + 1)
isComment :: String -> Bool
isComment (' ' : line) = isComment line
isComment ('-' : '-' : _) = True
isComment _ = False
isThreeBackticks :: String -> Bool
isThreeBackticks ('`' : '`' : '`' : _) = True
isThreeBackticks _ = False
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment