{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE RankNTypes #-}

module Types where

import           Control.Monad.Trans.Except (ExceptT)
import           Control.Monad.Trans.State (StateT)
import           Control.Monad.IO.Class (MonadIO)
import           Data.ByteString (ByteString)
import           Data.HashMap.Strict (HashMap)
import           Data.Sequence (Seq)
import           Data.Text (Text)
import           Data.Vector (Vector)
import qualified Text.Megaparsec as MP

data InterpreterState = InterpreterState
  { isSource     :: Text
  , isParseState :: MP.State Text
  , isOpStack    :: Seq Object
  , isDictStack  :: Seq (HashMap Text Object)
  , isExecStack  :: Seq Object
  } deriving (Show)

data BuiltIn = BuiltIn (Endsay ())

instance Show BuiltIn where show _ = "BuiltIn { ... }"

type Fragment = Vector Object

data ESErr = ESErr String deriving (Eq, Show)

newtype Endsay a =
  Endsay { runInterp :: ExceptT ESErr (StateT InterpreterState IO) a }
    deriving (Functor, Applicative, Monad, MonadIO)

data Object
  = OBool Bool
  | OFontId ()
  | OInteger Integer
  | OMark ()
  | OName Text
  | ONull
  | OOperator ()
  | OBuiltInOperator BuiltIn
  | OReal Double
  | OArray (Vector Object)
  | ODictionary (HashMap Text Object)
  | OFile ()
--  | OGState ()
--  | OPackedArray ()
  | OSave ()
  | OString Text
    deriving (Show)

data ParsedObject
  = POInteger Integer
  | POReal Double
  | PORadix Int Integer
  | POString Text
  | POByteString ByteString
  | POSymbol Text
  | POName Text
    deriving (Eq, Show)

data SourceLiteral = SourceLiteral
  { slObject :: ParsedObject
  , slLine   :: Int
  , slColumn :: Int
  , slText   :: Text
  } deriving (Eq, Show)
