{-# LANGUAGE PostfixOperators #-}
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
{-# HLINT ignore "Redundant return" #-}
{-# LANGUAGE FlexibleContexts #-}

-- | Implementations defined here are valid for any language renderer.
module Drasil.Shared.LanguageRenderer.LanguagePolymorphic (fileFromData,
  multiBody, block, multiBlock, obj, negateOp, csc, sec, cot, equalOp,
  notEqualOp, greaterOp, greaterEqualOp, lessOp, lessEqualOp, plusOp, minusOp,
  multOp, divideOp, moduloOp, var, classVar, instanceVarAccess,
  classVarAccessCheck, arrayElem, local, litChar, litDouble, litInt, litString,
  valueOf, arg, argsList, call, funcAppMixedArgs, newObjMixedArgs, lambda,
  objAccess, objMethodCall, func, get, set, listAccess, getFunc, setFunc, stmt,
  loopStmt, emptyStmt, assign, subAssign, objDecNew, print, closeFile,
  returnStmt, valStmt, comment, throw, ifCond, tryCatch, construct, param,
  method, getMethod, setMethod, initStmts, function, docFuncRepr, docFunc,
  buildClass, implementingClass, docClass, commentedClass, modFromData, fileDoc,
  docMod, OptionalSpace(..), defaultOptSpace, smartAdd, smartSub
) where

import Drasil.FileHandling.Legacy (indent)

import Drasil.Shared.CodeType (CodeType(..), ClassName)
import Drasil.Shared.InterfaceCommon (UnRepr(..), Label, Library, Body, Block,
  Variable, SVariable, Value, SValue, NamedArgs, MixedCall, MixedCtorCall,
  bodyStatements, oneLiner, VisibilitySym(..),
  VariableElim(variableName, variableType), ValueSym(valueType),
  NumericExpression((#+), (#-), (#/), sin, cos, tan), Comparison(..), funcApp,
  StatementSym(multi), AssignStatement((&++)), (&=), TypeElim(..),
  IOStatement(printStr, printStrLn, printFile, printFileStr, printFileStrLn),
  ifNoElse, convType, VSBinder, BinderElim(..), getCodeType, getTypeString,
  ValueExpression)
import qualified Drasil.Shared.InterfaceCommon as IC
import Drasil.GOOL.InterfaceGOOL (OOStatement, File, Module, Class, Initializers,
  CSStateVar, newObj, objMethodCallNoParams, ($.), AttachmentSym(..))
import qualified Drasil.GOOL.InterfaceGOOL as IG
import Drasil.Shared.RendererClassesCommon (InternalVarElim(variableBind),
  RenderValue(valFromData), RenderFunction(funcFromData),
  FunctionElim(functionType), RenderStatement(stmtFromData),
  StatementElim(statementTerm), MethodTypeSym(mType), RenderParam(paramFromData),
  RenderMethod(commentedFunc), BlockCommentSym(..), ValueElim (value),
  RenderVariable)
import qualified Drasil.Shared.RendererClassesCommon as RC
import Drasil.GOOL.RendererClassesOO (OORenderSym, RenderFile(commentedMod),
  OORenderMethod(intMethod), RenderClass(inherit, implements),
  RenderMod(updateModuleDoc))
import qualified Drasil.GOOL.RendererClassesOO as RO
import Drasil.Shared.AST (AttachmentTag(..), Terminator(..), isSource,
  ScopeTag(Local), ScopeData, sd, TypeData(..), BinderD, ParamData, FuncData)
import Drasil.Shared.Helpers (doubleQuotedText, vibcat, emptyIfEmpty, toCode,
  toState, onStateValue, on2StateValues, onStateList, getNestDegree,
  on2StateWrapped)
import Drasil.Shared.LanguageRenderer (dot, ifLabel, elseLabel, access, addExt,
  FuncDocRenderer, ClassDocRenderer, ModuleDocRenderer, getterName, setterName,
  valueList, namedArgList)
import qualified Drasil.Shared.LanguageRenderer as R
import Drasil.Shared.LanguageRenderer.Constructors (mkStmtNoEnd, mkStateVal,
  mkVal, mkStateVar, mkVar, mkClassVar, VSOp, unOpPrec, compEqualPrec, compPrec,
  addPrec, multPrec, typeFromData)
import Drasil.Shared.State (VS, FS, CS, MS, lensFStoGS, lensMStoVS, lensCStoFS,
  currMain, currFileType, addFile, setMainMod, setModuleName, getModuleName,
  addParameter, getParameters, useVarName)

import Prelude hiding (print,sin,cos,tan,(<>))
import Data.Maybe (fromMaybe, maybeToList)
import Control.Monad.State (modify)
import Control.Lens ((^.), over)
import Control.Lens.Zoom (zoom)
import Text.PrettyPrint.HughesPJ (Doc, text, empty, render, (<>), (<+>), ($+$),
  parens, brackets, integer, vcat, comma, isEmpty, space)
import qualified Text.PrettyPrint.HughesPJ as D

-- Bodies --

multiBody :: (RC.BodyElim r, Monad r) => [MS (r Body)] -> MS (r Doc)
multiBody :: forall (r :: * -> *).
(BodyElim r, Monad r) =>
[MS (r Body)] -> MS (r Body)
multiBody [MS (r Body)]
bs = ([Body] -> r Body) -> [State MethodState Body] -> MS (r Body)
forall a b s. ([a] -> b) -> [State s a] -> State s b
onStateList (Body -> r Body
forall (r :: * -> *) a. Monad r => a -> r a
toCode (Body -> r Body) -> ([Body] -> Body) -> [Body] -> r Body
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Body] -> Body
vibcat) ([State MethodState Body] -> MS (r Body))
-> [State MethodState Body] -> MS (r Body)
forall a b. (a -> b) -> a -> b
$ (MS (r Body) -> State MethodState Body)
-> [MS (r Body)] -> [State MethodState Body]
forall a b. (a -> b) -> [a] -> [b]
map ((r Body -> Body) -> MS (r Body) -> State MethodState Body
forall a b s. (a -> b) -> State s a -> State s b
onStateValue r Body -> Body
forall (r :: * -> *). BodyElim r => r Body -> Body
RC.body) [MS (r Body)]
bs

-- Blocks --

block
  :: (Monad r, RenderStatement r smt, StatementElim r smt)
  => [MS (r smt)] -> MS (r Doc)
block :: forall (r :: * -> *) smt.
(Monad r, RenderStatement r smt, StatementElim r smt) =>
[MS (r smt)] -> MS (r Body)
block [MS (r smt)]
sts = ([r smt] -> r Body) -> [MS (r smt)] -> State MethodState (r Body)
forall a b s. ([a] -> b) -> [State s a] -> State s b
onStateList (Body -> r Body
forall (r :: * -> *) a. Monad r => a -> r a
toCode (Body -> r Body) -> ([r smt] -> Body) -> [r smt] -> r Body
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Body] -> Body
R.block ([Body] -> Body) -> ([r smt] -> [Body]) -> [r smt] -> Body
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (r smt -> Body) -> [r smt] -> [Body]
forall a b. (a -> b) -> [a] -> [b]
map r smt -> Body
forall (r :: * -> *) smt. StatementElim r smt => r smt -> Body
RC.statement) ((MS (r smt) -> MS (r smt)) -> [MS (r smt)] -> [MS (r smt)]
forall a b. (a -> b) -> [a] -> [b]
map MS (r smt) -> MS (r smt)
forall (r :: * -> *) smt.
RenderStatement r smt =>
MS (r smt) -> MS (r smt)
RC.stmt [MS (r smt)]
sts)

multiBlock :: (RC.BlockElim r, Monad r) => [MS (r Block)] -> MS (r Doc)
multiBlock :: forall (r :: * -> *).
(BlockElim r, Monad r) =>
[MS (r Body)] -> MS (r Body)
multiBlock [MS (r Body)]
bs = ([Body] -> r Body) -> [State MethodState Body] -> MS (r Body)
forall a b s. ([a] -> b) -> [State s a] -> State s b
onStateList (Body -> r Body
forall (r :: * -> *) a. Monad r => a -> r a
toCode (Body -> r Body) -> ([Body] -> Body) -> [Body] -> r Body
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Body] -> Body
vibcat) ([State MethodState Body] -> MS (r Body))
-> [State MethodState Body] -> MS (r Body)
forall a b. (a -> b) -> a -> b
$ (MS (r Body) -> State MethodState Body)
-> [MS (r Body)] -> [State MethodState Body]
forall a b. (a -> b) -> [a] -> [b]
map ((r Body -> Body) -> MS (r Body) -> State MethodState Body
forall a b s. (a -> b) -> State s a -> State s b
onStateValue r Body -> Body
forall (r :: * -> *). BlockElim r => r Body -> Body
RC.block) [MS (r Body)]
bs

-- Types --

obj :: (Monad r) => ClassName -> VS (r TypeData)
obj :: forall (r :: * -> *). Monad r => ClassName -> VS (r TypeData)
obj ClassName
n = CodeType -> ClassName -> Body -> VS (r TypeData)
forall (r :: * -> *).
Monad r =>
CodeType -> ClassName -> Body -> VS (r TypeData)
typeFromData (ClassName -> CodeType
Object ClassName
n) ClassName
n (ClassName -> Body
text ClassName
n)

-- Unary Operators --

negateOp :: (Monad r) => VSOp r
negateOp :: forall (r :: * -> *). Monad r => VSOp r
negateOp = ClassName -> VSOp r
forall (r :: * -> *). Monad r => ClassName -> VSOp r
unOpPrec ClassName
"-"

csc :: (IC.Literal r, IC.NumericExpression r, TypeElim r) => SValue r -> SValue r
csc :: forall (r :: * -> *).
(Literal r, NumericExpression r, TypeElim r) =>
SValue r -> SValue r
csc SValue r
v = VS (r TypeData) -> SValue r
forall (r :: * -> *).
(Literal r, TypeElim r) =>
VS (r TypeData) -> SValue r
valOfOne ((r Value -> r TypeData) -> SValue r -> VS (r TypeData)
forall a b.
(a -> b)
-> StateT ValueState Identity a -> StateT ValueState Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap r Value -> r TypeData
forall (r :: * -> *). ValueSym r => r Value -> r TypeData
valueType SValue r
v) SValue r -> SValue r -> SValue r
forall (r :: * -> *).
NumericExpression r =>
SValue r -> SValue r -> SValue r
#/ SValue r -> SValue r
forall (r :: * -> *). NumericExpression r => SValue r -> SValue r
sin SValue r
v

sec :: (IC.Literal r, IC.NumericExpression r, TypeElim r) => SValue r -> SValue r
sec :: forall (r :: * -> *).
(Literal r, NumericExpression r, TypeElim r) =>
SValue r -> SValue r
sec SValue r
v = VS (r TypeData) -> SValue r
forall (r :: * -> *).
(Literal r, TypeElim r) =>
VS (r TypeData) -> SValue r
valOfOne ((r Value -> r TypeData) -> SValue r -> VS (r TypeData)
forall a b.
(a -> b)
-> StateT ValueState Identity a -> StateT ValueState Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap r Value -> r TypeData
forall (r :: * -> *). ValueSym r => r Value -> r TypeData
valueType SValue r
v) SValue r -> SValue r -> SValue r
forall (r :: * -> *).
NumericExpression r =>
SValue r -> SValue r -> SValue r
#/ SValue r -> SValue r
forall (r :: * -> *). NumericExpression r => SValue r -> SValue r
cos SValue r
v

cot :: (IC.Literal r, IC.NumericExpression r, TypeElim r) => SValue r -> SValue r
cot :: forall (r :: * -> *).
(Literal r, NumericExpression r, TypeElim r) =>
SValue r -> SValue r
cot SValue r
v = VS (r TypeData) -> SValue r
forall (r :: * -> *).
(Literal r, TypeElim r) =>
VS (r TypeData) -> SValue r
valOfOne ((r Value -> r TypeData) -> SValue r -> VS (r TypeData)
forall a b.
(a -> b)
-> StateT ValueState Identity a -> StateT ValueState Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap r Value -> r TypeData
forall (r :: * -> *). ValueSym r => r Value -> r TypeData
valueType SValue r
v) SValue r -> SValue r -> SValue r
forall (r :: * -> *).
NumericExpression r =>
SValue r -> SValue r -> SValue r
#/ SValue r -> SValue r
forall (r :: * -> *). NumericExpression r => SValue r -> SValue r
tan SValue r
v

valOfOne :: (IC.Literal r, TypeElim r) => VS (r TypeData) -> SValue r
valOfOne :: forall (r :: * -> *).
(Literal r, TypeElim r) =>
VS (r TypeData) -> SValue r
valOfOne VS (r TypeData)
t = VS (r TypeData)
t VS (r TypeData)
-> (r TypeData -> StateT ValueState Identity (r Value))
-> StateT ValueState Identity (r Value)
forall a b.
StateT ValueState Identity a
-> (a -> StateT ValueState Identity b)
-> StateT ValueState Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (CodeType -> StateT ValueState Identity (r Value)
forall {r :: * -> *}. Literal r => CodeType -> SValue r
getVal (CodeType -> StateT ValueState Identity (r Value))
-> (r TypeData -> CodeType)
-> r TypeData
-> StateT ValueState Identity (r Value)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. r TypeData -> CodeType
forall (r :: * -> *). TypeElim r => r TypeData -> CodeType
getCodeType)
  where getVal :: CodeType -> SValue r
getVal CodeType
Float = Float -> SValue r
forall (r :: * -> *). Literal r => Float -> SValue r
IC.litFloat Float
1.0
        getVal CodeType
_ = Double -> SValue r
forall (r :: * -> *). Literal r => Double -> SValue r
IC.litDouble Double
1.0

-- Binary Operators --

smartAdd
  :: (IC.Literal r, IC.NumericExpression r, RenderValue r, ValueElim r)
  => SValue r -> SValue r -> SValue r
smartAdd :: forall (r :: * -> *).
(Literal r, NumericExpression r, RenderValue r, ValueElim r) =>
SValue r -> SValue r -> SValue r
smartAdd SValue r
v1 SValue r
v2 = do
  r Value
v1' <- SValue r
v1
  r Value
v2' <- SValue r
v2
  case (r Value -> Maybe Integer
forall (r :: * -> *). ValueElim r => r Value -> Maybe Integer
RC.valueInt r Value
v1', r Value -> Maybe Integer
forall (r :: * -> *). ValueElim r => r Value -> Maybe Integer
RC.valueInt r Value
v2') of
    (Just Integer
i1, Just Integer
i2) -> Integer -> SValue r
forall (r :: * -> *).
(RenderValue r, TypeSym r) =>
Integer -> SValue r
litInt (Integer
i1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
i2)
    (Maybe Integer, Maybe Integer)
_                  -> SValue r
v1 SValue r -> SValue r -> SValue r
forall (r :: * -> *).
NumericExpression r =>
SValue r -> SValue r -> SValue r
#+ SValue r
v2

smartSub
  :: (IC.Literal r, IC.NumericExpression r, RenderValue r, ValueElim r)
  => SValue r -> SValue r -> SValue r
smartSub :: forall (r :: * -> *).
(Literal r, NumericExpression r, RenderValue r, ValueElim r) =>
SValue r -> SValue r -> SValue r
smartSub SValue r
v1 SValue r
v2 = do
  r Value
v1' <- SValue r
v1
  r Value
v2' <- SValue r
v2
  case (r Value -> Maybe Integer
forall (r :: * -> *). ValueElim r => r Value -> Maybe Integer
RC.valueInt r Value
v1', r Value -> Maybe Integer
forall (r :: * -> *). ValueElim r => r Value -> Maybe Integer
RC.valueInt r Value
v2') of
    (Just Integer
i1, Just Integer
i2) -> Integer -> SValue r
forall (r :: * -> *).
(RenderValue r, TypeSym r) =>
Integer -> SValue r
litInt (Integer
i1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
i2)
    (Maybe Integer, Maybe Integer)
_                  -> SValue r
v1 SValue r -> SValue r -> SValue r
forall (r :: * -> *).
NumericExpression r =>
SValue r -> SValue r -> SValue r
#- SValue r
v2

equalOp :: (Monad r) => VSOp r
equalOp :: forall (r :: * -> *). Monad r => VSOp r
equalOp = ClassName -> VSOp r
forall (r :: * -> *). Monad r => ClassName -> VSOp r
compEqualPrec ClassName
"=="

notEqualOp :: (Monad r) => VSOp r
notEqualOp :: forall (r :: * -> *). Monad r => VSOp r
notEqualOp = ClassName -> VSOp r
forall (r :: * -> *). Monad r => ClassName -> VSOp r
compEqualPrec ClassName
"!="

greaterOp :: (Monad r) => VSOp r
greaterOp :: forall (r :: * -> *). Monad r => VSOp r
greaterOp = ClassName -> VSOp r
forall (r :: * -> *). Monad r => ClassName -> VSOp r
compPrec ClassName
">"

greaterEqualOp :: (Monad r) => VSOp r
greaterEqualOp :: forall (r :: * -> *). Monad r => VSOp r
greaterEqualOp = ClassName -> VSOp r
forall (r :: * -> *). Monad r => ClassName -> VSOp r
compPrec ClassName
">="

lessOp :: (Monad r) => VSOp r
lessOp :: forall (r :: * -> *). Monad r => VSOp r
lessOp = ClassName -> VSOp r
forall (r :: * -> *). Monad r => ClassName -> VSOp r
compPrec ClassName
"<"

lessEqualOp :: (Monad r) => VSOp r
lessEqualOp :: forall (r :: * -> *). Monad r => VSOp r
lessEqualOp = ClassName -> VSOp r
forall (r :: * -> *). Monad r => ClassName -> VSOp r
compPrec ClassName
"<="

plusOp :: (Monad r) => VSOp r
plusOp :: forall (r :: * -> *). Monad r => VSOp r
plusOp = ClassName -> VSOp r
forall (r :: * -> *). Monad r => ClassName -> VSOp r
addPrec ClassName
"+"

minusOp :: (Monad r) => VSOp r
minusOp :: forall (r :: * -> *). Monad r => VSOp r
minusOp = ClassName -> VSOp r
forall (r :: * -> *). Monad r => ClassName -> VSOp r
addPrec ClassName
"-"

multOp :: (Monad r) => VSOp r
multOp :: forall (r :: * -> *). Monad r => VSOp r
multOp = ClassName -> VSOp r
forall (r :: * -> *). Monad r => ClassName -> VSOp r
multPrec ClassName
"*"

divideOp :: (Monad r) => VSOp r
divideOp :: forall (r :: * -> *). Monad r => VSOp r
divideOp = ClassName -> VSOp r
forall (r :: * -> *). Monad r => ClassName -> VSOp r
multPrec ClassName
"/"

moduloOp :: (Monad r) => VSOp r
moduloOp :: forall (r :: * -> *). Monad r => VSOp r
moduloOp = ClassName -> VSOp r
forall (r :: * -> *). Monad r => ClassName -> VSOp r
multPrec ClassName
"%"

-- Variables --

var :: (RenderVariable r) => Label -> VS (r TypeData) -> SVariable r
var :: forall (r :: * -> *).
RenderVariable r =>
ClassName -> VS (r TypeData) -> SVariable r
var ClassName
n VS (r TypeData)
t = ClassName -> VS (r TypeData) -> Body -> SVariable r
forall (r :: * -> *).
RenderVariable r =>
ClassName -> VS (r TypeData) -> Body -> SVariable r
mkStateVar ClassName
n VS (r TypeData)
t (ClassName -> Body
R.var ClassName
n)

classVar :: (RenderVariable r) => Label -> VS (r TypeData) -> SVariable r
classVar :: forall (r :: * -> *).
RenderVariable r =>
ClassName -> VS (r TypeData) -> SVariable r
classVar ClassName
n VS (r TypeData)
t = ClassName -> VS (r TypeData) -> Body -> SVariable r
forall (r :: * -> *).
RenderVariable r =>
ClassName -> VS (r TypeData) -> Body -> SVariable r
mkClassVar ClassName
n VS (r TypeData)
t (ClassName -> Body
R.var ClassName
n)

-- | To be used in classVarAccess implementations. Throws an error if the variable is
-- not class-level since classVarAccess is for accessing class-level variables from a class
classVarAccessCheck :: (InternalVarElim r) => r Variable -> r Variable
classVarAccessCheck :: forall (r :: * -> *). InternalVarElim r => r Variable -> r Variable
classVarAccessCheck r Variable
v = AttachmentTag -> r Variable
classVarCS (r Variable -> AttachmentTag
forall (r :: * -> *).
InternalVarElim r =>
r Variable -> AttachmentTag
variableBind r Variable
v)
  where classVarCS :: AttachmentTag -> r Variable
classVarCS AttachmentTag
InstanceLevel = ClassName -> r Variable
forall a. HasCallStack => ClassName -> a
error
          ClassName
"classVarAccess can only be used to access class-level variables"
        classVarCS AttachmentTag
ClassLevel = r Variable
v

instanceVarAccess
  :: (InternalVarElim r, RenderVariable r, ValueElim r, VariableElim r)
  => SValue r -> SVariable r -> SVariable r
instanceVarAccess :: forall (r :: * -> *).
(InternalVarElim r, RenderVariable r, ValueElim r,
 VariableElim r) =>
SValue r -> SVariable r -> SVariable r
instanceVarAccess SValue r
o' SVariable r
v' = do
  r Value
o <- SValue r
o'
  r Variable
v <- SVariable r
v'
  let instanceVarAccess' :: AttachmentTag -> SVariable r
instanceVarAccess' AttachmentTag
ClassLevel = ClassName -> SVariable r
forall a. HasCallStack => ClassName -> a
error
        ClassName
"Cannot access class-level variables through an object, use classVarAccess instead"
      instanceVarAccess' AttachmentTag
InstanceLevel = ClassName -> r TypeData -> Body -> SVariable r
forall (r :: * -> *).
RenderVariable r =>
ClassName -> r TypeData -> Body -> SVariable r
mkVar (Body -> ClassName
render (r Value -> Body
forall (r :: * -> *). ValueElim r => r Value -> Body
value r Value
o) ClassName -> ClassName -> ClassName
`access` r Variable -> ClassName
forall (r :: * -> *). VariableElim r => r Variable -> ClassName
variableName r Variable
v)
        (r Variable -> r TypeData
forall (r :: * -> *). VariableElim r => r Variable -> r TypeData
variableType r Variable
v) (Body -> Body -> Body
R.instanceVarAccess (r Value -> Body
forall (r :: * -> *). ValueElim r => r Value -> Body
RC.value r Value
o) (r Variable -> Body
forall (r :: * -> *). InternalVarElim r => r Variable -> Body
RC.variable r Variable
v))
  AttachmentTag -> SVariable r
instanceVarAccess' (r Variable -> AttachmentTag
forall (r :: * -> *).
InternalVarElim r =>
r Variable -> AttachmentTag
variableBind r Variable
v)

arrayElem
  :: (IC.IndexTranslator r, RenderVariable r, ValueElim r)
  => SValue r -> SValue r -> SVariable r
arrayElem :: forall (r :: * -> *).
(IndexTranslator r, RenderVariable r, ValueElim r) =>
SValue r -> SValue r -> SVariable r
arrayElem SValue r
arr' SValue r
i' = do
  r Value
i <- SValue r -> SValue r
forall (r :: * -> *). IndexTranslator r => SValue r -> SValue r
IC.intToIndex SValue r
i'
  r Value
arr <- SValue r
arr'
  let vName :: ClassName
vName = Body -> ClassName
render (r Value -> Body
forall (r :: * -> *). ValueElim r => r Value -> Body
RC.value r Value
arr) ClassName -> ClassName -> ClassName
forall a. [a] -> [a] -> [a]
++ ClassName
"[" ClassName -> ClassName -> ClassName
forall a. [a] -> [a] -> [a]
++ Body -> ClassName
render (r Value -> Body
forall (r :: * -> *). ValueElim r => r Value -> Body
RC.value r Value
i) ClassName -> ClassName -> ClassName
forall a. [a] -> [a] -> [a]
++ ClassName
"]"
      vType :: VS (r TypeData)
vType = VS (r TypeData) -> VS (r TypeData)
forall (r :: * -> *).
TypeSym r =>
VS (r TypeData) -> VS (r TypeData)
IC.innerType (VS (r TypeData) -> VS (r TypeData))
-> VS (r TypeData) -> VS (r TypeData)
forall a b. (a -> b) -> a -> b
$ r TypeData -> VS (r TypeData)
forall a. a -> StateT ValueState Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (r TypeData -> VS (r TypeData)) -> r TypeData -> VS (r TypeData)
forall a b. (a -> b) -> a -> b
$ r Value -> r TypeData
forall (r :: * -> *). ValueSym r => r Value -> r TypeData
valueType r Value
arr
      vRender :: Body
vRender = r Value -> Body
forall (r :: * -> *). ValueElim r => r Value -> Body
RC.value r Value
arr Body -> Body -> Body
<> Body -> Body
brackets (r Value -> Body
forall (r :: * -> *). ValueElim r => r Value -> Body
RC.value r Value
i)
  ClassName -> VS (r TypeData) -> Body -> SVariable r
forall (r :: * -> *).
RenderVariable r =>
ClassName -> VS (r TypeData) -> Body -> SVariable r
mkStateVar ClassName
vName VS (r TypeData)
vType Body
vRender

-- Scope --
local :: (Monad r) => r ScopeData
local :: forall (r :: * -> *). Monad r => r ScopeData
local = ScopeData -> r ScopeData
forall (r :: * -> *) a. Monad r => a -> r a
toCode (ScopeData -> r ScopeData) -> ScopeData -> r ScopeData
forall a b. (a -> b) -> a -> b
$ ScopeTag -> ScopeData
sd ScopeTag
Local

-- Values --

litChar :: (RenderValue r, IC.TypeSym r) => (Doc -> Doc) -> Char -> SValue r
litChar :: forall (r :: * -> *).
(RenderValue r, TypeSym r) =>
(Body -> Body) -> Char -> SValue r
litChar Body -> Body
f Char
c = VS (r TypeData) -> Body -> SValue r
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Body -> SValue r
mkStateVal VS (r TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
IC.char (Body -> Body
f (Body -> Body) -> Body -> Body
forall a b. (a -> b) -> a -> b
$ if Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n' then ClassName -> Body
text ClassName
"\\n" else Char -> Body
D.char Char
c)

litDouble :: (RenderValue r, IC.TypeSym r) => Double -> SValue r
litDouble :: forall (r :: * -> *).
(RenderValue r, TypeSym r) =>
Double -> SValue r
litDouble Double
d = VS (r TypeData) -> Body -> SValue r
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Body -> SValue r
mkStateVal VS (r TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
IC.double (Double -> Body
D.double Double
d)

litInt :: (RenderValue r, IC.TypeSym r) => Integer -> SValue r
litInt :: forall (r :: * -> *).
(RenderValue r, TypeSym r) =>
Integer -> SValue r
litInt Integer
i = Maybe Int -> Maybe Integer -> VS (r TypeData) -> Body -> SValue r
forall (r :: * -> *).
RenderValue r =>
Maybe Int -> Maybe Integer -> VS (r TypeData) -> Body -> SValue r
valFromData Maybe Int
forall a. Maybe a
Nothing (Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
i) VS (r TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
IC.int (Integer -> Body
integer Integer
i)

litString :: (RenderValue r, IC.TypeSym r) => String -> SValue r
litString :: forall (r :: * -> *).
(RenderValue r, TypeSym r) =>
ClassName -> SValue r
litString ClassName
s = VS (r TypeData) -> Body -> SValue r
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Body -> SValue r
mkStateVal VS (r TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
IC.string (ClassName -> Body
doubleQuotedText ClassName
s)

valueOf
  :: (InternalVarElim r, RenderValue r, VariableElim r)
  => SVariable r -> SValue r
valueOf :: forall (r :: * -> *).
(InternalVarElim r, RenderValue r, VariableElim r) =>
SVariable r -> SValue r
valueOf SVariable r
v' = do
  r Variable
v <- SVariable r
v'
  r TypeData -> Body -> SValue r
forall (r :: * -> *).
RenderValue r =>
r TypeData -> Body -> SValue r
mkVal (r Variable -> r TypeData
forall (r :: * -> *). VariableElim r => r Variable -> r TypeData
variableType r Variable
v) (r Variable -> Body
forall (r :: * -> *). InternalVarElim r => r Variable -> Body
RC.variable r Variable
v)

arg
  :: (RenderValue r, IC.TypeSym r, ValueElim r)
  => SValue r -> SValue r -> SValue r
arg :: forall (r :: * -> *).
(RenderValue r, TypeSym r, ValueElim r) =>
SValue r -> SValue r -> SValue r
arg SValue r
n' SValue r
args' = do
  r Value
n <- SValue r
n'
  r Value
args <- SValue r
args'
  r TypeData
s <- VS (r TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
IC.string
  r TypeData -> Body -> SValue r
forall (r :: * -> *).
RenderValue r =>
r TypeData -> Body -> SValue r
mkVal r TypeData
s (r Value -> r Value -> Body
forall (r :: * -> *). ValueElim r => r Value -> r Value -> Body
R.arg r Value
n r Value
args)

argsList :: (RenderValue r, IC.TypeSym r) => String -> SValue r
argsList :: forall (r :: * -> *).
(RenderValue r, TypeSym r) =>
ClassName -> SValue r
argsList ClassName
l = VS (r TypeData) -> Body -> SValue r
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Body -> SValue r
mkStateVal (VS (r TypeData) -> VS (r TypeData)
forall (r :: * -> *).
TypeSym r =>
VS (r TypeData) -> VS (r TypeData)
IC.arrayType VS (r TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
IC.string) (ClassName -> Body
text ClassName
l)

-- | First parameter is separator between name and value for named arguments,
-- rest similar to call from RendererClasses
call
  :: (InternalVarElim r, RenderValue r, ValueElim r)
  => Doc -> Maybe Library -> Maybe Doc -> MixedCall r
call :: forall (r :: * -> *).
(InternalVarElim r, RenderValue r, ValueElim r) =>
Body -> Maybe ClassName -> Maybe Body -> MixedCall r
call Body
sep Maybe ClassName
lib Maybe Body
o ClassName
n VS (r TypeData)
t [SValue r]
pas NamedArgs r
nas = do
  [r Value]
pargs <- [SValue r] -> StateT ValueState Identity [r Value]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence [SValue r]
pas
  [r Variable]
nms <- ((StateT ValueState Identity (r Variable), SValue r)
 -> StateT ValueState Identity (r Variable))
-> NamedArgs r -> StateT ValueState Identity [r Variable]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (StateT ValueState Identity (r Variable), SValue r)
-> StateT ValueState Identity (r Variable)
forall a b. (a, b) -> a
fst NamedArgs r
nas
  [r Value]
nargs <- ((StateT ValueState Identity (r Variable), SValue r) -> SValue r)
-> NamedArgs r -> StateT ValueState Identity [r Value]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (StateT ValueState Identity (r Variable), SValue r) -> SValue r
forall a b. (a, b) -> b
snd NamedArgs r
nas
  let libDoc :: Body
libDoc = Body -> (ClassName -> Body) -> Maybe ClassName -> Body
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (ClassName -> Body
text ClassName
n) (ClassName -> Body
text (ClassName -> Body)
-> (ClassName -> ClassName) -> ClassName -> Body
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ClassName -> ClassName -> ClassName
`access` ClassName
n)) Maybe ClassName
lib
      obDoc :: Body
obDoc = Body -> Maybe Body -> Body
forall a. a -> Maybe a -> a
fromMaybe Body
empty Maybe Body
o
  VS (r TypeData) -> Body -> SValue r
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Body -> SValue r
mkStateVal VS (r TypeData)
t (Body -> SValue r) -> Body -> SValue r
forall a b. (a -> b) -> a -> b
$ Body
obDoc Body -> Body -> Body
<> Body
libDoc Body -> Body -> Body
<> Body -> Body
parens ([r Value] -> Body
forall (r :: * -> *). ValueElim r => [r Value] -> Body
valueList [r Value]
pargs Body -> Body -> Body
<>
    (if [SValue r] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [SValue r]
pas Bool -> Bool -> Bool
|| NamedArgs r -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null NamedArgs r
nas then Body
empty else Body
comma) Body -> Body -> Body
<+> Body -> [(r Variable, r Value)] -> Body
forall (r :: * -> *).
(InternalVarElim r, ValueElim r) =>
Body -> [(r Variable, r Value)] -> Body
namedArgList Body
sep
    ([r Variable] -> [r Value] -> [(r Variable, r Value)]
forall a b. [a] -> [b] -> [(a, b)]
zip [r Variable]
nms [r Value]
nargs))

funcAppMixedArgs :: (RenderValue r) => MixedCall r
funcAppMixedArgs :: forall (r :: * -> *). RenderValue r => MixedCall r
funcAppMixedArgs = Maybe ClassName -> Maybe Body -> MixedCall r
forall (r :: * -> *).
RenderValue r =>
Maybe ClassName -> Maybe Body -> MixedCall r
RC.call Maybe ClassName
forall a. Maybe a
Nothing Maybe Body
forall a. Maybe a
Nothing

newObjMixedArgs
  :: (RenderValue r, UnRepr r TypeData)
  => String -> MixedCtorCall r
newObjMixedArgs :: forall (r :: * -> *).
(RenderValue r, UnRepr r TypeData) =>
ClassName -> MixedCtorCall r
newObjMixedArgs ClassName
s VS (r TypeData)
tp [SValue r]
vs NamedArgs r
ns = do
  r TypeData
t <- VS (r TypeData)
tp
  Maybe ClassName -> Maybe Body -> MixedCall r
forall (r :: * -> *).
RenderValue r =>
Maybe ClassName -> Maybe Body -> MixedCall r
RC.call Maybe ClassName
forall a. Maybe a
Nothing Maybe Body
forall a. Maybe a
Nothing (ClassName
s ClassName -> ClassName -> ClassName
forall a. [a] -> [a] -> [a]
++ r TypeData -> ClassName
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> ClassName
getTypeString r TypeData
t) (r TypeData -> VS (r TypeData)
forall a. a -> StateT ValueState Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return r TypeData
t) [SValue r]
vs NamedArgs r
ns

lambda
  :: (BinderElim r, RenderValue r, ValueSym r)
  => ([r BinderD] -> r Value -> Doc) -> [VSBinder r] -> SValue r -> SValue r
lambda :: forall (r :: * -> *).
(BinderElim r, RenderValue r, ValueSym r) =>
([r BinderD] -> r Value -> Body)
-> [VSBinder r] -> SValue r -> SValue r
lambda [r BinderD] -> r Value -> Body
f [VSBinder r]
ps' SValue r
ex' = do
  [r BinderD]
ps <- [VSBinder r] -> StateT ValueState Identity [r BinderD]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence [VSBinder r]
ps'
  r Value
ex <- SValue r
ex'
  let ft :: VS (r TypeData)
ft = [VS (r TypeData)] -> VS (r TypeData) -> VS (r TypeData)
forall (r :: * -> *).
TypeSym r =>
[VS (r TypeData)] -> VS (r TypeData) -> VS (r TypeData)
IC.funcType ((r BinderD -> VS (r TypeData)) -> [r BinderD] -> [VS (r TypeData)]
forall a b. (a -> b) -> [a] -> [b]
map (r TypeData -> VS (r TypeData)
forall a. a -> StateT ValueState Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (r TypeData -> VS (r TypeData))
-> (r BinderD -> r TypeData) -> r BinderD -> VS (r TypeData)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. r BinderD -> r TypeData
forall (r :: * -> *). BinderElim r => r BinderD -> r TypeData
binderType) [r BinderD]
ps) (r TypeData -> VS (r TypeData)
forall a. a -> StateT ValueState Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (r TypeData -> VS (r TypeData)) -> r TypeData -> VS (r TypeData)
forall a b. (a -> b) -> a -> b
$ r Value -> r TypeData
forall (r :: * -> *). ValueSym r => r Value -> r TypeData
valueType r Value
ex)
  Maybe Int -> Maybe Integer -> VS (r TypeData) -> Body -> SValue r
forall (r :: * -> *).
RenderValue r =>
Maybe Int -> Maybe Integer -> VS (r TypeData) -> Body -> SValue r
valFromData (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
0) Maybe Integer
forall a. Maybe a
Nothing VS (r TypeData)
ft ([r BinderD] -> r Value -> Body
f [r BinderD]
ps r Value
ex)

objAccess
  :: (FunctionElim r, RenderValue r, ValueElim r)
  => SValue r -> VS (r FuncData) -> SValue r
objAccess :: forall (r :: * -> *).
(FunctionElim r, RenderValue r, ValueElim r) =>
SValue r -> VS (r FuncData) -> SValue r
objAccess = (r Value -> r FuncData -> StateT ValueState Identity (r Value))
-> StateT ValueState Identity (r Value)
-> StateT ValueState Identity (r FuncData)
-> StateT ValueState Identity (r Value)
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> m c) -> m a -> m b -> m c
on2StateWrapped (\r Value
v r FuncData
f-> r TypeData -> Body -> StateT ValueState Identity (r Value)
forall (r :: * -> *).
RenderValue r =>
r TypeData -> Body -> SValue r
mkVal (r FuncData -> r TypeData
forall (r :: * -> *). FunctionElim r => r FuncData -> r TypeData
functionType r FuncData
f)
  (Body -> Body -> Body
R.objAccess (r Value -> Body
forall (r :: * -> *). ValueElim r => r Value -> Body
RC.value r Value
v) (r FuncData -> Body
forall (r :: * -> *). FunctionElim r => r FuncData -> Body
RC.function r FuncData
f)))

objMethodCall
  :: (RenderValue r, ValueElim r)
  => Label -> VS (r TypeData) -> SValue r -> [SValue r] -> NamedArgs r -> SValue r
objMethodCall :: forall (r :: * -> *).
(RenderValue r, ValueElim r) =>
ClassName
-> VS (r TypeData)
-> SValue r
-> [SValue r]
-> NamedArgs r
-> SValue r
objMethodCall ClassName
f VS (r TypeData)
t SValue r
ob [SValue r]
vs NamedArgs r
ns = SValue r
ob SValue r -> (r Value -> SValue r) -> SValue r
forall a b.
StateT ValueState Identity a
-> (a -> StateT ValueState Identity b)
-> StateT ValueState Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (\r Value
o -> Maybe ClassName -> Maybe Body -> MixedCall r
forall (r :: * -> *).
RenderValue r =>
Maybe ClassName -> Maybe Body -> MixedCall r
RC.call Maybe ClassName
forall a. Maybe a
Nothing
  (Body -> Maybe Body
forall a. a -> Maybe a
Just (Body -> Maybe Body) -> Body -> Maybe Body
forall a b. (a -> b) -> a -> b
$ r Value -> Body
forall (r :: * -> *). ValueElim r => r Value -> Body
RC.value r Value
o Body -> Body -> Body
<> Body
dot) ClassName
f VS (r TypeData)
t [SValue r]
vs NamedArgs r
ns)

-- Functions --

func
  :: (RenderFunction r, ValueElim r, ValueExpression r)
  => Label -> VS (r TypeData) -> [SValue r] -> VS (r FuncData)
func :: forall (r :: * -> *).
(RenderFunction r, ValueElim r, ValueExpression r) =>
ClassName -> VS (r TypeData) -> [SValue r] -> VS (r FuncData)
func ClassName
l VS (r TypeData)
t [SValue r]
vs = PosCall r
forall (r :: * -> *). ValueExpression r => PosCall r
funcApp ClassName
l VS (r TypeData)
t [SValue r]
vs SValue r
-> (r Value -> StateT ValueState Identity (r FuncData))
-> StateT ValueState Identity (r FuncData)
forall a b.
StateT ValueState Identity a
-> (a -> StateT ValueState Identity b)
-> StateT ValueState Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ((Body -> VS (r TypeData) -> StateT ValueState Identity (r FuncData)
forall (r :: * -> *).
RenderFunction r =>
Body -> VS (r TypeData) -> VS (r FuncData)
`funcFromData` VS (r TypeData)
t) (Body -> StateT ValueState Identity (r FuncData))
-> (r Value -> Body)
-> r Value
-> StateT ValueState Identity (r FuncData)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Body -> Body
R.func (Body -> Body) -> (r Value -> Body) -> r Value -> Body
forall b c a. (b -> c) -> (a -> b) -> a -> c
. r Value -> Body
forall (r :: * -> *). ValueElim r => r Value -> Body
RC.value)

get
  :: (RO.InternalGetSet r, IG.OOFunctionSym r)
  => SValue r -> SVariable r -> SValue r
get :: forall (r :: * -> *).
(InternalGetSet r, OOFunctionSym r) =>
SValue r -> SVariable r -> SValue r
get SValue r
v SVariable r
vToGet = SValue r
v SValue r -> VS (r FuncData) -> SValue r
forall (r :: * -> *).
OOFunctionSym r =>
SValue r -> VS (r FuncData) -> SValue r
$. SVariable r -> VS (r FuncData)
forall (r :: * -> *).
InternalGetSet r =>
SVariable r -> VS (r FuncData)
RO.getFunc SVariable r
vToGet

set :: (RO.InternalGetSet r, IG.OOFunctionSym r) => SValue r -> SVariable r -> SValue r -> SValue r
set :: forall (r :: * -> *).
(InternalGetSet r, OOFunctionSym r) =>
SValue r -> SVariable r -> SValue r -> SValue r
set SValue r
v SVariable r
vToSet SValue r
toVal = SValue r
v SValue r -> VS (r FuncData) -> SValue r
forall (r :: * -> *).
OOFunctionSym r =>
SValue r -> VS (r FuncData) -> SValue r
$. VS (r TypeData) -> SVariable r -> SValue r -> VS (r FuncData)
forall (r :: * -> *).
InternalGetSet r =>
VS (r TypeData) -> SVariable r -> SValue r -> VS (r FuncData)
RO.setFunc ((r Value -> r TypeData) -> SValue r -> VS (r TypeData)
forall a b s. (a -> b) -> State s a -> State s b
onStateValue r Value -> r TypeData
forall (r :: * -> *). ValueSym r => r Value -> r TypeData
valueType SValue r
v) SVariable r
vToSet SValue r
toVal

-- TODO [Brandon Bosman, 06/10/2026]: Figure out what to do with this
listAccess
  :: ( IC.IndexTranslator r
     , RC.InternalListFunc r
     , FunctionElim r
     , RenderFunction r
     , RenderValue r
     , TypeElim r
     , ValueElim r
     )
  => SValue r -> SValue r -> SValue r
listAccess :: forall (r :: * -> *).
(IndexTranslator r, InternalListFunc r, FunctionElim r,
 RenderFunction r, RenderValue r, TypeElim r, ValueElim r) =>
SValue r -> SValue r -> SValue r
listAccess SValue r
v SValue r
i = do
  r Value
v' <- SValue r
v
  let i' :: SValue r
i' = SValue r -> SValue r
forall (r :: * -> *). IndexTranslator r => SValue r -> SValue r
IC.intToIndex SValue r
i
      t :: VS (r TypeData)
t  = VS (r TypeData) -> VS (r TypeData)
forall (r :: * -> *).
TypeSym r =>
VS (r TypeData) -> VS (r TypeData)
IC.innerType (VS (r TypeData) -> VS (r TypeData))
-> VS (r TypeData) -> VS (r TypeData)
forall a b. (a -> b) -> a -> b
$ r TypeData -> VS (r TypeData)
forall a. a -> StateT ValueState Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (r TypeData -> VS (r TypeData)) -> r TypeData -> VS (r TypeData)
forall a b. (a -> b) -> a -> b
$ r Value -> r TypeData
forall (r :: * -> *). ValueSym r => r Value -> r TypeData
valueType r Value
v'
      checkType :: CodeType -> VS (r FuncData)
checkType (List CodeType
_) = VS (r TypeData) -> SValue r -> VS (r FuncData)
forall (r :: * -> *).
InternalListFunc r =>
VS (r TypeData) -> SValue r -> VS (r FuncData)
RC.listAccessFunc VS (r TypeData)
t SValue r
i'
      checkType (Set CodeType
_) = VS (r TypeData) -> SValue r -> VS (r FuncData)
forall (r :: * -> *).
InternalListFunc r =>
VS (r TypeData) -> SValue r -> VS (r FuncData)
RC.listAccessFunc VS (r TypeData)
t SValue r
i'
      checkType (Array CodeType
_) = SValue r
i' SValue r -> (r Value -> VS (r FuncData)) -> VS (r FuncData)
forall a b.
StateT ValueState Identity a
-> (a -> StateT ValueState Identity b)
-> StateT ValueState Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                              (\r Value
ix -> Body -> VS (r TypeData) -> VS (r FuncData)
forall (r :: * -> *).
RenderFunction r =>
Body -> VS (r TypeData) -> VS (r FuncData)
funcFromData (Body -> Body
brackets (r Value -> Body
forall (r :: * -> *). ValueElim r => r Value -> Body
RC.value r Value
ix)) VS (r TypeData)
t)
      checkType CodeType
_ = ClassName -> VS (r FuncData)
forall a. HasCallStack => ClassName -> a
error ClassName
"listAccess called on non-list-type value"
  r FuncData
f <- CodeType -> VS (r FuncData)
checkType (r TypeData -> CodeType
forall (r :: * -> *). TypeElim r => r TypeData -> CodeType
getCodeType (r Value -> r TypeData
forall (r :: * -> *). ValueSym r => r Value -> r TypeData
valueType r Value
v'))
  r TypeData -> Body -> SValue r
forall (r :: * -> *).
RenderValue r =>
r TypeData -> Body -> SValue r
mkVal (r FuncData -> r TypeData
forall (r :: * -> *). FunctionElim r => r FuncData -> r TypeData
RC.functionType r FuncData
f) (r Value -> Body
forall (r :: * -> *). ValueElim r => r Value -> Body
RC.value r Value
v' Body -> Body -> Body
<> r FuncData -> Body
forall (r :: * -> *). FunctionElim r => r FuncData -> Body
RC.function r FuncData
f)

getFunc
  :: (IG.OOFunctionSym r, VariableElim r)
  => SVariable r -> VS (r FuncData)
getFunc :: forall (r :: * -> *).
(OOFunctionSym r, VariableElim r) =>
SVariable r -> VS (r FuncData)
getFunc SVariable r
v = SVariable r
v SVariable r
-> (r Variable -> StateT ValueState Identity (r FuncData))
-> StateT ValueState Identity (r FuncData)
forall a b.
StateT ValueState Identity a
-> (a -> StateT ValueState Identity b)
-> StateT ValueState Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (\r Variable
vr -> ClassName
-> VS (r TypeData)
-> [SValue r]
-> StateT ValueState Identity (r FuncData)
forall (r :: * -> *).
OOFunctionSym r =>
ClassName -> VS (r TypeData) -> [SValue r] -> VS (r FuncData)
IG.func (ClassName -> ClassName
getterName (ClassName -> ClassName) -> ClassName -> ClassName
forall a b. (a -> b) -> a -> b
$ r Variable -> ClassName
forall (r :: * -> *). VariableElim r => r Variable -> ClassName
variableName r Variable
vr)
  (r TypeData -> VS (r TypeData)
forall a s. a -> State s a
toState (r TypeData -> VS (r TypeData)) -> r TypeData -> VS (r TypeData)
forall a b. (a -> b) -> a -> b
$ r Variable -> r TypeData
forall (r :: * -> *). VariableElim r => r Variable -> r TypeData
variableType r Variable
vr) [])

setFunc
  :: (IG.OOFunctionSym r, VariableElim r)
  => VS (r TypeData) -> SVariable r -> SValue r -> VS (r FuncData)
setFunc :: forall (r :: * -> *).
(OOFunctionSym r, VariableElim r) =>
VS (r TypeData) -> SVariable r -> SValue r -> VS (r FuncData)
setFunc VS (r TypeData)
t SVariable r
v SValue r
toVal = SVariable r
v SVariable r
-> (r Variable -> StateT ValueState Identity (r FuncData))
-> StateT ValueState Identity (r FuncData)
forall a b.
StateT ValueState Identity a
-> (a -> StateT ValueState Identity b)
-> StateT ValueState Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (\r Variable
vr -> ClassName
-> VS (r TypeData)
-> [SValue r]
-> StateT ValueState Identity (r FuncData)
forall (r :: * -> *).
OOFunctionSym r =>
ClassName -> VS (r TypeData) -> [SValue r] -> VS (r FuncData)
IG.func (ClassName -> ClassName
setterName (ClassName -> ClassName) -> ClassName -> ClassName
forall a b. (a -> b) -> a -> b
$ r Variable -> ClassName
forall (r :: * -> *). VariableElim r => r Variable -> ClassName
variableName r Variable
vr) VS (r TypeData)
t
  [SValue r
toVal])

-- Statements --

stmt
  :: (RenderStatement r smt, StatementElim r smt)
  => MS (r smt) -> MS (r smt)
stmt :: forall (r :: * -> *) smt.
(RenderStatement r smt, StatementElim r smt) =>
MS (r smt) -> MS (r smt)
stmt MS (r smt)
s' = do
  r smt
s <- MS (r smt)
s'
  Body -> MS (r smt)
forall (r :: * -> *) smt.
RenderStatement r smt =>
Body -> MS (r smt)
mkStmtNoEnd (r smt -> Body
forall (r :: * -> *) smt. StatementElim r smt => r smt -> Body
RC.statement r smt
s Body -> Body -> Body
<> Terminator -> Body
R.getTerm (r smt -> Terminator
forall (r :: * -> *) smt.
StatementElim r smt =>
r smt -> Terminator
statementTerm r smt
s))

loopStmt
  :: (RenderStatement r smt, StatementElim r smt)
  => MS (r smt) -> MS (r smt)
loopStmt :: forall (r :: * -> *) smt.
(RenderStatement r smt, StatementElim r smt) =>
MS (r smt) -> MS (r smt)
loopStmt = MS (r smt) -> MS (r smt)
forall (r :: * -> *) smt.
RenderStatement r smt =>
MS (r smt) -> MS (r smt)
RC.stmt (MS (r smt) -> MS (r smt))
-> (MS (r smt) -> MS (r smt)) -> MS (r smt) -> MS (r smt)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MS (r smt) -> MS (r smt)
forall (r :: * -> *) smt.
(RenderStatement r smt, StatementElim r smt) =>
MS (r smt) -> MS (r smt)
setEmpty

emptyStmt :: (RenderStatement r smt) => MS (r smt)
emptyStmt :: forall (r :: * -> *) smt. RenderStatement r smt => MS (r smt)
emptyStmt = Body -> MS (r smt)
forall (r :: * -> *) smt.
RenderStatement r smt =>
Body -> MS (r smt)
mkStmtNoEnd Body
empty

assign
  :: (InternalVarElim r, RenderStatement r smt, ValueElim r)
  => Terminator -> SVariable r -> SValue r -> MS (r smt)
assign :: forall (r :: * -> *) smt.
(InternalVarElim r, RenderStatement r smt, ValueElim r) =>
Terminator -> SVariable r -> SValue r -> MS (r smt)
assign Terminator
t SVariable r
vr' SValue r
v' = do
  r Variable
vr <- LensLike'
  (Zoomed (StateT ValueState Identity) (r Variable))
  MethodState
  ValueState
-> SVariable r -> StateT MethodState Identity (r Variable)
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))
  MethodState
  ValueState
(ValueState -> Focusing Identity (r Variable) ValueState)
-> MethodState -> Focusing Identity (r Variable) MethodState
Lens' MethodState ValueState
lensMStoVS SVariable r
vr'
  r Value
v <- LensLike'
  (Zoomed (StateT ValueState Identity) (r Value))
  MethodState
  ValueState
-> SValue r -> StateT MethodState Identity (r Value)
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))
  MethodState
  ValueState
(ValueState -> Focusing Identity (r Value) ValueState)
-> MethodState -> Focusing Identity (r Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue r
v'
  Body -> Terminator -> MS (r smt)
forall (r :: * -> *) smt.
RenderStatement r smt =>
Body -> Terminator -> MS (r smt)
stmtFromData (r Variable -> r Value -> Body
forall (r :: * -> *).
(InternalVarElim r, ValueElim r) =>
r Variable -> r Value -> Body
R.assign r Variable
vr r Value
v) Terminator
t

subAssign
  :: (InternalVarElim r, RenderStatement r smt, ValueElim r)
  => Terminator -> SVariable r -> SValue r -> MS (r smt)
subAssign :: forall (r :: * -> *) smt.
(InternalVarElim r, RenderStatement r smt, ValueElim r) =>
Terminator -> SVariable r -> SValue r -> MS (r smt)
subAssign Terminator
t SVariable r
vr' SValue r
v' = do
  r Variable
vr <- LensLike'
  (Zoomed (StateT ValueState Identity) (r Variable))
  MethodState
  ValueState
-> SVariable r -> StateT MethodState Identity (r Variable)
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))
  MethodState
  ValueState
(ValueState -> Focusing Identity (r Variable) ValueState)
-> MethodState -> Focusing Identity (r Variable) MethodState
Lens' MethodState ValueState
lensMStoVS SVariable r
vr'
  r Value
v <- LensLike'
  (Zoomed (StateT ValueState Identity) (r Value))
  MethodState
  ValueState
-> SValue r -> StateT MethodState Identity (r Value)
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))
  MethodState
  ValueState
(ValueState -> Focusing Identity (r Value) ValueState)
-> MethodState -> Focusing Identity (r Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue r
v'
  Body -> Terminator -> MS (r smt)
forall (r :: * -> *) smt.
RenderStatement r smt =>
Body -> Terminator -> MS (r smt)
stmtFromData (r Variable -> r Value -> Body
forall (r :: * -> *).
(InternalVarElim r, ValueElim r) =>
r Variable -> r Value -> Body
R.subAssign r Variable
vr r Value
v) Terminator
t

objDecNew
  :: (IC.DeclStatement r smt, IG.OOValueExpression r, VariableElim r)
  => SVariable r -> r ScopeData -> [SValue r] -> MS (r smt)
objDecNew :: forall (r :: * -> *) smt.
(DeclStatement r smt, OOValueExpression r, VariableElim r) =>
SVariable r -> r ScopeData -> [SValue r] -> MS (r smt)
objDecNew SVariable r
v r ScopeData
scp [SValue r]
vs = SVariable r -> r ScopeData -> SValue r -> MS (r smt)
forall (r :: * -> *) smt.
DeclStatement r smt =>
SVariable r -> r ScopeData -> SValue r -> MS (r smt)
IC.varDecDef SVariable r
v r ScopeData
scp (PosCtorCall r
forall (r :: * -> *). OOValueExpression r => PosCtorCall r
newObj ((r Variable -> r TypeData)
-> SVariable r -> State ValueState (r TypeData)
forall a b s. (a -> b) -> State s a -> State s b
onStateValue r Variable -> r TypeData
forall (r :: * -> *). VariableElim r => r Variable -> r TypeData
variableType SVariable r
v) [SValue r]
vs)

printList :: (IC.SharedStatement r smt) => Integer -> SValue r ->
  (SValue r -> MS (r smt)) -> (String -> MS (r smt)) ->
  (String -> MS (r smt)) -> MS (r smt)
printList :: forall (r :: * -> *) smt.
SharedStatement r smt =>
Integer
-> SValue r
-> (SValue r -> MS (r smt))
-> (ClassName -> MS (r smt))
-> (ClassName -> MS (r smt))
-> MS (r smt)
printList Integer
n SValue r
v SValue r -> MS (r smt)
prFn ClassName -> MS (r smt)
prStrFn ClassName -> MS (r smt)
prLnFn = [MS (r smt)] -> MS (r smt)
forall (r :: * -> *) smt.
StatementSym r smt =>
[MS (r smt)] -> MS (r smt)
multi [ClassName -> MS (r smt)
prStrFn ClassName
"[",
  MS (r smt) -> SValue r -> MS (r smt) -> MS (r Body) -> MS (r smt)
forall (r :: * -> *) smt.
ControlStatement r smt =>
MS (r smt) -> SValue r -> MS (r smt) -> MS (r Body) -> MS (r smt)
IC.for (SVariable r -> r ScopeData -> SValue r -> MS (r smt)
forall (r :: * -> *) smt.
DeclStatement r smt =>
SVariable r -> r ScopeData -> SValue r -> MS (r smt)
IC.varDecDef SVariable r
i r ScopeData
forall (r :: * -> *). ScopeSym r => r ScopeData
IC.local (Integer -> SValue r
forall (r :: * -> *). Literal r => Integer -> SValue r
IC.litInt Integer
0))
    (SVariable r -> SValue r
forall (r :: * -> *). VariableValue r => SVariable r -> SValue r
IC.valueOf SVariable r
i SValue r -> SValue r -> SValue r
forall (r :: * -> *).
Comparison r =>
SValue r -> SValue r -> SValue r
?< (SValue r -> SValue r
forall (r :: * -> *) smt. List r smt => SValue r -> SValue r
IC.listSize SValue r
v SValue r -> SValue r -> SValue r
forall (r :: * -> *).
NumericExpression r =>
SValue r -> SValue r -> SValue r
#- Integer -> SValue r
forall (r :: * -> *). Literal r => Integer -> SValue r
IC.litInt Integer
1)) (SVariable r
i &++)
    ([MS (r smt)] -> MS (r Body)
forall (r :: * -> *) smt.
BodySym r smt =>
[MS (r smt)] -> MS (r Body)
bodyStatements [SValue r -> MS (r smt)
prFn (SValue r -> SValue r -> SValue r
forall (r :: * -> *) smt.
List r smt =>
SValue r -> SValue r -> SValue r
IC.listAccess SValue r
v (SVariable r -> SValue r
forall (r :: * -> *). VariableValue r => SVariable r -> SValue r
IC.valueOf SVariable r
i)), ClassName -> MS (r smt)
prStrFn ClassName
", "]),
  [(SValue r, MS (r Body))] -> MS (r smt)
forall (r :: * -> *) smt.
ControlStatement r smt =>
[(SValue r, MS (r Body))] -> MS (r smt)
ifNoElse [(SValue r -> SValue r
forall (r :: * -> *) smt. List r smt => SValue r -> SValue r
IC.listSize SValue r
v SValue r -> SValue r -> SValue r
forall (r :: * -> *).
Comparison r =>
SValue r -> SValue r -> SValue r
?> Integer -> SValue r
forall (r :: * -> *). Literal r => Integer -> SValue r
IC.litInt Integer
0, MS (r smt) -> MS (r Body)
forall (r :: * -> *) smt.
BodySym r smt =>
MS (r smt) -> MS (r Body)
oneLiner (MS (r smt) -> MS (r Body)) -> MS (r smt) -> MS (r Body)
forall a b. (a -> b) -> a -> b
$
    SValue r -> MS (r smt)
prFn (SValue r -> SValue r -> SValue r
forall (r :: * -> *) smt.
List r smt =>
SValue r -> SValue r -> SValue r
IC.listAccess SValue r
v (SValue r -> SValue r
forall (r :: * -> *) smt. List r smt => SValue r -> SValue r
IC.listSize SValue r
v SValue r -> SValue r -> SValue r
forall (r :: * -> *).
NumericExpression r =>
SValue r -> SValue r -> SValue r
#- Integer -> SValue r
forall (r :: * -> *). Literal r => Integer -> SValue r
IC.litInt Integer
1)))],
  ClassName -> MS (r smt)
prLnFn ClassName
"]"]
  where l_i :: ClassName
l_i = ClassName
"list_i" ClassName -> ClassName -> ClassName
forall a. [a] -> [a] -> [a]
++ Integer -> ClassName
forall a. Show a => a -> ClassName
show Integer
n
        i :: SVariable r
i = ClassName -> VS (r TypeData) -> SVariable r
forall (r :: * -> *).
VariableSym r =>
ClassName -> VS (r TypeData) -> SVariable r
IC.var ClassName
l_i VS (r TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
IC.int

printSet :: (IC.SharedStatement r smt) => Integer -> SValue r ->
  (SValue r -> MS (r smt)) -> (String -> MS (r smt)) ->
  (String -> MS (r smt)) -> VS (r TypeData) -> MS (r smt)
printSet :: forall (r :: * -> *) smt.
SharedStatement r smt =>
Integer
-> SValue r
-> (SValue r -> MS (r smt))
-> (ClassName -> MS (r smt))
-> (ClassName -> MS (r smt))
-> VS (r TypeData)
-> MS (r smt)
printSet Integer
n SValue r
v SValue r -> MS (r smt)
prFn ClassName -> MS (r smt)
prStrFn ClassName -> MS (r smt)
prLnFn VS (r TypeData)
s = [MS (r smt)] -> MS (r smt)
forall (r :: * -> *) smt.
StatementSym r smt =>
[MS (r smt)] -> MS (r smt)
multi [ClassName -> MS (r smt)
prStrFn ClassName
"{ ",
  SVariable r -> SValue r -> MS (r Body) -> MS (r smt)
forall (r :: * -> *) smt.
ControlStatement r smt =>
SVariable r -> SValue r -> MS (r Body) -> MS (r smt)
IC.forEach SVariable r
i SValue r
v
    ([MS (r smt)] -> MS (r Body)
forall (r :: * -> *) smt.
BodySym r smt =>
[MS (r smt)] -> MS (r Body)
bodyStatements [SValue r -> MS (r smt)
prFn (SVariable r -> SValue r
forall (r :: * -> *). VariableValue r => SVariable r -> SValue r
IC.valueOf SVariable r
i),ClassName -> MS (r smt)
prStrFn ClassName
" "]),
  ClassName -> MS (r smt)
prLnFn ClassName
"}"]
  where set_i :: ClassName
set_i = ClassName
"set_i" ClassName -> ClassName -> ClassName
forall a. [a] -> [a] -> [a]
++ Integer -> ClassName
forall a. Show a => a -> ClassName
show Integer
n
        i :: SVariable r
i = ClassName -> VS (r TypeData) -> SVariable r
forall (r :: * -> *).
VariableSym r =>
ClassName -> VS (r TypeData) -> SVariable r
IC.var ClassName
set_i VS (r TypeData)
s

printObj :: ClassName -> (String -> MS (r smt)) -> MS (r smt)
printObj :: forall (r :: * -> *) smt.
ClassName -> (ClassName -> MS (r smt)) -> MS (r smt)
printObj ClassName
n ClassName -> MS (r smt)
prLnFn = ClassName -> MS (r smt)
prLnFn (ClassName -> MS (r smt)) -> ClassName -> MS (r smt)
forall a b. (a -> b) -> a -> b
$ ClassName
"Instance of " ClassName -> ClassName -> ClassName
forall a. [a] -> [a] -> [a]
++ ClassName
n ClassName -> ClassName -> ClassName
forall a. [a] -> [a] -> [a]
++ ClassName
" object"

print
  :: (RC.InternalIOStmt r smt, IC.SharedStatement r smt, TypeElim r)
  => Bool -> Maybe (SValue r) -> SValue r -> SValue r -> MS (r smt)
print :: forall (r :: * -> *) smt.
(InternalIOStmt r smt, SharedStatement r smt, TypeElim r) =>
Bool -> Maybe (SValue r) -> SValue r -> SValue r -> MS (r smt)
print Bool
newLn Maybe (SValue r)
f SValue r
printFn SValue r
v = LensLike'
  (Zoomed (StateT ValueState Identity) (r Value))
  MethodState
  ValueState
-> SValue r -> StateT MethodState Identity (r Value)
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))
  MethodState
  ValueState
(ValueState -> Focusing Identity (r Value) ValueState)
-> MethodState -> Focusing Identity (r Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue r
v StateT MethodState Identity (r Value)
-> (r Value -> StateT MethodState Identity (r smt))
-> StateT MethodState Identity (r smt)
forall a b.
StateT MethodState Identity a
-> (a -> StateT MethodState Identity b)
-> StateT MethodState Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= CodeType -> StateT MethodState Identity (r smt)
print' (CodeType -> StateT MethodState Identity (r smt))
-> (r Value -> CodeType)
-> r Value
-> StateT MethodState Identity (r smt)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. r TypeData -> CodeType
forall (r :: * -> *). TypeElim r => r TypeData -> CodeType
getCodeType (r TypeData -> CodeType)
-> (r Value -> r TypeData) -> r Value -> CodeType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. r Value -> r TypeData
forall (r :: * -> *). ValueSym r => r Value -> r TypeData
valueType
  where print' :: CodeType -> StateT MethodState Identity (r smt)
print' (List CodeType
t) = Integer
-> SValue r
-> (SValue r -> StateT MethodState Identity (r smt))
-> (ClassName -> StateT MethodState Identity (r smt))
-> (ClassName -> StateT MethodState Identity (r smt))
-> StateT MethodState Identity (r smt)
forall (r :: * -> *) smt.
SharedStatement r smt =>
Integer
-> SValue r
-> (SValue r -> MS (r smt))
-> (ClassName -> MS (r smt))
-> (ClassName -> MS (r smt))
-> MS (r smt)
printList (Integer -> CodeType -> Integer
getNestDegree Integer
1 CodeType
t) SValue r
v SValue r -> StateT MethodState Identity (r smt)
prFn ClassName -> StateT MethodState Identity (r smt)
prStrFn ClassName -> StateT MethodState Identity (r smt)
prLnFn
        print' (Object ClassName
n) = ClassName
-> (ClassName -> StateT MethodState Identity (r smt))
-> StateT MethodState Identity (r smt)
forall (r :: * -> *) smt.
ClassName -> (ClassName -> MS (r smt)) -> MS (r smt)
printObj ClassName
n ClassName -> StateT MethodState Identity (r smt)
prLnFn
        print' (Set CodeType
t) = Integer
-> SValue r
-> (SValue r -> StateT MethodState Identity (r smt))
-> (ClassName -> StateT MethodState Identity (r smt))
-> (ClassName -> StateT MethodState Identity (r smt))
-> VS (r TypeData)
-> StateT MethodState Identity (r smt)
forall (r :: * -> *) smt.
SharedStatement r smt =>
Integer
-> SValue r
-> (SValue r -> MS (r smt))
-> (ClassName -> MS (r smt))
-> (ClassName -> MS (r smt))
-> VS (r TypeData)
-> MS (r smt)
printSet (Integer -> CodeType -> Integer
getNestDegree Integer
1 CodeType
t) SValue r
v SValue r -> StateT MethodState Identity (r smt)
prFn ClassName -> StateT MethodState Identity (r smt)
prStrFn ClassName -> StateT MethodState Identity (r smt)
prLnFn (CodeType -> VS (r TypeData)
forall (r :: * -> *). TypeSym r => CodeType -> VS (r TypeData)
convType CodeType
t)
        print' CodeType
