Ada - Discrete_Random example - ada

Page 53 of "Programming in Ada 2012" by John Barnes shares an incomplete fragment of code that I cannot get to work.
I've come up with this as a full program expanding the code from the book...
with Ada.Numerics; use Ada.Numerics;
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
type Coin is (Heads, Tails);
package Random_Coin is new Discrete_Random(Coin);
use Random_Coin;
G : Generator;
C : Coin;
begin
for i in 1 .. 20 loop
C := Random(G);
Put (C'Image);
end loop;
end Main;
The "GPS" IDE I'm using complains of the following errors:
Line 6: "Discrete_Random" is undefined
Line 7: "Random_Coin" is undefined
Line 9: "Generator" is undefined
Line 14: "Random" is undefined
The IDE does give me the "intellisense" (to use a term from Visual Studio) that indicates that Discrete_Random is actually visible and available given the "with" and "use" statements I've added.
Can someone walk me through the stupid mistakes I'm making please?

The problem is that, unlike Ada.Numerics.Pi, in which Pi is a component of Ada.Numerics, Discrete_Random is a child of Ada.Numerics.
Once you’ve said use Ada.Numerics, you could write just Pi in your program, but you have to actually with Ada.Numerics.Discrete_Random in order for it to be available.
In fact, you don’t need to with or use Ada.Numerics, this works just fine:
with Ada.Numerics.Discrete_Random;
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
type Coin is (Heads, Tails);
package Random_Coin is new Ada.Numerics.Discrete_Random(Coin);

Related

Ada : custom type in range 1..var?

I'm a very beginner of Ada code. I use GPS from AdaCore.
I would create a variable sized by the user.
I write this :
-- My ada program --
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;
procedure main is
wanted : Integer := 10;
type custom is range 0..wanted;
...
But something went wrong in line 8 :
Builder results
C:\Users\**********\Desktop\ada project\src\main.adb
8:26 "wanted" is not static constant or named number (RM 4.9(5))
8:26 non-static expression used for integer type bound
I really don't understand what this mean... Can someone help me ?
Variable wanted is not a constant, it may change its value during program execution, therefore this variable is not allowed to be used as range constraint when declaring new types. You may however make it constant by using constant keyword (Wanted : constant Integer := 10;). It should resolve your problem.
As said by Timur, wanted has to be constant in its scope. This allows you some nice things such as declaring a type inside a procedure. Look at this, it might be of interest :)
-- My ada program --
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;
procedure Main is
procedure Test (Wanted : Integer) is
type custom is new Integer range 0..wanted;
begin
Put_Line("First value " & Custom'Image (Custom'First)
& " Last value " & Custom'Image (Custom'Last));
end Test;
begin
Test (10);
Test (12);
end Main;
Output is
First value 0 Last value 10
First value 0 Last value 12
In this case, your type is different from one call to another but it works as wanted is constant within the procedure. The only thing is that the type defined has to be a new derived type of the type of your parameter.
I let you think about the possibilities :)

How do you implement Generic_Sorting in Ada for a vector?

I'm trying to do some basic translations of old C++ code from many moons ago to learn Ada, and I have been absolutely stumped on how to sort a vector using the built-in Generic_Sorting. I haven't been able to find any concrete examples of it in action, the closest being a now-defunct Danish wiki article which looks like it would have had a full example but the archive didn't snatch it up: https://web.archive.org/web/20100222010428/http://wiki.ada-dk.org/index.php/Ada.Containers.Vectors#Vectors.Generic_Sorting
Here is the code as I thought it should work from the above link:
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Containers.Vectors; use Ada.Containers;
procedure Vectortest is
package IntegerVector is new Vectors
(Index_Type => Natural,
Element_Type => Integer);
package IVSorter is new Generic_Sorting;
IntVec : IntegerVector.Vector;
Cursor : IntegerVector.Cursor;
begin
IntVec.Append(3);
IntVec.Append(43);
IntVec.Append(34);
IntVec.Append(8);
IVSorter.Sort(Container => IntVec);
Cursor := IntegerVector.First(Input);
while IntegerVector.Has_Element(Cursor) loop
Put(IntegerVector.Element(Cursor));
IntegerVector.Next(Cursor);
end loop;
end Vectortest;
I've tried so many different combinations of use and with but all I can get are various error codes. The above code gives Generic_Sorting is not visible, but when I try to explicitly state with Ada.Containers.Vectors.Generic_Sorting I get the error "Ada.Containers.Vectors.Generic_Sorting" is not a predefined library unit. I have no idea what I'm doing wrong here, I'm sure it's a fundamental misunderstanding of the way Ada brings in packages, and I hope that nailing this down will help me understand it a bit better.
Generic_Sorting is an inner package to Ada.Containers.Vectors and cannot be explicitly withed (as you have discovered). And since Ada.Containers.Vectors is itself a generic package, Generic_Sorting is an inner package to the instantiation of Ada.Containers.Vectors. So you can reach it by prefixing with the name of the instance:
package IVSorter is new IntegerVector.Generic_Sorting;

Ada Source code modifications using ASIS(Ada Semantics interface specifications)

