Professional Documents
Culture Documents
-- Задача 1 ------------------------------------
updateValue :: Eq a => a -> b -> [(a,b)] -> [(a,b)]
updateValue x y [] = [(x,y)]
updateValue x y (a:abss)
| fst a == x = [(fst a, y)] ++ abss
| otherwise = [a] ++ (updateValue x y abss)
-- Задача 2 ------------------------------------
updateArray :: Value -> Value -> Value -> Value
updateArray (A a) (I i) (I v) = A (updateValue i v a)
updateArray _ _ _ = error "Bad arguments"
-- Задача 3 ------------------------------------
normalniyLookUp :: Eq a => [(a,b)] -> a -> Maybe b
normalniyLookUp arr x =
let res = [y | y <- arr, (fst y) == x]
in case null res of
False -> Just $ snd $ head res
True -> Nothing
applyOp :: Op -> Value -> Value -> Value
applyOp Add (I x) (I y) = I(x + y)
applyOp Minus (I x) (I y) = I(x - y)
applyOp Mul (I x) (I y) = I(x * y)
applyOp Less (I x) (I y)
| x < y = I 1
| otherwise = I 0
applyOp Equal (I x) (I y)
| x == y = I 1
| otherwise = I 0
applyOp Index (A a) (I i) = case normalniyLookUp a i of
Just v -> I v
Nothing -> I 0
applyOp _ _ _ = error "Bad arguments"
-- Задача 4 ------------------------------------
evExp :: Exp -> [FunDef] -> StateP -> Value
evExp (Const i) _ _ = I i
evExp (Var v) _ st = lookUp v st
evExp (OpApp o x y) dfs st = applyOp o (evExp x dfs st) (evExp y dfs st)
evExp (Cond p f s) dfs st
| (evExp p dfs st) == I 0 = evExp s dfs st
| otherwise = evExp f dfs st
evExp (FunApp idd es) dfs st =
let (vars, ef) = lookUp idd dfs
vs = evArgs es dfs st
new = evState vars vs
in evExp ef dfs new
-- Задача 5 ------------------------------------
evStmt :: Stmt -> [FunDef] -> [ProcDef] -> StateP -> StateP
evStmt (Assign n ex) dfx _ st = let i = evExp ex dfx st
in updateValue n i st
evStmt (AssignA n ex1 ex2) dfx _ st = updateValue n (updateArray arr f s) st
where f = evExp ex1 dfx st
s = evExp ex2 dfx st
arr = lookUp n st
evStmt (If ex stm1 stm2) dfx dpx st =
evStmt (if i /= 0 then stm1 else stm2) dfx dpx st
where I i = evExp ex dfx st
updState:: Id -> [Exp] -> [FunDef] ->[ProcDef] -> StateP -> StateP
updState n es dfx dpx st = let (par, _) = lookUp n dpx
vars = map (\x -> evExp x dfx st) es
in evState par vars ++ st
-- Задача 6 ------------------------------------
iswfOp1 :: Op -> [Maybe Type] -> Maybe Type
iswfOp1 Add [(Just It),(Just It)] = Just It
iswfOp1 Minus [(Just It),(Just It)] = Just It
iswfOp1 Mul [(Just It),(Just It)] = Just It
iswfOp1 Less [(Just It),(Just It)] = Just It
iswfOp1 Equal [(Just It),(Just It)] = Just It
iswfOp1 Index [(Just At),(Just It)] = Just It
iswfOp1 _ _ = Nothing
-- Задача 8 ------------------------------------
iswfFunDef :: FunDef -> FunEnv -> Bool
iswfFunDef fd fe = elem idTypes fe && iswfExp ex ve fe /= Nothing
where (fn,(ft,ex)) = fd
idTypes = (fn, map initType ft)
ve = map initvType ft
iswfProcDef :: ProcDef -> VarEnv -> FunEnv -> ProcEnv -> Bool
iswfProcDef pd ve fe pe = let (pname,(ptypes, st)) = pd
ptypesUpd = map initType ptypes
veUpd = map initvType ptypes ++ ve
peUpd = updateValue pname ptypesUpd pe
in elem (pname, ptypesUpd) peUpd &&
iswfStmt st veUpd fe peUpd
-- Задача 9 ------------------------------------
createEnv :: [(Id, ([VarDef], a))] -> [(Id, [Type])]
createEnv fd = map initFenv fd
where initFenv (fn, (fargs, _)) = (fn, map initType fargs)
varEnv :: VarEnv
varEnv = [("x",It), ("y",It), ("a",At)]
)
)
-- Функція, що обчислює число Фібоначчі
-- func fib(n) = (n<3 ? 1 : fib(n-1) + fib(n-2))
fib :: FunDef
fib = ("fib",
([Int "n"],
Cond (OpApp Less (Var "n") (Const 3))
(Const 1)
(OpApp Add (FunApp "fib" [OpApp Minus (Var "n") (Const 1)])
(FunApp "fib" [OpApp Minus (Var "n") (Const 2)]))
)
)
funEnv :: FunEnv
funEnv = [("biggest",[It,It]),("fib", [It]),("sumA",[At,It])]
procEnv :: ProcEnv
procEnv = [("gAdd",[It,It]),("sumA1",[At,It])]
-- Повні програми
-- gSum;
-- proc gAdd(x,y) gSum = x + y
-- proc main() call gAdd(5,10)
pr1 :: Program
pr1 = ([Int "gSum"], [], [gAdd, ("main",([],Call "gAdd" [Const 5, Const 10]))])
-- sA
-- proc sumA1(a[],n) {i;limit; .... }
-- proc main() {b[]; b[0]=9; b[2]=5; b[3]=7; b[5]=1;
-- call sumA1 (b,5)
-- }
pr2 :: Program
pr2 = ([Int "sA"], [],
[sumA1,
("main",([], sampleBlock))
])