_ = Bool
-> Maybe (SValue r)
-> SValue r
-> SValue r
-> StateT MethodState Identity (r smt)
forall (r :: * -> *) smt.
InternalIOStmt r smt =>
Bool -> Maybe (SValue r) -> SValue r -> SValue r -> MS (r smt)
RC.printSt Bool
newLn Maybe (SValue r)
f SValue r
printFn SValue r
v
        prFn :: SValue r -> StateT MethodState Identity (r smt)
prFn = (SValue r -> StateT MethodState Identity (r smt))
-> (SValue r -> SValue r -> StateT MethodState Identity (r smt))
-> Maybe (SValue r)
-> SValue r
-> StateT MethodState Identity (r smt)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe SValue r -> StateT MethodState Identity (r smt)
forall (r :: * -> *) smt.
IOStatement r smt =>
SValue r -> MS (r smt)
IC.print SValue r -> SValue r -> StateT MethodState Identity (r smt)
forall (r :: * -> *) smt.
IOStatement r smt =>
SValue r -> SValue r -> MS (r smt)
printFile Maybe (SValue r)
f
        prStrFn :: ClassName -> StateT MethodState Identity (r smt)
prStrFn = (ClassName -> StateT MethodState Identity (r smt))
-> (SValue r -> ClassName -> StateT MethodState Identity (r smt))
-> Maybe (SValue r)
-> ClassName
-> StateT MethodState Identity (r smt)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ClassName -> StateT MethodState Identity (r smt)
forall (r :: * -> *) smt.
IOStatement r smt =>
ClassName -> MS (r smt)
printStr SValue r -> ClassName -> StateT MethodState Identity (r smt)
forall (r :: * -> *) smt.
IOStatement r smt =>
SValue r -> ClassName -> MS (r smt)
printFileStr Maybe (SValue r)
f
        prLnFn :: ClassName -> StateT MethodState Identity (r smt)
