Make more functions tail-recursive, and use tail-rec List functions (#251)

This commit is contained in:
Guillaume Petiot 2018-08-23 18:53:07 +02:00 committed by Jérémie Dimino
parent 74749bb720
commit 081e49d882
5 changed files with 114 additions and 109 deletions

View File

@ -104,7 +104,7 @@ let default_keywords = [
"when"; "while"; "with"; "try_lwt"; "finally"; "for_lwt"; "lwt"; "when"; "while"; "with"; "try_lwt"; "finally"; "for_lwt"; "lwt";
] ]
let keywords = ref (List.fold_right String_set.add default_keywords String_set.empty) let keywords = ref (String_set.of_list default_keywords)
let add_keyword kwd = keywords := String_set.add kwd !keywords let add_keyword kwd = keywords := String_set.add kwd !keywords
(* +-----------------------------------------------------------------+ (* +-----------------------------------------------------------------+
@ -750,24 +750,24 @@ let split_words str =
| ' ' | '\t' | '\r' | '\n' | ',' -> true | ' ' | '\t' | '\r' | '\n' | ',' -> true
| _ -> false | _ -> false
in in
let rec skip i = let rec skip acc i =
if i = len then if i = len then
[] acc
else else
if is_sep str.[i] then if is_sep str.[i] then
skip (i + 1) skip acc (i + 1)
else else
extract i (i + 1) extract acc i (i + 1)
and extract i j = and extract acc i j =
if j = len then if j = len then
[String.sub str i (j - i)] (String.sub str i (j - i)) :: acc
else else
if is_sep str.[j] then if is_sep str.[j] then
String.sub str i (j - i) :: skip (j + 1) skip (String.sub str i (j - i) :: acc) (j + 1)
else else
extract i (j + 1) extract acc i (j + 1)
in in
skip 0 List.rev (skip [] 0)
let require packages = let require packages =
try try

View File

@ -771,12 +771,14 @@ let labels_of_newclass longident =
+-----------------------------------------------------------------+ *) +-----------------------------------------------------------------+ *)
(* Filter blanks and comments except for the last token. *) (* Filter blanks and comments except for the last token. *)
let rec filter tokens = let filter tokens =
match tokens with let rec aux acc = function
| [] -> [] | [] -> acc
| [((Blanks | Comment (_, true)), loc)] -> [(Blanks, loc)] | [((Blanks | Comment (_, true)), loc)] -> (Blanks, loc) :: acc
| ((Blanks | Comment (_, true)), _) :: rest -> filter rest | ((Blanks | Comment (_, true)), _) :: rest -> aux acc rest
| x :: rest -> x :: filter rest | x :: rest -> aux (x :: acc) rest
in
List.rev (aux [] tokens)
(* Reverse and filter blanks and comments except for the last (* Reverse and filter blanks and comments except for the last
token. *) token. *)

View File

@ -33,18 +33,21 @@ let strip_colors s =
with with
| Not_found -> None | Not_found -> None
in in
let rec find_color_escapes offset = let find_color_escapes offset =
let rec aux acc offset =
match find_escape offset with match find_escape offset with
| None -> [offset, len] | None -> (offset, len) :: acc
| Some esc_offset -> | Some esc_offset ->
try try
let i = String.index_from s esc_offset 'm' in let i = String.index_from s esc_offset 'm' in
(offset, esc_offset) :: find_color_escapes (i + 1) aux ((offset, esc_offset) :: acc) (i + 1)
with with
| Not_found -> [offset, len] | Not_found -> (offset, len) :: acc
in
aux [] offset
in in
find_color_escapes 0 find_color_escapes 0
|> List.map (fun (i, j) -> String.sub s i (j - i)) |> List.rev_map (fun (i, j) -> String.sub s i (j - i))
|> String.concat "" |> String.concat ""
let add history v = let add history v =

View File

