src/Tools/Haskell/Haskell.thy
changeset 74135 6a16f7a67193
parent 74134 ede8a01f063a
child 74136 7bbac3eb8adf
equal deleted inserted replaced
74134:ede8a01f063a 74135:6a16f7a67193
    24 module Isabelle.Bytes (
    24 module Isabelle.Bytes (
    25   Bytes,
    25   Bytes,
    26   make, unmake, pack, unpack,
    26   make, unmake, pack, unpack,
    27   empty, null, length, index, all, any,
    27   empty, null, length, index, all, any,
    28   head, last, take, drop, isPrefixOf, isSuffixOf,
    28   head, last, take, drop, isPrefixOf, isSuffixOf,
    29   concat, space, spaces, char, byte, max_byte, max_char, singleton
    29   concat, space, spaces, char, all_char, any_char, byte, max_byte, max_char, singleton
    30 )
    30 )
    31 where
    31 where
    32 
    32 
    33 import Prelude hiding (null, length, all, any, head, last, take, drop, concat)
    33 import Prelude hiding (null, length, all, any, head, last, take, drop, concat)
    34 
    34 
   109   if n < 64 then small_spaces ! n
   109   if n < 64 then small_spaces ! n
   110   else concat ((small_spaces ! (n `mod` 64)) : replicate (n `div` 64) (small_spaces ! 64))
   110   else concat ((small_spaces ! (n `mod` 64)) : replicate (n `div` 64) (small_spaces ! 64))
   111 
   111 
   112 char :: Word8 -> Char
   112 char :: Word8 -> Char
   113 char = toEnum . fromEnum
   113 char = toEnum . fromEnum
       
   114 
       
   115 all_char :: (Char -> Bool) -> Bytes -> Bool
       
   116 all_char pred = all (pred . char)
       
   117 
       
   118 any_char :: (Char -> Bool) -> Bytes -> Bool
       
   119 any_char pred = any (pred . char)
   114 
   120 
   115 byte :: Char -> Word8
   121 byte :: Char -> Word8
   116 byte = toEnum . fromEnum
   122 byte = toEnum . fromEnum
   117 
   123 
   118 max_byte :: Word8
   124 max_byte :: Word8
   347 
   353 
   348 instance StringLike Bytes where
   354 instance StringLike Bytes where
   349   space_explode :: Char -> Bytes -> [Bytes]
   355   space_explode :: Char -> Bytes -> [Bytes]
   350   space_explode c str =
   356   space_explode c str =
   351     if Bytes.null str then []
   357     if Bytes.null str then []
   352     else if c > Bytes.max_char || Bytes.all (/= (Bytes.byte c)) str then [str]
   358     else if Bytes.all_char (/= c) str then [str]
   353     else
   359     else
   354       explode (Bytes.unpack str)
   360       explode (Bytes.unpack str)
   355       where
   361       where
   356         explode rest =
   362         explode rest =
   357           case span (/= (Bytes.byte c)) rest of
   363           case span (/= (Bytes.byte c)) rest of
  2426 import Prelude hiding (read)
  2432 import Prelude hiding (read)
  2427 import Data.Maybe
  2433 import Data.Maybe
  2428 import qualified Data.ByteString as ByteString
  2434 import qualified Data.ByteString as ByteString
  2429 import qualified Isabelle.Bytes as Bytes
  2435 import qualified Isabelle.Bytes as Bytes
  2430 import Isabelle.Bytes (Bytes)
  2436 import Isabelle.Bytes (Bytes)
       
  2437 import qualified Isabelle.Symbol as Symbol
  2431 import qualified Isabelle.UTF8 as UTF8
  2438 import qualified Isabelle.UTF8 as UTF8
  2432 import qualified Isabelle.XML as XML
  2439 import qualified Isabelle.XML as XML
  2433 import qualified Isabelle.YXML as YXML
  2440 import qualified Isabelle.YXML as YXML
  2434 
  2441 
  2435 import Network.Socket (Socket)
  2442 import Network.Socket (Socket)
  2522 
  2529 
  2523 -- hybrid messages: line or length+block (with content restriction)
  2530 -- hybrid messages: line or length+block (with content restriction)
  2524 
  2531 
  2525 is_length :: Bytes -> Bool
  2532 is_length :: Bytes -> Bool
  2526 is_length msg =
  2533 is_length msg =
  2527   not (Bytes.null msg) && Bytes.all (\b -> 48 <= b && b <= 57) msg
  2534   not (Bytes.null msg) && Bytes.all_char (\c -> '0' <= c && c <= '9') msg
  2528 
  2535 
  2529 is_terminated :: Bytes -> Bool
  2536 is_terminated :: Bytes -> Bool
  2530 is_terminated msg =
  2537 is_terminated msg =
  2531   not (Bytes.null msg) && (Bytes.last msg == 13 || Bytes.last msg == 10)
  2538   not (Bytes.null msg) && Symbol.is_ascii_line_terminator (Bytes.char $ Bytes.last msg)
  2532 
  2539 
  2533 make_line_message :: Bytes -> [Bytes]
  2540 make_line_message :: Bytes -> [Bytes]
  2534 make_line_message msg =
  2541 make_line_message msg =
  2535   let n = Bytes.length msg in
  2542   let n = Bytes.length msg in
  2536     if is_length msg || is_terminated msg then
  2543     if is_length msg || is_terminated msg then
  2537       error ("Bad content for line message:\n" <> take 100 (UTF8.decode msg))
  2544       error ("Bad content for line message:\n" <> take 100 (UTF8.decode msg))
  2538     else
  2545     else
  2539       (if n > 100 || Bytes.any (== 10) msg then make_header [n + 1] else []) <> [msg, "\n"]
  2546       (if n > 100 || Bytes.any_char (== '\n') msg then make_header [n + 1] else []) <> [msg, "\n"]
  2540 
  2547 
  2541 write_line_message :: Socket -> Bytes -> IO ()
  2548 write_line_message :: Socket -> Bytes -> IO ()
  2542 write_line_message socket = write socket . make_line_message
  2549 write_line_message socket = write socket . make_line_message
  2543 
  2550 
  2544 read_line_message :: Socket -> IO (Maybe Bytes)
  2551 read_line_message :: Socket -> IO (Maybe Bytes)