{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}

-- | The logic to render Julia code is contained in this module
module Drasil.GProc.LanguageRenderer.JuliaRenderer (
  -- * Julia Code Configuration -- defines syntax of all Julia code
  JuliaCode(..), jlName, jlVersion
) where

import Drasil.FileHandling.Legacy (indent)

import Drasil.Shared.CodeType (CodeType(..))
import Drasil.Shared.InterfaceCommon (UnRepr(..), SharedProg, SharedStatement,
  Label, Body, Value, SValue, Variable, SVariable, Block, BodySym(..),
  BlockSym(..), TypeSym(..), TypeElim(..), getTypeString, VariableSym(..),
  VariableElim(..), ValueSym(..), Argument(..), Literal(..), MathConstant(..),
  VariableValue(..), CommandLineArgs(..), NumericExpression(..),
  BooleanExpression(..), Comparison(..), ValueExpression(..), funcApp,
  extFuncApp, libFuncApp, IndexTranslator(..), Reference(..), Array(..), List(..), Set(..),
  NativeVector(..), InternalList(..), StatementSym(..), AssignStatement(..),
  DeclStatement(..), IOStatement(..), StringStatement(..), FunctionSym,
  FuncAppStatement(..), CommentStatement(..), ControlStatement(..),
  VisibilitySym(..), ScopeSym(..), ParameterSym(..), BinderSym(..),
  BinderElim(..), MethodSym(..), (&=), switchAsIf, convScope)
import Drasil.GProc.InterfaceProc (ProcProg, Module, ProgramSym(..), FileSym(..),
  ModuleSym(..))

import Drasil.Shared.RendererClassesCommon (CommonRenderSym, ImportSym(..),
  RenderBody(..), BodyElim, RenderBlock(..), BlockElim, RenderType(..),
  UnaryOpSym(..), BinaryOpSym(..), OpElim(uOpPrec, bOpPrec), RenderVariable(..),
  InternalVarElim(variableBind), RenderValue(..), ValueElim(..),
  InternalListFunc(..), RenderFunction(..), FunctionElim(functionType),
  InternalAssignStmt(..), InternalIOStmt(..), InternalControlStmt(..),
  RenderStatement(..), StatementElim(statementTerm), RenderVisibility(..),
  VisibilityElim, MethodTypeSym(..), RenderParam(..),
  ParamElim(parameterName, parameterType), RenderMethod(..), MethodElim,
  BlockCommentSym(..), BlockCommentElim, ScopeElim(..), InternalBinderElim(..))
