src/Pure/Isar/runtime.ML
author wenzelm
Thu, 09 Sep 2010 17:20:27 +0200
changeset 39509 69c6d3e87660
parent 39201 c7a66b584147
child 39515 7189a138dd6c
permissions -rw-r--r--
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
wenzelm@31476
     1
(*  Title:      Pure/Isar/runtime.ML
wenzelm@31476
     2
    Author:     Makarius
wenzelm@31476
     3
wenzelm@31476
     4
Isar toplevel runtime support.
wenzelm@31476
     5
*)
wenzelm@31476
     6
wenzelm@31476
     7
signature RUNTIME =
wenzelm@31476
     8
sig
wenzelm@31476
     9
  exception UNDEF
wenzelm@31476
    10
  exception TERMINATE
wenzelm@31476
    11
  exception EXCURSION_FAIL of exn * string
wenzelm@31476
    12
  exception TOPLEVEL_ERROR
wenzelm@31476
    13
  val exn_context: Proof.context option -> exn -> exn
wenzelm@39200
    14
  val exn_messages: (exn -> Position.T) -> exn -> string list
wenzelm@31476
    15
  val exn_message: (exn -> Position.T) -> exn -> string
wenzelm@31476
    16
  val debugging: ('a -> 'b) -> 'a -> 'b
wenzelm@31476
    17
  val controlled_execution: ('a -> 'b) -> 'a -> 'b
wenzelm@33603
    18
  val toplevel_error: (exn -> unit) -> ('a -> 'b) -> 'a -> 'b
wenzelm@31476
    19
end;
wenzelm@31476
    20
wenzelm@31476
    21
structure Runtime: RUNTIME =
wenzelm@31476
    22
struct
wenzelm@31476
    23
wenzelm@31476
    24
(** exceptions **)
wenzelm@31476
    25
wenzelm@31476
    26
exception UNDEF;
wenzelm@31476
    27
exception TERMINATE;
wenzelm@31476
    28
exception EXCURSION_FAIL of exn * string;
wenzelm@31476
    29
exception TOPLEVEL_ERROR;
wenzelm@31476
    30
wenzelm@31476
    31
wenzelm@31476
    32
(* exn_context *)
wenzelm@31476
    33
wenzelm@31476
    34
exception CONTEXT of Proof.context * exn;
wenzelm@31476
    35
wenzelm@31476
    36
fun exn_context NONE exn = exn
wenzelm@31476
    37
  | exn_context (SOME ctxt) exn = CONTEXT (ctxt, exn);
wenzelm@31476
    38
wenzelm@31476
    39
wenzelm@31476
    40
(* exn_message *)
wenzelm@31476
    41
wenzelm@31476
    42
fun if_context NONE _ _ = []
wenzelm@31476
    43
  | if_context (SOME ctxt) f xs = map (f ctxt) xs;
wenzelm@31476
    44
wenzelm@39200
    45
fun exn_messages exn_position e =
wenzelm@31476
    46
  let
wenzelm@31476
    47
    fun raised exn name msgs =
wenzelm@31476
    48
      let val pos = Position.str_of (exn_position exn) in
wenzelm@31476
    49
        (case msgs of
wenzelm@31476
    50
          [] => "exception " ^ name ^ " raised" ^ pos
wenzelm@31476
    51
        | [msg] => "exception " ^ name ^ " raised" ^ pos ^ ": " ^ msg
wenzelm@31476
    52
        | _ => cat_lines (("exception " ^ name ^ " raised" ^ pos ^ ":") :: msgs))
wenzelm@31476
    53
      end;
wenzelm@31476
    54
wenzelm@31476
    55
    val detailed = ! Output.debugging;
wenzelm@31476
    56
wenzelm@39509
    57
    fun exn_msgs context exn =
wenzelm@39509
    58
      if Exn.is_interrupt exn then []
wenzelm@39509
    59
      else
