wenzelm@27340
|
1 |
(* Title: Pure/ML/ml_antiquote.ML
|
wenzelm@27340
|
2 |
Author: Makarius
|
wenzelm@27340
|
3 |
|
wenzelm@27340
|
4 |
Common ML antiquotations.
|
wenzelm@27340
|
5 |
*)
|
wenzelm@27340
|
6 |
|
wenzelm@27340
|
7 |
signature ML_ANTIQUOTE =
|
wenzelm@27340
|
8 |
sig
|
wenzelm@27340
|
9 |
val variant: string -> Proof.context -> string * Proof.context
|
wenzelm@44446
|
10 |
val macro: binding -> Proof.context context_parser -> theory -> theory
|
wenzelm@44446
|
11 |
val inline: binding -> string context_parser -> theory -> theory
|
wenzelm@44446
|
12 |
val declaration: string -> binding -> string context_parser -> theory -> theory
|
wenzelm@44446
|
13 |
val value: binding -> string context_parser -> theory -> theory
|
wenzelm@27340
|
14 |
end;
|
wenzelm@27340
|
15 |
|
wenzelm@27340
|
16 |
structure ML_Antiquote: ML_ANTIQUOTE =
|
wenzelm@27340
|
17 |
struct
|
wenzelm@27340
|
18 |
|
wenzelm@27340
|
19 |
(** generic tools **)
|
wenzelm@27340
|
20 |
|
wenzelm@27340
|
21 |
(* ML names *)
|
wenzelm@27340
|
22 |
|
wenzelm@37216
|
23 |
structure Names = Proof_Data
|
wenzelm@27340
|
24 |
(
|
wenzelm@27340
|
25 |
type T = Name.context;
|
wenzelm@27340
|
26 |
fun init _ = ML_Syntax.reserved;
|
wenzelm@27340
|
27 |
);
|
wenzelm@27340
|
28 |
|
wenzelm@27340
|
29 |
fun variant a ctxt =
|
wenzelm@27340
|
30 |
let
|
wenzelm@37216
|
31 |
val names = Names.get ctxt;
|
wenzelm@44208
|
32 |
val (b, names') = Name.variant a names;
|
wenzelm@37216
|
33 |
val ctxt' = Names.put names' ctxt;
|
wenzelm@27340
|
34 |
in (b, ctxt') end;
|
wenzelm@27340
|
35 |
|
wenzelm@27340
|
36 |
|
wenzelm@27340
|
37 |
(* specific antiquotations *)
|
wenzelm@27340
|
38 |
|
wenzelm@27379
|
39 |
fun macro name scan = ML_Context.add_antiq name
|
wenzelm@27868
|
40 |
(fn _ => scan :|-- (fn ctxt => Scan.depend (fn _ => Scan.succeed
|
wenzelm@35019
|
41 |
(Context.Proof ctxt, fn background => (K ("", ""), background)))));
|
wenzelm@27379
|
42 |
|
wenzelm@27340
|
43 |
fun inline name scan = ML_Context.add_antiq name
|
wenzelm@35019
|
44 |
(fn _ => scan >> (fn s => fn background => (K ("", s), background)));
|
wenzelm@27340
|
45 |
|
wenzelm@27340
|
46 |
fun declaration kind name scan = ML_Context.add_antiq name
|
wenzelm@35019
|
47 |
(fn _ => scan >> (fn s => fn background =>
|
wenzelm@27340
|
48 |
let
|
wenzelm@44446
|
49 |
val (a, background') =
|
wenzelm@44446
|
50 |
variant (translate_string (fn "." => "_" | c => c) (Binding.name_of name)) background;
|
wenzelm@27340
|
51 |
val env = kind ^ " " ^ a ^ " = " ^ s ^ ";\n";
|
wenzelm@41734
|
52 |
val body = "Isabelle." ^ a;
|
wenzelm@27340
|
53 |
in (K (env, body), background') end));
|
wenzelm@27340
|
54 |
|
wenzelm@27340
|
55 |
val value = declaration "val";
|
wenzelm@27340
|
56 |
|
wenzelm@27340
|
57 |
|
wenzelm@27340
|
58 |
|
wenzelm@30231
|
59 |
(** misc antiquotations **)
|
wenzelm@27340
|
60 |
|
wenzelm@44446
|
61 |
val _ = Context.>> (Context.map_theory
|
wenzelm@40369
|
62 |
|
wenzelm@44446
|
63 |
(inline (Binding.name "assert")
|
wenzelm@44446
|
64 |
(Scan.succeed "(fn b => if b then () else raise General.Fail \"Assertion failed\")") #>
|
wenzelm@36162
|
65 |
|
wenzelm@44446
|
66 |
inline (Binding.name "make_string") (Scan.succeed ml_make_string) #>
|
wenzelm@27340
|
67 |
|
wenzelm@44446
|
68 |
value (Binding.name "binding")
|
wenzelm@47836
|
69 |
(Scan.lift (Parse.position Args.name) >> ML_Syntax.make_binding) #>
|
wenzelm@27340
|
70 |
|
wenzelm@44446
|
71 |
value (Binding.name "theory")
|
wenzelm@44446
|
72 |
(Scan.lift Args.name >> (fn name =>
|
wenzelm@44446
|
73 |
"Context.get_theory (ML_Context.the_global_context ()) " ^ ML_Syntax.print_string name)
|
wenzelm@44446
|
74 |
|| Scan.succeed "ML_Context.the_global_context ()") #>
|
wenzelm@27340
|
75 |
|
wenzelm@44446
|
76 |
value (Binding.name "context") (Scan.succeed "ML_Context.the_local_context ()") #>
|
wenzelm@27340
|
77 |
|
wenzelm@44446
|
78 |
inline (Binding.name "typ") (Args.typ >> (ML_Syntax.atomic o ML_Syntax.print_typ)) #>
|
wenzelm@44446
|
79 |
inline (Binding.name "term") (Args.term >> (ML_Syntax.atomic o ML_Syntax.print_term)) #>
|
wenzelm@44446
|
80 |
inline (Binding.name "prop") (Args.prop >> (ML_Syntax.atomic o ML_Syntax.print_term)) #>
|
wenzelm@27379
|
81 |
|
wenzelm@44446
|
82 |
macro (Binding.name "let")
|
wenzelm@44446
|
83 |
(Args.context --
|
wenzelm@44446
|
84 |
Scan.lift
|
wenzelm@44446
|
85 |
(Parse.and_list1 (Parse.and_list1 Args.name_source -- (Args.$$$ "=" |-- Args.name_source)))
|
wenzelm@44446
|
86 |
>> (fn (ctxt, args) => #2 (Proof_Context.match_bind true args ctxt))) #>
|
wenzelm@27379
|
87 |
|
wenzelm@44446
|
88 |
macro (Binding.name "note")
|
wenzelm@44446
|
89 |
(Args.context :|-- (fn ctxt =>
|
wenzelm@44446
|
90 |
Parse.and_list1' (Scan.lift (Args.opt_thm_name I "=") -- Attrib.thms
|
wenzelm@44446
|
91 |
>> (fn ((a, srcs), ths) =>
|
wenzelm@44446
|
92 |
((a, map (Attrib.attribute (Proof_Context.theory_of ctxt)) srcs), [(ths, [])])))
|
wenzelm@44446
|
93 |
>> (fn args => #2 (Proof_Context.note_thmss "" args ctxt)))) #>
|
wenzelm@27340
|
94 |
|
wenzelm@44446
|
95 |
value (Binding.name "ctyp") (Args.typ >> (fn T =>
|
wenzelm@44446
|
96 |
"Thm.ctyp_of (ML_Context.the_global_context ()) " ^ ML_Syntax.atomic (ML_Syntax.print_typ T))) #>
|
wenzelm@27340
|
97 |
|
wenzelm@44446
|
98 |
value (Binding.name "cterm") (Args.term >> (fn t =>
|
wenzelm@47836
|
99 |
"Thm.cterm_of (ML_Context.the_global_context ()) " ^ ML_Syntax.atomic (ML_Syntax.print_term t))) #>
|
wenzelm@27340
|
100 |
|
wenzelm@44446
|
101 |
value (Binding.name "cprop") (Args.prop >> (fn t =>
|
wenzelm@47836
|
102 |
"Thm.cterm_of (ML_Context.the_global_context ()) " ^ ML_Syntax.atomic (ML_Syntax.print_term t))) #>
|
wenzelm@44446
|
103 |
|
wenzelm@44446
|
104 |
value (Binding.name "cpat")
|
wenzelm@44446
|
105 |
(Args.context --
|
wenzelm@44446
|
106 |
Scan.lift Args.name_source >> uncurry Proof_Context.read_term_pattern >> (fn t =>
|
wenzelm@44446
|
107 |
"Thm.cterm_of (ML_Context.the_global_context ()) " ^
|
wenzelm@44446
|
108 |
ML_Syntax.atomic (ML_Syntax.print_term t)))));
|
wenzelm@27340
|
109 |
|
wenzelm@27340
|
110 |
|
wenzelm@35396
|
111 |
(* type classes *)
|
wenzelm@35396
|
112 |
|
wenzelm@35677
|
113 |
fun class syn = Args.context -- Scan.lift Args.name_source >> (fn (ctxt, s) =>
|
wenzelm@43231
|
114 |
Proof_Context.read_class ctxt s
|
wenzelm@43162
|
115 |
|> syn ? Lexicon.mark_class
|
wenzelm@35396
|
116 |
|> ML_Syntax.print_string);
|
wenzelm@35396
|
117 |
|
wenzelm@44446
|
118 |
val _ = Context.>> (Context.map_theory
|
wenzelm@44446
|
119 |
(inline (Binding.name "class") (class false) #>
|
wenzelm@44446
|
120 |
inline (Binding.name "class_syntax") (class true) #>
|
wenzelm@35396
|
121 |
|
wenzelm@44446
|
122 |
inline (Binding.name "sort")
|
wenzelm@44446
|
123 |
(Args.context -- Scan.lift Args.name_source >> (fn (ctxt, s) =>
|
wenzelm@44446
|
124 |
ML_Syntax.atomic (ML_Syntax.print_sort (Syntax.read_sort ctxt s))))));
|
wenzelm@35396
|
125 |
|
wenzelm@35396
|
126 |
|
wenzelm@35361
|
127 |
(* type constructors *)
|
wenzelm@27340
|
128 |
|
wenzelm@36950
|
129 |
fun type_name kind check = Args.context -- Scan.lift (Parse.position Args.name_source)
|
wenzelm@35401
|
130 |
>> (fn (ctxt, (s, pos)) =>
|
wenzelm@35401
|
131 |
let
|
wenzelm@43231
|
132 |
val Type (c, _) = Proof_Context.read_type_name_proper ctxt false s;
|
wenzelm@43339
|
133 |
val decl = Type.the_decl (Proof_Context.tsig_of ctxt) (c, pos);
|
wenzelm@35401
|
134 |
val res =
|
wenzelm@35401
|
135 |
(case try check (c, decl) of
|
wenzelm@35401
|
136 |
SOME res => res
|
wenzelm@35401
|
137 |
| NONE => error ("Not a " ^ kind ^ ": " ^ quote c ^ Position.str_of pos));
|
wenzelm@35401
|
138 |
in ML_Syntax.print_string res end);
|
wenzelm@27340
|
139 |
|
wenzelm@44446
|
140 |
val _ = Context.>> (Context.map_theory
|
wenzelm@44446
|
141 |
(inline (Binding.name "type_name")
|
wenzelm@44446
|
142 |
(type_name "logical type" (fn (c, Type.LogicalType _) => c)) #>
|
wenzelm@44446
|
143 |
inline (Binding.name "type_abbrev")
|
wenzelm@44446
|
144 |
(type_name "type abbreviation" (fn (c, Type.Abbreviation _) => c)) #>
|
wenzelm@44446
|
145 |
inline (Binding.name "nonterminal")
|
wenzelm@44446
|
146 |
(type_name "nonterminal" (fn (c, Type.Nonterminal) => c)) #>
|
wenzelm@44446
|
147 |
inline (Binding.name "type_syntax")
|
wenzelm@44446
|
148 |
(type_name "type" (fn (c, _) => Lexicon.mark_type c))));
|
wenzelm@35361
|
149 |
|
wenzelm@35361
|
150 |
|
wenzelm@35361
|
151 |
(* constants *)
|
wenzelm@27340
|
152 |
|
wenzelm@36950
|
153 |
fun const_name check = Args.context -- Scan.lift (Parse.position Args.name_source)
|
wenzelm@35401
|
154 |
>> (fn (ctxt, (s, pos)) =>
|
wenzelm@35401
|
155 |
let
|
wenzelm@43231
|
156 |
val Const (c, _) = Proof_Context.read_const_proper ctxt false s;
|
wenzelm@43231
|
157 |
val res = check (Proof_Context.consts_of ctxt, c)
|
wenzelm@35401
|
158 |
handle TYPE (msg, _, _) => error (msg ^ Position.str_of pos);
|
wenzelm@35401
|
159 |
in ML_Syntax.print_string res end);
|
wenzelm@27340
|
160 |
|
wenzelm@44446
|
161 |
val _ = Context.>> (Context.map_theory
|
wenzelm@44446
|
162 |
(inline (Binding.name "const_name")
|
wenzelm@44702
|
163 |
(const_name (fn (consts, c) => (Consts.the_const consts c; c))) #>
|
wenzelm@44446
|
164 |
inline (Binding.name "const_abbrev")
|
wenzelm@44446
|
165 |
(const_name (fn (consts, c) => (Consts.the_abbreviation consts c; c))) #>
|
wenzelm@44446
|
166 |
inline (Binding.name "const_syntax")
|
wenzelm@44446
|
167 |
(const_name (fn (_, c) => Lexicon.mark_const c)) #>
|
wenzelm@35401
|
168 |
|
wenzelm@44446
|
169 |
inline (Binding.name "syntax_const")
|
wenzelm@44446
|
170 |
(Args.context -- Scan.lift (Parse.position Args.name) >> (fn (ctxt, (c, pos)) =>
|
wenzelm@44446
|
171 |
if is_some (Syntax.lookup_const (Proof_Context.syn_of ctxt) c)
|
wenzelm@44446
|
172 |
then ML_Syntax.print_string c
|
wenzelm@44446
|
173 |
else error ("Unknown syntax const: " ^ quote c ^ Position.str_of pos))) #>
|
wenzelm@35401
|
174 |
|
wenzelm@44446
|
175 |
inline (Binding.name "const")
|
wenzelm@44446
|
176 |
(Args.context -- Scan.lift Args.name_source -- Scan.optional
|
wenzelm@44446
|
177 |
(Scan.lift (Args.$$$ "(") |-- Parse.enum1' "," Args.typ --| Scan.lift (Args.$$$ ")")) []
|
wenzelm@44446
|
178 |
>> (fn ((ctxt, raw_c), Ts) =>
|
wenzelm@44446
|
179 |
let
|
wenzelm@44446
|
180 |
val Const (c, _) = Proof_Context.read_const_proper ctxt true raw_c;
|
wenzelm@44446
|
181 |
val const = Const (c, Consts.instance (Proof_Context.consts_of ctxt) (c, Ts));
|
wenzelm@44446
|
182 |
in ML_Syntax.atomic (ML_Syntax.print_term const) end))));
|
wenzelm@27340
|
183 |
|
wenzelm@47822
|
184 |
|
wenzelm@47822
|
185 |
(* outer syntax *)
|
wenzelm@47822
|
186 |
|
wenzelm@47836
|
187 |
fun with_keyword f =
|
wenzelm@47836
|
188 |
Args.theory -- Scan.lift (Parse.position Parse.string) >> (fn (thy, (name, pos)) =>
|
wenzelm@47836
|
189 |
(f (name, Thy_Header.the_keyword thy name)
|
wenzelm@47836
|
190 |
handle ERROR msg => error (msg ^ Position.str_of pos)));
|
wenzelm@47836
|
191 |
|
wenzelm@47822
|
192 |
val _ = Context.>> (Context.map_theory
|
wenzelm@47836
|
193 |
(value (Binding.name "keyword")
|
wenzelm@47836
|
194 |
(with_keyword
|
wenzelm@47836
|
195 |
(fn (name, NONE) => "Parse.$$$ " ^ ML_Syntax.print_string name
|
wenzelm@47836
|
196 |
| (name, SOME _) => error ("Expected minor keyword " ^ quote name))) #>
|
wenzelm@47836
|
197 |
value (Binding.name "command_spec")
|
wenzelm@47836
|
198 |
(with_keyword
|
wenzelm@47836
|
199 |
(fn (name, SOME kind) =>
|
wenzelm@47836
|
200 |
"Keyword.command_spec " ^ ML_Syntax.atomic
|
wenzelm@47836
|
201 |
(ML_Syntax.print_pair ML_Syntax.print_string
|
wenzelm@47836
|
202 |
(ML_Syntax.print_pair ML_Syntax.print_string
|
wenzelm@47836
|
203 |
(ML_Syntax.print_list ML_Syntax.print_string)) (name, kind))
|
wenzelm@47836
|
204 |
| (name, NONE) => error ("Expected command keyword " ^ quote name)))));
|
wenzelm@47822
|
205 |
|
wenzelm@27340
|
206 |
end;
|
wenzelm@27340
|
207 |
|