src/Tools/Haskell/Haskell.thy
changeset 69452 704915cf59fa
parent 69449 b516fdf8005c
child 69453 dcea1fffbfe6
equal deleted inserted replaced
69451:387894c2fb2c 69452:704915cf59fa
   111 
   111 
   112 See also \<^file>\<open>$ISABELLE_HOME/src/Pure/General/value.ML\<close>.
   112 See also \<^file>\<open>$ISABELLE_HOME/src/Pure/General/value.ML\<close>.
   113 -}
   113 -}
   114 
   114 
   115 module Isabelle.Value
   115 module Isabelle.Value
   116   (print_bool, parse_bool, print_int, parse_int, print_real, parse_real)
   116   (print_bool, parse_bool, parse_nat, print_int, parse_int, print_real, parse_real)
   117 where
   117 where
   118 
   118 
   119 import Data.Maybe
   119 import Data.Maybe
   120 import qualified Data.List as List
   120 import qualified Data.List as List
   121 import qualified Text.Read as Read
   121 import qualified Text.Read as Read
   129 
   129 
   130 parse_bool :: String -> Maybe Bool
   130 parse_bool :: String -> Maybe Bool
   131 parse_bool "true" = Just True
   131 parse_bool "true" = Just True
   132 parse_bool "false" = Just False
   132 parse_bool "false" = Just False
   133 parse_bool _ = Nothing
   133 parse_bool _ = Nothing
       
   134 
       
   135 
       
   136 {- nat -}
       
   137 
       
   138 parse_nat :: String -> Maybe Int
       
   139 parse_nat s =
       
   140   case Read.readMaybe s of
       
   141     Just n | n >= 0 -> Just n
       
   142     _ -> Nothing
   134 
   143 
   135 
   144 
   136 {- int -}
   145 {- int -}
   137 
   146 
   138 print_int :: Int -> String
   147 print_int :: Int -> String
  1377 
  1386 
  1378 See \<^file>\<open>$ISABELLE_HOME/src/Pure/PIDE/byte_message.ML\<close>
  1387 See \<^file>\<open>$ISABELLE_HOME/src/Pure/PIDE/byte_message.ML\<close>
  1379 and \<^file>\<open>$ISABELLE_HOME/src/Pure/PIDE/byte_message.scala\<close>.
  1388 and \<^file>\<open>$ISABELLE_HOME/src/Pure/PIDE/byte_message.scala\<close>.
  1380 -}
  1389 -}
  1381 
  1390 
  1382 module Isabelle.Byte_Message
  1391 module Isabelle.Byte_Message (
  1383   (read, read_block, read_line, trim_line,
  1392     write, newline,
  1384    read_line_message, write_line_message)
  1393     read, read_block, trim_line, read_line,
       
  1394     read_line_message, write_line_message
       
  1395   )
  1385 where
  1396 where
  1386 
  1397 
  1387 import Prelude hiding (read)
  1398 import Prelude hiding (read)
  1388 import Data.ByteString (ByteString)
  1399 import Data.ByteString (ByteString)
  1389 import qualified Data.ByteString as ByteString
  1400 import qualified Data.ByteString as ByteString
  1396 import qualified Network.Socket.ByteString as ByteString
  1407 import qualified Network.Socket.ByteString as ByteString
  1397 
  1408 
  1398 import qualified Isabelle.Value as Value
  1409 import qualified Isabelle.Value as Value
  1399 
  1410 
  1400 
  1411 
       
  1412 {- output operations -}
       
  1413 
       
  1414 write :: Socket -> [ByteString] -> IO ()
       
  1415 write = ByteString.sendMany
       
  1416 
       
  1417 newline :: ByteString
       
  1418 newline = ByteString.singleton 10
       
  1419 
       
  1420 
       
  1421 {- input operations -}
       
  1422 
  1401 read :: Socket -> Int -> IO ByteString
  1423 read :: Socket -> Int -> IO ByteString
  1402 read socket n = read_bytes 0 []
  1424 read socket n = read_body 0 []
  1403   where
  1425   where
  1404     result :: [ByteString] -> ByteString
       
  1405     result = ByteString.concat . reverse
  1426     result = ByteString.concat . reverse
  1406 
  1427     read_body len ss =
  1407     read_bytes :: Int -> [ByteString] -> IO ByteString
       
  1408     read_bytes len ss =
       
  1409       if len >= n then return (result ss)
  1428       if len >= n then return (result ss)
  1410       else
  1429       else
  1411         (do
  1430         (do
  1412           s <- ByteString.recv socket (min (n - len) 8192)
  1431           s <- ByteString.recv socket (min (n - len) 8192)
  1413           case ByteString.length s of
  1432           case ByteString.length s of
  1414             0 -> return (result ss)
  1433             0 -> return (result ss)
  1415             m -> read_bytes (len + m) (s : ss))
  1434             m -> read_body (len + m) (s : ss))
  1416 
  1435 
  1417 read_block :: Socket -> Int -> IO (Maybe ByteString)
  1436 read_block :: Socket -> Int -> IO (Maybe ByteString, Int)
  1418 read_block socket n = do
  1437 read_block socket n = do
  1419   s <- read socket n
  1438   msg <- read socket n
  1420   return (if ByteString.length s == n then Just s else Nothing)
  1439   let len = ByteString.length msg
       
  1440   return (if len == n then Just msg else Nothing, len)
       
  1441 
       
  1442 trim_line :: ByteString -> ByteString
       
  1443 trim_line s =
       
  1444   if n >= 2 && at (n - 2) == 13 && at (n - 1) == 10 then ByteString.take (n - 2) s
       
  1445   else if n >= 1 && (at (n - 1) == 13 || at (n - 1) == 10) then ByteString.take (n - 1) s
       
  1446   else s
       
  1447   where
       
  1448     n = ByteString.length s
       
  1449     at = ByteString.index s
  1421 
  1450 
  1422 read_line :: Socket -> IO (Maybe ByteString)
  1451 read_line :: Socket -> IO (Maybe ByteString)
  1423 read_line socket = read []
  1452 read_line socket = read_body []
  1424   where
  1453   where
  1425     result :: [Word8] -> ByteString
  1454     result = trim_line . ByteString.pack . reverse
  1426     result bs =
  1455     read_body bs = do
  1427       ByteString.pack $ reverse $
       
  1428         if not (null bs) && head bs == 13 then tail bs else bs
       
  1429 
       
  1430     read :: [Word8] -> IO (Maybe ByteString)
       
  1431     read bs = do
       
  1432       s <- ByteString.recv socket 1
  1456       s <- ByteString.recv socket 1
  1433       case ByteString.length s of
  1457       case ByteString.length s of
  1434         0 -> return (if null bs then Nothing else Just (result bs))
  1458         0 -> return (if null bs then Nothing else Just (result bs))
  1435         1 ->
  1459         1 ->
  1436           case ByteString.head s of
  1460           case ByteString.head s of
  1437             10 -> return (Just (result bs))
  1461             10 -> return (Just (result bs))
  1438             b -> read (b : bs)
  1462             b -> read_body (b : bs)
  1439 
       
  1440 trim_line :: ByteString -> ByteString
       
  1441 trim_line s =
       
  1442     if n >= 2 && at (n - 2) == 13 && at (n - 1) == 10 then ByteString.take (n - 2) s
       
  1443     else if n >= 1 && (at (n - 1) == 13 || at (n - 1) == 10) then ByteString.take (n - 1) s
       
  1444     else s
       
  1445   where
       
  1446     n = ByteString.length s
       
  1447     at = ByteString.index s
       
  1448 
  1463 
  1449 
  1464 
  1450 -- hybrid messages: line or length+block (with content restriction)
  1465 -- hybrid messages: line or length+block (with content restriction)
  1451 
  1466 
  1452 is_length :: ByteString -> Bool
  1467 is_length :: ByteString -> Bool
  1453 is_length s =
  1468 is_length msg =
  1454   not (ByteString.null s) && ByteString.all (\b -> 48 <= b && b <= 57) s
  1469   not (ByteString.null msg) && ByteString.all (\b -> 48 <= b && b <= 57) msg
  1455 
  1470 
  1456 has_line_terminator :: ByteString -> Bool
  1471 is_terminated :: ByteString -> Bool
  1457 has_line_terminator s =
  1472 is_terminated msg =
  1458   not (ByteString.null s) && (ByteString.last s == 13 || ByteString.last s == 10)
  1473   not (ByteString.null msg) && (ByteString.last msg == 13 || ByteString.last msg == 10)
  1459 
  1474 
  1460 write_line_message :: Socket -> ByteString -> IO ()
  1475 write_line_message :: Socket -> ByteString -> IO ()
  1461 write_line_message socket msg = do
  1476 write_line_message socket msg = do
  1462   when (is_length msg || has_line_terminator msg) $
  1477   when (is_length msg || is_terminated msg) $
  1463     error ("Bad content for line message:\n" ++ take 100 (UTF8.toString msg))
  1478     error ("Bad content for line message:\n" ++ take 100 (UTF8.toString msg))
  1464 
  1479 
  1465   let newline = ByteString.singleton 10
       
  1466   let n = ByteString.length msg
  1480   let n = ByteString.length msg
  1467   ByteString.sendMany socket
  1481   write socket
  1468     (if n > 100 || ByteString.any (== 10) msg then
  1482     (if n > 100 || ByteString.any (== 10) msg then
  1469       [UTF8.fromString (Value.print_int (n + 1)), newline, msg, newline]
  1483       [UTF8.fromString (Value.print_int (n + 1)), newline, msg, newline]
  1470      else [msg, newline])
  1484      else [msg, newline])
  1471 
  1485 
  1472 read_line_message :: Socket -> IO (Maybe ByteString)
  1486 read_line_message :: Socket -> IO (Maybe ByteString)
  1473 read_line_message socket = do
  1487 read_line_message socket = do
  1474   opt_line <- read_line socket
  1488   opt_line <- read_line socket
  1475   case opt_line of
  1489   case opt_line of
  1476     Nothing -> return Nothing
  1490     Nothing -> return Nothing
  1477     Just line ->
  1491     Just line ->
  1478       case Value.parse_int (UTF8.toString line) of
  1492       case Value.parse_nat (UTF8.toString line) of
  1479         Nothing -> return $ Just line
  1493         Nothing -> return $ Just line
  1480         Just n -> fmap trim_line <$> read_block socket n
  1494         Just n -> fmap trim_line . fst <$> read_block socket n
  1481 \<close>
  1495 \<close>
  1482 
  1496 
  1483 end
  1497 end