| author | wenzelm |
| Wed, 06 Aug 2008 10:43:42 +0200 | |
| changeset 27759 | ffb1b5f2690f |
| parent 27749 | 24f2b57a34ea |
| child 27764 | e0ee3cc240fe |
| 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 |
| 27744 | 18 |
val advance: Symbol.symbol list -> T -> T |
| 27426 | 19 |
val get_id: T -> string option |
20 |
val put_id: string -> T -> T |
|
| 25817 | 21 |
val of_properties: Markup.property list -> T |
| 23627 | 22 |
val properties_of: T -> Markup.property list |
| 26052 | 23 |
val default_properties: T -> Markup.property list -> Markup.property list |
| 26003 | 24 |
val str_of: T -> string |
| 25817 | 25 |
val thread_data: unit -> T |
26 |
val setmp_thread_data: T -> ('a -> 'b) -> 'a -> 'b
|
|
| 25954 | 27 |
val setmp_thread_data_seq: T -> ('a -> 'b Seq.seq) -> 'a -> 'b Seq.seq
|
| 27736 | 28 |
type range = T * T |
29 |
val encode_range: range -> T |
|
| 27741 | 30 |
val report: Markup.T -> T -> unit |
| 5010 | 31 |
end; |
32 |
||
33 |
structure Position: POSITION = |
|
34 |
struct |
|
35 |
||
36 |
(* datatype position *) |
|
37 |
||
| 26003 | 38 |
datatype T = Pos of (int * int) option * Markup.property list; |
39 |
||
40 |
fun line_of (Pos (SOME (m, _), _)) = SOME m |
|
41 |
| line_of _ = NONE; |
|
| 5010 | 42 |
|
| 26003 | 43 |
fun column_of (Pos (SOME (_, n), _)) = SOME n |
44 |
| column_of _ = NONE; |
|
| 5010 | 45 |
|
| 26003 | 46 |
fun file_of (Pos (_, props)) = AList.lookup (op =) props Markup.fileN; |
| 5010 | 47 |
|
| 26882 | 48 |
|
| 25817 | 49 |
val none = Pos (NONE, []); |
| 26882 | 50 |
|
51 |
fun line_file m name = Pos (SOME (m, 1), if name = "" then [] else [(Markup.fileN, name)]); |
|
52 |
fun line m = line_file m ""; |
|
53 |
val file = line_file 1; |
|
54 |
||
| 5010 | 55 |
|
| 27744 | 56 |
(* advance position *) |
57 |
||
| 27759 | 58 |
fun advance_count "\n" (m: int, _: int) = (m + 1, 1) |
| 27744 | 59 |
| advance_count s (m, n) = |
|
26633
ff317b19e24e
advance: do not count utf8 trailer bytes (which happen to be undefined or punctuation in iso-latin);
wenzelm
parents:
26052
diff
changeset
|
60 |
if Symbol.is_regular s andalso not (Symbol.is_utf8_trailer s) |
| 27744 | 61 |
then (m, n + 1) else (m, n); |
62 |
||
63 |
fun advance syms (Pos (SOME count, props)) = Pos (SOME (fold advance_count syms count), props) |
|
| 26003 | 64 |
| advance _ pos = pos; |
| 5010 | 65 |
|
| 23627 | 66 |
|
67 |
(* markup properties *) |
|
| 22158 | 68 |
|
| 27426 | 69 |
fun get_id (Pos (_, props)) = AList.lookup (op =) props Markup.idN; |
70 |
fun put_id id (Pos (count, props)) = Pos (count, AList.update (op =) (Markup.idN, id) props); |
|
71 |
||
| 26003 | 72 |
fun get_int props (name: string) = |
73 |
(case AList.lookup (op =) props name of |
|
74 |
NONE => NONE |
|
75 |
| SOME s => Int.fromString s); |
|
76 |
||
| 25817 | 77 |
fun of_properties props = |
| 23627 | 78 |
let |
| 26003 | 79 |
val count = |
80 |
(case get_int props Markup.lineN of |
|
81 |
NONE => NONE |
|
82 |
| SOME m => SOME (m, the_default 1 (get_int props Markup.columnN))); |
|
83 |
fun property name = the_list (find_first (fn (x: string, _) => x = name) props); |
|
|
27749
24f2b57a34ea
of_properties: observe Markup.position_properties';
wenzelm
parents:
27744
diff
changeset
|
84 |
in Pos (count, maps property Markup.position_properties') end; |
| 26003 | 85 |
|
86 |
fun properties_of (Pos (count, props)) = |
|
87 |
(case count of |
|
88 |
NONE => [] |
|
89 |
| SOME (m, n) => [(Markup.lineN, string_of_int m), (Markup.columnN, string_of_int n)]) @ props; |
|
90 |
||
| 26052 | 91 |
fun default_properties default props = |
92 |
if exists (member (op =) Markup.position_properties o #1) props then props |
|
93 |
else properties_of default @ props; |
|
94 |
||
| 25817 | 95 |
|
| 26003 | 96 |
(* str_of *) |
97 |
||
98 |
fun str_of pos = |
|
99 |
let |
|
100 |
val props = properties_of pos; |
|
101 |
val s = |
|
102 |
(case (line_of pos, file_of pos) of |
|
103 |
(SOME m, NONE) => "(line " ^ string_of_int m ^ ")" |
|
104 |
| (SOME m, SOME name) => "(line " ^ string_of_int m ^ " of " ^ quote name ^ ")" |
|
105 |
| _ => ""); |
|
106 |
in |
|
107 |
if null props then "" |
|
108 |
else (if s = "" then "" else " ") ^ Markup.markup (Markup.properties props Markup.position) s |
|
109 |
end; |
|
| 25817 | 110 |
|
| 23627 | 111 |
|
| 25817 | 112 |
(* thread data *) |
113 |
||
114 |
local val tag = Universal.tag () : T Universal.tag in |
|
115 |
||
116 |
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
|
117 |
|
|
f9ec18f7c0f6
setmp_thread_data: do nothing if Output.debugging;
wenzelm
parents:
26882
diff
changeset
|
118 |
fun setmp_thread_data pos f x = |
|
f9ec18f7c0f6
setmp_thread_data: do nothing if Output.debugging;
wenzelm
parents:
26882
diff
changeset
|
119 |
if ! Output.debugging then f x |
|
f9ec18f7c0f6
setmp_thread_data: do nothing if Output.debugging;
wenzelm
parents:
26882
diff
changeset
|
120 |
else Library.setmp_thread_data tag (thread_data ()) pos f x; |
| 25817 | 121 |
|
| 25954 | 122 |
fun setmp_thread_data_seq pos f seq = |
123 |
setmp_thread_data pos f seq |> Seq.wrap (fn pull => setmp_thread_data pos pull ()); |
|
124 |
||
| 25817 | 125 |
end; |
| 23673 | 126 |
|
| 27736 | 127 |
|
128 |
(* range *) |
|
129 |
||
130 |
type range = T * T; |
|
131 |
||
132 |
fun encode_range (Pos (count, props), Pos (end_count, _)) = |
|
133 |
let val props' = props |> fold_rev (AList.update op =) |
|
134 |
(case end_count of |
|
135 |
NONE => [] |
|
136 |
| SOME (m, n) => [(Markup.end_lineN, string_of_int m), (Markup.end_columnN, string_of_int n)]) |
|
137 |
in Pos (count, props') end; |
|
138 |
||
| 27741 | 139 |
|
140 |
(* report markup *) |
|
141 |
||
142 |
fun report markup pos = |
|
143 |
if pos = none then () |
|
144 |
else Output.status (Markup.markup (Markup.properties (properties_of pos) markup) ""); |
|
145 |
||
| 5010 | 146 |
end; |