{-# LANGUAGE FlexibleContexts #-}
-- | Contains renderer-related functions specific to GOOL

module Drasil.GProc.Renderers (
  renderType, renderParam, renderListDec, renderConstDecDef
) where

import Drasil.Shared.InterfaceCommon (Variable, Value, 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, UnRepr r TypeData, VariableElim r)
  => r Variable -> Doc
renderParam :: forall (r :: * -> *).
(InternalVarElim r, UnRepr r TypeData, VariableElim r) =>
r Variable -> Doc
renderParam r Variable
v = r TypeData -> Doc
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType (r Variable -> r TypeData
forall (r :: * -> *). VariableElim r => r Variable -> r TypeData
variableType r Variable
v) Doc -> Doc -> Doc
<+> r Variable -> Doc
forall (r :: * -> *). InternalVarElim r => r Variable -> Doc
variable r Variable
v

renderListDec
  :: (UnRepr r TypeData, ValueElim r, VariableElim r)
  => r Variable -> r Value -> Doc
renderListDec :: forall (r :: * -> *).
(UnRepr r TypeData, ValueElim r, VariableElim r) =>
r Variable -> r Value -> Doc
renderListDec r Variable
v r Value
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 Variable -> r TypeData
forall (r :: * -> *). VariableElim r => r Variable -> r TypeData
variableType r Variable
v)
  Doc -> Doc -> Doc
<> Doc -> Doc
parens (r Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
value r Value
n)

renderConstDecDef
  :: (InternalVarElim r, UnRepr r TypeData, ValueElim r, VariableElim r)
  => r Variable -> r Value -> Doc
renderConstDecDef :: forall (r :: * -> *).
(InternalVarElim r, UnRepr r TypeData, ValueElim r,
 VariableElim r) =>
r Variable -> r Value -> Doc
renderConstDecDef r Variable
v r Value
def = Doc
constDec' Doc -> Doc -> Doc
<+> r TypeData -> Doc
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType (r Variable -> r TypeData
forall (r :: * -> *). VariableElim r => r Variable -> r TypeData
variableType r Variable
v) Doc -> Doc -> Doc
<+>
  r Variable -> Doc
forall (r :: * -> *). InternalVarElim r => r Variable -> Doc
variable r Variable
v Doc -> Doc -> Doc
<+> Doc
equals Doc -> Doc -> Doc
<+> r Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
value r Value
def