i am developing a tool for finding sub type range overflow problems in Ada source code.for this purpose i am using ASIS for finding assignment statements in Ada source code and finding type of the variables on the right side of the assignment
expression.now i want to replace the variables(not of record type) of the assignment expression with 'first, 'last values of the variable type in the assignment statement so that i will get compilation error if any range overflow happens.below is an example what i am trying to convey.
procedure Example is
subtype A_Type is integer 1 .. 10;
subtype B_Type is integer -5 .. 5;
subtype C_Type is integer 1 .. 12;
A : A_Type;
B : B_Type;
C : C_Type;
begin
C := A + B;
end Example;
I want modify C := A + B; with C := A_Type'Last + B_Type'Last in the source code. C := A_Type'Last + B_Type'Last assignment statement will get warning at compile time or Constraint error during run time.
Is it possible do above modifications with ASIS?
For your purpose, you shouldn't rewrite the source text you are processing. You should rather write a new program, which only contains exactly the required declarations and assignments.
So the output should be something like:
with Type_Declarations;
procedure Test_Driver is
begin
declare
C : Type_Declarations.C_Type;
begin
C := Type_Declarations."+" (Type_Declarations.A_Type'First, Type_Declarations.B_Type'First);
C := Type_Declarations."+" (Type_Declarations.A_Type'First, Type_Declarations.B_Type'Last);
C := Type_Declarations."+" (Type_Declarations.A_Type'Last, Type_Declarations.B_Type'First);
C := Type_Declarations."+" (Type_Declarations.A_Type'Last, Type_Declarations.B_Type'Last);
end;
end Test_Driver;
ASIS was not designed to make modifications like that. You can, however take a look at libadalang from AdaCore, which supports this (and works on partial sources, so you won't have to precompile your sources)
GNAT includes utilities gnat2xml and xml2gnat; gnat2xml generates a representation of the source based on ASIS, and xml2gnat converts it back to Ada. You could maybe modify the XML output of the first and feed it back to the second.
Not that I’m recommending this; the XML schema isn’t documented, and is complicated.
If you want a tool that can apply modifications to Ada source code, you might be interested in our DMS Software Reengineering Toolkit with its Ada front end.
DMS parses source code to ASTs, and makes those ASTs available for modification using DMS's Abstract Syntax Tree procedural interface (direct hacking at the tree nodes) and/or DMS's rewrite rules (source-to-source transformations "if you see this replace it by that" written in [Ada] language surface syntax, that directly manipulates the trees. After your changes are made, DMS can prettyprint the source to regenerate valid Ada source code, even preserving comments and formatting in those places that have not been modified.

How to print integers in ada83 environment

I want to print integers in Ada 83. At present I am just using 'with Text_IO' and 'use Text_IO'. I don't want to print using the Integer'Image option. I want to use Integer_Text_IO in ada83. Please help me out with the syntax.
I am using below code:
with Text_IO;
use Text_IO;
i: INTEGER :=1;
package Int_IO is new Integer_IO(INTEGER);
use Int_IO; put(i);
I am getting 'expect signed integer type in instantiation of "Num" ' error.
The example below, which compiles, should help.
But please, when posting a question on StackOverflow (or anywhere on the Net, really) show us the code you’ve actually tried. The sample you’ve provided doesn’t come close to compiling (it fails at line 3 with compilation unit expected), and that makes it very hard for us to work out how to help you.
You’ll get expect signed integer type in instantiation of “Num” if you try to instantiate Text_IO with the wrong sort of type (for example, Float).
with Text_IO;
procedure Integer_IO_Demo is
package Int_IO is new Text_IO.Integer_IO (Integer);
begin
for J in 5 .. 10 loop
Int_IO.Put (J);
Text_IO.New_Line;
end loop;
end Integer_IO_Demo;

Programming in Ada error in executing files

I just started programming in Ada and I have a problem in executing some files .adb.
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;
procedure Trapeze(A:integer;B: Integer;C :Integer;D: Integer) is
procedure Traceligne(C:Character;X:Integer) is
begin
for I in 1 .. X loop
Put("C");
end loop;
end Traceligne;
H:Integer:=C;
Alpha:Integer:=D;
Decd:integer:=A;
Decg:integer:=B;
begin
for I in 1 .. H loop
Traceligne(' ',Decd);
Traceligne('*',Alpha);
Traceligne(' ',Decg);
Decd:=Decd-Integer(Decd*I/H);
Decg:=Decg-Integer(Decg*I/H);
Alpha:=Alpha+Integer(Decd*I/H)+Integer(Decg*I/H);
end loop;
get(x);
Trapeze(1,2,3,4)
end Trapeze;
i have this code error:
line 1: with: command not found.
I don't know the reason of this message .
PS: The question is simple for some programs my computer recognize the with Ada.Text_IOcommand and for some others it gives me the error mentioned before I don't know why.
In fact I found the real problem its in the compilation of the file it compiles but stops in gcc and doesn't continue to the gnatbind and gnatlink I hope you will have some suggestions.
The reason for the command not found message is that you're trying to execute the trapeze.adb file rather than an executable program built from it (trapeze or, on Windows, trapeze.exe).
The reason why GNAT hasn't built an executable program is that, in GNAT, a main program must be a parameterless procedure; presumably some of your test programs were parameterless, but this one isn't.
If you were hoping to be able to supply the parameters from the command line, as
$ ./trapeze 1 2 3 4
then you need to use Ada.Command_Line to retrieve them.

Resources