import qualified Drasil.Shared.RendererClassesCommon as RC (import', body, block,
  uOp, bOp, variable, value, function, statement, visibility, parameter, method,
  blockComment')
import Drasil.GProc.RendererClassesProc (ProcRenderSym, RenderFile(..),
  RenderMod(..), ModuleElim, ProcRenderMethod(..))
import qualified Drasil.GProc.RendererClassesProc as RC (module')
import Drasil.Shared.LanguageRenderer (printLabel, listSep, listSep',
  parameterList, forLabel, inLabel, tryLabel, catchLabel,
  valueList, binderList)
import qualified Drasil.Shared.LanguageRenderer as R (sqrt, abs, log10, log,
  exp, sin, cos, tan, asin, acos, atan, floor, ceil, multiStmt, body,
  addComments, blockCmt, docCmt, commentedMod, commentedItem, break, continue,
  constDec', assign, subAssign, addAssign)
import Drasil.Shared.LanguageRenderer.Constructors (mkVal, mkStateVal, VSOp,
  unOpPrec, powerPrec, unExpr, unExpr', binExpr, multPrec, typeUnExpr,
  typeBinExpr, mkStmtNoEnd, typeFromData)
import Drasil.Shared.LanguageRenderer.LanguagePolymorphic (OptionalSpace(..))
import qualified Drasil.Shared.LanguageRenderer.LanguagePolymorphic as G (
  block, multiBlock, litChar, litDouble, litInt, litString, valueOf, negateOp,
  equalOp, notEqualOp, greaterOp, greaterEqualOp, lessOp, lessEqualOp, plusOp,
  minusOp, multOp, divideOp, moduloOp, call, funcAppMixedArgs, lambda,
  listAccess, tryCatch, csc, multiBody, sec, cot, stmt, loopStmt, emptyStmt,
  print, comment, valStmt, returnStmt, param, docFunc, throw, arg, argsList,
  ifCond, smartAdd, local, var, smartSub)
import Drasil.GProc.Renderers (renderType)

import qualified Drasil.Shared.LanguageRenderer.Common as CS

import qualified Drasil.Shared.LanguageRenderer.CommonPseudoOO as CP (listDec,
  listDecDef, listSet, notNull, functionDoc, intToIndex', indexToInt', inOutFunc,
  docInOutFunc', forLoopError, openFileR', openFileW', openFileA', multiReturn,
  multiAssign, inOutCall, mainBody, argExists, litSet)

import qualified Drasil.Shared.LanguageRenderer.CLike as C (litTrue, litFalse,
  notOp, andOp, orOp, inlineIf, while)

import qualified Drasil.GProc.LanguageRenderer.AbstractProc as A (fileDoc,
  fileFromData, buildModule, docMod, modFromData, listAppend, listAdd,
  innerType, arrayElem, funcDecDef, function)
import qualified Drasil.Shared.LanguageRenderer.Macros as M (increment1,
  decrement1, ifExists, stringListVals, stringListLists, arrayDecAsList)
import Drasil.Shared.AST (Terminator(..), FileType(..), fileD, FuncData(..),
  ModData(..), md, updateMod, MethodData(..), mthd, OpData(..), ParamData(..),
  ProgData(..), TypeData(..), ValData(..), vd, VarData(..), vard, progD, fd, pd,
  updateMthd, ScopeTag(..), ScopeData(..), sd, BinderD(..), bindFormD)
import Drasil.Shared.Helpers (vibcat, toCode, toState, onCodeValue, onStateValue,
  on2CodeValues, on2StateValues, onCodeList, onStateList, emptyIfEmpty)
import Drasil.Shared.State (FS, MS, VS, lensGStoFS, revFiles, setFileType,
  lensMStoVS, getModuleImports, addModuleImportVS, getLangImports, getLibImports,
  addLibImportVS, useVarName, getMainDoc, genVarNameIf, setVarScope, getVarScope)

import Prelude hiding (break,print,sin,cos,tan,floor,(<>))
import Data.Maybe (fromMaybe, isNothing)
import Data.Functor ((<&>))
import Control.Lens.Zoom (zoom)
import Control.Monad.State (modify)
import Data.List (intercalate, sort)
import Text.PrettyPrint.HughesPJ (Doc, text, (<>), (<+>), empty, brackets, vcat,
  quotes, doubleQuotes, parens, equals, colon)
import qualified Text.PrettyPrint.HughesPJ as D (float)

jlExt :: String
jlExt :: Label
jlExt = Label
"jl"

newtype JuliaCode a = JLC {forall a. JuliaCode a -> a
unJLC :: a} deriving (forall a b. (a -> b) -> JuliaCode a -> JuliaCode b)
-> (forall a b. a -> JuliaCode b -> JuliaCode a)
-> Functor JuliaCode
forall a b. a -> JuliaCode b -> JuliaCode a
forall a b. (a -> b) -> JuliaCode a -> JuliaCode b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> JuliaCode a -> JuliaCode b
fmap :: forall a b. (a -> b) -> JuliaCode a -> JuliaCode b
$c<$ :: forall a b. a -> JuliaCode b -> JuliaCode a
<$ :: forall a b. a -> JuliaCode b -> JuliaCode a
Functor

instance Applicative JuliaCode where
  pure :: forall a. a -> JuliaCode a
pure = a -> JuliaCode a
forall a. a -> JuliaCode a
JLC
  (JLC a -> b
f) <*> :: forall a b. JuliaCode (a -> b) -> JuliaCode a -> JuliaCode b
<*> (JLC a
x) = b -> JuliaCode b
forall a. a -> JuliaCode a
JLC (a -> b
f a
x)

instance Monad JuliaCode where
  JLC a
x >>= :: forall a b. JuliaCode a -> (a -> JuliaCode b) -> JuliaCode b
>>= a -> JuliaCode b
f = a -> JuliaCode b
f a
x

instance SharedProg JuliaCode Doc (Doc, Terminator) MethodData
instance SharedStatement JuliaCode (Doc, Terminator)
instance ProcProg JuliaCode Doc (Doc, Terminator) MethodData ProgData

instance ProgramSym JuliaCode Doc (Doc, Terminator) MethodData ProgData where
  prog :: Label
-> Label -> [FS (JuliaCode File)] -> GSProgram JuliaCode ProgData
prog Label
n Label
st [FS (JuliaCode File)]
files = do
    [JuliaCode File]
fs <- (FS (JuliaCode File) -> StateT GOOLState Identity (JuliaCode File))
-> [FS (JuliaCode File)]
-> StateT GOOLState Identity [JuliaCode File]
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 (LensLike'
  (Zoomed (StateT FileState Identity) (JuliaCode File))
  GOOLState
  FileState
-> FS (JuliaCode File)
-> StateT GOOLState Identity (JuliaCode File)
forall c.
LensLike'
  (Zoomed (StateT FileState Identity) c) GOOLState FileState
-> StateT FileState Identity c -> StateT GOOLState 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) (JuliaCode File))
  GOOLState
  FileState
(FileState -> Focusing Identity (JuliaCode File) FileState)
-> GOOLState -> Focusing Identity (JuliaCode File) GOOLState
Lens' GOOLState FileState
lensGStoFS) [FS (JuliaCode File)]
files
    (GOOLState -> GOOLState) -> StateT GOOLState Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify GOOLState -> GOOLState
revFiles
    JuliaCode ProgData -> GSProgram JuliaCode ProgData
forall a. a -> StateT GOOLState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (JuliaCode ProgData -> GSProgram JuliaCode ProgData)
-> JuliaCode ProgData -> GSProgram JuliaCode ProgData
forall a b. (a -> b) -> a -> b
$ ([File] -> ProgData) -> [JuliaCode File] -> JuliaCode ProgData
forall (m :: * -> *) a b. Monad m => ([a] -> b) -> [m a] -> m b
onCodeList (Label -> Label -> [File] -> ProgData
progD Label
n Label
st) [JuliaCode File]
fs

instance CommonRenderSym JuliaCode Doc (Doc, Terminator) MethodData
instance ProcRenderSym JuliaCode Doc (Doc, Terminator) MethodData

instance UnRepr JuliaCode inner where
  unRepr :: JuliaCode inner -> inner
unRepr = JuliaCode inner -> inner
forall a. JuliaCode a -> a
unJLC

instance FileSym JuliaCode Doc (Doc, Terminator) MethodData where
  fileDoc :: FS (JuliaCode Module) -> FS (JuliaCode File)
fileDoc FS (JuliaCode Module)
m = do
    (FileState -> FileState) -> StateT FileState Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (FileType -> FileState -> FileState
setFileType FileType
Combined)
    Label -> FS (JuliaCode Module) -> FS (JuliaCode File)
forall (r :: * -> *).
RenderFile r =>
Label -> FS (r Module) -> FS (r File)
A.fileDoc Label
jlExt FS (JuliaCode Module)
m
  docMod :: Label
-> Label
-> [Label]
-> Label
-> FS (JuliaCode File)
-> FS (JuliaCode File)
docMod = Label
-> Label
-> Label
-> [Label]
-> Label
-> FS (JuliaCode File)
-> FS (JuliaCode File)
forall (r :: * -> *).
RenderFile r =>
Label
-> Label -> Label -> [Label] -> Label -> FS (r File) -> FS (r File)
A.docMod Label
jlExt

instance RenderFile JuliaCode where
  top :: JuliaCode Module -> JuliaCode Doc
top JuliaCode Module
_ = Doc -> JuliaCode Doc
forall (r :: * -> *) a. Monad r => a -> r a
toCode Doc
empty
  bottom :: JuliaCode Doc
bottom = Doc -> JuliaCode Doc
forall (r :: * -> *) a. Monad r => a -> r a
toCode Doc
empty

  commentedMod :: FS (JuliaCode File) -> FS (JuliaCode Doc) -> FS (JuliaCode File)
commentedMod = (JuliaCode File -> JuliaCode Doc -> JuliaCode File)
-> FS (JuliaCode File) -> FS (JuliaCode Doc) -> FS (JuliaCode File)
forall a b c s.
(a -> b -> c) -> State s a -> State s b -> State s c
on2StateValues ((File -> Doc -> File)
-> JuliaCode File -> JuliaCode Doc -> JuliaCode File
forall (r :: * -> *) a b c.
Applicative r =>
(a -> b -> c) -> r a -> r b -> r c
on2CodeValues File -> Doc -> File
R.commentedMod)

  fileFromData :: Label -> FS (JuliaCode Module) -> FS (JuliaCode File)
fileFromData = (Label -> JuliaCode Module -> JuliaCode File)
-> Label -> FS (JuliaCode Module) -> FS (JuliaCode File)
forall (r :: * -> *).
ModuleElim r =>
(Label -> r Module -> r File)
-> Label -> FS (r Module) -> FS (r File)
A.fileFromData ((Module -> File) -> JuliaCode Module -> JuliaCode File
forall (r :: * -> *) a b. Functor r => (a -> b) -> r a -> r b
onCodeValue ((Module -> File) -> JuliaCode Module -> JuliaCode File)
-> (Label -> Module -> File)
-> Label
-> JuliaCode Module
-> JuliaCode File
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Label -> Module -> File
fileD)

instance ImportSym JuliaCode where
  langImport :: Label -> JuliaCode Doc
langImport Label
n = let modName :: Doc
modName = Label -> Doc
text Label
n
    in Doc -> JuliaCode Doc
forall (r :: * -> *) a. Monad r => a -> r a
toCode (Doc -> JuliaCode Doc) -> Doc -> JuliaCode Doc
forall a b. (a -> b) -> a -> b
$ Doc
importLabel Doc -> Doc -> Doc
<+> Doc
modName
  modImport :: Label -> JuliaCode Doc
modImport Label
n = let modName :: Doc
modName = Label -> Doc
text Label
n
                    fileName :: Doc
fileName = Label -> Doc
text (Label -> Doc) -> Label -> Doc
forall a b. (a -> b) -> a -> b
$ Label
n Label -> Label -> Label
forall a. [a] -> [a] -> [a]
++ Char
'.' Char -> Label -> Label
forall a. a -> [a] -> [a]
: Label
jlExt
    in Doc -> JuliaCode Doc
forall (r :: * -> *) a. Monad r => a -> r a
toCode (Doc -> JuliaCode Doc) -> Doc -> JuliaCode Doc
forall a b. (a -> b) -> a -> b
$ [Doc] -> Doc
vcat [Doc
includeLabel Doc -> Doc -> Doc
<> Doc -> Doc
parens (Doc -> Doc
doubleQuotes Doc
fileName),
                      Doc
importLabel Doc -> Doc -> Doc
<+> Label -> Doc
text Label
"." Doc -> Doc -> Doc
<> Doc
modName]

instance BodySym JuliaCode (Doc, Terminator) where
  body :: [MS (JuliaCode Doc)] -> MS (JuliaCode Doc)
body = ([JuliaCode Doc] -> JuliaCode Doc)
-> [MS (JuliaCode Doc)] -> MS (JuliaCode Doc)
forall a b s. ([a] -> b) -> [State s a] -> State s b
onStateList (([Doc] -> Doc) -> [JuliaCode Doc] -> JuliaCode Doc
forall (m :: * -> *) a b. Monad m => ([a] -> b) -> [m a] -> m b
onCodeList [Doc] -> Doc
R.body)

  addComments :: Label -> MS (JuliaCode Doc) -> MS (JuliaCode Doc)
addComments Label
s = (JuliaCode Doc -> JuliaCode Doc)
-> MS (JuliaCode Doc) -> MS (JuliaCode Doc)
forall a b s. (a -> b) -> State s a -> State s b
onStateValue ((Doc -> Doc) -> JuliaCode Doc -> JuliaCode Doc
forall (r :: * -> *) a b. Functor r => (a -> b) -> r a -> r b
onCodeValue (Label -> Doc -> Doc -> Doc
R.addComments Label
s Doc
jlCmtStart))

instance RenderBody JuliaCode where
  multiBody :: [MS (JuliaCode Doc)] -> MS (JuliaCode Doc)
multiBody = [MS (JuliaCode Doc)] -> MS (JuliaCode Doc)
forall (r :: * -> *).
(BodyElim r, Monad r) =>
[MS (r Doc)] -> MS (r Doc)
G.multiBody

instance BodyElim JuliaCode where
  body :: JuliaCode Doc -> Doc
body = JuliaCode Doc -> Doc
forall a. JuliaCode a -> a
unJLC

instance BlockSym JuliaCode (Doc, Terminator) where
  block :: [MS (JuliaCode (Doc, Terminator))] -> MS (JuliaCode Doc)
block = [MS (JuliaCode (Doc, Terminator))] -> MS (JuliaCode Doc)
forall (r :: * -> *) smt.
(Monad r, RenderStatement r smt, StatementElim r smt) =>
[MS (r smt)] -> MS (r Doc)
G.block

instance RenderBlock JuliaCode where
  multiBlock :: [MS (JuliaCode Doc)] -> MS (JuliaCode Doc)
multiBlock = [MS (JuliaCode Doc)] -> MS (JuliaCode Doc)
forall (r :: * -> *).
(BlockElim r, Monad r) =>
[MS (r Doc)] -> MS (r Doc)
G.multiBlock

instance BlockElim JuliaCode where
  block :: JuliaCode Doc -> Doc
block = JuliaCode Doc -> Doc
forall a. JuliaCode a -> a
unJLC

instance TypeSym JuliaCode where
  bool :: VS (JuliaCode TypeData)
bool = VS (JuliaCode TypeData)
forall (r :: * -> *). Monad r => VS (r TypeData)
CS.bool
  int :: VS (JuliaCode TypeData)
int = VS (JuliaCode TypeData)
forall (r :: * -> *). Monad r => VS (r TypeData)
jlIntType
  float :: VS (JuliaCode TypeData)
float = VS (JuliaCode TypeData)
forall (r :: * -> *). Monad r => VS (r TypeData)
jlFloatType
  double :: VS (JuliaCode TypeData)
double = VS (JuliaCode TypeData)
forall (r :: * -> *). Monad r => VS (r TypeData)
jlDoubleType
  char :: VS (JuliaCode TypeData)
char = VS (JuliaCode TypeData)
forall (r :: * -> *). Monad r => VS (r TypeData)
jlCharType
  string :: VS (JuliaCode TypeData)
string = VS (JuliaCode TypeData)
forall (r :: * -> *). Monad r => VS (r TypeData)
jlStringType
  infile :: VS (JuliaCode TypeData)
infile = VS (JuliaCode TypeData)
forall (r :: * -> *). Monad r => VS (r TypeData)
jlInfileType
  outfile :: VS (JuliaCode TypeData)
outfile = VS (JuliaCode TypeData)
forall (r :: * -> *). Monad r => VS (r TypeData)
jlOutfileType
  referenceType :: VS (JuliaCode TypeData) -> VS (JuliaCode TypeData)
referenceType = VS (JuliaCode TypeData) -> VS (JuliaCode TypeData)
forall a. a -> a
id -- Ignore reference types in "high-level" langauges for now; later on think about using boxed/unboxed types
  listType :: VS (JuliaCode TypeData) -> VS (JuliaCode TypeData)
listType = VS (JuliaCode TypeData) -> VS (JuliaCode TypeData)
forall (r :: * -> *).
(Monad r, TypeElim r, UnRepr r TypeData) =>
VS (r TypeData) -> VS (r TypeData)
jlListType
  setType :: VS (JuliaCode TypeData) -> VS (JuliaCode TypeData)
setType = VS (JuliaCode TypeData) -> VS (JuliaCode TypeData)
forall (r :: * -> *).
(Monad r, TypeElim r, UnRepr r TypeData) =>
VS (r TypeData) -> VS (r TypeData)
jlSetType
  arrayType :: VS (JuliaCode TypeData) -> VS (JuliaCode TypeData)
arrayType = VS (JuliaCode TypeData) -> VS (JuliaCode TypeData)
forall (r :: * -> *).
TypeSym r =>
VS (r TypeData) -> VS (r TypeData)
listType -- Treat arrays and lists the same, as in Python
  innerType :: VS (JuliaCode TypeData) -> VS (JuliaCode TypeData)
innerType = VS (JuliaCode TypeData) -> VS (JuliaCode TypeData)
forall (r :: * -> *).
TypeElim r =>
VS (r TypeData) -> VS (r TypeData)
A.innerType
  funcType :: [VS (JuliaCode TypeData)]
-> VS (JuliaCode TypeData) -> VS (JuliaCode TypeData)
funcType = [VS (JuliaCode TypeData)]
-> VS (JuliaCode TypeData) -> VS (JuliaCode TypeData)
forall (r :: * -> *).
(Monad r, TypeElim r) =>
[VS (r TypeData)] -> VS (r TypeData) -> VS (r TypeData)
CS.funcType
  void :: VS (JuliaCode TypeData)
void = VS (JuliaCode TypeData)
forall (r :: * -> *). Monad r => VS (r TypeData)
jlVoidType

instance TypeElim JuliaCode where
  getCodeType :: JuliaCode TypeData -> CodeType
getCodeType = TypeData -> CodeType
cType (TypeData -> CodeType)
-> (JuliaCode TypeData -> TypeData)
-> JuliaCode TypeData
-> CodeType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode TypeData -> TypeData
forall a. JuliaCode a -> a
unJLC

instance RenderType JuliaCode where
  multiType :: [VS (JuliaCode TypeData)] -> VS (JuliaCode TypeData)
multiType [VS (JuliaCode TypeData)]
ts = do
    [JuliaCode TypeData]
typs <- [VS (JuliaCode TypeData)]
-> StateT ValueState Identity [JuliaCode TypeData]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence [VS (JuliaCode TypeData)]
ts
    let mt :: Label
mt = [Label] -> Label
jlTuple ([Label] -> Label) -> [Label] -> Label
forall a b. (a -> b) -> a -> b
$ (JuliaCode TypeData -> Label) -> [JuliaCode TypeData] -> [Label]
forall a b. (a -> b) -> [a] -> [b]
map JuliaCode TypeData -> Label
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Label
getTypeString [JuliaCode TypeData]
typs
    CodeType -> Label -> Doc -> VS (JuliaCode TypeData)
forall (r :: * -> *).
Monad r =>
CodeType -> Label -> Doc -> VS (r TypeData)
typeFromData CodeType
Void Label
mt (Label -> Doc
text Label
mt)

instance UnaryOpSym JuliaCode where
  notOp :: VSUnOp JuliaCode
notOp = VSUnOp JuliaCode
forall (r :: * -> *). Monad r => VSOp r
C.notOp
  negateOp :: VSUnOp JuliaCode
negateOp = VSUnOp JuliaCode
forall (r :: * -> *). Monad r => VSOp r
G.negateOp
  sqrtOp :: VSUnOp JuliaCode
sqrtOp = Label -> VSUnOp JuliaCode
forall (r :: * -> *). Monad r => Label -> VSOp r
jlUnaryMath Label
R.sqrt
  absOp :: VSUnOp JuliaCode
absOp = Label -> VSUnOp JuliaCode
forall (r :: * -> *). Monad r => Label -> VSOp r
jlUnaryMath Label
R.abs
  logOp :: VSUnOp JuliaCode
logOp = Label -> VSUnOp JuliaCode
forall (r :: * -> *). Monad r => Label -> VSOp r
jlUnaryMath Label
R.log10
  lnOp :: VSUnOp JuliaCode
lnOp = Label -> VSUnOp JuliaCode
forall (r :: * -> *). Monad r => Label -> VSOp r
jlUnaryMath Label
R.log
  expOp :: VSUnOp JuliaCode
expOp = Label -> VSUnOp JuliaCode
forall (r :: * -> *). Monad r => Label -> VSOp r
jlUnaryMath Label
R.exp
  sinOp :: VSUnOp JuliaCode
sinOp = Label -> VSUnOp JuliaCode
forall (r :: * -> *). Monad r => Label -> VSOp r
jlUnaryMath Label
R.sin
  cosOp :: VSUnOp JuliaCode
cosOp = Label -> VSUnOp JuliaCode
forall (r :: * -> *). Monad r => Label -> VSOp r
jlUnaryMath Label
R.cos
  tanOp :: VSUnOp JuliaCode
tanOp = Label -> VSUnOp JuliaCode
forall (r :: * -> *). Monad r => Label -> VSOp r
jlUnaryMath Label
R.tan
  asinOp :: VSUnOp JuliaCode
asinOp = Label -> VSUnOp JuliaCode
forall (r :: * -> *). Monad r => Label -> VSOp r
jlUnaryMath Label
R.asin
  acosOp :: VSUnOp JuliaCode
acosOp = Label -> VSUnOp JuliaCode
forall (r :: * -> *). Monad r => Label -> VSOp r
jlUnaryMath Label
R.acos
  atanOp :: VSUnOp JuliaCode
atanOp = Label -> VSUnOp JuliaCode
forall (r :: * -> *). Monad r => Label -> VSOp r
jlUnaryMath Label
R.atan
  floorOp :: VSUnOp JuliaCode
floorOp = Label -> VSUnOp JuliaCode
forall (r :: * -> *). Monad r => Label -> VSOp r
jlUnaryMath Label
R.floor
  ceilOp :: VSUnOp JuliaCode
ceilOp = Label -> VSUnOp JuliaCode
forall (r :: * -> *). Monad r => Label -> VSOp r
jlUnaryMath Label
R.ceil

instance BinaryOpSym JuliaCode where
  equalOp :: VSUnOp JuliaCode
equalOp = VSUnOp JuliaCode
forall (r :: * -> *). Monad r => VSOp r
G.equalOp
  notEqualOp :: VSUnOp JuliaCode
notEqualOp = VSUnOp JuliaCode
forall (r :: * -> *). Monad r => VSOp r
G.notEqualOp
  greaterOp :: VSUnOp JuliaCode
greaterOp = VSUnOp JuliaCode
forall (r :: * -> *). Monad r => VSOp r
G.greaterOp
  greaterEqualOp :: VSUnOp JuliaCode
greaterEqualOp = VSUnOp JuliaCode
forall (r :: * -> *). Monad r => VSOp r
G.greaterEqualOp
  lessOp :: VSUnOp JuliaCode
lessOp = VSUnOp JuliaCode
forall (r :: * -> *). Monad r => VSOp r
G.lessOp
  lessEqualOp :: VSUnOp JuliaCode
lessEqualOp = VSUnOp JuliaCode
forall (r :: * -> *). Monad r => VSOp r
G.lessEqualOp
  plusOp :: VSUnOp JuliaCode
plusOp = VSUnOp JuliaCode
forall (r :: * -> *). Monad r => VSOp r
G.plusOp
  minusOp :: VSUnOp JuliaCode
minusOp = VSUnOp JuliaCode
forall (r :: * -> *). Monad r => VSOp r
G.minusOp
  multOp :: VSUnOp JuliaCode
multOp = VSUnOp JuliaCode
forall (r :: * -> *). Monad r => VSOp r
G.multOp
  divideOp :: VSUnOp JuliaCode
divideOp = VSUnOp JuliaCode
forall (r :: * -> *). Monad r => VSOp r
G.divideOp
  powerOp :: VSUnOp JuliaCode
powerOp = Label -> VSUnOp JuliaCode
forall (r :: * -> *). Monad r => Label -> VSOp r
powerPrec Label
jlPower
  moduloOp :: VSUnOp JuliaCode
moduloOp = VSUnOp JuliaCode
forall (r :: * -> *). Monad r => VSOp r
G.moduloOp
  andOp :: VSUnOp JuliaCode
andOp = VSUnOp JuliaCode
forall (r :: * -> *). Monad r => VSOp r
C.andOp
  orOp :: VSUnOp JuliaCode
orOp = VSUnOp JuliaCode
forall (r :: * -> *). Monad r => VSOp r
C.orOp

instance OpElim JuliaCode where
  uOp :: JuliaCode OpData -> Doc
uOp = OpData -> Doc
opDoc (OpData -> Doc)
-> (JuliaCode OpData -> OpData) -> JuliaCode OpData -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode OpData -> OpData
forall a. JuliaCode a -> a
unJLC
  bOp :: JuliaCode OpData -> Doc
bOp = OpData -> Doc
opDoc (OpData -> Doc)
-> (JuliaCode OpData -> OpData) -> JuliaCode OpData -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode OpData -> OpData
forall a. JuliaCode a -> a
unJLC
  uOpPrec :: JuliaCode OpData -> Int
uOpPrec = OpData -> Int
opPrec (OpData -> Int)
-> (JuliaCode OpData -> OpData) -> JuliaCode OpData -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode OpData -> OpData
forall a. JuliaCode a -> a
unJLC
  bOpPrec :: JuliaCode OpData -> Int
bOpPrec = OpData -> Int
opPrec (OpData -> Int)
-> (JuliaCode OpData -> OpData) -> JuliaCode OpData -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode OpData -> OpData
forall a. JuliaCode a -> a
unJLC

instance ScopeSym JuliaCode where
  global :: JuliaCode ScopeData
global = ScopeData -> JuliaCode ScopeData
forall (r :: * -> *) a. Monad r => a -> r a
toCode (ScopeData -> JuliaCode ScopeData)
-> ScopeData -> JuliaCode ScopeData
forall a b. (a -> b) -> a -> b
$ ScopeTag -> ScopeData
sd ScopeTag
Global
  mainFn :: JuliaCode ScopeData
mainFn = JuliaCode ScopeData
forall (r :: * -> *). ScopeSym r => r ScopeData
global
  local :: JuliaCode ScopeData
local = JuliaCode ScopeData
forall (r :: * -> *). Monad r => r ScopeData
G.local

instance ScopeElim JuliaCode where
  scopeData :: JuliaCode ScopeData -> ScopeData
scopeData = JuliaCode ScopeData -> ScopeData
forall a. JuliaCode a -> a
unJLC

instance VariableSym JuliaCode where
  var :: Label -> VS (JuliaCode TypeData) -> SVariable JuliaCode
var = Label -> VS (JuliaCode TypeData) -> SVariable JuliaCode
forall (r :: * -> *).
RenderVariable r =>
Label -> VS (r TypeData) -> SVariable r
G.var
  constant :: Label -> VS (JuliaCode TypeData) -> SVariable JuliaCode
constant = Label -> VS (JuliaCode TypeData) -> SVariable JuliaCode
forall (r :: * -> *).
VariableSym r =>
Label -> VS (r TypeData) -> SVariable r
var
  extVar :: Label -> Label -> VS (JuliaCode TypeData) -> SVariable JuliaCode
extVar Label
l Label
n VS (JuliaCode TypeData)
t = (ValueState -> ValueState) -> StateT ValueState Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (Label -> ValueState -> ValueState
addModuleImportVS Label
l) StateT ValueState Identity ()
-> SVariable JuliaCode -> SVariable JuliaCode
forall a b.
StateT ValueState Identity a
-> StateT ValueState Identity b -> StateT ValueState Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Label -> Label -> VS (JuliaCode TypeData) -> SVariable JuliaCode
forall (r :: * -> *).
RenderVariable r =>
Label -> Label -> VS (r TypeData) -> SVariable r
CS.extVar Label
l Label
n VS (JuliaCode TypeData)
t

instance VariableElim JuliaCode where
  variableName :: JuliaCode Variable -> Label
variableName = Variable -> Label
varName (Variable -> Label)
-> (JuliaCode Variable -> Variable) -> JuliaCode Variable -> Label
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode Variable -> Variable
forall a. JuliaCode a -> a
unJLC
  variableType :: JuliaCode Variable -> JuliaCode TypeData
variableType = (Variable -> TypeData) -> JuliaCode Variable -> JuliaCode TypeData
forall (r :: * -> *) a b. Functor r => (a -> b) -> r a -> r b
onCodeValue Variable -> TypeData
varType

instance InternalVarElim JuliaCode where
  variableBind :: JuliaCode Variable -> AttachmentTag
variableBind = Variable -> AttachmentTag
varBind (Variable -> AttachmentTag)
-> (JuliaCode Variable -> Variable)
-> JuliaCode Variable
-> AttachmentTag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode Variable -> Variable
forall a. JuliaCode a -> a
unJLC
  variable :: JuliaCode Variable -> Doc
variable = Variable -> Doc
varDoc (Variable -> Doc)
-> (JuliaCode Variable -> Variable) -> JuliaCode Variable -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode Variable -> Variable
forall a. JuliaCode a -> a
unJLC

instance RenderVariable JuliaCode where
  varFromData :: AttachmentTag
-> Label -> VS (JuliaCode TypeData) -> Doc -> SVariable JuliaCode
varFromData AttachmentTag
b Label
n VS (JuliaCode TypeData)
t' Doc
d = do
    JuliaCode TypeData
t <- VS (JuliaCode TypeData)
t'
    JuliaCode Variable -> SVariable JuliaCode
forall a s. a -> State s a
toState (JuliaCode Variable -> SVariable JuliaCode)
-> JuliaCode Variable -> SVariable JuliaCode
forall a b. (a -> b) -> a -> b
$ (TypeData -> Doc -> Variable)
-> JuliaCode TypeData -> JuliaCode Doc -> JuliaCode Variable
forall (r :: * -> *) a b c.
Applicative r =>
(a -> b -> c) -> r a -> r b -> r c
on2CodeValues (AttachmentTag -> Label -> TypeData -> Doc -> Variable
vard AttachmentTag
b Label
n) JuliaCode TypeData
t (Doc -> JuliaCode Doc
forall (r :: * -> *) a. Monad r => a -> r a
toCode Doc
d)

instance ValueSym JuliaCode where
  valueType :: JuliaCode Value -> JuliaCode TypeData
valueType JuliaCode Value
v = Value -> TypeData
valType (Value -> TypeData) -> JuliaCode Value -> JuliaCode TypeData
forall (r :: * -> *) a b. Functor r => (a -> b) -> r a -> r b
<$> JuliaCode Value
v

instance Argument JuliaCode where
  pointerArg :: SValue JuliaCode -> SValue JuliaCode
pointerArg = SValue JuliaCode -> SValue JuliaCode
forall a. a -> a
id

instance Literal JuliaCode where
  litTrue :: SValue JuliaCode
litTrue = SValue JuliaCode
forall (r :: * -> *). (RenderValue r, TypeSym r) => SValue r
C.litTrue
  litFalse :: SValue JuliaCode
litFalse = SValue JuliaCode
forall (r :: * -> *). (RenderValue r, TypeSym r) => SValue r
C.litFalse
  litChar :: Char -> SValue JuliaCode
litChar = (Doc -> Doc) -> Char -> SValue JuliaCode
forall (r :: * -> *).
(RenderValue r, TypeSym r) =>
(Doc -> Doc) -> Char -> SValue r
G.litChar Doc -> Doc
quotes
  litDouble :: Double -> SValue JuliaCode
litDouble = Double -> SValue JuliaCode
forall (r :: * -> *).
(RenderValue r, TypeSym r) =>
Double -> SValue r
G.litDouble
  litFloat :: Float -> SValue JuliaCode
litFloat = Float -> SValue JuliaCode
forall (r :: * -> *).
(RenderValue r, TypeSym r) =>
Float -> SValue r
jlLitFloat
  litInt :: Integer -> SValue JuliaCode
litInt = Integer -> SValue JuliaCode
forall (r :: * -> *).
(RenderValue r, TypeSym r) =>
Integer -> SValue r
G.litInt
  litString :: Label -> SValue JuliaCode
litString = Label -> SValue JuliaCode
forall (r :: * -> *).
(RenderValue r, TypeSym r) =>
Label -> SValue r
G.litString
  litArray :: VS (JuliaCode TypeData) -> [SValue JuliaCode] -> SValue JuliaCode
litArray = VS (JuliaCode TypeData) -> [SValue JuliaCode] -> SValue JuliaCode
forall (r :: * -> *).
Literal r =>
VS (r TypeData) -> [SValue r] -> SValue r
litList
  litList :: VS (JuliaCode TypeData) -> [SValue JuliaCode] -> SValue JuliaCode
litList = VS (JuliaCode TypeData) -> [SValue JuliaCode] -> SValue JuliaCode
jlLitList
  litSet :: VS (JuliaCode TypeData) -> [SValue JuliaCode] -> SValue JuliaCode
litSet = (Doc -> Doc)
-> (Doc -> Doc)
-> VS (JuliaCode TypeData)
-> [SValue JuliaCode]
-> SValue JuliaCode
forall (r :: * -> *).
(RenderValue r, TypeSym r, ValueElim r) =>
(Doc -> Doc)
-> (Doc -> Doc) -> VS (r TypeData) -> [SValue r] -> SValue r
CP.litSet (Label -> Doc
text Label
"Set" Doc -> Doc -> Doc
<>) (Doc -> Doc
parens (Doc -> Doc) -> (Doc -> Doc) -> Doc -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc -> Doc
brackets)

instance MathConstant JuliaCode where
  pi :: SValue JuliaCode
  pi :: SValue JuliaCode
pi = VS (JuliaCode TypeData) -> Doc -> SValue JuliaCode
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Doc -> SValue r
mkStateVal VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
double Doc
jlPi

instance VariableValue JuliaCode where
  valueOf :: SVariable JuliaCode -> SValue JuliaCode
valueOf = SVariable JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(InternalVarElim r, RenderValue r, VariableElim r) =>
SVariable r -> SValue r
G.valueOf

instance CommandLineArgs JuliaCode where
  arg :: Integer -> SValue JuliaCode
arg Integer
n = SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(RenderValue r, TypeSym r, ValueElim r) =>
SValue r -> SValue r -> SValue r
G.arg (Integer -> SValue JuliaCode
forall (r :: * -> *). Literal r => Integer -> SValue r
litInt (Integer -> SValue JuliaCode) -> Integer -> SValue JuliaCode
forall a b. (a -> b) -> a -> b
$ Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1) SValue JuliaCode
forall (r :: * -> *). CommandLineArgs r => SValue r
argsList
  argsList :: SValue JuliaCode
argsList = Label -> SValue JuliaCode
forall (r :: * -> *).
(RenderValue r, TypeSym r) =>
Label -> SValue r
G.argsList Label
jlArgs
  argExists :: Integer -> SValue JuliaCode
argExists = Integer -> SValue JuliaCode
forall (r :: * -> *) smt.
SharedStatement r smt =>
Integer -> SValue r
CP.argExists

instance NumericExpression JuliaCode where
  #~ :: SValue JuliaCode -> SValue JuliaCode
(#~) = VSUnOp JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r, ValueSym r) =>
VSUnOp r -> SValue r -> SValue r
unExpr' VSUnOp JuliaCode
forall (r :: * -> *). UnaryOpSym r => VSUnOp r
negateOp
  #/^ :: SValue JuliaCode -> SValue JuliaCode
(#/^) = VSUnOp JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r, ValueSym r) =>
VSUnOp r -> SValue r -> SValue r
unExpr VSUnOp JuliaCode
forall (r :: * -> *). UnaryOpSym r => VSUnOp r
sqrtOp
  #| :: SValue JuliaCode -> SValue JuliaCode
(#|) = VSUnOp JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r, ValueSym r) =>
VSUnOp r -> SValue r -> SValue r
unExpr VSUnOp JuliaCode
forall (r :: * -> *). UnaryOpSym r => VSUnOp r
absOp
  #+ :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
(#+) = VSUnOp JuliaCode
-> SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, TypeElim r, ValueElim r, ValueSym r) =>
VSBinOp r -> SValue r -> SValue r -> SValue r
binExpr VSUnOp JuliaCode
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
plusOp
  #- :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
(#-) = VSUnOp JuliaCode
-> SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, TypeElim r, ValueElim r, ValueSym r) =>
VSBinOp r -> SValue r -> SValue r -> SValue r
binExpr VSUnOp JuliaCode
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
minusOp
  #* :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
(#*) = VSUnOp JuliaCode
-> SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, TypeElim r, ValueElim r, ValueSym r) =>
VSBinOp r -> SValue r -> SValue r -> SValue r
binExpr VSUnOp JuliaCode
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
multOp
  #/ :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
(#/) SValue JuliaCode
v1' SValue JuliaCode
v2' = do -- Julia has integer division via `÷` or `div()`
    JuliaCode Value
v1 <- SValue JuliaCode
v1'
    JuliaCode Value
v2 <- SValue JuliaCode
v2'
    let jlDivision :: CodeType -> CodeType -> SValue r -> SValue r -> SValue r
jlDivision CodeType
Integer CodeType
Integer = VSBinOp r -> SValue r -> SValue r -> SValue r
forall (r :: * -> *).
(OpElim r, RenderValue r, TypeElim r, ValueElim r, ValueSym r) =>
VSBinOp r -> SValue r -> SValue r -> SValue r
binExpr (Label -> VSBinOp r
forall (r :: * -> *). Monad r => Label -> VSOp r
multPrec Label
jlIntDiv)
        jlDivision CodeType
_ CodeType
_ = VSBinOp r -> SValue r -> SValue r -> SValue r
forall (r :: * -> *).
(OpElim r, RenderValue r, TypeElim r, ValueElim r, ValueSym r) =>
VSBinOp r -> SValue r -> SValue r -> SValue r
binExpr VSBinOp r
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
divideOp
    CodeType
-> CodeType
-> SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
forall {r :: * -> *}.
(OpElim r, RenderValue r, TypeElim r, ValueElim r, ValueSym r,
 Monad r, BinaryOpSym r) =>
CodeType -> CodeType -> SValue r -> SValue r -> SValue r
jlDivision (JuliaCode TypeData -> CodeType
forall (r :: * -> *). TypeElim r => r TypeData -> CodeType
getCodeType (JuliaCode TypeData -> CodeType) -> JuliaCode TypeData -> CodeType
forall a b. (a -> b) -> a -> b
$ JuliaCode Value -> JuliaCode TypeData
forall (r :: * -> *). ValueSym r => r Value -> r TypeData
valueType JuliaCode Value
v1) (JuliaCode TypeData -> CodeType
forall (r :: * -> *). TypeElim r => r TypeData -> CodeType
getCodeType (JuliaCode TypeData -> CodeType) -> JuliaCode TypeData -> CodeType
forall a b. (a -> b) -> a -> b
$ JuliaCode Value -> JuliaCode TypeData
forall (r :: * -> *). ValueSym r => r Value -> r TypeData
valueType JuliaCode Value
v2)
        (JuliaCode Value -> SValue JuliaCode
forall a. a -> StateT ValueState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JuliaCode Value
v1) (JuliaCode Value -> SValue JuliaCode
forall a. a -> StateT ValueState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JuliaCode Value
v2)
  #% :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
(#%) = VSUnOp JuliaCode
-> SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, TypeElim r, ValueElim r, ValueSym r) =>
VSBinOp r -> SValue r -> SValue r -> SValue r
binExpr VSUnOp JuliaCode
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
moduloOp
  #^ :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
(#^) = VSUnOp JuliaCode
-> SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, TypeElim r, ValueElim r, ValueSym r) =>
VSBinOp r -> SValue r -> SValue r -> SValue r
binExpr VSUnOp JuliaCode
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
powerOp

  log :: SValue JuliaCode -> SValue JuliaCode
log = VSUnOp JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r, ValueSym r) =>
VSUnOp r -> SValue r -> SValue r
unExpr VSUnOp JuliaCode
forall (r :: * -> *). UnaryOpSym r => VSUnOp r
logOp
  ln :: SValue JuliaCode -> SValue JuliaCode
ln = VSUnOp JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r, ValueSym r) =>
VSUnOp r -> SValue r -> SValue r
unExpr VSUnOp JuliaCode
forall (r :: * -> *). UnaryOpSym r => VSUnOp r
lnOp
  exp :: SValue JuliaCode -> SValue JuliaCode
exp = VSUnOp JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r, ValueSym r) =>
VSUnOp r -> SValue r -> SValue r
unExpr VSUnOp JuliaCode
forall (r :: * -> *). UnaryOpSym r => VSUnOp r
expOp
  sin :: SValue JuliaCode -> SValue JuliaCode
sin = VSUnOp JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r, ValueSym r) =>
VSUnOp r -> SValue r -> SValue r
unExpr VSUnOp JuliaCode
forall (r :: * -> *). UnaryOpSym r => VSUnOp r
sinOp
  cos :: SValue JuliaCode -> SValue JuliaCode
cos = VSUnOp JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r, ValueSym r) =>
VSUnOp r -> SValue r -> SValue r
unExpr VSUnOp JuliaCode
forall (r :: * -> *). UnaryOpSym r => VSUnOp r
cosOp
  tan :: SValue JuliaCode -> SValue JuliaCode
