3 * Author: Kaustuv Chaudhuri <kaustuv+@cs.cmu.edu>
4 * Annotations: Alex Vaynberg <alv@andrew.cmu.edu>
5 * Modified: Frank Pfenning <fp@cs.cmu.edu>
7 * This tracks filename and newline characters
8 * so character positions in lexer tokens
9 * can be converted to line.column format for error messages
12 signature PARSE_STATE =
14 (* setfile(filename) sets current filename and resets newline positions *)
15 val setfile : string -> unit
17 (* newline(pos) adds pos to current newline positions *)
18 val newline : int -> unit
20 (* returns the current position information based on two integer offsets *)
21 val ext : int * int -> Mark.ext option
24 structure ParseState :> PARSE_STATE =
27 val currFilename = ref "";
28 val currLines = ref (nil : int list);
30 fun setfile (filename) =
31 (currFilename := filename;
35 (currLines := pos :: !currLines)
37 (* look (pos, newline_positions, line_number) = (line, col)
38 * pos is buffer position
39 * newline_positions is (reverse) list of newline positions in file
40 * line_number is lenght of newline_positions
42 fun look (pos, a :: rest, n) =
43 (* a is end of line n *)
44 if a < pos then (n+1, pos-a)
45 else look (pos, rest, n-1)
46 | look (pos, nil, n) =
47 (* first line pos is off by 1 *)
50 (* ext (leftpos, rightpos) = SOME((leftline, leftcol), (rightline, rightcol), filename)
51 * return NONE for invalid position (0,0)
55 SOME (look (left, !currLines, List.length (!currLines)),
56 look (right, !currLines, List.length (!currLines)),