Common ML antiquotations.
authorwenzelm
Tue, 24 Jun 2008 19:43:16 +0200
changeset 273403de9f20f4e28
parent 27339 07194f87f9d0
child 27341 97e2ccba3b64
Common ML antiquotations.
src/Pure/ML/ml_antiquote.ML
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/Pure/ML/ml_antiquote.ML	Tue Jun 24 19:43:16 2008 +0200
     1.3 @@ -0,0 +1,154 @@
     1.4 +(*  Title:      Pure/ML/ml_antiquote.ML
     1.5 +    ID:         $Id$
     1.6 +    Author:     Makarius
     1.7 +
     1.8 +Common ML antiquotations.
     1.9 +*)
    1.10 +
    1.11 +signature ML_ANTIQUOTE =
    1.12 +sig
    1.13 +  val variant: string -> Proof.context -> string * Proof.context
    1.14 +  val inline: string ->
    1.15 +    (Context.generic * Args.T list -> string * (Context.generic * Args.T list)) -> unit
    1.16 +  val declaration: string -> string ->
    1.17 +    (Context.generic * Args.T list -> string * (Context.generic * Args.T list)) -> unit
    1.18 +  val value: string ->
    1.19 +    (Context.generic * Args.T list -> string * (Context.generic * Args.T list)) -> unit
    1.20 +  val the_thms: Proof.context -> int -> thm list
    1.21 +  val the_thm: Proof.context -> int -> thm
    1.22 +end;
    1.23 +
    1.24 +structure ML_Antiquote: ML_ANTIQUOTE =
    1.25 +struct
    1.26 +
    1.27 +(** generic tools **)
    1.28 +
    1.29 +(* ML names *)
    1.30 +
    1.31 +structure NamesData = ProofDataFun
    1.32 +(
    1.33 +  type T = Name.context;
    1.34 +  fun init _ = ML_Syntax.reserved;
    1.35 +);
    1.36 +
    1.37 +fun variant a ctxt =
    1.38 +  let
    1.39 +    val names = NamesData.get ctxt;
    1.40 +    val ([b], names') = Name.variants [a] names;
    1.41 +    val ctxt' = NamesData.put names' ctxt;
    1.42 +  in (b, ctxt') end;
    1.43 +
    1.44 +
    1.45 +(* specific antiquotations *)
    1.46 +
    1.47 +fun inline name scan = ML_Context.add_antiq name
    1.48 +  (scan >> (fn s => fn {struct_name, background} => ((K ("", s)), background)));
    1.49 +
    1.50 +fun declaration kind name scan = ML_Context.add_antiq name
    1.51 +  (scan >> (fn s => fn {struct_name, background} =>
    1.52 +    let
    1.53 +      val (a, background') = variant name background;
    1.54 +      val env = kind ^ " " ^ a ^ " = " ^ s ^ ";\n";
    1.55 +      val body = struct_name ^ "." ^ a;
    1.56 +    in (K (env, body), background') end));
    1.57 +
    1.58 +val value = declaration "val";
    1.59 +
    1.60 +
    1.61 +
    1.62 +(** concrete antiquotations **)
    1.63 +
    1.64 +fun context x = (Scan.state >> Context.proof_of) x;
    1.65 +
    1.66 +
    1.67 +(* misc *)
    1.68 +
    1.69 +val _ = value "theory"
    1.70 +  (Scan.lift Args.name >> (fn name => "ThyInfo.get_theory " ^ ML_Syntax.print_string name)
    1.71 +  || Scan.succeed "ML_Context.the_global_context ()");
    1.72 +
    1.73 +val _ = value "theory_ref"
    1.74 +  (Scan.lift Args.name >> (fn name =>
    1.75 +    "Theory.check_thy (ThyInfo.theory " ^ ML_Syntax.print_string name ^ ")")
    1.76 +  || Scan.succeed "Theory.check_thy (ML_Context.the_global_context ())");
    1.77 +
    1.78 +val _ = value "context" (Scan.succeed "ML_Context.the_local_context ()");
    1.79 +
    1.80 +val _ = inline "sort" (context -- Scan.lift Args.name >> (fn (ctxt, s) =>
    1.81 +  ML_Syntax.atomic (ML_Syntax.print_sort (Syntax.read_sort ctxt s))));
    1.82 +
    1.83 +val _ = inline "typ" (Args.typ >> (ML_Syntax.atomic o ML_Syntax.print_typ));
    1.84 +val _ = inline "term" (Args.term >> (ML_Syntax.atomic o ML_Syntax.print_term));
    1.85 +val _ = inline "prop" (Args.prop >> (ML_Syntax.atomic o ML_Syntax.print_term));
    1.86 +
    1.87 +val _ = value "ctyp" (Args.typ >> (fn T =>
    1.88 +  "Thm.ctyp_of (ML_Context.the_global_context ()) " ^ ML_Syntax.atomic (ML_Syntax.print_typ T)));
    1.89 +
    1.90 +val _ = value "cterm" (Args.term >> (fn t =>
    1.91 +  "Thm.cterm_of (ML_Context.the_global_context ()) " ^ ML_Syntax.atomic (ML_Syntax.print_term t)));
    1.92 +
    1.93 +val _ = value "cprop" (Args.prop >> (fn t =>
    1.94 +  "Thm.cterm_of (ML_Context.the_global_context ()) " ^ ML_Syntax.atomic (ML_Syntax.print_term t)));
    1.95 +
    1.96 +val _ = value "cpat"
    1.97 +  (context -- Scan.lift Args.name >> uncurry ProofContext.read_term_pattern >> (fn t =>
    1.98 +    "Thm.cterm_of (ML_Context.the_global_context ()) " ^ ML_Syntax.atomic (ML_Syntax.print_term t)));
    1.99 +
   1.100 +
   1.101 +fun type_ syn = (context -- Scan.lift Args.name >> (fn (ctxt, c) =>
   1.102 +    #1 (Term.dest_Type (ProofContext.read_tyname ctxt c))
   1.103 +    |> syn ? Sign.base_name
   1.104 +    |> ML_Syntax.print_string));
   1.105 +
   1.106 +val _ = inline "type_name" (type_ false);
   1.107 +val _ = inline "type_syntax" (type_ true);
   1.108 +
   1.109 +
   1.110 +fun const syn = context -- Scan.lift Args.name >> (fn (ctxt, c) =>
   1.111 +  #1 (Term.dest_Const (ProofContext.read_const_proper ctxt c))
   1.112 +  |> syn ? ProofContext.const_syntax_name ctxt
   1.113 +  |> ML_Syntax.print_string);
   1.114 +
   1.115 +val _ = inline "const_name" (const false);
   1.116 +val _ = inline "const_syntax" (const true);
   1.117 +
   1.118 +val _ = inline "const"
   1.119 +  (context -- Scan.lift Args.name --
   1.120 +    Scan.optional (Scan.lift (Args.$$$ "(") |-- Args.enum1 "," Args.typ --| Scan.lift (Args.$$$ ")")) []
   1.121 +    >> (fn ((ctxt, c), Ts) =>
   1.122 +      let val (c, _) = Term.dest_Const (ProofContext.read_const_proper ctxt c)
   1.123 +      in ML_Syntax.atomic (ML_Syntax.print_term (ProofContext.mk_const ctxt (c, Ts))) end));
   1.124 +
   1.125 +
   1.126 +(* abstract fact values *)
   1.127 +
   1.128 +val _ = ML_Context.add_keywords ["[", "]", "(", ")", "-", ","];   (* FIXME !? *)
   1.129 +
   1.130 +structure AuxFacts = ProofDataFun
   1.131 +(
   1.132 +  type T = thm list Inttab.table;
   1.133 +  fun init _ = Inttab.empty;
   1.134 +);
   1.135 +
   1.136 +fun the_thms ctxt name = the (Inttab.lookup (AuxFacts.get ctxt) name);
   1.137 +fun the_thm ctxt name = the_single (the_thms ctxt name);
   1.138 +
   1.139 +fun put_thms ths ctxt =
   1.140 +  let val i = serial ()
   1.141 +  in (i, AuxFacts.map (Inttab.update (i, ths)) ctxt) end;
   1.142 +
   1.143 +
   1.144 +fun thm_antiq kind scan = ML_Context.add_antiq kind
   1.145 +  (scan >> (fn ths => fn {struct_name, background} =>
   1.146 +    let
   1.147 +      val ((a, i), background') = background |> variant kind ||>> put_thms ths;
   1.148 +      val env = "val " ^ a ^ " = ML_Antiquote.the_" ^ kind ^
   1.149 +        " (ML_Context.the_local_context ()) " ^ string_of_int i ^ ";\n";
   1.150 +      val body = struct_name ^ "." ^ a;
   1.151 +    in (K (env, body), background') end));
   1.152 +
   1.153 +val _ = thm_antiq "thm" (Attrib.thm >> single);
   1.154 +val _ = thm_antiq "thms" Attrib.thms;
   1.155 +
   1.156 +end;
   1.157 +