content: {-
   - 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
  