❌ About FreshRSS

Reading view

There are new articles available, click to refresh the page.

Where is the actual character set for Ada program text defined?

I'm trying to make a tree-sitter parser, so that IDEs (in this case, Vim) can parse and do more advanced manipulation of Ada program text, such as extract-subprogram and rename-variable. But there seem to be some problems defining the character set.

In the Ada 2012 Reference Manual, I found a list of vague category descriptions, of the form 'Any character whose General Category is X' which means that for instance, besides the underscore, all of these ( ‿ ⁀ ⁔ ︳ ︴ ﹍ ﹎ ﹏ _) are also allowed in an identifier, which seems absurd, and GNAT rejects with 'illegal character'. The list is prefaced by this statement:

"The actual set of graphic symbols used by an implementation for the visual representation of the text of an Ada program is not specified."

Does that really mean there's no way to know which characters should be accepted?

Two pages on, these examples are explicitly given as valid identifiers, and yet GNAT 2021 rejects them:

procedure Main is
   Πλάτων  : constant := 12;     -- Plato
   Чайковский : constant := 12;  -- Tchaikovsky
   θ, φ : constant := 12;        -- Angles
begin
   null;
end Main;
$ gprbuild
using project file foo.gpr
Compile
   [Ada]          main.adb
main.adb:2:04: error: declaration expected
main.adb:2:05: error: illegal character
main.adb:3:04: error: declaration expected
main.adb:3:05: error: illegal character
main.adb:4:05: error: illegal character
gprbuild: *** compilation phase failed

Where is the actual character set for Ada programs defined? Has GNAT 2021 got it wrong?

An example program using Unicode characters in identifiers is below for your experimentation. Note that the use of wide characters in the literal string is outside the scope of the question.

main.adb:

with Ada.Wide_Text_IO; use Ada.Wide_Text_IO;

procedure Main is
   δεδομένα_πράμα : constant Wide_String := "Ο Πλάτων θα ενέκρινε";
begin
   Put_Line (Δεδομένα_πράμα);
end Main;

foo.gpr

project foo is

   for Source_Dirs use (".");
   for Main use ("main.adb");

   package Compiler is
      for Default_Switches ("ada") use ("-gnatW8", "-gnatiw");
   end Compiler;

end foo;

To build & run:

gprbuild
./main

Input masks in Ada

-- Date: 11/06/2022

with Ada.Text_IO; Use Ada.Text_Io;

procedure Masques is
  
    type XX is record
       X1 : character range 'A'..'D';
       X2 : character range 'E'..'H';
       X3 : character range 'I'..'L';
    end record;

begin

    Get_Line (XX);

end Masques;

I'm trying to write some sort of input masks to control the inputs as we do in IT. Of course the above example doesn't compile because Get_Line can't accept a record. Of course we can write an operation to put the characters together to create a string, thru a get or get_immediate.

-But the idea would be to use the language typing to control the input & to trap the errors by an exception by example.

-Some years ago, to the best of my recollection, i remember someone did this, but I'm unable to write it.. Thanks for the help.

Starting Gnat Studio with Alire fails

I have had a try at using Gnat Studio with the Alire package manager. Launching Gnat Studio using the 'alr edit' command is causing Gnat Studio to crash. I have had a look at the log file and there are several .dll files causing exceptions. The file entries are like this:

[PROJECTS.EXCEPTIONS] Unexpected exception: raised CONSTRAINT_ERROR : gnatcoll-projects.adb:5729 index check failed _PROJECTS.EXCEPTIONS_ [C:\GNATSTUDIO\bin\gps.libgnatcoll\libgnatcoll.dll] _PROJECTS.EXCEPTIONS_ 0x7ffc78dcecb8 ??? at ???

Gnat Studio opens in an 'inconsistent state' and crashes.

Regards Mike

gnatcoll-db includes dborm.py, need to understand routines in python

I was using gnatcoll-db, but the limitations made me to rewrite dborm.py in Ada. There are two routines in dborm.py (in python) that I don't understand, specifically compute_table_aliases and fields_count_array.

Any help will be welcome. Of course, the modifications can be shared between all of us.

