packages feed

cao-0.1.1: src/Language/CAO/Semantics/Casts.hs

{-  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 <http://www.gnu.org/licenses/>. -}

{-# 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 <paufil@di.uminho.pt>
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