Chapter 8 Mutable Variables and Loops
Where is this going: we want a looping construct, and if we add standard while loops we also need mutable variables.
We observe some awkwardness in the way loops are added: every expression is expected to return an integer result, but loops do not return values, they just modify state.
8.1 Recap
8.1.1 Current Grammar
<op>    ::= '+' | '-' | '*' | '/'
<bop>   ::= '==' | '!=' | '<' | '>' | '<=' | '>='
<atom>  ::= <number>
          | '('<simp>')'
          | <ident>
          | '{'<exp>'}'
<uatom> ::= [<op>]<atom>
<cond>  ::= <simp><bop><simp>
<simp>  ::= <uatom>[<op><uatom>]*
          | 'if' '('<cond>')' <simp> 'else' <simp>
<exp>   ::= <simp>
          | 'val' <ident> '=' <simp>';' <exp>8.1.2 Quiz
Are these syntactically valid programs?
    if (3 == 5) {
      2
    } * 4 else 8    if (3 == 2)
      val x = 3; x
    else
      5Answer:
- Yes
- No: ‘val’ x = 3; x is not a simple expression
8.2 Mutable Variables
8.2.1 Syntax
<op>    ::= '+' | '-' | '*' | '/'
<bop>   ::= '==' | '!=' | '<' | '>' | '<=' | '>='
<atom>  ::= <number>
          | '('<simp>')'
          | <ident>
          | '{'<exp>'}'
<uatom> ::= [<op>]<atom>
<cond>  ::= <simp><bop><simp>
<simp>  ::= <uatom>[<op><uatom>]*
          | 'if' '('<cond>')' <simp> 'else' <simp>
          | <ident> '=' <simp>
<exp>   ::= <simp>
          | 'val' <ident> '=' <simp>';' <exp>
          | 'var' <ident> '=' <simp>';' <exp>8.2.2 AST
case class VarDec(name: String, value: Exp, body: Exp) extends Exp
case class VarAssign(name: String, value: Exp) extends Exp8.2.3 Semantics
We can only assign to mutable variables, i.e. declared with ‘var’ (VarDec)
type Value = Int
def eval(exp: Exp)(env: ValueEnv): Val = exp match {
  case VarDec(x, rhs, body) =>
    eval(body)(env.withVar(x, eval(rhs)(env)))
  case VarAssign(x, rhs) =>
    env.updateVar(x, eval(rhs)(env)) // return the new value
}8.3 Loops
8.3.1 Syntax
<op>    ::= '+' | '-' | '*' | '/'
<bop>   ::= '==' | '!=' | '<' | '>' | '<=' | '>='
<atom>  ::= <number>
          | '('<simp>')'
          | <ident>
          | '{'<exp>'}'
<uatom> ::= [<op>]<atom>
<cond>  ::= <simp><bop><simp>
<simp>  ::= <uatom>[<op><uatom>]*
          | 'if' '('<cond>')' <simp> 'else' <simp>
          | <ident> '=' <simp>
<exp>   ::= <simp>
          | 'val' <ident> '=' <simp>';' <exp>
          | 'var' <ident> '=' <simp>';' <exp>
          | 'while' '(' <cond> ')' <simp>; <exp>8.3.2 AST
// Already defined
case class Cond(op: String, lop: Exp, rop: Exp)case class While(cond: Cond, lbody: Exp, body: Exp) extends Exp8.3.3 Semantics
type Value = Int
def eval(exp: Exp)(env: ValueEnv): Val = exp match {
  case While(Cond(op, l, r), lbody, body) =>
    while (evalCond(op)(eval(l)(env), eval(r)(env))) {
      eval(lbody)(env)
    }
    eval(body)(env)
}8.3.4 x86 Flags And Jump - Compile Loops
trans(While(Cond(op, l, r), lbody, body), 0)(Map())In order to compile while statement, we are going to follow this idea:
  jmp loop_cond
loop_body:
  ... # code for lbody
loop_cond:
  ... # code for l and r
  cmpq <r>, <l>
  j<op> loop_body # the jump operation depends on 'op'
  ... # code for bodyHow would we compile a do-while loop?
Answer: omit the unconditional jump
8.4 Parsing and Desugaring
8.4.1 We Can Write, Parse, and Compile Nice Code!!
var x = 2;
var y = 0;
while (y < 5) {
  x = x * x;
  y = y + 1
};
xCan we really???
We need to modify our program slightly.
var x = 2;
var y = 0;
while (y < 5) {
  val dummy = x = x * x;
  y = y + 1
};
xLet’s modify our grammar slightly instead!!
8.4.2 Grammar - Syntactic Sugar
<op>    ::= '+' | '-' | '*' | '/'
<bop>   ::= '==' | '!=' | '<' | '>' | '<=' | '>='
<atom>  ::= <number>
          | '('<simp>')'
          | <ident>
          | '{'<exp>'}'
<uatom> ::= [<op>]<atom>
<cond>  ::= <simp><bop><simp>
<simp>  ::= <uatom>[<op><uatom>]*
          | 'if' '('<cond>')' <simp> ['else' <simp>]
          | <ident> '=' <simp>
<exp>   ::= <simp>[';'<exp>]
          | 'val' <ident> '=' <simp>';'<exp>
          | 'var' <ident> '=' <simp>';'<exp>
          | 'while' '(' <cond> ')' <simp>';'<exp>Syntax sugar constructs are constructs that can be syntactically translated to other existing constructs. Syntactic sugar does not offer additional expressive power to the programmer; only some syntactic convenience
x = x + 1;
y = y + 1rather than
val dummy = x = x + 1;
y = y + 18.4.3 One-Sided Ifs
Similarly, we can support ifs without else clause:
if (x > 0)
  x = x - 1;
val y = x * 5;
xis now transformed into
val tmp = if (x > 0)
  x = x - 1
else
  0; // Won't be used
val y = x * 5;
y8.4.4 AST Of Sugared Expressions
Example 1
x = x + 1;
y = y + 1Let("tmp$1",
   VarAssign("x", Prim("+", Ref("x"), Lit(1)))
      VarAssign("y", Prim("+", Ref("y"), Lit(1)))
)Example 2
if (x > 0)
  x = x - 1;
val y = x * 5;
xLet("tmp$1",
  If(Cond(">", Ref("x"), Lit(0)),
    VarAssign("x", Prim("-", Ref("x"), Lit(1))),
    Lit(())),
  Let("y", Prim("*", Ref("x"), Lit(5)), Ref("x"))
)8.5 Where Are We?
We added variables, loops and some syntax sugar to our language.