author | wenzelm |
Tue, 13 Jan 2009 22:20:49 +0100 | |
changeset 29468 | c9bb4e06d173 |
parent 29467 | d98fe0c504a8 |
child 29484 | 15863d782ae3 |
permissions | -rw-r--r-- |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
1 |
(* Title: Pure/Isar/isar_document.ML |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
2 |
Author: Makarius |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
3 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
4 |
Interactive Isar documents. |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
5 |
*) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
6 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
7 |
signature ISAR_DOCUMENT = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
8 |
sig |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
9 |
type state_id = string |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
10 |
type command_id = string |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
11 |
type document_id = string |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
12 |
val define_command: command_id -> Toplevel.transition -> unit |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
13 |
val begin_document: document_id -> Path.T -> unit |
29468 | 14 |
val end_document: document_id -> unit |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
15 |
val edit_document: document_id -> document_id -> (command_id * command_id option) list -> unit |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
16 |
end; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
17 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
18 |
structure IsarDocument: ISAR_DOCUMENT = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
19 |
struct |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
20 |
|
29468 | 21 |
|
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
22 |
(* unique identifiers *) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
23 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
24 |
type document_id = string; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
25 |
type command_id = string; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
26 |
type state_id = string; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
27 |
|
29468 | 28 |
fun new_id () = "isabelle:" ^ serial_string (); |
29467 | 29 |
|
30 |
fun err_dup kind id = error ("Duplicate " ^ kind ^ ": " ^ quote id); |
|
31 |
fun err_undef kind id = error ("Unknown " ^ kind ^ ": " ^ quote id); |
|
32 |
||
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
33 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
34 |
(** execution states **) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
35 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
36 |
(* command status *) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
37 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
38 |
datatype status = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
39 |
Unprocessed | |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
40 |
Running of Toplevel.state option future | |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
41 |
Failed | |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
42 |
Finished of Toplevel.state; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
43 |
|
29468 | 44 |
fun markup_status Unprocessed = Markup.unprocessed |
45 |
| markup_status (Running future) = Markup.running (Task_Queue.str_of_task (Future.task_of future)) |
|
46 |
| markup_status Failed = Markup.failed |
|
47 |
| markup_status (Finished _) = Markup.finished; |
|
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
48 |
|
29468 | 49 |
fun update_status retry tr state status = |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
50 |
(case status of |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
51 |
Unprocessed => SOME (Running (Future.fork_pri 1 (fn () => |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
52 |
(case Toplevel.transition true tr state of |
29467 | 53 |
NONE => (Toplevel.error_msg tr (ERROR "Cannot terminate here!", ""); NONE) |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
54 |
| SOME (_, SOME err) => (Toplevel.error_msg tr err; NONE) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
55 |
| SOME (state', NONE) => SOME state')))) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
56 |
| Running future => |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
57 |
(case Future.peek future of |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
58 |
NONE => NONE |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
59 |
| SOME (Exn.Result NONE) => SOME Failed |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
60 |
| SOME (Exn.Result (SOME state')) => SOME (Finished state') |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
61 |
| SOME (Exn.Exn exn) => (Toplevel.error_msg tr (exn, ""); SOME Failed)) |
29468 | 62 |
| Failed => if retry then SOME Unprocessed else NONE |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
63 |
| _ => NONE); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
64 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
65 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
66 |
(* state *) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
67 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
68 |
datatype state = State of |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
69 |
{prev: state_id option, |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
70 |
command: command_id, |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
71 |
status: status}; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
72 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
73 |
fun make_state prev command status = State {prev = prev, command = command, status = status}; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
74 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
75 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
76 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
77 |
(** documents **) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
78 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
79 |
(* command entries *) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
80 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
81 |
datatype entry = Entry of |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
82 |
{prev: command_id option, |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
83 |
next: command_id option, |
29468 | 84 |
state: state_id option}; |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
85 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
86 |
fun make_entry prev next state = Entry {prev = prev, next = next, state = state}; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
87 |
|
29467 | 88 |
fun the_entry entries (id: command_id) = |
89 |
(case Symtab.lookup entries id of |
|
90 |
NONE => err_undef "document entry" id |
|
91 |
| SOME (Entry entry) => entry); |
|
92 |
||
93 |
fun put_entry (id: command_id, entry: entry) = Symtab.update (id, entry); |
|
94 |
||
95 |
fun map_entry (id: command_id) f entries = |
|
96 |
let |
|
97 |
val {prev, next, state} = the_entry entries id; |
|
98 |
val (prev', next', state') = f (prev, next, state); |
|
99 |
in put_entry (id, make_entry prev' next' state') entries end; |
|
100 |
||
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
101 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
102 |
(* document *) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
103 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
104 |
datatype document = Document of |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
105 |
{dir: Path.T, (*master directory*) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
106 |
name: string, (*theory name*) |
29467 | 107 |
start: command_id, (*empty start command*) |
108 |
entries: entry Symtab.table}; (*unique command entries indexed by command_id*) |
|
109 |
||
110 |
fun make_document dir name start entries = |
|
111 |
Document {dir = dir, name = name, start = start, entries = entries}; |
|
112 |
||
113 |
fun map_entries f (Document {dir, name, start, entries}) = |
|
114 |
make_document dir name start (f entries); |
|
115 |
||
116 |
||
29468 | 117 |
(* iterating entries *) |
118 |
||
119 |
fun fold_entries opt_id f (Document {start, entries, ...}) = |
|
120 |
let |
|
121 |
fun apply NONE x = x |
|
122 |
| apply (SOME id) x = apply (#next (the_entry entries id)) (f id x); |
|
123 |
in if is_some opt_id then apply opt_id else apply (SOME start) end; |
|
124 |
||
125 |
fun get_first_entries opt_id f (Document {start, entries, ...}) = |
|
29467 | 126 |
let |
29468 | 127 |
fun get NONE = NONE |
128 |
| get (SOME id) = (case f id of NONE => get (#next (the_entry entries id)) | some => some); |
|
129 |
in if is_some opt_id then get opt_id else get (SOME start) end; |
|
29467 | 130 |
|
29468 | 131 |
fun find_first_entries opt_id P = |
132 |
get_first_entries opt_id (fn x => if P x then SOME x else NONE); |
|
133 |
||
134 |
||
135 |
(* modify entries *) |
|
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
136 |
|
29467 | 137 |
fun insert_entry (id: command_id, id2: command_id) = map_entries (fn entries => |
29468 | 138 |
let val {prev, next, state} = the_entry entries id in |
29467 | 139 |
entries |> |
140 |
(case next of |
|
29468 | 141 |
NONE => put_entry (id2, make_entry (SOME id) NONE NONE) |
29467 | 142 |
| SOME id3 => |
29468 | 143 |
put_entry (id, make_entry prev (SOME id2) state) #> |
144 |
put_entry (id2, make_entry (SOME id) (SOME id3) NONE) #> |
|
145 |
put_entry (id3, make_entry (SOME id2) (#next (the_entry entries id3)) NONE)) |
|
29467 | 146 |
end); |
147 |
||
29468 | 148 |
fun delete_after (id: command_id) = map_entries (fn entries => |
29467 | 149 |
let val {prev, next, state} = the_entry entries id in |
150 |
entries |> |
|
151 |
(case next of |
|
152 |
NONE => error ("Missing next entry: " ^ quote id) |
|
153 |
| SOME id2 => |
|
154 |
(case #next (the_entry entries id2) of |
|
155 |
NONE => put_entry (id, make_entry prev NONE state) |
|
156 |
| SOME id3 => |
|
29468 | 157 |
put_entry (id, make_entry prev (SOME id3) state) #> |
158 |
put_entry (id3, make_entry (SOME id) (#next (the_entry entries id3)) NONE))) |
|
29467 | 159 |
end); |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
160 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
161 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
162 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
163 |
(** global configuration **) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
164 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
165 |
local |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
166 |
val global_states = ref (Symtab.empty: state Symtab.table); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
167 |
val global_commands = ref (Symtab.empty: Toplevel.transition Symtab.table); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
168 |
val global_documents = ref (Symtab.empty: document Symtab.table); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
169 |
in |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
170 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
171 |
fun change_states f = NAMED_CRITICAL "Isar" (fn () => change global_states f); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
172 |
fun get_states () = NAMED_CRITICAL "Isar" (fn () => ! global_states); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
173 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
174 |
fun change_commands f = NAMED_CRITICAL "Isar" (fn () => change global_commands f); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
175 |
fun get_commands () = NAMED_CRITICAL "Isar" (fn () => ! global_commands); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
176 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
177 |
fun change_documents f = NAMED_CRITICAL "Isar" (fn () => change global_documents f); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
178 |
fun get_documents () = NAMED_CRITICAL "Isar" (fn () => ! global_documents); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
179 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
180 |
fun init () = NAMED_CRITICAL "Isar" (fn () => |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
181 |
(global_states := Symtab.empty; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
182 |
global_commands := Symtab.empty; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
183 |
global_documents := Symtab.empty)); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
184 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
185 |
end; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
186 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
187 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
188 |
fun define_state (id: state_id) state = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
189 |
change_states (Symtab.update_new (id, state)) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
190 |
handle Symtab.DUP dup => err_dup "state" dup; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
191 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
192 |
fun the_state (id: state_id) = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
193 |
(case Symtab.lookup (get_states ()) id of |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
194 |
NONE => err_undef "state" id |
29468 | 195 |
| SOME (State state) => state); |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
196 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
197 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
198 |
fun define_command id tr = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
199 |
change_commands (Symtab.update_new (id, Toplevel.put_id id tr)) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
200 |
handle Symtab.DUP dup => err_dup ("command " ^ Toplevel.name_of tr) dup; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
201 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
202 |
fun the_command (id: command_id) = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
203 |
(case Symtab.lookup (get_commands ()) id of |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
204 |
NONE => err_undef "command" id |
29468 | 205 |
| SOME tr => tr); |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
206 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
207 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
208 |
fun define_document (id: document_id) document = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
209 |
change_documents (Symtab.update_new (id, document)) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
210 |
handle Symtab.DUP dup => err_dup "document" dup; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
211 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
212 |
fun the_document (id: document_id) = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
213 |
(case Symtab.lookup (get_documents ()) id of |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
214 |
NONE => err_undef "document" id |
29468 | 215 |
| SOME (Document doc) => doc); |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
216 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
217 |
|
29468 | 218 |
(* begin/end document *) |
29467 | 219 |
|
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
220 |
fun begin_document (id: document_id) path = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
221 |
let |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
222 |
val (dir, name) = ThyLoad.split_thy_path path; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
223 |
val _ = define_command id Toplevel.empty; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
224 |
val _ = define_state id (make_state NONE id (Finished Toplevel.toplevel)); |
29468 | 225 |
val entries = Symtab.make [(id, make_entry NONE NONE (SOME id))]; |
29467 | 226 |
val _ = define_document id (make_document dir name id entries); |
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
227 |
in () end; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
228 |
|
29468 | 229 |
fun end_document (id: document_id) = error "FIXME"; |
230 |
||
231 |
||
232 |
(* document editing *) |
|
233 |
||
234 |
fun refresh_states old_document new_document = |
|
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
235 |
let |
29468 | 236 |
val Document {entries = old_entries, ...} = old_document; |
237 |
val Document {entries = new_entries, ...} = new_document; |
|
238 |
||
239 |
fun is_changed id = |
|
240 |
(case try (the_entry new_entries) id of |
|
241 |
SOME {state = SOME _, ...} => false |
|
242 |
| _ => true); |
|
243 |
||
244 |
fun cancel_state id () = |
|
245 |
(case the_entry old_entries id of |
|
246 |
{state = SOME state_id, ...} => |
|
247 |
(case the_state state_id of |
|
248 |
{status = Running future, ...} => Future.cancel future |
|
249 |
| _ => ()) |
|
250 |
| _ => ()); |
|
251 |
||
252 |
fun new_state id (prev_state_id, new_states) = |
|
253 |
let |
|
254 |
val state_id = new_id (); |
|
255 |
val state = make_state prev_state_id id Unprocessed; |
|
256 |
val _ = define_state state_id state; |
|
257 |
in (SOME state_id, (state_id, state) :: new_states) end; |
|
258 |
in |
|
259 |
(case find_first_entries NONE is_changed old_document of |
|
260 |
NONE => new_document |
|
261 |
| SOME id => |
|
262 |
let |
|
263 |
val _ = fold_entries (SOME id) cancel_state old_document (); |
|
264 |
val (_, new_states) = fold_entries (SOME id) new_state new_document (NONE, []); |
|
265 |
(* FIXME update states *) |
|
266 |
in new_document end) |
|
267 |
end; |
|
268 |
||
269 |
fun edit_document (id: document_id) (id': document_id) edits = |
|
270 |
let |
|
271 |
val document = Document (the_document id); |
|
29467 | 272 |
val document' = |
29468 | 273 |
document |
274 |
|> fold (fn (id, SOME id2) => insert_entry (id, id2) | (id, NONE) => delete_after id) edits |
|
275 |
|> refresh_states document; |
|
276 |
val _ = define_document id' document'; |
|
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
277 |
in () end; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
278 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
279 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
280 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
281 |
(** concrete syntax **) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
282 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
283 |
local structure P = OuterParse structure V = ValueParse in |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
284 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
285 |
val _ = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
286 |
OuterSyntax.internal_command "Isar.define_command" |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
287 |
(P.string -- P.string >> (fn (id, text) => |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
288 |
Toplevel.imperative (fn () => |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
289 |
define_command id (OuterSyntax.prepare_command (Position.id id) text)))); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
290 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
291 |
val _ = |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
292 |
OuterSyntax.internal_command "Isar.begin_document" |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
293 |
(P.string -- P.string >> (fn (id, path) => |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
294 |
Toplevel.imperative (fn () => begin_document id (Path.explode path)))); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
295 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
296 |
val _ = |
29468 | 297 |
OuterSyntax.internal_command "Isar.end_document" |
298 |
(P.string >> (fn id => Toplevel.imperative (fn () => end_document id))); |
|
299 |
||
300 |
val _ = |
|
29459
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
301 |
OuterSyntax.internal_command "Isar.edit_document" |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
302 |
(P.string -- P.string -- V.list (P.string -- (P.string >> SOME) || P.string >> rpair NONE) |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
303 |
>> (fn ((id, new_id), edits) => Toplevel.imperative (fn () => end_document id new_id edits))); |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
304 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
305 |
end; |
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
306 |
|
8acad4f0a727
added Isar/isar_document.ML: Interactive Isar documents.
wenzelm
parents:
diff
changeset
|
307 |
end; |
29467 | 308 |