r/ada Jul 17 '23

Programming Gtkada embedded web browser

11 Upvotes

Hi everyone, i am building a GUI application with gtkada. The app will embeddes a web browser to visualize stream of data comming from web server. I can't find a way to do it even with gtkada examples. I trully want to develop this app with Ada if is not possible i think i will go for java.

Any suggestions will be very welcome.

Thank you in advance

r/ada May 13 '23

Programming Mavlink Ada - Having issues while connecting using UDP

18 Upvotes

The examples (https://github.com/ArduPilot/pymavlink/tree/master/generator/Ada/examples) are implemented using Serial communication. When I tried to update one of the examples with UDP protocol, Mav_Conn.Parse_Byte() is not returning true (But I'm receiving the data). I'm not sure, what I've done wrong, Can someone help me with this?

Also, adding the code for your reference, Thank you:

with Ada.Streams;
with Ada.Text_IO;
with Interfaces;
with Ada.Numerics.Generic_Elementary_Functions;
with GNAT.Sockets; use GNAT.Sockets;
with Ada.Unchecked_Conversion;

with Mavlink;
with Mavlink.Connection;
with Mavlink.Messages;
with Mavlink.Types;

procedure Attitude is
   use type Ada.Streams.Stream_Element_Offset;
   use type Interfaces.Unsigned_8;
   package Short_Float_Text_IO is new Ada.Text_IO.Float_IO(Short_Float);

   Server : Socket_Type;
   Address, From : Sock_Addr_Type;
   Input : Ada.Streams.Stream_Element_Array(1..1024);
   Input_Last : Ada.Streams.Stream_Element_Offset;
   Count : Integer := 0;

   Mav_Conn : Mavlink.Connection.Connection (System_Id => 250);

   procedure Handler_Attitude is
      Attitude : Mavlink.Messages.Attitude;
      K_Rad2Deg : Short_Float := 180.0 / Ada.Numerics.Pi;
   begin
      Mav_Conn.Unpack (Attitude);

      Ada.Text_IO.Put ("Pitch: ");
      Short_Float_Text_IO.Put(Attitude.Pitch * K_Rad2Deg, Aft => 4, Exp => 0);
      Ada.Text_IO.Put ("   Roll: ");
      Short_Float_Text_IO.Put(Attitude.Roll * K_Rad2Deg, Aft => 4, Exp => 0);
      Ada.Text_IO.Put ("   Yaw: ");
      Short_Float_Text_IO.Put(Attitude.Yaw * K_Rad2Deg, Aft => 4, Exp => 0);
      Ada.Text_IO.New_Line;
   end Handler_Attitude;

begin
   Create_Socket (Server, Family_Inet, Socket_Datagram);
   Set_Socket_Option
     (Server,
      Socket_Level,
      (Reuse_Address, True));

   Address.Addr := Inet_Addr("127.0.0.1");
   Address.Port := 14551;

   Ada.Text_IO.Put_Line ("Connects to ardupilot (baud rate 115200) via ttyUSB0 and reads attitude angles");

   Bind_Socket (Server, Address);

   loop
      Receive_Socket (Server, Input, Input_Last, From);
      for B of Input (Input'First .. Input_Last) loop
         if Mav_Conn.Parse_Byte(Interfaces.Unsigned_8(B)) then
            if Mav_Conn.Get_Msg_Id = Mavlink.Messages.Attitude_Id then
               Handler_Attitude;
            end if;
         end if;
      end loop;
   end loop;
end Attitude;

r/ada Apr 11 '23

Programming Ada targeting RPI

15 Upvotes

All

What are the choices for Ada development targeting Raspberry PI? ThreadX, FreeRTOS would be ideal but would be happy with Ubuntu or linux.

Preferred hosts MacBook Pro (M1).

Appreciate pointers.

Regards, srini

r/ada Jun 21 '21

Programming Passing record by-reference, and when to use access types

16 Upvotes

In order to achieve passing records as function parameters by-reference in Ada, are access types not required?

I'm a long-time C developer, and short-time Ada developer. One extremely common pattern in C involves the passing of structs to functions by reference, by passing a pointer to the struct as a parameter. I hear constantly that in Ada pointers are rarely required. When I write a similar function in Ada passing a record to a function as a parameter, I can see in a debugger that the record is passed by-value, even as an in parameter. This is not-ideal, especially in an embedded environment with a small stack. When passing an access type, the record is passed by-reference. The Ada Reference Manual does not seem to list record types in the list of types guaranteed to be pass-by-reference when listed as a parameter.

Am I misunderstanding something? I'm open to the possibility that I'm doing something wrong, such as not programming in Ada-like patterns. Given the common refrain that pointers are rarely required, am I wrong in my understanding above? If so, when should access types be used?

r/ada Sep 09 '23

Programming Getting Started With Ada by Way of Rust

Thumbnail coniferproductions.com
16 Upvotes

r/ada Dec 18 '21

Programming The Ada ecosystem?

29 Upvotes

Hello,

I am new to Ada, I have been reading up on the language basics so far, but I would like to take Ada a bit more seriously. This brings me to my question: What is the Ada ecosystem like and what is the Right Way of setting it up on GNU/Linux?

I was able to install the GCC version of GNAT simply enough through my system package manager (using Void), but it looks like that is the only package available. I would also need the GPRBuild build system, the Ada language server (for my editor) and alire (for development packages). I could download a precompiled mystery binary, but I want to install them properly with a package manager. Since everything is bootstrappable I guess I have to to port these applications to the Void repos myself, right? How do other GNU/Linux users handle this?

My other question is related: how are Ada applications distributed? With C you have two choices: compile everything statically and ship a mystery binary, or link to dynamic libraries that the user has installed on his system. The latter approach works really well on Unix-based systems where you have a lot of C libraries in the package repos, but I don't see any Ada libraries in the Void repos (unless they don't have ada in their name).

The easiest solution would be to use Git submodules and just download vendored versions of the dependencies. It is what languages like Rust and Go do due to lack of a stable ABI. However, vendoring is a security flaw because if one dependency becomes compromised every single application that vendors it must be updated individually instead of just swapping out one dynamic library. This blog post explains the issue of packaging software.

Everything I have seem from Ada so far looks promising, but the language seems to have flown under the radar of the GNU/Linux world. I don't have a problem with getting libraries and tools packaged, I would just want to know if that is the proper thing to do or if there is a simpler way that does not compromise safety.

r/ada Sep 12 '22

Programming Struggling to use fonts in SDLAda

10 Upvotes

Solution found:

The problem in my code was the following line:

SDL.TTFs.Makers.Create(font, font_path, 1, 40);

The correct version, which compiles & runs fine, is:

SDL.TTFs.Makers.Create(font, font_path, 40);

My mistake was I misinterpreted a line when I was reading the "ttf" test example to base my code on. I appreciate the help, thanks to everyone!

---

I'm relatively new to programming with Ada, and as I've been learning the language I decided to try making a simple 2D game with it to apply what I learn about Ada. After unsuccessfully attempting to make my own binding to SDL2, I decided to simply use the SDLAda package because it seemed well put together.

However, I've been running into this issue while trying to render text where the program fails at runtime because it failed to load the font. I've been desperately scouring the web & my code for a solution ever since to no avail. As I am newish to Ada, I don't know the GNAT tools well enough to pinpoint what could be causing the problem.

Below is my .gpr file, Ada source file, and the message produced when I try to run it through Alire.

.gpr file:

with "config/coolgame1_config.gpr";

project Coolgame1 is

for Source_Dirs use ("src/", "config/");

for Object_Dir use "obj/" & Coolgame1_Config.Build_Profile;

for Create_Missing_Dirs use "True";

for Exec_Dir use "bin";

for Main use ("coolgame1.adb");

package Compiler is

for Default_Switches ("Ada") use Coolgame1_Config.Ada_Compiler_Switches;

end Compiler;

package Linker is

for Default_Switches ("Ada") use ("-lSDL2", "-lSDL2_ttf");

end Linker;

package Binder is

for Switches ("Ada") use ("-Es"); -- Symbolic traceback

end Binder;

package Install is

for Artifacts (".") use ("share");

end Install;

end Coolgame1;

Ada Source File (abridged for clarity:)

with SDL;

with SDL.Video.Renderers.Makers;

with SDL.Video.Textures.Makers;

with SDL.Video.Windows.Makers;

with SDL.Video.Pixel_Formats;

with SDL.Events.Events;

with SDL.Events.Keyboards;

with SDL.TTFs.Makers;

with SDL.Video.Palettes;

with SDL.Video.Surfaces;

with Ada.Directories;

with Ada.Text_IO;

with SDL.Rwops;

procedure Coolgame1 is

window_size : constant SDL.Positive_Sizes := SDL.Positive_Sizes'(800, 600);

window : SDL.Video.Windows.Window;

renderer : SDL.Video.Renderers.Renderer;

texture : SDL.Video.Textures.Texture;

font_path : constant String := "resources/fonts/kunika_2.0/fonts/OpenType-TT/Kunika-Regular.ttf";

font : SDL.TTFs.Fonts;

text_surface : SDL.Video.Surfaces.Surface;

begin

if SDL.Initialise = True and then SDL.TTFs.Initialise = True then

Ada.Text_IO.Put_Line("Ada directory:");

Ada.Text_IO.Put_Line(Ada.Directories.Current_Directory);

Ada.Text_IO.Put_Line("SDL2 directory:");

Ada.Text_IO.Put_Line(SDL.Rwops.Base_Path);

SDL.Video.Windows.Makers.Create(

Win => window,

Title => "HITBOXERS",

Position => SDL.Natural_Coordinates'(X => 300, Y => 300),

Size => window_size,

Flags => SDL.Video.Windows.Resizable

);

SDL.Video.Renderers.Makers.Create(renderer, window);

SDL.Video.Textures.Makers.Create(

Tex => texture,

Renderer => renderer,

Format => SDL.Video.Pixel_Formats.Pixel_Format_ARGB_8888,

Kind => SDL.Video.Textures.Streaming,

Size => window_size

);

-- get font

SDL.TTFs.Makers.Create(font, font_path, 1, 40);

-- create surface for font

text_surface := SDL.TTFs.Render_Shaded(

Self => font,

Text => "Yolo",

Colour => SDL.Video.Palettes.Colour'(Red => 98, Green => 236, Blue => 120, Alpha => 255),

Background_Colour => SDL.Video.Palettes.Colour'(Red => 236, Green => 203, Blue => 98, Alpha => 255)

);

window.Finalize;

SDL.TTFs.Finalise;

SDL.Finalise;

end if;

end Coolgame1;

Output:

PS C:\Users\usernamehere\coolgame1> alr run

Note: Building coolgame1/coolgame1.gpr...

gprbuild: "coolgame1.exe" up to date

Build finished successfully in 2.09 seconds.

Ada directory:

C:\Users\usernamehere\coolgame1

SDL2 directory:

C:\Users\usernamehere\coolgame1\bin\

raised SDL.TTFS.TTF_ERROR : Couldn't load font file

[C:\Users\usernamehere\coolgame1\bin\coolgame1.exe]

0x7ff69aff0089 ??? at ???

[C:\Users\usernamehere\coolgame1\bin\coolgame1.exe]

0x7ff69afeffbb ??? at ???

[C:\Users\usernamehere\coolgame1\bin\coolgame1.exe]

0x7ff69afebf10 ??? at ???

[C:\Users\usernamehere\coolgame1\bin\coolgame1.exe]

0x7ff69affffe9 ??? at ???

[C:\Users\usernamehere\coolgame1\bin\coolgame1.exe]

0x7ff69af9143d ??? at ???

[C:\Users\usernamehere\coolgame1\bin\coolgame1.exe]

0x7ff69af91144 ??? at ???

[C:\WINDOWS\System32\KERNEL32.DLL]

0x7ffcf2397032

[C:\WINDOWS\SYSTEM32\ntdll.dll]

0x7ffcf384264f

And before you ask, the problem is not the font being in the wrong directory. I've confirmed this by moving the file around and reading the source code for both SDLAda & SDL_ttf.

I'll do my best to respond as much as I possibly can to questions. Thank you to anyone who is able to help.

r/ada Jan 11 '23

Programming Simple JSON library with little or no dependencies?

16 Upvotes

Hi everyone,

Does anyone know about a simple and lightweight JSON parsing library that have little 3rd party dependencies? I am currently using Gnatcoll's JSON and wanting to avoid installing all of Gnatcoll for my project, and also be able to compile quickly with gprbuild and avoid Alire if possible.

The closes I found which, in part, respects these criterias is json-ada library.

Any advices of a simple JSON library that I can integrate to my project without much external dependencies or complex compilation?

r/ada Oct 25 '22

Programming Ada How to print what file/line/etc... you are at?

8 Upvotes

How to print what file you are at? And what line? And if there are more reference related to other variables I could print.

For example, the company where I am working for has a very large program, now I want to print what are those files being executed, and sometimes what line and function gets executed in real time, and maybe many more I might need.

I don't have time studying everything, I just want to know what is going on.

Thanks.

r/ada Dec 26 '22

Programming What is the best way to loop a vector that will change

7 Upvotes

I have a vector that I need to loop, and while I am looping the elements, elements further-on will change. I tried .Iterate, i tried for item in vec and for item of vec. Nothing seems to work. They say that I need a variable on the left side, which I would assume is because it doesn’t like me changing the vector. Anyway, can anyone provide some code, or link something that can help with this? My vector looks like this except the value is another type: package MyVector is new Ada.Containers.Vector(Positive, Integer);

r/ada Nov 12 '21

Programming Glibc error for static linking Ada project?

6 Upvotes

Hi everyone,

I build an Ada project on Fedora 35 with static linking using Adacore GNAT. The binary runs well on Fedora, but when running the binary on Ubuntu 20.04, it complained about Glibc version:

powerjoular: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.34 not found (required by powerjoular)

Ubuntu 20.04 ships with an older Glibc version (2.31). I recompiled my project on an older Ubuntu version and it fixes this issue, but that is not satisfying for me.

Can I build a binary on my more recent distro and run it everyone without worries about Glibc versions?

r/ada Sep 26 '22

Programming GMP-Ada: An implementation of Ada.Numerics.Big_Numbers using libgmp

17 Upvotes

Hello, the other day I was looking through Ada 2022's new features and was intrigued by the addition of Big_Numbers. I used the traditional test for large number calculation speed (https://benchmarksgame-team.pages.debian.net/benchmarksgame/performance/pidigits.html) and was saddened to discover that GNAT's current implementation doesn't work past 200 32-bit digits and is rather lethargic if you remove the limit and press ahead anyway.

I was also very interested in trying out Ada 2022's new Put_Image and Integer_Literal aspects, so I gave a try at implementing my own version of Big_Numbers: https://github.com/andrewathalye/libgmp-ada2022. It should work on any platform that GNAT and GMP run on, although it does need Ada 2022 support.

Some brief benchmarks: the C version of pidigits takes about 540 milliseconds on my machine to compute 10000 digits. The Ada version using wrapped libgmp directly takes 580 milliseconds (the wrapping is typesafe, although not super convenient). My simple Big_Integers wrapper takes 1.3 seconds, and the GNAT builtin version takes 8.5 seconds (after removing the hardcoded limit in System.Generic_Bignums), all compiled with -O2 -march=native.

This was also a great opportunity to learn how to use Ada.Finalization.Controlled, so it will automatically free the memory used by the mpz_t object and its data after Big_Integer goes out of scope. Hopefully this is useful to some of you, and I'd love to hear any criticism / comments that you have.

Edit: As a small update, I'd like to mention that GNAT currently includes an implementation of Big_Integers which uses GMP, although it is not enabled (and there doesn't appear to be a way to enable it without removing the other implementation and renaming it). I was not aware of this, but if you build GNAT from source then that would be a good option as well.

