author | wenzelm |
Mon, 17 Mar 2008 22:34:25 +0100 | |
changeset 26311 | 81a0fc28b0de |
parent 26253 | 0506197d285f |
child 26435 | bdce320cd426 |
permissions | -rw-r--r-- |
25528
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
1 |
(* Title: Pure/Tools/isabelle_process.ML |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
2 |
ID: $Id$ |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
3 |
Author: Makarius |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
4 |
|
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
5 |
Isabelle process wrapper -- interaction via external program. |
25631 | 6 |
|
7 |
General format of process output: |
|
8 |
||
9 |
(a) unmarked stdout/stderr, no line structure (output should be |
|
25842 | 10 |
processed immediately as it arrives); |
25631 | 11 |
|
25841 | 12 |
(b) properly marked-up messages, e.g. for writeln channel |
25810 | 13 |
|
14 |
"\002A" ^ props ^ "\002,\n" ^ text ^ "\002.\n" |
|
15 |
||
25841 | 16 |
where the props consist of name=value lines terminated by "\002,\n" |
25810 | 17 |
each, and the remaining text is any number of lines (output is |
25842 | 18 |
supposed to be processed in one piece); |
25841 | 19 |
|
25842 | 20 |
(c) special init message holds "pid" and "session" property. |
25528
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
21 |
*) |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
22 |
|
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
23 |
signature ISABELLE_PROCESS = |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
24 |
sig |
26208 | 25 |
val output_markup: Markup.T -> output * output |
26 |
val full_markupN: string |
|
25554 | 27 |
val test_markupN: string |
25748 | 28 |
val isabelle_processN: string |
25528
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
29 |
val init: unit -> unit |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
30 |
end; |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
31 |
|
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
32 |
structure IsabelleProcess: ISABELLE_PROCESS = |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
33 |
struct |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
34 |
|
26208 | 35 |
(* explicit markup *) |
25554 | 36 |
|
26208 | 37 |
fun output_markup (name, props) = |
25554 | 38 |
(enclose "<" ">" (space_implode " " (name :: map XML.attribute props)), |
39 |
enclose "</" ">" name); |
|
40 |
||
26208 | 41 |
val full_markupN = "full_markup"; |
42 |
val test_markupN = "test_markup"; |
|
43 |
||
44 |
val _ = Markup.add_mode test_markupN output_markup; |
|
25554 | 45 |
|
46 |
||
25841 | 47 |
(* symbol output *) |
25554 | 48 |
|
25748 | 49 |
val isabelle_processN = "isabelle_process"; |
50 |
||
25554 | 51 |
local |
52 |
||
25841 | 53 |
fun output str = |
54 |
let |
|
55 |
fun out s = if Symbol.is_raw s then Symbol.decode_raw s else XML.text s; |
|
56 |
val syms = Symbol.explode str; |
|
57 |
in (implode (map out syms), Symbol.length syms) end; |
|
58 |
||
59 |
in |
|
60 |
||
61 |
val _ = Output.add_mode isabelle_processN output Symbol.encode_raw; |
|
62 |
||
63 |
end; |
|
64 |
||
65 |
||
66 |
(* message markup *) |
|
67 |
||
68 |
val STX = chr 2; |
|
69 |
val DEL = chr 127; |
|
70 |
||
71 |
fun special ch = STX ^ ch; |
|
25810 | 72 |
val special_sep = special ","; |
25576 | 73 |
val special_end = special "."; |
25554 | 74 |
|
25841 | 75 |
local |
25810 | 76 |
|
25841 | 77 |
fun print_props props = |
78 |
let |
|
79 |
val clean = translate_string (fn c => |
|
80 |
if c = STX orelse c = "\n" orelse c = "\r" then DEL else c); |
|
81 |
in implode (map (fn (x, y) => clean x ^ "=" ^ clean y ^ special_sep ^ "\n") props) end; |
|
82 |
||
83 |
fun get_pos (elem as XML.Elem (name, atts, ts)) = |
|
84 |
if name = Markup.positionN then SOME (Position.of_properties atts) |
|
85 |
else get_first get_pos ts |
|
86 |
| get_pos _ = NONE; |
|
25554 | 87 |
|
88 |
in |
|
89 |
||
25849 | 90 |
val _ = Markup.add_mode isabelle_processN (fn (name, props) => |
26208 | 91 |
if print_mode_active full_markupN orelse name = Markup.positionN |
92 |
then output_markup (name, props) else ("", "")); |
|
25849 | 93 |
|
26253 | 94 |
fun message ch txt0 = |
25841 | 95 |
let |
26253 | 96 |
val txt1 = XML.element "message" [] [txt0]; |
25841 | 97 |
val (txt, pos) = |
26253 | 98 |
(case try XML.tree_of_string txt1 of |
99 |
NONE => (txt1, Position.none) |
|
26208 | 100 |
| SOME xml => |
26253 | 101 |
(if print_mode_active full_markupN then XML.header ^ txt1 else XML.plain_content xml, |
26208 | 102 |
the_default Position.none (get_pos xml))) |
25841 | 103 |
|>> translate_string (fn c => if c = STX then DEL else c); |
104 |
val props = |
|
26053 | 105 |
Position.properties_of (Position.thread_data ()) |
106 |
|> Position.default_properties pos; |
|
25849 | 107 |
in Output.writeln_default (special ch ^ print_props props ^ txt ^ special_end) end; |
25554 | 108 |
|
25841 | 109 |
fun init_message () = |
110 |
let |
|
25849 | 111 |
val pid = ("pid", string_of_pid (Posix.ProcEnv.getpid ())); |
112 |
val session = ("session", List.last (Session.id ()) handle List.Empty => "unknown"); |
|
25841 | 113 |
val welcome = Session.welcome (); |
25849 | 114 |
in Output.writeln_default (special "H" ^ print_props [pid, session] ^ welcome ^ special_end) end; |
25748 | 115 |
|
25554 | 116 |
end; |
117 |
||
118 |
||
25841 | 119 |
(* channels *) |
120 |
||
121 |
fun setup_channels () = |
|
25849 | 122 |
(Output.writeln_fn := message "A"; |
123 |
Output.priority_fn := message "B"; |
|
124 |
Output.tracing_fn := message "C"; |
|
125 |
Output.warning_fn := message "D"; |
|
126 |
Output.error_fn := message "E"; |
|
127 |
Output.debug_fn := message "F"; |
|
128 |
Output.prompt_fn := message "G"); |
|
25841 | 129 |
|
130 |
||
26208 | 131 |
(* token translations *) |
132 |
||
133 |
local |
|
134 |
||
135 |
fun markup kind x = |
|
26253 | 136 |
((output_markup (kind, []) |-> enclose) (Output.output x), Symbol.length (Symbol.explode x)); |
26208 | 137 |
|
138 |
fun free_or_skolem x = |
|
139 |
(case try Name.dest_skolem x of |
|
140 |
NONE => markup Markup.freeN x |
|
141 |
| SOME x' => markup Markup.skolemN x'); |
|
142 |
||
143 |
fun var_or_skolem s = |
|
144 |
(case Lexicon.read_variable s of |
|
145 |
SOME (x, i) => |
|
146 |
(case try Name.dest_skolem x of |
|
147 |
NONE => markup Markup.varN s |
|
148 |
| SOME x' => markup Markup.skolemN |
|
149 |
(setmp show_question_marks true Term.string_of_vname (x', i))) |
|
150 |
| NONE => markup Markup.varN s); |
|
151 |
||
152 |
val token_trans = |
|
153 |
Syntax.tokentrans_mode full_markupN |
|
154 |
[("class", markup Markup.classN), |
|
155 |
("tfree", markup Markup.tfreeN), |
|
156 |
("tvar", markup Markup.tvarN), |
|
157 |
("free", free_or_skolem), |
|
158 |
("bound", markup Markup.boundN), |
|
159 |
("var", var_or_skolem)]; |
|
160 |
||
161 |
in |
|
162 |
||
163 |
val _ = Context.add_setup (Sign.add_tokentrfuns token_trans); |
|
164 |
||
165 |
end; |
|
166 |
||
25841 | 167 |
|
25554 | 168 |
(* init *) |
169 |
||
25528
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
170 |
fun init () = |
25841 | 171 |
(change print_mode (update (op =) isabelle_processN); |
25554 | 172 |
setup_channels (); |
25841 | 173 |
init_message (); |
25528
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
174 |
Isar.secure_main ()); |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
175 |
|
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
176 |
end; |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
177 |