Theory Compiler1

(*  Title:      JinjaDCI/Compiler/Compiler1.thy
    Author:     Tobias Nipkow, Susannah Mansky
    Copyright   TUM 2003, UIUC 2019-20

    Based on the Jinja theory Compiler/Compiler1.thy by Tobias Nipkow
*)

section ‹ Compilation Stage 1 ›

theory Compiler1 imports PCompiler J1 Hidden begin

text‹ Replacing variable names by indices. ›

primrec compE1  :: "vname list ⇒ expr ⇒ expr1"
  and compEs1 :: "vname list ⇒ expr list ⇒ expr1 list" where
  "compE1 Vs (new C) = new C"
| "compE1 Vs (Cast C e) = Cast C (compE1 Vs e)"
| "compE1 Vs (Val v) = Val v"
| "compE1 Vs (e1 «bop» e2) = (compE1 Vs e1) «bop» (compE1 Vs e2)"
| "compE1 Vs (Var V) = Var(last_index Vs V)"
| "compE1 Vs (V:=e) = (last_index Vs V):= (compE1 Vs e)"
| "compE1 Vs (e∙F{D}) = (compE1 Vs e)∙F{D}"
| "compE1 Vs (C∙sF{D}) = C∙sF{D}"
| "compE1 Vs (e1∙F{D}:=e2) = (compE1 Vs e1)∙F{D} := (compE1 Vs e2)"
| "compE1 Vs (C∙sF{D}:=e2) = C∙sF{D} := (compE1 Vs e2)"
| "compE1 Vs (e∙M(es)) = (compE1 Vs e)∙M(compEs1 Vs es)"
| "compE1 Vs (C∙sM(es)) = C∙sM(compEs1 Vs es)"
| "compE1 Vs {V:T; e} = {(size Vs):T; compE1 (Vs@[V]) e}"
| "compE1 Vs (e1;;e2) = (compE1 Vs e1);;(compE1 Vs e2)"
| "compE1 Vs (if (e) e1 else e2) = if (compE1 Vs e) (compE1 Vs e1) else (compE1 Vs e2)"
| "compE1 Vs (while (e) c) = while (compE1 Vs e) (compE1 Vs c)"
| "compE1 Vs (throw e) = throw (compE1 Vs e)"
| "compE1 Vs (try e1 catch(C V) e2) =
    try(compE1 Vs e1) catch(C (size Vs)) (compE1 (Vs@[V]) e2)"
| "compE1 Vs (INIT C (Cs,b) ← e) = INIT C (Cs,b) ← (compE1 Vs e)"
| "compE1 Vs (RI(C,e);Cs ← e') = RI(C,(compE1 Vs e));Cs ← (compE1 Vs e')"

| "compEs1 Vs []     = []"
| "compEs1 Vs (e#es) = compE1 Vs e # compEs1 Vs es"

lemma [simp]: "compEs1 Vs es = map (compE1 Vs) es"
(*<*)by(induct es type:list) simp_all(*>*)

lemma [simp]: "⋀Vs. sub_RI (compE1 Vs e) = sub_RI e"
 and [simp]: "⋀Vs. sub_RIs (compEs1 Vs es) = sub_RIs es"
proof(induct rule: sub_RI_sub_RIs_induct) qed(auto)

primrec fin1:: "expr ⇒ expr1" where
  "fin1(Val v) = Val v"
| "fin1(throw e) = throw(fin1 e)"

lemma comp_final: "final e ⟹ compE1 Vs e = fin1 e"
(*<*)by(erule finalE, simp_all)(*>*)


lemma [simp]:
      "⋀Vs. max_vars (compE1 Vs e) = max_vars e"
and "⋀Vs. max_varss (compEs1 Vs es) = max_varss es"
(*<*)by (induct e and es rule: max_vars.induct max_varss.induct) simp_all(*>*)


text‹ Compiling programs: ›

definition compP1 :: "J_prog ⇒ J1_prog"
where
  "compP1  ≡  compP (λb (pns,body). compE1 (case b of NonStatic ⇒ this#pns | Static ⇒ pns) body)"

(*<*)
declare compP1_def[simp]
(*>*)

end