Edited to complete information:

My project fork is here. I don't want to copy here the complete routines from dborm.py as I don't know exactly the license terms of ACS. dborm.py can be downloaded from https://github.com/AdaCore/gnatcoll-db/tree/master/gnatcoll_db2ada.

The routines that I want to translate to Ada are:

  • compute_table_aliases, lines 2407 to 2448. Really I don't understand the algorithm.
  • fields_count_array and fields_count, lines 2372 to 2397. For these routines I have a translation to Ada but when testing, the result is OK except in a few cases.

Here is my translation to Ada:

Max_Depth : constant := 3; type Counts_Array is array (0 .. Max_Depth) of Integer;

  function Fields_Count_Array (T         : Table_Description;
                               Follow_LJ : Boolean;
                               DepthMax  : Integer;
                               FKStop    : Field := No_Field)
                            return Counts_Array is
     FK_Stop : Boolean; -- to be reset before each call to fields_count_
     Depth   : Integer := 0;
     Temp    : Counts_Array;

     function Fields_Count (T         : Table_Description;
                            Depth     : Integer;
                            Follow_LJ : Boolean;
                            FKStop    : Field := No_Field) return Integer;
     function Fields_Count (T         : Table_Description;
                            Depth     : Integer;
                            Follow_LJ : Boolean;
                            FKStop    : Field := No_Field)
                         return Integer is
        Result : Integer;
        procedure Process_FK (FK : in out Field);
        procedure Process_FK (FK : in out Field) is
        begin
           if FK = FKStop then
              FK_Stop := True;
              return;
           end if;
           if FK_Stop then
              return;
           end if;
           if Follow_LJ or (not FK.Can_Be_Null) then
              Result := Result +
                Fields_Count (Pointed_Table (FK), Depth - 1, Follow_LJ);
           end if;
        end Process_FK;
     begin
        Result := Num_Fields (T);
        if Depth > 0 then
           For_Each_FK (T, Process_FK'Access);
        end if;
        return Result;
     end Fields_Count;

  begin
     while Depth <= DepthMax loop
        FK_Stop := False;
        Temp (Depth) := Fields_Count (T, Depth, Follow_LJ, FKStop);
        Depth := Depth + 1;
     end loop;
     return Temp;
  end Fields_Count_Array;

Note that all type definitions come from gnatcoll-sql.

I understand that this is difficult to follow, perphaps may be better if I send a report on the modifications and the complete new Ada package replacing dborm.py. How?

Get output from array in Ada

I want to print array data user input. But it give me error. I need to get input from user and store in the array. After this i want to print it also count each duplicate word.

with Ada.Text_IO;
use Ada.Text_IO;    

procedure Main is
   type String_Val is array (1 .. 100) of Character;
   type Int_Val is array (1 .. 100) of Integer;
   Data : String_Val;
begin
   Put_Line ("Please enter values (use space as seperator)");
   for I in 1..String_Val'Length loop
      Data(I) := Character'Value(Get_Line);
   end loop;
   for I in String_Val'Range loop
      Put (String_Val (Data));
   end loop;
end Main;

Defining a package with its sub units in Package Name?

I have run across code in Ncurses which defines packages with dot, "." subunits in the name, like this: Package body example.subunit1.subunit1 is .... .... end example;

Would I not just name the package "example" only and then later with example.subunit1; use example.subunit1;

OR does older Ada code (as found in Ncurses) have syntax to put a package's subunits in the package name?

Maximum line length Ada.Text_IO.Put_Line

I'm using GNATColl-sql to create SQL queries. I was thinking to perform a visual inspection of the generated SQL code using the "To_String" method, but when I call Ada.Text_IO.Put_Line or Ada.Text_IO.Put to see the SQL string, a carriage return is being added to the output.

For example, I cannot share the real query, if I expect:

SELECT orders.order_id, customers.last_name FROM orders INNER JOIN customers ON orders.customer_id = customers.customer_id WHERE orders.order_id <> 1 ORDER BY orders.order_id;

What I'm getting after Put_Line/Put instead (notice the line break at customers.cust CRLF omer_id):

SELECT orders.order_id, customers.last_name FROM orders INNER JOIN customers ON orders.customer_id = customers.cust
omer_id WHERE orders.order_id <> 1 ORDER BY orders.order_id;

I first suspected that carriage return was due to a GNATColl-sql bug, but now I suspect the procedure Ada.Text_IO.Put_Line has a maximum line length to print. Am I right?

I tried the procedure "Ada.Text_IO.Set_Line_Length" with a huge count value, greater than the position where the carriage return is added, but it is printed at the same place.

How can I print a large string on a line instead of several lines?

New suspicion:

I was running my main on GNATStudio, but if I directly run the main.exe on a cmd I can see the SQL on a line now. GNATStudio may be configuring a maximum line length for printing.

How do I define and statically initialize a vector index by an enumeration?

I'm unable to define a vector using an enumeration as an index.

First I define my record:

type contact_name is record
    first    : unbounded_string;
    last     : unbounded_string;
end record;

I define my enumeration:

type profession is (plumber, doctor, lawyer, ombudsman, dealer);

I declare my vector of contact_name using professional as the index type:

package Pro_Vector is new Ada.Containers.Vectors (Index_Type => Profession, Element_Type => contact_name);

Finally, I build my table:

Pro_Table : Pro_Vector.Vector := (plumber, ("Bob","daPlumah")) & 
(doctor, "Felix", "FeelGood"))

