summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbaren@mit.edu>2015-08-26 20:35:02 -0400
committerGravatar Benjamin Barenblat <bbaren@mit.edu>2015-08-26 20:35:02 -0400
commit7e59cdc766d922b72f74f6c8625d7c9cdafa4752 (patch)
tree11c13991ff21a36cc343c6694b30b77c9dc5595d
parent676bae0d916ca88fe2de61a749b237d03997503d (diff)
Add functions which operate on strings instead of counted slices
-rw-r--r--src/lib.urp1
-rw-r--r--src/regex.ur58
-rw-r--r--src/regex.urs25
3 files changed, 61 insertions, 23 deletions
diff --git a/src/lib.urp b/src/lib.urp
index 1339a60..7fcdc82 100644
--- a/src/lib.urp
+++ b/src/lib.urp
@@ -10,5 +10,6 @@ file /cgGvSqBi.js regex__FFI.js
script /cgGvSqBi.js
$/list
+$/option
$/string
regex
diff --git a/src/regex.ur b/src/regex.ur
index 0024561..b379646 100644
--- a/src/regex.ur
+++ b/src/regex.ur
@@ -20,33 +20,41 @@ fun concat (strings : list string) : string =
(* Substrings and matches *)
-type substring = {Start : int, Len : int}
-type match = {Whole : substring, Groups : list substring}
+type counted_substring = {Start : int, Len : int}
+type match a = {Whole : a, Groups : list a}
-fun substring_offset (delta : int) (substring : substring) : substring =
+fun substring_offset (delta : int) (substring : counted_substring)
+ : counted_substring =
{Start = substring.Start + delta, Len = substring.Len}
-fun match_offset (delta : int) (match : match) : match =
- {Whole = substring_offset delta match.Whole,
- Groups = List.mp (substring_offset delta) match.Groups}
+fun mp [a ::: Type] [b ::: Type] (f : a -> b) (match : match a) : match b =
+ {Whole = f match.Whole, Groups = List.mp f match.Groups}
+
+fun match_offset (delta : int)
+ : match counted_substring -> match counted_substring =
+ mp (substring_offset delta)
(* Returns the index of the character just _after_ a match. *)
-fun after_match (match : match) : int =
+fun after_match (match : match counted_substring) : int =
match.Whole.Start + match.Whole.Len
+fun get_substrings (haystack : string)
+ : match counted_substring -> match string =
+ mp (String.substring haystack)
+
(* Unmarshaling FFI types *)
structure FFI = Regex__FFI
(* Unmarshals an 'FFI.substring_t' from C into Ur. *)
-fun unmarshal_substring (substring : FFI.substring_t) : substring =
+fun unmarshal_substring (substring : FFI.substring_t) : counted_substring =
{Start = FFI.substring_start substring,
Len = FFI.substring_length substring}
(* Unmarshals an 'FFI.substring_list_t' from C into Ur. *)
fun unmarshal_substring_list (substrings : FFI.substring_list_t)
- : option match =
+ : option (match counted_substring) =
case FFI.substring_list_length substrings of
0 => None
| n_groups =>
@@ -70,11 +78,14 @@ fun validate (regex : string) : string =
then regex
else error <xml>regex: Empty regex</xml>
-fun match needle haystack =
+fun match' needle haystack =
unmarshal_substring_list (FFI.do_match (validate needle) haystack)
-fun all_matches needle haystack =
- case match needle haystack of
+fun match needle haystack =
+ Option.mp (get_substrings haystack) (match' needle haystack)
+
+fun all_matches' needle haystack =
+ case match' needle haystack of
None => []
| Some match =>
let
@@ -82,14 +93,17 @@ fun all_matches needle haystack =
in
match
:: List.mp (match_offset remaining_start)
- (all_matches needle
+ (all_matches' needle
(String.suffix haystack remaining_start))
end
-fun transform needle f_nomatch f_match haystack =
+fun all_matches needle haystack =
+ List.mp (get_substrings haystack) (all_matches' needle haystack)
+
+fun transform' needle f_nomatch f_match haystack =
let
val haystack_length = String.length haystack
- val matches = all_matches needle haystack
+ val matches = all_matches' needle haystack
in
(* Handle the first nonmatching region. *)
f_nomatch {Start = 0,
@@ -122,8 +136,20 @@ fun transform needle f_nomatch f_match haystack =
matches)
end
+fun transform needle f_nomatch f_match haystack =
+ transform' needle
+ (fn s => f_nomatch (String.substring haystack s))
+ (fn m => f_match (get_substrings haystack m))
+ haystack
+
+fun transform_matches' needle f_match haystack =
+ transform' needle (String.substring haystack) f_match haystack
+
fun transform_matches needle f_match haystack =
- transform needle (String.substring haystack) f_match haystack
+ transform' needle
+ (String.substring haystack)
+ (fn m => f_match (get_substrings haystack m))
+ haystack
fun replace needle haystack replacement =
transform_matches needle (fn _ => replacement) haystack
diff --git a/src/regex.urs b/src/regex.urs
index 6e7bdcc..d3b0815 100644
--- a/src/regex.urs
+++ b/src/regex.urs
@@ -16,8 +16,8 @@ specific language governing permissions and limitations under the License. *)
This library implements ECMAScript regular expressions. *)
-type substring = {Start : int, Len : int}
-type match = {Whole : substring, Groups : list substring}
+type match a = {Whole : a, Groups : list a}
+type counted_substring = {Start : int, Len : int}
(* Searching *)
@@ -25,12 +25,14 @@ type match = {Whole : substring, Groups : list substring}
'Some match' if a match succeeds and 'None' otherwise. *)
val match : string (* needle *)
-> string (* haystack *)
- -> option match
+ -> option (match string)
+val match' : string -> string -> option (match counted_substring)
(* Finds _all_ matches for a regular expression in a string. *)
val all_matches : string (* needle *)
-> string (* haystack *)
- -> list match
+ -> list (match string)
+val all_matches' : string -> string -> list (match counted_substring)
(* Replacement *)
@@ -44,9 +46,13 @@ val replace : string (* needle *)
(* Transforms a string by applying a function to replace every match in the
string. *)
val transform_matches : string (* needle *)
- -> (match -> string) (* transformation *)
+ -> (match string -> string) (* transformation *)
-> string (* haystack *)
-> string
+val transform_matches' : string
+ -> (match counted_substring -> string)
+ -> string
+ -> string
(* Executes a general regex-guided transformation over a string. Matches
'needle' against any part of 'haystack', splitting 'haystack' into matching and
@@ -74,7 +80,12 @@ evaluates to
"_a_*x*_b_*x*__"
*)
val transform : string (* needle *)
- -> (substring -> string) (* non-matching transformation *)
- -> (match -> string) (* matching transformation *)
+ -> (string -> string) (* non-matching transformation *)
+ -> (match string -> string) (* matching transformation *)
-> string (* haystack *)
-> string
+val transform' : string
+ -> (counted_substring -> string)
+ -> (match counted_substring -> string)
+ -> string
+ -> string