tan = VSUnOp JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r, ValueSym r) =>
VSUnOp r -> SValue r -> SValue r
unExpr VSUnOp JuliaCode
forall (r :: * -> *). UnaryOpSym r => VSUnOp r
tanOp
  csc :: SValue JuliaCode -> SValue JuliaCode
csc = SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(Literal r, NumericExpression r, TypeElim r) =>
SValue r -> SValue r
G.csc
  sec :: SValue JuliaCode -> SValue JuliaCode
sec = SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(Literal r, NumericExpression r, TypeElim r) =>
SValue r -> SValue r
G.sec
  cot :: SValue JuliaCode -> SValue JuliaCode
cot = SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(Literal r, NumericExpression r, TypeElim r) =>
SValue r -> SValue r
G.cot
  arcsin :: SValue JuliaCode -> SValue JuliaCode
arcsin = VSUnOp JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r, ValueSym r) =>
VSUnOp r -> SValue r -> SValue r
unExpr VSUnOp JuliaCode
forall (r :: * -> *). UnaryOpSym r => VSUnOp r
asinOp
  arccos :: SValue JuliaCode -> SValue JuliaCode
arccos = VSUnOp JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r, ValueSym r) =>
VSUnOp r -> SValue r -> SValue r
unExpr VSUnOp JuliaCode
forall (r :: * -> *). UnaryOpSym r => VSUnOp r
acosOp
  arctan :: SValue JuliaCode -> SValue JuliaCode
arctan = VSUnOp JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r, ValueSym r) =>
VSUnOp r -> SValue r -> SValue r
unExpr VSUnOp JuliaCode
forall (r :: * -> *). UnaryOpSym r => VSUnOp r
atanOp
  floor :: SValue JuliaCode -> SValue JuliaCode
floor = VSUnOp JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r, ValueSym r) =>
VSUnOp r -> SValue r -> SValue r
unExpr VSUnOp JuliaCode
forall (r :: * -> *). UnaryOpSym r => VSUnOp r
floorOp
  ceil :: SValue JuliaCode -> SValue JuliaCode
ceil = VSUnOp JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r, ValueSym r) =>
VSUnOp r -> SValue r -> SValue r
unExpr VSUnOp JuliaCode
forall (r :: * -> *). UnaryOpSym r => VSUnOp r
ceilOp

instance BooleanExpression JuliaCode where
  ?! :: SValue JuliaCode -> SValue JuliaCode
(?!) = VSUnOp JuliaCode
-> VS (JuliaCode TypeData) -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r) =>
VSUnOp r -> VS (r TypeData) -> SValue r -> SValue r
typeUnExpr VSUnOp JuliaCode
forall (r :: * -> *). UnaryOpSym r => VSUnOp r
notOp VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
bool
  ?&& :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
(?&&) = VSUnOp JuliaCode
-> VS (JuliaCode TypeData)
-> SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r) =>
VSBinOp r -> VS (r TypeData) -> SValue r -> SValue r -> SValue r
typeBinExpr VSUnOp JuliaCode
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
andOp VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
bool
  ?|| :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
(?||) = VSUnOp JuliaCode
-> VS (JuliaCode TypeData)
-> SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r) =>
VSBinOp r -> VS (r TypeData) -> SValue r -> SValue r -> SValue r
typeBinExpr VSUnOp JuliaCode
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
orOp VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
bool

instance Comparison JuliaCode where
  ?< :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
(?<) = VSUnOp JuliaCode
-> VS (JuliaCode TypeData)
-> SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r) =>
VSBinOp r -> VS (r TypeData) -> SValue r -> SValue r -> SValue r
typeBinExpr VSUnOp JuliaCode
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
lessOp VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
bool
  ?<= :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
(?<=) = VSUnOp JuliaCode
-> VS (JuliaCode TypeData)
-> SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r) =>
VSBinOp r -> VS (r TypeData) -> SValue r -> SValue r -> SValue r
typeBinExpr VSUnOp JuliaCode
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
lessEqualOp VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
bool
  ?> :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
(?>) = VSUnOp JuliaCode
-> VS (JuliaCode TypeData)
-> SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r) =>
VSBinOp r -> VS (r TypeData) -> SValue r -> SValue r -> SValue r
typeBinExpr VSUnOp JuliaCode
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
greaterOp VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
bool
  ?>= :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
(?>=) = VSUnOp JuliaCode
-> VS (JuliaCode TypeData)
-> SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r) =>
VSBinOp r -> VS (r TypeData) -> SValue r -> SValue r -> SValue r
typeBinExpr VSUnOp JuliaCode
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
greaterEqualOp VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
bool
  ?== :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
(?==) = VSUnOp JuliaCode
-> VS (JuliaCode TypeData)
-> SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r) =>
VSBinOp r -> VS (r TypeData) -> SValue r -> SValue r -> SValue r
typeBinExpr VSUnOp JuliaCode
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
equalOp VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
bool
  ?!= :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
(?!=) = VSUnOp JuliaCode
-> VS (JuliaCode TypeData)
-> SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, ValueElim r) =>
VSBinOp r -> VS (r TypeData) -> SValue r -> SValue r -> SValue r
typeBinExpr VSUnOp JuliaCode
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
notEqualOp VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
bool

instance ValueExpression JuliaCode where
  inlineIf :: SValue JuliaCode
-> SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
inlineIf = SValue JuliaCode
-> SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(RenderValue r, ValueElim r, ValueSym r) =>
SValue r -> SValue r -> SValue r -> SValue r
C.inlineIf

  funcAppMixedArgs :: MixedCall JuliaCode
funcAppMixedArgs = MixedCall JuliaCode
forall (r :: * -> *). RenderValue r => MixedCall r
G.funcAppMixedArgs
  extFuncAppMixedArgs :: Label -> MixedCall JuliaCode
extFuncAppMixedArgs Label
l Label
n VS (JuliaCode TypeData)
t [SValue JuliaCode]
ps NamedArgs JuliaCode
ns = do
    (ValueState -> ValueState) -> StateT ValueState Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (Label -> ValueState -> ValueState
addModuleImportVS Label
l)
    Label -> MixedCall JuliaCode
forall (r :: * -> *). RenderValue r => Label -> MixedCall r
CS.extFuncAppMixedArgs Label
l Label
n VS (JuliaCode TypeData)
t [SValue JuliaCode]
ps NamedArgs JuliaCode
ns
  libFuncAppMixedArgs :: Label -> MixedCall JuliaCode
libFuncAppMixedArgs Label
l Label
n VS (JuliaCode TypeData)
t [SValue JuliaCode]
ps NamedArgs JuliaCode
ns = do
    (ValueState -> ValueState) -> StateT ValueState Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (Label -> ValueState -> ValueState
addLibImportVS Label
l)
    Label -> MixedCall JuliaCode
forall (r :: * -> *). RenderValue r => Label -> MixedCall r
CS.extFuncAppMixedArgs Label
l Label
n VS (JuliaCode TypeData)
t [SValue JuliaCode]
ps NamedArgs JuliaCode
ns

  lambda :: [VSBinder JuliaCode] -> SValue JuliaCode -> SValue JuliaCode
lambda = ([JuliaCode BinderD] -> JuliaCode Value -> Doc)
-> [VSBinder JuliaCode] -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(BinderElim r, RenderValue r, ValueSym r) =>
([r BinderD] -> r Value -> Doc)
-> [VSBinder r] -> SValue r -> SValue r
G.lambda [JuliaCode BinderD] -> JuliaCode Value -> Doc
forall (r :: * -> *).
(InternalBinderElim r, ValueElim r) =>
[r BinderD] -> r Value -> Doc
jlLambda

  notNull :: SValue JuliaCode -> SValue JuliaCode
notNull = Label -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(Comparison r, VariableValue r) =>
Label -> SValue r -> SValue r
CP.notNull Label
jlNull

instance RenderValue JuliaCode where
  inputFunc :: SValue JuliaCode
inputFunc = VS (JuliaCode TypeData) -> Doc -> SValue JuliaCode
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Doc -> SValue r
mkStateVal VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
string (Doc
jlReadLine Doc -> Doc -> Doc
<> Doc -> Doc
parens Doc
empty)
  printFunc :: SValue JuliaCode
printFunc = VS (JuliaCode TypeData) -> Doc -> SValue JuliaCode
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Doc -> SValue r
mkStateVal VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
void Doc
jlPrintFunc
  printLnFunc :: SValue JuliaCode
printLnFunc = VS (JuliaCode TypeData) -> Doc -> SValue JuliaCode
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Doc -> SValue r
mkStateVal VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
void Doc
jlPrintLnFunc
  printFileFunc :: SValue JuliaCode -> SValue JuliaCode
printFileFunc SValue JuliaCode
_ = VS (JuliaCode TypeData) -> Doc -> SValue JuliaCode
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Doc -> SValue r
mkStateVal VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
void Doc
empty
  printFileLnFunc :: SValue JuliaCode -> SValue JuliaCode
printFileLnFunc SValue JuliaCode
_ = VS (JuliaCode TypeData) -> Doc -> SValue JuliaCode
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Doc -> SValue r
mkStateVal VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
void Doc
empty

  cast :: VS (JuliaCode TypeData) -> SValue JuliaCode -> SValue JuliaCode
cast = VS (JuliaCode TypeData) -> SValue JuliaCode -> SValue JuliaCode
jlCast

  call :: Maybe Label -> Maybe Doc -> MixedCall JuliaCode
call = Doc -> Maybe Label -> Maybe Doc -> MixedCall JuliaCode
forall (r :: * -> *).
(InternalVarElim r, RenderValue r, ValueElim r) =>
Doc -> Maybe Label -> Maybe Doc -> MixedCall r
G.call Doc
jlNamedArgSep

  valFromData :: Maybe Int
-> Maybe Integer
-> VS (JuliaCode TypeData)
-> Doc
-> SValue JuliaCode
valFromData Maybe Int
p Maybe Integer
i VS (JuliaCode TypeData)
t' Doc
d = do
    JuliaCode TypeData
t <- VS (JuliaCode TypeData)
t'
    JuliaCode Value -> SValue JuliaCode
forall a s. a -> State s a
toState (JuliaCode Value -> SValue JuliaCode)
-> JuliaCode Value -> SValue JuliaCode
forall a b. (a -> b) -> a -> b
$ (TypeData -> Doc -> Value)
-> JuliaCode TypeData -> JuliaCode Doc -> JuliaCode Value
forall (r :: * -> *) a b c.
Applicative r =>
(a -> b -> c) -> r a -> r b -> r c
on2CodeValues (Maybe Int -> Maybe Integer -> TypeData -> Doc -> Value
vd Maybe Int
p Maybe Integer
i) JuliaCode TypeData
t (Doc -> JuliaCode Doc
forall (r :: * -> *) a. Monad r => a -> r a
toCode Doc
d)

instance ValueElim JuliaCode where
  valuePrec :: JuliaCode Value -> Maybe Int
valuePrec = Value -> Maybe Int
valPrec (Value -> Maybe Int)
-> (JuliaCode Value -> Value) -> JuliaCode Value -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode Value -> Value
forall a. JuliaCode a -> a
unJLC
  valueInt :: JuliaCode Value -> Maybe Integer
valueInt = Value -> Maybe Integer
valInt (Value -> Maybe Integer)
-> (JuliaCode Value -> Value) -> JuliaCode Value -> Maybe Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode Value -> Value
forall a. JuliaCode a -> a
unJLC
  value :: JuliaCode Value -> Doc
value = Value -> Doc
val (Value -> Doc)
-> (JuliaCode Value -> Value) -> JuliaCode Value -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode Value -> Value
forall a. JuliaCode a -> a
unJLC

instance IndexTranslator JuliaCode where
  intToIndex :: SValue JuliaCode -> SValue JuliaCode
intToIndex = SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(Literal r, NumericExpression r, RenderValue r, ValueElim r) =>
SValue r -> SValue r
CP.intToIndex'
  indexToInt :: SValue JuliaCode -> SValue JuliaCode
indexToInt = SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(Literal r, NumericExpression r, RenderValue r, ValueElim r) =>
SValue r -> SValue r
CP.indexToInt'

instance Reference JuliaCode where
  makeRef :: SValue JuliaCode -> SValue JuliaCode
makeRef = SValue JuliaCode -> SValue JuliaCode
forall a. a -> a
id
  maybeDeref :: SValue JuliaCode -> SValue JuliaCode
maybeDeref = SValue JuliaCode -> SValue JuliaCode
forall a. a -> a
id

instance Array JuliaCode where
  arrayElem :: SValue JuliaCode -> SValue JuliaCode -> SVariable JuliaCode
arrayElem = SValue JuliaCode -> SValue JuliaCode -> SVariable JuliaCode
forall (r :: * -> *).
(IndexTranslator r, RenderVariable r, TypeElim r, ValueElim r) =>
SValue r -> SValue r -> SVariable r
A.arrayElem
  arrayLength :: SValue JuliaCode -> SValue JuliaCode
arrayLength = SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *) smt. List r smt => SValue r -> SValue r
listSize
  arrayCopy :: SValue JuliaCode -> SValue JuliaCode
arrayCopy SValue JuliaCode
arr = let
    arrTp :: VS (JuliaCode TypeData)
arrTp = (JuliaCode Value -> JuliaCode TypeData)
-> SValue JuliaCode -> VS (JuliaCode TypeData)
forall a b s. (a -> b) -> State s a -> State s b
onStateValue JuliaCode Value -> JuliaCode TypeData
forall (r :: * -> *). ValueSym r => r Value -> r TypeData
valueType SValue JuliaCode
arr
    in PosCall JuliaCode
forall (r :: * -> *). ValueExpression r => PosCall r
funcApp Label
"copy" VS (JuliaCode TypeData)
arrTp [SValue JuliaCode
arr]

instance List JuliaCode (Doc, Terminator) where
  listSize :: SValue JuliaCode -> SValue JuliaCode
listSize = Label -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
ValueExpression r =>
Label -> SValue r -> SValue r
CS.listSize Label
jlListSize
  listAdd :: SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
listAdd = Label
-> SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(IndexTranslator r, StatementSym r smt, ValueExpression r) =>
Label -> SValue r -> SValue r -> SValue r -> MS (r smt)
A.listAdd Label
jlListAdd
  listAppend :: SValue JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
listAppend = Label
-> SValue JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(StatementSym r smt, ValueExpression r) =>
Label -> SValue r -> SValue r -> MS (r smt)
A.listAppend Label
jlListAppend
  listAccess :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
listAccess = SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(IndexTranslator r, InternalListFunc r, FunctionElim r,
 RenderFunction r, RenderValue r, TypeElim r, ValueElim r) =>
SValue r -> SValue r -> SValue r
G.listAccess
  listSet :: SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
listSet = SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(AssignStatement r smt, IndexTranslator r, RenderVariable r,
 ValueElim r) =>
SValue r -> SValue r -> SValue r -> MS (r smt)
CP.listSet
  indexOf :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
indexOf = SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(IndexTranslator r, ValueExpression r, BinderSym r,
 VariableValue r, Comparison r) =>
SValue r -> SValue r -> SValue r
jlIndexOf

instance Set JuliaCode where
  contains :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
contains SValue JuliaCode
s SValue JuliaCode
e = PosCall JuliaCode
forall (r :: * -> *). ValueExpression r => PosCall r
funcApp Label
"in" VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
bool [SValue JuliaCode
e, SValue JuliaCode
s]
  setAdd :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
setAdd SValue JuliaCode
s SValue JuliaCode
e = PosCall JuliaCode
forall (r :: * -> *). ValueExpression r => PosCall r
funcApp Label
"push!" VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
void [SValue JuliaCode
s, SValue JuliaCode
e]
  setRemove :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
setRemove SValue JuliaCode
s SValue JuliaCode
e = PosCall JuliaCode
forall (r :: * -> *). ValueExpression r => PosCall r
funcApp Label
"delete!" VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
void [SValue JuliaCode
s, SValue JuliaCode
e]
  setUnion :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
setUnion SValue JuliaCode
a SValue JuliaCode
b = PosCall JuliaCode
forall (r :: * -> *). ValueExpression r => PosCall r
funcApp Label
"union!" VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
void [SValue JuliaCode
a, SValue JuliaCode
b]

instance NativeVector JuliaCode where
  vecScale :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
vecScale = VSUnOp JuliaCode
-> SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, TypeElim r, ValueElim r, ValueSym r) =>
VSBinOp r -> SValue r -> SValue r -> SValue r
binExpr VSUnOp JuliaCode
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
multOp
  vecAdd :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
vecAdd   = VSUnOp JuliaCode
-> SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(OpElim r, RenderValue r, TypeElim r, ValueElim r, ValueSym r) =>
VSBinOp r -> SValue r -> SValue r -> SValue r
binExpr VSUnOp JuliaCode
forall (r :: * -> *). BinaryOpSym r => VSBinOp r
plusOp
  vecIndex :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
vecIndex = SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(IndexTranslator r, InternalListFunc r, FunctionElim r,
 RenderFunction r, RenderValue r, TypeElim r, ValueElim r) =>
SValue r -> SValue r -> SValue r
G.listAccess
  vecDot :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
vecDot SValue JuliaCode
a SValue JuliaCode
b = Label -> PosCall JuliaCode
forall (r :: * -> *). ValueExpression r => Label -> PosCall r
libFuncApp Label
"LinearAlgebra" Label
"dot" VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
double [SValue JuliaCode
a, SValue JuliaCode
b]
  vecMag :: SValue JuliaCode -> SValue JuliaCode
vecMag SValue JuliaCode
a   = Label -> PosCall JuliaCode
forall (r :: * -> *). ValueExpression r => Label -> PosCall r
libFuncApp Label
"LinearAlgebra" Label
"norm" VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
double [SValue JuliaCode
a]
  vecUnit :: SValue JuliaCode -> SValue JuliaCode
vecUnit SValue JuliaCode
a  = SValue JuliaCode
a SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
NumericExpression r =>
SValue r -> SValue r -> SValue r
#/ SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *). NativeVector r => SValue r -> SValue r
vecMag SValue JuliaCode
a

instance InternalList JuliaCode where
  listSlice' :: Maybe (SValue JuliaCode)
-> Maybe (SValue JuliaCode)
-> Maybe (SValue JuliaCode)
-> SVariable JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode Doc)
listSlice' Maybe (SValue JuliaCode)
b Maybe (SValue JuliaCode)
e Maybe (SValue JuliaCode)
s SVariable JuliaCode
vn SValue JuliaCode
vo = SVariable JuliaCode
-> SValue JuliaCode
-> Maybe (SValue JuliaCode)
-> Maybe (SValue JuliaCode)
-> SValue JuliaCode
-> MS (JuliaCode Doc)
jlListSlice SVariable JuliaCode
vn SValue JuliaCode
vo Maybe (SValue JuliaCode)
b Maybe (SValue JuliaCode)
e (SValue JuliaCode -> Maybe (SValue JuliaCode) -> SValue JuliaCode
forall a. a -> Maybe a -> a
fromMaybe (Integer -> SValue JuliaCode
forall (r :: * -> *). Literal r => Integer -> SValue r
litInt Integer
1) Maybe (SValue JuliaCode)
s)