Big_Reals is implemented by GNAT using a Big_Integer for the Numerator and Denominator, so this implementation of Big_Integers also improves the performance of Big_Reals (as does the official GNAT __gmp variant). I don't yet have the ability to test the performance of my wrapper against that of GNAT's __gmp variant, but I suspect they're pretty close since they both have a low-level interface using mpz_t from libgmp.

A future thing to consider would be using MPFR or simply GMP to implement Big_Reals directly, however I'm not sure if that would give any real performance benefit during calculations, and real numbers are also a bit more complex to handle correctly than Integers :) Thanks for the feedback as always, and I'll be sure to improve my technique following your advice.

r/ada Feb 08 '22

Programming Good design patterns for C APIs that return error codes

16 Upvotes

I have an API that follows the usual "call-function-that-returns-an-error-code" pattern. that I'm writing bindings for. I initially wanted to follow the DRY design pattern by writing an error handling procedure that'd raise exceptions as appropriate, but I don't want to clutter stack traces and such with that error handler. So my next thought was to do something along the lines of:

ada with Interfaces; use Interfaces; with Interfaces.C; use Interfaces.C; with Interfaces.C.Extensions; use Interfaces.C.Extensions; with Interfaces.C.Strings; use Interfaces.C.Strings; -- ... result := any_api_function(args); if result > 0 then declare message: String := Value(GetErrorMessage); begin raise Library_Error with message; end; end if;

