2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[Demand]{@Demand@: the amount of demand on a value}
7 #include "HsVersions.h"
12 wwLazy, wwStrict, wwUnpackData, wwUnpackNew, wwPrim, wwEnum,
18 import BasicTypes ( NewOrData(..) )
20 import Pretty ( Doc, text )
25 %************************************************************************
27 \subsection{The @Demand@ data type}
29 %************************************************************************
33 = WwLazy -- Argument is lazy as far as we know
34 MaybeAbsent -- (does not imply worker's existence [etc]).
35 -- If MaybeAbsent == True, then it is
36 -- *definitely* lazy. (NB: Absence implies
39 | WwStrict -- Argument is strict but that's all we know
40 -- (does not imply worker's existence or any
41 -- calling-convention magic)
43 | WwUnpack -- Argument is strict & a single-constructor type
45 Bool -- True <=> wrapper unpacks it; False <=> doesn't
46 [Demand] -- Its constituent parts (whose StrictInfos
47 -- are in the list) should be passed
48 -- as arguments to the worker.
50 | WwPrim -- Argument is of primitive type, therefore
51 -- strict; doesn't imply existence of a worker;
52 -- argument should be passed as is to worker.
54 | WwEnum -- Argument is strict & an enumeration type;
55 -- an Int# representing the tag (start counting
56 -- at zero) should be passed to the worker.
59 type MaybeAbsent = Bool -- True <=> not even used
61 -- versions that don't worry about Absence:
64 wwUnpackData xs = WwUnpack DataType False xs
65 wwUnpackNew x = WwUnpack NewType False [x]
71 %************************************************************************
73 \subsection{Functions over @Demand@}
75 %************************************************************************
78 isStrict :: Demand -> Bool
80 isStrict WwStrict = True
81 isStrict (WwUnpack DataType _ _) = True
82 isStrict (WwUnpack NewType _ ds) = isStrict (head ds)
83 isStrict WwPrim = True
84 isStrict WwEnum = True
89 %************************************************************************
91 \subsection{Instances}
93 %************************************************************************
96 showDemands :: [Demand] -> String
97 showDemands wrap_args = show_demands wrap_args ""
100 #ifdef REALLY_HASKELL_1_3
102 instance Read Demand where
103 readList str = read_em [] str
104 instance Show Demand where
105 showList wrap_args rest = show_demands wrap_args rest
109 instance Text Demand where
110 readList str = read_em [] str
111 showList wrap_args rest = show_demands wrap_args rest
115 read_em acc ('L' : xs) = read_em (WwLazy False : acc) xs
116 read_em acc ('A' : xs) = read_em (WwLazy True : acc) xs
117 read_em acc ('S' : xs) = read_em (WwStrict : acc) xs
118 read_em acc ('P' : xs) = read_em (WwPrim : acc) xs
119 read_em acc ('E' : xs) = read_em (WwEnum : acc) xs
120 read_em acc (')' : xs) = [(reverse acc, xs)]
121 read_em acc ( 'U' : '(' : xs) = do_unpack DataType True acc xs
122 read_em acc ( 'u' : '(' : xs) = do_unpack DataType False acc xs
123 read_em acc ( 'N' : '(' : xs) = do_unpack NewType True acc xs
124 read_em acc ( 'n' : '(' : xs) = do_unpack NewType False acc xs
125 read_em acc rest = [(reverse acc, rest)]
127 do_unpack new_or_data wrapper_unpacks acc xs
128 = case (read_em [] xs) of
129 [(stuff, rest)] -> read_em (WwUnpack new_or_data wrapper_unpacks stuff : acc) rest
130 _ -> panic ("Demand.do_unpack:"++show acc++"::"++xs)
132 show_demands wrap_args rest
133 = foldr show1 rest wrap_args
135 show1 (WwLazy False) rest = 'L' : rest
136 show1 (WwLazy True) rest = 'A' : rest
137 show1 WwStrict rest = 'S' : rest
138 show1 WwPrim rest = 'P' : rest
139 show1 WwEnum rest = 'E' : rest
140 show1 (WwUnpack nd wu args) rest = ch ++ "(" ++ showList args (')' : rest)
148 instance Outputable Demand where
149 ppr sty si = text (showList [si] "")