wenzelm@39509
    60
        (case exn of
wenzelm@39509
    61
          Exn.EXCEPTIONS exns => maps (exn_msgs context) exns
wenzelm@39509
    62
        | CONTEXT (ctxt, exn) => exn_msgs (SOME ctxt) exn
wenzelm@39509
    63
        | EXCURSION_FAIL (exn, loc) =>
wenzelm@39509
    64
            map (fn msg => msg ^ Markup.markup Markup.location ("\n" ^ loc)) (exn_msgs context exn)
wenzelm@39509
    65
        | TERMINATE => ["Exit"]
wenzelm@39509
    66
        | TimeLimit.TimeOut => ["Timeout"]
wenzelm@39509
    67
        | TOPLEVEL_ERROR => ["Error"]
wenzelm@39509
    68
        | SYS_ERROR msg => ["## SYSTEM ERROR ##\n" ^ msg]
wenzelm@39509
    69
        | ERROR msg => [msg]
wenzelm@39509
    70
        | Fail msg => [raised exn "Fail" [msg]]
wenzelm@39509
    71
        | THEORY (msg, thys) =>
wenzelm@39509
    72
            [raised exn "THEORY" (msg :: (if detailed then map Context.str_of_thy thys else []))]
wenzelm@39509
    73
        | Syntax.AST (msg, asts) =>
wenzelm@39509
    74
            [raised exn "AST" (msg ::
wenzelm@39509
    75
              (if detailed then map (Pretty.string_of o Syntax.pretty_ast) asts else []))]
wenzelm@39509
    76
        | TYPE (msg, Ts, ts) =>
wenzelm@39509
    77
            [raised exn "TYPE" (msg ::
wenzelm@39509
    78
              (if detailed then
wenzelm@39509
    79
                if_context context Syntax.string_of_typ Ts @
wenzelm@39509
    80
                if_context context Syntax.string_of_term ts
wenzelm@39509
    81
               else []))]
wenzelm@39509
    82
        | TERM (msg, ts) =>
wenzelm@39509
    83
            [raised exn "TERM" (msg ::
wenzelm@39509
    84
              (if detailed then if_context context Syntax.string_of_term ts else []))]
wenzelm@39509
    85
        | THM (msg, i, thms) =>
wenzelm@39509
    86
            [raised exn ("THM " ^ string_of_int i) (msg ::
wenzelm@39509
    87
              (if detailed then if_context context Display.string_of_thm thms else []))]
wenzelm@39509
    88
        | _ => [raised exn (General.exnMessage exn) []]);
wenzelm@39200
    89
  in exn_msgs NONE e end;
wenzelm@39200
    90
wenzelm@39200
    91
fun exn_message exn_position exn =
wenzelm@39200
    92
  (case exn_messages exn_position exn of
wenzelm@39201
    93
    [] => "Interrupt"
wenzelm@39200
    94
  | msgs => cat_lines msgs);
wenzelm@31476
    95
wenzelm@31476
    96
wenzelm@31476
    97
wenzelm@31476
    98
(** controlled execution **)
wenzelm@31476
    99
wenzelm@31476
   100
fun debugging f x =
wenzelm@31476
   101
  if ! Output.debugging then
wenzelm@31476
   102
    Exn.release (exception_trace (fn () =>
wenzelm@31476
   103
      Exn.Result (f x) handle
wenzelm@31476
   104
        exn as UNDEF => Exn.Exn exn
wenzelm@31476
   105
      | exn as EXCURSION_FAIL _ => Exn.Exn exn))
wenzelm@31476
   106
  else f x;
wenzelm@31476
   107
wenzelm@31476
   108
fun controlled_execution f =
wenzelm@31476
   109
  f
wenzelm@31476
   110
  |> debugging
wenzelm@31476
   111
  |> Future.interruptible_task;
wenzelm@31476
   112
wenzelm@33603
   113
fun toplevel_error output_exn f x =
wenzelm@33603
   114
  let val ctxt = Option.map Context.proof_of (Context.thread_data ())
wenzelm@33603
   115
  in f x handle exn => (output_exn (exn_context ctxt exn); raise TOPLEVEL_ERROR) end;
wenzelm@31476
   116
wenzelm@31476
   117
end;
wenzelm@31476
   118