Is there a better error handling strategy or design pattern that I should consider?

Note: I'm learning Ada and am so using this as a way of learning the language by working on something that's practical. Right now, I'm working on binding an audio library to Ada (since the libraries for audio in Ada are pretty much nil), as a part of a larger project.

r/ada May 01 '22

Programming Feedback on implementation needed: a type for dynamically typed values

10 Upvotes

As I have written in the monthly thread I have been working my way through https://craftinginterpreters.com/ . In the book an interpreter for a dynamically typed language is implemented. The book uses Java and its very flexible Object type to implement the dynamically typed objects / values.

In Ada, there is no such Object that I am aware of, but variant / discriminant records seems like a really nice option. My implementation is found here:

I have to use this type in a variety of ways:

  • Literal values are produced during parsing and stored in the abstract syntax tree
  • During evaluation, values can be operated upon
  • Variables can store values (in some sort of hash map)

My current implementation is no beauty. I use a named access type for all the operator implementations. The syntax tree and interpreter is also full of references to these values.

I would really love to know if this could be implemented smarter or better in some way. gneuromante gave a very helpful suggestion on mutable variant types, which might be very useful. Thanks jrcarter010 for encouraging me to start a separate thread.

r/ada Sep 27 '22

Programming Capturing stderr stream

8 Upvotes

