Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | (* Copyright (C) 2014,2017 Matthew Fluet. |
2 | * Copyright (C) 2004-2007 Henry Cejtin, Matthew Fluet, Suresh | |
3 | * Jagannathan, and Stephen Weeks. | |
4 | * | |
5 | * MLton is released under a BSD-style license. | |
6 | * See the file MLton-LICENSE for details. | |
7 | *) | |
8 | ||
9 | functor WordXVector (S: WORD_X_VECTOR_STRUCTS): WORD_X_VECTOR = | |
10 | struct | |
11 | ||
12 | open S | |
13 | ||
14 | datatype t = T of {elementSize: WordSize.t, | |
15 | elements: WordX.t vector} | |
16 | ||
17 | local | |
18 | fun make f (T r) = f r | |
19 | in | |
20 | val elementSize = make #elementSize | |
21 | val elements = make #elements | |
22 | end | |
23 | ||
24 | fun layout (T {elements, elementSize}) = | |
25 | let | |
26 | fun vector () = | |
27 | Layout.seq | |
28 | [Layout.str "#[", | |
29 | Layout.fill (Layout.separateRight | |
30 | (Vector.toListMap | |
31 | (elements, WordX.layout), | |
32 | ",")), | |
33 | Layout.str "]"] | |
34 | fun string cs = | |
35 | Layout.seq | |
36 | [Layout.str "\"", | |
37 | Layout.str (String.escapeSML (String.implodeV cs)), | |
38 | Layout.str "\""] | |
39 | in | |
40 | if WordSize.equals (elementSize, WordSize.word8) | |
41 | then let | |
42 | val cs = Vector.map (elements, WordX.toChar) | |
43 | val l = Vector.length cs | |
44 | val n = Vector.fold (cs, 0, fn (c, n) => | |
45 | if Char.isGraph c | |
46 | orelse Char.isSpace c | |
47 | then n + 1 | |
48 | else n) | |
49 | in | |
50 | if l = 0 orelse (10 * n) div l > 9 | |
51 | then string cs | |
52 | else vector () | |
53 | end | |
54 | else vector () | |
55 | end | |
56 | ||
57 | val toString = Layout.toString o layout | |
58 | ||
59 | val hash = String.hash o toString | |
60 | ||
61 | fun equals (v, v') = | |
62 | WordSize.equals (elementSize v, elementSize v') | |
63 | andalso Vector.equals (elements v, elements v', WordX.equals) | |
64 | ||
65 | fun compare (v, v') = | |
66 | if WordSize.equals (elementSize v, elementSize v') | |
67 | then case Int.compare (Vector.length (elements v), Vector.length (elements v')) of | |
68 | LESS => LESS | |
69 | | EQUAL => Vector.compare (elements v, elements v', fn (w, w') => | |
70 | WordX.compare (w, w', {signed = false})) | |
71 | | GREATER => GREATER | |
72 | else Error.bug "WordXVector.compare" | |
73 | ||
74 | fun le (v, v') = | |
75 | case compare (v, v') of | |
76 | LESS => true | |
77 | | EQUAL => true | |
78 | | GREATER => false | |
79 | ||
80 | fun foldFrom (v, start, b, f) = Vector.foldFrom (elements v, start, b, f) | |
81 | ||
82 | fun forall (v, f) = Vector.forall (elements v, f) | |
83 | ||
84 | fun fromVector ({elementSize}, v) = | |
85 | T {elementSize = elementSize, | |
86 | elements = v} | |
87 | ||
88 | fun fromList ({elementSize}, l) = | |
89 | T {elementSize = elementSize, | |
90 | elements = Vector.fromList l} | |
91 | ||
92 | fun fromListRev ({elementSize}, l) = | |
93 | T {elementSize = elementSize, | |
94 | elements = Vector.fromListRev l} | |
95 | ||
96 | fun fromString s = | |
97 | T {elementSize = WordSize.byte, | |
98 | elements = Vector.tabulate (String.size s, fn i => | |
99 | WordX.fromChar (String.sub (s, i)))} | |
100 | ||
101 | fun length v = Vector.length (elements v) | |
102 | ||
103 | fun sub (v, i) = Vector.sub (elements v, i) | |
104 | ||
105 | fun tabulate ({elementSize}, n, f) = | |
106 | T {elementSize = elementSize, | |
107 | elements = Vector.tabulate (n, f)} | |
108 | ||
109 | fun toListMap (v, f) = Vector.toListMap (elements v, f) | |
110 | ||
111 | end |