prLnFn = if Bool
newLn then (ClassName -> StateT MethodState Identity (r smt))
-> (SValue r -> ClassName -> StateT MethodState Identity (r smt))
-> Maybe (SValue r)
-> ClassName
-> StateT MethodState Identity (r smt)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ClassName -> StateT MethodState Identity (r smt)
forall (r :: * -> *) smt.
IOStatement r smt =>
ClassName -> MS (r smt)
printStrLn SValue r -> ClassName -> StateT MethodState Identity (r smt)
forall (r :: * -> *) smt.
IOStatement r smt =>
SValue r -> ClassName -> MS (r smt)
printFileStrLn Maybe (SValue r)
f else (ClassName -> StateT MethodState Identity (r smt))
-> (SValue r -> ClassName -> StateT MethodState Identity (r smt))
-> Maybe (SValue r)
-> ClassName
-> StateT MethodState Identity (r smt)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
          ClassName -> StateT MethodState Identity (r smt)
forall (r :: * -> *) smt.
IOStatement r smt =>
ClassName -> MS (r smt)
printStr SValue r -> ClassName -> StateT MethodState Identity (r smt)
forall (r :: * -> *) smt.
IOStatement r smt =>
SValue r -> ClassName -> MS (r smt)
printFileStr Maybe (SValue r)
f

