-- This program introduces basic features of Ada:
-- Standard types, i/o, operators, strong typing, control structures
with ada.text_io; use ada.text_io; -- IO of characters and strings
with ada.integer_text_io; use ada.integer_text_io; -- IO of integers
-- Case insensitive:
with ada.float_text_io; use ADA.FLOAT_TEXT_IO; -- IO of floats
procedure intro_all is
-- All of these types are automatically available from package Standard
-- SIMPLE NUMERIC TYPES - Unitialized
i, j, k, int_sum, int_avg: Integer;
f, g, flt_sum, flt_avg: Float;
-- NUMERIC SUBTYPES - Initialized
m, n: Natural := 1; -- 0 .. Integer'last. Same operations as integer.
p, q: Positive := 2; -- 1 .. Integer'last. Same operations as integer.
-- CONSTANT (of a specified type)
c: constant Integer := 3;
-- NAMED NUMBERS - no type!
pi: constant := 3.14159_26535_89793_23846_26433_83279_50288_41971_69399_37510;
two_pi: constant := 2 * pi;
one_third: constant := 1 / 3; -- Really 1/3!
one: constant := 3 * one_third; -- Really one!
-- TYPE BOOLEAN: true or false
less: Boolean;
-- ENUMERATED Type
type Color is (red, blue, green);
my_car_color: Color := red;
type Days is (Sun, Mon, Tues, Wed, Thu, Fri, Sat);
today, tomorrow: Days := Fri;
package Days_IO is new Ada.Text_IO.Enumeration_IO(Days);
use Days_IO;
-- Type for a single 8-bit CHARACTER
a_char: Character := 's';
-- FIXED LENGTH STRINGS: A String is an array of Characters
-- Include lengths in name for later reference
s3: String := "bat"; -- initialized, size 3
s5: String(1 .. 5); -- not initialized
s6: String(1 .. 6);
s8: String(1 .. 8);
s10: String(1 .. 10);
s12: String(1 .. 12);
-- UNBOUNDED LENGTH STRINGS: see package Ada.Strings.Unbounded
begin
-- NUMERIC, STRING, and CHARACTER INPUT:
-- values from Standard Input are returned in the parameter!
-- numeric skips white space, looking for a number
-- character and string skip newline but not spaces
put("Enter an int, a nat, a string, a float, a string, a float and a character: ");
get(i); -- next integer, skips white space
get(j); -- next integer, skips white space
get(s5); -- 5 characters, skips end of line
get(f); -- next float, skips white space
get(s6); -- 6 characters, skips end of line
get(g); -- next float, skips white space
get(a_char); -- 1 character, skips end of line
-- Strings are arrays of characters:
s3(2) := 'i'; -- s3 is now "bit". Index starts at 1.
-- FIXED LENGTH STRING OPERATIONS: String lengths must match
s8 := s3 & s5;
s10 := s3 & s6 & a_char;
s12 := s3 & s6 & a_char & "!!";
put_line(s8);
put_line(s10);
put_line(s12);
-- ARITHMETIC OPERATIONS
k := i + j;
k := i - j;
k := i * j;
k := i / j; -- truncates
k := 2 ** 10; -- 1024
k := 13 mod 10; -- 3 -- Mod and rem identical for positives
k := 13 rem 10; -- 3
k := (-2) mod 12; -- 10 Useful for clock arithmetic
k := (-2) rem 12; -- -2 Like Java % operator
put("AREA: "); put(pi * f ** 2); new_line;
-- STRONG TYPING: ASSIGNMENT, EXPRESSIONS, PUT
-- Cannot mix types! These are all okay.
flt_sum := f + g;
int_sum := i + j;
int_avg := int_sum / 2;
flt_avg := flt_sum / 2.0;
flt_avg := float(int_sum) / 2.0; -- TYPE CONVERSION
flt_avg := float(int_sum / 2);
-- TYPE CHECKING FOR SUBTYPES
get(n);
i := n; -- Can mix parent types and subtypes. Where can errors occur?
get(i);
n := i;
p := i;
p := n;
n := p;
-- OUTPUT INTEGERS and FLOATS - No put_line for numeric
put(i); new_line; -- Default width: 11
put(i, 4); new_line; -- Minimum width 4
-- KEYWORD PARAMETERS
put(item => i, width => 4); new_line;
put(f, 4, 5, 0); new_line; -- Put is OVERLOADED
put(item => f, fore => 4, aft => 5, exp => 0); new_line;
-- 'IMG AND TYPE'IMAGE CONVERT TO A STRING, LIKE to_string
put_line(i'img); -- 'img is not standard: provided by GNAT
put_line(f'img);
put_line(integer'image(i));
put_line(float'image(f));
-- ENUMERATED TYPE
if my_car_color = red then
put_line("It's red!");
else
put_line("It's not red!");
end if;
if today in sat | sun then
put("Weekend!");
end if;
if today not in mon .. fri then -- Another way
put("Weekend!");
end if;
tomorrow := (if today = sat then sun else Days'Succ(today));
for d in Days loop
Days_IO.put(d);
put(Days'pos(d));
Days_IO.put(Days'val(Days'pos(d)));
new_line;
end loop;
for c in Color loop
if c = my_car_color then
put(c'img);
end if;
end loop;
-- Can also instantiate Ada.Text_IO.Enumeration_IO for get and put for colors
-- BOOLEAN
less := i < j; -- assign a boolean variable
put_line(less'img);
-- CONTROL STRUCTURES, BOOLEAN OPERATIONS: AND, OR, NOT, XOR
if less then
put_line(i'img & " < " & j'img);
elsif NOT (i = j) OR f > g then
put(i);
put(" /= ");
put_line(j'img & "OR f > g");
-- IN operator and a range
-- () required when mixing and, or
elsif i in 1 .. 10 and (j not in 1 .. 10 xor i * j /= 25) then
put_line("Interesting");
elsif f in 1.1 .. 2.1 then -- Ranges work for floats, too
put_line("Great, floats too");
else
put_line(i'img & " > " & j'img);
end if;
-- SHORT CIRCUIT EVALUATION: AND THEN, OR ELSE
if j /= 0 AND THEN i > 5 then -- Stop if NOT j/=0
put(i / j); new_line;
elsif i = 0 OR ELSE j = 0 then -- Stop if i=0
put_line("One or the other is 0");
end if;
-- CASE MUST ACCOUNT FOR ALL VALUES.
-- All branches must be disjoint
case i is
when 1 =>
put_line("It's one");
when 5 | 3 =>
put_line("It's three or five");
when 20 .. 29 =>
put_line("It's in the 20's");
when 7 | 30 .. 39 | 9 =>
put_line("It's 7 or 9 or in the 30's");
when others =>
put_line("It's neither odd <= 10,");
put_line("or in 20's or 30's");
end case;
int_sum := 0;
for k in i .. j loop -- RANGE ALLOWED TO BE EMPTY!
int_sum := int_sum + k;
end loop;
for k in reverse 1 .. 10 loop
put(k); -- Prints 10 to 1
end loop;
flt_sum := 0.0;
while i < 2 * j loop
flt_sum := flt_sum + f;
i := i + 1;
end loop;
put(f, 2, 2, 0);
new_line;
loop -- loop and a half
get(f);
exit when f < 0.0;
put(f, 2, 2, 0);
end loop;
new_line(2); -- two newlines
put_line("DONE");
end intro_all;