{-# LANGUAGE GADTs                 #-}
{-# LANGUAGE InstanceSigs          #-}
{-# LANGUAGE MultiParamTypeClasses #-}

module Language.Drasil.Literal.Lang where
import           Language.Drasil.Space     (Space (..))
import           Language.Drasil.WellTyped

data Literal where
    Int      :: Integer -> Literal
    Str      :: String -> Literal
    Dbl      :: Double -> Literal
    ExactDbl :: Integer -> Literal
    Perc     :: Integer -> Integer -> Literal
    deriving Literal -> Literal -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Literal -> Literal -> Bool
$c/= :: Literal -> Literal -> Bool
== :: Literal -> Literal -> Bool
$c== :: Literal -> Literal -> Bool
Eq

{- TODO: When typing the Expression language, this will be usable
instance Eq (Literal a) where
    (Int l)      == (Int r)      =  l == r
    (Str l)      == (Str r)      =  l == r
    (Dbl l)      == (Dbl r)      =  l == r
    (ExactDbl l) == (ExactDbl r) =  l == r
    (Perc l1 l2) == (Perc r1 r2) =  l1 == r1 && l2 == r2
    _            == _            =  False
-}

instance Typed Literal Space where
  infer :: TypingContext Space -> Literal -> Either Space TypeError
  infer :: TypingContext Space -> Literal -> Either Space String
infer TypingContext Space
_ (Int Integer
_)      = forall a b. a -> Either a b
Left Space
Integer
  infer TypingContext Space
_ (Str String
_)      = forall a b. a -> Either a b
Left Space
String
  infer TypingContext Space
_ (Dbl Double
_)      = forall a b. a -> Either a b
Left Space
Real
  infer TypingContext Space
_ (ExactDbl Integer
_) = forall a b. a -> Either a b
Left Space
Real
  infer TypingContext Space
_ (Perc Integer
_ Integer
_)   = forall a b. a -> Either a b
Left Space
Real

  check :: TypingContext Space -> Literal -> Space -> Either Space TypeError
  check :: TypingContext Space -> Literal -> Space -> Either Space String
check = forall e t.
Typed e t =>
TypingContext t -> e -> t -> Either t String
typeCheckByInfer