@ -316,10 +316,10 @@ let is_implicit_name name =
with with
Failure _ -> false Failure _ -> false
let rec map_items unwrap wrap items = let map_items unwrap wrap items =
match items with let rec aux acc = function
| [] -> | [] ->
[] acc
| item :: items -> | item :: items ->
let sig_item, _ = unwrap item in let sig_item, _ = unwrap item in
let name, rec_status = let name, rec_status =
@ -340,13 +340,12 @@ let rec map_items unwrap wrap items =
| Outcometree.Osig_ellipsis -> ("", Outcometree.Orec_not) | Outcometree.Osig_ellipsis -> ("", Outcometree.Orec_not)
#endif #endif
in in
let keep = let keep =
name = "" || name.[0] <> '_' || name = "" || name.[0] <> '_' ||
(UTop.get_create_implicits () && is_implicit_name name) (UTop.get_create_implicits () && is_implicit_name name)
in in
if keep then if keep then
item :: map_items unwrap wrap items aux (item :: acc) items
else else
(* Replace the [Orec_next] at the head of items by [Orec_first] *) (* Replace the [Orec_next] at the head of items by [Orec_first] *)
let items = let items =
@ -384,7 +383,9 @@ let rec map_items unwrap wrap items =
| Outcometree.Osig_value _ -> | Outcometree.Osig_value _ ->
items items
in in
map_items unwrap wrap items aux acc items
in
List.rev (aux [] items)
let print_out_signature pp items = let print_out_signature pp items =
if UTop.get_hide_reserved () then if UTop.get_hide_reserved () then
@ -535,7 +536,7 @@ let is_eval = function
| _ -> false | _ -> false
(* Returns the rewrite rule associated to a type, if any. *) (* Returns the rewrite rule associated to a type, if any. *)
let rec rule_of_type typ = let rule_of_type typ =
match (Ctype.expand_head !Toploop.toplevel_env typ).Types.desc with match (Ctype.expand_head !Toploop.toplevel_env typ).Types.desc with
| Types.Tconstr (path, _, _) -> begin | Types.Tconstr (path, _, _) -> begin
try try
@ -768,18 +769,18 @@ module Emacs(M : sig end) = struct
let command_oc = Unix.out_channel_of_descr (Unix.dup Unix.stdout) let command_oc = Unix.out_channel_of_descr (Unix.dup Unix.stdout)
let split_at ?(trim=false) ch str = let split_at ?(trim=false) ch str =
let rec aux i j = let rec aux acc i j =
if j = String.length str then if j = String.length str then
if trim && i = j then if trim && i = j then
[] acc
else else
[String.sub str i (j - i)] (String.sub str i (j - i)) :: acc
else if str.[j] = ch then else if str.[j] = ch then
String.sub str i (j - i) :: aux (j + 1) (j + 1) aux (String.sub str i (j - i) :: acc) (j + 1) (j + 1)
else else
aux i (j + 1) aux acc i (j + 1)
in in
aux 0 0 List.rev (aux [] 0 0)
(* +---------------------------------------------------------------+ (* +---------------------------------------------------------------+
| Sending commands to Emacs | | Sending commands to Emacs |

View File

@ -98,21 +98,20 @@ let load () =
Lwt_log.error_f "cannot load styles from %S: %s: %s" fn func (Unix.error_message error) Lwt_log.error_f "cannot load styles from %S: %s: %s" fn func (Unix.error_message error)
| exn -> Lwt.fail exn) | exn -> Lwt.fail exn)
let rec stylise_filter_layout stylise tokens = let stylise_filter_layout stylise tokens =
match tokens with let aux acc = function
| [] -> | (Comment (Comment_reg, _), loc) ->
[]
| (Comment (Comment_reg, _), loc) :: tokens ->
stylise loc styles.style_comment; stylise loc styles.style_comment;
stylise_filter_layout stylise tokens acc
| (Comment (Comment_doc, _), loc) :: tokens -> | (Comment (Comment_doc, _), loc) ->
stylise loc styles.style_doc; stylise loc styles.style_doc;
stylise_filter_layout stylise tokens acc
| (Blanks, loc) :: tokens -> | (Blanks, loc) ->
stylise loc styles.style_blanks; stylise loc styles.style_blanks;
stylise_filter_layout stylise tokens acc
| x :: tokens -> | x -> x :: acc
x :: stylise_filter_layout stylise tokens in
List.rev (List.fold_left aux [] tokens)
let rec stylise_rec stylise tokens = let rec stylise_rec stylise tokens =
match tokens with match tokens with