I am improving on some Haskell but have become stuck down trying to write an interpreter for testing language which tests math and relations. I have tested all data type cases but CallE. I believe I must make a new environment and map values using the map string method in Haskell but I do not know how it will look. Sorry for mistakes, English is not my best language!
// --------------- Declarations ----------------
data Expr =
IntE Integer
| PlusE Expr Expr
| TimesE Expr Expr
| BoolE Bool
| IfE Expr Expr Expr
| VarE String
| LetE String Expr Expr
| CallE String [Expr]
deriving (Eq,Ord,Show)
data Command =
DefC String [String] Expr
deriving (Eq,Ord,Show)
data Program =
Program [Command] Expr
deriving (Eq,Ord,Show)
data Value =
IntV Integer
| BoolV Bool
deriving (Eq,Ord,Show)
data Answer =
ValueA Value
| BadA
deriving (Eq,Ord,Show)
type Env = Map String Value
type FEnv = Map String ([String],Expr)
// --------------- Helper functions ----------------
interpExprMany :: FEnv -> Env -> [Expr] -> Maybe [Value]
interpExprMany fenv env es = case es of
[] -> Just []
e:es' -> case interpExpr fenv env e of
ValueA v -> case interpExprMany fenv env es' of
Just vs -> Just (v:vs)
Nothing -> Nothing
BadA -> Nothing
extendEnvMany :: [String] -> [Value] -> Env -> Maybe Env
extendEnvMany as bs env = case (as, bs) of
(as1:ass1, bs2:bss2) -> extendEnvMany ass1 bss2 (Map.insert as1 bs2 env)
([], []) -> Just env
// --------------- Implementation of interpreter----------------
interpExpr :: FEnv -> Env -> Expr -> Answer
interpExpr fenv env e = case e of
IntE i -> ValueA (IntV i)
BoolE b -> ValueA (BoolV b)
PlusE e1 e2 -> case (interpExpr fenv env e1,interpExpr fenv env e2) of
(ValueA (IntV i1),ValueA (IntV i2)) -> ValueA (IntV (i1 + i2))
_ -> BadA
IfE e1 e2 e3 -> case interpExpr fenv env e1 of
ValueA (BoolV b) ->
if b
then interpExpr fenv env e2
else interpExpr fenv env e3
VarE x -> case Map.lookup x env of
Just v -> ValueA v
...
...
...
CallE fx es -> undefined
Presumably
CallEtakes a routine name and a list of arguments, with the routine defined in the environment somehow. So you are going to have to look up the name in the environment to get the definition. You don't seem to have a constructor for this, so you will have to define one. Probably something likeThe first
Stringis the routine name, the second is the list of formal parameter names. Pass the formal parameter names and the actual arguments fromCallEtoenvExtendManyto get the inner environment, and callinterpExprwith that new environment.