computing science 370_ada_copyright jonathan mohr

Upload: melanie-riva

Post on 07-Apr-2018

218 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    1/23

    COMPUTING SCIENCE 370

    Programming Languages

    Ada

    Modularity and Abstraction

    Problem: The software crisis.

    y complex systems large programs exponential costsSolution: Break large programs into small independent modules.

    y linear costsQuestion: How is independent modularization achieved?

    Answer: Information hiding (Parnas)

    y one module for each design decisiony a change of decision involves only one module

    Data Abstraction

    y Users of an abstract data type are provided with procedures and functions to operate onthe data type.

    y The implementation is hidden and can be changed without the user's knowledge.E.g., String

    Functional Abstraction

    y Users of an algorithm are provided with a procedure, without implementation details.E.g., heapsort

    Characteristics ofFourth-Generation Programming Languages

    y modularityy functional and data abstractiony support for concurrent programming

    Syntactic Structure

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    2/23

    Ada's syntax, like that of most fourth-generation programming languages, is:

    1. in the Algol/Pascal traditionE.g.,

    2. procedure ()is3. 4. begin5. 6. end;

    but

    o ';' is a statement terminator (as in C), not a separator (as in Pascal)o identifiers have arbitrary lengtho case is not significant (but the convention is to use lower case for keywords and

    mixed upper and lower case for everything else)

    7. fully bracketedE.g.,8. loop . . . endloop

    9. if . . . end if10. case . . . end case11. record. . . end record12. package is . . . end

    o elsif introduced to avoid problems of fully-bracketed, nested if statements(making if more like cond).

    o if theno o elsif theno o elsif theno o elseo o end if;

    Note that only one 'end if' is needed.

    Structural Organization

    y Imperative -- two kinds:1. computational2. control flow

    I/O is implemented using two suggested standard packages.

    y Declarations -- five kinds:1. Objects: variables and constants2. Types: enumerations and types constructed from predefined types3. Subprograms: like Algol/Pascal, but allows use of built-in operators as names of

    subprograms on user-defined types (operator overloading)

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    3/23

    4. Packages: modules used for data abstraction contain types and subprograms defined by two separate modules

    a. specification (public) -- declarationsb. definition orbody (private) -- implementation

    5.

    Tasks: modules used for concurrencyy Separate compilation -- Ada supports true separate compilation.

    compilation unitA compilable block of code.

    independent compilationProgram units may be compiled independently and then integrated using a linker to form

    a complete program.E.g., Fortran, C

    o Compiler maintains a list of undeclared subroutines and variables and assumesthat they are external references.o All external references are resolved by the linker at link time.

    separate compilationProgram units are compiled separately, but not independently, in that external references

    are checked and resolved during compilation.E.g., Ada, Modula-2

    o Incorporates strong type checking.Data Structures

    y Four predefined typesy Integery Booleany Charactery Float

    o Float corresponds to the machine's usual precision, but programmers areencouraged to use constraints instead for more machine independence.

    range constrainta set of permissible values

    e.g., type Coordinateisrange -100 .. 100;

    floating-point constraintspecified precision

    e.g., type Coefficientis digits 10 range -1.0e10 .. 1.0e10;

    fixed-point constraintspecified absolute error bound

    e.g., type Dollarsis delta 0.01 range 0.00 .. 10_000_000.00;

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    4/23

    o Preservation of Information Principle -- The user should be able to specify thingsat an abstract level for the compiler to implement at the low level.

    y Five constructorso enumerationo arrayo

    recordo pointer (called an access)

    o subtypey Name equivalence

    o Why name equivalence?1. If the programmer restates a type definition with a different name, it is

    probably because the types are logically different.

    2. The alternative -- structural equivalence -- is not well defined and isdifficult to implement.

    (See also theprevious discussion of this topic and 4.3 Type Equivalence from

    Rationale for theD

    esign of the Ada Programming Language.)

    o A problem with name equivalence:o type Indexisrange 1 .. 100;oo AnInteger : Integer;o AnIndex : Index;oo AnInteger := AnIndex; -- illegal with nameequivalenceo AnIndex := AnIndex + 1; -- illegalassuming 1 isan Integer

    Solution: A constraint is defined as producing a subtype.

    subtypeA type which inherits all operations from its supertype, and is compatible with the

    supertype and all subtypes of that supertype.

    Declaration of a subtype may be explicit.

    E.g.,

    subtype Indexis Integerrange 1 .. 100;

    derived typeA type which inherits all operations from its supertype, but is not compatible with the

    supertype.

    Declaration of a derived type must be explicit.

    E.g.,

    type Percentisnew Integerrange 0 .. 100;

    Explicit coercion between a derived type and its subtype is allowed.

    E.g.,

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    5/23

    A_Percent := Percent( AnInteger);

    y Ada allows an identifier to belong to multiple enumerated types.E.g.,

    y type Primaryis ( Red, Blue, Green);y typeStopLightis ( Red, Amber, Green);

    Overloaded identifiers are disambiguated by context.

    y Index constraints allow general-purpose array procedures.E.g.,

    y type Vectorisarray ( Integerrange < >) of Book;yy Collection : Vector ( 1 .. 10000 );y Fiction : Vector ( 1 .. 20000 );yy procedureSort ( aVector : Vector)isy . . .

    o The compiler must pass the actual bounds as hidden parameters to the procedure.o Bounds are accessed as 'First and 'Last.

    E.g.,o subtype Indexis IntegerrangeaVector'First ..

    aVector'Last;oo Lower : Index;o Upper : Index;o Temp : Book;oo begino for Upperin A_Vector'Last .. A_Vector'First + 1 loopo for Lowerin A_Vector'First .. Upper - 1 loopo if A_Vector( Lower)> A_Vector( Lower + 1 )theno Temp := A_Vector( Lower);o A_Vector( Lower) := A_Vector( Lower + 1 );o A_Vector( Lower + 1 ) := Temp;o end if;o end loop;o end loop;o end Sort;

    Name Structures

    Bindings

    A name can be bound to:

    y constanty variabley typey procedure

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    6/23

    y functiony tasky package

    Declarations

    y In general, a declaration can:o allocate memoryo bind a name to a locationo initialize memory

    y In Ada, variable and constant declarations can do all three.E.g.,

    y Tax_Rate : Real := 1.0;y PI : constant := 3.141592653589;y Deduct_Rate : constant Real := Tax_Rate * 2.0;

    o Omitting the type in the declaration ofPI makes it a "universal real" (max.precision).

    o Initializations are performed during environment activation.o Constants cannot be changed after activation.

    y Declarations can be broken into two parts:o Specification:o Max_Size : constant Integer;o Definition:o Max_Size : constant Integer := 256;

    This allows a constant to be provided without defining its value as part of the interface.

    Problems with name structures in block-structured languages

    (Wulf and Shaw, 1973)

    Side effectsChanges in the non-local environment resulting from hidden access to (a) variable(s).E.g.,

    functionmax ( x, y : integer);begin

    count := count + 1; { sideeffect }if x>ythen

    max := x

    elsemax := y

    end;

    y count is declared in an outer block, and is being used to count the number oftimes the function is called.

    y If there is a bug involving count, it will be difficult to identify that it is modifiedin this function, especially if it is in a large program or ifmax is a predefined

    function in a library.E.g.

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    7/23

    y length := max( needed, requested );This line modifies count without mentioning it. (See the Manifest Interface

    Principle.)

    Indiscriminate accessThe inability to block access to variables which should be private.

    E.g.,

    y aStack must be declared in the same block as the procedures which use it (Pushand Pop).

    y To be visible to users, Push and Pop must be declared in a block containing alluses of them.

    y UserProc has indiscriminate access to aStack -- it may alter the stack withoutusing Push orPop.

    y Implementation details are also visible, and use of the stack (other than by PushorPop) may depend on those details, creating a maintenance problem.

    VulnerabilityThe inability of a program segment to preserve access to a variable.E.g.,

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    8/23

    y The nested block, illustrated by the code X := X + 1, has no access to the outerX.

    y Vulnerability may accidentally occur in maintaining a large program byintroducing a new variable.

    No overlapping definitionsThere is no control over shared access to variables.E.g., given three modules P1, P2, and P3 such that

    y P1 and P2 share DAy P2 and P3 share DB

    the language should provide a mechanism like

    but in a block-structured language, access must be like

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    9/23

    y Attributes of an alternative language which does not possess these four problems:1. No implicit inheritance of access to variables from enclosing blocks.

    Prevents side effects, indiscriminate access, and vulnerability.2. Access rights by mutual consent.

    Prevents indiscriminate access and vulnerability, and supports overlappingdefinitions.

    3. Decoupling of access rights to a structure and its parts.E.g., allow access to a stack through push and pop operations, but provide no

    access to 'top'. Prevents indiscriminate access.

    4. Different types of access modes.E.g. read-only vs. read/write.

    Addresses side effects and vulnerability.5. Decoupling of these orthogonal functions:

    definition of a name name access allocation

    E.g., in Algol,

    a name is defined by its appearance in a declaration; name access is defined as the current block and all inner blocks; allocation and deallocation are restricted to block entry and exit.

    Algol decouples name access and definition from allocation with own variables.

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    10/23

    In Pascal, decoupling is provided by use of pointers and dynamically allocated

    memory (new and dispose).

    PARNAS'S INFORMATION HIDING PRINCIPLES

    The language should permit modules to be designed such that

    1. the user has all the information needed to use the module correctly, and nothingmore;

    2. the implementor has all the information needed to implement the modulecorrectly, and nothing more.

    Packages

    Ada uses packages to implement information hiding.

    y A package consists of two parts: a specification part and a definition part.E.g., a specification:

    y package Complex_Pack isy type Complexis private;y I : constant Complex; -- deferred constantyy function "+" ( z1, z2 : Complex)return Complex;y function Real_Part ( z : Complex)return Complex;y function "+" ( x1 : Real;z2 : Complex)return Complex;y . . .yy privatey type Complexisrecordy Re, Im : Real := 0.0;y end record;yy I : constant Complex := ( 0.0, 1.0 );yy end Complex_Pack;y Features of the specification part:

    o Name access is by mutual consent -- everything declared in the public part of thispackage can be used by any other program which imports this package.

    o Programs and packages which import this package can be compiled even if theimplementation part of this package doesn't exist yet.

    o The private part indicates to the compiler how much space to allocate forvariables of the new data type in any routine which uses that type.E.g.,

    o declareo use Complex_Pack;o z : Complex;

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    11/23

    o z1 : Complex := 1.5 + 2.5 * I;o begino . . .

    Compare this approach with that of Modula-2: opaque types occupy one word.

    y The definition part of a package is separately compiled.E.g.,

    y packagebody Complex_Pack isyy function "+" ( z1, z2 : Complex)return Complexisy rp : constant Real := z1.re * z2.re - z1.im * z2.im;y ip : constant Real := z1.re * z2.im + z1.im * z2.re;y beginy return ( rp, ip );y end;y . . .y

    There is notation for importing only part of a package.y Packages are used for three purposes:

    1. Data abstraction -- data and associated procedures.2. Procedure libraries -- no data structures.

    E.g., a set of procedures and functions for statistical analysis (mean, standard

    deviation, plot, etc.).3. Shared data -- no procedures.

    E.g., a package to solve the overlapping definition problem by providing limitedaccess to multiple shared data areas:

    4. package Communicationis5. InPtr, OutPtr : Integerrange 0..99 := 0;6. Buffer : array ( 0 .. 99 ) of Character := ( 0..99 =>'');7. end Communication;8.9. procedure Putis10. use Communication;11. begin12. . . .13. Buffer( InPtr) := Next;14. InPtr := ( InPtr + 1 )mod 100;15. . . .16. end Put;17.18. procedure Takeis19. use Communication;20. begin21. . . .22. C := Buffer( OutPtr);23. . . .24. end Take;

    Internal vs. external representation

    o Complex_Pack is an example of an external representation of data abstraction:1. A type is exported.2. The user is responsible for declaring variables of the exported type.

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    12/23

    o An internal representation is an alternate, more powerful method forimplementing ADT's.

    1. Storage for the ADT is associated with the package instead of beingallocated by the user.

    E.g.,2. packageStack is3. procedure Push ( Item : in Integer);4. procedure Pop ( Item : out Integer);5. function Emptyreturn Boolean;6. function Fullreturn Boolean;7. Stack_Error : exception;8. end Stack;9. This package would be used by code of the form:10. declare11. useStack;12. First_Item : Integer;13. Second_Item : Integer;14. begin15. . . .16. Push( First_Item);17. Pop( Second_Item);18. . . .19. if Empty()then20. Push( Second_Item);21. end if;22. . . .23. end;24.In an array implementation, the package body would be:25. packagebodyStack is26. Stack : array ( 1..100 ) of Integer;27. Top : Integerrange 0..100 := 0;28.29. procedure Push ( Item : in Integer)is30. begin31. . . .32.However, this creates one instance ofStack, not a class ofStacks.

    Generic Packages

    To have several instances of the same ADT, we use ageneric package.E.g.,

    generic packageStack is. . .

    end Stack;

    y The body is the same as the previous example.y Instances of a Stack are created by:y package A_Stack isnew Stack;y package B_Stack isnew Stack;

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    13/23

    y Qualification is necessary to use Stack instances, because Ada cannot differentiatebetween A_Stack's operations and B_Stack's operations by context.E.g.,

    y A_Stack.Push( Item);y B_Stack.Pop( Item);y G

    eneric package instantiation is static (i.e., occurs at compile time), not dynamic likenew(p) in Pascal ornew Stack() in Java.

    y Generic packages may be parameterized.E.g., to instantiate one stack with a maximum of 100 integers and another of up to 200characters:

    y genericy Length : Natural := 100; -- defaultvaluey type Itemis private;y packageStack isy . . .y procedure Push ( An_Item : in Item)isy . . .

    o Item acts like a private type -- only assignment and equality comparison areavailable (since they don't depend on size or structure).

    o Instantiation now uses the parameters Length and Item:o package A_Char_Stack isnew Stack( 200, Character);o package An_Int_Stack isnew Stack( 100, Integer);

    y Implementation of a parameterized generic stack:y packagebodyStack isy Stack : array ( 1..Length ) of Item;y Top : Integerrange 0..Length := 0;y . . .y end Stack;y These stacks can be accessed by qualification,

    e.g.,y An_Int_Stack.Push( An_Item);y A_Char_Stack.Pop( An_Item);

    or by using Ada's context mechanism.

    e.g.,

    declareuse A_Char_Stack;use An_Int_Stack;

    An_Int_Item : Integer;A_Char_Item : Character;

    beginPush( An_Int_Item); -- overloadedPush( A_Char_Item);

    if A_Char_Stack.Full()then -- qualified. . .

    end;

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    14/23

    o Push is overloaded, but Ada can tell from the context (by looking at the type ofthe parameter) which Push procedure is intended.

    o Since there is no way to tell the difference between Full in the packageA_Char_Stack and Full in An_Int_Stack, the use of this procedure must bequalified.

    Comparison of Package and Procedure Instantiation

    Package Instantiation Procedure Instantiation

    separate data areas separate data areas

    common code area common code area

    static dynamic

    y Code sharing by generic packages can be complex:1. No parameters

    2. Same elements, different lengths (i.e., number of elements)

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    15/23

    Shared code accesses a Length indicator stored in each instance to dorange checking at run-time.3. Different element types of the same size, different lengths

    Since only equality comparison and assignment are used, only the size ofan element matters in the code.

    4. Elements of different sizes

    Code which depends on the element size (e.g., find the position of anelement in an array) accesses the size indicator stored by the compiler ineach instance.

    Control Structures

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    16/23

    Ada has seven classes of control structures, most of themfully bracketed:

    1. Conditionals2. Iterators3. Case4.

    Subprograms5. goto6. Exception handling7. Concurrency

    Conditionals

    if then

    end if;

    if then

    else

    end if;

    if then

    elsif then

    . . .

    else

    end if;

    Iterators

    y infinitey loopy y end loop;y mid-decision

    E.g., exit when KEY is found or when the search list is exhausted:y Index := List'First;y loopy if Index> List'Lasttheny

    exit;y end if;y if List ( Index) = Keytheny exit;y end if;y Index := Index + 1;y end loop;

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    17/23

    An alternative, abbreviated notation is available, which has the added benefit of makingthe exit point more clearly visible:

    Index := List'First;

    loopexit when Index> List'Last;

    exit when List ( Index) = Key;Index := Index + 1;

    end loop;

    y indefinite iteratory Index := List'First;y while Index

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    18/23

    o The compiler decides how it is to be implemented (performance).

    Compiler

    decides

    Copying

    Reference

    In Out In out

    Programmer decides

    Ada also supportsposition-independent parameters with default values.E.g.,

    procedure Draw_Axes( X_Origin, Y_Origin : Coordinate := 0;

    X_Scale, Y_Scale : Real := 1.0;

    X_Spacing, Y_Spacing : Natural := 1;X_Label, Y_Label : Boolean := True;X_Log, Y_Log : Boolean := False;Full_Grid : Boolean := False);

    y The call to this procedure may specify parameters by label, omitting some:Draw_Axes ( 500, 500, Y_Scale => 0.5, Y_Log => True,

    X_Spacing => 10, Y_Spacing => 10 );

    Position-independent parameters are an example of the Labelling Principle.

    Default parameters are an example of the Localized Cost Principle, because they allow users toignore options (parameters) which they do not require.

    However, costs are associated with these features, as they are with all features:

    y complexityy feature interaction

    E.g., operator overloading + default parameters:

    procedure P ( X : Integer; B : Boolean := False);

    procedure P (X: Integer; Y : Integer := 0 );

    What is the meaning ofP(3)?

    o It could refer to either procedure, as the second parameter of each has a defaultvalue.

    o SOLUTION: A set of subprogram declarations is illegal if it introduces thepotentialfor ambiguous calls.

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    19/23

    E.g., overloaded enumerations + overloaded procedures:

    type Primaryis ( Red, Blue, Yellow );typeStoplightis ( Red, Amber, Green);

    procedureSwitch ( Color : Primary;X, Y : Float);

    procedureSwitch ( Light : Stoplight; Y, X : Float);

    o Red and Switch are both overloaded.o There are no default values.o These procedure declarations are illegal, because they allow the following

    ambiguous call:o Switch ( Red, X => 0.0, Y => 0.0 );

    Goto

    EXERCISE: Was goto necessary, given that exit is provided?

    Exception Handling

    Exception handlerA block of code to be executed when an exception is raised(signalled).

    E.g.,

    procedure Producer ( . . . );useStack;

    begin. . .Push ( Data); -- If anexceptionisraised here

    -- (byattemptingto push to a fullstack),-- execution jumpsto ***

    . . .exception

    whenStack_Error =>declare

    Scratch : Integer;begin -- ***exception handler

    for I in 1 .. 3loop

    if not Empty ()thenPop ( Scratch );

    end if;

    end loop;Push ( Data);

    end;end Producer;

    Exceptionspropagate from callee to caller until an exeption handler is found:

    y If an exception is raised in procedure A, then look for the corresponding handler in theprocedure that called A (say, B).

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    20/23

    y If no handler for the raised exception is given in B, then look in the caller of B, etc.y If the main program is reached in this search down the dynamic chain and no exception

    handler is found there, terminate the program.

    This means that exception handlers use dynamic scoping.

    Why dynamic scoping?Different callers may want to take different actions.

    In implementation, an exception is like a dynamically scoped, non-local goto:

    y Execution of the subprogram in which the exception occurred and of the body of thecalling subprogram is aborted.

    y If the dynamic chain must be scanned to find the appropriate handler, the activationrecord of any subprogram or block that doesn't define a handler is deleted.

    Thus, exceptions violate both the Structure Principle and the Regularity Principle.

    Concurrency

    A tasking facility allows a program to do more than one thing at a time.E.g., a word processor that allows the user to edit one file while printing another:

    procedure Word_Processoris

    task Edit;end Edit;

    task body Editisbegin

    -- editsome fileend Edit;

    task Print;end Print;

    task body Printisbegin

    -- printsome file

    end Print;

    begin

    -- initiatetasksand wait fortheir completionend Word_Processor;

    In general, there are three common means of synchronizing communication between concurrent

    processes:

    y semaphoresy monitors

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    21/23

    y rendezvousAda uses rendezvous:

    y Taskentry declarations are like mailboxes ormessage ports.E.g.,

    y task Retrieve;y entrySeek ( K : Key);y . . .y end Retrieve;y One task sends a message to a mailbox in the other task, using syntax that looks like a

    procedure call with parameters.

    E.g.y task bodySummaryisy . . .y Seek ( ID );y . . .y end Summary;y The receiving taskaccepts the message from the named mailbox, and processes it.

    E.g.,y task body Retrieveisy . . .y acceptSeek ( K : Key) doy Save_Key := K;y end Seek;y . . .y end Retrieve;y If one of the tasks is ready and the other is not, then the ready task must wait to

    rendezvous with the other task. However, once the rendezvous has occurred (i.e., thecallee has accepted the parameters), both tasks continue executing concurrently (unlike a

    procedure call,

    E.g., a system which retrieves records to produce a summary, such that records may be retrievedconcurrently with the production of the summary:

    procedure DB_Systemis

    task Summary;

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    22/23

    end Summary;

    task bodySummaryis

    begin. . .Seek ( ID );. . .Fetch ( New_Record );. . .

    end Summary;

    task Retrieve;entrySeek ( K : Key);

    entry Fetch ( out P : Packet);end Retrieve;

    task body Retrieveisbegin

    loopacceptSeek ( K : Key) do

    Save_Key := K;end Seek;

    -- seek packetrecord and putitin New_Packet. . .

    accept Fetch ( out P : Packet) doP := New_Packet;

    end Fetch;end loop;

    end Retrieve;

    begin-- initiatetasksand wait fortheir completion

    end DB_System;

    Note that the Fetch message is sent from the taskSummary to the taskRetrieve, even though

    the data transfer of the record retrieved from the database is from Retrieve to Summary, because

    the mode of the Fetch message parameter is out -- when it receives a Fetch message, Retrieve

    copies the record it retrieved from the database into the out-mode parameter provided by

    Summary.

    Comparison of Subprograms and Tasks

    Subprogram Task

    Parameters transmitted from caller to callee. same

    Caller is suspended and callee is activated.Caller continues executing concurrently withcallee.

    When callee is deactivated, caller is Caller may not terminate until all local tasks

  • 8/6/2019 Computing Science 370_ada_copyright Jonathan Mohr

    23/23

    reactivated. finish.

    Ada provides a special synchronization control structure to allow a task to wait for any of several

    rendezvous.

    E.g.,

    selectacceptSend ( D : Document)do

    -- printthe document. . .

    end Send;oraccept Terminate

    doexit

    end Terminate;

    end select;

    A deadlockcan occur if one task is waiting for a rendezvous which never takes place. One way

    to avoid deadlocks is to useguarded entries so that a message is accepted only if a condition issatisfied:

    selectwhen Avail < SizeacceptSend ( D : in Document)do

    -- add documentto bufferAvail := Avail + 1;

    end Send;

    or when Avail> 0 accept Receive ( D : out Document)

    do-- returna document fromthebufferAvail := Avail - 1;

    end Receive;

    oraccept Terminate

    doexit

    end Terminate;end select;

    Copyright 2000, 2001Jonathan Mohrhttp://www.augustana.ab.ca/~mohrj/courses/common/csc370/lecture_notes/ada.html2 August 2011