Compiler Theory
Functions and Memory Cells
Functions
Syntax extension
e ::=
… | λx.
e | (
e e)
| x
| y
| … | xᵢ
, where x
, y
, …, xᵢ
(i ∈ ℕ).
The introduction rule for functions is λx.
e.
Semantics
e → e Reductions
(λx.
e)
e’ → e[e’/x
]
e[e’/x
] = e Substitutions
———————————————————
true[e'/x] = true
and so on, for all values.
——————————————
x[e'/x] = e'
x ≠ y
—————————————
y[e'/x] = y
≠ here is syntactic difference.
For dynamic scoping, we only need one rule.
e[e'/y] = e₂
——————————————————————
(λx.e)[e'/y] = λx.e₂
For static scoping, we need two rules.
fresh x₁ e[e'/y] = e₂ e₁[e'/y] = e₂ x ≠ y
——————————————————————————————————————————————————
(λx.e)[e'/y] = λx₁.e₂
e[e'/y] = e₂ x = y
————————————————————————
(λx.e)[e'/y] = λx.e₂
Memory cells
Syntax
e ::=
… | x
:=
e | deref x
| e;
e
e ;
e can also be modeled as begin
e … e end
.
Semantics
In order to write down small step operational semantics for memory cells, we need to model the heap. Thus, we add M to the rules to model the heap.
M ::=
• | M,[x ↦ e]
M, e → M’, e’ Reductions
M, x := e → M,[x ↦ e], e
which means that allocations return e as a result.
M,(add1 n₁ ) + n₂ → M,n₁ + add1 n₂
and so on.
[x ↦ e] ∈ M
———————————————————
M, deref x → M, e
M, e₁ → M', e₁'
———————————————————————
M, e₁;e₂ → M', e₁';e₂
—————————————————
M, v;e₂ → M, e₂
M, e →* M, e Conversions
——————————————
M, e →* M, e
M, e → M', e' M', e' →* M'', e''
——————————————————————————————————————
M, e →* M'', e''
M, e₁ →* M', e₁' M', e₂ →* M'', e₂'
—————————————————————————————————————————
M, e₁ + e₂ →* M'', e₁' + e₂'
eval(e) = v
·, e →* M', v
———————————————
eval(e) = v