annotate gcc/ada/prep.adb @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT COMPILER COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- P R E P --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
9 -- Copyright (C) 2002-2018, Free Software Foundation, Inc. --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
kono
parents:
diff changeset
17 -- for more details. You should have received a copy of the GNU General --
kono
parents:
diff changeset
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
kono
parents:
diff changeset
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
kono
parents:
diff changeset
20 -- --
kono
parents:
diff changeset
21 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
23 -- --
kono
parents:
diff changeset
24 ------------------------------------------------------------------------------
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 with Csets; use Csets;
kono
parents:
diff changeset
27 with Err_Vars; use Err_Vars;
kono
parents:
diff changeset
28 with Opt; use Opt;
kono
parents:
diff changeset
29 with Osint; use Osint;
kono
parents:
diff changeset
30 with Output; use Output;
kono
parents:
diff changeset
31 with Scans; use Scans;
kono
parents:
diff changeset
32 with Snames; use Snames;
kono
parents:
diff changeset
33 with Sinput;
kono
parents:
diff changeset
34 with Stringt; use Stringt;
kono
parents:
diff changeset
35 with Table;
kono
parents:
diff changeset
36 with Uintp; use Uintp;
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 with GNAT.Heap_Sort_G;
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 package body Prep is
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 use Symbol_Table;
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 type Token_Name_Array is array (Token_Type) of Name_Id;
kono
parents:
diff changeset
45 Token_Names : constant Token_Name_Array :=
kono
parents:
diff changeset
46 (Tok_Abort => Name_Abort,
kono
parents:
diff changeset
47 Tok_Abs => Name_Abs,
kono
parents:
diff changeset
48 Tok_Abstract => Name_Abstract,
kono
parents:
diff changeset
49 Tok_Accept => Name_Accept,
kono
parents:
diff changeset
50 Tok_Aliased => Name_Aliased,
kono
parents:
diff changeset
51 Tok_All => Name_All,
kono
parents:
diff changeset
52 Tok_Array => Name_Array,
kono
parents:
diff changeset
53 Tok_And => Name_And,
kono
parents:
diff changeset
54 Tok_At => Name_At,
kono
parents:
diff changeset
55 Tok_Begin => Name_Begin,
kono
parents:
diff changeset
56 Tok_Body => Name_Body,
kono
parents:
diff changeset
57 Tok_Case => Name_Case,
kono
parents:
diff changeset
58 Tok_Constant => Name_Constant,
kono
parents:
diff changeset
59 Tok_Declare => Name_Declare,
kono
parents:
diff changeset
60 Tok_Delay => Name_Delay,
kono
parents:
diff changeset
61 Tok_Delta => Name_Delta,
kono
parents:
diff changeset
62 Tok_Digits => Name_Digits,
kono
parents:
diff changeset
63 Tok_Else => Name_Else,
kono
parents:
diff changeset
64 Tok_Elsif => Name_Elsif,
kono
parents:
diff changeset
65 Tok_End => Name_End,
kono
parents:
diff changeset
66 Tok_Entry => Name_Entry,
kono
parents:
diff changeset
67 Tok_Exception => Name_Exception,
kono
parents:
diff changeset
68 Tok_Exit => Name_Exit,
kono
parents:
diff changeset
69 Tok_For => Name_For,
kono
parents:
diff changeset
70 Tok_Function => Name_Function,
kono
parents:
diff changeset
71 Tok_Generic => Name_Generic,
kono
parents:
diff changeset
72 Tok_Goto => Name_Goto,
kono
parents:
diff changeset
73 Tok_If => Name_If,
kono
parents:
diff changeset
74 Tok_Is => Name_Is,
kono
parents:
diff changeset
75 Tok_Limited => Name_Limited,
kono
parents:
diff changeset
76 Tok_Loop => Name_Loop,
kono
parents:
diff changeset
77 Tok_Mod => Name_Mod,
kono
parents:
diff changeset
78 Tok_New => Name_New,
kono
parents:
diff changeset
79 Tok_Null => Name_Null,
kono
parents:
diff changeset
80 Tok_Of => Name_Of,
kono
parents:
diff changeset
81 Tok_Or => Name_Or,
kono
parents:
diff changeset
82 Tok_Others => Name_Others,
kono
parents:
diff changeset
83 Tok_Out => Name_Out,
kono
parents:
diff changeset
84 Tok_Package => Name_Package,
kono
parents:
diff changeset
85 Tok_Pragma => Name_Pragma,
kono
parents:
diff changeset
86 Tok_Private => Name_Private,
kono
parents:
diff changeset
87 Tok_Procedure => Name_Procedure,
kono
parents:
diff changeset
88 Tok_Protected => Name_Protected,
kono
parents:
diff changeset
89 Tok_Raise => Name_Raise,
kono
parents:
diff changeset
90 Tok_Range => Name_Range,
kono
parents:
diff changeset
91 Tok_Record => Name_Record,
kono
parents:
diff changeset
92 Tok_Rem => Name_Rem,
kono
parents:
diff changeset
93 Tok_Renames => Name_Renames,
kono
parents:
diff changeset
94 Tok_Requeue => Name_Requeue,
kono
parents:
diff changeset
95 Tok_Return => Name_Return,
kono
parents:
diff changeset
96 Tok_Reverse => Name_Reverse,
kono
parents:
diff changeset
97 Tok_Select => Name_Select,
kono
parents:
diff changeset
98 Tok_Separate => Name_Separate,
kono
parents:
diff changeset
99 Tok_Subtype => Name_Subtype,
kono
parents:
diff changeset
100 Tok_Tagged => Name_Tagged,
kono
parents:
diff changeset
101 Tok_Task => Name_Task,
kono
parents:
diff changeset
102 Tok_Terminate => Name_Terminate,
kono
parents:
diff changeset
103 Tok_Then => Name_Then,
kono
parents:
diff changeset
104 Tok_Type => Name_Type,
kono
parents:
diff changeset
105 Tok_Until => Name_Until,
kono
parents:
diff changeset
106 Tok_Use => Name_Use,
kono
parents:
diff changeset
107 Tok_When => Name_When,
kono
parents:
diff changeset
108 Tok_While => Name_While,
kono
parents:
diff changeset
109 Tok_With => Name_With,
kono
parents:
diff changeset
110 Tok_Xor => Name_Xor,
kono
parents:
diff changeset
111 others => No_Name);
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 Already_Initialized : Boolean := False;
kono
parents:
diff changeset
114 -- Used to avoid repetition of the part of the initialisation that needs
kono
parents:
diff changeset
115 -- to be done only once.
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 Empty_String : String_Id;
kono
parents:
diff changeset
118 -- "", as a string_id
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 String_False : String_Id;
kono
parents:
diff changeset
121 -- "false", as a string_id
kono
parents:
diff changeset
122
kono
parents:
diff changeset
123 --------------
kono
parents:
diff changeset
124 -- Behavior --
kono
parents:
diff changeset
125 --------------
kono
parents:
diff changeset
126
kono
parents:
diff changeset
127 -- Accesses to procedure specified by procedure Initialize
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 Error_Msg : Error_Msg_Proc;
kono
parents:
diff changeset
130 -- Report an error
kono
parents:
diff changeset
131
kono
parents:
diff changeset
132 Scan : Scan_Proc;
kono
parents:
diff changeset
133 -- Scan one token
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 Set_Ignore_Errors : Set_Ignore_Errors_Proc;
kono
parents:
diff changeset
136 -- Indicate if error should be taken into account
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138 Put_Char : Put_Char_Proc;
kono
parents:
diff changeset
139 -- Output one character
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 New_EOL : New_EOL_Proc;
kono
parents:
diff changeset
142 -- Output an end of line indication
kono
parents:
diff changeset
143
kono
parents:
diff changeset
144 -------------------------------
kono
parents:
diff changeset
145 -- State of the Preprocessor --
kono
parents:
diff changeset
146 -------------------------------
kono
parents:
diff changeset
147
kono
parents:
diff changeset
148 type Pp_State is record
kono
parents:
diff changeset
149 If_Ptr : Source_Ptr;
kono
parents:
diff changeset
150 -- The location of the #if statement (used to flag #if with no
kono
parents:
diff changeset
151 -- corresponding #end if, at the end).
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 Else_Ptr : Source_Ptr;
kono
parents:
diff changeset
154 -- The location of the #else statement (used to detect multiple #else's)
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 Deleting : Boolean;
kono
parents:
diff changeset
157 -- Set to True when the code should be deleted or commented out
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 Match_Seen : Boolean;
kono
parents:
diff changeset
160 -- Set to True when a condition in an #if or an #elsif is True. Also set
kono
parents:
diff changeset
161 -- to True if Deleting at the previous level is True. Used to decide if
kono
parents:
diff changeset
162 -- Deleting should be set to True in a following #elsif or #else.
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 end record;
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 type Pp_Depth is new Nat;
kono
parents:
diff changeset
167
kono
parents:
diff changeset
168 Ground : constant Pp_Depth := 0;
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 package Pp_States is new Table.Table
kono
parents:
diff changeset
171 (Table_Component_Type => Pp_State,
kono
parents:
diff changeset
172 Table_Index_Type => Pp_Depth,
kono
parents:
diff changeset
173 Table_Low_Bound => 1,
kono
parents:
diff changeset
174 Table_Initial => 10,
kono
parents:
diff changeset
175 Table_Increment => 100,
kono
parents:
diff changeset
176 Table_Name => "Prep.Pp_States");
kono
parents:
diff changeset
177 -- A stack of the states of the preprocessor, for nested #if
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 type Operator is (None, Op_Or, Op_And);
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 -----------------
kono
parents:
diff changeset
182 -- Subprograms --
kono
parents:
diff changeset
183 -----------------
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 function Deleting return Boolean;
kono
parents:
diff changeset
186 -- Return True if code should be deleted or commented out
kono
parents:
diff changeset
187
kono
parents:
diff changeset
188 function Expression
kono
parents:
diff changeset
189 (Evaluate_It : Boolean;
kono
parents:
diff changeset
190 Complemented : Boolean := False) return Boolean;
kono
parents:
diff changeset
191 -- Evaluate a condition in an #if or an #elsif statement. If Evaluate_It
kono
parents:
diff changeset
192 -- is False, the condition is effectively evaluated, otherwise, only the
kono
parents:
diff changeset
193 -- syntax is checked.
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 procedure Go_To_End_Of_Line;
kono
parents:
diff changeset
196 -- Advance the scan pointer until we reach an end of line or the end of the
kono
parents:
diff changeset
197 -- buffer.
kono
parents:
diff changeset
198
kono
parents:
diff changeset
199 function Matching_Strings (S1, S2 : String_Id) return Boolean;
kono
parents:
diff changeset
200 -- Returns True if the two string parameters are equal (case insensitive)
kono
parents:
diff changeset
201
kono
parents:
diff changeset
202 ---------------------------------------
kono
parents:
diff changeset
203 -- Change_Reserved_Keyword_To_Symbol --
kono
parents:
diff changeset
204 ---------------------------------------
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 procedure Change_Reserved_Keyword_To_Symbol
kono
parents:
diff changeset
207 (All_Keywords : Boolean := False)
kono
parents:
diff changeset
208 is
kono
parents:
diff changeset
209 New_Name : constant Name_Id := Token_Names (Token);
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 begin
kono
parents:
diff changeset
212 if New_Name /= No_Name then
kono
parents:
diff changeset
213 case Token is
kono
parents:
diff changeset
214 when Tok_And
kono
parents:
diff changeset
215 | Tok_Else
kono
parents:
diff changeset
216 | Tok_Elsif
kono
parents:
diff changeset
217 | Tok_End
kono
parents:
diff changeset
218 | Tok_If
kono
parents:
diff changeset
219 | Tok_Or
kono
parents:
diff changeset
220 | Tok_Then
kono
parents:
diff changeset
221 =>
kono
parents:
diff changeset
222 if All_Keywords then
kono
parents:
diff changeset
223 Token := Tok_Identifier;
kono
parents:
diff changeset
224 Token_Name := New_Name;
kono
parents:
diff changeset
225 end if;
kono
parents:
diff changeset
226
kono
parents:
diff changeset
227 when others =>
kono
parents:
diff changeset
228 Token := Tok_Identifier;
kono
parents:
diff changeset
229 Token_Name := New_Name;
kono
parents:
diff changeset
230 end case;
kono
parents:
diff changeset
231 end if;
kono
parents:
diff changeset
232 end Change_Reserved_Keyword_To_Symbol;
kono
parents:
diff changeset
233
kono
parents:
diff changeset
234 ------------------------------------------
kono
parents:
diff changeset
235 -- Check_Command_Line_Symbol_Definition --
kono
parents:
diff changeset
236 ------------------------------------------
kono
parents:
diff changeset
237
kono
parents:
diff changeset
238 procedure Check_Command_Line_Symbol_Definition
kono
parents:
diff changeset
239 (Definition : String;
kono
parents:
diff changeset
240 Data : out Symbol_Data)
kono
parents:
diff changeset
241 is
kono
parents:
diff changeset
242 Index : Natural := 0;
kono
parents:
diff changeset
243 Result : Symbol_Data;
kono
parents:
diff changeset
244
kono
parents:
diff changeset
245 begin
kono
parents:
diff changeset
246 -- Look for the character '='
kono
parents:
diff changeset
247
kono
parents:
diff changeset
248 for J in Definition'Range loop
kono
parents:
diff changeset
249 if Definition (J) = '=' then
kono
parents:
diff changeset
250 Index := J;
kono
parents:
diff changeset
251 exit;
kono
parents:
diff changeset
252 end if;
kono
parents:
diff changeset
253 end loop;
kono
parents:
diff changeset
254
kono
parents:
diff changeset
255 -- If no character '=', then the value is True
kono
parents:
diff changeset
256
kono
parents:
diff changeset
257 if Index = 0 then
kono
parents:
diff changeset
258
kono
parents:
diff changeset
259 -- Put the symbol in the name buffer
kono
parents:
diff changeset
260
kono
parents:
diff changeset
261 Name_Len := Definition'Length;
kono
parents:
diff changeset
262 Name_Buffer (1 .. Name_Len) := Definition;
kono
parents:
diff changeset
263 Result := True_Value;
kono
parents:
diff changeset
264
kono
parents:
diff changeset
265 elsif Index = Definition'First then
kono
parents:
diff changeset
266 Fail ("invalid symbol definition """ & Definition & """");
kono
parents:
diff changeset
267
kono
parents:
diff changeset
268 else
kono
parents:
diff changeset
269 -- Put the symbol in the name buffer
kono
parents:
diff changeset
270
kono
parents:
diff changeset
271 Name_Len := Index - Definition'First;
kono
parents:
diff changeset
272 Name_Buffer (1 .. Name_Len) :=
kono
parents:
diff changeset
273 String'(Definition (Definition'First .. Index - 1));
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 -- Check the syntax of the value
kono
parents:
diff changeset
276
kono
parents:
diff changeset
277 if Definition (Index + 1) /= '"'
kono
parents:
diff changeset
278 or else Definition (Definition'Last) /= '"'
kono
parents:
diff changeset
279 then
kono
parents:
diff changeset
280 for J in Index + 1 .. Definition'Last loop
kono
parents:
diff changeset
281 case Definition (J) is
kono
parents:
diff changeset
282 when '_' | '.' | '0' .. '9' | 'a' .. 'z' | 'A' .. 'Z' =>
kono
parents:
diff changeset
283 null;
kono
parents:
diff changeset
284
kono
parents:
diff changeset
285 when others =>
kono
parents:
diff changeset
286 Fail ("illegal value """
kono
parents:
diff changeset
287 & Definition (Index + 1 .. Definition'Last)
kono
parents:
diff changeset
288 & """");
kono
parents:
diff changeset
289 end case;
kono
parents:
diff changeset
290 end loop;
kono
parents:
diff changeset
291 end if;
kono
parents:
diff changeset
292
kono
parents:
diff changeset
293 -- Even if the value is a string, we still set Is_A_String to False,
kono
parents:
diff changeset
294 -- to avoid adding additional quotes in the preprocessed sources when
kono
parents:
diff changeset
295 -- replacing $<symbol>.
kono
parents:
diff changeset
296
kono
parents:
diff changeset
297 Result.Is_A_String := False;
kono
parents:
diff changeset
298
kono
parents:
diff changeset
299 -- Put the value in the result
kono
parents:
diff changeset
300
kono
parents:
diff changeset
301 Start_String;
kono
parents:
diff changeset
302 Store_String_Chars (Definition (Index + 1 .. Definition'Last));
kono
parents:
diff changeset
303 Result.Value := End_String;
kono
parents:
diff changeset
304 end if;
kono
parents:
diff changeset
305
kono
parents:
diff changeset
306 -- Now, check the syntax of the symbol (we don't allow accented or
kono
parents:
diff changeset
307 -- wide characters).
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309 if Name_Buffer (1) not in 'a' .. 'z'
kono
parents:
diff changeset
310 and then Name_Buffer (1) not in 'A' .. 'Z'
kono
parents:
diff changeset
311 then
kono
parents:
diff changeset
312 Fail ("symbol """
kono
parents:
diff changeset
313 & Name_Buffer (1 .. Name_Len)
kono
parents:
diff changeset
314 & """ does not start with a letter");
kono
parents:
diff changeset
315 end if;
kono
parents:
diff changeset
316
kono
parents:
diff changeset
317 for J in 2 .. Name_Len loop
kono
parents:
diff changeset
318 case Name_Buffer (J) is
kono
parents:
diff changeset
319 when 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' =>
kono
parents:
diff changeset
320 null;
kono
parents:
diff changeset
321
kono
parents:
diff changeset
322 when '_' =>
kono
parents:
diff changeset
323 if J = Name_Len then
kono
parents:
diff changeset
324 Fail ("symbol """
kono
parents:
diff changeset
325 & Name_Buffer (1 .. Name_Len)
kono
parents:
diff changeset
326 & """ end with a '_'");
kono
parents:
diff changeset
327
kono
parents:
diff changeset
328 elsif Name_Buffer (J + 1) = '_' then
kono
parents:
diff changeset
329 Fail ("symbol """
kono
parents:
diff changeset
330 & Name_Buffer (1 .. Name_Len)
kono
parents:
diff changeset
331 & """ contains consecutive '_'");
kono
parents:
diff changeset
332 end if;
kono
parents:
diff changeset
333
kono
parents:
diff changeset
334 when others =>
kono
parents:
diff changeset
335 Fail ("symbol """
kono
parents:
diff changeset
336 & Name_Buffer (1 .. Name_Len)
kono
parents:
diff changeset
337 & """ contains illegal character(s)");
kono
parents:
diff changeset
338 end case;
kono
parents:
diff changeset
339 end loop;
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 Result.On_The_Command_Line := True;
kono
parents:
diff changeset
342
kono
parents:
diff changeset
343 -- Put the symbol name in the result
kono
parents:
diff changeset
344
kono
parents:
diff changeset
345 declare
kono
parents:
diff changeset
346 Sym : constant String := Name_Buffer (1 .. Name_Len);
kono
parents:
diff changeset
347
kono
parents:
diff changeset
348 begin
kono
parents:
diff changeset
349 for Index in 1 .. Name_Len loop
kono
parents:
diff changeset
350 Name_Buffer (Index) := Fold_Lower (Name_Buffer (Index));
kono
parents:
diff changeset
351 end loop;
kono
parents:
diff changeset
352
kono
parents:
diff changeset
353 Result.Symbol := Name_Find;
kono
parents:
diff changeset
354 Name_Len := Sym'Length;
kono
parents:
diff changeset
355 Name_Buffer (1 .. Name_Len) := Sym;
kono
parents:
diff changeset
356 Result.Original := Name_Find;
kono
parents:
diff changeset
357 end;
kono
parents:
diff changeset
358
kono
parents:
diff changeset
359 Data := Result;
kono
parents:
diff changeset
360 end Check_Command_Line_Symbol_Definition;
kono
parents:
diff changeset
361
kono
parents:
diff changeset
362 --------------
kono
parents:
diff changeset
363 -- Deleting --
kono
parents:
diff changeset
364 --------------
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 function Deleting return Boolean is
kono
parents:
diff changeset
367 begin
kono
parents:
diff changeset
368 -- Always return False when not inside an #if statement
kono
parents:
diff changeset
369
kono
parents:
diff changeset
370 if Opt.No_Deletion or else Pp_States.Last = Ground then
kono
parents:
diff changeset
371 return False;
kono
parents:
diff changeset
372 else
kono
parents:
diff changeset
373 return Pp_States.Table (Pp_States.Last).Deleting;
kono
parents:
diff changeset
374 end if;
kono
parents:
diff changeset
375 end Deleting;
kono
parents:
diff changeset
376
kono
parents:
diff changeset
377 ----------------
kono
parents:
diff changeset
378 -- Expression --
kono
parents:
diff changeset
379 ----------------
kono
parents:
diff changeset
380
kono
parents:
diff changeset
381 function Expression
kono
parents:
diff changeset
382 (Evaluate_It : Boolean;
kono
parents:
diff changeset
383 Complemented : Boolean := False) return Boolean
kono
parents:
diff changeset
384 is
kono
parents:
diff changeset
385 Evaluation : Boolean := Evaluate_It;
kono
parents:
diff changeset
386 -- Is set to False after an "or else" when left term is True and after
kono
parents:
diff changeset
387 -- an "and then" when left term is False.
kono
parents:
diff changeset
388
kono
parents:
diff changeset
389 Final_Result : Boolean := False;
kono
parents:
diff changeset
390
kono
parents:
diff changeset
391 Current_Result : Boolean := False;
kono
parents:
diff changeset
392 -- Value of a term
kono
parents:
diff changeset
393
kono
parents:
diff changeset
394 Current_Operator : Operator := None;
kono
parents:
diff changeset
395 Symbol1 : Symbol_Id;
kono
parents:
diff changeset
396 Symbol2 : Symbol_Id;
kono
parents:
diff changeset
397 Symbol_Name1 : Name_Id;
kono
parents:
diff changeset
398 Symbol_Name2 : Name_Id;
kono
parents:
diff changeset
399 Symbol_Pos1 : Source_Ptr;
kono
parents:
diff changeset
400 Symbol_Pos2 : Source_Ptr;
kono
parents:
diff changeset
401 Symbol_Value1 : String_Id;
kono
parents:
diff changeset
402 Symbol_Value2 : String_Id;
kono
parents:
diff changeset
403
kono
parents:
diff changeset
404 Relop : Token_Type;
kono
parents:
diff changeset
405
kono
parents:
diff changeset
406 begin
kono
parents:
diff changeset
407 -- Loop for each term
kono
parents:
diff changeset
408
kono
parents:
diff changeset
409 loop
kono
parents:
diff changeset
410 Change_Reserved_Keyword_To_Symbol;
kono
parents:
diff changeset
411
kono
parents:
diff changeset
412 Current_Result := False;
kono
parents:
diff changeset
413
kono
parents:
diff changeset
414 -- Scan current term, starting with Token
kono
parents:
diff changeset
415
kono
parents:
diff changeset
416 case Token is
kono
parents:
diff changeset
417
kono
parents:
diff changeset
418 -- Handle parenthesized expression
kono
parents:
diff changeset
419
kono
parents:
diff changeset
420 when Tok_Left_Paren =>
kono
parents:
diff changeset
421 Scan.all;
kono
parents:
diff changeset
422 Current_Result := Expression (Evaluation);
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 if Token = Tok_Right_Paren then
kono
parents:
diff changeset
425 Scan.all;
kono
parents:
diff changeset
426
kono
parents:
diff changeset
427 else
kono
parents:
diff changeset
428 Error_Msg -- CODEFIX
kono
parents:
diff changeset
429 ("`)` expected", Token_Ptr);
kono
parents:
diff changeset
430 end if;
kono
parents:
diff changeset
431
kono
parents:
diff changeset
432 -- Handle not expression
kono
parents:
diff changeset
433
kono
parents:
diff changeset
434 when Tok_Not =>
kono
parents:
diff changeset
435 Scan.all;
kono
parents:
diff changeset
436 Current_Result :=
kono
parents:
diff changeset
437 not Expression (Evaluation, Complemented => True);
kono
parents:
diff changeset
438
kono
parents:
diff changeset
439 -- Handle sequence starting with identifier
kono
parents:
diff changeset
440
kono
parents:
diff changeset
441 when Tok_Identifier =>
kono
parents:
diff changeset
442 Symbol_Name1 := Token_Name;
kono
parents:
diff changeset
443 Symbol_Pos1 := Token_Ptr;
kono
parents:
diff changeset
444 Scan.all;
kono
parents:
diff changeset
445
kono
parents:
diff changeset
446 if Token = Tok_Apostrophe then
kono
parents:
diff changeset
447
kono
parents:
diff changeset
448 -- symbol'Defined
kono
parents:
diff changeset
449
kono
parents:
diff changeset
450 Scan.all;
kono
parents:
diff changeset
451
kono
parents:
diff changeset
452 if Token = Tok_Identifier
kono
parents:
diff changeset
453 and then Token_Name = Name_Defined
kono
parents:
diff changeset
454 then
kono
parents:
diff changeset
455 Scan.all;
kono
parents:
diff changeset
456
kono
parents:
diff changeset
457 else
kono
parents:
diff changeset
458 Error_Msg ("identifier `Defined` expected", Token_Ptr);
kono
parents:
diff changeset
459 end if;
kono
parents:
diff changeset
460
kono
parents:
diff changeset
461 if Evaluation then
kono
parents:
diff changeset
462 Current_Result := Index_Of (Symbol_Name1) /= No_Symbol;
kono
parents:
diff changeset
463 end if;
kono
parents:
diff changeset
464
kono
parents:
diff changeset
465 -- Handle relational operator
kono
parents:
diff changeset
466
kono
parents:
diff changeset
467 elsif Token = Tok_Equal
kono
parents:
diff changeset
468 or else Token = Tok_Less
kono
parents:
diff changeset
469 or else Token = Tok_Less_Equal
kono
parents:
diff changeset
470 or else Token = Tok_Greater
kono
parents:
diff changeset
471 or else Token = Tok_Greater_Equal
kono
parents:
diff changeset
472 then
kono
parents:
diff changeset
473 Relop := Token;
kono
parents:
diff changeset
474 Scan.all;
kono
parents:
diff changeset
475 Change_Reserved_Keyword_To_Symbol;
kono
parents:
diff changeset
476
kono
parents:
diff changeset
477 if Token = Tok_Integer_Literal then
kono
parents:
diff changeset
478
kono
parents:
diff changeset
479 -- symbol = integer
kono
parents:
diff changeset
480 -- symbol < integer
kono
parents:
diff changeset
481 -- symbol <= integer
kono
parents:
diff changeset
482 -- symbol > integer
kono
parents:
diff changeset
483 -- symbol >= integer
kono
parents:
diff changeset
484
kono
parents:
diff changeset
485 declare
kono
parents:
diff changeset
486 Value : constant Int := UI_To_Int (Int_Literal_Value);
kono
parents:
diff changeset
487 Data : Symbol_Data;
kono
parents:
diff changeset
488
kono
parents:
diff changeset
489 Symbol_Value : Int;
kono
parents:
diff changeset
490 -- Value of symbol as Int
kono
parents:
diff changeset
491
kono
parents:
diff changeset
492 begin
kono
parents:
diff changeset
493 if Evaluation then
kono
parents:
diff changeset
494 Symbol1 := Index_Of (Symbol_Name1);
kono
parents:
diff changeset
495
kono
parents:
diff changeset
496 if Symbol1 = No_Symbol then
kono
parents:
diff changeset
497 Error_Msg_Name_1 := Symbol_Name1;
kono
parents:
diff changeset
498 Error_Msg ("unknown symbol %", Symbol_Pos1);
kono
parents:
diff changeset
499 Symbol_Value1 := No_String;
kono
parents:
diff changeset
500
kono
parents:
diff changeset
501 else
kono
parents:
diff changeset
502 Data := Mapping.Table (Symbol1);
kono
parents:
diff changeset
503
kono
parents:
diff changeset
504 if Data.Is_A_String then
kono
parents:
diff changeset
505 Error_Msg_Name_1 := Symbol_Name1;
kono
parents:
diff changeset
506 Error_Msg
kono
parents:
diff changeset
507 ("symbol % value is not integer",
kono
parents:
diff changeset
508 Symbol_Pos1);
kono
parents:
diff changeset
509
kono
parents:
diff changeset
510 else
kono
parents:
diff changeset
511 begin
kono
parents:
diff changeset
512 String_To_Name_Buffer (Data.Value);
kono
parents:
diff changeset
513 Symbol_Value :=
kono
parents:
diff changeset
514 Int'Value (Name_Buffer (1 .. Name_Len));
kono
parents:
diff changeset
515
kono
parents:
diff changeset
516 case Relop is
kono
parents:
diff changeset
517 when Tok_Equal =>
kono
parents:
diff changeset
518 Current_Result :=
kono
parents:
diff changeset
519 Symbol_Value = Value;
kono
parents:
diff changeset
520
kono
parents:
diff changeset
521 when Tok_Less =>
kono
parents:
diff changeset
522 Current_Result :=
kono
parents:
diff changeset
523 Symbol_Value < Value;
kono
parents:
diff changeset
524
kono
parents:
diff changeset
525 when Tok_Less_Equal =>
kono
parents:
diff changeset
526 Current_Result :=
kono
parents:
diff changeset
527 Symbol_Value <= Value;
kono
parents:
diff changeset
528
kono
parents:
diff changeset
529 when Tok_Greater =>
kono
parents:
diff changeset
530 Current_Result :=
kono
parents:
diff changeset
531 Symbol_Value > Value;
kono
parents:
diff changeset
532
kono
parents:
diff changeset
533 when Tok_Greater_Equal =>
kono
parents:
diff changeset
534 Current_Result :=
kono
parents:
diff changeset
535 Symbol_Value >= Value;
kono
parents:
diff changeset
536
kono
parents:
diff changeset
537 when others =>
kono
parents:
diff changeset
538 null;
kono
parents:
diff changeset
539 end case;
kono
parents:
diff changeset
540
kono
parents:
diff changeset
541 exception
kono
parents:
diff changeset
542 when Constraint_Error =>
kono
parents:
diff changeset
543 Error_Msg_Name_1 := Symbol_Name1;
kono
parents:
diff changeset
544 Error_Msg
kono
parents:
diff changeset
545 ("symbol % value is not an integer",
kono
parents:
diff changeset
546 Symbol_Pos1);
kono
parents:
diff changeset
547 end;
kono
parents:
diff changeset
548 end if;
kono
parents:
diff changeset
549 end if;
kono
parents:
diff changeset
550 end if;
kono
parents:
diff changeset
551
kono
parents:
diff changeset
552 Scan.all;
kono
parents:
diff changeset
553 end;
kono
parents:
diff changeset
554
kono
parents:
diff changeset
555 -- Error if relational operator other than = if not numbers
kono
parents:
diff changeset
556
kono
parents:
diff changeset
557 elsif Relop /= Tok_Equal then
kono
parents:
diff changeset
558 Error_Msg ("number expected", Token_Ptr);
kono
parents:
diff changeset
559
kono
parents:
diff changeset
560 -- Equality comparison of two strings
kono
parents:
diff changeset
561
kono
parents:
diff changeset
562 elsif Token = Tok_Identifier then
kono
parents:
diff changeset
563
kono
parents:
diff changeset
564 -- symbol = symbol
kono
parents:
diff changeset
565
kono
parents:
diff changeset
566 Symbol_Name2 := Token_Name;
kono
parents:
diff changeset
567 Symbol_Pos2 := Token_Ptr;
kono
parents:
diff changeset
568 Scan.all;
kono
parents:
diff changeset
569
kono
parents:
diff changeset
570 if Evaluation then
kono
parents:
diff changeset
571 Symbol1 := Index_Of (Symbol_Name1);
kono
parents:
diff changeset
572
kono
parents:
diff changeset
573 if Symbol1 = No_Symbol then
kono
parents:
diff changeset
574 if Undefined_Symbols_Are_False then
kono
parents:
diff changeset
575 Symbol_Value1 := String_False;
kono
parents:
diff changeset
576
kono
parents:
diff changeset
577 else
kono
parents:
diff changeset
578 Error_Msg_Name_1 := Symbol_Name1;
kono
parents:
diff changeset
579 Error_Msg ("unknown symbol %", Symbol_Pos1);
kono
parents:
diff changeset
580 Symbol_Value1 := No_String;
kono
parents:
diff changeset
581 end if;
kono
parents:
diff changeset
582
kono
parents:
diff changeset
583 else
kono
parents:
diff changeset
584 Symbol_Value1 :=
kono
parents:
diff changeset
585 Mapping.Table (Symbol1).Value;
kono
parents:
diff changeset
586 end if;
kono
parents:
diff changeset
587
kono
parents:
diff changeset
588 Symbol2 := Index_Of (Symbol_Name2);
kono
parents:
diff changeset
589
kono
parents:
diff changeset
590 if Symbol2 = No_Symbol then
kono
parents:
diff changeset
591 if Undefined_Symbols_Are_False then
kono
parents:
diff changeset
592 Symbol_Value2 := String_False;
kono
parents:
diff changeset
593
kono
parents:
diff changeset
594 else
kono
parents:
diff changeset
595 Error_Msg_Name_1 := Symbol_Name2;
kono
parents:
diff changeset
596 Error_Msg ("unknown symbol %", Symbol_Pos2);
kono
parents:
diff changeset
597 Symbol_Value2 := No_String;
kono
parents:
diff changeset
598 end if;
kono
parents:
diff changeset
599
kono
parents:
diff changeset
600 else
kono
parents:
diff changeset
601 Symbol_Value2 := Mapping.Table (Symbol2).Value;
kono
parents:
diff changeset
602 end if;
kono
parents:
diff changeset
603
kono
parents:
diff changeset
604 if Symbol_Value1 /= No_String
kono
parents:
diff changeset
605 and then
kono
parents:
diff changeset
606 Symbol_Value2 /= No_String
kono
parents:
diff changeset
607 then
kono
parents:
diff changeset
608 Current_Result :=
kono
parents:
diff changeset
609 Matching_Strings (Symbol_Value1, Symbol_Value2);
kono
parents:
diff changeset
610 end if;
kono
parents:
diff changeset
611 end if;
kono
parents:
diff changeset
612
kono
parents:
diff changeset
613 elsif Token = Tok_String_Literal then
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 -- symbol = "value"
kono
parents:
diff changeset
616
kono
parents:
diff changeset
617 if Evaluation then
kono
parents:
diff changeset
618 Symbol1 := Index_Of (Symbol_Name1);
kono
parents:
diff changeset
619
kono
parents:
diff changeset
620 if Symbol1 = No_Symbol then
kono
parents:
diff changeset
621 if Undefined_Symbols_Are_False then
kono
parents:
diff changeset
622 Symbol_Value1 := String_False;
kono
parents:
diff changeset
623
kono
parents:
diff changeset
624 else
kono
parents:
diff changeset
625 Error_Msg_Name_1 := Symbol_Name1;
kono
parents:
diff changeset
626 Error_Msg ("unknown symbol %", Symbol_Pos1);
kono
parents:
diff changeset
627 Symbol_Value1 := No_String;
kono
parents:
diff changeset
628 end if;
kono
parents:
diff changeset
629
kono
parents:
diff changeset
630 else
kono
parents:
diff changeset
631 Symbol_Value1 := Mapping.Table (Symbol1).Value;
kono
parents:
diff changeset
632 end if;
kono
parents:
diff changeset
633
kono
parents:
diff changeset
634 if Symbol_Value1 /= No_String then
kono
parents:
diff changeset
635 Current_Result :=
kono
parents:
diff changeset
636 Matching_Strings
kono
parents:
diff changeset
637 (Symbol_Value1,
kono
parents:
diff changeset
638 String_Literal_Id);
kono
parents:
diff changeset
639 end if;
kono
parents:
diff changeset
640 end if;
kono
parents:
diff changeset
641
kono
parents:
diff changeset
642 Scan.all;
kono
parents:
diff changeset
643
kono
parents:
diff changeset
644 else
kono
parents:
diff changeset
645 Error_Msg
kono
parents:
diff changeset
646 ("literal integer, symbol or literal string expected",
kono
parents:
diff changeset
647 Token_Ptr);
kono
parents:
diff changeset
648 end if;
kono
parents:
diff changeset
649
kono
parents:
diff changeset
650 -- Handle True or False
kono
parents:
diff changeset
651
kono
parents:
diff changeset
652 else
kono
parents:
diff changeset
653 if Evaluation then
kono
parents:
diff changeset
654 Symbol1 := Index_Of (Symbol_Name1);
kono
parents:
diff changeset
655
kono
parents:
diff changeset
656 if Symbol1 = No_Symbol then
kono
parents:
diff changeset
657 if Undefined_Symbols_Are_False then
kono
parents:
diff changeset
658 Symbol_Value1 := String_False;
kono
parents:
diff changeset
659
kono
parents:
diff changeset
660 else
kono
parents:
diff changeset
661 Error_Msg_Name_1 := Symbol_Name1;
kono
parents:
diff changeset
662 Error_Msg ("unknown symbol %", Symbol_Pos1);
kono
parents:
diff changeset
663 Symbol_Value1 := No_String;
kono
parents:
diff changeset
664 end if;
kono
parents:
diff changeset
665
kono
parents:
diff changeset
666 else
kono
parents:
diff changeset
667 Symbol_Value1 := Mapping.Table (Symbol1).Value;
kono
parents:
diff changeset
668 end if;
kono
parents:
diff changeset
669
kono
parents:
diff changeset
670 if Symbol_Value1 /= No_String then
kono
parents:
diff changeset
671 String_To_Name_Buffer (Symbol_Value1);
kono
parents:
diff changeset
672
kono
parents:
diff changeset
673 for Index in 1 .. Name_Len loop
kono
parents:
diff changeset
674 Name_Buffer (Index) :=
kono
parents:
diff changeset
675 Fold_Lower (Name_Buffer (Index));
kono
parents:
diff changeset
676 end loop;
kono
parents:
diff changeset
677
kono
parents:
diff changeset
678 if Name_Buffer (1 .. Name_Len) = "true" then
kono
parents:
diff changeset
679 Current_Result := True;
kono
parents:
diff changeset
680
kono
parents:
diff changeset
681 elsif Name_Buffer (1 .. Name_Len) = "false" then
kono
parents:
diff changeset
682 Current_Result := False;
kono
parents:
diff changeset
683
kono
parents:
diff changeset
684 else
kono
parents:
diff changeset
685 Error_Msg_Name_1 := Symbol_Name1;
kono
parents:
diff changeset
686 Error_Msg
kono
parents:
diff changeset
687 ("value of symbol % is not True or False",
kono
parents:
diff changeset
688 Symbol_Pos1);
kono
parents:
diff changeset
689 end if;
kono
parents:
diff changeset
690 end if;
kono
parents:
diff changeset
691 end if;
kono
parents:
diff changeset
692 end if;
kono
parents:
diff changeset
693
kono
parents:
diff changeset
694 -- Unrecognized sequence
kono
parents:
diff changeset
695
kono
parents:
diff changeset
696 when others =>
kono
parents:
diff changeset
697 Error_Msg ("`(`, NOT or symbol expected", Token_Ptr);
kono
parents:
diff changeset
698 end case;
kono
parents:
diff changeset
699
kono
parents:
diff changeset
700 -- Update the cumulative final result
kono
parents:
diff changeset
701
kono
parents:
diff changeset
702 case Current_Operator is
kono
parents:
diff changeset
703 when None =>
kono
parents:
diff changeset
704 Final_Result := Current_Result;
kono
parents:
diff changeset
705
kono
parents:
diff changeset
706 when Op_Or =>
kono
parents:
diff changeset
707 Final_Result := Final_Result or Current_Result;
kono
parents:
diff changeset
708
kono
parents:
diff changeset
709 when Op_And =>
kono
parents:
diff changeset
710 Final_Result := Final_Result and Current_Result;
kono
parents:
diff changeset
711 end case;
kono
parents:
diff changeset
712
kono
parents:
diff changeset
713 -- Handle AND
kono
parents:
diff changeset
714
kono
parents:
diff changeset
715 if Token = Tok_And then
kono
parents:
diff changeset
716 if Complemented then
kono
parents:
diff changeset
717 Error_Msg
kono
parents:
diff changeset
718 ("mixing NOT and AND is not allowed, parentheses are required",
kono
parents:
diff changeset
719 Token_Ptr);
kono
parents:
diff changeset
720
kono
parents:
diff changeset
721 elsif Current_Operator = Op_Or then
kono
parents:
diff changeset
722 Error_Msg ("mixing OR and AND is not allowed", Token_Ptr);
kono
parents:
diff changeset
723 end if;
kono
parents:
diff changeset
724
kono
parents:
diff changeset
725 Current_Operator := Op_And;
kono
parents:
diff changeset
726 Scan.all;
kono
parents:
diff changeset
727
kono
parents:
diff changeset
728 if Token = Tok_Then then
kono
parents:
diff changeset
729 Scan.all;
kono
parents:
diff changeset
730
kono
parents:
diff changeset
731 if Final_Result = False then
kono
parents:
diff changeset
732 Evaluation := False;
kono
parents:
diff changeset
733 end if;
kono
parents:
diff changeset
734 end if;
kono
parents:
diff changeset
735
kono
parents:
diff changeset
736 -- Handle OR
kono
parents:
diff changeset
737
kono
parents:
diff changeset
738 elsif Token = Tok_Or then
kono
parents:
diff changeset
739 if Complemented then
kono
parents:
diff changeset
740 Error_Msg
kono
parents:
diff changeset
741 ("mixing NOT and OR is not allowed, parentheses are required",
kono
parents:
diff changeset
742 Token_Ptr);
kono
parents:
diff changeset
743
kono
parents:
diff changeset
744 elsif Current_Operator = Op_And then
kono
parents:
diff changeset
745 Error_Msg ("mixing AND and OR is not allowed", Token_Ptr);
kono
parents:
diff changeset
746 end if;
kono
parents:
diff changeset
747
kono
parents:
diff changeset
748 Current_Operator := Op_Or;
kono
parents:
diff changeset
749 Scan.all;
kono
parents:
diff changeset
750
kono
parents:
diff changeset
751 if Token = Tok_Else then
kono
parents:
diff changeset
752 Scan.all;
kono
parents:
diff changeset
753
kono
parents:
diff changeset
754 if Final_Result then
kono
parents:
diff changeset
755 Evaluation := False;
kono
parents:
diff changeset
756 end if;
kono
parents:
diff changeset
757 end if;
kono
parents:
diff changeset
758
kono
parents:
diff changeset
759 -- No AND/OR operator, so exit from the loop through terms
kono
parents:
diff changeset
760
kono
parents:
diff changeset
761 else
kono
parents:
diff changeset
762 exit;
kono
parents:
diff changeset
763 end if;
kono
parents:
diff changeset
764 end loop;
kono
parents:
diff changeset
765
kono
parents:
diff changeset
766 return Final_Result;
kono
parents:
diff changeset
767 end Expression;
kono
parents:
diff changeset
768
kono
parents:
diff changeset
769 -----------------------
kono
parents:
diff changeset
770 -- Go_To_End_Of_Line --
kono
parents:
diff changeset
771 -----------------------
kono
parents:
diff changeset
772
kono
parents:
diff changeset
773 procedure Go_To_End_Of_Line is
kono
parents:
diff changeset
774 begin
kono
parents:
diff changeset
775 -- Scan until we get an end of line or we reach the end of the buffer
kono
parents:
diff changeset
776
kono
parents:
diff changeset
777 while Token /= Tok_End_Of_Line
kono
parents:
diff changeset
778 and then Token /= Tok_EOF
kono
parents:
diff changeset
779 loop
kono
parents:
diff changeset
780 Scan.all;
kono
parents:
diff changeset
781 end loop;
kono
parents:
diff changeset
782 end Go_To_End_Of_Line;
kono
parents:
diff changeset
783
kono
parents:
diff changeset
784 --------------
kono
parents:
diff changeset
785 -- Index_Of --
kono
parents:
diff changeset
786 --------------
kono
parents:
diff changeset
787
kono
parents:
diff changeset
788 function Index_Of (Symbol : Name_Id) return Symbol_Id is
kono
parents:
diff changeset
789 begin
kono
parents:
diff changeset
790 if Mapping.Table /= null then
kono
parents:
diff changeset
791 for J in Symbol_Id range 1 .. Symbol_Table.Last (Mapping) loop
kono
parents:
diff changeset
792 if Mapping.Table (J).Symbol = Symbol then
kono
parents:
diff changeset
793 return J;
kono
parents:
diff changeset
794 end if;
kono
parents:
diff changeset
795 end loop;
kono
parents:
diff changeset
796 end if;
kono
parents:
diff changeset
797
kono
parents:
diff changeset
798 return No_Symbol;
kono
parents:
diff changeset
799 end Index_Of;
kono
parents:
diff changeset
800
kono
parents:
diff changeset
801 ----------------
kono
parents:
diff changeset
802 -- Initialize --
kono
parents:
diff changeset
803 ----------------
kono
parents:
diff changeset
804
kono
parents:
diff changeset
805 procedure Initialize is
kono
parents:
diff changeset
806 begin
kono
parents:
diff changeset
807 if not Already_Initialized then
kono
parents:
diff changeset
808 Start_String;
kono
parents:
diff changeset
809 Store_String_Chars ("True");
kono
parents:
diff changeset
810 True_Value.Value := End_String;
kono
parents:
diff changeset
811
kono
parents:
diff changeset
812 Start_String;
kono
parents:
diff changeset
813 Empty_String := End_String;
kono
parents:
diff changeset
814
kono
parents:
diff changeset
815 Start_String;
kono
parents:
diff changeset
816 Store_String_Chars ("False");
kono
parents:
diff changeset
817 String_False := End_String;
kono
parents:
diff changeset
818
kono
parents:
diff changeset
819 Already_Initialized := True;
kono
parents:
diff changeset
820 end if;
kono
parents:
diff changeset
821 end Initialize;
kono
parents:
diff changeset
822
kono
parents:
diff changeset
823 ------------------
kono
parents:
diff changeset
824 -- List_Symbols --
kono
parents:
diff changeset
825 ------------------
kono
parents:
diff changeset
826
kono
parents:
diff changeset
827 procedure List_Symbols (Foreword : String) is
kono
parents:
diff changeset
828 Order : array (0 .. Integer (Symbol_Table.Last (Mapping)))
kono
parents:
diff changeset
829 of Symbol_Id;
kono
parents:
diff changeset
830 -- After alphabetical sorting, this array stores the indexes of the
kono
parents:
diff changeset
831 -- symbols in the order they are displayed.
kono
parents:
diff changeset
832
kono
parents:
diff changeset
833 function Lt (Op1, Op2 : Natural) return Boolean;
kono
parents:
diff changeset
834 -- Comparison routine for sort call
kono
parents:
diff changeset
835
kono
parents:
diff changeset
836 procedure Move (From : Natural; To : Natural);
kono
parents:
diff changeset
837 -- Move routine for sort call
kono
parents:
diff changeset
838
kono
parents:
diff changeset
839 --------
kono
parents:
diff changeset
840 -- Lt --
kono
parents:
diff changeset
841 --------
kono
parents:
diff changeset
842
kono
parents:
diff changeset
843 function Lt (Op1, Op2 : Natural) return Boolean is
kono
parents:
diff changeset
844 S1 : constant String :=
kono
parents:
diff changeset
845 Get_Name_String (Mapping.Table (Order (Op1)).Symbol);
kono
parents:
diff changeset
846 S2 : constant String :=
kono
parents:
diff changeset
847 Get_Name_String (Mapping.Table (Order (Op2)).Symbol);
kono
parents:
diff changeset
848 begin
kono
parents:
diff changeset
849 return S1 < S2;
kono
parents:
diff changeset
850 end Lt;
kono
parents:
diff changeset
851
kono
parents:
diff changeset
852 ----------
kono
parents:
diff changeset
853 -- Move --
kono
parents:
diff changeset
854 ----------
kono
parents:
diff changeset
855
kono
parents:
diff changeset
856 procedure Move (From : Natural; To : Natural) is
kono
parents:
diff changeset
857 begin
kono
parents:
diff changeset
858 Order (To) := Order (From);
kono
parents:
diff changeset
859 end Move;
kono
parents:
diff changeset
860
kono
parents:
diff changeset
861 package Sort_Syms is new GNAT.Heap_Sort_G (Move, Lt);
kono
parents:
diff changeset
862
kono
parents:
diff changeset
863 Max_L : Natural;
kono
parents:
diff changeset
864 -- Maximum length of any symbol
kono
parents:
diff changeset
865
kono
parents:
diff changeset
866 -- Start of processing for List_Symbols_Case
kono
parents:
diff changeset
867
kono
parents:
diff changeset
868 begin
kono
parents:
diff changeset
869 if Symbol_Table.Last (Mapping) = 0 then
kono
parents:
diff changeset
870 return;
kono
parents:
diff changeset
871 end if;
kono
parents:
diff changeset
872
kono
parents:
diff changeset
873 if Foreword'Length > 0 then
kono
parents:
diff changeset
874 Write_Eol;
kono
parents:
diff changeset
875 Write_Line (Foreword);
kono
parents:
diff changeset
876
kono
parents:
diff changeset
877 for J in Foreword'Range loop
kono
parents:
diff changeset
878 Write_Char ('=');
kono
parents:
diff changeset
879 end loop;
kono
parents:
diff changeset
880 end if;
kono
parents:
diff changeset
881
kono
parents:
diff changeset
882 -- Initialize the order
kono
parents:
diff changeset
883
kono
parents:
diff changeset
884 for J in Order'Range loop
kono
parents:
diff changeset
885 Order (J) := Symbol_Id (J);
kono
parents:
diff changeset
886 end loop;
kono
parents:
diff changeset
887
kono
parents:
diff changeset
888 -- Sort alphabetically
kono
parents:
diff changeset
889
kono
parents:
diff changeset
890 Sort_Syms.Sort (Order'Last);
kono
parents:
diff changeset
891
kono
parents:
diff changeset
892 Max_L := 7;
kono
parents:
diff changeset
893
kono
parents:
diff changeset
894 for J in 1 .. Symbol_Table.Last (Mapping) loop
kono
parents:
diff changeset
895 Get_Name_String (Mapping.Table (J).Original);
kono
parents:
diff changeset
896 Max_L := Integer'Max (Max_L, Name_Len);
kono
parents:
diff changeset
897 end loop;
kono
parents:
diff changeset
898
kono
parents:
diff changeset
899 Write_Eol;
kono
parents:
diff changeset
900 Write_Str ("Symbol");
kono
parents:
diff changeset
901
kono
parents:
diff changeset
902 for J in 1 .. Max_L - 5 loop
kono
parents:
diff changeset
903 Write_Char (' ');
kono
parents:
diff changeset
904 end loop;
kono
parents:
diff changeset
905
kono
parents:
diff changeset
906 Write_Line ("Value");
kono
parents:
diff changeset
907
kono
parents:
diff changeset
908 Write_Str ("------");
kono
parents:
diff changeset
909
kono
parents:
diff changeset
910 for J in 1 .. Max_L - 5 loop
kono
parents:
diff changeset
911 Write_Char (' ');
kono
parents:
diff changeset
912 end loop;
kono
parents:
diff changeset
913
kono
parents:
diff changeset
914 Write_Line ("------");
kono
parents:
diff changeset
915
kono
parents:
diff changeset
916 for J in 1 .. Order'Last loop
kono
parents:
diff changeset
917 declare
kono
parents:
diff changeset
918 Data : constant Symbol_Data := Mapping.Table (Order (J));
kono
parents:
diff changeset
919
kono
parents:
diff changeset
920 begin
kono
parents:
diff changeset
921 Get_Name_String (Data.Original);
kono
parents:
diff changeset
922 Write_Str (Name_Buffer (1 .. Name_Len));
kono
parents:
diff changeset
923
kono
parents:
diff changeset
924 for K in Name_Len .. Max_L loop
kono
parents:
diff changeset
925 Write_Char (' ');
kono
parents:
diff changeset
926 end loop;
kono
parents:
diff changeset
927
kono
parents:
diff changeset
928 String_To_Name_Buffer (Data.Value);
kono
parents:
diff changeset
929
kono
parents:
diff changeset
930 if Data.Is_A_String then
kono
parents:
diff changeset
931 Write_Char ('"');
kono
parents:
diff changeset
932
kono
parents:
diff changeset
933 for J in 1 .. Name_Len loop
kono
parents:
diff changeset
934 Write_Char (Name_Buffer (J));
kono
parents:
diff changeset
935
kono
parents:
diff changeset
936 if Name_Buffer (J) = '"' then
kono
parents:
diff changeset
937 Write_Char ('"');
kono
parents:
diff changeset
938 end if;
kono
parents:
diff changeset
939 end loop;
kono
parents:
diff changeset
940
kono
parents:
diff changeset
941 Write_Char ('"');
kono
parents:
diff changeset
942
kono
parents:
diff changeset
943 else
kono
parents:
diff changeset
944 Write_Str (Name_Buffer (1 .. Name_Len));
kono
parents:
diff changeset
945 end if;
kono
parents:
diff changeset
946 end;
kono
parents:
diff changeset
947
kono
parents:
diff changeset
948 Write_Eol;
kono
parents:
diff changeset
949 end loop;
kono
parents:
diff changeset
950
kono
parents:
diff changeset
951 Write_Eol;
kono
parents:
diff changeset
952 end List_Symbols;
kono
parents:
diff changeset
953
kono
parents:
diff changeset
954 ----------------------
kono
parents:
diff changeset
955 -- Matching_Strings --
kono
parents:
diff changeset
956 ----------------------
kono
parents:
diff changeset
957
kono
parents:
diff changeset
958 function Matching_Strings (S1, S2 : String_Id) return Boolean is
kono
parents:
diff changeset
959 begin
kono
parents:
diff changeset
960 String_To_Name_Buffer (S1);
kono
parents:
diff changeset
961
kono
parents:
diff changeset
962 for Index in 1 .. Name_Len loop
kono
parents:
diff changeset
963 Name_Buffer (Index) := Fold_Lower (Name_Buffer (Index));
kono
parents:
diff changeset
964 end loop;
kono
parents:
diff changeset
965
kono
parents:
diff changeset
966 declare
kono
parents:
diff changeset
967 String1 : constant String := Name_Buffer (1 .. Name_Len);
kono
parents:
diff changeset
968
kono
parents:
diff changeset
969 begin
kono
parents:
diff changeset
970 String_To_Name_Buffer (S2);
kono
parents:
diff changeset
971
kono
parents:
diff changeset
972 for Index in 1 .. Name_Len loop
kono
parents:
diff changeset
973 Name_Buffer (Index) := Fold_Lower (Name_Buffer (Index));
kono
parents:
diff changeset
974 end loop;
kono
parents:
diff changeset
975
kono
parents:
diff changeset
976 return String1 = Name_Buffer (1 .. Name_Len);
kono
parents:
diff changeset
977 end;
kono
parents:
diff changeset
978 end Matching_Strings;
kono
parents:
diff changeset
979
kono
parents:
diff changeset
980 --------------------
kono
parents:
diff changeset
981 -- Parse_Def_File --
kono
parents:
diff changeset
982 --------------------
kono
parents:
diff changeset
983
kono
parents:
diff changeset
984 -- This procedure REALLY needs some more comments ???
kono
parents:
diff changeset
985
kono
parents:
diff changeset
986 procedure Parse_Def_File is
kono
parents:
diff changeset
987 Symbol : Symbol_Id;
kono
parents:
diff changeset
988 Symbol_Name : Name_Id;
kono
parents:
diff changeset
989 Original_Name : Name_Id;
kono
parents:
diff changeset
990 Data : Symbol_Data;
kono
parents:
diff changeset
991 Value_Start : Source_Ptr;
kono
parents:
diff changeset
992 Value_End : Source_Ptr;
kono
parents:
diff changeset
993 Ch : Character;
kono
parents:
diff changeset
994
kono
parents:
diff changeset
995 use ASCII;
kono
parents:
diff changeset
996
kono
parents:
diff changeset
997 begin
kono
parents:
diff changeset
998 Def_Line_Loop :
kono
parents:
diff changeset
999 loop
kono
parents:
diff changeset
1000 Scan.all;
kono
parents:
diff changeset
1001
kono
parents:
diff changeset
1002 exit Def_Line_Loop when Token = Tok_EOF;
kono
parents:
diff changeset
1003
kono
parents:
diff changeset
1004 if Token /= Tok_End_Of_Line then
kono
parents:
diff changeset
1005 Change_Reserved_Keyword_To_Symbol;
kono
parents:
diff changeset
1006
kono
parents:
diff changeset
1007 if Token /= Tok_Identifier then
kono
parents:
diff changeset
1008 Error_Msg ("identifier expected", Token_Ptr);
kono
parents:
diff changeset
1009 goto Cleanup;
kono
parents:
diff changeset
1010 end if;
kono
parents:
diff changeset
1011
kono
parents:
diff changeset
1012 Symbol_Name := Token_Name;
kono
parents:
diff changeset
1013 Name_Len := 0;
kono
parents:
diff changeset
1014
kono
parents:
diff changeset
1015 for Ptr in Token_Ptr .. Scan_Ptr - 1 loop
kono
parents:
diff changeset
1016 Name_Len := Name_Len + 1;
kono
parents:
diff changeset
1017 Name_Buffer (Name_Len) := Sinput.Source (Ptr);
kono
parents:
diff changeset
1018 end loop;
kono
parents:
diff changeset
1019
kono
parents:
diff changeset
1020 Original_Name := Name_Find;
kono
parents:
diff changeset
1021 Scan.all;
kono
parents:
diff changeset
1022
kono
parents:
diff changeset
1023 if Token /= Tok_Colon_Equal then
kono
parents:
diff changeset
1024 Error_Msg -- CODEFIX
kono
parents:
diff changeset
1025 ("`:=` expected", Token_Ptr);
kono
parents:
diff changeset
1026 goto Cleanup;
kono
parents:
diff changeset
1027 end if;
kono
parents:
diff changeset
1028
kono
parents:
diff changeset
1029 Scan.all;
kono
parents:
diff changeset
1030
kono
parents:
diff changeset
1031 if Token = Tok_Integer_Literal then
kono
parents:
diff changeset
1032 declare
kono
parents:
diff changeset
1033 Ptr : Source_Ptr := Token_Ptr;
kono
parents:
diff changeset
1034
kono
parents:
diff changeset
1035 begin
kono
parents:
diff changeset
1036 Start_String;
kono
parents:
diff changeset
1037 while Ptr < Scan_Ptr loop
kono
parents:
diff changeset
1038 Store_String_Char (Sinput.Source (Ptr));
kono
parents:
diff changeset
1039 Ptr := Ptr + 1;
kono
parents:
diff changeset
1040 end loop;
kono
parents:
diff changeset
1041
kono
parents:
diff changeset
1042 Data := (Symbol => Symbol_Name,
kono
parents:
diff changeset
1043 Original => Original_Name,
kono
parents:
diff changeset
1044 On_The_Command_Line => False,
kono
parents:
diff changeset
1045 Is_A_String => False,
kono
parents:
diff changeset
1046 Value => End_String);
kono
parents:
diff changeset
1047 end;
kono
parents:
diff changeset
1048
kono
parents:
diff changeset
1049 Scan.all;
kono
parents:
diff changeset
1050
kono
parents:
diff changeset
1051 if Token /= Tok_End_Of_Line and then Token /= Tok_EOF then
kono
parents:
diff changeset
1052 Error_Msg ("extraneous text in definition", Token_Ptr);
kono
parents:
diff changeset
1053 goto Cleanup;
kono
parents:
diff changeset
1054 end if;
kono
parents:
diff changeset
1055
kono
parents:
diff changeset
1056 elsif Token = Tok_String_Literal then
kono
parents:
diff changeset
1057 Data := (Symbol => Symbol_Name,
kono
parents:
diff changeset
1058 Original => Original_Name,
kono
parents:
diff changeset
1059 On_The_Command_Line => False,
kono
parents:
diff changeset
1060 Is_A_String => True,
kono
parents:
diff changeset
1061 Value => String_Literal_Id);
kono
parents:
diff changeset
1062
kono
parents:
diff changeset
1063 Scan.all;
kono
parents:
diff changeset
1064
kono
parents:
diff changeset
1065 if Token /= Tok_End_Of_Line and then Token /= Tok_EOF then
kono
parents:
diff changeset
1066 Error_Msg ("extraneous text in definition", Token_Ptr);
kono
parents:
diff changeset
1067 goto Cleanup;
kono
parents:
diff changeset
1068 end if;
kono
parents:
diff changeset
1069
kono
parents:
diff changeset
1070 elsif Token = Tok_End_Of_Line or else Token = Tok_EOF then
kono
parents:
diff changeset
1071 Data := (Symbol => Symbol_Name,
kono
parents:
diff changeset
1072 Original => Original_Name,
kono
parents:
diff changeset
1073 On_The_Command_Line => False,
kono
parents:
diff changeset
1074 Is_A_String => False,
kono
parents:
diff changeset
1075 Value => Empty_String);
kono
parents:
diff changeset
1076
kono
parents:
diff changeset
1077 else
kono
parents:
diff changeset
1078 Value_Start := Token_Ptr;
kono
parents:
diff changeset
1079 Value_End := Token_Ptr - 1;
kono
parents:
diff changeset
1080 Scan_Ptr := Token_Ptr;
kono
parents:
diff changeset
1081
kono
parents:
diff changeset
1082 Value_Chars_Loop :
kono
parents:
diff changeset
1083 loop
kono
parents:
diff changeset
1084 Ch := Sinput.Source (Scan_Ptr);
kono
parents:
diff changeset
1085
kono
parents:
diff changeset
1086 case Ch is
kono
parents:
diff changeset
1087 when '_' | '.' | '0' .. '9' | 'a' .. 'z' | 'A' .. 'Z' =>
kono
parents:
diff changeset
1088 Value_End := Scan_Ptr;
kono
parents:
diff changeset
1089 Scan_Ptr := Scan_Ptr + 1;
kono
parents:
diff changeset
1090
kono
parents:
diff changeset
1091 when ' ' | HT | VT | CR | LF | FF =>
kono
parents:
diff changeset
1092 exit Value_Chars_Loop;
kono
parents:
diff changeset
1093
kono
parents:
diff changeset
1094 when others =>
kono
parents:
diff changeset
1095 Error_Msg ("illegal character", Scan_Ptr);
kono
parents:
diff changeset
1096 goto Cleanup;
kono
parents:
diff changeset
1097 end case;
kono
parents:
diff changeset
1098 end loop Value_Chars_Loop;
kono
parents:
diff changeset
1099
kono
parents:
diff changeset
1100 Scan.all;
kono
parents:
diff changeset
1101
kono
parents:
diff changeset
1102 if Token /= Tok_End_Of_Line and then Token /= Tok_EOF then
kono
parents:
diff changeset
1103 Error_Msg ("extraneous text in definition", Token_Ptr);
kono
parents:
diff changeset
1104 goto Cleanup;
kono
parents:
diff changeset
1105 end if;
kono
parents:
diff changeset
1106
kono
parents:
diff changeset
1107 Start_String;
kono
parents:
diff changeset
1108
kono
parents:
diff changeset
1109 while Value_Start <= Value_End loop
kono
parents:
diff changeset
1110 Store_String_Char (Sinput.Source (Value_Start));
kono
parents:
diff changeset
1111 Value_Start := Value_Start + 1;
kono
parents:
diff changeset
1112 end loop;
kono
parents:
diff changeset
1113
kono
parents:
diff changeset
1114 Data := (Symbol => Symbol_Name,
kono
parents:
diff changeset
1115 Original => Original_Name,
kono
parents:
diff changeset
1116 On_The_Command_Line => False,
kono
parents:
diff changeset
1117 Is_A_String => False,
kono
parents:
diff changeset
1118 Value => End_String);
kono
parents:
diff changeset
1119 end if;
kono
parents:
diff changeset
1120
kono
parents:
diff changeset
1121 -- Now that we have the value, get the symbol index
kono
parents:
diff changeset
1122
kono
parents:
diff changeset
1123 Symbol := Index_Of (Symbol_Name);
kono
parents:
diff changeset
1124
kono
parents:
diff changeset
1125 if Symbol /= No_Symbol then
kono
parents:
diff changeset
1126
kono
parents:
diff changeset
1127 -- If we already have an entry for this symbol, replace it
kono
parents:
diff changeset
1128 -- with the new value, except if the symbol was declared on
kono
parents:
diff changeset
1129 -- the command line.
kono
parents:
diff changeset
1130
kono
parents:
diff changeset
1131 if Mapping.Table (Symbol).On_The_Command_Line then
kono
parents:
diff changeset
1132 goto Continue;
kono
parents:
diff changeset
1133 end if;
kono
parents:
diff changeset
1134
kono
parents:
diff changeset
1135 else
kono
parents:
diff changeset
1136 -- As it is the first time we see this symbol, create a new
kono
parents:
diff changeset
1137 -- entry in the table.
kono
parents:
diff changeset
1138
kono
parents:
diff changeset
1139 if Mapping.Table = null then
kono
parents:
diff changeset
1140 Symbol_Table.Init (Mapping);
kono
parents:
diff changeset
1141 end if;
kono
parents:
diff changeset
1142
kono
parents:
diff changeset
1143 Symbol_Table.Increment_Last (Mapping);
kono
parents:
diff changeset
1144 Symbol := Symbol_Table.Last (Mapping);
kono
parents:
diff changeset
1145 end if;
kono
parents:
diff changeset
1146
kono
parents:
diff changeset
1147 Mapping.Table (Symbol) := Data;
kono
parents:
diff changeset
1148 goto Continue;
kono
parents:
diff changeset
1149
kono
parents:
diff changeset
1150 <<Cleanup>>
kono
parents:
diff changeset
1151 Set_Ignore_Errors (To => True);
kono
parents:
diff changeset
1152
kono
parents:
diff changeset
1153 while Token /= Tok_End_Of_Line and then Token /= Tok_EOF loop
kono
parents:
diff changeset
1154 Scan.all;
kono
parents:
diff changeset
1155 end loop;
kono
parents:
diff changeset
1156
kono
parents:
diff changeset
1157 Set_Ignore_Errors (To => False);
kono
parents:
diff changeset
1158
kono
parents:
diff changeset
1159 <<Continue>>
kono
parents:
diff changeset
1160 null;
kono
parents:
diff changeset
1161 end if;
kono
parents:
diff changeset
1162 end loop Def_Line_Loop;
kono
parents:
diff changeset
1163 end Parse_Def_File;
kono
parents:
diff changeset
1164
kono
parents:
diff changeset
1165 ----------------
kono
parents:
diff changeset
1166 -- Preprocess --
kono
parents:
diff changeset
1167 ----------------
kono
parents:
diff changeset
1168
kono
parents:
diff changeset
1169 procedure Preprocess (Source_Modified : out Boolean) is
kono
parents:
diff changeset
1170 Start_Of_Processing : Source_Ptr;
kono
parents:
diff changeset
1171 Cond : Boolean;
kono
parents:
diff changeset
1172 Preprocessor_Line : Boolean := False;
kono
parents:
diff changeset
1173 No_Error_Found : Boolean := True;
kono
parents:
diff changeset
1174 Modified : Boolean := False;
kono
parents:
diff changeset
1175
kono
parents:
diff changeset
1176 procedure Output (From, To : Source_Ptr);
kono
parents:
diff changeset
1177 -- Output the characters with indexes From .. To in the buffer to the
kono
parents:
diff changeset
1178 -- output file.
kono
parents:
diff changeset
1179
kono
parents:
diff changeset
1180 procedure Output_Line (From, To : Source_Ptr);
kono
parents:
diff changeset
1181 -- Output a line or the end of a line from the buffer to the output
kono
parents:
diff changeset
1182 -- file, followed by an end of line terminator. Depending on the value
kono
parents:
diff changeset
1183 -- of Deleting and the switches, the line may be commented out, blank or
kono
parents:
diff changeset
1184 -- not output at all.
kono
parents:
diff changeset
1185
kono
parents:
diff changeset
1186 ------------
kono
parents:
diff changeset
1187 -- Output --
kono
parents:
diff changeset
1188 ------------
kono
parents:
diff changeset
1189
kono
parents:
diff changeset
1190 procedure Output (From, To : Source_Ptr) is
kono
parents:
diff changeset
1191 begin
kono
parents:
diff changeset
1192 for J in From .. To loop
kono
parents:
diff changeset
1193 Put_Char (Sinput.Source (J));
kono
parents:
diff changeset
1194 end loop;
kono
parents:
diff changeset
1195 end Output;
kono
parents:
diff changeset
1196
kono
parents:
diff changeset
1197 -----------------
kono
parents:
diff changeset
1198 -- Output_Line --
kono
parents:
diff changeset
1199 -----------------
kono
parents:
diff changeset
1200
kono
parents:
diff changeset
1201 procedure Output_Line (From, To : Source_Ptr) is
kono
parents:
diff changeset
1202 begin
kono
parents:
diff changeset
1203 if Deleting or else Preprocessor_Line then
kono
parents:
diff changeset
1204 if Blank_Deleted_Lines then
kono
parents:
diff changeset
1205 New_EOL.all;
kono
parents:
diff changeset
1206
kono
parents:
diff changeset
1207 elsif Comment_Deleted_Lines then
kono
parents:
diff changeset
1208 Put_Char ('-');
kono
parents:
diff changeset
1209 Put_Char ('-');
kono
parents:
diff changeset
1210 Put_Char ('!');
kono
parents:
diff changeset
1211
kono
parents:
diff changeset
1212 if From < To then
kono
parents:
diff changeset
1213 Put_Char (' ');
kono
parents:
diff changeset
1214 Output (From, To);
kono
parents:
diff changeset
1215 end if;
kono
parents:
diff changeset
1216
kono
parents:
diff changeset
1217 New_EOL.all;
kono
parents:
diff changeset
1218 end if;
kono
parents:
diff changeset
1219
kono
parents:
diff changeset
1220 else
kono
parents:
diff changeset
1221 Output (From, To);
kono
parents:
diff changeset
1222 New_EOL.all;
kono
parents:
diff changeset
1223 end if;
kono
parents:
diff changeset
1224 end Output_Line;
kono
parents:
diff changeset
1225
kono
parents:
diff changeset
1226 -- Start of processing for Preprocess
kono
parents:
diff changeset
1227
kono
parents:
diff changeset
1228 begin
kono
parents:
diff changeset
1229 Start_Of_Processing := Scan_Ptr;
kono
parents:
diff changeset
1230
kono
parents:
diff changeset
1231 -- First a call to Scan, because Initialize_Scanner is not doing it
kono
parents:
diff changeset
1232
kono
parents:
diff changeset
1233 Scan.all;
kono
parents:
diff changeset
1234
kono
parents:
diff changeset
1235 Input_Line_Loop : loop
kono
parents:
diff changeset
1236 exit Input_Line_Loop when Token = Tok_EOF;
kono
parents:
diff changeset
1237
kono
parents:
diff changeset
1238 Preprocessor_Line := False;
kono
parents:
diff changeset
1239
kono
parents:
diff changeset
1240 if Token /= Tok_End_Of_Line then
kono
parents:
diff changeset
1241
kono
parents:
diff changeset
1242 -- Preprocessor line
kono
parents:
diff changeset
1243
kono
parents:
diff changeset
1244 if Token = Tok_Special and then Special_Character = '#' then
kono
parents:
diff changeset
1245 Modified := True;
kono
parents:
diff changeset
1246 Preprocessor_Line := True;
kono
parents:
diff changeset
1247 Scan.all;
kono
parents:
diff changeset
1248
kono
parents:
diff changeset
1249 case Token is
kono
parents:
diff changeset
1250
kono
parents:
diff changeset
1251 -- #if
kono
parents:
diff changeset
1252
kono
parents:
diff changeset
1253 when Tok_If =>
kono
parents:
diff changeset
1254 declare
kono
parents:
diff changeset
1255 If_Ptr : constant Source_Ptr := Token_Ptr;
kono
parents:
diff changeset
1256
kono
parents:
diff changeset
1257 begin
kono
parents:
diff changeset
1258 Scan.all;
kono
parents:
diff changeset
1259 Cond := Expression (not Deleting);
kono
parents:
diff changeset
1260
kono
parents:
diff changeset
1261 -- Check for an eventual "then"
kono
parents:
diff changeset
1262
kono
parents:
diff changeset
1263 if Token = Tok_Then then
kono
parents:
diff changeset
1264 Scan.all;
kono
parents:
diff changeset
1265 end if;
kono
parents:
diff changeset
1266
kono
parents:
diff changeset
1267 -- It is an error to have trailing characters after
kono
parents:
diff changeset
1268 -- the condition or "then".
kono
parents:
diff changeset
1269
kono
parents:
diff changeset
1270 if Token /= Tok_End_Of_Line
kono
parents:
diff changeset
1271 and then Token /= Tok_EOF
kono
parents:
diff changeset
1272 then
kono
parents:
diff changeset
1273 Error_Msg
kono
parents:
diff changeset
1274 ("extraneous text on preprocessor line",
kono
parents:
diff changeset
1275 Token_Ptr);
kono
parents:
diff changeset
1276 No_Error_Found := False;
kono
parents:
diff changeset
1277 Go_To_End_Of_Line;
kono
parents:
diff changeset
1278 end if;
kono
parents:
diff changeset
1279
kono
parents:
diff changeset
1280 declare
kono
parents:
diff changeset
1281 -- Set the initial state of this new "#if". This
kono
parents:
diff changeset
1282 -- must be done before incrementing the Last of
kono
parents:
diff changeset
1283 -- the table, otherwise function Deleting does
kono
parents:
diff changeset
1284 -- not report the correct value.
kono
parents:
diff changeset
1285
kono
parents:
diff changeset
1286 New_State : constant Pp_State :=
kono
parents:
diff changeset
1287 (If_Ptr => If_Ptr,
kono
parents:
diff changeset
1288 Else_Ptr => 0,
kono
parents:
diff changeset
1289 Deleting => Deleting
kono
parents:
diff changeset
1290 or else not Cond,
kono
parents:
diff changeset
1291 Match_Seen => Deleting or else Cond);
kono
parents:
diff changeset
1292
kono
parents:
diff changeset
1293 begin
kono
parents:
diff changeset
1294 Pp_States.Increment_Last;
kono
parents:
diff changeset
1295 Pp_States.Table (Pp_States.Last) := New_State;
kono
parents:
diff changeset
1296 end;
kono
parents:
diff changeset
1297 end;
kono
parents:
diff changeset
1298
kono
parents:
diff changeset
1299 -- #elsif
kono
parents:
diff changeset
1300
kono
parents:
diff changeset
1301 when Tok_Elsif =>
kono
parents:
diff changeset
1302 Cond := False;
kono
parents:
diff changeset
1303
kono
parents:
diff changeset
1304 if Pp_States.Last = 0
kono
parents:
diff changeset
1305 or else Pp_States.Table (Pp_States.Last).Else_Ptr /= 0
kono
parents:
diff changeset
1306 then
kono
parents:
diff changeset
1307 Error_Msg ("no IF for this ELSIF", Token_Ptr);
kono
parents:
diff changeset
1308 No_Error_Found := False;
kono
parents:
diff changeset
1309
kono
parents:
diff changeset
1310 else
kono
parents:
diff changeset
1311 Cond :=
kono
parents:
diff changeset
1312 not Pp_States.Table (Pp_States.Last).Match_Seen;
kono
parents:
diff changeset
1313 end if;
kono
parents:
diff changeset
1314
kono
parents:
diff changeset
1315 Scan.all;
kono
parents:
diff changeset
1316 Cond := Expression (Cond);
kono
parents:
diff changeset
1317
kono
parents:
diff changeset
1318 -- Check for an eventual "then"
kono
parents:
diff changeset
1319
kono
parents:
diff changeset
1320 if Token = Tok_Then then
kono
parents:
diff changeset
1321 Scan.all;
kono
parents:
diff changeset
1322 end if;
kono
parents:
diff changeset
1323
kono
parents:
diff changeset
1324 -- It is an error to have trailing characters after the
kono
parents:
diff changeset
1325 -- condition or "then".
kono
parents:
diff changeset
1326
kono
parents:
diff changeset
1327 if Token /= Tok_End_Of_Line
kono
parents:
diff changeset
1328 and then Token /= Tok_EOF
kono
parents:
diff changeset
1329 then
kono
parents:
diff changeset
1330 Error_Msg
kono
parents:
diff changeset
1331 ("extraneous text on preprocessor line",
kono
parents:
diff changeset
1332 Token_Ptr);
kono
parents:
diff changeset
1333 No_Error_Found := False;
kono
parents:
diff changeset
1334
kono
parents:
diff changeset
1335 Go_To_End_Of_Line;
kono
parents:
diff changeset
1336 end if;
kono
parents:
diff changeset
1337
kono
parents:
diff changeset
1338 -- Depending on the value of the condition, set the new
kono
parents:
diff changeset
1339 -- values of Deleting and Match_Seen.
kono
parents:
diff changeset
1340
kono
parents:
diff changeset
1341 if Pp_States.Last > 0 then
kono
parents:
diff changeset
1342 if Pp_States.Table (Pp_States.Last).Match_Seen then
kono
parents:
diff changeset
1343 Pp_States.Table (Pp_States.Last).Deleting := True;
kono
parents:
diff changeset
1344 else
kono
parents:
diff changeset
1345 if Cond then
kono
parents:
diff changeset
1346 Pp_States.Table (Pp_States.Last).Match_Seen :=
kono
parents:
diff changeset
1347 True;
kono
parents:
diff changeset
1348 Pp_States.Table (Pp_States.Last).Deleting :=
kono
parents:
diff changeset
1349 False;
kono
parents:
diff changeset
1350 end if;
kono
parents:
diff changeset
1351 end if;
kono
parents:
diff changeset
1352 end if;
kono
parents:
diff changeset
1353
kono
parents:
diff changeset
1354 -- #else
kono
parents:
diff changeset
1355
kono
parents:
diff changeset
1356 when Tok_Else =>
kono
parents:
diff changeset
1357 if Pp_States.Last = 0 then
kono
parents:
diff changeset
1358 Error_Msg ("no IF for this ELSE", Token_Ptr);
kono
parents:
diff changeset
1359 No_Error_Found := False;
kono
parents:
diff changeset
1360
kono
parents:
diff changeset
1361 elsif
kono
parents:
diff changeset
1362 Pp_States.Table (Pp_States.Last).Else_Ptr /= 0
kono
parents:
diff changeset
1363 then
kono
parents:
diff changeset
1364 Error_Msg -- CODEFIX
kono
parents:
diff changeset
1365 ("duplicate ELSE line", Token_Ptr);
kono
parents:
diff changeset
1366 No_Error_Found := False;
kono
parents:
diff changeset
1367 end if;
kono
parents:
diff changeset
1368
kono
parents:
diff changeset
1369 -- Set the possibly new values of Deleting and Match_Seen
kono
parents:
diff changeset
1370
kono
parents:
diff changeset
1371 if Pp_States.Last > 0 then
kono
parents:
diff changeset
1372 if Pp_States.Table (Pp_States.Last).Match_Seen then
kono
parents:
diff changeset
1373 Pp_States.Table (Pp_States.Last).Deleting :=
kono
parents:
diff changeset
1374 True;
kono
parents:
diff changeset
1375
kono
parents:
diff changeset
1376 else
kono
parents:
diff changeset
1377 Pp_States.Table (Pp_States.Last).Match_Seen :=
kono
parents:
diff changeset
1378 True;
kono
parents:
diff changeset
1379 Pp_States.Table (Pp_States.Last).Deleting :=
kono
parents:
diff changeset
1380 False;
kono
parents:
diff changeset
1381 end if;
kono
parents:
diff changeset
1382
kono
parents:
diff changeset
1383 -- Set the Else_Ptr to check for illegal #elsif later
kono
parents:
diff changeset
1384
kono
parents:
diff changeset
1385 Pp_States.Table (Pp_States.Last).Else_Ptr :=
kono
parents:
diff changeset
1386 Token_Ptr;
kono
parents:
diff changeset
1387 end if;
kono
parents:
diff changeset
1388
kono
parents:
diff changeset
1389 Scan.all;
kono
parents:
diff changeset
1390
kono
parents:
diff changeset
1391 -- Error of character present after "#else"
kono
parents:
diff changeset
1392
kono
parents:
diff changeset
1393 if Token /= Tok_End_Of_Line
kono
parents:
diff changeset
1394 and then Token /= Tok_EOF
kono
parents:
diff changeset
1395 then
kono
parents:
diff changeset
1396 Error_Msg
kono
parents:
diff changeset
1397 ("extraneous text on preprocessor line",
kono
parents:
diff changeset
1398 Token_Ptr);
kono
parents:
diff changeset
1399 No_Error_Found := False;
kono
parents:
diff changeset
1400 Go_To_End_Of_Line;
kono
parents:
diff changeset
1401 end if;
kono
parents:
diff changeset
1402
kono
parents:
diff changeset
1403 -- #end if;
kono
parents:
diff changeset
1404
kono
parents:
diff changeset
1405 when Tok_End =>
kono
parents:
diff changeset
1406 if Pp_States.Last = 0 then
kono
parents:
diff changeset
1407 Error_Msg ("no IF for this END", Token_Ptr);
kono
parents:
diff changeset
1408 No_Error_Found := False;
kono
parents:
diff changeset
1409 end if;
kono
parents:
diff changeset
1410
kono
parents:
diff changeset
1411 Scan.all;
kono
parents:
diff changeset
1412
kono
parents:
diff changeset
1413 if Token /= Tok_If then
kono
parents:
diff changeset
1414 Error_Msg -- CODEFIX
kono
parents:
diff changeset
1415 ("IF expected", Token_Ptr);
kono
parents:
diff changeset
1416 No_Error_Found := False;
kono
parents:
diff changeset
1417
kono
parents:
diff changeset
1418 else
kono
parents:
diff changeset
1419 Scan.all;
kono
parents:
diff changeset
1420
kono
parents:
diff changeset
1421 if Token /= Tok_Semicolon then
kono
parents:
diff changeset
1422 Error_Msg -- CODEFIX
kono
parents:
diff changeset
1423 ("`;` Expected", Token_Ptr);
kono
parents:
diff changeset
1424 No_Error_Found := False;
kono
parents:
diff changeset
1425
kono
parents:
diff changeset
1426 else
kono
parents:
diff changeset
1427 Scan.all;
kono
parents:
diff changeset
1428
kono
parents:
diff changeset
1429 -- Error of character present after "#end if;"
kono
parents:
diff changeset
1430
kono
parents:
diff changeset
1431 if Token /= Tok_End_Of_Line
kono
parents:
diff changeset
1432 and then Token /= Tok_EOF
kono
parents:
diff changeset
1433 then
kono
parents:
diff changeset
1434 Error_Msg
kono
parents:
diff changeset
1435 ("extraneous text on preprocessor line",
kono
parents:
diff changeset
1436 Token_Ptr);
kono
parents:
diff changeset
1437 No_Error_Found := False;
kono
parents:
diff changeset
1438 end if;
kono
parents:
diff changeset
1439 end if;
kono
parents:
diff changeset
1440 end if;
kono
parents:
diff changeset
1441
kono
parents:
diff changeset
1442 -- In case of one of the errors above, skip the tokens
kono
parents:
diff changeset
1443 -- until the end of line is reached.
kono
parents:
diff changeset
1444
kono
parents:
diff changeset
1445 Go_To_End_Of_Line;
kono
parents:
diff changeset
1446
kono
parents:
diff changeset
1447 -- Decrement the depth of the #if stack
kono
parents:
diff changeset
1448
kono
parents:
diff changeset
1449 if Pp_States.Last > 0 then
kono
parents:
diff changeset
1450 Pp_States.Decrement_Last;
kono
parents:
diff changeset
1451 end if;
kono
parents:
diff changeset
1452
kono
parents:
diff changeset
1453 -- Illegal preprocessor line
kono
parents:
diff changeset
1454
kono
parents:
diff changeset
1455 when others =>
kono
parents:
diff changeset
1456 No_Error_Found := False;
kono
parents:
diff changeset
1457
kono
parents:
diff changeset
1458 if Pp_States.Last = 0 then
kono
parents:
diff changeset
1459 Error_Msg -- CODEFIX
kono
parents:
diff changeset
1460 ("IF expected", Token_Ptr);
kono
parents:
diff changeset
1461
kono
parents:
diff changeset
1462 elsif
kono
parents:
diff changeset
1463 Pp_States.Table (Pp_States.Last).Else_Ptr = 0
kono
parents:
diff changeset
1464 then
kono
parents:
diff changeset
1465 Error_Msg
kono
parents:
diff changeset
1466 ("IF, ELSIF, ELSE, or `END IF` expected",
kono
parents:
diff changeset
1467 Token_Ptr);
kono
parents:
diff changeset
1468
kono
parents:
diff changeset
1469 else
kono
parents:
diff changeset
1470 Error_Msg ("IF or `END IF` expected", Token_Ptr);
kono
parents:
diff changeset
1471 end if;
kono
parents:
diff changeset
1472
kono
parents:
diff changeset
1473 -- Skip to the end of this illegal line
kono
parents:
diff changeset
1474
kono
parents:
diff changeset
1475 Go_To_End_Of_Line;
kono
parents:
diff changeset
1476 end case;
kono
parents:
diff changeset
1477
kono
parents:
diff changeset
1478 -- Not a preprocessor line
kono
parents:
diff changeset
1479
kono
parents:
diff changeset
1480 else
kono
parents:
diff changeset
1481 -- Do not report errors for those lines, even if there are
kono
parents:
diff changeset
1482 -- Ada parsing errors.
kono
parents:
diff changeset
1483
kono
parents:
diff changeset
1484 Set_Ignore_Errors (To => True);
kono
parents:
diff changeset
1485
kono
parents:
diff changeset
1486 if Deleting then
kono
parents:
diff changeset
1487 Go_To_End_Of_Line;
kono
parents:
diff changeset
1488
kono
parents:
diff changeset
1489 else
kono
parents:
diff changeset
1490 while Token /= Tok_End_Of_Line
kono
parents:
diff changeset
1491 and then Token /= Tok_EOF
kono
parents:
diff changeset
1492 loop
kono
parents:
diff changeset
1493 if Token = Tok_Special
kono
parents:
diff changeset
1494 and then Special_Character = '$'
kono
parents:
diff changeset
1495 then
kono
parents:
diff changeset
1496 Modified := True;
kono
parents:
diff changeset
1497
kono
parents:
diff changeset
1498 declare
kono
parents:
diff changeset
1499 Dollar_Ptr : constant Source_Ptr := Token_Ptr;
kono
parents:
diff changeset
1500 Symbol : Symbol_Id;
kono
parents:
diff changeset
1501
kono
parents:
diff changeset
1502 begin
kono
parents:
diff changeset
1503 Scan.all;
kono
parents:
diff changeset
1504 Change_Reserved_Keyword_To_Symbol;
kono
parents:
diff changeset
1505
kono
parents:
diff changeset
1506 if Token = Tok_Identifier
kono
parents:
diff changeset
1507 and then Token_Ptr = Dollar_Ptr + 1
kono
parents:
diff changeset
1508 then
kono
parents:
diff changeset
1509 -- $symbol
kono
parents:
diff changeset
1510
kono
parents:
diff changeset
1511 Symbol := Index_Of (Token_Name);
kono
parents:
diff changeset
1512
kono
parents:
diff changeset
1513 -- If symbol exists, replace by its value
kono
parents:
diff changeset
1514
kono
parents:
diff changeset
1515 if Symbol /= No_Symbol then
kono
parents:
diff changeset
1516 Output (Start_Of_Processing, Dollar_Ptr - 1);
kono
parents:
diff changeset
1517 Start_Of_Processing := Scan_Ptr;
kono
parents:
diff changeset
1518 String_To_Name_Buffer
kono
parents:
diff changeset
1519 (Mapping.Table (Symbol).Value);
kono
parents:
diff changeset
1520
kono
parents:
diff changeset
1521 if Mapping.Table (Symbol).Is_A_String then
kono
parents:
diff changeset
1522
kono
parents:
diff changeset
1523 -- Value is an Ada string
kono
parents:
diff changeset
1524
kono
parents:
diff changeset
1525 Put_Char ('"');
kono
parents:
diff changeset
1526
kono
parents:
diff changeset
1527 for J in 1 .. Name_Len loop
kono
parents:
diff changeset
1528 Put_Char (Name_Buffer (J));
kono
parents:
diff changeset
1529
kono
parents:
diff changeset
1530 if Name_Buffer (J) = '"' then
kono
parents:
diff changeset
1531 Put_Char ('"');
kono
parents:
diff changeset
1532 end if;
kono
parents:
diff changeset
1533 end loop;
kono
parents:
diff changeset
1534
kono
parents:
diff changeset
1535 Put_Char ('"');
kono
parents:
diff changeset
1536
kono
parents:
diff changeset
1537 else
kono
parents:
diff changeset
1538 -- Value is a sequence of characters, not
kono
parents:
diff changeset
1539 -- an Ada string.
kono
parents:
diff changeset
1540
kono
parents:
diff changeset
1541 for J in 1 .. Name_Len loop
kono
parents:
diff changeset
1542 Put_Char (Name_Buffer (J));
kono
parents:
diff changeset
1543 end loop;
kono
parents:
diff changeset
1544 end if;
kono
parents:
diff changeset
1545 end if;
kono
parents:
diff changeset
1546 end if;
kono
parents:
diff changeset
1547 end;
kono
parents:
diff changeset
1548 end if;
kono
parents:
diff changeset
1549
kono
parents:
diff changeset
1550 Scan.all;
kono
parents:
diff changeset
1551 end loop;
kono
parents:
diff changeset
1552 end if;
kono
parents:
diff changeset
1553
kono
parents:
diff changeset
1554 Set_Ignore_Errors (To => False);
kono
parents:
diff changeset
1555 end if;
kono
parents:
diff changeset
1556 end if;
kono
parents:
diff changeset
1557
kono
parents:
diff changeset
1558 pragma Assert (Token = Tok_End_Of_Line or else Token = Tok_EOF);
kono
parents:
diff changeset
1559
kono
parents:
diff changeset
1560 -- At this point, the token is either end of line or EOF. The line to
kono
parents:
diff changeset
1561 -- possibly output stops just before the token.
kono
parents:
diff changeset
1562
kono
parents:
diff changeset
1563 Output_Line (Start_Of_Processing, Token_Ptr - 1);
kono
parents:
diff changeset
1564
kono
parents:
diff changeset
1565 -- If we are at the end of a line, the scan pointer is at the first
kono
parents:
diff changeset
1566 -- non-blank character (may not be the first character of the line),
kono
parents:
diff changeset
1567 -- so we have to deduct Start_Of_Processing from the token pointer.
kono
parents:
diff changeset
1568
kono
parents:
diff changeset
1569 if Token = Tok_End_Of_Line then
kono
parents:
diff changeset
1570 if Sinput.Source (Token_Ptr) = ASCII.CR
kono
parents:
diff changeset
1571 and then Sinput.Source (Token_Ptr + 1) = ASCII.LF
kono
parents:
diff changeset
1572 then
kono
parents:
diff changeset
1573 Start_Of_Processing := Token_Ptr + 2;
kono
parents:
diff changeset
1574 else
kono
parents:
diff changeset
1575 Start_Of_Processing := Token_Ptr + 1;
kono
parents:
diff changeset
1576 end if;
kono
parents:
diff changeset
1577 end if;
kono
parents:
diff changeset
1578
kono
parents:
diff changeset
1579 -- Now, scan the first token of the next line. If the token is EOF,
kono
parents:
diff changeset
1580 -- the scan pointer will not move, and the token will still be EOF.
kono
parents:
diff changeset
1581
kono
parents:
diff changeset
1582 Set_Ignore_Errors (To => True);
kono
parents:
diff changeset
1583 Scan.all;
kono
parents:
diff changeset
1584 Set_Ignore_Errors (To => False);
kono
parents:
diff changeset
1585 end loop Input_Line_Loop;
kono
parents:
diff changeset
1586
kono
parents:
diff changeset
1587 -- Report an error for any missing some "#end if;"
kono
parents:
diff changeset
1588
kono
parents:
diff changeset
1589 for Level in reverse 1 .. Pp_States.Last loop
kono
parents:
diff changeset
1590 Error_Msg ("no `END IF` for this IF", Pp_States.Table (Level).If_Ptr);
kono
parents:
diff changeset
1591 No_Error_Found := False;
kono
parents:
diff changeset
1592 end loop;
kono
parents:
diff changeset
1593
kono
parents:
diff changeset
1594 Source_Modified := No_Error_Found and Modified;
kono
parents:
diff changeset
1595 end Preprocess;
kono
parents:
diff changeset
1596
kono
parents:
diff changeset
1597 -----------------
kono
parents:
diff changeset
1598 -- Setup_Hooks --
kono
parents:
diff changeset
1599 -----------------
kono
parents:
diff changeset
1600
kono
parents:
diff changeset
1601 procedure Setup_Hooks
kono
parents:
diff changeset
1602 (Error_Msg : Error_Msg_Proc;
kono
parents:
diff changeset
1603 Scan : Scan_Proc;
kono
parents:
diff changeset
1604 Set_Ignore_Errors : Set_Ignore_Errors_Proc;
kono
parents:
diff changeset
1605 Put_Char : Put_Char_Proc;
kono
parents:
diff changeset
1606 New_EOL : New_EOL_Proc)
kono
parents:
diff changeset
1607 is
kono
parents:
diff changeset
1608 begin
kono
parents:
diff changeset
1609 pragma Assert (Already_Initialized);
kono
parents:
diff changeset
1610
kono
parents:
diff changeset
1611 Prep.Error_Msg := Error_Msg;
kono
parents:
diff changeset
1612 Prep.Scan := Scan;
kono
parents:
diff changeset
1613 Prep.Set_Ignore_Errors := Set_Ignore_Errors;
kono
parents:
diff changeset
1614 Prep.Put_Char := Put_Char;
kono
parents:
diff changeset
1615 Prep.New_EOL := New_EOL;
kono
parents:
diff changeset
1616 end Setup_Hooks;
kono
parents:
diff changeset
1617
kono
parents:
diff changeset
1618 end Prep;