instance InternalListFunc JuliaCode where
  listAccessFunc :: VS (JuliaCode TypeData)
-> SValue JuliaCode -> VS (JuliaCode FuncData)
listAccessFunc = VS (JuliaCode TypeData)
-> SValue JuliaCode -> VS (JuliaCode FuncData)
forall (r :: * -> *).
(RenderFunction r, TypeElim r, ValueElim r, ValueSym r) =>
VS (r TypeData) -> SValue r -> VS (r FuncData)
CS.listAccessFunc

instance BinderSym JuliaCode where
  binder :: Label -> VS (JuliaCode TypeData) -> VSBinder JuliaCode
binder Label
nm VS (JuliaCode TypeData)
tp = (TypeData -> BinderD) -> JuliaCode TypeData -> JuliaCode BinderD
forall (r :: * -> *) a b. Functor r => (a -> b) -> r a -> r b
onCodeValue (Label -> TypeData -> BinderD
bindFormD Label
nm) (JuliaCode TypeData -> JuliaCode BinderD)
-> VS (JuliaCode TypeData) -> VSBinder JuliaCode
forall (r :: * -> *) a b. Functor r => (a -> b) -> r a -> r b
<$> VS (JuliaCode TypeData)
tp

instance BinderElim JuliaCode where
  binderName :: JuliaCode BinderD -> Label
binderName = BinderD -> Label
bindName (BinderD -> Label)
-> (JuliaCode BinderD -> BinderD) -> JuliaCode BinderD -> Label
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode BinderD -> BinderD
forall a. JuliaCode a -> a
unJLC
  binderType :: JuliaCode BinderD -> JuliaCode TypeData
binderType = (BinderD -> TypeData) -> JuliaCode BinderD -> JuliaCode TypeData
forall (r :: * -> *) a b. Functor r => (a -> b) -> r a -> r b
onCodeValue BinderD -> TypeData
bindType

instance InternalBinderElim JuliaCode where
  binderElim :: JuliaCode BinderD -> Doc
binderElim = Label -> Doc
text (Label -> Doc)
-> (JuliaCode BinderD -> Label) -> JuliaCode BinderD -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BinderD -> Label
bindName (BinderD -> Label)
-> (JuliaCode BinderD -> BinderD) -> JuliaCode BinderD -> Label
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode BinderD -> BinderD
forall a. JuliaCode a -> a
unJLC

instance RenderFunction JuliaCode where
  funcFromData :: Doc -> VS (JuliaCode TypeData) -> VS (JuliaCode FuncData)
funcFromData Doc
d = (JuliaCode TypeData -> JuliaCode FuncData)
-> VS (JuliaCode TypeData) -> VS (JuliaCode FuncData)
forall a b s. (a -> b) -> State s a -> State s b
onStateValue ((JuliaCode TypeData -> JuliaCode FuncData)
 -> VS (JuliaCode TypeData) -> VS (JuliaCode FuncData))
-> (JuliaCode TypeData -> JuliaCode FuncData)
-> VS (JuliaCode TypeData)
-> VS (JuliaCode FuncData)
forall a b. (a -> b) -> a -> b
$ (TypeData -> FuncData) -> JuliaCode TypeData -> JuliaCode FuncData
forall (r :: * -> *) a b. Functor r => (a -> b) -> r a -> r b
onCodeValue (TypeData -> Doc -> FuncData
`fd` Doc
d)

instance FunctionElim JuliaCode where
  functionType :: JuliaCode FuncData -> JuliaCode TypeData
functionType = (FuncData -> TypeData) -> JuliaCode FuncData -> JuliaCode TypeData
forall (r :: * -> *) a b. Functor r => (a -> b) -> r a -> r b
onCodeValue FuncData -> TypeData
fType
  function :: JuliaCode FuncData -> Doc
function = FuncData -> Doc
funcDoc (FuncData -> Doc)
-> (JuliaCode FuncData -> FuncData) -> JuliaCode FuncData -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode FuncData -> FuncData
forall a. JuliaCode a -> a
unJLC

instance InternalAssignStmt JuliaCode (Doc, Terminator) where
  multiAssign :: [SVariable JuliaCode]
-> [SValue JuliaCode] -> MS (JuliaCode (Doc, Terminator))
multiAssign = (Doc -> Doc)
-> [SVariable JuliaCode]
-> [SValue JuliaCode]
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(AssignStatement r smt, InternalVarElim r, RenderValue r,
 RenderVariable r, ValueElim r) =>
(Doc -> Doc) -> [SVariable r] -> [SValue r] -> MS (r smt)
CP.multiAssign Doc -> Doc
forall a. a -> a
id

instance InternalIOStmt JuliaCode (Doc, Terminator) where
  printSt :: Bool
-> Maybe (SValue JuliaCode)
-> SValue JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
printSt = Bool
-> Maybe (SValue JuliaCode)
-> SValue JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
jlPrint

instance InternalControlStmt JuliaCode (Doc, Terminator) where
  multiReturn :: [SValue JuliaCode] -> MS (JuliaCode (Doc, Terminator))
multiReturn = (Doc -> Doc)
-> [SValue JuliaCode] -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(ControlStatement r smt, RenderValue r, ValueElim r) =>
(Doc -> Doc) -> [SValue r] -> MS (r smt)
CP.multiReturn Doc -> Doc
forall a. a -> a
id

instance RenderStatement JuliaCode (Doc, Terminator) where
  stmt :: MS (JuliaCode (Doc, Terminator))
-> MS (JuliaCode (Doc, Terminator))
stmt = MS (JuliaCode (Doc, Terminator))
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(RenderStatement r smt, StatementElim r smt) =>
MS (r smt) -> MS (r smt)
G.stmt
  loopStmt :: MS (JuliaCode (Doc, Terminator))
-> MS (JuliaCode (Doc, Terminator))
loopStmt = MS (JuliaCode (Doc, Terminator))
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(RenderStatement r smt, StatementElim r smt) =>
MS (r smt) -> MS (r smt)
G.loopStmt
  stmtFromData :: Doc -> Terminator -> MS (JuliaCode (Doc, Terminator))
stmtFromData Doc
d Terminator
t = JuliaCode (Doc, Terminator) -> MS (JuliaCode (Doc, Terminator))
forall a s. a -> State s a
toState (JuliaCode (Doc, Terminator) -> MS (JuliaCode (Doc, Terminator)))
-> JuliaCode (Doc, Terminator) -> MS (JuliaCode (Doc, Terminator))
forall a b. (a -> b) -> a -> b
$ (Doc, Terminator) -> JuliaCode (Doc, Terminator)
forall (r :: * -> *) a. Monad r => a -> r a
toCode (Doc
d, Terminator
t)

instance StatementElim JuliaCode (Doc, Terminator) where
  statement :: JuliaCode (Doc, Terminator) -> Doc
statement = (Doc, Terminator) -> Doc
forall a b. (a, b) -> a
fst ((Doc, Terminator) -> Doc)
-> (JuliaCode (Doc, Terminator) -> (Doc, Terminator))
-> JuliaCode (Doc, Terminator)
-> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode (Doc, Terminator) -> (Doc, Terminator)
forall a. JuliaCode a -> a
unJLC
  statementTerm :: JuliaCode (Doc, Terminator) -> Terminator
statementTerm = (Doc, Terminator) -> Terminator
forall a b. (a, b) -> b
snd ((Doc, Terminator) -> Terminator)
-> (JuliaCode (Doc, Terminator) -> (Doc, Terminator))
-> JuliaCode (Doc, Terminator)
-> Terminator
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode (Doc, Terminator) -> (Doc, Terminator)
forall a. JuliaCode a -> a
unJLC

instance StatementSym JuliaCode (Doc, Terminator) where
  valStmt :: SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
valStmt = Terminator -> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(RenderStatement r smt, ValueElim r) =>
Terminator -> SValue r -> MS (r smt)
G.valStmt Terminator
Empty
  emptyStmt :: MS (JuliaCode (Doc, Terminator))
emptyStmt = MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt. RenderStatement r smt => MS (r smt)
G.emptyStmt
  multi :: [MS (JuliaCode (Doc, Terminator))]
-> MS (JuliaCode (Doc, Terminator))
multi = ([JuliaCode (Doc, Terminator)] -> JuliaCode (Doc, Terminator))
-> [MS (JuliaCode (Doc, Terminator))]
-> MS (JuliaCode (Doc, Terminator))
forall a b s. ([a] -> b) -> [State s a] -> State s b
onStateList (([(Doc, Terminator)] -> (Doc, Terminator))
-> [JuliaCode (Doc, Terminator)] -> JuliaCode (Doc, Terminator)
forall (m :: * -> *) a b. Monad m => ([a] -> b) -> [m a] -> m b
onCodeList [(Doc, Terminator)] -> (Doc, Terminator)
R.multiStmt)

instance AssignStatement JuliaCode (Doc, Terminator) where
  assign :: SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
assign = SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
jlAssign
  &-= :: SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
(&-=) = SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
jlSubAssign
  &+= :: SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
(&+=) = SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
jlIncrement
  &++ :: SVariable JuliaCode -> MS (JuliaCode (Doc, Terminator))
(&++) = SVariable JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(AssignStatement r smt, Literal r) =>
SVariable r -> MS (r smt)
M.increment1
  &-- :: SVariable JuliaCode -> MS (JuliaCode (Doc, Terminator))
(&--) = SVariable JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(AssignStatement r smt, Literal r) =>
SVariable r -> MS (r smt)
M.decrement1

instance DeclStatement JuliaCode (Doc, Terminator) where
  varDec :: SVariable JuliaCode
-> JuliaCode ScopeData -> MS (JuliaCode (Doc, Terminator))
varDec SVariable JuliaCode
v JuliaCode ScopeData
scp = SVariable JuliaCode
-> JuliaCode ScopeData
-> Maybe (SValue JuliaCode)
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(AssignStatement r smt, ScopeElim r, VariableElim r) =>
SVariable r -> r ScopeData -> Maybe (SValue r) -> MS (r smt)
CS.varDecDef SVariable JuliaCode
v JuliaCode ScopeData
scp Maybe (SValue JuliaCode)
forall a. Maybe a
Nothing
  varDecDef :: SVariable JuliaCode
-> JuliaCode ScopeData
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
varDecDef SVariable JuliaCode
v JuliaCode ScopeData
scp SValue JuliaCode
e = SVariable JuliaCode
-> JuliaCode ScopeData
-> Maybe (SValue JuliaCode)
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(AssignStatement r smt, ScopeElim r, VariableElim r) =>
SVariable r -> r ScopeData -> Maybe (SValue r) -> MS (r smt)
CS.varDecDef SVariable JuliaCode
v JuliaCode ScopeData
scp (SValue JuliaCode -> Maybe (SValue JuliaCode)
forall a. a -> Maybe a
Just SValue JuliaCode
e)
  setDec :: SVariable JuliaCode
-> JuliaCode ScopeData -> MS (JuliaCode (Doc, Terminator))
setDec = SVariable JuliaCode
-> JuliaCode ScopeData -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
DeclStatement r smt =>
SVariable r -> r ScopeData -> MS (r smt)
varDec
  setDecDef :: SVariable JuliaCode
-> JuliaCode ScopeData
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
setDecDef = SVariable JuliaCode
-> JuliaCode ScopeData
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
DeclStatement r smt =>
SVariable r -> r ScopeData -> SValue r -> MS (r smt)
varDecDef
  listDec :: Integer
-> SVariable JuliaCode
-> JuliaCode ScopeData
-> MS (JuliaCode (Doc, Terminator))
listDec Integer
_ = SVariable JuliaCode
-> JuliaCode ScopeData -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(DeclStatement r smt, Literal r, VariableElim r) =>
SVariable r -> r ScopeData -> MS (r smt)
CP.listDec
  listDecDef :: SVariable JuliaCode
-> JuliaCode ScopeData
-> [SValue JuliaCode]
-> MS (JuliaCode (Doc, Terminator))
listDecDef = SVariable JuliaCode
-> JuliaCode ScopeData
-> [SValue JuliaCode]
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(DeclStatement r smt, Literal r, VariableElim r) =>
SVariable r -> r ScopeData -> [SValue r] -> MS (r smt)
CP.listDecDef
  arrayDec :: Integer
-> SValue JuliaCode
-> SVariable JuliaCode
-> JuliaCode ScopeData
-> MS (JuliaCode (Doc, Terminator))
arrayDec = Integer
-> SValue JuliaCode
-> SVariable JuliaCode
-> JuliaCode ScopeData
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(SharedStatement r smt, VariableElim r) =>
Integer -> SValue r -> SVariable r -> r ScopeData -> MS (r smt)
M.arrayDecAsList
  arrayDecDef :: SVariable JuliaCode
-> JuliaCode ScopeData
-> [SValue JuliaCode]
-> MS (JuliaCode (Doc, Terminator))
arrayDecDef = SVariable JuliaCode
-> JuliaCode ScopeData
-> [SValue JuliaCode]
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
DeclStatement r smt =>
SVariable r -> r ScopeData -> [SValue r] -> MS (r smt)
listDecDef
  constDecDef :: SVariable JuliaCode
-> JuliaCode ScopeData
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
constDecDef = SVariable JuliaCode
-> JuliaCode ScopeData
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
jlConstDecDef
  funcDecDef :: SVariable JuliaCode
-> JuliaCode ScopeData
-> [SVariable JuliaCode]
-> MS (JuliaCode Doc)
-> MS (JuliaCode (Doc, Terminator))
funcDecDef = SVariable JuliaCode
-> JuliaCode ScopeData
-> [SVariable JuliaCode]
-> MS (JuliaCode Doc)
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) vis smt md.
ProcRenderSym r vis smt md =>
SVariable r
-> r ScopeData -> [SVariable r] -> MS (r Doc) -> MS (r smt)
A.funcDecDef

instance IOStatement JuliaCode (Doc, Terminator) where
  print :: SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
print      = Bool
-> Maybe (SValue JuliaCode)
-> SValue JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(InternalIOStmt r smt, SharedStatement r smt, TypeElim r) =>
Bool -> Maybe (SValue r) -> SValue r -> SValue r -> MS (r smt)
jlOut Bool
False Maybe (SValue JuliaCode)
forall a. Maybe a
Nothing SValue JuliaCode
forall (r :: * -> *). RenderValue r => SValue r
printFunc
  printLn :: SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
printLn    = Bool
-> Maybe (SValue JuliaCode)
-> SValue JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(InternalIOStmt r smt, SharedStatement r smt, TypeElim r) =>
Bool -> Maybe (SValue r) -> SValue r -> SValue r -> MS (r smt)
jlOut Bool
True  Maybe (SValue JuliaCode)
forall a. Maybe a
Nothing SValue JuliaCode
forall (r :: * -> *). RenderValue r => SValue r
printLnFunc
  printStr :: Label -> MS (JuliaCode (Doc, Terminator))
printStr   = Bool
-> Maybe (SValue JuliaCode)
-> SValue JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(InternalIOStmt r smt, SharedStatement r smt, TypeElim r) =>
Bool -> Maybe (SValue r) -> SValue r -> SValue r -> MS (r smt)
jlOut Bool
False Maybe (SValue JuliaCode)
forall a. Maybe a
Nothing SValue JuliaCode
forall (r :: * -> *). RenderValue r => SValue r
printFunc   (SValue JuliaCode -> MS (JuliaCode (Doc, Terminator)))
-> (Label -> SValue JuliaCode)
-> Label
-> MS (JuliaCode (Doc, Terminator))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Label -> SValue JuliaCode
forall (r :: * -> *). Literal r => Label -> SValue r
litString
  printStrLn :: Label -> MS (JuliaCode (Doc, Terminator))
printStrLn = Bool
-> Maybe (SValue JuliaCode)
-> SValue JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(InternalIOStmt r smt, SharedStatement r smt, TypeElim r) =>
Bool -> Maybe (SValue r) -> SValue r -> SValue r -> MS (r smt)
jlOut Bool
True  Maybe (SValue JuliaCode)
forall a. Maybe a
Nothing SValue JuliaCode
forall (r :: * -> *). RenderValue r => SValue r
printLnFunc (SValue JuliaCode -> MS (JuliaCode (Doc, Terminator)))
-> (Label -> SValue JuliaCode)
-> Label
-> MS (JuliaCode (Doc, Terminator))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Label -> SValue JuliaCode
forall (r :: * -> *). Literal r => Label -> SValue r
litString

  printFile :: SValue JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
printFile SValue JuliaCode
f      = Bool
-> Maybe (SValue JuliaCode)
-> SValue JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(InternalIOStmt r smt, SharedStatement r smt, TypeElim r) =>
Bool -> Maybe (SValue r) -> SValue r -> SValue r -> MS (r smt)
jlOut Bool
False (SValue JuliaCode -> Maybe (SValue JuliaCode)
forall a. a -> Maybe a
Just SValue JuliaCode
f) SValue JuliaCode
forall (r :: * -> *). RenderValue r => SValue r
printFunc
  printFileLn :: SValue JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
printFileLn SValue JuliaCode
f    = Bool
-> Maybe (SValue JuliaCode)
-> SValue JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(InternalIOStmt r smt, SharedStatement r smt, TypeElim r) =>
Bool -> Maybe (SValue r) -> SValue r -> SValue r -> MS (r smt)
jlOut Bool
True (SValue JuliaCode -> Maybe (SValue JuliaCode)
forall a. a -> Maybe a
Just SValue JuliaCode
f) SValue JuliaCode
forall (r :: * -> *). RenderValue r => SValue r
printLnFunc
  printFileStr :: SValue JuliaCode -> Label -> MS (JuliaCode (Doc, Terminator))
printFileStr SValue JuliaCode
f   = SValue JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
IOStatement r smt =>
SValue r -> SValue r -> MS (r smt)
printFile   SValue JuliaCode
f (SValue JuliaCode -> MS (JuliaCode (Doc, Terminator)))
-> (Label -> SValue JuliaCode)
-> Label
-> MS (JuliaCode (Doc, Terminator))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Label -> SValue JuliaCode
forall (r :: * -> *). Literal r => Label -> SValue r
litString
  printFileStrLn :: SValue JuliaCode -> Label -> MS (JuliaCode (Doc, Terminator))
printFileStrLn SValue JuliaCode
f = SValue JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
IOStatement r smt =>
SValue r -> SValue r -> MS (r smt)
printFileLn SValue JuliaCode
f (SValue JuliaCode -> MS (JuliaCode (Doc, Terminator)))
-> (Label -> SValue JuliaCode)
-> Label
-> MS (JuliaCode (Doc, Terminator))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Label -> SValue JuliaCode
forall (r :: * -> *). Literal r => Label -> SValue r
litString

  getInput :: SVariable JuliaCode -> MS (JuliaCode (Doc, Terminator))
getInput = SValue JuliaCode
-> SVariable JuliaCode -> MS (JuliaCode (Doc, Terminator))
jlInput SValue JuliaCode
forall (r :: * -> *). RenderValue r => SValue r
inputFunc
  discardInput :: MS (JuliaCode (Doc, Terminator))
discardInput = SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
StatementSym r smt =>
SValue r -> MS (r smt)
valStmt SValue JuliaCode
forall (r :: * -> *). RenderValue r => SValue r
inputFunc
  getFileInput :: SValue JuliaCode
-> SVariable JuliaCode -> MS (JuliaCode (Doc, Terminator))
getFileInput SValue JuliaCode
f = SValue JuliaCode
-> SVariable JuliaCode -> MS (JuliaCode (Doc, Terminator))
jlInput (SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *). ValueExpression r => SValue r -> SValue r
readLine SValue JuliaCode
f)
  discardFileInput :: SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
discardFileInput SValue JuliaCode
f = SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
StatementSym r smt =>
SValue r -> MS (r smt)
valStmt (SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *). ValueExpression r => SValue r -> SValue r
readLine SValue JuliaCode
f)
  openFileR :: SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
openFileR SVariable JuliaCode
f SValue JuliaCode
n = SVariable JuliaCode
f SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
AssignStatement r smt =>
SVariable r -> SValue r -> MS (r smt)
&= SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(Literal r, ValueExpression r) =>
SValue r -> SValue r
CP.openFileR' SValue JuliaCode
n
  openFileW :: SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
openFileW SVariable JuliaCode
f SValue JuliaCode
n = SVariable JuliaCode
f SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
AssignStatement r smt =>
SVariable r -> SValue r -> MS (r smt)
&= SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(Literal r, ValueExpression r) =>
SValue r -> SValue r
CP.openFileW' SValue JuliaCode
n
  openFileA :: SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
openFileA SVariable JuliaCode
f SValue JuliaCode
n = SVariable JuliaCode
f SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
AssignStatement r smt =>
SVariable r -> SValue r -> MS (r smt)
&= SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(Literal r, ValueExpression r) =>
SValue r -> SValue r
CP.openFileA' SValue JuliaCode
n
  closeFile :: SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
