20080309170358!ada Programming PDF
20080309170358!ada Programming PDF
Contents
1 Basic
1.1 Things to look out for
1.1.1 comb format
1.1.1.1 if statements
1.1.1.2 procedures
1.1.1.3 functions
1.1.1.4 records
1.1.1.5 class records
1.1.1.6 package declarations
1.1.1.7 generic declarations
1.1.2 Type and subtype
1.1.3 Constrained types and unconstrained types
1.1.4 Dynamic types
Augusta Ada King,
1.1.5 Separation of interface Countess of Lovelace.
1.2 "Hello, world!" programs
1.2.1 "Hello, world!"
1.2.2 "Hello, world!" with renames
1.2.3 "Hello, world!" with use
1.2.4 FAQ: Why is "Hello, world!" sooo big?
2 Installing
2.1 GNAT 3.15p, the latest public GMGPL release
2.2 GNAT GPL Edition (Ada 2005)
2.3 The GNU Ada Project
2.4 Prebuilt packages as part of larger distributions
2.4.1 Mac OS X
2.4.2 Linux
2.4.2.1 SuSE
2.4.2.2 Debian
2.4.2.3 Mandrake
2.4.3 Windows
2.4.3.1 AIDE
2.4.3.2 MinGW
2.4.3.3 Cygwin
2.4.4 MS-DOS
2.4.4.1 DJGPP
2.4.5 Solaris 8, 9, 10 on SPARC and x86
2.5 Build your own
2.5.1 Linux
2.5.2 Windows
2.5.2.1 Cygwin
2.6 See also
2.6.1 Wikibook
3 Building
3.1 Building with various compilers
3.1.1 GNAT
3.1.1.1 GNAT commandline
3.1.1.2 GNAT IDE
3.1.2 Rational APEX
3.1.3 ObjectAda
3.1.4 Macintosh OS X
3.1.5 To be completed
3.2 Compiling our Demo Source
3.2.1 GNAT
14.4.2.1 Ada 95
14.4.2.2 Ada 2005
14.4.3 Ada Quality and Style Guide
15 Strings
15.1 Fixed-length string handling
15.2 Bounded-length string handling
15.3 Unbounded-length string handling
15.4 See also
15.4.1 Wikibook
15.4.2 Ada 95 Reference Manual
15.4.3 Ada 2005 Reference Manual
16 Subprograms
16.1 Procedures
16.2 Functions
16.3 Named parameters
16.4 Default parameters
16.5 See also
16.5.1 Wikibook
16.5.2 Ada 95 Reference Manual
16.5.3 Ada 2005 Reference Manual
16.5.4 Ada Quality and Style Guide
17 Packages
17.1 Parts of a package
17.1.1 The public package specification
17.1.2 The private package specification
17.1.3 The package body
17.2 Using packages
17.2.1 Standard with
17.2.2 Private with
17.2.3 Limited with
17.2.4 With type
17.3 Package organisation
17.3.1 Child packages
17.3.2 Nested packages
17.3.3 Subunits
17.4 See also
17.4.1 Wikibook
17.4.2 Wikipedia
17.4.3 Ada 95 Reference Manual
17.4.4 Ada 2005 Reference Manual
18 Input Output
18.1 Text I/O
18.2 Direct I/O
18.3 Sequential I/O
18.4 Storage I/O
18.5 Stream I/O
18.6 See also
18.6.1 Wikibook
18.6.2 Ada 95 Reference Manual
18.6.3 Ada 2005 Reference Manual
18.6.4 Ada Quality and Style Guide
19 Exceptions
19.1 Robustness
19.2 Modules, preconditions and postconditions
19.3 Predefined exceptions
19.4 Input-output exceptions
19.5 Exception declarations
19.6 Raising exceptions
19.7 Exception handling and propagation
19.8 Information about an exception occurrence
19.9 See also
19.9.1 Wikibook
19.9.2 Ada 95 Reference Manual
19.9.3 Ada 2005 Reference Manual
19.9.4 Ada Quality and Style Guide
20 Generics
20.1 Parametric polymorphism (generic units)
20.2 See also
20.2.1 Wikibook
20.2.2 Wikipedia
20.2.3 Ada Reference Manual
21 Tasking
21.1 Tasks
21.1.1 Rendezvous
21.1.2 Selective Wait
21.1.3 Guards
21.2 Protected types
21.3 Entry families
21.4 Termination
21.5 Timeout
21.6 Conditional entry calls
21.7 Requeue statements
21.8 Scheduling
21.9 Interfaces
21.10 See also
21.10.1 Wikibook
21.10.2 Ada Reference Manual
21.10.2.1 Ada 95
21.10.2.2 Ada 2005
21.11 Ada Quality and Style Guide
22 Object Orientation
22.1 Object-orientation on Ada
22.1.1 The package
22.1.1.1 A little note for C++ programmers
22.1.2 The tagged record
22.1.2.1 The class-wide type
22.1.3 Primitive operations
22.1.4 Interfaces
22.2 Class names
22.2.1 Classes/Class
22.2.2 Class/Object
22.2.3 Class/Class_Type
22.3 See also
22.3.1 Wikibook
22.3.2 Wikipedia
22.3.3 Ada Reference Manual
22.3.3.1 Ada 95
22.3.3.2 Ada 2005
22.3.4 Ada Quality and Style Guide
23 Ada 2005
23.1 Language features
23.1.1 Character set
23.1.2 Interfaces
23.1.3 Union
23.1.4 With
23.1.5 Access types
23.1.5.1 Not null access
23.1.5.2 Anonymous access
23.2 Language library
23.2.1 Container
23.2.2 Scan Filesystem Directories and
Environment Variables
23.2.3 Numerics
23.3 Real-Time and High Integrity Systems
23.3.1 Ravenscar profile
23.3.2 New scheduling policies
23.3.3 Dynamic priorities for protected objects
23.4 Summary of what's new
23.4.1 New keywords
23.4.2 New pragmas
23.4.3 New attributes
23.4.4 New packages
23.5 See also
23.5.1 Wikibook
23.5.2 Pages in the category Ada 2005
23.6 External links
23.6.1 Papers and presentations
23.6.2 Rationale
Basic
comb format
There is a comb format in all the control structures and module structures. See the following
examples for the comb format. You don't have to understand what the examples do yet - just
look for the similarities in layout.
if statements
procedures
functions
records
class records
package declarations
package P is
declarations
private
declarations
end P;
generic declarations
generic
declarations
package P is
declarations
private
declarations
end P;
Note that semicolons consistently terminate statements and declarations; and that the empty
string is not a valid statement: the null statement is null;.
Dynamic types
Where values in Pascal or C must be static (e.g. the subscript bounds of an array) they may
be dynamic in Ada. However, static expressions are required in certain cases where dynamic
evaluation would not permit a reasonable implementation (e.g. in setting the number of
digits of precision of a floating point type).
Separation of interface
Ada consistently supports a separation of interface and mechanism. You can see this in the
format of a package, which separates its declaration from its body; and in the concept of a
private type, whose representation in terms of Ada data structures is inaccessible outside the
scope containing its definition.
with Ada.Text_IO;
procedure Hello is
begin
Ada.Text_IO.Put_Line("Hello, world!");
end Hello;
The with statement adds the package Ada.Text_IO to the program. It contains all
functionality needed for textual Input/Output. It makes the declarations (i.e. all types and the
operations on them) within Ada.Text_IO visible by selection. In Ada, packages are used as
toolboxes, providing a collection of tools and types in one easy-to-access module.
Next we declare a main procedure. In Ada the main procedure does not need to be called
"main". It is implementation defined which subprograms can be used as main subprograms.
However, an implementation is required to support all main subprograms that are public
parameterless library procedures. (The last sentence is a quote from the reference manual,
RM 10.2(29).)
Since with only makes the content of a package visible by selection, we need to prefix the
procedure name Put_Line with the package name Ada.Text_IO. If you need procedures from
a package more often some form of shortcut is needed. There are two options open:
with Ada.Text_IO;
procedure Hello is
package IO renames Ada.Text_IO;
begin
IO.Put_Line("Hello, world!");
IO.New_Line;
IO.Put_Line("I am an Ada program with package rename.");
end Hello;
renames can also be used for procedures, functions, variables, array elements. It can not be
used for types - a type rename can be accomplished with subtype.
with Ada.Text_IO;
procedure Hello is
use Ada.Text_IO;
begin
Put_Line("Hello, world!");
New_Line;
Put_Line("I am an Ada program with package use.");
end Hello;
use can be used for packages and in the form of use type for types. use type makes only the
operators of the given type directly visible but not any other operations on the type.
Standard behavior for Ada compilers — or good compilers in general — is not to create the
best code possible but to be optimized for ease of use. This is done to not frighten away
potential new users by providing a system which does not work "out of the box".
The GNAT project files which you can download alongside the example programs use better
tuned compiler, binder and linker options. If you use those your "Hello, world!" will be a lot
smaller:
32K ./Linux-i686-Debug/hello_world_1
8,0K ./Linux-i686-Release/hello_world_1
36K ./Linux-x86_64-Debug/hello_world_1
12K ./Linux-x86_64-Release/hello_world_1
1,1M ./Windows_NT-i686-Debug/hello_world_1.exe
16K ./Windows_NT-i686-Release/hello_world_1.exe
32K ./VMS-AXP-Debug/hello_world_1.exe
12K ./VMS-AXP-Release/hello_world_1.exe
Installing
The only free and fully functional Ada compiler available is the GNAT Compiler, which is part
of the GNU Compiler Collection. GNAT is the only compiler that supports all the annexes of
the Ada standard.
Linux
ftp://ftp.cs.kuleuven.ac.be/pub/Ada-Belgium/mirrors/gnu-ada/3.15p/gnat-3.15p-i686-pc-redha
ftp://ftp.cs.kuleuven.ac.be/pub/Ada-Belgium/mirrors/gnu-ada/3.15p/florist-3.15p-src.tgz
ftp://ftp.cs.kuleuven.ac.be/pub/Ada-Belgium/mirrors/gnu-ada/3.15p/asis/asis-3.15p-src.tgz
http://libre.adacore.com/gps/gps-2.1.0-academic-x86-linux.tgz
Windows
ftp://ftp.cs.kuleuven.ac.be/pub/Ada-Belgium/mirrors/gnu-ada/3.15p/winnt/gnat-3.15p-nt.exe
ftp://ftp.cs.kuleuven.ac.be/pub/Ada-Belgium/mirrors/gnu-ada/3.15p/winnt/gnatwin-3.15p.exe
ftp://ftp.cs.kuleuven.ac.be/pub/Ada-Belgium/mirrors/gnu-ada/3.15p/asis/asis-3.15p-src.tgz
http://libre.adacore.com/gps/gps-2.1.0-academic-x86-windows.exe
OS/2
ftp://ftp.cs.kuleuven.ac.be/pub/Ada-Belgium/mirrors/gnu-ada/3.15p/contrib/os2/gnat-3.15p-os
FLORIST is a library that provides a POSIX programming interface to the operating system.
ASIS, the Ada Semantic Interface Specification, is a library that allows Ada programs to
examine and manipulate other Ada programs.
You can download GNAT GPL Edition from the Libre site: http://libre.adacore.com/
Most notably the The GNU Ada Project also provides the scripts used to create the packages.
This may be helpfull if you plan to port the compiler to another platform or create a so called
cross compiler.
You can find The GNU Ada Project at: http://gnuada.sourceforge.net. There are GPL and
GMGPL licenced version available.
gcc --version
gcc (GCC) 4.0.1
Copyright (C) 2004 Free Software Foundation, Inc.
Dies ist freie Software; die Kopierbedingungen stehen in den Quellen. Es
gibt KEINE Garantie; auch nicht für VERKAUFBARKEIT oder FÜR SPEZIELLE ZWECKE.
GCC-Versions beginning with 3.3. are buggy and you should either try to upgrade to a 3.4.
version or later, or stick with GNAT 3.15p.
Mac OS X
GNAT for Macintosh (http://www.adapower.net/macos/) provides a version of the GNAT
Compiler, Xcode integration and bindings.
Linux
Most versions of Linux come with GNAT packages as part of their GCC distribution. These
can be used instead of the Libre Version.
SuSE
All versions of SuSE Linux have a GNAT compiler included. SuSE versions 9.2 and higher
also contains ASIS, Florist and GLADE libraries. The following two packages are needed:
gnat
gnat-runtime
For 64 bit system you will need the 32 bit compatibility packages as well:
gnat-32bit
gnat-runtime-32bit
Debian
The GNU/Ada compiler (GNAT) can be installed on a Debian system with this command:
This will also give you a list of related packages, which are likely to be useful for an Ada
programmer.
`gnat' is GNAT 3.15p (the Libre version), with several bug fixes. Besides this version, Debian
`sarge' also carries `gnat-3.3' (not recommended) and `gnat-3.4'.
Mandrake
The GNU/Ada compiler (GNAT) can be installed on a Mandrake system with this command:
urpmi gnat
Windows
Both MinGW for Windows and Cygwin have GNAT as part of their GCC distribution.
AIDE
MinGW
The following list should help you install. {I may have forgotten something - but this is wiki,
just add to the list}
1. Install MinGW-3.1.0-1.exe.
1. extract binutils-2.15.91-20040904-1.tar.gz.
2. extract mingw-runtime-3.5.tar.gz.
3. extract gcc-core-3.4.2-20040916-1.tar.gz.
4. extract gcc-ada-3.4.2-20040916-1.tar.gz.
5. extract gcc-g++-3.4.2-20040916-1.tar.gz (Optional).
6. extract gcc-g77-3.4.2-20040916-1.tar.gz (Optional).
7. extract gcc-java-3.4.2-20040916-1.tar.gz (Optional).
8. extract gcc-objc-3.4.2-20040916-1.tar.gz (Optional).
9. extract w32api-3.1.tar.gz.
2. Install mingw32-make-3.80.0-3.exe (Optional).
3. Install gdb-5.2.1-1.exe (Optional).
4. Install MSYS-1.0.10.exe (Optional).
5. Install msysDTK-1.0.1.exe (Optional).
1. extract msys-automake-1.8.2.tar.bz2 (Optional).
2. extract msys-autoconf-2.59.tar.bz2 (Optional).
3. extract msys-libtool-1.5.tar.bz2 (Optional).
I have made good experience in using D:\MinGW as target directory for all installations and
extractiations.
Also noteworthy is that the the Windows version for GNAT from Libre is also based on
MinGW.
Cygwin
MS-DOS
DJGPP has GNAT as part of their GCC distribution.
DJGPP
DJGPP programs run also in a DOS command box in Windows, as well as in native MS-DOS
systems.
Linux
For Linux users, there are instructions for building your own GNAT compiler at:
http://ada.krischik.com/index.php/Articles/CompileGNAT
Windows
Cygwin
A new Cygwin build is done just the same way the Linux build is done.
See also
Wikibook
Ada Programming
Building
Ada programs are usually easier to build than programs written in other languages like C or
C++, which frequently require a makefile. This is because an Ada source file already
specifies the dependencies of its source unit. See the with keyword for further details.
Building an Ada program is not defined by the Reference Manual, so this process is
absolutely dependent on the compiler. Usually the compiler kit includes a make tool which
compiles a main program and all its dependencies, and links an executable file.
If the file contains a procedure, gnatmake will generate an executable file with the
procedure as main program. Otherwise, e.g. a package, gnatmake will compile the unit and
all its dependencies.
GNAT commandline
gnatmake can be written as one word gnatmake or two words gnat make. For a full list of
gnat commands just type gnat without any further commandline option. The output will look
something like this:
Commands FIND, LIST, PRETTY, STUB and XREF accept project file switches -vPx, -Pprj and -Xnam=val
For further help on the option just type the command (one word or two words - as you like)
without any further commandline option.
GNAT IDE
The GNAT toolchain comes with an IDE (Integrated Development Environment) called GPS (GNAT
Programming System). You need to download and install it separately. The GPS features a
There are also GNAT plugins for Emacs (Ada Mode (http://libre.adacore.com/adamode/) ) and
KDevelop available.
Rational APEX
Rational APEX is a complete development environment comprising a language sensitive
editor, compiler, debugger, coverage analyser, configuration management and much more.
You normally work with APEX running a GUI.
APEX has been built for the development of big programs. Therefore the basic entity of APEX
is a subsystem, a directory with certain traits recognized by APEX. All Ada compilation units
have to reside in subsystems.
You can define an export set, i.e. the set of Ada units visible to other subsystems. However
for a subsystem A to gain visibility to another subsystem B, A has to import B. After
importing, A sees all units in B's export set. (This is much like the with-clauses, but here
visibility means only potential visibility for Ada: units to be actually visible must be
mentioned in a with-clause of course; units not in the export set cannot be used in
with-clauses of Ada units in external subsystems.)
Normally subsystems should be hierarchically ordered, i.e. form a directed graph. But for
special uses, subsystems can also mutually import one another.
A view can be defined to be the development view. Other views then hold releases at
different stages.
Each Ada compilation unit has to reside in a file of its own. When compiling an Ada unit, the
compiler follows the with-clauses. If a unit is not found within the subsystem holding the
compilee, the compiler searches the import list (only the direct imports are considered, not
the closure).
Units can be taken under version control. In each subsystem, a set of histories can be
defined. An Ada unit can be taken under control in a history. If you want to edit it, you first
have to check it out - it gets a new version number. After the changes, you can check it in
again, i.e. make the changes permanent (or you abandon your changes, i.e. go back to the
previous version). You normally check out units in the development view only; check-outs in
release views can be forbidden.
You can select which version shall be the active one; normally it is the one latest checked in.
You can even switch histories to get different development paths. e.g. different bodies of the
same specification for different targets.
ObjectAda
ObjectAda is a set of tools for editing, compiling, navigating and debugging programs written
in Ada. There are various editions of ObjectAda. With some editions you compile programs
for the same platform and operating systems on which you run the tools. These are called
native. With others, you can produce programs for different operating systems and
platforms. One possible platform is the Java virtual machine.
These remarks apply to the native Microsoft Windows edition. You can run the translation
Whether you prefer to work from the IDE, or from the command line, a little bookkeeping is
required. This is done by creating a project. Each project consists of a number of source files,
and a number of settings like search paths for additional Ada libraries and other
dependences. Each project also has at least one target. Typically, there is a debug target,
and a release target. The names of the targets indicate their purpose. At one time you
compile for debugging, typically during development, at other times you compile with
different settings, for example when the program is ready for release. Some (all
commercial?) editions of ObjectAda permit a Java (VM) target.
Macintosh OS X
Apple's free (gratis) IDE, XCode, is included with every Macintosh (but requires an explicit
installation step from DVD-ROM or CD-ROM) and is also downloadable from
http://developer.apple.com. XCode uses the GNU Compiler Collection and thus supports Ada,
GDB, etc., and also includes myriad tools for optimizing code which are unique to the
Macintosh platform. However, GNAT must be installed separately as it is (as of 2005) not
distributed as part of XCode. Get the binary and/or sources at http://www.macada.org/, along
with numerous tools and bindings including bindings to Apple's Carbon frameworks which
allow the development of complete, "real" Mac programs, all in Ada.
To be completed
You can help Wikibooks by adding the build information for other compilers. Click on the edit
link over this title.
First you need to extract the sources. Use your favorite zip tool to achieve that. On extraction
a directory with the same name as the filename is created. Beware: WinZip might also create
a directory equaling the filename so Windows users need to be careful using the right option
otherwise they end up with wikibook-ada-1_2_0.src\wikibook-ada-1_2_0.
Once you extraced the files you will find all sources in wikibook-ada-1_2_0/Source. You could
compile them right there. For your convinience we also provide ready made project files for
the following IDEs (If you find a directory for an IDEs not named it might be in the making and not actualy
work).
GNAT
You will find multi-target GNAT Project files and a multi-make Makefile file in
wikibook-ada-2_0_0/GNAT. For i686 Linux and Windows you can compile any demo using:
gps -P project_file
For other target platform it is a bit more difficult since you need to tell the project files which
target you want to create. The following options can be used:
you can define if you like a debug or release version so you can compare how the options
affect size and speed.
os ("Linux", "OS2", "Windows_NT", "VMS")
choose your operating system. Since there is no Ada 2005 available for OS/2 don't expect
all examples to compile.
target ("i686", "x86_64", "AXP")
choose your CPU - "i686" is any form of 32bit Intel or AMD CPU, "x86_64" is an 64 bit
Intel or AMD CPU and if you have an "AXP" then you know it.
Remember to type all options as they are shown. To compile a debug version on x86_64
Linux you type:
As said in the beginning there is also a makefile available that will automatically dertermine
the target used. So if you have a GNU make you can save yourself a lot of typing by using:
make project
or even use
make all
Each compile is stored inside it's own directory which is created in the form of
wikibook-ada-2_0_0/GNAT/OS-Target-Style. Emtpy directorys are provided inside the
archive.
Rational APEX
APEX uses the subsystem and view directory structure, so you will have to create those first
and copy the source files into the view. After creating a view using the architecture model of
your choice, use the menu option "Compile -> Maintenance -> Import Text Files". In the
Import Text Files dialog, add "wikibook-ada-2_0_0/Source/*.ad?" to select the Ada source
files from the directory you orignally extracted to. Apex uses the file extensions .1.ada for
specs and .2.ada for bodies -- don't worry, the import text files command will change these
automatically.
To link an example, select its main subprogram in the directory viewer and click the link
button in the toolbar, or "Compile -> Link" from the menu. Double-click the executable to run
it. You can use the shift-key modifier to bypass the link or run dialog.
ObjectAda
ObjectAda commandline
The following describes using the ObjectAda tools for Windows in a console window.
Before you can use the ObjectAda tools from the command line, make sure the PATH
enviroment variable lists the directory containing the ObjectAda tools. Something like
set path=%path%;P:\Programs\Aonix\ObjectAda\bin
A minimal ObjectAda project can have just one source file. like the Hello World program
provided in
To build an executable from this source file, follow these steps (assuming the current
directory is a fresh one and contains the above mentioned source file):
This makes your sources known to the ObjectAda tools. Have a look at the file UNIT.MAP
created by adareg in the current directory if you like seeing what is happening under the
hood.
Notice that you specify the name of the main unit as argument to adabuild, not the name of
the source file. In this case, it is Hello_World_1 as in
procedure Hello_World_1 is
More information about the tools can be found in the user guide Using the command line
interface, installed with the ObjectAda tools.
See also
GNAT Online Documentation
GNAT User's Guide (http://gcc.gnu.org/onlinedocs/gcc-4.0.1/gnat_ugn_unw/)
Wikibook
Ada Programming
Control
Conditionals
Conditional clauses are blocks of code that will only execute if a particular expression (the
condition) is true.
if-else
The if-else statement is the simplest of the conditional statements. They are also called
branches, as when the program arrives at an "if" statement during its execution, control will
"branch" off into one of two or more "directions". An if-else statement is generally in the
following form:
if condition then
statement;
else
other statement;
end if ;
If the original condition is met, then all the code within the first statement is executed. The
optional else section specifies an alternative statement that will be executed if the condition
is false. Exact syntax will vary between programming languages, but the majority of
programming languages (especially procedural and structured languages) will have some
form of if-else conditional statement built-in. The if-else statement can usually be extended to
the following form:
if condition then
statement;
elsif condition then
other statement;
elsif condition then
other statement;
...
else condition then
another statement;
end if;
Only one statement in the entire block will be executed. This statement will be the first one
with a condition which evaluates to be true. The concept of an if-else-if structure is easier to
understand with the aid of an example:
with Ada.Text_IO;
use Ada.Text_IO;
...
type Degrees is new Float range -273.15 .. Float'Last;
...
Temperature : Degrees;
...
if Temperature >= 40.0 then
Put_Line ("It's extremely hot");
elsif Temperature >= 30.0 then
Put_Line ("It's hot");
elsif Temperature >= 20.0 then
Put_Line ("It's warm");
elsif Temperature >= 10.0 then
Put_Line ("It's cool");
elsif Temperature >= 0.0 then
Put_Line ("It's cold");
else
Put_Line ("It's freezing");
end if;
Optimizing hints
When this program executes, the computer will check all conditions in order until one of
them matches its concept of truth. As soon as this occurs, the program will execute the
statement immediately following the condition and continue on, without checking any other
condition for truth. For this reason, when you are trying to optimize a program, it is a good
idea to sort your if-else conditions in descending probability. This will ensure that in the most
common scenarios, the computer has to do less work, as it will most likely only have to check
one or two "branches" before it finds the statement which it should execute. However, when
writing programs for the first time, try not to think about this too much lest you find yourself
undertaking premature optimization.
Having said all that, you should be aware that an optimizing compiler might rearrange your
if statement at will when the statement in question is free from side effects. Among other
techniques optimizing compilers might even apply jump tables and binary searches.
In Ada, conditional statements with more than one conditional do not use short-circuit
evaluation by default. In order to mimic C/C++'s short-circuit evaluation, use and then or or
else between the conditions.
case
Often it is necessary to compare one specific variable against several constant expressions.
For this kind of conditional expression the case statement exists. The above example is such
a case and could also be written like this:
case X is
when 1 =>
Walk_The_Dog;
when 5 =>
Launch_Nuke;
when 8 | 10 =>
Sell_All_Stock;
end case;
unconditionals
Unconditionals let you change the flow of your program without a condition. You should be
careful when using unconditionals. Often they make programs difficult to understand. Read
Isn't goto evil? for more information.
return
End a function and return to the calling procedure or function.
For procedures:
return;
For functions:
return Value;
goto
transfer control to the statement after the label.
goto Label;
Dont_Do_Something;
<<Label>>
...
One often hears that goto is evil and one should avoid using goto. But it is often overlooked
that any return, which is not the last statement inside a procedure or function, is also an
unconditional statement - a goto in disguise.
Therefore if you have functions and procedures with more than one return statement you
can just as well use goto. When it comes down to readability the following two samples are
almost the same:
procedure Use_Return is
begin
Do_Something;
if Test then
return;
end if;
Do_Something_Else;
return;
end Use_Return;
procedure Use_Goto is
begin
Do_Something;
if Test then
goto Exit_Use_Goto;
end if;
Do_Something_Else;
<<Exit_Use_Goto>>
return;
end Use_Goto;
Because the use of a goto needs the declaration of a label, the goto is in fact as twice as
readable than the use of return. So if readability is your concern and not a strict "don't use
goto" programming rule then you should rather use goto than multiple returns. Best, of
course, is the structured approach where neither goto nor multiple returns are needed:
procedure Use_If is
begin
Do_Something;
end if;
return;
end Use_If;
loops
Loops allow you to have a set of statements repeated over and over again.
endless loop
The endless loop is a loop which never ends and the statements inside are repeated forever.
Never is meant as a relative term here — if the computer is switched off then even endless
loops will end very abruptly.
Endless_Loop :
loop
Do_Something;
The loop name is an optional feature of Ada. Naming loops is nice for readability but not
strictly needed.
While_Loop :
while X <= 5 loop
X := Calculate_Something;
end loop While_Loop;
Until_Loop :
loop
X := Calculate_Something;
Exit_Loop :
loop
X := Calculate_Something;
exit Exit_Loop when X > 5;
Do_Something (X);
end loop Exit_Loop;
In Ada the exit condition can be combined with any other loop statement as well. You can
also have more then one exit statement. You can also exit a named outer loop if you have
several loops inside each other.
for loop
Quite often one needs a loop where a specific variable is counted from a given start value up
or down to a specific end value. You could use the while loop here - but since this is a very
common loop there is an easier syntax available.
For_Loop :
for I in Integer range 1 .. 10 loop
Do_Something (I)
You don't have to declare both type and range as seen in the example. If you leave out the
type then the compiler will determine the type by context and leave out the range then the
loop will iterate over every valid value for the type given.
As always with Ada: when "determine by context" gives two or more possible options then an
error will be displayed and then you have to name the type to be used. Ada will only do
"guess-works" when it is safe to do so.
Another very common situation is the need for a loop which iterates over every element of an
array. The following sample code shows you how to achieve this:
Array_Loop :
for I in X'Range loop
X (I) := Get_Next_Element;
With X being an array. Note: This syntax is mostly used on arrays - hence the name - but will
also work with other types when a full iteration is needed.
Working Demo
The following Demo shows how to iterate over every element of an integer type.
with Ada.Text_IO;
procedure Range_1 is
type Range_Type is range -5 .. 10;
package T_IO renames Ada.Text_IO;
package I_IO is new Ada.Text_IO.Integer_IO (Range_Type);
begin
for A in Range_Type loop
I_IO.Put (Item => A,
Width => 3,
Base => 10);
if A < Range_Type'Last then
T_IO.Put (",");
else
T_IO.New_Line;
end if;
end loop;
end Range_1;
See also
Wikibook
Ada Programming
(http://www.adaic.com/standards/95aarm/html/AA-5-7.html) )
5.8 Goto Statements (http://www.adaic.com/standards/95lrm/html/RM-5-8.html) (Annotated
(http://www.adaic.com/standards/95aarm/html/AA-5-8.html) )
6.5 Return Statements (http://www.adaic.com/standards/95lrm/html/RM-6-5.html)
(Annotated (http://www.adaic.com/standards/95aarm/html/AA-6-5.html) )
Subtypes
This Page describes how to declare new types, how they are related to each other and how to
convert them. If you are looking for actual types available in Ada see Ada
Programming/Types.
Types in Ada
The Ada typing system is hierarchical like in some other languages. However Ada uses its
own vernacular when talking about type hierarchies.
What C++ calls sub- and supertypes, Ada calls child and parent (or ancestor) types. The
ultimate ancestor of some type is called the root type. Different types in a hierarchy are
incompatible, but may be converted into one another. Types in disjunct hierarchies cannot be
converted into one another.
There is however another mechanism called subtyping. A subtype is not a new type but it
may add constraints to the type. Objects of different subtypes of a common type are
compatible; assignments between them force certain language defined checks to be
performed.
type T is ...;
subtype S is T [constraint];
The constraint is optional. To be exact: The type declaration declares a type and its first
subtype T. The type itself is anonymous and can be named with the Base attribute: T'Base. S
is a subtype of T.
Subtype categories
Ada supports various categories of subtypes which have different abilities. Here is an
overview in alphabetical order.
Anonymous subtype
A subtype which does not have a name assigned to it. Such a subtype is created with a
variable declaration:
Base type
Within this document we almost always speak of subtypes. But where there is a subtype
there must also be a base type from which it is derived. In Ada all base types are anonymous
and only subtypes may be named.
But it is still possible to use base type by the use of the 'Base attribute.
Constrained subtype
A subtype of an indefinite subtype that does add a constraint. The following example defines
a 10 character string sub-type.
If all constraints of an original indefinite subtype are defined then the new sub-type is a
definite subtype.
Definite subtype
A definite subtype is a subtype whose size is known at compile-time. All subtypes which are
not indefinite subtypes are, by definition, definite subtypes.
Indefinite subtype
An indefinite subtype is a subtype whose size is not known at compile-time but is
dynamically calculated at run-time. An indefinite subtype does not by itself provide enough
information to create an object; an additional constraint or explicit initialization expression is
necessary in order to calculate the actual size and therefore create the object.
X is an object of the indefinite (sub)type String. Its constraint is derived implicitly from its
initial value. X may change its value, but not its bounds.
It should be noted that it is not necessary to initialize the object from a literal. You can also
use a function. For example:
Named subtype
A subtype which has a name assigned to it. These subtypes are created with the keyword
type (remember that types are always anonymous, the name in a type declaration is the
name of the first subtype) or subtype. For example:
Count_to_Ten is the first subtype of a suitable integer base type. If you however would like to
use this as an index constraint on String, the following declaration is illegal:
This is because String has Positive as index, which is a subtype of Integer (these declarations
are taken from package Standard):
Unconstrained subtype
A subtype of an indefinite subtype that does not add a constraint only introduces a new name
for the original subtype.
Type declaration
Declaring new types
New types are declared with the keyword type.
Both declarations create a new type hierarchy and name the first subtype.
Declaring subtypes
Subtypes are declared with the keyword subtype.
Unlike C/C++ Ada never converts types automatically. Even if converting them would be
safe. The following example won't work:
X1 : Integer_1 := 5;
X2 : Integer_2 := X1;
This is different for subtypes. All the subtypes sharing the same base type don't actually need
to be converted when interchanged. The above example with subtypes will work fine (base
type is Integer):
X1 : Integer_1 := 5;
X2 : Integer_2 := X1;
Converting subtypes
Sometimes however it may be necessary to explicitly convert subtypes.
The conversion result My_String (X1) now has the same contents as X1, but different bounds.
Note that the equality operation does not compare the bounds, only the contents. Thus:
Converting data
Data does not always come in the format you need them and you face the task of converting
them. Ada as a true multi-purpose language with a special emphasis on "mission critical",
"system programming" and "safety" has several converting techniques.
This is a short pragmatic overview of data conversions. The examples are all numeric, but
there are conversions for most kinds of data types. As the most difficult part is choosing the
right type of conversion, I have sorted them so that you should try the first one first; the last
technique is "the last resort if all other fails". Also added are few related techniques which
you might choose instead of actually converting the data.
Since the most important aspect is not the result of a successful conversion, but how the
system will react to an invalid conversion, all examples also demonstrate faulty conversions.
Evaluate as
This is not really a conversion. It only tells the compiler how a given expression should be
evaluated, most important in case of overloading resolution problems.
Type_Name'(Expression)
This means that the expression has to be evaluated as having the given type.
Imagine you have two enumeration types directly visible with homographic literals, like so:
then
Enum_1'(A)
tells the compiler that you mean that A which is of type Enum_1. Normally you would not
need this kind of qualified expression; overload resolution does this for you. But there are
cases where this syntax is required.
As seen in the following example, this syntax if often used when creating new objects. If you
try to compile the example, it will fail with a compilation error since the compiler will
determine that 256 is not in range of Byte.
with Ada.Text_IO;
procedure Convert_Evaluate_As is
type Byte is mod 2**8;
type Byte_Ptr is access Byte;
Rename view
This technique too, is not really a conversion but just creates a different view to your data. It
is used in object oriented programming and only available to classes - called tagged types in
Ada.
Child_Instance : Child_Type;
Parent_View : Parent_Type'Class renames Parent_Type'Class (Child_Instance);
Renaming the view of a tagged type creates no code and no data is copied, it only gives a
new name to something which already exists. Performance is optimal since the rename is
completely done at compile time.
Checked conversion
The checked conversion is in syntax rather similar to the "evaluate as". It does not use the '
(called tick) and thus looks much like a function call.
Type_Name (Expression)
As the chapter heading suggests, the conversion is checked at runtime and if it is invalid, a
CONSTRAINT_ERROR exception will be raised. The data also need to be convertible.
The following example shows the conversion of two integer types. When you compile the
example with GNAT, you will get several warnings. In our case, the compiler determines that
the runtime check will always fail and warns us about that.
Remember: Since the optimizer checks for the necessity of runtime checks and removes
them if they are not needed, you should normally not worry about the performance
implications of checked conversions.
with Ada.Text_IO;
procedure Convert_Checked is
type Short is range -128 .. +127;
type Byte is mod 256;
In object-oriented programming
Within object-oriented programming you have to distinguish between specific types and
class-wide types.
With specific types, only conversions to ancestors are possible and, of course, are checked.
There are no conversions to derived, i.e. child types (where would you get the further components
from?); extension aggregates have to be used instead.
Child_Instance : Child_Type;
Parent_Instance : Parent_Type := Parent_Type (Child_Instance);
With class wide types, conversions to ancestor and child types are possible and are checked
as well. These conversions are only view conversions.
Before consider a view conversion on a class-wide type you should check if a view rename is
Address conversion
Ada's access type is not just a memory location (a thin pointer). Depending on
implementation and the access type used, the access might keep additional information (a fat
pointer). For example Gnat keeps two memory addresses for each access to an indefinite
object - one for the data and one for the constraint informations (Size, First, Last).
If you want to convert an access to a simple memory location you can use the package
System.Address_To_Access_Conversions. Note however that an address and a fat pointer
cannot be converted reversibly into one another.
The address of an array object is the address of its first component. Thus the bounds get lost
in such a conversion.
A'Address = A(A'First)'Address
Unchecked conversion
One of the great criticisms of Pascal was "there is no escape". The reason was that
sometimes you have to convert the incompatible. For this purpose, Ada has the generic
function Unchecked_Conversion:
generic
type Source (<>) is limited private;
type Target (<>) is limited private;
function Ada.Unchecked_Conversion (S : Source) return Target;
Unchecked_Conversion will bit-copy the data and there are absolutely no checks. It is your
chore to make sure that the requirements on unchecked conversion as stated in RM 13.9
(http://www.adaic.com/standards/95lrm/html/RM-13-9.html) (Annotated
(http://www.adaic.com/standards/95aarm/html/AA-13-9.html) ) are fulfilled; if not, the result is
implementation dependent and may even lead to abnormal data.
A function call to an (instance) will copy the source to the destination. The compiler may also
do a conversion in place (every instance has the convention Intrinsic).
In the example below, you can see how this is done. When run, the example it will output "A
= -1, B = 255". No error will be reported, but is this the result you expect?
with Ada.Text_IO;
with Ada.Unchecked_Conversion;
procedure Convert_Unchecked is
begin
B := Convert (A);
T_IO.Put ("A = ");
I_IO.Put (Item => A,
Width => 5,
Base => 10);
T_IO.Put (", B = ");
M_IO.Put (Item => B,
Width => 5,
Base => 10);
end Convert_Unchecked;
Overlays
If the copying of the result of Unchecked_Conversion is too much waste in terms of
performance, then you can try overlays, i.e. address mappings. By using overlays, both
objects share the same memory location. If you assign a value to one, the other changes as
well. The syntax is:
While overlays might look more elegant than Unchecked_Conversion, you should be aware
that they are even more dangerous and have even greater potential for doing something very
wrong. For example if Source'Size < Target'Size and you assign a value to Target, you
might inadvertently write into memory allocated to a different object.
You have to take care also of implicit initialisations of objects of the target type, since they
would overwrite the actual value of the source object. The Import pragma with convention
Ada can be used to prevent this, since it avoids the implicit initialisation, RM B.1
(http://www.adaic.com/standards/95lrm/html/RM-B-1.html) (Annotated
(http://www.adaic.com/standards/95aarm/html/AA-B-1.html) ).
The example below does the same as the example from "Unchecked Conversion".
with Ada.Text_IO;
procedure Convert_Address_Mapping is
type Short is range -128 .. +127;
type Byte is mod 256;
See also
Wikibook
Ada Programming
Types
This page describes the various types available in Ada. If you want to know how to declare
new types, how they relate to each other and how to convert them see Ada
Programming/Subtypes
Types in Ada
If you look at Ada's list of keywords, you will notice that there is no int or INTEGER like for
example with C/C++.
Ada has only a very small set of predefined types, rather new types are defined according to
domain specific needs. Thus Ada is more like PL/I where data types are described in terms of
what is needed and not chosen from a predefined set.
Unlike PL/I, the description of a data type is not done "low level" in terms of bits but "high
level" using human readable values. If a low level specification is needed as well, optional
representation clauses can be used.
Example:
1. The type is defined as a range of whole numbers with lower bound 1 and upper bound
31. No values outside this range can be assigned to objects of this type. The type is also
given the name "Day_Of_Month".
2. Representation clause: use 8 bit of storage. If Size is not specified then the compiler will
choose a suitable size.
You should not specify representation clauses if there is no pressing need (like e.g.
interfacing to external devices). The more freedom the compiler has, the better code can be
generated.
Strong typing
Objects of different types in Ada are incompatible, i.e. may not be assigned or mixed, even if
they have matching value ranges.
This prevents inadvertent mixing of apples and oranges. If you really need to combine
objects of different types, you have to use type conversions.
Should you need many type conversions, i.e. if Ada's strong typing gets into your way, this
generally is an indication of bad program design. Consider using subtype instead.
Type classification
In the predefined package Standard, the most basic types are defined. As stated before, you
normally do not use those types, rather define your own ones. This is the set of type classes
you have at your convenience. Do follow the links to get more information.
Predefined types
Are you missing specific types?
Integer
This type covers at least the range -2**15+1 .. +2**15-1 (RM 3.5.4 (21)
(http://www.adaic.com/standards/95lrm/html/RM-3-5-4.html) (Annotated
(http://www.adaic.com/standards/95aarm/html/AA-3-5-4.html) )).
Float
There is only a very weak implementation requirement on this type (RM 3.5.7 (14)
(http://www.adaic.com/standards/95lrm/html/RM-3-5-7.html) (Annotated
(http://www.adaic.com/standards/95aarm/html/AA-3-5-7.html) )).
Character
In Ada, characters are a special form of Enumerations. There are two predefined kinds of
character types: 8-bit characters (called Character) and 16-bit characters (called
Wide_Character). In Ada 2005, a 32-bit character type called Wide_Wide_Character will
be added. You can also specify your own character types.
String
In Ada, strings are a special form of Arrays, namely arrays of characters. Since there are
two kinds of characters, there are also two kinds of strings: String is an array of
Character, Wide_String is an array of Wide_Character. For ease of treatment of strings,
there are special packages in three variants, one for handling fixed length strings:
Ada.Strings.Fixed; one for strings with varying lengths below a certain upper bound:
Ada.Strings.Bounded; and one for strings of unbounded lengths: Ada.Strings.Unbounded
(for the wide kinds, prefix each name with Wide_ or Wide_Wide_).
Boolean
A Boolean in Ada is an Enumeration of False and True.
See also
Wikibook
Ada Programming
Ada Programming/Subtypes
Programming:Types, general concepts about types in programming
Integer types
A range is an integer value which ranges from a First to a last Last. It is defined as
When a value is assigned to a range it is checked for vality and an exceptions is raised when
the value is not within First to Last.
Working demo
The following Demo defines a new range from -5 to 10 and then prints the whole range out.
with Ada.Text_IO;
procedure Range_1 is
type Range_Type is range -5 .. 10;
begin
for A in Range_Type loop
I_IO.Put (
Item => A,
Width => 3,
Base => 10);
See also
Wikibook
Ada Programming
Ada Programming/Types
Ada Programming/Keywords/range
mod Modulus
Where Last is Modulus - 1; The mod type has a wrap around functionality so that
and
But beware: the Modulus of Half_Byte is still 256! Arithmetic with such a type is interesting
to say the least.
See also
Wikibook
Ada Programming
Ada Programming/Types
Ada Programming/Keywords/mod
Enumerations
An enumeration type is defined as a list of possible values:
Like for numeric types, where e.g. 1 is an integer literal, Red, Green and Blue are called the
literals of this type. There are no other values assignable to objects of this type.
Primary_Color'Pos (Red) = 0
Primary_Color'Val (0) = Red
There are two other important attributes: Image and Value (don't confuse Val with Value).
Image returns the string representation of the value (in capital letters), Value is the inverse:
These attributes are important for simple IO (there are more elaborate IO facilities in
Ada.Text_IO for enumeration types). Note that, since Ada is case-insensitive, the string given
to 'Value can be in any case.
Enumeration literals
Literals are overloadable, i.e. you can have another type with the same literals.
Overload resolution within the context of use of a literal normally resolves which Red is
meant. Only if you have an unresolvable overloading conflict, you can qualify with special
syntax which Red is meant:
Primary_Color'(Red)
Like many other declarative items, enumeration literals can be renamed. In fact, such a
literal is a actually function, so it has to be renamed as such:
Note that redeclaration as a function does not affect the staticness of the literal.
This literal 'A' has nothing in common with the literal 'A' of the predefined type Character
(or Wide_Character).
Every type that has at least one character literal is a character type. For every character
type, string literals and the concatenation operator "&" are also implicitly defined.
Enumeration subtypes
You can use range to subtype an enumeration type:
See also
Wikibook
Ada Programming
Ada Programming/Types
Ada Programming/Libraries/Standard
Description
To define a floating point type you only have to say how many digits are needed:
digits Num_Digits
If you like you can declare the minimum range needed as well:
This facility is a great benefit of Ada over (most) other programming languages. In other
languages, you just choose between "float" and "long float", and what most people do is:
In Ada, you specify the accuracy you need, and the compiler will choose an appropriate
floating point type with at least the accuracy you asked for. This way, your requirement is
guaranteed. Moreover, if the computer has more than two floating point types available, the
compiler can make use of all of them.
See also
Wikibook
Ada Programming
Ada Programming/Types
Ada Programming/Types/range
Ada Programming/Types/delta
Ada Programming/Keywords/digits
Description
A fixed point type defines a set of values that are evenly spaced according to the fixed point
type's "delta" value. In contrast, floating point values are all spaced according to powers of
two. When you want to represent a real number with a floating point type, the number
actually stored will vary. When you represent a number as a fixed point type, you can be sure
that the number stored will be accurate within the bounds specified by the delta.
For example, if you define a fixed point type with a delta of 0.1, you will be able to accurately
store the values 0.1, 1.0, 2.2, 5.7, etc. You will not be able to accurately store the value 0.01.
Instead, the value will be rounded down to 0.0.
If the compiler accepts your fixed point type definition, it guarantees that values represented
by that type will have at least the degree of accuracy specified (or greater). If the compiler
can not support the type definition (e.g. due to limited hardware) then a compile-time error
will result.
The delta can be any real value -- for example you may define a circle with one arcsecond
resolution with:
There is one rather strange rule about fixed and floating point variables: Because of the way
they are internally represented the range might only go up to 'Last - Delta. This is a bit
like a circle -- there 0° and 360° is also the same.
Delta needs to be a positive or negative power of 10 - otherwise the type will not be a
decimal fixed point.
delta 10 ** +2 digits 12
delta 10 ** -2 digits 12
If you like you can also define the minimum range needed:
See also
Wikibook
Ada Programming
Ada Programming/Types
Ada Programming/Types/range
Ada Programming/Types/digits
Ada Programming/Keywords/delta
Arrays
An array is a collection of elements which can be accessed by an index. In Ada any definite
type is allowed as element and any discrete type, i.e. Range, Modular or Enumeration, can be
used as an index.
Declaring arrays
Ada's arrays are quite powerful and so there are quite a few syntax variations, which are
presented below.
Basic syntax
The basic form of an Ada array is:
where Index_Range is a range of values within a discrete index type, and Element_Type is a
definite subtype. The array consists of one element of "Element_Type" for each possible
value in the given range. If you for example want to count how often a specific letter appears
inside a text, you could use:
Do not use Integer as the element type, since negative occurrences do not seem sensible.
Since this may involve a lot of typing and you may also run out of useful names for new
subtypes, the array declaration allows for a shortcut:
Since First and Last are expressions of Index_Type, a simpler form of the above is:
Note that if First and Last are numeric literals, this implies the index type Integer.
If in the example above the character counter should only count upper case characters and
discard all other characters, you can use the following array type:
arrays:
When you declare objects of such a type, the bounds must of course be given and the object
is constrained to them.
You define objects of such an unconstrained type in several ways (the extrapolation to other
arrays than String should be obvious):
(These declaration additionally define anonymous subtypes of String.) In the first example,
the range of indices is explicitly given. In the second example, the range is implicitly defined
from the initial expression, which here could be via a function reading data from some file.
Both objects are constrained to their ranges, i.e. they cannot grow nor shrink.
Since we have packed the array, the compiler will use as little storage as possible. And in
most cases this will mean that 8 boolean values will fit into one byte.
So Ada knows about arrays where more then one element shares one address. So what if you
need to address each single element. Just not using pragma Pack is not enough. If the CPU
has very fast bit access, the compiler might pack the array without being told. You need to
tell the compiler that you need to address each element via an access.
Using arrays
When accessing to elements the index is specified between parenthesis. It is also possible to
access slices in this way:
In both cases, if the resulting array does not fit in the destination array, Constraint_Error is
raised.
If you try to access an existing element by indexing outside the array bounds,
Constraint_Error is raised (unless checks are suppressed).
See also
Wikibook
Ada Programming
Ada Programming/Types
Programming:Data_Structures
Programming:Data_Structures:Arrays
Records
A record is a composite type that groups one or more fields. A field can be of any type, even
a record.
Basic record
type Basic_Record is
record
A : Integer;
end record;
Null record
The null record is when a type without data is needed. There are two ways to declare a null
record:
type Null_Record is
record
null;
end record;
For the compiler they are the same. However, programmers often use the first variant if the
type is not finished yet to show that they are planning to expand the type later, or they
usually use the second if the (tagged) record is a base class in object oriented programming.
Discriminated record
Variant record
The variant record is a special type of discriminated record where the presence of some
components depend on the value of the discriminant.
case Option is
when Red =>
-- components for red
when Yellow =>
-- components for yellow
when Green =>
-- components for green
end case;
end record;
Union
This language feature will be made available in the forthcoming Ada 2005 standard.
case Option is
when Red =>
-- components for red
when Yellow =>
-- components for yellow
when Green =>
-- components for green
end case;
end record;
The difference to a variant record is such that Option is not actually stored inside the record
and never checked for correctness - it's just a dummy.
This kind of records are usually used for interfacing with C but can be used for other
purposes as well (then without pragma Convention (C, Union);).
Tagged record
The tagged record is one part of what in other languages is called a class. It is the basic
foundation of object orientated programming in Ada. The other two parts a class in Ada
needs is a package and primitive operations.
type Basic_Record is
record
A : aliased Integer;
end record ;
See also
Wikibook
Ada Programming
Ada Programming/Types
Ada Programming/Keywords/record
Ada Programming/Keywords/null
Ada Programming/Keywords/abstract
Ada Programming/Keywords/case
Ada Programming/Keywords/when
Ada Programming/Pragmas/Unchecked_Union
Ada 2005
Ada Issues
Access types
Remember that Ada support user defined storage pools. You can defined the storage pool
used with
Access all
Handles an access to an object which was created on any storage pool, on the stack or at
library level (static).
Access constant
Handles an access either to a constant or variable object which was created on any storage
pool, on the stack or at library level (static), but with a restriction to read-only usage of the
referenced object, whether it be intrinsically a constant or a variable.
Anonymous access
An anonymous access is used as a parameter to a function, procedure or a discriminated
type. Here some examples:
type Day_Data (
Store_For_Day : access Day_Of_Month)
is record
-- components
end record;
Before you use an anonymous access you should consider if the "out" or "in out" modifier is
not more appropriate - see access performance to see why.
This language feature will be made available in the forthcoming Ada 2005 standard.
The type must then always point to an object, so initializations are compulsory.
Access to subprogram
An access to subprogram allows us to call a subprogram without knowing its name nor its
declaration location. One of the uses of this kind of access is the well known callbacks.
type Callback_Procedure
is access procedure (
Id : Integer;
Text : String);
type Callback_Function
is access function (
The_Alarm : in Alarm)
return
Natural;
For getting an access to a subprogram the attribute Access is applied to a subprogram name
with the proper prototype.
procedure Process_Event (
Id : Integer;
Text : String);
procedure Test (
Call_Back : access procedure (
Id : Integer;
Text : String));
Therefore in order to delete an object from the heap you will need the generic unit
Ada.Unchecked_Deallocation.
with Ada.Unchecked_Deallocation;
procedure Deallocation_Sample is
type Vector is array (Integer range <>) of Float;
type Vector_Ref is access Vector;
procedure Free_Vector is new Ada.Unchecked_Deallocation
(Object => Vector, Name => Vector_Ref);
VA : Vector_Ref;
begin
VA := new Vector (1 .. 10);
VA.all := (others => 0.0);
-- ... Do whatever you need to do with the vector
Free_Vector (VA); -- The memory is deallocated and VA is now null
end Deallocation_Sample;
Since Ada does allow for user defined storage pools you could also try a garbage collector
library.
Implicit dereferencing
If you declare a record type, and an access type for it, thus:
Ada.Text_IO.Put(Father.First_Name);
and be careful:
Obj1 := Obj2; -- Obj1 now refers to the same person as Obj2 (shallow copy)
Obj1.all := Obj2.all; -- Obj1 still refers to a different object from Obj2,
-- but it has the same content (deep copy).
Access FAQ
A few "Frequently Asked Question" and "Frequently Encountered Problems" (mostly from
former C users) regarding Ada's access types.
But this is wrong because access all is more error prone! One example: When
Unchecked_Deallocation is used on an access all it is not checked that the object actually
belongs to the proper storage pool - or if the object belongs to any storage pool at all. The
following example, invalidly and perhaps disastrously, will try to deallocate a stack object:
declare
type Day_Of_Month is range 1 .. 31;
type Day_Of_Month_Access is access all Day_Of_Month;
procedure Free
is new Ada.Unchecked_Deallocation (
Object => Day_Of_Month
Name => Day_Of_Month_Access);
A : aliased Day_Of_Month;
Ptr : Day_Of_Month_Access := A'Access;
begin
Free(Ptr);
end;
With a simple access you know at least that you won't try to deallocate a stack object.
Depending on the implementation an access might also render better performance then
access all.
Access performance
Ada performs run-time checks on access types, so not all access types render the same
performance. In other places of the Ada Programming we suggest that you should not care
about runtime checks since the optimizer will remove them when they are not needed.
However former C programmers often use anonymous access - which have worse
performance - instead of of using "out" or "in out" which has best performance. Here a
C compatible pointer
The correct way to create a C compatible access is to use pragma Convention:
pragma Convention (
Convention => C,
Entity => Day_Of_Month);
type Day_Of_Month_Access is access Day_Of_Month;
pragma Convention (
Convention => C,
Entity => Day_Of_Month_Access);
pragma Convention should be used on any type you want to use in C. The compiler should
warn you if the type cannot be made C compatible.
You may also consider the following - shorter - alternative when declaring Day_Of_Month:
Before you use access types in C you should consider using the normal "in", "out" and "in
out" modifiers. pragma Export and pragma Import knows how parameters are usually
passed in C and will use a pointer to pass a parameter automatically where a "normal" C
programmer would have used them as well.
Of course the definition of a "normal" C programmer is not left to change, the RM contains
precise rules on when to use a pointer for "in", "out", and "in out" - see "B.3 Interfacing with
C (http://www.adaic.com/standards/95lrm/html/RM-B-3.html) (Annotated
(http://www.adaic.com/standards/95aarm/html/AA-B-3.html) )".
Where is void*?
While actually been a problem for "interfacing with C", here is a possible solution:
procedure Test
is
subtype Pvoid is System.Address;
-- the declare in C, like this.
-- int C_fun(int *)
Pointer : Pvoid ;
See also
Wikibook
Ada Programming
Ada Programming/Types
Ada 2005
(Annotated (http://www.adaic.com/standards/rm-amend/html/AA-3-7.html) )
3.10 Access Types (http://www.adaic.com/standards/rm-amend/html/RM-3-10.html)
(Annotated (http://www.adaic.com/standards/rm-amend/html/AA-3-10.html) )
6.1 Subprogram Declarations
(http://www.adaic.com/standards/rm-amend/html/RM-6-1.html) (Annotated
(http://www.adaic.com/standards/rm-amend/html/AA-6-1.html) )
B.3 Interfacing with C (http://www.adaic.com/standards/rm-amend/html/RM-B-3.html)
(Annotated (http://www.adaic.com/standards/rm-amend/html/AA-B-3.html) )
Strings
Ada supports three different types of strings. Each string type is designed to solve a different
problem.
In addition, every string type is implemented for each available Characters type (Character,
Wide_Character, Wide_Wide_Character) giving a complement of nine combinations.
However once the length has been calculated and the strings have been created the length
stays constant. Try the following program which shows a typical mistake:
with Ada.Text_IO;
with Ada.Command_Line;
procedure Show_Commandline_1 is
begin
T_IO.Put ("Argument 1 = ");
T_IO.Put_Line (X);
X := CL.Argument (2);
The program will only work when the 1st and 2nd parameter have the same length. This is
even true when the 2nd parameter is shorter. There is neither an automatic padding of
Having said that, the package Ada.Strings.Fixed contains a set of procedures and functions
for Fixed-Length String Handling which allows padding of shorter strings and truncation of
longer strings.
with Ada.Text_IO;
with Ada.Command_Line;
with Ada.Strings.Fixed;
procedure Show_Commandline_2 is
Like Fixed-Length Strings the maximum length does not need to be known at compile time -
it can also be calculated at runtime - as the example below shows:
with Ada.Text_IO;
with Ada.Command_Line;
with Ada.Strings.Bounded;
procedure Show_Commandline_3 is
function Max_Lenght (
Value_1 : Integer;
Value_2 : Integer)
return
Integer;
function Max_Lenght (
Value_1 : Integer;
Value_2 : Integer)
return
Integer
is
Retval : Integer;
begin
if Value_1 > Value_2 then
Retval := Value_1;
else
Retval := Value_2;
end if;
return Retval;
end Max_Lenght;
pragma Inline (Max_Lenght);
package SB
is new Ada.Strings.Bounded.Generic_Bounded_Length (
Max => Max_Lenght (
Value_1 => CL.Argument (1)'Length,
Value_2 => CL.Argument (2)'Length));
X : SB.Bounded_String
:= SB.To_Bounded_String (CL.Argument (1));
begin
T_IO.Put ("Argument 1 = ");
T_IO.Put_Line (SB.To_String (X));
X := SB.To_Bounded_String (CL.Argument (2));
You should know that Bounded-Length Strings have some distinct disadvantages. Most
noticeable is that each Bounded-Length String is a different type which makes converting
them rather cumbersome. Also a Bounded-Length String type always allocates memory for
the maximum permitted string length for the type. The memory allocation for a
Bounded-Length String is equal to the maximum number of string "characters" plus an
implementation dependent number containing the string length (each character can require
allocation of more than one byte per character, depending on the underlying character type
of the string, and the length number is 4 bytes long for the Windows GNAT Ada compiler
v3.15p, for example).
As the name suggest the Unbounded-Length String can hold strings of almost any length -
limited only to the value of Integer'Last or your available heap memory.
with Ada.Text_IO;
with Ada.Command_Line;
with Ada.Strings.Unbounded;
procedure Show_Commandline_4 is
As you see the Unbounded-Length String example is also the shortest (discarding the first
example - which is buggy) - this makes using Unbounded-Length Strings very appealing.
See also
Wikibook
Ada Programming
Subprograms
In Ada the subprograms are classified into two categories: procedures and functions.
Procedures are called as sentences and do not return any value, whereas the functions are
called as components of expressions and return a value, usually assigned to an object
(variable or constant).
Procedures
A procedure call in Ada constitutes a sentence by itself.
The parameters that can be passed to a procedure can be of three different modes:
in: the formal parameter is a constant and allows only reading the value of the associated
real parameter.
in out: the formal parameter is a variable and the real parameter value can be read or
written.
out: the formal parameter is a variable and the procedure assigns a value to it. In Ada 95
you can later read the value, but in Ada 83 out parameters were write-only.
For example:
When the procedure is called with the sentence A_Test (5 + P, 48, Q);, the expressions 5
+ P and 48 are evaluated (expressions are only allowed for in parameters), and then
assigned to the formal parameters A and B, that behave like constants. Then, the value A + B
is assigned to formal variable C. In this case, formal parameter C is a new variable whose
value will be assigned to the real parameter Q when the procedure finishes. In Ada 83 if you
wanted to read the value of Q, besides being able to modify it, C would have to use in out
mode. This restriction was later removed in Ada 95, it is now the programmer's responsibility
to read an out parameter only after having assigned a value to it.
Within a procedure, the return sentence can be used without arguments to exit the
procedure and return the control to the caller.
with Ada.Numerics.Elementary_Functions;
use Ada.Numerics.Elementary_Functions;
procedure Quadratic_Equation
(A, B, C : Float; -- By default it is "in".
R1, R2 : out Float;
Valid : out Boolean)
is
Z : Float;
begin
Z := B**2 - 4.0 * A * C;
if Z > 0.0 or A = 0.0 then
Valid := False; -- Being out parameter, it must be modified at least once.
R1 := 0.0;
R2 := 0.0;
else
Valid := True;
R1 := (-B + Sqrt (Z)) / (2.0 * A);
R2 := (-B - Sqrt (Z)) / (2.0 * A);
end if;
end Quadratic_Equation;
Suppose that a function SQRT exists that calculates the square root of the last parameter. If
the roots are real, they are given back in R1 and R2, but if they are complex or the equation
degenerates (A = 0), the execution of the procedure finishes after assigning to the Valid
variable the False value, so that it is controlled after the call to the procedure. Notice that
the out parameters must be modified at least once, and that if a mode is not specified, it is
implied in.
Functions
A function is a subprogram that can be invoked as part of an expression. Functions can only
take in parameters, another mode cannot be specified (the in mode is mandatory and the
default). In this sense, Ada functions behave more like mathematical functions than in other
languages. The specification of the function is necessary to show to the clients all the
information needed to invoke it.
The formal parameters of a function behave as local constants whose values are provided by
the corresponding real parameters. The sentence return is used to indicate the value
returned by the function call and to give back the control to the expression that called the
function. The expression of the sentence return is of arbitrary complexity and must be of the
same type declared in the specification. If an incompatible type is used, the compiler gives
an error. If the restrictions of a subtype are not fulfilled, e.g. a range, it raises a
Constraint_Error exception.
The body of the function can contain several return sentences and the execution of any of
them will finish the function, returning control to the sentence that invoked it. If the flow of
control within the function branches several ways, it is necessary to make sure that each one
of them is finished with a return sentence. If at run time the end of a function is reached
without encountering a return statement, the exception Program_Error is raised. Therefore,
the body of a function must have at least one return sentence.
Every call to a function produces a new copy of any object declared within it, including the
parameters. When the function finalizes, its objects disappear. Therefore, it is possible to call
the function recursively. For example, consider this implementation of the factorial function:
When evaluating the expression Factorial (4); the function will be called with parameter 4
and within the function it will try to evaluate the expression Factorial (3), calling itself as
a function, but in this case parameter N would be 3 (each call copies the parameters) and so
on until N = 1 is evaluated which will finalize the recursion and then the expression will
begin to be completed in the reverse order.
In this example, the function can be used on a vector of arbitrary dimension. Therefore, there
are no static bounds in the parameters passed to the functions. For example, it is possible to
be used in the following way:
In the same way, a function can also return a type whose bounds are not known a priori. For
example:
The variable Result has the same bounds as V, so the returned vector will always have the
same dimension as the one passed as parameter.
Named parameters
In both procedures and function calls, the order of parameters can be altered using named
notation, that is, the name of the formal parameter followed of the symbol => and then the
real parameter. For example:
Quadratic_Equation (Valid => OK, A => 1.0, B => 2.0, C => 3.0, R1 => P, R2 => Q);
F := Factorial (N => (3 + I));
This involves knowing the formal parameters names which are always specified in the
subprogram specification. As the real parameter is assigned one by one to the real one, there
is no problem of ambiguity. Remember that the formal parameter goes to the left of the =>
symbol; in the case where the real parameter has the same name as the formal one, there
would not be any ambiguity since they are in different scopes.
Default parameters
On the other hand, formal parameters, both in procedures and in functions, might have
default values. They can, therefore, be skipped in the subprogram call. For example:
In the first sentence, a "regular call" is used (with positional notation), in the second, it is
used positional and then by default, third it uses all the parameters by default, in fourth
named and by default, and, finally, the fifth uses positional and named notation. When mixing
both notations, the positional one has to precede the named one.
See also
Wikibook
Ada Programming
Ada Programming/Operators
Packages
One of the biggest advantages of Ada over most other programming languages is its well
defined system of modularization and separate compilation. Even though Ada allows
separate compilation, it maintains the strong type checking among the various compilations
by enforcing rules of compilation order and compatibility checking. Ada uses separate
compilation (like Modula-2, Java and C#), and not independent compilation (as C/C++ does),
in which the various parts are compiled with no knowledge of the other compilation units
with which they will be combined.
A note to C/C++ users: Yes, you can use the preprocessor to emulate separate compilation --
but it is only an emulation and the smallest mistake leads to very hard to find bugs. It is
telling that all C/C++ successor languages including D have turned away from the
independent compilation and the use of the preprocessor.
So it's good to know that Ada has separate compilation ever since Ada-83 and is probably the
most sophisticated implementation around.
Parts of a package
(http://en.wikibooks.org/w/index.php?title=Ada_Programming/All_Chapters&action=edit) .
A package consists of 3 parts but only the specification is mandatory: you leave out the body
and the private part if you don't need them - you can have package specification without
package body and the private package specification is optional.
package Public_Only_Package is
end Public_Only_Package;
package Package_With_Private is
end Package_With_Private;
package Package_With_Body is
type Basic_Record is
record
A : Integer;
end record ;
end Package_With_Body;
end Package_With_Body;
pragma Pure_Function
Only available when using GNAT.
Using packages
This section is a stub. You can help Wikibooks by expanding it
(http://en.wikibooks.org/w/index.php?title=Ada_Programming/All_Chapters&action=edit) .
To utilize a package it's needed to name it in a with clause, whereas to have direct visibility
of that package it's needed to name it in a use clause.
For C++ programmers, Ada's with clause is analogous to the C++ preprocessor's #include
and Ada's use is similar to the using namespace statement in C++. In particular, use leads
to the same namespace pollution problems as using namespace and thus should be used
sparingly. Renaming can shorten long compound names to a manageable length, while the
use type clause makes a type's operators visible. These features reduce the need for plain
use.
Standard with
Private with
This language feature will be made available in the forthcoming Ada 2005 standard.
package Private_With is
-- The package Ada.String.Unbounded is not visible at this point
type Basic_Record is
record
A : Unbounded.Unbounded_String;
end record;
end Private_With;
end Private_With;
Limited with
This language feature will be made available in the forthcoming Ada 2005 standard.
package Employees is
type Employee is tagged private;
procedure Assign_Employee
(E : in out Employee;
D : access Departments.Department'Class);
type Dept_Ptr is access all Departments.Department'Class;
procedure Choose_Manager
(Dept : in out Department;
Manager : access Employees.Employee'Class);
...
end Departments;
With type
Package organisation
This section is a stub. You can help Wikibooks by expanding it
(http://en.wikibooks.org/w/index.php?title=Ada_Programming/All_Chapters&action=edit) .
Child packages
Ada allows one to extend the functionality of a unit (package) with children. These children
can inherit, with certain exceptions, all the functionality of the parent, and only allow
visibility as desired. Example:
with OS_I.Put_Trace;
It is possible to prevent visibility merely by placing the package statement, and the package
body statement in the body of the parent. A with of a child also 'withs in' the parent
Nested packages
A nested package is a package declared inside a package:
Subunits
See also
Wikibook
Ada Programming
Wikipedia
Module
Input Output
Ada has 5 independent libraries for input/output operations. So the most important lesson to
learn is choosing the right one.
Text I/O
Text I/O is probably the most used Input/Output package. All data inside the file are
represented by human readable text. Text I/O provides support for line and page layout but
the standard is free form text.
Direct I/O
Direct I/O is used for random access files which contain only elements of one specific type.
With Direct_IO you can position the file pointer to any element of that type (random access),
however you can't freely choose the element type, the element type needs to be a definite
subtype.
Sequential I/O
Sequential I/O is used for sequential access files which contain only elements of one specific
type. With Sequential_IO it is the other way round: you can choose between definite and
indefinite element types but you have to read and write the elements one after the other.
Storage I/O
Storage I/O allows you to store one element inside a memory buffer. The element needs to be
a definite subtype. Storage I/O is useful in Concurrent programming where it can be used to
move elements from one task to another.
Stream I/O
Stream I/O is the most powerful input/output package which Ada provides. Stream I/O allows
you to mix objects from different element types in one sequential file. In order to read/write
from/to a stream each type provides a 'Read and 'Write attribute as well as an 'Input and
'Output attribute. These attributes are automatically generated for each type you declare.
The 'Read and 'Write attributes treat the elements as raw data. They are suitable for low
level input/output as well as interfacing with other programming languages.
The 'Input and 'Output attribute add additional control informations to the file, like for
example the 'First and 'Last attributes from an array.
In object orientated programming you can also use the 'Class'Input and 'Class'Output
attributes - they will store and recover the actual object type as well.
Stream I/O is also the most flexible input/output package. All I/O attributes can be replaced
with user defined functions or procedures using representation clauses and you can provide
your own Stream I/O types using flexible object oriented techniques.
See also
Wikibook
Ada Programming
Ada Programming/Libraries/Ada.Direct_IO
Ada Programming/Libraries/Ada.Sequential_IO
Ada Programming/Libraries/Ada.Storage_IO
Ada Programming/Libraries/Ada.Streams
Ada Programming/Libraries/Ada.Streams.Stream_IO
Ada Programming/Libraries/Ada.Text_IO
Ada Programming/Libraries/Ada.Text_IO.Complex_IO (nested package)
Ada Programming/Libraries/Ada.Text_IO.Decimal_IO (nested package)
Ada Programming/Libraries/Ada.Text_IO.Enumeration_IO (nested package)
Ada Programming/Libraries/Ada.Text_IO.Fixed_IO (nested package)
Ada Programming/Libraries/Ada.Text_IO.Float_IO (nested package)
Ada Programming/Libraries/Ada.Text_IO.Integer_IO (nested package)
Ada Programming/Libraries/Ada.Text_IO.Modular_IO (nested package)
Ada Programming/Libraries/Ada.Text_IO.Editing
Ada Programming/Libraries/Ada.Float_Text_IO
Ada Programming/Libraries/Ada.Integer_Text_IO
Exceptions
Robustness
Robustness is the ability of a system or system component to behave “reasonably” when it
detects an anomaly, e.g.:
Take as example a telephone exchange control program. What should the control program do
when a line fails? It is unacceptable simply to halt — all calls will then fail. Better would be to
abandon the current call (only), record that the line is out of service, and continue. Better
still would be to try to reuse the line — the fault might be transient. Robustness is desirable
in all systems, but It is essential in systems on which human safety or welfare depends, e.g.,
hospital patient monitoring, aircraft fly-by-wire, nuclear power station control, etc.
A unit (e.g., block or subprogram body) may raise an exception, to signal that an anomaly
has been detected. The computation that raised the exception is abandoned (and can
never be resumed, although it can be restarted).
A unit may propagate an exception that has been raised by itself (or propagated out of
another unit it has called).
A unit may alternatively handle such an exception, allowing programmer-defined
recovery from an anomalous situation. Exception handlers are segregated from
normal-case code.
Predefined exceptions
The predefined exceptions are those defined in package Standard. Every language-defined
run-time error causes a predefined exception to be raised. Some examples are:
Ex.1
Ex.2
loop
P := new Int_Node'(0, P);
end loop; -- Soon raises Storage_Error,
-- because of the extreme memory leak.
versus
...
A negative argument to Sqrt causes Constraint_Error to be explicitly raised inside Sqrt, and
propagated out. Triangle simply propagates the exception (by not handling it).
A negative argument to Sqrt now raises Constraint_Error at the point of call. Sqrt is never
even entered.
Input-output exceptions
Some examples of exceptions raised by subprograms of the predefined package
Ada.Text_IO are:
Ex. 1
declare
A : Matrix (1 .. M, 1 .. N);
begin
for I in 1 .. M loop
for J in 1 .. N loop
begin
Get (A(I,J));
exception
when Data_Error =>
Put ("Ill-formed matrix element");
A(I,J) := 0.0;
end;
end loop;
end loop;
exception
when End_Error =>
Put ("Matrix element(s) missing");
end;
Exception declarations
Exceptions are declared rather like objects, but they are not objects. For example, recursive
re-entry to a scope where an exception is declared does not create a new exception of the
same name; instead the exception declared in the outer invocation is reused.
Ex.1
Line_Failed : exception;
Ex.2
package Directory_Enquiries is
Name_Duplicated : exception;
Name_Absent : exception;
Directory_Full : exception;
end Directory_Enquiries;
Raising exceptions
The raise statement explicitly raises a specified exception.
Ex. 1
by completing;
by executing a return statement;
by raising a different exception (raise e;);
by re-raising the same exception (raise;).
Ex. 1
...
exception
when Line_Failed =>
begin -- attempt recovery
Log_Error;
Retransmit (Current_Packet);
exception
when Line_Failed =>
Notify_Engineer; -- recovery failed!
Abandon_Call;
end;
...
Exception_Name: return the full exception name using the dot notation and in uppercase
letters. For example, Queue.Overflow.
Exception_Message: return the exception message associated with the occurrence.
Exception_Information: return a string including the exception name and the associated
exception message.
The exception message content is implementation defined when it is not set by the user who
raises the exception. It usually contains a reason for the exception and the raising location.
declare
Valve_Failure : exception;
begin
...
Raise_Exception (Valve_Failure'Identity, "Failure while opening");
...
Raise_Exception (Valve_Failure'Identity, "Failure while closing");
...
exception
when Fail: Valve_Failure =>
Put (Exceptions_Message (Fail));
end;
The package also provides subprograms for saving exception occurrences and reraising
them.
See also
Wikibook
Ada Programming
Generics
For example, to define a procedure for swaping variables of any (non-limited) type:
generic
type Element_T is private; -- Generic formal type parameter
procedure Swap (X, Y : in out Element_T);
The Swap subprogram is said to be generic. The subprogram specification is preceded by the
generic formal part consisting of the reserved word generic followed by a list of generic
formal parameters which may be empty. The entities declared as generic are not directly
usable, it is necessary to instantiate them.
To be able to use Swap, it is necessary to create an instance for the wanted type. For
example:
Now the Swap_Integers procedure can be used for variables of type Integer.
The generic procedure can be instantiated for all the needed types. It can be instantiated
with different names or, if the same identifier is used in the instantiation, each declaration
overloads the procedure:
Similarly, generic packages can be used, for example, to implement a stack of any kind of
elements:
generic
Max: Positive;
type Element_T is private;
package Generic_Stack is
procedure Push (E: Element_T);
function Pop return Element_T;
end Generic_Stack;
declare
package Float_100_Stack is new Generic_Stack (100, Float);
use Float_100_Stack;
begin
Push (45.8);
-- ...
end;
Formal parameters are of mode in by default and can be in out, but never out. In case it is in,
the parameter will behave as a constant whose value is provided by the corresponding actual
parameter. Of course, an in generic parameter cannot be of a limited type, because the copy
is not allowed and the formal parameter takes its value by means of copying. In case the
generic parameter is of mode in out, it behaves as a variable that renames the corresponding
actual parameter; in this case, the actual parameter must be a variable and its determination
is made in the moment of the unit instantiation.
generic
type Element_T is private;
with function "*" (X, Y: Element_T) return Element_T;
function Square (X : Element_T) return Element_T;
This generic function could be used, for example, with matrices, having defined the matrix
product.
with Square;
with Matrices;
procedure Matrix_Example is
function Square_Matrix is new Square
(Element_T => Matrices.Matrix_T, "*" => Matrices.Product);
A: Matrix_T := Matrix_T.Identity;
begin
A := Square_Matrix (A);
end Matrix_Example;
See also
Wikibook
Ada Programming
Ada Programming/Object Orientation: tagged types provides other mean of
polymorphism in Ada.
Wikipedia
Generic programming
Tasking
Tasks
A task unit is a program unit that is obeyed concurrently with the rest of an Ada program.
The corresponding activity, a new locus of control, is called a task in Ada terminology, and is
similar to a thread, for example in Java Threads. The execution of the main program is also a
task, the anonymous environment task. A task unit has both a declaration and a body, which
is mandatory. A task body may be compiled separately as a subunit, but a task may not be a
library unit, nor may it be generic. Every task depends on a master, which is the immediately
surrounding declarative region - a block, a subprogram, another task, or a package. The
execution of a master does not complete until all its dependant tasks have terminated. The
environment task is the master of all other tasks; it terminates only when all other tasks have
terminated.
Task units are similar to packages in that a task declaration defines entities exported from
the task, whereas its body contains local declarations and statements of the task.
task Single is
declarations of exported identifiers
end Single;
...
task body Single is
local declarations and statements
end Single;
task No_Exports;
Ex. 1
procedure Housekeeping is
task Check_CPU;
task Backup_Disk;
It is possible to declare task types, thus allowing task units to be created dynamically, and
incorporated in data structures:
task type T is
...
end T;
...
Task_1, Task_2 : T;
...
task body T is
...
end T;
Task types are limited, i.e. they are restricted in the same way as limited private types, so
assignment and comparison are not allowed.
Rendezvous
The only entities that a task may export are entries. An entry looks much like a procedure. It
has an identifier and may have in, out or in out parameters. Ada supports communication
from task to task by means of the entry call. Information passes between tasks through the
actual parameters of the entry call. We can encapsulate data structures within tasks and
operate on them by means of entry calls, in a way analogous to the use of packages for
encapsulating variables. The main difference is that an entry is executed by the called task,
not the calling task, which is suspended until the call completes. If the called task is not
ready to service a call on an entry, the calling task waits in a (FIFO) queue associated with
the entry. This interaction between calling task and called task is known as a rendezvous.
The calling task requests rendezvous with a specific named task by calling one of its entries.
A task accepts rendezvous with any caller of a specific entry by executing an accept
statement for the entry. If no caller is waiting, it is held up. Thus entry call and accept
statement behave symmetrically. (To be honest, optimized object code may reduce the
number of context switches below the number implied by this naive description.)
Ex. 2 The following task type implements a single-slot buffer, i.e. an encapsulated variable
that can have values inserted and removed in strict alternation. Note that the buffer task has
no need of state variables to implement the buffer protocol: the alternation of insertion and
removal operations is directly enforced by the control structure in the body of
Encapsulated_Buffer_Task_Type.
Selective Wait
To avoid being held up when it could be doing productive work, a server task often needs the
freedom to accept a call on any one of a number of alternative entries. It does this by means
of the selective wait statement, which allows a task to wait for a call on any of two or more
entries.
If only one of the alternatives in a selective wait statement has a pending entry call, then that
one is accepted. If two or more alternatives have calls pending, the implementation is free to
accept any one of them. For example, it could choose one at random. This introduces
bounded non-determinism into the program. A sound Ada program should not depend on a
particular method being used to choose between pending entry calls. (However, there are
facilities to influence the method used, when that is necessary.)
Ex. 3
x, y : Encapsulated_Variable_Task_Type;
it : Item;
...
x.Store(Some_Expression);
...
x.Fetch (it);
y.Store (it);
Again, note that the control structure of the body ensures that an
Encapsulated_Variable_Task_Type must be given an initial value by a first Store operation
before any Fetch operation can be accepted.
Guards
Depending on circumstances, a server task may not be able to accept calls for some of the
entries that have accept alternatives in a selective wait statement. The acceptance of any
alternative can be made conditional by using a guard, which is Boolean precondition for
acceptance. This makes it easy to write monitor-like server tasks, with no need for an explicit
signaling mechanism, nor for mutual exclusion. An alternative with a True guard is said to be
open. It is an error if no alternative is open when the selective wait statement is executed,
and this raises the Program_Error exception.
Ex. 4
task Cyclic_Buffer_Task_Type is
entry Insert (An_Item : in Item);
entry Remove (An_Item : out Item);
end Cyclic_Buffer_Task_Type;
...
task body Cyclic_Buffer_Task_Type is
Q_Size : constant := 100;
subtype Q_Range is Positive range 1 .. Q_Size;
Length : Natural range 0 .. Q_Size := 0;
Head, Tail : Q_Range := 1;
Data : array (Q_Range) of Item;
begin
loop
select
when Length < Q_Size =>
accept Insert (An_Item : in Item) do
Data(Tail) := An_Item;
end Insert;
Tail := Tail mod Q_Size + 1;
Length := Length + 1;
or
when Length > 0 =>
accept Remove (An_Item : out Item) do
An_Item := Data(Head);
end Remove;
Head := Head mod Q_Size + 1;
Length := Length - 1;
end select;
end loop;
end Cyclic_Buffer_Task_Type;
Protected types
Tasks allow for encapsulation and safe usage of variable data without the need for any
explicit mutual exclusion and signaling mechanisms. Ex. 4 shows how easy it is to write
server tasks that safely manage locally-declared data on behalf of multiple clients. There is
no need for mutual exclusion of access to the managed data, because it is never accessed
concurrently. However, the overhead of creating a task merely to serve up some data may be
excessive. For such applications, Ada 95 provides protected modules. A protected module
encapsulates a data structure and exports subprograms that operate on it under automatic
mutual exclusion. It also provides automatic, implicit signaling of conditions between client
tasks. Again, a protected module can be either a single protected object or a protected type,
allowing many protected objects to be created.
A protected module can export only procedures, functions and entries, and its body may
contain only the bodies of procedures, functions and entries. The protected data is declared
after private in its specification, but is accessible only within the protected module's body.
Protected procedures and entries may read and/or write its encapsulated data, and
automatically exclude each other. Protected functions may only read the encapsulated data,
so that multiple protected function calls can with complete safety be concurrently executed
in the same protected object; but protected procedure calls and entry calls exclude protected
function calls, and vice versa. Exported entries and subprograms of a protected object are
executed by its calling task, as a protected object has no independent locus of control. (To be
honest, optimized object code may reduce the number of context switches below the number
implied by this naive description.)
Like a task entry, a protected entry can employ a guard to control admission. This provides
automatic signaling, and ensures that when a protected entry call is accepted, its guard
condition is True, so that a guard provides a reliable precondition for the entry body.
Ex. 5 The following is a simple protected type analogous to the Encapsulated_Buffer task in
Ex. 2.
Note how the guards, using the state variable Empty, ensure that messages are alternately
inserted and removed, and that no attempt can be made to take data from an empty buffer.
All this is achieved without explicit signaling or mutual exclusion constructs, whether in the
calling task or in the protected type itself.
The notation for calling a protected entry or procedure is exactly the same as that for calling
a task entry. This makes it easy to replace one implementation of the abstract type by the
other, the calling code being unaffected.
Ex. 6 The following task type implements Dijkstra's semaphore ADT, with FIFO scheduling of
resumed processes. The algorithm will accept calls to both Wait and Signal, so long as the
semaphore invariant would not be violated. When that circumstance approaches, calls to
Wait are ignored for the time being.
Ex. 7 The Initialize and Signal operations of this protected type are unconditional, so they
are implemented as protected procedures, but the Wait operation must be guarded and is
therefore implemented as an entry.
Unlike the task type above, this does not ensure that Initialize is called before Wait or Signal,
and Count is given a default initial value instead. Restoring this defensive feature of the task
version is left as an exercise for the reader.
Entry families
Sometimes we need a group of related entries. Entry families, indexed by a discrete type,
meet this need.
Note that the busy wait else null is necessary here to prevent the task from being
suspended on some buffer I when there was no call pending for it, because such suspension
would delay serving requests for all the other buffers (perhaps indefinitely).
Termination
Server tasks often contain infinite loops to allow them to service an arbitrary number of calls
in succession. But control cannot leave a task's master until the task terminates, so we need
a way for a server to know when it should terminate. This is done by a terminate alternative
in a selective wait.
Ex. 9
Conditions (1) and (2) ensure that the task is in a fit state to stop. Conditions (3) and (4)
ensure that stopping cannot have an adverse effect on the rest of the program, because no
further calls that might change its state are possible.
Timeout
A task may need to avoid being held up by calling to a slow server. A timed entry call lets a
client specify a maximum delay before achieving rendezvous, failing which the attempted
entry call is withdrawn and an alternative sequence of statements is executed.
Ex. 10
task Password_Server is
entry Check (User, Pass : in String; Valid : out Boolean);
entry Set (User, Pass : in String);
end Password_Server;
...
User_Name, Password : String (1 .. 8);
...
Put ("Please give your new password:");
Get_Line (Password);
select
Password_Server.Set (User_Name, Password);
Put_Line ("Done");
or
delay 10.0;
Put_Line ("The system is busy now, please try again later.");
end select;
To time out the functionality provided by a task, two distinct entries are needed: one to pass
in arguments, and one to collect the result. Timing out on rendezvous with the latter
achieves the desired effect.
Ex. 11
task Process_Data is
entry Input (D : in Datum);
entry Output (D : out Datum);
end Process_Data;
Input_Data, Output_Data : Datum;
loop
collect Input_Data from sensors;
Process_Data.Input (Input_Data);
select
Process_Data.Output (Output_Data);
pass Output_Data to display task;
or
delay 0.1;
Log_Error ("Processing did not complete quickly enough.");
end select;
end loop;
Ex. 12
task Resource_Lender is
entry Get_Loan (Period : in Duration);
entry Give_Back;
end Resource_Lender;
...
task body Resource_Lender is
Period_Of_Loan : Duration;
begin
loop
select
accept Get_Loan (Period : in Duration) do
Period_Of_Loan := Period;
end Get_Loan;
select
accept Give_Back;
or
delay Period_Of_Loan;
Log_Error ("Borrower did not give up loan soon enough.");
end select;
or
terminate;
end select;
end loop;
end Resource_Lender;
select
...
else
...
end select;
and
select
...
or
delay 0.0
...
end select;
are equivalent.
Requeue statements
A requeue statement allows an accept statement or entry body to be completed while
redirecting to a different or the same entry queue. The called entry has to share the same
parameter list or be parameter-less.
Scheduling
FIFO, priority, priority inversion avoidance, ... to be completed
Interfaces
This language feature will be made available in the forthcoming Ada 2005 standard.
See also
Wikibook
Ada Programming
Ada 2005
Object Orientation
Object-orientation on Ada
An Ada class consists of three building blocks:
a package
a record (data storage)
primitive operations (methods).
Note: Rigorously the meaning of the term class is different in Ada than in C++, Java and
others. In Ada, a class is a special type whose values are those of the union of all the types
derived from a given tagged type, called the class-wide type. In C++, the term class is a bit
polysemic, it does mean the former concept, and it is a concrete type with operations
associated, and finally a construct to define them.
The package
Every class has to be defined inside a package. One package may contain more than one
class. You might be surprised about that requirement but you should remember that every
class needs some housekeeping information which has to be kept somewhere; in Ada this
housekeeping information is part of the package.
If you have ever, when linking a C++ program, got an error message telling you that the
virtual function table for class X was not found then you might appreciate this restriction. In
Ada you never get this error message - the Ada equivalent of the virtual function table is part
of the package. The same goes for the Ada equivalent of a virtual inline function, another
cause of trouble when linking C++ programs - and they too work flawlessly in Ada.
package Person is
type Object is tagged
record
Name : String (1 .. 10);
Gender : Gender_Type;
end record;
end Person;
with Person;
package Programmer is
Whenever you declare a tagged type, the compiler will also provide a Class type for you. This
type is called a class-wide type. Beginners often consider the class-wide type as some
abstract concept. But this is not true! The Class type is a real data type. You can declare
variables of the class-wide type, assign values to them, use the class-wide type as a
parameter to functions and procedures and so forth.
The interesting part is that the class-wide type can hold values of any child class of the
declared base type; in fact, there are no objects of this class-wide type - an object always is
of a specific child type. This means that, unlike with most other object-oriented programming
languages, you do not need to resort to the use of heap memory for storing arbitrary
members of a class family but you can use the Class type instead.
Since the size of the child class is not known at compile time, any class-wide type is an
indefinite subtype.
Primitive operations
The primitive operations of a given tagged type are those having a parameter or return value
of this type and are declared immediately in the same package as the type.
Primitive operations are inherited and can be overridden for derived types.
Examples:
package X is
type Object is tagged null record;
end X;
A note for C++ programers: Class types are "by reference types" - they are always passed to
a subprogram by using a pointer and never use "call by value" - using an access explicitly is
therefore seldom needed.
Please note that neither named access types nor class-wide types qualify as class members.
Procedures and functions having those as a parameter are just normal subprograms sharing
the same package without belonging to the class.
Examples:
package X is
package Inner is
end X;
Note for C++ programmers: Procedures and functions like these can serve the same purpose
as "non virtual" and "static" methods have in C++.
This language feature will be made available in the forthcoming Ada 2005 standard.
package X is
overriding
function Class_Member_3 return Derived_Object;
not overriding
function New_Class_Member_1 return Derived_Object;
end X;
This is a good programming practice because it avoids some nasty bugs like not overriding
an inherited subprogram because the programmer spelt the identifier incorrectly, or because
a new parameter is added later in the parent type.
It can also be used with abstract operations, with renamings, or when instantiating a generic
subprogram:
not overriding
procedure Class_Member_1 (This : in Object) is abstract;
overriding
function Class_Member_2 return Object renames Old_Class_Member;
not overriding
procedure Class_Member_3 (This : out Object)
is new Generic_Procedure (Element => Integer);
Interfaces
This language feature will be made available in the forthcoming Ada 2005 standard.
Interfaces allow for a limited form of multiple inheritance. On a sematic level they are similar
to an "abstract tagged null record" as they may have primitive operations but cannot hold
any data. These operations cannot have a body, so they are either declared abstract or null.
Abstract means the operation has to be overridden, null means the default implementation is
a null body, i.e. one that does nothing.
package Printable is
with Person;
package Programmer is
type Object is new Person.Object
and Printable.Object
with
record
Skilled_In : Language_List;
end record;
overriding
procedure Class_Member_1 (This : in Object);
not overriding
procedure New_Class_Member (This : Object; That : String);
end Programmer;
As usual, all inherited abstract operations must be overriden altough null subprograms ones
need not.
Class names
Both the class package and the class record need a name. In theory they may have the same
name, but in practice this leads to nasty (because of unintutive error messages) name clashes when
you use the use clause. So over time three de facto naming standards have been commonly
used.
Classes/Class
The package is named by a plural noun and the record is named by the corresponding
singular form.
package Persons is
type Person is tagged
record
Name : String (1 .. 10);
Gender : Gender_Type;
end record;
end Persons;
Disadvantage: Some "multiples" are tricky to spell, especially for those of us who aren't
native English speakers.
Class/Object
The package is named after the class, the record is just named Object.
package Person is
type Object is tagged
record
Name : String (1 .. 10);
Gender : Gender_Type;
end record;
end Person;
Disadvantage: You can't use the use clause on more than one such class packages at any one
time. However you can always use the "type" instead of the package.
Class/Class_Type
The package is named after the class, the record is postfixed with _Type.
package Person is
type Person_Type is tagged
record
Name : String (1 .. 10);
Gender : Gender_Type;
end record;
end Person;
See also
Wikibook
Ada Programming
Ada Programming/Types/record
record
interface
tagged
Wikipedia
Object-oriented programming
Ada 2005
(Annotated (http://www.adaic.com/standards/rm-amend/html/AA-3-10.html) )
Ada 2005
This is an overview of the major features that will be available in the upcoming Ada 2005
(sometimes refered as Ada 200Y or Ada 2006). For the rationale and a more detailed (and
very technical) description, see the draft of the Amendment
(http://www.ada-auth.org/AI-XREF.HTML#Amend_Doc) to the Ada Reference Manual
following the links to the last version of every Ada Issue document (AI).
Although the standard is not published yet, it is possible to test some of its new features
right now. Many of these additions are totally implemented by the following Free Software
compilers:
After downloading and installing any of them, remember to use the -gnat05 switch when
compiling Ada 2005 code.
Language features
Character set
Not only does Ada 2005 now support a new 32-bit character type — called
Wide_Wide_Character — but the source code itself may be of this extended character set as
well. Thus Russians and Indians, for example, will be able to use their native language in
identifiers and comments. And mathematicians will rejoice: The whole Greek and fractur
character sets are available for identifiers. For example, Ada.Numerics will be extended with
a new constant:
π : constant := Pi;
This is not a new idea – GNAT always had the -gnatic compiler option to specify the
character set [1] (http://gcc.gnu.org/onlinedocs/gnat_ugn_unw/Character-Set-Control.html) .
But now this idea will become standard, so all Ada compilers will need to support Unicode
4.0 for identifiers —as the new standard requires.
See also:
Interfaces
Interfaces allow for a limited form of multiple inheritance similar to Java and C#.
See also:
Union
In addition to Ada's safe variant record an unchecked C style union is now available.
See also:
With
The with statement got a massive upgrade. First there is the new limited with which allows
two packages to with each other. Then there is private with to make a package only visible
inside the private part of the specification. The latter also allows to make child units visible.
See also:
Access types
Not null access
An access type definition can specify that the access type can never be null.
Anonymous access
The possible uses of anonymous access types are extended. They are allowed virtually in
every type or object definition, including access to subprogram parameters. Anonymous
access types may point to constant objects as well. Also, they could be declared to be not
null.
With the addition of the following operations in package Standard, it is possible to test the
equality of anonymous access types.
See also:
Language library
Container
The main addition to the language library is the generic packages for containers. If you are
familiar with the C++ STL, you will likely feel very much at home using Ada.Containers.
If you know how to write Ada programs, and have a need for vectors, sets, or maps (tables),
please have a look at the AI-20302 AI Text
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-20302.TXT) mentioned above. There is an
!examples section in the text explaining the use of the containers in some detail. Matthew
Heaney provides a number of demonstration programs with his reference implementation of
AI-302 (Ada.Containers) which you can find at tigris (http://charles.tigris.org) .
Numerics
Besides the new constant of package Ada.Numerics (see Character Set above), the most
important addition are the packages to operate with vectors and matrices.
See also:
Ravenscar profile
See also:
New pragmas
pragma Assert
pragma Assertion_Policy
pragma Detect_Blocking
pragma No_Return
pragma Partition_Elaboration_Policy
pragma Preelaborable_Initialization
pragma Priority_Specific_Dispatching
pragma Profile
pragma Unsuppress
pragma Unchecked_Union
New attributes
Machine_Rounding
Mod
Priority
Wide_Wide_Image
Wide_Wide_Value
Wide_Wide_Width
New packages
Assertions:
Ada.Assertions
Container library:
Ada.Containers
Ada.Containers.Vectors
Ada.Containers.Doubly_Linked_Lists
Ada.Containers.Generic_Array_Sort (generic procedure)
General OS facilities:
Ada.Directories
Ada.Directories.Information
Ada.Environment_Variables
String hashing:
Ada.Strings.Hash (generic function)
Ada.Strings.Fixed.Hash (generic function)
Ada.Strings.Bounded.Hash (generic function)
Ada.Strings.Unbounded.Hash (generic function)
Ada.Strings.Wide_Hash (generic function)
Ada.Strings.Wide_Fixed.Wide_Hash (generic function)
Ada.Strings.Wide_Bounded.Wide_Hash (generic function)
Ada.Strings.Wide_Unbounded.Wide_Hash (generic function)
Ada.Strings.Wide_Wide_Hash (generic function)
Ada.Strings.Wide_Wide_Fixed.Wide_Wide_Hash (generic function)
Ada.Strings.Wide_Wide_Bounded.Wide_Wide_Hash (generic function)
Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Hash (generic function)
Time operations:
Ada.Calendar.Time_Zones
Ada.Calendar.Arithmetic
Ada.Calendar.Formatting
Tagged types:
Ada.Tags.Generic_Dispatching_Constructor (generic function)
Text packages:
Ada.Complex_Text_IO
Ada.Text_IO.Bounded_IO
Ada.Text_IO.Unbounded_IO
Ada.Wide_Text_IO.Bounded_IO
Ada.Wide_Text_IO.Unbounded_IO
Ada.Wide_Characters
Ada.Wide_Wide_Characters
Wide_Wide_Character packages:
Ada.Strings.Wide_Wide_Bounded
Ada.Strings.Wide_Wide_Fixed
Ada.Strings.Wide_Wide_Maps
Ada.Strings.Wide_Wide_Maps.Wide_Wide_Constants
Ada.Strings.Wide_Wide_Unbounded
Ada.Wide_Wide_Text_IO
Ada.Wide_Wide_Text_IO.Complex_IO
Ada.Wide_Wide_Text_IO.Editing
Ada.Wide_Wide_Text_IO.Text_Streams
Ada.Wide_Wide_Text_IO.Unbounded_IO
Execution-time clocks:
Ada.Execution_Time
Ada.Execution_Time.Timers
Ada.Execution_Time.Group_Budgets
Dispatching:
Ada.Dispatching
Ada.Dispatching.EDF
Ada.Dispatching.Round_Robin
Timing events:
Ada.Real_Time.Timing_Events
Task termination procedures:
Ada.Task_Termination
See also
Wikibook
Ada Programming/Object Orientation
Ada Programming/Types/access
Ada Programming/Keywords
Ada Programming/Keywords/and
Ada Programming/Keywords/interface
Ada Programming/Attributes
Ada Programming/Pragmas
Ada Programming/Pragmas/Restrictions
Ada Programming/Libraries/Ada.Containers
Ada Programming/Libraries/Ada.Directories
External links
Papers and presentations
Ada 2005: Putting it all together
(http://www.sigada.org/conf/sigada2004/SIGAda2004-CDROM/SIGAda2004-Proceedings/Ada200
(SIGAda 2004 presentation)
GNAT: The road to Ada 2005
(http://www.adacore.com/multimedia/pdfs/Ada2005_AdaSpain05.pdf) (Ada-Spain 2005
presentation)
GNAT and Ada 2005 (http://www.adacore.com/multimedia/pdfs/GNAT_and_Ada2005.pdf)
, and the presentation of this paper
(http://www.adacore.com/multimedia/pdfs/Ada2005_SIGAda.pdf) at SIGAda 2004
An invitation to Ada 2005
(http://sigada.org/ada_letters/sept2003/Invitation_to_Ada_2005.pdf) , and the
presentation of this paper
(http://www.cs.kuleuven.ac.be/~dirk/ada-belgium/events/04/040616-aec-ada2005.pdf) at
Ada-Europe 2004
Rationale
Rationale for Ada 2005 by John Barnes:
Introduction (http://www.adacore.com/multimedia/pdfs/Ada05_rational_00.pdf)
Object Oriented Model (http://www.adacore.com/multimedia/pdfs/Ada05_rational_01.pdf)
Access Types (http://www.adacore.com/multimedia/pdfs/Ada05_rational_02.pdf)
Structure and Visibility
(http://www.adacore.com/multimedia/pdfs/Ada05_rational_03.pdf)
Tasking and Real-Time (http://www.adacore.com/multimedia/pdfs/Ada05_rational_04.pdf)
Exceptions, Generics, Etc.
(http://www.adacore.com/multimedia/pdfs/Ada05_rational_05.pdf)
Language Requirements
Instructions to the Ada Rapporteur Group from SC22/WG9 for Preparation of the
Amendment to ISO/IEC 8652 (http://www.open-std.org/jtc1/sc22/WG9/n412.pdf) (10
October 2002), and a presentation of this document
(http://std.dkuug.dk/JTC1/sc22/wg9/n423.pdf) at SIGAda 2002
Ada Issues
Amendment 200Y (http://www.ada-auth.org/AI-XREF.HTML#Amend_Doc)
AI-00387 Introduction to Amendment
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00387.TXT)
AI-10284 New reserved words
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-10284.TXT)
AI-00252 Object.Operation notation
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00252.TXT)
AI-20218 Accidental overloading when overriding
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-20218.TXT)
AI-00348 Null procedures
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00348.TXT)
AI-00287 Limited aggregates allowed
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00287.TXT)
AI-00326 Incomplete types
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00326.TXT)
AI-00317 Partial parameter lists for formal packages
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00317.TXT)
AI-00376 Interfaces.C works for C++ as well
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00376.TXT)
AI-00368 Restrictions for obsolescent features
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00368.TXT)
AI-00381 New Restrictions identifier No_Dependence
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00381.TXT)
AI-00224 pragma Unsuppress
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00224.TXT)
AI-00161 Default-initialized objects
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00161.TXT)
AI-00361 Raise with message
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00361.TXT)
AI-00286 Assert pragma
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00286.TXT)
AI-00328 Preinstantiations of Complex_IO
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00328.TXT)
AI-00301 Operations on language-defined string types
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00301.TXT)
AI-00340 Mod attribute
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00340.TXT)
AI-00364 Fixed-point multiply/divide
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00364.TXT)
AI-00267 Fast float-to-integer conversions
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00267.TXT)
AI-00321 Definition of dispatching policies
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00321.TXT)
AI-00329 pragma No_Return -- procedures that never return
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00329.TXT)
AI-00362 Some predefined packages should be recategorized
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00362.TXT)
AI-00351 Time operations
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00351.TXT)
AI-00427 Default parameters and Calendar operations
(http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00427.TXT)
Tips
It turns out you don't have to. Nonchalantly mentioned in the ARM
(http://www.adaic.org/standards/95lrm/html/RM-TTL.html) , and generally skipped over in
tutorials, (at least, the ones that I've read) is the fact that private types can be completed in
the unit's body itself, making them much closer to the relevant code, and saving a recompile
of the specification, as well as every unit depending on it. This may seem like a small thing,
and, for small projects, it is. However, if you have one of those uncooperative types that
requires dozens of tweaks, or if your dependence graph has much depth, the time and
annoyance saved add up quickly.
Also, this construction is very useful when coding a shared library, because it permits change
the implementation of the type while still providing a compatible ABI.
Code sample:
package Private_And_Body is
type Private_Type is limited private;
-- Operations...
private
type Body_Type; -- Defined in the body
type Private_Type is access Body_Type;
end Private_And_Body;
The type in the public part is an access to the hidden type. This has the drawback that
memory management has to be provided by the package implementation. That is the reason
why Private_Type is a limited type, the client will not be allowed to copy the access values,
in order to prevent dangling references.
These types are sometimes called "Taft types" --named after Tucker Taft, the main designer
of Ada 95-- because were introduced in the so-called Taft Amendment to Ada 83. In other
programming languages, this construction is called opaque pointers".
The mental stumbling block is that most examples given of generics are packages, and the
Set package is already generic. In this case, the solution is to make the Apply_To_All
procedure generic as well; that is, to nest the generics. Generic procedures inside packages
exist in a strange scoping limbo, where anything in scope at the instantiation can be used by
the instantiation, and anything normally in scope at the formal can be accessed by the
formal. The end result is that the relevant scoping roadblocks no longer apply. It isn't the full
generic
type Element is private;
package Sets is
type Set is private;
[..]
generic
with procedure Apply_To_One (The_Element : in out Element);
procedure Apply_To_All (The_Set : in out Set);
end Sets;
See also
Wikibook
Ada Programming
Algorithms
Introduction
Welcome to the Ada implementations of the Computer Science:Algorithms. For those who
are new to Ada Programming a few notes:
All examples are fully functional with all the needed input and output operations.
However, only the code needed to outline the algorithms at hand is copied into the text -
the full samples are available via the download links. (Note: It can take up to 48 hours until the
cvs is updated).
We seldom use predefined types in the sample code but define special types suitable for
the algorithms at hand.
Ada allows for default function parameters; however, we always fill in and name all
parameters, so the reader can see which options are available.
We seldom use shortcuts - like using the attributes Image or Value for String <=>
Integer conversions.
All these rules make the code more elaborate then perhaps needed. However, we also hope it
makes the code easier to understand
Chapter 1: Introduction
The following codes are implementations of the Inventing an Algorithm examples.
To Lower
The Ada example code does not append to the array as the algorithms. Instead we create an
empy arrays of the desired lenght and then replace the characters inside.
Would the append appoach be impossible with Ada. No - but it would be significantly more
complex and slower.
Simple Implementation
(http://cvs.sourceforge.net/viewcvs.py/wikibook-ada/demos/Source/fibonacci_1.adb?only_with_tag=HEAD&view=marku
, view as plain text
(http://cvs.sourceforge.net/viewcvs.py/*checkout*/wikibook-ada/demos/Source/fibonacci_1.adb) , download
page (https://sourceforge.net/project/showfiles.php?group_id=124904) )
...
To calculate Fibonacci numbers negative values are not needed so we define an integer type
which starts at 0. With the integer type defined you can calculate up until Fib (87). Fib
(88) will result in an Constraint_Error.
You might notice that there is not equivalence for the assert (n >= 0) from the original
exapmle. Ada will test the correctness of the parameter before the function is called.
Cached Implementation
...
For this implementation we need a special cash type can also store a -1 as "not calculated"
marker
The actual type for calculating the fibonacci numbers continues to start at 0. As it is a
subtype of the cache type Ada will automaticly convert between the two. (the convertion is - of
course - checked for validity)
In order to know how large the cache need to be we first read the actual value from the
command line.
The Cache array starts with element 2 since Fib (0) and Fib (1) are constants and ends with
the value we want to calculate.
type Cache_Array is
array (Integer_Type range 2 .. Value) of Cache_Type;
The Cache is initialized to the first valid value of the cache type - this is -1.
...
This implementation is faithful to the original from the Computer Science:Algorithms book.
However, in Ada you would normaly do it a little different:
when you use a slightly larger array which also stores the elements 0 and 1 and initializes
then to the correct values
type Cache_Array is
array (Integer_Type range 0 .. Value) of Cache_Type;
F : Cache_Array :=
(0 => 0,
1 => 1,
others => Cache_Type'First);
if N = 0 or else N = 1 then
return N;
elsif F (N) /= Cache_Type'First then
This will save about 45% of the execution-time (measured on Linux i686) while needing only two
more elements in the cache array.
No 64 bit integers
Your Ada compiler does not support 64 bit integer numbers? Then you could try to use
decimal numbers instead. Using decimal numbers results in a slower program (takes about
three times as long) but the result will be the same.
The following example shows you how to define a suitable decimal type. Do experiment with
the digits and range parameters until you get the optimum out of your Ada.
You should know that floating point numbers are unsuitable for the calculation of fibonacci
numbers. They will not report an error condition when the number calculated becomes too
large - instead they will lose in precision which makes the result meaningless.
Function overloading
Description
Function overloading (also polymorphism or method overloading) is a programming
concept that allows programmers to define two or more functions with the same name.
Each function has a unique signature (or header), which is derived from:
1. function/procedure name
2. number of arguments
3. arguments' type
4. arguments' order
5. arguments' name
6. return type
Please note: Not all above signature options are available in all programming languages.
Demonstration
Since functions' names are in this case the same, we must preserve uniqueness of
signatures, by changing something from the parameter list (last three alienees).
If the functions' signatures are sufficiently different, the compiler can distinguish which
function was intended to be used at each occurence. This process of searching for the
appropriate function is called function resolution and can be quite an intensive one,
especially if there are a lot of equally named functions.
When two or more functions match the criteria in function resolution process, an ambiguity
error is reported by compiler. Adding more information to compiler by editing the source
code (using for example type casting), can address such doubts.
The example code shows how function overloading can be used. As functions do practically
the same thing, it makes sense to use function overloading.
G : Random_Pack.Generator;
begin
Random_Pack.Reset (G);
return Random_Pack.Random (G);
end Generate_Number;
G : Random_Pack.Generator;
begin
Random_Pack.Reset (G);
return Random_Pack.Random (G);
end Generate_Number;
Note that you can not overload a generic procedure or generic function within the same
package. The following example will fail to compile:
package myPackage
generic
type Value_Type is (<>);
-- The first declaration of a generic subprogram
-- with the name "Generic_Subprogram"
procedure Generic_Subprogram (Value : in out Value_Type);
...
generic
type Value_Type is (<>);
-- This subprogram has the same name, but no
-- input or output parameters. A non-generic
-- procedure would be overloaded here.
-- Since this procedure is generic, overloading
-- is not allowed and this package will not compile.
procedure Generic_Subprogram;
...
generic
type Value_Type is (<>);
-- The same situation.
-- Even though this is a function and not
-- a procedure, generic overloading of
-- the name "Generic_Subprogram" is not allowed.
function Generic_Subprogram (Value : Value_Type) return Value_Type;
end myPackage;
See also
Wikibook
Ada Programming
Ada Programming/Subprograms
(http://www.adaic.com/standards/rm-amend/html/RM-6-6.html) (Annotated
(http://www.adaic.com/standards/rm-amend/html/AA-6-6.html) )
8.6 The Context of Overload Resolution
(http://www.adaic.com/standards/rm-amend/html/RM-8-6.html) (Annotated
(http://www.adaic.com/standards/rm-amend/html/AA-8-6.html) )
Mathematical calculations
Ada is very well suited for all kind of calculations. You can define you own fixed point and
floting point types and - with the aid of generic packages call all the mathematical functions
you need. I that respect Ada is on par with Fortran. This module will show you how to use
them and while we progress we create a simple RPN calculator.
Simple calculations
Addition
Additions can be done using the predefined operator +. The operator is predefined for all
numeric types and the following, working code, demonstrates its use:
Value_1 : Value_Type;
Value_2 : Value_Type;
begin
T_IO.Put ("First Value : ");
F_IO.Get (Value_1);
T_IO.Put ("Second Value : ");
F_IO.Get (Value_2);
F_IO.Put (Value_1);
T_IO.Put (" + ");
F_IO.Put (Value_2);
T_IO.Put (" = ");
F_IO.Put (Value_1 + Value_2);
end Numeric_1;
Subtraction
Subtractions can be done using the predefined operator -. The following extended demo
shows the use of + and - operator together:
procedure Numeric_2
is
type Value_Type
is digits
12
range
-999_999_999_999.0e999 .. 999_999_999_999.0e999;
Value_1 : Value_Type;
Value_2 : Value_Type;
Result : Value_Type;
Operation : Character;
begin
T_IO.Put ("First Value : ");
F_IO.Get (Value_1);
T_IO.Put ("Second Value : ");
F_IO.Get (Value_2);
T_IO.Put ("Operation : ");
T_IO.Get (Operation);
case Operation is
when '+' =>
Result := Value_1 + Value_2;
when '-' =>
Result := Value_1 - Value_2;
when others =>
T_IO.Put_Line ("Illegal Operation.");
goto Exit_Numeric_2;
end case;
F_IO.Put (Value_1);
T_IO.Put (" ");
T_IO.Put (Operation);
T_IO.Put (" ");
F_IO.Put (Value_2);
T_IO.Put (" = ");
F_IO.Put (Result);
<<Exit_Numeric_2>>
return;
end Numeric_2;
Purists might be surprised about the use of goto - but some people prefer the use of goto
over the use of multiple return statements if inside functions - given that, the opinions on this
topic vary strongly. See the isn't goto evil article.
Multiplication
Multiplicationcan be done using the predefined operator *. For a demo see the next chapter
about Division.
Division
Divisions can be done using the predefined operators /, mod, rem. The operator / performes a
normal division, mod returns a modulus division and rem returns the remainder of the
modulus division.
The following extended demo shows the use of the +, -, * and / operators together as well as
the use of an four number wide stack to store intermediate results:
The operators mod and rem are not part of the demonstration as they are only defined for
integer types.
with Ada.Text_IO;
procedure Numeric_3 is
procedure Pop_Value;
procedure Push_Value;
procedure Pop_Value is
begin
Values (Values'First + 1 .. Values'Last) :=
Values (Values'First + 2 .. Values'Last) & 0.0;
end Pop_Value;
procedure Push_Value is
begin
Values (Values'First + 1 .. Values'Last) :=
Values (Values'First .. Values'Last - 1);
end Push_Value;
begin
Main_Loop:
loop
T_IO.Put (">");
T_IO.Get_Line (Operation, Last);
if Last = 1 and then Operation (1) = '+' then
Values (1) := Values (1) + Values (2);
Pop_Value;
elsif Last = 1 and then Operation (1) = '-' then
Values (1) := Values (1) + Values (2);
Pop_Value;
elsif Last = 1 and then Operation (1) = '*' then
Values (1) := Values (1) * Values (2);
Pop_Value;
elsif Last = 1 and then Operation (1) = '/' then
Values (1) := Values (1) / Values (2);
Pop_Value;
elsif Last = 4 and then Operation (1 .. 4) = "exit" then
exit Main_Loop;
else
Push_Value;
F_IO.Get (From => Operation, Item => Values (1), Last => Last);
end if;
Display_Loop:
for I in reverse Value_Array'Range loop
F_IO.Put
(Item => Values (I),
Fore => F_IO.Default_Fore,
Aft => F_IO.Default_Aft,
Exp => 4);
T_IO.New_Line;
end loop Display_Loop;
end loop Main_Loop;
return;
end Numeric_3;
Exponential calculations
All exponential functions are defined inside the generic package
Ada.Numerics.Generic_Elementary_Functions.
Power of
Calculation of the form are performed by the operator **. Beware: There are two versions
of this operator. The predefined operator ** allows only for Standart.Integer to be used as
exponent. If you need to use a floating point type as exponent you need to use the ** defined
in Ada.Numerics.Generic_Elementary_Functions.
Root
The square root is calculated with the function Sqrt(). There is no function defined to
calculate an abritary root . However you can use logarithms to calculate an arbitrary root
using the mathematical identity: which will become root := Exp (Log (a) /
b) in Ada. Alternatively, use which, in Ada, is root := a**(1/b).
Logarithm
Ada.Numerics.Generic_Elementary_Functions defines a function for both the arbritary
logarithm and the natural logaritm both of of which have the same name Log()
distinquished by the amount of parameters.
Demonstration
The following extended demo shows the how to use the exponential functions in Ada. The
new demo also uses Unbounded_String instead of Strings which make the comparisons
easier.
Please note that from now on we won't copy the full sources any more. Do follow the
download links to see the full programm.
with Ada.Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;
with Ada.Strings.Unbounded;
procedure Numeric_4 is
package Str renames Ada.Strings.Unbounded;
package T_IO renames Ada.Text_IO;
procedure Pop_Value;
procedure Push_Value;
function Get_Line return Str.Unbounded_String;
use Value_Functions;
use type Str.Unbounded_String;
begin
Main_Loop :
loop
T_IO.Put (">");
Operation := Get_Line;
...
elsif Operation = "e" then
-- insert e
Push_Value;
Values (1) := Ada.Numerics.e;
elsif Operation = "**" or else Operation = "^" then
-- power of x^y
Values (1) := Values (1) ** Values (2);
Pop_Value;
elsif Operation = "sqr" then
-- square root
Values (1) := Sqrt (Values (1));
elsif Operation = "root" then
-- arbritary root
Values (1) :=
Exp (Log (Values (2)) / Values (1));
Pop_Value;
elsif Operation = "ln" then
-- natural logarithm
Values (1) := Log (Values (1));
elsif Operation = "log" then
-- based logarithm
Values (1) :=
Log (Base => Values (1), X => Values (2));
Pop_Value;
elsif Operation = "exit" then
exit Main_Loop;
else
Push_Value;
F_IO.Get
(From => Str.To_String (Operation),
Item => Values (1),
Last => Dummy);
end if;
...
end loop Main_Loop;
return;
end Numeric_4;
Higher math
Trigonometric calculations
The full set of trigonometric functions are defined inside the generic package
Ada.Numerics.Generic_Elementary_Functions. All functions are defined for 2π and an
arbirtary cycle value (a full cycle of revolution).
with Ada.Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;
with Ada.Strings.Unbounded;
procedure Numeric_5 is
...
...
...
begin
Main_Loop :
loop
Display_Loop :
for I in reverse Value_Array'Range loop
Put_Line (Values (I));
end loop Display_Loop;
T_IO.Put (">");
Operation := Get_Line;
...
elsif Operation = "deg" then
-- switch to degrees
Cycle := 360.0;
elsif Operation = "rad" then
-- switch to degrees
Cycle := Ada.Numerics.Pi;
elsif Operation = "grad" then
-- switch to degrees
Cycle := 400.0;
elsif Operation = "pi" or else Operation = "π" then
-- switch to degrees
Push_Value;
Values (1) := Ada.Numerics.Pi;
elsif Operation = "sin" then
-- sinus
Values (1) := Sin (X => Values (1), Cycle => Cycle);
elsif Operation = "cos" then
-- cosinus
Values (1) := Cot (X => Values (1), Cycle => Cycle);
elsif Operation = "tan" then
-- tangents
Values (1) := Tan (X => Values (1), Cycle => Cycle);
elsif Operation = "cot" then
-- cotanents
Values (1) := Cot (X => Values (1), Cycle => Cycle);
elsif Operation = "asin" then
-- arc-sinus
Values (1) := Arcsin (X => Values (1), Cycle => Cycle);
elsif Operation = "acos" then
-- arc-cosinus
Values (1) := Arccos (X => Values (1), Cycle => Cycle);
elsif Operation = "atan" then
-- arc-tangents
Values (1) := Arctan (Y => Values (1), Cycle => Cycle);
elsif Operation = "acot" then
-- arc-cotanents
Values (1) := Arccot (X => Values (1), Cycle => Cycle);
...
end loop Main_Loop;
return;
end Numeric_5;
112 of 154 09/01/06 23:23
Ada Programming/All Chapters - Wikibooks, collection... http://en.wikibooks.org/wiki/Ada_Programming/All_C...
The Demo also contains an improved numeric output which behaves more like a normal
calculator.
Hyperbolic calculations
You guessed it: The full set of hyperbolic functions is defined inside the generic package
Ada.Numerics.Generic_Elementary_Functions.
with Ada.Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;
with Ada.Strings.Unbounded;
with Ada.Exceptions;
procedure Numeric_6 is
package Str renames Ada.Strings.Unbounded;
package T_IO renames Ada.Text_IO;
package Exept renames Ada.Exceptions;
...
begin
Main_Loop :
loop
Try :
begin
Display_Loop :
...
elsif Operation = "sinh" then
-- sinus hyperbolic
Values (1) := Sinh (Values (1));
elsif Operation = "cosh" then
-- cosinus hyperbolic
Values (1) := Coth (Values (1));
elsif Operation = "tanh" then
-- tangents hyperbolic
Values (1) := Tanh (Values (1));
elsif Operation = "coth" then
-- cotanents hyperbolic
Values (1) := Coth (Values (1));
elsif Operation = "asinh" then
-- arc-sinus hyperbolic
Values (1) := Arcsinh (Values (1));
elsif Operation = "acosh" then
-- arc-cosinus hyperbolic
Values (1) := Arccosh (Values (1));
elsif Operation = "atanh" then
-- arc-tangents hyperbolic
Values (1) := Arctanh (Values (1));
elsif Operation = "acoth" then
-- arc-cotanents hyperbolic
Values (1) := Arccoth (Values (1));
...
exception
when An_Exception : others =>
T_IO.Put_Line
(Exept.Exception_Information (An_Exception));
end Try;
end loop Main_Loop;
return;
end Numeric_6;
As added bonus this version supports error handling and therefore won't just crash when an
illegal calculation is performed.
Complex arithmethic
For complex arithmethic Ada provides the package Ada.Numerics.Generic_Complex_Types.
This package is part of the "special need Annexes" which means it is optional. The open
source Ada compiler GNAT implements all "special need Annexes" and therefore has complex
arithmethic available.
Since Ada support user defined operators all (+, -, *) operators have there usual meaning as
soon as the package Ada.Numerics.Generic_Complex_Types has been instanciated (package ...
is new ...) and the type has been made visible (use type ...)
So, with only a very few modifications you can convert your "normals" calculator to a
calculator for complex arithmetic:
with Ada.Text_IO.Complex_IO;
with Ada.Numerics.Generic_Complex_Types;
with Ada.Numerics.Generic_Complex_Elementary_Functions;
with Ada.Strings.Unbounded;
with Ada.Exceptions;
procedure Numeric_7 is
...
package Complex_Types is new Ada.Numerics.Generic_Complex_Types (
Value_Type);
package Complex_Functions is new
Ada.Numerics.Generic_Complex_Elementary_Functions (
Complex_Types);
package C_IO is new Ada.Text_IO.Complex_IO (Complex_Types);
type Value_Array is
array (Natural range 1 .. 4) of Complex_Types.Complex;
Values : Value_Array :=
(others => Complex_Types.Complex'(Re => 0.0, Im => 0.0));
...
procedure Put_Line (Value : in Complex_Types.Complex) is
begin
if (abs Value_Type'Exponent (Value.Re) >=
abs Value_Type'Exponent (10.0 ** C_IO.Default_Aft))
or else (abs Value_Type'Exponent (Value.Im) >=
abs Value_Type'Exponent (10.0 ** C_IO.Default_Aft))
then
C_IO.Put
(Item => Value,
Fore => C_IO.Default_Aft,
Aft => C_IO.Default_Aft,
Exp => 4);
else
C_IO.Put
(Item => Value,
Fore => C_IO.Default_Aft,
Aft => C_IO.Default_Aft,
Exp => 0);
end if;
T_IO.New_Line;
return;
end Put_Line;
begin
...
elsif Operation = "e" then
-- insert e
Push_Value;
Values (1) :=
Complex_Types.Complex'(Re => Ada.Numerics.e, Im => 0.0);
...
elsif Operation = "pi" or else Operation = "π" then
-- insert pi
Push_Value;
Values (1) :=
Complex_Types.Complex'(Re => Ada.Numerics.Pi, Im => 0.0);
elsif Operation = "sin" then
-- sinus
Values (1) := Sin (Values (1));
elsif Operation = "cos" then
-- cosinus
Values (1) := Cot (Values (1));
elsif Operation = "tan" then
-- tangents
Values (1) := Tan (Values (1));
elsif Operation = "cot" then
-- cotanents
Values (1) := Cot (Values (1));
elsif Operation = "asin" then
-- arc-sinus
Values (1) := Arcsin (Values (1));
elsif Operation = "acos" then
-- arc-cosinus
Values (1) := Arccos (Values (1));
elsif Operation = "atan" then
-- arc-tangents
Values (1) := Arctan (Values (1));
elsif Operation = "acot" then
-- arc-cotanents
Values (1) := Arccot (Values (1));
...
return;
115 of 154 09/01/06 23:23
Ada Programming/All Chapters - Wikibooks, collection... http://en.wikibooks.org/wiki/Ada_Programming/All_C...
Since there is no I/O package for vector and matrix I/O creating a demo is by far more
complex - and hence not ready yet. You can have a look at the curren progress which will be
a universal calculator merging all feature.
Status: Stalled - for a Vector and Matrix stack we need Indefinite_Vectors - wich are
currently not part of GNAT/Pro. Well I could use the booch components ...
See also
Wikibook
Ada Programming
Ada Programming/Delimiters/-
Ada Programming/Libraries/Ada.Numerics.Generic_Complex_Types
Ada Programming/Libraries/Ada.Numerics.Generic_Elementary_Functions
(http://www.adaic.com/standards/95aarm/html/RM-G-3.html) )
Statements
Note: there are some simplifications in the explanations below. Don't take anything too
literally.
This command has a verb ("Put_Line") and other details (what to print). In this case, the
command "Put_Line" means "show on the screen," not "print on the printer." The
programmer either gives the statement directly to the computer (by typing it while running a
special program), or creates a text file with the command in it. You could create a file called
"hi.txt", put the above command in it, and give the file to the computer.
If you have more than one command in the file, each will be performed in order, top to
bottom. So the file could contain:
This does seem like a lot of typing but don't worry: Ada allows you to declare shorter
aliasnames if you need a long statement very often.
The computer will perform each of these commands sequentially. It's invaluable to be able to
"play computer" when programming. Ask yourself, "If I were the computer, what would I do
with these statements?" If you're not sure what the answer is, then you are very likely to
write incorrect code. Stop and check the manual for the programming language you're using.
In the above case, the computer will look at the first statement, determine that it's a
Put_Line statement, look at what needs to be printed, and display that text on the computer
screen. It'll look like this:
Hi there!
Note that the quotation marks aren't there. Their purpose in the program is to tell the
computer where the text begins and ends, just like in English prose. The computer will then
continue to the next statement, perform its command, and the screen will look like this:
Hi there!
Strange things are afoot...
When the computer gets to the end of the text file, it stops. There are many different kinds of
statements, depending on which programming language is being used. For example, there
could be a beep statement that causes the computer to output a beep on its speaker, or a
window statement that causes a new window to pop up.
Also, the way statements are written will vary depending on the programming language.
These differences are fairly superficial. The set of rules like the first two is called a
programming language's syntax. The set of verbs is called its library.
This article is available in wikibook pseudocode, Ada, C, C++, Delphi and Python - do have a
look at the other languages as well.
Variables
Variables are references that stand in for a value that is contained at a certain memory
address.
Variables are said to have a value and may have a data type. If a variable has a type, then
only values of this type may be assigned to it. Variables do not always have a type.
A value can have many values of many different types: integers (7), ratios (1/2),
(approximations of) reals (10.234), complex numbers (4+2i), characters ('a'), strings
("hello"), and much more.
Different languages use different names for their types and may not include any of the above.
Assignment statements
An assignment statement is used to set a variable to a new value.
X := 10;
The example set the variable X to the integer value of 10. The assignment statement
overwrites the contents of the variable and the previous value is lost.
In some languages, before a variable can be used, it will have to be declared, where the
declaration specifies the type.
declare
X : Integer := 10;
begin
Do_Something (X);
end;
Uses
Variables store everything in your program. The purpose of any useful program is to modify
variables.
See also
Ada Reference Manual
3.3 Objects and Named Numbers
(http://www.adaic.com/standards/95lrm/html/RM-3-3.html) (Annotated
(http://www.adaic.com/standards/95aarm/html/AA-3-3.html) )
Lexical elements
Character set
The character set used in Ada programs is composed of:
Take into account that in Ada 95 the letter range includes accented characters and other
letters used in Western Europe languages, those belonging to the ISO Latin-1 character set,
as ç, ñ, ð, etc.
In Ada 2005 the character set has been extended to the full Unicode set, so the identifiers
and comments can be writen in almost any language in the world.
Ada is a case-insensitive language, i. e. the upper-case set is equivalent to the lower-case set
except in character string literals and character literals.
Lexical elements
In Ada we can find the following lexical elements:
Identifiers
Numeric literals
Character literals
String literals
Delimiters
Coments
Reserved words
Example:
Identifiers
Definition in BNF:
From this definition we must exclude the keywords that are reserved words in the language
and cannot be used as identifiers.
Examples:
Exercise: could you give the reason for not being legal for each one of them?
Numbers
The numeric literals are composed of the following characters:
digits 0 .. 9
the decimal separator .,
the exponentiation sign e or E,
the negative sign - and
the underscore _.
The underscore is used as separator for improving legibility for humans, but it is ignored by
the compiler. You can separate numbers following any rationale, e.g. decimal integers in
groups of three digits, or binary integers in groups of eight digits.
For example, the real number 98.4 can be represented as: 9.84E1, 98.4e0, 984.0e-1 or
0.984E+2, but not as 984e-1.
For integer numbers, for example 1900, it could be written as 1900, 19E2, 190e+1 or
1_900E+0.
A numeric literal could also be expressed in a base different to 10, by enclosing the number
between # characters, and preceding it by the base, which can be a number between 2 and
16. For example, 2#101# is 1012, that is 510. Another example, with exponent would be
16#B#E2, that is 11 × 16² = 2,560.
Character literals
Their type is Standard.Character. They are delimited by an apostrophe (').
Examples:
String literals
String literals are of type Standard.String. They are delimited by the quotation mark (").
Example:
Delimiters
Single delimiters are one of the following special characters:
Compound delimiters are composed of two special characters, and they are the following
ones:
Comments
Comments in Ada start with two consecutive hyphens (--) and end in the end of line.
Reserved words
Reserved words are equivalent in upper-case and lower-case letters, although the typical
style is the one from the Reference Manual, that is to write them in all lower-case letters.
In Ada some keywords have a different meaning depending on context. You can refer to Ada
Programming/Keywords and the following pages for each keyword.
Ada Keywords
abort else new return
abs elsif not reverse
abstract end null
accept entry select
access exception of separate
aliased exit or subtype
all others synchronized
and for out
array function overriding tagged
at task
generic package terminate
begin goto pragma then
body private type
if procedure
case in protected until
constant interface use
is raise
declare range when
delay limited record while
See also
Wikibook
Ada Programming
Ada Programming/Delimiters
Ada Programming/Keywords
Keywords
List of keywords
Ada Keywords
abort else new return
abs elsif not reverse
abstract end null
accept entry select
access exception of separate
aliased exit or subtype
all others synchronized
and for out
array function overriding tagged
at task
generic package terminate
begin goto pragma then
body private type
if procedure
case in protected until
constant interface use
is raise
See also
Wikibook
Ada Programming
Delimiters
;
semicolon
<
less than sign (also operator)
=
equal sign (also operator =)
>
greater than sign (also operator)
|
vertical line
Others
The following ones are special characters but not delimiters.
"
quotation mark, used in string literals.
#
number sign, used in number literals with base.
The following special characters are reserved but currently unused in Ada:
[
left square bracket
]
right square bracket
{
left curly bracket
}
right curly bracket
See also
Wikibook
Ada Programming
(http://www.adaic.com/standards/95lrm/html/RM-2-2.html) (Annotated
(http://www.adaic.com/standards/95aarm/html/AA-2-2.html) )
Operators
Standard operators
Ada allows operator overloading for all standard operators and so the following summaries
can only describe the suggested standard operations for each operator. It is quite possible to
misuse any standard operator to perform something unusual.
Each operator is either a keyword or a delimiter -- hence all operator pages are redirects to
the appropiate keyword or delimiter.
Logical operators
and
and , (also keyword and)
or
or , (also keyword or)
xor
exclusive or , (also keyword xor)
Relational operators
/=
Not Equal , (also special character /=)
=
Equal , (also special character =)
<
Less than , (also special character <)
<=
Less than or equal to ( ), (also special character <=)
>
Greater than ( ), (also special character >)
>=
Greater than or equal to ( ), (also special character >=)
+
Plus sign ( ) (also special character +)
-
Minus sign ( ), (also special character -)
Multiplying operator
*
Multiply, , (also special character *)
/
Divide , (also special character /)
mod
modulus (also keyword mod)
rem
remainder (also keyword rem)
Shortcut operators
The shortcut operators cannot be overloaded.
and then
e.g. if Y /= 0 and then X/Y > Limit then ...
or else
e.g. if Ptr = null or else Ptr.I = 0 then ...
Membership tests
The Membership Tests too cannot be overloaded.
in
element of, , e.g. if I in Positive then, (also keyword in)
not in
not element of, ,e.g. if I not in Positive then, (also keyword in)
See also
Wikibook
Ada Programming
Ada Operators
and and then > + abs &
or or else >= - mod
xor = < * rem in
not /= <= ** / not in
Attributes
A : Natural := Integer'Size; -- A is now 32 (with the GNAT compiler for the x86 architecture)
However, unlike the sizeof operator from C/C++ the Size attribute can also be set:
type Byte is range -128 .. 127; -- The range fits into 8 bits but the
-- compiler is still free to choose.
for Byte'Size use 8; -- Now we force the compiler to use 8 bits.
Of course not all attributes can be set. An attribute starts with a tick ' and is followed by its
name. The compiler determines by context if the tick is the beginning of an attribute or of a
character literal.
A–B
'Access
'Address
'Adjacent
'Aft
'Alignment
'Base
'Bit_Order
'Body_Version
C
'Callable
'Caller
'Ceiling
'Class
'Component_Size
'Compose
'Constrained
'Copy_Sign
'Count
D–F
'Definite
'Delta
'Denorm
'Digits
'Emax (Obsolescent)
'Exponent
'External_Tag
'Epsilon (Obsolescent)
'First
'First_Bit
'Floor
'Fore
'Fraction
G–L
'Identity
'Image
'Input
'Large (Obsolescent)
'Last
'Last_Bit
'Leading_Part
'Length
M
'Machine
'Machine_Emax
'Machine_Emin
'Machine_Mantissa
'Machine_Overflows
'Machine_Radix
'Machine_Rounding (Ada 2005)
'Machine_Rounds
'Mantissa (Obsolescent)
'Max
'Max_Size_In_Storage_Elements
'Min
'Mod (Ada 2005)
'Model
'Model_Emin
'Model_Epsilon
'Model_Mantissa
'Model_Small
'Modulus
O–R
'Output
'Partition_ID
'Pos
'Position
'Pred
'Priority (Ada 2005)
'Range
'Read
'Remainder
'Round
'Rounding
S
'Safe_Emax (Obsolescent)
'Safe_First
'Safe_Large (Obsolescent)
'Safe_Last
'Safe_Small (Obsolescent)
'Scale
'Scaling
'Signed_Zeros
'Size
'Small
'Storage_Pool
'Storage_Size
'Succ
T–V
'Tag
'Terminated
'Truncation
'Unbiased_Rounding
'Unchecked_Access
'Val
'Valid
'Value
'Version
W–Z
'Wide_Image
'Wide_Value
'Wide_Wide_Image (Ada 2005)
'Wide_Wide_Value (Ada 2005)
'Wide_Wide_Width (Ada 2005)
'Wide_Width
'Width
'Write
GNAT
This is an implementation defined attribute
(http://gcc.gnu.org/onlinedocs/gnat_rm/Implementation-Defined-Attributes.html) of the
GNAT compiler.
A–D
'Abort_Signal (GNAT)
'Address_Size (GNAT)
'Asm_Input (GNAT)
'Asm_Output (GNAT)
'AST_Entry (GNAT)
'Bit (GNAT)
'Bit_Position (GNAT)
'Code_Address (GNAT)
'Default_Bit_Order (GNAT)
E–H
'Elaborated (GNAT)
'Elab_Body (GNAT)
'Elab_Spec (GNAT)
'Emax (GNAT)
'Enum_Rep (GNAT)
'Epsilon (GNAT)
'Fixed_Value (GNAT)
'Has_Access_Values (GNAT)
'Has_Discriminants (GNAT)
I–N
'Img (GNAT)
'Integer_Value (GNAT)
'Machine_Size (GNAT)
'Max_Interrupt_Priority (GNAT)
'Max_Priority (GNAT)
'Maximum_Alignment (GNAT)
'Mechanism_Code (GNAT)
'Null_Parameter (GNAT)
O–T
'Object_Size (GNAT)
'Passed_By_Reference (GNAT)
'Range_Length (GNAT)
'Storage_Unit (GNAT)
'Target_Name (GNAT)
'Tick (GNAT)
'To_Address (GNAT)
'Type_Class (GNAT)
U–Z
'UET_Address (GNAT)
'Unconstrained_Array (GNAT)
'Universal_Literal_String (GNAT)
'Unrestricted_Access (GNAT)
'VADS_Size (GNAT)
'Value_Size (GNAT)
'Wchar_T_Size (GNAT)
'Word_Size (GNAT)
See also
Wikibook
Ada Programming
(http://www.adaic.com/standards/95lrm/html/RM-K.html) (Annotated
(http://www.adaic.com/standards/95aarm/html/AA-K.html) )
Pragmas
Description
Pragmas control the compiler, i.e. they are compiler directives. They have the standard form
of
Ada 2005
This is a new Ada 2005 pragma.
Obsolescent
This is a deprecated pragma and it should not be used in new code.
A–H
All_Calls_Remote
Assert (Ada 2005)
Assertion_Policy (Ada 2005)
Asynchronous
Atomic
Atomic_Components
Attach_Handler
Controlled
Convention
Detect_Blocking (Ada 2005)
Discard_Names
Elaborate
Elaborate_All
Elaborate_Body
Export
I–O
Import
Inline
Inspection_Point
Interface (Obsolescent)
Interrupt_Handler
Interrupt_Priority
Linker_Options
List
Locking_Policy
Memory_Size (Obsolescent)
No_Return (Ada 2005)
Normalize_Scalars
Optimize
P–R
Pack
Page
Partition_Elaboration_Policy (Ada 2005)
Preelaborable_Initialization (Ada 2005)
Preelaborate
Priority
Priority_Specific_Dispatching (Ada 2005)
Profile (Ada 2005)
Pure
Queueing_Policy
Remote_Call_Interface
Remote_Types
Restrictions
Reviewable
S–Z
Shared (Obsolescent)
Shared_Passive
Storage_Size
Storage_Unit (Obsolescent)
Suppress
System_Name (Obsolescent)
Task_Dispatching_Policy
Unchecked_Union (Ada 2005)
Unsuppress (Ada 2005)
Volatile
Volatile_Components
Currently, there are only listed the implementation defined attributes of the GNAT compiler.
You can help Wikibooks adding
(http://en.wikibooks.org/w/index.php?title=Ada_Programming/Pragmas&action=edit)
implementation dependent attributes of other compilers:
GNAT
This is an implementation defined pragma
(http://gcc.gnu.org/onlinedocs/gnat_rm/Implementation-Defined-Pragmas.html) of the
GNAT compiler.
A–C
Abort_Defer (GNAT)
Ada_83 (GNAT)
Ada_95 (GNAT)
Ada_05 (GNAT)
Annotate (GNAT)
Ast_Entry (GNAT)
C_Pass_By_Copy (GNAT)
Comment (GNAT)
Common_Object (GNAT)
Compile_Time_Warning (GNAT)
Complex_Representation (GNAT)
Component_Alignment (GNAT)
Convention_Identifier (GNAT)
CPP_Class (GNAT)
CPP_Constructor (GNAT)
CPP_Virtual (GNAT)
CPP_Vtable (GNAT)
D–H
Debug (GNAT)
Elaboration_Checks (GNAT)
Eliminate (GNAT)
Export_Exception (GNAT)
Export_Function (GNAT)
Export_Object (GNAT)
Export_Procedure (GNAT)
Export_Value (GNAT)
Export_Valued_Procedure (GNAT)
Extend_System (GNAT)
External (GNAT)
External_Name_Casing (GNAT)
Finalize_Storage_Only (GNAT)
Float_Representation (GNAT)
I–L
Ident (GNAT)
Import_Exception (GNAT)
Import_Function (GNAT)
Import_Object (GNAT)
Import_Procedure (GNAT)
Import_Valued_Procedure (GNAT)
Initialize_Scalars (GNAT)
Inline_Always (GNAT)
Inline_Generic (GNAT)
Interface_Name (GNAT)
Interrupt_State (GNAT)
Keep_Names (GNAT)
License (GNAT)
Link_With (GNAT)
Linker_Alias (GNAT)
Linker_Section (GNAT)
Long_Float (GNAT: OpenVMS)
M–S
Machine_Attribute (GNAT)
Main_Storage (GNAT)
Obsolescent (GNAT)
Passive (GNAT)
Polling (GNAT)
Profile_Warnings (GNAT)
Propagate_Exceptions (GNAT)
Psect_Object (GNAT)
Pure_Function (GNAT)
Restriction_Warnings (GNAT)
Source_File_Name (GNAT)
Source_File_Name_Project (GNAT)
Source_Reference (GNAT)
Stream_Convert (GNAT)
Style_Checks (GNAT)
Subtitle (GNAT)
Suppress_All (GNAT)
Suppress_Exception_Locations (GNAT)
Suppress_Initialization (GNAT)
T–Z
Task_Info (GNAT)
Task_Name (GNAT)
Task_Storage (GNAT)
Thread_Body (GNAT)
Time_Slice (GNAT)
Title (GNAT)
Unimplemented_Unit (GNAT)
Universal_Data (GNAT)
Unreferenced (GNAT)
Unreserve_All_Interrupts (GNAT)
Use_VADS_Size (GNAT)
Validity_Checks (GNAT)
Warnings (GNAT)
Weak_External (GNAT)
See also
Wikibook
Ada Programming
Ada 2005
Libraries: Standard
The Standard package is implicit. This means two things:
1. You do not need to with or use the package, in fact you cannot (see below). It's always
available (except where hidden by a homograph, RM 8.3 (8)
(http://www.adaic.com/standards/95lrm/html/RM-8-3.html) (Annotated
(http://www.adaic.com/standards/95aarm/html/AA-8-3.html) )).
2. Standard may contain constructs which are not quite legal Ada (like the definitions of
Character and Wide_Character).
A with clause mentioning Standard references a user-defined package Standard that hides
the predefined one. So do not do this. However any library unit hidden by a homograph can
be made visible again by qualifying its name with Standard, like e.g. Standard.My_Unit.
Implementation
Since the package Standard is very important for portability, here are some examples for
various compilers:
Portability
The only mandatory types in Standard are Boolean, Integer and its subtypes, Float,
Character, Wide_Character, String, Wide_String, Duration. There is an implementation
permission in RM A.1 (51) (http://www.adaic.com/standards/95lrm/html/RM-A-1.html)
(Annotated (http://www.adaic.com/standards/95aarm/html/AA-A-1.html) ) that there may be more integer
and floating point types and an implementation advice RM A.1 (52)
(http://www.adaic.com/standards/95lrm/html/RM-A-1.html) (Annotated
(http://www.adaic.com/standards/95aarm/html/AA-A-1.html) ) about the names to be chosen. There even
is no requirement that those additional types must have different sizes. So it is e.g. legal for
an implementation to provide two types Long_Integer and Long_Long_Integer which both
have the same range and size.
Note that the ranges and sizes of these types can be different in every platform (except of
course for Boolean and [Wide_]Character). There is an implementation requirement that the size of
type Integer is at least 16 bits, and that of Long_Integer at least 32 bits (if present) RM 3.5.4
(21..22) (http://www.adaic.com/standards/95lrm/html/RM-3-5-4.html) (Annotated
(http://www.adaic.com/standards/95aarm/html/AA-3-5-4.html) ). So if you want full portability of your
types, do not use types from Standard (except where you must, see below), rather define you own
types. A compiler will reject any type declaration whose range it cannot satisfy.
This means e.g. if you need a 64 bit type and find that with your current implementation
Standard.Long_Long_Integer is such a type, when porting your program to another
implementation, this type may be shorter, but the compiler will not tell you - and your
program will most probably crash. However, when you define your own type like
then, when porting to an implementation that cannot satisfy this range, the compiler will
reject your program.
The type Integer is mandatory when you use [wide] strings or exponentiation x**i. This is
why some projects even define their own strings, but this means throwing out the child with
the bath tub. Using Integer with strings and exponentiation will normally not lead to
portability issues.
See also
Wikibook
Ada Programming
Ada Programming/Libraries#Predefined Language Libraries
Libraries: Ada
The Ada package is only an anchor or namespace for Ada's standard library. Most compilers
will not allow you to add new packages to the Ada hierarchy and even if your compiler allows
it you should not do so since all package names starting with Ada. are reserved for future
extensions.
Ada 2005
This package is proposed for the Ada 2005 standard.
A–C
Ada.Assertions (Ada 2005)
Ada.Asynchronous_Task_Control
Ada.Calendar
Ada.Calendar.Arithmetic (Ada 2005)
Ada.Calendar.Formatting (Ada 2005)
Ada.Calendar.Time_Zones (Ada 2005)
Ada.Characters
Ada.Characters.Conversions (Ada 2005)
Ada.Characters.Handling
Ada.Characters.Latin_1
Ada.Command_Line
Ada.Complex_Text_IO (Ada 2005)
Ada.Containers (Ada 2005)
Ada.Containers.Doubly_Linked_Lists (Ada 2005)
Ada.Containers.Generic_Array_Sort (Ada 2005 generic procedure)
Ada.Containers.Generic_Constrained_Array_Sort (Ada 2005 generic procedure)
Ada.Containers.Hashed_Maps (Ada 2005)
Ada.Containers.Hashed_Sets (Ada 2005)
Ada.Containers.Indefinite_Doubly_Linked_Lists (Ada 2005)
Ada.Containers.Indefinite_Hashed_Maps (Ada 2005)
Ada.Containers.Indefinite_Hashed_Sets (Ada 2005)
Ada.Containers.Indefinite_Ordered_Maps (Ada 2005)
Ada.Containers.Indefinite_Ordered_Sets (Ada 2005)
Ada.Containers.Indefinite_Vectors (Ada 2005)
Ada.Containers.Ordered_Maps (Ada 2005)
Ada.Containers.Ordered_Sets (Ada 2005)
Ada.Containers.Vectors (Ada 2005)
D–F
Ada.Decimal
Ada.Direct_IO
Ada.Directories (Ada 2005)
Ada.Directories.Information (Ada 2005)
Ada.Dispatching (Ada 2005)
Ada.Dispatching.EDF (Ada 2005)
Ada.Dispatching.Round_Robin (Ada 2005)
Ada.Dynamic_Priorities
Ada.Environment_Variables (Ada 2005)
Ada.Exceptions
Ada.Execution_Time (Ada 2005)
Ada.Execution_Time.Timers (Ada 2005)
Ada.Execution_Time.Group_Budgets (Ada 2005)
Ada.Finalization
Ada.Float_Text_IO
Ada.Float_Wide_Text_IO
Ada.Float_Wide_Wide_Text_IO (Ada 2005)
G–R
Ada.Integer_Text_IO
Ada.Integer_Wide_Text_IO
Ada.Integer_Wide_Wide_Text_IO (Ada 2005)
Ada.Interrupts
Ada.Interrupts.Names
Ada.IO_Exceptions
Ada.Numerics
Ada.Numerics.Complex_Arrays (Ada 2005)
Ada.Numerics.Complex_Elementary_Functions
Ada.Numerics.Complex_Types
Ada.Numerics.Discrete_Random
Ada.Numerics.Elementary_Functions
Ada.Numerics.Float_Random
Ada.Numerics.Generic_Complex_Arrays (Ada 2005)
Ada.Numerics.Generic_Complex_Elementary_Functions
Ada.Numerics.Generic_Complex_Types
Ada.Numerics.Generic_Elementary_Functions
Ada.Numerics.Generic_Real_Arrays (Ada 2005)
Ada.Numerics.Real_Arrays (Ada 2005)
R–S
Ada.Real_Time
Ada.Real_Time.Timing_Events (Ada 2005)
Ada.Sequential_IO
Ada.Storage_IO
Ada.Streams
Ada.Streams.Stream_IO
Ada.Strings
Ada.Strings.Bounded
Ada.Strings.Bounded.Hash (Ada 2005 generic function)
Ada.Strings.Fixed
Ada.Strings.Fixed.Hash (Ada 2005 generic function)
Ada.Strings.Hash (Ada 2005 generic function)
Ada.Strings.Maps
Ada.Strings.Maps.Constants
Ada.Strings.Unbounded
Ada.Strings.Unbounded.Hash (Ada 2005 generic function)
Ada.Strings.Wide_Bounded
Ada.Strings.Wide_Bounded.Wide_Hash (Ada 2005 generic function)
Ada.Strings.Wide_Fixed
Ada.Strings.Wide_Fixed.Wide_Hash (Ada 2005 generic function)
Ada.Strings.Wide_Hash (Ada 2005 generic function)
Ada.Strings.Wide_Maps
Ada.Strings.Wide_Maps.Wide_Constants
Ada.Strings.Wide_Unbounded
Ada.Strings.Wide_Unbounded.Wide_Hash (Ada 2005 generic function)
Ada.Strings.Wide_Wide_Bounded (Ada 2005)
Ada.Strings.Wide_Wide_Bounded.Wide_Wide_Hash (Ada 2005 generic function)
Ada.Strings.Wide_Wide_Fixed (Ada 2005)
Ada.Strings.Wide_Wide_Fixed.Wide_Wide_Hash (Ada 2005 generic function)
Ada.Strings.Wide_Wide_Hash (Ada 2005 generic function)
Ada.Strings.Wide_Wide_Maps (Ada 2005)
Ada.Strings.Wide_Wide_Maps.Wide_Wide_Constants (Ada 2005)
Ada.Strings.Wide_Wide_Unbounded (Ada 2005)
Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Hash (Ada 2005 generic function)
Ada.Synchronous_Task_Control
T–U
Ada.Tags
Ada.Tags.Generic_Dispatching_Constructor (generic function)
Ada.Task_Attributes
Ada.Task_Identification
Ada.Task_Termination (Ada 2005)
Ada.Text_IO
Ada.Text_IO.Bounded_IO (Ada 2005)
Ada.Text_IO.Complex_IO
Ada.Text_IO.Decimal_IO (Nested package of Ada.Text_IO)
Ada.Text_IO.Editing
Ada.Text_IO.Enumeration_IO (Nested package of Ada.Text_IO)
Ada.Text_IO.Fixed_IO (Nested package of Ada.Text_IO)
Ada.Text_IO.Float_IO (Nested package of Ada.Text_IO)
Ada.Text_IO.Integer_IO (Nested package of Ada.Text_IO)
Ada.Text_IO.Modular_IO (Nested package of Ada.Text_IO)
Ada.Text_IO.Text_Streams
Ada.Text_IO.Unbounded_IO (Ada 2005)
Ada.Unchecked_Conversion (generic function)
Ada.Unchecked_Deallocation (generic procedure)
W–Z
Ada.Wide_Characters (Ada 2005)
Ada.Wide_Text_IO
Ada.Wide_Text_IO.Bounded_IO (Ada 2005)
Ada.Wide_Text_IO.Complex_IO
Ada.Wide_Text_IO.Decimal_IO (Nested package of Ada.Wide_Text_IO)
Ada.Wide_Text_IO.Editing
Ada.Wide_Text_IO.Enumeration_IO (Nested package of Ada.Wide_Text_IO)
Ada.Wide_Text_IO.Fixed_IO (Nested package of Ada.Wide_Text_IO)
Ada.Wide_Text_IO.Float_IO (Nested package of Ada.Wide_Text_IO)
Ada.Wide_Text_IO.Integer_IO (Nested package of Ada.Wide_Text_IO)
Ada.Wide_Text_IO.Modular_IO (Nested package of Ada.Wide_Text_IO)
Ada.Wide_Text_IO.Text_Streams
Ada.Wide_Text_IO.Unbounded_IO (Ada 2005)
Ada.Wide_Wide_Characters (Ada 2005)
Ada.Wide_Wide_Text_IO (Ada 2005)
Ada.Wide_Wide_Text_IO.Bounded_IO (Ada 2005)
Ada.Wide_Wide_Text_IO.Complex_IO (Ada 2005)
Ada.Wide_Wide_Text_IO.Decimal_IO (Nested package of Ada.Wide_Wide_Text_IO)
Ada.Wide_Wide_Text_IO.Editing (Ada 2005)
Ada.Wide_Wide_Text_IO.Enumeration_IO (Nested package of Ada.Wide_Wide_Text_IO)
Ada.Wide_Wide_Text_IO.Fixed_IO (Nested package of Ada.Wide_Wide_Text_IO)
Ada.Wide_Wide_Text_IO.Float_IO (Nested package of Ada.Wide_Wide_Text_IO)
Ada.Wide_Wide_Text_IO.Integer_IO (Nested package of Ada.Wide_Wide_Text_IO)
Ada.Wide_Wide_Text_IO.Modular_IO (Nested package of Ada.Wide_Wide_Text_IO)
Ada.Wide_Wide_Text_IO.Text_Streams (Ada 2005)
Ada.Wide_Wide_Text_IO.Unbounded_IO (Ada 2005)
Currently, there are only listed the implementation defined attributes of the GNAT compiler.
You can help Wikibooks adding
(http://en.wikibooks.org/w/index.php?title=Ada_Programming/Libraries/Ada&action=edit)
implementation dependent attributes of other compilers:
GNAT
Extended package implemented by GNAT
(http://gcc.gnu.org/onlinedocs/gnat_rm/The-GNAT-Library.html) .
ObjectAda
Extended package implemented by ObjectAda.
APEX
Extended package implemented by IBM/Rational APEX.
A–K
Ada.Characters.Latin_9 (GNAT)
Ada.Characters.Wide_Latin_1 (GNAT)
Ada.Characters.Wide_Latin_9 (GNAT)
Ada.Characters.Wide_Wide_Latin_1 (GNAT)
Ada.Characters.Wide_Wide_Latin_9 (GNAT)
Ada.Command_Line.Environment (GNAT)
Ada.Command_Line.Remove (GNAT)
Ada.Direct_IO.C_Streams (GNAT)
Ada.Exceptions.Is_Null_Occurrence (GNAT child function)
Ada.Exceptions.Traceback (GNAT)
L–Q
Ada.Long_Float_Text_IO (GNAT)
Ada.Long_Float_Wide_Text_IO (GNAT)
Ada.Long_Integer_Text_IO (GNAT)
Ada.Long_Integer_Wide_Text_IO (GNAT)
Ada.Long_Long_Float_Text_IO (GNAT)
Ada.Long_Long_Float_Wide_Text_IO (GNAT)
Ada.Long_Long_Integer_Text_IO (GNAT)
Ada.Long_Long_Integer_Wide_Text_IO (GNAT)
Ada.Numerics.Long_Complex_Elementary_Functions (GNAT)
Ada.Numerics.Long_Complex_Types (GNAT)
Ada.Numerics.Long_Elementary_Functions (GNAT)
Ada.Numerics.Long_Long_Complex_Elementary_Functions (GNAT)
Ada.Numerics.Long_Long_Complex_Types (GNAT)
Ada.Numerics.Long_Long_Elementary_Functions (GNAT)
Ada.Numerics.Short_Complex_Elementary_Functions (GNAT)
Ada.Numerics.Short_Complex_Types (GNAT)
Ada.Numerics.Short_Elementary_Functions (GNAT)
R–Z
Ada.Sequential_IO.C_Streams (GNAT)
Ada.Short_Float_Text_IO (GNAT)
Ada.Short_Float_Wide_Text_IO (GNAT)
Ada.Short_Integer_Text_IO (GNAT)
Ada.Short_Integer_Wide_Text_IO (GNAT)
Ada.Short_Short_Integer_Text_IO (GNAT)
Ada.Short_Short_Integer_Wide_Text_IO (GNAT)
Ada.Streams.Stream_IO.C_Streams (GNAT)
Ada.Strings.Unbounded.Text_IO (GNAT)
Ada.Strings.Wide_Unbounded.Wide_Text_IO (GNAT)
Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO (GNAT)
Ada.Text_IO.C_Streams (GNAT)
Ada.Wide_Text_IO.C_Streams (GNAT)
Ada.Wide_Wide_Text_IO.C_Streams (GNAT)
See also
Wikibook
Ada Programming
Ada Programming/Libraries
Ada Programming/Libraries/Standard
Ada Programming/Libraries/System
Ada Programming/Libraries/Interfaces
Libraries: Interfaces
The Interfaces package helps in interfacing with other programming languages. Ada is one of
the few languages where interfacing with other languages is part of the language standard.
The language standard defines the interfaces for C, Cobol and Fortran. Of course any
implementation might define further interfaces - GNAT for example defines an interface to
C++.
Interfacing with other languages is actually provided by pragma Export, pragma Import
and pragma Convention
Child Packages
Interfaces.C
Interfaces.C.Extensions (GNAT)
Interfaces.C.Pointers
Interfaces.C.Streams (GNAT)
Interfaces.C.Strings
Interfaces.CPP (GNAT)
Interfaces.COBOL
Interfaces.Fortran
Interfaces.OS2Lib (GNAT, OS/2)
Interfaces.OS2Lib.Errors (GNAT, OS/2)
Interfaces.OS2Lib.Synchronization (GNAT, OS/2)
Interfaces.OS2Lib.Threads (GNAT, OS/2)
Interfaces.Packed_Decimal (GNAT)
Interfaces.VxWorks (GNAT, VxWorks)
Interfaces.VxWorks.IO (GNAT, VxWorks)
See also
Wikibook
Ada Programming
Ada Programming/Libraries
Ada Programming/Libraries/Standard
Ada Programming/Libraries/Ada
Ada Programming/Libraries/System
Ada 2005
(http://www.adaic.com/standards/95aarm/html/AA-B.html) )
B.2 The Package Interfaces
(http://www.adaic.com/standards/rm-amend/html/RM-B-2.html) (Annotated
(http://www.adaic.com/standards/rm-amend/html/AA-B-2.html) )
Libraries: System
Libraries: GNAT
Child packages
GNAT.Array_Split
GNAT.AWK
GNAT.Bounded_Buffers
GNAT.Bounded_Mailboxes
GNAT.Bubble_Sort
GNAT.Bubble_Sort_A
GNAT.Bubble_Sort_G
GNAT.Calendar
GNAT.Calendar.Time_IO
GNAT.Case_Util
GNAT.CGI
GNAT.CGI.Cookie
GNAT.CGI.Debug
GNAT.Command_Line
GNAT.Compiler_Version
GNAT.CRC32
GNAT.Ctrl_C
GNAT.Current_Exception
GNAT.Debug_Pools
GNAT.Debug_Utilities
GNAT.Directory_Operations
GNAT.Directory_Operations.Iteration
GNAT.Dynamic_HTables
GNAT.Dynamic_Tables
GNAT.Exception_Actions
GNAT.Exceptions
GNAT.Exception_Traces
GNAT.Expect
GNAT.Float_Control
GNAT.Heap_Sort
GNAT.Heap_Sort_A
GNAT.Heap_Sort_G
GNAT.HTable
GNAT.IO
GNAT.IO_Aux
GNAT.Lock_Files
GNAT.MD5
GNAT.Memory_Dump
GNAT.Most_Recent_Exception
GNAT.OS_Lib
GNAT.Perfect_Hash_Generators
GNAT.Regexp
GNAT.Registry
GNAT.Regpat
GNAT.Secondary_Stack_Info
GNAT.Semaphores
GNAT.Signals
GNAT.Sockets
GNAT.Sockets_examples
GNAT.Sockets.Constants
GNAT.Sockets.Linker_Options
GNAT.Sockets.Thin
GNAT.Source_Info
GNAT.Spelling_Checker
GNAT.Spitbol
GNAT.Spitbol.Patterns
GNAT.Spitbol.Table_Boolean new
GNAT.Spitbol.Table_Integer
GNAT.Spitbol.Table_VString new
GNAT.Strings
GNAT.String_Split
GNAT.Table
GNAT.Task_Lock
GNAT.Threads
GNAT.Traceback
GNAT.Traceback.Symbolic
GNAT.Wide_String_Split
See also
External links
The GNAT Library (http://gcc.gnu.org/onlinedocs/gnat_rm/The-GNAT-Library.html)
Wikibook
Ada Programming
Ada Programming/Libraries
Libraries
Standard
Ada
Interfaces
System
GNAT
Multi Purpose
Container Libraries
GUI Libraries
Distributed Objects
Database
Web Programming
Input/Output
See also
Wikibook
Ada Programming
</noinclude> <noinclude>
Libraries: Multi-Purpose
See also
Wikibook
Ada Programming
Ada Programming/Libraries
Libraries: Container
The following Libraries help you in store an manage object inside container classes:
Booch Components
the most complete of all container class libraries (at least when used with AdaCL, Ada Class
Library).
AdaCL, Ada Class Library
A Booch Components extension pack for storing indefinite objects.
Charles
Build on the C++ STL and therefore very easy to learn for C++ developers.
AI302
Proof of concept for Ada.Containers
Ada.Containers
This language feature will be made available in the forthcoming Ada 2005 standard.
See also
Wikibook
Ada Programming
Ada Programming/Libraries
Libraries: GUI
The following Libraries can be used to make Graphic User Interfaces:
GtkAda
Ada version of the GTK+ libraries. Can be used on multiple platforms.
See also
Wikibook
Ada Programming
Ada Programming/Libraries
Libraries: Distributed
The following Libraries help you in Distributed programming:
GLADE
A full implementation of the Ada Annex E: Distributed Systems
(http://www.adaic.org/standards/95lrm/html/RM-E.html)
PolyORB
A CORBA and Annex E: Distributed Systems
(http://www.adaic.org/standards/95lrm/html/RM-E.html) implementation.
See also
Wikibook
Ada Programming
Ada Programming/Libraries
Programming:CORBA
Libraries: Database
The following Libraries help you in Database programming:
GNADE
description missing.
APQ
description missing.
GWindows
ODBC in Windows.
See also
Wikibook
Ada Programming
Ada Programming/Libraries
Libraries: Web
The following libraries help you in Internet or Web programming:
See also
Wikibook
Ada Programming
Ada Programming/Libraries
Libraries: IO
The following libraries help you when doing input/output:
See also
Wikibook
Ada Programming
Ada Programming/Libraries
Platform
Ada is known to be very portable, but there is sometimes a necessity of using a specific
platform feature. For that matter, there are some non-standard libraries.
Ada Programming/Platform/Linux
Ada Programming/Platform/VM
Ada Programming/Platform/VM/Java
Ada Programming/Platform/VM/dotNET
Ada Programming/Platform/Windows
Ada Programming/Platform/Windows/win32binding
See also
Wikibook
Ada Programming
Platform: Linux
The following libraries help you when you target the Linux Platform.
Florist
POSIX.5 binding. It will let you perform Linux system calls in the POSIX subset.
Ncurses
text terminal library.
Texttools
ncurses-based library for the Linux console.
GtkAda
GUI library (actually multiplatform).
See also
Wikibook
Ada Programming
Ada Programming/Libraries
External resources
The Big Online Book of Linux Ada Programming
(http://www.pegasoft.ca/resources/boblap/book.html)
Ada for GNU/Linux Team (ALT) (http://www.gnuada.org/alt.html) , a bit outdated.
Platform: Windows
The following Libraries and Tools help you when you target the MS-Windows Platform.
GWindows
Win32 binding
GNATCOM
COM/DCOM/ActiveX binding
GNAVI
Visual RAD (Rapid application development) Development environment
Console
Libraries for console I/O.
See also
Wikibook
Ada Programming
Ada Programming/Libraries
Platform: VM
The following libraries help you when you target a virtual machine.
Java
Programming Ada 95 in Java's JVM (JGnat)
.NET
Programming Ada 95 in C#'s CLI (A#)
See also
Wikibook
Ada Programming
Ada Programming/Libraries
Portals
147 of 154 09/01/06 23:23
Ada Programming/All Chapters - Wikibooks, collection... http://en.wikibooks.org/wiki/Ada_Programming/All_C...
AdaBasis (http://www.iste.uni-stuttgart.de/ps/ada-software/ada-software.html)
AdaBasis consists of about 560 MB of public domain source code and documents, mainly
taken from the Public Ada Library (PAL). The software has been classified and is
presented in a hierarchical manner, separated in different application domains, and, for
some domains, with an additional multi-faceted searching facility.
The intent is to provide students, teachers and researchers with a large collection of
reusable Ada components and systems for use in language and software engineering
courses.
AdaBasis was set up by the Programming Languages Group of the Institut für Informatik
at the University of Stuttgart, Germany. They plan to enlarge the library in the future,
and welcome free public domain contributions. For more informations or to make
suggestions please contact adabasis@informatik.uni-stuttgart.de
(mailto:adabasis@informatik.uni-stuttgart.de)
AdaWorld (http://www.adaworld.com/)
Here you'll find all the different projects that are either hosted here or elsewhere on the
web and talked about, documented and updated here. For the sake of organization, the
projects have been grouped into five categories, which will also be broken down into sub
categories where necessary.
AdaPower
(http://www.adapower.com/index.php?Command=Packages&Title=Packages+for+Reuse)
Ada Tools and Resources.
SourceForge (https://sourceforge.net/softwaremap/trove_list.php?form_cat=163)
Currently there are 102 Ada projects hosted at SourceForge - including the example
programs for Programming:Ada (https://sourceforge.net/projects/wikibook-ada) .
The Public Ada Library (PAL)
(http://www.iste.uni-stuttgart.de/ps/AdaBasis/pal_1195/ada/pal.html)
The PAL is a library of Ada and VHDL software, information, and courseware that
contains over 1 BILLION bytes of material (mainly in compressed form). All items in the
PAL have been released to the public with unlimited distribution, and, in most cases (the
exceptions are shareware), the items are freeware.
See also
Wikibook
Ada Programming
Ada Programming/Tutorials
Ada Programming/Wikis
0. PREAMBLE
The purpose of this License is to make a manual, textbook, or other functional and useful
document "free" in the sense of freedom: to assure everyone the effective freedom to copy
and redistribute it, with or without modifying it, either commercially or noncommercially.
Secondarily, this License preserves for the author and publisher a way to get credit for their
work, while not being considered responsible for modifications made by others.
This License is a kind of "copyleft", which means that derivative works of the document must
themselves be free in the same sense. It complements the GNU General Public License,
which is a copyleft license designed for free software.
We have designed this License in order to use it for manuals for free software, because free
software needs free documentation: a free program should come with manuals providing the
same freedoms that the software does. But this License is not limited to software manuals; it
can be used for any textual work, regardless of subject matter or whether it is published as a
printed book. We recommend this License principally for works whose purpose is instruction
or reference.
A "Modified Version" of the Document means any work containing the Document or a portion
of it, either copied verbatim, or with modifications and/or translated into another language.
The "Invariant Sections" are certain Secondary Sections whose titles are designated, as
being those of Invariant Sections, in the notice that says that the Document is released under
this License. If a section does not fit the above definition of Secondary then it is not allowed
to be designated as Invariant. The Document may contain zero Invariant Sections. If the
Document does not identify any Invariant Sections then there are none.
The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or
Back-Cover Texts, in the notice that says that the Document is released under this License. A
Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.
generic paint programs or (for drawings) some widely available drawing editor, and that is
suitable for input to text formatters or for automatic translation to a variety of formats
suitable for input to text formatters. A copy made in an otherwise Transparent file format
whose markup, or absence of markup, has been arranged to thwart or discourage
subsequent modification by readers is not Transparent. An image format is not Transparent
if used for any substantial amount of text. A copy that is not "Transparent" is called
"Opaque".
Examples of suitable formats for Transparent copies include plain ASCII without markup,
Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and
standard-conforming simple HTML, PostScript or PDF designed for human modification.
Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include
proprietary formats that can be read and edited only by proprietary word processors, SGML
or XML for which the DTD and/or processing tools are not generally available, and the
machine-generated HTML, PostScript or PDF produced by some word processors for output
purposes only.
The "Title Page" means, for a printed book, the title page itself, plus such following pages as
are needed to hold, legibly, the material this License requires to appear in the title page. For
works in formats which do not have any title page as such, "Title Page" means the text near
the most prominent appearance of the work's title, preceding the beginning of the body of
the text.
A section "Entitled XYZ" means a named subunit of the Document whose title either is
precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another
language. (Here XYZ stands for a specific section name mentioned below, such as
"Acknowledgements", "Dedications", "Endorsements", or "History".) To "Preserve the Title"
of such a section when you modify the Document means that it remains a section "Entitled
XYZ" according to this definition.
The Document may include Warranty Disclaimers next to the notice which states that this
License applies to the Document. These Warranty Disclaimers are considered to be included
by reference in this License, but only as regards disclaiming warranties: any other
implication that these Warranty Disclaimers may have is void and has no effect on the
meaning of this License.
2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either commercially or
noncommercially, provided that this License, the copyright notices, and the license notice
saying this License applies to the Document are reproduced in all copies, and that you add
no other conditions whatsoever to those of this License. You may not use technical measures
to obstruct or control the reading or further copying of the copies you make or distribute.
However, you may accept compensation in exchange for copies. If you distribute a large
enough number of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and you may publicly
display copies.
3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly have printed covers) of the
Document, numbering more than 100, and the Document's license notice requires Cover
Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both
covers must also clearly and legibly identify you as the publisher of these copies. The front
cover must present the full title with all words of the title equally prominent and visible. You
may add other material on the covers in addition. Copying with changes limited to the
covers, as long as they preserve the title of the Document and satisfy these conditions, can
be treated as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit legibly, you should put the first
ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto
adjacent pages.
If you publish or distribute Opaque copies of the Document numbering more than 100, you
must either include a machine-readable Transparent copy along with each Opaque copy, or
state in or with each Opaque copy a computer-network location from which the general
network-using public has access to download using public-standard network protocols a
complete Transparent copy of the Document, free of added material. If you use the latter
option, you must take reasonably prudent steps, when you begin distribution of Opaque
copies in quantity, to ensure that this Transparent copy will remain thus accessible at the
stated location until at least one year after the last time you distribute an Opaque copy
(directly or through your agents or retailers) of that edition to the public.
It is requested, but not required, that you contact the authors of the Document well before
redistributing any large number of copies, to give them a chance to provide you with an
updated version of the Document.
4. MODIFICATIONS
You may copy and distribute a Modified Version of the Document under the conditions of
sections 2 and 3 above, provided that you release the Modified Version under precisely this
License, with the Modified Version filling the role of the Document, thus licensing
distribution and modification of the Modified Version to whoever possesses a copy of it. In
addition, you must do these things in the Modified Version:
A. Use in the Title Page (and on the covers, if any) a title distinct from that of the
Document, and from those of previous versions (which should, if there were any, be listed
in the History section of the Document). You may use the same title as a previous version
if the original publisher of that version gives permission.
B. List on the Title Page, as authors, one or more persons or entities responsible for
authorship of the modifications in the Modified Version, together with at least five of the
principal authors of the Document (all of its principal authors, if it has fewer than five),
unless they release you from this requirement.
C. State on the Title page the name of the publisher of the Modified Version, as the
publisher.
D. Preserve all the copyright notices of the Document.
E. Add an appropriate copyright notice for your modifications adjacent to the other
copyright notices.
F. Include, immediately after the copyright notices, a license notice giving the public
permission to use the Modified Version under the terms of this License, in the form
shown in the Addendum below.
G. Preserve in that license notice the full lists of Invariant Sections and required Cover
Texts given in the Document's license notice.
H. Include an unaltered copy of this License.
I. Preserve the section Entitled "History", Preserve its Title, and add to it an item stating
at least the title, year, new authors, and publisher of the Modified Version as given on the
Title Page. If there is no section Entitled "History" in the Document, create one stating
the title, year, authors, and publisher of the Document as given on its Title Page, then
add an item describing the Modified Version as stated in the previous sentence.
J. Preserve the network location, if any, given in the Document for public access to a
Transparent copy of the Document, and likewise the network locations given in the
Document for previous versions it was based on. These may be placed in the "History"
section. You may omit a network location for a work that was published at least four
years before the Document itself, or if the original publisher of the version it refers to
gives permission.
K. For any section Entitled "Acknowledgements" or "Dedications", Preserve the Title of
the section, and preserve in the section all the substance and tone of each of the
contributor acknowledgements and/or dedications given therein.
L. Preserve all the Invariant Sections of the Document, unaltered in their text and in
their titles. Section numbers or the equivalent are not considered part of the section
titles.
M. Delete any section Entitled "Endorsements". Such a section may not be included in
the Modified Version.
N. Do not retitle any existing section to be Entitled "Endorsements" or to conflict in title
with any Invariant Section.
O. Preserve any Warranty Disclaimers.
If the Modified Version includes new front-matter sections or appendices that qualify as
Secondary Sections and contain no material copied from the Document, you may at your
option designate some or all of these sections as invariant. To do this, add their titles to the
list of Invariant Sections in the Modified Version's license notice. These titles must be
distinct from any other section titles.
You may add a section Entitled "Endorsements", provided it contains nothing but
endorsements of your Modified Version by various parties--for example, statements of peer
review or that the text has been approved by an organization as the authoritative definition
of a standard.
You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25
words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version.
Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or
through arrangements made by) any one entity. If the Document already includes a cover
text for the same cover, previously added by you or by arrangement made by the same entity
you are acting on behalf of, you may not add another; but you may replace the old one, on
explicit permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this License give permission to use
their names for publicity for or to assert or imply endorsement of any Modified Version.
5. COMBINING DOCUMENTS
You may combine the Document with other documents released under this License, under
the terms defined in section 4 above for modified versions, provided that you include in the
combination all of the Invariant Sections of all of the original documents, unmodified, and list
them all as Invariant Sections of your combined work in its license notice, and that you
preserve all their Warranty Disclaimers.
The combined work need only contain one copy of this License, and multiple identical
Invariant Sections may be replaced with a single copy. If there are multiple Invariant
Sections with the same name but different contents, make the title of each such section
unique by adding at the end of it, in parentheses, the name of the original author or
publisher of that section if known, or else a unique number. Make the same adjustment to
the section titles in the list of Invariant Sections in the license notice of the combined work.
In the combination, you must combine any sections Entitled "History" in the various original
documents, forming one section Entitled "History"; likewise combine any sections Entitled
"Acknowledgements", and any sections Entitled "Dedications". You must delete all sections
Entitled "Endorsements."
6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other documents released under
this License, and replace the individual copies of this License in the various documents with
a single copy that is included in the collection, provided that you follow the rules of this
License for verbatim copying of each of the documents in all other respects.
You may extract a single document from such a collection, and distribute it individually
under this License, provided you insert a copy of this License into the extracted document,
and follow this License in all other respects regarding verbatim copying of that document.
If the Cover Text requirement of section 3 is applicable to these copies of the Document,
then if the Document is less than one half of the entire aggregate, the Document's Cover
Texts may be placed on covers that bracket the Document within the aggregate, or the
electronic equivalent of covers if the Document is in electronic form. Otherwise they must
appear on printed covers that bracket the whole aggregate.
8. TRANSLATION
Translation is considered a kind of modification, so you may distribute translations of the
Document under the terms of section 4. Replacing Invariant Sections with translations
requires special permission from their copyright holders, but you may include translations of
some or all Invariant Sections in addition to the original versions of these Invariant Sections.
You may include a translation of this License, and all the license notices in the Document,
and any Warranty Disclaimers, provided that you also include the original English version of
this License and the original versions of those notices and disclaimers. In case of a
disagreement between the translation and the original version of this License or a notice or
disclaimer, the original version will prevail.
9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document except as expressly
provided for under this License. Any other attempt to copy, modify, sublicense or distribute
the Document is void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under this License will not
have their licenses terminated so long as such parties remain in full compliance.
Each version of the License is given a distinguishing version number. If the Document
specifies that a particular numbered version of this License "or any later version" applies to
it, you have the option of following the terms and conditions either of that specified version
or of any later version that has been published (not as a draft) by the Free Software
Foundation. If the Document does not specify a version number of this License, you may
choose any version ever published (not as a draft) by the Free Software Foundation.
External links
GNU Free Documentation License (Wikipedia article on the license)
Official GNU FDL webpage (http://www.gnu.org/copyleft/fdl.html)
Categories: Books with print version | Ada Programming/Ada 2005 feature | Section stubs |
Ada Programming | Wikibooks enforced policies | Ada programming language | Programming