Organization of the Meeting of the CSE Logic & Types Division on 20 September 2019
Types (simplified)
a : ATy ::= int | double
t : Ty ::= t | bool
Γ : Cxt = List Ty
Indices
x : a ∈ Γ
i : a ∈ Γ
----------- here -------------- there
0 : a ∈ Γ,a 1+ i : a ∈ Γ,b
Expressions (simplified), fixed Γ
data Exp (t : Ty)
_+_ : (e₁ e₂ : Exp a) → Exp a
_<_ : (e₁ e₂ : Exp a) → Exp bool
_&&_ : (e₁ e₂ : Exp bool) → Exp bool
var : (x : t ∈ Γ) → Exp t
lit : (v : Val t) → Exp t
Statements (simplified)
data Stm
assign (x : t ∈ Γ) (e : Exp t)
ifElse (e : Exp bool) (s₁ s₂ : Stm)
while (e : Exp Bool) (s : Stm)
block (ss : List Stm)
JVM manages memory: stack, heap, function calls
Each method runs with
Byte-code verifier checks correct memory access.
Taught to students in class Programming Language Technology.
Expressions: (leave value on the stack)
⟦ v : int ⟧ = iconst v
⟦ x : int ⟧ = iload x
⟦ e₁ + e₂ ⟧ = ⟦e₁⟧; ⟦e₂⟧; iadd
Statements: (leave nothing on the stack)
⟦ x = e ⟧ = ⟦e⟧; istore x
⟦ if (e) s₁ else s₂ ⟧ =
L_else, L_end ← newLabel
⟦e⟧
ifeq L_else
⟦s₁⟧
goto L_end
L_else: ⟦s₂⟧
L_end:
⟦ while (e) s ⟧ =
L_start, L_end ← newLabel
L_start: ⟦e⟧
ifeq L_end
⟦s⟧
goto L_start
L_end:
We can produce statically well-typed JVM code.
Jump-free instructions (simplified):
stack can shrink and grow: Φ ⊸ Φ’
data JF Φ Φ'
iadd : JF (Φ,int,int) (Φ,int)
iload (x : int ∈ Γ) : JF Φ (Φ,int)
iconst (v : val int) : JF Φ (Φ,int)
dmul : JF (Φ,double,double) (Φ,double)
Control: jump to label l.
labels are de Bruijn indices into a list of stack types
Λ : Labels = List Cxt
High-level control structures: flowcharts.
Compilation to flow charts:
⟦ if (e) s₁ else s₂ ; s ⟧ =
let L_end = ⟦s⟧
let L_then = ⟦s₁⟧; goto L_end
let L_else = ⟦s₂⟧; goto L_end
⟦e⟧
branch L_then L_else
⟦ while (e) s₀ ; s ⟧ =
let L_end = ⟦s⟧
fix L_start
let L_body = ⟦s₀⟧; goto L_start
⟦e⟧
branch L_body L_end
Typed by initial stack.
data FC Λ Φ
_∷_ (c : JF Φ Φ') (fc : FC Λ Φ') : FC Λ Φ
goto (l : Φ ∈ Λ) : FC Λ Φ
branch (l₁ l₂ : Φ ∈ Λ) : FC Λ (Φ,bool)
let (fc₁ : FC Λ Φ) (fc₂ : FC (Λ,Φ) Φ' : FC Λ Φ'
fix (fc : FC (Λ,Φ) Φ) : FC Λ Φ
Labels are locally defined.
Compiling statements:
⟦ if (e) s₁ else s₂ ⟧(k) =
let k
let ⟦s₁⟧(goto 0)
let ⟦s₂⟧(goto 1)
⟦e⟧(1,0)
⟦ while (e) s₀ ⟧(k) =
let k
fix
let ⟦s₀⟧(goto 0)
⟦e⟧(0,2)
Compiling conditions:
⟦ true ⟧(l₁,l₂) = goto l₁
⟦ e < e' ⟧(l₁,l₂) = ⟦e⟧(⟦e'⟧(branch l₁ l₂))
⟦ e && e' ⟧(l₁,l₂) = let ⟦e'⟧(l₁,l₂) ⟦e⟧(1+l₁,0)
Compiling arithmetic expressions:
⟦ v ⟧(k) = iconst v ∷ k
⟦ e + e'⟧(k) = ⟦e⟧(⟦e'⟧(iadd ∷ k))
Basic blocks are FCs without label definition (let,fix).
flat : FC Λ Φ → Σ (τ : Λ' ⊇ Λ) (bbs : BBs Λ' τ) (bb : BB Λ' Φ)
BBs Λ τ = AllExt (BB Λ) τ
Time to think about context extensions Λ’ ⊇ Λ !
Γ₁ ⊆ Γ₂
Append
Γ₂ = Γ₁,Δ
Sublist
Γ₁ embeds into Γ₂ in a order-preserving way
Arbitrary renaming
∀ a → a ∈ Γ₁ → a ∈ Γ₂