module Feldspar.Core.Functions.Array
( arrayLen
, getIx
, setIx
, getLength
, RandomAccess (..)
) where
import Data.List
import Feldspar.Set
import Feldspar.Range
import Feldspar.Core.Types
import Feldspar.Core.Representation
import Feldspar.Core.Constructs
import Feldspar.Core.Functions.Num ()
import Feldspar.DSL.Expression
import Feldspar.DSL.Lambda
import Feldspar.DSL.Network
arrayLen :: Type a => Data Length -> [a] -> Data [a]
arrayLen len = array (dataSize len :> universal)
evalGetIx :: Range Length -> [a] -> Index -> a
evalGetIx l as i
| not (i `inRange` r) = error "getIx: index out of bounds"
| i >= la = error "getIx: reading garbage"
| otherwise = genericIndex as i
where
la = genericLength as
r = rangeByRange 0 (l1)
getIx :: Type a => Data [a] -> Data Index -> Data a
getIx arr = function2 "(!)" sizeProp (evalGetIx l) arr
where
sizeProp (_:>aSize) _ = aSize
l:>_ = dataSize arr
setIx
:: Type a
=> Data [a]
-> Data Index
-> Data a
-> Data [a]
setIx arr i a =
nodeData (dataSize arr)
$ Inject (Node SetIx)
:$: toEdge i
:$: toEdge a
:$: toEdge arr
getLength :: Type a => Data [a] -> Data Length
getLength arr = case undoEdge (unData arr) of
Inject (Node Parallel) :$: len :$: _ :$: arr' -> Data len + getLength (Data arr')
Inject (Node SetLength) :$: len :$: _ -> Data len
Inject (Node SetIx) :$: _ :$: _ :$: arr' -> getLength (Data arr')
_ -> case dataSize arr of
(Range l b :> _)
| l == b -> value l
otherwise -> function1 "length" sizeProp genericLength arr
where
sizeProp (lSize:>_) = lSize
infixl 9 !
class RandomAccess a
where
type Element a
(!) :: a -> Data Index -> Element a
instance Type a => RandomAccess (Data [a])
where
type Element (Data [a]) = Data a
(!) = getIx