KiCS-0.8.6: src/Curry/RunTimeSystem.hs
{-# OPTIONS -O0 #-}
module Curry.RunTimeSystem (
module Curry.RunTimeSystem.BaseCurry,
module Curry.RunTimeSystem
) where
import System.IO
import Curry.RunTimeSystem.BaseCurry
import System.IO.Unsafe
import Data.IORef
-------------------------------------------------
-- normal forms which are all based on ctcStore
-- and may be called from compiled programs.
-------------------------------------------------
--SHOCKING: there was an additional ctcStore False (nf ...) around here,
-- runtimes were desastrous. Why was that??????
nfCTC :: (BaseCurry a,BaseCurry b) => (b -> Result a) -> b -> Result a
nfCTC cont = ctcStore False (nf cont)
hnfCTC :: (BaseCurry a,BaseCurry b) => (b -> Result a) -> b -> Result a
hnfCTC = ctcStore False
gnfCTC :: (BaseCurry a,BaseCurry b) => (b -> Result a) -> b -> Result a
gnfCTC cont = ctcStore True (gnf cont)
ghnfCTC :: (BaseCurry a,BaseCurry b) => (b -> Result a) -> b -> Result a
ghnfCTC = ctcStore True
-----------------------------------------------------------------
-- treatment for the basic cases of flexible pattern matching
-----------------------------------------------------------------
-- called by generated functions for matching failure
patternFail :: (BaseCurry a,BaseCurry b) => String -> a -> b
patternFail s x = case consKind x of
Failed -> addException (curryError s) x
_ -> failed (PatternMatchFail s)
----------------------------------------------------------------------
-- generate logic objects
----------------------------------------------------------------------
-- generate branching
withRef :: (Int -> a) -> Int -> a
withRef f 0 = f 0
withRef f i = f $! nextRef i
---------------------------------------------------------------
-- manipulating references: the unsafe part of CurryToHaskell
---------------------------------------------------------------
-- the global state of references
storeRefCounter :: IORef Int
{-# NOINLINE storeRefCounter #-}
storeRefCounter = unsafePerformIO (newIORef 1)
-- generate a new reference
nextRef :: Int -> Int
{-# NOINLINE nextRef #-}
nextRef i = unsafePerformIO (do
v <- readIORef storeRefCounter
writeIORef storeRefCounter (v+i+1)
return v)
---------------------------------------------------------------
-- run-time options (also unsafe)
---------------------------------------------------------------
-- the easiest way to have different modes for run-time behaviour is
-- a global state of run-time options.
-- the settings are only read once and stay the same during the whole computation.
data RunTimeOptions = RTO {currentModule :: String}
runTimeDefaults :: RunTimeOptions
runTimeDefaults = RTO {currentModule = ""}
runTimeOptions :: IORef RunTimeOptions
{-# NOINLINE runTimeOptions #-}
runTimeOptions = unsafePerformIO (newIORef runTimeDefaults)
setRunTimeOptions :: RunTimeOptions -> IO ()
setRunTimeOptions = writeIORef runTimeOptions
freeF :: (BaseCurry b, BaseCurry a) => (b -> a) -> a
freeF = freeOrBased
orF :: BaseCurry a => a -> a -> a
orF = orCTC
-----------------------------------------------------------------------
-- implementation of getProgName (module System) expressions
-----------------------------------------------------------------------
setProgName :: String -> IO ()
setProgName n = do
opts <- readIORef runTimeOptions
writeIORef runTimeOptions (opts{currentModule=n})
setProgNameAndOrBased :: String -> IO ()
setProgNameAndOrBased = setProgName
getProgName :: IO String
getProgName = readIORef runTimeOptions >>= return . currentModule
----------------------------------------------------------------------
-- alternatives for implementation of options
----------------------------------------------------------------------
orCTC :: BaseCurry a => a -> a -> a
orCTC x y = branching (mkRefWithGenInfo NoGenerator (nextRef 0)) [x,y]
-- free variables in or-based mode
freeOrBased :: (BaseCurry b, BaseCurry a) => (b -> a) -> a
freeOrBased f = f (generator (nextRef 0))
----------------------------------------------------------
-- some declarations for external read and show instances
----------------------------------------------------------
ten,eleven,zero :: Int
ten = 10
eleven = 11
zero = 0
readQualified :: String -> String -> String -> [((),String)]
readQualified mod name r = [((),s) | (name',s) <- lex r, name' == name]
++ [((),s3) | (mod',s1) <- lex r
, mod' == mod
, (".",s2) <- lex s1
, (name',s3) <- lex s2
, name' == name]