src/Pure/ML/ml_context.ML
changeset 59127 723b11f8ffbf
parent 59112 e670969f34df
child 59917 9830c944670f
equal deleted inserted replaced
59126:ff0703716c51 59127:723b11f8ffbf
    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 
    75 
    77 
    76 fun value_decl a s ctxt =
    78 fun value_decl a s ctxt =
    77   let
    79   let
    78     val (b, ctxt') = variant a ctxt;
    80     val (b, ctxt') = variant a ctxt;
    79     val env = "val " ^ b ^ " = " ^ s ^ ";\n";
    81     val env = "val " ^ b ^ " = " ^ s ^ ";\n";
    80     val body = "Isabelle." ^ b;
    82     val body = struct_name ctxt ^ "." ^ b;
    81     fun decl (_: Proof.context) = (env, body);
    83     fun decl (_: Proof.context) = (env, body);
    82   in (decl, ctxt') end;
    84   in (decl, ctxt') end;
    83 
    85 
    84 
    86 
    85 (* theory data *)
    87 (* theory data *)
   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