Question: I'm working on a Haskell assignment and I can't get the following outputs right: ghci> rankP [LDB True, LDI 1, LDI 10, LDI 5, IFELSE
I'm working on a Haskell assignment and I can't get the following outputs right:
ghci> rankP [LDB True, LDI 1, LDI 10, LDI 5, IFELSE [ADD] [LDI 7], ADD ] 0
what I get: Just 3
Expected: Just 1
ghci> rankP [LDI 10, LDI 5, LDB True, IFELSE [LDB False, IFELSE [ADD, DUP] [MULT]] [LDI 7] ] 0
what I get: Just 3
Expected: Just 1
And Here is my code:
import Data.Maybe
type Prog = [Cmd] data Cmd = LDI Int | ADD | MULT | DUP | DEC | SWAP | POP Int | IFELSE Prog Prog | LDB Bool | LEQ deriving Show data Val = I Int | B Bool deriving Show
type Stack = [Val]
data Result = A Stack | RankError | TypeError deriving Show
type D = Stack -> Stack type Rank = Int type CmdRank = (Int, Int)
-- Define a function rankP that computes the rank of a program -- when ran with a stack of rank r. -- Maybe data type is used to capture rank error. rankP :: Prog -> Rank -> Maybe Rank rankP [] s' = Just s' rankP (c:cs) s | s < n = Nothing | otherwise = rankP cs (s - n + m) where (n,m) = rankC c
rankError :: Prog -> Int -> Bool rankError p srank = ((rankP p srank) == Nothing )
-- Define a function run for evaluating a program with a given stack run :: Prog -> Stack -> Result --run [] s = Just s -- base case run p s = if (rankError p (length s)) then RankError else if isNothing((sem p s)) then TypeError else A (fromJust(sem p s))
sem :: Prog -> Stack -> Maybe Stack sem [] s = Just s sem [][] = Nothing sem (c:cs) s = case semCmd c s of Just s' -> sem cs s' Nothing -> Nothing semCmd :: Cmd -> Stack -> Maybe Stack -- loads integer onto the stack semCmd (LDI c ) s = Just (I c:s)
-- loads boolean parameter onto the stack semCmd (LDB b ) s = Just (B b:s)
-- add integers onto the stack semCmd ADD (I x:I y:xs) = Just (I (x+y):xs)
semCmd DEC (I x : xs) = Just (I (x - 1) : xs)
-- multiplies integer semCmd MULT (I x:I y:xs) = Just (I (x*y):xs)
-- places a copy of the stack's topmost element on the stack semCmd DUP (x:xs) = Just (x:x:xs)
semCmd SWAP (x : y : xs) = Just (y : x : xs)
-- removes the top integer from the stack. -- If top is greater than the second top, then the true is pushed on the stack semCmd LEQ (I x: I y:xs) = Just (B (x<=y):xs)
-- removes the top of the stack and if the value is true, --then run the first program, else run the secound program. semCmd (POP k) s | k <= length s = Just (drop k s) | otherwise = Nothing --semCmd (IFELSE m n) ((B x): xs) = sem (if x then m else n) xs semCmd (IFELSE [] _ ) ((B True): s) = Just s semCmd (IFELSE p1 _ ) ((B True): s) = sem p1 s semCmd (IFELSE _ []) ((B False): s) = Just s semCmd (IFELSE _ p2) ((B False): s) = sem p2 s --semCmd (IFELSE p1 _) ((B False): s) = semCmd _ _ = Nothing
rankC::Cmd -> CmdRank rankC (LDI _) = (0,1) rankC (LDB _) = (0,1) rankC LEQ = (2,1) rankC ADD = (2,1) rankC MULT = (2,1) rankC DUP = (1,2) rankC DEC = (1,1) rankC SWAP = (2,2) rankC (POP k) = (k,0) rankC (IFELSE p q) = (0,0)
I will upvote! thanks!
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
