{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecursiveDo #-}
module CodeGen.RiscV.AsmGen (ppRiscVAsm) where
import CodeGen.Module (Module (..))
import qualified CodeGen.RiscV.Lib as Rv
import Control.Monad.State (MonadState, State, evalState, gets, modify)
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Text (Text)
import qualified Data.Text as Txt
import Foreign (fromBool)
import MonadUtils (locally)
import qualified StdLib
import Transformations.Anf.Anf
import Trees.Common
ppRiscVAsm :: Module -> Text
ppRiscVAsm :: Module -> Identifier
ppRiscVAsm Module
m = [CodeLine] -> Identifier
Rv.ppCodeLines ([CodeLine] -> Identifier) -> [CodeLine] -> Identifier
forall a b. (a -> b) -> a -> b
$ Module -> [CodeLine]
genModule Module
m
type CodeGenM = Rv.AsmBuilderT (State Env)
data Env = Env
{ Env -> Map Identifier' Operand
locVars :: Map Identifier' Rv.Operand,
Env -> Map Identifier' Operand
globVars :: Map Identifier' Rv.Operand,
Env -> Map Identifier' (Operand, Arity)
funs :: Map Identifier' (Rv.Operand, Arity)
}
genModule :: Module -> [Rv.CodeLine]
genModule :: Module -> [CodeLine]
genModule (Module (Program [GlobalDeclaration]
decls)) = (State Env [CodeLine] -> Env -> [CodeLine])
-> Env -> State Env [CodeLine] -> [CodeLine]
forall a b c. (a -> b -> c) -> b -> a -> c
flip State Env [CodeLine] -> Env -> [CodeLine]
forall s a. State s a -> s -> a
evalState (Map Identifier' Operand
-> Map Identifier' Operand
-> Map Identifier' (Operand, Arity)
-> Env
Env Map Identifier' Operand
forall k a. Map k a
Map.empty Map Identifier' Operand
forall k a. Map k a
Map.empty Map Identifier' (Operand, Arity)
forall k a. Map k a
Map.empty) (State Env [CodeLine] -> [CodeLine])
-> State Env [CodeLine] -> [CodeLine]
forall a b. (a -> b) -> a -> b
$
AsmBuilderT (State Env) () -> State Env [CodeLine]
forall (m :: * -> *) a. Monad m => AsmBuilderT m a -> m [CodeLine]
Rv.compileT (AsmBuilderT (State Env) () -> State Env [CodeLine])
-> AsmBuilderT (State Env) () -> State Env [CodeLine]
forall a b. (a -> b) -> a -> b
$ do
(DeclarationWithArity -> AsmBuilderT (State Env) ())
-> [DeclarationWithArity] -> AsmBuilderT (State Env) ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ DeclarationWithArity -> AsmBuilderT (State Env) ()
genStdLibDecl [DeclarationWithArity]
StdLib.allDeclsWithArity
(GlobalDeclaration -> AsmBuilderT (State Env) ())
-> [GlobalDeclaration] -> AsmBuilderT (State Env) ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ GlobalDeclaration -> AsmBuilderT (State Env) ()
genGlobDecl [GlobalDeclaration]
decls
(() -> AsmBuilderT (State Env) ()) -> AsmBuilderT (State Env) ()
forall (m :: * -> *). MonadAsmBuilder m => (() -> m ()) -> m ()
Rv.mainFunction ((() -> AsmBuilderT (State Env) ()) -> AsmBuilderT (State Env) ())
-> (() -> AsmBuilderT (State Env) ()) -> AsmBuilderT (State Env) ()
forall a b. (a -> b) -> a -> b
$ \()
_ -> (GlobalDeclaration -> AsmBuilderT (State Env) ())
-> [GlobalDeclaration] -> AsmBuilderT (State Env) ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ GlobalDeclaration -> AsmBuilderT (State Env) ()
gVarDef [GlobalDeclaration]
decls
where
gVarDef :: GlobalDeclaration -> CodeGenM ()
gVarDef :: GlobalDeclaration -> AsmBuilderT (State Env) ()
gVarDef = \case
GlobVarDecl Identifier'
ident Expression
value -> do
Operand
addr <- Identifier' -> AsmBuilderT (State Env) Operand
forall (m :: * -> *). MonadState Env m => Identifier' -> m Operand
findGlobVar Identifier'
ident
Operand
value' <- Expression -> AsmBuilderT (State Env) Operand
genExpr Expression
value
Operand -> Operand -> AsmBuilderT (State Env) ()
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> Operand -> m ()
Rv.storeToLabeledAddr Operand
addr Operand
value'
GlobalDeclaration
_ -> () -> AsmBuilderT (State Env) ()
forall a. a -> AsmBuilderT (State Env) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
genStdLibDecl :: StdLib.DeclarationWithArity -> CodeGenM ()
genStdLibDecl :: DeclarationWithArity -> AsmBuilderT (State Env) ()
genStdLibDecl DeclarationWithArity
decl = DeclarationWithArity -> AsmBuilderT (State Env) Operand
declareAsExtern DeclarationWithArity
decl AsmBuilderT (State Env) Operand
-> (Operand -> AsmBuilderT (State Env) ())
-> AsmBuilderT (State Env) ()
forall a b.
AsmBuilderT (State Env) a
-> (a -> AsmBuilderT (State Env) b) -> AsmBuilderT (State Env) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= DeclarationWithArity -> Operand -> AsmBuilderT (State Env) ()
register DeclarationWithArity
decl
where
declareAsExtern :: StdLib.DeclarationWithArity -> CodeGenM Rv.Operand
declareAsExtern :: DeclarationWithArity -> AsmBuilderT (State Env) Operand
declareAsExtern (Identifier
ident, Arity
_) = Identifier -> AsmBuilderT (State Env) Operand
forall (m :: * -> *). MonadAsmBuilder m => Identifier -> m Operand
Rv.externFunction Identifier
ident
register :: StdLib.DeclarationWithArity -> Rv.Operand -> CodeGenM ()
register :: DeclarationWithArity -> Operand -> AsmBuilderT (State Env) ()
register (Identifier
ident, Arity
arity) Operand
fun = Identifier' -> Operand -> Arity -> AsmBuilderT (State Env) ()
forall (m :: * -> *).
MonadState Env m =>
Identifier' -> Operand -> Arity -> m ()
regFun (Identifier -> Identifier'
Txt Identifier
ident) Operand
fun Arity
arity
genGlobDecl :: GlobalDeclaration -> CodeGenM ()
genGlobDecl :: GlobalDeclaration -> AsmBuilderT (State Env) ()
genGlobDecl = \case
GlobVarDecl Identifier'
ident Expression
_ -> do
Operand
var <- Identifier -> AsmBuilderT (State Env) Operand
forall (m :: * -> *). MonadAsmBuilder m => Identifier -> m Operand
Rv.globalVar (String -> Identifier
Txt.pack (String -> Identifier) -> String -> Identifier
forall a b. (a -> b) -> a -> b
$ Identifier' -> String
genId Identifier'
ident)
Identifier' -> Operand -> AsmBuilderT (State Env) ()
forall (m :: * -> *).
MonadState Env m =>
Identifier' -> Operand -> m ()
regGlobVar Identifier'
ident Operand
var
GlobFunDecl Identifier'
ident [Identifier']
params Expression
body -> mdo
Identifier' -> Operand -> Arity -> AsmBuilderT (State Env) ()
forall (m :: * -> *).
MonadState Env m =>
Identifier' -> Operand -> Arity -> m ()
regFun Identifier'
ident Operand
fun ([Identifier'] -> Arity
forall a. [a] -> Arity
forall (t :: * -> *) a. Foldable t => t a -> Arity
length [Identifier']
params)
Operand
fun <- AsmBuilderT (State Env) Operand -> AsmBuilderT (State Env) Operand
forall s (m :: * -> *) a. MonadState s m => m a -> m a
locally (AsmBuilderT (State Env) Operand
-> AsmBuilderT (State Env) Operand)
-> AsmBuilderT (State Env) Operand
-> AsmBuilderT (State Env) Operand
forall a b. (a -> b) -> a -> b
$ do
Identifier
-> Int64
-> ([Operand] -> AsmBuilderT (State Env) Operand)
-> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Identifier -> Int64 -> ([Operand] -> m Operand) -> m Operand
Rv.function
(String -> Identifier
Txt.pack (String -> Identifier) -> String -> Identifier
forall a b. (a -> b) -> a -> b
$ Identifier' -> String
genId Identifier'
ident)
(Arity -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Arity -> Int64) -> Arity -> Int64
forall a b. (a -> b) -> a -> b
$ [Identifier'] -> Arity
forall a. [a] -> Arity
forall (t :: * -> *) a. Foldable t => t a -> Arity
length [Identifier']
params)
(([Operand] -> AsmBuilderT (State Env) Operand)
-> AsmBuilderT (State Env) Operand)
-> ([Operand] -> AsmBuilderT (State Env) Operand)
-> AsmBuilderT (State Env) Operand
forall a b. (a -> b) -> a -> b
$ \[Operand]
args -> do
((Identifier', Operand) -> AsmBuilderT (State Env) ())
-> [(Identifier', Operand)] -> AsmBuilderT (State Env) ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ((Identifier' -> Operand -> AsmBuilderT (State Env) ())
-> (Identifier', Operand) -> AsmBuilderT (State Env) ()
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Identifier' -> Operand -> AsmBuilderT (State Env) ()
forall (m :: * -> *).
MonadState Env m =>
Identifier' -> Operand -> m ()
regLocVar) ([Identifier']
params [Identifier'] -> [Operand] -> [(Identifier', Operand)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` [Operand]
args)
Expression -> AsmBuilderT (State Env) Operand
genExpr Expression
body
() -> AsmBuilderT (State Env) ()
forall a. a -> AsmBuilderT (State Env) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
genId :: Identifier' -> String
genId :: Identifier' -> String
genId = \case
Txt Identifier
txt -> Identifier -> String
Txt.unpack Identifier
txt
Gen IdCnt
n Identifier
txt -> Identifier -> String
Txt.unpack Identifier
txt String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"_" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> IdCnt -> String
forall a. Show a => a -> String
show IdCnt
n
genExpr :: Expression -> CodeGenM Rv.Operand
genExpr :: Expression -> AsmBuilderT (State Env) Operand
genExpr = \case
ExprAtom AtomicExpression
atom -> AtomicExpression -> AsmBuilderT (State Env) Operand
genAtom AtomicExpression
atom
ExprComp ComplexExpression
ce -> ComplexExpression -> AsmBuilderT (State Env) Operand
genComp ComplexExpression
ce
ExprLetIn (Identifier'
ident, Expression
val) Expression
expr -> do
Operand
val' <- Expression -> AsmBuilderT (State Env) Operand
genExpr Expression
val
Identifier' -> Operand -> AsmBuilderT (State Env) ()
forall (m :: * -> *).
MonadState Env m =>
Identifier' -> Operand -> m ()
regLocVar Identifier'
ident Operand
val'
Expression -> AsmBuilderT (State Env) Operand
genExpr Expression
expr
genAtom :: AtomicExpression -> CodeGenM Rv.Operand
genAtom :: AtomicExpression -> AsmBuilderT (State Env) Operand
genAtom = \case
AtomId Identifier'
ident -> Identifier' -> AsmBuilderT (State Env) Operand
findAny Identifier'
ident
AtomicExpression
AtomUnit -> Int64 -> AsmBuilderT (State Env) Operand
forall (m :: * -> *). MonadAsmBuilder m => Int64 -> m Operand
Rv.immediate Int64
0
AtomBool Bool
bool -> Int64 -> AsmBuilderT (State Env) Operand
forall (m :: * -> *). MonadAsmBuilder m => Int64 -> m Operand
Rv.immediate (Int64 -> AsmBuilderT (State Env) Operand)
-> Int64 -> AsmBuilderT (State Env) Operand
forall a b. (a -> b) -> a -> b
$ Bool -> Int64
forall a. Num a => Bool -> a
fromBool Bool
bool
AtomInt Int64
int -> Int64 -> AsmBuilderT (State Env) Operand
forall (m :: * -> *). MonadAsmBuilder m => Int64 -> m Operand
Rv.immediate Int64
int
genComp :: ComplexExpression -> CodeGenM Rv.Operand
genComp :: ComplexExpression -> AsmBuilderT (State Env) Operand
genComp = \case
CompApp Identifier'
f AtomicExpression
arg -> do
Operand
f' <- Identifier' -> AsmBuilderT (State Env) Operand
findAny Identifier'
f
Operand
arg' <- AtomicExpression -> AsmBuilderT (State Env) Operand
genAtom AtomicExpression
arg
Operand
applyF <- Identifier' -> AsmBuilderT (State Env) Operand
findFun (Identifier -> Identifier'
Txt Identifier
"miniml_apply")
Operand -> [Operand] -> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> [Operand] -> m Operand
Rv.call Operand
applyF [Operand
f', Operand
arg']
CompIte AtomicExpression
c Expression
t Expression
e -> do
Operand
c' <- AtomicExpression -> AsmBuilderT (State Env) Operand
genAtom AtomicExpression
c
Operand
-> (() -> AsmBuilderT (State Env) Operand)
-> (() -> AsmBuilderT (State Env) Operand)
-> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> (() -> m Operand) -> (() -> m Operand) -> m Operand
Rv.ite Operand
c' (\()
_ -> Expression -> AsmBuilderT (State Env) Operand
genExpr Expression
t) (\()
_ -> Expression -> AsmBuilderT (State Env) Operand
genExpr Expression
e)
CompBinOp BinaryOperator
op AtomicExpression
lhs AtomicExpression
rhs -> do
Operand
lhs' <- AtomicExpression -> AsmBuilderT (State Env) Operand
genAtom AtomicExpression
lhs
Operand
rhs' <- AtomicExpression -> AsmBuilderT (State Env) Operand
genAtom AtomicExpression
rhs
let opF :: Operand -> Operand -> AsmBuilderT (State Env) Operand
opF = case BinaryOperator
op of
BoolOp BooleanOperator
AndOp -> Operand -> Operand -> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> Operand -> m Operand
Rv.and
BoolOp BooleanOperator
OrOp -> Operand -> Operand -> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> Operand -> m Operand
Rv.or
ArithOp ArithmeticOperator
PlusOp -> Operand -> Operand -> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> Operand -> m Operand
Rv.add
ArithOp ArithmeticOperator
MinusOp -> Operand -> Operand -> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> Operand -> m Operand
Rv.sub
ArithOp ArithmeticOperator
MulOp -> Operand -> Operand -> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> Operand -> m Operand
Rv.mul
ArithOp ArithmeticOperator
DivOp ->
( \Operand
lhs'' Operand
rhs'' -> do
Operand
divF <- Identifier' -> AsmBuilderT (State Env) Operand
findFun (Identifier -> Identifier'
Txt Identifier
"miniml_div")
Operand -> [Operand] -> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> [Operand] -> m Operand
Rv.call Operand
divF [Operand
lhs'', Operand
rhs'']
)
CompOp ComparisonOperator
EqOp -> Operand -> Operand -> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> Operand -> m Operand
Rv.eq
CompOp ComparisonOperator
NeOp -> Operand -> Operand -> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> Operand -> m Operand
Rv.ne
CompOp ComparisonOperator
LtOp -> Operand -> Operand -> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> Operand -> m Operand
Rv.lt
CompOp ComparisonOperator
LeOp -> Operand -> Operand -> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> Operand -> m Operand
Rv.le
CompOp ComparisonOperator
GtOp -> Operand -> Operand -> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> Operand -> m Operand
Rv.gt
CompOp ComparisonOperator
GeOp -> Operand -> Operand -> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> Operand -> m Operand
Rv.ge
Operand -> Operand -> AsmBuilderT (State Env) Operand
opF Operand
lhs' Operand
rhs'
CompUnOp UnaryOperator
op AtomicExpression
x -> do
Operand
x' <- AtomicExpression -> AsmBuilderT (State Env) Operand
genAtom AtomicExpression
x
let opF :: Operand -> AsmBuilderT (State Env) Operand
opF = case UnaryOperator
op of
UnaryOperator
UnMinusOp -> Operand -> AsmBuilderT (State Env) Operand
forall (m :: * -> *). MonadAsmBuilder m => Operand -> m Operand
Rv.neg
Operand -> AsmBuilderT (State Env) Operand
opF Operand
x'
findAny :: Identifier' -> CodeGenM Rv.Operand
findAny :: Identifier' -> AsmBuilderT (State Env) Operand
findAny Identifier'
ident = do
Maybe Operand
maybeLocVar <- (Env -> Maybe Operand) -> AsmBuilderT (State Env) (Maybe Operand)
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets ((Map Identifier' Operand -> Identifier' -> Maybe Operand
forall k a. Ord k => Map k a -> k -> Maybe a
Map.!? Identifier'
ident) (Map Identifier' Operand -> Maybe Operand)
-> (Env -> Map Identifier' Operand) -> Env -> Maybe Operand
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Env -> Map Identifier' Operand
locVars)
case Maybe Operand
maybeLocVar of
Just Operand
locVar -> Operand -> AsmBuilderT (State Env) Operand
forall a. a -> AsmBuilderT (State Env) a
forall (m :: * -> *) a. Monad m => a -> m a
return Operand
locVar
Maybe Operand
Nothing -> do
Maybe (Operand, Arity)
maybeFun <- (Env -> Maybe (Operand, Arity))
-> AsmBuilderT (State Env) (Maybe (Operand, Arity))
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets ((Map Identifier' (Operand, Arity)
-> Identifier' -> Maybe (Operand, Arity)
forall k a. Ord k => Map k a -> k -> Maybe a
Map.!? Identifier'
ident) (Map Identifier' (Operand, Arity) -> Maybe (Operand, Arity))
-> (Env -> Map Identifier' (Operand, Arity))
-> Env
-> Maybe (Operand, Arity)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Env -> Map Identifier' (Operand, Arity)
funs)
case Maybe (Operand, Arity)
maybeFun of
Just (Operand
fun, Arity
arity) -> do
Operand
funToPafF <- Identifier' -> AsmBuilderT (State Env) Operand
findFun (Identifier -> Identifier'
Txt Identifier
"miniml_fun_to_paf")
Operand
arity' <- Int64 -> AsmBuilderT (State Env) Operand
forall (m :: * -> *). MonadAsmBuilder m => Int64 -> m Operand
Rv.immediate (Int64 -> AsmBuilderT (State Env) Operand)
-> Int64 -> AsmBuilderT (State Env) Operand
forall a b. (a -> b) -> a -> b
$ Arity -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Arity
arity
Operand -> [Operand] -> AsmBuilderT (State Env) Operand
forall (m :: * -> *).
MonadAsmBuilder m =>
Operand -> [Operand] -> m Operand
Rv.call Operand
funToPafF [Operand
fun, Operand
arity']
Maybe (Operand, Arity)
Nothing -> Identifier' -> AsmBuilderT (State Env) Operand
forall (m :: * -> *). MonadState Env m => Identifier' -> m Operand
findGlobVar Identifier'
ident
findGlobVar :: (MonadState Env m) => Identifier' -> m Rv.Operand
findGlobVar :: forall (m :: * -> *). MonadState Env m => Identifier' -> m Operand
findGlobVar Identifier'
ident = (Env -> Operand) -> m Operand
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets ((Map Identifier' Operand -> Identifier' -> Operand
forall k a. Ord k => Map k a -> k -> a
Map.! Identifier'
ident) (Map Identifier' Operand -> Operand)
-> (Env -> Map Identifier' Operand) -> Env -> Operand
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Env -> Map Identifier' Operand
globVars)
findFun :: Identifier' -> CodeGenM Rv.Operand
findFun :: Identifier' -> AsmBuilderT (State Env) Operand
findFun Identifier'
ident = (Env -> Operand) -> AsmBuilderT (State Env) Operand
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets ((Operand, Arity) -> Operand
forall a b. (a, b) -> a
fst ((Operand, Arity) -> Operand)
-> (Env -> (Operand, Arity)) -> Env -> Operand
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Map Identifier' (Operand, Arity) -> Identifier' -> (Operand, Arity)
forall k a. Ord k => Map k a -> k -> a
Map.! Identifier'
ident) (Map Identifier' (Operand, Arity) -> (Operand, Arity))
-> (Env -> Map Identifier' (Operand, Arity))
-> Env
-> (Operand, Arity)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Env -> Map Identifier' (Operand, Arity)
funs)
regLocVar :: (MonadState Env m) => Identifier' -> Rv.Operand -> m ()
regLocVar :: forall (m :: * -> *).
MonadState Env m =>
Identifier' -> Operand -> m ()
regLocVar Identifier'
ident Operand
var = (Env -> Env) -> m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((Env -> Env) -> m ()) -> (Env -> Env) -> m ()
forall a b. (a -> b) -> a -> b
$
\Env
env -> Env
env {locVars :: Map Identifier' Operand
locVars = Identifier'
-> Operand -> Map Identifier' Operand -> Map Identifier' Operand
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Identifier'
ident Operand
var (Env -> Map Identifier' Operand
locVars Env
env)}
regGlobVar :: (MonadState Env m) => Identifier' -> Rv.Operand -> m ()
regGlobVar :: forall (m :: * -> *).
MonadState Env m =>
Identifier' -> Operand -> m ()
regGlobVar Identifier'
ident Operand
gVar = (Env -> Env) -> m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((Env -> Env) -> m ()) -> (Env -> Env) -> m ()
forall a b. (a -> b) -> a -> b
$
\Env
env -> Env
env {globVars :: Map Identifier' Operand
globVars = Identifier'
-> Operand -> Map Identifier' Operand -> Map Identifier' Operand
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Identifier'
ident Operand
gVar (Env -> Map Identifier' Operand
globVars Env
env)}
regFun :: (MonadState Env m) => Identifier' -> Rv.Operand -> Arity -> m ()
regFun :: forall (m :: * -> *).
MonadState Env m =>
Identifier' -> Operand -> Arity -> m ()
regFun Identifier'
ident Operand
fun Arity
paramsCnt = (Env -> Env) -> m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((Env -> Env) -> m ()) -> (Env -> Env) -> m ()
forall a b. (a -> b) -> a -> b
$
\Env
env -> Env
env {funs :: Map Identifier' (Operand, Arity)
funs = Identifier'
-> (Operand, Arity)
-> Map Identifier' (Operand, Arity)
-> Map Identifier' (Operand, Arity)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Identifier'
ident (Operand
fun, Arity
paramsCnt) (Env -> Map Identifier' (Operand, Arity)
funs Env
env)}