-- | Built-in operations and types module Basis ( primBasis, srcBasis, basis2venv, basis2tenv ) where import Util import BasisUtils import Value (Valuable(..), Value(..), VRecord(..)) import AST import Type import qualified Data.Loc import qualified Basis.IO import qualified Basis.Socket import qualified Basis.Exn import qualified Basis.Thread import qualified Basis.Channel import qualified Basis.MVar import qualified Basis.Future import qualified Basis.Array import qualified Basis.Row import qualified IO import qualified System.Environment as Env import Data.IORef (IORef, newIORef, readIORef, atomicModifyIORef) import System.Random (randomIO) import System.Exit (exitWith, ExitCode(..)) import Data.Typeable -- Primitive operations implemented in Haskell primBasis :: [Entry Raw] primBasis = [ --- --- Ordinary constants: --- --- name -: type -= value -- Primitive types: "unit" `primtype` tcUnit, "exn" `primtype` tcExn, "int" `primtype` tcInt, "char" `primtype` tcChar, "float" `primtype` tcFloat, "string" `primtype` tcString, "unlimited" `primtype` tcUn, "affine" `primtype` tcAf, "*" `primtype` tcTuple, "record" `primtype` tcRecord, "variant" `primtype` tcVariant, "rowend" `primtype` tcRowEnd, "rowdots#" `primtype` tcRowDots, -- Needed by renamer "\\/" `primtype` tcJoin, "->" `primtype` tcFun, -- Bool needs to be known to the parser for if expression dec [sgQ| type bool = false | true |], -- Lists need to be known by the parser for list syntax dec [sgQ| type `a list = [] | (::) of `a * `a list |], submod "INTERNALS" [ submod "PrimTypes" [ dec [sgQ| type unit = type unit |], dec [sgQ| type variant = type variant |], dec [sgQ| type record = type record |], dec [sgQ| type rowend = type rowend |], dec [sgQ| type unlimited = type unlimited |], dec [sgQ| type affine = type affine |], dec [sgQ| type bool = type bool |], dec [sgQ| type list = type list |], val "nilRecord" -: [ty| (unlimited, rowend) record |] -= MultiplicativeRecord [] ] ], -- Sums dec [sgQ| type `a option = None | Some of `a |], dec [sgQ| type `a + `b = Left of `a | Right of `b |], -- Arithmetic binArith "+" (+), binArith "-" (-), binArith "*" (*), binArith "/" div, binArith "%" mod, fun "~" -: [ty| int -> int |] -= (negate :: Integer -> Integer), fun "abs" -: [ty| int -> int |] -= (abs :: Integer -> Integer) , fun "<=" -: [ty| int -> int -> bool |] -= ((<=) :: Integer -> Integer -> Bool), fun "string_of_int" -: [ty| int -> string |] -= (show :: Integer -> String), fun "int_of_string" -: [ty| string -> int |] -= (read :: String -> Integer), fun "random_int" -: [ty| unit -> int |] -= \() -> (randomIO :: IO Int), -- Floating point arithmetic fun "<=." -: [ty| float -> float -> bool |] -= ((<=) :: Double -> Double -> Bool), fun "<." -: [ty| float -> float -> bool |] -= ((<) :: Double -> Double -> Bool), fun "+." -: [ty| float -> float -> float |] -= ((+) :: Double -> Double -> Double), fun "-." -: [ty| float -> float -> float |] -= ((-) :: Double -> Double -> Double), fun "*." -: [ty| float -> float -> float |] -= ((*) :: Double -> Double -> Double), fun "/." -: [ty| float -> float -> float |] -= ((/) :: Double -> Double -> Double), fun "**" -: [ty| float -> float -> float |] -= ((**) :: Double -> Double -> Double), fun "~." -: [ty| float -> float |] -= (negate :: Double -> Double), fun "sqrt" -: [ty| float -> float |] -= (sqrt :: Double -> Double), fun "log" -: [ty| float -> float |] -= (log :: Double -> Double), fun "absf" -: [ty| float -> float |] -= (abs :: Double -> Double), fun "float_of_int" -: [ty| int -> float |] -= (fromIntegral :: Integer -> Double), fun "int_of_float" -: [ty| float -> int |] -= (round :: Double -> Integer), fun "string_of_float" -: [ty| float -> string |] -= (show :: Double -> String), fun "float_of_string" -: [ty| string -> float |] -= (read :: String -> Double), -- Strings fun "explode" -: [ty| string -> char list |] -= (map vinj ∷ String → [Value]), fun "implode" -: [ty| char list -> string |] -= (map vprj ∷ [Value] → String), fun "^" -: [ty| string -> string -> string |] -= ((++) :: String -> String -> String), fun "string_of" -: [ty| all 'a. 'a -> string |] -= (return . show :: Value -> IO String), fun "string_length" -: [ty| string -> int |] -= \s -> toInteger (length (s :: String)), -- "Magic" equality and print; failure fun "==" -: [ty| all 'a. 'a -> 'a -> bool |] -= ((==) :: Value -> Value -> Bool), fun "print" -: [ty| all 'a. 'a -> unit |] -= (print :: Value -> IO ()), -- I/O fun "putChar" -: [ty| char -> unit |] -= putChar . integer2char, fun "getChar" -: [ty| unit -> char |] -= \() -> fmap char2integer getChar, fun "flush" -: [ty| unit -> unit |] -= \() -> IO.hFlush IO.stdout, fun "putStr" -: [ty| string -> unit |] -= putStr, fun "putStrLn" -: [ty| string -> unit |] -= putStrLn, fun "getLine" -: [ty| unit -> string |] -= \() -> getLine, -- System and the environment fun "getArgs" -: [ty| unit -> string list |] -= \() -> Env.getArgs, fun "getProgName" -: [ty| unit -> string |] -= \() -> Env.getProgName, fun "getEnv" -: [ty| string -> string |] -= Env.getEnv, fun "getEnvironment" -: [ty| unit -> (string * string) list |] -= \() -> Env.getEnvironment, fun "exit" -: [ty| ∀ `a. int -> `a |] -= \z -> exitWith (if z == 0 then ExitSuccess else ExitFailure z) ∷ IO (), -- References dec [sgQ| type `a ref qualifier U |], dec [sgQ| type `a aref qualifier A |], fun "ref" -: [ty| all `a. `a -> `a ref |] -= (\v -> Ref `fmap` newIORef v), fun "aref" -: [ty| all `a. `a -> `a aref |] -= (\v -> Ref `fmap` newIORef v), fun "!" -: [ty| all 'a. 'a ref -> 'a |] -= (\r -> readIORef (unRef r)), fun "!!" -: [ty| all 'a. 'a aref -> 'a aref * 'a |] -= (\r -> do v <- readIORef (unRef r) return (r, v)), fun "<-" -: [ty| all `a. `a ref -> `a -> `a |] -= (\r v -> do atomicModifyIORef (unRef r) (\v' -> (v, v'))), fun "<-!" -: [ty| all `a `b. `a aref -> `b -o `b aref * `a |] -= (\r v -> do atomicModifyIORef (unRef r) (\v' -> (v, (r, v')))), submod "Unsafe" [ -- Unsafe coercions fun "unsafeCoerce" -: [ty| all `b `a. `a -> `b |] -= (id :: Value -> Value), fun "unsafeDup" -: [ty| all `a. `a -> `a * `a |] -= ((\v -> (v, v)) :: Value -> (Value, Value)) ], submod "IO" Basis.IO.entries, submod "Channel" Basis.Channel.entries, submod "Thread" Basis.Thread.entries, submod "MVar" Basis.MVar.entries, submod "Future" Basis.Future.entries, submod "Prim" [ submod "Socket" Basis.Socket.entries, submod "Exn" Basis.Exn.entries, submod "Array" Basis.Array.entries, submod "Row" Basis.Row.entries ] ] newtype Ref = Ref { unRef :: IORef Value } deriving (Eq, Typeable) instance Valuable Ref where veq = (==) vppr _ = text "#" -- | Built-in operations implemented in the object language srcBasis :: String srcBasis = "libbasis.alms"