module PreludePrim ( -- Conversion ord, chr, intToFloat, ceiling, floor, truncate, round -- Int , (+), (-), (*), div, mod, quot, rem, negate , (==), (/=), (<), (>), (<=), (>=) -- Float , (+.), (-.), (*.), (/.) , (==.), (/=.), (<.), (>.), (<=.), (>=.) , sqrt, (**.), exp, log, sin, cos, tan -- Enum , enumFrom, enumFromThen, enumFromTo, enumFromThenTo -- IO monad , return , unsafePerformIO , putChar, putStr, putStrLn -- IO files , getChar , Handle, stdin, stdout, stderr , IOMode(..), openFile, hClose , hGetChar, hPutChar, hPutString -- strictness , ($!), seq -- misc , error, catch, catchEof, raise ) where import LvmLang ( return = returnIO, bindIO , (+), (-), (*), div = (/), mod = (%), quot, rem, negInt , (==), (/=), (<), (>), (<=), (>=) , (+.), (-.), (*.), (/.) , (==.), (/=.), (<.), (>.), (<=.), (>=.) , ($!), seq , True -- hack ) import LvmIO ( stdinChannel = stdin, stdoutChannel = stdout, stderrChannel = stderr , Channel(), Input(), Output() , CreateMode(CreateIfNotExists, CreateOverwrite) , openInputFile, openOutputFile , close, flush , inputChar, outputChar, outputString ) import LvmException ( error, errorPacked {- hack -}, catch, raise , Exception(System), SystemException(EndOfFile) ) import HeliumLang ( ''$negate'' , ''$enumFrom'', ''$enumFromThen'', ''$enumFromTo'', ''$enumFromThenTo'' , ''$primPutChar'', ''$primPutStr'', ''$primPutStrLn'', ''$primUnsafePerformIO'' ) custom infix (+) : public [6,"left"] custom infix (-) : public [6,"left"] custom infix (*) : public [7,"left"] custom infix div : public [7,"left"] custom infix mod : public [7,"left"] custom infix quot : public [7,"left"] custom infix rem : public [7,"left"] custom infix (==) : public [4,"none"] custom infix (/=) : public [4,"none"] custom infix (<) : public [4,"none"] custom infix (>) : public [4,"none"] custom infix (<=) : public [4,"none"] custom infix (>=) : public [4,"none"] custom infix (+.) : public [6,"left"] custom infix (-.) : public [6,"left"] custom infix (*.) : public [7,"left"] custom infix (/.) : public [7,"left"] custom infix (==.) : public [4,"none"] custom infix (/=.) : public [4,"none"] custom infix (<.) : public [4,"none"] custom infix (>.) : public [4,"none"] custom infix (<=.) : public [4,"none"] custom infix (>=.) : public [4,"none"] custom infix (**.) : public [8,"right"] custom infix ($!) : public [0,"right"] ord :: Char -> Int ord x = x chr :: Int -> Char chr x = x {-------------------------------------------------------------------------- IO --------------------------------------------------------------------------} putChar :: Char -> IO () putChar c = ''$primPutChar''c putStr :: String -> IO () putStr s = ''$primPutStr'' s putStrLn :: String -> IO () putStrLn s = ''$primPutStrLn'' s unsafePerformIO :: IO a -> a unsafePerformIO io = ''$primUnsafePerformIO'' io -- Float extern primFloatSqrt "fp_sqrt" :: "FF" extern float_of_string_extern "float_of_string" :: "Fz" sqrt :: Float -> Float sqrt x = let! x = x y = float_of_string_extern "0.0" in case (>=.) x y of { True -> primFloatSqrt x ; _ -> errorPacked "Can't apply sqrt to negative floating-point number" } extern primFloatPower "fp_pow" :: "FFF" (**.) :: Float -> Float -> Float (**.) x y = let! x = x in let! y = y in primFloatPower x y extern primFloatExp "fp_exp" :: "FF" exp :: Float -> Float exp x = let! x = x in primFloatExp x extern primFloatLog "fp_log" :: "FF" log :: Float -> Float log x = let! x = x in primFloatLog x extern primFloatSin "fp_sin" :: "FF" sin :: Float -> Float sin x = let! x = x in primFloatSin x extern primFloatCos "fp_cos" :: "FF" cos :: Float -> Float cos x = let! x = x in primFloatCos x extern primFloatTan "fp_tan" :: "FF" tan :: Float -> Float tan x = let! x = x in primFloatTan x extern primIntToFloat "float_of_int" :: "FI" intToFloat :: Int -> Float intToFloat x = let! x = x in primIntToFloat x extern primFloatCeil "fp_ceil" :: "FF" ceiling :: Float -> Int ceiling x = let! x = x y = primFloatCeil x in primFloatTruncateInt y extern primFloatFloor "fp_floor" :: "FF" floor :: Float -> Int floor x = let! x = x y = primFloatFloor x in primFloatTruncateInt y extern primFloatTruncateInt "fp_trunc_int" :: "IF" truncate :: Float -> Int truncate x = let! x = x in primFloatTruncateInt x extern primFloatNear "fp_near" :: "FF" extern primFloatRoundInt "fp_round_int" :: "IF" round :: Float -> Int round x = let! y = x z = primFloatNear y i = primFloatRoundInt z in i {-------------------------------------------------------------------------- Re-export Builtins --------------------------------------------------------------------------} negate :: Int -> Int negate x = ''$negate'' x enumFrom :: Int -> [Int] enumFrom n = ''$enumFrom'' n enumFromTo :: Int -> Int -> [Int] enumFromTo n m = ''$enumFromTo'' n m enumFromThen :: Int -> Int -> [Int] enumFromThen n a = ''$enumFromThen'' n a enumFromThenTo :: Int -> Int -> Int -> [Int] enumFromThenTo n a m = ''$enumFromThenTo'' n a m {-------------------------------------------------------------------------- IO --------------------------------------------------------------------------} data Handle = HandleRead (Channel Input) | HandleWrite (Channel Output) data IOMode = ReadMode | WriteMode | AppendMode stdin :: Handle stdin = HandleRead stdinChannel stdout :: Handle stdout = HandleWrite stdoutChannel stderr :: Handle stderr = HandleWrite stderrChannel getChar :: IO Char getChar = inputChar stdinChannel -- hGetChar stdin openFile :: String -> IOMode -> IO Handle openFile fpath mode = case mode of ReadMode -> bindIO (openInputFile fpath True) (\ch -> return (HandleRead ch)) WriteMode -> bindIO (openOutputFile fpath True CreateOverwrite) (\ch -> return (HandleWrite ch)) AppendMode-> bindIO (openOutputFile fpath True CreateIfNotExists) (\ch -> return (HandleWrite ch)) hClose :: Handle -> IO () hClose handle = case handle of HandleRead ch -> close ch HandleWrite ch -> -- FUUCCKK: alleen maar om altijd geflushed te closen.. catch (bindIO (flush ch) (\_ -> close ch)) (\exn -> bindIO (catch (close ch) (\_ -> raise exn)) (\_ -> raise exn)) hFlush :: Handle -> IO () hFlush handle = case handle of HandleRead ch -> flush ch HandleWrite ch -> flush ch hGetChar :: Handle -> IO Char hGetChar handle = case handle of HandleRead ch -> inputChar ch HandleWrite ch -> errorPacked "PreludePrim.hGetChar: Handle is not open for reading" hPutChar :: Handle -> Char -> IO () hPutChar handle c = case handle of HandleRead ch -> errorPacked "PreludePrim.hPutChar: Handle is not open for writing" HandleWrite ch -> outputChar ch c hPutString :: Handle -> String -> IO () hPutString handle s = case handle of HandleRead ch -> errorPacked "PreludePrim.hPutString: Handle is not open for writing" HandleWrite ch -> outputString ch s catchEof :: IO a -> IO a -> IO a catchEof io onEof = catch io (\exn -> case exn of System sysexn -> case sysexn of EndOfFile -> onEof _ -> raise exn _ -> raise exn )