{-
 - Compile: ghc -O2 -W -Wall gen_class_examples.hs
 -
 - This program generates some tests for re2c code point classes.
 - For each test, some code unit sequences are chosen that should
 - be lexed either as code points or as control characters inside
 - of class by re2c. These sequences are permutated.
 -
 - Each permutation gives one class.
 -}
import Data.List (permutations)

charsets :: [(String, String, [String])]
charsets =
    [ ("class1.re", "-i",
        [ "-"
        , "-"
        , "\\\\"
        , "\\]"
        , "\\a"
        ])
    , ("class2.re", "-i",
        [ "-"
        , "-"
        , "\\/"
        , "a"
        , "/"
        ])
    , ("class3.re", "-i8",
        [ "-"
        , "\\x12"
        , "\\X3456"
        , "\\u7890"
        , "\\U0010FfFf"
        ])
    , ("class4.re", "-i",
        [ "-"
        , "\\001"
        , "\\123"
        , "\\245"
        , "\\367"
        ])
    ]

neg :: String -> String
neg s = '^' : s

wrap :: String -> String
wrap s = concat ["/*!re2c [", s, "] { act } * { def } */"]

content :: String -> [String] -> String
content opts chars =
    let ss = map concat $ permutations chars
        ls = map (\s -> unlines $ map wrap [s, neg s]) ss
        header1 = "// re2c $INPUT -o $OUTPUT " ++ opts
        header2 = "autogenerated by gen_class_examples.hs"
    in  unlines $ header1 : header2 : ls

main :: IO ()
main = do
    mapM_ (\ (name, opts, cs) -> writeFile name $ content opts cs) charsets
