lh-l4v/tools/c-parser/name_generation.ML

261 lines
8.1 KiB
Standard ML

(*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: BSD-2-Clause
*)
signature NAME_GENERATION =
sig
val initialisation_function : string
val return_var_name : int Absyn.ctype -> MString.t
val embret_var_name : string * int -> MString.t
val dest_embret : MString.t -> (string * int) option
val C_global_var : MString.t -> MString.t
val global_var : string -> string
val global_addr : string -> string
val fake_param : string -> int -> string
val tag_name_with_type : {name: string, typname:string} -> string
val adglob_rcd_tyname : string
val adglob_struct_var : string
val naming_scheme_name : string
val enum_const_name : string -> string
val enum_const_summary_lemma_sfx : string
val untouched_global_name : MString.t -> MString.t
val global_initializer_name : MString.t -> MString.t
val global_data_name : string -> string
val global_rcd_name : string
val global_ext_type : string
val global_exn_var_name : string
val global_exn_var : string
val global_heap : string
val global_heap_var : string
val local_rcd_name : string
val C_struct_name : string -> string
val unC_struct_name : string -> string
val C_field_name : string -> string
val unC_field_name : string -> string
val internalAnonStructPfx : string
val mkAnonStructName : int -> string
val mkIdentUScoreSafe : string -> string
val rmUScoreSafety : string -> string
val apt_string : string -> string
val gensym : string -> string
val numCopyN : string
val phantom_state_name : string
val ghost_state_name : string
val owned_by_fn_name : string
val mk_localstatic : {fname : string, vname : string } -> MString.t
end;
(*
[initialisation_function] is the name of the implicit initialisation
function responsible for initialising global variables.
[return_var_name ty] is the 'name' of the variable that stands for a
function's return value, given the type of the value returned by the
function.
[tag_name_with_type {name,typname}] combines the two strings to create
a new variable name. Used when two local variables are requested and
have different types. (The Hoare environment can't cope with this, so
one or both variables need to pick up new names.)
[embret_var_name(f,i)] is the name of the variable that stands for
the ith return value from a function f that is called while embedded
in some expression.
[dest_embret s] returns SOME(f,i) if embret_var_name(f,i) = s, NONE
if there is no such f and i.
[global_var s] translates a global variable to an Isabelle variable
name. Note that the only variables so treated are special Hoare
environments like the heap, and the well-typedness environment -
there aren't any C global variables treated this way.
[C_global_var s] translates a C global variable name.
[global_addr s] translates a global C variable name into the name of an
Isabelle constant that will hold that variable's address in the heap.
[fake_param s i] gives a name for a parameter based on the name of the
function and the number of the parameter in the list.
[adglob_rcd_tyname] is the name of the C struct type that
contains the global variables that are addressed.
[adglob_rcd_addr] is the name of the Isabelle variable (it will be a
locale parameter) containing the address of the addressed globals
struct in the heap.
[enum_const_name s] gives back the Isabelle name of the constant
that will correspond to the enumeration constant s.
[enum_const_summary_lemma_sfx] is the suffix appended to the name of
an enumeration type to generate the name of the lemma that lists all
of the definitions for that type's constants.
[global_heap_var] is the name of the global variable corresponding to
the program's heap, which will be of type (addr -> byte x heap_typ_desc).
This includes both components in the same variable to provide serialisation
of updates.
[global_rcd_name] is the name of the record type that stores the
program's global variables. May need to be turned into a fully-qualified
name through the use of Sign.intern_tycon
[global_ext_type] is similar, but gives the type name suitable for
axiomatic type class instantiation.
[local_rcd_name] is the name of the (polymorphic) record type that
contains all the local variables, and is an extension of the
StateSpace.state record type.
[global_exn_var_name] is the name of the local variable that contains the
current type of exception (Break|Return|Continue).
[global_exn_var] is the name of the local variable accessor that gets the
current type of exception (Break|Return|Continue).
[C_struct_name s] "munges" the name s of a C struct type into a form
that is acceptable for the Isabelle verification.
[C_field_name s] "munges" the name s of a field in a C struct type
into a form that is acceptable for the Isabelle verification.
[apt_string] translates a term representing a term to one that will have
the _quote parse translation applied to it in read_cterm.
[gensym s] returns a string prefixed by s which hasn't been returned by
gensym before. It does this by appending a "_<n>" where <n> is the string
corresponding to a so-far unused integer.
*)
structure NameGeneration :> NAME_GENERATION =
struct
val initialisation_function = "___special___init"
fun embret_var_name (f,i) =
if i < 1 then raise Fail "embret_var_name: i < 1"
else if i = 1 then MString.mk ("ret__" ^ f)
else MString.mk (f ^ "_eret_" ^ Int.toString i)
fun dest_embret s0 =
let
val s = MString.dest s0
in
if String.isPrefix "ret__" s then
SOME (String.extract(s,5,NONE), 1)
else let
open Substring
val (pfx, digsfx) = splitr Char.isDigit (full s)
in
if isEmpty digsfx then NONE
else if isSuffix "_eret_" pfx then
SOME (string (trimr 6 pfx), valOf (Int.fromString (string digsfx)))
else
NONE
end
end
fun return_var_name ty = embret_var_name (Absyn.tyname ty, 1)
fun tag_name_with_type {name: string, typname:string} = name ^ "___" ^ typname
fun fake_param f i = f ^ "_param_" ^ Int.toString i
fun ext_type t = t ^ "_ext"
fun enum_const_name s = s
val enum_const_summary_lemma_sfx = "_defs"
fun fix_underscore s = if String.isPrefix "_" s
then "underscore" ^ s else s
fun untouched_global_name s =
s |> MString.dest |> fix_underscore |> MString.mk
fun global_initializer_name s =
fix_underscore (MString.dest s) ^ "_global_initializer" |> MString.mk
fun global_data_name s = fix_underscore s ^ "_global_data"
val global_rcd_name = "globals"
val global_ext_type = ext_type global_rcd_name
val global_exn_var_name = "global_exn_var"
val global_exn_var = global_exn_var_name ^ "_'"
val local_rcd_name = "myvars"
fun C_global_var s = s
fun global_var s = Hoare.varname s
fun global_addr s = s ^"_addr"
fun global_upd s = global_var s ^ "_upd"
val global_heap = "t_hrs"
val global_heap_var = global_var global_heap
fun apt_string s = "[.[" ^ s ^ "].]"
val gs_n = ref 1
fun gensym s = (s ^ "_" ^ Int.toString (!gs_n) before
gs_n := !gs_n + 1)
val numCopyN = "tyCopy"
fun C_struct_name s = s ^ "_C"
fun unC_struct_name s =
if String.isSuffix "_C" s then
String.extract(s,0,SOME(size s - 2))
else s
fun C_field_name s = s ^ "_C"
fun unC_field_name s =
if String.isSuffix "_C" s then
String.extract(s,0,SOME(size s - 2))
else s
val adglob_rcd_tyname = "adglobs_struct"
val adglob_struct_var = "adglobs"
val phantom_state_name = "phantom_machine_state"
val ghost_state_name = "ghost'state"
val naming_scheme_name = "\\" ^ "<Gamma>_naming"
val owned_by_fn_name = "owner'ship"
val internalAnonStructPfx = "ISA_anon_struct|"
fun mkAnonStructName i = "AnonStruct" ^ Int.toString i ^ "'"
(* mkIdentUScoreSafe is injective on identifiers that can be
generated by the lexer *)
val ussafe_pfx = "StrictC'"
fun mkIdentUScoreSafe s =
if String.sub(s, 0) = #"_" then ussafe_pfx^s
else s
fun rmUScoreSafety s =
if String.isPrefix ussafe_pfx s then
String.extract(s, String.size ussafe_pfx, NONE)
else s
fun mk_localstatic {fname, vname} =
MString.mk ("static'" ^ fname ^ "'" ^ vname)
end;