hw2: init

This commit is contained in:
2026-02-21 21:09:49 -08:00
parent fd9063e09d
commit 5138e3f817
5 changed files with 420 additions and 0 deletions

80
hw2/hs/WhileInterp.hs Normal file
View 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
View 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
View 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