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  }