closeFile SValue JuliaCode
f = SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
StatementSym r smt =>
SValue r -> MS (r smt)
valStmt (SValue JuliaCode -> MS (JuliaCode (Doc, Terminator)))
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall a b. (a -> b) -> a -> b
$ PosCall JuliaCode
forall (r :: * -> *). ValueExpression r => PosCall r
funcApp Label
jlCloseFunc VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
void [SValue JuliaCode
f]
  getFileInputLine :: SValue JuliaCode
-> SVariable JuliaCode -> MS (JuliaCode (Doc, Terminator))
getFileInputLine = SValue JuliaCode
-> SVariable JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
IOStatement r smt =>
SValue r -> SVariable r -> MS (r smt)
getFileInput
  discardFileLine :: SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
discardFileLine = SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
IOStatement r smt =>
SValue r -> MS (r smt)
discardFileInput
  getFileInputAll :: SValue JuliaCode
-> SVariable JuliaCode -> MS (JuliaCode (Doc, Terminator))
getFileInputAll SValue JuliaCode
f SVariable JuliaCode
v = SVariable JuliaCode
v SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
AssignStatement r smt =>
SVariable r -> SValue r -> MS (r smt)
&= SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *). ValueExpression r => SValue r -> SValue r
readLines SValue JuliaCode
f

instance StringStatement JuliaCode (Doc, Terminator) where
  stringSplit :: Char
-> SVariable JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
stringSplit Char
d SVariable JuliaCode
vnew SValue JuliaCode
s = SVariable JuliaCode
vnew SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
AssignStatement r smt =>
SVariable r -> SValue r -> MS (r smt)
&= PosCall JuliaCode
forall (r :: * -> *). ValueExpression r => PosCall r
funcApp Label
jlSplit (VS (JuliaCode TypeData) -> VS (JuliaCode TypeData)
forall (r :: * -> *).
TypeSym r =>
VS (r TypeData) -> VS (r TypeData)
listType VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
string) [SValue JuliaCode
s, Label -> SValue JuliaCode
forall (r :: * -> *). Literal r => Label -> SValue r
litString [Char
d]]
  stringListVals :: [SVariable JuliaCode]
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
stringListVals = [SVariable JuliaCode]
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(AssignStatement r smt, List r smt, Literal r, RenderValue r,
 TypeElim r, VariableElim r) =>
[SVariable r] -> SValue r -> MS (r smt)
M.stringListVals
  stringListLists :: [SVariable JuliaCode]
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
stringListLists = [SVariable JuliaCode]
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(RenderValue r, SharedStatement r smt, TypeElim r,
 VariableElim r) =>
[SVariable r] -> SValue r -> MS (r smt)
M.stringListLists

instance FunctionSym JuliaCode where

instance FuncAppStatement JuliaCode (Doc, Terminator) where
  inOutCall :: InOutCall JuliaCode (Doc, Terminator)
inOutCall = PosCall JuliaCode -> InOutCall JuliaCode (Doc, Terminator)
forall (r :: * -> *) smt.
(InternalAssignStmt r smt, StatementSym r smt, VariableValue r) =>
(Label -> VS (r TypeData) -> [SValue r] -> SValue r)
-> Label
-> [SValue r]
-> [SVariable r]
-> [SVariable r]
-> MS (r smt)
CP.inOutCall PosCall JuliaCode
forall (r :: * -> *). ValueExpression r => PosCall r
funcApp
  extInOutCall :: Label -> InOutCall JuliaCode (Doc, Terminator)
extInOutCall Label
m = PosCall JuliaCode -> InOutCall JuliaCode (Doc, Terminator)
forall (r :: * -> *) smt.
(InternalAssignStmt r smt, StatementSym r smt, VariableValue r) =>
(Label -> VS (r TypeData) -> [SValue r] -> SValue r)
-> Label
-> [SValue r]
-> [SVariable r]
-> [SVariable r]
-> MS (r smt)
CP.inOutCall (Label -> PosCall JuliaCode
forall (r :: * -> *). ValueExpression r => Label -> PosCall r
extFuncApp Label
m)

instance CommentStatement JuliaCode (Doc, Terminator) where
  comment :: Label -> MS (JuliaCode (Doc, Terminator))
comment = Doc -> Label -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
RenderStatement r smt =>
Doc -> Label -> MS (r smt)
G.comment Doc
jlCmtStart

instance ControlStatement JuliaCode (Doc, Terminator) where
  break :: MS (JuliaCode (Doc, Terminator))
break = Doc -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
RenderStatement r smt =>
Doc -> MS (r smt)
mkStmtNoEnd Doc
R.break
  continue :: MS (JuliaCode (Doc, Terminator))
continue = Doc -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
RenderStatement r smt =>
Doc -> MS (r smt)
mkStmtNoEnd Doc
R.continue
  returnStmt :: SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
returnStmt = Terminator -> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(RenderStatement r smt, ValueElim r) =>
Terminator -> SValue r -> MS (r smt)
G.returnStmt Terminator
Empty
  throw :: Label -> MS (JuliaCode (Doc, Terminator))
throw = (JuliaCode Value -> Doc)
-> Terminator -> Label -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(Literal r, RenderStatement r smt) =>
(r Value -> Doc) -> Terminator -> Label -> MS (r smt)
G.throw JuliaCode Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
jlThrow Terminator
Empty
  ifCond :: [(SValue JuliaCode, MS (JuliaCode Doc))]
-> MS (JuliaCode Doc) -> MS (JuliaCode (Doc, Terminator))
ifCond = (Doc -> Doc)
-> Doc
-> OptionalSpace
-> Doc
-> Doc
-> Doc
-> [(SValue JuliaCode, MS (JuliaCode Doc))]
-> MS (JuliaCode Doc)
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(BodyElim r, RenderStatement r smt, ValueElim r) =>
(Doc -> Doc)
-> Doc
-> OptionalSpace
-> Doc
-> Doc
-> Doc
-> [(SValue r, MS (r Doc))]
-> MS (r Doc)
-> MS (r smt)
G.ifCond Doc -> Doc
forall a. a -> a
id Doc
empty OptionalSpace
jlSpace Doc
elseIfLabel Doc
empty Doc
jlEnd
  switch :: SValue JuliaCode
-> [(SValue JuliaCode, MS (JuliaCode Doc))]
-> MS (JuliaCode Doc)
-> MS (JuliaCode (Doc, Terminator))
switch = SValue JuliaCode
-> [(SValue JuliaCode, MS (JuliaCode Doc))]
-> MS (JuliaCode Doc)
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(ControlStatement r smt, Comparison r) =>
SValue r -> [(SValue r, MS (r Doc))] -> MS (r Doc) -> MS (r smt)
switchAsIf
  ifExists :: SValue JuliaCode
-> MS (JuliaCode Doc)
-> MS (JuliaCode Doc)
-> MS (JuliaCode (Doc, Terminator))
ifExists = SValue JuliaCode
-> MS (JuliaCode Doc)
-> MS (JuliaCode Doc)
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(ControlStatement r smt, ValueExpression r) =>
SValue r -> MS (r Doc) -> MS (r Doc) -> MS (r smt)
M.ifExists
  for :: MS (JuliaCode (Doc, Terminator))
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
-> MS (JuliaCode Doc)
-> MS (JuliaCode (Doc, Terminator))
for MS (JuliaCode (Doc, Terminator))
_ SValue JuliaCode
_ MS (JuliaCode (Doc, Terminator))
_ MS (JuliaCode Doc)
_ = Label -> MS (JuliaCode (Doc, Terminator))
forall a. HasCallStack => Label -> a
error (Label -> MS (JuliaCode (Doc, Terminator)))
-> Label -> MS (JuliaCode (Doc, Terminator))
forall a b. (a -> b) -> a -> b
$ Label -> Label
CP.forLoopError Label
jlName
  forRange :: SVariable JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode Doc)
-> MS (JuliaCode (Doc, Terminator))
forRange SVariable JuliaCode
i SValue JuliaCode
initv SValue JuliaCode
finalv SValue JuliaCode
stepv = SVariable JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode Doc)
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
ControlStatement r smt =>
SVariable r -> SValue r -> MS (r Doc) -> MS (r smt)
forEach SVariable JuliaCode
i (SValue JuliaCode
-> SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
jlRange SValue JuliaCode
initv SValue JuliaCode
finalv SValue JuliaCode
stepv)
  forEach :: SVariable JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode Doc)
-> MS (JuliaCode (Doc, Terminator))
forEach = (JuliaCode Variable -> JuliaCode Value -> JuliaCode Doc -> Doc)
-> SVariable JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode Doc)
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
RenderStatement r smt =>
(r Variable -> r Value -> r Doc -> Doc)
-> SVariable r -> SValue r -> MS (r Doc) -> MS (r smt)
CS.forEach' JuliaCode Variable -> JuliaCode Value -> JuliaCode Doc -> Doc
forall (r :: * -> *).
(BodyElim r, InternalVarElim r, ValueElim r) =>
r Variable -> r Value -> r Doc -> Doc
jlForEach
  while :: SValue JuliaCode
-> MS (JuliaCode Doc) -> MS (JuliaCode (Doc, Terminator))
while = (Doc -> Doc)
-> Doc
-> Doc
-> SValue JuliaCode
-> MS (JuliaCode Doc)
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
(BodyElim r, RenderStatement r smt, ValueElim r) =>
(Doc -> Doc) -> Doc -> Doc -> SValue r -> MS (r Doc) -> MS (r smt)
C.while Doc -> Doc
forall a. a -> a
id Doc
empty Doc
jlEnd
  tryCatch :: MS (JuliaCode Doc)
-> MS (JuliaCode Doc) -> MS (JuliaCode (Doc, Terminator))
tryCatch = (JuliaCode Doc -> JuliaCode Doc -> Doc)
-> MS (JuliaCode Doc)
-> MS (JuliaCode Doc)
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
RenderStatement r smt =>
(r Doc -> r Doc -> Doc) -> MS (r Doc) -> MS (r Doc) -> MS (r smt)
G.tryCatch JuliaCode Doc -> JuliaCode Doc -> Doc
forall (r :: * -> *). BodyElim r => r Doc -> r Doc -> Doc
jlTryCatch
  assert :: SValue JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
assert SValue JuliaCode
condition SValue JuliaCode
errorMessage = do
    JuliaCode Value
cond <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Value))
  MethodState
  ValueState
-> SValue JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Value))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Value) ValueState)
-> MethodState -> Focusing Identity (JuliaCode Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue JuliaCode
condition
    JuliaCode Value
errMsg <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Value))
  MethodState
  ValueState
-> SValue JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Value))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Value) ValueState)
-> MethodState -> Focusing Identity (JuliaCode Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue JuliaCode
errorMessage
    Doc -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
RenderStatement r smt =>
Doc -> MS (r smt)
mkStmtNoEnd (JuliaCode Value -> JuliaCode Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> r Value -> Doc
jlAssert JuliaCode Value
cond JuliaCode Value
errMsg)

instance VisibilitySym JuliaCode Doc where

  private :: JuliaCode Doc
private = Doc -> JuliaCode Doc
forall (r :: * -> *) a. Monad r => a -> r a
toCode Doc
empty -- Julia doesn't have private/public members
  public :: JuliaCode Doc
public = Doc -> JuliaCode Doc
forall (r :: * -> *) a. Monad r => a -> r a
toCode Doc
empty

instance RenderVisibility JuliaCode Doc where
  visibilityFromData :: VisibilityTag -> Doc -> JuliaCode Doc
visibilityFromData VisibilityTag
_ = Doc -> JuliaCode Doc
forall (r :: * -> *) a. Monad r => a -> r a
toCode

instance VisibilityElim JuliaCode Doc where
  visibility :: JuliaCode Doc -> Doc
visibility = JuliaCode Doc -> Doc
forall a. JuliaCode a -> a
unJLC

instance MethodTypeSym JuliaCode where
  mType :: VS (JuliaCode TypeData) -> MSMthdType JuliaCode
mType = LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode TypeData))
  MethodState
  ValueState
-> VS (JuliaCode TypeData) -> MSMthdType JuliaCode
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) (JuliaCode TypeData))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode TypeData) ValueState)
-> MethodState
-> Focusing Identity (JuliaCode TypeData) MethodState
Lens' MethodState ValueState
lensMStoVS

instance ParameterSym JuliaCode where
  param :: SVariable JuliaCode -> MS (JuliaCode ParamData)
param = (JuliaCode Variable -> Doc)
-> SVariable JuliaCode -> MS (JuliaCode ParamData)
forall (r :: * -> *).
(RenderParam r, VariableElim r) =>
(r Variable -> Doc) -> SVariable r -> MS (r ParamData)
G.param JuliaCode Variable -> Doc
jlParam
  pointerParam :: SVariable JuliaCode -> MS (JuliaCode ParamData)
pointerParam = SVariable JuliaCode -> MS (JuliaCode ParamData)
forall (r :: * -> *).
ParameterSym r =>
SVariable r -> MS (r ParamData)
param

instance RenderParam JuliaCode where
  paramFromData :: SVariable JuliaCode -> Doc -> MS (JuliaCode ParamData)
paramFromData SVariable JuliaCode
v' Doc
d = do
    JuliaCode Variable
v <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Variable))
  MethodState
  ValueState
-> SVariable JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Variable))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Variable) ValueState)
-> MethodState
-> Focusing Identity (JuliaCode Variable) MethodState
Lens' MethodState ValueState
lensMStoVS SVariable JuliaCode
v'
    JuliaCode ParamData -> MS (JuliaCode ParamData)
forall a s. a -> State s a
toState (JuliaCode ParamData -> MS (JuliaCode ParamData))
-> JuliaCode ParamData -> MS (JuliaCode ParamData)
forall a b. (a -> b) -> a -> b
$ (Variable -> Doc -> ParamData)
-> JuliaCode Variable -> JuliaCode Doc -> JuliaCode ParamData
forall (r :: * -> *) a b c.
Applicative r =>
(a -> b -> c) -> r a -> r b -> r c
on2CodeValues Variable -> Doc -> ParamData
pd JuliaCode Variable
v (Doc -> JuliaCode Doc
forall (r :: * -> *) a. Monad r => a -> r a
toCode Doc
d)

instance ParamElim JuliaCode where
  parameterName :: JuliaCode ParamData -> Label
parameterName = JuliaCode Variable -> Label
forall (r :: * -> *). VariableElim r => r Variable -> Label
variableName (JuliaCode Variable -> Label)
-> (JuliaCode ParamData -> JuliaCode Variable)
-> JuliaCode ParamData
-> Label
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ParamData -> Variable)
-> JuliaCode ParamData -> JuliaCode Variable
forall (r :: * -> *) a b. Functor r => (a -> b) -> r a -> r b
onCodeValue ParamData -> Variable
paramVar
  parameterType :: JuliaCode ParamData -> JuliaCode TypeData
parameterType = JuliaCode Variable -> JuliaCode TypeData
forall (r :: * -> *). VariableElim r => r Variable -> r TypeData
variableType (JuliaCode Variable -> JuliaCode TypeData)
-> (JuliaCode ParamData -> JuliaCode Variable)
-> JuliaCode ParamData
-> JuliaCode TypeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ParamData -> Variable)
-> JuliaCode ParamData -> JuliaCode Variable
forall (r :: * -> *) a b. Functor r => (a -> b) -> r a -> r b
onCodeValue ParamData -> Variable
paramVar
  parameter :: JuliaCode ParamData -> Doc
parameter = ParamData -> Doc
paramDoc (ParamData -> Doc)
-> (JuliaCode ParamData -> ParamData) -> JuliaCode ParamData -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode ParamData -> ParamData
forall a. JuliaCode a -> a
unJLC

instance MethodSym JuliaCode Doc (Doc, Terminator) MethodData where
  docMain :: MS (JuliaCode Doc) -> MS (JuliaCode MethodData)
docMain = MS (JuliaCode Doc) -> MS (JuliaCode MethodData)
forall (r :: * -> *) vis smt md.
MethodSym r vis smt md =>
MS (r Doc) -> MS (r md)
mainFunction
  function :: Label
-> JuliaCode Doc
-> VS (JuliaCode TypeData)
-> [MS (JuliaCode ParamData)]
-> MS (JuliaCode Doc)
-> MS (JuliaCode MethodData)
function = Label
-> JuliaCode Doc
-> VS (JuliaCode TypeData)
-> [MS (JuliaCode ParamData)]
-> MS (JuliaCode Doc)
-> MS (JuliaCode MethodData)
forall (r :: * -> *) vis md.
ProcRenderMethod r vis md =>
Label
-> r vis
-> VS (r TypeData)
-> [MS (r ParamData)]
-> MS (r Doc)
-> MS (r md)
A.function
  mainFunction :: MS (JuliaCode Doc) -> MS (JuliaCode MethodData)
mainFunction = MS (JuliaCode Doc) -> MS (JuliaCode MethodData)
forall (r :: * -> *) md.
(BodyElim r, RenderMethod r md) =>
MS (r Doc) -> MS (r md)
CP.mainBody
  docFunc :: Label
-> [Label]
-> Maybe Label
-> MS (JuliaCode MethodData)
-> MS (JuliaCode MethodData)
docFunc = FuncDocRenderer
-> Label
-> [Label]
-> Maybe Label
-> MS (JuliaCode MethodData)
-> MS (JuliaCode MethodData)
forall (r :: * -> *) md.
RenderMethod r md =>
FuncDocRenderer
-> Label -> [Label] -> Maybe Label -> MS (r md) -> MS (r md)
G.docFunc FuncDocRenderer
CP.functionDoc

  inOutFunc :: Label -> JuliaCode Doc -> InOutFunc JuliaCode MethodData
inOutFunc Label
n JuliaCode Doc
s = (VS (JuliaCode TypeData)
 -> [MS (JuliaCode ParamData)]
 -> MS (JuliaCode Doc)
 -> MS (JuliaCode MethodData))
-> InOutFunc JuliaCode MethodData
forall (r :: * -> *) smt md.
(InternalControlStmt r smt, SharedStatement r smt, RenderBody r,
 RenderType r, VariableElim r) =>
(VS (r TypeData) -> [MS (r ParamData)] -> MS (r Doc) -> MS (r md))
-> [SVariable r]
-> [SVariable r]
-> [SVariable r]
-> MS (r Doc)
-> MS (r md)
CP.inOutFunc (Label
-> JuliaCode Doc
-> VS (JuliaCode TypeData)
-> [MS (JuliaCode ParamData)]
-> MS (JuliaCode Doc)
-> MS (JuliaCode MethodData)
forall (r :: * -> *) vis smt md.
MethodSym r vis smt md =>
Label
-> r vis
-> VS (r TypeData)
-> [MS (r ParamData)]
-> MS (r Doc)
-> MS (r md)
function Label
n JuliaCode Doc
s)
  docInOutFunc :: Label -> JuliaCode Doc -> DocInOutFunc JuliaCode MethodData
docInOutFunc Label
n JuliaCode Doc
s = FuncDocRenderer
-> InOutFunc JuliaCode MethodData
-> DocInOutFunc JuliaCode MethodData
forall (r :: * -> *) md.
RenderMethod r md =>
FuncDocRenderer
-> ([SVariable r]
    -> [SVariable r] -> [SVariable r] -> MS (r Doc) -> MS (r md))
-> Label
-> [(Label, SVariable r)]
-> [(Label, SVariable r)]
-> [(Label, SVariable r)]
-> MS (r Doc)
-> MS (r md)
CP.docInOutFunc' FuncDocRenderer
CP.functionDoc (Label -> JuliaCode Doc -> InOutFunc JuliaCode MethodData
forall (r :: * -> *) vis smt md.
MethodSym r vis smt md =>
Label -> r vis -> InOutFunc r md
inOutFunc Label
n JuliaCode Doc
s)

instance RenderMethod JuliaCode MethodData where
  commentedFunc :: MS (JuliaCode Doc)
-> MS (JuliaCode MethodData) -> MS (JuliaCode MethodData)
commentedFunc MS (JuliaCode Doc)
cmt MS (JuliaCode MethodData)
m = (JuliaCode MethodData
 -> JuliaCode (Doc -> Doc) -> JuliaCode MethodData)
-> MS (JuliaCode MethodData)
-> State MethodState (JuliaCode (Doc -> Doc))
-> MS (JuliaCode MethodData)
forall a b c s.
(a -> b -> c) -> State s a -> State s b -> State s c
on2StateValues ((MethodData -> (Doc -> Doc) -> MethodData)
-> JuliaCode MethodData
-> JuliaCode (Doc -> Doc)
-> JuliaCode MethodData
forall (r :: * -> *) a b c.
Applicative r =>
(a -> b -> c) -> r a -> r b -> r c
on2CodeValues MethodData -> (Doc -> Doc) -> MethodData
updateMthd) MS (JuliaCode MethodData)
m
    ((JuliaCode Doc -> JuliaCode (Doc -> Doc))
-> MS (JuliaCode Doc) -> State MethodState (JuliaCode (Doc -> Doc))
forall a b s. (a -> b) -> State s a -> State s b
onStateValue ((Doc -> Doc -> Doc) -> JuliaCode Doc -> JuliaCode (Doc -> Doc)
forall (r :: * -> *) a b. Functor r => (a -> b) -> r a -> r b
onCodeValue Doc -> Doc -> Doc
R.commentedItem) MS (JuliaCode Doc)
cmt)
  mthdFromData :: VisibilityTag -> Doc -> MS (JuliaCode MethodData)