closeFile
  :: (IG.InternalValueExp r, StatementSym r smt)
  => Label -> SValue r -> MS (r smt)
closeFile :: forall (r :: * -> *) smt.
(InternalValueExp r, StatementSym r smt) =>
ClassName -> SValue r -> MS (r smt)
closeFile ClassName
n SValue r
f = SValue r -> MS (r smt)
forall (r :: * -> *) smt.
StatementSym r smt =>
SValue r -> MS (r smt)
IC.valStmt (SValue r -> MS (r smt)) -> SValue r -> MS (r smt)
forall a b. (a -> b) -> a -> b
$ VS (r TypeData) -> SValue r -> ClassName -> SValue r
forall (r :: * -> *).
InternalValueExp r =>
VS (r TypeData) -> SValue r -> ClassName -> SValue r
objMethodCallNoParams VS (r TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
IC.void SValue r
f ClassName
n

returnStmt
  :: (RenderStatement r smt, ValueElim r)
  => Terminator -> SValue r -> MS (r smt)
returnStmt :: forall (r :: * -> *) smt.
(RenderStatement r smt, ValueElim r) =>
Terminator -> SValue r -> MS (r smt)
returnStmt Terminator
t SValue r
v' = do
  r Value
v <- LensLike'
  (Zoomed (StateT ValueState Identity) (r Value))
  MethodState
  ValueState
-> SValue r -> StateT MethodState Identity (r Value)
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))
  MethodState
  ValueState
