{-# LANGUAGE FlexibleContexts #-}
-- | Contains common implementations specific to GOOL

module Drasil.GOOL.LanguageRenderer.CommonGOOL (
  constDecDef, classMethodCall
) where

import Drasil.Shared.InterfaceCommon (UnRepr(..), SVariable, SValue, VSType,
  MSStatement, NamedArgs, VariableElim(..))
import Drasil.Shared.RendererClassesCommon (CommonRenderSym, ScopeElim(..),
  RenderValue(..))
import Drasil.Shared.LanguageRenderer.Constructors (mkStmt)
import Drasil.Shared.LanguageRenderer (dot)
import Drasil.GOOL.Renderers (renderType, renderConstDecDef)
import Drasil.Shared.AST (TypeData, ScopeData)
import Drasil.Shared.State (lensMStoVS, useVarName, setVarScope)

import Control.Lens.Zoom (zoom)
import Control.Monad.State (modify)

constDecDef :: (CommonRenderSym r, UnRepr r TypeData) => SVariable r ->
  r ScopeData -> SValue r -> MSStatement r
constDecDef :: forall (r :: * -> *).
(CommonRenderSym r, UnRepr r TypeData) =>
SVariable r -> r ScopeData -> SValue r -> MSStatement r
constDecDef SVariable r
vr' r ScopeData
scp SValue r
v'= do
  r (Variable r)
vr <- LensLike'
  (Zoomed (StateT ValueState Identity) (r (Variable r)))
  MethodState
  ValueState
-> SVariable r -> StateT MethodState Identity (r (Variable r))
forall c.
LensLike'
  (Zoomed (StateT ValueState Identity) c) MethodState ValueState
-> StateT ValueState Identity c -> StateT MethodState Identity c
forall (m :: * -> *) (n :: * -> *) s t c.
Zoom m n s t =>
LensLike' (Zoomed m c) t s -> m c -> n c
zoom LensLike'
  (Zoomed (StateT ValueState Identity) (r (Variable r)))
  MethodState
  ValueState
(ValueState -> Focusing Identity (r (Variable r)) ValueState)
-> MethodState -> Focusing Identity (r (Variable r)) MethodState
Lens' MethodState ValueState
lensMStoVS SVariable r
vr'
  r (Value r)
v <- LensLike'
  (Zoomed (StateT ValueState Identity) (r (Value r)))
  MethodState
  ValueState
-> SValue r -> StateT MethodState Identity (r (Value r))
forall c.
LensLike'
  (Zoomed (StateT ValueState Identity) c) MethodState ValueState
-> StateT ValueState Identity c -> StateT MethodState Identity c
forall (m :: * -> *) (n :: * -> *) s t c.
Zoom m n s t =>
LensLike' (Zoomed m c) t s -> m c -> n c
zoom LensLike'
  (Zoomed (StateT ValueState Identity) (r (Value r)))
  MethodState
  ValueState
(ValueState -> Focusing Identity (r (Value r)) ValueState)
-> MethodState -> Focusing Identity (r (Value r)) MethodState
Lens' MethodState ValueState
lensMStoVS SValue r
v'
  (MethodState -> MethodState) -> StateT MethodState Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((MethodState -> MethodState) -> StateT MethodState Identity ())
-> (MethodState -> MethodState) -> StateT MethodState Identity ()
forall a b. (a -> b) -> a -> b
$ String -> MethodState -> MethodState
useVarName (String -> MethodState -> MethodState)
-> String -> MethodState -> MethodState
forall a b. (a -> b) -> a -> b
$ r (Variable r) -> String
forall (r :: * -> *). VariableElim r => r (Variable r) -> String
variableName r (Variable r)
vr
  (MethodState -> MethodState) -> StateT MethodState Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((MethodState -> MethodState) -> StateT MethodState Identity ())
-> (MethodState -> MethodState) -> StateT MethodState Identity ()
forall a b. (a -> b) -> a -> b
$ String -> ScopeData -> MethodState -> MethodState
setVarScope (r (Variable r) -> String
forall (r :: * -> *). VariableElim r => r (Variable r) -> String
variableName r (Variable r)
vr) (r ScopeData -> ScopeData
forall (r :: * -> *). ScopeElim r => r ScopeData -> ScopeData
scopeData r ScopeData
scp)
  Doc -> MSStatement r
forall (r :: * -> *). CommonRenderSym r => Doc -> MSStatement r
mkStmt (r (Variable r) -> r (Value r) -> Doc
forall (r :: * -> *).
(CommonRenderSym r, UnRepr r TypeData) =>
r (Variable r) -> r (Value r) -> Doc
renderConstDecDef r (Variable r)
vr r (Value r)
v)

classMethodCall :: (CommonRenderSym r, UnRepr r TypeData) => String ->
  VSType r -> VSType r -> [SValue r] -> NamedArgs r -> SValue r
classMethodCall :: forall (r :: * -> *).
(CommonRenderSym r, UnRepr r TypeData) =>
String
-> VSType r -> VSType r -> [SValue r] -> NamedArgs r -> SValue r
classMethodCall String
f VSType r
t VSType r
cls [SValue r]
vs NamedArgs r
ns = do
  r TypeData
c <- VSType r
cls
  Maybe String -> Maybe Doc -> MixedCall r
forall (r :: * -> *).
RenderValue r =>
Maybe String -> Maybe Doc -> MixedCall r
call Maybe String
forall a. Maybe a
Nothing (Doc -> Maybe Doc
forall a. a -> Maybe a
Just (Doc -> Maybe Doc) -> Doc -> Maybe Doc
forall a b. (a -> b) -> a -> b
$ r TypeData -> Doc
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType r TypeData
c Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Doc
dot) String
f VSType r
t [SValue r]
vs NamedArgs r
ns