src/Tools/Haskell/Haskell.thy
changeset 74134 ede8a01f063a
parent 74133 b701251205d2
child 74135 6a16f7a67193
equal deleted inserted replaced
74133:b701251205d2 74134:ede8a01f063a
    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, byte, max_byte, max_char, singleton
    30   trim_line
       
    31 )
    30 )
    32 where
    31 where
    33 
    32 
    34 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)
    35 
    34 
   127   array (0, max_byte)
   126   array (0, max_byte)
   128     [(i, make (ByteString.singleton i)) | i <- [0 .. max_byte]]
   127     [(i, make (ByteString.singleton i)) | i <- [0 .. max_byte]]
   129 
   128 
   130 singleton :: Word8 -> Bytes
   129 singleton :: Word8 -> Bytes
   131 singleton b = singletons ! b
   130 singleton b = singletons ! b
   132 
       
   133 trim_line :: Bytes -> Bytes
       
   134 trim_line s =
       
   135   if n >= 2 && at (n - 2) == '\r' && at (n - 1) == '\n' then take (n - 2) s
       
   136   else if n >= 1 && (at (n - 1) == '\r' || at (n - 1) == '\n') then take (n - 1) s
       
   137   else s
       
   138   where
       
   139     n = length s
       
   140     at = char . index s
       
   141 \<close>
   131 \<close>
   142 
   132 
   143 generate_file "Isabelle/UTF8.hs" = \<open>
   133 generate_file "Isabelle/UTF8.hs" = \<open>
   144 {-  Title:      Isabelle/UTF8.hs
   134 {-  Title:      Isabelle/UTF8.hs
   145     Author:     Makarius
   135     Author:     Makarius
   224 -}
   214 -}
   225 
   215 
   226 {-# LANGUAGE OverloadedStrings #-}
   216 {-# LANGUAGE OverloadedStrings #-}
   227 {-# LANGUAGE TypeSynonymInstances #-}
   217 {-# LANGUAGE TypeSynonymInstances #-}
   228 {-# LANGUAGE FlexibleInstances #-}
   218 {-# LANGUAGE FlexibleInstances #-}
       
   219 {-# LANGUAGE InstanceSigs #-}
   229 
   220 
   230 module Isabelle.Library (
   221 module Isabelle.Library (
   231   (|>), (|->), (#>), (#->),
   222   (|>), (|->), (#>), (#->),
   232 
   223 
   233   the, the_default,
   224   the, the_default,
   313 
   304 
   314 {- string-like interfaces -}
   305 {- string-like interfaces -}
   315 
   306 
   316 class (IsString a, Monoid a, Eq a, Ord a) => StringLike a where
   307 class (IsString a, Monoid a, Eq a, Ord a) => StringLike a where
   317   space_explode :: Char -> a -> [a]
   308   space_explode :: Char -> a -> [a]
       
   309   trim_line :: a -> a
   318 
   310 
   319 instance StringLike String where
   311 instance StringLike String where
       
   312   space_explode :: Char -> String -> [String]
   320   space_explode c = Split.split (Split.dropDelims (Split.whenElt (== c)))
   313   space_explode c = Split.split (Split.dropDelims (Split.whenElt (== c)))
       
   314   trim_line :: String -> String
       
   315   trim_line s =
       
   316     if not (null s) && Symbol.is_ascii_line_terminator (last s) then
       
   317       case reverse s of
       
   318         '\n' : '\r' : rest -> reverse rest
       
   319         '\r' : rest -> reverse rest
       
   320         '\n' : rest -> reverse rest
       
   321         _ -> s
       
   322     else s
   321 
   323 
   322 instance StringLike Text where
   324 instance StringLike Text where
       
   325   space_explode :: Char -> Text -> [Text]
   323   space_explode c str =
   326   space_explode c str =
   324     if Text.null str then []
   327     if Text.null str then []
   325     else if Text.all (/= c) str then [str]
   328     else if Text.all (/= c) str then [str]
   326     else map Text.pack $ space_explode c $ Text.unpack str
   329     else map Text.pack $ space_explode c $ Text.unpack str
       
   330   trim_line :: Text -> Text
       
   331   trim_line s =
       
   332     if n >= 2 && at (n - 2) == '\r' && at (n - 1) == '\n' then Text.take (n - 2) s
       
   333     else if n >= 1 && Symbol.is_ascii_line_terminator (at (n - 1)) then Text.take (n - 1) s
       
   334     else s
       
   335     where
       
   336       n = Text.length s
       
   337       at = Text.index s
   327 
   338 
   328 instance StringLike Lazy.Text where
   339 instance StringLike Lazy.Text where
       
   340   space_explode :: Char -> Lazy.Text -> [Lazy.Text]
   329   space_explode c str =
   341   space_explode c str =
   330     if Lazy.null str then []
   342     if Lazy.null str then []
   331     else if Lazy.all (/= c) str then [str]
   343     else if Lazy.all (/= c) str then [str]
   332     else map Lazy.pack $ space_explode c $ Lazy.unpack str
   344     else map Lazy.pack $ space_explode c $ Lazy.unpack str
       
   345   trim_line :: Lazy.Text -> Lazy.Text
       
   346   trim_line = Lazy.fromStrict . trim_line . Lazy.toStrict
   333 
   347 
   334 instance StringLike Bytes where
   348 instance StringLike Bytes where
       
   349   space_explode :: Char -> Bytes -> [Bytes]
   335   space_explode c str =
   350   space_explode c str =
   336     if Bytes.null str then []
   351     if Bytes.null str then []
   337     else if c > Bytes.max_char || Bytes.all (/= (Bytes.byte c)) str then [str]
   352     else if c > Bytes.max_char || Bytes.all (/= (Bytes.byte c)) str then [str]
   338     else
   353     else
   339       explode (Bytes.unpack str)
   354       explode (Bytes.unpack str)
   340       where
   355       where
   341         explode rest =
   356         explode rest =
   342           case span (/= (Bytes.byte c)) rest of
   357           case span (/= (Bytes.byte c)) rest of
   343             (_, []) -> [Bytes.pack rest]
   358             (_, []) -> [Bytes.pack rest]
   344             (prfx, _ : rest') -> Bytes.pack prfx : explode rest'
   359             (prfx, _ : rest') -> Bytes.pack prfx : explode rest'
       
   360   trim_line :: Bytes -> Bytes
       
   361   trim_line s =
       
   362     if n >= 2 && at (n - 2) == '\r' && at (n - 1) == '\n' then Bytes.take (n - 2) s
       
   363     else if n >= 1 && Symbol.is_ascii_line_terminator (at (n - 1)) then Bytes.take (n - 1) s
       
   364     else s
       
   365     where
       
   366       n = Bytes.length s
       
   367       at = Bytes.char . Bytes.index s
   345 
   368 
   346 class StringLike a => STRING a where make_string :: a -> String
   369 class StringLike a => STRING a where make_string :: a -> String
   347 instance STRING String where make_string = id
   370 instance STRING String where make_string = id
   348 instance STRING Text where make_string = Text.unpack
   371 instance STRING Text where make_string = Text.unpack
   349 instance STRING Lazy.Text where make_string = Lazy.unpack
   372 instance STRING Lazy.Text where make_string = Lazy.unpack
   386 split_lines :: StringLike a => a -> [a]
   409 split_lines :: StringLike a => a -> [a]
   387 split_lines = space_explode '\n'
   410 split_lines = space_explode '\n'
   388 
   411 
   389 cat_lines :: StringLike a => [a] -> a
   412 cat_lines :: StringLike a => [a] -> a
   390 cat_lines = space_implode "\n"
   413 cat_lines = space_implode "\n"
   391 
       
   392 trim_line :: String -> String
       
   393 trim_line line =
       
   394   if not (null line) && Symbol.is_ascii_line_terminator (last line) then
       
   395     case reverse line of
       
   396       '\n' : '\r' : rest -> reverse rest
       
   397       '\r' : rest -> reverse rest
       
   398       '\n' : rest -> reverse rest
       
   399       _ -> line
       
   400   else line
       
   401 \<close>
   414 \<close>
   402 
   415 
   403 
   416 
   404 generate_file "Isabelle/Symbol.hs" = \<open>
   417 generate_file "Isabelle/Symbol.hs" = \<open>
   405 {-  Title:      Isabelle/Symbols.hs
   418 {-  Title:      Isabelle/Symbols.hs
  2457   return (if len == n then Just msg else Nothing, len)
  2470   return (if len == n then Just msg else Nothing, len)
  2458 
  2471 
  2459 read_line :: Socket -> IO (Maybe Bytes)
  2472 read_line :: Socket -> IO (Maybe Bytes)
  2460 read_line socket = read_body []
  2473 read_line socket = read_body []
  2461   where
  2474   where
  2462     result = Bytes.trim_line . Bytes.pack . reverse
  2475     result = trim_line . Bytes.pack . reverse
  2463     read_body bs = do
  2476     read_body bs = do
  2464       s <- Socket.recv socket 1
  2477       s <- Socket.recv socket 1
  2465       case ByteString.length s of
  2478       case ByteString.length s of
  2466         0 -> return (if null bs then Nothing else Just (result bs))
  2479         0 -> return (if null bs then Nothing else Just (result bs))
  2467         1 ->
  2480         1 ->
  2534   case opt_line of
  2547   case opt_line of
  2535     Nothing -> return Nothing
  2548     Nothing -> return Nothing
  2536     Just line ->
  2549     Just line ->
  2537       case Value.parse_nat line of
  2550       case Value.parse_nat line of
  2538         Nothing -> return $ Just line
  2551         Nothing -> return $ Just line
  2539         Just n -> fmap Bytes.trim_line . fst <$> read_block socket n
  2552         Just n -> fmap trim_line . fst <$> read_block socket n
  2540 
  2553 
  2541 
  2554 
  2542 read_yxml :: Socket -> IO (Maybe XML.Body)
  2555 read_yxml :: Socket -> IO (Maybe XML.Body)
  2543 read_yxml socket = do
  2556 read_yxml socket = do
  2544   res <- read_line_message socket
  2557   res <- read_line_message socket