packages feed

cedict-0.2.1: Data/Char/CEDICT/C/Declarations.hs

 {- }
  
  Takes the special lists and makes them in to C.

 { -}

{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}

module Data.Char.CEDICT.C.Declarations where

import Data.Char.CEDICT.Reader.ListRebuild
import Data.Char.CEDICT.Reader.RoseBush

import Data.List
import Data.Ord
import Data.Word
import qualified Data.ByteString
import qualified Data.ByteString.UTF8

consInt i                    =  Data.ByteString.cons $ toEnum i
snocNull                     =  flip Data.ByteString.snoc null
 where
  null                       =  0 :: Word8 

class Byteable d where
  toBytes                   ::  d -> Data.ByteString.ByteString
instance Byteable Data.ByteString.ByteString where
  toBytes                    =  id 
instance Byteable String where
  toBytes                    =  Data.ByteString.UTF8.fromString
instance Byteable Char where
  toBytes c                  =  toBytes [c] 
instance Byteable (Char, [Char]) where
  toBytes (a, b)             =  Data.ByteString.append char text 
   where
    char                     =  toBytes a
    text                     =  toBytes $ b

class CDeclarables thing where
  toCDecl                   ::  thing -> String -> Data.ByteString.ByteString
instance CDeclarables CharCharList where
  toCDecl ccList name        =  Data.ByteString.concat
    [ toBytes lenDecl
    , toBytes arrayDecl
    , arrayLiteral
    ]
   where
    byteified                =  map toBytes ccList
    len                      =  show $ length ccList
    arrayName                =  name ++ "_elements"
    lenName                  =  name ++ "_length"
    lenDecl =
      "\nconst int " ++ lenName ++ " = " ++ len ++ ";\n"
    arrayDecl =
      "\nconst char*\n" ++ arrayName ++ "[" ++ len ++ "] =\n"
    arrayLiteral             =  Data.ByteString.concat
      [ toBytes "  { \""
      , Data.ByteString.intercalate (toBytes "\"\n  , \"") byteified
      , toBytes "\"\n  };\n"
      ]
instance CDeclarables DictList where
  toCDecl dList name         =  Data.ByteString.concat
    [ trieDecl
    , trieLiteral
    , defsDecl
    , defsLiteral
    , pinsDecl
    , pinsLiteral
    ]
   where
    (keys, values)           =  readyToSerialize dList
    --splitToJoin           ::  ((String, String) -> String) -> [String]
    splitToJoin f            =  map (intercalate " // " . map f) values
    pins                     =  map emptyToNULL $ splitToJoin fst
    defs                     =  map emptyToNULL $ splitToJoin snd
    emptyToNULL ""           =  "NULL"
    emptyToNULL s            =  "\"" ++ replacer s ++ "\""
     where
      replacer ('"':s)       =  '\\' : '"' : replacer s
      replacer (k:s)         =  k : replacer s
      replacer []            =  []
    trie                     =  concatMap (uncurry display) keys
     where
      display i d = [padded i] ++ (map displayKey d) ++ (map displayOffset d)
       where
        displayOffset        =  (padded . snd)
        displayKey           =  f . fst
         where
          f key              =  num ++ spaces ++ "/*  " ++ [key] ++ "  */"
           where
            num              =  padded $ fromEnum key
            spaces           =  replicate (12 - length num) ' '
        padded num           =  replicate (5 - length shown) ' ' ++ shown
         where
          shown              =  show num
    [trieName, defsName, pinsName] =
      map (name ++) ["_trie", "_defs", "_pins"]
    trieDecl                 =  toBytes $
      "\nconst int\n" ++ trieName ++ ('[':(show $ length trie)) ++ "] =\n"
    trieLiteral              =  toBytes . concat $
      [ "  { "
      , intercalate "\n  , " trie 
      , "\n  };\n"
      ]
    pinsDecl                 =  toBytes $
      "\nconst char*\n" ++ pinsName ++ ('[':(show $ length pins)) ++ "] =\n"
    pinsLiteral              =  Data.ByteString.concat
      [ toBytes "  { "
      , toBytes $ intercalate "\n  , " pins
      , toBytes "\n  };\n"
      ]
    defsDecl                 =  toBytes $
      "\nconst char*\n" ++ defsName ++ ('[':(show $ length defs)) ++ "] =\n"
    defsLiteral              =  Data.ByteString.concat
      [ toBytes "  { "
      , toBytes $ intercalate "\n  , " defs
      , toBytes "\n  };\n"
      ]