src/Pure/ML/ml_antiquotation.ML
author wenzelm
Thu, 23 Jan 2025 22:19:30 +0100
changeset 81960 326ecfc079a6
parent 78804 d4e9d6b7f48d
permissions -rw-r--r--
support for @{instantiate (no_beta) ...};
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
56072
31e427387ab5 tuned signature -- clarified module name;
wenzelm
parents: 56071
diff changeset
     1
(*  Title:      Pure/ML/ml_antiquotation.ML
27340
3de9f20f4e28 Common ML antiquotations.
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
3de9f20f4e28 Common ML antiquotations.
wenzelm
parents:
diff changeset
     3
56205
ceb8a93460b7 clarified modules;
wenzelm
parents: 56072
diff changeset
     4
ML antiquotations.
27340
3de9f20f4e28 Common ML antiquotations.
wenzelm
parents:
diff changeset
     5
*)
3de9f20f4e28 Common ML antiquotations.
wenzelm
parents:
diff changeset
     6
56072
31e427387ab5 tuned signature -- clarified module name;
wenzelm
parents: 56071
diff changeset
     7
signature ML_ANTIQUOTATION =
27340
3de9f20f4e28 Common ML antiquotations.
wenzelm
parents:
diff changeset
     8
sig
73549
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
     9
  val value_decl: string -> string -> Proof.context ->
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    10
    (Proof.context -> string * string) * Proof.context
56205
ceb8a93460b7 clarified modules;
wenzelm
parents: 56072
diff changeset
    11
  val declaration: binding -> 'a context_parser ->
