procedure sumSquares(v, w: in integer; x: out integer) is begin x := v**2 + w**2; end demo; answer: integer; begin sumSquares(10,20, answer); -- answer is passed in to get the result end sumSquares;In this example, we say that we pass
answer
to sumSquares
.
What we mean is that we tell sumSquares
to put its
result into the variable answer
.
and
and or
ALWAYS evaluate both of their
operators.
This is useful if evaluating the second operand would fail, as in
if x /= 0 and then y / x > 3 thenIt is important to consider the difference between regular and short circuit if evaluating the second operand causes a side effect!
with ada.long_long_integer_text_io; with ada.integer_text_io; with ada.long_long_float_text_io; ... ada.long_long_integer_text_io.put(long_long_integer'last); ada.integer_text_io.put(long_long_integer'size); ada.long_long_float_text_io.put(long_long_float'last); ada.integer_text_io.put(long_long_float'size); ada.integer_text_io.put(long_long_float'mantissa);
f: Float := Float(3);There is a slight difference from Java in how casting to an integer works, as seen here:
int i = (int) (5.0 / 2.0); // i is 2 i: Integer := Integer( (5.0 / 2.0) ); // i is 3
type MyArray is array(first .. last) of Type; type MyRecord is record field1: Type1 := initialValue; -- Initialize a field field2: Type2; -- Must be a named type (ie not an anonymous array type) end record; Type MyEnum is (newValue1, newValue2, newValue3);Remember that these just define types; they do not allocate anything.
type Temperature is range 0 .. 100; type Pressure is range 10 .. 50; t: Temperature; p: Pressure; ... t := p; -- Causes a type error t := Temperature'last; -- Temperature'last is 100 t := t + 1; -- will cause a Constraint ErrorThe compiler considers Temperature and Pressure to be new types that can't be mixed. Subtypes (such as Natural and Positive) have some similar features to new numeric types but they can be mixed (ie you can assign a Positive to a Natural). More information on subtypes is further on in this section.
procedure minutes is -- MinuteType takes values from 0 to 59 type MinuteType is mod 60; package Minute_IO is new Text_IO.Modular_IO (Num => MinuteType); use Minute_IO; m: MinuteType; begin m := 50; m := m + 20; put(m); -- Output: 10C and C++ have unsigned types. Java's only unsigned type is char.
type Color is (red, blue, green);
introduces
red
, etc as new literals as values that can be taken on by program variables.
For example: roomColor: Color := red;
type Character is ( -- some lines deleted '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', -- some lines deleted )The FAQ section on Characters and Strings shows examples of using attributes Character'pos and Character'val.
with Ada.Text_IO; procedure tryEnum is type Color is (red, blue, green); package Color_IO is new Ada.Text_IO.Enumeration_IO(Color); use Color_IO; c: Color; begin Color_IO.get(c); -- Enter blue here, for example put(c); -- output: blue put(Color'pos(c)); -- output: 1 (for input blue) put(Color'val(red)); -- output: 0
with Ada.Text_IO; procedure tryEnum is type Grade is ('A', 'B', 'C', 'D', 'F'); package Grade_IO is new Ada.Text_IO.Enumeration_IO(Grade); use package Grade_IO; c: Grade; begin get(c); -- Example Input: 'B' put(c); -- output: 'B' put(Grade'pos(c)); -- output: 1 (for input 'B') get(c); -- Example Input: B -- causes a DATA ERROR
subtype Natural is Integer range 0 .. Integer'Last; subtype Positive is Integer range 1 .. Integer'Last;We can also define subtypes using inheritance, which is not discussed further here.
i1,i2: Integer; n1, n2: Natural; ... i1 := n1; n2 := i2;Both of these assignments compile. At runtime, the first will always succeed; however the second can generate a Constraint Error, which will occur if
i2
is negative.
Thus, for the second, the compiler generates code that checks at run time
whether the value of i2
is a Natural.
Parent p1, p2; Child c1, c2; ... p1 = c1; c2 = (Child) p2; c2 = p2; // Compile errorThe first assignment will always succeed; however the second can generate a ClassCastException if, for example, p2 is a reference to an instance of class Parent. The third assignment does not compile; a cast is required to tell to the compiler to accept the assignment, even though it is dangerous. In the second case, the compiler will generate code to check the value of
p2
at runtime to verify that it references an instance of class Child.
int i1, i2; long l1, l2; l2 = i2; // Cast not required, always succeeds i1 = (int) l1; // Requires a cast, what happens if l1 is not a valid int? i1 = l1; // Compiler error: requires a castThe first assignment is a widening conversion, which always succeeds. The second (and third) is a narrowing conversion, which requires a cast to tell the compiler to do the narrowing conversion, even though at runtime the value of
l1
may not be a valid int
.
Integer'Image, as in "s: String := Integer'Image(v);
".
Gnat also provides a 'Img attribute, which is similar.
Other types also have 'Image attributes.
Integer'Value, as in "v: Integer := Integer'value("123");
"
type String is array(Positive range <>) of Character;
Character'Pos
, as in "n: Natural := Character'Pos(c);
"
declare subtype Digit is Natural range 0 .. 9; subtype DigitChar is Character range '0' .. '9'; function charToInt(c: DigitChar) return Digit is begin return Character'Pos(c) - Character'Pos('0'); end charToInt; begin ada.integer_text_io.put(charToInt('2'));
Character'Val
, as in "c: Character := Character'Val(n);
".
put_line("ABC" & Ada.Characters.Latin_1.HT & "DEF");
while not end_of_file loop get(c); put(c); end loop;However, this does not print any newlines since get(c) skips newlines. Here is a version that preserves the newlines.
while not end_of_file loop if end_of_line then new_line; skip_line; else get(c); put(c); end if; end loop;To actually read the individual end of line characters as characters, you can use
Ada.Sequential_IO
.
Below is an example that does this. It opens and reads from the file "myFile.txt";
I don't know how to do the same from Standard Input.
with Ada.Sequential_IO; with ada.text_io; use ada.text_io; procedure putch3 is package Char_IO is new Ada.Sequential_IO(Character); use Char_IO; MyFile: Char_IO.File_Type; c: character; begin open (File => MyFile, Name => "myFile.txt", Mode => In_File); while not end_of_file(MyFile) loop read (MyFile, c); put(c); -- put_line(character'pos(c)); -- If you want the ASCII value of c end loop; Close (File => MyFile); end putch3;
C: Character; EOL: Boolean; N: Integer; ... loop exit when end_of_file; look_ahead(C, EOL); if EOL then skip_line; elsif is_digit(C) then get(N); else get(C); end if; end loop
.all
mean pp
is of type
PersonPtr
(ie pp
is a pointer to a Person
)
the pp.all
is the name of the Person
that pp
points
to. This is the entire Person
, so that it is legal to say:
aPerson: Person := pp.all;If
Person
is a record type (which would normal),
to get to a field of a person, say something like
p.all.name
or
p.all.address
.
When accessing a field, the .all
is optional.
Foo myFoo = new Foo();
the class Foo
is used for both the type of
the reference variable myFoo
and for the class of the object that myFoo
refers to. Thus, Java
conflates (ie munges) two separate concepts. In Ada, there are separate types for the
pointer and for the object pointed to, keeping these two concepts separate.
Here's the answer for generics. Imagine that you have a generic package called package A and you want to add child package B to package A. No changes to A are required. B must be generic as well. Simply create a generic package called A.B. Example is here
function foo(a, b: integer) return integer is begin if a=b then return a; end if; end foo;the return will not be executed if a and b are different. The compiler compiles the routine, but warns you that a runtime error might occur.
type MyArray is array (1 .. 100) of Integer; type foofoo is record a: array (1..100) of integer; -- Will not compile b: MyArray; -- Will compile end record
procedure foo1(a: array(1..10) of integer) is -- Not allowed type MyArrayType is array(1..10) of integer) -- Define a type procedure foo2(a: array(1..10) of integer) is -- Pass a var of that type
a
can't be used with the dot notation.
This is typically because either a
is not variable of record type or the implementation of a
is not visible.
In other words, you are treating the variable a
as if it were of
record type with fields (ie you might be saying a.x
), and
it is not.
The error message makes more sense if you know that
"selected component" is Ada's name for an entity of the form
"prefix.selector". Thus, in a.x := b.y + 3
, both
a.x
and b.y
are selected components,
and in the first selected component, the prefix is a
and in
the second, the prefix is b
.
for c in 'a' .. 'z' loopThe answer is that the compiler can't tell if 'a' is a literal of type Character or of type Wide_Character. You can tell it which it is supposed to be by using a type qualifier, like this:
for c in Character'('a') .. 'z' loopDon't confuse the type qualifier above with a type conversion (which does not have the quote).
:filetype indent on :filetype plugin on :syntax enablePut these commands in your .vimrc to have them execute automatically.
:echo $MYVIMRC
:set makeprg=gnatmake\ %After you have done this command, you can use :make to compile your file.
:set makeprg=gnatmake\ %
:abbrev atio ada.text_ioyou can input atio to get the library name. You can put this command into your ada.vim file or you can put it (any other ada specific commands that you might have) in a file called
ada.vim
in a directory called ftplugin
in your vimfiles directory.
The vimfiles directory can be in a directory called .vim in your H: drive or,
on your own machine, it can be in a directory called vimfiles in the directory where
you have vim installed.