Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
fsharp
提交
4990f64f
F
fsharp
项目概览
dotNET Platform
/
fsharp
10 个月 前同步成功
通知
0
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
fsharp
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
4990f64f
编写于
5月 20, 2022
作者:
D
Don Syme
提交者:
GitHub
5月 20, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Apply formatting to "Utilities" (#13171)
* change formatting settings * apply formatting
上级
e8fc5fb1
变更
20
展开全部
隐藏空白更改
内联
并排
Showing
20 changed file
with
3960 addition
and
2678 deletion
+3960
-2678
.fantomasignore
.fantomasignore
+4
-2
src/Compiler/Utilities/EditDistance.fs
src/Compiler/Utilities/EditDistance.fs
+54
-37
src/Compiler/Utilities/FileSystem.fs
src/Compiler/Utilities/FileSystem.fs
+336
-223
src/Compiler/Utilities/HashMultiMap.fs
src/Compiler/Utilities/HashMultiMap.fs
+73
-60
src/Compiler/Utilities/ImmutableArray.fs
src/Compiler/Utilities/ImmutableArray.fs
+69
-31
src/Compiler/Utilities/InternalCollections.fs
src/Compiler/Utilities/InternalCollections.fs
+160
-121
src/Compiler/Utilities/PathMap.fs
src/Compiler/Utilities/PathMap.fs
+18
-13
src/Compiler/Utilities/QueueList.fs
src/Compiler/Utilities/QueueList.fs
+48
-31
src/Compiler/Utilities/ResizeArray.fs
src/Compiler/Utilities/ResizeArray.fs
+273
-147
src/Compiler/Utilities/RidHelpers.fs
src/Compiler/Utilities/RidHelpers.fs
+10
-4
src/Compiler/Utilities/TaggedCollections.fs
src/Compiler/Utilities/TaggedCollections.fs
+755
-521
src/Compiler/Utilities/XmlAdapters.fs
src/Compiler/Utilities/XmlAdapters.fs
+3
-4
src/Compiler/Utilities/ildiag.fs
src/Compiler/Utilities/ildiag.fs
+38
-15
src/Compiler/Utilities/illib.fs
src/Compiler/Utilities/illib.fs
+761
-495
src/Compiler/Utilities/range.fs
src/Compiler/Utilities/range.fs
+210
-147
src/Compiler/Utilities/rational.fs
src/Compiler/Utilities/rational.fs
+52
-37
src/Compiler/Utilities/sformat.fs
src/Compiler/Utilities/sformat.fs
+954
-678
src/Compiler/Utilities/sr.fs
src/Compiler/Utilities/sr.fs
+90
-73
src/Compiler/Utilities/zmap.fs
src/Compiler/Utilities/zmap.fs
+35
-27
src/Compiler/Utilities/zset.fs
src/Compiler/Utilities/zset.fs
+17
-12
未找到文件。
.fantomasignore
浏览文件 @
4990f64f
...
...
@@ -13,7 +13,6 @@ vsintegration/
# Explicitly unformatted implementation files
src/FSharp.Core/**/*.fs
src/Compiler/**/*.fs
src/Compiler/AbstractIL/**/*.fs
src/Compiler/Checking/**/*.fs
src/Compiler/CodeGen/**/*.fs
...
...
@@ -27,9 +26,12 @@ src/Compiler/Service/**/*.fs
src/Compiler/Symbols/**/*.fs
src/Compiler/SyntaxTree/**/*.fs
src/Compiler/TypedTree/**/*.fs
src/Compiler/Utilities/**/*.fs
src/Microsoft.FSharp.Compiler/**/*.fs
# Fantomas limitations on implementation files (to investigate)
src/Compiler/Utilities/lib.fs
# Fantomas limitations on signature files (to investigate)
src/Compiler/AbstractIL/ilread.fsi
...
...
src/Compiler/Utilities/EditDistance.fs
浏览文件 @
4990f64f
...
...
@@ -8,24 +8,28 @@ open System
/// Given an offset and a radius from that offset, does mChar exist in that part of str?
let
inline
existsInWin
(
mChar
:
char
)
(
str
:
string
)
(
offset
:
int
)
(
rad
:
int
)
=
let
startAt
=
Math
.
Max
(
0
,
offset
-
rad
)
let
endAt
=
Math
.
Min
(
offset
+
rad
,
str
.
Length
-
1
)
if
endAt
-
startAt
<
0
then
false
let
endAt
=
Math
.
Min
(
offset
+
rad
,
str
.
Length
-
1
)
if
endAt
-
startAt
<
0
then
false
else
let
rec
exists
index
=
if
str
[
index
]
=
mChar
then
true
elif
index
=
endAt
then
false
else
exists
(
index
+
1
)
exists
startAt
let
jaro
(
s1
:
string
)
(
s2
:
string
)
=
let
jaro
(
s1
:
string
)
(
s2
:
string
)
=
// The radius is half of the lesser of the two string lengths rounded up.
let
matchRadius
=
let
matchRadius
=
let
minLen
=
Math
.
Min
(
s1
.
Length
,
s2
.
Length
)
minLen
/
2
+
minLen
%
2
let
rec
nextChar
(
s1
:
string
)
(
s2
:
string
)
i
c
=
let
rec
nextChar
(
s1
:
string
)
(
s2
:
string
)
i
c
=
if
i
<
s1
.
Length
then
let
c
=
s1
[
i
]
if
not
(
existsInWin
c
s2
i
matchRadius
)
then
nextChar
s1
s2
(
i
+
1
)
c
else
...
...
@@ -33,52 +37,67 @@ let jaro (s1: string) (s2: string) =
else
struct
(
i
,
c
)
// The sets of common characters and their lengths as floats
// The sets of common characters and their lengths as floats
// The number of transpositions within the sets of common characters.
let
struct
(
transpositions
,
c1length
,
c2length
)
=
let
rec
loop
i
j
mismatches
c1length
c2length
=
if
i
<
s1
.
Length
&&
j
<
s2
.
Length
then
let
struct
(
ti
,
ci
)
=
nextChar
s1
s2
i
'
'
let
struct
(
tj
,
cj
)
=
nextChar
s2
s1
j
'
'
if
ci
<>
cj
then
loop
(
ti
+
1
)
(
tj
+
1
)
(
mismatches
+
1
)
(
c1length
+
1
)
(
c2length
+
1
)
else
loop
(
ti
+
1
)
(
tj
+
1
)
mismatches
(
c1length
+
1
)
(
c2length
+
1
)
else
struct
(
i
,
j
,
mismatches
,
c1length
,
c2length
)
else
struct
(
i
,
j
,
mismatches
,
c1length
,
c2length
)
let
struct
(
i
,
j
,
mismatches
,
c1length
,
c2length
)
=
loop
0
0
0
0
0
let
rec
loop
(
s1
:
string
)
(
s2
:
string
)
i
length
=
let
rec
loop
(
s1
:
string
)
(
s2
:
string
)
i
length
=
if
i
<
s1
.
Length
-
1
then
let
c
=
s1
[
i
]
if
existsInWin
c
s2
i
matchRadius
then
if
existsInWin
c
s2
i
matchRadius
then
loop
s1
s2
(
i
+
1
)
(
length
+
1
)
else
loop
s1
s2
(
i
+
1
)
length
else
length
let
c1length
=
loop
s1
s2
i
c1length
|>
float
let
c2length
=
loop
s2
s1
j
c2length
|>
float
struct
((
float
mismatches
+
abs
(
c1length
-
c2length
))
/
2
.
0
,
c1length
,
c2length
)
let
tLength
=
Math
.
Max
(
c1length
,
c2length
)
// The jaro distance as given by 1/3 ( m2/|s1| + m1/|s2| + (mc-t)/mc )
let
result
=
(
c1length
/
float
s1
.
Length
+
c2length
/
float
s2
.
Length
+
(
tLength
-
transpositions
)
/
tLength
)
/
3
.
0
// This is for cases where |s1|, |s2| or m are zero
if
Double
.
IsNaN
result
then
0
.
0
else
result
let
result
=
(
c1length
/
float
s1
.
Length
+
c2length
/
float
s2
.
Length
+
(
tLength
-
transpositions
)
/
tLength
)
/
3
.
0
// This is for cases where |s1|, |s2| or m are zero
if
Double
.
IsNaN
result
then
0
.
0
else
result
/// Calculates the Jaro-Winkler edit distance between two strings.
/// The edit distance is a metric that allows to measure the amount of similarity between two strings.
let
JaroWinklerDistance
s1
s2
=
let
JaroWinklerDistance
s1
s2
=
let
jaroScore
=
jaro
s1
s2
// Accumulate the number of matching initial characters
let
maxLength
=
(
min
s1
.
Length
s2
.
Length
)
-
1
let
rec
calcL
i
acc
=
if
i
>
maxLength
||
s1
[
i
]
<>
s2
[
i
]
then
acc
else
calcL
(
i
+
1
)
(
acc
+
1
.
0
)
if
i
>
maxLength
||
s1
[
i
]
<>
s2
[
i
]
then
acc
else
calcL
(
i
+
1
)
(
acc
+
1
.
0
)
let
l
=
min
(
calcL
0
0
.
0
)
4
.
0
// Calculate the JW distance
let
p
=
0
.
1
...
...
@@ -88,7 +107,7 @@ let JaroWinklerDistance s1 s2 =
/// also known as the "optimal string alignment" distance.
/// - read more at https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance
/// - Implementation taken from http://www.navision-blog.de/2008/11/01/damerau-levenshtein-distance-in-fsharp-part-ii/
let
private
calcDamerauLevenshtein
(
a
:
string
,
b
:
string
)
=
let
private
calcDamerauLevenshtein
(
a
:
string
,
b
:
string
)
=
let
m
=
b
.
Length
+
1
let
mutable
lastLine
=
Array
.
init
m
id
let
mutable
lastLastLine
=
Array
.
zeroCreate
m
...
...
@@ -96,34 +115,32 @@ let private calcDamerauLevenshtein (a:string, b:string) =
for
i
in
1
..
a
.
Length
do
actLine
[
0
]
<-
i
for
j
in
1
..
b
.
Length
do
let
cost
=
if
a
[
i
-
1
]
=
b
[
j
-
1
]
then
0
else
1
let
cost
=
if
a
[
i
-
1
]
=
b
[
j
-
1
]
then
0
else
1
let
deletion
=
lastLine
[
j
]
+
1
let
insertion
=
actLine
[
j
-
1
]
+
1
let
substitution
=
lastLine
[
j
-
1
]
+
cost
actLine
[
j
]
<-
deletion
|>
min
insertion
|>
min
substitution
let
insertion
=
actLine
[
j
-
1
]
+
1
let
substitution
=
lastLine
[
j
-
1
]
+
cost
actLine
[
j
]
<-
deletion
|>
min
insertion
|>
min
substitution
if
i
>
1
&&
j
>
1
then
if
a
[
i
-
1
]
=
b
[
j
-
2
]
&&
a
[
i
-
2
]
=
b
[
j
-
1
]
then
let
transposition
=
lastLastLine
[
j
-
2
]
+
cost
actLine
[
j
]
<-
min
actLine
[
j
]
transposition
if
a
[
i
-
1
]
=
b
[
j
-
2
]
&&
a
[
i
-
2
]
=
b
[
j
-
1
]
then
let
transposition
=
lastLastLine
[
j
-
2
]
+
cost
actLine
[
j
]
<-
min
actLine
[
j
]
transposition
// swap lines
let
temp
=
lastLastLine
lastLastLine
<-
lastLine
lastLine
<-
actLine
actLine
<-
temp
lastLine
[
b
.
Length
]
/// Calculates the edit distance between two strings.
/// The edit distance is a metric that allows to measure the amount of difference between two strings
/// The edit distance is a metric that allows to measure the amount of difference between two strings
/// and shows how many edit operations (insert, delete, substitution) are needed to transform one string into the other.
let
CalculateEditDistance
(
a
:
string
,
b
:
string
)
=
let
CalculateEditDistance
(
a
:
string
,
b
:
string
)
=
if
a
.
Length
>
b
.
Length
then
calcDamerauLevenshtein
(
a
,
b
)
calcDamerauLevenshtein
(
a
,
b
)
else
calcDamerauLevenshtein
(
b
,
a
)
\ No newline at end of file
calcDamerauLevenshtein
(
b
,
a
)
src/Compiler/Utilities/FileSystem.fs
浏览文件 @
4990f64f
此差异已折叠。
点击以展开。
src/Compiler/Utilities/HashMultiMap.fs
浏览文件 @
4990f64f
...
...
@@ -3,81 +3,86 @@
namespace
Internal
.
Utilities
.
Collections
open
System
.
Collections
.
Generic
// Each entry in the HashMultiMap dictionary has at least one entry. Under normal usage each entry has _only_
// one entry. So use two hash tables: one for the main entries and one for the overflow.
[<
Sealed
>]
type
internal
HashMultiMap
<
'
Key
,
'
Value
>(
size
:
int
,
comparer
:
IEqualityComparer
<
'
Key
>)
=
type
internal
HashMultiMap
<
'
Key
,
'
Value
>(
size
:
int
,
comparer
:
IEqualityComparer
<
'
Key
>)
=
let
firstEntries
=
Dictionary
<_,
_>(
size
,
comparer
)
let
firstEntries
=
Dictionary
<_,_>(
size
,
comparer
)
let
rest
=
Dictionary
<_,
_>(
3
,
comparer
)
let
rest
=
Dictionary
<_,_>(
3
,
comparer
)
new
(
comparer
:
IEqualityComparer
<
'
Key
>)
=
HashMultiMap
<
'
Key
,
'
Value
>(
11
,
comparer
)
new
(
comparer
:
IEqualityComparer
<
'
Key
>)
=
HashMultiMap
<
'
Key
,
'
Value
>(
11
,
comparer
)
new
(
entries
:
seq
<
'
Key
*
'
Value
>,
comparer
:
IEqualityComparer
<
'
Key
>)
as
x
=
new
HashMultiMap
<
'
Key
,
'
Value
>(
11
,
comparer
)
then
entries
|>
Seq
.
iter
(
fun
(
k
,
v
)
->
x
.
Add
(
k
,
v
))
new
(
entries
:
seq
<
'
Key
*
'
Value
>,
comparer
:
IEqualityComparer
<
'
Key
>)
as
x
=
new
HashMultiMap
<
'
Key
,
'
Value
>(
11
,
comparer
)
then
entries
|>
Seq
.
iter
(
fun
(
k
,
v
)
->
x
.
Add
(
k
,
v
))
member
x
.
GetRest
(
k
)
=
match
rest
.
TryGetValue
k
with
|
true
,
res
->
res
|
_
->
[]
member
x
.
Add
(
y
,
z
)
=
member
x
.
Add
(
y
,
z
)
=
match
firstEntries
.
TryGetValue
y
with
|
true
,
res
->
rest
[
y
]
<-
res
::
x
.
GetRest
(
y
)
|
true
,
res
->
rest
[
y
]
<-
res
::
x
.
GetRest
(
y
)
|
_
->
()
firstEntries
[
y
]
<-
z
member
x
.
Clear
()
=
firstEntries
.
Clear
()
rest
.
Clear
()
member
x
.
Clear
()
=
firstEntries
.
Clear
()
rest
.
Clear
()
member
x
.
FirstEntries
=
firstEntries
member
x
.
Rest
=
rest
member
x
.
Copy
()
=
let
res
=
HashMultiMap
<
'
Key
,
'
Value
>(
firstEntries
.
Count
,
firstEntries
.
Comparer
)
for
kvp
in
firstEntries
do
res
.
FirstEntries
.
Add
(
kvp
.
Key
,
kvp
.
Value
)
member
x
.
Copy
()
=
let
res
=
HashMultiMap
<
'
Key
,
'
Value
>(
firstEntries
.
Count
,
firstEntries
.
Comparer
)
for
kvp
in
firstEntries
do
res
.
FirstEntries
.
Add
(
kvp
.
Key
,
kvp
.
Value
)
for
kvp
in
rest
do
res
.
Rest
.
Add
(
kvp
.
Key
,
kvp
.
Value
)
for
kvp
in
rest
do
res
.
Rest
.
Add
(
kvp
.
Key
,
kvp
.
Value
)
res
member
x
.
Item
with
get
(
y
:
'
Key
)
=
member
x
.
Item
with
get
(
y
:
'
Key
)
=
match
firstEntries
.
TryGetValue
y
with
|
true
,
res
->
res
|
_
->
raise
(
KeyNotFoundException
(
"The item was not found in collection"
))
and
set
(
y
:
'
Key
)
(
z
:
'
Value
)
=
x
.
Replace
(
y
,
z
)
and
set
(
y
:
'
Key
)
(
z
:
'
Value
)
=
x
.
Replace
(
y
,
z
)
member
x
.
FindAll
(
y
)
=
member
x
.
FindAll
(
y
)
=
match
firstEntries
.
TryGetValue
y
with
|
true
,
res
->
res
::
x
.
GetRest
(
y
)
|
_
->
[]
member
x
.
Fold
f
acc
=
member
x
.
Fold
f
acc
=
let
mutable
res
=
acc
for
kvp
in
firstEntries
do
res
<-
f
kvp
.
Key
kvp
.
Value
res
match
x
.
GetRest
(
kvp
.
Key
)
with
|
[]
->
()
|
rest
->
|
rest
->
for
z
in
rest
do
res
<-
f
kvp
.
Key
z
res
res
member
x
.
Iterate
(
f
)
=
member
x
.
Iterate
(
f
)
=
for
kvp
in
firstEntries
do
f
kvp
.
Key
kvp
.
Value
match
x
.
GetRest
(
kvp
.
Key
)
with
|
[]
->
()
|
rest
->
|
rest
->
for
z
in
rest
do
f
kvp
.
Key
z
...
...
@@ -85,28 +90,25 @@ type internal HashMultiMap<'Key,'Value>(size: int, comparer: IEqualityComparer<'
member
x
.
ContainsKey
(
y
)
=
firstEntries
.
ContainsKey
(
y
)
member
x
.
Remove
(
y
)
=
member
x
.
Remove
(
y
)
=
match
firstEntries
.
TryGetValue
y
with
// NOTE: If not ok then nothing to remove - nop
|
true
,
_
res
->
// We drop the FirstEntry. Here we compute the new FirstEntry and residue MoreEntries
match
rest
.
TryGetValue
y
with
|
true
,
res
->
match
res
with
|
[
h
]
->
firstEntries
[
y
]
<-
h
;
match
res
with
|
[
h
]
->
firstEntries
[
y
]
<-
h
rest
.
Remove
(
y
)
|>
ignore
|
h
::
t
->
|
h
::
t
->
firstEntries
[
y
]
<-
h
rest
[
y
]
<-
t
|
_
->
()
|
_
->
firstEntries
.
Remove
(
y
)
|>
ignore
|
_
->
()
|
_
->
firstEntries
.
Remove
(
y
)
|>
ignore
|
_
->
()
member
x
.
Replace
(
y
,
z
)
=
firstEntries
[
y
]
<-
z
member
x
.
Replace
(
y
,
z
)
=
firstEntries
[
y
]
<-
z
member
x
.
TryFind
(
y
)
=
match
firstEntries
.
TryGetValue
y
with
...
...
@@ -117,49 +119,60 @@ type internal HashMultiMap<'Key,'Value>(size: int, comparer: IEqualityComparer<'
interface
IEnumerable
<
KeyValuePair
<
'
Key
,
'
Value
>>
with
member
s
.
GetEnumerator
()
=
member
s
.
GetEnumerator
()
=
let
elems
=
List
<_>(
firstEntries
.
Count
+
rest
.
Count
)
for
kvp
in
firstEntries
do
elems
.
Add
(
kvp
)
for
z
in
s
.
GetRest
(
kvp
.
Key
)
do
elems
.
Add
(
KeyValuePair
(
kvp
.
Key
,
z
))
elems
.
Add
(
KeyValuePair
(
kvp
.
Key
,
z
))
(
elems
.
GetEnumerator
()
:>
IEnumerator
<_>)
interface
System
.
Collections
.
IEnumerable
with
member
s
.
GetEnumerator
()
=
((
s
:>
seq
<_>).
GetEnumerator
()
:>
System
.
Collections
.
IEnumerator
)
member
s
.
GetEnumerator
()
=
((
s
:>
seq
<_>).
GetEnumerator
()
:>
System
.
Collections
.
IEnumerator
)
interface
IDictionary
<
'
Key
,
'
Value
>
with
interface
IDictionary
<
'
Key
,
'
Value
>
with
member
s
.
Item
with
get
x
=
s
[
x
]
and
set
x
v
=
s
[
x
]
<-
v
member
s
.
Item
with
get
x
=
s
[
x
]
and
set
x
v
=
s
[
x
]
<-
v
member
s
.
Keys
=
([|
for
kvp
in
s
->
kvp
.
Key
|]
:>
ICollection
<
'
Key
>)
member
s
.
Values
=
([|
for
kvp
in
s
->
kvp
.
Value
|]
:>
ICollection
<
'
Value
>)
member
s
.
Add
(
k
,
v
)
=
s
[
k
]
<-
v
member
s
.
Add
(
k
,
v
)
=
s
[
k
]
<-
v
member
s
.
ContainsKey
(
k
)
=
s
.
ContainsKey
(
k
)
member
s
.
TryGetValue
(
k
,
r
)
=
match
s
.
TryFind
k
with
Some
v
->
(
r
<-
v
;
true
)
|
_
->
false
member
s
.
TryGetValue
(
k
,
r
)
=
match
s
.
TryFind
k
with
|
Some
v
->
(
r
<-
v
true
)
|
_
->
false
member
s
.
Remove
(
k
:
'
Key
)
=
let
res
=
s
.
ContainsKey
(
k
)
in
s
.
Remove
(
k
);
res
member
s
.
Remove
(
k
:
'
Key
)
=
let
res
=
s
.
ContainsKey
(
k
)
in
s
.
Remove
(
k
)
res
interface
ICollection
<
KeyValuePair
<
'
Key
,
'
Value
>>
with
interface
ICollection
<
KeyValuePair
<
'
Key
,
'
Value
>>
with
member
s
.
Add
(
x
)
=
s
[
x
.
Key
]
<-
x
.
Value
member
s
.
Clear
()
=
s
.
Clear
()
member
s
.
Clear
()
=
s
.
Clear
()
member
s
.
Remove
(
x
)
=
member
s
.
Remove
(
x
)
=
match
s
.
TryFind
x
.
Key
with
|
Some
v
->
|
Some
v
->
if
Unchecked
.
equals
v
x
.
Value
then
s
.
Remove
(
x
.
Key
)
true
|
_
->
false
...
...
@@ -168,9 +181,9 @@ type internal HashMultiMap<'Key,'Value>(size: int, comparer: IEqualityComparer<'
|
Some
v
when
Unchecked
.
equals
v
x
.
Value
->
true
|
_
->
false
member
s
.
CopyTo
(
arr
,
arrIndex
)
=
s
|>
Seq
.
iteri
(
fun
j
x
->
arr
[
arrIndex
+
j
]
<-
x
)
member
s
.
CopyTo
(
arr
,
arrIndex
)
=
s
|>
Seq
.
iteri
(
fun
j
x
->
arr
[
arrIndex
+
j
]
<-
x
)
member
s
.
IsReadOnly
=
false
member
s
.
Count
=
s
.
Count
src/Compiler/Utilities/ImmutableArray.fs
浏览文件 @
4990f64f
...
...
@@ -5,8 +5,7 @@ open System.Collections.Immutable
[<
RequireQualifiedAccess
>]
module
ImmutableArrayBuilder
=
let
create
size
:
ImmutableArray
<
'
T
>.
Builder
=
ImmutableArray
.
CreateBuilder
(
size
)
let
create
size
:
ImmutableArray
<
'
T
>.
Builder
=
ImmutableArray
.
CreateBuilder
(
size
)
[<
RequireQualifiedAccess
>]
module
ImmutableArray
=
...
...
@@ -23,8 +22,10 @@ module ImmutableArray =
invalidArg
"n"
"Below zero."
let
builder
=
ImmutableArray
.
CreateBuilder
(
n
)
for
i
=
0
to
n
-
1
do
builder
.
Add
(
f
i
)
builder
.
MoveToImmutable
()
let
iter
f
(
arr
:
ImmutableArray
<
'
T
>)
=
...
...
@@ -55,8 +56,10 @@ module ImmutableArray =
|
1
->
ImmutableArray
.
Create
(
mapper
arr
[
0
])
|
_
->
let
builder
=
ImmutableArray
.
CreateBuilder
(
arr
.
Length
)
for
i
=
0
to
arr
.
Length
-
1
do
builder
.
Add
(
mapper
arr
[
i
])
builder
.
MoveToImmutable
()
let
mapi
(
mapper
:
int
->
'
T
->
'
U
)
(
arr
:
ImmutableArray
<
'
T
>)
:
ImmutableArray
<_>
=
...
...
@@ -65,120 +68,155 @@ module ImmutableArray =
|
1
->
ImmutableArray
.
Create
(
mapper
0
arr
[
0
])
|
_
->
let
builder
=
ImmutableArray
.
CreateBuilder
(
arr
.
Length
)
for
i
=
0
to
arr
.
Length
-
1
do
builder
.
Add
(
mapper
i
arr
[
i
])
builder
.
MoveToImmutable
()
let
map2
(
mapper
:
'
T1
->
'
T2
->
'
T
)
(
arr1
:
ImmutableArray
<
'
T1
>)
(
arr2
:
ImmutableArray
<
'
T2
>)
:
ImmutableArray
<_>
=
if
arr1
.
Length
<>
arr2
.
Length
then
invalidOp
"Block lengths do not match."
match
arr1
.
Length
with
|
0
->
ImmutableArray
.
Empty
|
1
->
ImmutableArray
.
Create
(
mapper
arr1
[
0
]
arr2
[
0
])
|
n
->
let
builder
=
ImmutableArray
.
CreateBuilder
(
n
)
for
i
=
0
to
n
-
1
do
builder
.
Add
(
mapper
arr1
[
i
]
arr2
[
i
])
builder
.
MoveToImmutable
()
let
mapi2
(
mapper
:
int
->
'
T1
->
'
T2
->
'
T
)
(
arr1
:
ImmutableArray
<
'
T1
>)
(
arr2
:
ImmutableArray
<
'
T2
>)
:
ImmutableArray
<_>
=
if
arr1
.
Length
<>
arr2
.
Length
then
invalidOp
"Block lengths do not match."
match
arr1
.
Length
with
|
0
->
ImmutableArray
.
Empty
|
1
->
ImmutableArray
.
Create
(
mapper
0
arr1
[
0
]
arr2
[
0
])
|
n
->
let
builder
=
ImmutableArray
.
CreateBuilder
(
n
)
for
i
=
0
to
n
-
1
do
builder
.
Add
(
mapper
i
arr1
[
i
]
arr2
[
i
])
builder
.
MoveToImmutable
()
let
concat
(
arrs
:
ImmutableArray
<
ImmutableArray
<
'
T
>>)
:
ImmutableArray
<
'
T
>
=
match
arrs
.
Length
with
|
0
->
ImmutableArray
.
Empty
|
1
->
arrs
[
0
]
|
2
->
arrs
[
0
].
AddRange
(
arrs
[
1
])
|
2
->
arrs
[
0
].
AddRange
(
arrs
[
1
])
|
_
->
let
mutable
acc
=
0
let
mutable
acc
=
0
for
h
in
arrs
do
acc
<-
acc
+
h
.
Length
let
builder
=
ImmutableArray
.
CreateBuilder
(
acc
)
for
i
=
0
to
arrs
.
Length
-
1
do
builder
.
AddRange
(
arrs
[
i
])
builder
.
MoveToImmutable
()
let
forall
predicate
(
arr
:
ImmutableArray
<
'
T
>)
=
let
len
=
arr
.
Length
let
rec
loop
i
=
i
>=
len
||
(
predicate
arr
[
i
]
&&
loop
(
i
+
1
))
let
rec
loop
i
=
i
>=
len
||
(
predicate
arr
[
i
]
&&
loop
(
i
+
1
))
loop
0
let
forall2
predicate
(
arr1
:
ImmutableArray
<
'
T1
>)
(
arr2
:
ImmutableArray
<
'
T2
>)
=
if
arr1
.
Length
<>
arr2
.
Length
then
invalidOp
"Block lengths do not match."
let
f
=
OptimizedClosures
.
FSharpFunc
<_,
_,
_>.
Adapt
(
predicate
)
let
f
=
OptimizedClosures
.
FSharpFunc
<_,
_,
_>.
Adapt
(
predicate
)
let
len1
=
arr1
.
Length
let
rec
loop
i
=
i
>=
len1
||
(
f
.
Invoke
(
arr1
[
i
],
arr2
[
i
])
&&
loop
(
i
+
1
))
let
rec
loop
i
=
i
>=
len1
||
(
f
.
Invoke
(
arr1
[
i
],
arr2
[
i
])
&&
loop
(
i
+
1
))
loop
0
let
tryFind
predicate
(
arr
:
ImmutableArray
<
'
T
>)
=
let
rec
loop
i
=
if
i
>=
arr
.
Length
then
None
else
if
predicate
arr
[
i
]
then
Some
arr
[
i
]
else
loop
(
i
+
1
)
loop
0
let
rec
loop
i
=
if
i
>=
arr
.
Length
then
None
else
if
predicate
arr
[
i
]
then
Some
arr
[
i
]
else
loop
(
i
+
1
)
loop
0
let
tryFindIndex
predicate
(
arr
:
ImmutableArray
<
'
T
>)
=
let
len
=
arr
.
Length
let
rec
go
n
=
if
n
>=
len
then
None
elif
predicate
arr
[
n
]
then
Some
n
else
go
(
n
+
1
)
go
0
let
len
=
arr
.
Length
let
rec
go
n
=
if
n
>=
len
then
None
elif
predicate
arr
[
n
]
then
Some
n
else
go
(
n
+
1
)
go
0
let
tryPick
chooser
(
arr
:
ImmutableArray
<
'
T
>)
=
let
rec
loop
i
=
if
i
>=
arr
.
Length
then
None
else
match
chooser
arr
[
i
]
with
|
None
->
loop
(
i
+
1
)
|
res
->
res
loop
0
let
rec
loop
i
=
if
i
>=
arr
.
Length
then
None
else
match
chooser
arr
[
i
]
with
|
None
->
loop
(
i
+
1
)
|
res
->
res
loop
0
let
ofSeq
(
xs
:
'
T
seq
)
=
ImmutableArray
.
CreateRange
(
xs
)
let
ofSeq
(
xs
:
'
T
seq
)
=
ImmutableArray
.
CreateRange
(
xs
)
let
append
(
arr1
:
ImmutableArray
<
'
T1
>)
(
arr2
:
ImmutableArray
<
'
T1
>)
:
ImmutableArray
<_>
=
arr1
.
AddRange
(
arr2
)
let
append
(
arr1
:
ImmutableArray
<
'
T1
>)
(
arr2
:
ImmutableArray
<
'
T1
>)
:
ImmutableArray
<_>
=
arr1
.
AddRange
(
arr2
)
let
createOne
(
item
:
'
T
)
:
ImmutableArray
<_>
=
ImmutableArray
.
Create
(
item
)
let
createOne
(
item
:
'
T
)
:
ImmutableArray
<_>
=
ImmutableArray
.
Create
(
item
)
let
filter
predicate
(
arr
:
ImmutableArray
<
'
T
>)
:
ImmutableArray
<
'
T
>
=
let
builder
=
ImmutableArray
.
CreateBuilder
(
arr
.
Length
)
for
i
=
0
to
arr
.
Length
-
1
do
if
predicate
arr
[
i
]
then
builder
.
Add
(
arr
[
i
])
builder
.
Capacity
<-
builder
.
Count
builder
.
MoveToImmutable
()
let
exists
predicate
(
arr
:
ImmutableArray
<
'
T
>)
=
let
len
=
arr
.
Length
let
rec
loop
i
=
i
<
len
&&
(
predicate
arr
[
i
]
||
loop
(
i
+
1
))
let
rec
loop
i
=
i
<
len
&&
(
predicate
arr
[
i
]
||
loop
(
i
+
1
))
len
>
0
&&
loop
0
let
choose
(
chooser
:
'
T
->
'
U
option
)
(
arr
:
ImmutableArray
<
'
T
>)
:
ImmutableArray
<
'
U
>
=
let
builder
=
ImmutableArray
.
CreateBuilder
(
arr
.
Length
)
for
i
=
0
to
arr
.
Length
-
1
do
let
result
=
chooser
arr
[
i
]
if
result
.
IsSome
then
builder
.
Add
(
result
.
Value
)
builder
.
Capacity
<-
builder
.
Count
builder
.
MoveToImmutable
()
let
isEmpty
(
arr
:
ImmutableArray
<_>)
=
arr
.
IsEmpty
let
fold
folder
state
(
arr
:
ImmutableArray
<_>)
=
let
f
=
OptimizedClosures
.
FSharpFunc
<_,
_,
_>.
Adapt
(
folder
)
let
f
=
OptimizedClosures
.
FSharpFunc
<_,
_,
_>.
Adapt
(
folder
)
let
mutable
state
=
state
for
i
=
0
to
arr
.
Length
-
1
do
for
i
=
0
to
arr
.
Length
-
1
do
state
<-
f
.
Invoke
(
state
,
arr
[
i
])
state
src/Compiler/Utilities/InternalCollections.fs
浏览文件 @
4990f64f
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace
Internal
.
Utilities
.
Collections
open
System
[<
StructuralEquality
;
NoComparison
>]
type
internal
ValueStrength
<
'
T
when
'
T
:
not
struct
>
=
|
Strong
of
'
T
type
internal
ValueStrength
<
'
T
when
'
T
:
not
struct
>
=
|
Strong
of
'
T
#
if
FX_NO_GENERIC_WEAKREFERENCE
|
Weak
of
WeakReference
|
Weak
of
WeakReference
#
else
|
Weak
of
WeakReference
<
'
T
>
|
Weak
of
WeakReference
<
'
T
>
#
endif
type
internal
AgedLookup
<
'
Token
,
'
Key
,
'
Value
when
'
Value
:
not
struct
>(
keepStrongly
:
int
,
areSimilar
,
?
requiredToKeep
,
?
keepMax
:
int
)
=
type
internal
AgedLookup
<
'
Token
,
'
Key
,
'
Value
when
'
Value
:
not
struct
>(
keepStrongly
:
int
,
areSimilar
,
?
requiredToKeep
,
?
keepMax
:
int
)
=
/// The list of items stored. Youngest is at the end of the list.
/// The choice of order is somewhat arbitrary. If the other way then adding
/// items would be O(1) and removing O(N).
let
mutable
refs
:(
'
Key
*
ValueStrength
<
'
Value
>)
list
=
[]
let
mutable
refs
:
(
'
Key
*
ValueStrength
<
'
Value
>)
list
=
[]
let
mutable
keepStrongly
=
keepStrongly
// The 75 here determines how long the list should be passed the end of strongly held
// references. Some operations are O(N) and we don't want to let things get out of
// hand.
let
keepMax
=
defaultArg
keepMax
75
let
mutable
keepMax
=
max
keepStrongly
keepMax
let
requiredToKeep
=
defaultArg
requiredToKeep
(
fun
_
->
false
)
let
keepMax
=
defaultArg
keepMax
75
let
mutable
keepMax
=
max
keepStrongly
keepMax
let
requiredToKeep
=
defaultArg
requiredToKeep
(
fun
_
->
false
)
/// Look up a the given key, return <c>None</c> if not found.
let
TryPeekKeyValueImpl
(
data
,
key
)
=
let
rec
Lookup
key
=
function
let
TryPeekKeyValueImpl
(
data
,
key
)
=
let
rec
Lookup
key
=
function
// Treat a list of key-value pairs as a lookup collection.
// This function returns true if two keys are the same according to the predicate
// function passed in.
|
[]
->
None
|
(
similarKey
,
value
)
::
t
->
if
areSimilar
(
key
,
similarKey
)
then
Some
(
similarKey
,
value
)
else
Lookup
key
t
Lookup
key
data
|
[]
->
None
|
(
similarKey
,
value
)
::
t
->
if
areSimilar
(
key
,
similarKey
)
then
Some
(
similarKey
,
value
)
else
Lookup
key
t
Lookup
key
data
/// Determines whether a particular key exists.
let
Exists
(
data
,
key
)
=
TryPeekKeyValueImpl
(
data
,
key
).
IsSome
let
Exists
(
data
,
key
)
=
TryPeekKeyValueImpl
(
data
,
key
).
IsSome
/// Set a particular key's value.
let
Add
(
data
,
key
,
value
)
=
data
@
[
key
,
value
]
let
Add
(
data
,
key
,
value
)
=
data
@
[
key
,
value
]
/// Promote a particular key value.
let
Promote
(
data
,
key
,
value
)
=
(
data
|>
List
.
filter
(
fun
(
similarKey
,_)->
not
(
areSimilar
(
key
,
similarKey
))))
@
[
(
key
,
value
)
]
let
Promote
(
data
,
key
,
value
)
=
(
data
|>
List
.
filter
(
fun
(
similarKey
,
_)
->
not
(
areSimilar
(
key
,
similarKey
))))
@
[
(
key
,
value
)
]
/// Remove a particular key value.
let
RemoveImpl
(
data
,
key
)
=
let
keep
=
data
|>
List
.
filter
(
fun
(
similarKey
,_)->
not
(
areSimilar
(
key
,
similarKey
)))
let
RemoveImpl
(
data
,
key
)
=
let
keep
=
data
|>
List
.
filter
(
fun
(
similarKey
,
_)
->
not
(
areSimilar
(
key
,
similarKey
)))
keep
let
TryGetKeyValueImpl
(
data
,
key
)
=
match
TryPeekKeyValueImpl
(
data
,
key
)
with
|
Some
(
similarKey
,
value
)
as
result
->
let
TryGetKeyValueImpl
(
data
,
key
)
=
match
TryPeekKeyValueImpl
(
data
,
key
)
with
|
Some
(
similarKey
,
value
)
as
result
->
// If the result existed, move it to the end of the list (more likely to keep it)
result
,
Promote
(
data
,
similarKey
,
value
)
|
None
->
None
,
data
result
,
Promote
(
data
,
similarKey
,
value
)
|
None
->
None
,
data
/// Remove weak entries from the list that have been collected.
let
FilterAndHold
(
tok
:
'
Token
)
=
let
FilterAndHold
(
tok
:
'
Token
)
=
ignore
tok
// reading 'refs' requires a token
[
for
key
,
value
in
refs
do
match
value
with
|
Strong
(
value
)
->
yield
(
key
,
value
)
|
Weak
(
weakReference
)
->
[
for
key
,
value
in
refs
do
match
value
with
|
Strong
(
value
)
->
yield
(
key
,
value
)
|
Weak
(
weakReference
)
->
#
if
FX_NO_GENERIC_WEAKREFERENCE
match
weakReference
.
Target
with
|
null
->
()
|
value
->
yield
key
,(
value
:?>
'
Value
)
]
match
weakReference
.
Target
with
|
null
->
()
|
value
->
yield
key
,
(
value
:?>
'
Value
)
]
#
else
match
weakReference
.
TryGetTarget
()
with
|
false
,
_
->
()
|
true
,
value
->
yield
key
,
value
]
match
weakReference
.
TryGetTarget
()
with
|
false
,
_
->
()
|
true
,
value
->
yield
key
,
value
]
#
endif
let
AssignWithStrength
(
tok
,
newData
)
=
let
AssignWithStrength
(
tok
,
newData
)
=
let
actualLength
=
List
.
length
newData
let
tossThreshold
=
max
0
(
actualLength
-
keepMax
)
// Delete everything less than this threshold
let
weakThreshold
=
max
0
(
actualLength
-
keepStrongly
)
// Weaken everything less than this threshold
let
newData
=
newData
|>
List
.
mapi
(
fun
n
kv
->
n
,
kv
)
// Place the index.
let
newData
=
newData
|>
List
.
filter
(
fun
(
n
:
int
,
v
)
->
n
>=
tossThreshold
||
requiredToKeep
(
snd
v
))
let
newData
=
newData
|>
List
.
map
(
fun
(
n
:
int
,(
k
,
v
))
->
let
handle
=
if
n
<
weakThreshold
&&
not
(
requiredToKeep
v
)
then
let
newData
=
newData
|>
List
.
mapi
(
fun
n
kv
->
n
,
kv
)
// Place the index.
let
newData
=
newData
|>
List
.
filter
(
fun
(
n
:
int
,
v
)
->
n
>=
tossThreshold
||
requiredToKeep
(
snd
v
))
let
newData
=
newData
|>
List
.
map
(
fun
(
n
:
int
,
(
k
,
v
))
->
let
handle
=
if
n
<
weakThreshold
&&
not
(
requiredToKeep
v
)
then
#
if
FX_NO_GENERIC_WEAKREFERENCE
Weak
(
WeakReference
(
v
))
Weak
(
WeakReference
(
v
))
#
else
Weak
(
WeakReference
<_>(
v
))
Weak
(
WeakReference
<_>(
v
))
#
endif
else
else
Strong
(
v
)
k
,
handle
)
k
,
handle
)
ignore
tok
// Updating refs requires tok
refs
<-
newData
member
al
.
TryPeekKeyValue
(
tok
,
key
)
=
member
al
.
TryPeekKeyValue
(
tok
,
key
)
=
// Returns the original key value as well since it may be different depending on equality test.
let
data
=
FilterAndHold
(
tok
)
TryPeekKeyValueImpl
(
data
,
key
)
member
al
.
TryGetKeyValue
(
tok
,
key
)
=
TryPeekKeyValueImpl
(
data
,
key
)
member
al
.
TryGetKeyValue
(
tok
,
key
)
=
let
data
=
FilterAndHold
(
tok
)
let
result
,
newData
=
TryGetKeyValueImpl
(
data
,
key
)
AssignWithStrength
(
tok
,
newData
)
let
result
,
newData
=
TryGetKeyValueImpl
(
data
,
key
)
AssignWithStrength
(
tok
,
newData
)
result
member
al
.
TryGet
(
tok
,
key
)
=
member
al
.
TryGet
(
tok
,
key
)
=
let
data
=
FilterAndHold
(
tok
)
let
result
,
newData
=
TryGetKeyValueImpl
(
data
,
key
)
AssignWithStrength
(
tok
,
newData
)
let
result
,
newData
=
TryGetKeyValueImpl
(
data
,
key
)
AssignWithStrength
(
tok
,
newData
)
match
result
with
|
Some
(_,
value
)
->
Some
(
value
)
|
Some
(_,
value
)
->
Some
(
value
)
|
None
->
None
member
al
.
Put
(
tok
,
key
,
value
)
=
member
al
.
Put
(
tok
,
key
,
value
)
=
let
data
=
FilterAndHold
(
tok
)
let
data
=
if
Exists
(
data
,
key
)
then
RemoveImpl
(
data
,
key
)
else
data
let
data
=
Add
(
data
,
key
,
value
)
AssignWithStrength
(
tok
,
data
)
// This will remove extras
member
al
.
Remove
(
tok
,
key
)
=
let
data
=
if
Exists
(
data
,
key
)
then
RemoveImpl
(
data
,
key
)
else
data
let
data
=
Add
(
data
,
key
,
value
)
AssignWithStrength
(
tok
,
data
)
// This will remove extras
member
al
.
Remove
(
tok
,
key
)
=
let
data
=
FilterAndHold
(
tok
)
let
newData
=
RemoveImpl
(
data
,
key
)
AssignWithStrength
(
tok
,
newData
)
let
newData
=
RemoveImpl
(
data
,
key
)
AssignWithStrength
(
tok
,
newData
)
member
al
.
Clear
(
tok
)
=
let
_
discards
=
FilterAndHold
(
tok
)
AssignWithStrength
(
tok
,
[])
let
_
discards
=
FilterAndHold
(
tok
)
AssignWithStrength
(
tok
,
[]
)
member
al
.
Resize
(
tok
,
newKeepStrongly
,
?
newKeepMax
)
=
let
newKeepMax
=
defaultArg
newKeepMax
75
keepStrongly
<-
newKeepStrongly
keepMax
<-
max
newKeepStrongly
newKeepMax
let
keep
=
FilterAndHold
(
tok
)
AssignWithStrength
(
tok
,
keep
)
let
newKeepMax
=
defaultArg
newKeepMax
75
keepStrongly
<-
newKeepStrongly
keepMax
<-
max
newKeepStrongly
newKeepMax
let
keep
=
FilterAndHold
(
tok
)
AssignWithStrength
(
tok
,
keep
)
type
internal
MruCache
<
'
Token
,
'
Key
,
'
Value
when
'
Value
:
not
struct
>
(
keepStrongly
,
areSame
,
?
isStillValid
:
'
Key
*
'
Value
->
bool
,
?
areSimilar
,
?
requiredToKeep
,
?
keepMax
)
=
type
internal
MruCache
<
'
Token
,
'
Key
,
'
Value
when
'
Value
:
not
struct
>(
keepStrongly
,
areSame
,
?
isStillValid
:
'
Key
*
'
Value
->
bool
,
?
areSimilar
,
?
requiredToKeep
,
?
keepMax
)
=
/// Default behavior of <c>areSimilar</c> function is areSame.
let
areSimilar
=
defaultArg
areSimilar
areSame
/// The list of items in the cache. Youngest is at the end of the list.
/// The choice of order is somewhat arbitrary. If the other way then adding
/// items would be O(1) and removing O(N).
let
cache
=
AgedLookup
<
'
Token
,
'
Key
,
'
Value
>(
keepStrongly
=
keepStrongly
,
areSimilar
=
areSimilar
,?
keepMax
=
keepMax
,?
requiredToKeep
=
requiredToKeep
)
let
cache
=
AgedLookup
<
'
Token
,
'
Key
,
'
Value
>(
keepStrongly
=
keepStrongly
,
areSimilar
=
areSimilar
,
?
keepMax
=
keepMax
,
?
requiredToKeep
=
requiredToKeep
)
/// Whether or not this result value is still valid.
let
isStillValid
=
defaultArg
isStillValid
(
fun
_
->
true
)
member
bc
.
ContainsSimilarKey
(
tok
,
key
)
=
member
bc
.
ContainsSimilarKey
(
tok
,
key
)
=
match
cache
.
TryPeekKeyValue
(
tok
,
key
)
with
|
Some
(_
similarKey
,
_
value
)
->
true
|
Some
(_
similarKey
,
_
value
)
->
true
|
None
->
false
member
bc
.
TryGetAny
(
tok
,
key
)
=
member
bc
.
TryGetAny
(
tok
,
key
)
=
match
cache
.
TryPeekKeyValue
(
tok
,
key
)
with
|
Some
(
similarKey
,
value
)->
if
areSame
(
similarKey
,
key
)
then
Some
(
value
)
else
None
|
Some
(
similarKey
,
value
)
->
if
areSame
(
similarKey
,
key
)
then
Some
(
value
)
else
None
|
None
->
None
member
bc
.
TryGet
(
tok
,
key
)
=
member
bc
.
TryGet
(
tok
,
key
)
=
match
cache
.
TryGetKeyValue
(
tok
,
key
)
with
|
Some
(
similarKey
,
value
)
->
if
areSame
(
similarKey
,
key
)
&&
isStillValid
(
key
,
value
)
then
Some
value
else
None
|
Some
(
similarKey
,
value
)
->
if
areSame
(
similarKey
,
key
)
&&
isStillValid
(
key
,
value
)
then
Some
value
else
None
|
None
->
None
member
bc
.
TryGetSimilarAny
(
tok
,
key
)
=
member
bc
.
TryGetSimilarAny
(
tok
,
key
)
=
match
cache
.
TryGetKeyValue
(
tok
,
key
)
with
|
Some
(_,
value
)
->
Some
value
|
Some
(_,
value
)
->
Some
value
|
None
->
None
member
bc
.
TryGetSimilar
(
tok
,
key
)
=
member
bc
.
TryGetSimilar
(
tok
,
key
)
=
match
cache
.
TryGetKeyValue
(
tok
,
key
)
with
|
Some
(_,
value
)
->
if
isStillValid
(
key
,
value
)
then
Some
value
else
None
|
Some
(_,
value
)
->
if
isStillValid
(
key
,
value
)
then
Some
value
else
None
|
None
->
None
member
bc
.
Set
(
tok
,
key
:
'
Key
,
value
:
'
Value
)
=
cache
.
Put
(
tok
,
key
,
value
)
member
bc
.
RemoveAnySimilar
(
tok
,
key
)
=
cache
.
Remove
(
tok
,
key
)
member
bc
.
Clear
(
tok
)
=
cache
.
Clear
(
tok
)
member
bc
.
Set
(
tok
,
key
:
'
Key
,
value
:
'
Value
)
=
cache
.
Put
(
tok
,
key
,
value
)
member
bc
.
RemoveAnySimilar
(
tok
,
key
)
=
cache
.
Remove
(
tok
,
key
)
member
bc
.
Clear
(
tok
)
=
cache
.
Clear
(
tok
)
member
bc
.
Resize
(
tok
,
newKeepStrongly
,
?
newKeepMax
)
=
cache
.
Resize
(
tok
,
newKeepStrongly
,
?
newKeepMax
=
newKeepMax
)
cache
.
Resize
(
tok
,
newKeepStrongly
,
?
newKeepMax
=
newKeepMax
)
src/Compiler/Utilities/PathMap.fs
浏览文件 @
4990f64f
...
...
@@ -17,20 +17,22 @@ module internal PathMap =
let
empty
=
PathMap
Map
.
empty
let
addMapping
(
src
:
string
)
(
dst
:
string
)
(
PathMap
map
)
:
PathMap
=
let
addMapping
(
src
:
string
)
(
dst
:
string
)
(
PathMap
map
)
:
PathMap
=
// Normalise the path
let
normalSrc
=
FileSystem
.
GetFullPathShim
src
let
oldPrefix
=
if
normalSrc
.
EndsWith
dirSepStr
then
normalSrc
else
normalSrc
+
dirSepStr
if
normalSrc
.
EndsWith
dirSepStr
then
normalSrc
else
normalSrc
+
dirSepStr
// Always add a path separator
map
|>
Map
.
add
oldPrefix
dst
|>
PathMap
// Map a file path with its replacement.
// This logic replicates C#'s PathUtilities.NormalizePathPrefix
let
apply
(
PathMap
map
)
(
filePath
:
string
)
:
string
=
let
apply
(
PathMap
map
)
(
filePath
:
string
)
:
string
=
// Find the first key in the path map that matches a prefix of the
// normalized path. We expect the client to use consistent capitalization;
// we use ordinal (case-sensitive) comparisons.
...
...
@@ -40,23 +42,26 @@ module internal PathMap =
// to check if it was a partial match
// e.g. for the map /goo=/bar and file name /goooo
if
filePath
.
StartsWith
(
oldPrefix
,
StringComparison
.
Ordinal
)
then
let
replacement
=
replacementPrefix
+
filePath
.
Substring
(
oldPrefix
.
Length
-
1
)
let
replacement
=
replacementPrefix
+
filePath
.
Substring
(
oldPrefix
.
Length
-
1
)
// Normalize the path separators if used uniformly in the replacement
let
hasSlash
=
replacementPrefix
.
IndexOf
'
/
'
>=
0
let
hasBackslash
=
replacementPrefix
.
IndexOf
'\\'
>=
0
if
hasSlash
&&
not
hasBackslash
then
replacement
.
Replace
(
'\\'
,
'
/
'
)
elif
hasBackslash
&&
not
hasSlash
then
replacement
.
Replace
(
'
/
'
,
'\\'
)
else
replacement
if
hasSlash
&&
not
hasBackslash
then
replacement
.
Replace
(
'\\'
,
'
/
'
)
elif
hasBackslash
&&
not
hasSlash
then
replacement
.
Replace
(
'
/
'
,
'\\'
)
else
replacement
|>
Some
else
None
)
None
)
|>
Option
.
defaultValue
filePath
let
applyDir
pathMap
(
dirName
:
string
)
:
string
=
if
dirName
.
EndsWith
dirSepStr
then
apply
pathMap
dirName
let
applyDir
pathMap
(
dirName
:
string
)
:
string
=
if
dirName
.
EndsWith
dirSepStr
then
apply
pathMap
dirName
else
let
mapped
=
apply
pathMap
(
dirName
+
dirSepStr
)
mapped
.
TrimEnd
(
Path
.
DirectorySeparatorChar
,
Path
.
AltDirectorySeparatorChar
)
mapped
.
TrimEnd
(
Path
.
DirectorySeparatorChar
,
Path
.
AltDirectorySeparatorChar
)
src/Compiler/Utilities/QueueList.fs
浏览文件 @
4990f64f
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace
Internal
.
Utilities
.
Collections
namespace
Internal
.
Utilities
.
Collections
open
System
.
Collections
open
System
.
Collections
.
Generic
/// Iterable functional collection with O(1) append-1 time. Useful for data structures where elements get added at the
/// end but the collection must occasionally be iterated. Iteration is slower and may allocate because
/// end but the collection must occasionally be iterated. Iteration is slower and may allocate because
/// a suffix of elements is stored in reverse order.
///
/// The type doesn't support structural hashing or comparison.
type
internal
QueueList
<
'
T
>(
firstElementsIn
:
'
T
list
,
lastElementsRevIn
:
'
T
list
,
numLastElementsIn
:
int
)
=
type
internal
QueueList
<
'
T
>(
firstElementsIn
:
'
T
list
,
lastElementsRevIn
:
'
T
list
,
numLastElementsIn
:
int
)
=
let
numFirstElements
=
List
.
length
firstElementsIn
// Push the lastElementsRev onto the firstElements every so often.
let
push
=
numLastElementsIn
>
numFirstElements
/
5
// Compute the contents after pushing.
let
firstElements
=
if
push
then
List
.
append
firstElementsIn
(
List
.
rev
lastElementsRevIn
)
else
firstElementsIn
let
firstElements
=
if
push
then
List
.
append
firstElementsIn
(
List
.
rev
lastElementsRevIn
)
else
firstElementsIn
let
lastElementsRev
=
if
push
then
[]
else
lastElementsRevIn
let
numLastElements
=
if
push
then
0
else
numLastElementsIn
// Compute the last elements on demand.
let
lastElements
()
=
if
push
then
[]
else
List
.
rev
lastElementsRev
let
lastElements
()
=
if
push
then
[]
else
List
.
rev
lastElementsRev
static
let
empty
=
QueueList
<
'
T
>([],
[]
,
0
)
static
member
Empty
:
QueueList
<
'
T
>
=
empty
static
member
Empty
:
QueueList
<
'
T
>
=
empty
new
(
xs
:
'
T
list
)
=
QueueList
(
xs
,[],
0
)
member
x
.
ToList
()
=
if
push
then
firstElements
else
List
.
append
firstElements
(
lastElements
()
)
new
(
xs
:
'
T
list
)
=
QueueList
(
xs
,
[]
,
0
)
member
x
.
ToList
()
=
if
push
then
firstElements
else
List
.
append
firstElements
(
lastElements
()
)
member
x
.
FirstElements
=
firstElements
member
x
.
LastElements
=
lastElements
()
member
x
.
LastElements
=
lastElements
()
/// This operation is O(1), unless a push happens, which is rare.
member
x
.
AppendOne
(
y
)
=
QueueList
(
firstElements
,
y
::
lastElementsRev
,
numLastElements
+
1
)
member
x
.
AppendOne
(
y
)
=
QueueList
(
firstElements
,
y
::
lastElementsRev
,
numLastElements
+
1
)
member
x
.
Append
(
ys
:
seq
<_>)
=
member
x
.
Append
(
ys
:
seq
<_>)
=
let
newElements
=
Seq
.
toList
ys
let
newLength
=
List
.
length
newElements
let
lastElementsRevIn
=
List
.
rev
newElements
@
lastElementsRev
QueueList
(
firstElements
,
lastElementsRevIn
,
numLastElementsIn
+
newLength
)
// This operation is O(n) anyway, so executing ToList() here is OK
interface
IEnumerable
<
'
T
>
with
member
x
.
GetEnumerator
()
:
IEnumerator
<
'
T
>
=
(
x
.
ToList
()
:>
IEnumerable
<_>).
GetEnumerator
()
interface
IEnumerable
<
'
T
>
with
member
x
.
GetEnumerator
()
:
IEnumerator
<
'
T
>
=
(
x
.
ToList
()
:>
IEnumerable
<_>).
GetEnumerator
()
interface
IEnumerable
with
member
x
.
GetEnumerator
()
:
IEnumerator
=
((
x
:>
IEnumerable
<
'
T
>).
GetEnumerator
()
:>
IEnumerator
)
interface
IEnumerable
with
member
x
.
GetEnumerator
()
:
IEnumerator
=
((
x
:>
IEnumerable
<
'
T
>).
GetEnumerator
()
:>
IEnumerator
)
module
internal
QueueList
=
let
empty
<
'
T
>
:
QueueList
<
'
T
>
=
QueueList
<
'
T
>.
Empty
let
ofSeq
(
x
:
seq
<_>)
=
QueueList
(
List
.
ofSeq
x
)
let
ofSeq
(
x
:
seq
<_>)
=
QueueList
(
List
.
ofSeq
x
)
let
rec
iter
f
(
x
:
QueueList
<_>)
=
Seq
.
iter
f
x
let
rec
iter
f
(
x
:
QueueList
<_>)
=
Seq
.
iter
f
x
let
rec
map
f
(
x
:
QueueList
<_>)
=
ofSeq
(
Seq
.
map
f
x
)
let
rec
map
f
(
x
:
QueueList
<_>)
=
ofSeq
(
Seq
.
map
f
x
)
let
rec
exists
f
(
x
:
QueueList
<_>)
=
Seq
.
exists
f
x
let
rec
exists
f
(
x
:
QueueList
<_>)
=
Seq
.
exists
f
x
let
rec
filter
f
(
x
:
QueueList
<_>)
=
ofSeq
(
Seq
.
filter
f
x
)
let
rec
filter
f
(
x
:
QueueList
<_>)
=
ofSeq
(
Seq
.
filter
f
x
)
let
rec
foldBack
f
(
x
:
QueueList
<_>)
acc
=
List
.
foldBack
f
x
.
FirstElements
(
List
.
foldBack
f
x
.
LastElements
acc
)
let
rec
foldBack
f
(
x
:
QueueList
<_>)
acc
=
List
.
foldBack
f
x
.
FirstElements
(
List
.
foldBack
f
x
.
LastElements
acc
)
let
forall
f
(
x
:
QueueList
<_>)
=
Seq
.
forall
f
x
let
forall
f
(
x
:
QueueList
<_>)
=
Seq
.
forall
f
x
let
ofList
(
x
:_
list
)
=
QueueList
(
x
)
let
ofList
(
x
:
_
list
)
=
QueueList
(
x
)
let
toList
(
x
:
QueueList
<_>)
=
Seq
.
toList
x
let
toList
(
x
:
QueueList
<_>)
=
Seq
.
toList
x
let
tryFind
f
(
x
:
QueueList
<_>)
=
Seq
.
tryFind
f
x
let
tryFind
f
(
x
:
QueueList
<_>)
=
Seq
.
tryFind
f
x
let
one
x
=
QueueList
[
x
]
let
one
x
=
QueueList
[
x
]
let
appendOne
(
x
:
QueueList
<_>)
y
=
x
.
AppendOne
(
y
)
let
appendOne
(
x
:
QueueList
<_>)
y
=
x
.
AppendOne
(
y
)
let
append
(
x
:
QueueList
<_>)
(
ys
:
QueueList
<_>)
=
x
.
Append
(
ys
)
let
append
(
x
:
QueueList
<_>)
(
ys
:
QueueList
<_>)
=
x
.
Append
(
ys
)
src/Compiler/Utilities/ResizeArray.fs
浏览文件 @
4990f64f
...
...
@@ -7,175 +7,244 @@ open FSharp.Core.OptimizedClosures
[<
CompilationRepresentation
(
CompilationRepresentationFlags
.
ModuleSuffix
)>]
module
internal
ResizeArray
=
let
length
(
arr
:
ResizeArray
<
'
T
>)
=
arr
.
Count
let
length
(
arr
:
ResizeArray
<
'
T
>)
=
arr
.
Count
let
get
(
arr
:
ResizeArray
<
'
T
>)
(
n
:
int
)
=
arr
[
n
]
let
get
(
arr
:
ResizeArray
<
'
T
>)
(
n
:
int
)
=
arr
[
n
]
let
set
(
arr
:
ResizeArray
<
'
T
>)
(
n
:
int
)
(
x
:
'
T
)
=
arr
[
n
]
<-
x
let
set
(
arr
:
ResizeArray
<
'
T
>)
(
n
:
int
)
(
x
:
'
T
)
=
arr
[
n
]
<-
x
let
create
(
n
:
int
)
x
=
ResizeArray
<_>(
seq
{
for
_
in
1
..
n
->
x
})
let
create
(
n
:
int
)
x
=
ResizeArray
<_>(
seq
{
for
_
in
1
..
n
->
x
})
let
init
(
n
:
int
)
(
f
:
int
->
'
T
)
=
ResizeArray
<_>(
seq
{
for
i
in
0
..
n
-
1
->
f
i
})
let
init
(
n
:
int
)
(
f
:
int
->
'
T
)
=
ResizeArray
<_>(
seq
{
for
i
in
0
..
n
-
1
->
f
i
})
let
blit
(
arr1
:
ResizeArray
<
'
T
>)
start1
(
arr2
:
ResizeArray
<
'
T
>)
start2
len
=
if
start1
<
0
then
invalidArg
"start1"
"index must be positive"
if
start2
<
0
then
invalidArg
"start2"
"index must be positive"
if
len
<
0
then
invalidArg
"len"
"length must be positive"
if
start1
+
len
>
length
arr1
then
invalidArg
"start1"
"(start1+len) out of range"
if
start2
+
len
>
length
arr2
then
invalidArg
"start2"
"(start2+len) out of range"
for
i
=
0
to
len
-
1
do
arr2
[
start2
+
i
]
<-
arr1
[
start1
+
i
]
if
start1
<
0
then
invalidArg
"start1"
"index must be positive"
let
concat
(
arrs
:
ResizeArray
<
'
T
>
list
)
=
ResizeArray
<_>(
seq
{
for
arr
in
arrs
do
for
x
in
arr
do
yield
x
})
if
start2
<
0
then
invalidArg
"start2"
"index must be positive"
let
append
(
arr1
:
ResizeArray
<
'
T
>)
(
arr2
:
ResizeArray
<
'
T
>)
=
concat
[
arr1
;
arr2
]
if
len
<
0
then
invalidArg
"len"
"length must be positive"
if
start1
+
len
>
length
arr1
then
invalidArg
"start1"
"(start1+len) out of range"
if
start2
+
len
>
length
arr2
then
invalidArg
"start2"
"(start2+len) out of range"
for
i
=
0
to
len
-
1
do
arr2
[
start2
+
i
]
<-
arr1
[
start1
+
i
]
let
concat
(
arrs
:
ResizeArray
<
'
T
>
list
)
=
ResizeArray
<_>(
seq
{
for
arr
in
arrs
do
for
x
in
arr
do
yield
x
}
)
let
append
(
arr1
:
ResizeArray
<
'
T
>)
(
arr2
:
ResizeArray
<
'
T
>)
=
concat
[
arr1
;
arr2
]
let
sub
(
arr
:
ResizeArray
<
'
T
>)
start
len
=
if
start
<
0
then
invalidArg
"start"
"index must be positive"
if
len
<
0
then
invalidArg
"len"
"length must be positive"
if
start
+
len
>
length
arr
then
invalidArg
"len"
"length must be positive"
ResizeArray
<_>(
seq
{
for
i
in
start
..
start
+
len
-
1
->
arr
[
i
]
})
let
fill
(
arr
:
ResizeArray
<
'
T
>)
(
start
:
int
)
(
len
:
int
)
(
x
:
'
T
)
=
if
start
<
0
then
invalidArg
"start"
"index must be positive"
if
len
<
0
then
invalidArg
"len"
"length must be positive"
if
start
+
len
>
length
arr
then
invalidArg
"len"
"length must be positive"
for
i
=
start
to
start
+
len
-
1
do
if
start
<
0
then
invalidArg
"start"
"index must be positive"
if
len
<
0
then
invalidArg
"len"
"length must be positive"
if
start
+
len
>
length
arr
then
invalidArg
"len"
"length must be positive"
ResizeArray
<_>(
seq
{
for
i
in
start
..
start
+
len
-
1
->
arr
[
i
]
})
let
fill
(
arr
:
ResizeArray
<
'
T
>)
(
start
:
int
)
(
len
:
int
)
(
x
:
'
T
)
=
if
start
<
0
then
invalidArg
"start"
"index must be positive"
if
len
<
0
then
invalidArg
"len"
"length must be positive"
if
start
+
len
>
length
arr
then
invalidArg
"len"
"length must be positive"
for
i
=
start
to
start
+
len
-
1
do
arr
[
i
]
<-
x
let
copy
(
arr
:
ResizeArray
<
'
T
>)
=
ResizeArray
<_>(
arr
)
let
copy
(
arr
:
ResizeArray
<
'
T
>)
=
ResizeArray
<_>(
arr
)
let
toList
(
arr
:
ResizeArray
<_>)
=
let
mutable
res
=
[]
for
i
=
length
arr
-
1
downto
0
do
res
<-
arr
[
i
]
::
res
res
let
ofList
(
l
:
_
list
)
=
let
len
=
l
.
Length
let
res
=
ResizeArray
<_>(
len
)
let
rec
add
=
function
|
[]
->
()
|
e
::
l
->
res
.
Add
(
e
);
add
l
let
rec
add
=
function
|
[]
->
()
|
e
::
l
->
res
.
Add
(
e
)
add
l
add
l
res
let
iter
f
(
arr
:
ResizeArray
<_>)
=
let
iter
f
(
arr
:
ResizeArray
<_>)
=
for
i
=
0
to
arr
.
Count
-
1
do
f
arr
[
i
]
let
map
f
(
arr
:
ResizeArray
<_>)
=
let
len
=
length
arr
let
res
=
ResizeArray
<_>(
len
)
for
i
=
0
to
len
-
1
do
res
.
Add
(
f
arr
[
i
])
res
let
mapi
f
(
arr
:
ResizeArray
<_>)
=
let
f
=
FSharpFunc
<_,
_,_>.
Adapt
(
f
)
let
f
=
FSharpFunc
<_,
_,
_>.
Adapt
(
f
)
let
len
=
length
arr
let
res
=
ResizeArray
<_>(
len
)
for
i
=
0
to
len
-
1
do
res
.
Add
(
f
.
Invoke
(
i
,
arr
[
i
]))
res
let
iteri
f
(
arr
:
ResizeArray
<_>)
=
let
f
=
FSharpFunc
<_,_,_>.
Adapt
(
f
)
let
f
=
FSharpFunc
<_,
_,
_>.
Adapt
(
f
)
for
i
=
0
to
arr
.
Count
-
1
do
f
.
Invoke
(
i
,
arr
[
i
])
let
exists
(
f
:
'
T
->
bool
)
(
arr
:
ResizeArray
<
'
T
>)
=
let
len
=
length
arr
let
rec
loop
i
=
i
<
len
&&
(
f
arr
[
i
]
||
loop
(
i
+
1
))
let
len
=
length
arr
let
rec
loop
i
=
i
<
len
&&
(
f
arr
[
i
]
||
loop
(
i
+
1
))
loop
0
let
forall
f
(
arr
:
ResizeArray
<_>)
=
let
len
=
length
arr
let
rec
loop
i
=
i
>=
len
||
(
f
arr
[
i
]
&&
loop
(
i
+
1
))
let
rec
loop
i
=
i
>=
len
||
(
f
arr
[
i
]
&&
loop
(
i
+
1
))
loop
0
let
indexNotFound
()
=
raise
(
System
.
Collections
.
Generic
.
KeyNotFoundException
(
"An index satisfying the predicate was not found in the collection"
))
let
indexNotFound
()
=
raise
(
System
.
Collections
.
Generic
.
KeyNotFoundException
(
"An index satisfying the predicate was not found in the collection"
))
let
find
f
(
arr
:
ResizeArray
<_>)
=
let
rec
loop
i
=
if
i
>=
length
arr
then
indexNotFound
()
let
find
f
(
arr
:
ResizeArray
<_>)
=
let
rec
loop
i
=
if
i
>=
length
arr
then
indexNotFound
()
elif
f
arr
[
i
]
then
arr
[
i
]
else
loop
(
i
+
1
)
else
loop
(
i
+
1
)
loop
0
let
tryPick
f
(
arr
:
ResizeArray
<_>)
=
let
rec
loop
i
=
if
i
>=
length
arr
then
None
else
match
f
arr
[
i
]
with
|
None
->
loop
(
i
+
1
)
|
res
->
res
let
rec
loop
i
=
if
i
>=
length
arr
then
None
else
match
f
arr
[
i
]
with
|
None
->
loop
(
i
+
1
)
|
res
->
res
loop
0
let
tryFind
f
(
arr
:
ResizeArray
<_>)
=
let
rec
loop
i
=
let
tryFind
f
(
arr
:
ResizeArray
<_>)
=
let
rec
loop
i
=
if
i
>=
length
arr
then
None
elif
f
arr
[
i
]
then
Some
arr
[
i
]
else
loop
(
i
+
1
)
else
loop
(
i
+
1
)
loop
0
let
iter2
f
(
arr1
:
ResizeArray
<
'
T
>)
(
arr2
:
ResizeArray
<
'
b
>)
=
let
f
=
FSharpFunc
<_,
_,_>.
Adapt
(
f
)
let
iter2
f
(
arr1
:
ResizeArray
<
'
T
>)
(
arr2
:
ResizeArray
<
'
b
>)
=
let
f
=
FSharpFunc
<_,
_,
_>.
Adapt
(
f
)
let
len1
=
length
arr1
if
len1
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
for
i
=
0
to
len1
-
1
do
if
len1
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
for
i
=
0
to
len1
-
1
do
f
.
Invoke
(
arr1
[
i
],
arr2
[
i
])
let
map2
f
(
arr1
:
ResizeArray
<
'
T
>)
(
arr2
:
ResizeArray
<
'
b
>)
=
let
f
=
FSharpFunc
<_,
_,_>.
Adapt
(
f
)
let
map2
f
(
arr1
:
ResizeArray
<
'
T
>)
(
arr2
:
ResizeArray
<
'
b
>)
=
let
f
=
FSharpFunc
<_,
_,
_>.
Adapt
(
f
)
let
len1
=
length
arr1
if
len1
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
if
len1
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
let
res
=
ResizeArray
<_>(
len1
)
for
i
=
0
to
len1
-
1
do
res
.
Add
(
f
.
Invoke
(
arr1
[
i
],
arr2
[
i
]))
res
let
choose
f
(
arr
:
ResizeArray
<_>)
=
let
res
=
ResizeArray
<_>()
let
choose
f
(
arr
:
ResizeArray
<_>)
=
let
res
=
ResizeArray
<_>()
for
i
=
0
to
length
arr
-
1
do
match
f
arr
[
i
]
with
match
f
arr
[
i
]
with
|
None
->
()
|
Some
b
->
res
.
Add
(
b
)
res
let
filter
f
(
arr
:
ResizeArray
<_>)
=
let
res
=
ResizeArray
<_>()
for
i
=
0
to
length
arr
-
1
do
let
x
=
arr
[
i
]
let
filter
f
(
arr
:
ResizeArray
<_>)
=
let
res
=
ResizeArray
<_>()
for
i
=
0
to
length
arr
-
1
do
let
x
=
arr
[
i
]
if
f
x
then
res
.
Add
(
x
)
res
let
partition
f
(
arr
:
ResizeArray
<_>)
=
let
res1
=
ResizeArray
<_>()
let
res2
=
ResizeArray
<_>()
for
i
=
0
to
length
arr
-
1
do
let
x
=
arr
[
i
]
if
f
x
then
res1
.
Add
(
x
)
else
res2
.
Add
(
x
)
res1
,
res2
let
rev
(
arr
:
ResizeArray
<_>)
=
let
len
=
length
arr
let
res
=
ResizeArray
<_>(
len
)
for
i
=
len
-
1
downto
0
do
res
.
Add
(
arr
[
i
])
res
let
foldBack
(
f
:
'
T
->
'
State
->
'
State
)
(
arr
:
ResizeArray
<
'
T
>)
(
acc
:
'
State
)
=
let
mutable
res
=
acc
let
len
=
length
arr
for
i
=
len
-
1
downto
0
do
let
partition
f
(
arr
:
ResizeArray
<_>)
=
let
res1
=
ResizeArray
<_>()
let
res2
=
ResizeArray
<_>()
for
i
=
0
to
length
arr
-
1
do
let
x
=
arr
[
i
]
if
f
x
then
res1
.
Add
(
x
)
else
res2
.
Add
(
x
)
res1
,
res2
let
rev
(
arr
:
ResizeArray
<_>)
=
let
len
=
length
arr
let
res
=
ResizeArray
<_>(
len
)
for
i
=
len
-
1
downto
0
do
res
.
Add
(
arr
[
i
])
res
let
foldBack
(
f
:
'
T
->
'
State
->
'
State
)
(
arr
:
ResizeArray
<
'
T
>)
(
acc
:
'
State
)
=
let
mutable
res
=
acc
let
len
=
length
arr
for
i
=
len
-
1
downto
0
do
res
<-
f
(
get
arr
i
)
res
res
let
fold
(
f
:
'
State
->
'
T
->
'
State
)
(
acc
:
'
State
)
(
arr
:
ResizeArray
<
'
T
>)
=
let
mutable
res
=
acc
let
len
=
length
arr
for
i
=
0
to
len
-
1
do
let
fold
(
f
:
'
State
->
'
T
->
'
State
)
(
acc
:
'
State
)
(
arr
:
ResizeArray
<
'
T
>)
=
let
mutable
res
=
acc
let
len
=
length
arr
for
i
=
0
to
len
-
1
do
res
<-
f
res
(
get
arr
i
)
res
let
toArray
(
arr
:
ResizeArray
<
'
T
>)
=
arr
.
ToArray
()
...
...
@@ -184,109 +253,155 @@ module internal ResizeArray =
let
toSeq
(
arr
:
ResizeArray
<
'
T
>)
=
Seq
.
readonly
arr
let
sort
f
(
arr
:
ResizeArray
<
'
T
>)
=
arr
.
Sort
(
System
.
Comparison
(
f
))
let
sortBy
f
(
arr
:
ResizeArray
<
'
T
>)
=
arr
.
Sort
(
System
.
Comparison
(
fun
x
y
->
compare
(
f
x
)
(
f
y
)))
let
sort
f
(
arr
:
ResizeArray
<
'
T
>)
=
arr
.
Sort
(
System
.
Comparison
(
f
))
let
sortBy
f
(
arr
:
ResizeArray
<
'
T
>)
=
arr
.
Sort
(
System
.
Comparison
(
fun
x
y
->
compare
(
f
x
)
(
f
y
)))
let
exists2
f
(
arr1
:
ResizeArray
<_>)
(
arr2
:
ResizeArray
<_>)
=
let
len1
=
length
arr1
if
len1
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
let
rec
loop
i
=
i
<
len1
&&
(
f
arr1
[
i
]
arr2
[
i
]
||
loop
(
i
+
1
))
if
len1
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
let
rec
loop
i
=
i
<
len1
&&
(
f
arr1
[
i
]
arr2
[
i
]
||
loop
(
i
+
1
))
loop
0
let
findIndex
f
(
arr
:
ResizeArray
<_>)
=
let
rec
go
n
=
if
n
>=
length
arr
then
indexNotFound
()
elif
f
arr
[
n
]
then
n
else
go
(
n
+
1
)
let
rec
go
n
=
if
n
>=
length
arr
then
indexNotFound
()
elif
f
arr
[
n
]
then
n
else
go
(
n
+
1
)
go
0
let
findIndexi
f
(
arr
:
ResizeArray
<_>)
=
let
rec
go
n
=
if
n
>=
length
arr
then
indexNotFound
()
elif
f
n
arr
[
n
]
then
n
else
go
(
n
+
1
)
let
rec
go
n
=
if
n
>=
length
arr
then
indexNotFound
()
elif
f
n
arr
[
n
]
then
n
else
go
(
n
+
1
)
go
0
let
foldSub
f
acc
(
arr
:
ResizeArray
<_>)
start
fin
=
let
foldSub
f
acc
(
arr
:
ResizeArray
<_>)
start
fin
=
let
mutable
res
=
acc
for
i
=
start
to
fin
do
res
<-
f
res
arr
[
i
]
res
<-
f
res
arr
[
i
]
res
let
foldBackSub
f
(
arr
:
ResizeArray
<_>)
start
fin
acc
=
let
mutable
res
=
acc
let
foldBackSub
f
(
arr
:
ResizeArray
<_>)
start
fin
acc
=
let
mutable
res
=
acc
for
i
=
fin
downto
start
do
res
<-
f
arr
[
i
]
res
res
let
reduce
f
(
arr
:
ResizeArray
<_>)
=
let
reduce
f
(
arr
:
ResizeArray
<_>)
=
let
arrn
=
length
arr
if
arrn
=
0
then
invalidArg
"arr"
"the input array may not be empty"
else
foldSub
f
arr
[
0
]
arr
1
(
arrn
-
1
)
let
reduceBack
f
(
arr
:
ResizeArray
<_>)
=
if
arrn
=
0
then
invalidArg
"arr"
"the input array may not be empty"
else
foldSub
f
arr
[
0
]
arr
1
(
arrn
-
1
)
let
reduceBack
f
(
arr
:
ResizeArray
<_>)
=
let
arrn
=
length
arr
if
arrn
=
0
then
invalidArg
"arr"
"the input array may not be empty"
else
foldBackSub
f
arr
0
(
arrn
-
2
)
arr
[
arrn
-
1
]
if
arrn
=
0
then
invalidArg
"arr"
"the input array may not be empty"
else
foldBackSub
f
arr
0
(
arrn
-
2
)
arr
[
arrn
-
1
]
let
fold2
f
(
acc
:
'
T
)
(
arr1
:
ResizeArray
<
'
T1
>)
(
arr2
:
ResizeArray
<
'
T2
>)
=
let
f
=
FSharpFunc
<_,
_,_,_>.
Adapt
(
f
)
let
mutable
res
=
acc
let
f
=
FSharpFunc
<_,
_,
_,
_>.
Adapt
(
f
)
let
mutable
res
=
acc
let
len
=
length
arr1
if
len
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
if
len
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
for
i
=
0
to
len
-
1
do
res
<-
f
.
Invoke
(
res
,
arr1
[
i
],
arr2
[
i
])
res
<-
f
.
Invoke
(
res
,
arr1
[
i
],
arr2
[
i
])
res
let
foldBack2
f
(
arr1
:
ResizeArray
<
'
T1
>)
(
arr2
:
ResizeArray
<
'
T2
>)
(
acc
:
'
b
)
=
let
f
=
FSharpFunc
<_,
_,_,_>.
Adapt
(
f
)
let
mutable
res
=
acc
let
f
=
FSharpFunc
<_,
_,
_,
_>.
Adapt
(
f
)
let
mutable
res
=
acc
let
len
=
length
arr1
if
len
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
for
i
=
len
-
1
downto
0
do
res
<-
f
.
Invoke
(
arr1
[
i
],
arr2
[
i
],
res
)
if
len
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
for
i
=
len
-
1
downto
0
do
res
<-
f
.
Invoke
(
arr1
[
i
],
arr2
[
i
],
res
)
res
let
forall2
f
(
arr1
:
ResizeArray
<_>)
(
arr2
:
ResizeArray
<_>)
=
let
forall2
f
(
arr1
:
ResizeArray
<_>)
(
arr2
:
ResizeArray
<_>)
=
let
len1
=
length
arr1
if
len1
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
let
rec
loop
i
=
i
>=
len1
||
(
f
arr1
[
i
]
arr2
[
i
]
&&
loop
(
i
+
1
))
if
len1
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
let
rec
loop
i
=
i
>=
len1
||
(
f
arr1
[
i
]
arr2
[
i
]
&&
loop
(
i
+
1
))
loop
0
let
isEmpty
(
arr
:
ResizeArray
<_>)
=
length
(
arr
:
ResizeArray
<_>)
=
0
let
iteri2
f
(
arr1
:
ResizeArray
<
'
T
>)
(
arr2
:
ResizeArray
<
'
b
>)
=
let
f
=
FSharpFunc
<_,
_,_,_>.
Adapt
(
f
)
let
f
=
FSharpFunc
<_,
_,
_,
_>.
Adapt
(
f
)
let
len1
=
length
arr1
if
len1
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
for
i
=
0
to
len1
-
1
do
f
.
Invoke
(
i
,
arr1
[
i
],
arr2
[
i
])
let
mapi2
(
f
:
int
->
'
T
->
'
b
->
'
c
)
(
arr1
:
ResizeArray
<
'
T
>)
(
arr2
:
ResizeArray
<
'
b
>)
=
let
f
=
FSharpFunc
<_,_,_,_>.
Adapt
(
f
)
if
len1
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
for
i
=
0
to
len1
-
1
do
f
.
Invoke
(
i
,
arr1
[
i
],
arr2
[
i
])
let
mapi2
(
f
:
int
->
'
T
->
'
b
->
'
c
)
(
arr1
:
ResizeArray
<
'
T
>)
(
arr2
:
ResizeArray
<
'
b
>)
=
let
f
=
FSharpFunc
<_,
_,
_,
_>.
Adapt
(
f
)
let
len1
=
length
arr1
if
len1
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
if
len1
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
init
len1
(
fun
i
->
f
.
Invoke
(
i
,
arr1
[
i
],
arr2
[
i
]))
let
scanBackSub
f
(
arr
:
ResizeArray
<
'
T
>)
start
fin
acc
=
let
f
=
FSharpFunc
<_,
_,_>.
Adapt
(
f
)
let
scanBackSub
f
(
arr
:
ResizeArray
<
'
T
>)
start
fin
acc
=
let
f
=
FSharpFunc
<_,
_,
_>.
Adapt
(
f
)
let
mutable
state
=
acc
let
res
=
create
(
2
+
fin
-
start
)
acc
let
res
=
create
(
2
+
fin
-
start
)
acc
for
i
=
fin
downto
start
do
state
<-
f
.
Invoke
(
arr
[
i
],
state
)
res
[
i
-
start
]
<-
state
res
let
scanSub
f
acc
(
arr
:
ResizeArray
<
'
T
>)
start
fin
=
let
f
=
FSharpFunc
<_,
_,_>.
Adapt
(
f
)
let
scanSub
f
acc
(
arr
:
ResizeArray
<
'
T
>)
start
fin
=
let
f
=
FSharpFunc
<_,
_,
_>.
Adapt
(
f
)
let
mutable
state
=
acc
let
res
=
create
(
fin
-
start
+
2
)
acc
let
res
=
create
(
fin
-
start
+
2
)
acc
for
i
=
start
to
fin
do
state
<-
f
.
Invoke
(
state
,
arr
[
i
])
res
[
i
-
start
+
1
]
<-
state
res
[
i
-
start
+
1
]
<-
state
res
let
scan
f
acc
(
arr
:
ResizeArray
<
'
T
>)
=
let
scan
f
acc
(
arr
:
ResizeArray
<
'
T
>)
=
let
arrn
=
length
arr
scanSub
f
acc
arr
0
(
arrn
-
1
)
let
scanBack
f
(
arr
:
ResizeArray
<
'
T
>)
acc
=
let
scanBack
f
(
arr
:
ResizeArray
<
'
T
>)
acc
=
let
arrn
=
length
arr
scanBackSub
f
arr
0
(
arrn
-
1
)
acc
...
...
@@ -295,27 +410,38 @@ module internal ResizeArray =
res
.
Add
(
x
)
res
let
tryFindIndex
f
(
arr
:
ResizeArray
<
'
T
>)
=
let
rec
go
n
=
if
n
>=
length
arr
then
None
elif
f
arr
[
n
]
then
Some
n
else
go
(
n
+
1
)
let
tryFindIndex
f
(
arr
:
ResizeArray
<
'
T
>)
=
let
rec
go
n
=
if
n
>=
length
arr
then
None
elif
f
arr
[
n
]
then
Some
n
else
go
(
n
+
1
)
go
0
let
tryFindIndexi
f
(
arr
:
ResizeArray
<
'
T
>)
=
let
rec
go
n
=
if
n
>=
length
arr
then
None
elif
f
n
arr
[
n
]
then
Some
n
else
go
(
n
+
1
)
let
tryFindIndexi
f
(
arr
:
ResizeArray
<
'
T
>)
=
let
rec
go
n
=
if
n
>=
length
arr
then
None
elif
f
n
arr
[
n
]
then
Some
n
else
go
(
n
+
1
)
go
0
let
zip
(
arr1
:
ResizeArray
<_>)
(
arr2
:
ResizeArray
<_>)
=
let
len1
=
length
arr1
if
len1
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
let
zip
(
arr1
:
ResizeArray
<_>)
(
arr2
:
ResizeArray
<_>)
=
let
len1
=
length
arr1
if
len1
<>
length
arr2
then
invalidArg
"arr2"
"the arrays have different lengths"
init
len1
(
fun
i
->
arr1
[
i
],
arr2
[
i
])
let
unzip
(
arr
:
ResizeArray
<_>)
=
let
unzip
(
arr
:
ResizeArray
<_>)
=
let
len
=
length
arr
let
res1
=
ResizeArray
<_>(
len
)
let
res2
=
ResizeArray
<_>(
len
)
for
i
=
0
to
len
-
1
do
let
x
,
y
=
arr
[
i
]
for
i
=
0
to
len
-
1
do
let
x
,
y
=
arr
[
i
]
res1
.
Add
(
x
)
res2
.
Add
(
y
)
res1
,
res2
res1
,
res2
src/Compiler/Utilities/RidHelpers.fs
浏览文件 @
4990f64f
...
...
@@ -10,14 +10,20 @@ module internal RidHelpers =
// Where rid is: win, win-x64, win-x86, osx-x64, linux-x64 etc ...
let
probingRids
,
baseRid
,
platformRid
=
let
processArchitecture
=
RuntimeInformation
.
ProcessArchitecture
let
baseRid
=
if
RuntimeInformation
.
IsOSPlatform
(
OSPlatform
.
Windows
)
then
"win"
elif
RuntimeInformation
.
IsOSPlatform
(
OSPlatform
.
OSX
)
then
"osx"
else
"linux"
if
RuntimeInformation
.
IsOSPlatform
(
OSPlatform
.
Windows
)
then
"win"
elif
RuntimeInformation
.
IsOSPlatform
(
OSPlatform
.
OSX
)
then
"osx"
else
"linux"
let
platformRid
=
match
processArchitecture
with
|
Architecture
.
X64
->
baseRid
+
"-x64"
|
Architecture
.
X64
->
baseRid
+
"-x64"
|
Architecture
.
X86
->
baseRid
+
"-x86"
|
Architecture
.
Arm64
->
baseRid
+
"-arm64"
|
_
->
baseRid
+
"-arm"
[|
"any"
;
baseRid
;
platformRid
|],
baseRid
,
platformRid
src/Compiler/Utilities/TaggedCollections.fs
浏览文件 @
4990f64f
此差异已折叠。
点击以展开。
src/Compiler/Utilities/XmlAdapters.fs
浏览文件 @
4990f64f
...
...
@@ -7,12 +7,11 @@ let s_escapeChars = [| '<'; '>'; '\"'; '\''; '&' |]
let
getEscapeSequence
c
=
match
c
with
|
'
<
'
->
"<"
|
'
>
'
->
">"
|
'
<
'
->
"<"
|
'
>
'
->
">"
|
'\"'
->
"""
|
'\''
->
"'"
|
'
&
'
->
"&"
|
'
&
'
->
"&"
|
_
as
ch
->
ch
.
ToString
()
let
escape
str
=
String
.
collect
getEscapeSequence
str
src/Compiler/Utilities/ildiag.fs
浏览文件 @
4990f64f
...
...
@@ -2,21 +2,44 @@
/// Configurable Diagnostics channel for the Abstract IL library
module
internal
FSharp
.
Compiler
.
AbstractIL
.
Diagnostics
module
internal
FSharp
.
Compiler
.
AbstractIL
.
Diagnostics
let
mutable
diagnosticsLog
=
Some
stdout
let
setDiagnosticsChannel
s
=
diagnosticsLog
<-
s
let
dflushn
()
=
match
diagnosticsLog
with
None
->
()
|
Some
d
->
d
.
WriteLine
()
;
d
.
Flush
()
let
dflush
()
=
match
diagnosticsLog
with
None
->
()
|
Some
d
->
d
.
Flush
()
let
dprintn
(
s
:
string
)
=
match
diagnosticsLog
with
None
->
()
|
Some
d
->
d
.
Write
s
;
d
.
Write
"
\n
"
;
dflush
()
let
dprintf
(
fmt
:
Format
<_,_,_,_>)
=
Printf
.
kfprintf
dflush
(
match
diagnosticsLog
with
None
->
System
.
IO
.
TextWriter
.
Null
|
Some
d
->
d
)
fmt
let
dprintfn
(
fmt
:
Format
<_,_,_,_>)
=
Printf
.
kfprintf
dflushn
(
match
diagnosticsLog
with
None
->
System
.
IO
.
TextWriter
.
Null
|
Some
d
->
d
)
fmt
let
setDiagnosticsChannel
s
=
diagnosticsLog
<-
s
let
dflushn
()
=
match
diagnosticsLog
with
|
None
->
()
|
Some
d
->
d
.
WriteLine
()
d
.
Flush
()
let
dflush
()
=
match
diagnosticsLog
with
|
None
->
()
|
Some
d
->
d
.
Flush
()
let
dprintn
(
s
:
string
)
=
match
diagnosticsLog
with
|
None
->
()
|
Some
d
->
d
.
Write
s
d
.
Write
"
\n
"
dflush
()
let
dprintf
(
fmt
:
Format
<_,
_,
_,
_>)
=
Printf
.
kfprintf
dflush
(
match
diagnosticsLog
with
|
None
->
System
.
IO
.
TextWriter
.
Null
|
Some
d
->
d
)
fmt
let
dprintfn
(
fmt
:
Format
<_,
_,
_,
_>)
=
Printf
.
kfprintf
dflushn
(
match
diagnosticsLog
with
|
None
->
System
.
IO
.
TextWriter
.
Null
|
Some
d
->
d
)
fmt
src/Compiler/Utilities/illib.fs
浏览文件 @
4990f64f
此差异已折叠。
点击以展开。
src/Compiler/Utilities/range.fs
浏览文件 @
4990f64f
此差异已折叠。
点击以展开。
src/Compiler/Utilities/rational.fs
浏览文件 @
4990f64f
...
...
@@ -5,62 +5,77 @@ module internal Internal.Utilities.Rational
open
System
.
Numerics
type
Rational
=
{
numerator
:
BigInteger
denominator
:
BigInteger
}
type
Rational
=
{
numerator
:
BigInteger
denominator
:
BigInteger
}
let
rec
gcd
a
(
b
:
BigInteger
)
=
if
b
=
BigInteger
.
Zero
then
a
else
gcd
b
(
a
%
b
)
let
lcm
a
b
=
(
a
*
b
)
/
(
gcd
a
b
)
if
b
=
BigInteger
.
Zero
then
a
else
gcd
b
(
a
%
b
)
let
lcm
a
b
=
(
a
*
b
)
/
(
gcd
a
b
)
let
mkRational
p
q
=
let
p
,
q
=
if
q
=
BigInteger
.
Zero
then
raise
(
System
.
DivideByZeroException
()
)
let
g
=
gcd
q
p
in
p
/
g
,
q
/
g
let
p
,
q
=
if
q
>
BigInteger
.
Zero
then
p
,
q
else
-
p
,
-
q
in
{
numerator
=
p
denominator
=
q
}
let
p
,
q
=
if
q
=
BigInteger
.
Zero
then
raise
(
System
.
DivideByZeroException
()
)
let
g
=
gcd
q
p
in
p
/
g
,
q
/
g
let
p
,
q
=
if
q
>
BigInteger
.
Zero
then
p
,
q
else
-
p
,
-
q
in
{
numerator
=
p
;
denominator
=
q
}
let
intToRational
(
p
:
int
)
=
mkRational
(
BigInteger
(
p
))
BigInteger
.
One
let
intToRational
(
p
:
int
)
=
mkRational
(
BigInteger
(
p
))
BigInteger
.
One
let
ZeroRational
=
mkRational
BigInteger
.
Zero
BigInteger
.
One
let
OneRational
=
mkRational
BigInteger
.
One
BigInteger
.
One
let
AddRational
m
n
=
let
d
=
gcd
m
.
denominator
n
.
denominator
let
m'
=
m
.
denominator
/
d
let
n'
=
n
.
denominator
/
d
mkRational
(
m
.
numerator
*
n'
+
n
.
numerator
*
m'
)
(
m
.
denominator
*
n'
)
let
d
=
gcd
m
.
denominator
n
.
denominator
let
m'
=
m
.
denominator
/
d
let
n'
=
n
.
denominator
/
d
mkRational
(
m
.
numerator
*
n'
+
n
.
numerator
*
m'
)
(
m
.
denominator
*
n'
)
let
NegRational
m
=
mkRational
(-
m
.
numerator
)
m
.
denominator
let
NegRational
m
=
mkRational
(-
m
.
numerator
)
m
.
denominator
let
MulRational
m
n
=
mkRational
(
m
.
numerator
*
n
.
numerator
)
(
m
.
denominator
*
n
.
denominator
)
mkRational
(
m
.
numerator
*
n
.
numerator
)
(
m
.
denominator
*
n
.
denominator
)
let
DivRational
m
n
=
mkRational
(
m
.
numerator
*
n
.
denominator
)
(
m
.
denominator
*
n
.
numerator
)
mkRational
(
m
.
numerator
*
n
.
denominator
)
(
m
.
denominator
*
n
.
numerator
)
let
AbsRational
m
=
mkRational
(
abs
m
.
numerator
)
m
.
denominator
let
AbsRational
m
=
mkRational
(
abs
m
.
numerator
)
m
.
denominator
let
RationalToString
m
=
if
m
.
denominator
=
BigInteger
.
One
then
m
.
numerator
.
ToString
()
else
sprintf
"(%A/%A)"
m
.
numerator
m
.
denominator
if
m
.
denominator
=
BigInteger
.
One
then
m
.
numerator
.
ToString
()
else
sprintf
"(%A/%A)"
m
.
numerator
m
.
denominator
let
GcdRational
m
n
=
mkRational
(
gcd
m
.
numerator
n
.
numerator
)
(
lcm
m
.
denominator
n
.
denominator
)
let
GcdRational
m
n
=
mkRational
(
gcd
m
.
numerator
n
.
numerator
)
(
lcm
m
.
denominator
n
.
denominator
)
let
GetNumerator
p
=
int
p
.
numerator
let
GetDenominator
p
=
int
p
.
denominator
let
SignRational
p
=
if
p
.
numerator
<
BigInteger
.
Zero
then
-
1
else
if
p
.
numerator
>
BigInteger
.
Zero
then
1
else
0
let
SignRational
p
=
if
p
.
numerator
<
BigInteger
.
Zero
then
-
1
else
if
p
.
numerator
>
BigInteger
.
Zero
then
1
else
0
src/Compiler/Utilities/sformat.fs
浏览文件 @
4990f64f
此差异已折叠。
点击以展开。
src/Compiler/Utilities/sr.fs
浏览文件 @
4990f64f
此差异已折叠。
点击以展开。
src/Compiler/Utilities/zmap.fs
浏览文件 @
4990f64f
...
...
@@ -6,41 +6,49 @@ open Internal.Utilities.Collections.Tagged
open
System
.
Collections
.
Generic
/// Maps with a specific comparison function
type
internal
Zmap
<
'
Key
,
'
T
>
=
Internal
.
Utilities
.
Collections
.
Tagged
.
Map
<
'
Key
,
'
T
>
type
internal
Zmap
<
'
Key
,
'
T
>
=
Internal
.
Utilities
.
Collections
.
Tagged
.
Map
<
'
Key
,
'
T
>
module
internal
Zmap
=
module
internal
Zmap
=
let
empty
(
ord
:
IComparer
<
'
T
>)
=
Map
<_,
_,_>.
Empty
(
ord
)
let
empty
(
ord
:
IComparer
<
'
T
>)
=
Map
<_,
_,
_>.
Empty
(
ord
)
let
add
k
v
(
m
:
Zmap
<_,_>)
=
m
.
Add
(
k
,
v
)
let
find
k
(
m
:
Zmap
<_,_>)
=
m
[
k
]
let
tryFind
k
(
m
:
Zmap
<_,_>)
=
m
.
TryFind
(
k
)
let
remove
k
(
m
:
Zmap
<_,_>)
=
m
.
Remove
(
k
)
let
mem
k
(
m
:
Zmap
<_,_>)
=
m
.
ContainsKey
(
k
)
let
iter
action
(
m
:
Zmap
<_,_>)
=
m
.
Iterate
(
action
)
let
first
f
(
m
:
Zmap
<_,_>)
=
m
.
First
(
fun
k
v
->
if
f
k
v
then
Some
(
k
,
v
)
else
None
)
let
exists
f
(
m
:
Zmap
<_,_>)
=
m
.
Exists
(
f
)
let
forall
f
(
m
:
Zmap
<_,_>)
=
m
.
ForAll
(
f
)
let
map
mapping
(
m
:
Zmap
<_,_>)
=
m
.
MapRange
(
mapping
)
let
mapi
mapping
(
m
:
Zmap
<_,_>)
=
m
.
Map
(
mapping
)
let
fold
f
(
m
:
Zmap
<_,_>)
x
=
m
.
Fold
f
x
let
toList
(
m
:
Zmap
<_,_>)
=
m
.
ToList
()
let
foldSection
lo
hi
f
(
m
:
Zmap
<_,_>)
x
=
m
.
FoldSection
lo
hi
f
x
let
add
k
v
(
m
:
Zmap
<_,
_>)
=
m
.
Add
(
k
,
v
)
let
find
k
(
m
:
Zmap
<_,
_>)
=
m
[
k
]
let
tryFind
k
(
m
:
Zmap
<_,
_>)
=
m
.
TryFind
(
k
)
let
remove
k
(
m
:
Zmap
<_,
_>)
=
m
.
Remove
(
k
)
let
mem
k
(
m
:
Zmap
<_,
_>)
=
m
.
ContainsKey
(
k
)
let
iter
action
(
m
:
Zmap
<_,
_>)
=
m
.
Iterate
(
action
)
let
isEmpty
(
m
:
Zmap
<_,_>)
=
m
.
IsEmpty
let
first
f
(
m
:
Zmap
<_,
_>)
=
m
.
First
(
fun
k
v
->
if
f
k
v
then
Some
(
k
,
v
)
else
None
)
let
foldMap
f
z
(
m
:
Zmap
<_,_>)
=
let
m
,
z
=
m
.
FoldAndMap
(
fun
k
v
z
->
let
z
,
v'
=
f
z
k
v
in
v'
,
z
)
z
in
z
,
m
let
exists
f
(
m
:
Zmap
<_,
_>)
=
m
.
Exists
(
f
)
let
forall
f
(
m
:
Zmap
<_,
_>)
=
m
.
ForAll
(
f
)
let
map
mapping
(
m
:
Zmap
<_,
_>)
=
m
.
MapRange
(
mapping
)
let
mapi
mapping
(
m
:
Zmap
<_,
_>)
=
m
.
Map
(
mapping
)
let
fold
f
(
m
:
Zmap
<_,
_>)
x
=
m
.
Fold
f
x
let
toList
(
m
:
Zmap
<_,
_>)
=
m
.
ToList
()
let
foldSection
lo
hi
f
(
m
:
Zmap
<_,
_>)
x
=
m
.
FoldSection
lo
hi
f
x
let
choose
f
(
m
:
Zmap
<_,_>)
=
m
.
First
(
f
)
let
isEmpty
(
m
:
Zmap
<_,
_>)
=
m
.
IsEmpty
let
chooseL
f
(
m
:
Zmap
<_,
_>)
=
m
.
Fold
(
fun
k
v
s
->
match
f
k
v
with
None
->
s
|
Some
x
->
x
::
s
)
[]
let
foldMap
f
z
(
m
:
Zmap
<_,
_>)
=
let
m
,
z
=
m
.
FoldAndMap
(
fun
k
v
z
->
let
z
,
v'
=
f
z
k
v
in
v'
,
z
)
z
in
z
,
m
let
ofList
ord
xs
=
Internal
.
Utilities
.
Collections
.
Tagged
.
Map
<_,_>.
FromList
(
ord
,
xs
)
let
choose
f
(
m
:
Zmap
<_,
_>)
=
m
.
First
(
f
)
let
keys
(
m
:
Zmap
<_,_>)
=
m
.
Fold
(
fun
k
_
s
->
k
::
s
)
[]
let
values
(
m
:
Zmap
<_,_>)
=
m
.
Fold
(
fun
_
v
s
->
v
::
s
)
[]
let
chooseL
f
(
m
:
Zmap
<_,
_>)
=
m
.
Fold
(
fun
k
v
s
->
match
f
k
v
with
|
None
->
s
|
Some
x
->
x
::
s
)
[]
let
ofList
ord
xs
=
Internal
.
Utilities
.
Collections
.
Tagged
.
Map
<_,
_>.
FromList
(
ord
,
xs
)
let
keys
(
m
:
Zmap
<_,
_>)
=
m
.
Fold
(
fun
k
_
s
->
k
::
s
)
[]
let
values
(
m
:
Zmap
<_,
_>)
=
m
.
Fold
(
fun
_
v
s
->
v
::
s
)
[]
let
memberOf
m
k
=
mem
k
m
src/Compiler/Utilities/zset.fs
浏览文件 @
4990f64f
...
...
@@ -8,9 +8,10 @@ open System.Collections.Generic
/// Sets with a specific comparison function
type
internal
Zset
<
'
T
>
=
Internal
.
Utilities
.
Collections
.
Tagged
.
Set
<
'
T
>
module
internal
Zset
=
module
internal
Zset
=
let
empty
(
ord
:
IComparer
<
'
T
>)
=
Internal
.
Utilities
.
Collections
.
Tagged
.
Set
<_,_>.
Empty
(
ord
)
let
empty
(
ord
:
IComparer
<
'
T
>)
=
Internal
.
Utilities
.
Collections
.
Tagged
.
Set
<_,
_>.
Empty
(
ord
)
let
isEmpty
(
s
:
Zset
<_>)
=
s
.
IsEmpty
...
...
@@ -19,33 +20,37 @@ module internal Zset =
let
add
x
(
s
:
Zset
<_>)
=
s
.
Add
(
x
)
let
addList
xs
a
=
List
.
fold
(
fun
a
x
->
add
x
a
)
a
xs
let
singleton
ord
x
=
add
x
(
empty
ord
)
let
remove
x
(
s
:
Zset
<_>)
=
s
.
Remove
(
x
)
let
fold
(
f
:
'
T
->
'
b
->
'
b
)
(
s
:
Zset
<_>)
b
=
s
.
Fold
f
b
let
fold
(
f
:
'
T
->
'
b
->
'
b
)
(
s
:
Zset
<_>)
b
=
s
.
Fold
f
b
let
iter
f
(
s
:
Zset
<_>)
=
s
.
Iterate
f
let
iter
f
(
s
:
Zset
<_>)
=
s
.
Iterate
f
let
forall
predicate
(
s
:
Zset
<_>)
=
s
.
ForAll
predicate
let
forall
predicate
(
s
:
Zset
<_>)
=
s
.
ForAll
predicate
let
count
(
s
:
Zset
<_>)
=
s
.
Count
let
count
(
s
:
Zset
<_>)
=
s
.
Count
let
exists
predicate
(
s
:
Zset
<_>)
=
s
.
Exists
predicate
let
subset
(
s1
:
Zset
<_>)
(
s2
:
Zset
<_>)
=
s1
.
IsSubsetOf
s2
let
subset
(
s1
:
Zset
<_>)
(
s2
:
Zset
<_>)
=
s1
.
IsSubsetOf
s2
let
equal
(
s1
:
Zset
<_>)
(
s2
:
Zset
<_>)
=
Internal
.
Utilities
.
Collections
.
Tagged
.
Set
<_,_>.
Equality
(
s1
,
s2
)
let
equal
(
s1
:
Zset
<_>)
(
s2
:
Zset
<_>)
=
Internal
.
Utilities
.
Collections
.
Tagged
.
Set
<_,
_>.
Equality
(
s1
,
s2
)
let
elements
(
s
:
Zset
<_>)
=
s
.
ToList
()
let
filter
predicate
(
s
:
Zset
<_>)
=
s
.
Filter
predicate
let
union
(
s1
:
Zset
<_>)
(
s2
:
Zset
<_>)
=
Internal
.
Utilities
.
Collections
.
Tagged
.
Set
<_,_>.
Union
(
s1
,
s2
)
let
union
(
s1
:
Zset
<_>)
(
s2
:
Zset
<_>)
=
Internal
.
Utilities
.
Collections
.
Tagged
.
Set
<_,
_>.
Union
(
s1
,
s2
)
let
inter
(
s1
:
Zset
<_>)
(
s2
:
Zset
<_>)
=
Internal
.
Utilities
.
Collections
.
Tagged
.
Set
<_,_>.
Intersection
(
s1
,
s2
)
let
inter
(
s1
:
Zset
<_>)
(
s2
:
Zset
<_>)
=
Internal
.
Utilities
.
Collections
.
Tagged
.
Set
<_,
_>.
Intersection
(
s1
,
s2
)
let
diff
(
s1
:
Zset
<_>)
(
s2
:
Zset
<_>)
=
Internal
.
Utilities
.
Collections
.
Tagged
.
Set
<_,_>.
Difference
(
s1
,
s2
)
let
diff
(
s1
:
Zset
<_>)
(
s2
:
Zset
<_>)
=
Internal
.
Utilities
.
Collections
.
Tagged
.
Set
<_,
_>.
Difference
(
s1
,
s2
)
let
memberOf
m
k
=
contains
k
m
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录