author | wenzelm |
Fri, 23 May 2008 21:18:47 +0200 | |
changeset 26977 | e736139b553d |
parent 26890 | f9ec18f7c0f6 |
child 27426 | c0ef698c0904 |
permissions | -rw-r--r-- |
6118 | 1 |
(* Title: Pure/General/position.ML |
5010 | 2 |
ID: $Id$ |
3 |
Author: Markus Wenzel, TU Muenchen |
|
4 |
||
23673 | 5 |
Source positions. |
5010 | 6 |
*) |
7 |
||
8 |
signature POSITION = |
|
9 |
sig |
|
10 |
type T |
|
23673 | 11 |
val line_of: T -> int option |
26003 | 12 |
val column_of: T -> int option |
23673 | 13 |
val file_of: T -> string option |
5010 | 14 |
val none: T |
26882 | 15 |
val line_file: int -> string -> T |
5010 | 16 |
val line: int -> T |
23673 | 17 |
val file: string -> T |
26003 | 18 |
val advance: Symbol.symbol -> T -> T |
25817 | 19 |
val of_properties: Markup.property list -> T |
23627 | 20 |
val properties_of: T -> Markup.property list |
26052 | 21 |
val default_properties: T -> Markup.property list -> Markup.property list |
26003 | 22 |
val str_of: T -> string |
25817 | 23 |
val thread_data: unit -> T |
24 |
val setmp_thread_data: T -> ('a -> 'b) -> 'a -> 'b |
|
25954 | 25 |
val setmp_thread_data_seq: T -> ('a -> 'b Seq.seq) -> 'a -> 'b Seq.seq |
5010 | 26 |
end; |
27 |
||
28 |
structure Position: POSITION = |
|
29 |
struct |
|
30 |
||
31 |
(* datatype position *) |
|
32 |
||
26003 | 33 |
datatype T = Pos of (int * int) option * Markup.property list; |
34 |
||
35 |
fun line_of (Pos (SOME (m, _), _)) = SOME m |
|
36 |
| line_of _ = NONE; |
|
5010 | 37 |
|
26003 | 38 |
fun column_of (Pos (SOME (_, n), _)) = SOME n |
39 |
| column_of _ = NONE; |
|
5010 | 40 |
|
26003 | 41 |
fun file_of (Pos (_, props)) = AList.lookup (op =) props Markup.fileN; |
5010 | 42 |
|
26882 | 43 |
|
25817 | 44 |
val none = Pos (NONE, []); |
26882 | 45 |
|
46 |
fun line_file m name = Pos (SOME (m, 1), if name = "" then [] else [(Markup.fileN, name)]); |
|
47 |
fun line m = line_file m ""; |
|
48 |
val file = line_file 1; |
|
49 |
||
5010 | 50 |
|
26003 | 51 |
fun advance "\n" (Pos (SOME (m, _), props)) = Pos (SOME (m + 1, 1), props) |
26633
ff317b19e24e
advance: do not count utf8 trailer bytes (which happen to be undefined or punctuation in iso-latin);
wenzelm
parents:
26052
diff
changeset
|
52 |
| advance s (pos as Pos (SOME (m, n), props)) = |
ff317b19e24e
advance: do not count utf8 trailer bytes (which happen to be undefined or punctuation in iso-latin);
wenzelm
parents:
26052
diff
changeset
|
53 |
if Symbol.is_regular s andalso not (Symbol.is_utf8_trailer s) |
ff317b19e24e
advance: do not count utf8 trailer bytes (which happen to be undefined or punctuation in iso-latin);
wenzelm
parents:
26052
diff
changeset
|
54 |
then Pos (SOME (m, n + 1), props) else pos |
26003 | 55 |
| advance _ pos = pos; |
5010 | 56 |
|
23627 | 57 |
|
58 |
(* markup properties *) |
|
22158 | 59 |
|
26003 | 60 |
fun get_int props (name: string) = |
61 |
(case AList.lookup (op =) props name of |
|
62 |
NONE => NONE |
|
63 |
| SOME s => Int.fromString s); |
|
64 |
||
25817 | 65 |
fun of_properties props = |
23627 | 66 |
let |
26003 | 67 |
val count = |
68 |
(case get_int props Markup.lineN of |
|
69 |
NONE => NONE |
|
70 |
| SOME m => SOME (m, the_default 1 (get_int props Markup.columnN))); |
|
71 |
fun property name = the_list (find_first (fn (x: string, _) => x = name) props); |
|
72 |
in (Pos (count, property Markup.fileN @ property Markup.idN)) end; |
|
73 |
||
74 |
fun properties_of (Pos (count, props)) = |
|
75 |
(case count of |
|
76 |
NONE => [] |
|
77 |
| SOME (m, n) => [(Markup.lineN, string_of_int m), (Markup.columnN, string_of_int n)]) @ props; |
|
78 |
||
26052 | 79 |
fun default_properties default props = |
80 |
if exists (member (op =) Markup.position_properties o #1) props then props |
|
81 |
else properties_of default @ props; |
|
82 |
||
25817 | 83 |
|
26003 | 84 |
(* str_of *) |
85 |
||
86 |
fun str_of pos = |
|
87 |
let |
|
88 |
val props = properties_of pos; |
|
89 |
val s = |
|
90 |
(case (line_of pos, file_of pos) of |
|
91 |
(SOME m, NONE) => "(line " ^ string_of_int m ^ ")" |
|
92 |
| (SOME m, SOME name) => "(line " ^ string_of_int m ^ " of " ^ quote name ^ ")" |
|
93 |
| _ => ""); |
|
94 |
in |
|
95 |
if null props then "" |
|
96 |
else (if s = "" then "" else " ") ^ Markup.markup (Markup.properties props Markup.position) s |
|
97 |
end; |
|
25817 | 98 |
|
23627 | 99 |
|
25817 | 100 |
(* thread data *) |
101 |
||
102 |
local val tag = Universal.tag () : T Universal.tag in |
|
103 |
||
104 |
fun thread_data () = the_default none (Multithreading.get_data tag); |
|
26890
f9ec18f7c0f6
setmp_thread_data: do nothing if Output.debugging;
wenzelm
parents:
26882
diff
changeset
|
105 |
|
f9ec18f7c0f6
setmp_thread_data: do nothing if Output.debugging;
wenzelm
parents:
26882
diff
changeset
|
106 |
fun setmp_thread_data pos f x = |
f9ec18f7c0f6
setmp_thread_data: do nothing if Output.debugging;
wenzelm
parents:
26882
diff
changeset
|
107 |
if ! Output.debugging then f x |
f9ec18f7c0f6
setmp_thread_data: do nothing if Output.debugging;
wenzelm
parents:
26882
diff
changeset
|
108 |
else Library.setmp_thread_data tag (thread_data ()) pos f x; |
25817 | 109 |
|
25954 | 110 |
fun setmp_thread_data_seq pos f seq = |
111 |
setmp_thread_data pos f seq |> Seq.wrap (fn pull => setmp_thread_data pos pull ()); |
|
112 |
||
25817 | 113 |
end; |
23673 | 114 |
|
5010 | 115 |
end; |