4. Static SemanticsΒΆ
foobar:
module statics/calc
imports signatures/-
rules
init ^ (s) := new s.
[[ Program(stats) ^ (s) ]] :=
new s', s' ---> s,
Stats[[ stats ^ (s') ]].
Stats[[ [] ^ (s) ]].
Stats[[ [ stat | stats ] ^ (s) ]] :=
Stat[[ stat ^ (s, s_nxt) ]],
Stats[[ stats ^ (s_nxt) ]].
Stat[[ Bind(x, e) ^ (s, s') ]] :=
s' == s_nxt,
new s_nxt, s_nxt ---> s,
{x} <- s_nxt, {x} : ty_gen,
ty_gen genOf ty,
[[ e ^ (s) : ty ]].
Stat[[ Exp(e) ^ (s, s_nxt) ]] :=
s == s_nxt,
[[ e ^ (s) : ty ]].
rules // numbers
[[ Num(x) ^ (s) : NumT() ]].
[[ Pow(e1, e2) ^ (s) : NumT() ]] :=
[[ e1 ^ (s) : NumT() ]],
[[ e2 ^ (s) : NumT() ]].
[[ Mul(e1, e2) ^ (s) : NumT() ]] :=
[[ e1 ^ (s) : NumT() ]],
[[ e2 ^ (s) : NumT() ]].
[[ Add(e1, e2) ^ (s) : NumT() ]] :=
[[ e1 ^ (s) : NumT() ]],
[[ e2 ^ (s) : NumT() ]].
[[ Sub(e1, e2) ^ (s) : NumT() ]] :=
[[ e1 ^ (s) : NumT() ]],
[[ e2 ^ (s) : NumT() ]].
[[ Div(e1, e2) ^ (s) : NumT() ]] :=
[[ e1 ^ (s) : NumT() ]],
[[ e2 ^ (s) : NumT() ]].
[[ Eq(e1, e2) ^ (s) : BoolT() ]] :=
[[ e1 ^ (s) : NumT() ]],
[[ e2 ^ (s) : NumT() ]].
[[ Lt(e1, e2) ^ (s) : BoolT() ]] :=
[[ e1 ^ (s) : NumT() ]],
[[ e2 ^ (s) : NumT() ]].
rules // booleans
[[ True() ^ (s) : BoolT() ]].
[[ False() ^ (s) : BoolT() ]].
[[ If(e1, e2, e3) ^ (s) : ty2 ]] :=
[[ e1 ^ (s) : BoolT() ]],
[[ e2 ^ (s) : ty2 ]],
[[ e3 ^ (s) : ty3 ]],
ty2 == ty3 | error $[branches should have same type] @ e2.
rules // variables and functions
[[ Var(x) ^ (s) : ty ]] :=
{x} -> s, {x} |-> d, d : ty_gen, ty instOf ty_gen.
[[ Let(x, e1, e2) ^ (s) : ty2 ]] :=
new s', {x} <- s', {x} : ty, s' -P-> s,
[[ e1 ^ (s) : ty ]],
[[ e2 ^ (s') : ty2 ]].
[[ Fun([x], e) ^ (s) : FunT(ty1, ty2) ]] :=
new s', {x} <- s', {x} : ty1, s' -P-> s,
[[ e ^ (s') : ty2 ]].
[[ App(e1, e2) ^ (s) : ty2 ]] :=
[[ e1 ^ (s) : FunT(ty1, ty2) ]],
[[ e2 ^ (s) : ty1 ]].