Compiler Construction bio photo

Compiler Construction

Twitter Github

Edit on GitHub

Homework Assignments Week 1.7: Specifications with NaBL2 (Answers)

Writing NaBL2 Rules

The rules for sequential let are

[[ LetSeq(binds, e) ^ (s) : ty ]] :=
  new s_let,
  BindSeq[[ binds ^ (s, s_let) ]],
  [[ e ^ (s_let) : ty ]].

BindSeq[[ [] ^ (s, s_let) ]] :=
  s_let ---> s.

BindSeq[[ [Bind(x, e)|binds] ^ (s, s_let) ]] :=
  new s_bind, s_bind ---> s,
  s_bind -> Var{x}, Var{x} : ty,
  [[ e ^ (s) : ty ]],
  BindSeq[[ binds ^ (s_bind, s_let) ]].

[[ VarRef(x) ^ (s) : ty ]] :=
  Var{x} -> s, Var{x} |-> d, d : ty.

Applying NaBL2 Rules

 1. Step by step application of the rules to the program gives:

   [[ LetRec([Bind("x"{1},IntLit(42)),Bind("y"{2},VarRef("x"{3}))],VarRef("y"{4})) ^ (s) : ty ]]
=> new s_let, s_let ---> s,
   Map1[[ [Bind("x"{1},IntLit(42)),Bind("y"{2},VarRef("x"{3}))] ^ (s_let) : ty ]],
   [[ VarRef("y"{4}) ^ (s_let) : ty ]]
=> new s_let, s_let ---> s,
   [[ Bind("x"{1},IntLit(42)) ^ (s_let) ]],
   [[ Bind("y"{2},VarRef("x"{3})) ^ (s_let) ]],
   [[ VarRef("y"{4}) ^ (s_let) : ty ]]
=> new s_let, s_let ---> s,
   Var{"x"@1} <- s_let, Var{"x"@1} : ty1, [[ IntLit(42) ^ (s_let) : ty1 ]],
   [[ Bind("y"{2},VarRef("x"{3})) ^ (s_let) ]],
   [[ VarRef("y"@4) ^ (s_let) : ty ]]
=> new s_let, s_let ---> s,
   Var{"x"@1} <- s_let, Var{"x"@1} : ty1, ty1 == INT(),
   [[ Bind("y"{2},VarRef("x"{3})) ^ (s_let) ]],
   [[ VarRef("y"@4) ^ (s_let) : ty ]]
=> new s_let, s_let ---> s,
   Var{"x"@1} <- s_let, Var{"x"@1} : ty1, ty1 == INT(),
   Var{"y"@2} <- s_let, Var{"y"@2} : ty2, [[ VarRef("x"{3}) ^ (s_let) : ty2 ]].
   [[ VarRef("y"@4) ^ (s_let) : ty ]]
=> new s_let, s_let ---> s,
   Var{"x"@1} <- s_let, Var{"x"@1} : ty1, ty1 == INT(),
   Var{"y"@2} <- s_let, Var{"y"@2} : ty2, Var{"x"@3} -> s_let, Var{"x"@3} |-> d1, d1 : ty2,
   [[ VarRef("y"@4) ^ (s_let) : ty ]]
=> new s_let, s_let ---> s,
   Var{"x"@1} <- s_let, Var{"x"@1} : ty1, ty1 == INT(),
   Var{"y"@2} <- s_let, Var{"y"@2} : ty2, Var{"x"@3} -> s_let, Var{"x"@3} |-> d1, d1 : ty2,
   Var{"y"@4} -> s_let, Var{"y"@4} |-> d2, d2 : ty

 2. Only the rules for let and bind have to be changed. The rules are changed in such a way that the expressions in the binds are not checked in the let scope, but in the surrounding lexical scope. These are the rules for parallel lets:

[[ LetRec(binds) ^ (s) : ty ]] :=
  new s_let, s_let ---> s,
  Map1[[ binds ^ (s, s_let) ]],
  [[ e ^ (s_let) : ty ]].

[[ Bind(x, e) ^ (s, s_let) ]] :=
  Var{x} <- s_let, Var{x} : ty,
  [[ e ^ (s) : ty ]].