mthdFromData VisibilityTag
_ Doc
d = JuliaCode MethodData -> MS (JuliaCode MethodData)
forall a s. a -> State s a
toState (JuliaCode MethodData -> MS (JuliaCode MethodData))
-> JuliaCode MethodData -> MS (JuliaCode MethodData)
forall a b. (a -> b) -> a -> b
$ MethodData -> JuliaCode MethodData
forall (r :: * -> *) a. Monad r => a -> r a
toCode (MethodData -> JuliaCode MethodData)
-> MethodData -> JuliaCode MethodData
forall a b. (a -> b) -> a -> b
$ Doc -> MethodData
mthd Doc
d

instance ProcRenderMethod JuliaCode Doc MethodData where
  intFunc :: Bool
-> Label
-> JuliaCode Doc
-> MSMthdType JuliaCode
-> [MS (JuliaCode ParamData)]
-> MS (JuliaCode Doc)
-> MS (JuliaCode MethodData)
intFunc Bool
_ Label
n JuliaCode Doc
_ MSMthdType JuliaCode
_ [MS (JuliaCode ParamData)]
ps MS (JuliaCode Doc)
b = do
    [JuliaCode ParamData]
pms <- [MS (JuliaCode ParamData)]
-> StateT MethodState Identity [JuliaCode ParamData]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence [MS (JuliaCode ParamData)]
ps
    MethodData -> JuliaCode MethodData
forall (r :: * -> *) a. Monad r => a -> r a
toCode (MethodData -> JuliaCode MethodData)
-> (JuliaCode Doc -> MethodData)
-> JuliaCode Doc
-> JuliaCode MethodData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc -> MethodData
mthd (Doc -> MethodData)
-> (JuliaCode Doc -> Doc) -> JuliaCode Doc -> MethodData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Label -> [JuliaCode ParamData] -> JuliaCode Doc -> Doc
forall (r :: * -> *).
(BodyElim r, ParamElim r) =>
Label -> [r ParamData] -> r Doc -> Doc
jlIntFunc Label
n [JuliaCode ParamData]
pms (JuliaCode Doc -> JuliaCode MethodData)
-> MS (JuliaCode Doc) -> MS (JuliaCode MethodData)
forall (r :: * -> *) a b. Functor r => (a -> b) -> r a -> r b
<$> MS (JuliaCode Doc)
b

instance MethodElim JuliaCode MethodData where
  method :: JuliaCode MethodData -> Doc
method = MethodData -> Doc
mthdDoc (MethodData -> Doc)
-> (JuliaCode MethodData -> MethodData)
-> JuliaCode MethodData
-> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode MethodData -> MethodData
forall a. JuliaCode a -> a
unJLC

instance ModuleSym JuliaCode Doc (Doc, Terminator) MethodData where
  buildModule :: Label
-> [Label] -> [MS (JuliaCode MethodData)] -> FS (JuliaCode Module)
buildModule Label
n [Label]
is [MS (JuliaCode MethodData)]
fs = Label
-> [Label] -> [MS (JuliaCode MethodData)] -> FS (JuliaCode Module)
jlModContents Label
n [Label]
is [MS (JuliaCode MethodData)]
fs FS (JuliaCode Module)
-> (JuliaCode Module -> JuliaCode Module) -> FS (JuliaCode Module)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&>
    (Doc -> Doc) -> JuliaCode Module -> JuliaCode Module
forall (r :: * -> *).
RenderMod r =>
(Doc -> Doc) -> r Module -> r Module
updateModuleDoc (\Doc
m -> Doc -> Doc -> Doc
emptyIfEmpty Doc
m ([Doc] -> Doc
vibcat [Label -> Doc
jlModStart Label
n, Doc
m, Doc
jlEnd]))

instance RenderMod JuliaCode where
  modFromData :: Label -> FS Doc -> FS (JuliaCode Module)
modFromData Label
n = Label
-> (Doc -> JuliaCode Module) -> FS Doc -> FS (JuliaCode Module)
forall (r :: * -> *).
Label -> (Doc -> r Module) -> FS Doc -> FS (r Module)
A.modFromData Label
n (Module -> JuliaCode Module
forall (r :: * -> *) a. Monad r => a -> r a
toCode (Module -> JuliaCode Module)
-> (Doc -> Module) -> Doc -> JuliaCode Module
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Label -> Doc -> Module
md Label
n)
  updateModuleDoc :: (Doc -> Doc) -> JuliaCode Module -> JuliaCode Module
updateModuleDoc Doc -> Doc
f = (Module -> Module) -> JuliaCode Module -> JuliaCode Module
forall (r :: * -> *) a b. Functor r => (a -> b) -> r a -> r b
onCodeValue ((Doc -> Doc) -> Module -> Module
updateMod Doc -> Doc
f)

instance ModuleElim JuliaCode where
  module' :: JuliaCode Module -> Doc
module' = Module -> Doc
modDoc (Module -> Doc)
-> (JuliaCode Module -> Module) -> JuliaCode Module -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode Module -> Module
forall a. JuliaCode a -> a
unJLC

instance BlockCommentSym JuliaCode where
  blockComment :: [Label] -> JuliaCode Doc
blockComment [Label]
lns = Doc -> JuliaCode Doc
forall (r :: * -> *) a. Monad r => a -> r a
toCode (Doc -> JuliaCode Doc) -> Doc -> JuliaCode Doc
forall a b. (a -> b) -> a -> b
$ [Label] -> Doc -> Doc -> Doc
R.blockCmt [Label]
lns Doc
jlBlockCmtStart Doc
jlBlockCmtEnd
  docComment :: forall a. State a [Label] -> State a (JuliaCode Doc)
docComment = ([Label] -> JuliaCode Doc)
-> State a [Label] -> State a (JuliaCode Doc)
forall a b s. (a -> b) -> State s a -> State s b
onStateValue (\[Label]
lns -> Doc -> JuliaCode Doc
forall (r :: * -> *) a. Monad r => a -> r a
toCode (Doc -> JuliaCode Doc) -> Doc -> JuliaCode Doc
forall a b. (a -> b) -> a -> b
$ [Label] -> Doc -> Doc -> Doc
R.docCmt [Label]
lns Doc
jlDocCmtStart
    Doc
jlDocCmtEnd)

instance BlockCommentElim JuliaCode where
  blockComment' :: JuliaCode Doc -> Doc
blockComment' = JuliaCode Doc -> Doc
forall a. JuliaCode a -> a
unJLC

-- convenience
jlName, jlVersion :: String
jlName :: Label
jlName = Label
"Julia"
jlVersion :: Label
jlVersion = Label
"1.10.3"

-- Concrete versions of each Julia datatype
jlIntConc, jlFloatConc, jlDoubleConc, jlCharConc, jlStringConc, jlListConc,
  jlSetConc, jlFile, jlVoid :: String
jlIntConc :: Label
jlIntConc = Label
"Int64"
jlFloatConc :: Label
jlFloatConc = Label
"Float32"
jlDoubleConc :: Label
jlDoubleConc = Label
"Float64"
jlCharConc :: Label
jlCharConc = Label
"Char"
jlStringConc :: Label
jlStringConc = Label
"String"
jlListConc :: Label
jlListConc = Label
"Array"
jlSetConc :: Label
jlSetConc = Label
"Set"
jlFile :: Label
jlFile = Label
"IOStream"
jlVoid :: Label
jlVoid = Label
"Nothing"

-- The only consistent way of creating floats is by casting
jlLitFloat :: (RenderValue r, TypeSym r) => Float -> SValue r
jlLitFloat :: forall (r :: * -> *).
(RenderValue r, TypeSym r) =>
Float -> SValue r
jlLitFloat Float
f = VS (r TypeData) -> Doc -> SValue r
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Doc -> SValue r
mkStateVal VS (r TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
float (Label -> Doc
text Label
jlFloatConc Doc -> Doc -> Doc
<> Doc -> Doc
parens (Float -> Doc
D.float Float
f))

jlLitList :: VS (JuliaCode TypeData) -> [SValue JuliaCode] -> SValue JuliaCode
jlLitList :: VS (JuliaCode TypeData) -> [SValue JuliaCode] -> SValue JuliaCode
jlLitList VS (JuliaCode TypeData)
t' [SValue JuliaCode]
es = do
  JuliaCode TypeData
t <- VS (JuliaCode TypeData)
t'
  let lt' :: VS (JuliaCode TypeData)
lt' = VS (JuliaCode TypeData) -> VS (JuliaCode TypeData)
forall (r :: * -> *).
TypeSym r =>
VS (r TypeData) -> VS (r TypeData)
listType VS (JuliaCode TypeData)
t'
  [JuliaCode Value]
elems <- [SValue JuliaCode] -> StateT ValueState Identity [JuliaCode 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 JuliaCode]
es
  let typeDec :: Doc
typeDec = if [SValue JuliaCode] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [SValue JuliaCode]
es then JuliaCode TypeData -> Doc
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType JuliaCode TypeData
t else Doc
empty
  VS (JuliaCode TypeData) -> Doc -> SValue JuliaCode
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Doc -> SValue r
mkStateVal VS (JuliaCode TypeData)
lt' (Doc
typeDec Doc -> Doc -> Doc
<> Doc -> Doc
brackets ([JuliaCode Value] -> Doc
forall (r :: * -> *). ValueElim r => [r Value] -> Doc
valueList [JuliaCode Value]
elems))

jlCast :: VS (JuliaCode TypeData) -> SValue JuliaCode -> SValue JuliaCode
jlCast :: VS (JuliaCode TypeData) -> SValue JuliaCode -> SValue JuliaCode
jlCast VS (JuliaCode TypeData)
t' SValue JuliaCode
v' = do
  JuliaCode TypeData
t <- VS (JuliaCode TypeData)
t'
  JuliaCode Value
v <- SValue JuliaCode
v'
  let vTp :: CodeType
vTp = JuliaCode TypeData -> CodeType
forall (r :: * -> *). TypeElim r => r TypeData -> CodeType
getCodeType (JuliaCode TypeData -> CodeType) -> JuliaCode TypeData -> CodeType
forall a b. (a -> b) -> a -> b
$ JuliaCode Value -> JuliaCode TypeData
forall (r :: * -> *). ValueSym r => r Value -> r TypeData
valueType JuliaCode Value
v
      tTp :: CodeType
tTp = JuliaCode TypeData -> CodeType
forall (r :: * -> *). TypeElim r => r TypeData -> CodeType
getCodeType JuliaCode TypeData
t
      vDoc :: Doc
vDoc = JuliaCode Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value JuliaCode Value
v
      tDoc :: Doc
tDoc = JuliaCode TypeData -> Doc
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType JuliaCode TypeData
t
      jlCast' :: CodeType -> CodeType -> Doc -> Doc -> Doc
      -- Converting string to char
      jlCast' :: CodeType -> CodeType -> Doc -> Doc -> Doc
jlCast' CodeType
String CodeType
Char Doc
vDoc' Doc
_ = Label -> Doc
text Label
"only" Doc -> Doc -> Doc
<> Doc -> Doc
parens Doc
vDoc'
      -- Converting string to something else
      jlCast' CodeType
String CodeType
_    Doc
vDoc' Doc
tDoc' = Label -> Doc
text Label
"parse" Doc -> Doc -> Doc
<> Doc -> Doc
parens (Doc
tDoc' Doc -> Doc -> Doc
<> Doc
listSep' Doc -> Doc -> Doc
<+> Doc
vDoc')
      -- Converting non-string to char
      jlCast' CodeType
_      CodeType
Char Doc
vDoc' Doc
_ = Label -> Doc
text Label
"only" Doc -> Doc -> Doc
<> Doc -> Doc
parens (Label -> Doc
text Label
"string" Doc -> Doc -> Doc
<> Doc -> Doc
parens Doc
vDoc')
      -- Converting something to string
      jlCast' CodeType
_      CodeType
String Doc
vDoc' Doc
_ = Label -> Doc
text Label
"string" Doc -> Doc -> Doc
<> Doc -> Doc
parens Doc
vDoc'
      -- Converting non-string to non-string
      jlCast' CodeType
_      CodeType
_    Doc
vDoc' Doc
tDoc' = Doc
tDoc' Doc -> Doc -> Doc
<> Doc -> Doc
parens Doc
vDoc'
  JuliaCode TypeData -> Doc -> SValue JuliaCode
forall (r :: * -> *).
RenderValue r =>
r TypeData -> Doc -> SValue r
mkVal JuliaCode TypeData
t (CodeType -> CodeType -> Doc -> Doc -> Doc
jlCast' CodeType
vTp CodeType
tTp Doc
vDoc Doc
tDoc)

jlAssign :: SVariable JuliaCode -> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
jlAssign :: SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
jlAssign SVariable JuliaCode
vr' SValue JuliaCode
v' = do
  JuliaCode Variable
vr <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Variable))
  MethodState
  ValueState
-> SVariable JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Variable))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Variable) ValueState)
-> MethodState
-> Focusing Identity (JuliaCode Variable) MethodState
Lens' MethodState ValueState
lensMStoVS SVariable JuliaCode
vr'
  JuliaCode Value
v <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Value))
  MethodState
  ValueState
-> SValue JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Value))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Value) ValueState)
-> MethodState -> Focusing Identity (JuliaCode Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue JuliaCode
v'
  ScopeData
scpData <- Label -> MS ScopeData
getVarScope (JuliaCode Variable -> Label
forall (r :: * -> *). VariableElim r => r Variable -> Label
variableName JuliaCode Variable
vr) -- Need to do global declarations
  Doc -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
RenderStatement r smt =>
Doc -> MS (r smt)
mkStmtNoEnd (Doc -> MS (JuliaCode (Doc, Terminator)))
-> Doc -> MS (JuliaCode (Doc, Terminator))
forall a b. (a -> b) -> a -> b
$ ScopeData -> Doc
jlGlobalDec ScopeData
scpData Doc -> Doc -> Doc
<+> JuliaCode Variable -> JuliaCode Value -> Doc
forall (r :: * -> *).
(InternalVarElim r, ValueElim r) =>
r Variable -> r Value -> Doc
R.assign JuliaCode Variable
vr JuliaCode Value
v

jlSubAssign :: SVariable JuliaCode -> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
jlSubAssign :: SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
jlSubAssign SVariable JuliaCode
vr' SValue JuliaCode
v' = do
  JuliaCode Variable
vr <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Variable))
  MethodState
  ValueState
-> SVariable JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Variable))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Variable) ValueState)
-> MethodState
-> Focusing Identity (JuliaCode Variable) MethodState
Lens' MethodState ValueState
lensMStoVS SVariable JuliaCode
vr'
  JuliaCode Value
v <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Value))
  MethodState
  ValueState
-> SValue JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Value))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Value) ValueState)
-> MethodState -> Focusing Identity (JuliaCode Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue JuliaCode
v'
  ScopeData
scpData <- Label -> MS ScopeData
getVarScope (JuliaCode Variable -> Label
forall (r :: * -> *). VariableElim r => r Variable -> Label
variableName JuliaCode Variable
vr) -- Need to do global declarations
  Doc -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
RenderStatement r smt =>
Doc -> MS (r smt)
mkStmtNoEnd (Doc -> MS (JuliaCode (Doc, Terminator)))
-> Doc -> MS (JuliaCode (Doc, Terminator))
forall a b. (a -> b) -> a -> b
$ ScopeData -> Doc
jlGlobalDec ScopeData
scpData Doc -> Doc -> Doc
<+> JuliaCode Variable -> JuliaCode Value -> Doc
forall (r :: * -> *).
(InternalVarElim r, ValueElim r) =>
r Variable -> r Value -> Doc
R.subAssign JuliaCode Variable
vr JuliaCode Value
v

jlIncrement :: SVariable JuliaCode -> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
jlIncrement :: SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
jlIncrement SVariable JuliaCode
vr' SValue JuliaCode
v'= do
  JuliaCode Variable
vr <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Variable))
  MethodState
  ValueState
-> SVariable JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Variable))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Variable) ValueState)
-> MethodState
-> Focusing Identity (JuliaCode Variable) MethodState
Lens' MethodState ValueState
lensMStoVS SVariable JuliaCode
vr'
  JuliaCode Value
v <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Value))
  MethodState
  ValueState
-> SValue JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Value))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Value) ValueState)
-> MethodState -> Focusing Identity (JuliaCode Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue JuliaCode
v'
  ScopeData
scpData <- Label -> MS ScopeData
getVarScope (JuliaCode Variable -> Label
forall (r :: * -> *). VariableElim r => r Variable -> Label
variableName JuliaCode Variable
vr) -- Need to do global declarations
  Doc -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
RenderStatement r smt =>
Doc -> MS (r smt)
mkStmtNoEnd (Doc -> MS (JuliaCode (Doc, Terminator)))
-> Doc -> MS (JuliaCode (Doc, Terminator))
forall a b. (a -> b) -> a -> b
$ ScopeData -> Doc
jlGlobalDec ScopeData
scpData Doc -> Doc -> Doc
<+> JuliaCode Variable -> JuliaCode Value -> Doc
forall (r :: * -> *).
(InternalVarElim r, ValueElim r) =>
r Variable -> r Value -> Doc
R.addAssign JuliaCode Variable
vr JuliaCode Value
v

jlGlobalDec :: ScopeData -> Doc
jlGlobalDec :: ScopeData -> Doc
jlGlobalDec ScopeData
scp = if ScopeData -> ScopeTag
scopeTag ScopeData
scp ScopeTag -> ScopeTag -> Bool
forall a. Eq a => a -> a -> Bool
== ScopeTag
Global then Doc
jlGlobal else Doc
empty

jlGlobal :: Doc
jlGlobal :: Doc
jlGlobal = Label -> Doc
text Label
"global"

jlConstDecDef
  :: SVariable JuliaCode
  -> JuliaCode ScopeData
  -> SValue JuliaCode
  -> MS (JuliaCode (Doc, Terminator))
jlConstDecDef :: SVariable JuliaCode
-> JuliaCode ScopeData
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
jlConstDecDef SVariable JuliaCode
v' JuliaCode ScopeData
scp SValue JuliaCode
def' = do
  let scpData :: ScopeData
scpData = JuliaCode ScopeData -> ScopeData
forall (r :: * -> *). ScopeElim r => r ScopeData -> ScopeData
scopeData JuliaCode ScopeData
scp
  JuliaCode Variable
v <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Variable))
  MethodState
  ValueState
-> SVariable JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Variable))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Variable) ValueState)
-> MethodState
-> Focusing Identity (JuliaCode Variable) MethodState
Lens' MethodState ValueState
lensMStoVS SVariable JuliaCode
v'
  JuliaCode Value
def <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Value))
  MethodState
  ValueState
