@@ -67,6 +67,7 @@ type manager =
67
67
over_right_gap : limit Links .t ; (* * associates the right limit of a token to
68
68
the left limit of the next *)
69
69
cache : (srcloc * limit ) Links .t ;
70
+ leftmost_in_file : (string , limit ) Hashtbl .t ;
70
71
id : string ; (* * manager identifier (for logging/debugging) *)
71
72
}
72
73
@@ -79,18 +80,24 @@ let new_manager: string -> manager =
79
80
right_of = Links. create 42 ;
80
81
over_right_gap = Links. create 42 ;
81
82
cache = Links. create 42 ;
83
+ leftmost_in_file = Hashtbl. create 3 ;
82
84
id = Pretty. to_string " %s-%u" manager_name ! id;
83
85
}
84
86
85
87
(* * Returns left and right (potentially fresh) limits for the given source
86
88
location; for any given file, must be called with the leftmost location
87
89
first. *)
90
+ (* TODO: try to see whether registering the leftmost location in each file could
91
+ be done more efficiently wihtout a membership test on each new location (but
92
+ the pre-processor does not provide change-of-file info to the parser). *)
88
93
let limits: manager -> srcloc -> limit * limit = fun ctx loc ->
89
94
let s, e = match Cobol_common.Srcloc. as_unique_lexloc loc with
90
95
| Some lexloc -> lexloc
91
96
| _ -> Limit. make_virtual () , Limit. make_virtual ()
92
97
in
93
98
Links. replace ctx.right_of s (loc, e); (* replace to deal with duplicates *)
99
+ if not (Hashtbl. mem ctx.leftmost_in_file s.pos_fname)
100
+ then Hashtbl. add ctx.leftmost_in_file s.pos_fname s;
94
101
s, e
95
102
96
103
(* * Links token limits *)
@@ -102,12 +109,7 @@ let link_limits ctx left right =
102
109
in [filename] that is registered in [ctx] (internal). Use with moderation
103
110
as this is quite inefficient. *)
104
111
let leftmost_limit_in ~filename ctx =
105
- Links. fold begin fun l _ -> function
106
- | None when l.Lexing. pos_fname = filename -> Some l
107
- | Some l' when l.Lexing. pos_cnum < l'.pos_cnum &&
108
- l.Lexing. pos_fname = filename -> Some l
109
- | res -> res
110
- end ctx.right_of None
112
+ Hashtbl. find_opt ctx.leftmost_in_file filename
111
113
112
114
(* * Returns a source location that spans between two given limits; returns a
113
115
valid pointwise location if the two given limits are physically equal. *)
0 commit comments