Changeset 2441 for src/Pugs/Types/Array.hs
- Timestamp:
- 04/28/05 18:38:12 (4 years ago)
- svk:copy_cache_prev:
- 3914
- Files:
-
- 1 modified
-
src/Pugs/Types/Array.hs (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Pugs/Types/Array.hs
r2221 r2441 1 {-# OPTIONS_GHC -fglasgow-exts #-} 2 3 module Pugs.Types.Array where 4 5 import {-# SOURCE #-} Pugs.AST 6 import Pugs.Internals 7 import Pugs.Types 8 9 type Index = Int 10 11 class (Typeable a) => Class a where 12 iType :: a -> Type 13 iType = const $ mkType "Array" 14 fetch :: a -> Eval VArray 15 fetch av = do 16 size <- fetchSize av 17 mapM (fetchVal av) [0..size-1] 18 store :: a -> VArray -> Eval () 19 store av list = do 1 type ArrayIndex = Int 2 3 class (Typeable a) => ArrayClass a where 4 array_iType :: a -> Type 5 array_iType = const $ mkType "Array" 6 array_fetch :: a -> Eval VArray 7 array_fetch av = do 8 size <- array_fetchSize av 9 mapM (array_fetchVal av) [0..size-1] 10 array_store :: a -> VArray -> Eval () 11 array_store av list = do 20 12 forM_ ([0..] `zip` list) $ \(idx, val) -> do 21 sv <- fetchElem av idx13 sv <- array_fetchElem av idx 22 14 writeIVar sv val 23 storeSize av (length list)24 fetchKeys :: a -> Eval [Index]25 fetchKeys av = do26 svList <- fetch av15 array_storeSize av (length list) 16 array_fetchKeys :: a -> Eval [ArrayIndex] 17 array_fetchKeys av = do 18 svList <- array_fetch av 27 19 return $ zipWith const [0..] svList 28 fetchElem :: a ->Index -> Eval (IVar VScalar) -- autovivify29 fetchElem av idx = do30 return $ proxyScalar ( fetchVal av idx) (storeVal av idx)31 storeElem :: a ->Index -> IVar VScalar -> Eval () -- binding32 storeElem av idx sv = do20 array_fetchElem :: a -> ArrayIndex -> Eval (IVar VScalar) -- autovivify 21 array_fetchElem av idx = do 22 return $ proxyScalar (array_fetchVal av idx) (array_storeVal av idx) 23 array_storeElem :: a -> ArrayIndex -> IVar VScalar -> Eval () -- binding 24 array_storeElem av idx sv = do 33 25 val <- readIVar sv 34 storeVal av idx val35 fetchVal :: a ->Index -> Eval Val36 fetchVal av idx = do37 rv <- existsElem av idx38 if rv then readIVar =<< fetchElem av idx26 array_storeVal av idx val 27 array_fetchVal :: a -> ArrayIndex -> Eval Val 28 array_fetchVal av idx = do 29 rv <- array_existsElem av idx 30 if rv then readIVar =<< array_fetchElem av idx 39 31 else return undef 40 storeVal :: a ->Index -> Val -> Eval ()41 storeVal av idx val = do42 sv <- fetchElem av idx32 array_storeVal :: a -> ArrayIndex -> Val -> Eval () 33 array_storeVal av idx val = do 34 sv <- array_fetchElem av idx 43 35 writeIVar sv val 44 fetchSize :: a -> EvalIndex45 fetchSize av = do46 vals <- fetch av36 array_fetchSize :: a -> Eval ArrayIndex 37 array_fetchSize av = do 38 vals <- array_fetch av 47 39 return $ length vals 48 storeSize :: a ->Index -> Eval ()49 storeSize av sz = do50 size <- fetchSize av40 array_storeSize :: a -> ArrayIndex -> Eval () 41 array_storeSize av sz = do 42 size <- array_fetchSize av 51 43 case size `compare` sz of 52 GT -> mapM_ (const $ pop av) [size .. sz-1]44 GT -> mapM_ (const $ array_pop av) [size .. sz-1] 53 45 EQ -> return () -- no need to do anything 54 LT -> mapM_ (\idx -> storeElem av idx lazyUndef) [size .. sz-1]55 extendSize :: a ->Index -> Eval ()56 extendSize _ 0 = return ()57 extendSize av sz = do58 size <- fetchSize av46 LT -> mapM_ (\idx -> array_storeElem av idx lazyUndef) [size .. sz-1] 47 array_extendSize :: a -> ArrayIndex -> Eval () 48 array_extendSize _ 0 = return () 49 array_extendSize av sz = do 50 size <- array_fetchSize av 59 51 when (size < sz) $ do 60 mapM_ (\idx -> storeElem av idx lazyUndef) [size .. sz-1]61 deleteElem :: a ->Index -> Eval ()62 deleteElem av idx = do63 size <- fetchSize av52 mapM_ (\idx -> array_storeElem av idx lazyUndef) [size .. sz-1] 53 array_deleteElem :: a -> ArrayIndex -> Eval () 54 array_deleteElem av idx = do 55 size <- array_fetchSize av 64 56 let idx' = if idx < 0 then idx `mod` size else idx 65 57 case (size - 1) `compare` idx' of 66 58 GT -> return () -- no such index 67 EQ -> storeSize av (size - 1) -- truncate68 LT -> storeElem av idx' lazyUndef -- set to undef69 existsElem :: a ->Index -> Eval VBool70 existsElem av idx = do71 size <- fetchSize av59 EQ -> array_storeSize av (size - 1) -- truncate 60 LT -> array_storeElem av idx' lazyUndef -- set to undef 61 array_existsElem :: a -> ArrayIndex -> Eval VBool 62 array_existsElem av idx = do 63 size <- array_fetchSize av 72 64 return $ size > (if idx < 0 then idx `mod` size else idx) 73 clear :: a -> Eval ()74 clear av =storeSize av 075 push :: a -> [Val] -> Eval ()76 push av vals = do77 size <- fetchSize av65 array_clear :: a -> Eval () 66 array_clear av = array_storeSize av 0 67 array_push :: a -> [Val] -> Eval () 68 array_push av vals = do 69 size <- array_fetchSize av 78 70 forM_ ([size..] `zip` vals) $ \(idx, val) -> do 79 storeElem av idx (lazyScalar val)80 pop :: a -> Eval Val81 pop av = do82 size <- fetchSize av71 array_storeElem av idx (lazyScalar val) 72 array_pop :: a -> Eval Val 73 array_pop av = do 74 size <- array_fetchSize av 83 75 if size == 0 84 76 then return undef 85 77 else do 86 sv <- fetchElem av $ size - 187 storeSize av $ size - 178 sv <- array_fetchElem av $ size - 1 79 array_storeSize av $ size - 1 88 80 readIVar sv 89 shift :: a -> Eval Val90 shift av = do91 vals <- splice av 0 1 []81 array_shift :: a -> Eval Val 82 array_shift av = do 83 vals <- array_splice av 0 1 [] 92 84 return $ last (undef:vals) 93 unshift :: a -> [Val] -> Eval ()94 unshift av vals = do95 splice av 0 0 vals85 array_unshift :: a -> [Val] -> Eval () 86 array_unshift av vals = do 87 array_splice av 0 0 vals 96 88 return () 97 splice :: a -> Index ->Index -> [Val] -> Eval [Val]98 splice av off len vals = do99 size <- fetchSize av89 array_splice :: a -> ArrayIndex -> ArrayIndex -> [Val] -> Eval [Val] 90 array_splice av off len vals = do 91 size <- array_fetchSize av 100 92 let off' = if off < 0 then off + size else off 101 93 len' = if len < 0 then len + size - off' else len 102 result <- mapM ( fetchElem av) [off' .. off' + len' - 1]94 result <- mapM (array_fetchElem av) [off' .. off' + len' - 1] 103 95 let off = if off' > size then size else off' 104 96 len = if off + len' > size then size - off else len' … … 108 100 -- Move items up to make room 109 101 let delta = cnt - len 110 extendSize av (size + delta)102 array_extendSize av (size + delta) 111 103 (`mapM_` reverse [off + len .. size - 1]) $ \idx -> do 112 val <- fetchElem av idx113 storeElem av (idx + delta) val104 val <- array_fetchElem av idx 105 array_storeElem av (idx + delta) val 114 106 LT -> do 115 107 let delta = len - cnt 116 108 (`mapM_` [off + len .. size - 1]) $ \idx -> do 117 val <- fetchElem av idx118 storeElem av (idx - delta) val119 storeSize av (size - delta)109 val <- array_fetchElem av idx 110 array_storeElem av (idx - delta) val 111 array_storeSize av (size - delta) 120 112 _ -> return () 121 113 forM_ ([0..] `zip` vals) $ \(idx, val) -> do 122 storeElem av (off + idx) (lazyScalar val)114 array_storeElem av (off + idx) (lazyScalar val) 123 115 mapM readIVar result 116 117 instance ArrayClass IArraySlice where 118 array_iType = const $ mkType "Array::Slice" 119 array_store av vals = mapM_ (uncurry writeIVar) (zip av vals) 120 array_fetchSize = return . length 121 array_fetchElem av idx = getIndex idx Nothing (return av) Nothing 122 array_storeSize _ _ = return () -- XXX error? 123 array_storeElem _ _ _ = retConstError undef 124 125 instance ArrayClass IArray where 126 array_store av vals = do 127 let svList = map lazyScalar vals 128 liftSTM $ writeTVar av svList 129 array_fetchSize av = do 130 svList <- liftSTM $ readTVar av 131 return $ length svList 132 array_storeSize av sz = do 133 liftSTM $ modifyTVar av $ take sz . (++ repeat lazyUndef) 134 array_shift av = do 135 svList <- liftSTM $ readTVar av 136 case svList of 137 (sv:rest) -> do 138 liftSTM $ writeTVar av rest 139 readIVar sv 140 _ -> return undef 141 array_unshift av vals = do 142 liftSTM $ modifyTVar av 143 (map lazyScalar vals ++) 144 array_extendSize _ 0 = return () 145 array_extendSize av sz = do 146 liftSTM . modifyTVar av $ \svList -> 147 if null $ drop (sz-1) svList 148 then take sz (svList ++ repeat lazyUndef) 149 else svList 150 array_fetchVal av idx = do 151 readIVar =<< getIndex idx (Just $ constScalar undef) 152 (liftSTM $ readTVar av) 153 Nothing -- don't bother extending 154 array_fetchKeys av = do 155 svList <- liftSTM $ readTVar av 156 return $ zipWith const [0..] svList 157 array_fetchElem av idx = do 158 sv <- getIndex idx Nothing 159 (liftSTM $ readTVar av) 160 (Just (array_extendSize av $ idx+1)) 161 if refType (MkRef sv) == mkType "Scalar::Lazy" 162 then do 163 val <- readIVar sv 164 sv' <- newScalar val 165 liftSTM . modifyTVar av $ \svList -> 166 let idx' = idx `mod` length svList in 167 take idx' svList ++ (sv' : drop (idx'+1) svList) 168 return sv' 169 else return sv 170 array_existsElem av idx | idx < 0 = array_existsElem av (abs idx - 1) 171 array_existsElem av idx = do 172 svList <- liftSTM $ readTVar av 173 return . not . null $ drop idx svList 174 array_deleteElem av idx = do 175 liftSTM . modifyTVar av $ \svList -> 176 let idx' | idx < 0 = idx `mod` length svList -- XXX wrong; wraparound 177 | otherwise = idx in 178 if null $ drop (idx' + 1) svList 179 then take idx' svList 180 else take idx' svList ++ (lazyUndef : drop (idx'+1) svList) 181 array_storeElem av idx sv = do 182 liftSTM . modifyTVar av $ \svList -> 183 let idx' | idx < 0 = idx `mod` length svList -- XXX wrong; wraparound 184 | otherwise = idx in 185 take idx svList ++ (sv : drop (idx'+1) svList) 186 187 instance ArrayClass VArray where 188 array_iType = const $ mkType "Array::Const" 189 array_store [] _ = return () 190 array_store _ [] = return () 191 array_store (a:as) vals@(v:vs) = do 192 env <- ask 193 ref <- fromVal a 194 if isaType (envClasses env) "List" (refType ref) 195 then writeRef ref (VList vals) 196 else do 197 writeRef ref v 198 array_store as vs 199 array_fetch = return 200 array_fetchSize = return . length 201 array_fetchVal av idx = getIndex idx (Just undef) (return av) Nothing 202 array_storeVal _ _ _ = retConstError undef 203 array_storeElem _ _ _ = retConstError undef 204 205 instance ArrayClass (IVar VPair) where 206 array_iType = const $ mkType "Pair" 207 array_fetch pv = do 208 (k, v) <- readIVar pv 209 return [k, v] 210 array_existsElem _ idx = return (idx >= -2 || idx <= 1) 211 array_fetchSize = const $ return 2 212 array_fetchVal pv (-2) = return . fst =<< readIVar pv 213 array_fetchVal pv (-1) = return . snd =<< readIVar pv 214 array_fetchVal pv 0 = return . fst =<< readIVar pv 215 array_fetchVal pv 1 = return . snd =<< readIVar pv 216 array_fetchVal _ _ = return undef 217 array_storeVal _ _ _ = retConstError undef 218 array_storeElem _ _ _ = retConstError undef 219 array_deleteElem _ _ = retConstError undef 220