-> SValue JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Value))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Value) ValueState)
-> MethodState -> Focusing Identity (JuliaCode Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue JuliaCode
def'
  (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
$ Label -> MethodState -> MethodState
useVarName (Label -> MethodState -> MethodState)
-> Label -> MethodState -> MethodState
forall a b. (a -> b) -> a -> b
$ JuliaCode Variable -> Label
forall (r :: * -> *). VariableElim r => r Variable -> Label
variableName JuliaCode 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
$ Label -> ScopeData -> MethodState -> MethodState
setVarScope (JuliaCode Variable -> Label
forall (r :: * -> *). VariableElim r => r Variable -> Label
variableName JuliaCode Variable
v) ScopeData
scpData
  let decDoc :: Doc
decDoc = if ScopeData -> ScopeTag
scopeTag ScopeData
scpData ScopeTag -> ScopeTag -> Bool
forall a. Eq a => a -> a -> Bool
== ScopeTag
Global then Doc
R.constDec' else Doc
empty
  Doc -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
RenderStatement r smt =>
Doc -> MS (r smt)
mkStmtNoEnd (Doc -> MS (JuliaCode (Doc, Terminator)))
-> Doc -> MS (JuliaCode (Doc, Terminator))
forall a b. (a -> b) -> a -> b
$ Doc
decDoc Doc -> Doc -> Doc
<+> JuliaCode Variable -> Doc
forall (r :: * -> *). InternalVarElim r => r Variable -> Doc
RC.variable JuliaCode Variable
v Doc -> Doc -> Doc
<+> Doc
equals Doc -> Doc -> Doc
<+> JuliaCode Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value JuliaCode Value
def

-- List API
jlListSize, jlListAdd, jlListAppend, jlListAbsdex :: Label
jlListSize :: Label
jlListSize   = Label
"length"
jlListAdd :: Label
jlListAdd    = Label
"insert!"
jlListAppend :: Label
jlListAppend = Label
"append!"
jlListAbsdex :: Label
jlListAbsdex = Label
"findfirst"

jlIndexOf
  :: (IndexTranslator r, ValueExpression r, BinderSym r, VariableValue r, Comparison r)
  => SValue r
  -> SValue r
  -> SValue r
jlIndexOf :: forall (r :: * -> *).
(IndexTranslator r, ValueExpression r, BinderSym r,
 VariableValue r, Comparison r) =>
SValue r -> SValue r -> SValue r
jlIndexOf SValue r
l SValue r
v = do
  r Value
v' <- SValue r
v
  let t :: StateT ValueState Identity (r TypeData)
t = r TypeData -> StateT ValueState Identity (r TypeData)
forall (r :: * -> *) a. Monad r => a -> r a
toCode (r TypeData -> StateT ValueState Identity (r TypeData))
-> r TypeData -> StateT ValueState Identity (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'
  SValue r -> SValue r
forall (r :: * -> *). IndexTranslator r => SValue r -> SValue r
indexToInt (SValue r -> SValue r) -> SValue r -> SValue r
forall a b. (a -> b) -> a -> b
$ PosCall r
forall (r :: * -> *). ValueExpression r => PosCall r
funcApp
    Label
jlListAbsdex StateT ValueState Identity (r TypeData)
t [[VSBinder r] -> SValue r -> SValue r
forall (r :: * -> *).
ValueExpression r =>
[VSBinder r] -> SValue r -> SValue r
lambda [Label -> StateT ValueState Identity (r TypeData) -> VSBinder r
forall (r :: * -> *).
BinderSym r =>
Label -> VS (r TypeData) -> VSBinder r
binder Label
"x" StateT ValueState Identity (r TypeData)
t] (SVariable r -> SValue r
forall (r :: * -> *). VariableValue r => SVariable r -> SValue r
valueOf (Label -> StateT ValueState Identity (r TypeData) -> SVariable r
forall (r :: * -> *).
VariableSym r =>
Label -> VS (r TypeData) -> SVariable r
var Label
"x" StateT ValueState Identity (r TypeData)
t) SValue r -> SValue r -> SValue r
forall (r :: * -> *).
Comparison r =>
SValue r -> SValue r -> SValue r
?== SValue r
v), SValue r
l]

-- List slicing in Julia.  See HelloWorld.jl to see the full suite of
-- possible outputs of this function.
jlListSlice
  :: SVariable JuliaCode
  -> SValue JuliaCode
  -> Maybe (SValue JuliaCode)
  -> Maybe (SValue JuliaCode)
  -> SValue JuliaCode
  -> MS (JuliaCode Block)
jlListSlice :: SVariable JuliaCode
-> SValue JuliaCode
-> Maybe (SValue JuliaCode)
-> Maybe (SValue JuliaCode)
-> SValue JuliaCode
-> MS (JuliaCode Doc)
jlListSlice SVariable JuliaCode
vn SValue JuliaCode
vo Maybe (SValue JuliaCode)
beg Maybe (SValue JuliaCode)
end SValue JuliaCode
step = do

  JuliaCode Variable
vnew <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Variable))
  MethodState
  ValueState
-> SVariable JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Variable))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Variable) ValueState)
-> MethodState
-> Focusing Identity (JuliaCode Variable) MethodState
Lens' MethodState ValueState
lensMStoVS SVariable JuliaCode
vn
  ScopeData
scpData <- Label -> MS ScopeData
getVarScope (Label -> MS ScopeData) -> Label -> MS ScopeData
forall a b. (a -> b) -> a -> b
$ JuliaCode Variable -> Label
forall (r :: * -> *). VariableElim r => r Variable -> Label
variableName JuliaCode Variable
vnew
  let scp :: JuliaCode ScopeData
scp = ScopeData -> JuliaCode ScopeData
forall (r :: * -> *). ScopeSym r => ScopeData -> r ScopeData
convScope ScopeData
scpData

  JuliaCode Value
stepV <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Value))
  MethodState
  ValueState
-> SValue JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Value))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Value) ValueState)
-> MethodState -> Focusing Identity (JuliaCode Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue JuliaCode
step

  let mbStepV :: Maybe Integer
mbStepV = JuliaCode Value -> Maybe Integer
forall (r :: * -> *). ValueElim r => r Value -> Maybe Integer
valueInt JuliaCode Value
stepV
  Label
bName <- Bool -> Label -> MS Label
genVarNameIf (Maybe (SValue JuliaCode) -> Bool
forall a. Maybe a -> Bool
isNothing Maybe (SValue JuliaCode)
beg Bool -> Bool -> Bool
&& Maybe Integer -> Bool
forall a. Maybe a -> Bool
isNothing Maybe Integer
mbStepV) Label
"begIdx"
  Label
eName <- Bool -> Label -> MS Label
genVarNameIf (Maybe Integer -> Bool
forall a. Maybe a -> Bool
isNothing Maybe Integer
mbStepV) Label
"endIdx"

  let begVar :: SVariable JuliaCode
begVar = Label -> VS (JuliaCode TypeData) -> SVariable JuliaCode
forall (r :: * -> *).
VariableSym r =>
Label -> VS (r TypeData) -> SVariable r
var Label
bName VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
int
      endVar :: SVariable JuliaCode
endVar = Label -> VS (JuliaCode TypeData) -> SVariable JuliaCode
forall (r :: * -> *).
VariableSym r =>
Label -> VS (r TypeData) -> SVariable r
var Label
eName VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
int

      (MS (JuliaCode (Doc, Terminator))
setBeg, SValue JuliaCode
begVal) = case (Maybe (SValue JuliaCode)
beg, Maybe Integer
mbStepV) of
        -- If we have a value for beg, just use it
        (Just SValue JuliaCode
b, Maybe Integer
_)        -> (MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt. StatementSym r smt => MS (r smt)
emptyStmt, SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *). IndexTranslator r => SValue r -> SValue r
intToIndex SValue JuliaCode
b)
        -- If we don't have a value for `beg` but we do for `step`, use `begin` or `end`
        (Maybe (SValue JuliaCode)
Nothing, Just Integer
s)  -> (MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt. StatementSym r smt => MS (r smt)
emptyStmt,
          if Integer
s Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0 then VS (JuliaCode TypeData) -> Doc -> SValue JuliaCode
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Doc -> SValue r
mkStateVal VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
int Doc
jlBegin else VS (JuliaCode TypeData) -> Doc -> SValue JuliaCode
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Doc -> SValue r
mkStateVal VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
int Doc
jlEnd)
        -- Otherwise, generate an if-statement to calculate `beg` at runtime
        (Maybe (SValue JuliaCode)
Nothing, Maybe Integer
Nothing) -> (SVariable JuliaCode
-> JuliaCode ScopeData
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
DeclStatement r smt =>
SVariable r -> r ScopeData -> SValue r -> MS (r smt)
varDecDef SVariable JuliaCode
begVar JuliaCode ScopeData
scp (SValue JuliaCode -> MS (JuliaCode (Doc, Terminator)))
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall a b. (a -> b) -> a -> b
$
          SValue JuliaCode
-> SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
ValueExpression r =>
SValue r -> SValue r -> SValue r -> SValue r
inlineIf (SValue JuliaCode
step SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
Comparison r =>
SValue r -> SValue r -> SValue r
?> Integer -> SValue JuliaCode
forall (r :: * -> *). Literal r => Integer -> SValue r
litInt Integer
0) (Integer -> SValue JuliaCode
forall (r :: * -> *). Literal r => Integer -> SValue r
litInt Integer
1) (SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *) smt. List r smt => SValue r -> SValue r
listSize SValue JuliaCode
vo),
          SVariable JuliaCode -> SValue JuliaCode
forall (r :: * -> *). VariableValue r => SVariable r -> SValue r
valueOf SVariable JuliaCode
begVar)

      -- Similar to `begVal`, but if we're given a value, we have to either
      -- do nothing or add 2 based on the sign of `step`, because `end` needs
      -- to be inclusive
      (MS (JuliaCode (Doc, Terminator))
setEnd, SValue JuliaCode
endVal) = case (Maybe (SValue JuliaCode)
end, Maybe Integer
mbStepV) of
        (Just SValue JuliaCode
e, Just Integer
s)  -> (MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt. StatementSym r smt => MS (r smt)
emptyStmt,
          if Integer
s Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0 then SValue JuliaCode
e else SValue JuliaCode
e SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(Literal r, NumericExpression r, RenderValue r, ValueElim r) =>
SValue r -> SValue r -> SValue r
`G.smartAdd` Integer -> SValue JuliaCode
forall (r :: * -> *). Literal r => Integer -> SValue r
litInt Integer
2)
        (Just SValue JuliaCode
e, Maybe Integer
Nothing) -> (SVariable JuliaCode
-> JuliaCode ScopeData
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
DeclStatement r smt =>
SVariable r -> r ScopeData -> SValue r -> MS (r smt)
varDecDef SVariable JuliaCode
endVar JuliaCode ScopeData
scp (SValue JuliaCode -> MS (JuliaCode (Doc, Terminator)))
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall a b. (a -> b) -> a -> b
$
          SValue JuliaCode
-> SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
ValueExpression r =>
SValue r -> SValue r -> SValue r -> SValue r
inlineIf (SValue JuliaCode
step SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
Comparison r =>
SValue r -> SValue r -> SValue r
?> Integer -> SValue JuliaCode
forall (r :: * -> *). Literal r => Integer -> SValue r
litInt Integer
0) SValue JuliaCode
e (SValue JuliaCode
e SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(Literal r, NumericExpression r, RenderValue r, ValueElim r) =>
SValue r -> SValue r -> SValue r
`G.smartAdd` Integer -> SValue JuliaCode
forall (r :: * -> *). Literal r => Integer -> SValue r
litInt Integer
2),
          SVariable JuliaCode -> SValue JuliaCode
forall (r :: * -> *). VariableValue r => SVariable r -> SValue r
valueOf SVariable JuliaCode
endVar)
        (Maybe (SValue JuliaCode)
Nothing, Just Integer
s) -> (MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt. StatementSym r smt => MS (r smt)
emptyStmt,
          if Integer
s Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0 then VS (JuliaCode TypeData) -> Doc -> SValue JuliaCode
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Doc -> SValue r
mkStateVal VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
int Doc
jlEnd else VS (JuliaCode TypeData) -> Doc -> SValue JuliaCode
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Doc -> SValue r
mkStateVal VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
int Doc
jlBegin)
        (Maybe (SValue JuliaCode)
Nothing, Maybe Integer
Nothing) -> (SVariable JuliaCode
-> JuliaCode ScopeData
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
DeclStatement r smt =>
SVariable r -> r ScopeData -> SValue r -> MS (r smt)
varDecDef SVariable JuliaCode
endVar JuliaCode ScopeData
scp (SValue JuliaCode -> MS (JuliaCode (Doc, Terminator)))
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall a b. (a -> b) -> a -> b
$
          SValue JuliaCode
-> SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
ValueExpression r =>
SValue r -> SValue r -> SValue r -> SValue r
inlineIf (SValue JuliaCode
step SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
Comparison r =>
SValue r -> SValue r -> SValue r
?> Integer -> SValue JuliaCode
forall (r :: * -> *). Literal r => Integer -> SValue r
litInt Integer
0) (SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *) smt. List r smt => SValue r -> SValue r
listSize SValue JuliaCode
vo) (Integer -> SValue JuliaCode
forall (r :: * -> *). Literal r => Integer -> SValue r
litInt Integer
1), SVariable JuliaCode -> SValue JuliaCode
forall (r :: * -> *). VariableValue r => SVariable r -> SValue r
valueOf SVariable JuliaCode
endVar)

      setToSlice :: MS (JuliaCode (Doc, Terminator))
setToSlice = SVariable JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
-> Maybe Integer
-> MS (JuliaCode (Doc, Terminator))
jlListSlice' SVariable JuliaCode
vn SValue JuliaCode
vo SValue JuliaCode
begVal SValue JuliaCode
endVal SValue JuliaCode
step Maybe Integer
mbStepV

  [MS (JuliaCode (Doc, Terminator))] -> MS (JuliaCode Doc)
forall (r :: * -> *) smt.
BlockSym r smt =>
[MS (r smt)] -> MS (r Doc)
block [
      MS (JuliaCode (Doc, Terminator))
setBeg,
      MS (JuliaCode (Doc, Terminator))
setEnd,
      MS (JuliaCode (Doc, Terminator))
setToSlice
    ]

jlListSlice'
  :: SVariable JuliaCode
  -> SValue JuliaCode
  -> SValue JuliaCode
  -> SValue JuliaCode
  -> SValue JuliaCode
  -> Maybe Integer
  -> MS (JuliaCode (Doc, Terminator))
jlListSlice' :: SVariable JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
-> SValue JuliaCode
-> Maybe Integer
-> MS (JuliaCode (Doc, Terminator))
jlListSlice' SVariable JuliaCode
vn SValue JuliaCode
vo SValue JuliaCode
beg SValue JuliaCode
end SValue JuliaCode
step Maybe Integer
mStep = do
  JuliaCode Value
vold  <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Value))
  MethodState
  ValueState
