umwi_0.1.0_34abe384/generator/src/generator.adb

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
with Ada.Strings.UTF_Encoding.Wide_Wide_Strings;
use  Ada.Strings.UTF_Encoding.Wide_Wide_Strings;
with Ada.Wide_Wide_Text_IO; use Ada.Wide_Wide_Text_IO;
with Ada.Characters.Conversions;

with AAA.Strings;

with Tools; use Tools;
with Tools.Emoji_Classifier;

procedure Generator is
   F : aliased File_Type;

   procedure Put_Line (Text : Wide_Wide_String) is
   begin
      Put_Line (F, Text);
   end Put_Line;

   procedure Put_Line is
   begin
      New_Line (F);
   end Put_Line;

   function H (S : String) return String
   is ("16#" & S & "#");

   Comb_Range : Tools.Range_Maker;
   First_Comb : Boolean := True;

   ---------------
   -- Combining --
   ---------------

   procedure Combining (Line : Tools.WWString) is
      use AAA.Strings;
      use Ada.Characters;
      Fields : constant Vector := Split (Conversions.To_String (Line), ';');
      --  The UnicodeData.txt file contains ASCII only so this is safe
   begin
      if Fields (3) (String'(Fields (3))'First) in 'M' | 'n' then
         --  A Marking general category is the combining telltale
         declare
            Opt_Range : constant Tools.Optional_Range :=
                          Comb_Range.Add
                            (New_Code (Natural'Value (H (Fields (1)))));
         begin
            if not Opt_Range.Empty then
               Put_Line ((if First_Comb then "      " else "    | ")
                         & Opt_Range.Codes.Image);
               First_Comb := False;
            end if;
         end;
      end if;
   end Combining;

   ---------
   -- EAW --
   ---------

   procedure EAW (Line : Tools.WWString) is
      use AAA.Strings;
   begin
      if Line = "" or else Line (Line'First) = '#' then
         return;
      end if;

      declare
         Line8 : constant String := Encode (Line); -- To UTF8
         Codes : constant Vector := Split (Line8, ';', Trim => True);
         Sepco : constant Vector := Split (Codes (1), '.');
         Width : constant Vector := Split (Codes (2), '#', Trim => True);
      begin
         if Width (1) /= "N" then -- This is covered by the "others" clause
            Put_Line ("      when " & C (Sepco (1)) & " .. "
                      & (if Sepco.Length in 3
                        then C (Sepco (3))
                        else C (Sepco (1)))
                      & " => " & Decode (Width (1)) & ",");
            Put_Line ("      --  " & Decode (Width (2)));
         end if;
      end;
   end EAW;

begin
   Create (F, Name => "../src/umwi-generated.ads");

   --  Preamble
   Put_Line ("pragma Style_Checks (Off);");
   Put_Line;
   Put_Line ("package Umwi.Generated with Preelaborate is");
   Put_Line;
   Put_Line ("   --  This file is generated by the generator nested crate 😁");
   Put_Line;

   --  Combining code points
   Put_Line
     ("   subtype Combining is WWChar with Static_Predicate => Combining in");
   Tools.Iterate ("share/generator/UnicodeData.txt", Combining'Access);
   Put_Line ("   ;");

   --  Emoji
   declare
      package X is new Emoji_Classifier ("Emoji", F'Unchecked_Access);
   begin
      Tools.Iterate ("share/generator/emoji-data.txt", X.Classify'Access);
      Put_Line ("   ;");
   end;

   --  Emoji_Presentation
   declare
      package X is new Emoji_Classifier ("Emoji_Presentation",
                                         F'Unchecked_Access);
   begin
      Tools.Iterate ("share/generator/emoji-data.txt", X.Classify'Access);
      Put_Line ("   ;");
   end;

   --  Emoji_Modifier_Base
   declare
      package X is new Emoji_Classifier ("Emoji_Modifier_Base",
                                         F'Unchecked_Access);
   begin
      Tools.Iterate ("share/generator/emoji-data.txt", X.Classify'Access);
      Put_Line ("   ;");
   end;

   --  Emoji_Modifier
   declare
      package X is new Emoji_Classifier ("Emoji_Modifier",
                                         F'Unchecked_Access);
   begin
      Tools.Iterate ("share/generator/emoji-data.txt", X.Classify'Access);
      Put_Line ("   ;");
   end;

   --  Emoji_Component
   declare
      package X is new Emoji_Classifier ("Emoji_Component",
                                         F'Unchecked_Access);
   begin
      Tools.Iterate ("share/generator/emoji-data.txt", X.Classify'Access);
      Put_Line ("   ;");
   end;

   --  Extended_Pictographic
   declare
      package X is new Emoji_Classifier ("Extended_Pictographic",
                                         F'Unchecked_Access);
   begin
      Tools.Iterate ("share/generator/emoji-data.txt", X.Classify'Access);
      Put_Line ("   ;");
   end;

   --  East_Asian_Width
   Put_Line;
   Put_Line ("   function Width (Symbol : WWChar) return East_Asian_Width");
   Put_Line ("   is (case Symbol is");
   Tools.Iterate ("share/generator/EastAsianWidth.txt", EAW'Access);
   Put_Line ("      when others => N);");

   --  Closure
   Put_Line;
   Put_Line ("end Umwi.Generated;");

   Close (F);
end Generator;