module Main where
import IO
import Binary
import qualified Binary
import Directory
import System
data ZooTree = ZT (Bin ZooTree) (Bin ZooTree) String
deriving Binary
zero = int2BinPtr 0
main = do
exists <- doesFileExist "zoo"
zoo <- openBin (File "zoo" RW)
(root,eof) <- (if exists then
get zoo
else do
put zoo (zero,zero)
root <- put zoo (ZT zero zero "dog")
eof <- tellBin zoo
putAt zoo zero (root,eof)
return (root,eof)
)
(_,_,end) <- untilCatch isEOFError
( \(p, z, end) -> do
( if p==zero then
qanda "Have you thought of an animal"
(return ())
(finish zoo zero end)
else return ())
(ZT y n s) <- getAt zoo z
( if (y == zero) then
qanda ("Is it a "++s++"?")
( do newroot <- getAt zoo zero
return (zero, newroot, end) )
( do putStrLn "What is it then?"
t <- getLine
putStrLn ("What question has answer yes for a "
++s++" but no for a "++t)
q <- getLine
putAt zoo end (ZT zero zero t)
qpos <- put zoo (ZT z end q)
newend <- tellBin zoo
putAt zoo p qpos
newroot <- getAt zoo zero
return (zero, newroot, newend) )
else
qanda s
(return (unsafeShiftBinPtr 0 z, y, end))
(return (unsafeShiftBinPtr sizeofBinPtr z, n, end)))
) (zero {-:: Bin (Bin ZooTree)-}, root, eof)
finish zoo zero end
qanda :: String -> (IO a) -> (IO a) -> (IO a)
qanda q y n = do
putStrLn q
(a:_) <- getLine
case a of
'y' -> y
'n' -> n
_ -> putStrLn "Start answer y or n." >> qanda q y n
finish zoo zero end = do
putAt zoo (unsafeShiftBinPtr sizeofBinPtr zero) end
closeBin zoo
exitWith ExitSuccess
------
untilCatch :: (IOError->Bool) -> (a->IO a) -> a -> IO a
untilCatch_ :: (IOError->Bool) -> IO () -> IO ()
untilCatch p f a =
catch (f a >>= \x-> return (True,x))
(\e-> if p e then return (False,a) else ioError e)
>>= \(ok,a')->
if ok then untilCatch p f a' else return a'
untilCatch_ p f =
catch (f >> return True)
(\e-> if p e then return False else ioError e)
>>= \ok->
if ok then untilCatch_ p f else return ()
------
|