-> SValue JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Value))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Value) ValueState)
-> MethodState -> Focusing Identity (JuliaCode Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue JuliaCode
vo
  JuliaCode Value
beg'  <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Value))
  MethodState
  ValueState
-> SValue JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Value))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Value) ValueState)
-> MethodState -> Focusing Identity (JuliaCode Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue JuliaCode
beg
  JuliaCode Value
end'  <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Value))
  MethodState
  ValueState
-> SValue JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Value))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Value) ValueState)
-> MethodState -> Focusing Identity (JuliaCode Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue JuliaCode
end
  JuliaCode Value
step' <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Value))
  MethodState
  ValueState
-> SValue JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Value))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Value) ValueState)
-> MethodState -> Focusing Identity (JuliaCode Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue JuliaCode
step
  let stepDoc :: Doc
stepDoc = case Maybe Integer
mStep of
        (Just Integer
1) -> Doc
empty
        Maybe Integer
_        -> Doc
colon Doc -> Doc -> Doc
<> JuliaCode Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value JuliaCode Value
step'
      theSlice :: SValue JuliaCode
theSlice = VS (JuliaCode TypeData) -> Doc -> SValue JuliaCode
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Doc -> SValue r
mkStateVal VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
void (JuliaCode Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value JuliaCode Value
vold Doc -> Doc -> Doc
<> Doc -> Doc
brackets (JuliaCode Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value JuliaCode Value
beg' Doc -> Doc -> Doc
<> Doc
stepDoc Doc -> Doc -> Doc
<> Doc
colon Doc -> Doc -> Doc
<> JuliaCode Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value JuliaCode Value
end'))
  SVariable JuliaCode
vn SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
AssignStatement r smt =>
SVariable r -> SValue r -> MS (r smt)
&= SValue JuliaCode
theSlice

-- Other functionality
jlRange :: SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
jlRange :: SValue JuliaCode
-> SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
jlRange SValue JuliaCode
initv SValue JuliaCode
finalv SValue JuliaCode
stepv = do
  JuliaCode TypeData
t <- VS (JuliaCode TypeData) -> VS (JuliaCode TypeData)
forall (r :: * -> *).
TypeSym r =>
VS (r TypeData) -> VS (r TypeData)
listType VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
int
  JuliaCode Value
iv <- SValue JuliaCode
initv
  JuliaCode Value
sv <- SValue JuliaCode
stepv
  JuliaCode Value
fv <- SValue JuliaCode
finalv SValue JuliaCode -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(Literal r, NumericExpression r, RenderValue r, ValueElim r) =>
SValue r -> SValue r -> SValue r
`G.smartSub` Integer -> SValue JuliaCode
forall (r :: * -> *). Literal r => Integer -> SValue r
litInt Integer
1
  JuliaCode TypeData -> Doc -> SValue JuliaCode
forall (r :: * -> *).
RenderValue r =>
r TypeData -> Doc -> SValue r
mkVal JuliaCode TypeData
t (JuliaCode Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value JuliaCode Value
iv Doc -> Doc -> Doc
<> Doc
colon Doc -> Doc -> Doc
<> JuliaCode Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value JuliaCode Value
sv Doc -> Doc -> Doc
<> Doc
colon Doc -> Doc -> Doc
<> JuliaCode Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value JuliaCode Value
fv)

jlSplit :: String
jlSplit :: Label
jlSplit = Label
"split"

jlPrintFunc, jlPrintLnFunc :: Doc
jlPrintFunc :: Doc
jlPrintFunc = Label -> Doc
text Label
printLabel
jlPrintLnFunc :: Doc
jlPrintLnFunc = Label -> Doc
text Label
"println"

jlParseFunc :: Label
jlParseFunc :: Label
jlParseFunc = Label
"parse"

jlType, arrow, jlNamedArgSep :: Doc
jlType :: Doc
jlType = Doc
colon Doc -> Doc -> Doc
<> Doc
colon
arrow :: Doc
arrow = Label -> Doc
text Label
"->"
jlNamedArgSep :: Doc
jlNamedArgSep = Doc
equals

jlTuple :: [String] -> String
jlTuple :: [Label] -> Label
jlTuple [Label]
ts = Label
"Tuple{" Label -> Label -> Label
forall a. [a] -> [a] -> [a]
++ Label -> [Label] -> Label
forall a. [a] -> [[a]] -> [a]
intercalate Label
listSep [Label]
ts Label -> Label -> Label
forall a. [a] -> [a] -> [a]
++ Label
"}"

-- Operators
jlUnaryMath :: (Monad r) => String -> VSOp r
jlUnaryMath :: forall (r :: * -> *). Monad r => Label -> VSOp r
jlUnaryMath = Label -> VSOp r
forall (r :: * -> *). Monad r => Label -> VSOp r
unOpPrec

jlPower, jlIntDiv :: String
jlPower :: Label
jlPower = Label
"^"
jlIntDiv :: Label
jlIntDiv = Label
"÷"

-- Constants
jlPi :: Doc
jlPi :: Doc
jlPi = Label -> Doc
text Label
"pi"

-- Comments
jlCmtStart, jlBlockCmtStart, jlBlockCmtEnd, jlDocCmtStart, jlDocCmtEnd :: Doc
jlCmtStart :: Doc
jlCmtStart      = Label -> Doc
text Label
"#"
jlBlockCmtStart :: Doc
jlBlockCmtStart = Label -> Doc
text Label
"#="
jlBlockCmtEnd :: Doc
jlBlockCmtEnd   = Label -> Doc
text Label
"=#"
jlDocCmtStart :: Doc
jlDocCmtStart   = Label -> Doc
text Label
"\"\"\""
jlDocCmtEnd :: Doc
jlDocCmtEnd     = Label -> Doc
text Label
"\"\"\""

-- Control structures

jlSpace :: OptionalSpace
jlSpace :: OptionalSpace
jlSpace = OSpace {oSpace :: Doc
oSpace = Doc
empty}

-- | Creates a for-each loop in Julia
jlForEach
  :: (BodyElim r, InternalVarElim r, ValueElim r)
  => r Variable -> r Value -> r Body -> Doc
jlForEach :: forall (r :: * -> *).
(BodyElim r, InternalVarElim r, ValueElim r) =>
r Variable -> r Value -> r Doc -> Doc
jlForEach r Variable
i r Value
lstVar r Doc
b = [Doc] -> Doc
vcat [
  Doc
forLabel Doc -> Doc -> Doc
<+> r Variable -> Doc
forall (r :: * -> *). InternalVarElim r => r Variable -> Doc
RC.variable r Variable
i Doc -> Doc -> Doc
<+> Doc
inLabel Doc -> Doc -> Doc
<+> r Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value r Value
lstVar,
  Doc -> Doc
indent (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ r Doc -> Doc
forall (r :: * -> *). BodyElim r => r Doc -> Doc
RC.body r Doc
b,
  Doc
jlEnd]

-- | Creates the contents of a module in Julia
jlModContents
  :: Label -> [Label] -> [MS (JuliaCode MethodData)] -> FS (JuliaCode Module)
jlModContents :: Label
-> [Label] -> [MS (JuliaCode MethodData)] -> FS (JuliaCode Module)
jlModContents Label
n [Label]
is = Label
-> FS Doc
-> FS Doc
-> [MS (JuliaCode MethodData)]
-> FS (JuliaCode Module)
forall (r :: * -> *) md.
(MethodElim r md, RenderMod r) =>
Label -> FS Doc -> FS Doc -> [MS (r md)] -> FS (r Module)
A.buildModule Label
n (do
  [Label]
lis <- FS [Label]
getLangImports
  [Label]
libis <- FS [Label]
getLibImports
  [Label]
mis <- FS [Label]
getModuleImports
  Doc -> FS Doc
forall a. a -> StateT FileState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Doc -> FS Doc) -> Doc -> FS Doc
forall a b. (a -> b) -> a -> b
$ [Doc] -> Doc
vibcat [
    [Doc] -> Doc
vcat ((Label -> Doc) -> [Label] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (JuliaCode Doc -> Doc
forall (r :: * -> *). UnRepr r Doc => r Doc -> Doc
RC.import' (JuliaCode Doc -> Doc) -> (Label -> JuliaCode Doc) -> Label -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Label -> JuliaCode Doc
li) [Label]
lis),
    [Doc] -> Doc
vcat ((Label -> Doc) -> [Label] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (JuliaCode Doc -> Doc
forall (r :: * -> *). UnRepr r Doc => r Doc -> Doc
RC.import' (JuliaCode Doc -> Doc) -> (Label -> JuliaCode Doc) -> Label -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Label -> JuliaCode Doc
li) ([Label] -> [Label]
forall a. Ord a => [a] -> [a]
sort ([Label] -> [Label]) -> [Label] -> [Label]
forall a b. (a -> b) -> a -> b
$ [Label]
is [Label] -> [Label] -> [Label]
forall a. [a] -> [a] -> [a]
++ [Label]
libis)),
    [Doc] -> Doc
vcat ((Label -> Doc) -> [Label] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (JuliaCode Doc -> Doc
forall (r :: * -> *). UnRepr r Doc => r Doc -> Doc
RC.import' (JuliaCode Doc -> Doc) -> (Label -> JuliaCode Doc) -> Label -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Label -> JuliaCode Doc
mi) [Label]
mis)])
  (do FS Doc
getMainDoc)
  where mi, li :: Label -> JuliaCode Doc
        mi :: Label -> JuliaCode Doc
mi = Label -> JuliaCode Doc
forall (r :: * -> *). ImportSym r => Label -> r Doc
modImport
        li :: Label -> JuliaCode Doc
li = Label -> JuliaCode Doc
forall (r :: * -> *). ImportSym r => Label -> r Doc
langImport

-- Functions
-- | Creates a function.  n is function name, pms is list of parameters, and
--   bod is body.
jlIntFunc
  :: (BodyElim r, ParamElim r)
  => Label -> [r ParamData] -> r Body -> Doc
jlIntFunc :: forall (r :: * -> *).
(BodyElim r, ParamElim r) =>
Label -> [r ParamData] -> r Doc -> Doc
jlIntFunc Label
n [r ParamData]
pms r Doc
bod = do
  [Doc] -> Doc
vcat [Doc
jlFunc Doc -> Doc -> Doc
<+> Label -> Doc
text Label
n Doc -> Doc -> Doc
<> Doc -> Doc
parens ([r ParamData] -> Doc
forall (r :: * -> *). ParamElim r => [r ParamData] -> Doc
parameterList [r ParamData]
pms),
        Doc -> Doc
indent (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ r Doc -> Doc
forall (r :: * -> *). BodyElim r => r Doc -> Doc
RC.body r Doc
bod,
        Doc
jlEnd]

jlLambda :: (InternalBinderElim r, ValueElim r) => [r BinderD] ->
  r Value -> Doc
jlLambda :: forall (r :: * -> *).
(InternalBinderElim r, ValueElim r) =>
[r BinderD] -> r Value -> Doc
jlLambda [r BinderD]
ps r Value
ex = [r BinderD] -> Doc
forall (r :: * -> *). InternalBinderElim r => [r BinderD] -> Doc
binderList [r BinderD]
ps Doc -> Doc -> Doc
<+> Doc
arrow Doc -> Doc -> Doc
<+> r Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value r Value
ex

-- Exceptions
jlThrow :: (ValueElim r) => r Value -> Doc
jlThrow :: forall (r :: * -> *). ValueElim r => r Value -> Doc
jlThrow r Value
errMsg = Doc
jlThrowLabel Doc -> Doc -> Doc
<> Doc -> Doc
parens (r Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value r Value
errMsg)

jlTryCatch :: (BodyElim r) => r Body -> r Body -> Doc
jlTryCatch :: forall (r :: * -> *). BodyElim r => r Doc -> r Doc -> Doc
jlTryCatch r Doc
tryB r Doc
catchB = [Doc] -> Doc
vcat [
  Doc
tryLabel,
  Doc -> Doc
indent (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ r Doc -> Doc
forall (r :: * -> *). BodyElim r => r Doc -> Doc
RC.body r Doc
tryB,
  Doc
catchLabel Doc -> Doc -> Doc
<+> Doc
jlException,
  Doc -> Doc
indent (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ r Doc -> Doc
forall (r :: * -> *). BodyElim r => r Doc -> Doc
RC.body r Doc
catchB,
  Doc
jlEnd]

jlException :: Doc
jlException :: Doc
jlException = Label -> Doc
text Label
"ErrorException"

includeLabel, importLabel :: Doc
includeLabel :: Doc
includeLabel = Label -> Doc
text Label
"include"
importLabel :: Doc
importLabel = Label -> Doc
text Label
"import"

-- Assertions
jlAssert :: (ValueElim r) => r Value -> r Value -> Doc
jlAssert :: forall (r :: * -> *). ValueElim r => r Value -> r Value -> Doc
jlAssert r Value
condition r Value
errorMessage = [Doc] -> Doc
vcat [
  Label -> Doc
text Label
"@assert" Doc -> Doc -> Doc
<+> r Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value r Value
condition Doc -> Doc -> Doc
<+> r Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value r Value
errorMessage
  ]

jlMod, elseIfLabel, jlFunc, jlBegin, jlEnd, jlThrowLabel :: Doc
jlMod :: Doc
jlMod        = Label -> Doc
text Label
"module"
elseIfLabel :: Doc
elseIfLabel  = Label -> Doc
text Label
"elseif"
jlFunc :: Doc
jlFunc       = Label -> Doc
text Label
"function"
jlBegin :: Doc
jlBegin      = Label -> Doc
text Label
"begin"
jlEnd :: Doc
jlEnd        = Label -> Doc
text Label
"end"
jlThrowLabel :: Doc
jlThrowLabel = Label -> Doc
text Label
"error" -- TODO: this hints at an underdeveloped exception system

jlParam :: JuliaCode Variable -> Doc
jlParam :: JuliaCode Variable -> Doc
jlParam JuliaCode Variable
v = JuliaCode Variable -> Doc
forall (r :: * -> *). InternalVarElim r => r Variable -> Doc
RC.variable JuliaCode Variable
v Doc -> Doc -> Doc
<> Doc
jlType Doc -> Doc -> Doc
<> JuliaCode TypeData -> Doc
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType (JuliaCode Variable -> JuliaCode TypeData
forall (r :: * -> *). VariableElim r => r Variable -> r TypeData
variableType JuliaCode Variable
v)

-- Type names specific to Julia (there's a lot of them)
jlIntType :: (Monad r) => VS (r TypeData)
jlIntType :: forall (r :: * -> *). Monad r => VS (r TypeData)
jlIntType = CodeType -> Label -> Doc -> VS (r TypeData)
forall (r :: * -> *).
Monad r =>
CodeType -> Label -> Doc -> VS (r TypeData)
typeFromData CodeType
Integer Label
jlIntConc (Label -> Doc
text Label
jlIntConc)

jlFloatType :: (Monad r) => VS (r TypeData)
jlFloatType :: forall (r :: * -> *). Monad r => VS (r TypeData)
jlFloatType = CodeType -> Label -> Doc -> VS (r TypeData)
forall (r :: * -> *).
Monad r =>
CodeType -> Label -> Doc -> VS (r TypeData)
typeFromData CodeType
Float Label
jlFloatConc (Label -> Doc
text Label
jlFloatConc)

jlDoubleType :: (Monad r) => VS (r TypeData)
jlDoubleType :: forall (r :: * -> *). Monad r => VS (r TypeData)
jlDoubleType = CodeType -> Label -> Doc -> VS (r TypeData)
forall (r :: * -> *).
Monad r =>
CodeType -> Label -> Doc -> VS (r TypeData)
typeFromData CodeType
Double Label
jlDoubleConc (Label -> Doc
text Label
jlDoubleConc)

jlCharType :: (Monad r) => VS (r TypeData)
jlCharType :: forall (r :: * -> *). Monad r => VS (r TypeData)
jlCharType = CodeType -> Label -> Doc -> VS (r TypeData)
forall (r :: * -> *).
Monad r =>
CodeType -> Label -> Doc -> VS (r TypeData)
typeFromData CodeType
Char Label
jlCharConc (Label -> Doc
text Label
jlCharConc)

jlStringType :: (Monad r) => VS (r TypeData)
jlStringType :: forall (r :: * -> *). Monad r => VS (r TypeData)
jlStringType = CodeType -> Label -> Doc -> VS (r TypeData)
forall (r :: * -> *).
Monad r =>
CodeType -> Label -> Doc -> VS (r TypeData)
typeFromData CodeType
String Label
jlStringConc (Label -> Doc
text Label
jlStringConc)

jlInfileType :: (Monad r) => VS (r TypeData)
jlInfileType :: forall (r :: * -> *). Monad r => VS (r TypeData)
jlInfileType = CodeType -> Label -> Doc -> VS (r TypeData)
forall (r :: * -> *).
Monad r =>
CodeType -> Label -> Doc -> VS (r TypeData)
typeFromData CodeType
InFile Label
jlFile (Label -> Doc
text Label
jlFile)

jlOutfileType :: (Monad r) => VS (r TypeData)
jlOutfileType :: forall (r :: * -> *). Monad r => VS (r TypeData)
jlOutfileType = CodeType -> Label -> Doc -> VS (r TypeData)
forall (r :: * -> *).
Monad r =>
CodeType -> Label -> Doc -> VS (r TypeData)
typeFromData CodeType
OutFile Label
jlFile (Label -> Doc
text Label
jlFile)

jlListType :: (Monad r, TypeElim r, UnRepr r TypeData) =>
  VS (r TypeData) -> VS (r TypeData)
jlListType :: forall (r :: * -> *).
(Monad r, TypeElim r, UnRepr r TypeData) =>
VS (r TypeData) -> VS (r TypeData)
jlListType VS (r TypeData)
t' = do
  r TypeData
t <- VS (r TypeData)
t'
  let typeName :: Label
typeName = Label
jlListConc Label -> Label -> Label
forall a. [a] -> [a] -> [a]
++ Label
"{" Label -> Label -> Label
forall a. [a] -> [a] -> [a]
++ r TypeData -> Label
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Label
getTypeString r TypeData
t Label -> Label -> Label
forall a. [a] -> [a] -> [a]
++ Label
"}"
  CodeType -> Label -> Doc -> VS (r TypeData)
forall (r :: * -> *).
Monad r =>
CodeType -> Label -> Doc -> VS (r TypeData)
typeFromData (CodeType -> CodeType
List (CodeType -> CodeType) -> CodeType -> CodeType
forall a b. (a -> b) -> a -> b
$ r TypeData -> CodeType
forall (r :: * -> *). TypeElim r => r TypeData -> CodeType
getCodeType r TypeData
t) Label
typeName (Label -> Doc
text Label
typeName)

jlSetType :: (Monad r, TypeElim r, UnRepr r TypeData) =>
  VS (r TypeData) -> VS (r TypeData)
jlSetType :: forall (r :: * -> *).
(Monad r, TypeElim r, UnRepr r TypeData) =>
VS (r TypeData) -> VS (r TypeData)
jlSetType VS (r TypeData)
t' = do
  r TypeData
t <- VS (r TypeData)
t'
  let typeName :: Label
typeName = Label
jlSetConc Label -> Label -> Label
forall a. [a] -> [a] -> [a]
++ Label
"{" Label -> Label -> Label
forall a. [a] -> [a] -> [a]
++ r TypeData -> Label
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Label
getTypeString r TypeData
t Label -> Label -> Label
forall a. [a] -> [a] -> [a]
++ Label
"}"
  CodeType -> Label -> Doc -> VS (r TypeData)
forall (r :: * -> *).
Monad r =>
CodeType -> Label -> Doc -> VS (r TypeData)
typeFromData (CodeType -> CodeType
Set (CodeType -> CodeType) -> CodeType -> CodeType
forall a b. (a -> b) -> a -> b
$ r TypeData -> CodeType
forall (r :: * -> *). TypeElim r => r TypeData -> CodeType
getCodeType r TypeData
t) Label
typeName (Label -> Doc
text Label
typeName)

jlVoidType :: (Monad r) => VS (r TypeData)
jlVoidType :: forall (r :: * -> *). Monad r => VS (r TypeData)
jlVoidType = CodeType -> Label -> Doc -> VS (r TypeData)
forall (r :: * -> *).
Monad r =>
CodeType -> Label -> Doc -> VS (r TypeData)
typeFromData CodeType
Void Label
jlVoid (Label -> Doc
text Label
jlVoid)

jlNull :: Label
jlNull :: Label
jlNull = Label
"nothing"

-- Modules
-- | Creates the text for the start of a module.
--   n is the name of the module.
jlModStart :: Label -> Doc
jlModStart :: Label -> Doc
jlModStart Label
n = Doc
jlMod Doc -> Doc -> Doc
<+> Label -> Doc
text Label
n

-- IO
jlPrint :: Bool -> Maybe (SValue JuliaCode) -> SValue JuliaCode ->
  SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
-- Printing to console
jlPrint :: Bool
-> Maybe (SValue JuliaCode)
-> SValue JuliaCode
-> SValue JuliaCode
-> MS (JuliaCode (Doc, Terminator))
jlPrint Bool
_ Maybe (SValue JuliaCode)
f' SValue JuliaCode
p' SValue JuliaCode
v' = do
  JuliaCode Value
f <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Value))
  MethodState
  ValueState
-> SValue JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Value))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Value) ValueState)
-> MethodState -> Focusing Identity (JuliaCode Value) MethodState
Lens' MethodState ValueState
lensMStoVS (SValue JuliaCode -> StateT MethodState Identity (JuliaCode Value))
-> SValue JuliaCode
-> StateT MethodState Identity (JuliaCode Value)
forall a b. (a -> b) -> a -> b
$ SValue JuliaCode -> Maybe (SValue JuliaCode) -> SValue JuliaCode
forall a. a -> Maybe a -> a
fromMaybe (VS (JuliaCode TypeData) -> Doc -> SValue JuliaCode
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Doc -> SValue r
mkStateVal VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
void Doc
empty) Maybe (SValue JuliaCode)
f' -- The file to print to
  JuliaCode Value
prf <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Value))
  MethodState
  ValueState
-> SValue JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Value))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Value) ValueState)
-> MethodState -> Focusing Identity (JuliaCode Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue JuliaCode
p' -- The print function to use
  JuliaCode Value
v <- LensLike'
  (Zoomed (StateT ValueState Identity) (JuliaCode Value))
  MethodState
  ValueState
-> SValue JuliaCode
-> StateT MethodState Identity (JuliaCode 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) (JuliaCode Value))
  MethodState
  ValueState
(ValueState -> Focusing Identity (JuliaCode Value) ValueState)
-> MethodState -> Focusing Identity (JuliaCode Value) MethodState
Lens' MethodState ValueState
lensMStoVS SValue JuliaCode
v' -- The value to print
  let fl :: Doc
fl = Doc -> Doc -> Doc
emptyIfEmpty (JuliaCode Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value JuliaCode Value
f) (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ JuliaCode Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value JuliaCode Value
f Doc -> Doc -> Doc
<> Doc
listSep'
  Doc -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
RenderStatement r smt =>
Doc -> MS (r smt)
mkStmtNoEnd (Doc -> MS (JuliaCode (Doc, Terminator)))
-> Doc -> MS (JuliaCode (Doc, Terminator))
forall a b. (a -> b) -> a -> b
$ JuliaCode Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value JuliaCode Value
prf Doc -> Doc -> Doc
<> Doc -> Doc
parens (Doc
fl Doc -> Doc -> Doc
<> JuliaCode Value -> Doc
forall (r :: * -> *). ValueElim r => r Value -> Doc
RC.value JuliaCode Value
v)

-- jlPrint can handle lists, so don't use G.print for lists
jlOut
  :: (InternalIOStmt r smt, SharedStatement r smt, TypeElim r)
  => Bool -> Maybe (SValue r) -> SValue r -> SValue r -> MS (r smt)
jlOut :: forall (r :: * -> *) smt.
(InternalIOStmt r smt, SharedStatement r smt, TypeElim r) =>
Bool -> Maybe (SValue r) -> SValue r -> SValue r -> MS (r smt)
jlOut 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)
jlOut' (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 jlOut' :: CodeType -> StateT MethodState Identity (r smt)
jlOut' (List 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)
printSt Bool
newLn Maybe (SValue r)
f SValue r
printFn SValue r
v
        jlOut' CodeType
_ = Bool
-> Maybe (SValue r)
-> SValue r
-> SValue r
-> StateT MethodState Identity (r smt)
forall (r :: * -> *) smt.
(InternalIOStmt r smt, SharedStatement r smt, TypeElim r) =>
Bool -> Maybe (SValue r) -> SValue r -> SValue r -> MS (r smt)
G.print Bool
newLn Maybe (SValue r)
f SValue r
printFn SValue r
v

jlInput :: SValue JuliaCode -> SVariable JuliaCode -> MS (JuliaCode (Doc, Terminator))
jlInput :: SValue JuliaCode
-> SVariable JuliaCode -> MS (JuliaCode (Doc, Terminator))
jlInput SValue JuliaCode
inSrc SVariable JuliaCode
v = SVariable JuliaCode
v SVariable JuliaCode
-> SValue JuliaCode -> MS (JuliaCode (Doc, Terminator))
forall (r :: * -> *) smt.
AssignStatement r smt =>
SVariable r -> SValue r -> MS (r smt)
&= (SVariable JuliaCode
v SVariable JuliaCode
-> (JuliaCode Variable -> SValue JuliaCode) -> SValue JuliaCode
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 -> SValue JuliaCode
jlInput' (CodeType -> SValue JuliaCode)
-> (JuliaCode Variable -> CodeType)
-> JuliaCode Variable
-> SValue JuliaCode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode TypeData -> CodeType
forall (r :: * -> *). TypeElim r => r TypeData -> CodeType
getCodeType (JuliaCode TypeData -> CodeType)
-> (JuliaCode Variable -> JuliaCode TypeData)
-> JuliaCode Variable
-> CodeType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JuliaCode Variable -> JuliaCode TypeData
forall (r :: * -> *). VariableElim r => r Variable -> r TypeData
variableType)
  where jlInput' :: CodeType -> SValue JuliaCode
jlInput' CodeType
Integer = Label
-> VS (JuliaCode TypeData) -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(RenderValue r, ValueExpression r) =>
Label -> VS (r TypeData) -> SValue r -> SValue r
jlParse Label
jlIntConc VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
int SValue JuliaCode
inSrc
        jlInput' CodeType
Float = Label
-> VS (JuliaCode TypeData) -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(RenderValue r, ValueExpression r) =>
Label -> VS (r TypeData) -> SValue r -> SValue r
jlParse Label
jlFloatConc VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
float SValue JuliaCode
inSrc
        jlInput' CodeType
Double = Label
-> VS (JuliaCode TypeData) -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(RenderValue r, ValueExpression r) =>
Label -> VS (r TypeData) -> SValue r -> SValue r
jlParse Label
jlDoubleConc VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
double SValue JuliaCode
inSrc
        jlInput' CodeType
Boolean = Label
-> VS (JuliaCode TypeData) -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(RenderValue r, ValueExpression r) =>
Label -> VS (r TypeData) -> SValue r -> SValue r
jlParse Label
CS.boolRender VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
bool SValue JuliaCode
inSrc
        jlInput' CodeType
String = SValue JuliaCode
inSrc
        jlInput' CodeType
Char = Label
-> VS (JuliaCode TypeData) -> SValue JuliaCode -> SValue JuliaCode
forall (r :: * -> *).
(RenderValue r, ValueExpression r) =>
Label -> VS (r TypeData) -> SValue r -> SValue r
jlParse Label
jlCharConc VS (JuliaCode TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
char SValue JuliaCode
inSrc
        jlInput' CodeType
_ = Label -> SValue JuliaCode
forall a. HasCallStack => Label -> a
error Label
"Attempt to read a value of unreadable type"

readLine, readLines :: (ValueExpression r) => SValue r -> SValue r
readLine :: forall (r :: * -> *). ValueExpression r => SValue r -> SValue r
readLine SValue r
f = PosCall r
forall (r :: * -> *). ValueExpression r => PosCall r
funcApp Label
jlReadLineFunc VS (r TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
string [SValue r
f]
readLines :: forall (r :: * -> *). ValueExpression r => SValue r -> SValue r
readLines SValue r
f = PosCall r
forall (r :: * -> *). ValueExpression r => PosCall r
funcApp Label
jlReadLinesFunc (VS (r TypeData) -> VS (r TypeData)
forall (r :: * -> *).
TypeSym r =>
VS (r TypeData) -> VS (r TypeData)
listType VS (r TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
string) [SValue r
f]

jlReadLine :: Doc
jlReadLine :: Doc
jlReadLine = Label -> Doc
text Label
jlReadLineFunc

jlReadLineFunc, jlReadLinesFunc, jlCloseFunc :: Label
jlReadLineFunc :: Label
jlReadLineFunc = Label
"readline"
jlReadLinesFunc :: Label
jlReadLinesFunc = Label
"readlines"
jlCloseFunc :: Label
jlCloseFunc = Label
"close"

jlArgs :: Label
jlArgs :: Label
jlArgs = Label
"ARGS"

jlParse :: (RenderValue r, ValueExpression r) => Label -> VS (r TypeData) ->
  SValue r -> SValue r
jlParse :: forall (r :: * -> *).
(RenderValue r, ValueExpression r) =>
Label -> VS (r TypeData) -> SValue r -> SValue r
jlParse Label
tl VS (r TypeData)
tp SValue r
v = let
  typeLabel :: SValue r
typeLabel = VS (r TypeData) -> Doc -> SValue r
forall (r :: * -> *).
RenderValue r =>
VS (r TypeData) -> Doc -> SValue r
mkStateVal VS (r TypeData)
forall (r :: * -> *). TypeSym r => VS (r TypeData)
void (Label -> Doc
text Label
tl)
  in PosCall r
forall (r :: * -> *). ValueExpression r => PosCall r
funcApp Label
jlParseFunc VS (r TypeData)
tp [SValue r
typeLabel, SValue r
v]