src/Tools/code/code_name.ML
changeset 30648 17365ef082f3
parent 30364 577edc39b501
child 31013 69a476d6fea6
equal deleted inserted replaced
30647:ef8f46c3158a 30648:17365ef082f3
     4 Some code generator infrastructure concerning names.
     4 Some code generator infrastructure concerning names.
     5 *)
     5 *)
     6 
     6 
     7 signature CODE_NAME =
     7 signature CODE_NAME =
     8 sig
     8 sig
     9   structure StringPairTab: TABLE
       
    10   val first_upper: string -> string
       
    11   val first_lower: string -> string
       
    12   val dest_name: string -> string * string
       
    13 
       
    14   val purify_var: string -> string
     9   val purify_var: string -> string
    15   val purify_tvar: string -> string
    10   val purify_tvar: string -> string
    16   val purify_sym: string -> string
    11   val purify_base: string -> string
    17   val purify_base: bool -> string -> string
       
    18   val check_modulename: string -> string
    12   val check_modulename: string -> string
    19 
    13 
    20   type var_ctxt
       
    21   val make_vars: string list -> var_ctxt
       
    22   val intro_vars: string list -> var_ctxt -> var_ctxt
       
    23   val lookup_var: var_ctxt -> string -> string
       
    24 
       
    25   val read_const_exprs: theory -> string list -> string list * string list
    14   val read_const_exprs: theory -> string list -> string list * string list
    26   val mk_name_module: Name.context -> string option -> (string -> string option)
       
    27     -> 'a Graph.T -> string -> string
       
    28 end;
    15 end;
    29 
    16 
    30 structure Code_Name: CODE_NAME =
    17 structure Code_Name: CODE_NAME =
    31 struct
    18 struct
    32 
    19 
    33 (** auxiliary **)
       
    34 
       
    35 structure StringPairTab =
       
    36   TableFun(type key = string * string val ord = prod_ord fast_string_ord fast_string_ord);
       
    37 
       
    38 val first_upper = implode o nth_map 0 Symbol.to_ascii_upper o explode;
       
    39 val first_lower = implode o nth_map 0 Symbol.to_ascii_lower o explode;
       
    40 
       
    41 val dest_name =
       
    42   apfst Long_Name.implode o split_last o fst o split_last o Long_Name.explode;
       
    43 
       
    44 
       
    45 (** purification **)
    20 (** purification **)
    46 
    21 
    47 fun purify_name upper lower =
    22 fun purify_name upper =
    48   let
    23   let
    49     fun is_valid s = Symbol.is_ascii_letter s orelse Symbol.is_ascii_digit s orelse s = "'";
    24     fun is_valid s = Symbol.is_ascii_letter s orelse Symbol.is_ascii_digit s orelse s = "'";
    50     val is_junk = not o is_valid andf Symbol.is_regular;
    25     val is_junk = not o is_valid andf Symbol.is_regular;
    51     val junk = Scan.many is_junk;
    26     val junk = Scan.many is_junk;
    52     val scan_valids = Symbol.scanner "Malformed input"
    27     val scan_valids = Symbol.scanner "Malformed input"
    53       ((junk |--
    28       ((junk |--
    54         (Scan.optional (Scan.one Symbol.is_ascii_letter) "x" ^^ (Scan.many is_valid >> implode)
    29         (Scan.optional (Scan.one Symbol.is_ascii_letter) "x" ^^ (Scan.many is_valid >> implode)
    55         --| junk))
    30         --| junk))
    56       ::: Scan.repeat ((Scan.many1 is_valid >> implode) --| junk));
    31       ::: Scan.repeat ((Scan.many1 is_valid >> implode) --| junk));
    57     fun upper_lower cs = if upper then nth_map 0 Symbol.to_ascii_upper cs
    32     fun upper_lower cs = if upper then nth_map 0 Symbol.to_ascii_upper cs
    58       else if lower then (if forall Symbol.is_ascii_upper cs
    33       else (if forall Symbol.is_ascii_upper cs
    59         then map else nth_map 0) Symbol.to_ascii_lower cs
    34         then map else nth_map 0) Symbol.to_ascii_lower cs;
    60       else cs;
       
    61   in
    35   in
    62     explode
    36     explode
    63     #> scan_valids
    37     #> scan_valids
    64     #> space_implode "_"
    38     #> space_implode "_"
    65     #> explode
    39     #> explode
    66     #> upper_lower
    40     #> upper_lower
    67     #> implode
    41     #> implode
    68   end;
    42   end;
    69 
    43 
    70 fun purify_var "" = "x"
    44 fun purify_var "" = "x"
    71   | purify_var v = purify_name false true v;
    45   | purify_var v = purify_name false v;
    72 
    46 
    73 fun purify_tvar "" = "'a"
    47 fun purify_tvar "" = "'a"
    74   | purify_tvar v =
    48   | purify_tvar v =
    75       (unprefix "'" #> explode #> filter Symbol.is_ascii_letter #> cons "'" #> implode) v;
    49       (unprefix "'" #> explode #> filter Symbol.is_ascii_letter #> cons "'" #> implode) v;
    76 
    50 
    79   (*FIMXE should disappear as soon as hierarchical theory name spaces are available*)
    53   (*FIMXE should disappear as soon as hierarchical theory name spaces are available*)
    80   #> Symbol.scanner "Malformed name"
    54   #> Symbol.scanner "Malformed name"
    81       (Scan.repeat ($$ "_" |-- $$ "_" >> (fn _ => ".") || Scan.one Symbol.is_regular))
    55       (Scan.repeat ($$ "_" |-- $$ "_" >> (fn _ => ".") || Scan.one Symbol.is_regular))
    82   #> implode
    56   #> implode
    83   #> Long_Name.explode
    57   #> Long_Name.explode
    84   #> map (purify_name true false);
    58   #> map (purify_name true);
    85 
    59 
    86 (*FIMXE non-canonical function treating non-canonical names*)
    60 (*FIMXE non-canonical function treating non-canonical names*)
    87 fun purify_base _ "op &" = "and"
    61 fun purify_base "op &" = "and"
    88   | purify_base _ "op |" = "or"
    62   | purify_base "op |" = "or"
    89   | purify_base _ "op -->" = "implies"
    63   | purify_base "op -->" = "implies"
    90   | purify_base _ "{}" = "empty"
    64   | purify_base "op :" = "member"
    91   | purify_base _ "op :" = "member"
    65   | purify_base "*" = "product"
    92   | purify_base _ "op Int" = "intersect"
    66   | purify_base "+" = "sum"
    93   | purify_base _ "op Un" = "union"
    67   | purify_base s = if String.isPrefix "op =" s
    94   | purify_base _ "*" = "product"
    68       then "eq" ^ purify_name false s
    95   | purify_base _ "+" = "sum"
    69       else purify_name false s;
    96   | purify_base lower s = if String.isPrefix "op =" s
       
    97       then "eq" ^ purify_name false lower s
       
    98       else purify_name false lower s;
       
    99 
       
   100 val purify_sym = purify_base false;
       
   101 
    70 
   102 fun check_modulename mn =
    71 fun check_modulename mn =
   103   let
    72   let
   104     val mns = Long_Name.explode mn;
    73     val mns = Long_Name.explode mn;
   105     val mns' = map (purify_name true false) mns;
    74     val mns' = map (purify_name true) mns;
   106   in
    75   in
   107     if mns' = mns then mn else error ("Invalid module name: " ^ quote mn ^ "\n"
    76     if mns' = mns then mn else error ("Invalid module name: " ^ quote mn ^ "\n"
   108       ^ "perhaps try " ^ quote (Long_Name.implode mns'))
    77       ^ "perhaps try " ^ quote (Long_Name.implode mns'))
   109   end;
    78   end;
   110 
       
   111 
       
   112 (** variable name contexts **)
       
   113 
       
   114 type var_ctxt = string Symtab.table * Name.context;
       
   115 
       
   116 fun make_vars names = (fold (fn name => Symtab.update_new (name, name)) names Symtab.empty,
       
   117   Name.make_context names);
       
   118 
       
   119 fun intro_vars names (namemap, namectxt) =
       
   120   let
       
   121     val (names', namectxt') = Name.variants names namectxt;
       
   122     val namemap' = fold2 (curry Symtab.update) names names' namemap;
       
   123   in (namemap', namectxt') end;
       
   124 
       
   125 fun lookup_var (namemap, _) name = case Symtab.lookup namemap name
       
   126  of SOME name' => name'
       
   127   | NONE => error ("Invalid name in context: " ^ quote name);
       
   128 
    79 
   129 
    80 
   130 (** misc **)
    81 (** misc **)
   131 
    82 
   132 fun read_const_exprs thy =
    83 fun read_const_exprs thy =
   148       | read_const_expr s = if String.isSuffix ".*" s
    99       | read_const_expr s = if String.isSuffix ".*" s
   149           then ([], consts_of (SOME (unsuffix ".*" s)))
   100           then ([], consts_of (SOME (unsuffix ".*" s)))
   150           else ([Code_Unit.read_const thy s], []);
   101           else ([Code_Unit.read_const thy s], []);
   151   in pairself flat o split_list o map read_const_expr end;
   102   in pairself flat o split_list o map read_const_expr end;
   152 
   103 
   153 fun mk_name_module reserved_names module_prefix module_alias program =
       
   154   let
       
   155     fun mk_alias name = case module_alias name
       
   156      of SOME name' => name'
       
   157       | NONE => name
       
   158           |> Long_Name.explode
       
   159           |> map (fn name => (the_single o fst) (Name.variants [name] reserved_names))
       
   160           |> Long_Name.implode;
       
   161     fun mk_prefix name = case module_prefix
       
   162      of SOME module_prefix => Long_Name.append module_prefix name
       
   163       | NONE => name;
       
   164     val tab =
       
   165       Symtab.empty
       
   166       |> Graph.fold ((fn name => Symtab.default (name, (mk_alias #> mk_prefix) name))
       
   167            o fst o dest_name o fst)
       
   168              program
       
   169   in the o Symtab.lookup tab end;
       
   170 
       
   171 end;
   104 end;