{- CAO Compiler
Copyright (C) 2014 Cryptography and Information Security Group, HASLab - INESC TEC and Universidade do Minho
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see . -}
{-# LANGUAGE ViewPatterns #-}
{-
Module : $Header$
Description : Semantics of casts.
Copyright : (C) 2014 Cryptography and Information Security Group, HASLab - INESC TEC and Universidade do Minho
License : GPL
Maintainer : Paulo Silva
Stability : experimental
Portability : non-portable
-}
module Language.CAO.Semantics.Casts ( convertTo) where
import Data.List
import Language.CAO.Common.Literal
import Language.CAO.Common.Polynomial
import Language.CAO.Common.Var
import Language.CAO.Semantics.Bits
import Language.CAO.Semantics.Integer
import Language.CAO.Index
import Language.CAO.Syntax
import Language.CAO.Type
import Language.CAO.Type.Utils
convertTo :: Type Var -> TExpr Var -> Expr Var
convertTo Int (TyE Int e@(Lit (ILit _)))
= e
convertTo Int (TyE RInt (Lit (ILit n)))
= Lit (ILit n)
convertTo RInt (TyE RInt e@(Lit (ILit _)))
= e
convertTo RInt (TyE Int (Lit (ILit n)))
= Lit (ILit n)
convertTo Int (TyE _ (Lit (BSLit sig s)))
= case sig of
U -> Lit $ ILit $ ubitsToInteger s
S -> Lit $ ILit $ sbitsToInteger s
convertTo Int (unTyp -> Lit (PLit (Pol [Mon (CoefI (IInt n)) EZero])))
= Lit $ ILit n
convertTo (Bits U (IInt k)) (unTyp -> Lit (BSLit _ s))
= Lit $ BSLit U $ genericTake k (s ++ repeat False)
convertTo (Bits S (IInt k)) (unTyp -> Lit (BSLit _ s))
= Lit $ BSLit S $ genericTake k (s ++ repeat (head s))
convertTo (Bits s (IInt n)) (unTyp -> Lit (ILit i))
= Lit $ BSLit s $ genericTake n $ integerToBits i
convertTo ty@(Bits _ _) p@(unTyp -> Lit (PLit _))
= convertTo ty (annTyE Int (convertTo Int p))
convertTo ty@(Mod _ _ _) (unTyp -> l@(Lit (PLit (Pol [Mon (CoefI (IInt i)) EZero])))) =
case getModulusBase ty of
IInt n -> Lit $ PLit (Pol [Mon (CoefI $ IInt $ i `mod` n) EZero])
_ -> l
convertTo ty@(Mod _ _ _) (unTyp -> l@(Lit (ILit n))) =
case getModulusBase ty of
IInt i -> Lit $ PLit $ Pol [Mon (CoefI $ IInt $ n `mod` i) EZero]
_ -> l
convertTo _ e = unTyp e