###################################################
#                                                 #
#  char_basic - Unicode general category (basic)  #
#                                                 #
###################################################

norename enum class char_basic

predefined

  L 0
  M 1
  N 2
  P 3
  S 4
  Z 5
  C 6
  I 7

end


###################################################
#                                                 #
#  char_cat - the Unicode general category        #
#                                                 #
###################################################

norename enum class char_cat

noncreation

  coerce basic: char_basic := char_basic!with_code(self.to_int div 10)

predefined

  Lu 0
  Ll 1
  Lt 2
  Lm 3
  Lo 4

  Mn 10
  Mc 11
  Me 12

  Nd 20
  Nl 21
  No 22

  Pc 31
  Pd 32
  Ps 33
  Pe 34
  Pi 35
  Pf 36
  Po 37

  Sm 40
  Sc 41
  Sk 42
  So 43

  Zs 50
  Zl 51
  Zp 52

  Cc 60
  Cf 61
  Cs 62
  Co 63
  Cn 64

  I 70

end


###################################################
#                                                 #
#   char_bidi - bidirectional formatting class    #
#                                                 #
###################################################

norename enum class char_bidi

predefined

  L
  LRE
  LRO
  R
  AL
  RLE
  RLO
  PDF
  EN
  ES
  ET
  AN
  CS
  NSM
  BN
  B
  S
  WS
  ON

end


###################################################
#                                                 #
#  char_map - mapping type (none, canonical, ...) #
#                                                 #
###################################################

norename enum class char_map

predefined

  none
  canonical
  font
  nobreak
  initial
  medial
  final
  isolated
  circle
  super
  sub
  vertical
  wide
  narrow
  small
  square
  fraction
  compat

end


###################################################
#                                                 #
#  char - one Unicode character                   #
#                                                 #
#  Numbers are represented as a numerator and a   #
#  denominator.  Denominator 0 indicates          #
#  non-numeric; denominator 1 indicates integer.  #
#  There is a separate is_decimal field, because  #
#  some characters with decimal values are not    #
#  in the decimal class (e.g. superscripts).      #
#                                                 #
#  Use a wide window to view the entries one      #
#  per line.                                      #
#                                                 #
###################################################

norename enum class char

   category: char_cat
   combining_class: byte
   bidi_class: char_bidi
   is_decimal: bool
   numerator, denominator: int
   is_mirrored: bool
   maptype: char_map
   map: string
   upper_case: string
   lower_case: string
   title_case: string

invariant

   if is_decimal then denominator = 1 else true end

noncreation

  cmp(other: char): int := to_int - other.to_int

  is_number: bool := denominator <> 0
  number_val: real require is_number end := numerator / denominator

  is_int: bool := denominator = 1
  int_val: int require is_int end := numerator
   
predefined

$INSERT_CHAR_LIST_HERE$
    
end