(ValueState -> Focusing Identity (r Value) ValueState)
-> MethodState -> Focusing Identity (r Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue r
v'
  Body -> Terminator -> MS (r smt)
forall (r :: * -> *) smt.
RenderStatement r smt =>
Body -> Terminator -> MS (r smt)
stmtFromData ([r Value] -> Body
forall (r :: * -> *). ValueElim r => [r Value] -> Body
R.return' [r Value
v]) Terminator
t

valStmt :: (RenderStatement r smt, ValueElim r) => Terminator -> SValue r -> MS (r smt)
valStmt :: forall (r :: * -> *) smt.
(RenderStatement r smt, ValueElim r) =>
Terminator -> SValue r -> MS (r smt)
valStmt Terminator
t SValue r
v' = do
  r Value
v <- LensLike'
  (Zoomed (StateT ValueState Identity) (r Value))
  MethodState
  ValueState
-> SValue r -> StateT MethodState Identity (r Value)
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))
  MethodState
  ValueState
(ValueState -> Focusing Identity (r Value) ValueState)
-> MethodState -> Focusing Identity (r Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue r
v'
  Body -> Terminator -> MS (r smt)
forall (r :: * -> *) smt.
RenderStatement r smt =>
Body -> Terminator -> MS (r smt)
stmtFromData (r Value -> Body
forall (r :: * -> *). ValueElim r => r Value -> Body
RC.value r Value
v) Terminator
t

comment :: (RenderStatement r smt) => Doc -> Label -> MS (r smt)
comment :: forall (r :: * -> *) smt.
RenderStatement r smt =>
Body -> ClassName -> MS (r smt)
comment Body
cs ClassName
c = Body -> MS (r smt)
forall (r :: * -> *) smt.
RenderStatement r smt =>
Body -> MS (r smt)
mkStmtNoEnd (ClassName -> Body -> Body
R.comment ClassName
c Body
cs)

throw :: (IC.Literal r, RenderStatement r smt) => (r Value -> Doc) -> Terminator ->
  Label -> MS (r smt)
throw :: forall (r :: * -> *) smt.
(Literal r, RenderStatement r smt) =>
(r Value -> Body) -> Terminator -> ClassName -> MS (r smt)
throw r Value -> Body
f Terminator
t ClassName
l = do
  r Value
msg <- LensLike'
  (Zoomed (StateT ValueState Identity) (r Value))
  MethodState
  ValueState
-> StateT ValueState Identity (r Value)
-> StateT MethodState Identity (r Value)
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))
  MethodState
  ValueState
