"code" attribute is now managed by basic code generator module.
authorberghofe
Thu, 20 Dec 2001 14:57:15 +0100
changeset 12555e6d7f040fdc7
parent 12554 671b4d632c34
child 12556 5e2593ef0a44
"code" attribute is now managed by basic code generator module.
src/Pure/codegen.ML
     1.1 --- a/src/Pure/codegen.ML	Thu Dec 20 14:55:28 2001 +0100
     1.2 +++ b/src/Pure/codegen.ML	Thu Dec 20 14:57:15 2001 +0100
     1.3 @@ -21,6 +21,7 @@
     1.4  
     1.5    val add_codegen: string -> term codegen -> theory -> theory
     1.6    val add_tycodegen: string -> typ codegen -> theory -> theory
     1.7 +  val add_attribute: string -> theory attribute -> theory -> theory
     1.8    val print_codegens: theory -> unit
     1.9    val generate_code: theory -> (string * string) list -> string
    1.10    val generate_code_i: theory -> (string * term) list -> string
    1.11 @@ -90,18 +91,24 @@
    1.12      {codegens : (string * term codegen) list,
    1.13       tycodegens : (string * typ codegen) list,
    1.14       consts : ((string * typ) * term mixfix list) list,
    1.15 -     types : (string * typ mixfix list) list};
    1.16 +     types : (string * typ mixfix list) list,
    1.17 +     attrs: (string * theory attribute) list};
    1.18  
    1.19 -  val empty = {codegens = [], tycodegens = [], consts = [], types = []};
    1.20 +  val empty =
    1.21 +    {codegens = [], tycodegens = [], consts = [], types = [], attrs = []};
    1.22    val copy = I;
    1.23    val prep_ext = I;
    1.24  
    1.25 -  fun merge ({codegens = codegens1, tycodegens = tycodegens1, consts = consts1, types = types1},
    1.26 -             {codegens = codegens2, tycodegens = tycodegens2, consts = consts2, types = types2}) =
    1.27 +  fun merge
    1.28 +    ({codegens = codegens1, tycodegens = tycodegens1,
    1.29 +      consts = consts1, types = types1, attrs = attrs1},
    1.30 +     {codegens = codegens2, tycodegens = tycodegens2,
    1.31 +      consts = consts2, types = types2, attrs = attrs2}) =
    1.32      {codegens = rev (merge_alists (rev codegens1) (rev codegens2)),
    1.33       tycodegens = rev (merge_alists (rev tycodegens1) (rev tycodegens2)),
    1.34 -     consts   = merge_alists consts1 consts2,
    1.35 -     types    = merge_alists types1 types2};
    1.36 +     consts = merge_alists consts1 consts2,
    1.37 +     types = merge_alists types1 types2,
    1.38 +     attrs = merge_alists attrs1 attrs2};
    1.39  
    1.40    fun print sg ({codegens, tycodegens, ...} : T) =
    1.41      Pretty.writeln (Pretty.chunks
    1.42 @@ -116,28 +123,48 @@
    1.43  (**** add new code generators to theory ****)
    1.44  
    1.45  fun add_codegen name f thy =
    1.46 -  let val {codegens, tycodegens, consts, types} = CodegenData.get thy
    1.47 +  let val {codegens, tycodegens, consts, types, attrs} = CodegenData.get thy
    1.48    in (case assoc (codegens, name) of
    1.49        None => CodegenData.put {codegens = (name, f) :: codegens,
    1.50 -        tycodegens = tycodegens, consts = consts, types = types} thy
    1.51 +        tycodegens = tycodegens, consts = consts, types = types,
    1.52 +        attrs = attrs} thy
    1.53      | Some _ => error ("Code generator " ^ name ^ " already declared"))
    1.54    end;
    1.55  
    1.56  fun add_tycodegen name f thy =
    1.57 -  let val {codegens, tycodegens, consts, types} = CodegenData.get thy
    1.58 +  let val {codegens, tycodegens, consts, types, attrs} = CodegenData.get thy
    1.59    in (case assoc (tycodegens, name) of
    1.60        None => CodegenData.put {tycodegens = (name, f) :: tycodegens,
    1.61 -        codegens = codegens, consts = consts, types = types} thy
    1.62 +        codegens = codegens, consts = consts, types = types,
    1.63 +        attrs = attrs} thy
    1.64      | Some _ => error ("Code generator " ^ name ^ " already declared"))
    1.65    end;
    1.66  
    1.67  
    1.68 +(**** code attribute ****)
    1.69 +
    1.70 +fun add_attribute name att thy =
    1.71 +  let val {codegens, tycodegens, consts, types, attrs} = CodegenData.get thy
    1.72 +  in (case assoc (attrs, name) of
    1.73 +      None => CodegenData.put {tycodegens = tycodegens,
    1.74 +        codegens = codegens, consts = consts, types = types,
    1.75 +        attrs = (name, att) :: attrs} thy
    1.76 +    | Some _ => error ("Code attribute " ^ name ^ " already declared"))
    1.77 +  end;
    1.78 +
    1.79 +val code_attr =
    1.80 +  Attrib.syntax (Scan.depend (fn thy => Scan.optional Args.name "" >>
    1.81 +    (fn name => (thy, case assoc (#attrs (CodegenData.get thy), name) of
    1.82 +          None => error ("Unknown code attribute: " ^ quote name)
    1.83 +        | Some att => att)))); 
    1.84 +
    1.85 +
    1.86  (**** associate constants with target language code ****)
    1.87  
    1.88  fun gen_assoc_consts prep_type xs thy = foldl (fn (thy, (s, tyopt, syn)) =>
    1.89    let
    1.90      val sg = sign_of thy;
    1.91 -    val {codegens, tycodegens, consts, types} = CodegenData.get thy;
    1.92 +    val {codegens, tycodegens, consts, types, attrs} = CodegenData.get thy;
    1.93      val cname = Sign.intern_const sg s;
    1.94    in
    1.95      (case Sign.const_type sg cname of
    1.96 @@ -152,7 +179,8 @@
    1.97           in (case assoc (consts, (cname, T')) of
    1.98               None => CodegenData.put {codegens = codegens,
    1.99                 tycodegens = tycodegens,
   1.100 -               consts = ((cname, T'), syn) :: consts, types = types} thy
   1.101 +               consts = ((cname, T'), syn) :: consts,
   1.102 +               types = types, attrs = attrs} thy
   1.103             | Some _ => error ("Constant " ^ cname ^ " already associated with code"))
   1.104           end
   1.105       | _ => error ("Not a constant: " ^ s))
   1.106 @@ -165,13 +193,13 @@
   1.107  
   1.108  fun assoc_types xs thy = foldl (fn (thy, (s, syn)) =>
   1.109    let
   1.110 -    val {codegens, tycodegens, consts, types} = CodegenData.get thy;
   1.111 +    val {codegens, tycodegens, consts, types, attrs} = CodegenData.get thy;
   1.112      val tc = Sign.intern_tycon (sign_of thy) s
   1.113    in
   1.114      (case assoc (types, tc) of
   1.115         None => CodegenData.put {codegens = codegens,
   1.116           tycodegens = tycodegens, consts = consts,
   1.117 -         types = (tc, syn) :: types} thy
   1.118 +         types = (tc, syn) :: types, attrs = attrs} thy
   1.119       | Some _ => error ("Type " ^ tc ^ " already associated with code"))
   1.120    end) (thy, xs);
   1.121  
   1.122 @@ -212,7 +240,8 @@
   1.123      val (xs as x::_) = explode (rename (space_implode "_"
   1.124        (NameSpace.unpack (Sign.cond_extern sg kind s))));
   1.125      fun check_str [] = ""
   1.126 -      | check_str (x::xs) =
   1.127 +      | check_str (" " :: xs) = "_" ^ check_str xs
   1.128 +      | check_str (x :: xs) =
   1.129            (if Symbol.is_letter x orelse Symbol.is_digit x orelse x="_" then x
   1.130             else "_" ^ string_of_int (ord x)) ^ check_str xs
   1.131    in
   1.132 @@ -462,7 +491,10 @@
   1.133    [CodegenData.init,
   1.134     add_codegen "default" default_codegen,
   1.135     add_tycodegen "default" default_tycodegen,
   1.136 -   assoc_types [("fun", parse_mixfix (K dummyT) "(_ ->/ _)")]];
   1.137 +   assoc_types [("fun", parse_mixfix (K dummyT) "(_ ->/ _)")],
   1.138 +   Attrib.add_attributes [("code",
   1.139 +     (code_attr, K Attrib.undef_local_attribute),
   1.140 +     "declare theorems for code generation")]];
   1.141  
   1.142  end;
   1.143