1 package frost.core
2
3 uses frost.unsafe.Pointer
4
5 ====================================================================================================
6 Represents any Unicode codepoint in the entire range from 0 to 1,114,112.
7
8 A single-codepoint string literal may be used wherever a `Char32` is expected. That is, it is legal
9 to write:
10
11 def c:Char32 := "A"
12
13 Note that a string which visually appears to be a single character may in fact consist of more than
14 one Unicode codepoint, and thus not be accepted as a `Char32` literal.
15 ====================================================================================================
16 class Char32 : Value, HashKey<Char32>, Comparable<Char32> {
17 @private
18 def value:Int32
19
20 ================================================================================================
21 Creates a `Char32` with the specified codepoint.
22 ================================================================================================
23 @pre(value >= 0 & value < 1114112< 1114112)
24 init(value:Int32) {
25 self.value := value
26 }
27
28 ================================================================================================
29 Returns the difference between the codepoints of two `Char32`s.
30 ================================================================================================
31 function -(other:Char32):Int32 {
32 return value - other.value
33 }
34
35 ================================================================================================
36 Returns the difference between the codepoints of two `Char32`s.
37 ================================================================================================
38 @priority(1)
39 function -(other:Char32):Int {
40 return (value - other.value).asInt
41 }
42
43 @override
44 function =(other:Char32):Bit {
45 return value = other.value
46 }
47
48 @override
49 function !=(other:Char32):Bit {
50 return value != other.value
51 }
52
53 @override
54 function <(other:Char32):Bit {
55 return value < other.value
56 }< other.value
57 }
58
59 @override
60 function >(other:Char32):Bit {
61 return value > other.value
62 }
63
64 @override
65 function <=(other:Char32):Bit {
66 return value <= other.value
67 }
68
69 @override
70 function >=(other:Char32):Bit {
71 return value >= other.value
72 }
73
74 ================================================================================================
75 `true` if this character is whitespace.
76 ================================================================================================
77 property isWhitespace:Bit
78 function get_isWhitespace():Bit {
79 -- FIXME respect all Unicode whitespace
80 match self {
81 when "\n", "\r", "\t", " " {
82 return true
83 }
84 otherwise {
85 return false
86 }
87 }
88 }
89
90 ================================================================================================
91 `true` if this character is a numeric digit.
92 ================================================================================================
93 property isDigit:Bit
94 function get_isDigit():Bit {
95 -- FIXME respect all Unicode digits
96 return self >= "0" & self <= "9"
97 }
98
99 ================================================================================================
100 Returns a string consisting of `count` copies of this character.
101 ================================================================================================
102 function *(count:Int):String {
103 def result := MutableString()
104 for i in 0 .. count {
105 result.append(self)
106 }
107 return result.finish()
108 }
109
110 ================================================================================================
111 Returns a string consisting of `count` copies of the given character.
112 ================================================================================================
113 @class
114 function *(count:Int, char:Char32):String {
115 return char * count
116 }
117
118 @override
119 function get_hash():Int {
120 return asInt
121 }
122
123 ================================================================================================
124 This character converted to a `Char8`. If this number is not in the range of a `Char8`, a safety
125 violation occurs.
126 ================================================================================================
127 property asChar8:Char8
128 function get_asChar8():Char8 {
129 return Char8(asUInt8)
130 }
131
132 ================================================================================================
133 This character converted to a `Char16`. If this number is not in the range of a `Char16`, a
134 safety violation occurs.
135 ================================================================================================
136 property asChar16:Char16
137 function get_asChar16():Char16 {
138 return Char16(asUInt16)
139 }
140
141 ================================================================================================
142 This character's codepoint converted to an 8 bit signed number. If this number is not in the
143 range of an 8 bit signed number, a safety violation occurs.
144 ================================================================================================
145 property asInt8:Int8
146 function get_asInt8():Int8 {
147 return value.asInt8
148 }
149
150 ================================================================================================
151 This character's codepoint converted to a 16 bit signed number. If this number is not in the
152 range of a 16 bit signed number, a safety violation occurs.
153 ================================================================================================
154 property asInt16:Int16
155 function get_asInt16():Int16 {
156 return value.asInt16
157 }
158
159 ================================================================================================
160 This character's codepoint converted to a 32 bit signed number.
161 ================================================================================================
162 property asInt32:Int32
163 function get_asInt32():Int32 {
164 return value
165 }
166
167 ================================================================================================
168 This character's codepoint converted to a 64 bit signed number.
169 ================================================================================================
170 property asInt64:Int64
171 function get_asInt64():Int64 {
172 return value.asInt64
173 }
174
175 ================================================================================================
176 This character's codepoint converted to an `Int`.
177 ================================================================================================
178 property asInt:Int
179 function get_asInt():Int {
180 return value.asInt
181 }
182
183 ================================================================================================
184 This character's codepoint converted to an 8 bit unsigned number. If this number is not in the
185 range of an 8 bit unsigned number, a safety violation occurs.
186 ================================================================================================
187 property asUInt8:UInt8
188 function get_asUInt8():UInt8 {
189 return value.asUInt8
190 }
191
192 ================================================================================================
193 This character's codepoint converted to a 16 bit unsigned number. If this number is not in the
194 range of a 16 bit unsigned number, a safety violation occurs.
195 ================================================================================================
196 property asUInt16:UInt16
197 function get_asUInt16():UInt16 {
198 return value.asUInt16
199 }
200
201 ================================================================================================
202 This character's codepoint converted to a 32 bit unsigned number.
203 ================================================================================================
204 property asUInt32:UInt32
205 function get_asUInt32():UInt32 {
206 return value.asUInt32
207 }
208
209 ================================================================================================
210 This character's codepoint converted to a 64 bit unsigned number.
211 ================================================================================================
212 property asUInt64:UInt64
213 function get_asUInt64():UInt64 {
214 return value.asUInt64
215 }
216
217 ================================================================================================
218 This character's codepoint converted to a `UInt`.
219 ================================================================================================
220 property asUInt:UInt
221 function get_asUInt():UInt {
222 return value.asUInt
223 }
224
225 ================================================================================================
226 This character converted to a `Char8`. If this number is not in the range of a `Char8`, it
227 silently overflows.
228 ================================================================================================
229 property toChar8:Char8
230 function get_toChar8():Char8 {
231 return Char8(toUInt8)
232 }
233
234 ================================================================================================
235 This character converted to a `Char16`. If this number is not in the range of a `Char16`, it
236 silently overflows.
237 ================================================================================================
238 property toChar16:Char16
239 function get_toChar16():Char16 {
240 return Char16(toUInt16)
241 }
242
243 ================================================================================================
244 This character's codepoint converted to an 8 bit signed number. If this number is not in the
245 range of an 8 bit signed number, it silently overflows.
246 ================================================================================================
247 property toInt8:Int8
248 function get_toInt8():Int8 {
249 return value.toInt8
250 }
251
252 ================================================================================================
253 This character's codepoint converted to a 16 bit signed number. If this number is not in the
254 range of a 16 bit signed number, it silently overflows.
255 ================================================================================================
256 property toInt16:Int16
257 function get_toInt16():Int16 {
258 return value.toInt16
259 }
260
261 ================================================================================================
262 This character's codepoint converted to a 32 bit signed number.
263 ================================================================================================
264 property toInt32:Int32
265 function get_toInt32():Int32 {
266 return value
267 }
268
269 ================================================================================================
270 This character's codepoint converted to a 64 bit signed number.
271 ================================================================================================
272 property toInt64:Int64
273 function get_toInt64():Int64 {
274 return value.toInt64
275 }
276
277 ================================================================================================
278 This character's codepoint converted to an `Int`.
279 ================================================================================================
280 property toInt:Int
281 function get_toInt():Int {
282 return value.toInt
283 }
284
285 ================================================================================================
286 This character's codepoint converted to an 8 bit unsigned number. If this number is not in the
287 range of an 8 bit unsigned number, it silently overflows.
288 ================================================================================================
289 property toUInt8:UInt8
290 function get_toUInt8():UInt8 {
291 return value.toUInt8
292 }
293
294 ================================================================================================
295 This character's codepoint converted to a 16 bit unsigned number. If this number is not in the
296 range of a 16 bit unsigned number, it silently overflows.
297 ================================================================================================
298 property toUInt16:UInt16
299 function get_toUInt16():UInt16 {
300 return value.toUInt16
301 }
302
303 ================================================================================================
304 This character's codepoint converted to a 32 bit unsigned number.
305 ================================================================================================
306 property toUInt32:UInt32
307 function get_toUInt32():UInt32 {
308 return value.toUInt32
309 }
310
311 ================================================================================================
312 This character's codepoint converted to a 64 bit unsigned number.
313 ================================================================================================
314 property toUInt64:UInt64
315 function get_toUInt64():UInt64 {
316 return value.toUInt64
317 }
318
319 ================================================================================================
320 This character's codepoint converted to a `UInt`.
321 ================================================================================================
322 property toUInt:UInt
323 function get_toUInt():UInt {
324 return value.toUInt
325 }
326
327 ================================================================================================
328 Returns a single-character `String` containing this `Char32`.
329 ================================================================================================
330 @override
331 function get_toString():String {
332 if value < 0x80< 0x80 {
333 def data := Pointer<Char8>.alloc(1)
334 data[0] := Char8(value.asUInt8)
335 return String(data, 1)
336 }
337 if value < 0x800< 0x800 {
338 def data := Pointer<Char8>.alloc(2)
339 data[0] := Char8((value >> 6 || 0b11000000).asUInt8)
340 data[1] := Char8((value && 0b111111 || 0b10000000).asUInt8)
341 return String(data, 2)
342 }
343 if value < 0x10000< 0x10000 {
344 def data := Pointer<Char8>.alloc(3)
345 data[0] := Char8((value >> 12 || 0b11100000).asUInt8)
346 data[1] := Char8((value >> 6 && 0b111111 || 0b10000000).asUInt8)
347 data[2] := Char8((value && 0b111111 || 0b10000000).asUInt8)
348 return String(data, 3)
349 }
350 def data := Pointer<Char8>.alloc(4)
351 data[0] := Char8((value >> 18 || 0b11110000).asUInt8)
352 data[1] := Char8((value >> 12 && 0b111111 || 0b10000000).asUInt8)
353 data[2] := Char8((value >> 6 && 0b111111 || 0b10000000).asUInt8)
354 data[3] := Char8((value && 0b111111 || 0b10000000).asUInt8)
355 return String(data, 4)
356 }
357 }