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