(ValueState -> Focusing Identity (r Value) ValueState)
-> MethodState -> Focusing Identity (r Value) MethodState
Lens' MethodState ValueState
lensMStoVS (ClassName -> StateT ValueState Identity (r Value)
forall (r :: * -> *). Literal r => ClassName -> SValue r
IC.litString ClassName
l)
  Body -> Terminator -> MS (r smt)
forall (r :: * -> *) smt.
RenderStatement r smt =>
Body -> Terminator -> MS (r smt)
stmtFromData (r Value -> Body
f r Value
msg) Terminator
t

newtype OptionalSpace = OSpace {OptionalSpace -> Body
oSpace :: Doc}

defaultOptSpace :: OptionalSpace
defaultOptSpace :: OptionalSpace
defaultOptSpace = OSpace {oSpace :: Body
oSpace = Body
space}

optSpaceDoc :: OptionalSpace -> Doc
optSpaceDoc :: OptionalSpace -> Body
optSpaceDoc OSpace {oSpace :: OptionalSpace -> Body
oSpace = Body
sp} = Body
sp

-- ControlStatements --

-- 1st parameter is a Doc function to use on the render of each condition (i.e. parens)
-- 2nd parameter is the syntax for starting a block in an if-condition
-- 3rd parameter is the keyword for an else-if statement
-- 4th parameter is the syntax for ending a block in an if-condition
-- 5th parameter is the syntax for ending an if-statement
ifCond
  :: (RC.BodyElim r, RenderStatement r smt, ValueElim r)
  => (Doc -> Doc)
  -> Doc
  -> OptionalSpace
  -> Doc
  -> Doc
  -> Doc
  -> [(SValue r, MS (r Body))]
  -> MS (r Body)
  -> MS (r smt)
ifCond :: forall (r :: * -> *) smt.
(BodyElim r, RenderStatement r smt, ValueElim r) =>
(Body -> Body)
-> Body
-> OptionalSpace
-> Body
-> Body
-> Body
-> [(SValue r, MS (r Body))]
-> MS (r Body)
-> MS (r smt)
ifCond Body -> Body
_ Body
_ OptionalSpace
_ Body
_ Body
_ Body
_ [] MS (r Body)
_ = ClassName -> MS (r smt)
forall a. HasCallStack => ClassName -> a
error ClassName
"if condition created with no cases"
ifCond Body -> Body
f Body
ifStart OptionalSpace
os Body
elif Body
bEnd Body
ifEnd ((SValue r, MS (r Body))
c:[(SValue r, MS (r Body))]
cs) MS (r Body)
eBody =
    let ifSect :: (StateT ValueState Identity (r Value), State MethodState (r Body))
-> State MethodState Body
ifSect (StateT ValueState Identity (r Value)
v, State MethodState (r Body)
b) = (r Value -> r Body -> Body)
-> State MethodState (r Value)
-> State MethodState (r Body)
-> State MethodState Body
forall a b c s.
(a -> b -> c) -> State s a -> State s b -> State s c
on2StateValues (\r Value
val r Body
bd -> [Body] -> Body
vcat [
          Body
ifLabel Body -> Body -> Body
<+> Body -> Body
f (r Value -> Body
forall (r :: * -> *). ValueElim r => r Value -> Body
RC.value r Value
val) Body -> Body -> Body
<> OptionalSpace -> Body
optSpaceDoc OptionalSpace
os Body -> Body -> Body
<> Body
ifStart,
          Body -> Body
indent (Body -> Body) -> Body -> Body
forall a b. (a -> b) -> a -> b
$ r Body -> Body
forall (r :: * -> *). BodyElim r => r Body -> Body
RC.body r Body
bd,
          Body
bEnd]) (LensLike'
  (Zoomed (StateT ValueState Identity) (r Value))
  MethodState
  ValueState
-> StateT ValueState Identity (r Value)
-> State MethodState (r Value)
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))
  MethodState
  ValueState
Lens' MethodState ValueState
lensMStoVS StateT ValueState Identity (r Value)
v) State MethodState (r Body)
b
        elseIfSect :: (StateT ValueState Identity (r Value), State MethodState (r Body))
-> State MethodState Body
elseIfSect (StateT ValueState Identity (r Value)
v, State MethodState (r Body)
b) = (r Value -> r Body -> Body)
-> State MethodState (r Value)
-> State MethodState (r Body)
-> State MethodState Body
forall a b c s.
(a -> b -> c) -> State s a -> State s b -> State s c
on2StateValues (\r Value
val r Body
bd -> [Body] -> Body
vcat [
          Body
elif Body -> Body -> Body
<+> Body -> Body
f (r Value -> Body
forall (r :: * -> *). ValueElim r => r Value -> Body
RC.value r Value
val) Body -> Body -> Body
<> OptionalSpace -> Body
optSpaceDoc OptionalSpace
os Body -> Body -> Body
<> Body
ifStart,
          Body -> Body
indent (Body -> Body) -> Body -> Body
forall a b. (a -> b) -> a -> b
$ r Body -> Body
forall (r :: * -> *). BodyElim r => r Body -> Body
RC.body r Body
bd,
          Body
bEnd]) (LensLike'
  (Zoomed (StateT ValueState Identity) (r Value))
  MethodState
  ValueState
-> StateT ValueState Identity (r Value)
-> State MethodState (r Value)
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))
  MethodState
  ValueState
Lens' MethodState ValueState
lensMStoVS StateT ValueState Identity (r Value)
v) State MethodState (r Body)
b
        elseSect :: State MethodState Body
elseSect = (r Body -> Body) -> MS (r Body) -> State MethodState Body
forall a b s. (a -> b) -> State s a -> State s b
onStateValue (\r Body
bd -> Body -> Body -> Body
emptyIfEmpty (r Body -> Body
forall (r :: * -> *). BodyElim r => r Body -> Body
RC.body r Body
bd) ([Body] -> Body
vcat [
          Body
elseLabel Body -> Body -> Body
<> OptionalSpace -> Body
optSpaceDoc OptionalSpace
os Body -> Body -> Body
<> Body
ifStart,
          Body -> Body
indent (Body -> Body) -> Body -> Body
forall a b. (a -> b) -> a -> b
$ r Body -> Body
forall (r :: * -> *). BodyElim r => r Body -> Body
RC.body r Body
bd,
          Body
bEnd]) Body -> Body -> Body
$+$ Body
ifEnd) MS (r Body)
eBody
    in [State MethodState Body] -> StateT MethodState Identity [Body]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence ((SValue r, MS (r Body)) -> State MethodState Body
forall {r :: * -> *} {r :: * -> *}.
(ValueElim r, BodyElim r) =>
(StateT ValueState Identity (r Value), State MethodState (r Body))
-> State MethodState Body
ifSect (SValue r, MS (r Body))
c State MethodState Body
-> [State MethodState Body] -> [State MethodState Body]
forall a. a -> [a] -> [a]
: ((SValue r, MS (r Body)) -> State MethodState Body)
-> [(SValue r, MS (r Body))] -> [State MethodState Body]
forall a b. (a -> b) -> [a] -> [b]
map (SValue r, MS (r Body)) -> State MethodState Body
forall {r :: * -> *} {r :: * -> *}.
(ValueElim r, BodyElim r) =>
(StateT ValueState Identity (r Value), State MethodState (r Body))
-> State MethodState Body
elseIfSect [(SValue r, MS (r Body))]
cs [State MethodState Body]
-> [State MethodState Body] -> [State MethodState Body]
forall a. [a] -> [a] -> [a]
++ [State MethodState Body
elseSect])
      StateT MethodState Identity [Body]
-> ([Body] -> MS (r smt)) -> MS (r smt)
forall a b.
StateT MethodState Identity a
-> (a -> StateT MethodState Identity b)
-> StateT MethodState Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Body -> MS (r smt)
forall (r :: * -> *) smt.
RenderStatement r smt =>
Body -> MS (r smt)
mkStmtNoEnd (Body -> MS (r smt)) -> ([Body] -> Body) -> [Body] -> MS (r smt)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Body] -> Body
vcat)

tryCatch :: (RenderStatement r smt) => (r Body -> r Body -> Doc) ->
  MS (r Body) -> MS (r Body) -> MS (r smt)
tryCatch :: forall (r :: * -> *) smt.
RenderStatement r smt =>
(r Body -> r Body -> Body)
-> MS (r Body) -> MS (r Body) -> MS (r smt)
tryCatch r Body -> r Body -> Body
f = (r Body -> r Body -> StateT MethodState Identity (r smt))
-> StateT MethodState Identity (r Body)
-> StateT MethodState Identity (r Body)
-> StateT MethodState Identity (r smt)
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> m c) -> m a -> m b -> m c
on2StateWrapped (\r Body
tb1 r Body
tb2 -> Body -> StateT MethodState Identity (r smt)
forall (r :: * -> *) smt.
RenderStatement r smt =>
Body -> MS (r smt)
mkStmtNoEnd (r Body -> r Body -> Body
f r Body
tb1 r Body
tb2))

-- Methods --

