-- | Contains renderer-related functions specific to GOOL
module Drasil.GProc.Renderers (
  renderType, renderParam, renderListDec, renderConstDecDef
) where

import Drasil.Shared.InterfaceCommon (UnRepr(..), VariableElim(..))
import Drasil.Shared.RendererClassesCommon (InternalVarElim(..), ValueElim(..))
import Drasil.Shared.LanguageRenderer (new', constDec')
import Drasil.Shared.CodeType (CodeType(..))
import Drasil.Shared.AST (TypeData(..))

import Prelude hiding ((<>))
import Text.PrettyPrint.HughesPJ (Doc, (<+>), (<>), space, equals, parens)

renderType :: (UnRepr r TypeData) => r TypeData -> Doc
renderType :: forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType r TypeData
tp = case TypeData -> CodeType
cType (TypeData -> CodeType) -> TypeData -> CodeType
forall a b. (a -> b) -> a -> b
$ r TypeData -> TypeData
forall (repr :: * -> *) contents.
UnRepr repr contents =>
repr contents -> contents
unRepr r TypeData
tp of
    (Object ClassName
_) -> ClassName -> Doc
forall a. HasCallStack => ClassName -> a
error ClassName
"Classes are not supported in procedural languages"
    CodeType
_ -> TypeData -> Doc
typeDoc (TypeData -> Doc) -> TypeData -> Doc
forall a b. (a -> b) -> a -> b
$ r TypeData -> TypeData
forall (repr :: * -> *) contents.
UnRepr repr contents =>
repr contents -> contents
unRepr r TypeData
tp

renderParam
  :: (InternalVarElim r var, UnRepr r TypeData, VariableElim r var TypeData)
  => r var -> Doc
renderParam :: forall (r :: * -> *) var.
(InternalVarElim r var, UnRepr r TypeData,
 VariableElim r var TypeData) =>
r var -> Doc
renderParam r var
v = r TypeData -> Doc
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType (r var -> r TypeData
forall {k} (r :: k -> *) (var :: k) (typ :: k).
VariableElim r var typ =>
r var -> r typ
variableType r var
v) Doc -> Doc -> Doc
<+> r var -> Doc
forall {k} (r :: k -> *) (var :: k).
InternalVarElim r var =>
r var -> Doc
variable r var
v

renderListDec
  :: (UnRepr r TypeData, ValueElim r val, VariableElim r var TypeData)
  => r var -> r val -> Doc
renderListDec :: forall (r :: * -> *) val var.
(UnRepr r TypeData, ValueElim r val,
 VariableElim r var TypeData) =>
r var -> r val -> Doc
renderListDec r var
v r val
n = Doc
space Doc -> Doc -> Doc
<> Doc
equals Doc -> Doc -> Doc
<+> Doc
new' Doc -> Doc -> Doc
<+> r TypeData -> Doc
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType (r var -> r TypeData
forall {k} (r :: k -> *) (var :: k) (typ :: k).
VariableElim r var typ =>
r var -> r typ
variableType r var
v)
  Doc -> Doc -> Doc
<> Doc -> Doc
parens (r val -> Doc
forall {k} (r :: k -> *) (val :: k).
ValueElim r val =>
r val -> Doc
value r val
n)

renderConstDecDef
  ::
    ( InternalVarElim r var
    , UnRepr r TypeData
    , ValueElim r val
    , VariableElim r var TypeData
    )
  => r var -> r val -> Doc
renderConstDecDef :: forall (r :: * -> *) var val.
(InternalVarElim r var, UnRepr r TypeData, ValueElim r val,
 VariableElim r var TypeData) =>
r var -> r val -> Doc
renderConstDecDef r var
v r val
def = Doc
constDec' Doc -> Doc -> Doc
<+> r TypeData -> Doc
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType (r var -> r TypeData
forall {k} (r :: k -> *) (var :: k) (typ :: k).
VariableElim r var typ =>
r var -> r typ
variableType r var
v) Doc -> Doc -> Doc
<+>
  r var -> Doc
forall {k} (r :: k -> *) (var :: k).
InternalVarElim r var =>
r var -> Doc
variable r var
v Doc -> Doc -> Doc
<+> Doc
equals Doc -> Doc -> Doc
<+> r val -> Doc
forall {k} (r :: k -> *) (val :: k).
ValueElim r val =>
r val -> Doc
value r val
def