src/Pure/codegen.ML
changeset 14858 9fc1a5cf9b5a
parent 14818 ad83019a66a4
child 14886 b792081d2399
--- a/src/Pure/codegen.ML	Tue Jun 01 12:36:26 2004 +0200
+++ b/src/Pure/codegen.ML	Tue Jun 01 14:59:22 2004 +0200
@@ -36,6 +36,7 @@
     (exn option * string) Graph.T * term -> (exn option * string) Graph.T * Pretty.T
   val invoke_tycodegen: theory -> string -> bool ->
     (exn option * string) Graph.T * typ -> (exn option * string) Graph.T * Pretty.T
+  val mk_id: string -> string
   val mk_const_id: Sign.sg -> string -> string
   val mk_type_id: Sign.sg -> string -> string
   val rename_term: term -> term
@@ -273,34 +274,55 @@
 
 (**** make valid ML identifiers ****)
 
-fun gen_mk_id kind rename sg s =
+fun is_ascii_letdig x = Symbol.is_ascii_letter x orelse
+  Symbol.is_ascii_digit x orelse Symbol.is_ascii_quasi x;
+
+fun dest_sym s = (case split_last (snd (take_prefix (equal "\\") (explode s))) of
+    ("<" :: "^" :: xs, ">") => (true, implode xs)
+  | ("<" :: xs, ">") => (false, implode xs)
+  | _ => sys_error "dest_sym");
+  
+fun mk_id s = if s = "" then "" else
   let
-    val (xs as x::_) = explode (rename (space_implode "_"
-      (NameSpace.unpack (Sign.cond_extern sg kind s))));
-    fun check_str [] = ""
-      | check_str (" " :: xs) = "_" ^ check_str xs
-      | check_str (x :: xs) =
-          (if Symbol.is_letdig x then x
-           else "_" ^ string_of_int (ord x)) ^ check_str xs
+    fun check_str [] = []
+      | check_str xs = (case take_prefix is_ascii_letdig xs of
+          ([], " " :: zs) => check_str zs
+        | ([], "_" :: zs) => check_str zs
+        | ([], z :: zs) =>
+          if size z = 1 then string_of_int (ord z) :: check_str zs
+          else (case dest_sym z of
+              (true, "isub") => check_str zs
+            | (true, "isup") => "" :: check_str zs
+            | (ctrl, s') => (if ctrl then "ctrl_" ^ s' else s') :: check_str zs)
+        | (ys, zs) => implode ys :: check_str zs);
+    val s' = space_implode "_"
+      (flat (map (check_str o Symbol.explode) (NameSpace.unpack s)))
   in
-    (if not (Symbol.is_letter x) then "id" else "") ^ check_str xs
+    if Symbol.is_ascii_letter (hd (explode s')) then s' else "id_" ^ s'
   end;
 
-val mk_const_id = gen_mk_id Sign.constK
-  (fn s => if s mem ThmDatabase.ml_reserved then s ^ "_const" else s);
+fun mk_const_id sg s =
+  let val s' = mk_id (Sign.cond_extern sg Sign.constK s)
+  in if s' mem ThmDatabase.ml_reserved then s' ^ "_const" else s' end;
 
-val mk_type_id = gen_mk_id Sign.typeK
-  (fn s => if s mem ThmDatabase.ml_reserved then s ^ "_type" else s);
+fun mk_type_id sg s =
+  let val s' = mk_id (Sign.cond_extern sg Sign.typeK s)
+  in if s' mem ThmDatabase.ml_reserved then s' ^ "_type" else s' end;
 
 fun rename_terms ts =
   let
     val names = foldr add_term_names
       (ts, map (fst o fst) (Drule.vars_of_terms ts));
-    val clash = names inter ThmDatabase.ml_reserved;
-    val ps = clash ~~ variantlist (clash, names);
+    val reserved = names inter ThmDatabase.ml_reserved;
+    val (illegal, alt_names) = split_list (mapfilter (fn s =>
+      let val s' = mk_id s in if s = s' then None else Some (s, s') end) names)
+    val ps = (reserved @ illegal) ~~
+      variantlist (map (suffix "'") reserved @ alt_names, names);
 
-    fun rename (Var ((a, i), T)) = Var ((if_none (assoc (ps, a)) a, i), T)
-      | rename (Free (a, T)) = Free (if_none (assoc (ps, a)) a, T)
+    fun rename_id s = if_none (assoc (ps, s)) s;
+
+    fun rename (Var ((a, i), T)) = Var ((rename_id a, i), T)
+      | rename (Free (a, T)) = Free (rename_id a, T)
       | rename (Abs (s, T, t)) = Abs (s, T, rename t)
       | rename (t $ u) = rename t $ rename u
       | rename t = t;
@@ -387,7 +409,7 @@
          separate (Pretty.brk 1) (p :: ps) @ [Pretty.str ")"])
      else Pretty.block (separate (Pretty.brk 1) (p :: ps));
 
-fun new_names t xs = variantlist (xs,
+fun new_names t xs = variantlist (map mk_id xs,
   map (fst o fst o dest_Var) (term_vars t) union
   add_term_names (t, ThmDatabase.ml_reserved));