73549
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    12
    (Token.src -> 'a -> Proof.context -> (Proof.context -> string * string) * Proof.context) ->
56205
ceb8a93460b7 clarified modules;
wenzelm
parents: 56072
diff changeset
    13
    theory -> theory
69592
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    14
  val declaration_embedded: binding -> 'a context_parser ->
73549
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    15
    (Token.src -> 'a -> Proof.context -> (Proof.context -> string * string) * Proof.context) ->
69592
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    16
    theory -> theory
43560
d1650e3720fd ML antiquotations are managed as theory data, with proper name space and entity markup;
wenzelm
parents: 43326
diff changeset
    17
  val inline: binding -> string context_parser -> theory -> theory
69592
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    18
  val inline_embedded: binding -> string context_parser -> theory -> theory
43560
d1650e3720fd ML antiquotations are managed as theory data, with proper name space and entity markup;
wenzelm
parents: 43326
diff changeset
    19
  val value: binding -> string context_parser -> theory -> theory
69592
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    20
  val value_embedded: binding -> string context_parser -> theory -> theory
78701
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    21
  val special_form: binding ->
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    22
    (Proof.context -> Input.source -> string * ML_Lex.token Antiquote.antiquote list list) ->
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    23
    theory -> theory
73586
76d0b6597c91 support for conditional ML text;
wenzelm
parents: 73551
diff changeset
    24
  val conditional: binding -> (Proof.context -> bool) -> theory -> theory
27340
3de9f20f4e28 Common ML antiquotations.
wenzelm
parents:
diff changeset
    25
end;
3de9f20f4e28 Common ML antiquotations.
wenzelm
parents:
diff changeset
    26
56072
31e427387ab5 tuned signature -- clarified module name;
wenzelm
parents: 56071
diff changeset
    27
structure ML_Antiquotation: ML_ANTIQUOTATION =
27340
3de9f20f4e28 Common ML antiquotations.
wenzelm
parents:
diff changeset
    28
struct
3de9f20f4e28 Common ML antiquotations.
wenzelm
parents:
diff changeset
    29
56205
ceb8a93460b7 clarified modules;
wenzelm
parents: 56072
diff changeset
    30
(* define antiquotations *)
ceb8a93460b7 clarified modules;
wenzelm
parents: 56072
diff changeset
    31
73549
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    32
fun value_decl a s ctxt =
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    33
  let
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    34
    val (b, ctxt') = ML_Context.variant a ctxt;
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    35
    val env = "val " ^ b ^ " = " ^ s ^ ";\n";
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    36
    val body = ML_Context.struct_name ctxt ^ "." ^ b;
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    37
    fun decl (_: Proof.context) = (env, body);
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    38
  in (decl, ctxt') end;
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    39
69592
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    40
local
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    41
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    42
fun gen_declaration name embedded scan body =
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    43
  ML_Context.add_antiquotation name embedded
73549
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    44
    (fn range => fn src => fn orig_ctxt =>
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    45
      let
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    46
        val (x, _) = Token.syntax scan src orig_ctxt;
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    47
        val (decl, ctxt') = body src x orig_ctxt;
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    48
      in (decl #> apply2 (ML_Lex.tokenize_range range), ctxt') end);
27340
3de9f20f4e28 Common ML antiquotations.
wenzelm
parents:
diff changeset
    49
69592
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    50
fun gen_inline name embedded scan =
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    51
  gen_declaration name embedded scan (fn _ => fn s => fn ctxt => (K ("", s), ctxt));
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    52
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    53
fun gen_value name embedded scan =
73549
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
    54
  gen_declaration name embedded scan (fn _ => value_decl (Binding.name_of name));
69592
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    55
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    56
in
27340
3de9f20f4e28 Common ML antiquotations.
wenzelm
parents:
diff changeset
    57
69592
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    58
fun declaration name = gen_declaration name false;
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    59
fun declaration_embedded name = gen_declaration name true;
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    60
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    61
fun inline name = gen_inline name false;
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    62
fun inline_embedded name = gen_inline name true;
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    63
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    64
fun value name = gen_value name false;
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    65
fun value_embedded name = gen_value name true;
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    66
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
    67
end;
27340
3de9f20f4e28 Common ML antiquotations.
wenzelm
parents:
diff changeset
    68
3de9f20f4e28 Common ML antiquotations.
wenzelm
parents:
diff changeset
    69
73586
76d0b6597c91 support for conditional ML text;
wenzelm
parents: 73551
diff changeset
    70
(* ML macros *)
73550
2f6855142a8c support for ML special forms: modified evaluation similar to Scheme;
wenzelm
parents: 73549
diff changeset
    71
78701
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    72
fun special_form binding parse =
78804
d4e9d6b7f48d clarified signature;
wenzelm
parents: 78701
diff changeset
    73
  ML_Context.add_antiquotation_embedded binding
d4e9d6b7f48d clarified signature;
wenzelm
parents: 78701
diff changeset
    74
    (fn _ => fn input => fn ctxt =>
73550
2f6855142a8c support for ML special forms: modified evaluation similar to Scheme;
wenzelm
parents: 73549
diff changeset
    75
      let
74291
b83fa8f3a271 ML antiquotations for type constructors and term constants;
wenzelm
parents: 73586
diff changeset
    76
        val tokenize = ML_Lex.tokenize_no_range;
78701
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    77
        val tokenize_range = ML_Lex.tokenize_range (Input.range_of input);
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    78
        val eq = tokenize " = ";
73551
53c148e39819 proper treatment of nested antiquotations;
wenzelm
parents: 73550
diff changeset
    79
78701
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    80
        val (operator, sections) = parse ctxt input;
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    81
        val (decls, ctxt') = ML_Context.expand_antiquotes_list sections ctxt;
73551
53c148e39819 proper treatment of nested antiquotations;
wenzelm
parents: 73550
diff changeset
    82
        fun decl' ctxt'' =
73550
2f6855142a8c support for ML special forms: modified evaluation similar to Scheme;
wenzelm
parents: 73549
diff changeset
    83
          let
78701
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    84
            val (sections_env, sections_body) = split_list (decls ctxt'');
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    85
            val sections_bind =
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    86
              sections_body |> map_index (fn (i, body) =>
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    87
                let
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    88
                  val name = tokenize ("expr" ^ (if i = 0 then "" else string_of_int i));
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    89
                  val bind = if i = 0 then tokenize "val " else tokenize "and ";
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    90
                in (bind @ name @ eq @ body, name) end);
73551
53c148e39819 proper treatment of nested antiquotations;
wenzelm
parents: 73550
diff changeset
    91
            val ml_body' =
78701
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    92
              tokenize "let " @ maps #1 sections_bind @
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    93
              tokenize " val " @ tokenize_range "result" @ eq @
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    94
              tokenize operator @ maps #2 sections_bind @ tokenize " in result end";
c7b2697094ac more general ML_Antiquotation.special_form;
wenzelm
parents: 78690
diff changeset
    95
          in (flat sections_env, ml_body') end;
73551
53c148e39819 proper treatment of nested antiquotations;
wenzelm
parents: 73550
diff changeset
    96
      in (decl', ctxt') end);
73550
2f6855142a8c support for ML special forms: modified evaluation similar to Scheme;
wenzelm
parents: 73549
diff changeset
    97
73586
76d0b6597c91 support for conditional ML text;
wenzelm
parents: 73551
diff changeset
    98
fun conditional binding check =
78804
d4e9d6b7f48d clarified signature;
wenzelm
parents: 78701
diff changeset
    99
  ML_Context.add_antiquotation_embedded binding
d4e9d6b7f48d clarified signature;
wenzelm
parents: 78701
diff changeset
   100
    (fn _ => fn input => fn ctxt =>
d4e9d6b7f48d clarified signature;
wenzelm
parents: 78701
diff changeset
   101
      if check ctxt then ML_Context.read_antiquotes input ctxt
d4e9d6b7f48d clarified signature;
wenzelm
parents: 78701
diff changeset
   102
      else (K ([], []), ctxt));
73586
76d0b6597c91 support for conditional ML text;
wenzelm
parents: 73551
diff changeset
   103
73550
2f6855142a8c support for ML special forms: modified evaluation similar to Scheme;
wenzelm
parents: 73549
diff changeset
   104
56205
ceb8a93460b7 clarified modules;
wenzelm
parents: 56072
diff changeset
   105
(* basic antiquotations *)
27340
3de9f20f4e28 Common ML antiquotations.
wenzelm
parents:
diff changeset
   106
53171
a5e54d4d9081 added Theory.setup convenience;
wenzelm
parents: 53170
diff changeset
   107
val _ = Theory.setup
64556
851ae0e7b09c more symbols;
wenzelm
parents: 62900
diff changeset
   108
 (declaration (Binding.make ("here", \<^here>)) (Scan.succeed ())
59112
e670969f34df expand ML cartouches to Input.source;
wenzelm
parents: 58011
diff changeset
   109
    (fn src => fn () =>
73549
a2c589d5e1e4 clarified signature: more detailed token positions for antiquotations;
wenzelm
parents: 69592
diff changeset
   110
      value_decl "position" (ML_Syntax.print_position (#2 (Token.name_of_src src)))) #>
56071
2ffdedb0c044 added ML antiquotation @{here};
wenzelm
parents: 56069
diff changeset
   111
64556
851ae0e7b09c more symbols;
wenzelm
parents: 62900
diff changeset
   112
  inline (Binding.make ("make_string", \<^here>)) (Args.context >> K ML_Pretty.make_string_fn) #>
62662
291cc01f56f5 @{make_string} is available during Pure bootstrap;
wenzelm
parents: 59112
diff changeset
   113
69592
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
   114
  value_embedded (Binding.make ("binding", \<^here>))
74563
042041c0ebeb clarified modules;
wenzelm
parents: 74291
diff changeset
   115
    (Scan.lift Parse.embedded_input >> (ML_Syntax.make_binding o Input.source_content)) #>
62850
1f1a2c33ccf4 clarified conditional compilation;
wenzelm
parents: 62662
diff changeset
   116
69592
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
   117
  value_embedded (Binding.make ("cartouche", \<^here>))
62850
1f1a2c33ccf4 clarified conditional compilation;
wenzelm
parents: 62662
diff changeset
   118
    (Scan.lift Args.cartouche_input >> (fn source =>
1f1a2c33ccf4 clarified conditional compilation;
wenzelm
parents: 62662
diff changeset
   119
      "Input.source true " ^ ML_Syntax.print_string (Input.text_of source) ^ " " ^
69470
c8c3285f1294 more ML antiquotations;
wenzelm
parents: 69349
diff changeset
   120
        ML_Syntax.atomic (ML_Syntax.print_range (Input.range_of source)))) #>
c8c3285f1294 more ML antiquotations;
wenzelm
parents: 69349
diff changeset
   121
69592
a80d8ec6c998 support for isabelle update -u control_cartouches;
wenzelm
parents: 69470
diff changeset
   122
  inline_embedded (Binding.make ("verbatim", \<^here>))
74563
042041c0ebeb clarified modules;
wenzelm
parents: 74291
diff changeset
   123
    (Scan.lift Parse.embedded >> ML_Syntax.print_string));
46948
aae5566d6756 added ML antiquotation @{keyword};
wenzelm
parents: 43794
diff changeset
   124
27340
3de9f20f4e28 Common ML antiquotations.
wenzelm
parents:
diff changeset
   125
end;