-- this file illustrates conventional programming techniques in Ada
with Text_Io, Ada.Integer_Text_Io;
use Text_Io, Ada.Integer_Text_Io;
with Ada.Float_Text_Io; use Ada.Float_Text_Io;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
procedure Lotsastuff is
-- spec section
X : Integer;
X1, X2 : Integer;
Y : Integer := 0;
F : Float;
P : Boolean := True; -- can be false also
S1 : String(1..5); -- fixed length string
S2 : Unbounded_String;
-- arrays
type Myartype is array(0..3) of Integer; -- array indices are 0-3, not 0-2!
M0 : Myartype;
M1 : Myartype;
-- note: M1 : array(0..3) of Integer; -- is not same type as m0
-- that is, you'll not be able to treat m0 and m1 to be of the same type.
-- This is part of the very strongly typed aspect of Ada95. Better safe
-- than sorry.
-- boolean operators:
-- not, and then, or else, and , or
-- (A or else B) is A || B
-- in Ada, the logical connectives have two forms: there's "and" and
-- "or", and "and then" and "or else". "and" and "or" uses eager
-- evaluation (call by value) while "and then" and "or else" are like in
-- C/Java: they're short-circuited.
-- function that returns a boolean (x is an "in" parameter by default):
function Isbig(X : Integer) return Boolean is
Anothervar : Float;
begin -- body of isbig
Anothervar := 3.14;
if (X>50 and then 3>2) then return True; else return False; end if;
end Isbig;
-- definition of a record type, similar to 'struct' in C - not oop.
type Rational is
record
Numerator : Integer;
Denominator : Integer;
end record;
-- procedure to invert rational as an in out parameter
procedure Invert(R : in out Rational) is
Temp : Integer;
begin
if not(R.Numerator = 0) then
Temp := R.Numerator;
R.Numerator := R.Denominator;
R.Denominator := Temp;
end if;
end Invert;
-- printing a rational number with formated output
procedure Printrat(R: Rational) is
begin
Put(R.Numerator,Width=>1);
Put("/"); Put (R.Denominator,Width=>1);
end Printrat;
Myrat : Rational; -- a rational to be used in body of main program
-- linked list record type
type Node; -- prototype for forward reference
type Nodept is access Node; -- pointer, sort of
type Node is
record
Head: Integer;
Tail: Nodept;
end record;
-- familiar "cons"tructor for linked lists:
function Cons(H:Integer;T:Nodept) return Nodept is
Newnode : Nodept;
begin
Newnode := new Node;
Newnode.Head := H;
Newnode.Tail := T;
return Newnode;
end Cons;
-- why don't you define car and cdr!
L : Nodept;
begin -- body section of lotsastuff
Myrat.Numerator := 1;
Myrat.Denominator := 2;
Invert(Myrat);
Printrat(Myrat); New_Line;
-- static scoping of variables:
X := 2;
declare -- let
X : Integer; -- local specs can also contain functions and procedures.
Y : Character;
begin
X := 3; -- affects only local x
Y := 'A';
end;
Put(X); New_Line; -- should print 2
-- array access;
M1(2) := 3;
M1 := (2,4,6,8); -- can also inline array expressions such as (2,4,6,8).
M0 := (2,4,6,8);
-- can compare equality of entire arrays:
if (M1 = M0) then Put("true"); else Put("false"); end if;
New_Line;
-- strings. "abcd" is a bounded string of type String(1..4);
-- if you declared S : String(1..4), you MUST assign it 4 characters!
-- This is stupid, but it's the way it is. Every language have annoying
-- stuff.
S2 := To_Unbounded_String("abcdefg"); -- converts string to unbounded
Put(To_String(S2)); -- must convert to regular string before printing.
-- A "reverse for loop"
-- note again, array indices work differently from C/Java: they do not need
-- to start from 0 (in this case they do), and if you declared array(0..3)
-- then the valid indices are indeed from 0 to 3, not 0 to 2 as you might
-- expect from C/Java.
for I in reverse 0..3 loop
Put(M1(I),Width=>1);
end loop;
New_Line;
-- use of linked lists.
L := Cons(3,(Cons(5,null)));
Put(L.Tail.Head); New_Line;
-- case statements - similar to cond or switch:
case L.Head is
when 1 => Put("head is 1");
when 2..4 => begin Put("head is between "); Put("2 and 4"); end;
when others => put("head is something else"); -- "others" is keyword
end case;
New_Line;
end Lotsastuff;
-- output of this program:
-- 2/1
-- 2
-- true
-- abcdefg8642
-- 5
-- head is between 2 and 4