560 likes | 573 Views
Learn the basic structure of Ada programs, including packages, functions, procedures, and how to be a client accessing different elements. Explore integer type declarations, strong typing, subtypes, exceptions handling, and modular types in Ada.
E N D
An Introduction to Ada Programming Languages Fall 2003
Basic Structure of a Program • A program is a collection of units • Packages • Functions • Procedures • Bound together to form a program • Typically a unit is stored in a file • Units reference other units
Procedure • procedure H (M : Integer) isdeclarationsbeginstatementsreturn;end H; • Typical use is procedure Main is … which defines the main program
Function • function Max (A : Integer; B : Integer)return Integeris Result : Integer;beginif A > B then Result := A;else Result := B;end if;return Result;end Max;
Packages • Packages define a related collection of types, and subprograms (procedure and functions) • A package provides a set of services to a client • A package may be a client of another package
Package Spec (Declaration) • package X isdeclarations types subprogram specs (but not subprogram bodies)end X;
Subprogram Specs • procedure Print_In_Hex (X : Integer); • function Max (A, B : Integer)return Integer; • Note the semicolon instead of is • A subprogram spec has everything you need to know to use the subprogram • A client needs only the spec
Package Bodies • packagebody X isdeclarations subprograms local to body variables/constants local to body subprogram bodies for subprogram specs appearing in the package specbegininitialization statementsend X;
How to be A Client • To access a package, use a WITH:with Calendar;procedure Main is Today : Calendar.Time;…end Main;
The Use Clause • Accessing Stuff in Calendar without dots • with Calendar;use Calendar;procedure Main is Today : Time;…end Main;
Package Bodies as Clients • with Calendar;package body Julian_Calendar_Stuff is …end Julian_Calendar_Stuff; • Here we have the implementation of a package done using stuff in another package
Package Specs as Clients • A package spec can build on another spec • with Calendar;use Calendarpackage To_Do_List is …procedure Enter (T : Time; M : String); -- Enter new item in todo list. Time is -- deadline. M is description.end To_Do_List;
The Idea of a Package Spec • Write the package spec • It is like a contract between client and body of the spec • Write the body • Write the client • Last two activities are completely independent (and should not talk to one another except “via” the spec)
Integer Type Declarations • Type Integer is built in • But you don’t want to use it • Because its range is implementation defined • Because it is defined to match the machine not your problem • Because it does not take advantage of strong typing to prevent errors
Defining Integer Types • Define type according to use • type Day_In_Year is range 1 .. 366;type Age is range 0 .. 130;type Temperature is range -20 .. +180; • Now we can define variables of the type • Today_Day : Day_In_Year;Employee_Age : Age;Machine_Room_Temp : Temperature;
Why Define Integer Types • No dependence on implementation • Unlike type int in C • Range of types matches problem • Get an error or warning at compile time • Age := 200; • Or an exception at runtime • Age := Age + 1000;
Strong Typing • Cannot mix integer types: • Current_Temp : Temperature;Current_Pressure : Pressure; • Current_Temp := Current_Pressure + 1; • Error, cannot assign pressure to temperature • Current_Temp := Current_Temp + Current_Pressure • Error, cannot add temperature to pressure
Integer Subtypes • A subtype creates a limited range • But is still the same type • subtype OK_Operating_Range is Temperature range 70 .. 80;Room_Temp : Temperature;Machine_Room_Temp : OK_Operating_Range…Machine_Room_Temp := Room_Temp; • Raises exception if Room_Temp out of range
Catching Exceptions • You can catch an exception at run time • begin … Machine_Room_Temp := Room_Temp …exceptionwhen Constraint_Error =>recovery stuffend;
Unsigned (Modular) Types • Modular types have wrap around: • type M is mod 7; -- values are 0,1,2,3,4,5,6q : m := 6; -- initialization…q := q + 2; -- result is 1 • Most common use, conventional unsigned • type Uns_32 is mod 2 ** 32; • Remember that twos complement arithmetic is equivalent to arithmetic mod 2**wordsize
Real Types • Float types (control relative accuracy) • type My_Float isdigits 7;type Xfloat is digits 7 range 1.0 .. 10.0;subtype F1 is My_Float range 1.0 .. 5.0; • Digits is decimal digits of relative precision • There is a formal model for fpt in Ada • Target independent (parametrized) • Guarantees minimal accuracy • Operations defined in terms of model numbers • Results fall in defined model interval
Fixed-Point Types • Fixed-point types are real types where you control the absolute accuracy. • Typically implemented as scaled integers • type Velocity is delta 0.125 range 0.0 .. 10.0; • Decimal fixed-point types • Decimal small • Typical use in financial programming • type Money is digits 10delta 0.01 range 0.00 .. 999_999_999.00;
Character Types • Built in types • Character (8-bit Latin-1) • Wide_Character (16-bit Unicode/ISO 10646) • Good enough for most purposes, but you can define your own types: • type My_Character is (‘A’, ‘B’, ‘C’, ….); • Note on standard types • Standard types are in package Standard that is automatically visible in every unit.
Enumeration Types • An enumeration type is a sequence of ordered enumeration literals: • type State is (Off, Powering_Up, On); • No arithmetic defined • S1, S2 : State;S1 := S1 + S2; -- Illegal • Can add/subtract one • State’Pred (S1)State’Succ (S2) • These are examples of attributes
Boolean Types • Predefined enumeration type • type Boolean is (False, True); • Expressions of type boolean used in • if statements • while loops • exit statements • Etc.
Access Types • Access types function like pointers • But are not necessarily implemented that way • type r is access integer;type s is access all integer; • The all allows the access value to reference any item at all. Without all, you can only reference objects specifically allocated for the pool in question.
Using Access Types • Allocate an object using new • type AI is access all integer;Ptr : AI;…Ptr := new Integer; -- uninitializedPtr := new Integer’(12); -- initialized • To obtain value dereference: • V : Integer;…V := Ptr.all;
Array Types • Arrays can have 1 or more subscripts • type Vector is array (Integer range 1 .. 10) of Integer;type Matrix isarray (Integer range 0 .. 10, Character range ‘A’ .. ‘Z’) of Vector; VV : Vector := (others => 10); -- aggregateMM : Matrix;…MM (5, ‘C’) := VV;VV (1 .. 5) := VV (2 .. 6); -- slicing (one dim only)
Array Bounds and Types • Are the bounds of an array answer part of the properties of the array type? • Things are much cleaner if we answer yes, as in Pascal, but this is very limiting • For example, a sort routine cannot take a vector of any size to sort. • Instead we consider the bounds to be like the range of an integer type
Unconstrained Arrays • Unconstrained array type has no bounds • type UA is array (Int range <>) of Int;-- cannot use UA to declare a variable-- instead must build a subtypesubtype UA5 is UA (1 .. 5);UAV5 : UA5 := (6,5,4,3,2);-- can also set bounds for a variableUAV2 : UA (1 .. 2);
String Types • A string type is an array whose elements are a character type. • Two standard built in string types • type String is array (Natural range <>) of Character;type Wide_String is array (Natural range <>) of Wide_Character;S : String (1 .. 5) := “Hello”; • Note: Natural is a predefined subtype of Integer with bounds 0 .. Integer’Last;
Record Types • Like struct in C • type Date isrecord Year : Year_Number := 2002; -- default Month : Month_Number; Day : Day_Number;end record;DD : Date;EE : Date := (2001, 8, Day => 27);…DD.Month := EE.Month – 1;
Arrays/Records and Access Types • Access types and records/arrays • type A is array (Int range 0 .. 10) of Int;type AP is access A;AV : AP;…AV.all (3) := AV (4); -- can omit .all here • Similarly do not need .all for fields of records • DP.Month := DP.all.Month + 1;
What about Union Types? • The union type in C is fundamentally unsafe, and therefore unacceptable • union (int, float) puzzle; • Now puzzle has either an int or a float • But at runtime, cannot tell which • So we have to trust the programer • In Ada we are short on trust
Instead, Discriminated Types • A record can have discriminants: • type IF is (Int, Float);type Int_Float (V : IF := Int) is recordcase V iswhen Int => Int_Val : Integer;when Float => Float_Val : Float;end case;end record; • Now the value of the discriminant V shows what type is currently present
More on Discriminated Records • Referencing a discriminanted type • Puzzle : Int_Float;…Puzzle := (Float, 1.0);F := Puzzle.Float_Val; -- OKI := Puzzle.Int_Val; -- raise exception…Puzzle.V := Int; -- not allowed!
More on Discriminated Records • Can make subtypes • subtype PuzzleI is puzzle (Int);-- this type only holds int values • Can dimension arrays from discriminant: • Subtype Vlen is Integer range 1 .. 10;type Vstr (Vlen : Integer := 0) is record Data : String (1 .. Vlen);end record;VV : Vstr := (5, “hello”);
Other Types • Derived types (copying a type) • Extended types (object oriented stuff) • Task types (active threads) • Protected types (passive synchronization) • More on all these later!
Statement Forms • Assignment statement (is not an expression) • Variable := expression; • If statements • ifconditionthenstatementselsifconditionthenstatements…elsestatementsend if;
Statement Forms (cont) • Loops • for J in Integer range 1 .. 10 loopstatementsendloop; • while condition loopstatementsend loop; • loopstatementsend loop;
Statements (cont) • Exit statement • exit;exit when condition; • Can only be used in a loop • Can use labels: • Outer : loop Inner : loop …exit Inner when Done;end loop Inner;end loop Outer;
Statements (cont) • Case statements • caseexpressioniswhen 0 => statementswhen 1 | 10 => statementswhen 2 .. 9 => statementsend case; • All values in when branches must be static • All possible values of expression must be included exactly once • Can use when others => to cover rest
Statements (cont) • Return statement • return; -- procedurereturnexpression; -- function • Only in procedure/function • Function must have at least one return • Raise statement • raiseexception-name;
Declaring and Handling Exceptions • Declaring an exception • Error, Disaster : exception; • Raising an exception • raise Disaster;-- strips stack frames till a handler is found • Handling an exception • exceptionwhen Disaster => statements
More on Exception Handling • Anywhere we have begin end, we can do: • beginstatementsexceptionwhen handler => statements;when handler => statements;end;
Block Statement • Block statement can be used anywhere • declare -- declare section optionaldeclarationsbeginstatementsexception -- exception section optionalhandlersend;
Back to Packages • Private types and private parts • A type can be declared private • Implementation is hidden • But can provide subprograms that operate on instances of the type
A Package for Stacks • package Stacks is • type Stack is private; • procedure Push (It : Character; On : in out Stack); • procedure Pop (It : Character; From : in out Stack); • function Empty (S : Stack) return Boolean; • Stack_Empty : exception; • Stack_Full : exception; • private • type Stack is record • top : Integer := 0; • contents : String (1 .. 80) := (others => ‘*’); • end record; • end Stacks;
A client of Stacks • with Stacks;package Mumbo is … … S : Stacks.Stack; … Stacks.Push (‘x’, S); … exception when Stacks.Stack_Full => …end Mumbo;
A client of Stacks • with Stacks; use Stackspackage Mumbo is … … S : Stack; … Push (‘x’, S); … exception when Stack_Full => …end Mumbo;