Library AST
This file defines a number of data types and operations used in
the abstract syntax trees of many of the intermediate languages.
Require Import Coqlib.
Require Import Errors.
Require Import Integers.
Set Implicit Arguments.
Syntactic elements
Definition ident := positive.
Definition ident_eq := peq.
The intermediate languages are weakly typed, using only two types:
Tint for integers and pointers, and Tfloat for floating-point
numbers.
Inductive typ : Set :=
| Tint : typ
.
Definition typesize (ty: typ) : Z :=
match ty with Tint => 4 end.
Lemma typesize_pos: forall ty, typesize ty > 0.
Proof. destruct ty; simpl; omega. Qed.
Lemma typ_eq: forall (t1 t2: typ), {t1=t2} + {t1<>t2}.
Proof. decide equality. Qed.
Lemma opt_typ_eq: forall (t1 t2: option typ), {t1=t2} + {t1<>t2}.
Proof.
destruct t1; destruct t2; eauto; try (right; discriminate).
destruct (typ_eq t t0).
left. congruence.
right. congruence.
Qed.
Additionally, function definitions and function calls are annotated
by function signatures indicating the number and types of arguments,
as well as the type of the returned value if any. These signatures
are used in particular to determine appropriate calling conventions
for the function.
Record signature : Type := mksignature {
sig_args: list typ;
sig_res: option typ
}.
Definition proj_sig_res (s: signature) : typ :=
match s.(sig_res) with
| None => Tint
| Some t => t
end.
Memory accesses (load and store instructions) are annotated by
a ``memory chunk'' indicating the type, size and signedness of the
chunk of memory being accessed.
Inductive memory_chunk : Type :=
| Mint8signed : memory_chunk
| Mint8unsigned : memory_chunk
| Mint16signed : memory_chunk
| Mint16unsigned : memory_chunk
| Mint32 : memory_chunk
.
The type (integer/pointer or float) of a chunk.
Definition type_of_chunk (c: memory_chunk) : typ :=
match c with
| Mint8signed => Tint
| Mint8unsigned => Tint
| Mint16signed => Tint
| Mint16unsigned => Tint
| Mint32 => Tint
end.
Initialization data for global variables.
Inductive init_data: Type :=
| Init_int8: int -> init_data
| Init_int16: int -> init_data
| Init_int32: int -> init_data
| Init_space: Z -> init_data
| Init_addrof: ident -> int -> init_data.
Information attached to global variables.
Record globvar (V: Type) : Type := mkglobvar {
gvar_info: V;
gvar_init: list init_data;
gvar_readonly: bool;
gvar_volatile: bool
}.
Whole programs consist of:
- a collection of global definitions (name and description);
- the name of the ``main'' function that serves as entry point in the program.
Inductive globdef (F V: Type) : Type :=
| Gfun (f: F)
| Gvar (v: globvar V).
Implicit Arguments Gfun [F V].
Implicit Arguments Gvar [F V].
Generic transformations over programs
Section TRANSF_PROGRAM.
Variable A B V: Type.
Variable transf: A -> B.
Definition transform_program_globdef (idg: ident * globdef A V) : ident * globdef B V :=
match idg with
| (id, Gfun f) => (id, Gfun (transf f))
| (id, Gvar v) => (id, Gvar v)
end.
End TRANSF_PROGRAM.
The following is a more general presentation of transform_program where
global variable information can be transformed, in addition to function
definitions. Moreover, the transformation functions can fail and
return an error message.
Open Local Scope error_monad_scope.
Open Local Scope string_scope.
Section TRANSF_PROGRAM_GEN.
Variables A B V W: Type.
Variable transf_fun: A -> res B.
Variable transf_var: V -> res W.
Definition transf_globvar (g: globvar V) : res (globvar W) :=
do info' <- transf_var g.(gvar_info);
OK (mkglobvar info' g.(gvar_init) g.(gvar_readonly) g.(gvar_volatile)).
Fixpoint transf_globdefs (l: list (ident * globdef A V)) : res (list (ident * globdef B W)) :=
match l with
| nil => OK nil
| (id, Gfun f) :: l' =>
match transf_fun f with
| Error msg => Error (MSG "In function " :: CTX id :: MSG ": " :: msg)
| OK tf =>
do tl' <- transf_globdefs l'; OK ((id, Gfun tf) :: tl')
end
| (id, Gvar v) :: l' =>
match transf_globvar v with
| Error msg => Error (MSG "In variable " :: CTX id :: MSG ": " :: msg)
| OK tv =>
do tl' <- transf_globdefs l'; OK ((id, Gvar tv) :: tl')
end
end.
End TRANSF_PROGRAM_GEN.
The following is a relational presentation of
transform_partial_augment_preogram. Given relations between function
definitions and between variable information, it defines a relation
between programs stating that the two programs have appropriately related
shapes (global names are preserved and possibly augmented, etc)
and that identically-named function definitions
and variable information are related.
Section MATCH_PROGRAM.
Variable A B V W: Type.
Variable match_fundef: A -> B -> Prop.
Variable match_varinfo: V -> W -> Prop.
Inductive match_globdef: ident * globdef A V -> ident * globdef B W -> Prop :=
| match_glob_fun: forall id f1 f2,
match_fundef f1 f2 ->
match_globdef (id, Gfun f1) (id, Gfun f2)
| match_glob_var: forall id init ro vo info1 info2,
match_varinfo info1 info2 ->
match_globdef (id, Gvar (mkglobvar info1 init ro vo)) (id, Gvar (mkglobvar info2 init ro vo)).
End MATCH_PROGRAM.
Function definitions are the union of internal and external functions.
Inductive fundef (G F: Type): Type :=
| Internal: F -> fundef G F
| External: G -> fundef G F.
Implicit Arguments Internal [F G].
Implicit Arguments External [F G].
Section TRANSF_FUNDEF.
Variable G A B: Type.
Variable transf: A -> B.
Definition transf_fundef (fd: fundef G A): fundef G B :=
match fd with
| Internal f => Internal (transf f)
| External ef => External ef
end.
End TRANSF_FUNDEF.
Section TRANSF_PARTIAL_FUNDEF.
Variable G A B: Type.
Variable transf_partial: A -> res B.
Definition transf_partial_fundef (fd: fundef G A): res (fundef G B) :=
match fd with
| Internal f => do f' <- transf_partial f; OK (Internal f')
| External ef => OK (External ef)
end.
End TRANSF_PARTIAL_FUNDEF.