## Computer Science 1

### Just The Basics

The purpose of this document is to provide just enough Ada programming information for an entry level student to succeed in a first programming class (Computer Science CS1). As in any introductory programming class, some topics are omitted. Do not waste your time looking for such things as generic units; this type of information is just not here.

The reserved words are in upper case (like RECORD) for easy recognition.

### Index

Basic Structure
Variables and Data Types
Variable Declarations
Variable Initialization
Literals
Constants
Enumeration Types
ARRAYs
Strings
Conversion
RECORDs
PACKAGEs
PACKAGE Declaration
PACKAGE BODY
PACKAGE Usage
Statements and Expressions
FOR LOOPs
Infinite LOOPs
Simple Expressions
IF THEN ELSE
CASE
Operators and Precedence Order
Concatenation
Input and Output
WITH and USE For I/O
Input from Standard Input
Output to Standard Output
Redirection
File Open
File Close
File Input Using Strings
Subprograms
Parameter Modes
FUNCTIONs
PROCEDUREs
Recursion
Basic Structure

The simplest form of a program is given below (beginning with PROCEDURE and ending with an END statement. The sample program intro_03 computes the first twenty fibonacci numbers. Note that comments begin with -- in Ada.

```
PROCEDURE identifier IS
declarative part
BEGIN
sequence of statements
END identifier;

--   Program to Compute Series of Fibonacci Numbers
--   Algorithm:  The current Fibonacci number is the sum of last two
--               Fibonacci numbers.  The initial numbers are 1 and 1.
--               The next Fibonacci numbers in order are 2, 3, and 5.
--

PROCEDURE intro_03 IS

fibonacci  : Integer := 1;    --  Current value of the Fibonacci no.
last       : Integer := 1;    --  Last value of the Fibonacci number
n          : Integer := 2;    --  Incremental variable (see LOOP)
temp       : Integer;         --  Temporary variable

--                  --
--   Main Routine   --
--                  --
BEGIN
(Item => "Program intro_03 -- Fibonacci Number Sequence");
Ada.Text_IO.new_line (Spacing => 2);           --  Double space
Ada.Text_IO.put (Item => "    Integer    Fibonacci Number");
Ada.Text_IO.put (Item => "    -------    --------------- ");

Ada.Integer_Text_IO.put (Item => n, Width => 9);  --  Seq. num.
Ada.Integer_Text_IO.put (Item => fibonacci, Width => 15);

FOR n IN 3..20 LOOP           --  Incr. by 1 from 3 to 20
temp := fibonacci;
fibonacci := fibonacci + last;
last := temp;
Ada.Integer_Text_IO.put (Item => n, Width => 9);  --  Seq. num.
Ada.Integer_Text_IO.put (Item => fibonacci, Width => 15);
END LOOP;
END intro_03;

```

### Variables and Data Types

Variable Declaration

The syntax of a variable declaration is variable_name : data_type; Multiple variables can be declared in the same statement.

```     letter     : Character;  --  Single character
next_vowel : Character;
delta_v    : Float;      --  Floating point number
delta_h    : Float;
n          : Integer;    --  Integer number: negative, 0, positive
last       : Integer;
count      : Natural;    --  Integer counting numbers: 0, positive
total      : Natural;
name       : String (1..20);  --  String, a sequence characters

a, b, c, d : Character;  --  Multiple variables can be declared
i, j, k    : Integer;    --    when separated by commas
h1, h2, hx : Float;
idx1, idx2 : Natural;
nam1, nam2 : String (1..20);
```
Variable Initialization

The syntax of variable initialization is variable_name : data_type := literal;.

```     last_vowel : Character      := 'U';
fibonacci  : Integer        := 1;
pi         : Float          := 3.14159;
max_count  : Natural        := 1260;
her_name   : String (1..10) := "Ada Byron*";
--           String length must match variable definition
```
Literals

In the statement i := i + 1; the 1 is a literal.

```     Character literals     'a', 'A'                   --  Single quote
Float literals         -20.0, 0.0, 3.14159, 20.0
Integer literals       -29, 0, 37
Natural literals        0, 1, 2, ...
String literals        "Strike any key when ready ..."
--  Double quote
```
Constants

Constants are variables whose values do not change. Constants must have their initial value specified.

```--   asterisk : CONSTANT           := '*';      ERROR: does not compile
asterisk : CONSTANT Character := '*';

max      : CONSTANT           := 40;       --  or
max      : CONSTANT Integer   := 40;

pi       : CONSTANT           := 3.14159;  --  or
pi       : CONSTANT Float     := 3.14159;

zero     : CONSTANT           := 0;        --  or
zero     : CONSTANT Natural   := 0;

--   spaces   : CONSTANT           := "     ";  ERROR: does not compile
spaces   : CONSTANT String (1..5) := "     ";
```
Enumeration Types

Enumeration types allow listed items (such as Sunday, Monday, Tuesday, etc.) to be used as literals. In the example below, Sunday is an enumeration literal and is used as an identifier.

```     TYPE day_type IS (Sunday, Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday);
day : day_type;

day := Tuesday;

FOR day IN Sunday..Saturday LOOP
.
IF day = Sunday THEN
.
.
END LOOP;
.
END LOOP;
```
The first item in an enumeration list has the position number of 0. The n-th item in an enumeration list has a position number of n-1. Enumeration types also have attributes. The attributes of an enumeration list are as follows (see example above for the enumeration TYPE declaration):

 Attribute Meaning Example First first value days'first is Sunday Last last value days'last is Saturday Pred predecessor value days'pred(Friday) is Thursday Pos position number days'pos(Wednesday) is 3 Succ successor value days'succ(Wednesday) is Thursday Val value of position number days'val(4) is Thursday

ARRAYs

An array is a collection of identical elements. Each element is identified by an index value. The index value must be in the range of elements declared. Let x : array(1..10) of float; then the index value for array x must 1 through 10 only. Ada supports four basic ARRAY operations: store values, retrieve values, ARRAY assignment (copy a ARRAY), and equality test (includes inequality test).

```     One dimensional arrays

move_num  : ARRAY (1..max) of integer;
move_char : ARRAY (1..max) of character;

initial   : ARRAY (1..max) of integer :=
( 7,  4,  5,  6,  2,  8,  1,  3 );
charname  : ARRAY (1..max) of character :=
('G','D','E','F','B','H','A','C');

One dimensional arrays (declared by TYPE)

TYPE my_array_type IS ARRAY (1..100) of Integer RANGE 1..100;

x, y : my_array_type;

Two dimensional arrays

screen    : ARRAY (1..max,1..max) of character;

routable  : ARRAY (0..7, 1..3) of integer :=
((4, 2, 1),   --  row 0
(5, 3, 0),   --  row 1
(6, 0, 3),   --  row 2
(7, 1, 2),   --  row 3
(0, 6, 5),   --  row 4
(1, 7, 4),   --  row 5
(2, 4, 7),   --  row 6
(3, 5, 6));  --  row 7

Two dimensional arrays (declared by TYPE)

TYPE my_screen IS ARRAY (1..24,1..80) of Character;

display1 : my_screen;

Array operations

x(n) := n;          --  Store in an array

y := x;             --  Assignment of array

IF x = y THEN ...   --  Test for equality

a := y(45);         --  Retrieve from an array

Note: Assignment and test for equality ARRAY operations must be done
on the same TYPEd array.  For example, given IF x = y THEN ...
ARRAYs x and y must be declared as follows:

TYPE my_array_type IS ARRAY (1..100) of Integer;

x, y : my_array_type;
```
Strings

String is a predefined length not specified array type that is a sequence of characters.

```     in_string    : string (1..78);
error_string : string (1..33) :=

FOR i IN 1..78 LOOP           --  Blank contents of string
in_string(i) := ' ';
END LOOP;
```
Conversion

Ada is a strongly typed language. Data type conversion should be explicit.

```     Float to integer    integer_x := integer(float_x * 20.0);
Float to natural    natural_y := natural(float_y * 14.0);

Integer to Float    float_angle :=
2.0 * pi * float(integer_angle) / 360.0;
Natural to Float    float_angle :=
2.0 * pi * float(natural_angle) / 360.0;
```
RECORDs

The RECORD data structure is included in Ada as a TYPE. Ada supports four basic RECORD operations: store values, retrieve values, RECORD assignment (copy a RECORD), and equality test (includes inequality test).

```     --  Example One:  Address Data as a RECORD

TYPE address IS RECORD             --  RECORD TYPE Definition
street     : String (1..20);
apt_no     : String (1..5);
city       : String (1..20);
state_code : String (1..2);
zip_code   : String (1..10);
END RECORD;

my_street     : String (1..20);
my_apt_no     : String (1..5);
my_city       : String (1..20);
my_state_code : String (1..2);
my_zip_code   : String (1..10);
--  Store values
current.street     := "1887 Forest Lane    ";
current.apt_no     := "#33  ";
current.city       := "Great Falls Landing ";
current.state_code := "VA";
current.zip_code   := "22132_1234";

prior := current;                  --  Assignment (copy RECORD)

my_street     := prior.street;     --  Retrieve values from RECORD
my_apt_no     := prior.apt_no;
my_city       := prior.city;
my_state_code := prior.state_code;
my_zip_code   := prior.zip_code;

--  Example Two:  Complex Numbers as a RECORD

TYPE complex IS RECORD             --  RECORD TYPE Definition
real  : Float;
imag  : Float;
END RECORD;

x    : complex := ( 1.0, -2.0);    --  Declare x a complex RECORD
y    : complex := ( 3.0, +4.0);    --    and Initialize RECORD x
z    : complex;
zero : complex := ( 0.0,  0.0);

z.real := x.real + y.real;         --  Retrieve and store values
z.imag := x.imag + y.imag;

IF z /= zero THEN                  --  Inequality Test
....
END IF;
```

### PACKAGEs

PACKAGE Declaration -- A Specification

PACKAGEs are both declared and have PACKAGE BODYs. A PACKAGE is a way of grouping FUNCTIONs, PROCEDUREs, and TASKs (and other program entities) into a named container. PACKAGE declarations contain information that is visible to other program units. The PACKAGE declaration defines the interface to the program units within the PACKAGE.

```--   PACKAGE box Definition -- Draw a Box to the Screen
--
--           Sample PACKAGE Definition
PACKAGE box IS

base_row  : Natural          :=  1;     --  Current row
base_col  : Natural          :=  1;     --  Current column

max_rows  : CONSTANT Natural := 24;     --  Set max rows
max_cols  : CONSTANT Natural := 80;     --  Set max columns

char_set  : Character        := '*';    --  Default box drawing char

SUBTYPE valid_row IS Natural RANGE 1..max_rows;
SUBTYPE valid_col IS Natural RANGE 1..max_cols;

PROCEDURE Char (my_char : character);   --  Set box drawing char
--  Pre:  current value of char_set
--  Post: new value of char_set assigned

PROCEDURE ClearScreen;                  --  Clear entire screen
--  Pre:  none
--  Post: screen is cleared, cursor at position (1,1)
--  Position cursor
PROCEDURE MoveCursor (row : valid_row; col : valid_col);
--  Pre:  current position of cursor
--  Post: cursor at new in-range position
--  Make (draw) the box
PROCEDURE Draw (down : valid_row; over : valid_col);
--  Pre:  none
--  Post: box drawn, cursor returned to base position
END box;
```
PACKAGE BODY

A PACKAGE is a way of grouping FUNCTIONs, PROCEDUREs, and TASKs (and other program entities) into a named container. PACKAGE BODYs contain the inplementation details that are not visible to other program units.

```--   PACKAGE BODY box Definition -- Draw a Box to the Screen
--
--           Sample PACKAGE BODY Definition
--           Routine ClearScreen adapted from Michael Feldman at GWU
--           Routine MoveCursor  adapted from Michael Feldman at GWU
--

PACKAGE BODY box IS

PROCEDURE Char (my_char : character) IS  --  Set box drawing char
BEGIN
char_set := my_char;
END char;

PROCEDURE ClearScreen IS                 --  Clear entire screen
BEGIN
base_col := 1;
base_row := 1;

END ClearScreen;
--  Position cursor
PROCEDURE MoveCursor (row : valid_row; col : valid_col) IS
BEGIN
base_row := row;
base_col := col;

Ada.Integer_Text_IO.put (Item => row, Width => 1);
Ada.Integer_Text_IO.put (Item => col, Width => 1);
END MoveCursor;

PROCEDURE Draw (down : valid_row; over : valid_col) IS
top_row,  bottom_row : Natural;
left_col, right_col  : Natural;
BEGIN
left_col   := base_col;
right_col  := base_col+over-1;
top_row    := base_row;
bottom_row := base_row+down-1;

FOR i IN left_col..right_col LOOP   --  Draw top of the box
END LOOP;

FOR i IN top_row..bottom_row LOOP   --  Draw left side of box
MoveCursor (row => i, col => left_col);
END  LOOP;

MoveCursor (col => left_col, row => bottom_row);
For i IN left_col..right_col LOOP   --  Draw bottom of box
END LOOP;

FOR i IN top_row..bottom_row LOOP   --  Draw right side of box
MoveCursor (row => i, col => right_col);
END  LOOP;

MoveCursor (col => base_col, row => base_row);
END Draw;
END box;
```
PACKAGE Usage

The WITH statement includes one or more library packages with a program.

The WITH statements in the example below include the standard text, float, and integer library routines in a program. The PACKAGE name must be explicitly referenced in the code (for example: Ada.Text_IO.new_line).

```WITH Ada.Text_IO;          --  Include Ada.Text_IO library routines and
```
The USE statement precludes the explicit declaration of a package when a specific library package is being used. The package name does not have to be referenced.

```WITH Ada.Text_IO;          --  Include Ada.Text_IO library routines and
USE  Ada.Text_IO;          --  Precludes explicit declaration

--
--   Sample String "put" statements implicitly referencing Ada.Text_IO
--
put (Item => "This put statement implicitly references Ada.Text_IO");
put (Item => "  because of the USE Ada.Text_IO statement above.   ");
new_line;
```
The PACKAGE box is defined in this section. The PACKAGE box is included in the program "box_it" (shown below) by the WITH statement. The PROCEDUREs in the PACKAGE box are reference by the naming both the PACKAGE and the PROCEDUREs [for example: box.ClearScreen or box.MoveCursor (row => 1, col => 2) ]. Given that a USE statement (that is "USE box;") was included after the WITH statements, the PROCEDUREs in the PACKAGE box can be referenced without explicit reference to the PACKAGE [for example: ClearScreen or MoveCursor (row => 1, col => 2) ].

```--   Program to Exercise Box PACKAGE

WITH box;

PROCEDURE box_it IS
BEGIN
box.ClearScreen;

box.Char('-');
box.MoveCursor (row => 1, col => 2);
box.Draw (down => 3, over => 78);
box.MoveCursor (row => 2, col => 24);

box.Char('*');
box.MoveCursor (row => 10, col => 24);
box.Draw (down => 3, over => 34);

box.Char('#');
box.MoveCursor (row =>  7, col => 15);
box.Draw (down => 9, over => 12);

box.Char('%');
box.MoveCursor (row =>  7, col => 55);
box.Draw (down => 9, over => 12);

box.MoveCursor (row => 24, col => 2);

END box_it;
```

### Statements and Expressions

FOR LOOPs

The index variable in a FOR LOOP does not have to be declared. Remember, if the FOR LOOP index variable is an explicitly declared variable, then the index variable is a different variable (with the same name).

```     FOR n IN 3..20 LOOP                --  Simple LOOP
temp := fibonacci;
fibonacci := fibonacci + last;
last := temp;
Ada.Integer_Text_IO.put (Item => n, Width => 9);
Ada.Integer_Text_IO.put (Item => fibonacci, Width => 15);
END LOOP;

FOR i IN 1..max LOOP               --  Nested FOR LOOPs
FOR j IN 1..max LOOP
END LOOP;
END LOOP;
```
Infinite LOOPs

Ada supports infinite LOOPs. Infinite LOOPs can be used in TASKs or in read file loops (where end of file is handled by an EXCEPTION).

```     LOOP
--  Write output data
Ada.Float_Text_IO.put (Item => v1, Fore => 7, Aft => 2, Exp => 0);
Ada.Float_Text_IO.put (Item => h1, Fore => 7, Aft => 2, Exp => 0);
Ada.Float_Text_IO.put (Item => v2, Fore => 7, Aft => 2, Exp => 0);
Ada.Float_Text_IO.put (Item => h2, Fore => 7, Aft => 2, Exp => 0);
END LOOP;

EXCEPTION WHEN End_error  =>
```
Simple Expressions

Expressions in assignment statements (":=") are to the right of the equal sign. The condition evaluated in an IF statement is also an expression.

```     Simple expressions:

character    next_vowel := 'o';

float        delta_v_sq := (v2 - v1) ** 2;
delta_sum  := (delta_v_sq + delta_h_sq) * 0.10;
angle := 2.0 * pi * float(p) / 360.0;

integer      i := i + 1;

natural      new_value := abs(any_value) + mod(old_value,10);
--                      Note the " "
string       my_string := " " & packname(j) & "-";

Expressions can be used in index values

screen(coord_x+max/2,coord_y+max/2) := '*';
```
IF THEN ELSE

IF statements evaluate expressions. "j <= 0" is an expression which is either true (THEN clause) or false (ELSE clause).

```     IF j <= 0 THEN                     --  Simple IF statement
END IF;

IF x >= -12 AND x <= 12 THEN       --  IF THEN ELSE
Ada.Text_IO.put (Item => "The value of x is in range");
ELSE
(Item => "The value of x is outside the expected range");
END IF;

IF    q = 3 THEN                   --  IF THEN ELSIF
Ada.Text_IO.put (Item => "The value of q is 3");
ELSIF q = 2 THEN
Ada.Text_IO.put (Item => "The value of q is 2");
ELSIF q = 1 THEN
Ada.Text_IO.put (Item => "The value of q is 1");
ELSE
Ada.Text_IO.put (Item => "The value of q is not defined");
END IF;
```
CASE

The CASE statement is used to select one of several alternatives. The WHEN clause in the CASE statement contains the value of an expression (such as "this_day = Monday") to be evaluated. If the WHEN expression is true, then the instruction(s) that follow the "=>" are executed. The WHEN OTHERS clause is intended as a "catch all", whenever other WHEN expression choices fail.

```     --  Example:  Days of the week

TYPE days IS (Sunday, Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday );

this_day : days;

CASE this_day IS
WHEN Monday   => status := holiday;
WHEN Tuesday  => status := school;
WHEN Wednesday |              --  Multiple choices are
Thursday  |              --    separated by "|" ("or")
Friday   => status := work;
WHEN OTHERS   => status := weekend;
END CASE;

```
Operators and Precedence Order

Operators and their precedence are given in the table below. Parenthesis can be used change the order of evaluation.

```     5*7+6*4+9 evaluates to 35+24+9 = 68
5*(7+6)*(4+9) evaluates to 5*13*13 = 1345
```
 Operator Type Precedence Order (highest first) Arithmetic ** Arithmetic *, /, MOD, REM Arithmetic unary - Arithmetic +, - Logical /=, <, <=, >, >=, IN, NOT IN Logical AND, OR, XOR, AND THEN, OR ELSE

Concatenation

Concatenation is the joining of two or more strings into a single string.

```     a_string   := "aaa";
b_string   := "bbbb";
c_string   := "cCCCc";
abc_string := a_string & b_string & c_string;

This sequence of assignment statements produces the string below:

"aaabbbbcCCCc"

A similar result can be displayed as output by the following lines:

Ada.Text_IO.put (a_string);        --  These three statements
Ada.Text_IO.put (b_string);        --    create the same result
Ada.Text_IO.put (c_string);        --    as the statement below.

Ada.Text_IO.put (a_string & b_string & c_string);
```

### INPUT and OUTPUT

WITH and USE For I/O

The information presented in this subsection is copied from the subsection titled PACKAGE Usage.

The WITH statement includes one or more library packages with a program.

The WITH statements in the example below include the standard text, float, and integer library routines in a program. The PACKAGE name must be explicitly referenced in the code (for example: Ada.Text_IO.new_line).

```WITH Ada.Text_IO;          --  Include Ada.Text_IO library routines and
```
The USE statement precludes the explicit declaration of a package when a specific library package is being used. The package name does not have to be referenced.

```WITH Ada.Text_IO;          --  Include Ada.Text_IO library routines and
USE  Ada.Text_IO;          --  Precludes explicit declaration

--
--   Sample String "put" statements implicitly referencing Ada.Text_IO
--
put (Item => "This put statement implicitly references Ada.Text_IO");
put (Item => "  because of the USE Ada.Text_IO statement above.   ");
new_line;
```
Input from Standard Input

Character, float, integer, and natural input are delimited by white space. White space means that one or more blanks are between each value. String input is delimited by end_of_line markers. See File Input Using Strings for a sample string input routine.

```     my_char  : Character;         --  Variable declaration for all types
my_float : Float;
my_int   : Integer;
my_natl  : Natural;
my_str   : String (1..20);

--
--  Input of Variables using get
--  (the "get" is preceded by a prompt using the "put" statement)
--
Ada.Text_IO.put (Item => "Enter a single character and <cr> ");
Ada.Text_IO.get (Item => my_char);          --  Character variable

Ada.Text_IO.put (Item => "Enter a floating point number and <cr> ");
Ada.Float_Text_IO.get (Item => my_float);   --  Float variable

Ada.Text_IO.put (Item => "Enter an integer number and <cr> ");
Ada.Integer_Text_IO.get (Item => my_int);   --  Integer variable

Ada.Text_IO.put (Item => "Enter a natural number and <cr> ");
Ada.Integer_Text_IO.get (Item => my_natl);  --  Natural variable

Ada.Text_IO.put (Item => "Enter a 20 character string and <cr> ");
Ada.Text_IO.get (Item => my_str);           --  String variable
```
Output to Standard Output

The length to be displayed of a variable must be specified or a default length is displayed.

Let the Integer (or Natural) variable "hi" have the value 23; then, Ada.Integer_Text_IO.put (Item => hi, Width => 5) displays "...23" ("." represents a blank space). WARNING: In the event that an Integer (or Natural) variable value exceeds the specified Width, the value of the variable is displayed. If hi = 12345678 and Width => 5, then the number displayed is 12345678.

Let the Float variable next_float have the value 1234.567; then, Ada.Float_Text_IO.put (Item => next_float, Fore => 7, Aft => 5, Exp = 0) displays "...1234.56700" ("." represents a blank space). WARNING: In the event that a Float variable exceeds the specified Fore, the value of the variable is displayed. If next_float = 1234567.89 with Fore => 4 and Aft => 4, the the number displayed is 1234567.8900.

```     my_char  : Character;         --  Variable declaration for all types
my_float : Float;
my_int   : Integer;
my_natl  : Natural;
my_str   : String (1..40);

--
--  Output of Literals using Put
--
Ada.Text_IO.put (Item => '*');               --  Character literal
(Item => 123.45, Fore => 4, Aft => 4, Exp => 0);
--  Integer literal
Ada.Integer_Text_IO.put (Item => 76, Width => 8);
--  Natural literal
Ada.Integer_Text_IO.put (Item => 98, Width => 8);
--  String literal
Ada.Text_IO.put (Item => "A string is a collection of characters");

--
--  Assign values to variables
--
my_char  := '#';
my_float := -2.54;
my_int   := -32768;
my_natl  := 32767;
my_str   := "This is program intro_put.adb***********";

--
--  Output of Variables using Put
--
Ada.Text_IO.put (Item => my_char);           --  Character variable
(Item => my_float, Fore => 6, Aft => 6, Exp => 0);
--  Integer variable
Ada.Integer_Text_IO.put (Item => my_int, Width => 8);
--  Natural variable
Ada.Integer_Text_IO.put (Item => my_natl, Width => 8);
Ada.Text_IO.put (Item => my_str);             --  String variable

--
--  New Lines in Output
--
Ada.Text_IO.new_line (Spacing => 1);     --  or
```
Redirection of Input / Output

Redirection of input, using the "<" symbol, changes the standard input device from the keyboard to a file. Redirection of output, using the ">" symbol, changes the standard output device from the display to a file or printer. Redirection of output is very useful in order to capture results that are larger than a screen.

```     Redirection of input from a file:
intro_04.exe  <intro_04.dat

Redirection of output to a file:
intro_05.exe  >intro_05.lst

Redirection of output to a printer (PC DOS format only):
intro_05.exe  >PRN

Example of input from a file and output to a file
program.exe   <input.dat  >output.lst
```
File Open

The standard input is from the keyboard. Other input sources, such as files, must be declared (unless redirection is used).

```     inp   : Ada.Text_IO.File_Type;          --  File must be declared
--  Open input file
Ada.Text_IO.open  (File => inp, Mode => in_file,
Name => file_name_string);
```
File Close

Input sources that must be opened with an open statement must also be closed using a close statement.

```     Ada.Text_IO.close (File => inp);        --  Close input file
```
File Input Using Strings

The example below shows how to read file input using strings. Special consideration should be given to End_of_Line markers. If one or more characters preceed an End_of_Line marker, get_line reads one record and repositions to the beginning of the next record. The get_line does not read past contiguous End_of_Line markers; Skip_Line must be used.

```     --  Open input file
Ada.Text_IO.open  (File => inp, Mode => in_file,
Name => file_name_string);

--  Continue LOOP until end of file
WHILE NOT Ada.Text_IO.End_of_File(File => inp) LOOP

--  Skip input strings of zero length
END LOOP;
--  Get input string
Ada.Text_IO.get_line (File => inp, Item => in_string,
Last => in_length);
--  Blank remainder of string
FOR i IN in_length+in_string'last LOOP
in_string(i) :=  ' ';
END LOOP;
.
.                          --  Process input string
.
END LOOP;

Ada.Text_IO.close (File => inp);  --  Close input file
```

### SUBPROGRAMS

Parameter Modes

Subprograms (i.e., FUNCTIONs and PROCEDUREs) have distinct parameters modes. They are defined in the following table.

 Parameter Mode FUNCTIONs PROCEDUREs Description IN Legal Legal Passed into the subprogram, are constants in the subprogram, and may not be changes in the in the subprogram OUT Not legal Legal Passed out of the subprogram, a parameters value is defined (assigned) inside the subprogram. INOUT Not legal Legal Passed into the subprogram, and may be changed by the subprogram, and the parameters value is passed out of the subprogram

FUNCTIONs

FUNCTIONs return a single value to the calling program using the RETURN statement. The default parameter mode is "IN", thus "(n : Integer)" is equivalent to "(n : IN Integer)".

```     --
--   FUNCTION days_in_month
--
FUNCTION days_in_month (in_month : IN Natural;
in_year  : IN Natural) RETURN Natural IS
--
--   FUNCTION days_in_Feb:  This a FUNCTION within a FUNCTION
--
FUNCTION days_in_FEB RETURN Natural IS
BEGIN
IF    in_year MOD 100 = 0 THEN RETURN 28;
ELSIF in_year MOD   4 = 0 THEN RETURN 29;  --  Leap year
ELSE                           RETURN 28;
END IF;
END days_in_Feb;
BEGIN
CASE in_month IS
WHEN  1 =>  RETURN 31;  --  JAN
WHEN  2 =>  RETURN days_in_Feb (in_month);
WHEN  3 =>  RETURN 31;  --  MAR
WHEN  4 =>  RETURN 30;  --  APR
WHEN  5 =>  RETURN 31;  --  MAY
WHEN  6 =>  RETURN 30;  --  JUN
WHEN  7 =>  RETURN 31;  --  JUL
WHEN  8 =>  RETURN 31;  --  AUG
WHEN  9 =>  RETURN 31;  --  SEP
WHEN 10 =>  RETURN 31;  --  OCT
WHEN 11 =>  RETURN 30;  --  NOV
WHEN 12 =>  RETURN 31;  --  DEC
WHEN OTHERS RETURN 99;  --  Invalid month
END IF;
END days_in_month;
```
Variables declared locally within a FUNCTION have their scope limited to within the FUNCTION.

PROCEDUREs

PROCEDURES do not return values using the RETURN statement. The parameter mode can be "IN" for an input parameter, "OUT" for an output parameter, and "INOUT" for a parameter whose mode is both input and output.

```     --
--   PROCEDURE display_days_in_a_month:  Format -> 23 MAR 1997
--
PROCEDURE proc_display_month (in_year  : IN Natural;
in_month : IN Natural;
in_days  : IN Natural) IS
TYPE    month_enum IS (Jan, Feb, Mar, Apr, May, Jun,
Jul, Aug, Sep, Oct, Nov, Dec);
(Enum => month_enum);
BEGIN
FOR day_current IN 1..in_days LOOP
(Item => day_current, Width => 2);
month_IO.put    (Item => (month_enum'val(in_month-1)));
(Item => in_year, Width => 5);
END LOOP;
END display_days_in_a_month;

--
--   PROCEDURE sort_column:
--   Sort the columns of a two-dimensional array
--
PROCEDURE sort_column (square: INOUT ARRAY of integer (1..n,1..n)) IS
BEGIN
FOR k IN 1..max-1 LOOP
FOR i IN 1..max-1 LOOP
IF (square(i,j) > square(i+1,j)) THEN
temp := square(i+1,j);
square(i+1,j) := square(i,j);
square(i,j) := temp;
END IF;
END LOOP;
END LOOP;
RETURN;
END sort_column;
```
Variables declared locally within a PROCEDURE have their scope limited to within the PROCEDURE.

Recursion

A recursive subprogram is a subprogram that calls itself. Both FUNCTIONs and PROCEDUREs can be recursive. Each instance of the recursive subprogram has its own version of the calling parameters and all items (variables, arrays, etc.) declared in the body of the subprogram.

```WITH Ada.Text_IO;            --  Include Ada.Text_IO library routines
PROCEDURE fibonaci IS

max : Integer := 20;

FUNCTION fibon (n : Integer) RETURN Integer IS
BEGIN                   --  The FUNCTION "fibon" is recursive
IF n <= 2 THEN
RETURN 1;
ELSE
RETURN fibon (n-1) + fibon (n-2);
END IF;
END fibon;
--                  --
--   Main Routine   --
--                  --
BEGIN