-
Notifications
You must be signed in to change notification settings - Fork 5
Use a rope of string array instead of a list of strings #37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 10 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
54f646a
Use a rope of string array instead of a list of strings
hannesm d2ef194
use Array.sub in to_strings
hannesm f260b38
avoid List.rev in to_strings
hannesm 26dd217
use rev_append
hannesm 220a99d
List.rev_cut is no longer needed
hannesm 969a929
patch: introduce off_mine, as suggested by @shym
hannesm c9f97c4
avoid physical equality, avoid polymorphic equality (suggested by @ki…
hannesm d91becf
Rope: remove last field of 'App', which is not used (suggested by @ki…
hannesm 1bdbea3
Rope: add an interface file, suggested by @kit-ty-kate
hannesm 556011f
Rope: introduce equal_to_string_list, remove to_strings - suggested b…
hannesm dc61f4b
Rope.of_string: avoid iterating over the list
hannesm 835047d
no polymorphic cmp + style
kit-ty-kate 01d557e
add many hunks test from external
hannesm 592e610
update README
hannesm 543f19d
update submodule
hannesm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,5 +9,4 @@ end | |
|
|
||
| module List : sig | ||
| val last : 'a list -> 'a | ||
| val rev_cut : int -> 'a list -> 'a list * 'a list | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| (* Originally from https://github.com/robur-coop/utcp, written by | ||
| Calascibetta Romain <[email protected]> *) | ||
|
|
||
| (* A rope data structure where each node is a line *) | ||
|
|
||
| type t = | ||
| | Str of string array * bool * int * int | ||
| | App of t * t * int | ||
|
|
||
| let length = function | ||
| | Str (_, _, len, _) -> len | ||
| | App (_, _, len) -> len | ||
|
|
||
| (* keep compatibility with 4.08 *) | ||
| let min_int (a : int) (b : int) = min a b | ||
| external unsafe_blit_string : string -> int -> bytes -> int -> int -> unit | ||
| = "caml_blit_string" [@@noalloc] | ||
|
|
||
| let append t1 t2 = | ||
| App (t1, t2, length t1 + length t2) | ||
|
|
||
| let empty = Str (Array.make 0 "", true, 0, 0) | ||
|
|
||
| let rec unsafe_sub t start stop = | ||
| if start = 0 && Int.equal stop (length t) then | ||
| t | ||
| else if Int.equal start stop then | ||
| empty | ||
| else match t with | ||
| | Str (data, nl, len, off) -> | ||
| assert (stop <= len); | ||
| Str (data, nl, stop - start, off + start) | ||
| | App (l, r, _) -> | ||
| let len = length l in | ||
| if stop <= len then unsafe_sub l start stop | ||
| else if start >= len then unsafe_sub r (start - len) (stop - len) | ||
| else append (unsafe_sub l start len) (unsafe_sub r 0 (stop - len)) | ||
|
|
||
| let chop t ?(off = 0) len = | ||
| if len < 0 || len > length t - off | ||
| then invalid_arg "Rope.chop"; | ||
| if len = 0 then empty else unsafe_sub t off (off + len) | ||
|
|
||
| let shift t len = | ||
| if len < 0 then | ||
| invalid_arg "Rope.shift"; | ||
| if len = 0 then t | ||
| else | ||
| let max = length t in | ||
| let len = min_int max len in | ||
| let l = len + (max - len) in | ||
| unsafe_sub t len l | ||
|
|
||
| let rec last_is_nl = function | ||
| | Str (a, nl, len, off) -> if Array.length a - off = len then nl else true | ||
| | App (_, r, _) -> last_is_nl r | ||
|
|
||
| let rec byte_length = function | ||
| | Str (s, _, len, off) as a -> | ||
| let sum = ref 0 in | ||
| for idx = off to len + off - 1 do | ||
| let data = Array.unsafe_get s idx in | ||
| sum := !sum + String.length data + 1 | ||
| done; | ||
| !sum - if last_is_nl a then 0 else 1 | ||
| | App (l, r, _) -> byte_length l + byte_length r | ||
|
|
||
| let rec into_bytes buf dst_off = function | ||
| | Str (s, _, len, off) as a -> | ||
| let off' = ref dst_off in | ||
| for idx = off to len + off - 1 do | ||
| let data = Array.unsafe_get s idx in | ||
| unsafe_blit_string data 0 buf !off' (String.length data); | ||
| off' := !off' + String.length data + 1; | ||
| if idx - off < len - 1 || (idx - off = len - 1 && last_is_nl a) then | ||
| Bytes.unsafe_set buf (!off' - 1) '\n' | ||
| done | ||
| | App (l, r, _) -> | ||
| into_bytes buf dst_off l; | ||
| into_bytes buf (dst_off + byte_length l) r | ||
|
|
||
| let to_string t = | ||
| let len = byte_length t in | ||
| let buf = Bytes.create len in | ||
| into_bytes buf 0 t; | ||
| Bytes.unsafe_to_string buf | ||
|
|
||
| let concat a b = append a b | ||
|
|
||
| let of_strings xs last_is_nl = | ||
| let d = Array.of_list xs in | ||
| Str (d, last_is_nl, Array.length d, 0) | ||
|
|
||
| let of_string str = | ||
| let splitted = String.split_on_char '\n' str in | ||
| let last_is_nl = String.unsafe_get str (String.length str - 1) = '\n' in | ||
| let splitted = if last_is_nl then List.rev (List.tl (List.rev splitted)) else splitted in | ||
| let d = Array.of_list splitted in | ||
| Str (d, last_is_nl, Array.length d, 0) | ||
|
|
||
| let rec equal_to_string_list t = function | ||
| | [] -> length t = 0 | ||
| | hd :: tl -> | ||
| let rec find_data = function | ||
| | Str (data, _, len, off) -> | ||
| if len > 0 then Some (Array.get data off) else None | ||
| | App (l, r, _) -> | ||
| if length l > 0 then | ||
| find_data l | ||
| else | ||
| find_data r | ||
| in | ||
| match find_data t with | ||
| | None -> false | ||
| | Some data -> | ||
| String.equal hd data && | ||
| equal_to_string_list (shift t 1) tl | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| type t (** The type for a rope data structure *) | ||
|
|
||
| val length : t -> int | ||
| (** [length t] returns the amount of strings in [t]. *) | ||
|
|
||
| val empty : t | ||
| (** [empty] is the empty rope. *) | ||
|
|
||
| val of_strings : string list -> bool -> t | ||
| (** [of_strings xs nl] is a rope [t] which contains the strings of [xs]. If | ||
| [nl] is true, the last string will have a newline, otherwise not. *) | ||
|
|
||
| val of_string : string -> t | ||
| (** [of_string str] will split the string [str] on newline, and return a rope. *) | ||
|
|
||
| val to_string : t -> string | ||
| (** [to_string t] is the string where the contents of [t] is present. *) | ||
|
|
||
| val chop : t -> ?off:int -> int -> t | ||
| (** [chop t ~off len] returns a new rope that contains [len] strings starting | ||
| at [off] of the provided rope [t]. Raises Invalid_argument if [len] and | ||
| [off] are not inside the bounds. *) | ||
|
|
||
| val shift : t -> int -> t | ||
| (** [shift t len] returns a new rope that does not contain the first [len] | ||
| strings, but only the remaining strings of [t]. *) | ||
|
|
||
| val concat : t -> t -> t | ||
| (** [concat t t'] returns a new rope which contains [t] followed by [t']. *) | ||
|
|
||
| val last_is_nl : t -> bool | ||
| (** [last_is_nl t] returns [true] if the last string should have a newline. *) | ||
|
|
||
| val equal_to_string_list : t -> string list -> bool | ||
| (** [equal_to_string_list t xs] returns [true] if the content of [t] is equal to | ||
| the content of [xs]. *) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.