From: Arnaud Charlet <charlet@adacore.com>
To: gcc-patches@gcc.gnu.org
Cc: Vincent Celier <celier@adacore.com>
Subject: [Ada] Comparaison of symbols to integers in preprocessing
Date: Mon, 14 Oct 2013 13:24:00 -0000 [thread overview]
Message-ID: <20131014131445.GA12993@adacore.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 538 bytes --]
When preprocessing a source, it is now possible to use comparaison of
symbols with integers, using operators =, <, <=, > or >=, as in:
#if symbol = 3
#if symbol <= 20
Tested on x86_64-pc-linux-gnu, committed on trunk
2013-10-14 Vincent Celier <celier@adacore.com>
* prep.adb (Expression): Accept terms of the form 'symbol <relop>
integer", where relop is =, <, <=, > or >=.
(Parse_Def_File): Accept literal integer values.
* gcc-interface/Make-lang.in: Add s-valint.o, s-valuns.o and
s-valuti.o to the compiler object files.
[-- Attachment #2: difs --]
[-- Type: text/plain, Size: 8305 bytes --]
Index: prep.adb
===================================================================
--- prep.adb (revision 203521)
+++ prep.adb (working copy)
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2002-2012, Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2013, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -33,6 +33,7 @@
with Sinput;
with Stringt; use Stringt;
with Table;
+with Uintp; use Uintp;
with GNAT.Heap_Sort_G;
@@ -268,9 +269,14 @@
-- Check the syntax of the value
- if Definition (Index + 1) /= '"'
- or else Definition (Definition'Last) /= '"'
+ if Definition (Index + 1) = '"'
+ and then Definition (Definition'Last) = '"'
then
+ Result.Is_A_String := True;
+
+ else
+ Result.Is_A_String := False;
+
for J in Index + 1 .. Definition'Last loop
case Definition (J) is
when '_' | '.' | '0' .. '9' | 'a' .. 'z' | 'A' .. 'Z' =>
@@ -286,7 +292,6 @@
-- And put the value in the result
- Result.Is_A_String := False;
Start_String;
Store_String_Chars (Definition (Index + 1 .. Definition'Last));
Result.Value := End_String;
@@ -390,6 +395,8 @@
Symbol_Value1 : String_Id;
Symbol_Value2 : String_Id;
+ Relop : Token_Type;
+
begin
-- Loop for each term
@@ -447,13 +454,97 @@
Current_Result := Index_Of (Symbol_Name1) /= No_Symbol;
end if;
- elsif Token = Tok_Equal then
+ elsif
+ Token = Tok_Equal or else
+ Token = Tok_Less or else
+ Token = Tok_Less_Equal or else
+ Token = Tok_Greater or else
+ Token = Tok_Greater_Equal
+ then
+ Relop := Token;
Scan.all;
-
Change_Reserved_Keyword_To_Symbol;
- if Token = Tok_Identifier then
+ if Token = Tok_Integer_Literal then
+ -- symbol = integer
+ -- symbol < integer
+ -- symbol <= integer
+ -- symbol > integer
+ -- symbol >= integer
+
+ declare
+ Value : constant Int := UI_To_Int (Int_Literal_Value);
+ Data : Symbol_Data;
+ Symbol_Value : Int;
+ begin
+ if Evaluation then
+ Symbol1 := Index_Of (Symbol_Name1);
+
+ if Symbol1 = No_Symbol then
+ Error_Msg_Name_1 := Symbol_Name1;
+ Error_Msg ("unknown symbol %", Symbol_Pos1);
+ Symbol_Value1 := No_String;
+
+ else
+ Data := Mapping.Table (Symbol1);
+
+ if Data.Is_A_String then
+ Error_Msg_Name_1 := Symbol_Name1;
+ Error_Msg
+ ("symbol % value is not integer",
+ Symbol_Pos1);
+
+ else
+ begin
+ String_To_Name_Buffer (Data.Value);
+ Symbol_Value :=
+ Int'Value (Name_Buffer (1 .. Name_Len));
+
+ case Relop is
+ when Tok_Equal =>
+ Current_Result :=
+ Symbol_Value = Value;
+
+ when Tok_Less =>
+ Current_Result :=
+ Symbol_Value < Value;
+
+ when Tok_Less_Equal =>
+ Current_Result :=
+ Symbol_Value <= Value;
+
+ when Tok_Greater =>
+ Current_Result :=
+ Symbol_Value > Value;
+
+ when Tok_Greater_Equal =>
+ Current_Result :=
+ Symbol_Value >= Value;
+
+ when others =>
+ null;
+ end case;
+
+ exception
+ when Constraint_Error =>
+ Error_Msg_Name_1 := Symbol_Name1;
+ Error_Msg
+ ("symbol % value is not integer",
+ Symbol_Pos1);
+ end;
+ end if;
+ end if;
+ end if;
+
+ Scan.all;
+ end;
+
+ elsif Relop /= Tok_Equal then
+ Error_Msg ("number expected", Token_Ptr);
+
+ elsif Token = Tok_Identifier then
+
-- symbol = symbol
Symbol_Name2 := Token_Name;
@@ -535,7 +626,8 @@
else
Error_Msg
- ("symbol or literal string expected", Token_Ptr);
+ ("literal integer, symbol or literal string expected",
+ Token_Ptr);
end if;
else
@@ -914,7 +1006,33 @@
Scan.all;
- if Token = Tok_String_Literal then
+ if Token = Tok_Integer_Literal then
+ declare
+ Ptr : Source_Ptr := Token_Ptr;
+
+ begin
+ Start_String;
+
+ while Ptr < Scan_Ptr loop
+ Store_String_Char (Sinput.Source (Ptr));
+ Ptr := Ptr + 1;
+ end loop;
+
+ Data := (Symbol => Symbol_Name,
+ Original => Original_Name,
+ On_The_Command_Line => False,
+ Is_A_String => False,
+ Value => End_String);
+ end;
+
+ Scan.all;
+
+ if Token /= Tok_End_Of_Line and then Token /= Tok_EOF then
+ Error_Msg ("extraneous text in definition", Token_Ptr);
+ goto Cleanup;
+ end if;
+
+ elsif Token = Tok_String_Literal then
Data := (Symbol => Symbol_Name,
Original => Original_Name,
On_The_Command_Line => False,
@@ -1088,8 +1206,7 @@
begin
Start_Of_Processing := Scan_Ptr;
- -- We need to call Scan for the first time, because Initialize_Scanner
- -- is no longer doing it.
+ -- First a call to Scan, because Initialize_Scanner is not doing it
Scan.all;
Index: gcc-interface/Make-lang.in
===================================================================
--- gcc-interface/Make-lang.in (revision 203521)
+++ gcc-interface/Make-lang.in (working copy)
@@ -371,6 +371,9 @@
ada/s-traent.o \
ada/s-unstyp.o \
ada/s-utf_32.o \
+ ada/s-valint.o \
+ ada/s-valuns.o \
+ ada/s-valuti.o \
ada/s-wchcnv.o \
ada/s-wchcon.o \
ada/s-wchjis.o \
reply other threads:[~2013-10-14 13:14 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20131014131445.GA12993@adacore.com \
--to=charlet@adacore.com \
--cc=celier@adacore.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).