When I try to compile it says expect signed integer type of Index_Type. It also claims Pro_Vector is undefined. I substituted profession for natural and it compiled, but my static initialization has errors.

Why won't it accept my enum as an index. I was under the impression that Ada is super safe. By using an unconstrained type like Natural, doesn't it compromise safety. Also, how do I statically initialize my vector?

How to use different fix point types in mathematical operations in Ada?

For the program at the end I get the following error messages from gnat:

test2.adb:23:61: error: invalid operand types for operator "-"
test2.adb:23:61: error: left operand has type "Gain_Type" defined at line 11
test2.adb:23:61: error: right operand has type "Offset_Type" defined at line 12

Unfortunately I did not find a good example how to resolve this in a way resulting in speed optimized code for rather small embedded targets.

Always casting everything to the biggest type does not make that much sense I feel. What is the best way to do that/ isn't there a good reference existing how to efficiently use fixed point for a bit more complicated mathematical problems?

procedure Test2 is
   Adc_Width   : constant Positive := 10;
   Adc_Delta   : constant Float    := 2.0**(-Adc_Width);
   Adc_Mod   : constant    := 2**Adc_Width;
   Error_Delta : constant          := 2.0**(-1);
   Gain_Min    : constant Float    := 1.0 - 2.0 * Adc_Delta;
   Gain_Max    : constant Float    := 1.0 + 2.0 * Adc_Delta;
   Offset_Min  : constant Float    := -0.5 * Adc_Delta;
   Offset_Max  : constant Float    := 2.0 * Adc_Delta;
   type Gain_Type is delta Adc_Delta * Error_Delta range Gain_Min .. Gain_Max;
   type Offset_Type is
      delta Adc_Delta * Error_Delta range Offset_Min .. Offset_Max;
   type Adc_Encoded_Type is mod Adc_Mod with
      Size => 16;
   subtype Adc_Value_Type is natural range 0 .. Adc_Encoded_Type'Modulus - 1;
   type Adc_Delta_Type is delta Adc_Delta range 0.0 .. 1.0 - Adc_Delta;
   function Compensate
    (Adc : in Adc_Encoded_Type; Gain : in Gain_Type; Offset : in Offset_Type)
     return Adc_Delta_Type
   is
   begin
      return Adc_Delta_Type (((Adc_Value_Type (Adc) * Gain) - Offset) / Adc_Mod);
   end Compensate;
begin
end Test2;

How to std::rotate in Ada?

Does an equivalent to std::rotate exist in the Ada standard libraries? If not, is there a consensus in the Ada community of some non-standard algorithms library for this sort of operation? I found the Ada Standard Generic Library but it was a proof of concept from 1996 and does not include rotate for arrays (it does for trees, though).

I whittled down the demo on the cppreference page linked above:

