hw2: init
This commit is contained in:
80
hw2/hs/WhileInterp.hs
Normal file
80
hw2/hs/WhileInterp.hs
Normal file
@@ -0,0 +1,80 @@
|
||||
{-
|
||||
Name: <Your name here>
|
||||
Class: CS 252
|
||||
Assigment: HW2
|
||||
Date: <Date assignment is due>
|
||||
Description: <Describe the program and what it does>
|
||||
-}
|
||||
|
||||
|
||||
module WhileInterp (
|
||||
Expression(..),
|
||||
Binop(..),
|
||||
Value(..),
|
||||
testProgram,
|
||||
run
|
||||
) where
|
||||
|
||||
import Data.Map (Map)
|
||||
import qualified Data.Map as Map
|
||||
|
||||
-- We represent variables as strings.
|
||||
type Variable = String
|
||||
|
||||
-- The store is an associative map from variables to values.
|
||||
-- (The store roughly corresponds with the heap in a language like Java).
|
||||
type Store = Map Variable Value
|
||||
|
||||
data Expression =
|
||||
Var Variable -- x
|
||||
| Val Value -- v
|
||||
| Assign Variable Expression -- x := e
|
||||
| Sequence Expression Expression -- e1; e2
|
||||
| Op Binop Expression Expression
|
||||
| If Expression Expression Expression -- if e1 then e2 else e3
|
||||
| While Expression Expression -- while (e1) e2
|
||||
deriving (Show)
|
||||
|
||||
data Binop =
|
||||
Plus -- + :: Int -> Int -> Int
|
||||
| Minus -- - :: Int -> Int -> Int
|
||||
| Times -- * :: Int -> Int -> Int
|
||||
| Divide -- / :: Int -> Int -> Int
|
||||
| Gt -- > :: Int -> Int -> Bool
|
||||
| Ge -- >= :: Int -> Int -> Bool
|
||||
| Lt -- < :: Int -> Int -> Bool
|
||||
| Le -- <= :: Int -> Int -> Bool
|
||||
deriving (Show)
|
||||
|
||||
data Value =
|
||||
IntVal Int
|
||||
| BoolVal Bool
|
||||
deriving (Show)
|
||||
|
||||
|
||||
-- This function will be useful for defining binary operations.
|
||||
-- The first case is done for you.
|
||||
-- Be sure to explicitly check for a divide by 0 and throw an error.
|
||||
applyOp :: Binop -> Value -> Value -> Value
|
||||
applyOp Plus (IntVal i) (IntVal j) = IntVal $ i + j
|
||||
applyOp _ _ _ = error "TBD"
|
||||
|
||||
|
||||
-- Implement this function according to the specified semantics
|
||||
evaluate :: Expression -> Store -> (Value, Store)
|
||||
evaluate (Op o e1 e2) s =
|
||||
let (v1,s1) = evaluate e1 s
|
||||
(v2,s') = evaluate e2 s1
|
||||
in (applyOp o v1 v2, s')
|
||||
evaluate _ _ = error "TBD"
|
||||
|
||||
|
||||
-- Evaluates a program with an initially empty state
|
||||
run :: Expression -> (Value, Store)
|
||||
run prog = evaluate prog Map.empty
|
||||
|
||||
-- The same as run, but only returns the Store
|
||||
testProgram :: Expression -> Store
|
||||
testProgram prog = snd $ run prog
|
||||
|
||||
|
||||
12
hw2/hs/mapExample.hs
Normal file
12
hw2/hs/mapExample.hs
Normal file
@@ -0,0 +1,12 @@
|
||||
import Data.Map (Map)
|
||||
import qualified Data.Map as Map
|
||||
|
||||
m = Map.empty
|
||||
|
||||
m' = Map.insert "a" 42 m
|
||||
|
||||
main = do
|
||||
case (Map.lookup "a" m') of
|
||||
Just i -> putStrLn $ show i
|
||||
_ -> error "Key is not in the map"
|
||||
|
||||
36
hw2/hs/test.hs
Normal file
36
hw2/hs/test.hs
Normal file
@@ -0,0 +1,36 @@
|
||||
import WhileInterp
|
||||
|
||||
-- Here are a few tests that you can use to check your implementation.
|
||||
w_test = (Sequence (Assign "X" (Op Plus (Op Minus (Op Plus (Val (IntVal 1)) (Val (IntVal 2))) (Val (IntVal 3))) (Op Plus (Val (IntVal 1)) (Val (IntVal 3))))) (Sequence (Assign "Y" (Val (IntVal 0))) (While (Op Gt (Var "X") (Val (IntVal 0))) (Sequence (Assign "Y" (Op Plus (Var "Y") (Var "X"))) (Assign "X" (Op Minus (Var "X") (Val (IntVal 1))))))))
|
||||
|
||||
w_fact = (Sequence (Assign "N" (Val (IntVal 2))) (Sequence (Assign "F" (Val (IntVal 1))) (While (Op Gt (Var "N") (Val (IntVal 0))) (Sequence (Assign "X" (Var "N")) (Sequence (Assign "Z" (Var "F")) (Sequence (While (Op Gt (Var "X") (Val (IntVal 1))) (Sequence (Assign "F" (Op Plus (Var "Z") (Var "F"))) (Assign "X" (Op Minus (Var "X") (Val (IntVal 1)))))) (Assign "N" (Op Minus (Var "N") (Val (IntVal 1))))))))))
|
||||
|
||||
testUnit :: IO ()
|
||||
testUnit = do
|
||||
-- Should be: (IntVal 1,fromList [])
|
||||
putStrLn $ show $ WhileInterp.run (Val (IntVal 1))
|
||||
-- Should be: (BoolVal True,fromList [("X",BoolVal True)])
|
||||
putStrLn $ show $ WhileInterp.run (Assign "X" (Val (BoolVal True)))
|
||||
-- Should be: (IntVal 2,fromList [])
|
||||
putStrLn $ show $ WhileInterp.run (Sequence (Val (IntVal 1)) (Val (IntVal 2)))
|
||||
-- Should be: (IntVal 11,fromList [])
|
||||
putStrLn $ show $ WhileInterp.run (Op Plus (Val (IntVal 9)) (Val (IntVal 2)))
|
||||
-- Should be: (IntVal 1,fromList [])
|
||||
putStrLn $ show $ WhileInterp.run (If (Val (BoolVal True)) (Val (IntVal 1)) (Val (IntVal 2)))
|
||||
-- Should be: (IntVal 2,fromList [])
|
||||
putStrLn $ show $ WhileInterp.run (If (Val (BoolVal False)) (Val (IntVal 1)) (Val (IntVal 2)))
|
||||
-- Should be: (BoolVal False,fromList [])
|
||||
putStrLn $ show $ WhileInterp.run (While (Val (BoolVal False)) (Val (IntVal 42)))
|
||||
-- Should be: (IntVal 666,fromList [("X",IntVal 666)])
|
||||
putStrLn $ show $ WhileInterp.run (Sequence
|
||||
(Assign "X" (Val (IntVal 666)))
|
||||
(Var "X"))
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
testUnit
|
||||
-- Should be: fromList [("X",IntVal 0),("Y",IntVal 10)]
|
||||
putStrLn $ show $ WhileInterp.testProgram w_test
|
||||
-- Should be: fromList [("F",IntVal 2),("N",IntVal 0),("X",IntVal 1),("Z",IntVal 2)]
|
||||
putStrLn $ show $ WhileInterp.testProgram w_fact
|
||||
|
||||
Reference in New Issue
Block a user