@@ -3,7 +3,10 @@ Copyright © 2023-2025 François G. Dorais. All rights reserved.
33Released under Apache 2.0 license as described in the file LICENSE.
44-/
55module
6+ public import Std.Data.HashMap
7+
68public section
9+
710/-- Low-level conversion from `UInt32` to `Char` (*unsafe* )
811
912 This function translates to a no-op in the compiler. However, it does not
@@ -1014,5 +1017,65 @@ def BidiClass.ofAbbrev! (abbr : String.Slice) : BidiClass :=
10141017instance : Repr BidiClass where
10151018 reprPrec bc _ := s! "Unicode.BidiClass.{ bc.toAbbrev} "
10161019
1020+ /-!
1021+ ## Scripts ##
1022+ -/
1023+
1024+ /-- Check if valid script identifier -/
1025+ @[inline]
1026+ def Script.isValid (c : UInt32) : Bool :=
1027+ let c0 := (c >>> 24 ).toUInt8
1028+ let c1 := (c >>> 16 ).toUInt8
1029+ let c2 := (c >>> 8 ).toUInt8
1030+ let c3 := c.toUInt8
1031+ (c0 ≤ 'Z' .toUInt8 && 'A' .toUInt8 ≤ c0)
1032+ && (c1 ≤ 'z' .toUInt8 && 'a' .toUInt8 ≤ c1)
1033+ && (c2 ≤ 'z' .toUInt8 && 'a' .toUInt8 ≤ c2)
1034+ && (c3 ≤ 'z' .toUInt8 && 'a' .toUInt8 ≤ c3)
1035+
1036+ /-- Script identifier type -/
1037+ structure Script where
1038+ code : UInt32
1039+ is_valid : Script.isValid code
1040+ deriving DecidableEq, Hashable
1041+
1042+ namespace Script
1043+
1044+ /-- Default value is `Zzzz` (`Unknown`) -/
1045+ instance : Inhabited Script where
1046+ default := {
1047+ code := (((('Z' .val <<< 8 ||| 'z' .val) <<< 8 ) ||| 'z' .val) <<< 8 ) ||| 'z' .val
1048+ is_valid := by decide
1049+ }
1050+
1051+ /-- String abbreviation of script -/
1052+ @ [extern "unicode_script_to_abbrev" ]
1053+ def toAbbrev : Script → String
1054+ | ⟨c, _⟩ =>
1055+ let c0 := Char.ofUInt8 (c >>> 24 ).toUInt8
1056+ let c1 := Char.ofUInt8 (c >>> 16 ).toUInt8
1057+ let c2 := Char.ofUInt8 (c >>> 8 ).toUInt8
1058+ let c3 := Char.ofUInt8 c.toUInt8
1059+ String.ofList [c0, c1, c2, c3]
1060+
1061+ @ [extern "unicode_script_of_abbrev" ]
1062+ private opaque ofAbbrevAux (abbr : String) : UInt32
1063+
1064+ /-- Get script from abbreviation -/
1065+ def ofAbbrev? (abbr : String.Slice) : Option Script :=
1066+ if abbr.utf8ByteSize = 4 then
1067+ let code := ofAbbrevAux abbr.toString
1068+ if h : Script.isValid code then
1069+ some ⟨code, h⟩
1070+ else
1071+ none
1072+ else
1073+ none
1074+
1075+ @ [inline, inherit_doc ofAbbrev?]
1076+ def ofAbbrev! (abbr : String.Slice) : Script := ofAbbrev? abbr |>.get!
1077+
1078+ end Script
1079+
10171080end Unicode
10181081end
0 commit comments