never executed always true always false
1 {-# LANGUAGE DeriveGeneric, DeriveDataTypeable, DeriveFunctor, DeriveTraversable, DeriveFoldable #-}
2
3 module Conjure.Language.Expression.Op.Indexing where
4
5 import Conjure.Prelude
6 import Conjure.Language.Expression.Op.Internal.Common
7
8 import qualified Data.Aeson as JSON -- aeson
9 import qualified Data.Aeson.KeyMap as KM
10
11 import qualified Data.Vector as V -- vector
12
13 -- pretty
14 import Conjure.Language.Pretty as Pr ( cat )
15
16
17 data OpIndexing x = OpIndexing x x
18 deriving (Eq, Ord, Show, Data, Functor, Traversable, Foldable, Typeable, Generic)
19
20 instance Serialize x => Serialize (OpIndexing x)
21 instance Hashable x => Hashable (OpIndexing x)
22 instance ToJSON x => ToJSON (OpIndexing x) where toJSON = genericToJSON jsonOptions
23 instance FromJSON x => FromJSON (OpIndexing x) where parseJSON = genericParseJSON jsonOptions
24
25 instance (TypeOf x, Pretty x, ExpressionLike x, ReferenceContainer x) => TypeOf (OpIndexing x) where
26 typeOf p@(OpIndexing m i) = do
27 tyM <- typeOf m
28 tyI <- typeOf i
29 case tyM of
30 TypeMatrix tyIndex inn
31 | typesUnify [tyIndex, tyI] -> return inn
32 | otherwise -> failDoc $ "Indexing with inappropriate type:" <++> vcat
33 [ "The expression:" <+> pretty p
34 , "Indexing:" <+> pretty m
35 , "Expected type of index:" <+> pretty tyIndex
36 , "Actual type of index :" <+> pretty tyI
37 ]
38 TypeList inn
39 | typesUnify [TypeInt TagInt, tyI] -> return inn
40 | otherwise -> failDoc $ "Indexing with inappropriate type:" <++> vcat
41 [ "The expression:" <+> pretty p
42 , "Indexing:" <+> pretty m
43 , "Expected type of index:" <+> pretty (TypeInt TagInt)
44 , "Actual type of index :" <+> pretty tyI
45 ]
46 TypeTuple inns -> do
47 TypeInt t <- typeOf i
48 case t of
49 TagInt -> return ()
50 _ -> failDoc $ "Tuples cannot be indexed by enums/unnameds:" <++> pretty p
51 case intOut "OpIndexing" i of
52 Nothing -> failDoc $ "Tuples can only be indexed by constants:" <++> pretty p
53 Just iInt | iInt <= 0 || iInt > genericLength inns ->
54 failDoc $ "Out of bounds tuple indexing:" <++> pretty p
55 | otherwise -> return (at inns (fromInteger (iInt-1)))
56 TypeRecord inns -> do
57 nm <- nameOut i
58 case lookup nm inns of
59 Nothing -> failDoc $ "Record indexing with non-member field:" <++> vcat
60 [ "The expression:" <+> pretty p
61 , "Indexing:" <+> pretty m
62 , "With type:" <+> pretty tyM
63 ]
64 Just ty -> return ty
65 TypeVariant inns -> do
66 nm <- nameOut i
67 case lookup nm inns of
68 Nothing -> failDoc $ "Variant indexing with non-member field:" <++> vcat
69 [ "The expression:" <+> pretty p
70 , "Indexing:" <+> pretty m
71 , "With type:" <+> pretty tyM
72 ]
73 Just ty -> return ty
74 _ -> failDoc $ "Indexing something other than a matrix or a tuple:" <++> vcat
75 [ "The expression:" <+> pretty p
76 , "Indexing:" <+> pretty m
77 , "With type:" <+> pretty tyM
78 ]
79
80 instance SimplifyOp OpIndexing x where
81 simplifyOp _ = na "simplifyOp{OpIndexing}"
82
83 instance Pretty x => Pretty (OpIndexing x) where
84 prettyPrec _ (OpIndexing a b) = Pr.cat [pretty a, nest 4 (prBrackets (pretty b))]
85
86 instance VarSymBreakingDescription x => VarSymBreakingDescription (OpIndexing x) where
87 varSymBreakingDescription (OpIndexing a b) = JSON.Object $ KM.fromList
88 [ ("type", JSON.String "OpIndexing")
89 , ("children", JSON.Array $ V.fromList
90 [ varSymBreakingDescription a
91 , varSymBreakingDescription b
92 ])
93 ]