{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}

-- |
-- Module      : Jikka.CPlusPlus.Convert.UseInitialization
-- Description : replaces declarations by assignments with initializations. / 代入による宣言を初期化による宣言で置き換えます。
-- Copyright   : (c) Kimiyuki Onaka, 2020
-- License     : Apache License 2.0
-- Maintainer  : kimiyuki95@gmail.com
-- Stability   : experimental
-- Portability : portable
module Jikka.CPlusPlus.Convert.UseInitialization
  ( run,
  )
where

import Jikka.CPlusPlus.Language.Expr
import Jikka.CPlusPlus.Language.Util
import Jikka.Common.Alpha
import Jikka.Common.Error

runStatement :: Statement -> Statement
runStatement :: Statement -> Statement
runStatement = \case
  Declare Type
t VarName
x DeclareRight
init -> case (Type
t, DeclareRight
init) of
    (TyVector Type
_, DeclareCopy (Call (VecCtor Type
_) [])) -> Type -> VarName -> DeclareRight -> Statement
Declare Type
t VarName
x DeclareRight
DeclareDefault
    (TyVector Type
_, DeclareCopy (Call (VecCtor Type
_) [Expr]
es)) -> Type -> VarName -> DeclareRight -> Statement
Declare Type
t VarName
x ([Expr] -> DeclareRight
DeclareInitialize [Expr]
es)
    (Type
TyConvexHullTrick, DeclareCopy (Call Function
ConvexHullTrickCtor [Expr]
es)) -> Type -> VarName -> DeclareRight -> Statement
Declare Type
t VarName
x ([Expr] -> DeclareRight
DeclareInitialize [Expr]
es)
    (TySegmentTree Monoid'
_, DeclareCopy (Call (SegmentTreeCtor Monoid'
_) [Expr]
es)) -> Type -> VarName -> DeclareRight -> Statement
Declare Type
t VarName
x ([Expr] -> DeclareRight
DeclareInitialize [Expr]
es)
    (Type
_, DeclareRight
_) -> Type -> VarName -> DeclareRight -> Statement
Declare Type
t VarName
x DeclareRight
init
  Statement
stmt -> Statement
stmt

runProgram :: Program -> Program
runProgram :: Program -> Program
runProgram = (Expr -> Expr) -> (Statement -> Statement) -> Program -> Program
mapExprStatementProgram Expr -> Expr
forall a. a -> a
id Statement -> Statement
runStatement

-- | `run` unpack tuples.
--
-- == Examples
--
-- Before:
--
-- > vector<int> xs = vector<int>(n, 0);
--
-- After:
--
-- > vector<int> xs(n, 0);
run :: (MonadAlpha m, MonadError Error m) => Program -> m Program
run :: Program -> m Program
run Program
prog = String -> m Program -> m Program
forall (m :: * -> *) a. MonadError Error m => String -> m a -> m a
wrapError' String
"Jikka.CPlusPlus.Convert.UseInitialization" (m Program -> m Program) -> m Program -> m Program
forall a b. (a -> b) -> a -> b
$ do
  Program -> m Program
forall (m :: * -> *) a. Monad m => a -> m a
return (Program -> m Program) -> Program -> m Program
forall a b. (a -> b) -> a -> b
$ Program -> Program
runProgram Program
prog