construct :: (Monad r) => Label -> MS (r TypeData)
construct :: forall (r :: * -> *). Monad r => ClassName -> MS (r TypeData)
construct ClassName
n = LensLike'
  (Zoomed (StateT ValueState Identity) (r TypeData))
  MethodState
  ValueState
-> StateT ValueState Identity (r TypeData)
-> StateT MethodState Identity (r TypeData)
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 TypeData))
  MethodState
  ValueState
(ValueState -> Focusing Identity (r TypeData) ValueState)
-> MethodState -> Focusing Identity (r TypeData) MethodState
Lens' MethodState ValueState
lensMStoVS (StateT ValueState Identity (r TypeData)
 -> StateT MethodState Identity (r TypeData))
-> StateT ValueState Identity (r TypeData)
-> StateT MethodState Identity (r TypeData)
forall a b. (a -> b) -> a -> b
$ CodeType
-> ClassName -> Body -> StateT ValueState Identity (r TypeData)
forall (r :: * -> *).
Monad r =>
CodeType -> ClassName -> Body -> VS (r TypeData)
typeFromData (ClassName -> CodeType
Object ClassName
n) ClassName
n Body
empty

param
  :: (RenderParam r, VariableElim r)
  => (r Variable -> Doc) -> SVariable r -> MS (r ParamData)
param :: forall (r :: * -> *).
(RenderParam r, VariableElim r) =>
(r Variable -> Body) -> SVariable r -> MS (r ParamData)
param r Variable -> Body
f SVariable r
v' = do
  r Variable
v <- LensLike'
  (Zoomed (StateT ValueState Identity) (r Variable))
  MethodState
  ValueState
-> SVariable r -> StateT MethodState Identity (r Variable)
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))
  MethodState
  ValueState
(ValueState -> Focusing Identity (r Variable) ValueState)
-> MethodState -> Focusing Identity (r Variable) MethodState
Lens' MethodState ValueState
lensMStoVS SVariable r
v'
  let n :: ClassName
n = r Variable -> ClassName
forall (r :: * -> *). VariableElim r => r Variable -> ClassName
variableName r Variable
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
$ ClassName -> MethodState -> MethodState
addParameter ClassName
n
  (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
$ ClassName -> MethodState -> MethodState
useVarName ClassName
n
  SVariable r -> Body -> MS (r ParamData)
forall (r :: * -> *).
RenderParam r =>
SVariable r -> Body -> MS (r ParamData)
paramFromData SVariable r
v' (Body -> MS (r ParamData)) -> Body -> MS (r ParamData)
forall a b. (a -> b) -> a -> b
$ r Variable -> Body
f r Variable
v

method
  :: (OORenderMethod r vis md att)
  => Label
  -> r vis
  -> r att
  -> VS (r TypeData)
  -> [MS (r ParamData)]
  -> MS (r Body)
  -> MS (r md)
method :: forall (r :: * -> *) vis md att.
OORenderMethod r vis md att =>
ClassName
-> r vis
-> r att
-> VS (r TypeData)
-> [MS (r ParamData)]
-> MS (r Body)
-> MS (r md)
method ClassName
n r vis
s r att
p VS (r TypeData)
t = Bool
-> ClassName
-> r vis
-> r att
-> MSMthdType r
-> [MS (r ParamData)]
-> MS (r Body)
-> MS (r md)
forall (r :: * -> *) vis md att.
OORenderMethod r vis md att =>
Bool
-> ClassName
-> r vis
-> r att
-> MSMthdType r
-> [MS (r ParamData)]
-> MS (r Body)
-> MS (r md)
intMethod Bool
False ClassName
n r vis
s r att
p (VS (r TypeData) -> MSMthdType r
forall (r :: * -> *).
MethodTypeSym r =>
VS (r TypeData) -> MSMthdType r
mType VS (r TypeData)
t)

getMethod :: (OORenderSym r vis smt md svr att) => SVariable r -> MS (r md)
getMethod :: forall (r :: * -> *) vis smt md svr att.
OORenderSym r vis smt md svr att =>
SVariable r -> MS (r md)
getMethod SVariable r
v = LensLike'
  (Zoomed (StateT ValueState Identity) (r Variable))
  MethodState
  ValueState
-> SVariable r -> StateT MethodState Identity (r Variable)
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))
  MethodState
  ValueState
(ValueState -> Focusing Identity (r Variable) ValueState)
-> MethodState -> Focusing Identity (r Variable) MethodState
Lens' MethodState ValueState
lensMStoVS SVariable r
v StateT MethodState Identity (r Variable)
-> (r Variable -> StateT MethodState Identity (r md))
-> StateT MethodState Identity (r md)
forall a b.
StateT MethodState Identity a
-> (a -> StateT MethodState Identity b)
-> StateT MethodState Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (\r Variable
vr -> ClassName
-> r vis
-> r att
-> VS (r TypeData)
-> [MS (r ParamData)]
-> MS (r Body)
-> StateT MethodState Identity (r md)
forall (r :: * -> *) vis smt md att.
OOMethodSym r vis smt md att =>
ClassName
-> r vis
-> r att
-> VS (r TypeData)
-> [MS (r ParamData)]
-> MS (r Body)
-> MS (r md)
IG.method (ClassName -> ClassName
getterName (ClassName -> ClassName) -> ClassName -> ClassName
forall a b. (a -> b) -> a -> b
$ r Variable -> ClassName
forall (r :: * -> *). VariableElim r => r Variable -> ClassName
variableName
  r Variable
vr) r vis
forall (r :: * -> *) vis. VisibilitySym r vis => r vis
public r att
forall (r :: * -> *) att. AttachmentSym r att => r att
instanceLevel (r TypeData -> VS (r TypeData)
forall a s. a -> State s a
toState (r TypeData -> VS (r TypeData)) -> r TypeData -> VS (r TypeData)
forall a b. (a -> b) -> a -> b
$ r Variable -> r TypeData
forall (r :: * -> *). VariableElim r => r Variable -> r TypeData
variableType r Variable
vr) [] MS (r Body)
getBody)
  where getBody :: MS (r Body)
getBody = MS (r smt) -> MS (r Body)
forall (r :: * -> *) smt.
BodySym r smt =>
MS (r smt) -> MS (r Body)
oneLiner (MS (r smt) -> MS (r Body)) -> MS (r smt) -> MS (r Body)
forall a b. (a -> b) -> a -> b
$ SValue r -> MS (r smt)
forall (r :: * -> *) smt.
ControlStatement r smt =>
SValue r -> MS (r smt)
IC.returnStmt (SVariable r -> SValue r
forall (r :: * -> *). VariableValue r => SVariable r -> SValue r
IC.valueOf (SVariable r -> SValue r) -> SVariable r -> SValue r
forall a b. (a -> b) -> a -> b
$ SVariable r -> SVariable r
forall (r :: * -> *).
(SelfSym r, VariableValue r) =>
SVariable r -> SVariable r
IG.instanceVarSelf SVariable r
v)

setMethod :: (OORenderSym r vis smt md svr att) => SVariable r -> MS (r md)
setMethod :: forall (r :: * -> *) vis smt md svr att.
OORenderSym r vis smt md svr att =>
SVariable r -> MS (r md)
setMethod SVariable r
v = LensLike'
  (Zoomed (StateT ValueState Identity) (r Variable))
  MethodState
  ValueState
-> SVariable r -> StateT MethodState Identity (r Variable)
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))
  MethodState
  ValueState
(ValueState -> Focusing Identity (r Variable) ValueState)
-> MethodState -> Focusing Identity (r Variable) MethodState
Lens' MethodState ValueState
lensMStoVS SVariable r
v StateT MethodState Identity (r Variable)
-> (r Variable -> StateT MethodState Identity (r md))
-> StateT MethodState Identity (r md)
forall a b.
StateT MethodState Identity a
-> (a -> StateT MethodState Identity b)
-> StateT MethodState Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (\r Variable
vr -> ClassName
-> r vis
-> r att
-> VS (r TypeData)
-> [MS (r ParamData)]
-> MS (r Body)
-> StateT MethodState Identity (r md)
forall (r :: * -> *) vis smt md att.
OOMethodSym r vis smt md att =>
ClassName
-> r vis
-> r att
-> VS (r TypeData)
-> [MS (r ParamData)]
-> MS (r Body)
-> MS (r md)
IG.method (ClassName -> ClassName
setterName (ClassName -> ClassName) -> ClassName -> ClassName
forall a b. (a -> b) -> a -> b
$ r Variable -> ClassName
forall (r :: * -> *). VariableElim r => r Variable -> ClassName
variableName
  r Variable
vr) r vis
forall (r :: * -> *) vis. VisibilitySym r vis => r vis
public r att
forall (r :: * -> *) att. AttachmentSym r att => r att
instanceLevel VS (r TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
IC.void [SVariable r -> MS (r ParamData)
forall (r :: * -> *).
ParameterSym r =>
SVariable r -> MS (r ParamData)
IC.param SVariable r
v] MS (r Body)
setBody)
  where setBody :: MS (r Body)
setBody = MS (r smt) -> MS (r Body)
forall (r :: * -> *) smt.
BodySym r smt =>
MS (r smt) -> MS (r Body)
oneLiner (MS (r smt) -> MS (r Body)) -> MS (r smt) -> MS (r Body)
forall a b. (a -> b) -> a -> b
$ SVariable r -> SVariable r
forall (r :: * -> *).
(SelfSym r, VariableValue r) =>
SVariable r -> SVariable r
IG.instanceVarSelf SVariable r
v SVariable r -> SValue r -> MS (r smt)
forall (r :: * -> *) smt.
AssignStatement r smt =>
SVariable r -> SValue r -> MS (r smt)
&= SVariable r -> SValue r
forall (r :: * -> *). VariableValue r => SVariable r -> SValue r
IC.valueOf SVariable r
v

initStmts :: (OOStatement r smt) => Initializers r -> MS (r Body)
initStmts :: forall (r :: * -> *) smt.
OOStatement r smt =>
Initializers r -> MS (r Body)
initStmts = [MS (r smt)] -> MS (r Body)
forall (r :: * -> *) smt.
BodySym r smt =>
[MS (r smt)] -> MS (r Body)
bodyStatements ([MS (r smt)] -> MS (r Body))
-> (Initializers r -> [MS (r smt)])
-> Initializers r
-> MS (r Body)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((SVariable r, SValue r) -> MS (r smt))
-> Initializers r -> [MS (r smt)]
forall a b. (a -> b) -> [a] -> [b]
map (\(SVariable r
vr, SValue r
vl) -> SVariable r -> SVariable r
forall (r :: * -> *).
(SelfSym r, VariableValue r) =>
SVariable r -> SVariable r
IG.instanceVarSelf SVariable r
vr SVariable r -> SValue r -> MS (r smt)
forall (r :: * -> *) smt.
AssignStatement r smt =>
SVariable r -> SValue r -> MS (r smt)
&= SValue r
vl)

function
  :: (AttachmentSym r att, OORenderMethod r vis md att)
  => Label -> r vis -> VS (r TypeData) -> [MS (r ParamData)] -> MS (r Body) -> MS (r md)
function :: forall (r :: * -> *) att vis md.
(AttachmentSym r att, OORenderMethod r vis md att) =>
ClassName
-> r vis
-> VS (r TypeData)
-> [MS (r ParamData)]
-> MS (r Body)
-> MS (r md)
function ClassName
n r vis
s VS (r TypeData)
t = Bool
-> ClassName
-> r vis
-> r att
-> MSMthdType r
-> [MS (r ParamData)]
-> MS (r Body)
-> MS (r md)
forall (r :: * -> *) vis md att.
OORenderMethod r vis md att =>
Bool
-> ClassName
-> r vis
-> r att
-> MSMthdType r
-> [MS (r ParamData)]
-> MS (r Body)
-> MS (r md)
RO.intFunc Bool
False ClassName
n r vis
s r att
forall (r :: * -> *) att. AttachmentSym r att => r att
classLevel (VS (r TypeData) -> MSMthdType r
forall (r :: * -> *).
MethodTypeSym r =>
VS (r TypeData) -> MSMthdType r
mType VS (r TypeData)
t)

docFuncRepr :: (RenderMethod r md) => FuncDocRenderer -> String ->
  [String] -> [String] -> MS (r md) -> MS (r md)
docFuncRepr :: forall (r :: * -> *) md.
RenderMethod r md =>
FuncDocRenderer
-> ClassName
-> [ClassName]
-> [ClassName]
-> MS (r md)
-> MS (r md)
docFuncRepr FuncDocRenderer
f ClassName
desc [ClassName]
pComms [ClassName]
rComms = MS (r Body) -> MS (r md) -> MS (r md)
forall (r :: * -> *) md.
RenderMethod r md =>
MS (r Body) -> MS (r md) -> MS (r md)
commentedFunc (State MethodState [ClassName] -> MS (r Body)
forall a. State a [ClassName] -> State a (r Body)
forall (r :: * -> *) a.
BlockCommentSym r =>
State a [ClassName] -> State a (r Body)
docComment (State MethodState [ClassName] -> MS (r Body))
-> State MethodState [ClassName] -> MS (r Body)
forall a b. (a -> b) -> a -> b
$ ([ClassName] -> [ClassName])
-> State MethodState [ClassName] -> State MethodState [ClassName]
forall a b s. (a -> b) -> State s a -> State s b
onStateValue
  (\[ClassName]
ps -> FuncDocRenderer
f ClassName
desc ([ClassName] -> [ClassName] -> [(ClassName, ClassName)]
forall a b. [a] -> [b] -> [(a, b)]
zip [ClassName]
ps [ClassName]
pComms) [ClassName]
rComms) State MethodState [ClassName]
getParameters)

docFunc :: (RenderMethod r md) => FuncDocRenderer -> String -> [String] ->
  Maybe String -> MS (r md) -> MS (r md)
docFunc :: forall (r :: * -> *) md.
RenderMethod r md =>
FuncDocRenderer
-> ClassName
-> [ClassName]
-> Maybe ClassName
-> MS (r md)
-> MS (r md)
docFunc FuncDocRenderer
f ClassName
desc [ClassName]
pComms Maybe ClassName
rComm = FuncDocRenderer
-> ClassName
-> [ClassName]
-> [ClassName]
-> MS (r md)
-> MS (r md)
forall (r :: * -> *) md.
RenderMethod r md =>
FuncDocRenderer
-> ClassName
-> [ClassName]
-> [ClassName]
-> MS (r md)
-> MS (r md)
docFuncRepr FuncDocRenderer
f ClassName
desc [ClassName]
pComms (Maybe ClassName -> [ClassName]
forall a. Maybe a -> [a]
maybeToList Maybe ClassName
rComm)

-- Classes --

buildClass
  :: (RenderClass r vis md svr, VisibilitySym r vis)
  =>  Maybe Label -> [CSStateVar r svr] -> [MS (r md)] -> [MS (r md)] -> CS (r Class)
buildClass :: forall (r :: * -> *) vis md svr.
(RenderClass r vis md svr, VisibilitySym r vis) =>
Maybe ClassName
-> [CSStateVar r svr] -> [MS (r md)] -> [MS (r md)] -> CS (r Body)
buildClass Maybe ClassName
p [CSStateVar r svr]
stVars [MS (r md)]
constructors [MS (r md)]
methods = do
  ClassName
n <- LensLike'
  (Zoomed (StateT FileState Identity) ClassName) ClassState FileState
-> StateT FileState Identity ClassName
-> StateT ClassState Identity ClassName
forall c.
LensLike'
  (Zoomed (StateT FileState Identity) c) ClassState FileState
-> StateT FileState Identity c -> StateT ClassState 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 FileState Identity) ClassName) ClassState FileState
(FileState -> Focusing Identity ClassName FileState)
-> ClassState -> Focusing Identity ClassName ClassState
Lens' ClassState FileState
lensCStoFS StateT FileState Identity ClassName
getModuleName
  ClassName