#include <algorithm>
#include <iostream>
#include <vector>

auto print = [](auto const& remark, auto const& v) {
    std::cout << remark;
    for (int n : v)
        std::cout << n << ' ';
    std::cout << '\n';
};

int main()
{
    std::vector<int> v{2, 4, 2, 0};

    print("before rotate:\t\t", v);

    // simple rotation to the left
    std::rotate(v.begin(), v.begin() + 1, v.end());

    print("simple rotate left:\t", v);

    // simple rotation to the right
    std::rotate(v.rbegin(), v.rbegin() + 1, v.rend());

    print("simple rotate right:\t", v);
}

The equivalent Ada would be this, if I had a drop-in replacement for the std::rotate calls:

with Ada.Text_IO;
with Ada.Characters;
with Ada.Characters.Latin_1;

procedure Main is
   Tab : Character renames Ada.Characters.Latin_1.HT;

   type Number_List_Type is array (1 .. 4) of Integer;

   procedure Print (Remark : String; Numbers : Number_List_Type) is
      use Ada.Text_IO;
      Endline : Character renames Ada.Characters.Latin_1.LF;
   begin
      Put (Remark);
      for N of Numbers loop
         Put (N'Image & ' ');
      end loop;
      Put (Endline);
   end;

   V : Number_List_Type := (2, 4, 2, 0);
begin
   print("before rotate:" & Tab & Tab, v);

   -- simple rotation to the left
   -- std::rotate(v.begin(), v.begin() + 1, v.end());

   print("simple rotate left:" & Tab, v);

   -- simple rotation to the right
   -- std::rotate(v.rbegin(), v.rbegin() + 1, v.rend());

   print("simple rotate right:" & Tab, v);
end Main;

Expected output:

before rotate:          2 4 2 0
simple rotate left:     4 2 0 2
simple rotate right:    2 4 2 0

Linking error using community edition 2021 on Fedora 36

I have used Ada successfully for years; but I am trying to create "hello world," and I am getting the following error:

/opt/GNAT/2021/bin/../libexec/gcc/x86_64-pc-linux-gnu/10.3.1/ld:
.gnu.build.attributes has both ordered
[.gnu.build.attributes.lo.exit in /lib/../lib64/crt1.o] and unordered
[.gnu.build.attributes in /lib/../lib64/crt1.o] sections
/opt/GNAT/2021/bin/../libexec/gcc/x86_64-pc-linux-gnu/10.3.1/ld:
final link failed: bad value collect2: error: ld returned 1 exit status

Using Ada, using instance of Ada.Numerics.Generic_Elementary_Functions(Real), calculating Nth root and output same

Using Ada 2018 (increment of 2012), within a loop structure, I need to calculate the Nth root of Integers.

  1. In my package combinations.ads specification declaration (using GNAT GPS), I have
type Real           is digits 6;
  1. In package body combinations.adb, I have a procedure build, where before the begin, I instantiate Ada’s Generic_Elementary_Functions(Float), with
package Fermat_math is new
   Ada.Numerics.Generic_Elementary_Functions(Real)  ;
   use Fermat_math 

Later, in output section, I try:

-- -------------- buggy, fix
--   combo_sum_root := Fermat_math.Exp (Log (Integer(combo_sum_root) / n);  — n is integer type
     combo_sum_root := Real(combo_sum) ** (1/n) ; 
-- -------------

   put(" and sum's root is ");
   put(combo_sum_root'image );  —  -- gives all roots as 1.00000E+00

I had it working a few weeks back, with roots = 3.878… etc., but I lost that in careless version control.

Actual Code here:

— combinations.ads specification ------------------------------------------
with gearbox;
use  gearbox;
with Ada.Float_Text_IO  ; use Ada.Float_Text_IO;

with Ada.Text_IO;  use Ada.Text_IO;
with Ada.Numerics; use Ada.Numerics;

with Ada.Numerics.Elementary_Functions;
use  Ada.Numerics.Elementary_Functions;

package combinations is

type combo_action   is (add_element,clear, show, show_sum, Build);
type Real           is digits 6    ;

combo_sum_root      : Real         ;
i,n,b, combos_cnt
,combo_sum          : integer      ;

procedure get_parms                ;
Procedure build  (b,n,r:integer)   ;

end combinations;

-- combinations.adb BODY ---------------------------------------
with Text_IO              ;  use Text_IO;
with Ada.Text_IO          ;  use Ada.Text_IO;
with Ada.INteger_Text_IO  ;  use Ada.Integer_Text_IO;
with Ada.Strings.Unbounded;  use Ada.Strings.UNbounded;
with gearbox              ;  use gearbox;
with Ada.Numerics.Generic_Elementary_Functions ;

package body combinations is

group, Intersection_count,r     : Integer              ;
done, get_value                 : boolean := false     ;
CR: constant Character := Character'Val (13)           ;
type gear_arrays is array(positive range <>) of integer;

-- ------------------------------------------------------------


procedure get_parms is
begin
...

 end get_parms ;

-- --------------------------------------------------
 procedure build  (b,n,r: Integer) is
-- --------------------------------------------------
cnt, e_cnt, value                : integer :=0      ;
launch, pause                    : character        ;
run_again                        : String := " "    ;
show_group                       : Unbounded_string ;
all_done, combo_done             : boolean := false ;
combo_sum_root                   : Real             ;
progress_string : Unbounded_String                  ;
gears:gear_array     (1..r)                         ;

-- with Ada.Numerics.Generic_Elementary_Functions   ;  — in specification .ads file
 package Fermat_math is new
  Ada.Numerics.Generic_Elementary_Functions(Real)  ;
 use Fermat_math                                   ;

begin
...
...

put("Selecting "); -- put(tot_combos, width=>1);
put(" Possible Combinations,"); New_line;
While Not all_done loop  -- for all/x combiNatioNs
 ...  
end loop;
   -- ------------------------
   combo_sum := 0;
   for e in  1..r loop  -- select r value, element of grou & size of combiatios
     value := fermats(gears(e).position,1);
     ...
   put ("Combination sum is "); put (combo_sum, width => 1);
  …..
  -- -------------- buggy, fix
--   combo_sum_root := Fermat_math.Exp (Log (Integer(combo_sum_root) / n);
 combo_sum_root := Real(combo_sum) ** (1/n) ; 
  -- -------------

   put(" and sum's root is ");
   put(combo_sum_root'image );  -- gives all roots as 1.00000E+00

   end loop;

     group := group + 1;  --
   end if;  -- is New group and shift
  end loop;  -- Not all doNe

 eNd build;
begin   -- package
 Null;
end combinations;

Parametrizing blob types using gnatcoll.sql

I am using the Ada library gnatcoll.sql to create parametrizable SQL queries.

While I am able to create Integer parameters for type SQL_Field_Integer using the function:

function Integer_Param (Index : Positive) return Integer_Fields.Field'Class
  renames Integer_Fields.Param;

As well as for the following types using their respective functions:

SQL_Field_Bigint, SQL_Field_Text, SQL_Field_Boolean, SQL_Field_Float, SQL_Field_Long_Float, SQL_Field_Money, SQL_Field_Time, SQL_Field_Date

I am not able to parametrize Blob fields, I don't find those type mappings nor any service except the postgresql/sqlite bindings at low-level.

How can I parametrize blob types? As String?

How can I install the ZFP (Zero Foot Print) RTS (Run Time System) for AVR with the Alire package manager for Ada?

How can I install the ZFP (Zero Foot Print) RTS (Run Time System) for AVR with the Alire package manager for Ada?

My project file, I think correctly, contains:

project Avr is
   for Runtime("Ada") use "zfp";
   for Target use "avr-elf";
end Avr;

alire.toml hopefully correction contains:

[[depends-on]]
gnat_avr_elf = ">=11.2.4"

Unfortunately, when running alr build, I get:

gprconfig: can't find a toolchain for the following configuration:
gprconfig: language 'ada', target 'avr-elf', runtime 'zfp'

I found documentation for programming AVR with Ada, but this assumes that I build the tool-chain myself and not have a package manager at least providing the GNU tool-chain.

The same applies to Programming Arduino with Ada.

❌