11 val the_local_context: unit -> Proof.context |
11 val the_local_context: unit -> Proof.context |
12 val thm: xstring -> thm |
12 val thm: xstring -> thm |
13 val thms: xstring -> thm list |
13 val thms: xstring -> thm list |
14 val exec: (unit -> unit) -> Context.generic -> Context.generic |
14 val exec: (unit -> unit) -> Context.generic -> Context.generic |
15 val check_antiquotation: Proof.context -> xstring * Position.T -> string |
15 val check_antiquotation: Proof.context -> xstring * Position.T -> string |
|
16 val struct_name: Proof.context -> string |
16 val variant: string -> Proof.context -> string * Proof.context |
17 val variant: string -> Proof.context -> string * Proof.context |
17 type decl = Proof.context -> string * string |
18 type decl = Proof.context -> string * string |
18 val value_decl: string -> string -> Proof.context -> decl * Proof.context |
19 val value_decl: string -> string -> Proof.context -> decl * Proof.context |
19 val add_antiquotation: binding -> (Token.src -> Proof.context -> decl * Proof.context) -> |
20 val add_antiquotation: binding -> (Token.src -> Proof.context -> decl * Proof.context) -> |
20 theory -> theory |
21 theory -> theory |
21 val print_antiquotations: Proof.context -> unit |
22 val print_antiquotations: Proof.context -> unit |
22 val eval_antiquotes: ML_Lex.token Antiquote.antiquote list * Position.T -> |
|
23 Context.generic option -> (ML_Lex.token list * ML_Lex.token list) * Context.generic option |
|
24 val eval: ML_Compiler.flags -> Position.T -> ML_Lex.token Antiquote.antiquote list -> unit |
23 val eval: ML_Compiler.flags -> Position.T -> ML_Lex.token Antiquote.antiquote list -> unit |
25 val eval_file: ML_Compiler.flags -> Path.T -> unit |
24 val eval_file: ML_Compiler.flags -> Path.T -> unit |
26 val eval_source: ML_Compiler.flags -> Input.source -> unit |
25 val eval_source: ML_Compiler.flags -> Input.source -> unit |
27 val eval_in: Proof.context option -> ML_Compiler.flags -> Position.T -> |
26 val eval_in: Proof.context option -> ML_Compiler.flags -> Position.T -> |
28 ML_Lex.token Antiquote.antiquote list -> unit |
27 ML_Lex.token Antiquote.antiquote list -> unit |
50 |
49 |
51 |
50 |
52 |
51 |
53 (** ML antiquotations **) |
52 (** ML antiquotations **) |
54 |
53 |
55 (* unique names *) |
54 (* names for generated environment *) |
56 |
55 |
57 structure Names = Proof_Data |
56 structure Names = Proof_Data |
58 ( |
57 ( |
59 type T = Name.context; |
58 type T = string * Name.context; |
60 val init_names = ML_Syntax.reserved |> fold Name.declare ["ML_context", "ML_print_depth"]; |
59 val init_names = ML_Syntax.reserved |> fold Name.declare ["ML_context", "ML_print_depth"]; |
61 fun init _ = init_names; |
60 fun init _ = ("Isabelle0", init_names); |
62 ); |
61 ); |
63 |
62 |
|
63 fun struct_name ctxt = #1 (Names.get ctxt); |
|
64 val struct_begin = (Names.map o apfst) (fn _ => "Isabelle" ^ serial_string ()); |
|
65 |
64 fun variant a ctxt = |
66 fun variant a ctxt = |
65 let |
67 let |
66 val names = Names.get ctxt; |
68 val names = #2 (Names.get ctxt); |
67 val (b, names') = Name.variant (Name.desymbolize (SOME false) a) names; |
69 val (b, names') = Name.variant (Name.desymbolize (SOME false) a) names; |
68 val ctxt' = Names.put names' ctxt; |
70 val ctxt' = (Names.map o apsnd) (K names') ctxt; |
69 in (b, ctxt') end; |
71 in (b, ctxt') end; |
70 |
72 |
71 |
73 |
72 (* decl *) |
74 (* decl *) |
73 |
75 |
116 |
118 |
117 val antiq = |
119 val antiq = |
118 Parse.!!! (Parse.position Parse.xname -- Parse.args --| Scan.ahead Parse.eof) |
120 Parse.!!! (Parse.position Parse.xname -- Parse.args --| Scan.ahead Parse.eof) |
119 >> uncurry Token.src; |
121 >> uncurry Token.src; |
120 |
122 |
121 val begin_env0 = ML_Lex.tokenize "structure Isabelle =\nstruct\n"; |
123 fun make_env name visible = |
122 |
124 (ML_Lex.tokenize |
123 fun begin_env visible = |
125 ("structure " ^ name ^ " =\nstruct\n\ |
124 ML_Lex.tokenize |
|
125 ("structure Isabelle =\nstruct\n\ |
|
126 \val ML_context = Context_Position.set_visible " ^ Bool.toString visible ^ |
126 \val ML_context = Context_Position.set_visible " ^ Bool.toString visible ^ |
127 " (ML_Context.the_local_context ());\n\ |
127 " (ML_Context.the_local_context ());\n\ |
128 \val ML_print_depth =\n\ |
128 \val ML_print_depth =\n\ |
129 \ let val default = ML_Options.get_print_depth ()\n\ |
129 \ let val default = ML_Options.get_print_depth ()\n\ |
130 \ in fn () => ML_Options.get_print_depth_default default end;\n"); |
130 \ in fn () => ML_Options.get_print_depth_default default end;\n"), |
131 |
131 ML_Lex.tokenize "end;"); |
132 val end_env = ML_Lex.tokenize "end;"; |
132 |
133 val reset_env = ML_Lex.tokenize "structure Isabelle = struct end"; |
133 fun reset_env name = ML_Lex.tokenize ("structure " ^ name ^ " = struct end"); |
134 |
134 |
135 fun expanding (Antiquote.Text tok) = ML_Lex.is_cartouche tok |
135 fun expanding (Antiquote.Text tok) = ML_Lex.is_cartouche tok |
136 | expanding (Antiquote.Antiq _) = true; |
136 | expanding (Antiquote.Antiq _) = true; |
137 |
|
138 in |
|
139 |
137 |
140 fun eval_antiquotes (ants, pos) opt_context = |
138 fun eval_antiquotes (ants, pos) opt_context = |
141 let |
139 let |
142 val visible = |
140 val visible = |
143 (case opt_context of |
141 (case opt_context of |
144 SOME (Context.Proof ctxt) => Context_Position.is_visible ctxt |
142 SOME (Context.Proof ctxt) => Context_Position.is_visible ctxt |
145 | _ => true); |
143 | _ => true); |
146 val opt_ctxt = Option.map (Context.Proof o Context.proof_of) opt_context; |
144 val opt_ctxt = Option.map Context.proof_of opt_context; |
147 |
145 |
148 val ((ml_env, ml_body), opt_ctxt') = |
146 val ((ml_env, ml_body), opt_ctxt') = |
149 if forall (not o expanding) ants |
147 if forall (not o expanding) ants |
150 then ((begin_env0, map (fn Antiquote.Text tok => tok) ants), opt_ctxt) |
148 then (([], map (fn Antiquote.Text tok => tok) ants), opt_ctxt) |
151 else |
149 else |
152 let |
150 let |
153 fun tokenize range = apply2 (ML_Lex.tokenize #> map (ML_Lex.set_range range)); |
151 fun tokenize range = apply2 (ML_Lex.tokenize #> map (ML_Lex.set_range range)); |
154 |
152 |
155 fun expand (Antiquote.Antiq (ss, {range, ...})) ctxt = |
153 fun expand (Antiquote.Antiq (ss, {range, ...})) ctxt = |
174 else (K ([], [tok]), ctxt); |
172 else (K ([], [tok]), ctxt); |
175 |
173 |
176 val ctxt = |
174 val ctxt = |
177 (case opt_ctxt of |
175 (case opt_ctxt of |
178 NONE => error ("No context -- cannot expand ML antiquotations" ^ Position.here pos) |
176 NONE => error ("No context -- cannot expand ML antiquotations" ^ Position.here pos) |
179 | SOME ctxt => Context.proof_of ctxt); |
177 | SOME ctxt => struct_begin ctxt); |
180 |
178 |
|
179 val (begin_env, end_env) = make_env (struct_name ctxt) visible; |
181 val (decls, ctxt') = fold_map expand ants ctxt; |
180 val (decls, ctxt') = fold_map expand ants ctxt; |
182 val (ml_env, ml_body) = |
181 val (ml_env, ml_body) = |
183 decls |> map (fn decl => decl ctxt') |> split_list |> apply2 flat; |
182 decls |> map (fn decl => decl ctxt') |> split_list |> apply2 flat; |
184 in ((begin_env visible @ ml_env, ml_body), SOME (Context.Proof ctxt')) end; |
183 in ((begin_env @ ml_env @ end_env, ml_body), SOME ctxt') end; |
185 in ((ml_env @ end_env, ml_body), opt_ctxt') end; |
184 in ((ml_env, ml_body), opt_ctxt') end; |
|
185 |
|
186 in |
186 |
187 |
187 fun eval flags pos ants = |
188 fun eval flags pos ants = |
188 let |
189 let |
189 val non_verbose = ML_Compiler.verbose false flags; |
190 val non_verbose = ML_Compiler.verbose false flags; |
190 |
191 |
191 (*prepare source text*) |
192 (*prepare source text*) |
192 val ((env, body), env_ctxt) = eval_antiquotes (ants, pos) (Context.thread_data ()); |
193 val ((env, body), env_ctxt) = eval_antiquotes (ants, pos) (Context.thread_data ()); |
193 val _ = |
194 val _ = |
194 (case Option.map Context.proof_of env_ctxt of |
195 (case env_ctxt of |
195 SOME ctxt => |
196 SOME ctxt => |
196 if Config.get ctxt ML_Options.source_trace andalso Context_Position.is_visible ctxt |
197 if Config.get ctxt ML_Options.source_trace andalso Context_Position.is_visible ctxt |
197 then tracing (cat_lines [ML_Lex.flatten env, ML_Lex.flatten body]) |
198 then tracing (cat_lines [ML_Lex.flatten env, ML_Lex.flatten body]) |
198 else () |
199 else () |
199 | NONE => ()); |
200 | NONE => ()); |
200 |
201 |
201 (*prepare static ML environment*) |
202 (*prepare environment*) |
202 val _ = |
203 val _ = |
203 Context.setmp_thread_data |
204 Context.setmp_thread_data |
204 (Option.map (Context.mapping I (Context_Position.set_visible false)) env_ctxt) |
205 (Option.map (Context.Proof o Context_Position.set_visible false) env_ctxt) |
205 (fn () => (ML_Compiler.eval non_verbose Position.none env; Context.thread_data ())) () |
206 (fn () => (ML_Compiler.eval non_verbose Position.none env; Context.thread_data ())) () |
206 |> (fn NONE => () | SOME context' => Context.>> (ML_Env.inherit context')); |
207 |> (fn NONE => () | SOME context' => Context.>> (ML_Env.inherit context')); |
207 |
208 |
|
209 (*eval body*) |
208 val _ = ML_Compiler.eval flags pos body; |
210 val _ = ML_Compiler.eval flags pos body; |
209 val _ = ML_Compiler.eval non_verbose Position.none reset_env; |
211 |
|
212 (*clear environment*) |
|
213 val _ = |
|
214 (case (env_ctxt, is_some (Context.thread_data ())) of |
|
215 (SOME ctxt, true) => |
|
216 let |
|
217 val name = struct_name ctxt; |
|
218 val _ = ML_Compiler.eval non_verbose Position.none (reset_env name); |
|
219 val _ = Context.>> (ML_Env.forget_structure name); |
|
220 in () end |
|
221 | _ => ()); |
210 in () end; |
222 in () end; |
211 |
223 |
212 end; |
224 end; |
213 |
225 |
214 |
226 |