src/Tools/Haskell/Haskell.thy
changeset 74130 54a108beed3e
parent 74129 c3794f56a2e2
child 74132 9f18eb2a8039
equal deleted inserted replaced
74129:c3794f56a2e2 74130:54a108beed3e
    23   Bytes,
    23   Bytes,
    24   make, unmake, pack, unpack,
    24   make, unmake, pack, unpack,
    25   empty, null, length, index, all, any,
    25   empty, null, length, index, all, any,
    26   head, last, take, drop, isPrefixOf, isSuffixOf,
    26   head, last, take, drop, isPrefixOf, isSuffixOf,
    27   concat, space, spaces, singleton, char, byte,
    27   concat, space, spaces, singleton, char, byte,
    28   trim_line, space_explode, split_lines
    28   trim_line
    29 )
    29 )
    30 where
    30 where
    31 
    31 
    32 import Prelude hiding (null, length, all, any, head, last, take, drop, concat)
    32 import Prelude hiding (null, length, all, any, head, last, take, drop, concat)
    33 
    33 
   128   else if n >= 1 && (at (n - 1) == '\r' || at (n - 1) == '\n') then take (n - 1) s
   128   else if n >= 1 && (at (n - 1) == '\r' || at (n - 1) == '\n') then take (n - 1) s
   129   else s
   129   else s
   130   where
   130   where
   131     n = length s
   131     n = length s
   132     at = char . index s
   132     at = char . index s
   133 
       
   134 space_explode :: Word8 -> Bytes -> [Bytes]
       
   135 space_explode sep str =
       
   136   if null str then []
       
   137   else if all (/= sep) str then [str]
       
   138   else explode (unpack str)
       
   139   where
       
   140     explode rest =
       
   141       case span (/= sep) rest of
       
   142         (_, []) -> [pack rest]
       
   143         (prfx, _ : rest') -> pack prfx : explode rest'
       
   144 
       
   145 split_lines :: Bytes -> [Bytes]
       
   146 split_lines = space_explode (byte '\n')
       
   147 \<close>
   133 \<close>
   148 
   134 
   149 generate_file "Isabelle/UTF8.hs" = \<open>
   135 generate_file "Isabelle/UTF8.hs" = \<open>
   150 {-  Title:      Isabelle/UTF8.hs
   136 {-  Title:      Isabelle/UTF8.hs
   151     Author:     Makarius
   137     Author:     Makarius
   248 where
   234 where
   249 
   235 
   250 import qualified Data.Text as Text
   236 import qualified Data.Text as Text
   251 import Data.Text (Text)
   237 import Data.Text (Text)
   252 import qualified Data.Text.Lazy as Lazy
   238 import qualified Data.Text.Lazy as Lazy
       
   239 import GHC.Exts (IsList, Item)
   253 import Data.String (IsString)
   240 import Data.String (IsString)
   254 import qualified Data.List.Split as Split
   241 import qualified Data.List.Split as Split
   255 import qualified Isabelle.Symbol as Symbol
   242 import qualified Isabelle.Symbol as Symbol
       
   243 import qualified Isabelle.Bytes as Bytes
   256 import Isabelle.Bytes (Bytes)
   244 import Isabelle.Bytes (Bytes)
   257 import qualified Isabelle.UTF8 as UTF8
   245 import qualified Isabelle.UTF8 as UTF8
   258 
   246 
   259 
   247 
   260 {- functions -}
   248 {- functions -}
   316 separate _ xs = xs;
   304 separate _ xs = xs;
   317 
   305 
   318 
   306 
   319 {- string-like interfaces -}
   307 {- string-like interfaces -}
   320 
   308 
   321 class (IsString a, Monoid a, Eq a, Ord a) => StringLike a
   309 class (IsList a, IsString a, Monoid a, Eq a, Ord a) => StringLike a
   322 instance StringLike String
   310   where
   323 instance StringLike Text
   311     space_explode :: Item a -> a -> [a]
   324 instance StringLike Lazy.Text
   312     split_lines :: a -> [a]
   325 instance StringLike Bytes
   313 
       
   314 instance StringLike String where
       
   315   space_explode sep = Split.split (Split.dropDelims (Split.whenElt (== sep)))
       
   316   split_lines = space_explode '\n'
       
   317 
       
   318 instance StringLike Text where
       
   319   space_explode sep str =
       
   320     if Text.null str then []
       
   321     else if Text.all (/= sep) str then [str]
       
   322     else map Text.pack $ space_explode sep $ Text.unpack str
       
   323   split_lines = space_explode '\n'
       
   324 
       
   325 instance StringLike Lazy.Text where
       
   326   space_explode sep str =
       
   327     if Lazy.null str then []
       
   328     else if Lazy.all (/= sep) str then [str]
       
   329     else map Lazy.pack $ space_explode sep $ Lazy.unpack str
       
   330   split_lines = space_explode '\n'
       
   331 
       
   332 instance StringLike Bytes where
       
   333   space_explode sep str =
       
   334     if Bytes.null str then []
       
   335     else if Bytes.all (/= sep) str then [str]
       
   336     else explode (Bytes.unpack str)
       
   337     where
       
   338       explode rest =
       
   339         case span (/= sep) rest of
       
   340           (_, []) -> [Bytes.pack rest]
       
   341           (prfx, _ : rest') -> Bytes.pack prfx : explode rest'
       
   342   split_lines = space_explode (Bytes.byte '\n')
   326 
   343 
   327 class StringLike a => STRING a where make_string :: a -> String
   344 class StringLike a => STRING a where make_string :: a -> String
   328 instance STRING String where make_string = id
   345 instance STRING String where make_string = id
   329 instance STRING Text where make_string = Text.unpack
   346 instance STRING Text where make_string = Text.unpack
   330 instance STRING Lazy.Text where make_string = Lazy.unpack
   347 instance STRING Lazy.Text where make_string = Lazy.unpack
   364 commas = space_implode ", "
   381 commas = space_implode ", "
   365 commas_quote = commas . map quote
   382 commas_quote = commas . map quote
   366 
   383 
   367 cat_lines :: StringLike a => [a] -> a
   384 cat_lines :: StringLike a => [a] -> a
   368 cat_lines = space_implode "\n"
   385 cat_lines = space_implode "\n"
   369 
       
   370 
       
   371 space_explode :: Char -> String -> [String]
       
   372 space_explode c = Split.split (Split.dropDelims (Split.whenElt (== c)))
       
   373 
       
   374 split_lines :: String -> [String]
       
   375 split_lines = space_explode '\n'
       
   376 
   386 
   377 trim_line :: String -> String
   387 trim_line :: String -> String
   378 trim_line line =
   388 trim_line line =
   379   if not (null line) && Symbol.is_ascii_line_terminator (last line) then
   389   if not (null line) && Symbol.is_ascii_line_terminator (last line) then
   380     case reverse line of
   390     case reverse line of
  1716 keyword1, keyword2 :: BYTES a => a -> T
  1726 keyword1, keyword2 :: BYTES a => a -> T
  1717 keyword1 name = mark_str (Markup.keyword1, name)
  1727 keyword1 name = mark_str (Markup.keyword1, name)
  1718 keyword2 name = mark_str (Markup.keyword2, name)
  1728 keyword2 name = mark_str (Markup.keyword2, name)
  1719 
  1729 
  1720 text :: BYTES a => a -> [T]
  1730 text :: BYTES a => a -> [T]
  1721 text = breaks . map str . filter (not . Bytes.null) . Bytes.space_explode Bytes.space . make_bytes
  1731 text = breaks . map str . filter (not . Bytes.null) . space_explode Bytes.space . make_bytes
  1722 
  1732 
  1723 paragraph :: [T] -> T
  1733 paragraph :: [T] -> T
  1724 paragraph = markup Markup.paragraph
  1734 paragraph = markup Markup.paragraph
  1725 
  1735 
  1726 para :: BYTES a => a -> T
  1736 para :: BYTES a => a -> T
  2467 write_message socket = write socket . make_message
  2477 write_message socket = write socket . make_message
  2468 
  2478 
  2469 parse_header :: Bytes -> [Int]
  2479 parse_header :: Bytes -> [Int]
  2470 parse_header line =
  2480 parse_header line =
  2471   let
  2481   let
  2472     res = map Value.parse_nat (Bytes.space_explode (Bytes.byte ',') line)
  2482     res = map Value.parse_nat (space_explode (Bytes.byte ',') line)
  2473   in
  2483   in
  2474     if all isJust res then map fromJust res
  2484     if all isJust res then map fromJust res
  2475     else error ("Malformed message header: " <> quote (UTF8.decode line))
  2485     else error ("Malformed message header: " <> quote (UTF8.decode line))
  2476 
  2486 
  2477 read_chunk :: Socket -> Int -> IO Bytes
  2487 read_chunk :: Socket -> Int -> IO Bytes