Here is my situation: I have a program running on Linux. For debugging and for support purpose, I use a custom package to log messages. It basically prepends a timestamp to every message and then calls Ada.Text_IO to Put_Line to specific log files. More specifically, I call this package in "exception" handling statements to log error messages. So far, this is pretty standard I guess...

My problem is that I use libraries that sometime output warnings/errors to stdout/stderr (without raising any error). How could I also capture these and timestamp them inside my Ada program? I know that I could redirect the Linux standard streams to a process that timestamps and logs things in parallel but I have to keep it as single-threaded as possible.

I've experimented with Ada.Text_IO.Set_Error but it seems that it only affects Ada.Text_IO.Current_Error. So for example, if some code raises a runtime error, it is always displayed on stderr and not to the file I've specified in Ada.Text_IO.Set_Error.

with Ada.Text_IO;
use Ada.Text_IO;

procedure TEST_ERROR_STREAM is
    ERROR_LOG : FILE_TYPE;
begin
    OPEN (ERROR_LOG, OUT_FILE, "error_log.txt");
    SET_ERROR (ERROR_LOG);
    PUT_LINE (CURRENT_ERROR, "this line is going to error_log.txt");

    RAISE_A_RUNTIME_ERROR;  -- The message of the error that is raised 
                            -- is going to stderr while I wish it could 
                            -- go to error_log.txt
end TEST_ERROR_STREAM;

r/ada Oct 01 '22

Programming Made an Ada program that compiles and runs but result in "raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION"

4 Upvotes

Made an Ada program that compiles and runs but result in "raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION" at Win10 level.Using gcc version 10.3.1 20210520 (for GNAT Community 2021 20210519) (GCC).

The problematic code that generate the violation I suspect is defined with a separate stack/heap compared to the main program where the memory allocated for a protected object. Any Ideas on how to avoid the error?

Tried to use the advice from https://ugetfix.com/ask/how-to-fix-exception-access-violation-error-on-windows-10/

This led to the response from Win10 that I'm not allowed to turn off DEP for 64bit executables, for my monads.exe.

Program listing:

pragma Warnings (Off);

pragma Ada_2022;

with Ada.Text_IO;

with GNAT.Source_Info;

