diff --git a/hw2/hs/WhileInterp.hs b/hw2/hs/WhileInterp.hs index 271de6c..2b1eb75 100644 --- a/hw2/hs/WhileInterp.hs +++ b/hw2/hs/WhileInterp.hs @@ -1,9 +1,10 @@ {- - Name: + Name: Yuri Tatishchev Class: CS 252 Assigment: HW2 - Date: - Description: + Date: 2026-03-06 + Description: Implements the big-step operational semantics for + the WHILE language described in `while-semantics.pdf` -} @@ -33,6 +34,8 @@ data Expression = | Op Binop Expression Expression | If Expression Expression Expression -- if e1 then e2 else e3 | While Expression Expression -- while (e1) e2 + | BoolOp BoolBinop Expression Expression + | Not Expression deriving (Show) data Binop = @@ -46,6 +49,11 @@ data Binop = | Le -- <= :: Int -> Int -> Bool deriving (Show) +data BoolBinop = + And + | Or + deriving (Show) + data Value = IntVal Int | BoolVal Bool @@ -57,17 +65,61 @@ data Value = -- 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" +applyOp Minus (IntVal i) (IntVal j) = IntVal $ i - j +applyOp Times (IntVal i) (IntVal j) = IntVal $ i * j +applyOp Divide (IntVal i) (IntVal j) = IntVal $ i `div` j +applyOp Gt (IntVal i) (IntVal j) = BoolVal $ i > j +applyOp Ge (IntVal i) (IntVal j) = BoolVal $ i >= j +applyOp Lt (IntVal i) (IntVal j) = BoolVal $ i < j +applyOp Le (IntVal i) (IntVal j) = BoolVal $ i <= j +applyOp _ _ _ = error "Not implemented for non-integer values" +applyBoolOp :: BoolBinop -> Value -> Value -> Value +applyBoolOp And (BoolVal b1) (BoolVal b2) = BoolVal $ b1 && b2 +applyBoolOp Or (BoolVal b1) (BoolVal b2) = BoolVal $ b1 || b2 +applyBoolOp _ _ _ = error "Not implemented for non-boolean values" + +applyNot :: Value -> Value +applyNot (BoolVal b) = BoolVal $ not b +applyNot _ = error "Not implemented for non-boolean values" -- Implement this function according to the specified semantics evaluate :: Expression -> Store -> (Value, Store) +evaluate (Val v) s = (v, s) +evaluate (Var x) s = case Map.lookup x s of + Just v -> (v, s) + Nothing -> error "Variable not found" +evaluate (Assign x e) s = + let (v,s') = evaluate e s + in (v, Map.insert x v s') +evaluate (Sequence e1 e2) s = + let (_,s1) = evaluate e1 s + (v2,s') = evaluate e2 s1 + in (v2, s') 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" - +evaluate (If e1 e2 e3) s = + let (v1,s1) = evaluate e1 s + in case v1 of + BoolVal b -> if b then evaluate e2 s1 else evaluate e3 s1 + _ -> error "Not implemented for non-boolean values" +evaluate (While e1 e2) s = + let (v1,s1) = evaluate e1 s + in case v1 of + BoolVal b -> if b then + let (_, s2) = evaluate e2 s1 + in evaluate (While e1 e2) s2 + else (BoolVal False, s1) + _ -> error "Not implemented for non-boolean values" +evaluate (BoolOp o e1 e2) s = + let (v1,s1) = evaluate e1 s + (v2,s') = evaluate e2 s1 + in (applyBoolOp o v1 v2, s') +evaluate (Not e) s = + let (v,s') = evaluate e s + in (applyNot v, s') -- Evaluates a program with an initially empty state run :: Expression -> (Value, Store)