<commit_before>{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, ScopedTypeVariables #-}
-- | This Is an Ever-Changing AnSyn for L0.  Some types, such as
-- @Exp@, are parametrised by type representation.
-- See "L0.TypeChecker" and the 'Exp' type for more information.
module L0.AbSyn
  ( locStr
  , Type(..)
  , TypeBox(..)
  , ppType
  , arrayDims
  , arrayShape
  , peelArray
  , baseType
  , basicType
  , arrayType
  , stripArray
  , blankValue
  , Value(..)
  , valueType
  , arrayVal
  , emptyArray
  , ppValue
  , Ident(..)
  , Exp(..)
  , expType
  , expToValue
  , ppExp
  , BinOp(..)
  , opStr
  , ppBinOp
  , Lambda(..)
  , lambdaType
  , TupIdent(..)
  , ppTupId
  , FunDec
  , Prog
  , progNames
  , prettyPrint
  )
  where

import Data.Array
import Data.Data
import Data.List
import Data.Generics
import Data.Loc

locStr :: SrcLoc -> String
locStr (SrcLoc NoLoc) = "unknown location"
locStr (SrcLoc (Loc (Pos file line1 col1 _) (Pos _ line2 col2 _))) =
  -- Assume that both positions are in the same file (what would the
  -- alternative mean?)
  file ++ ":" ++ show line1 ++ ":" ++ show col1
       ++ "-" ++ show line2 ++ ":" ++ show col2

-- | L0 Types: Int, Bool, Char, Tuple, multidim-regular Array
--  TODO: please add float, double, long int, etc.
data Type = Int SrcLoc
          | Bool SrcLoc
          | Char SrcLoc
          | Real SrcLoc
          | Tuple [Type] SrcLoc
          | Array Type (Maybe (Exp (Maybe Type))) SrcLoc -- ^ 1st arg: array's element type, 2nd arg: its length
            deriving (Eq, Ord, Show, Typeable, Data)

instance Located Type where
  locOf (Int loc) = locOf loc
  locOf (Bool loc) = locOf loc
  locOf (Char loc) = locOf loc
  locOf (Real loc) = locOf loc
  locOf (Tuple _ loc) = locOf loc
  locOf (Array _ _ loc) = locOf loc

-- | Return the dimensionality of a type.  For non-arrays, this is
-- zero.  For a one-dimensional array it is one, for a two-dimensional
-- it is two, and so forth.
arrayDims :: Type -> Int
arrayDims (Array t _ _) = 1 + arrayDims t
arrayDims _             = 0

-- | A type box provides a way to box a type, and possibly retrieve
-- one.
class (Eq ty, Ord ty, Show ty, Data ty, Typeable ty) => TypeBox ty where
  unboxType :: ty -> Maybe Type
  boxType :: Type -> ty

instance TypeBox (Maybe Type) where
  unboxType = id
  boxType = Just

instance TypeBox Type where
  unboxType = Just
  boxType = id

-- | @peelArray n t@ returns the type resulting from peeling the first
-- @n@ array dimensions from @t@.  Returns @Nothing@ if @t@ has less
-- than @n@ dimensions.
peelArray :: Int -> Type -> Maybe Type
peelArray 0 t = Just t
peelArray n (Array t _ _) = peelArray (n-1) t
peelArray _ _ = Nothing

-- | Returns the bottommost type of an array.
baseType :: Type -> Type
baseType (Array t _ _) = baseType t
baseType t = t

-- | A type is a basic type if it is not an array and any component
-- types are basic types.
basicType :: Type -> Bool
basicType (Array {}) = False
basicType (Tuple ts _) = all basicType ts
basicType _ = True

-- | @array n t@ is the type of @n@-dimensional arrays having @t@ as
-- the base type.
arrayType :: Int -> Type -> Type<commit_msg>adding a phony getExpType to TypeBox<commit_after>{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, ScopedTypeVariables #-}
-- | This Is an Ever-Changing AnSyn for L0.  Some types, such as
-- @Exp@, are parametrised by type representation.
-- See "L0.TypeChecker" and the 'Exp' type for more information.
module L0.AbSyn
  ( locStr
  , Type(..)
  , TypeBox(..)
  , ppType
  , arrayDims
  , arrayShape
  , peelArray
  , baseType
  , basicType
  , arrayType
  , stripArray
  , blankValue
  , Value(..)
  , valueType
  , arrayVal
  , emptyArray
  , ppValue
  , Ident(..)
  , Exp(..)
  , expType
  , expToValue
  , ppExp
  , BinOp(..)
  , opStr
  , ppBinOp
  , Lambda(..)
  , lambdaType
  , TupIdent(..)
  , ppTupId
  , FunDec
  , Prog
  , progNames
  , prettyPrint
  )
  where

import Data.Array
import Data.Data
import Data.List
import Data.Generics
import Data.Loc

locStr :: SrcLoc -> String
locStr (SrcLoc NoLoc) = "unknown location"
locStr (SrcLoc (Loc (Pos file line1 col1 _) (Pos _ line2 col2 _))) =
  -- Assume that both positions are in the same file (what would the
  -- alternative mean?)
  file ++ ":" ++ show line1 ++ ":" ++ show col1
       ++ "-" ++ show line2 ++ ":" ++ show col2

-- | L0 Types: Int, Bool, Char, Tuple, multidim-regular Array
--  TODO: please add float, double, long int, etc.
data Type = Int SrcLoc
          | Bool SrcLoc
          | Char SrcLoc
          | Real SrcLoc
          | Tuple [Type] SrcLoc
          | Array Type (Maybe (Exp (Maybe Type))) SrcLoc -- ^ 1st arg: array's element type, 2nd arg: its length
            deriving (Eq, Ord, Show, Typeable, Data)

instance Located Type where
  locOf (Int loc) = locOf loc
  locOf (Bool loc) = locOf loc
  locOf (Char loc) = locOf loc
  locOf (Real loc) = locOf loc
  locOf (Tuple _ loc) = locOf loc
  locOf (Array _ _ loc) = locOf loc

-- | Return the dimensionality of a type.  For non-arrays, this is
-- zero.  For a one-dimensional array it is one, for a two-dimensional
-- it is two, and so forth.
arrayDims :: Type -> Int
arrayDims (Array t _ _) = 1 + arrayDims t
arrayDims _             = 0

-- | A type box provides a way to box a type, and possibly retrieve
-- one.
class (Eq ty, Ord ty, Show ty, Data ty, Typeable ty) => TypeBox ty where
  unboxType :: ty -> Maybe Type
  boxType :: Type -> ty
  getExpType :: Exp ty -> ty

instance TypeBox (Maybe Type) where
  unboxType = id
  boxType = Just
  getExpType _ = Nothing

instance TypeBox Type where
  unboxType = Just
  boxType = id
  getExpType = expType

-- | @peelArray n t@ returns the type resulting from peeling the first
-- @n@ array dimensions from @t@.  Returns @Nothing@ if @t@ has less
-- than @n@ dimensions.
peelArray :: Int -> Type -> Maybe Type
peelArray 0 t = Just t
peelArray n (Array t _ _) = peelArray (n-1) t
peelArray _ _ = Nothing

-- | Returns the bottommost type of an array.
baseType :: Type -> Type
baseType (Array t _ _) = baseType t
baseType t = t

-- | A type is a basic type if it is not an array and any component
-- types are basic types.
basicType :: Type -> Bool
basicType (Array {}) = False
basicType (Tuple ts _) = all basicType ts
basicType _ = True

-- | @array n t@ is the type of @n@-dimensional arrays having @t@ as
-- the base type.
arrayType :: Int -> Type -> Type
{'fraction_non_alphanumeric': 0.11204744069912609, 'fraction_numerical': 0.0056179775280898875, 'mean_word_length': 2.734848484848485, 'pattern_counts': {'":': 6, '<': 3, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7171780', 'n_tokens_mistral': 2190, 'n_tokens_neox': 2163, 'n_words': 826}