-- | SSTG Syntax Definitions
module SSTG.Core.Syntax.Language
    ( module SSTG.Core.Syntax.Language
    ) where

type Program  = GenProgram  Name Var

type Lit      = GenLit      Name Var
type Atom     = GenAtom     Name Var
type PrimFun  = GenPrimFun  Name Var
type Expr     = GenExpr     Name Var
type Alt      = GenAlt      Name Var
type AltCon   = GenAltCon   Name Var
type Binding  = GenBinding  Name Var
type BindRhs  = GenBindRhs  Name Var

type ConTag   = GenConTag   Name
type DataCon  = GenDataCon  Name
type Type     = GenType     Name
type TyBinder = GenTyBinder Name
type Coercion = GenCoercion Name
type TyCon    = GenTyCon    Name
type AlgTyRhs = GenAlgTyRhs Name

-- | STG Program
newtype GenProgram bnd var = Program [GenBinding bnd var]
                           deriving (Show, Eq, Read)
-- | NameSpace
data NameSpace = VarNSpace | DataNSpace | TvNSpace | TcClsNSpace
               deriving (Show, Eq, Read, Ord)

-- | Name
data Name = Name String (Maybe String) NameSpace Int
          deriving (Show, Eq, Read, Ord)

-- | Variable
data Var = Var Name (GenType Name) deriving (Show, Eq, Read)

-- | Literal
data GenLit bnd var = MachChar   Char     (GenType bnd)
                    | MachStr    String   (GenType bnd)
                    | MachInt    Int      (GenType bnd)
                    | MachWord   Int      (GenType bnd)
                    | MachFloat  Rational (GenType bnd)
                    | MachDouble Rational (GenType bnd)
                    | MachNullAddr        (GenType bnd)
                    | MachLabel  String   (Maybe Int) (GenType bnd)
                    | BlankAddr
                    | AddrLit    Int
                    | SymLit     var
                    | SymLitEval (GenPrimFun bnd var) [GenLit bnd var]
                    deriving (Show, Eq, Read)

-- | Atomic
data GenAtom bnd var = VarAtom var
                     | LitAtom (GenLit bnd var)
                     deriving (Show, Eq, Read)

-- | Primitive Operation
data GenPrimFun bnd var = PrimFun bnd (GenType bnd) deriving (Show, Eq, Read)

-- | GenExpression
data GenExpr bnd var = Atom    (GenAtom bnd var)
                     | PrimApp (GenPrimFun bnd var)  [GenAtom bnd var]
                     | ConApp  (GenDataCon bnd)      [GenAtom bnd var]
                     | FunApp  var                   [GenAtom bnd var]
                     | Let     (GenBinding bnd var)  (GenExpr bnd var)
                     | Case    (GenExpr bnd var) var [GenAlt bnd var]
                     deriving (Show, Eq, Read)

-- | Case Alt
data GenAlt bnd var = Alt (GenAltCon bnd var) [var] (GenExpr bnd var)
                    deriving (Show, Eq, Read)

-- | Alt Constructor
data GenAltCon bnd var = DataAlt (GenDataCon bnd)
                       | LitAlt  (GenLit bnd var)
                       | Default
                       deriving (Show, Eq, Read)

-- | Binding
data GenBinding bnd var = Binding RecForm [(var, GenBindRhs bnd var)]
                        deriving (Show, Eq, Read)

-- | Recursive?
data RecForm = Rec | NonRec deriving (Show, Eq, Read)

-- | Form of Bind Rhs
data GenBindRhs bnd var = ConForm (GenDataCon bnd) [GenAtom bnd var]
                        | FunForm [var]            (GenExpr bnd var)
                        deriving (Show, Eq, Read)

-- | Data Constructor ID
data GenConTag bnd = ConTag bnd Int deriving (Show, Eq, Read)

-- | Data Constructor
data GenDataCon bnd = DataCon (GenConTag bnd) (GenType bnd) [GenType bnd]
                    deriving (Show, Eq, Read)

-- | Type
data GenType bnd = TyVarTy    bnd               (GenType bnd)
                 | AppTy      (GenType bnd)     (GenType bnd)
                 | ForAllTy   (GenTyBinder bnd) (GenType bnd)
                 | CastTy     (GenType bnd)     (GenCoercion bnd)
                 | TyConApp   (GenTyCon bnd)    [GenType bnd]
                 | CoercionTy (GenCoercion bnd)
                 | LitTy      TyLit
                 | FunTy      (GenType bnd)     (GenType bnd)
                 | Bottom
                 deriving (Show, Eq, Read)

-- | TyBinder
data GenTyBinder bnd = NamedTyBndr bnd (GenType bnd)
                     | AnonTyBndr      (GenType bnd)
                     deriving (Show, Eq, Read)

-- | TyLit
data TyLit = NumTyLit Int
           | StrTyLit String
           deriving (Show, Eq, Read)

-- | Coercion
data GenCoercion bnd = Coercion (GenType bnd) (GenType bnd)
                     deriving (Show, Eq, Read)

-- | TyCon
data GenTyCon bnd = FunTyCon     bnd
                  | AlgTyCon     bnd (GenAlgTyRhs bnd)
                  | SynonymTyCon bnd
                  | FamilyTyCon  bnd
                  | PrimTyCon    bnd
                  | Promoted     bnd (GenDataCon bnd)
                  | TcTyCon      bnd
                  deriving (Show, Eq, Read)

-- | Algebraic Type Constructor RHS
data GenAlgTyRhs bnd = AbstractTyCon Bool
                     | DataTyCon     [GenConTag bnd]
                     | TupleTyCon    (GenConTag bnd)
                     | NewTyCon      (GenConTag bnd)
                     deriving (Show, Eq, Read)