-- Copyright © 2026 Lingenic LLC. All rights reserved.
-- Licensed under the Lingenic Source-Available License v2.3.
-- Production use requires a separate license from Licensor.
-- See LICENSE.md and COPYRIGHT in the project root.
--
-------------------------------------------------------------------------------
-- Lingenic-Text
-- Formally Verified Unicode Text Processing Library
--
-- Root package: core types used throughout the library.
-------------------------------------------------------------------------------
package Lingenic_Text
with SPARK_Mode => On,
Pure
is
-- A Unicode codepoint: U+0000 .. U+10FFFF.
--
-- This subtype is the full Unicode codespace and DOES include the
-- surrogate range U+D800 .. U+DFFF. Surrogates are not Unicode scalar
-- values, but they are codepoints in the abstract sense, so the type
-- system does not exclude them here. Scalar-value-only inputs are
-- enforced structurally one layer up by the UTF-8 well-formedness
-- predicates (`UTF8_Spec.WF3` rejects the `ED A0..BF tail` lead-tail
-- combinations that would encode surrogates), so any codepoint that
-- reaches the algorithm layer via `UTF8.Decode` is already a scalar
-- value. Use `Is_Scalar_Value` (below) when filtering codepoints
-- obtained from non-UTF-8 sources.
subtype Codepoint is Natural range 0 .. 16#10_FFFF#;
-- A single byte value
subtype Byte is Natural range 0 .. 255;
-- A contiguous array of bytes (e.g. UTF-8 encoded text)
type Byte_Array is array (Positive range <>) of Byte;
-- Maximum codepoint value
Max_Codepoint : constant Codepoint := 16#10_FFFF#;
-- Total number of codepoint values
Codepoint_Count : constant Positive := Max_Codepoint + 1;
-- Surrogate range (not valid scalar values)
Surrogate_First : constant := 16#D800#;
Surrogate_Last : constant := 16#DFFF#;
-- A Unicode scalar value: a codepoint that is not a surrogate
function Is_Scalar_Value (CP : Codepoint) return Boolean is
(CP < Surrogate_First or CP > Surrogate_Last);
-- Noncharacter codepoints: U+FDD0..U+FDEF and U+xFFFE, U+xFFFF per plane
function Is_Noncharacter (CP : Codepoint) return Boolean is
((CP >= 16#FDD0# and CP <= 16#FDEF#)
or (CP mod 16#10000# >= 16#FFFE#));
---------------------------------------------------------------------------
-- ASCII byte constants used by UCD file format and parser
---------------------------------------------------------------------------
LF_Byte : constant Byte := 10; -- Line feed
CR_Byte : constant Byte := 13; -- Carriage return
Space_Byte : constant Byte := 32; -- Space
Tab_Byte : constant Byte := 9; -- Horizontal tab
Hash_Byte : constant Byte := 35; -- '#'
Dot_Byte : constant Byte := 46; -- '.'
Semicolon_Byte : constant Byte := 59; -- ';'
Zero_Byte : constant Byte := 48; -- '0'
Nine_Byte : constant Byte := 57; -- '9'
Upper_A_Byte : constant Byte := 65; -- 'A'
Upper_F_Byte : constant Byte := 70; -- 'F'
---------------------------------------------------------------------------
-- Character classification for UCD file parsing
---------------------------------------------------------------------------
function Is_Hex_Digit (B : Byte) return Boolean is
(B in Zero_Byte .. Nine_Byte
or else B in Upper_A_Byte .. Upper_F_Byte);
function Hex_Value (B : Byte) return Natural is
(if B in Zero_Byte .. Nine_Byte then B - Zero_Byte
else B - Upper_A_Byte + 10)
with Pre => Is_Hex_Digit (B),
Post => Hex_Value'Result <= 15;
function Is_Line_End (B : Byte) return Boolean is
(B = LF_Byte or B = CR_Byte);
function Is_Field_Space (B : Byte) return Boolean is
(B = Space_Byte or B = Tab_Byte);
end Lingenic_Text;