0

I asked a question similar to this earlier, and had the original question resolved. I have run into an additional problem that was hidden by the other error. I am able to make statements like "if" statements work properly, but not a "while" statement. When a "stmt" is evaluated, the environment must be updated. This works properly for my "if" statement like this:

exec :: Env -> Stmt -> Env
exec env (If c t e) = 
    exec env ( if eval env c == BoolLit True then t else e )

eval Looks like this:

eval :: Env -> Expr -> Expr
eval _ (IntLit i) = IntLit i
eval _ (BoolLit b) = BoolLit b
eval env (Var n) = lookupVar env n
eval env (BinOp op a b) = primEval op (eval env a) (eval env b)

The file being parsed looks like this:

x = 1; c = 0;
if (x < 2) c = c + 1; else ;

My attempt to have the while statement working is done like this:

exec env (While c t) = exec env ( if eval env c == BoolLit True then t)

But this gives a parse error on ')'. The expected format of the while statement in the file being parsed:

x = 1; c = 1;
while (x < 10)
{
  c = c * x;
  x = x + 1;
}
c

I'm trying to understand how I can return the proper environment based on this expected format. It would be simple if there were already a similar structure for while statements in Haskell, but nothing exists like this that I am aware of.

Nibirue
  • 411
  • 1
  • 15
  • 29

1 Answers1

4

You are missing an else clause in your function, it should probably be:

exec env (While c t) = if eval env c == BoolLit True then exec env t else env

To actually make it work, that is to execute the body multiple times:

exec env (While c t) = if   eval env c == BoolLit True 
                       then exec (exec env t) (While c t)
                       else env
Jakub Hampl
  • 39,863
  • 10
  • 77
  • 106