packages feed

language-lustre-1.0.0: Language/Lustre/Semantics/Value.hs

{-# Language OverloadedStrings #-}
module Language.Lustre.Semantics.Value where

import Text.PrettyPrint as P
import Language.Lustre.Name
import Language.Lustre.AST
import Language.Lustre.Pretty

-- | The universe of basic values.
-- These are the values used for a specific time instance.
data Value    = VInt    !Integer
              | VBool   !Bool
              | VReal   !Rational
              | VEnum   !OrigName !OrigName       -- ^ Type, value
              | VStruct !OrigName ![Field Value]  -- ^ Type, fields
              | VArray  ![Value]
                deriving Show


instance Eq Value where
  x == y =
    case (x,y) of
      (VInt a,  VInt b)        -> a == b
      (VBool a, VBool b)       -> a == b
      (VReal a, VReal b)       -> a == b
      (VEnum t1 a, VEnum t2 b) -> t1 == t2 && a == b
      (VArray as, VArray bs)   -> cmpArr as bs
      (VStruct t1 as, VStruct t2 bs) | t1 == t2 -> cmpStr as bs
      _ -> False -- Type error

    where
    cmpArr as bs =
      case (as,bs) of
        ([],[])          -> True
        (a : xs, b : ys) -> a == b && cmpArr xs ys
        _                -> False

    cmpStr as bs =
      case (as,bs) of
        ([],[]) -> True
        (Field f v:more, fs) ->
          case getField f fs of
            Nothing -> False
            Just (v2,fs') -> v == v2 && cmpStr more fs'
        _ -> False -- Malformed structs

    getField nm fs =
      case fs of
        [] -> Nothing
        Field f a : more -> if nm == f
                               then Just (a,more)
                               else do (a',more') <- getField nm more
                                       return (a', Field f a : more')



-- | The evaluation monad.
type EvalM      = Either Error
type Error      = String

-- | Crash evaluation. We'd like to avoid calls to this.
crash :: String -> String -> EvalM a
crash x y = Left (x ++ ": " ++ y)

typeError :: String -> String -> EvalM a
typeError x y = crash x ("Type error, expected " ++ y)


--------------------------------------------------------------------------------

instance Pretty Value where
  ppPrec _ val =
    case val of
      VInt n -> integer n
      VBool b -> text (show b)
      VReal r -> double (fromRational r) -- XXX
      VEnum _ a -> pp a
      VStruct _ fs -> braces (commaSep (map pp fs))
      VArray vs -> brackets (hsep (punctuate comma (map pp vs)))