module Language.Scheme.Macro.Matches (getData, setData) where
import Language.Scheme.Types
import Control.Exception
_create :: Int
-> LispVal
_create level
| level < 1 = Nil ""
| level == 1 = List []
| otherwise = List [_create $ level 1]
fill :: [LispVal] -> Int -> [LispVal]
fill l len
| length l < len = fill (l ++ [List []]) len
| otherwise = l
getData :: LispVal
-> [Int]
-> LispVal
getData (List lData) (i:is) = do
if length lData < i
then Nil ""
else do
let lst = drop i lData
if not (null lst)
then getData (head lst) is
else Nil ""
getData val [] = val
getData val _ = val
setData :: LispVal
-> [Int]
-> LispVal
-> LispVal
setData (List lData) (i:is) val = do
if not (null is) && length lData < i + 1
then set $ fill lData $ i + 1
else set lData
where
set listData = do
let content = splitAt i listData
case (snd content) of
[] -> List $ listData ++ [val]
[c] -> if length is < 1
then List $ (fst content) ++ [val] ++ [c]
else List $ (fst content) ++ [setData c is val]
(c:cs) -> if length is < 1
then List $ (fst content) ++ [val] ++ [c] ++ cs
else List $ (fst content) ++ [setData c is val] ++ cs
setData _ _ val = val
_cmp :: LispVal -> LispVal -> IO ()
_cmp input expected = do
print input
print (assert (eqVal expected input) input)
_test :: IO ()
_test = do
_cmp (setData (List [Number 1, Number 2, Number 3, Number 4]) [4] (Number 5))
(List [Number 1, Number 2, Number 3, Number 4, Number 5])
_cmp (setData (List [Number 1, Number 2, Number 3, Number 4]) [1] (Number 5))
(List [Number 1, Number 5, Number 2, Number 3, Number 4])
_cmp (setData (List [List [Number 1, Number 2], List [Number 3, Number 4, Number 5]]) [1, 3] (Number 6))
(List [List [Number 1, Number 2], List [Number 3, Number 4, Number 5, Number 6]])
_cmp (setData (List [List [Number 1, Number 2], List [Number 3, Number 4, Number 5]]) [1, 2] (Number 6))
(List [List [Number 1, Number 2], List [Number 3, Number 4, Number 6, Number 5]])
_cmp (setData (List [List [Number 1, Number 2], List [Number 3, Number 4, Number 5]]) [0, 2] (Number 6))
(List [List [Number 1, Number 2, Number 6], List [Number 3, Number 4, Number 5]])
let a = _create 2
_cmp a
(List [List []])
let b = setData a [0, 0] $ Atom "test"
_cmp b (List [List [Atom "test"]])
let c = setData b [0, 1] $ Atom "test2"
_cmp c (List [List [Atom "test", Atom "test2"]])
_cmp (setData (List []) [0, 1, 0] $ Atom "test")
(List [List[List [], List[Atom "test"]]])
let cc = setData b [1, 0] $ Atom "test2"
_cmp cc (List [List [Atom "test"], List [Atom "test2"]])
let cc2 = setData b [1, 4] $ Atom "test2"
_cmp cc2 (List [List [Atom "test"], List [Atom "test2"]])
let cc3 = setData b [4, 0] $ Atom "test2"
_cmp cc3 (List [List [Atom "test"], List [], List [], List [], List [Atom "test2"]])
_cmp (setData (List []) [4, 0] (Number 5))
(List [List [], List [], List [], List [], List [Number 5]])
_cmp (getData (List [List [List [], List [Number 1, Number 2, Number 3, Number 4]]]) [0, 1, 2])
(Number 3)
_cmp (getData (List [List [List [], List [Atom "1", Number 2, Number 3, Number 4]]]) [0, 1, 0])
(Atom "1")
_cmp (getData (List [List [List [], List [Atom "1", Number 2, Number 3, Number 4]]]) [0, 1])
(List [Atom "1", Number 2, Number 3, Number 4])