on master help sign in
micro opt: use pokeArray instead of a foldM
766b6f8coreyoconnor
src/Data/Marshalling.hs+6−4
@@ -1,13 +1,14 @@
1+{-# LANGUAGE BangPatterns #-}
1-- Copyright 2009 Corey O'Connor
2-- Copyright 2009 Corey O'Connor
2module Data.Marshalling ( module Data.Marshalling
3module Data.Marshalling ( module Data.Marshalling
3 , module Data.Word
4 , module Data.Word
4 , module Foreign.Ptr
5 , module Foreign.Ptr
5 , module Foreign.ForeignPtr
6 , module Foreign.ForeignPtr
6 , module Foreign.Marshal
7 , module Foreign.Marshal
8+ , module Foreign.Storable
7 )
9 )
8 where
10 where
9
11
10−import Control.Monad ( foldM )
11import Control.Monad.Trans
12import Control.Monad.Trans
12
13
13import Data.Word
14import Data.Word
@@ -15,6 +16,7 @@ import Data.Word
15import Foreign.Ptr
16import Foreign.Ptr
16import Foreign.ForeignPtr
17import Foreign.ForeignPtr
17import Foreign.Marshal
18import Foreign.Marshal
19+import Foreign.Marshal.Array
18import Foreign.Storable
20import Foreign.Storable
19
21
20type OutputBuffer = Ptr Word8
22type OutputBuffer = Ptr Word8
@@ -23,7 +25,7 @@ string_to_bytes :: String -> [Word8]
23string_to_bytes str = map (toEnum . fromEnum) str
25string_to_bytes str = map (toEnum . fromEnum) str
24
26
25serialize_bytes :: MonadIO m => [Word8] -> OutputBuffer -> m OutputBuffer
27serialize_bytes :: MonadIO m => [Word8] -> OutputBuffer -> m OutputBuffer
26−serialize_bytes bytes out_ptr = foldM ( \ptr b -> liftIO (poke ptr b) >> return ( ptr `plusPtr` 1 ) )
28+serialize_bytes bytes !out_ptr = do
27− out_ptr
29+ liftIO $! pokeArray out_ptr bytes
28− bytes
30+ return $! out_ptr `plusPtr` ( length bytes )
29
31
src/Data/Terminfo/Eval.hs+82−16
@@ -1,7 +1,11 @@
1+{-# LANGUAGE MagicHash #-}
2+{-# LANGUAGE BangPatterns #-}
3+{-# LANGUAGE ScopedTypeVariables #-}
1{-# LANGUAGE RecordWildCards #-}
4{-# LANGUAGE RecordWildCards #-}
2{-# LANGUAGE FlexibleContexts #-}
5{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE NoMonomorphismRestriction #-}
6{-# LANGUAGE NoMonomorphismRestriction #-}
4{-# LANGUAGE NamedFieldPuns #-}
7{-# LANGUAGE NamedFieldPuns #-}
8+{-# OPTIONS_GHC -funbox-strict-fields -O #-}
5{- Evaluates the paramaterized terminfo string capability with the given parameters.
9{- Evaluates the paramaterized terminfo string capability with the given parameters.
6 -
10 -
7 - todo: This can be greatly simplified.
11 - todo: This can be greatly simplified.
@@ -21,9 +25,11 @@ import Control.Monad.State.Strict
21import Control.Monad.Trans
25import Control.Monad.Trans
22
26
23import Data.Array.Unboxed
27import Data.Array.Unboxed
24−import Data.Bits ( (.|.) )
28+import Data.Bits ( (.|.), (.&.), xor )
25import Data.List
29import Data.List
30+
26−import Data.Word
31+import GHC.Prim
32+import GHC.Word
27
33
28type EvalT m a = ReaderT (CapExpression,[CapParam]) (StateT [CapParam] m) a
34type EvalT m a = ReaderT (CapExpression,[CapParam]) (StateT [CapParam] m) a
29type Eval a = EvalT Identity a
35type Eval a = EvalT Identity a
@@ -37,11 +43,11 @@ pop = do
37read_param :: MonadReader (CapExpression, [CapParam]) m => Word -> m CapParam
43read_param :: MonadReader (CapExpression, [CapParam]) m => Word -> m CapParam
38read_param pn = do
44read_param pn = do
39 (_,params) <- ask
45 (_,params) <- ask
40− return $ genericIndex params pn
46+ return $! genericIndex params pn
41
47
42push :: MonadState [CapParam] m => CapParam -> m ()
48push :: MonadState [CapParam] m => CapParam -> m ()
43−push v = do
49+push !v = do
44− stack <-get
50+ stack <- get
45 put (v : stack)
51 put (v : stack)
46
52
47apply_param_ops :: CapExpression -> [CapParam] -> [CapParam]
53apply_param_ops :: CapExpression -> [CapParam] -> [CapParam]
@@ -53,8 +59,8 @@ apply_param_op params IncFirstTwo = map (+ 1) params
53-- | range is 0-based offset into cap_bytes and count
59-- | range is 0-based offset into cap_bytes and count
54--
60--
55-- todo: The returned list is not assured to have a length st. length == count
61-- todo: The returned list is not assured to have a length st. length == count
56−bytes_for_range :: CapExpression -> (Word8, Word8) -> [Word8]
62+bytes_for_range :: CapExpression -> Word8 -> Word8 -> [Word8]
57−bytes_for_range cap (offset, count)
63+bytes_for_range cap !offset !count
58 = take (fromEnum count)
64 = take (fromEnum count)
59 $ drop (fromEnum offset)
65 $ drop (fromEnum offset)
60 $ elems
66 $ elems
@@ -71,13 +77,19 @@ cap_ops_required_bytes ops = do
71 return $ sum counts
77 return $ sum counts
72
78
73cap_op_required_bytes :: CapOp -> Eval Word
79cap_op_required_bytes :: CapOp -> Eval Word
74−cap_op_required_bytes (Bytes (_, c)) = return $ toEnum $ fromEnum c
80+cap_op_required_bytes (Bytes _ c) = return $ toEnum $ fromEnum c
75cap_op_required_bytes DecOut = do
81cap_op_required_bytes DecOut = do
76 p <- pop
82 p <- pop
77 return $ toEnum $ length $ show p
83 return $ toEnum $ length $ show p
84+cap_op_required_bytes CharOut = do
85+ pop
86+ return 1
78cap_op_required_bytes (PushParam pn) = do
87cap_op_required_bytes (PushParam pn) = do
79 read_param pn >>= push
88 read_param pn >>= push
80 return 0
89 return 0
90+cap_op_required_bytes (PushValue v) = do
91+ push v
92+ return 0
81cap_op_required_bytes (Conditional expr parts) = do
93cap_op_required_bytes (Conditional expr parts) = do
82 c_expr <- cap_ops_required_bytes expr
94 c_expr <- cap_ops_required_bytes expr
83 c_parts <- foldM cond_parts_required_bytes 0 parts
95 c_parts <- foldM cond_parts_required_bytes 0 parts
@@ -98,13 +110,36 @@ cap_op_required_bytes BitwiseOr = do
98 v_1 <- pop
110 v_1 <- pop
99 push $ v_0 .|. v_1
111 push $ v_0 .|. v_1
100 return 0
112 return 0
113+cap_op_required_bytes BitwiseAnd = do
114+ v_0 <- pop
115+ v_1 <- pop
116+ push $ v_0 .&. v_1
117+ return 0
118+cap_op_required_bytes BitwiseXOr = do
119+ v_0 <- pop
120+ v_1 <- pop
121+ push $ v_0 `xor` v_1
122+ return 0
123+cap_op_required_bytes ArithPlus = do
124+ v_0 <- pop
125+ v_1 <- pop
126+ push $ v_0 + v_1
127+ return 0
101cap_op_required_bytes CompareEq = do
128cap_op_required_bytes CompareEq = do
102 v_0 <- pop
129 v_0 <- pop
103 v_1 <- pop
130 v_1 <- pop
104 push $ if v_0 == v_1 then 1 else 0
131 push $ if v_0 == v_1 then 1 else 0
105 return 0
132 return 0
106−cap_op_required_bytes (LiteralInt i) = do
133+cap_op_required_bytes CompareLt = do
107− return $ toEnum $ length $ show i
134+ v_0 <- pop
135+ v_1 <- pop
136+ push $ if v_0 < v_1 then 1 else 0
137+ return 0
138+cap_op_required_bytes CompareGt = do
139+ v_0 <- pop
140+ v_1 <- pop
141+ push $ if v_0 > v_1 then 1 else 0
142+ return 0
108
143
109serialize_cap_expression :: MonadIO m => CapExpression -> [CapParam] -> OutputBuffer -> m OutputBuffer
144serialize_cap_expression :: MonadIO m => CapExpression -> [CapParam] -> OutputBuffer -> m OutputBuffer
110serialize_cap_expression cap params out_ptr = do
145serialize_cap_expression cap params out_ptr = do
@@ -116,18 +151,28 @@ serialize_cap_ops :: MonadIO m => OutputBuffer -> CapOps -> EvalT m OutputBuffer
116serialize_cap_ops out_ptr ops = foldM serialize_cap_op out_ptr ops
151serialize_cap_ops out_ptr ops = foldM serialize_cap_op out_ptr ops
117
152
118serialize_cap_op :: MonadIO m => OutputBuffer -> CapOp -> EvalT m OutputBuffer
153serialize_cap_op :: MonadIO m => OutputBuffer -> CapOp -> EvalT m OutputBuffer
119−serialize_cap_op out_ptr (Bytes (offset, c)) = do
154+serialize_cap_op out_ptr (Bytes offset c) = do
120 (cap, _) <- ask
155 (cap, _) <- ask
121− let out_bytes = bytes_for_range cap (offset, c)
156+ let out_bytes = bytes_for_range cap offset c
122 serialize_bytes out_bytes out_ptr
157 serialize_bytes out_bytes out_ptr
123serialize_cap_op out_ptr DecOut = do
158serialize_cap_op out_ptr DecOut = do
124 p <- pop
159 p <- pop
125 let out_str = show p
160 let out_str = show p
126 out_bytes = string_to_bytes out_str
161 out_bytes = string_to_bytes out_str
127 serialize_bytes out_bytes out_ptr
162 serialize_bytes out_bytes out_ptr
163+serialize_cap_op out_ptr CharOut = do
164+ W# p <- pop
165+ -- todo? Truncate the character value to a single byte?
166+ let !out_byte = W8# (and# p 0xFF##)
167+ !out_ptr' = out_ptr `plusPtr` 1
168+ liftIO $ poke out_ptr out_byte
169+ return out_ptr'
128serialize_cap_op out_ptr (PushParam pn) = do
170serialize_cap_op out_ptr (PushParam pn) = do
129 read_param pn >>= push
171 read_param pn >>= push
130 return out_ptr
172 return out_ptr
173+serialize_cap_op out_ptr (PushValue v) = do
174+ push v
175+ return out_ptr
131serialize_cap_op out_ptr (Conditional expr parts) = do
176serialize_cap_op out_ptr (Conditional expr parts) = do
132 out_ptr' <- serialize_cap_ops out_ptr expr
177 out_ptr' <- serialize_cap_ops out_ptr expr
133 out_ptr'' <- foldM serialize_cond_parts out_ptr' parts
178 out_ptr'' <- foldM serialize_cond_parts out_ptr' parts
@@ -148,13 +193,34 @@ serialize_cap_op out_ptr BitwiseOr = do
148 v_1 <- pop
193 v_1 <- pop
149 push $ v_0 .|. v_1
194 push $ v_0 .|. v_1
150 return out_ptr
195 return out_ptr
196+serialize_cap_op out_ptr BitwiseAnd = do
197+ v_0 <- pop
198+ v_1 <- pop
199+ push $ v_0 .&. v_1
200+ return out_ptr
201+serialize_cap_op out_ptr BitwiseXOr = do
202+ v_0 <- pop
203+ v_1 <- pop
204+ push $ v_0 `xor` v_1
205+ return out_ptr
206+serialize_cap_op out_ptr ArithPlus = do
207+ v_0 <- pop
208+ v_1 <- pop
209+ push $ v_0 + v_1
210+ return out_ptr
151serialize_cap_op out_ptr CompareEq = do
211serialize_cap_op out_ptr CompareEq = do
152 v_0 <- pop
212 v_0 <- pop
153 v_1 <- pop
213 v_1 <- pop
154 push $ if v_0 == v_1 then 1 else 0
214 push $ if v_0 == v_1 then 1 else 0
155 return out_ptr
215 return out_ptr
156−serialize_cap_op out_ptr (LiteralInt i) = do
216+serialize_cap_op out_ptr CompareLt = do
157− let out_str = show i
217+ v_0 <- pop
158− out_bytes = string_to_bytes out_str
218+ v_1 <- pop
159− serialize_bytes out_bytes out_ptr
219+ push $ if v_0 < v_1 then 1 else 0
220+ return out_ptr
221+serialize_cap_op out_ptr CompareGt = do
222+ v_0 <- pop
223+ v_1 <- pop
224+ push $ if v_0 > v_1 then 1 else 0
225+ return out_ptr
160
226
src/Data/Terminfo/Parse.hs+106−40
@@ -1,13 +1,16 @@
1+{-# LANGUAGE ScopedTypeVariables #-}
1{-# LANGUAGE BangPatterns #-}
2{-# LANGUAGE BangPatterns #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE NoMonomorphismRestriction #-}
4{-# LANGUAGE NoMonomorphismRestriction #-}
4{-# LANGUAGE NamedFieldPuns #-}
5{-# LANGUAGE NamedFieldPuns #-}
6+{-# OPTIONS_GHC -funbox-strict-fields -O #-}
5module Data.Terminfo.Parse ( module Data.Terminfo.Parse
7module Data.Terminfo.Parse ( module Data.Terminfo.Parse
6 , Text.ParserCombinators.Parsec.ParseError
8 , Text.ParserCombinators.Parsec.ParseError
7 )
9 )
8 where
10 where
9
11
10import Control.Monad ( liftM )
12import Control.Monad ( liftM )
13+import Control.Parallel.Strategies
11
14
12import Data.Array.Unboxed
15import Data.Array.Unboxed
13import Data.Monoid
16import Data.Monoid
@@ -20,33 +23,44 @@ type BytesOffset = Word8
20type CapBytes = UArray Word8 Word8
23type CapBytes = UArray Word8 Word8
21
24
22data CapExpression = CapExpression
25data CapExpression = CapExpression
23− { cap_ops :: CapOps
26+ { cap_ops :: !CapOps
24− , cap_bytes :: CapBytes
27+ , cap_bytes :: !CapBytes
25− , source_string :: String
28+ , source_string :: !String
26− , param_count :: Word
29+ , param_count :: !Word
27− , param_ops :: ParamOps
30+ , param_ops :: !ParamOps
28 }
31 }
29
32
33+instance NFData CapExpression where
34+ rnf (CapExpression ops !_bytes !_str !_c !_p_ops)
35+ = rnf ops
36+
30type CapParam = Word
37type CapParam = Word
31
38
32type CapOps = [CapOp]
39type CapOps = [CapOp]
33data CapOp =
40data CapOp =
34− Bytes (BytesOffset, BytesLength)
41+ Bytes !BytesOffset !BytesLength
35− | DecOut
42+ | DecOut | CharOut
36 -- This stores a 0-based index to the parameter. However the operation that implies this op is
43 -- This stores a 0-based index to the parameter. However the operation that implies this op is
37 -- 1-based
44 -- 1-based
38− | PushParam !Word
45+ | PushParam !Word | PushValue !Word
39 -- The conditional parts are the sequence of (%t expression, %e expression) pairs.
46 -- The conditional parts are the sequence of (%t expression, %e expression) pairs.
40 -- The %e expression may be NOP
47 -- The %e expression may be NOP
41 | Conditional
48 | Conditional
42− { conditional_expr :: CapOps
49+ { conditional_expr :: !CapOps
43− , conditional_parts :: [(CapOps, CapOps)]
50+ , conditional_parts :: ![(CapOps, CapOps)]
44 }
51 }
45− | BitwiseOr
52+ | BitwiseOr | BitwiseXOr | BitwiseAnd
53+ | ArithPlus
46− | CompareEq
54+ | CompareEq | CompareLt | CompareGt
47− | LiteralInt Int
48 deriving ( Show )
55 deriving ( Show )
49
56
57+instance NFData CapOp where
58+ rnf (Bytes offset c) = rnf offset >| rnf c
59+ rnf (PushParam !_pn) = ()
60+ rnf (PushValue !_v) = ()
61+ rnf (Conditional c_expr c_parts) = rnf c_expr >| rnf c_parts
62+ rnf _ = ()
63+
50type ParamOps = [ParamOp]
64type ParamOps = [ParamOp]
51data ParamOp =
65data ParamOp =
52 IncFirstTwo
66 IncFirstTwo
@@ -61,16 +75,18 @@ parse_cap_expression cap_string =
61 in case v of
75 in case v of
62 Left e -> Left e
76 Left e -> Left e
63 Right build_results ->
77 Right build_results ->
64− Right $ CapExpression
78+ Right $! ( CapExpression
65− { cap_ops = out_cap_ops build_results
79+ { cap_ops = out_cap_ops build_results
66− -- The cap bytes are the lower 8 bits of the input string's characters.
80+ -- The cap bytes are the lower 8 bits of the input string's characters.
67− -- \todo Verify the input string actually contains an 8bit byte per character.
81+ -- \todo Verify the input string actually contains an 8bit byte per character.
68− , cap_bytes = listArray (0, toEnum $ length cap_string - 1)
82+ , cap_bytes = listArray (0, toEnum $ length cap_string - 1)
69− $ map (toEnum . fromEnum) cap_string
83+ $ map (toEnum . fromEnum) cap_string
70− , source_string = cap_string
84+ , source_string = cap_string
71− , param_count = out_param_count build_results
85+ , param_count = out_param_count build_results
72− , param_ops = out_param_ops build_results
86+ , param_ops = out_param_ops build_results
73− }
87+ }
88+ `using` rnf
89+ )
74
90
75type CapParser a = GenParser Char BuildState a
91type CapParser a = GenParser Char BuildState a
76
92
@@ -90,17 +106,20 @@ literal_percent_parser = do
90 char '%'
106 char '%'
91 start_offset <- getState >>= return . next_offset
107 start_offset <- getState >>= return . next_offset
92 inc_offset 1
108 inc_offset 1
93− return $ BuildResults 0 [Bytes (start_offset, 1)] []
109+ return $ BuildResults 0 [Bytes start_offset 1] []
94
110
95param_op_parser :: CapParser BuildResults
111param_op_parser :: CapParser BuildResults
96param_op_parser
112param_op_parser
97 = increment_op_parser
113 = increment_op_parser
98 <|> push_op_parser
114 <|> push_op_parser
99 <|> dec_out_parser
115 <|> dec_out_parser
116+ <|> char_out_parser
100 <|> conditional_op_parser
117 <|> conditional_op_parser
101 <|> bitwise_op_parser
118 <|> bitwise_op_parser
119+ <|> arith_op_parser
102 <|> literal_int_op_parser
120 <|> literal_int_op_parser
103 <|> compare_op_parser
121 <|> compare_op_parser
122+ <|> char_const_parser
104
123
105increment_op_parser :: CapParser BuildResults
124increment_op_parser :: CapParser BuildResults
106increment_op_parser = do
125increment_op_parser = do
@@ -121,6 +140,12 @@ dec_out_parser = do
121 inc_offset 1
140 inc_offset 1
122 return $ BuildResults 0 [ DecOut ] []
141 return $ BuildResults 0 [ DecOut ] []
123
142
143+char_out_parser :: CapParser BuildResults
144+char_out_parser = do
145+ char 'c'
146+ inc_offset 1
147+ return $ BuildResults 0 [ CharOut ] []
148+
124conditional_op_parser :: CapParser BuildResults
149conditional_op_parser :: CapParser BuildResults
125conditional_op_parser = do
150conditional_op_parser = do
126 char '?'
151 char '?'
@@ -156,11 +181,11 @@ conditional_op_parser = do
156 return $ BuildResults n'' [ Conditional cond cond_parts ] p_ops
181 return $ BuildResults n'' [ Conditional cond cond_parts ] p_ops
157
182
158 where
183 where
159− many_p p end = choice
184+ many_p !p !end = choice
160 [ try end >> return []
185 [ try end >> return []
161− , do v <- p
186+ , do !v <- p
162− vs <- many_p p end
187+ !vs <- many_p p end
163− return $ v : vs
188+ return $! v : vs
164 ]
189 ]
165 many_expr end = liftM mconcat $ many_p ( param_escape_parser <|> bytes_op_parser ) end
190 many_expr end = liftM mconcat $ many_p ( param_escape_parser <|> bytes_op_parser ) end
166
191
@@ -180,8 +205,10 @@ conditional_end_parser = do
180 inc_offset 2
205 inc_offset 2
181
206
182bitwise_op_parser :: CapParser BuildResults
207bitwise_op_parser :: CapParser BuildResults
183−bitwise_op_parser = do
208+bitwise_op_parser
184− bitwise_or_parser
209+ = bitwise_or_parser
210+ <|> bitwise_and_parser
211+ <|> bitwise_xor_parser
185
212
186bitwise_or_parser :: CapParser BuildResults
213bitwise_or_parser :: CapParser BuildResults
187bitwise_or_parser = do
214bitwise_or_parser = do
@@ -189,22 +216,53 @@ bitwise_or_parser = do
189 inc_offset 1
216 inc_offset 1
190 return $ BuildResults 0 [ BitwiseOr ] [ ]
217 return $ BuildResults 0 [ BitwiseOr ] [ ]
191
218
219+bitwise_and_parser :: CapParser BuildResults
220+bitwise_and_parser = do
221+ char '&'
222+ inc_offset 1
223+ return $ BuildResults 0 [ BitwiseAnd ] [ ]
224+
225+bitwise_xor_parser :: CapParser BuildResults
226+bitwise_xor_parser = do
227+ char '^'
228+ inc_offset 1
229+ return $ BuildResults 0 [ BitwiseXOr ] [ ]
230+
231+arith_op_parser :: CapParser BuildResults
232+arith_op_parser = do
233+ char '+'
234+ inc_offset 1
235+ return $ BuildResults 0 [ ArithPlus ] [ ]
236+
192literal_int_op_parser :: CapParser BuildResults
237literal_int_op_parser :: CapParser BuildResults
193literal_int_op_parser = do
238literal_int_op_parser = do
194 char '{'
239 char '{'
195 inc_offset 1
240 inc_offset 1
196 n_str <- many1 digit
241 n_str <- many1 digit
197 inc_offset $ toEnum $ length n_str
242 inc_offset $ toEnum $ length n_str
198− let n = read n_str
243+ let n :: Word = read n_str
199 char '}'
244 char '}'
200 inc_offset 1
245 inc_offset 1
201− return $ BuildResults 0 [ LiteralInt n ] [ ]
246+ return $ BuildResults 0 [ PushValue n ] [ ]
202
247
203compare_op_parser :: CapParser BuildResults
248compare_op_parser :: CapParser BuildResults
204−compare_op_parser = do
249+compare_op_parser
250+ = compare_eq_op
251+ <|> compare_lt_op
252+ <|> compare_gt_op
253+ where
254+ compare_eq_op = do
205− char '='
255+ char '='
206− inc_offset 1
256+ inc_offset 1
207− return $ BuildResults 0 [ CompareEq ] [ ]
257+ return $ BuildResults 0 [ CompareEq ] [ ]
258+ compare_lt_op = do
259+ char '<'
260+ inc_offset 1
261+ return $ BuildResults 0 [ CompareLt ] [ ]
262+ compare_gt_op = do
263+ char '>'
264+ inc_offset 1
265+ return $ BuildResults 0 [ CompareGt ] [ ]
208
266
209bytes_op_parser :: CapParser BuildResults
267bytes_op_parser :: CapParser BuildResults
210bytes_op_parser = do
268bytes_op_parser = do
@@ -214,7 +272,15 @@ bytes_op_parser = do
214 !s <- getState
272 !s <- getState
215 let s' = s { next_offset = start_offset + c }
273 let s' = s { next_offset = start_offset + c }
216 setState s'
274 setState s'
217− return $ BuildResults 0 [Bytes (start_offset, c)] []
275+ return $ BuildResults 0 [Bytes start_offset c] []
276+
277+char_const_parser :: CapParser BuildResults
278+char_const_parser = do
279+ char '\''
280+ char_value <- liftM (toEnum . fromEnum) anyChar
281+ char '\''
282+ inc_offset 3
283+ return $ BuildResults 0 [ PushValue char_value ] [ ]
218
284
219data BuildState = BuildState
285data BuildState = BuildState
220 { next_offset :: Word8
286 { next_offset :: Word8
@@ -230,9 +296,9 @@ initial_build_state :: BuildState
230initial_build_state = BuildState 0
296initial_build_state = BuildState 0
231
297
232data BuildResults = BuildResults
298data BuildResults = BuildResults
233− { out_param_count :: Word
299+ { out_param_count :: !Word
234− , out_cap_ops :: CapOps
300+ , out_cap_ops :: !CapOps
235− , out_param_ops :: ParamOps
301+ , out_param_ops :: !ParamOps
236 }
302 }
237
303
238instance Monoid BuildResults where
304instance Monoid BuildResults where
vty.cabal+1−1
@@ -27,7 +27,7 @@ Build-Depends: base >= 4 && < 5, bytestring, containers, unix, uvector
27Build-Depends: terminfo >= 0.2 && < 0.3
27Build-Depends: terminfo >= 0.2 && < 0.3
28Build-Depends: utf8-string >= 0.3 && < 0.4
28Build-Depends: utf8-string >= 0.3 && < 0.4
29Build-Depends: mtl >= 1.1.0.0 && < 1.2
29Build-Depends: mtl >= 1.1.0.0 && < 1.2
30−Build-Depends: ghc-prim
30+Build-Depends: ghc-prim, parallel
31Build-Depends: array
31Build-Depends: array
32Build-Depends: parsec >= 2 && < 4
32Build-Depends: parsec >= 2 && < 4
33Build-Depends: vector-space >= 0.5 && < 0.6
33Build-Depends: vector-space >= 0.5 && < 0.6