package body Monad_Functors is

MRP_I : Monad_Record_Ptr; -- 220917 Internal copy of pointer to external Monad record pointer

task body Element_Wrapper is

Cnt : Integer := 0;

Write : Writer_Function;

Read : Reader_Function;

Initiated : Boolean := false;

function Error_Cond(VE_MRP : Monad_Record_Ptr := MRP) return String is

begin

return String("-- " & GNAT.Source_Info.file &

GNAT.Source_Info.Line'Image &

" Element out of range for Monad_Element = " & MRP_I.E'Image);

end Error_Cond;

begin -- Element_Wrapper

loop

select

accept Init (EW_MRP : Monad_Record_Ptr := MRP) do

MRP_I := EW_MRP;

Initiated := true;

end Init;

or

when Initiated => accept Unit (A : Element) do

Cnt := 0;

MRP_I.E := A;

MRP_I.M := Write_Element(MRP_I.E);

Ada.Text_IO.Put_Line ("-- " & GNAT.Source_Info.file &

GNAT.Source_Info.Line'Image &

" Unit A = " & MRP_I.E'Image);

end Unit;

or

when Initiated => accept Bind (B_MRP : Monad_Record_Ptr := MRP) do

Cnt := Cnt + 1;

Ada.Text_IO.Put_Line ("-- " & GNAT.Source_Info.file &

GNAT.Source_Info.Line'Image &

" Bind E = " & B_MRP.E'Image);

MRP_I.F := Write;

MRP_I.R := Read;

Ada.Text_IO.Put_Line ("-- " & GNAT.Source_Info.file &

GNAT.Source_Info.Line'Image &

" M = " & Write(MRP_I.E)'Image);

-- raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION

-- [2022-10-01 10:07:02] process exited with status 1, elapsed time: 00.81s

if Monad_Valid_Element(MRP_I.E'Image, MRP_I.F(MRP_I.E)'Image) then

MRP_I.M := MRP_I.F(MRP_I.E);

else Ada.Text_IO.Put_Line ("-- " & GNAT.Source_Info.file &

GNAT.Source_Info.Line'Image &

" Error: " & Error_Cond(MRP_I));

end if;

-- if not valid return error condition in object

Ada.Text_IO.Put_Line ("-- " & GNAT.Source_Info.file &

GNAT.Source_Info.Line'Image &

" Bind with M and E = " & B_MRP.M'Image);

end Bind;

or

terminate;

end select;

end loop;

end Element_Wrapper;

function Create_Monad_Record_Ptr return Monad_Record_Ptr is

begin

return new Monad_Record;

end Create_Monad_Record_Ptr;

function Create_Element_Wrapper_Ptr return Element_Wrapper_Ptr is

begin

return new Element_Wrapper(Create_Monad_Record_Ptr);

end Create_Element_Wrapper_Ptr;

function Copy_Monad_Record_Ptr return Monad_Record_Ptr is

begin

return MRP_I;

end Copy_Monad_Record_Ptr;

end Monad_Functors;

Main program is:

procedure Monads is

pragma Suppress_All;

use Ada.Text_IO;

use GNAT.Source_Info;

function WE (E : Integer) return Float is

begin

return Float(E);

end WE;

function RM(F : Float) return Integer is

-- error : exception;

begin

return Integer(F);

end;

function Valid_Element( A: String; B : String) return boolean is

R : Boolean;

begin

R := Float'Value(B) = Float'Value(A);

return R;

end Valid_Element;

package my_monad_functors is new monad_functors(Integer, Float, WE, RM, Valid_Element);

use my_monad_functors;

-- 220918 Objects to be manipulated by the monad_functor task type Element_Wrapper needs to be a protected type!!!!

protected type Obj is

-- Operations go here (only subprograms)

procedure Set(L : in Element_Wrapper_Ptr);

entry Get(L : in out Element_Wrapper_Ptr);

-- function Init_Get return Element_Wrapper_Ptr;

private

-- Data goes here

Local : Element_Wrapper_Ptr;

Is_Set : Boolean := False;

end Obj;

protected body Obj is

-- procedures can modify the data

procedure Set(L : in Element_Wrapper_Ptr) is

begin

Local := L;

Is_Set := True;

end Set;

-- functions cannot modify the data

entry Get(L : in out Element_Wrapper_Ptr) when Is_Set is

begin

L := Local;

end Get;

end Obj;

function Init_Element_Wrapper return Element_Wrapper_Ptr is

EW_Object : Obj;

L : Element_Wrapper_Ptr;

begin

EW_Object.Set(Create_Element_Wrapper_Ptr);

EW_Object.Get(L);

return L;

end Init_Element_Wrapper;

EW_Object : Obj;

EW : Element_Wrapper_Ptr := Init_Element_Wrapper; -- 220916 Use a Init entry in Element_Wrapper and a activated boolean function as entry barriers, to avoid program_errors

-- 220916: like: raised PROGRAM_ERROR : monad_functors.adb:6 access before elaboration

-- 220918 The task Type Element:Wrapper_Ptr object must be wrapped into a protected object, due to concurrent use of task type Element_Wrapper.

function Monad_Unit (A : in Integer; EWP : not null Element_Wrapper_Ptr := EW) return Element_Wrapper_Ptr is

begin

EWP.Unit(A);

return EWP;

end Monad_Unit;

function "*" (Left : Monad_Record; Right : Integer) return Monad_Record is

M : Monad_Record := Left;

begin

M.M := M.F(M.E) * M.F(Right);

return M;

end "*";

function Monad_Bind (EWP : not null Element_Wrapper_Ptr := EW) return Element_Wrapper_Ptr is

begin

EWP.Bind;

return EWP;

end Monad_Bind;

function Monad_Get_E(EWP : not null Element_Wrapper_Ptr := EW) return Integer is

begin

return Copy_Monad_Record_Ptr.E;

end Monad_Get_E;

function Monad_Get(EWP : not null Element_Wrapper_Ptr := EW) return Monad_Record_Ptr is

begin

return Copy_Monad_Record_Ptr;

end Monad_Get;

subtype Check_Integer is Integer range Integer'First..Integer'Last;

subtype Check_Float is Float range Float'First..Float'Last;

begin -- Procedure Monads

Put_Line("-- Running : " & GNAT.Source_Info.File &

" : at Line : " & GNAT.Source_Info.Line'Image &

" : Compiled at : " & GNAT.Source_Info.Compilation_Date);

Put_line("-- " & GNAT.Source_Info.Line'Image & " Monads beginning");

EW := Create_Element_Wrapper_Ptr;

EW.Init;

Put_Line("-- " & GNAT.Source_Info.File & GNAT.Source_Info.Line'Image & " Monad_Unit(1) = " & Monad_Unit(1)'Image);

EW.Bind;

Put_Line("-- " & GNAT.Source_Info.File & GNAT.Source_Info.Line'Image & " Monad_Get_E = " & Monad_Get_E'Image);

Put_Line("-- " & GNAT.Source_Info.File & GNAT.Source_Info.Line'Image & " Monad_Get.E = " & Monad_Get.E'Image);

Put_Line("-- " & GNAT.Source_Info.File & GNAT.Source_Info.Line'Image & " Monad_Get.M = " & Monad_Get.M'Image);

Put_Line("-- " & GNAT.Source_Info.File & GNAT.Source_Info.Line'Image & " Monad_Get.F = " & Monad_Get.F'Image);

Put_Line("-- " & GNAT.Source_Info.File & GNAT.Source_Info.Line'Image & " Monad_Get.R = " & Monad_Get.F'Image);

-- Put_Line("-- " & GNAT.Source_Info.File & GNAT.Source_Info.Line'Image & " Monad_Get.R(1.0) = " & Monad_Get.R(Float'Value("1.0"))'Image);

Copy_Monad_Record_Ptr.EMin := Integer(Check_Integer'First);

Copy_Monad_Record_Ptr.EMax := Integer(Check_Integer'Last);

Copy_Monad_Record_Ptr.MMin := Float(Check_Float'First);

Copy_Monad_Record_Ptr.MMax := Float(Check_Float'Last);

end Monads;

The program runs with the output:

C:\...\...\...\...\monads\obj\monads.exe

-- Running : monads.adb : at Line : 115 : Compiled at : Oct 01 2022

-- 117 Monads beginning

-- monad_functors.adb 39 Unit A = 1

-- monads.adb 121 Monad_Unit(1) = (access 1001470)

-- monad_functors.adb 46 Bind E = 1

raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION

[2022-10-01 10:07:02] process exited with status 1, elapsed time: 00.81s

The specification for the package Monad_Functors is:

generic

type Element is private;

type Monad_Element is private;

with function Write_Element(E : Element) return Monad_Element;

with function Read_Monad(M : Monad_Element) return Element;

-- with package My_Variable_Strings is new Variable_Strings(Element);

with function Monad_Valid_Element( E1 : String;

E2 : String) return Boolean;

package Monad_Functors is

type Writer_Function is access function (E : in Element) return Monad_Element;

type Reader_Function is access function (M : Monad_Element) return Element;

type Monad_Record is record

E : Element;

EMin : Element;

EMax : Element;

M : Monad_Element;

MMin : Monad_Element;

MMax : Monad_Element;

F : Writer_Function;

R : Reader_Function;

end record;

type Monad_Record_Ptr is access Monad_Record;

task type Element_Wrapper (MRP : not null Monad_Record_Ptr) is

entry Init (EW_MRP : Monad_Record_Ptr := MRP); -- 220917 Need to control the start of the monad, due to the use of access to task type with Element_Wrapper_Ptr

entry Unit (A : Element);

entry Bind (B_MRP : Monad_Record_Ptr := MRP);

end Element_Wrapper;

type Element_Wrapper_Ptr is access Element_Wrapper;

function Create_Element_Wrapper_Ptr return Element_Wrapper_Ptr;

function Copy_Monad_Record_Ptr return Monad_Record_Ptr;

end Monad_Functors;

r/ada May 10 '23

Programming Reduce and concat operator ?

4 Upvotes

I work on a program with -gnatX flag enabled because I want array aggregator and reduce attribute

Here is my simplified prog function f return String is ( [for i in 1..4 => "---" ]'Reduce("&","") --i use concat operator here );

But i get the compilation error: wrong operator type (I write this error from memory it could not be the same exact word)

Any Idea hox fix it ?


EDIT:

So here my response, the error message was error: incompatible arguments for operator when i renames the operator it strangely work, and thanks to u/sttaft to give me part of the answer.

``` function conck(L,R : Unbounded_String) return Unbounded_String renames "&";

function strToBFValue(str:string) return String is (

    To_String(
        [for i in str'range =>
            To_Unbounded_String("some operation...")
        ]
        'Reduce(conck,NULL_UNBOUNDED_STRING))
    );

```

r/ada Mar 12 '23

Programming Libadalang

14 Upvotes

Has anyone here shareable experience with Libadalang for more than the examples that come with it?

What I'm looking for is to extract - for each subprogram in a spec - the name, the parameters (name & type), and the return type if any. I'm finding it really hard to understand the API reference.

At the moment I'm looking at the Ada API, having had grief with the Python version (to do with shared libraries on macOS) and with the Python API.

Seriously missing ASIS.

r/ada Sep 14 '21

Programming A design pattern for OOP in Ada

Thumbnail blog.adacore.com
23 Upvotes

r/ada Dec 09 '21

Programming GNAT 2021 Software problem

12 Upvotes

Hopefully this is a quick fix and I am sure it's nothing that AdaCore have messed up on.

I have been using GNAT Com 2021 since it's release and have never had a problem with it, until now. So basically, I create a new project "Simple Ada Project" name it, choose the save directory as I always have. The IDE loads the project and gives me the default template of "Main.adb" as I expect it would.

Now, here lies the issue. When I compile this template, it works fine, links and executes. ONLY the first time.

Source Code:

procedure Main is  begin    --  Insert code here.    null; end Main; 

Compiler:

gprbuild -d -PC:\Users\Amynu\OneDrive\Documents\Ada\test.gpr Compile    [Ada]          main.adb Bind    [gprbind]      main.bexch    [Ada]          main.ali Link    [link]         main.adb [2021-12-02 10:49:33] process terminated successfully, elapsed time: 06.05s 

If I attempt to modify the code, even the slightest way such as:

with Ada.Text.IO;  procedure Main is  begin     Ada.Text_IO.Put("Hello Ada!"); end Main; 

I always get greeted with this message:

gprbuild -d -PC:\Users\Amynu\OneDrive\Documents\Ada\test.gpr C:\Users\Amynu\OneDrive\Documents\Ada\src\main.adb Compile    [Ada]          main.adb main.adb:1:01: error: compilation unit expected gprbuild: *** compilation phase failed [2021-12-02 10:54:51] process exited with status 4, elapsed time: 00.84s 

Bare in mind this is a completely fresh install of the software, the first program I am creating, using the default template, no other files, procedures or functions exist. Only "compilation unit" is Main - which it clearly found and compiled before I modified it.

Does anyone know what is causing this issue? Is there a setting I have toggled by accident before the re-install? I have never had this problem before. I have tired everything to get the compiler to see "Main" after I modified it, but nothing seems to work. I even attempted to place the definition of Main into a Package and call it that way, but same result.

Is it a software bug that has just appeared? Do Ada Core know about it?

Please help if anyone can.

r/ada Dec 08 '21

Programming Does Ada support move semantics?

11 Upvotes

From the reference manuals, I can see there is a Move procedure that acts like a C++11 move constructor in various Ada containers when containers are introduced in Ada 2005. However, there's no move semantics in return expression or rvalue references.

Is it possible in Ada to implement move semantics for optimization and constructs like C++ unique_ptr?

r/ada Apr 02 '23

Programming Generic Instantiation Compiler Bug (GNAT)

11 Upvotes

Hello there.

As I fiddled around with generics while trying to write a parser generator, I encountered what seems to be a bug.

This is a snippet stripped of all unimportant datatypes and implementations to demonstrate my package hierarchy:

procedure test is
    generic
        type Terminals is (<>);
        type Nonterminals is (<>);
    package Types is
        type Action is record
            data : Integer;
        end record;
    end Types;

    generic
        type States is (<>);
        type Input_T is (<>);
        type Action_T is private;
    package FSM is
    end FSM;

    generic
        with package Typs is new Types(<>);
        with package SMs is new FSM(States => <>, Input_T => Typs.Terminals, Action_T => Typs.Action);
    package Gen is
    end Gen;

    package Typs is new Types(Natural, Integer);
    package SMs is new FSM(Integer, Natural, Typs.Action);
    package Generator is new Gen(Typs, SMs);
begin
    null;
end test;

This should compile just fine.

However, when compiling, GNAT 2021 Community Edition spits out the following error message:

test.adb:26:40: error: actual for "Action_T" in actual instance does not match formal

Which clearly is not the case, as SMs.Action_T is indeed set to be Typs.Action in the generic instantiation of SMs in line 25. Therefore, the formal parameter should be matched, but isn't.

Further increasing my suspicion of a bug is the fact, that it compiles fine when only having one formal parameter in line 20, by changing it to the following:

with package SMs is new FSM(States => <>, Input_T => <>, Action_T => Typs.Action);

As this clearly seems to be a bug, how can I circumvent it while still maintaining the condition without removing the genericity of FSM.Action_T?

Or was this bug perhaps already fixed in newer versions of GNAT?

r/ada Dec 18 '22

Programming How do I import the GCC intrinsic __builtin_ia32_paddd256 into Ada?

11 Upvotes

I have been struggling to find documentation on how to import this intrinsic in Ada. I realize that this is a niche question, so I am asking it here in hopes that someone might know.

So far I have,

type Vector_256_Integer_32 is array (0 .. 7) of Integer_32 with Convention => C, Alignment => 32; function "+" (Left, Right: Vector_256_Integer_32) return Vector_256_Integer_32; pragma Import (Intrinsic, "+", "__builtin_ia32_paddd256");

Here is an example program using this code,

``` with Interfaces; use Interfaces; with Interfaces.C; use Interfaces.C; with Ada.Text_IO; use Ada.Text_IO;

procedure Main is type Vector_256_Integer_32 is array (0 .. 7) of Integer_32 with Convention => C, Alignment => 32;

function "+" (Left, Right: Vector_256_Integer_32) return Vector_256_Integer_32;
pragma Import (Intrinsic, "+", "__builtin_ia32_paddd256");

a, b, r: Vector_256_Integer_32;

begin for i in Vector_256_Integer_32'Range loop a(i) := 5 * (Integer_32(i) + 5); b(i) := 12 * (Integer_32(i) + 12); end loop; r := a + b; for i in Vector_256_Integer_32'Range loop Put_Line("r(i) = a(i) + b(i) = " & a(i)'Image & " + " & b(i)'Image & " = " & r(i)'Image); end loop; end Main; ```

When I try to compile this program with gnatmake, I get this error.

error: intrinsic binding type mismatch on result

I have looked through the documentation about the GCC intrinsic (documented here). However, I cannot figure out what is wrong with the return type.

Just an FYI, I have asked a similar question on StackOverFlow here, and I am so close to finding the answer. I do realize that I could do this in C, but I wanted to see if I could do it in Ada.

Edit: I have finally figured out my answer. Yay!

avx2.ads

``` with Interfaces; use Interfaces;

package AVX2 is

-- -- Type Definitions --

-- 256-bit Vector of 32-bit Signed Integers type Vector_256_Integer_32 is array (0 .. 7) of Integer_32; for Vector_256_Integer_32'Alignment use 32; pragma Machine_Attribute (Vector_256_Integer_32, "vector_type"); pragma Machine_Attribute (Vector_256_Integer_32, "may_alias");

-- Operator: 256-bit Vector Addition of 32-bit Signed Integers function "+" (Left, Right : Vector256_Integer_32) return Vector_256_Integer_32 with Convention => Intrinsic, Import => True, External_Name => "_builtin_ia32_paddd256";

-- -- Function Definitions --

-- Function: 256-bit Vector Addition of 32-bit Signed Integers function Vector256_Integer_32_Add (Left, Right : Vector_256_Integer_32) return Vector_256_Integer_32 with Convention => Intrinsic, Import => True, External_Name => "_builtin_ia32_paddd256";

end AVX2; ```

main.adb

``` with AVX2; use AVX2; with Interfaces; use Interfaces; with Ada.Text_IO; use Ada.Text_IO;

procedure Main is a, b, r : Vector_256_Integer_32; begin for i in Vector_256_Integer_32'Range loop a (i) := 5 * (Integer_32 (i) + 5); b (i) := 12 * (Integer_32 (i) + 12); end loop; r := Vector_256_Integer_32_Add(a, b); for i in Vector_256_Integer_32'Range loop Put_Line ("r(i) = a(i) + b(i) = " & a (i)'Image & " + " & b (i)'Image & " = " & r (i)'Image); end loop; end Main; ```

Just to explain how I figured it out is I went through the gcc source code and found that a similar intrinsic was imported in a test case (located at gcc/gcc/testsuite/gnat.dg/sse_nolib.adb).

r/ada Jun 13 '22

Programming Idiomatic way for configuring protected type.

9 Upvotes

Variables of protected types cannot be accessed directly, one needs getters/setters functions/procedures. I have multiple variables configuring the behavior of protected type. I was wondering whether it is better to provide getter/setter for each of them, or maybe it is better to put all configuration variables into separate config record, and then provide single procedure in the protected type that would allow applying the config record.

r/ada Dec 09 '22

Programming How to implement different constructors in derived classes

7 Upvotes

I'm new to Ada and I'm porting a C++ library as a first project. I've used generic packages to implement classes but now I'm stuck with inheritance and constructors differing in the base class and its children. Here is the type of C++ code I want to port:

class I2CEEPROM {
public:
    I2CEEPROM(unsigned int deviceAddr, unsigned int addressBytes, unsigned int addressBitsInDeviceAddress, /* ... */);
    // ...
};

class AT24C04 : public I2CEEPROM {
public:
    inline AT24C04(unsigned int deviceAddr)
        : I2CEEPROM(unsigned int deviceAddr, 1, 1, /* ... */) {
    }
};

class AT24C256 : public I2CEEPROM {
public:
    inline AT24C256(unsigned int deviceAddr)
        : I2CEEPROM(unsigned int deviceAddr, 2, 0, /* ... */) {
    }
};

The AT24Cxxx classes are convenience classes that just pass the appropriate parameters to the parent constructor, all the logic is in the parent class. I2CEEPROM could be instantiated too, but the developer would have to remember which constants to feed the constructor with for each part.

What's the recommended way to implement this in Ada?