- if List.for_all (List.for_all (function e -> List.length e = 1)) a
- then
- let p = get_p() in
- List.iter (List.iter (List.iter (function (_,pos) -> pos := p))) a
- else
- let all = r @ List.concat xs in
- let rec find_first_available a = function
- [] -> raise Not_found
- | (str,pos)::xs ->
- if str = a && !pos = Ast0.NoMetaPos
- then pos
- else find_first_available a xs in
- List.iter
- (function (str,pos) ->
- match !pos with
- Ast0.NoMetaPos ->
- (try
- let entries = List.map (find_first_available str) all in
- let p = get_p() in
- pos := p;
- List.iter (function pos -> pos := p) entries
- with Not_found -> ())
- | _ -> (* already have a variable *) ())
- f;
- loop xs
+ let safe_add p pos =
+ (* don't add pos var where a pos var is already present *)
+ if Common.inter_set previously_used pos = [] then p::pos else pos in
+ let p =
+ if List.for_all (List.for_all (function e -> List.length e = 1)) a
+ then
+ let p = get_p() in
+ List.iter
+ (List.iter
+ (List.iter (function (_,pos) -> pos := safe_add p !pos)))
+ a;
+ [p]
+ else
+ let all = r @ List.concat xs in
+ let rec find_first_available a = function
+ [] -> raise Not_found
+ | (str,pos)::xs ->
+ if str = a && Common.inter_set previously_used !pos = []
+ then pos
+ else find_first_available a xs in
+ List.fold_left
+ (function prev ->
+ function (str,pos) ->
+ if Common.inter_set previously_used !pos = []
+ then
+ try
+ let entries = List.map (find_first_available str) all in
+ let p = get_p() in
+ pos := p::!pos;
+ List.iter (function pos -> pos := p :: !pos) entries;
+ p::prev
+ with Not_found -> prev
+ (* otherwise already annotated *)
+ else prev)
+ [] f in
+ loop (p@previously_used) xs