src/Tools/Haskell/Haskell.thy
changeset 74132 9f18eb2a8039
parent 74130 54a108beed3e
child 74133 b701251205d2
equal deleted inserted replaced
74131:e4575152b525 74132:9f18eb2a8039
    16 Compact byte strings.
    16 Compact byte strings.
    17 
    17 
    18 See \<^file>\<open>$ISABELLE_HOME/src/Pure/General/bytes.ML\<close>
    18 See \<^file>\<open>$ISABELLE_HOME/src/Pure/General/bytes.ML\<close>
    19 and \<^file>\<open>$ISABELLE_HOME/src/Pure/General/bytes.scala\<close>.
    19 and \<^file>\<open>$ISABELLE_HOME/src/Pure/General/bytes.scala\<close>.
    20 -}
    20 -}
       
    21 
       
    22 {-# LANGUAGE TypeApplications #-}
    21 
    23 
    22 module Isabelle.Bytes (
    24 module Isabelle.Bytes (
    23   Bytes,
    25   Bytes,
    24   make, unmake, pack, unpack,
    26   make, unmake, pack, unpack,
    25   empty, null, length, index, all, any,
    27   empty, null, length, index, all, any,
    26   head, last, take, drop, isPrefixOf, isSuffixOf,
    28   head, last, take, drop, isPrefixOf, isSuffixOf,
    27   concat, space, spaces, singleton, char, byte,
    29   concat, space, spaces, char, byte, max_byte, max_char, singleton,
    28   trim_line
    30   trim_line
    29 )
    31 )
    30 where
    32 where
    31 
    33 
    32 import Prelude hiding (null, length, all, any, head, last, take, drop, concat)
    34 import Prelude hiding (null, length, all, any, head, last, take, drop, concat)
   106 spaces :: Int -> Bytes
   108 spaces :: Int -> Bytes
   107 spaces n =
   109 spaces n =
   108   if n < 64 then small_spaces ! n
   110   if n < 64 then small_spaces ! n
   109   else concat ((small_spaces ! (n `mod` 64)) : replicate (n `div` 64) (small_spaces ! 64))
   111   else concat ((small_spaces ! (n `mod` 64)) : replicate (n `div` 64) (small_spaces ! 64))
   110 
   112 
       
   113 char :: Word8 -> Char
       
   114 char = toEnum . fromEnum
       
   115 
       
   116 byte :: Char -> Word8
       
   117 byte = toEnum . fromEnum
       
   118 
       
   119 max_byte :: Word8
       
   120 max_byte = maxBound
       
   121 
       
   122 max_char :: Char
       
   123 max_char = char max_byte
       
   124 
   111 singletons :: Array Word8 Bytes
   125 singletons :: Array Word8 Bytes
   112 singletons =
   126 singletons =
   113   array (minBound, maxBound)
   127   array (0, max_byte)
   114     [(i, make (ByteString.singleton i)) | i <- [minBound .. maxBound]]
   128     [(i, make (ByteString.singleton i)) | i <- [0 .. max_byte]]
   115 
   129 
   116 singleton :: Word8 -> Bytes
   130 singleton :: Word8 -> Bytes
   117 singleton b = singletons ! b
   131 singleton b = singletons ! b
   118 
       
   119 char :: Word8 -> Char
       
   120 char = toEnum . fromEnum
       
   121 
       
   122 byte :: Char -> Word8
       
   123 byte = toEnum . fromEnum
       
   124 
   132 
   125 trim_line :: Bytes -> Bytes
   133 trim_line :: Bytes -> Bytes
   126 trim_line s =
   134 trim_line s =
   127   if n >= 2 && at (n - 2) == '\r' && at (n - 1) == '\n' then take (n - 2) s
   135   if n >= 2 && at (n - 2) == '\r' && at (n - 1) == '\n' then take (n - 2) s
   128   else if n >= 1 && (at (n - 1) == '\r' || at (n - 1) == '\n') then take (n - 1) s
   136   else if n >= 1 && (at (n - 1) == '\r' || at (n - 1) == '\n') then take (n - 1) s
   304 separate _ xs = xs;
   312 separate _ xs = xs;
   305 
   313 
   306 
   314 
   307 {- string-like interfaces -}
   315 {- string-like interfaces -}
   308 
   316 
   309 class (IsList a, IsString a, Monoid a, Eq a, Ord a) => StringLike a
   317 class (IsString a, Monoid a, Eq a, Ord a) => StringLike a where
   310   where
   318   space_explode :: Char -> a -> [a]
   311     space_explode :: Item a -> a -> [a]
       
   312     split_lines :: a -> [a]
       
   313 
   319 
   314 instance StringLike String where
   320 instance StringLike String where
   315   space_explode sep = Split.split (Split.dropDelims (Split.whenElt (== sep)))
   321   space_explode c = Split.split (Split.dropDelims (Split.whenElt (== c)))
   316   split_lines = space_explode '\n'
       
   317 
   322 
   318 instance StringLike Text where
   323 instance StringLike Text where
   319   space_explode sep str =
   324   space_explode c str =
   320     if Text.null str then []
   325     if Text.null str then []
   321     else if Text.all (/= sep) str then [str]
   326     else if Text.all (/= c) str then [str]
   322     else map Text.pack $ space_explode sep $ Text.unpack str
   327     else map Text.pack $ space_explode c $ Text.unpack str
   323   split_lines = space_explode '\n'
       
   324 
   328 
   325 instance StringLike Lazy.Text where
   329 instance StringLike Lazy.Text where
   326   space_explode sep str =
   330   space_explode c str =
   327     if Lazy.null str then []
   331     if Lazy.null str then []
   328     else if Lazy.all (/= sep) str then [str]
   332     else if Lazy.all (/= c) str then [str]
   329     else map Lazy.pack $ space_explode sep $ Lazy.unpack str
   333     else map Lazy.pack $ space_explode c $ Lazy.unpack str
   330   split_lines = space_explode '\n'
       
   331 
   334 
   332 instance StringLike Bytes where
   335 instance StringLike Bytes where
   333   space_explode sep str =
   336   space_explode c str =
   334     if Bytes.null str then []
   337     if Bytes.null str then []
   335     else if Bytes.all (/= sep) str then [str]
   338     else if c > Bytes.max_char || Bytes.all (/= (Bytes.byte c)) str then [str]
   336     else explode (Bytes.unpack str)
   339     else
   337     where
   340       explode (Bytes.unpack str)
   338       explode rest =
   341       where
   339         case span (/= sep) rest of
   342         explode rest =
   340           (_, []) -> [Bytes.pack rest]
   343           case span (/= (Bytes.byte c)) rest of
   341           (prfx, _ : rest') -> Bytes.pack prfx : explode rest'
   344             (_, []) -> [Bytes.pack rest]
   342   split_lines = space_explode (Bytes.byte '\n')
   345             (prfx, _ : rest') -> Bytes.pack prfx : explode rest'
   343 
   346 
   344 class StringLike a => STRING a where make_string :: a -> String
   347 class StringLike a => STRING a where make_string :: a -> String
   345 instance STRING String where make_string = id
   348 instance STRING String where make_string = id
   346 instance STRING Text where make_string = Text.unpack
   349 instance STRING Text where make_string = Text.unpack
   347 instance STRING Lazy.Text where make_string = Lazy.unpack
   350 instance STRING Lazy.Text where make_string = Lazy.unpack
   378 space_implode s = mconcat . separate s
   381 space_implode s = mconcat . separate s
   379 
   382 
   380 commas, commas_quote :: StringLike a => [a] -> a
   383 commas, commas_quote :: StringLike a => [a] -> a
   381 commas = space_implode ", "
   384 commas = space_implode ", "
   382 commas_quote = commas . map quote
   385 commas_quote = commas . map quote
       
   386 
       
   387 split_lines :: StringLike a => a -> [a]
       
   388 split_lines = space_explode '\n'
   383 
   389 
   384 cat_lines :: StringLike a => [a] -> a
   390 cat_lines :: StringLike a => [a] -> a
   385 cat_lines = space_implode "\n"
   391 cat_lines = space_implode "\n"
   386 
   392 
   387 trim_line :: String -> String
   393 trim_line :: String -> String
  1726 keyword1, keyword2 :: BYTES a => a -> T
  1732 keyword1, keyword2 :: BYTES a => a -> T
  1727 keyword1 name = mark_str (Markup.keyword1, name)
  1733 keyword1 name = mark_str (Markup.keyword1, name)
  1728 keyword2 name = mark_str (Markup.keyword2, name)
  1734 keyword2 name = mark_str (Markup.keyword2, name)
  1729 
  1735 
  1730 text :: BYTES a => a -> [T]
  1736 text :: BYTES a => a -> [T]
  1731 text = breaks . map str . filter (not . Bytes.null) . space_explode Bytes.space . make_bytes
  1737 text = breaks . map str . filter (not . Bytes.null) . space_explode ' ' . make_bytes
  1732 
  1738 
  1733 paragraph :: [T] -> T
  1739 paragraph :: [T] -> T
  1734 paragraph = markup Markup.paragraph
  1740 paragraph = markup Markup.paragraph
  1735 
  1741 
  1736 para :: BYTES a => a -> T
  1742 para :: BYTES a => a -> T
  2477 write_message socket = write socket . make_message
  2483 write_message socket = write socket . make_message
  2478 
  2484 
  2479 parse_header :: Bytes -> [Int]
  2485 parse_header :: Bytes -> [Int]
  2480 parse_header line =
  2486 parse_header line =
  2481   let
  2487   let
  2482     res = map Value.parse_nat (space_explode (Bytes.byte ',') line)
  2488     res = map Value.parse_nat (space_explode ',' line)
  2483   in
  2489   in
  2484     if all isJust res then map fromJust res
  2490     if all isJust res then map fromJust res
  2485     else error ("Malformed message header: " <> quote (UTF8.decode line))
  2491     else error ("Malformed message header: " <> quote (UTF8.decode line))
  2486 
  2492 
  2487 read_chunk :: Socket -> Int -> IO Bytes
  2493 read_chunk :: Socket -> Int -> IO Bytes