-> r vis
-> r Body
-> [CSStateVar r svr]
-> [MS (r md)]
-> [MS (r md)]
-> CS (r Body)
forall (r :: * -> *) vis md svr.
RenderClass r vis md svr =>
ClassName
-> r vis
-> r Body
-> [CSStateVar r svr]
-> [MS (r md)]
-> [MS (r md)]
-> CS (r Body)
RO.intClass ClassName
n r vis
forall (r :: * -> *) vis. VisibilitySym r vis => r vis
public (Maybe ClassName -> r Body
forall (r :: * -> *) vis md svr.
RenderClass r vis md svr =>
Maybe ClassName -> r Body
inherit Maybe ClassName
p) [CSStateVar r svr]
stVars [MS (r md)]
constructors [MS (r md)]
methods

implementingClass :: (RenderClass r vis md svr, VisibilitySym r vis) => Label -> [Label] ->
  [CSStateVar r svr] -> [MS (r md)] -> [MS (r md)] -> CS (r Class)
implementingClass :: forall (r :: * -> *) vis md svr.
(RenderClass r vis md svr, VisibilitySym r vis) =>
ClassName
-> [ClassName]
-> [CSStateVar r svr]
-> [MS (r md)]
-> [MS (r md)]
-> CS (r Body)
implementingClass ClassName
n [ClassName]
is = ClassName
-> r vis
-> r Body
-> [CSStateVar r svr]
-> [MS (r md)]
-> [MS (r md)]
-> CS (r Body)
forall (r :: * -> *) vis md svr.
RenderClass r vis md svr =>
ClassName
-> r vis
-> r Body
-> [CSStateVar r svr]
-> [MS (r md)]
-> [MS (r md)]
-> CS (r Body)
RO.intClass ClassName
n r vis
forall (r :: * -> *) vis. VisibilitySym r vis => r vis
public ([ClassName] -> r Body
forall (r :: * -> *) vis md svr.
RenderClass r vis md svr =>
[ClassName] -> r Body
implements [ClassName]
is)

docClass
  :: (RenderClass r vis md svr)
  => ClassDocRenderer -> String -> CS (r Class) -> CS (r Class)
docClass :: forall (r :: * -> *) vis md svr.
RenderClass r vis md svr =>
ClassDocRenderer -> ClassName -> CS (r Body) -> CS (r Body)
docClass ClassDocRenderer
cdr ClassName
d = CS (r Body) -> CS (r Body) -> CS (r Body)
forall (r :: * -> *) vis md svr.
RenderClass r vis md svr =>
CS (r Body) -> CS (r Body) -> CS (r Body)
RO.commentedClass (State ClassState [ClassName] -> CS (r Body)
forall a. State a [ClassName] -> State a (r Body)
forall (r :: * -> *) a.
BlockCommentSym r =>
State a [ClassName] -> State a (r Body)
docComment (State ClassState [ClassName] -> CS (r Body))
-> State ClassState [ClassName] -> CS (r Body)
forall a b. (a -> b) -> a -> b
$ [ClassName] -> State ClassState [ClassName]
forall a s. a -> State s a
toState ([ClassName] -> State ClassState [ClassName])
-> [ClassName] -> State ClassState [ClassName]
forall a b. (a -> b) -> a -> b
$ ClassDocRenderer
cdr ClassName
d)

commentedClass
  :: (RC.BlockCommentElim r, RO.ClassElim r, Monad r)
  => CS (r Doc) -> CS (r Class) -> CS (r Doc)
commentedClass :: forall (r :: * -> *).
(BlockCommentElim r, ClassElim r, Monad r) =>
CS (r Body) -> CS (r Body) -> CS (r Body)
commentedClass = (r Body -> r Body -> r Body)
-> State ClassState (r Body)
-> State ClassState (r Body)
-> State ClassState (r Body)
forall a b c s.
(a -> b -> c) -> State s a -> State s b -> State s c
on2StateValues (\r Body
cmt r Body
cs -> Body -> r Body
forall (r :: * -> *) a. Monad r => a -> r a
toCode (Body -> r Body) -> Body -> r Body
forall a b. (a -> b) -> a -> b
$ Body -> Body -> Body
R.commentedItem
  (r Body -> Body
forall (r :: * -> *). BlockCommentElim r => r Body -> Body
RC.blockComment' r Body
cmt) (r Body -> Body
forall (r :: * -> *). ClassElim r => r Body -> Body
RO.class' r Body
cs))

-- Modules --

modFromData :: Label -> (Doc -> r Module) -> FS Doc -> FS (r Module)
modFromData :: forall (r :: * -> *).
ClassName -> (Body -> r Module) -> FS Body -> FS (r Module)
modFromData ClassName
n Body -> r Module
f FS Body
d = (FileState -> FileState) -> StateT FileState Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (ClassName -> FileState -> FileState
setModuleName ClassName
n) StateT FileState Identity ()
-> StateT FileState Identity (r Module)
-> StateT FileState Identity (r Module)
forall a b.
StateT FileState Identity a
-> StateT FileState Identity b -> StateT FileState Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Body -> r Module)
-> FS Body -> StateT FileState Identity (r Module)
forall a b s. (a -> b) -> State s a -> State s b
onStateValue Body -> r Module
f FS Body
d

-- Files --

fileDoc
  :: (RC.BlockElim r, RenderMod r, RenderFile r)
  => String -> (r Module -> r Block) -> r Block -> FS (r Module) -> FS (r File)
fileDoc :: forall (r :: * -> *).
(BlockElim r, RenderMod r, RenderFile r) =>
ClassName
-> (r Module -> r Body) -> r Body -> FS (r Module) -> FS (r File)
fileDoc ClassName
ext r Module -> r Body
topb r Body
botb FS (r Module)
mdl = do
  r Module
m <- FS (r Module)
mdl
  ClassName
nm <- StateT FileState Identity ClassName
getModuleName
  let fp :: ClassName
fp = ClassName -> ClassName -> ClassName
addExt ClassName
ext ClassName
nm
      updm :: r Module
updm = (Body -> Body) -> r Module -> r Module
forall (r :: * -> *).
RenderMod r =>
(Body -> Body) -> r Module -> r Module
updateModuleDoc (\Body
d -> Body -> Body -> Body
emptyIfEmpty Body
d
        (Body -> Body -> Body -> Body
R.file (r Body -> Body
forall (r :: * -> *). BlockElim r => r Body -> Body
RC.block (r Body -> Body) -> r Body -> Body
forall a b. (a -> b) -> a -> b
$ r Module -> r Body
topb r Module
m) Body
d (r Body -> Body
forall (r :: * -> *). BlockElim r => r Body -> Body
RC.block r Body
botb))) r Module
m
  ClassName -> FS (r Module) -> FS (r File)
forall (r :: * -> *).
RenderFile r =>
ClassName -> FS (r Module) -> FS (r File)
RO.fileFromData ClassName
fp (r Module -> FS (r Module)
forall a s. a -> State s a
toState r Module
updm)

-- | Generates a file for a documented module.
--   mdr is a function that takes description, author, and module name and
--                                                     returns a doc comment
--   e is the file extension
--   d is the description (I think)
--   a is a list of authors
--   dt is the date
--   fl is the file
docMod
  :: (RenderFile r)
  => ModuleDocRenderer
  -> String
  -> String
  -> String
  -> [String]
  -> String
  -> FS (r File)
  -> FS (r File)
docMod :: forall (r :: * -> *).
RenderFile r =>
ModuleDocRenderer
-> ClassName
-> ClassName
-> ClassName
-> [ClassName]
-> ClassName
-> FS (r File)
-> FS (r File)
docMod ModuleDocRenderer
mdr ClassName
e ClassName
wm ClassName
d [ClassName]
a ClassName
dt FS (r File)
fl = FS (r File) -> FS (r Body) -> FS (r File)
forall (r :: * -> *).
RenderFile r =>
FS (r File) -> FS (r Body) -> FS (r File)
commentedMod FS (r File)
fl (State FileState [ClassName] -> FS (r Body)
forall a. State a [ClassName] -> State a (r Body)
forall (r :: * -> *) a.
BlockCommentSym r =>
State a [ClassName] -> State a (r Body)
docComment (State FileState [ClassName] -> FS (r Body))
-> State FileState [ClassName] -> FS (r Body)
forall a b. (a -> b) -> a -> b
$ ModuleDocRenderer
mdr ClassName
wm ClassName
d [ClassName]
a ClassName
dt ClassDocRenderer -> (ClassName -> ClassName) -> ClassDocRenderer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ClassName -> ClassName -> ClassName
addExt ClassName
e
  ClassDocRenderer
-> StateT FileState Identity ClassName
-> State FileState [ClassName]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT FileState Identity ClassName
getModuleName)

fileFromData
  :: (RO.ModuleElim r)
  => (FilePath -> r Module -> r File) -> FilePath -> FS (r Module) -> FS (r File)
fileFromData :: forall (r :: * -> *).
ModuleElim r =>
(ClassName -> r Module -> r File)
-> ClassName -> FS (r Module) -> FS (r File)
fileFromData ClassName -> r Module -> r File
f ClassName
fpath FS (r Module)
mdl' = do
  -- Add this file to list of files as long as it is not empty
  r Module
mdl <- FS (r Module)
mdl'
  (FileState -> FileState) -> StateT FileState Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\FileState
s -> if Body -> Bool
isEmpty (r Module -> Body
forall (r :: * -> *). ModuleElim r => r Module -> Body
RO.module' r Module
mdl)
    then FileState
s
    else ASetter FileState FileState GOOLState GOOLState
-> (GOOLState -> GOOLState) -> FileState -> FileState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter FileState FileState GOOLState GOOLState
Lens' FileState GOOLState
lensFStoGS (FileType -> ClassName -> GOOLState -> GOOLState
addFile (FileState
s FileState -> Getting FileType FileState FileType -> FileType
forall s a. s -> Getting a s a -> a
^. Getting FileType FileState FileType
Lens' FileState FileType
currFileType) ClassName
fpath) (FileState -> FileState) -> FileState -> FileState
forall a b. (a -> b) -> a -> b
$
      -- If this is the main source file, set it as the main module in the state
      if FileState
s FileState -> Getting Bool FileState Bool -> Bool
forall s a. s -> Getting a s a -> a
^. Getting Bool FileState Bool
Lens' FileState Bool
currMain Bool -> Bool -> Bool
&& FileType -> Bool
isSource (FileState
s FileState -> Getting FileType FileState FileType -> FileType
forall s a. s -> Getting a s a -> a
^. Getting FileType FileState FileType
Lens' FileState FileType
currFileType)
        then ASetter FileState FileState GOOLState GOOLState
-> (GOOLState -> GOOLState) -> FileState -> FileState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter FileState FileState GOOLState GOOLState
Lens' FileState GOOLState
lensFStoGS (ClassName -> GOOLState -> GOOLState
setMainMod ClassName
fpath) FileState
s
        else FileState
s)
  r File -> FS (r File)
forall a. a -> StateT FileState Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (r File -> FS (r File)) -> r File -> FS (r File)
forall a b. (a -> b) -> a -> b
$ ClassName -> r Module -> r File
f ClassName
fpath r Module
mdl

-- Helper functions

setEmpty :: (RenderStatement r smt, StatementElim r smt) => MS (r smt) -> MS (r smt)
setEmpty :: forall (r :: * -> *) smt.
(RenderStatement r smt, StatementElim r smt) =>
MS (r smt) -> MS (r smt)
setEmpty MS (r smt)
s' = MS (r smt)
s' MS (r smt) -> (r smt -> MS (r smt)) -> MS (r smt)
forall a b.
StateT MethodState Identity a
-> (a -> StateT MethodState Identity b)
-> StateT MethodState Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Body -> MS (r smt)
forall (r :: * -> *) smt.
RenderStatement r smt =>
Body -> MS (r smt)
mkStmtNoEnd (Body -> MS (r smt)) -> (r smt -> Body) -> r smt -> MS (r smt)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. r smt -> Body
forall (r :: * -> *) smt. StatementElim r smt => r smt -> Body
RC.statement