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

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

import Drasil.Shared.InterfaceCommon (UnRepr(..), VariableSym(..),
  VariableElim(..), ValueSym(..))
import Drasil.Shared.RendererClassesCommon (CommonRenderSym, InternalVarElim(..),
  ValueElim(..))
import Drasil.GProc.RendererClassesProc (ProcRenderSym)
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 :: (ProcRenderSym r, UnRepr r TypeData) => r (Variable r) -> Doc
renderParam :: forall (r :: * -> *).
(ProcRenderSym r, UnRepr r TypeData) =>
r (Variable r) -> Doc
renderParam r (Variable r)
v = r TypeData -> Doc
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType (r (Variable r) -> r TypeData
forall (r :: * -> *).
VariableElim r =>
r (Variable r) -> r TypeData
variableType r (Variable r)
v) Doc -> Doc -> Doc
<+> r (Variable r) -> Doc
forall (r :: * -> *). InternalVarElim r => r (Variable r) -> Doc
variable r (Variable r)
v

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

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