on master help sign in
Add F# syntax test file
commitd395f64f580c4c8f48d5c3b2e94d78ee9001c3ef authorMohamed Abdelnour <mohamed.k.abdelnour@gmail.com> dateSat 29 May 2021, 02:23 (5 years ago) parentc962704
3 files changed+391
tests/syntax-tests/highlighted/F#/string.fs+182 tests/syntax-tests/source/F#/LICENSE.md+27 tests/syntax-tests/source/F#/string.fs+182
tests/syntax-tests/highlighted/F#/string.fsnew file+182
@@ -0,0 +1,182 @@
1+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+namespace Microsoft.FSharp.Core
4+
5+ open System
6+ open System.Text
7+ open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
8+ open Microsoft.FSharp.Core.Operators
9+ open Microsoft.FSharp.Core.Operators.Checked
10+ open Microsoft.FSharp.Collections
11+ open Microsoft.FSharp.Primitives.Basics
12+
13+ [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
14+ [<RequireQualifiedAccess>]
15+ module String =
16+ [<Literal>]
17+ /// LOH threshold is calculated from Internal.Utilities.Library.LOH_SIZE_THRESHOLD_BYTES,
18+ /// and is equal to 80_000 / sizeof<char>
19+ let LOH_CHAR_THRESHOLD = 40_000
20+
21+ [<CompiledName("Length")>]
22+ let length (str:string) = if isNull str then 0 else str.Length
23+
24+ [<CompiledName("Concat")>]
25+ let concat sep (strings : seq<string>) = 
26+
27+ let concatArray sep (strings: string []) =
28+ match length sep with
29+ | 0 -> String.Concat strings
30+ // following line should be used when this overload becomes part of .NET Standard (it's only in .NET Core)
31+ //| 1 -> String.Join(sep.[0], strings, 0, strings.Length)
32+ | _ -> String.Join(sep, strings, 0, strings.Length)
33+
34+ match strings with
35+ | :? array<string> as arr -> 
36+ concatArray sep arr
37+
38+ | :? list<string> as lst -> 
39+ lst 
40+ |> List.toArray 
41+ |> concatArray sep
42+
43+ | _ ->
44+ String.Join(sep, strings)
45+
46+ [<CompiledName("Iterate")>]
47+ let iter (action : (char -> unit)) (str:string) =
48+ if not (String.IsNullOrEmpty str) then
49+ for i = 0 to str.Length - 1 do
50+ action str.[i] 
51+
52+ [<CompiledName("IterateIndexed")>]
53+ let iteri action (str:string) =
54+ if not (String.IsNullOrEmpty str) then
55+ let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(action)
56+ for i = 0 to str.Length - 1 do
57+ f.Invoke(i, str.[i]) 
58+
59+ [<CompiledName("Map")>]
60+ let map (mapping: char -> char) (str:string) =
61+ if String.IsNullOrEmpty str then
62+ String.Empty
63+ else
64+ let result = str.ToCharArray()
65+ let mutable i = 0
66+ for c in result do
67+ result.[i] <- mapping c
68+ i <- i + 1
69+
70+ new String(result)
71+
72+ [<CompiledName("MapIndexed")>]
73+ let mapi (mapping: int -> char -> char) (str:string) =
74+ let len = length str
75+ if len = 0 then 
76+ String.Empty
77+ else
78+ let result = str.ToCharArray()
79+ let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(mapping)
80+
81+ let mutable i = 0
82+ while i < len do
83+ result.[i] <- f.Invoke(i, result.[i])
84+ i <- i + 1
85+
86+ new String(result)
87+
88+ [<CompiledName("Filter")>]
89+ let filter (predicate: char -> bool) (str:string) =
90+ let len = length str
91+
92+ if len = 0 then 
93+ String.Empty
94+
95+ elif len > LOH_CHAR_THRESHOLD then
96+ // By using SB here, which is twice slower than the optimized path, we prevent LOH allocations 
97+ // and 'stop the world' collections if the filtering results in smaller strings.
98+ // We also don't pre-allocate SB here, to allow for less mem pressure when filter result is small.
99+ let res = StringBuilder()
100+ str |> iter (fun c -> if predicate c then res.Append c |> ignore)
101+ res.ToString()
102+
103+ else
104+ // Must do it this way, since array.fs is not yet in scope, but this is safe
105+ let target = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked len
106+ let mutable i = 0
107+ for c in str do
108+ if predicate c then 
109+ target.[i] <- c
110+ i <- i + 1
111+
112+ String(target, 0, i)
113+
114+ [<CompiledName("Collect")>]
115+ let collect (mapping: char -> string) (str:string) =
116+ if String.IsNullOrEmpty str then
117+ String.Empty
118+ else
119+ let res = StringBuilder str.Length
120+ str |> iter (fun c -> res.Append(mapping c) |> ignore)
121+ res.ToString()
122+
123+ [<CompiledName("Initialize")>]
124+ let init (count:int) (initializer: int-> string) =
125+ if count < 0 then invalidArgInputMustBeNonNegative "count" count
126+ let res = StringBuilder count
127+ for i = 0 to count - 1 do 
128+ res.Append(initializer i) |> ignore
129+ res.ToString()
130+
131+ [<CompiledName("Replicate")>]
132+ let replicate (count:int) (str:string) =
133+ if count < 0 then invalidArgInputMustBeNonNegative "count" count
134+
135+ let len = length str
136+ if len = 0 || count = 0 then 
137+ String.Empty
138+
139+ elif len = 1 then
140+ new String(str.[0], count)
141+
142+ elif count <= 4 then
143+ match count with
144+ | 1 -> str
145+ | 2 -> String.Concat(str, str)
146+ | 3 -> String.Concat(str, str, str)
147+ | _ -> String.Concat(str, str, str, str)
148+
149+ else
150+ // Using the primitive, because array.fs is not yet in scope. It's safe: both len and count are positive.
151+ let target = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked (len * count)
152+ let source = str.ToCharArray()
153+
154+ // O(log(n)) performance loop:
155+ // Copy first string, then keep copying what we already copied 
156+ // (i.e., doubling it) until we reach or pass the halfway point
157+ Array.Copy(source, 0, target, 0, len)
158+ let mutable i = len
159+ while i * 2 < target.Length do
160+ Array.Copy(target, 0, target, i, i)
161+ i <- i * 2
162+
163+ // finally, copy the remain half, or less-then half
164+ Array.Copy(target, 0, target, i, target.Length - i)
165+ new String(target)
166+
167+
168+ [<CompiledName("ForAll")>]
169+ let forall predicate (str:string) =
170+ if String.IsNullOrEmpty str then
171+ true
172+ else
173+ let rec check i = (i >= str.Length) || (predicate str.[i] && check (i+1)) 
174+ check 0
175+
176+ [<CompiledName("Exists")>]
177+ let exists predicate (str:string) =
178+ if String.IsNullOrEmpty str then
179+ false
180+ else
181+ let rec check i = (i < str.Length) && (predicate str.[i] || check (i+1)) 
182+ check 0 
tests/syntax-tests/source/F#/LICENSE.mdnew file+27
@@ -0,0 +1,27 @@
1+The `string.fs` file has been added from https://github.com/dotnet/fsharp under the following license:
2+
3+```text
4+The MIT License (MIT)
5+
6+Copyright (c) Microsoft Corporation.
7+All rights reserved.
8+
9+Permission is hereby granted, free of charge, to any person obtaining a copy
10+of this software and associated documentation files (the "Software"), to deal
11+in the Software without restriction, including without limitation the rights
12+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+copies of the Software, and to permit persons to whom the Software is
14+furnished to do so, subject to the following conditions:
15+
16+The above copyright notice and this permission notice shall be included in all
17+copies or substantial portions of the Software.
18+
19+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25+SOFTWARE.
26+
27+```
tests/syntax-tests/source/F#/string.fsnew file+182
@@ -0,0 +1,182 @@
1+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+namespace Microsoft.FSharp.Core
4+
5+ open System
6+ open System.Text
7+ open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
8+ open Microsoft.FSharp.Core.Operators
9+ open Microsoft.FSharp.Core.Operators.Checked
10+ open Microsoft.FSharp.Collections
11+ open Microsoft.FSharp.Primitives.Basics
12+
13+ [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
14+ [<RequireQualifiedAccess>]
15+ module String =
16+ [<Literal>]
17+ /// LOH threshold is calculated from Internal.Utilities.Library.LOH_SIZE_THRESHOLD_BYTES,
18+ /// and is equal to 80_000 / sizeof<char>
19+ let LOH_CHAR_THRESHOLD = 40_000
20+
21+ [<CompiledName("Length")>]
22+ let length (str:string) = if isNull str then 0 else str.Length
23+
24+ [<CompiledName("Concat")>]
25+ let concat sep (strings : seq<string>) =
26+
27+ let concatArray sep (strings: string []) =
28+ match length sep with
29+ | 0 -> String.Concat strings
30+ // following line should be used when this overload becomes part of .NET Standard (it's only in .NET Core)
31+ //| 1 -> String.Join(sep.[0], strings, 0, strings.Length)
32+ | _ -> String.Join(sep, strings, 0, strings.Length)
33+
34+ match strings with
35+ | :? array<string> as arr ->
36+ concatArray sep arr
37+
38+ | :? list<string> as lst ->
39+ lst
40+ |> List.toArray
41+ |> concatArray sep
42+
43+ | _ ->
44+ String.Join(sep, strings)
45+
46+ [<CompiledName("Iterate")>]
47+ let iter (action : (char -> unit)) (str:string) =
48+ if not (String.IsNullOrEmpty str) then
49+ for i = 0 to str.Length - 1 do
50+ action str.[i]
51+
52+ [<CompiledName("IterateIndexed")>]
53+ let iteri action (str:string) =
54+ if not (String.IsNullOrEmpty str) then
55+ let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(action)
56+ for i = 0 to str.Length - 1 do
57+ f.Invoke(i, str.[i])
58+
59+ [<CompiledName("Map")>]
60+ let map (mapping: char -> char) (str:string) =
61+ if String.IsNullOrEmpty str then
62+ String.Empty
63+ else
64+ let result = str.ToCharArray()
65+ let mutable i = 0
66+ for c in result do
67+ result.[i] <- mapping c
68+ i <- i + 1
69+
70+ new String(result)
71+
72+ [<CompiledName("MapIndexed")>]
73+ let mapi (mapping: int -> char -> char) (str:string) =
74+ let len = length str
75+ if len = 0 then
76+ String.Empty
77+ else
78+ let result = str.ToCharArray()
79+ let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(mapping)
80+
81+ let mutable i = 0
82+ while i < len do
83+ result.[i] <- f.Invoke(i, result.[i])
84+ i <- i + 1
85+
86+ new String(result)
87+
88+ [<CompiledName("Filter")>]
89+ let filter (predicate: char -> bool) (str:string) =
90+ let len = length str
91+
92+ if len = 0 then
93+ String.Empty
94+
95+ elif len > LOH_CHAR_THRESHOLD then
96+ // By using SB here, which is twice slower than the optimized path, we prevent LOH allocations
97+ // and 'stop the world' collections if the filtering results in smaller strings.
98+ // We also don't pre-allocate SB here, to allow for less mem pressure when filter result is small.
99+ let res = StringBuilder()
100+ str |> iter (fun c -> if predicate c then res.Append c |> ignore)
101+ res.ToString()
102+
103+ else
104+ // Must do it this way, since array.fs is not yet in scope, but this is safe
105+ let target = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked len
106+ let mutable i = 0
107+ for c in str do
108+ if predicate c then
109+ target.[i] <- c
110+ i <- i + 1
111+
112+ String(target, 0, i)
113+
114+ [<CompiledName("Collect")>]
115+ let collect (mapping: char -> string) (str:string) =
116+ if String.IsNullOrEmpty str then
117+ String.Empty
118+ else
119+ let res = StringBuilder str.Length
120+ str |> iter (fun c -> res.Append(mapping c) |> ignore)
121+ res.ToString()
122+
123+ [<CompiledName("Initialize")>]
124+ let init (count:int) (initializer: int-> string) =
125+ if count < 0 then invalidArgInputMustBeNonNegative "count" count
126+ let res = StringBuilder count
127+ for i = 0 to count - 1 do
128+ res.Append(initializer i) |> ignore
129+ res.ToString()
130+
131+ [<CompiledName("Replicate")>]
132+ let replicate (count:int) (str:string) =
133+ if count < 0 then invalidArgInputMustBeNonNegative "count" count
134+
135+ let len = length str
136+ if len = 0 || count = 0 then
137+ String.Empty
138+
139+ elif len = 1 then
140+ new String(str.[0], count)
141+
142+ elif count <= 4 then
143+ match count with
144+ | 1 -> str
145+ | 2 -> String.Concat(str, str)
146+ | 3 -> String.Concat(str, str, str)
147+ | _ -> String.Concat(str, str, str, str)
148+
149+ else
150+ // Using the primitive, because array.fs is not yet in scope. It's safe: both len and count are positive.
151+ let target = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked (len * count)
152+ let source = str.ToCharArray()
153+
154+ // O(log(n)) performance loop:
155+ // Copy first string, then keep copying what we already copied
156+ // (i.e., doubling it) until we reach or pass the halfway point
157+ Array.Copy(source, 0, target, 0, len)
158+ let mutable i = len
159+ while i * 2 < target.Length do
160+ Array.Copy(target, 0, target, i, i)
161+ i <- i * 2
162+
163+ // finally, copy the remain half, or less-then half
164+ Array.Copy(target, 0, target, i, target.Length - i)
165+ new String(target)
166+
167+
168+ [<CompiledName("ForAll")>]
169+ let forall predicate (str:string) =
170+ if String.IsNullOrEmpty str then
171+ true
172+ else
173+ let rec check i = (i >= str.Length) || (predicate str.[i] && check (i+1))
174+ check 0
175+
176+ [<CompiledName("Exists")>]
177+ let exists predicate (str:string) =
178+ if String.IsNullOrEmpty str then
179+ false
180+ else
181+ let rec check i = (i < str.Length) && (predicate str.[i] || check (i+1))
182+ check 0