home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / prog1 / ada-tutr.lzh / ADA-TUTR.DAT < prev    next >
Text File  |  1989-02-26  |  455KB  |  7,648 lines

  1.  120 562103210471054105910891093110911191127113811491159116911831195120512171229123812541281129913191335135613771386139114001406141414351445145514591466147314851506152815501570158315911600161016211629163816481659167616911710173117381749175717651773178317911813183418561875189319031914192519351947196619902014201820252031205520702090210321132133215921852189219421992211223022502271228122902301232023392366238723942406241524252435245524692494252125272533253825612584260626152621262826342640264726532665269127192734274227502759277127892809283328502860286728792899292429472973298830023015303030443057307330853110313531433152316231743197322132403253326532763288331833363352337133873403342334403460348435033520353535473560357735893610363136463659366536703676368237063727374837703791380538203833384738613878390339243947395839703980398940014024404740784095410441234138414941604175418541984214423842564278429443164333435343654384440544254446446144784495451645384561458045974617462846434662467446914708472247414761476847824794480348114824483548574879489649044916492549354955497249945011503350455059507350945116513251535167518552015216523052505269527852895297531953365351537153935398540454105425544554615480550055095521553255565577559556095626564256575669568757105736575757755788580058125834584958675878589359055916592759405963598059996011602560326039604560666087610061296138614761556163617161796199621462406263627762916304632663516370638764036410641864266434644164666477648765036518653365456557657766046626664166526665667866926714673267476770679668126831685068676885690869326953697670017025704270587073709071107123713771467158717671947219723272527258726672737279729673167337735573677380739474137432745174707477748574937501750975357563757776007618762776407650766076817699771877387760777977847792779978187841785378767901790779177924793179567985800480248041806280818093                                                                                                                                2459$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  2.                                                                   {;4}m 
  3.                {;4}m                                                   {;4}m 
  4.                {;4}m         C O N G R A T U L A T I O N S !        {;4}m   {;4}m 
  5.                {;4}m                                                   {;4}m 
  6.                                                                   {;4}m 
  7.  
  8.  
  9.        You've successfully completed ADA-TUTR, the Interactive Ada Tutor.{;4}m
  10.  
  11.  
  12.                  Your comments and suggestions are encouraged.
  13.                               Please send them to:
  14.  
  15.            Software Innovations Technology, Attention: John J. Herro
  16.                 1083 Mandarin Drive NE, Palm Bay, FL 32905-4706
  17.  
  18.  
  19.                                 Have a good day!
  20.  
  21.  
  22.                1645$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  23.  
  24.                           Thank you for using ADA-TUTR{;4}m.
  25.  
  26.  
  27.                   Please send your comments and suggestions to
  28.  
  29.            Software Innovations Technology, Attention: John J. Herro
  30.                 1083 Mandarin Drive NE, Palm Bay, FL 32905-4706
  31.  
  32.  
  33.                 I hope to see you again soon.  Have a good day!
  34.  
  35.  
  36.  
  37.                              1471Y102N108B108 108#105M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  38.  
  39.  
  40.                        The current screen number is XXX.
  41.  
  42.                   You're about XX percent through the course.
  43.  
  44.  
  45.  
  46.  
  47.                        Do you want to exit ADA-TUTR{;4}m now?
  48. 1HPlease press Y for yes or N for no.     3918Y107N120$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$${;4}m                                                                           {;4}m 
  49.       {;4}m                                                                     {;4}m 
  50.       {;4}m                        W E L C O M E   T O                          {;4}m 
  51.       {;4}m                                                                     {;4}m 
  52.       {;4}m                          A D A - T U T R                         {;4}m   {;4}m 
  53.       {;4}m                                                                     {;4}m 
  54.       {;4}m         T H E   I N T E R A C T I V E   A D A   T U T O R           {;4}m 
  55.       {;4}m                                                                     {;4}m 
  56.                             by John J. Herro, Ph.D.                        {;4}m 
  57.  
  58.     Software Innovations Technology                  Serial #  14509
  59.         1083 Mandarin Drive NE                        Version  1.20
  60.        Palm Bay, FL  32905-4706                        21-DEC-1988
  61.             (407) 951-0233                    Copyright 1988  John J. Herro
  62.  
  63.     Shareware: Try ADA-TUTR{;4}m free.  To use it after the free trial, individ-
  64.     uals must register and organizations must buy a license.  Both are very
  65.     inexpensive, and give many benefits.  See page 2 of PRINT.ME for infor-
  66.     mation.  Whether or not you use ADA-TUTR{;4}m and register or buy a license,
  67.     please copy the complete program and give unmodified copies to others!
  68.  
  69.                          Have you used ADA-TUTR{;4}m before?
  70. 1H        Please press Y for yes or N for no.  You need not hit ENTER.                                                          1369#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  71.  
  72.                    What screen number would you like to see?
  73.  
  74.        (If you don't know, type 106 and I'll take you to the main menu.)
  75.  
  76.  
  77. Please type the number and press ENTER:
  78.      2517A104B109C110D111E112F113G114H115I116J117K118L119$$$$$$$$$$$$                                   MAIN MENU
  79.  
  80.  
  81. A{;4}m  Restart the Program.                  G{;4}m  Records, Arrays, and Assignment 3
  82.  
  83. B{;4}m  Introduction                          H{;4}m  Recursion and Assignment 4
  84.  
  85. C{;4}m  The Format of an Ada Program          I{;4}m  Subprograms and Packages
  86.  
  87. D{;4}m  Generic Instantiation and             J{;4}m  Additional Types, Exceptions,
  88.       Assignment 1                             TEXT_IO, and Assignment 5
  89.  
  90. E{;4}m  Simple Declarations and Simple        K{;4}m  Generics, Tasking, and Assignment 6
  91.       Attributes
  92.                                          L{;4}m  Advanced Topics
  93. F{;4}m  Operators, Control Constructs, and
  94.       Assignment 2                       X{;4}m  Exit the Program.
  95. 1HPlease press a letter.                                                           191211002099309841065105 100B100#105M106$$$$$$$$$$$$$$$$$$$$$$$$
  96.  
  97.                                  WELCOME BACK!{;4}m
  98.  
  99.  
  100.  
  101.                                Would you like to:
  102.  
  103.  
  104.                    1{;4}m  Resume where we left off?
  105.  
  106.                    2{;4}m  Go back to the last question?
  107.  
  108.                    3{;4}m  Go back to the last Outside Assignment?
  109.  
  110.                    4{;4}m  Go to the main menu?
  111.  
  112.                    5{;4}m  Go to a screen number of your choice?
  113. 1HPlease press 1, 2, 3, 4, or 5.                                                                177211002099309841065105 100B100#105M106$$$$$$$$$$$$$$$$$$$$$$$$
  114.  
  115.                                Would you like to:
  116.  
  117.  
  118.                    1{;4}m  Go back to where we were?
  119.  
  120.                    2{;4}m  Go back to the last question?
  121.  
  122.                    3{;4}m  Go back to the last Outside Assignment?
  123.  
  124.                    4{;4}m  Go to the main menu?
  125.  
  126.                    5{;4}m  Go to a screen number of your choice?
  127. 1HPlease press 1, 2, 3, 4, or 5.    2050A120B121C123D124E125F131M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                  INTRODUCTION
  128.                                       MENU
  129.  
  130.  
  131.                  A{;4}m  Welcome
  132.  
  133.                  B{;4}m  Printed Course Notes
  134.  
  135.                  C{;4}m  Do I Need an Ada Compiler for this Course?
  136.  
  137.                  D{;4}m  What is Ada?
  138.  
  139.                  E{;4}m  A Very Brief History of Ada
  140.  
  141.                  F{;4}m  What is a "Validated" Ada Compiler?
  142.  
  143.  
  144.                  M{;4}m  Go Back to the Main Menu.
  145.  
  146.                  X{;4}m  Exit the Program.
  147. 1HPlease press a letter.                          2072A138B140C151D153E154F162G163M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          THE FORMAT OF AN ADA PROGRAM
  148.                                       MENU
  149.  
  150.  
  151.       A{;4}m  Our First Ada Program               F{;4}m  Numbers
  152.  
  153.       B{;4}m  Local Declarations                  G{;4}m  Making the Dot Notation
  154.                                                    Automatic
  155.       C{;4}m  Capitalization and Spacing
  156.  
  157.       D{;4}m  Comments                            M{;4}m  Go Back to the Main Menu.
  158.  
  159.       E{;4}m  Identifiers                         X{;4}m  Exit the Program.
  160. 1HPlease press a letter.    1954A172B178C180D183M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                     GENERIC INSTANTIATION AND ASSIGNMENT 1
  161.                                       MENU
  162.  
  163.  
  164.                   A{;4}m  Displaying Integers
  165.  
  166.                   B{;4}m  Generic Instantiation
  167.  
  168.                   C{;4}m  Outside Assignment 1 -
  169.                         Preparing to Run Ada on Your Computer
  170.  
  171.                   D{;4}m  The Ada Library
  172.  
  173.  
  174.                   M{;4}m  Go Back to the Main Menu.
  175.  
  176.                   X{;4}m  Exit the Program.
  177. 1HPlease press a letter.                      1928A190B196C205D207M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   SIMPLE DECLARATIONS AND SIMPLE ATTRIBUTES
  178.                                       MENU
  179.  
  180.  
  181.                           A{;4}m  Variables and Constants
  182.  
  183.                           B{;4}m  Enumeration Types
  184.  
  185.                           C{;4}m  Subtypes
  186.  
  187.                           D{;4}m  Simple Attributes
  188.  
  189.  
  190.                           M{;4}m  Go Back to the Main Menu.
  191.  
  192.                           X{;4}m  Exit the Program.
  193. 1HPlease press a letter.                                                2370A223B225C230D238E247F249G255H257I262J268K271M106$$$$$$$$$$$$                OPERATORS, CONTROL CONSTRUCTS, AND ASSIGNMENT 2
  194.                                       MENU
  195.  
  196.  
  197.      A{;4}m  Operators                       H{;4}m  Labels and GOTOs
  198.  
  199.      B{;4}m  Range Tests                     I{;4}m  The CASE Construct
  200.  
  201.      C{;4}m  The Short Circuit Forms         J{;4}m  Brief Overview of Functions
  202.  
  203.      D{;4}m  The IF Block                    K{;4}m  Outside Assignment 2 -
  204.                                               Exercise in Enumeration Types
  205.      E{;4}m  WHILE Loops
  206.  
  207.      F{;4}m  FOR Loops                       M{;4}m  Go Back to the Main Menu
  208.  
  209.      G{;4}m  The EXIT Statement              X{;4}m  Exit the Program.
  210. 1HPlease press a letter.      2158A279B287C299D306E318F320M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                       RECORDS, ARRAYS, AND ASSIGNMENT 3
  211.                                       MENU
  212.  
  213.  
  214.                           A{;4}m  Records
  215.  
  216.                           B{;4}m  Arrays
  217.  
  218.                           C{;4}m  Multidimensional Arrays
  219.  
  220.                           D{;4}m  Strings
  221.  
  222.                           E{;4}m  Array Operators
  223.  
  224.                           F{;4}m  Outside Assignment 3 -
  225.                                 Exercise in Records
  226.  
  227.  
  228.                           M{;4}m  Go Back to the Main Menu.
  229.  
  230.                           X{;4}m  Exit the Program.
  231. 1HPlease press a letter.                  1915A327B334C339M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                           RECURSION AND ASSIGNMENT 4
  232.                                       MENU
  233.  
  234.  
  235.                          A{;4}m  Recursion
  236.  
  237.                          B{;4}m  The Tower of Hanoi Problem
  238.  
  239.                          C{;4}m  Outside Assignment 4 -
  240.                                Exercise in Recursion
  241.  
  242.  
  243.                          M{;4}m  Go Back to the Main Menu.
  244.  
  245.                          X{;4}m  Exit the Program.
  246. 1HPlease press a letter.                                                             2128A344B356C363D371E379F394M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                            SUBPROGRAMS AND PACKAGES
  247.                                       MENU
  248.  
  249.  
  250.                      A{;4}m  Procedures and Functions
  251.  
  252.                      B{;4}m  Default Parameters
  253.  
  254.                      C{;4}m  Packages
  255.  
  256.                      D{;4}m  Functions with Infix Notation
  257.  
  258.                      E{;4}m  Information Hiding: Private Types
  259.  
  260.                      F{;4}m  Type TEXT and Limited Private Types
  261.  
  262.  
  263.                      M{;4}m  Go Back to the Main Menu.
  264.  
  265.                      X{;4}m  Exit the Program.
  266. 1HPlease press a letter.                                                2162A409B426C428D434E451F461M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$            ADDITIONAL TYPES, EXCEPTIONS, TEXT_IO, AND ASSIGNMENT 5
  267.                                       MENU
  268.  
  269.  
  270.                      A{;4}m  Access Types
  271.  
  272.                      B{;4}m  User Defined Types and Portability
  273.  
  274.                      C{;4}m  Derived Types
  275.  
  276.                      D{;4}m  Exceptions
  277.  
  278.                      E{;4}m  More About TEXT_IO
  279.  
  280.                      F{;4}m  Outside Assignment 5 -
  281.                            Writing a Simple Line Editor
  282.  
  283.  
  284.                      M{;4}m  Go Back to the Main Menu.
  285.  
  286.                      X{;4}m  Exit the Program.
  287. 1HPlease press a letter.              1867A469B477C497M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      GENERICS, TASKING, AND ASSIGNMENT 6
  288.                                       MENU
  289.  
  290.  
  291.                           A{;4}m  Generics
  292.  
  293.                           B{;4}m  Tasking
  294.  
  295.                           C{;4}m  Outside Assignment 6 -
  296.                                 Exercise in Tasking
  297.  
  298.  
  299.                           M{;4}m  Go Back to the Main Menu.
  300.  
  301.                           X{;4}m  Exit the Program.
  302. 1HPlease press a letter.         2541A502B504C506D511E518F527G530H536I538J545K548L554M106$$$$$$$$                                ADVANCED TOPICS
  303.                                       MENU
  304.  
  305.  
  306. A{;4}m  Renaming                              H{;4}m  Subprogram Parameters with Generics
  307.  
  308. B{;4}m  Packages STANDARD and ASCII           I{;4}m  Representation Clauses and SYSTEM
  309.  
  310. C{;4}m  An Alternative to Infix Notation      J{;4}m  Unchecked Conversion and Unchecked
  311.                                                Deallocation
  312. D{;4}m  Record Discriminants and Record
  313.       Variants                           K{;4}m  Pragmas
  314.  
  315. E{;4}m  Fixed Point and Universal Types       L{;4}m  Loose Ends and Pitfalls
  316.  
  317. F{;4}m  More Attributes                       M{;4}m  Go Back to the Main Menu.
  318.  
  319. G{;4}m  SEQUENTIAL_IO and DIRECT_IO           X{;4}m  Exit the Program.
  320. 1HPlease press a letter.                                   3624 121B104$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                                                      {;4}m 
  321.            {;4}m                                                           {;4}m 
  322.            {;4}m     WELCOME TO ADA-TUTR, THE INTERACTIVE ADA TUTOR!    {;4}m   {;4}m 
  323.            {;4}m                                                           {;4}m 
  324.                                                                       {;4}m 
  325.  
  326. ADA-TUTR{;4}m will make you an excellent Ada programmer in minimum time.  You should
  327. be familiar with at least one other high-level language (Basic, Pascal, etc.)
  328.  
  329. You can study as long as you like.  Whenever you want to exit the program, just
  330. type X.  (I'll ask you to confirm that you really want to exit, in case you
  331. typed X by mistake.)  I'll remember exactly where we left off, so when you're
  332. ready to learn again, you'll be able to go back there or to any other lesson.
  333. Remember, just type X at any time to exit ADA-TUTR{;4}m.
  334.  
  335. ADA-TUTR{;4}m works with monochrome as well as color computers.  Please adjust the
  336. brightness and contrast of your screen now, so that the highlighted{;4}m words are
  337. noticeably brighter than the others, but all are easy to read.  You can set the
  338. colors at any time by typing S, and I'll remember your color choices.
  339.  
  340. Please send your comments and suggestions to Software Innovations Technology,
  341. Attention: John J. Herro, 1083 Mandarin Drive NE, Palm Bay, FL 32905-4706.
  342. 1HPlease type a space to go on.  (You need not hit ENTER.)                                                    2729 122B120$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              PRINTED COURSE NOTES
  343.  
  344. To get the most from ADA-TUTR{;4}m, you should have a printed copy of the PRINT.ME
  345. file.  If you haven't started printing the course notes yet, read this screen
  346. and then type X to exit the program temporarily.  Remember, you can leave
  347. ADA-TUTR{;4}m at any time, and later pick up exactly where you left off.
  348.  
  349. Then, when the system prompt (usually C>{;4}m) appears, type:
  350.  
  351.                                  PRINT PRINT.ME{;4}m
  352.  
  353. You can then restart ADA-TUTR{;4}m while your course notes are being printed.
  354. Please read through page 2 now.  If you got this far, you don't need page 3.
  355. Please read page 39 if you want to install ADA-TUTR{;4}m on a non-PC computer, such
  356. as a mainframe.
  357.  
  358. By the way, if you're using a PC and you ever want to print the screen that's
  359. currently being displayed, just hold a Shift key while pressing the PrtSc{;4}m key.
  360. 1HPlease type X to exit, a space to go on, or B to go back.                                               2961 123B121$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In addition to the printed course notes, we recommend (but don't require) that
  361. you have access to the Military Standard Ada Programming Language manual,
  362. ANSI/MIL-STD-1815A, 1983.  This volume is often called the Language Reference
  363. Manual{;4}m, or LRM{;4}m.  You'll probably find it in a public library, or perhaps in
  364. your company library.  If you can borrow an LRM, it's legal to copy the entire
  365. book.  You can also buy an LRM very inexpensively.
  366.  
  367. Although the LRM is a good reference, it's difficult reading and not a good
  368. learning tool.  With ADA-TUTR{;4}m you probably won't need a textbook, but if{;4}m you
  369. feel you do, try one of the following:
  370.  
  371.       1.  S. J. Young, AN INTRODUCTION TO ADA, Wiley and Sons, 1984
  372.  
  373.       2.  J. G. P. Barnes, PROGRAMMING IN ADA, Addison-Wesley, 1983
  374.  
  375.       3.  G. Booch, SOFTWARE ENGINEERING WITH ADA, Benjamin-Cummings, 1983
  376.  
  377. We have no financial interest in any of these authors or publishers; we simply
  378. selected three books out of many.  We don't recommend using books dated before
  379. 1983, because the Ada language changed then, and you'll be confused.
  380. 1HPlease type a space to go on, or B to go back.               2543 124B122$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   DO I NEED AN ADA COMPILER FOR THIS COURSE?
  381.  
  382. An Ada compiler is helpful, but not required.  As we go along, there will be
  383. six Outside Assignments; most of them ask you to write and compile a short Ada
  384. program.  If you don't have access to an Ada compiler, just skip the Outside
  385. Assignments.
  386.  
  387. A brief list of Ada compilers available for the PC and compatibles is in your
  388. printed course notes, on pages 36-37.  We tried to include all the popular Ada
  389. compilers, but we might have missed some.  If you know of an Ada compiler that
  390. you think should be on that list, please contact us.
  391.  
  392. A screen editor / word processor is very helpful, and we can send you a copy of
  393. one free or nearly free.  Please see page 38 of your printed course notes for
  394. details.
  395.  
  396. That's enough discussion of what's recommended for ADA-TUTR{;4}m.  Let's begin!
  397. 1HPlease type a space to go on, or B to go back.                                 3027 125B123$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                  WHAT IS ADA?
  398.  
  399. Ada is a modern language designed for programming large scale and real time
  400. systems.  Ada is also an excellent general purpose language.  It has many new
  401. features which help prevent errors and detect errors earlier.
  402.  
  403. However, Ada is much more than a new language.  It's also a new programming
  404. philosophy{;4}m.  Beware of learning just "Ada syntax"; you'll wind up writing
  405. Basic-like (or Pascal-like, etc.) programs that happen to be coded in Ada.  If
  406. you do that, you'll lose the many benefits of Ada.  Unfortunately, you won't
  407. see why Ada is a new programming philosophy until later in this course.  (By
  408. the time we get to packages and information hiding, you'll be an enthusiastic
  409. convert.)  In the meantime, please take our word for it:  Ada is a whole new
  410. programming philosophy, not just another language.
  411.  
  412. Because of its many features, Ada is relatively complicated.  There's about
  413. seven times as much to learn as Pascal.  However, the effort pays great
  414. dividends.  Once you learn the language, Ada programs are easier to write,
  415. easier to read, and much easier to modify a month or a year later.
  416. 1HPlease type a space to go on, or B to go back.                                                 3046 126B124$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          A VERY BRIEF HISTORY OF ADA
  417.  
  418. Ada was named for Augusta Ada Byron, countess of Lovelace and daughter of the
  419. poet Lord Byron.  She worked with Charles Babbage on his Analytical Engine, and
  420. has been called the world's first programmer.  The Language Reference Manual
  421. (LRM) was given the number ANSI/MIL-STD-1815A because Augusta Ada Byron was
  422. born in 1815.
  423.  
  424. Ada was invented because the U.S. Department of Defense (DoD) realized that
  425. none of the existing languages was very suitable for real-time control of
  426. large, embedded systems.  An embedded system is a computer system inside a
  427. product other than a computer, such as an intelligent oven or a guided missile.
  428. Programs for embedded systems are usually written with a cross compiler{;4}m, a
  429. compiler that runs on one machine and produces code for another.  Cross
  430. compilers are often called compilers for short.
  431.  
  432. In 1977 the DoD issued a Request for Proposal to develop a new language; the
  433. leading four contenders were designated Blue, Red, Yellow, and Green.
  434. Eventually Green was selected to be Ada; it was designed by the company
  435. Honeywell Bull under the direction of Jean Ichbiah of France.
  436. 1HPlease type a space to go on, or B to go back.                              18242127112831294130B125$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QIn the author's opinion, which one{;4}m of the following statements is true?
  437.  
  438.  
  439. 1.  Ada is simpler than Pascal.
  440.  
  441. 2.  Although Ada was designed for embedded systems, it makes a good general
  442.     purpose language.
  443.  
  444. 3.  Basic and Pascal programs can easily be translated into good Ada programs.
  445.  
  446. 4.  In languages that are simpler than Ada, errors are usually detected earlier
  447.     than in Ada.
  448. 1HPlease press 1, 2, 3, or 4, or B to go back.                                                    1438 131B126Q126$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$You're right!{;4}m  Ada makes use of the latest advances in software engineering, so
  449. it makes an excellent general purpose language.
  450. 1HPlease type a space to go on, or B or Q to go back to the question.                                      1864 131B126Q126$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, Ada is more complicated than Pascal.  So far as the philosophy{;4}m is
  451. concerned, Ada is an extension (or "superset") of Pascal.  However, in syntax{;4}m
  452. Ada isn't a superset of Pascal; the Ada syntax is different.
  453.  
  454. Although Ada is more complicated than Pascal (and many other languages), it has
  455. many advantages.  These advantages pay dividends in reduced effort to develop
  456. and maintain programs.
  457. 1HPlease type a space to go on, or B or Q to go back to the question.            1515 131B126Q126$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, it might be easy to translate Basic and Pascal programs into Ada, but the
  458. resulting programs wouldn't be very good, because they'd fail to take advantage
  459. of the features of Ada.
  460. 1HPlease type a space to go on, or B or Q to go back to the question.                                                             1756 131B126Q126$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, Ada has a reputation for detecting errors earlier than the simpler
  461. languages.  Ada detects errors at compile time that other languages detect at
  462. run time or not at all.  Examples are calling a subprogram with the wrong
  463. number of arguments, and unintentionally mixing different types in an
  464. expression.  We'll learn more about these things later.
  465. 1HPlease type a space to go on, or B or Q to go back to the question.                    3013T132F133B126$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q                      WHAT IS A "VALIDATED" ADA COMPILER?
  466.  
  467. Although the name "Ada" is no longer a trademark of the Department of Defense,
  468. the Ada Joint Program Office (AJPO) still validates Ada compilers (and cross
  469. compilers).  Only validated compilers may display an emblem that says,
  470. "Validated Ada ... This product conforms to ANSI/MIL-STD-1815A as determined by
  471. the AJPO under its current testing procedures."
  472.  
  473. If a compiler conforms exactly to the standard, and isn't a subset or superset
  474. of Ada, it can be validated after passing an extensive suite of tests (called
  475. the Ada Compiler Validation Capability, or ACVC).  The ACVC is updated every 18
  476. months, and the Validation Certificate expires one year after the ACVC.  After
  477. the certificate expires, the compiler must be retested under a new ACVC.
  478.  
  479. An unnumbered page in the beginning of the LRM says that "Only compilers which
  480. have been validated ... shall be used in DoD systems."  Also, a 1987 DoD
  481. Directive (3405.2) says that only validated Ada compilers may be used on
  482. mission critical systems.
  483.  
  484.  
  485. True or False?  Subsets and supersets of standard Ada may be called "Ada."
  486. 1HPlease press T for true or F for false, or B to go back.                                                               1926 134B131Q131$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$You're right!{;4}m  Compilers not conforming exactly to the Ada standard may be
  487. called "Ada."  This was true even when "Ada" was a DoD trademark.  A preface to
  488. the LRM says that compilers not conforming to the standard may be called "Ada"
  489. if there's a clear statement that they don't conform.
  490.  
  491. Of course, only validated Ada compilers are to be used on DoD systems, and
  492. validated compilers can't be subsets or supersets of standard Ada.
  493. 1HPlease type a space to go on, or B or Q to go back to the question.                                                  1922 134B131Q131$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$True.  It's a common misconception that subsets and supersets may not be called
  494. "Ada."  However, this was allowed even when "Ada" was a DoD trademark.  A
  495. preface to the LRM says that compilers not conforming to the standard may be
  496. called "Ada" if there's a clear statement that they don't conform.
  497.  
  498. It's true that only validated Ada compilers are to be used in DoD systems.
  499. Validated compilers can't be subsets or supersets of standard Ada.
  500. 1HPlease type a space to go on, or B or Q to go back to the question.                                                      1361F135T136B131$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QTrue or False?  The Validation tests are performed to provide reasonable
  501. assurance that a compiler is bug-free.
  502. 1HPlease press T for true or F for false, or B to go back.               1615 137B134Q134$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$You're right!{;4}m  The Validation tests are performed to make sure that a compiler
  503. conforms to the Ada standard, and isn't a subset or superset.  A compiler isn't
  504. believed to be bug-free just because it earned a Validation Certificate.
  505. 1HPlease type a space to go on, or B or Q to go back to the question.                                                             1616 137B134Q134$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$False.  That's a common misconception, but validation only determines that a
  506. compiler conforms exactly to the Ada standard, and isn't a subset or superset.
  507. A compiler isn't believed to be bug-free just because it earned a Validation
  508. Certificate.
  509. 1HPlease type a space to go on, or B or Q to go back to the question.                                                            2136 138B134$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  510.  
  511.    Introduction                             Records, Arrays, and Assignment 3
  512.  
  513. >  THE FORMAT OF AN ADA PROGRAM{;4}m             Recursion and Assignment 4
  514.  
  515.    Generic Instantiation and                Subprograms and Packages
  516.       Assignment 1
  517.                                             Additional Types, Exceptions,
  518.    Simple Declarations and Simple              TEXT_IO, and Assignment 5
  519.       Attributes
  520.                                             Generics, Tasking, and Assignment 6
  521.    Operators, Control Constructs, and
  522.       Assignment 2                          Advanced Topics
  523. 1HPlease type a space to go on, or B to go back.                                        3042 139B137$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                             OUR FIRST ADA PROGRAM
  524.  
  525. Now let's look at a simple Ada program.  This program merely prints "Hello!" on
  526. the terminal.
  527.  
  528.                          with TEXT_IO;
  529.                          procedure HELLO is
  530.                          begin
  531.                             TEXT_IO.PUT_LINE("Hello!");
  532.                          end HELLO;{;4}m
  533.  
  534. TEXT_IO is a "package" that comes with the Ada language.  We'll learn more
  535. about packages later.  TEXT_IO contains, among other things, a procedure
  536. PUT_LINE that takes one argument of type STRING and prints it on the terminal.
  537. In this case, the STRING argument is "Hello!"{;4}m.  Ada doesn't have any special
  538. I/O statements.  I/O is done by calling procedures that Ada provides for us.
  539.  
  540. Even though the package TEXT_IO comes with Ada, our procedure HELLO can't "see"
  541. it unless it says with TEXT_IO;{;4}m.  With that statement, our procedure can call
  542. any procedure or function inside TEXT_IO.  We call a procedure by giving the
  543. package name (TEXT_IO), followed by a dot and the name of the procedure within
  544. the package.  Like Pascal and unlike Fortran, the word CALL isn't used in Ada.
  545. 1HPlease type a space to go on, or B to go back.                                  3143 140B138$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                         with TEXT_IO;
  546.                          procedure HELLO is
  547.                          begin
  548.                             TEXT_IO.PUT_LINE("Hello!");
  549.                          end HELLO;{;4}m
  550.  
  551. The statement with TEXT_IO;{;4}m is called a context clause{;4}m because it specifies the
  552. "context" in which procedure HELLO is compiled.
  553.  
  554. In Ada a procedure{;4}m can be called either from another procedure or as the main
  555. program.  In this example, HELLO is the main program; it calls PUT_LINE.
  556.  
  557. Every Ada statement, including the last, ends with a semicolon.  (Technically,
  558. the lines above without semicolons aren't statements.)  In Pascal, semicolons
  559. come between{;4}m statements, but in Ada, a semicolon ends{;4}m a statement.
  560.  
  561. In Ada, the end{;4}m statement may optionally give the name of the procedure or
  562. function.  If a name is given, the compiler will check that it agrees with the
  563. name at the beginning.  If it doesn't agree, the compiler will issue a message.
  564.  
  565. The statements between begin{;4}m and end{;4}m (this program has only one) are called
  566. executable statements; when they're obeyed they're said to be executed{;4}m.
  567. 1HPlease type a space to go on, or B to go back.                                 3137 141B139$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                               LOCAL DECLARATIONS
  568.  
  569.                          with TEXT_IO;
  570.                          procedure HELLO is
  571.                             I    : INTEGER;
  572.                             X, Y : FLOAT;{;4}m
  573.                          begin
  574.                             TEXT_IO.PUT_LINE("Hello!");
  575.                          end HELLO;
  576.  
  577. Local declarations may appear between procedure{;4}m and begin{;4}m.  This simple program
  578. doesn't need any, but we've added two declarative statements by way of example.
  579. Executable statements are said to be executed{;4}m when they're obeyed, but when a
  580. declarative statement is obeyed, it's said to be elaborated{;4}m.  Declarative
  581. statements are elaborated at run time, not compile time.
  582.  
  583. In this example, when the procedure is called (either from another procedure or
  584. as the main program), the declarations are elaborated and variables I, X, and Y
  585. are brought into existence.  Then the executable statement(s) are obeyed.  When
  586. the end{;4}m statement is reached and the procedure returns, I, X, and Y go out of
  587. existence.  These three variables are local to procedure HELLO and can't be
  588. accessed from outside this procedure.
  589. 1HPlease type a space to go on, or B to go back.                                       2966 142B140$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                         with TEXT_IO;
  590.                          procedure HELLO is
  591.                             I    : INTEGER;
  592.                             X, Y : FLOAT;{;4}m
  593.                          begin
  594.                             TEXT_IO.PUT_LINE("Hello!");
  595.                          end HELLO;
  596.  
  597. If HELLO is called again, I, X, and Y will again be brought into existence, but
  598. their previous values won't necessarily be remembered between calls.  (Of
  599. course, in this simple example, I, X, and Y aren't given values anyway.)
  600.  
  601. Like Pascal and unlike Basic and Fortran, every Ada variable must be declared.
  602. But unlike Pascal, Ada programs don't need to say "var".  Ada knows that the
  603. objects declared above are variables.  Constant declarations contain the
  604. reserved word constant{;4}m and may or may not specify a type, like this:
  605.  
  606.                       PI     : constant := 3.141592654;
  607.                       TWO_PI : constant FLOAT := 2.0 * PI;{;4}m
  608.  
  609. Declarations are elaborated in order, top to bottom.  The two declarations
  610. above must appear in the order shown, because the second refers to the first.
  611. 1HPlease type a space to go on, or B to go back.          2214 143B141$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      PI     : constant := 3.141592654;
  612.                       TWO_PI : constant FLOAT := 2.0 * PI;{;4}m
  613.  
  614. The difference between specifying a type and not specifying a type in a
  615. constant declaration is subtle, and will be explained in the Advanced Topics
  616. section under "Universal Types."  For now, it doesn't make any difference
  617. whether or not a constant declaration specifies a type.  The compiler can tell
  618. from the constant whether the type is INTEGER or FLOAT.
  619.  
  620. Unlike Pascal, Ada allows constant declarations to be intermixed with variable
  621. declarations, so long as no declaration refers to a declaration below it.
  622. 1HPlease type a space to go on, or B to go back.                                                              1757314411452146B142$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q               1         with TEXT_IO;
  623.                          procedure HELLO is
  624.                2            I    : INTEGER;
  625.                             X, Y : FLOAT;
  626.                          begin
  627.                3            TEXT_IO.PUT_LINE("Hello!");
  628.                          end HELLO;
  629.  
  630. OK, in the program above, where are the executable statement(s){;4}m?
  631. 1HPlease press 1, 2, or 3, or B to go back.                   1867 147B143Q143$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$               1         with TEXT_IO;
  632.                          procedure HELLO is
  633.                2            I    : INTEGER;
  634.                             X, Y : FLOAT;
  635.                          begin
  636.                3            TEXT_IO.PUT_LINE("Hello!");{;4}m
  637.                          end HELLO;
  638.  
  639. You're right!{;4}m  Executable statements are placed between begin{;4}m and end{;4}m.
  640. 1HPlease type a space to go on, or B or Q to go back to the question.         1929 147B143Q143$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$               1         with TEXT_IO;
  641.                          procedure HELLO is
  642.                2            I    : INTEGER;
  643.                             X, Y : FLOAT;
  644.                          begin
  645.                3            TEXT_IO.PUT_LINE("Hello!");
  646.                          end HELLO;
  647.  
  648. No, with TEXT_IO;{;4}m is a context clause{;4}m.  Executable statements are placed
  649. between begin{;4}m and end{;4}m.
  650. 1HPlease type a space to go on, or B or Q to go back to the question.                                               2021 147B143Q143$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$               1         with TEXT_IO;
  651.                          procedure HELLO is
  652.                2            I    : INTEGER;
  653.                             X, Y : FLOAT;
  654.                          begin
  655.                3            TEXT_IO.PUT_LINE("Hello!");
  656.                          end HELLO;
  657.  
  658. No, declarative{;4}m statements are placed between procedure{;4}m and begin{;4}m.  Executable{;4}m
  659. statements are placed between begin{;4}m and end{;4}m.
  660. 1HPlease type a space to go on, or B or Q to go back to the question.                                                       1733214811493150B143$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q               1         with TEXT_IO;
  661.                          procedure HELLO is
  662.                2            I    : INTEGER;
  663.                             X, Y : FLOAT;
  664.                          begin
  665.                3            TEXT_IO.PUT_LINE("Hello!");
  666.                          end HELLO;
  667.  
  668. Now, where are the local declaration(s){;4}m?
  669. 1HPlease press 1, 2, or 3, or B to go back.                                           1870 151B147Q147$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$               1         with TEXT_IO;
  670.                          procedure HELLO is
  671.                2            I    : INTEGER;
  672.                             X, Y : FLOAT;{;4}m
  673.                          begin
  674.                3            TEXT_IO.PUT_LINE("Hello!");
  675.                          end HELLO;
  676.  
  677. You're right!{;4}m  Local declarations are placed between procedure{;4}m and begin{;4}m.
  678. 1HPlease type a space to go on, or B or Q to go back to the question.      1932 151B147Q147$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$               1         with TEXT_IO;
  679.                          procedure HELLO is
  680.                2            I    : INTEGER;
  681.                             X, Y : FLOAT;
  682.                          begin
  683.                3            TEXT_IO.PUT_LINE("Hello!");
  684.                          end HELLO;
  685.  
  686. No, with TEXT_IO;{;4}m is a context clause{;4}m.  Local declarations are placed between
  687. procedure{;4}m and begin{;4}m.
  688. 1HPlease type a space to go on, or B or Q to go back to the question.                                            2017 151B147Q147$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$               1         with TEXT_IO;
  689.                          procedure HELLO is
  690.                2            I    : INTEGER;
  691.                             X, Y : FLOAT;
  692.                          begin
  693.                3            TEXT_IO.PUT_LINE("Hello!");
  694.                          end HELLO;
  695.  
  696. No, executable{;4}m statements are placed between begin{;4}m and end{;4}m.  Local declarations{;4}m
  697. are placed between procedure{;4}m and begin{;4}m.
  698. 1HPlease type a space to go on, or B or Q to go back to the question.                                                           2641 152B147$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                           CAPITALIZATION AND SPACING
  699.  
  700.                          with TEXT_IO;
  701.                          procedure HELLO is
  702.                             I    : INTEGER;
  703.                             X, Y : FLOAT;
  704.                          begin
  705.                             TEXT_IO.PUT_LINE("Hello!");
  706.                          end HELLO;
  707.  
  708. Except in quoted STRINGs like "Hello!", capitalization isn't important in Ada.
  709. The LRM shows all reserved words in lower case and all identifiers in upper
  710. case, so that's the style we're using in our examples.
  711.  
  712. In Ada, unlike Fortran, statements may begin anywhere on the line; columns
  713. aren't significant.  Most people indent the local declarations and the
  714. executable statements three spaces, as shown above.  Spaces and tabs may not
  715. appear within{;4}m reserved words and identifiers, but they may freely be used
  716. between{;4}m elements of the program.
  717. 1HPlease type a space to go on, or B to go back.                                   2456 153B151$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                         with TEXT_IO;
  718.                          procedure HELLO is
  719.                             I    : INTEGER;
  720.                             X, Y : FLOAT;
  721.                          begin
  722.                             TEXT_IO.PUT_LINE("Hello!");
  723.                          end HELLO;
  724.  
  725. Since a semicolon marks the end of a statement, we can put several statements
  726. on one line, like this:
  727.  
  728.                           I : INTEGER;   X, Y : FLOAT;
  729.  
  730. We can also continue a statement over several lines, breaking anywhere a space
  731. would be permitted, like this:
  732.  
  733.                                 TEXT_IO.
  734.                                      PUT_LINE(
  735.                                      "Hello!");
  736.  
  737. Most people follow the capitalization and spacing style of the LRM, so we'll do
  738. that in this course.
  739. 1HPlease type a space to go on, or B to go back.                    2868 154B152$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    COMMENTS
  740.  
  741.           with TEXT_IO;
  742.           procedure HELLO is
  743.              -- This program prints "Hello!" on the screen.{;4}m
  744.              I    : INTEGER; -- These declarations aren't needed; they{;4}m
  745.              X, Y : FLOAT;   -- were added only to provide examples.{;4}m
  746.           begin
  747.              TEXT_IO.PUT_LINE("Hello!");
  748.           end HELLO;
  749.  
  750. Comments in Ada begin with a double hyphen (double minus sign) and continue
  751. through the end of the line.  No space is permitted inside the double hyphen.
  752. As shown, a comment can be an entire line, or it can follow code on a line.
  753.  
  754. Ada programs generally have less need for comments than programs written in
  755. other languages.  The reason is that, as we'll see, the identifiers can be as
  756. long as we like and can have very meaningful names.  Also, when we learn about
  757. named notation, we'll see that calls to subprograms can be made much more
  758. readable in Ada than in other languages.  These features and others tend to
  759. make Ada programs self documenting.
  760. 1HPlease type a space to go on, or B to go back.        3069 155B153$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                  IDENTIFIERS
  761.  
  762.                          with TEXT_IO;
  763.                          procedure HELLO is
  764.                             I    : INTEGER;
  765.                             X, Y : FLOAT;
  766.                          begin
  767.                             TEXT_IO.PUT_LINE("Hello!");
  768.                          end HELLO;
  769.  
  770. In this program, everything in capital letters is an identifier{;4}m.  Ada
  771. identifiers may contain letters, digits, and underlines, but must start with a
  772. letter.  They may not contain spaces or other characters.  Identifiers may be
  773. as long as you like, up to the length of a line.  (The maximum line length
  774. depends on the particular implementation of Ada.)  All characters are
  775. significant, so THIS_IS_A_LONG_IDENTIFIER_1 and THIS_IS_A_LONG_IDENTIFIER_2 are
  776. distinct.  Since underlines are significant, A_B is different from AB.  Every
  777. underline must be followed by a letter or a digit.  Thus, you can't have two
  778. underlines together, and an identifier can't end in an underline.
  779.  
  780. Reserved words{;4}m may not be used as identifiers.  The 63 Ada reserved words are
  781. listed on page 4 of your printed course notes, and in section 2.9 of the LRM.
  782. 1HPlease type a space to go on, or B to go back.       1665315611572158415951606161B154$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q                 1.  1553B
  783.  
  784.                  2.  BEGIN
  785.  
  786.                  3.  This_Is_a_Very_Long_Name_for_an_Identifier
  787.  
  788.                  4.  SYS$QIO
  789.  
  790.                  5.  NUMBER_OF_TARGETS_
  791.  
  792.                  6.  MAX SPEED
  793.  
  794.  
  795. Only one{;4}m of the above is a legal Ada identifier.  Which is it?
  796. 1HPlease press 1, 2, 3, 4, 5, or 6, or B to go back.           2036 162B155Q155$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 1.  1553B
  797.  
  798.                  2.  BEGIN
  799.  
  800.                  3.  This_Is_a_Very_Long_Name_for_an_Identifier{;4}m
  801.  
  802.                  4.  SYS$QIO
  803.  
  804.                  5.  NUMBER_OF_TARGETS_
  805.  
  806.                  6.  MAX SPEED
  807.  
  808.  
  809. You're right!{;4}m  An Ada identifier can be as long as we like (up to the length of
  810. a line), and upper/lower case isn't important in Ada.
  811.  
  812. Number 1 begins with a digit, 2 is a reserved word, 4 has a dollar sign, 5 has
  813. a trailing underline, and 6 has a space.
  814. 1HPlease type a space to go on, or B or Q to go back to the question.                                        1715 162B155Q155$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 1.  1553B
  815.  
  816.                  2.  BEGIN
  817.  
  818.                  3.  This_Is_a_Very_Long_Name_for_an_Identifier
  819.  
  820.                  4.  SYS$QIO
  821.  
  822.                  5.  NUMBER_OF_TARGETS_
  823.  
  824.                  6.  MAX SPEED
  825.  
  826.  
  827. No, number 1 is illegal because Ada identifiers must begin with a letter.
  828. 1HPlease type a space to go on, or B or Q to go back to the question.                                                             1713 162B155Q155$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 1.  1553B
  829.  
  830.                  2.  BEGIN
  831.  
  832.                  3.  This_Is_a_Very_Long_Name_for_an_Identifier
  833.  
  834.                  4.  SYS$QIO
  835.  
  836.                  5.  NUMBER_OF_TARGETS_
  837.  
  838.                  6.  MAX SPEED
  839.  
  840.  
  841. No, number 2 is illegal because begin{;4}m is a reserved word.
  842. 1HPlease type a space to go on, or B or Q to go back to the question.                                                               1761 162B155Q155$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 1.  1553B
  843.  
  844.                  2.  BEGIN
  845.  
  846.                  3.  This_Is_a_Very_Long_Name_for_an_Identifier
  847.  
  848.                  4.  SYS$QIO
  849.  
  850.                  5.  NUMBER_OF_TARGETS_
  851.  
  852.                  6.  MAX SPEED
  853.  
  854.  
  855. No, number 4 is illegal because of the dollar sign.  Ada identifiers may
  856. contain only letters, digits, and underlines.
  857. 1HPlease type a space to go on, or B or Q to go back to the question.               1914 162B155Q155$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 1.  1553B
  858.  
  859.                  2.  BEGIN
  860.  
  861.                  3.  This_Is_a_Very_Long_Name_for_an_Identifier
  862.  
  863.                  4.  SYS$QIO
  864.  
  865.                  5.  NUMBER_OF_TARGETS_
  866.  
  867.                  6.  MAX SPEED
  868.  
  869.  
  870. No, number 5 is illegal because of the trailing underline.  Every underline
  871. must be followed by a letter or a digit.  You can't have a trailing underline,
  872. and you can't have two underlines together.
  873. 1HPlease type a space to go on, or B or Q to go back to the question.                                                              1755 162B155Q155$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 1.  1553B
  874.  
  875.                  2.  BEGIN
  876.  
  877.                  3.  This_Is_a_Very_Long_Name_for_an_Identifier
  878.  
  879.                  4.  SYS$QIO
  880.  
  881.                  5.  NUMBER_OF_TARGETS_
  882.  
  883.                  6.  MAX SPEED
  884.  
  885.  
  886. No, number 6 is illegal because of the space.  Ada identifiers may contain only
  887. letters, digits, and underlines.
  888. 1HPlease type a space to go on, or B or Q to go back to the question.                     3124 163B155$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    NUMBERS
  889.  
  890. In numbers, unlike identifiers, underlines are not{;4}m significant.  Thus 12345{;4}m and
  891. 12_345{;4}m are equivalent.  Spaces aren't permitted within numbers.  When an
  892. underline appears in a number, it must be surrounded by digits.  Thus, all of
  893. these are illegal:     123_     123_.0     _123     12__3
  894.  
  895. Floating point numbers must have at least one digit before and one digit after
  896. the decimal point.  Unlike Basic and Fortran, Ada forces us to write 1.0{;4}m
  897. instead of 1.{;4}m, and 0.5{;4}m instead of .5{;4}m.  Scientific notation may be used: 1.3E-3{;4}m
  898. is the same as 0.0013{;4}m.  Non-negative exponents may be used even in integers:
  899. 12E3{;4}m means 12_000{;4}m.
  900.  
  901. Numbers may be specified in any base from 2 to 16, as shown below.  These three
  902. numbers are all equal:
  903.  
  904.            16#FC03#         2#1111_1100_0000_0011#         8#176003#{;4}m
  905.  
  906. A number with a base may have an exponent.  The number after the E{;4}m is still
  907. written in decimal, and gives the power by which the base is raised.  Thus
  908. 2#110#E5{;4}m is 6 times 2**5, or 192.
  909. 1HPlease type a space to go on, or B to go back.                                                    3063 164B162$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                       MAKING THE DOT NOTATION AUTOMATIC
  910.  
  911. These two programs are equivalent:
  912.  
  913.       with TEXT_IO;                           with TEXT_IO; use TEXT_IO;{;4}m
  914.       procedure HELLO is                      procedure HELLO is
  915.       begin                                   begin
  916.          TEXT_IO.{;4}mPUT_LINE("Hello!");             PUT_LINE("Hello!");
  917.       end HELLO;                              end HELLO;
  918.  
  919. We've said that the statement with TEXT_IO;{;4}m makes the package visible{;4}m, so that
  920. our program can call the procedures and functions in it.  To call a procedure,
  921. we write the name of the package, a dot, and the name of the procedure.
  922.  
  923. The statement use TEXT_IO;{;4}m tells the compiler to supply the name of the package
  924. and the dot for us.  That's why the two programs above are equivalent.
  925.  
  926. Remember, in Ada with{;4}m provides visibility; use{;4}m asks the compiler to supply the
  927. package name and the dot.
  928.  
  929. The Ada meanings of the words with{;4}m and use{;4}m are more or less reversed from their
  930. meanings in Pascal.  Also, in Ada one can't use{;4}m records, only packages.
  931. 1HPlease type a space to go on, or B to go back.             3118 165B163$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$      with TEXT_IO;                           with TEXT_IO; use TEXT_IO;{;4}m
  932.       procedure HELLO is                      procedure HELLO is
  933.       begin                                   begin
  934.          TEXT_IO.{;4}mPUT_LINE("Hello!");             PUT_LINE("Hello!");
  935.       end HELLO;                              end HELLO;
  936.  
  937. A program can with{;4}m and use{;4}m several packages.  For example, there's a package
  938. that comes with Ada called CALENDAR.  Suppose we've also compiled two packages
  939. of our own, called MY_PKG_1 and MY_PKG_2.  Then our program might say
  940.  
  941.                   with TEXT_IO, CALENDAR, MY_PKG_1, MY_PKG_2;
  942.                   use  TEXT_IO, CALENDAR, MY_PKG_1, MY_PKG_2;{;4}m
  943.  
  944. In this case, when the compiler sees the call to PUT_LINE, it will search all
  945. four packages that we've use{;4}md for a procedure PUT_LINE that takes one STRING
  946. argument.  If it finds no procedure PUT_LINE, the compiler will print an error
  947. message, like "PUT_LINE is not declared" or "Undeclared identifier PUT_LINE."
  948.  
  949. You may ask, what if there are several procedures PUT_LINE among the four
  950. packages?  Will the compiler stop when it finds the first PUT_LINE?  No.
  951. 1HPlease type a space to go on, or B to go back.                                                          2829 166B164$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                  with TEXT_IO, CALENDAR, MY_PKG_1, MY_PKG_2;
  952.                   use  TEXT_IO, CALENDAR, MY_PKG_1, MY_PKG_2;{;4}m
  953.  
  954. If the compiler finds several PUT_LINEs, the name PUT_LINE is said to be
  955. overloaded{;4}m.  In that case the compiler will use the number{;4}m and types{;4}m of
  956. arguments to try to select the right PUT_LINE.  For example, if TEXT_IO
  957. contains a PUT_LINE that takes one STRING argument, and MY_PKG_1 contains a
  958. PUT_LINE that takes one INTEGER argument, the compiler will write a call to
  959. TEXT_IO.PUT_LINE and not MY_PKG_1.PUT_LINE, because the calling statement
  960. supplies one STRING argument.
  961.  
  962. If there's more than one PUT_LINE that takes exactly one STRING argument, then
  963. the call is ambiguous and the compiler can't resolve the overloading.  The
  964. error message will be something like "Ambiguity detected during overload
  965. resolution" or "Ambiguous expression."  In that case, we'd have to specify
  966. TEXT_IO.{;4}mPUT_LINE even though we said use TEXT_IO;{;4}m.
  967. 1HPlease type a space to go on, or B to go back.                                               2730 167B165$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In summary, the compiler will search all the packages that we've use{;4}md for a
  968. procedure with the correct number and types of arguments.  If it finds exactly
  969. one, everything's fine.  If it finds no procedure with the correct name, the
  970. error message will be something like "Undeclared identifier."  If it finds one
  971. or more procedures with the correct name, but none of them has the right number
  972. and types of arguments, it will print an error message like "Inconsistency
  973. detected during overload resolution" or "Unresolvable expression."  Finally, if
  974. it finds more than one procedure with the correct number and types of
  975. arguments, the message is "Ambiguity detected during overload resolution" or
  976. "Ambiguous expression."
  977.  
  978. Overloading may seem like an unnecessary complication at this point, but you'll
  979. see later how very useful it can be.  Overloading is especially useful with
  980. the infix operators when we create our own types.  All of this will be covered
  981. later.
  982. 1HPlease type a space to go on, or B to go back.                                              19344168116921703170B166$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QWhich one{;4}m of the following would most likely be the cause of the message
  983. "Inconsistency detected during overload resolution"?
  984.  
  985.  
  986.     1.  You tried to use{;4}m a package that you didn't with{;4}m.
  987.  
  988.     2.  You misspelled the name of a package in a call using dot notation.
  989.  
  990.     3.  You misspelled the name of a procedure or function in a call.
  991.  
  992.     4.  You called a procedure or function with the wrong number or types of
  993.         arguments.
  994. 1HPlease press 1, 2, 3, or 4, or B to go back.                                          2034 171B167Q167$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  You tried to use a package that you didn't with.
  995.  
  996.     2.  You misspelled the name of a package in a call using dot notation.
  997.  
  998.     3.  You misspelled the name of a procedure or function in a call.
  999.  
  1000.     4.  You called a procedure or function with the wrong number or types of
  1001.         arguments.{;4}m
  1002.  
  1003.  
  1004. You're right!{;4}m  The message "Inconsistency detected during overload resolution"
  1005. usually means that you called a procedure or a function with the wrong number
  1006. or types of arguments.
  1007. 1HPlease type a space to go on, or B or Q to go back to the question.                                          2025 171B167Q167$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  You tried to use{;4}m a package that you didn't with{;4}m.
  1008.  
  1009.     2.  You misspelled the name of a package in a call using dot notation.
  1010.  
  1011.     3.  You misspelled the name of a procedure or function in a call.
  1012.  
  1013.     4.  You called a procedure or function with the wrong number or types of
  1014.         arguments.
  1015.  
  1016.  
  1017. No, for number 1 the message would be something like "This package is not named
  1018. in a prior with{;4}m clause," or "use{;4}m clause was not expected here."
  1019. 1HPlease type a space to go on, or B or Q to go back to the question.                                                   1950 171B167Q167$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  You tried to use{;4}m a package that you didn't with{;4}m.
  1020.  
  1021.     2.  You misspelled the name of a package in a call using dot notation.
  1022.  
  1023.     3.  You misspelled the name of a procedure or function in a call.
  1024.  
  1025.     4.  You called a procedure or function with the wrong number or types of
  1026.         arguments.
  1027.  
  1028.  
  1029. No, if you misspell the name of a package, procedure, or function, the most
  1030. probable error message would be "Undeclared identifier."
  1031. 1HPlease type a space to go on, or B or Q to go back to the question.                          2150 172B167$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  1032.  
  1033.    Introduction                             Records, Arrays, and Assignment 3
  1034.  
  1035.    The Format of an Ada Program             Recursion and Assignment 4
  1036.  
  1037. >  GENERIC INSTANTIATION AND{;4}m                Subprograms and Packages
  1038.       ASSIGNMENT 1{;4}m
  1039.                                             Additional Types, Exceptions,
  1040.    Simple Declarations and Simple              TEXT_IO, and Assignment 5
  1041.       Attributes
  1042.                                             Generics, Tasking, and Assignment 6
  1043.    Operators, Control Constructs, and
  1044.       Assignment 2                          Advanced Topics
  1045. 1HPlease type a space to go on, or B to go back.                          2874 173B171$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              DISPLAYING INTEGERS
  1046.  
  1047. with TEXT_IO; use TEXT_IO;                           with TEXT_IO; use TEXT_IO;
  1048. procedure HELLO is             THIS         THIS{;4}m     procedure ADD is
  1049. begin                       <= IS             IS =>{;4}m  begin
  1050.    PUT_LINE("Hello!"{;4}m);         RIGHT       WRONG{;4}m        PUT_LINE(2 + 2{;4}m);
  1051. end HELLO;                                           end ADD;
  1052.  
  1053. Now let's write a program called ADD that adds 2 + 2 and prints the result.
  1054. You may think that we could take the HELLO program and substitute 2 + 2{;4}m for
  1055. "Hello!"{;4}m, but that won't work.  (We never said Ada is easy!)  Why won't it
  1056. work?  Because TEXT_IO doesn't have a procedure PUT_LINE that takes an INTEGER
  1057. argument.  One correct program is this:
  1058.  
  1059.         with TEXT_IO; use TEXT_IO;
  1060.         procedure ADD is
  1061.            package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;{;4}m
  1062.         begin
  1063.            PUT(2 + 2);
  1064.            NEW_LINE;{;4}m
  1065.         end ADD;
  1066. 1HPlease type a space to go on, or B to go back.  3347 174B172$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        with TEXT_IO; use TEXT_IO;
  1067.         procedure ADD is
  1068.            package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;{;4}m
  1069.         begin
  1070.            PUT(2 + 2);
  1071.            NEW_LINE;
  1072.         end ADD;
  1073.  
  1074. __________ TEXT_IO __________  The package TEXT_IO contains procedures for type
  1075. | PUT_LINE for type STRING  |  STRING.  This package is ready-to-use.  However,
  1076. | PUT      for type STRING  |  inside TEXT_IO is another package, INTEGER_IO,
  1077. | GET_LINE for type STRING  |  that's not{;4}m ready-to-use.  It's called a generic{;4}m
  1078. | GET      for type STRING  |  package because it has an empty box{;4}m (<>{;4}m) in
  1079. | NEW_LINE                  |  place of the type.  We can make a new, ready-to-
  1080. | ...                       |  -use package from INTEGER_IO by giving the type:
  1081. |                           |  package MY_INT_IO is new INTEGER_IO(INTEGER{;4}m); we
  1082. |  ______ INTEGER_IO ______ |  could have used any name in place of MY_INT_IO.
  1083. |  | PUT for type <>      | |  Note that we've declared our new package locally
  1084. |  | GET for type <>      | |  inside the procedure ADD.  MY_INT_IO now has the
  1085. |  | ...                  | |  same procedures and functions as INTEGER_IO, but
  1086. |  |______________________| |  with the empty box filled in with the type
  1087. |___________________________|  INTEGER, like this:
  1088. 1HPlease type a space to go on, or B to go back.                             3335 175B173$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                with TEXT_IO; use TEXT_IO;
  1089. __________ TEXT_IO __________   procedure ADD is
  1090. | PUT_LINE for type STRING  |      package MY_INT_IO is new INTEGER_IO({;4}m
  1091. | PUT      for type STRING  |           INTEGER); use MY_INT_IO;{;4}m
  1092. | GET_LINE for type STRING  |   begin
  1093. | GET      for type STRING  |      PUT(2 + 2);{;4}m
  1094. | NEW_LINE                  |      NEW_LINE;{;4}m
  1095. | ...                       |   end ADD;
  1096. |                           |
  1097. |  ______ INTEGER_IO ______ |    ______ MY_INT_IO _______{;4}m
  1098. |  | PUT for type <>      | |    | PUT for type INTEGER |{;4}m
  1099. |  | GET for type <>      | |    | GET for type INTEGER |{;4}m
  1100. |  | ...                  | |    | ...                  |{;4}m
  1101. |  |______________________| |    |______________________|{;4}m
  1102. |___________________________|
  1103.  
  1104. Since INTEGER_IO (and therefore MY_INT_IO) doesn't have a PUT_LINE, we call
  1105. MY_INT_IO.PUT and then TEXT_IO.NEW_LINE.  Note that our program says
  1106. use MY_INT_IO;{;4}m after declaring MY_INT_IO.  When the compiler sees the call
  1107. PUT(2 + 2);{;4}m it writes code to call MY_INT_IO.PUT rather than TEXT_IO.PUT,
  1108. because MY_INT_IO.PUT takes an argument of type INTEGER.  The compiler then
  1109. finds NEW_LINE in TEXT_IO and writes a call to TEXT_IO.NEW_LINE.
  1110. 1HPlease type a space to go on, or B to go back.                                         1331F176T177B174$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QTrue or False?  In our example, a program could call INTEGER_IO.PUT{;4}m.
  1111. 1HPlease press T for true or F for false, or B to go back.                                             1620 178B175Q175$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$You're right!{;4}m  Since INTEGER_IO is generic, a program can't call its procedures
  1112. and functions.  The program must specify the type and create an instance{;4}m of
  1113. INTEGER_IO, such as MY_INT_IO.  It can then call PUT in MY_INT_IO.
  1114. 1HPlease type a space to go on, or B or Q to go back to the question.                                                        1563 178B175Q175$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$False.  Since INTEGER_IO is generic, a program can't call its procedures and
  1115. functions.  The program must specify the type and create an instance{;4}m of
  1116. INTEGER_IO, such as MY_INT_IO.  It can then call PUT in MY_INT_IO.
  1117. 1HPlease type a space to go on, or B or Q to go back to the question.             3357 179B175$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                             GENERIC INSTANTIATION
  1118.  
  1119.                  package MY_INT_IO is new INTEGER_IO(INTEGER);{;4}m
  1120.  
  1121.               ______ INTEGER_IO ______    ______ MY_INT_IO _______{;4}m
  1122.               | PUT for type <>      |    | PUT for type INTEGER |{;4}m
  1123.               | GET for type <>      |    | GET for type INTEGER |{;4}m
  1124.               | ...                  |    | ...                  |{;4}m
  1125.               |______________________|    |______________________|{;4}m
  1126.  
  1127. This process of creating an instance{;4}m of the generic package INTEGER_IO for the
  1128. type INTEGER is called generic instantiation{;4}m.  Later in this course we'll
  1129. learn to write our own generic packages, procedures, and functions.  However,
  1130. we wanted to learn, early in the course, how to instantiate an already written
  1131. generic package in order to display integers.
  1132.  
  1133. But why does Ada make TEXT_IO ready-to-use for STRINGs, while INTEGER_IO is
  1134. generic, and has to be instantiated for INTEGERs?  Because programs normally
  1135. use only one type STRING, but can have several integer types.  Right now, we
  1136. know of only one integer type, the standard INTEGER.  Later we'll learn about
  1137. user-defined types and derived types, and we'll see how there can be several
  1138. integer types.  INTEGER_IO can be instantiated for each of these types.
  1139. 1HPlease type a space to go on, or B to go back.                   2436 180B178$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Since INTEGER_IO is often instantiated for the standard INTEGER type, some
  1140. implementations of Ada provide an already-instantiated package for the type
  1141. INTEGER, equivalent to our package MY_INT_IO.  However, an implementation of
  1142. Ada need not supply such a package to meet the Ada standard.  Our program did
  1143. its own instantiation of INTEGER_IO so that it would run on any Ada that meets
  1144. the standard.
  1145.  
  1146. There's another generic package within TEXT_IO called FLOAT_IO.  Input and
  1147. output of floating point numbers is done by instantiating FLOAT_IO for the type
  1148. FLOAT.  As with integers, we'll later learn how there can be several floating
  1149. point types besides the standard FLOAT.
  1150.  
  1151. We're now ready for our first Outside Assignment!  Let's compile and run our
  1152. two sample programs, HELLO and ADD.
  1153. 1HPlease type a space to go on, or B to go back.  
  1154.                                       2943 181B179$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A          OUTSIDE ASSIGNMENT 1 - PREPARING TO RUN ADA ON YOUR COMPUTER
  1155.  
  1156. Since these screens disappear, you'll probably want to refer to your printed
  1157. course notes when doing the Outside Assignments.  The first assignment appears
  1158. on page 5.  In this assignment, we'll compile, link, and run our first two
  1159. programs, HELLO and ADD.
  1160.  
  1161. First compile HELLO.ADA, then link, and then execute the program.  The exact
  1162. steps will depend on the Ada compiler you're using.  You'll probably have to
  1163. refer to the documentation that came with your compiler.  Note that some
  1164. implementations of Ada use the term "binding" instead of "linking."  When you
  1165. run the program, it should print Hello!{;4}m on your screen.
  1166.  
  1167. Then compile ADD.ADA, link, and run the program.
  1168.  
  1169. Note that when we compile, we specify the name of the source file being
  1170. compiled.  Many, but not all, implementations of Ada assume the extension to be
  1171. .ADA if it's not specified.  When we link, we specify the name of the main
  1172. program, which in our examples agrees with the name of the source file.  The
  1173. linking step produces a file which we can execute.
  1174. 1HPlease type a space to go on, or B to go back.                                 2237 182B180$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Note that, before we can compile an Ada program, we must create our own Ada
  1175. library.  Some implementations of Ada come with a library already created for
  1176. us; others require us to type a command to create a library.  When we compile
  1177. HELLO.ADA and ADD.ADA, the procedures HELLO and ADD are added to our library.
  1178. We'll discuss the Ada library in more detail later.
  1179.  
  1180. If you haven't done so already, please type X to exit ADA-TUTR{;4}m temporarily,
  1181. read page 5 of your printed course notes, and try the first Outside Assignment.
  1182.  
  1183. When you finish Outside Assignment 1, we'll go on to discuss the Ada library
  1184. and separate compilation of program units.
  1185. 1HPlease type X to exit, a space to go on, or B to go back.                                       1925 183B181$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              Congratulations on Completing Outside Assignment 1!{;4}m
  1186.  
  1187. We know this first assignment wasn't very interesting, because the programs
  1188. HELLO.ADA and ADD.ADA were supplied for you.  But we had to be sure we can
  1189. compile, link, and execute Ada programs, so we can do the remaining
  1190. assignments.
  1191.  
  1192. The rest of the Outside Assignments should be more challenging!
  1193.  
  1194. Let's go on to discuss the Ada library and separate compilation of program
  1195. units.
  1196. 1HPlease type a space to go on, or B to go back.                                                   2941 184B182$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                THE ADA LIBRARY
  1197.  
  1198. Why do we have to have our own library before running an Ada compiler, unlike
  1199. other compilers?  Because compilers for other languages simply take source code
  1200. and produce object code.  Ada compilers, however, take source code and a
  1201. library and produce object code and an updated library.  The library remembers
  1202. what we've compiled.
  1203.  
  1204.                                 ________________
  1205.                                |                |
  1206.              Source Code       |  Fortran,      |      Object Code
  1207.        ----------------------->|  Pascal, etc.  |----------------------->
  1208.                                |  Compiler      |
  1209.                                |________________|
  1210.  
  1211.                                 ________________
  1212.              Source Code       |                |      Object Code
  1213.        ----------------------->|  Ada           |----------------------->
  1214.              Ada Library       |  Compiler      |  Updated Ada Library
  1215.        ----------------------->|                |----------------------->
  1216.                                |________________|
  1217. 1HPlease type a space to go on, or B to go back.                                   3568 185B183$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$This gives us the advantage that Ada compilation is separate but dependent{;4}m.
  1218. Some languages, such as Fortran, offer separate and independent{;4}m compilation.  A
  1219. Fortran main program and a subroutine can be compiled independently, perhaps a
  1220. month apart.  When the subroutine is compiled, Fortran knows nothing about the
  1221. main program, and vice versa.  An advantage of separate{;4}m compilation is that we
  1222. can develop our program one piece at a time and compile each piece as it's
  1223. developed.  However, the independent{;4}m compilation is a disadvantage.  The
  1224. compiler can't check that the number and types of arguments in the call agree
  1225. with the number and types of arguments in the subroutine.  A Fortran main
  1226. program might say CALL SUB(I, J, K){;4}m, while the subroutine might say
  1227. SUBROUTINE SUB(I, J){;4}m.  Both of these will compile correctly.  When the program
  1228. is run, however, the results are unpredictable.  The program might simply give
  1229. wrong answers with no warning.
  1230.  
  1231. Other languages, such as early Pascal and many versions of Basic, don't have
  1232. separate compilation at all.  The compiler could check the number and types of
  1233. arguments in a call, because the entire program must be compiled at one time.
  1234. But the advantages of separate compilation are lost.  We can't develop the
  1235. program one piece at a time, compiling each piece as it's developed.  And if we
  1236. make the slightest change in one part of the program, the whole program has to
  1237. be recompiled.
  1238. 1HPlease type a space to go on, or B to go back.        3513 186B184$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Ada gives us the advantages of both systems, because compilation is separate
  1239. but dependent{;4}m.  We can compile a subprogram today and the calling program next
  1240. month.  (We could also put both into one file and compile them together.)  Each
  1241. compilation unit updates the library when it's compiled.  Thus, when a call to
  1242. a subprogram is encountered, the compiler will check the number and types of
  1243. arguments against the subprogram already in the library.
  1244.  
  1245. We could also write the calling program before{;4}m the subprogram, because Ada lets
  1246. us compile the subprogram specification{;4}m separately from its body{;4}m.  (We'll learn
  1247. more about that later.)  The specification contains the name of the subprogram,
  1248. and the names, number, and types of any arguments.  The specification also
  1249. tells which arguments are inputs, which are outputs, and which are both inputs
  1250. and outputs.  That's all the information the compiler needs to compile calls to
  1251. the subprogram; the body can be supplied later.  When the subprogram body is
  1252. compiled, the compiler will make sure it's consistent with the specification.
  1253.  
  1254. Ada comes with several packages, such as TEXT_IO.  These are already compiled
  1255. and placed into the library.  That's why our programs can say with TEXT_IO;{;4}m and
  1256. call its procedures and functions.
  1257.  
  1258. Ada libraries are a complication compared to other languages, but they offer
  1259. great advantages in program development.
  1260. 1HPlease type a space to go on, or B to go back.                                                               1355T187F188B185$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QTrue or False?  A procedure specification must be compiled before calls to the
  1261. procedure can be compiled.
  1262. 1HPlease press T for true or F for false, or B to go back.                     1426 189B186Q186$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$You're right!{;4}m  The specification contains all the information the compiler
  1263. needs to compile calls to the procedure.
  1264. 1HPlease type a space to go on, or B or Q to go back to the question.                                                  1460 189B186Q186$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$True.  The compiler needs the information in the specification to compile calls
  1265. to the procedure.  However, the procedure body{;4}m can be compiled later.
  1266. 1HPlease type a space to go on, or B or Q to go back to the question.                2150 190B186$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  1267.  
  1268.    Introduction                             Records, Arrays, and Assignment 3
  1269.  
  1270.    The Format of an Ada Program             Recursion and Assignment 4
  1271.  
  1272.    Generic Instantiation and                Subprograms and Packages
  1273.       Assignment 1
  1274.                                             Additional Types, Exceptions,
  1275. >  SIMPLE DECLARATIONS AND SIMPLE{;4}m              TEXT_IO, and Assignment 5
  1276.       ATTRIBUTES{;4}m
  1277.                                             Generics, Tasking, and Assignment 6
  1278.    Operators, Control Constructs, and
  1279.       Assignment 2                          Advanced Topics
  1280. 1HPlease type a space to go on, or B to go back.                          2867 191B189$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                             VARIABLES AND CONSTANTS
  1281.  
  1282.       procedure DECLARATIONS_DEMO is
  1283.          I, J, K : INTEGER;
  1284.          L, M    : INTEGER := 30;{;4}m
  1285.          F, G    : FLOAT;
  1286.          FACTOR  : constant := 1000;
  1287.       begin
  1288.          J := L + 10;          -- Simple assignment statements.
  1289.          F := 0.0;
  1290.          G := F + L;           -- ILLEGAL.  Can't accidentally mix types.
  1291.          G := F + FLOAT(L);    -- Legal.  Can deliberately convert types.
  1292.          K := INTEGER(F) + L;  -- Legal.
  1293.          FACTOR := 100;        -- ILLEGAL.  Constants can't change.
  1294.       end DECLARATIONS_DEMO;
  1295.  
  1296. This program doesn't do anything except demonstrate Ada declarations.  The
  1297. statement I, J, K : INTEGER;{;4}m brings three integer variables into existence.
  1298. The next statement creates two more integer variables and initializes both of
  1299. them to 30.  Every time this procedure is called, L and M are brought into
  1300. existence and initialized to 30.  Note that this is different from a Fortran
  1301. DATA statement, which initializes only once at compile time.
  1302. 1HPlease type a space to go on, or B to go back.         2954 192B190$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$      procedure DECLARATIONS_DEMO is
  1303.          I, J, K : INTEGER;
  1304.          L, M    : INTEGER := 30;
  1305.          F, G    : FLOAT;
  1306.          FACTOR  : constant := 1000;{;4}m
  1307.       begin
  1308.          J := L + 10;          -- Simple assignment statements.
  1309.          F := 0.0;
  1310.          G := F + L;           -- ILLEGAL.  Can't accidentally mix types.{;4}m
  1311.          G := F + FLOAT(L);    -- Legal.  Can deliberately convert types.
  1312.          K := INTEGER(F) + L;  -- Legal.
  1313.          FACTOR := 100;        -- ILLEGAL.  Constants can't change.
  1314.       end DECLARATIONS_DEMO;
  1315.  
  1316. The statement F, G    : FLOAT;{;4}m creates two variables of type FLOAT.  The next
  1317. statement names a constant.  Writing FACTOR{;4}m is then equivalent to writing 1000{;4}m.
  1318. Unlike variables, constants must{;4}m be initialized.
  1319.  
  1320. The first two executable statements are simple assignment statements.  The
  1321. symbol :={;4}m is read "becomes."  In the third executable statement, the compiler
  1322. will reject the expression F + L{;4}m because Ada doesn't let us accidentally mix a
  1323. FLOAT with an INTEGER.
  1324. 1HPlease type a space to go on, or B to go back.                      3070 193B191$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$      procedure DECLARATIONS_DEMO is
  1325.          I, J, K : INTEGER;
  1326.          L, M    : INTEGER := 30;
  1327.          F, G    : FLOAT;
  1328.          FACTOR  : constant := 1000;
  1329.       begin
  1330.          J := L + 10;          -- Simple assignment statements.
  1331.          F := 0.0;
  1332.          G := F + L;           -- ILLEGAL.  Can't accidentally mix types.
  1333.          G := F + FLOAT(L);    -- Legal.  Can deliberately convert types.
  1334.          K := INTEGER(F) + L;  -- Legal.
  1335.          FACTOR := 100;        -- ILLEGAL.  Constants can't change.{;4}m
  1336.       end DECLARATIONS_DEMO;
  1337.  
  1338. However, Ada lets us deliberately{;4}m mix types.  The statement G := F + FLOAT(L);{;4}m
  1339. is legal because it converts L from INTEGER to FLOAT, adds it to F which is of
  1340. type FLOAT, and stores the result in G, also of type FLOAT.  Likewise, the next
  1341. statement is legal because it converts F to INTEGER, adds the integer L, and
  1342. stores the result in the integer K.  But note that when a FLOAT is converted to
  1343. INTEGER, it's rounded, not truncated.  (Later we'll present two functions that
  1344. truncate integers.)  The last executable statement is illegal because a
  1345. constant can't appear on the left side of an assignment statement.
  1346. 1HPlease type a space to go on, or B to go back.      193311942195B192$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q        with TEXT_IO; use TEXT_IO;
  1347.         procedure TRY_ME is
  1348.            package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  1349.            N : INTEGER := 1;
  1350.         begin
  1351.            PUT(N);
  1352.            NEW_LINE;
  1353.            N := 2;
  1354.         end TRY_ME;{;4}m
  1355.  
  1356. What number will be displayed the second{;4}m time procedure TRY_ME is called?
  1357.  
  1358.                         1.  The program will display 1.
  1359.  
  1360.                         2.  The program will display 2.
  1361. 1HPlease press 1 or 2, or B to go back.                                           1859 196B193Q193$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        with TEXT_IO; use TEXT_IO;
  1362.         procedure TRY_ME is
  1363.            package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  1364.            N : INTEGER := 1;
  1365.         begin
  1366.            PUT(N);
  1367.            NEW_LINE;
  1368.            N := 2;
  1369.         end TRY_ME;{;4}m
  1370.  
  1371. You're right!{;4}m  N is brought into existence and initialized to 1 each time the
  1372. procedure is called, so 1 will be displayed.
  1373. 1HPlease type a space to go on, or B or Q to go back to the question.                 2034 196B193Q193$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        with TEXT_IO; use TEXT_IO;
  1374.         procedure TRY_ME is
  1375.            package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  1376.            N : INTEGER := 1;
  1377.         begin
  1378.            PUT(N);
  1379.            NEW_LINE;
  1380.            N := 2;
  1381.         end TRY_ME;
  1382.  
  1383. No, N is declared locally within TRY_ME.  So N is brought into existence and
  1384. initialized to 1 each{;4}m time the procedure is called, and the procedure will
  1385. display 1 each time.  Also remember that N goes out of existence when TRY_ME
  1386. returns.
  1387. 1HPlease type a space to go on, or B or Q to go back to the question.                                          2849 197B193$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                               ENUMERATION TYPES
  1388.  
  1389. In Ada we can declare enumeration types{;4}m, where we enumerate every possible
  1390. value for a type.  For example, if we declare
  1391.  
  1392.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1393.    RC : RAINBOW_COLOR;{;4}m
  1394.  
  1395. then RC can have any of 7 values.  In the executable region we might write
  1396. RC := RED;{;4}m and we could also test: if RC = RED then{;4}m ... end if;{;4}m.  The
  1397. enumerated values, enclosed in parentheses, must follow the rules for Ada
  1398. identifiers, or they can be single characters{;4}m enclosed in '{;4}m marks (called "tic"
  1399. marks), thus:
  1400.  
  1401.                   type EVEN_DIGIT is ('0', '2', '4', '6', '8');{;4}m
  1402.  
  1403. It's illegal to write type PROCESSOR is (8086, Z80, 1750A);{;4}m because two of the
  1404. values aren't legal Ada identifiers.  However, it's OK to mix characters and
  1405. identifiers in the same declaration, thus:
  1406.  
  1407.                      type MIXED is (BIG, SMALL, 'X', '9');{;4}m
  1408. 1HPlease type a space to go on, or B to go back.                           2811 198B196$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1409.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  1410.    RC : RAINBOW_COLOR;
  1411.    TC : TRAFFIC_LIGHT_COLOR;{;4}m
  1412.  
  1413. With the above declarations, RC could have any of 7 values, and TC could have
  1414. any of 3 values.  The compiler will have no trouble compiling
  1415.  
  1416.                                    RC := RED;
  1417.                                    TC := RED;{;4}m
  1418.  
  1419. because it knows that in RC := RED;{;4}m RED must be the RAINBOW_COLOR if it's
  1420. stored into RC, and in TC := RED;{;4}m RED must be the TRAFFIC_LIGHT_COLOR if it's
  1421. stored into TC.  The compiler knows that the types across :={;4}m must always match.
  1422. Naturally, it's illegal to write RC := 2;{;4}m because of the mixed types.
  1423.  
  1424. Also, if we have a procedure DISPLAY that takes one argument of type
  1425. RAINBOW_COLOR, the compiler could handle DISPLAY(RED);{;4}m because it knows that
  1426. RED must be the RAINBOW_COLOR to fit the procedure.
  1427. 1HPlease type a space to go on, or B to go back.                                                                 3628 199B197$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1428.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);{;4}m
  1429.  
  1430. However, if we had a procedure DISPLAY that takes one RAINBOW_COLOR and another
  1431. procedure DISPLAY that takes one TRAFFIC_LIGHT_COLOR, then the statement
  1432. DISPLAY(RED);{;4}m would be ambiguous; the compiler couldn't possibly know which
  1433. DISPLAY to call.  In that case, we could specify the type by writing
  1434. RAINBOW_COLOR'(RED){;4}m.  This is called qualifying{;4}m the name RED; note the '{;4}m with
  1435. the parentheses.  The call would be DISPLAY(RAINBOW_COLOR'(RED));{;4}m.  The
  1436. statements DISPLAY(VIOLET);{;4}m and DISPLAY(AMBER);{;4}m aren't ambiguous; the compiler
  1437. will figure out which DISPLAY to call in these cases.
  1438.  
  1439. Declaring an enumeration type not only defines equality for objects of that
  1440. type, but also an order for the values.  Thus we can check for <, >, <=, etc.
  1441. For example, if we declare A, B: RAINBOW_COLOR;{;4}m and later write, in the
  1442. executable region, A := YELLOW;{;4}m and B := BLUE;{;4}m then the test if A < B then{;4}m ...
  1443. will turn out to be TRUE.  YELLOW{;4}m is considered less than BLUE{;4}m.
  1444.  
  1445. Input and output of enumeration types can be done by instantiating the generic
  1446. package TEXT_IO.ENUMERATION_IO.  For example:
  1447. with TEXT_IO; use TEXT_IO;{;4}m ...
  1448. package MY_RAINBOW_IO is new ENUMERATION_IO(RAINBOW_COLOR); use MY_RAINBOW_IO;{;4}m
  1449. 1HPlease type a space to go on, or B to go back.                                                3073 200B198$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Here are two enumeration types built into the Ada language:
  1450.  
  1451.       type BOOLEAN is (FALSE, TRUE);
  1452.  
  1453.       type CHARACTER is ({;4}m [nul],{;4}m [soh],{;4}m [stx],{;4}m ... , ' ', '!', '"',{;4}m ... ,
  1454.                           '0', '1', '2',{;4}m ... , 'A', 'B', 'C',{;4}m ... ,
  1455.                           'a', 'b', 'c',{;4}m ... ,{;4}m [del] );{;4}m
  1456.  
  1457. Since the above two declarations are built into the Ada language, they
  1458. shouldn't be repeated in your programs.  Note that type BOOLEAN is just an
  1459. enumeration type.  The relational operators ( ={;4}m, >{;4}m, <={;4}m, etc. ) all return
  1460. results of type BOOLEAN.
  1461.  
  1462. The definition of type CHARACTER can't be completely written out, because there
  1463. are 33 unprintable ASCII characters.  However, the enumeration type CHARACTER
  1464. contains all 128 values, in ASCII character order.  On this screen, we've
  1465. denoted the unprintable characters with names in brackets, and we've also used
  1466. "..." for brevity.  Note that even if Ada is run on an EBCDIC machine, it's
  1467. guaranteed that type CHARACTER contains the 128 ASCII characters in ASCII
  1468. character order.
  1469. 1HPlease type a space to go on, or B to go back.   16734201120222033204B199$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q              1.  type COUNT is ("1", "2", "3", "AB", "CD", "EF");
  1470.  
  1471.               2.  type COUNT is ('1', '2', '3', 'AB', 'CD', 'EF');
  1472.  
  1473.               3.  type COUNT is (1, 2, 3, AB, CD, EF);
  1474.  
  1475.               4.  type COUNT is ('1', '2', '3', AB, CD, EF);
  1476.  
  1477.  
  1478. Which one{;4}m of the above type declarations is legal?
  1479. 1HPlease press 1, 2, 3, or 4, or B to go back.   2147 205B200Q200$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.  type COUNT is ("1", "2", "3", "AB", "CD", "EF");
  1480.  
  1481.               2.  type COUNT is ('1', '2', '3', 'AB', 'CD', 'EF');
  1482.  
  1483.               3.  type COUNT is (1, 2, 3, AB, CD, EF);
  1484.  
  1485.               4.  type COUNT is ('1', '2', '3', AB, CD, EF);{;4}m
  1486.  
  1487.  
  1488. You're right!{;4}m  Enumeration types can contain single characters between '{;4}m marks,
  1489. and Ada identifiers.  Number 1 is illegal because it contains STRINGs, number 2
  1490. because '{;4}m marks may enclose only single characters, and number 3 because an Ada
  1491. identifier can't begin with a digit.
  1492. 1HPlease type a space to go on, or B or Q to go back to the question.                             1854 205B200Q200$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.  type COUNT is ("1", "2", "3", "AB", "CD", "EF");
  1493.  
  1494.               2.  type COUNT is ('1', '2', '3', 'AB', 'CD', 'EF');
  1495.  
  1496.               3.  type COUNT is (1, 2, 3, AB, CD, EF);
  1497.  
  1498.               4.  type COUNT is ('1', '2', '3', AB, CD, EF);
  1499.  
  1500.  
  1501. No, number 1 is illegal because an enumeration type can't contain STRINGs, only
  1502. single characters between '{;4}m marks, and Ada identifiers.
  1503. 1HPlease type a space to go on, or B or Q to go back to the question.                      1935 205B200Q200$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.  type COUNT is ("1", "2", "3", "AB", "CD", "EF");
  1504.  
  1505.               2.  type COUNT is ('1', '2', '3', 'AB', 'CD', 'EF');
  1506.  
  1507.               3.  type COUNT is (1, 2, 3, AB, CD, EF);
  1508.  
  1509.               4.  type COUNT is ('1', '2', '3', AB, CD, EF);
  1510.  
  1511.  
  1512. No, number 2 is illegal because only single characters may appear between '{;4}m
  1513. marks.  Enumeration types contain single characters between '{;4}m marks, and Ada
  1514. identifiers.
  1515. 1HPlease type a space to go on, or B or Q to go back to the question.                                         1922 205B200Q200$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.  type COUNT is ("1", "2", "3", "AB", "CD", "EF");
  1516.  
  1517.               2.  type COUNT is ('1', '2', '3', 'AB', 'CD', 'EF');
  1518.  
  1519.               3.  type COUNT is (1, 2, 3, AB, CD, EF);
  1520.  
  1521.               4.  type COUNT is ('1', '2', '3', AB, CD, EF);
  1522.  
  1523.  
  1524. No, number 3 is illegal because an Ada identifier can't begin with a digit.
  1525. Enumeration types can contain only single characters between '{;4}m marks, and Ada
  1526. identifiers.
  1527. 1HPlease type a space to go on, or B or Q to go back to the question.                                                      2969 206B200$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    SUBTYPES
  1528.  
  1529. A subtype does not{;4}m define a new type, but it imposes a range constraint on
  1530. objects of that subtype.  For example,
  1531.  
  1532. subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  1533. D : DAY_SUBTYPE; -- D can have only INTEGER values from 1 to 31.{;4}m
  1534.  
  1535. type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1536. subtype BRIGHT_COLOR is RAINBOW_COLOR range ORANGE .. GREEN;
  1537. B : BRIGHT_COLOR; -- B can have only RAINBOW_COLOR values from ORANGE to GREEN.{;4}m
  1538.  
  1539. subtype PROBABILITY is FLOAT range 0.0 .. 1.0;
  1540. P : PROBABILITY; -- P can have only FLOAT values from 0.0 to 1.0.{;4}m
  1541.  
  1542. Every time the program stores a value into D, B, or P, a check is made to see
  1543. if the value is in range.  If it isn't, the message CONSTRAINT_ERROR is
  1544. printed.  Constraint Errors are usually detected at run time.
  1545.  
  1546. Since subtypes don't define new types, the type{;4}m of D is INTEGER, the type of B
  1547. is RAINBOW_COLOR, and that of P is FLOAT.  Thus, if we write I : INTEGER;{;4}m we
  1548. can write D := D + I;{;4}m etc., because D and I have the same type.
  1549. 1HPlease type a space to go on, or B to go back.       2350 207B205$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$We don't have to give the name of the subtype explicitly.  If we declare
  1550.  
  1551.                            D : INTEGER range 1 .. 31;{;4}m
  1552.  
  1553. the compiler creates its own name for the subtype internally; we never see it.
  1554. This is called an anonymous{;4}m subtype.  The name the compiler creates will be one
  1555. that we can't accidentally create ourselves.  Perhaps it will contain a control
  1556. character or punctuation mark that Ada doesn't allow us to put into an
  1557. identifier.  The above declaration is equivalent to
  1558.  
  1559.                  subtype{;4}m (something) is INTEGER range 1 .. 31;
  1560.                  D :{;4}m (something);{;4}m
  1561.  
  1562. where (something) represents the anonymous subtype that we can't see or write.
  1563. 1HPlease type a space to go on, or B to go back.                          3423 208B206$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                               SIMPLE ATTRIBUTES
  1564.  
  1565. An attribute{;4}m consists of apostrophe (called a "tic" mark for short), and the
  1566. name of the attribute.  Attributes often follow type names.  They're something
  1567. like functions, except that they usually involve a type.  For example:
  1568.  
  1569.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1570.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  1571.    RAINBOW_COLOR'SUCC(GREEN){;4}m       is BLUE{;4}m
  1572.    TRAFFIC_LIGHT_COLOR'PRED(GREEN){;4}m is AMBER{;4}m
  1573.  
  1574. The attributes SUCC{;4}m and PRED{;4}m stand for successor and predecessor, respectively.
  1575. In RAINBOW_COLORs, the successor of GREEN{;4}m is BLUE{;4}m, and in TRAFFIC_LIGHT_COLORs,
  1576. the predecessor of GREEN{;4}m is AMBER{;4}m.  Thus we could write R : RAINBOW_COLOR;{;4}m and
  1577. then R := RAINBOW_COLOR'SUCC(GREEN);{;4}m.  You'll get a CONSTRAINT_ERROR if you
  1578. try to take the successor of the last item or the predecessor of the first; for
  1579. example, taking RAINBOW_COLOR'PRED(RED) will cause an error.
  1580.  
  1581. SUCC and PRED work with any discrete type{;4}m.  That means any integer type or
  1582. enumeration type.  These two attributes aren't particularly useful with integer
  1583. types, because we can simply add or subtract 1 instead.  So they're usually
  1584. used with enumeration types.
  1585. 1HPlease type a space to go on, or B to go back.                                                     3644 209B207$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1586.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  1587.  
  1588. The attribute POS{;4}m converts from a discrete type to an integer, and VAL{;4}m converts
  1589. from an integer to a discrete type.  Again, the type is usually an enumeration
  1590. type, because there's little point converting from integer to integer.
  1591.  
  1592. For example, RAINBOW_COLOR'POS(ORANGE){;4}m is 1{;4}m.  (The positions are numbered from
  1593. zero.)  RAINBOW_COLOR'POS(RED){;4}m is 0{;4}m and RAINBOW_COLOR'POS(VIOLET){;4}m is 6{;4}m.
  1594. TRAFFIC_LIGHT_COLOR'POS(GREEN){;4}m is 2{;4}m, but RAINBOW_COLOR'POS(GREEN){;4}m is 3{;4}m.
  1595. CHARACTER'POS('A'){;4}m is 65{;4}m, because the ASCII value of 'A' is 65, and the type
  1596. CHARACTER contains all 128 characters in ASCII order.  CHARACTER'POS('0'){;4}m is
  1597. 48{;4}m, because the ASCII value of the character '0' is 48.
  1598.  
  1599. VAL{;4}m converts the other way, so RAINBOW_COLOR'VAL(0){;4}m is RED{;4}m, and
  1600. RAINBOW_COLOR'VAL(6){;4}m is VIOLET{;4}m.  Taking the RAINBOW_COLOR'VAL of an argument
  1601. outside the range 0 .. 6 will raise a CONSTRAINT_ERROR.  CHARACTER'VAL(65){;4}m is
  1602. 'A'{;4}m, and CHARACTER'VAL(7){;4}m is the "bell" character (control-G).  Since BOOLEAN
  1603. is an enumeration type, BOOLEAN'VAL(0){;4}m is FALSE{;4}m and BOOLEAN'VAL(1){;4}m is TRUE{;4}m.
  1604. 1HPlease type a space to go on, or B to go back.                                155412102211B208$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q     type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  1605.  
  1606.                           What is MONTH_TYPE'POS(FEB)?
  1607.  
  1608.  
  1609.                           1.  MONTH_TYPE'POS(FEB) is 1.
  1610.  
  1611.                           2.  MONTH_TYPE'POS(FEB) is 2.
  1612. 1HPlease press 1 or 2, or B to go back.                      1532 212B209Q209$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  1613.  
  1614. You're right!{;4}m  The positions are numbered from zero, so FEB is in position 1,
  1615. and MONTH_TYPE'POS(FEB) is 1.
  1616. 1HPlease type a space to go on, or B or Q to go back to the question.                                            1471 212B209Q209$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  1617.  
  1618. No, the positions are numbered from zero, so FEB is in position 1, and
  1619. MONTH_TYPE'POS(FEB) is 1.
  1620. 1HPlease type a space to go on, or B or Q to go back to the question.     3235 213B209$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$While POS{;4}m and VAL{;4}m convert to and from integers, the attributes IMAGE{;4}m and VALUE{;4}m
  1621. convert to and from STRINGs.  They work with any discrete types, and are useful
  1622. with integer types as well as enumeration types.  For example,
  1623.  
  1624.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1625.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  1626.  
  1627.    RAINBOW_COLOR'VALUE("RED"){;4}m       is RED{;4}m
  1628.    RAINBOW_COLOR'VALUE("yellow"){;4}m    is YELLOW{;4}m
  1629.    TRAFFIC_LIGHT_COLOR'IMAGE(AMBER){;4}m is "AMBER"{;4}m
  1630.  
  1631.    INTEGER'VALUE("123"){;4}m is  123{;4}m
  1632.    INTEGER'IMAGE(123){;4}m   is " 123"{;4}m
  1633.    INTEGER'IMAGE(-123){;4}m  is "-123"{;4}m
  1634.  
  1635. Note that if I is an INTEGER, we can write PUT(INTEGER'IMAGE(I));{;4}m without
  1636. having to instantiate INTEGER_IO.  However, this won't work for type FLOAT,
  1637. only for discrete types.  VALUE{;4}m will raise a CONSTRAINT_ERROR if the STRING
  1638. can't be converted to the discrete type.  For example, taking
  1639. RAINBOW_COLOR'VALUE("CHARTREUSE"){;4}m or INTEGER'VALUE("12X3"){;4}m will normally print
  1640. CONSTRAINT_ERROR on the terminal and stop the program.
  1641. 1HPlease type a space to go on, or B to go back.                                         3256 214B212$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$For any discrete type, the attributes FIRST{;4}m and LAST{;4}m are also available.
  1642.  
  1643.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1644.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  1645.    RAINBOW_COLOR'FIRST{;4}m      is RED{;4}m
  1646.    TRAFFIC_LIGHT_COLOR'LAST{;4}m is GREEN{;4}m
  1647.  
  1648. A program can use these attributes with INTEGER to determine the size of
  1649. integers on the host computer.  For example, if your PC Ada has 16-bit 2's
  1650. complement integers, while a mainframe Ada uses 32-bit 2's complement, then
  1651.  
  1652.     INTEGER'FIRST{;4}m is -32_768{;4}m on your PC and -2_147_483_648{;4}m on the mainframe.
  1653.     INTEGER'LAST{;4}m  is  32_767{;4}m on your PC and  2_147_483_647{;4}m on the mainframe.
  1654.  
  1655. Most attributes can also be used with subtypes:
  1656.                  subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  1657.                  DAY_SUBTYPE'FIRST{;4}m is 1{;4}m
  1658.                  DAY_SUBTYPE'LAST{;4}m  is 31{;4}m
  1659.  
  1660. There are two subtype definitions involving LAST{;4}m built into the Ada language:
  1661.               subtype POSITIVE is INTEGER range 1 .. INTEGER'LAST;
  1662.               subtype NATURAL  is INTEGER range 0 .. INTEGER'LAST;{;4}m
  1663. 1HPlease type a space to go on, or B to go back.                    3123 215B213$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$More attributes are discussed in the Advanced Topics section.  In summary,
  1664. discrete type{;4}m means any integer or enumeration type.  (The only integer type
  1665. we've learned about so far is the standard INTEGER.)
  1666.  
  1667.        POS{;4}m converts from a discrete type to an integer.
  1668.        VAL{;4}m converts from an integer to a discrete type.
  1669.        IMAGE{;4}m converts from a discrete type to STRING.
  1670.        VALUE{;4}m converts from STRING to a discrete type.
  1671.        FIRST{;4}m and LAST{;4}m take no argument and give a discrete type.
  1672.        SUCC{;4}m and PRED{;4}m take a discrete type and give the same discrete type.
  1673.  
  1674.  
  1675.        Also remember that a type name followed by '{;4}m denotes an attribute{;4}m:
  1676.                          PUT(CHARACTER'{;4}mVAL(7)); -- beep
  1677.  
  1678.                 A type name followed by ( ){;4}m denotes conversion{;4}m:
  1679.                                G := F + FLOAT({;4}mI){;4}m;
  1680.  
  1681.             And a type name followed by '( ){;4}m denotes qualification{;4}m:
  1682.                           DISPLAY(RAINBOW_COLOR'({;4}mRED){;4}m);
  1683. 1HPlease type a space to go on, or B to go back.                                                     185682161217221832174219522062207221B214$$$$$$$$$$$$$$$$$$$$$$$Q          1.  RAINBOW_COLOR'FIRST             5.  RAINBOW_COLOR'PRED
  1684.  
  1685.           2.  RAINBOW_COLOR'IMAGE             6.  RAINBOW_COLOR'SUCC
  1686.  
  1687.           3.  RAINBOW_COLOR'LAST              7.  RAINBOW_COLOR'VAL
  1688.  
  1689.           4.  RAINBOW_COLOR'POS               8.  RAINBOW_COLOR'VALUE
  1690.  
  1691.  
  1692. Which one of the above attributes would you use to convert from the STRING
  1693. "Blue"{;4}m to the RAINBOW_COLOR BLUE{;4}m?
  1694. 1HPlease press 1, 2, 3, 4, 5, 6, 7, or 8, or B to go back.                    1525 222B215Q215$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$You're right!{;4}m  The attribute VALUE{;4}m converts from STRING to a discrete type.
  1695.  
  1696.                       RAINBOW_COLOR'VALUE("Blue"){;4}m is BLUE{;4}m.
  1697. 1HPlease type a space to go on, or B or Q to go back to the question.                                                   1655 222B215Q215$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, FIRST{;4}m and LAST{;4}m take no argument and return a discrete type:
  1698.  
  1699.           RAINBOW_COLOR'FIRST{;4}m is RED{;4}m and RAINBOW_COLOR'LAST{;4}m is VIOLET{;4}m.
  1700.  
  1701. You want to convert from a STRING argument to a discrete type.
  1702. 1HPlease type a space to go on, or B or Q to go back to the question.                     1541 222B215Q215$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, IMAGE{;4}m converts from a discrete type to STRING:
  1703.  
  1704.                       RAINBOW_COLOR'IMAGE(BLUE){;4}m is "BLUE"{;4}m.
  1705.  
  1706. You want to convert from STRING to a discrete type.
  1707. 1HPlease type a space to go on, or B or Q to go back to the question.                                   1539 222B215Q215$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, POS{;4}m converts from a discrete type to an integer:
  1708.  
  1709.                          RAINBOW_COLOR'POS(BLUE){;4}m is 4{;4}m.
  1710.  
  1711. You want to convert from STRING to a discrete type.
  1712. 1HPlease type a space to go on, or B or Q to go back to the question.                                     1670 222B215Q215$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, PRED{;4}m and SUCC{;4}m take a discrete type argument and return the same discrete
  1713. type.
  1714.  
  1715.    RAINBOW_COLOR'PRED(BLUE){;4}m is GREEN{;4}m and RAINBOW_COLOR'SUCC(BLUE){;4}m is INDIGO{;4}m.
  1716.  
  1717. You want to convert from STRING to a discrete type.
  1718. 1HPlease type a space to go on, or B or Q to go back to the question.      1539 222B215Q215$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, VAL{;4}m converts from an integer to a discrete type.
  1719.  
  1720.                          RAINBOW_COLOR'VAL(4){;4}m is BLUE{;4}m.
  1721.  
  1722. You want to convert from STRING to a discrete type.
  1723. 1HPlease type a space to go on, or B or Q to go back to the question.                                     2150 223B215$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  1724.  
  1725.    Introduction                             Records, Arrays, and Assignment 3
  1726.  
  1727.    The Format of an Ada Program             Recursion and Assignment 4
  1728.  
  1729.    Generic Instantiation and                Subprograms and Packages
  1730.       Assignment 1
  1731.                                             Additional Types, Exceptions,
  1732.    Simple Declarations and Simple              TEXT_IO, and Assignment 5
  1733.       Attributes
  1734.                                             Generics, Tasking, and Assignment 6
  1735. >  OPERATORS, CONTROL CONSTRUCTS, AND{;4}m
  1736.       ASSIGNMENT 2{;4}m                          Advanced Topics
  1737. 1HPlease type a space to go on, or B to go back.                          3520 224B222$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                   OPERATORS
  1738.  
  1739. The four basic arithmetic operators, +{;4}m, -{;4}m, *{;4}m, and /{;4}m, can be used with any
  1740. integer or floating point type.  (We'll learn about fixed point types in the
  1741. Advanced Topics section.)  The exponentiation operator, **{;4}m, takes a base of
  1742. type INTEGER or FLOAT, and an exponent of type INTEGER.  It returns the same
  1743. type as the base.  Note that FLOAT ** FLOAT doesn't come with Ada.  Of course,
  1744. a vendor may supply a math package with his Ada compiler to increase its sales
  1745. appeal.  If the math package includes a function "**" to raise a FLOAT base to
  1746. a FLOAT exponent, then our programs can with{;4}m and use{;4}m the package and then use
  1747. **{;4}m between two FLOATs.  (Similarly, EXP, LOG, and the trig functions don't
  1748. come with Ada, but the vendor may supply them in a math package.)
  1749.  
  1750. The six relational operators{;4}m are:
  1751.  
  1752. <{;4}m  less than                  >{;4}m  greater than                  ={;4}m  equal to
  1753.  
  1754. <={;4}m less than or equal to      >={;4}m greater than or equal to      /={;4}m not equal to
  1755.  
  1756. Five of these are the same as in Basic and Pascal, but the Ada symbol for "not
  1757. equal to" is /={;4}m, because <>{;4}m means box{;4}m.  The relational operators compare two
  1758. objects of the same type, and return a result of type BOOLEAN.
  1759. 1HPlease type a space to go on, or B to go back.                                                        3757 225B223$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$All of the above operators are used between{;4}m two objects (e.g., B := A + B;{;4}m).
  1760. Of course, +{;4}m and -{;4}m may also be unary{;4}m operators (B := +A;  A := -A;{;4}m).
  1761.  
  1762. The operators and{;4}m, or{;4}m, and xor{;4}m are used between two BOOLEAN objects, and not{;4}m is
  1763. a unary BOOLEAN operator.  Naturally, xor{;4}m is the exclusive or:  A xor B{;4}m is TRUE
  1764. if either A or B is TRUE, but not if both are TRUE.
  1765.  
  1766. The numeric operator abs{;4}m takes the absolute value of an INTEGER or FLOAT.
  1767. Since abs{;4}m is a unary operator like -{;4}m, we can write B := abs A;{;4}m.  We may, but
  1768. don't have to, write B := abs(A);{;4}m.
  1769.  
  1770. When used between two integers, /{;4}m gives only the integer part of the quotient.
  1771. Thus 9/4{;4}m is 2.  The operators mod{;4}m (modulo) and rem{;4}m (remainder) are very similar
  1772. to each other, and are used between two integers to give only the remainder in
  1773. division.  For example, 9 mod 4{;4}m is 1.  For positive arguments, mod{;4}m and rem{;4}m are
  1774. the same.  But with negative arguments, mod{;4}m gives the sign of the denominator
  1775. while rem{;4}m gives the sign of the numerator.  Many programmers simply ignore rem{;4}m
  1776. and use mod{;4}m exclusively.
  1777.  
  1778. The operator &{;4}m concatenates arrays, so we'll discuss it later.  We'll learn
  1779. that a STRING is one type of array (an array of CHARACTERs), so &{;4}m can
  1780. concatenate STRINGs.
  1781. 1HPlease type a space to go on, or B to go back.                   2417 226B224$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                  RANGE TESTS
  1782.  
  1783. The reserved word in{;4}m tests if something is inside a range, and returns a
  1784. BOOLEAN result.  For example, if LOWER, UPPER, and X are declared as FLOATs, we
  1785. need not write
  1786.  
  1787.                      if X >= LOWER and X <= UPPER then{;4}m ...
  1788.  
  1789. This can be expressed more clearly as
  1790.  
  1791.                         if X in LOWER .. UPPER then{;4}m ...
  1792.  
  1793. We can also write not in{;4}m.  Thus X not in LOWER .. UPPER{;4}m is a clear way of
  1794. expressing X < LOWER or X > UPPER{;4}m.
  1795.  
  1796. A subtype may be substituted for the range to the right of in{;4}m.  If DAY_SUBTYPE
  1797. is defined as a subtype of INTEGER, and D is an INTEGER, then we can write
  1798. D in DAY_SUBTYPE{;4}m.
  1799. 1HPlease type a space to go on, or B to go back.                                                           1742122722283229B225$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QIf we have the following declarations:
  1800.  
  1801.                              B       : BOOLEAN;
  1802.                              A, X, Y : CHARACTER;
  1803.  
  1804. then which one{;4}m of the following is illegal{;4}m?
  1805.  
  1806.                        1.    B := X <> Y;
  1807.  
  1808.                        2.    B := A in X .. Y;
  1809.  
  1810.                        3.    B := A = X and X = Y;
  1811. 1HPlease press 1, 2, or 3, or B to go back.                                  1774 230B226Q226$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                             B       : BOOLEAN;
  1812.                              A, X, Y : CHARACTER;
  1813.  
  1814.  
  1815.                        1.    B := X <> Y;{;4}m
  1816.  
  1817.                        2.    B := A in X .. Y;
  1818.  
  1819.                        3.    B := A = X and X = Y;
  1820.  
  1821.  
  1822. You're right!{;4}m  Number 1 is illegal because <>{;4}m should be /={;4}m.
  1823. 1HPlease type a space to go on, or B or Q to go back to the question.  1852 230B226Q226$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                             B       : BOOLEAN;
  1824.                              A, X, Y : CHARACTER;
  1825.  
  1826.  
  1827.                        1.    B := X <> Y;
  1828.  
  1829.                        2.    B := A in X .. Y;
  1830.  
  1831.                        3.    B := A = X and X = Y;
  1832.  
  1833.  
  1834. No, number 2 is legal.  The reserved word in{;4}m tests to see if A is within the
  1835. range X to Y.  It returns a BOOLEAN result, which is stored in B.
  1836. 1HPlease type a space to go on, or B or Q to go back to the question.                        2151 230B226Q226$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                             B       : BOOLEAN;
  1837.                              A, X, Y : FLOAT;
  1838.  
  1839.  
  1840.                        1.    B := X <> Y;
  1841.  
  1842.                        2.    B := A in X .. Y;
  1843.  
  1844.                        3.    B := A = X and X = Y;
  1845.  
  1846.  
  1847. No, number 3 is legal.  Parentheses aren't necessary here, but it's the same as
  1848. if we had written
  1849.  
  1850.                            B := (A = X) and (X = Y);
  1851.  
  1852. In two places ={;4}m returns a BOOLEAN result.  Then and{;4}m takes the two BOOLEAN
  1853. results and also returns a result of type BOOLEAN.  That final result is then
  1854. stored in B.
  1855. 1HPlease type a space to go on, or B or Q to go back to the question.                         2772 231B226$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                            THE SHORT CIRCUIT FORMS
  1856.  
  1857. Suppose that N{;4}m (for numerator) and D{;4}m (for denominator) are FLOATs, and we want
  1858. to execute a block of code if the quotient is 10.0 or greater.  We could write
  1859.  
  1860.                            if N/D >= 10.0 then{;4}m
  1861.                               -----;
  1862.                               -----;  (block of code)
  1863.                               -----;
  1864.                            end if;{;4}m
  1865.  
  1866. However, we realize that if D{;4}m is 0.0, the program will raise a NUMERIC_ERROR or
  1867. CONSTRAINT_ERROR trying to compute N/D{;4}m.  If the denominator is zero, we
  1868. consider the quotient to be very large, so we want to execute the block of code
  1869. when D is zero.  Our second attempt might be
  1870.  
  1871.                          if D = 0.0 or N/D >= 10.0{;4}m then
  1872.                             -----;
  1873.                             -----;  (block of code)
  1874.                             -----;
  1875.                          end if;
  1876. 1HPlease type a space to go on, or B to go back.    2965 232B230$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                         if D = 0.0 or N/D >= 10.0{;4}m then
  1877.                             -----;
  1878.                             -----;  (block of code)
  1879.                             -----;
  1880.                          end if;
  1881.  
  1882. Here we hope{;4}m that N/D{;4}m won't be evaluated if D{;4}m is zero.  We figure that the
  1883. compiler should be smart enough to know that if the expression before or{;4}m is
  1884. TRUE, then the whole expression must be TRUE, so the expression to the right of
  1885. or{;4}m needn't be evaluated.  However, there's no guarantee that the compiler will
  1886. write code to skip the evaluation of the second expression when the first is
  1887. TRUE.  An optimizing compiler just might, for some unknown reason, even decide
  1888. that the expression on the right should be evaluated first.
  1889.  
  1890. However, Ada has a "short circuit" form called or else{;4}m, that looks like this:
  1891.  
  1892.                       if D = 0.0 or else{;4}m N/D >= 10.0 then
  1893.                          -----;
  1894.                          -----;  (block of code)
  1895.                          -----;
  1896.                       end if;
  1897. 1HPlease type a space to go on, or B to go back.           3372 233B231$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      if D = 0.0 or else{;4}m N/D >= 10.0 then
  1898.                          -----;
  1899.                          -----;  (block of code)
  1900.                          -----;
  1901.                       end if;
  1902.  
  1903. Ada guarantees that the expression to the left of or else{;4}m will be evaluated
  1904. first.  If this expression is TRUE, the entire expression must be TRUE, and
  1905. it's guaranteed that the second expression won't be evaluated.  If the first
  1906. expression is FALSE, then of course the second expression must be evaluated to
  1907. determine if the entire expression is TRUE.  Note that the code above will
  1908. never try to divide by zero.  If D{;4}m is zero, the expression on the left is TRUE.
  1909. The expression on the right won't be evaluated in that case.
  1910.  
  1911. There's another "short circuit" form called and then{;4}m.  If the expression to
  1912. the left of and then{;4}m is FALSE, the whole expression must be FALSE, and the
  1913. expression on the right won't be evaluated.  If the expression on the left is
  1914. TRUE, then the expression on the right must be evaluated to determine the value
  1915. of the entire expression.  Suppose this time that we want to execute a block of
  1916. code if N/D is less than{;4}m 10.0.  If the denominator is zero, we consider the
  1917. quotient to be very large, and we don't want to execute the block of code in
  1918. that case.  We can write the following:
  1919. 1HPlease type a space to go on, or B to go back.    2667 234B232$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      if D /= 0.0 and then{;4}m N/D < 10.0 then
  1920.                          -----;
  1921.                          -----;  (block of code)
  1922.                          -----;
  1923.                       end if;
  1924.  
  1925. Again this protects us from trying to divide by zero.  If D{;4}m is zero, the
  1926. expression on the left is FALSE.  The second expression won't be evaluated in
  1927. that case.
  1928.  
  1929. Don't use the short circuit forms where the standard and{;4}m and or{;4}m will do.  The
  1930. short circuit forms prevent certain compiler optimizations by requiring the
  1931. expression on the left to be evaluated first.
  1932.  
  1933. After we discuss arrays, we'll see how the short circuit forms can prevent us
  1934. from using out-of-range subscripts.  And when we learn about access types,
  1935. we'll see how the short circuit forms can keep us from dereferencing a null
  1936. pointer.  That means trying to access "the object pointed to" when there's no
  1937. such object.
  1938. 1HPlease type a space to go on, or B to go back.         194112352236B233$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QAssume that N{;4}m has been declared FLOAT{;4}m, and that our program with{;4}ms and use{;4}ms a
  1939. math package with a square root function called SQRT{;4}m.  Naturally, we don't want
  1940. to call SQRT{;4}m with a negative argument.  Which of the following would be more
  1941. appropriate?
  1942.  
  1943.  
  1944.            1.    if N >= 0.0 and then{;4}m SQRT(N) > 1.618 then ...
  1945.  
  1946.            2.    if N >= 0.0 or else{;4}m  SQRT(N) > 1.618 then ...
  1947. 1HPlease press 1 or 2, or B to go back.                                   1665 237B234Q234$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$           1.    if N >= 0.0 and then SQRT(N) > 1.618 then ...{;4}m
  1948.  
  1949.            2.    if N >= 0.0 or else  SQRT(N) > 1.618 then ...
  1950.  
  1951.  
  1952. You're right!{;4}m  We don't want the second expression to be evaluated if the first
  1953. expression is FALSE, so we use and then{;4}m.
  1954. 1HPlease type a space to go on, or B or Q to go back to the question.           2147 237B234Q234$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$           1.    if N >= 0.0 and then SQRT(N) > 1.618 then ...
  1955.  
  1956.            2.    if N >= 0.0 or else  SQRT(N) > 1.618 then ...
  1957.  
  1958.  
  1959. No, we don't want the second expression to be evaluated if the first expression
  1960. is FALSE.  The form or else{;4}m bypasses the evaluation of the second expression
  1961. when the first expression is TRUE.  Note that if A{;4}m is true, we know the value
  1962. of A or B{;4}m without evaluating B{;4}m.  Using or else{;4}m in place of or{;4}m guarantees that B{;4}m
  1963. won't be evaluated when A{;4}m is TRUE.
  1964. 1HPlease type a space to go on, or B or Q to go back to the question.                             2947 238B234$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                               CONTROL CONSTRUCTS
  1965.  
  1966. You're almost ready to write your own Ada program in an Outside Assignment, but
  1967. first we need to discuss the control constructs.
  1968.  
  1969. Ada encourages structured programming by providing control constructs such as
  1970.  
  1971.                          block if{;4}ms with elsif{;4}ms and else{;4}m
  1972.                          while{;4}m loops
  1973.                          for{;4}m loops
  1974.                          case{;4}m statements
  1975.  
  1976. Ada also provides a goto{;4}m statement, but it's seldom if ever needed.  That's
  1977. because the constructs above handle the flow of control more clearly, making
  1978. the program easier to read.  With the constructs above, we know how control
  1979. reaches each statement.  When goto{;4}ms are used, there can be many paths to a
  1980. statement, and we're not sure how control got there.
  1981.  
  1982. Let's look at the above control constructs, and the goto{;4}m statement, one at a
  1983. time.  Discussion of the declare{;4}m statement and Ada "blocks" is postponed until
  1984. we cover exception handlers.
  1985. 1HPlease type a space to go on, or B to go back.                             3419 239B237$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                 THE "IF" BLOCK
  1986.  
  1987.                           if{;4}m A >= B and C = A + D then{;4}m
  1988.                              -----;
  1989.                              -----;  (block of code)
  1990.                              -----;
  1991.                           end if;{;4}m
  1992.  
  1993. In Ada, every if{;4}m introduces a block of code that ends with end if;{;4}m.  There are
  1994. no exceptions; every if{;4}m always has an end if;{;4}m.  The condition is followed by
  1995. then{;4}m, and it can be any expression with a BOOLEAN result.  The above example
  1996. is valid if A, B, C, and D are suitably declared.  Note that each statement in
  1997. the block of code, including the last, has a semicolon.  Note also that end if;{;4}m
  1998. is two reserved words, so there must be at least one space between them.  All
  1999. Ada control constructs, including if{;4}m blocks, can be nested to any depth.
  2000.  
  2001. In Pascal, if{;4}m is designed to execute only one statement conditionally.  If
  2002. there's a whole block of statements to be executed conditionally, it has to be
  2003. enclosed with "begin ... end" so it will be considered as one statement.  In
  2004. Ada, however, if{;4}m always starts a block of code, so "begin ... end" isn't
  2005. necessary.  The end of the block is always marked by end if;{;4}m even if there's
  2006. just one statement in the block.
  2007. 1HPlease type a space to go on, or B to go back.                                                         3265 240B238$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          if A >= B and C = A + D then
  2008.                              -----;
  2009.                              -----;
  2010.                              -----;
  2011.                           elsif G = H + P then
  2012.                              -----;
  2013.                           elsif Q > R or S <= T then
  2014.                              -----;
  2015.                              -----;
  2016.                           else
  2017.                              -----;
  2018.                           end if;{;4}m
  2019.  
  2020. The reserved words elsif{;4}m and else{;4}m are also available; note the unusual spelling
  2021. of elsif{;4}m.  In the above example, only one of the four blocks of code will be
  2022. executed.  If A >= B and C = A + D{;4}m is TRUE, the first block of code will be
  2023. executed and the remaining tests and blocks will be skipped.  Control will
  2024. continue after the end if;{;4}m.  If A >= B and C = A + D{;4}m is FALSE, then G = H + P{;4}m
  2025. will be tested.  If it's TRUE, the second block, and only that block, will be
  2026. executed; otherwise, Q > R or S <= T{;4}m will be tested.  If that's TRUE, the third
  2027. block will be executed; otherwise the else{;4}m block will be executed.  If all the
  2028. tests are FALSE and there's no else{;4}m block, then no blocks are executed.
  2029. 1HPlease type a space to go on, or B to go back.           3522 241B239$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$if A >= B and C = A + D then                      if A >= B and C = A + D then
  2030.    -----;                                            -----;
  2031.    -----;                                            -----;
  2032.    -----;                          THESE{;4}m             -----;
  2033. elsif G = H + P then          <=    TWO    =>{;4}m     else
  2034.    -----;                           ARE{;4}m              if G = H + P then
  2035. elsif Q > R or S <= T then      EQUIVALENT!{;4}m             -----;
  2036.    -----;                                            else
  2037.    -----;                                               if Q > R or S <= T then
  2038. else                                                       -----;
  2039.    -----;                                                  -----;
  2040. end if;                                                 else
  2041.                                                            -----;
  2042.                                                         end if;
  2043.                                                      end if;
  2044.                                                   end if;
  2045.  
  2046. As shown, elsif{;4}m is equivalent to else{;4}m plus if{;4}m ... end if;{;4}m.  Although the two
  2047. program segments above are equivalent, the one on the left is much clearer.
  2048. The example on the left doesn't require multiple end if;{;4}ms at the bottom, and
  2049. the indentation emphasizes that only one of the four blocks of code will be
  2050. executed.
  2051. 1HPlease type a space to go on, or B to go back.                                                      244222421243324442455246B240$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q                              D, N : INTEGER := 1;
  2052.                               ...
  2053.                               if D = 0 then
  2054.                                  ONE;
  2055.                               elsif N/D = 1 then
  2056.                                  TWO;
  2057.                               elsif D = 1 then
  2058.                                  THREE;
  2059.                               else
  2060.                                  FOUR;
  2061.                               end if;
  2062.  
  2063. In this segment of code, which procedure(s) will be called?
  2064.  
  2065.                   1.  Procedure ONE will be called.
  2066.                   2.  Procedure TWO will be called.
  2067.                   3.  Procedure THREE will be called.
  2068.                   4.  Procedure FOUR will be called.
  2069.                   5.  Procedures TWO and THREE will be called.
  2070. 1HPlease press 1, 2, 3, 4, or 5, or B to go back.                                  2332 247B241Q241$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              D, N : INTEGER := 1;
  2071.                               ...
  2072.                               if D = 0 then
  2073.                                  ONE;
  2074.                               elsif N/D = 1 then
  2075.                                  TWO;{;4}m
  2076.                               elsif D = 1 then
  2077.                                  THREE;
  2078.                               else
  2079.                                  FOUR;
  2080.                               end if;
  2081.  
  2082. You're right!{;4}m  The first test, D = 0, is FALSE, so the second test is made.
  2083. N/D = 1 is TRUE, so TWO is called.  Since only one block of code is executed in
  2084. an if{;4}m block, the remaining tests are not done.
  2085. 1HPlease type a space to go on, or B or Q to go back to the question.                                            2230 247B241Q241$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              D, N : INTEGER := 1;
  2086.                               ...
  2087.                               if D = 0 then
  2088.                                  ONE;
  2089.                               elsif N/D = 1 then
  2090.                                  TWO;
  2091.                               elsif D = 1 then
  2092.                                  THREE;
  2093.                               else
  2094.                                  FOUR;
  2095.                               end if;
  2096.  
  2097. No, both D and N are initialized to 1, so the first test, D = 0, is FALSE and
  2098. the second test is made.  The block that's executed is the first block
  2099. following a test that's TRUE.
  2100. 1HPlease type a space to go on, or B or Q to go back to the question.                                              2427 247B241Q241$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              D, N : INTEGER := 1;
  2101.                               ...
  2102.                               if D = 0 then
  2103.                                  ONE;
  2104.                               elsif N/D = 1 then
  2105.                                  TWO;
  2106.                               elsif D = 1 then
  2107.                                  THREE;
  2108.                               else
  2109.                                  FOUR;
  2110.                               end if;
  2111.  
  2112. No, both D and N are initialized to 1, so the second test, N/D = 1, is TRUE.
  2113. The block that's executed is the first{;4}m block following a test that's TRUE.
  2114. Once a block is executed, no further tests in that if{;4}m block are made.  Thus,
  2115. THREE isn't called even though D = 1 is TRUE.
  2116. 1HPlease type a space to go on, or B or Q to go back to the question.                                                 2314 247B241Q241$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              D, N : INTEGER := 1;
  2117.                               ...
  2118.                               if D = 0 then
  2119.                                  ONE;
  2120.                               elsif N/D = 1 then
  2121.                                  TWO;
  2122.                               elsif D = 1 then
  2123.                                  THREE;
  2124.                               else
  2125.                                  FOUR;
  2126.                               end if;
  2127.  
  2128. No, both D and N are initialized to 1, so the second test, N/D = 1, is TRUE.
  2129. The block that's executed is the first block following a test that's TRUE.  The
  2130. else{;4}m block is executed only if all the tests are FALSE.
  2131. 1HPlease type a space to go on, or B or Q to go back to the question.                                                              2266 247B241Q241$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              D, N : INTEGER := 1;
  2132.                               ...
  2133.                               if D = 0 then
  2134.                                  ONE;
  2135.                               elsif N/D = 1 then
  2136.                                  TWO;
  2137.                               elsif D = 1 then
  2138.                                  THREE;
  2139.                               else
  2140.                                  FOUR;
  2141.                               end if;
  2142.  
  2143. No, although N/D = 1 and D = 1 are both TRUE, only one{;4}m block of code in an if{;4}m
  2144. block is executed.  The block that's executed is the first{;4}m block following a
  2145. test that's TRUE.
  2146. 1HPlease type a space to go on, or B or Q to go back to the question.          2561 248B241$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                 "WHILE" LOOPS
  2147.  
  2148.                                while{;4}m I < 10 loop{;4}m
  2149.                                   -----;
  2150.                                   -----;
  2151.                                   -----;
  2152.                                end loop;{;4}m
  2153.  
  2154. The while{;4}m loop first evaluates the BOOLEAN expression (I < 10{;4}m in this example).
  2155. If it's FALSE, the block of code isn't executed at all, and execution continues
  2156. after the end loop;{;4}m.  If it's TRUE, the block of code is executed and then the
  2157. BOOLEAN condition is again evaluated.  If the condition is still TRUE, the
  2158. block is executed again and the BOOLEAN expression is evaluated again, and so
  2159. forth.  When the BOOLEAN expression becomes FALSE, the block of code is skipped
  2160. and execution continues after the end loop;{;4}m.
  2161. 1HPlease type a space to go on, or B to go back.               2162 249B247$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$To create an "infinite loop," it isn't necessary to write while TRUE loop{;4}m.  We
  2162. simply write loop{;4}m, as follows:
  2163.  
  2164.                                    loop{;4}m
  2165.                                       -----;
  2166.                                       -----;
  2167.                                       -----;
  2168.                                    end loop;{;4}m
  2169.  
  2170. Ada doesn't have a "repeat ... until" loop, with the test at the bottom.
  2171. However, we can create a loop that's equivalent to a "repeat ... until" loop by
  2172. using an infinite loop with an exit{;4}m statement, to be covered later.
  2173.  
  2174. 1HPlease type a space to go on, or B to go back.              3464 250B248$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                   "FOR" LOOPS
  2175.  
  2176.          for IX in 1 .. 10 loop         for IX in reverse 1 .. 10 loop{;4}m
  2177.             -----;                         -----;
  2178.             -----;                         -----;
  2179.          end loop;                      end loop;{;4}m
  2180.  
  2181. Here are two sample for{;4}m loops.  We need not declare the index (IX{;4}m in these
  2182. examples) in the declarative region of the program; an index of a for{;4}m loop
  2183. declares itself.  In these examples, IX{;4}m comes into existence at the for{;4}m
  2184. statement and goes out of existence at end loop;{;4}m the index isn't available
  2185. outside the loop.  If the name IX{;4}m happens to be used in the declarative region,
  2186. it's a different IX{;4}m.  Inside the loop IX{;4}m refers to the index; there the name IX{;4}m
  2187. is said to hide{;4}m any IX{;4}m that might be mentioned in the declarative region.
  2188.  
  2189. The index variable may not be modified.  In these examples, IX{;4}m may not appear
  2190. on the left side of an assignment statement, etc.
  2191.  
  2192. In the first example above, the block of statements is executed ten times, with
  2193. IX equal to 1, then 2, then 3, etc., up to 10.  In the second example, IX
  2194. starts at 10 and counts down to 1.  Note that the range is still written
  2195. 1 .. 10{;4}m, but the keyword reverse{;4}m precedes the range.
  2196. 1HPlease type a space to go on, or B to go back.            3444 251B249$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The index of a for{;4}m loop can have any discrete type (integer or enumeration
  2197. type).  It can't be of type FLOAT.  For example, if we write
  2198.  
  2199.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2200.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  2201.  
  2202. then we can write for IX in RED .. BLUE loop{;4}m, and the compiler will know that
  2203. IX{;4}m must be of type RAINBOW_COLOR.  Similarly, the type of IX{;4}m will be
  2204. TRAFFIC_LIGHT_COLOR if we write for IX in RED .. AMBER loop{;4}m.  But the compiler
  2205. can't handle for IX in RED .. GREEN loop{;4}m because of the ambiguity.  In this
  2206. case we have to specify the type.  For example, we could write either of these:
  2207.                   for IX in RAINBOW_COLOR'(RED) .. GREEN loop
  2208.                 for IX in RAINBOW_COLOR range RED .. GREEN loop{;4}m
  2209.  
  2210. Because the index can have any discrete type, there's no STEP clause in Ada.
  2211. One might increment an INTEGER index by 2, but we couldn't add 2 to RED.  For
  2212. uniformity, no STEP clause is available, even if the index type is INTEGER.
  2213.  
  2214. Ranges may contain expressions.  If A, B, C, and D are INTEGER variables, we
  2215. can say for I in A + B .. C + D loop{;4}m or for I in reverse A + B .. C + D loop{;4}m.
  2216. In both cases the range is null if C + D is less than A + B.  That won't cause
  2217. an error; the loop is simply skipped when the range is null.
  2218. 1HPlease type a space to go on, or B to go back.                                1720225212533254B250$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QIf we have
  2219.  
  2220.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2221.    J : INTEGER := 5;
  2222.  
  2223. which one of these statements is illegal{;4}m?
  2224.  
  2225.  
  2226.                         1.  for I in -J .. J loop
  2227.  
  2228.                         2.  for I in J .. VIOLET loop
  2229.  
  2230.                         3.  for I in VIOLET .. RED loop
  2231. 1HPlease press 1, 2, or 3, or B to go back.                                                        1866 255B251Q251$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2232.    J : INTEGER := 5;
  2233.  
  2234.                         1.  for I in -J .. J loop
  2235.  
  2236.                         2.  for I in J .. VIOLET loop{;4}m
  2237.  
  2238.                         3.  for I in VIOLET .. RED loop
  2239.  
  2240.  
  2241. You're right!{;4}m  Number 2 is illegal because the expressions before and after the
  2242. "..{;4}m" must be of the same type.
  2243. 1HPlease type a space to go on, or B or Q to go back to the question.          1922 255B251Q251$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2244.    J : INTEGER := 5;
  2245.  
  2246.                         1.  for I in -J .. J loop
  2247.  
  2248.                         2.  for I in J .. VIOLET loop
  2249.  
  2250.                         3.  for I in VIOLET .. RED loop
  2251.  
  2252.  
  2253. No, number 1 is legal.  The expressions on both sides of ..{;4}m have the same type.
  2254. I{;4}m will be of type INTEGER and will take 11 values, from -5 to 5.
  2255. 1HPlease type a space to go on, or B or Q to go back to the question.                                                      2161 255B251Q251$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2256.    J : INTEGER := 5;
  2257.  
  2258.                         1.  for I in -J .. J loop
  2259.  
  2260.                         2.  for I in J .. VIOLET loop
  2261.  
  2262.                         3.  for I in VIOLET .. RED loop
  2263.  
  2264.  
  2265. No, number 3 is legal.  The expressions on both sides of ..{;4}m have the same type.
  2266. The loop will be skipped because RED is less than VIOLET, giving a null range.
  2267. But the syntax is legal.  To make I{;4}m start at VIOLET and count down to RED, we
  2268. would write
  2269.  
  2270.                       for I in reverse RED .. VIOLET loop
  2271. 1HPlease type a space to go on, or B or Q to go back to the question.               3265 256B251$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              THE "EXIT" STATEMENT
  2272.  
  2273.          for I in 1 .. 10 loop            for I in 1 .. 10 loop
  2274.             J := 0;                          J := 0;
  2275.             loop                             loop
  2276.                J := J + 1;                      J := J + 1;
  2277.                if A(I, J) = 0 then
  2278.                   exit;                         exit when A(I, J) = 0;
  2279.                end if;{;4}m
  2280.             end loop;                        end loop;
  2281.             B(I) := J;                       B(I) := J;
  2282.          end loop;                        end loop;
  2283.  
  2284. The statement exit;{;4}m exits the innermost loop.  In the example at the left,
  2285. exit;{;4}m transfers control to the statement B(I) := J;{;4}m.  Since exit;{;4}m is often the
  2286. only statement in an if{;4}m block, exit when{;4}m is available to abbreviate an if{;4}m block
  2287. with exit;{;4}m as its only statement.  The two examples above are equivalent.
  2288.  
  2289. Although exit;{;4}m can appear anywhere inside any kind of loop, well-structured
  2290. Ada programs use only exit when{;4}m, and then only as the last statement of an
  2291. otherwise infinite loop, as shown at the right above.  This simulates a
  2292. "repeat ... until" loop, which isn't directly available in Ada.
  2293. 1HPlease type a space to go on, or B to go back.           3311 257B255$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                       OUTER:
  2294.                        for I in 1 .. 10 loop{;4}m
  2295.                           J := 0;
  2296.                           loop
  2297.                              J := J + 1;
  2298.                              exit OUTER when A(I, J) = 0;{;4}m
  2299.                           end loop;
  2300.                           B(I) := J;
  2301.                        end loop OUTER;{;4}m
  2302.                        K := J;
  2303.  
  2304. An exit{;4}m statement can exit other than the innermost loop by naming{;4}m the loop to
  2305. be exited.  In this example, the for{;4}m loop is named OUTER{;4}m.  A loop name is any
  2306. Ada identifier, and is followed by a colon.  Of course, OUTER:{;4}m could have been
  2307. placed on the same line as the for{;4}m statement.  When a loop is named, the end{;4}m
  2308. loop{;4}m statement must repeat the name of the loop.  The exit{;4}m statement can then
  2309. name the loop to be exited, as in exit OUTER;{;4}m or exit OUTER when A(I, J) = 0;{;4}m.
  2310. In this example, the exit{;4}m statement transfers control to the statement K := J;{;4}m,
  2311. not to B(I) := J;{;4}m.
  2312.  
  2313. Well-structured programs don't use exit{;4}m to leave any loop except the innermost
  2314. loop.  The above example isn't well-structured.
  2315. 1HPlease type a space to go on, or B to go back.                                                                 2849 258B256$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                LABELS AND GOTOS
  2316.  
  2317.                        OUTER:
  2318.                        for I in 1 .. 10 loop
  2319.                           J := 0;
  2320.                           loop
  2321.                              J := J + 1;
  2322.                              exit OUTER when A(I, J) = 0;
  2323.                           end loop;
  2324.                           B(I) := J;
  2325.                        end loop OUTER;
  2326.                        K := J;
  2327.  
  2328. Although an Ada loop name looks exactly like a Pascal label, OUTER:{;4}m is not{;4}m a
  2329. label, and the program can't goto OUTER{;4}m.  An Ada label looks like this:
  2330.  
  2331.                                    << JAIL >>{;4}m
  2332.  
  2333. The <<{;4}m ... >>{;4}m makes the label very conspicuous, whether it's on the same line
  2334. as a statement or on a line by itself.  The program can then say goto JAIL;{;4}m.
  2335. Like all reserved words, goto{;4}m can't contain a space.  Well-structured Ada
  2336. programs don't need goto{;4}ms and labels, so their use is very rare.
  2337. 1HPlease type a space to go on, or B to go back.                           2233125922603261B257$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q                        I_LOOP:   for I in 1 .. 10 loop
  2338.                                      J := 0;
  2339.                         J_LOOP:      loop
  2340.                                         J := J + 1;
  2341.                                         exit;
  2342.                                      end loop J_LOOP;
  2343.                                      L := J;
  2344.                                   end loop I_LOOP;
  2345.                                   M := J;
  2346.  
  2347.  
  2348. In the program segment above, which statement will be executed after exit;{;4}m?
  2349.  
  2350.                            1.  L := J;
  2351.  
  2352.                            2.  M := J;
  2353.  
  2354.                            3.  for I in 1 .. 10 loop
  2355. 1HPlease press 1, 2, or 3, or B to go back.                                           2167 262B258Q258$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                        I_LOOP:   for I in 1 .. 10 loop
  2356.                                      J := 0;
  2357.                         J_LOOP:      loop
  2358.                                         J := J + 1;
  2359.                                         exit;
  2360.                                      end loop J_LOOP;
  2361.                                      L := J;{;4}m
  2362.                                   end loop I_LOOP;
  2363.                                   M := J;
  2364.  
  2365.  
  2366. You're right!{;4}m  When used without a name, exit;{;4}m leaves the innermost loop, so
  2367. the next statement executed is L := J;{;4}m.
  2368. 1HPlease type a space to go on, or B or Q to go back to the question.         2048 262B258Q258$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                        I_LOOP:   for I in 1 .. 10 loop
  2369.                                      J := 0;
  2370.                         J_LOOP:      loop
  2371.                                         J := J + 1;
  2372.                                         exit;
  2373.                                      end loop J_LOOP;
  2374.                                      L := J;
  2375.                                   end loop I_LOOP;
  2376.                                   M := J;
  2377.  
  2378.  
  2379. No, when used without a name, exit;{;4}m leaves the innermost{;4}m loop.
  2380. 1HPlease type a space to go on, or B or Q to go back to the question.                            2166 262B258Q258$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                        I_LOOP:   for I in 1 .. 10 loop
  2381.                                      J := 0;
  2382.                         J_LOOP:      loop
  2383.                                         J := J + 1;
  2384.                                         exit;
  2385.                                      end loop J_LOOP;
  2386.                                      L := J;
  2387.                                   end loop I_LOOP;
  2388.                                   M := J;
  2389.  
  2390.  
  2391. No, when used without a name, exit;{;4}m leaves the innermost loop.  The next
  2392. statement executed will be the first statement after the end of the innermost
  2393. loop.
  2394. 1HPlease type a space to go on, or B or Q to go back to the question.          3974 263B258$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              THE "CASE" CONSTRUCT
  2395.  
  2396. case C is{;4}m                        In this example, assume that C{;4}m is of type
  2397.    when '*' =>{;4}m                   CHARACTER.  The expression being tested (C{;4}m),
  2398.       -----;{;4}m                     must have a discrete type: integer or
  2399.       -----;{;4}m                     enumeration type.  The case{;4}m construct must
  2400.    when '#' | '$' =>{;4}m             handle all possible values, but when others{;4}m is
  2401.       -----;{;4}m                     available.  If no action is desired for
  2402.       -----;{;4}m                     characters not mentioned, we can write when{;4}m
  2403.       -----;{;4}m                     others => null;{;4}m.  The Ada statement null;{;4}m does
  2404.    when '0' .. '9' =>{;4}m            nothing.  Note that the vertical bar can be
  2405.       -----;{;4}m                     used to apply several cases to one block of
  2406.    when 'A'..'Z' | 'a'..'z' =>{;4}m   code, and that ranges can be used.  Here, if C{;4}m
  2407.       -----;{;4}m                     is '*', the first block is executed; if it's
  2408.       -----;{;4}m                     '#' or '$', the second block is executed.  If
  2409.       -----;{;4}m                     it's a digit, the third block is executed, and
  2410.    when others =>{;4}m                if it's a letter (upper or lower case), the
  2411.       -----;{;4}m                     fourth block is executed.  If C{;4}m is anything
  2412.       -----;{;4}m                     else, the fifth (last) block of code is
  2413. end case;{;4}m                        executed.
  2414. 1HPlease type a space to go on, or B to go back.  2758 264B262$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$case C is
  2415.    when '*' =>                        if C = '*' then
  2416.       -----;                             -----;
  2417.       -----;                             -----;
  2418.    when '#' | '$' =>                  elsif C = '#' or C = '$' then
  2419.       -----;                             -----;
  2420.       -----;                             -----;
  2421.       -----;                             -----;
  2422.    when '0' .. '9' =>                 elsif C in '0' .. '9' then
  2423.       -----;                             -----;
  2424.    when 'A'..'Z' | 'a'..'z' =>        elsif C in 'A'..'Z' or C in 'a'..'z' then
  2425.       -----;                             -----;
  2426.       -----;                             -----;
  2427.       -----;                             -----;
  2428.    when others =>                     else
  2429.       -----;                             -----;
  2430.       -----;                             -----;
  2431. end case;                             end if;
  2432.  
  2433. Note that these two examples are equivalent.  In both cases only one block of
  2434. code will be executed.
  2435. 1HPlease type a space to go on, or B to go back.                  2519326512662267B263$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QIf we have
  2436.  
  2437.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2438.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  2439.    F : FLOAT range 0.0 .. 2.0;
  2440.    R : RAINBOW_COLOR;
  2441.    T : TRAFFIC_LIGHT_COLOR;
  2442.  
  2443. then which one{;4}m of the following program segments is legal{;4}m?
  2444.  
  2445.             1:                            2:                         3:
  2446.  
  2447.  case R is                       case F is                    case T is
  2448.    when RED | GREEN =>              when 0.0 .. 1.0 =>           when RED =>
  2449.       -----;                           -----;                       -----;
  2450.    when BLUE .. VIOLET =>           when others =>               when others =>
  2451.       -----;                           -----;                       -----;
  2452.  end case;                       end case;                    end case;
  2453.  
  2454. 1HPlease press 1, 2, or 3, or B to go back.                                                         2847 268B264Q264$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2455.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  2456.    F : FLOAT range 0.0 .. 2.0;
  2457.    R : RAINBOW_COLOR;
  2458.    T : TRAFFIC_LIGHT_COLOR;
  2459.  
  2460.             1:                            2:                         3:{;4}m
  2461.  
  2462.  case R is                       case F is                    case T is{;4}m
  2463.    when RED | GREEN =>              when 0.0 .. 1.0 =>           when RED =>{;4}m
  2464.       -----;                           -----;                       -----;{;4}m
  2465.    when BLUE .. VIOLET =>           when others =>               when others =>{;4}m
  2466.       -----;                           -----;                       -----;{;4}m
  2467.  end case;                       end case;                    end case;{;4}m
  2468.  
  2469. You're right!{;4}m  Number 1 is illegal because it doesn't account for all possible
  2470. values of R{;4}m, and number 2 is illegal because F{;4}m doesn't have a discrete type.
  2471. 1HPlease type a space to go on, or B or Q to go back to the question.                             2542 268B264Q264$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2472.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  2473.    F : FLOAT range 0.0 .. 2.0;
  2474.    R : RAINBOW_COLOR;
  2475.    T : TRAFFIC_LIGHT_COLOR;
  2476.  
  2477.             1:                            2:                         3:
  2478.  
  2479.  case R is                       case F is                    case T is
  2480.    when RED | GREEN =>              when 0.0 .. 1.0 =>           when RED =>
  2481.       -----;                           -----;                       -----;
  2482.    when BLUE .. VIOLET =>           when others =>               when others =>
  2483.       -----;                           -----;                       -----;
  2484.  end case;                       end case;                    end case;
  2485.  
  2486. No, number 1 is illegal because it doesn't account for all the possible values
  2487. of R{;4}m.
  2488. 1HPlease type a space to go on, or B or Q to go back to the question.                                  2520 268B264Q264$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2489.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  2490.    F : FLOAT range 0.0 .. 2.0;
  2491.    R : RAINBOW_COLOR;
  2492.    T : TRAFFIC_LIGHT_COLOR;
  2493.  
  2494.             1:                            2:                         3:
  2495.  
  2496.  case R is                       case F is                    case T is
  2497.    when RED | GREEN =>              when 0.0 .. 1.0 =>           when RED =>
  2498.       -----;                           -----;                       -----;
  2499.    when BLUE .. VIOLET =>           when others =>               when others =>
  2500.       -----;                           -----;                       -----;
  2501.  end case;                       end case;                    end case;
  2502.  
  2503. No, number 2 is illegal because F{;4}m doesn't have a discrete type.
  2504. 1HPlease type a space to go on, or B or Q to go back to the question.                                                        2934 269B264$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          BRIEF OVERVIEW OF FUNCTIONS
  2505.  
  2506.               procedure FUNCT_DEMO is
  2507.                  X : FLOAT := 1.2;
  2508.                  Y : FLOAT;
  2509.                  function TWICE(DUMMY : in FLOAT) return FLOAT is
  2510.                     ANSWER : FLOAT;
  2511.                  begin
  2512.                     ANSWER := DUMMY * 2.0;
  2513.                     return ANSWER;
  2514.                  end TWICE;{;4}m
  2515.               begin
  2516.                  Y := TWICE(X);
  2517.               end FUNCT_DEMO;
  2518.  
  2519. Later we'll cover functions and procedures in detail, but let's look briefly at
  2520. functions now so we can do Outside Assignment 2.  Here procedure FUNCT_DEMO
  2521. locally declares a function TWICE.  TWICE can be called only from within
  2522. FUNCT_DEMO:  Y := TWICE(X);{;4}m.  Note that the function specification gives the
  2523. name (DUMMY), mode (in) and type (FLOAT) of any dummy arguments, or parameters.
  2524. For functions, the mode of all parameters must be in{;4}m, never out{;4}m or in out{;4}m.  The
  2525. function specification also gives the type being return{;4}med, in this case FLOAT.
  2526. 1HPlease type a space to go on, or B to go back.                                          2649 270B268$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              procedure FUNCT_DEMO is
  2527.                  X : FLOAT := 1.2;
  2528.                  Y : FLOAT;
  2529.                  function TWICE(DUMMY : in FLOAT) return FLOAT is
  2530.                     ANSWER : FLOAT;
  2531.                  begin
  2532.                     ANSWER := DUMMY * 2.0;
  2533.                     return ANSWER;{;4}m
  2534.                  end TWICE;
  2535.               begin
  2536.                  Y := TWICE(X);
  2537.               end FUNCT_DEMO;
  2538.  
  2539. The function body must have return{;4}m followed by an expression of the right type.
  2540. In well-structured functions, this is the last statement before end{;4}m.  We don't
  2541. return a value by placing the name of the function in an assignment statement,
  2542. as in Fortran.  Note that function TWICE could be written more simply as
  2543.  
  2544.                 function TWICE(DUMMY : in FLOAT) return FLOAT is
  2545.                 begin
  2546.                    return DUMMY * 2.0;
  2547.                 end TWICE;
  2548. 1HPlease type a space to go on, or B to go back.                           2918 271B269$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$         procedure FUNCT_DEMO is
  2549.             X : FLOAT := 1.2;
  2550.             Y : FLOAT;
  2551.             function TWICE(DUMMY : in FLOAT) return FLOAT is separate;{;4}m
  2552.          begin
  2553.             Y := TWICE(X);
  2554.          end FUNCT_DEMO;
  2555.  
  2556.          separate (FUNCT_DEMO)
  2557.          function TWICE(DUMMY : in FLOAT) return FLOAT is{;4}m
  2558.          begin
  2559.             return DUMMY * 2.0;
  2560.          end TWICE;
  2561.  
  2562. The function can be placed in a separate file and compiled later.  Here the
  2563. calling program can be compiled once, and later the function can be edited and
  2564. recompiled as often as desired.  TWICE{;4}m is still local to FUNCT_DEMO{;4}m.  The
  2565. phrase separate (FUNCT_DEMO){;4}m tells Ada that this subprogram is part of the
  2566. previously compiled unit FUNCT_DEMO{;4}m.  It's as if the function were cut out and
  2567. "pasted" where the calling program says function TWICE{;4}m ... is separate;{;4}m.  Ada
  2568. can still compile the call Y := TWICE(X);{;4}m because the calling program contains
  2569. the specification of the function.
  2570. 1HPlease type a space to go on, or B to go back.                                                          3321 272B270$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A              OUTSIDE ASSIGNMENT 2 - EXERCISE IN ENUMERATION TYPES
  2571.  
  2572. Separate compilation is the basis of our next Outside Assignment.  The function
  2573. we want you to write is completely specified by these two lines of Ada:
  2574.  
  2575.       type TRIANGLE is (EQUILATERAL, ISOSCELES, SCALENE, NOT_A_TRIANGLE);
  2576.       function TRITYPE(LEN1, LEN2, LEN3 : in INTEGER) return TRIANGLE;{;4}m
  2577.  
  2578. From these two lines, it's obvious that the function must decide whether three
  2579. integers, representing the lengths of the sides of a triangle, in fact
  2580. represent an equilateral triangle, an isosceles triangle, a scalene triangle,
  2581. or no triangle at all.  (An equilateral triangle has three equal sides; an
  2582. isosceles triangle has only two equal sides.  A scalene triangle has sides of
  2583. three different lengths, and the integers -1, 0, 5 represent no triangle.)
  2584.  
  2585. A test driver for your function is already written, and is in the file
  2586. TRITEST.ADA{;4}m.  A listing starts on page 7 of your printed course notes.  You
  2587. need not understand the test driver.  It's sufficient to know that if your
  2588. function passes all the tests, the message "Congratulations, you completed the
  2589. assignment!" is shown.  For any failed tests, the test driver displays the test
  2590. case, the answer from your function, and the correct answer.  This will help
  2591. you in debugging your function.
  2592. 1HPlease type a space to go on, or B to go back.                                                       2822 273B271$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Note that the test driver, which is the main program, contains
  2593.  
  2594.   type TRIANGLE is (EQUILATERAL, ISOSCELES, SCALENE, NOT_A_TRIANGLE);
  2595.   function TRITYPE(LEN1, LEN2, LEN3 : in INTEGER) return TRIANGLE is separate;
  2596.  
  2597. This allows you to edit and recompile your function as often as you like,
  2598. without having to recompile the test driver.  Since type TRIANGLE{;4}m is defined in
  2599. the calling program, you should not{;4}m define it in your function.
  2600.  
  2601. To get you started, a dummy solution is given in TRITYPE.DUM{;4}m.  You can copy it
  2602. and edit the copy to become your real solution.  It looks like this:
  2603.  
  2604.        -- Dummy solution for Outside Assignment 2
  2605.        -- Edit to become your real solution.
  2606.        separate (TRITEST)
  2607.        function TRITYPE(LEN1, LEN2, LEN3 : in INTEGER) return TRIANGLE is
  2608.        begin
  2609.           return NOT_A_TRIANGLE;
  2610.        end TRITYPE;
  2611.  
  2612. If you wish, you can compile this dummy solution before editing it.  Then
  2613. you'll see what error messages from the test driver look like.
  2614. 1HPlease type a space to go on, or B to go back.                                                      2641 274B272$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       -- Dummy solution for Outside Assignment 2
  2615.        -- Edit to become your real solution.
  2616.        separate (TRITEST)
  2617.        function TRITYPE(LEN1, LEN2, LEN3 : in INTEGER) return TRIANGLE is
  2618.        begin{;4}m
  2619.           return NOT_A_TRIANGLE;
  2620.        end TRITYPE;{;4}m
  2621.  
  2622. When you do edit the function, you'll probably want to remove or change the
  2623. first two comment lines.  Don't change the lines highlighted{;4}m above.  You may
  2624. want to create a new variable of type TRIANGLE, and return that variable
  2625. instead of the constant NOT_A_TRIANGLE at the end of your function:
  2626.  
  2627.        separate (TRITEST)
  2628.        function TRITYPE(LEN1, LEN2, LEN3 : in INTEGER) return TRIANGLE is
  2629.           ANSWER : TRIANGLE;{;4}m
  2630.        begin
  2631.           if ... end if;
  2632.           return ANSWER;{;4}m
  2633.        end TRITYPE;
  2634.  
  2635. However, that's not the only way to solve the problem, just a suggestion.
  2636. 1HPlease type a space to go on, or B to go back.                                   2459 275B273$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Here are the steps to follow for Outside Assignment 2.  They're also in your
  2637. printed course notes on page 9:
  2638.  
  2639. 1.  Compile the test driver TRITEST.ADA.  Also, make a copy of the dummy
  2640.     solution by typing COPY TRITYPE.DUM TRITYPE.ADA{;4}m.  You need do this step
  2641.     only once.
  2642.  
  2643. 2.  Edit TRITYPE.ADA to become your real solution.  You can skip this step the
  2644.     first time through, to see error messages from the test driver.
  2645.  
  2646. 3.  Compile your solution TRITYPE.ADA.  If there are compiler errors, go back
  2647.     to step 2.
  2648.  
  2649. 4.  Link with the name of the main program TRITEST.  Then execute.  If the test
  2650.     driver prints error messages, go back to step 2.
  2651.  
  2652. 5.  When the message "Congratulations, you completed the assignment!" is
  2653.     printed, you'll have a chance to compare your solution with ours.
  2654. 1HPlease type a space to go on, or B to go back.                 2174 276B274$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Remember that a function can't change the values of its parameters (in this
  2655. case, LEN1, LEN2, and LEN3), because function parameters are always of mode in{;4}m.
  2656.  
  2657. This assignment should be a simple exercise in enumeration types and the
  2658. control constructs.  Our solution easily fits on one screen.  If you find your
  2659. solution getting long and difficult, you should probably think through the
  2660. problem again.  See if there's a simple way to test for the four possible
  2661. answers.
  2662.  
  2663. Please type X to exit ADA-TUTR{;4}m temporarily, and try Outside Assignment 2.  Work
  2664. at your own pace; there's no deadline.  Good luck!
  2665. 1HPlease type X to exit, a space to go on, or B to go back.  2236 277B275$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              Congratulations on Completing Outside Assignment 2!{;4}m
  2666.  
  2667. Our solution is in TRITYPE.ANS{;4}m.  It looks like this:
  2668.  
  2669. -- Our solution to Outside Assignment 2:
  2670. separate (TRITEST)
  2671. function TRITYPE(LEN1, LEN2, LEN3 : in INTEGER) return TRIANGLE is
  2672.    ANSWER : TRIANGLE;
  2673. begin
  2674.    if LEN1 + LEN2 <= LEN3  or LEN1 + LEN3 <= LEN2  or LEN2 + LEN3 <= LEN1  then
  2675.       ANSWER := NOT_A_TRIANGLE;
  2676.    elsif  LEN1 = LEN2  and  LEN2 = LEN3  then
  2677.       ANSWER := EQUILATERAL;
  2678.    elsif  LEN1 = LEN2  or  LEN2 = LEN3  or  LEN1 = LEN3  then
  2679.       ANSWER := ISOSCELES;
  2680.    else
  2681.       ANSWER := SCALENE;
  2682.    end if;
  2683.    return ANSWER;
  2684. end TRITYPE;
  2685. 1HPlease type a space to go on, or B to go back.                                        2670 278B276$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Note that it isn't necessary to include tests for sides <= 0, because if any
  2686. side <= 0, one of the three tests in the following would have to catch that:
  2687.  
  2688. if  LEN1 + LEN2 <= LEN3  or  LEN1 + LEN3 <= LEN2  or  LEN2 + LEN3 <= LEN1  then
  2689.    ANSWER := NOT_A_TRIANGLE;
  2690.  
  2691. However, most students include tests for sides <= 0, so if you did, don't feel
  2692. bad.  It doesn't do any harm.
  2693.  
  2694. You must have realized by now that it's impossible to draw a triangle with
  2695. sides 1, 2, and 3.  The sum of any two sides must be greater than the third.
  2696.  
  2697. There are many correct ways to solve this problem.  Some students sort the
  2698. three sides first.  Some initialize ANSWER to SCALENE in the declarative region
  2699. and omit the code
  2700.  
  2701.                              else
  2702.                                 ANSWER := SCALENE;
  2703.  
  2704. If you saw the message "Congratulations, you completed the assignment!" you can
  2705. consider your solution correct.  Let's go on to discuss Records and Arrays.
  2706. 1HPlease type a space to go on, or B to go back.      2136 279B277$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  2707.  
  2708.    Introduction                          >  RECORDS, ARRAYS, AND ASSIGNMENT 3{;4}m
  2709.  
  2710.    The Format of an Ada Program             Recursion and Assignment 4
  2711.  
  2712.    Generic Instantiation and                Subprograms and Packages
  2713.       Assignment 1
  2714.                                             Additional Types, Exceptions,
  2715.    Simple Declarations and Simple              TEXT_IO, and Assignment 5
  2716.       Attributes
  2717.                                             Generics, Tasking, and Assignment 6
  2718.    Operators, Control Constructs, and
  2719.       Assignment 2                          Advanced Topics
  2720. 1HPlease type a space to go on, or B to go back.                                        3046 280B278$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    RECORDS
  2721.  
  2722. A record{;4}m lets us group several declarations together and refer to them as one:
  2723.  
  2724.      type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  2725.      subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  2726.      type DATE is
  2727.         record
  2728.            DAY   : DAY_SUBTYPE;{;4}m   -- Note that DAY_SUBTYPE and
  2729.            MONTH : MONTH_TYPE;{;4}m    -- MONTH_TYPE must be defined
  2730.            YEAR  : INTEGER;{;4}m       -- before type DATE is defined.
  2731.         end record;
  2732.      USA : DATE;{;4}m
  2733.  
  2734. In this example, USA{;4}m has three parts (called "fields"):  USA.DAY{;4}m, USA.MONTH{;4}m,
  2735. and USA.YEAR{;4}m.  The fields of a record can be of any type, including other
  2736. records.  Here USA.DAY{;4}m is of type{;4}m INTEGER, USA.MONTH{;4}m is of type MONTH_TYPE, and
  2737. USA.YEAR{;4}m is of type INTEGER.  The parts of USA{;4}m may be used separately:
  2738.  
  2739.                                USA.DAY := 4;
  2740.                                USA.MONTH := JUL;
  2741.                                USA.YEAR := 1776;{;4}m
  2742. 1HPlease type a space to go on, or B to go back.                              3074 281B279$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  2743.      subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  2744.      type DATE is
  2745.         record
  2746.            DAY   : DAY_SUBTYPE;
  2747.            MONTH : MONTH_TYPE;
  2748.            YEAR  : INTEGER;
  2749.         end record;
  2750.      USA : DATE;{;4}m
  2751.  
  2752. However, USA{;4}m can also be used as one object.  For example, we could have
  2753. assigned all three fields in one statement:  USA := (4, JUL, 1776);{;4}m.  Here the
  2754. object on the left is of type DATE, and the object on the right is called an
  2755. aggregate{;4}m.  The aggregate fits the type DATE because it contains an INTEGER, a
  2756. MONTH_TYPE, and another INTEGER.  This aggregate is said to use positional{;4}m
  2757. notation because its three parts appear in the same order as the three parts of
  2758. the record definition:  first DAY, then MONTH, then YEAR.
  2759.  
  2760. We can specify the parts of an aggregate in any order we like if we use named{;4}m
  2761. notation: USA := (MONTH => JUL, DAY => 4, YEAR => 1776);{;4}m.  The symbol =>{;4}m is
  2762. read "arrow."  Using named notation often improves program readability,
  2763. especially if the names of the fields are well chosen.
  2764. 1HPlease type a space to go on, or B to go back.  2427 282B280$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  2765.      subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  2766.      type DATE is
  2767.         record
  2768.            DAY   : DAY_SUBTYPE;
  2769.            MONTH : MONTH_TYPE;
  2770.            YEAR  : INTEGER;
  2771.         end record;
  2772.      USA : DATE;{;4}m
  2773.  
  2774. We can switch from positional to named notation in an aggregate.  But once we
  2775. use named notation, the compiler loses track of position, so we can't switch
  2776. back to positional.  For example, the following is legal{;4}m:
  2777.  
  2778.                     USA := (4, YEAR => 1776, MONTH => JUL);{;4}m
  2779.  
  2780. But the following is illegal{;4}m because positional notation can't follow named in
  2781. an aggregate:
  2782.  
  2783.                    USA := (4, YEAR => 1776, JUL); -- illegal
  2784. 1HPlease type a space to go on, or B to go back.                                                 22453283128422854286B281$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q    procedure RECORD_EXERCISE is
  2785.        type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  2786.        subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  2787.        type DATE is
  2788.           record
  2789.              DAY   : DAY_SUBTYPE;
  2790.              MONTH : MONTH_TYPE;
  2791.              YEAR  : INTEGER;
  2792.           end record;
  2793.        D1, D2, D3 : DATE;  -- 1{;4}m
  2794.     begin
  2795.        D1 := (MONTH => AUG, DAY => 14, YEAR => 1945);  -- 2{;4}m
  2796.        D2.DAY := 22;
  2797.        D2.MONTH := 1;  -- 3{;4}m
  2798.        D2.YEAR := 1983;
  2799.        D3 := D2;  -- 4{;4}m
  2800.     end RECORD_EXERCISE;
  2801.  
  2802. Which commented line in the above program is illegal{;4}m?
  2803. 1HPlease press 1, 2, 3, or 4, or B to go back.                               1543 287B282Q282$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       D2.MONTH := 1;  -- 3{;4}m
  2804.  
  2805. You're right!{;4}m  This statement is illegal, because the types are mixed.
  2806. D2.MONTH{;4}m is of type MONTH_TYPE, and 1{;4}m is an integer.
  2807. 1HPlease type a space to go on, or B or Q to go back to the question.                                 1458 287B282Q282$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       D1, D2, D3 : DATE;  -- 1
  2808.  
  2809. No, this statement is legal, because several objects may be declared in one
  2810. statement, if the objects are separated by commas.
  2811. 1HPlease type a space to go on, or B or Q to go back to the question.                  1517 287B282Q282$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       D1 := (MONTH => AUG, DAY => 14, YEAR => 1945);  -- 2
  2812.  
  2813. No, this statement is legal, because the fields within the aggregate may appear
  2814. in any order when named notation is used.
  2815. 1HPlease type a space to go on, or B or Q to go back to the question.                                                           1531 287B282Q282$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       D3 := D2;  -- 4
  2816.  
  2817. No, this statement is legal, because D3{;4}m and D2{;4}m both have the same type: DATE{;4}m.
  2818. An entire record can be assigned with one statement.
  2819. 1HPlease type a space to go on, or B or Q to go back to the question.                                             3346 288B282$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                     ARRAYS
  2820.  
  2821. To declare an array in Ada, we specify the type and range of the subscript{;4}m,
  2822. followed by the type of the elements{;4}m of the array.  The subscript can have any
  2823. discrete type (integer or enumeration), and the elements of the array can be of
  2824. any type at all, including records and other arrays.  There are three ways to
  2825. declare an array in Ada.  Here are three examples of the most direct, but least
  2826. flexible, way (types RAINBOW_COLOR and DATE must be defined earlier):
  2827.  
  2828. A : array(RAINBOW_COLOR range ORANGE .. BLUE) of DATE;{;4}m
  2829.    -- A four-element array, each element of which is a record with three parts.
  2830.    -- The allowable subscripts are ORANGE, YELLOW, GREEN, and BLUE.  Note that
  2831.    -- A(YELLOW) is of type DATE, and A(YELLOW).YEAR is of type INTEGER.
  2832. B : array(INTEGER range -10 .. 10) of INTEGER;{;4}m
  2833.    -- An array of 21 INTEGERs, with INTEGER subscripts.
  2834. C : array(0 .. 30) of FLOAT;{;4}m
  2835.    -- Here (0 .. 30) is understood to mean (INTEGER range 0 .. 30), and we have
  2836.    -- an array of 31 FLOATs, with INTEGER subscripts.{;4}m
  2837.  
  2838. A subscript can be an expression; if I is an INTEGER, we can write C(2*I){;4}m.  If
  2839. a subscript is out-of-range (for example, A(RED){;4}m or C(-32){;4}m), the program will
  2840. raise a CONSTRAINT_ERROR.
  2841. 1HPlease type a space to go on, or B to go back.                              3061 289B287$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$This direct method of declaring arrays is usually used to create single arrays
  2842. for table lookup, etc., where there's no need to have several arrays of the
  2843. same type.  A better way to declare an array is to specify a type name for the
  2844. array itself.  Then several objects can be declared to have that same type.
  2845. For example,
  2846.  
  2847.                   type VECTOR100 is array(1 .. 100) of FLOAT;
  2848.                   type VECTOR300 is array(1 .. 300) of FLOAT;
  2849.                   D, E, F : VECTOR100;
  2850.                   G, H    : VECTOR300;{;4}m
  2851.  
  2852. Here D, E, and F are all of type VECTOR100{;4}m, so we can write D := E;{;4}m  and assign
  2853. the entire array with one statement.  Similarly, we can write G := H;{;4}m, but not
  2854. G := F;{;4}m.
  2855.  
  2856. Note that the example above takes four statements.  An even better way to
  2857. declare arrays is to leave the range of the subscript unspecified with the box{;4}m
  2858. symbol, <>{;4}m, specifying the range when declaring the objects.  For example,
  2859.  
  2860.                 type VECTOR is array(INTEGER range <>) of FLOAT;
  2861.                 D, E, F : VECTOR(1 .. 100);
  2862.                 G, H    : VECTOR(1 .. 300);{;4}m
  2863. 1HPlease type a space to go on, or B to go back.               3072 290B288$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$There are two errors to avoid when declaring arrays in this way.  One is to
  2864. declare a type with the box symbol for the range of the subscript, and then
  2865. fail to specify the range when declaring an object (other than a constant):
  2866.  
  2867.                type VECTOR is array(INTEGER range <>) of FLOAT;
  2868.                D1 : VECTOR; -- illegal{;4}m
  2869.                D2 : constant{;4}m VECTOR := (2.3, 4.5, 4.0); -- legal{;4}m
  2870.  
  2871. This error is called unconstrained array{;4}m.  Unconstrained arrays are legal in
  2872. dummy arguments ("formal parameters") of procedures and functions, and a
  2873. function can return{;4}m an unconstrained array type.  (We'll learn about these
  2874. things later.)  But an unconstrained array is illegal when declaring a
  2875. variable, because the compiler needs to know the range of the subscript.
  2876.  
  2877. The other error is to specify the range of the subscript twice: once when
  2878. declaring the type and once when declaring the object:
  2879.  
  2880.                   type VECTOR100 is array(1 .. 100) of FLOAT;
  2881.                   D2 : VECTOR100(1 .. 100);  -- illegal{;4}m
  2882.  
  2883. Even if the two ranges agree, this is illegal and is called doubly constrained
  2884. array{;4}m.
  2885. 1HPlease type a space to go on, or B to go back.    3152 291B289$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Arrays may be initialized and assigned with aggregates, and both positional and
  2886. named notation may be used.  For example, arrays A{;4}m and B{;4}m are equal here:
  2887.  
  2888.  type VECTOR5 is array(1 .. 5) of FLOAT;
  2889.  A : constant VECTOR5 := (2.0, 4.0, 8.0, 16.0, 32.0);
  2890.  B : constant VECTOR5 := (1 => 2.0, 2 => 4.0, 3 => 8.0, 4 => 16.0, 5 => 32.0);{;4}m
  2891.  
  2892. The aggregate must fill the whole array, but the reserved word others{;4}m is
  2893. available.  Here's an array of 500 FLOAT variables, all initialized to 0.0:
  2894.  
  2895.                   type VECTOR500 is array(1 .. 500) of FLOAT;
  2896.                   V1 : VECTOR500 := (others => 0.0);{;4}m
  2897.  
  2898. If others{;4}m follows named notation, it's best to qualify the aggregate with the
  2899. type name.  Here W(10) = 1.3, W(15) = -30.7, and the rest of the array is 0.0:
  2900.  
  2901.      W : VECTOR500 := VECTOR500'(10 => 1.3,  15 => -30.7,  others => 0.0);{;4}m
  2902.  
  2903. Sometimes we must{;4}m qualify an aggregate when others{;4}m is used with named notation;
  2904. at other times it's optional.  The rules (LRM section 4.3.2, paragraphs 4-8)
  2905. are very complicated.  It's easiest always to qualify an aggregate when others{;4}m
  2906. follows named notation, as shown above.
  2907. 1HPlease type a space to go on, or B to go back.                        3056 292B290$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In array aggregates, multiple choices can be denoted with the vertical bar (|{;4}m),
  2908. shift-backslash on your keyboard.  In this array, the elements with odd
  2909. subscripts are TRUE, while the elements with even subscripts are FALSE:
  2910.  
  2911.           type DECADE is array(1 .. 10) of BOOLEAN;
  2912.           D1 : DECADE;{;4}m
  2913.           ...
  2914.           D1 := DECADE'(1 | 3 | 5 | 7 | 9 => TRUE,  others => FALSE);{;4}m
  2915.  
  2916. Here we assigned to D1 with an executable statement for variety; we could also
  2917. have initialized D1 in the declarative region with the same aggregate.  Some
  2918. people read the vertical bar as "and," others as "or."  One can say, "Elements
  2919. 1, and{;4}m 3, and 5, and 7, and 9 are TRUE," or one can say, "If the subscript is
  2920. 1, or{;4}m 3, or 5, or 7, or 9, the array element is TRUE."
  2921.  
  2922. Array aggregates can also contain ranges.  In this array, elements 1 and 6 - 10
  2923. are 1; the rest are 0.  Arrays L1{;4}m and L2{;4}m are equal:
  2924.  
  2925.          type LIST15 is array(1 .. 15) of INTEGER;
  2926.          L1 : LIST15 := LIST15'(1 | 6 .. 10 => 1,  others => 0);
  2927.          L2 : LIST15 := (1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0);{;4}m
  2928. 1HPlease type a space to go on, or B to go back.                    23561293229432954296B291$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Qwith TEXT_IO; use TEXT_IO;
  2929. procedure ARRAY_QUIZ is
  2930.    package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  2931.    subtype CAPITAL_LETTER is CHARACTER range 'A' .. 'Z';
  2932.    type SET_OF_LETTERS is array(CAPITAL_LETTER) of BOOLEAN;
  2933.    VOWELS : SET_OF_LETTERS :=
  2934.         SET_OF_LETTERS'('A' | 'E' | 'I' | 'O' | 'U' => TRUE,  others => FALSE);
  2935.    LETTER : CAPITAL_LETTER;
  2936. begin
  2937.    LETTER := 'E';
  2938.    PUT(BOOLEAN'POS(VOWELS(LETTER)));
  2939. end ARRAY_QUIZ;{;4}m
  2940.  
  2941.                         What will this program print?
  2942.  
  2943.                         1.  The program will print 1.
  2944.  
  2945.                         2.  The program will print 2.
  2946.  
  2947.                         3.  The program will print TRUE.
  2948.  
  2949.                         4.  The program will print E.
  2950. 1HPlease press 1, 2, 3, or 4, or B to go back.                    2421 297B292Q292$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$with TEXT_IO; use TEXT_IO;
  2951. procedure ARRAY_QUIZ is
  2952.    package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  2953.    subtype CAPITAL_LETTER is CHARACTER range 'A' .. 'Z';
  2954.    type SET_OF_LETTERS is array(CAPITAL_LETTER) of BOOLEAN;
  2955.    VOWELS : SET_OF_LETTERS :=
  2956.         SET_OF_LETTERS'('A' | 'E' | 'I' | 'O' | 'U' => TRUE,  others => FALSE);
  2957.    LETTER : CAPITAL_LETTER;
  2958. begin
  2959.    LETTER := 'E';
  2960.    PUT(BOOLEAN'POS(VOWELS(LETTER)));
  2961. end ARRAY_QUIZ;{;4}m
  2962.  
  2963.  
  2964. You're right!{;4}m  VOWELS has 26 elements, with subscripts 'A' through 'Z'.
  2965. VOWELS(LETTER) is VOWELS('E'), which is TRUE, and since Ada defines
  2966.  
  2967.                          type BOOLEAN is (FALSE, TRUE);
  2968.  
  2969. and the positions are numbered starting from 0, BOOLEAN'POS(TRUE) is 1.
  2970. 1HPlease type a space to go on, or B or Q to go back to the question.                                                       2226 297B292Q292$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$with TEXT_IO; use TEXT_IO;
  2971. procedure ARRAY_QUIZ is
  2972.    package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  2973.    subtype CAPITAL_LETTER is CHARACTER range 'A' .. 'Z';
  2974.    type SET_OF_LETTERS is array(CAPITAL_LETTER) of BOOLEAN;
  2975.    VOWELS : SET_OF_LETTERS :=
  2976.         SET_OF_LETTERS'('A' | 'E' | 'I' | 'O' | 'U' => TRUE,  others => FALSE);
  2977.    LETTER : CAPITAL_LETTER;
  2978. begin
  2979.    LETTER := 'E';
  2980.    PUT(BOOLEAN'POS(VOWELS(LETTER)));
  2981. end ARRAY_QUIZ;
  2982.  
  2983.  
  2984. No.  Recall that Ada defines
  2985.  
  2986.                          type BOOLEAN is (FALSE, TRUE);
  2987.  
  2988. and that the positions are numbered starting with 0 for the POS{;4}m attribute.
  2989. 1HPlease type a space to go on, or B or Q to go back to the question.                                                  2313 297B292Q292$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$with TEXT_IO; use TEXT_IO;
  2990. procedure ARRAY_QUIZ is
  2991.    package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  2992.    subtype CAPITAL_LETTER is CHARACTER range 'A' .. 'Z';
  2993.    type SET_OF_LETTERS is array(CAPITAL_LETTER) of BOOLEAN;
  2994.    VOWELS : SET_OF_LETTERS :=
  2995.         SET_OF_LETTERS'('A' | 'E' | 'I' | 'O' | 'U' => TRUE,  others => FALSE);
  2996.    LETTER : CAPITAL_LETTER;
  2997. begin
  2998.    LETTER := 'E';
  2999.    PUT(BOOLEAN'POS(VOWELS(LETTER)));
  3000. end ARRAY_QUIZ;
  3001.  
  3002.  
  3003. No.  Indeed VOWELS(LETTER) is VOWELS('E'), which is TRUE, but the program takes
  3004. the BOOLEAN'POS of VOWELS(LETTER).  Recall that the attribute POS{;4}m converts from
  3005. a discrete type (in this case, BOOLEAN) to an integer.
  3006. 1HPlease type a space to go on, or B or Q to go back to the question.                                                               2350 297B292Q292$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$with TEXT_IO; use TEXT_IO;
  3007. procedure ARRAY_QUIZ is
  3008.    package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  3009.    subtype CAPITAL_LETTER is CHARACTER range 'A' .. 'Z';
  3010.    type SET_OF_LETTERS is array(CAPITAL_LETTER) of BOOLEAN;
  3011.    VOWELS : SET_OF_LETTERS :=
  3012.         SET_OF_LETTERS'('A' | 'E' | 'I' | 'O' | 'U' => TRUE,  others => FALSE);
  3013.    LETTER : CAPITAL_LETTER;
  3014. begin
  3015.    LETTER := 'E';
  3016.    PUT(BOOLEAN'POS(VOWELS(LETTER)));
  3017. end ARRAY_QUIZ;
  3018.  
  3019.  
  3020. No.  While LETTER is 'E', and LETTER appears inside the PUT statement, the
  3021. argument of PUT is the BOOLEAN'POS of one element of array VOWELS
  3022. (specifically, the element whose subscript is 'E').  Recall that the POS{;4}m
  3023. attribute always returns an integer.
  3024. 1HPlease type a space to go on, or B or Q to go back to the question.                          2616 298B292$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In an array declaration, we can totally omit the range of the subscript (not
  3025. even supplying a box), if the type or subtype of the subscript has a reasonable
  3026. number of possible values.  For example, in
  3027.  
  3028.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  3029.    R : array(RAINBOW_COLOR) of FLOAT;{;4}m
  3030.  
  3031. we have an array of seven FLOATs, because there are seven possible values of
  3032. type RAINBOW_COLOR.  Similarly,
  3033.  
  3034.                         V : array(CHARACTER) of BOOLEAN;{;4}m
  3035.  
  3036. creates an array of 128 BOOLEANs.  However, J : array(INTEGER) of FLOAT;{;4}m is an
  3037. attempt to declare a very large array indeed!  In a case like this, we can use
  3038. a subtype in the subscript declaration:
  3039.  
  3040.                  subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  3041.                  J : array(DAY_SUBTYPE) of FLOAT;{;4}m
  3042.  
  3043. This creates an array of 31 FLOATs.
  3044. 1HPlease type a space to go on, or B to go back.                                                            3459 299B297$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The attributes FIRST{;4}m and LAST{;4}m, which we've seen with discrete types, can also
  3045. be used with array types and with the array names themselves.  For example,
  3046.  
  3047.                  type MY_VECTOR is array(30 .. 33) of INTEGER;
  3048.                  MV : MY_VECTOR;{;4}m
  3049.                  ...
  3050.                  MV(30) := 1000;
  3051.                  MV(31) := 20;
  3052.                  MV(32) := -70;
  3053.                  MV(33) := -500;{;4}m
  3054.  
  3055. Here MV'FIRST{;4}m and MY_VECTOR'FIRST{;4}m are both 30.  MV'LAST{;4}m and MY_VECTOR'LAST{;4}m are
  3056. both 33.  Note that FIRST{;4}m and LAST{;4}m refer to the subscripts, not to the values
  3057. of the array elements.  Thus MV'FIRST{;4}m is not{;4}m 1000.  To obtain the value of the
  3058. first element, we would use MV'FIRST{;4}m as a subscript{;4}m.  MV(MV'FIRST){;4}m is 1000.
  3059.  
  3060. The attribute RANGE{;4}m is an abbreviation for FIRST .. LAST{;4}m.  It can be used only
  3061. with array types and array names, not with discrete types.  Thus MV'RANGE{;4}m and
  3062. MY_VECTOR'RANGE{;4}m both mean 30 .. 33{;4}m.  We can't write INTEGER'RANGE{;4}m, even though
  3063. we can write INTEGER'FIRST{;4}m and INTEGER'LAST{;4}m.  The attribute LENGTH{;4}m is also
  3064. available:  MV'LENGTH{;4}m and MY_VECTOR'LENGTH{;4}m are both 4.
  3065. 1HPlease type a space to go on, or B to go back.                 3012 300B298$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                            MULTIDIMENSIONAL ARRAYS
  3066.  
  3067. Ada arrays may have any number of dimensions, and the subscripts may be of
  3068. different discrete types.  For example, assuming RAINBOW_COLOR, MONTH_TYPE, and
  3069. DATE have already been defined, we can write
  3070.  
  3071.      X : array(INTEGER range -10 .. -1, RAINBOW_COLOR range ORANGE .. BLUE,
  3072.                MONTH_TYPE range FEB .. JUN) of DATE;{;4}m
  3073.  
  3074. Here the first subscript is of type INTEGER and has 10 possible values, the
  3075. second subscript is of type RAINBOW_COLOR and has four possible values, and the
  3076. third subscript has type MONTH_TYPE with five possible values.  Thus we have
  3077. a three-dimensional array of 10 * 4 * 5 = 200 DATEs.  One element of the array
  3078. might be X(-5, GREEN, APR){;4}m; one field of that element might be
  3079. X(-5, GREEN, APR).YEAR{;4}m.  The array in this example probably has no use, other
  3080. than demonstrating that multiple subscripts need not have the same type.
  3081.  
  3082. If one subscript of a multidimensional array type is constrained, they must all
  3083. be constrained.  We can't write
  3084.  
  3085.     type RECTANGLE is array(1 .. 5, INTEGER range <>) of FLOAT;  -- illegal
  3086. 1HPlease type a space to go on, or B to go back.                                                                3221 301B299$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Multidimensional arrays are initialized or assigned with nested aggregates{;4}m.  We
  3087. can create a two-dimensional array of FLOATs, initializing all 50 elements to
  3088. 1.0, with MAT : array(0 .. 9, 1 .. 5) of FLOAT := (others => (others => 1.0));{;4}m.
  3089.  
  3090. Here X is a 10-by-10 array of INTEGERs.  All elements are 0, except X(4, 5),
  3091. which is 1.  We qualify the aggregate because others{;4}m follows named notation:
  3092.  
  3093.       type SQUARE10 is array (1 .. 10, 1 .. 10) of INTEGER;
  3094.       X : SQUARE10 := SQUARE10'(     4     =>   (5 => 1, others => 0),
  3095.                                    others  =>       (others => 0)       );{;4}m
  3096.  
  3097. We initialize or assign an array of arrays{;4}m with nested aggregates, the same as
  3098. a multidimensional array.  However, we access a single element differently:
  3099.  
  3100.   type SQUARE10 is array(1 .. 10, 1 .. 10) of INTEGER;
  3101.   type ROW10    is array(1 .. 10) of INTEGER;
  3102.   type MAT10    is array(1 .. 10) of ROW10;
  3103.   S : SQUARE10 := (others => (others => 0)); -- S is a two-dimensional array.
  3104.   M : MAT10    := (others => (others => 0)); -- M is an array of arrays.{;4}m
  3105.   ...
  3106.   S(4, 5) := 1; -- a single element of a two-dimensional array
  3107.   M(4)(5) := 1; -- a single element of an array of arrays{;4}m
  3108. 1HPlease type a space to go on, or B to go back.                                                       2042 302B300$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The "short circuit" forms can prevent us from using array subscripts that are
  3109. out of range.  For example, if we write
  3110.  
  3111.                     A : array(1 .. 10) of FLOAT;
  3112.                     I : INTEGER;
  3113.                     ...
  3114.                     if I in A'RANGE and then A(I) = 0.0{;4}m then
  3115.                        -----;
  3116.                        -----;  (block of code)
  3117.                        -----;
  3118.                     end if;
  3119.  
  3120. then we know the program won't try to evaluate A(I){;4}m when I is outside the range
  3121. 1 to 10.
  3122. 1HPlease type a space to go on, or B to go back.                                  2118330313042305B301$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QWhich one of these is illegal{;4}m?
  3123.  
  3124.  
  3125.           1.    subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  3126.                 type GROUP is array(DAY_SUBTYPE) of FLOAT;
  3127.                 GR : GROUP;
  3128.                 ...
  3129.                 GR(3) := 0.0;
  3130.  
  3131.  
  3132.           2.    type LIST is array(1 .. 10) of INTEGER;
  3133.                 type PAGE is array(1 .. 20) of LIST;
  3134.                 PG : PAGE;
  3135.                 ...
  3136.                 PG(5)(10) := 0;
  3137.  
  3138.  
  3139.           3.    type ROW is array (INTEGER range <>) of INTEGER;
  3140.                 R1 : ROW;
  3141.                 ...
  3142.                 R1(1) := 0;
  3143. 1HPlease press 1, 2, or 3, or B to go back.                                                          1944 306B302Q302$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$          3.    type ROW is array (INTEGER range <>) of INTEGER;
  3144.                 R1 : ROW;
  3145.                 ...
  3146.                 R1(1) := 0;{;4}m
  3147.  
  3148. You're right!{;4}m  The above is illegal because the range of the subscript must be
  3149. specified, either in the first line, (INTEGER range 1 .. 10){;4}m, or in the
  3150. second, R1 : ROW(1 .. 10);{;4}m, but not both.  This is the unconstrained array{;4}m
  3151. error mentioned earlier.
  3152. 1HPlease type a space to go on, or B or Q to go back to the question.                                1835 306B302Q302$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$          1.    subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  3153.                 type GROUP is array(DAY_SUBTYPE) of FLOAT;
  3154.                 GP : GROUP;
  3155.                 ...
  3156.                 GP(3) := 0.0;
  3157.  
  3158. No, the above is legal.  GP is an array of 31 elements.  The subscript ranges
  3159. from 1 to 31, and each element has type FLOAT.  Therefore, GP(3) has type
  3160. FLOAT, and the assignment is legal.
  3161. 1HPlease type a space to go on, or B or Q to go back to the question.                                         2113 306B302Q302$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$          2.    type LIST is array(1 .. 10) of INTEGER;
  3162.                 type PAGE is array(1 .. 20) of LIST;
  3163.                 PG : PAGE;
  3164.                 ...
  3165.                 PG(5)(10) := 0;
  3166.  
  3167. No, the above is legal.  The elements of an array can be of any type, including
  3168. other arrays.  Here PG has type PAGE, which is an array of LIST.  Therefore
  3169. PG(5) has type LIST (which is an array of INTEGER), and PG(5)(10) has type
  3170. INTEGER.  Thus the assignment is legal.  The notation PG(5)(10) may seem
  3171. strange, but it's correct Ada when we have an array of arrays.
  3172. 1HPlease type a space to go on, or B or Q to go back to the question.                                                               3263 307B302$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    STRINGS
  3173.  
  3174. There's one very important array type declaration built into the Ada language.
  3175. As with types BOOLEAN and CHARACTER, and subtypes POSITIVE and NATURAL, this
  3176. definition comes with Ada and shouldn't be repeated in our programs:
  3177.  
  3178.              type STRING is array(POSITIVE range <>) of CHARACTER;{;4}m
  3179.  
  3180. Thus we can declare, for example, S : STRING(1 .. 5);{;4}m.  We can't simply write
  3181. S : STRING;{;4}m because we can't declare unconstrained arrays.  (We can declare
  3182. S : constant STRING := "Hello";{;4}m).  Note that STRING isn't a special type in
  3183. Ada, it's just an array of CHARACTERs.  Everything we learned about arrays
  3184. applies to STRINGs.  For example, we can assign to S using the same syntax that
  3185. we use when assigning to an array of any other type.  If we write
  3186. S : STRING(1 .. 5);{;4}m we can write:
  3187.  
  3188.                         S := ('H', 'e', 'l', 'l', 'o');{;4}m
  3189.  
  3190. However, this notation is clumsy, so Ada allows us to abbreviate an array of
  3191. CHARACTER constants using the double quote.  Thus S := "Hello";{;4}m is equivalent
  3192. to the statement above.  If a quotation mark appears inside the string, it must
  3193. be doubled.  Thus TEXT_IO.PUT_LINE("a ""big"" man");{;4}m will print a "big" man{;4}m.
  3194. 1HPlease type a space to go on, or B to go back.             3262 308B306$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$It may seem disappointing that Ada STRINGs have fixed length, and that we can't
  3195. declare a variable S : STRING;{;4}m.  Later we'll learn how to define our own type
  3196. TEXT to get around this restriction and simulate variable-length STRINGs.
  3197.  
  3198. When arrays are assigned, the lengths{;4}m must be the same on both sides of the :={;4}m,
  3199. and the types{;4}m must be the same, but the subscripts{;4}m needn't be the same.
  3200. For example, if we have
  3201.  
  3202.                 type VECTOR is array(INTEGER range <>) of FLOAT;
  3203.                 V1 : VECTOR(1 .. 5);
  3204.                 V2 : VECTOR(2 .. 6) := (others => 0.0);
  3205.  
  3206.                 S1 : STRING(1 .. 5);
  3207.                 S2 : STRING(2 .. 6) := (others => ' ');{;4}m
  3208.  
  3209. then we can write V1 := V2;{;4}m and S1 := S2;{;4}m even though the subscripts are
  3210. different, because the array lengths are the same and the element types are the
  3211. same.  But we'll get a CONSTRAINT_ERROR if we write S1 := "Hello there";{;4}m or
  3212. S1 := "Hi";{;4}m or V1 := (1.0, 2.0, 3.0);{;4}m, because these arrays have wrong lengths.
  3213. Ada won't automatically truncate STRINGs or pad with blanks.  Of course, it
  3214. would be easy to write our own procedure to assign STRINGs of different
  3215. lengths, padding or truncating as necessary.
  3216. 1HPlease type a space to go on, or B to go back.              4059 309B307$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A slice{;4}m of an array is a portion of an array, and is indicated with a range{;4}m in
  3217. the subscript.  A slice is itself an array.  Some languages use the term
  3218. "substring" to refer to a slice of a STRING, but in Ada we can take a slice of
  3219. any{;4}m kind of array, not just an array of CHARACTERs.  So instead of "substring,"
  3220. we use the more general term "slice."  For example, if we have
  3221.  
  3222.        A : array(1 .. 10) of INTEGER := (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);{;4}m
  3223.  
  3224. then A(1 .. 3){;4}m is the array (1, 2, 3){;4}m and A(6 .. 9){;4}m is the array (6, 7, 8, 9){;4}m.
  3225. Similarly, if we have S : STRING(1 .. 11) := "Hello there";{;4}m then S(8 .. 11){;4}m is
  3226. "here"{;4}m and S(4 .. 5){;4}m is "lo"{;4}m.  We can also write S(1 .. 10) := S(2 .. 11);{;4}m and
  3227. A(1 .. 3) := A(4 .. 6);{;4}m since the lengths are the same on both sides.
  3228.  
  3229. If the value preceding ..{;4}m is greater than the value following it, we have a
  3230. null range{;4}m.  A slice with a null range has a length of zero, and is called a
  3231. null slice{;4}m.  In the case of a null slice, the subscript is not{;4}m checked for
  3232. CONSTRAINT_ERROR.  Thus, even if N is 0 we could write S(1 .. N);{;4}m which would
  3233. produce the null string ""{;4}m.  This is legal, even though Ada defines
  3234. "type STRING is array(POSITIVE{;4}m range <>) of CHARACTER;".  Assigning a null
  3235. slice to a null slice does no harm and generates no error; it does nothing.
  3236. Also, if S{;4}m is a null array, then S'LENGTH{;4}m is 0, and S'FIRST{;4}m and S'LAST{;4}m don't
  3237. exist.  Using FIRST{;4}m or LAST{;4}m with a null array will raise a CONSTRAINT_ERROR.
  3238. 1HPlease type a space to go on, or B to go back.                 2657 310B308$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Beginners sometimes confuse a CHARACTER{;4}m with a STRING of length 1{;4}m.  If we
  3239. write
  3240.  
  3241.                               S : STRING(1 .. 10);
  3242.                               I : INTEGER := 5;{;4}m
  3243.  
  3244. then S(I){;4}m is a CHARACTER and S(I .. I){;4}m is a STRING of length 1.  Also, 'X'{;4}m is a
  3245. CHARACTER while "X"{;4}m is a STRING of length 1.  Thus we could write
  3246.  
  3247.                                S(I) := 'X';
  3248.                                S(I .. I) := "X";{;4}m
  3249.  
  3250. but we'd be mixing types if we were to write S(I) := "X";{;4}m or S(I .. I) := 'X';{;4}m.
  3251.  
  3252. Fortunately, TEXT_IO has a PUT for type CHARACTER as well as a PUT for type
  3253. STRING.  (It also has a GET for each of these types.)  Thus we can write either
  3254. PUT(S(I .. I));{;4}m or PUT(S(I));{;4}m.  However, PUT_LINE and GET_LINE exist only for
  3255. STRINGs, not for CHARACTERs.
  3256. 1HPlease type a space to go on, or B to go back.                   18314311131223133314531563167317B309$$$$$$$$$$$$$$$$$$$$$$$$$$$Q    1.  HELLO  : STRING := "Hello there";
  3257.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3258.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3259.     4.  HELLO  : STRING(2 .. 6) := "Hello";
  3260.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3261.     6.  PROMPT : STRING(1 .. 3) := ">";
  3262.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3263.  
  3264.  
  3265. Which one{;4}m of the above is legal?
  3266. 1HPlease press 1, 2, 3, 4, 5, 6, or 7, or B to go back.                                             2873 318B310Q310$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  HELLO  : STRING := "Hello there";
  3267.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3268.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3269.     4.  HELLO  : STRING(2 .. 6) := "Hello";{;4}m
  3270.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3271.     6.  PROMPT : STRING(1 .. 3) := ">";
  3272.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3273.  
  3274.  
  3275. You're right!{;4}m  Number 4 creates HELLO, a STRING of length 5, and initializes it
  3276. to "Hello", a STRING of the same length.  The subscript of HELLO need not start
  3277. at 1, so long as the length is 5.
  3278.  
  3279. Number 1 attempts to create an unconstrained array.  Number 2 has a zero
  3280. subscript, while Ada defines type STRING for POSITIVE subscripts.  Number 3
  3281. should have '*'{;4}m instead of "*"{;4}m.  Number 5 tries to set each of the first three
  3282. elements, which are CHARACTERs, to a STRING.  Number 6 tries to store a STRING
  3283. of length 1 into a STRING of length 3, and number 7 should have "{;4}mHello"{;4}m
  3284. instead of '{;4}mHello'{;4}m.
  3285. 1HPlease type a space to go on, or B or Q to go back to the question.   2444 318B310Q310$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  HELLO  : STRING := "Hello there";
  3286.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3287.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3288.     4.  HELLO  : STRING(2 .. 6) := "Hello";
  3289.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3290.     6.  PROMPT : STRING(1 .. 3) := ">";
  3291.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3292.  
  3293.  
  3294. No, number 1 is illegal because it tries to create an unconstrained array.  The
  3295. fact that "Hello there"{;4}m has a definite length doesn't make the statement legal.
  3296. We must constrain the STRING to a length of 11 by writing, for example,
  3297. HELLO  : STRING(1 .. 11) := "Hello there";{;4}m.  However, it is{;4}m legal to write
  3298.  
  3299.                    HELLO : constant{;4}m STRING := "Hello there";
  3300. 1HPlease type a space to go on, or B or Q to go back to the question.                                2060 318B310Q310$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  HELLO  : STRING := "Hello there";
  3301.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3302.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3303.     4.  HELLO  : STRING(2 .. 6) := "Hello";
  3304.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3305.     6.  PROMPT : STRING(1 .. 3) := ">";
  3306.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3307.  
  3308.  
  3309. No, number 2 is illegal because of the zero subscript.  Ada defines "type
  3310. STRING is array(POSITIVE{;4}m range <>) of CHARACTER;".  Therefore, the subscripts
  3311. must be 1 or greater.
  3312. 1HPlease type a space to go on, or B or Q to go back to the question.                2052 318B310Q310$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  HELLO  : STRING := "Hello there";
  3313.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3314.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3315.     4.  HELLO  : STRING(2 .. 6) := "Hello";
  3316.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3317.     6.  PROMPT : STRING(1 .. 3) := ">";
  3318.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3319.  
  3320.  
  3321. No, number 3 is illegal because "*"{;4}m should be '*'{;4}m.  As it stands, it tries to
  3322. assign a STRING of length 1 to each of the elements, which are CHARACTERs.
  3323. 1HPlease type a space to go on, or B or Q to go back to the question.                        2450 318B310Q310$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  HELLO  : STRING := "Hello there";
  3324.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3325.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3326.     4.  HELLO  : STRING(2 .. 6) := "Hello";
  3327.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3328.     6.  PROMPT : STRING(1 .. 3) := ">";
  3329.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3330.  
  3331.  
  3332. No, number 5 is illegal because it tries to initialize each of the first three
  3333. elements, which are CHARACTERs, to a STRING of length 3.  We could, however,
  3334. have written simply HELLO : STRING(1 .. 5);{;4}m, and then written the following in
  3335. the executable region:
  3336.  
  3337.                             HELLO(1 .. 3) := "Hel";
  3338.                             HELLO(4) := 'l';
  3339.                             HELLO(5) := 'o';{;4}m
  3340. 1HPlease type a space to go on, or B or Q to go back to the question.                          1932 318B310Q310$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  HELLO  : STRING := "Hello there";
  3341.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3342.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3343.     4.  HELLO  : STRING(2 .. 6) := "Hello";
  3344.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3345.     6.  PROMPT : STRING(1 .. 3) := ">";
  3346.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3347.  
  3348.  
  3349. No, number 6 is illegal because it tries to assign a STRING of length 1 to a
  3350. STRING of length 3.
  3351. 1HPlease type a space to go on, or B or Q to go back to the question.                                            2240 318B310Q310$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  HELLO  : STRING := "Hello there";
  3352.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3353.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3354.     4.  HELLO  : STRING(2 .. 6) := "Hello";
  3355.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3356.     6.  PROMPT : STRING(1 .. 3) := ">";
  3357.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3358.  
  3359.  
  3360. No, number 7 is illegal because it should say "{;4}mHello"{;4}m instead of '{;4}mHello'{;4}m.  Ada
  3361. "tic" marks ('{;4}m) always enclose a single CHARACTER, while double quotes ("{;4}m)
  3362. always enclose an array of CHARACTERs, that is, a STRING.
  3363. 1HPlease type a space to go on, or B or Q to go back to the question.                                    2566 319B310$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                ARRAY OPERATORS
  3364.  
  3365. The operator &{;4}m concatenates any two arrays of the same type, including two
  3366. STRINGs.  It can also concatenate a single element with an array of that
  3367. element type, or two single elements into an array of length two.  For example,
  3368. every use of &{;4}m below is legal:
  3369.  
  3370.            C, D : CHARACTER := '*';
  3371.            S2   : STRING(1 .. 2);
  3372.            S3   : STRING(1 .. 3) := (others => ' ');
  3373.            S5   : STRING(1 .. 5);
  3374.  
  3375.            type VECTOR is array(INTEGER range <>) of FLOAT;
  3376.            F, G : FLOAT := 1.2;
  3377.            V2   : VECTOR(1 .. 2);
  3378.            V3   : VECTOR(1 .. 3) := (others => 0.0);
  3379.            V5   : VECTOR(1 .. 5);
  3380.            ...
  3381.            S2 := C & D;  S5 := S2 & S3;  S3 := C & S2;  S3 := S2 & C;
  3382.            V2 := F & G;  V5 := V2 & V3;  V3 := F & V2;  V3 := V2 & F;{;4}m
  3383. 1HPlease type a space to go on, or B to go back.          3355 320B318$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The operators and{;4}m, or{;4}m, xor{;4}m, and not{;4}m, defined for BOOLEANs, are also defined for
  3384. one-dimensional arrays of BOOLEAN.  They operate element by element on the
  3385. arrays.  Thus, we can simulate sets{;4}m in Ada.  For example, if we write
  3386.  
  3387.     type SET_OF_CHARS is array(CHARACTER) of BOOLEAN;
  3388.     S1 : SET_OF_CHARS := SET_OF_CHARS'('*' | '#' => TRUE, others => FALSE);
  3389.     S2 : SET_OF_CHARS := SET_OF_CHARS'('*' | '?' => TRUE, others => FALSE);{;4}m
  3390.  
  3391. then S1 or S2{;4}m is SET_OF_CHARS'('*' | '#' | '?' => TRUE, others => FALSE){;4}m,
  3392. and S1 and S2{;4}m is SET_OF_CHARS'('*' => TRUE, others => FALSE){;4}m.
  3393.  
  3394. The operators ={;4}m and /={;4}m can compare two records or two arrays of the same type.
  3395. Records are equal if each of their corresponding fields are equal, arrays, if
  3396. each of their corresponding elements are equal.  Arrays of different lengths
  3397. are always unequal.  The four remaining relational operators can compare two
  3398. arrays of the same type.  They're compared element by element until a
  3399. difference is found.  For example, if we have
  3400.  
  3401.                         S : STRING(1 .. 6) := "to all";
  3402.                         T : STRING(1 .. 7) := "to Bill";{;4}m
  3403.  
  3404. then S > T{;4}m because 'a' > 'B' in Ada's definition of type CHARACTER.
  3405. 1HPlease type a space to go on, or B to go back.                     2727 321B319$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A                   OUTSIDE ASSIGNMENT 3 - EXERCISE IN RECORDS
  3406.  
  3407. Your third Outside Assignment is to write a function specified by
  3408.  
  3409.      type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  3410.      subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  3411.      type DATE is
  3412.         record
  3413.            DAY   : DAY_SUBTYPE;
  3414.            MONTH : MONTH_TYPE;
  3415.            YEAR  : INTEGER;
  3416.         end record;
  3417.      function TOMORROW(TODAY : in DATE) return DATE;{;4}m
  3418.  
  3419. Given any date, TOMORROW should return the following date.  Your function will
  3420. be tested only with legal dates.  As with Outside Assignment 2, a test driver
  3421. is already written; it's in NEXTDATE.ADA{;4}m.  A listing is on page 10 of your
  3422. printed course notes, but you needn't understand the test driver.  If your
  3423. function fails any test, you'll see the test case, the answer from your
  3424. function, and the right answer.  Otherwise, you'll see "Congratulations, you
  3425. completed the assignment!"
  3426. 1HPlease type a space to go on, or B to go back.                                                 3135 322B320$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The definitions of MONTH_TYPE, DAY_SUBTYPE, and DATE are in the test driver;
  3427. you shouldn't define them inside your function.  A dummy solution is in
  3428. TOMORROW.DUM{;4}m; it looks like this:
  3429.  
  3430.                -- Dummy solution to Outside Assignment 3
  3431.                separate (NEXTDATE)
  3432.                function TOMORROW(TODAY : in DATE) return DATE is
  3433.                begin{;4}m
  3434.                   return TODAY;
  3435.                end TOMORROW;{;4}m
  3436.  
  3437. Again, you'll probably want to remove or change the comment line, and you
  3438. shouldn't change the lines highlighted{;4}m above.  You may, but don't have to,
  3439. include ANSWER : DATE;{;4}m in the declarative region and make return ANSWER;{;4}m the
  3440. last statement before end TOMORROW;{;4}m.
  3441.  
  3442. Normally, years divisible by 4 are leap years.  But if a year is divisible by
  3443. 100, it must also be divisible by 400 to be a leap year.  Thus, 2000 is a leap
  3444. year, but 1900 and 2100 are not.  Note that TODAY.YEAR{;4}m is divisible by 4 if and
  3445. only if TODAY.YEAR mod 4 = 0{;4}m.  You can assume that TODAY.YEAR{;4}m will always be
  3446. between 1583 and 3999, because outside this range the calendar gets more
  3447. complicated.
  3448. 1HPlease type a space to go on, or B to go back.                                         2519 323B321$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The steps to follow for Outside Assignment 3 are very similar to those of
  3449. Outside Assignment 2.  They're in your printed course notes on page 11:
  3450.  
  3451. 1.  Compile the test driver NEXTDATE.ADA.  Also, make a copy of the dummy
  3452.     solution by typing COPY TOMORROW.DUM TOMORROW.ADA{;4}m.  You need do this step
  3453.     only once.
  3454.  
  3455. 2.  Edit TOMORROW.ADA to become your real solution.  You can skip this step the
  3456.     first time through, to see error messages from the test driver.
  3457.  
  3458. 3.  Compile TOMORROW.ADA.  If there are compiler errors, go back to step 2.
  3459.  
  3460. 4.  Link with the name of the main program NEXTDATE.  Then execute.  If the
  3461.     test driver prints error messages, go back to step 2.
  3462.  
  3463. 5.  When the message "Congratulations, you completed the assignment!" is
  3464.     printed, you'll have a chance to compare your solution with ours.
  3465. 1HPlease type a space to go on, or B to go back.                                                         3161 324B322$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$There are many ways to solve this problem.  In our solution we declared an
  3466. array of DAY_SUBTYPE with subscripts of type MONTH_TYPE.  Some students use a
  3467. case{;4}m construct on TODAY.MONTH; some use an if{;4}m block with elsif{;4}ms.
  3468.  
  3469. This assignment should be a simple exercise in records.  Our solution fits on
  3470. one screen.  If your solution starts to get long and difficult, you should
  3471. think the problem through again.  Don't try to save the computer a few
  3472. microseconds; computers are supposed to save people time.  Instead, minimize
  3473. the complexity{;4}m of the program to save yourself programming effort.
  3474.  
  3475. Remember that an entire record can be assigned in one statement.  Also, try to
  3476. calculate the number of days in the month and then{;4}m test for end of month and
  3477. end of year in only one place.  This is better than having several blocks of
  3478. code testing for end of month and end of year in three or four different places
  3479. in your program.  One last hint: remember that MONTH_TYPE'SUCC(TODAY.MONTH)
  3480. will raise a CONSTRAINT_ERROR if TODAY.MONTH is DEC.
  3481.  
  3482. Please type X to exit ADA-TUTR{;4}m temporarily, and try Outside Assignment 3.  Work
  3483. at your own pace; there's no deadline.  Good luck!
  3484. 1HPlease type X to exit, a space to go on, or B to go back.               2652 325B323$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              Congratulations on Completing Outside Assignment 3!{;4}m
  3485.  
  3486. -- Our solution to Outside Assignment 3 (in TOMORROW.ANS):
  3487. separate (NEXTDATE)
  3488. function TOMORROW(TODAY : in DATE) return DATE is
  3489.    LENGTH : array(MONTH_TYPE) of DAY_SUBTYPE :=
  3490.                (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  3491.    ANSWER : DATE;
  3492. begin
  3493.    if TODAY.YEAR mod 4 = 0 and
  3494.         (TODAY.YEAR mod 100 /= 0 or TODAY.YEAR mod 400 = 0) then
  3495.       LENGTH(FEB) := 29;
  3496.    end if;
  3497.    if TODAY.DAY /= LENGTH(TODAY.MONTH) then                -- Not end of month.
  3498.       ANSWER := (TODAY.DAY + 1, TODAY.MONTH, TODAY.YEAR);
  3499.    elsif TODAY.MONTH /= DEC then          -- End of month, but not end of year.
  3500.       ANSWER := (1, MONTH_TYPE'SUCC(TODAY.MONTH), TODAY.YEAR);
  3501.    else                                                         -- End of year.
  3502.       ANSWER := (1, JAN, TODAY.YEAR + 1);
  3503.    end if;
  3504.    return ANSWER;
  3505. end TOMORROW;
  3506. 1HPlease type a space to go on, or B to go back.                        2916 326B324$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In our solution, the first if{;4}m statement checks for leap year.  We made use of
  3507. the fact that the locally declared array LENGTH{;4}m is re-initialized every time
  3508. the function is called.  After this if{;4}m statement, the number of days in the
  3509. month is in LENGTH(TODAY.MONTH){;4}m, and it's easy to test for end of month and end
  3510. of year - in only one place in the program.
  3511.  
  3512. We could have written MONTH_TYPE'LAST{;4}m instead of DEC{;4}m, and MONTH_TYPE'FIRST{;4}m
  3513. instead of JAN{;4}m.  We could even have used DAY_SUBTYPE'FIRST{;4}m.  But the author
  3514. reasoned that if our calendar ever changes, the entire program will probably
  3515. have to be rewritten anyway!  The program seems a little easier to read when we
  3516. use the names DEC{;4}m and JAN{;4}m and the number 1{;4}m directly.
  3517.  
  3518. Your solution might be entirely different from ours.  If the test driver said
  3519. "Congratulations, you completed the assignment!" you can consider your solution
  3520. correct.  Let's go on to discuss recursion.
  3521. 1HPlease type a space to go on, or B to go back.                                                            2136 327B325$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  3522.  
  3523.    Introduction                             Records, Arrays, and Assignment 3
  3524.  
  3525.    The Format of an Ada Program          >  RECURSION AND ASSIGNMENT 4{;4}m
  3526.  
  3527.    Generic Instantiation and                Subprograms and Packages
  3528.       Assignment 1
  3529.                                             Additional Types, Exceptions,
  3530.    Simple Declarations and Simple              TEXT_IO, and Assignment 5
  3531.       Attributes
  3532.                                             Generics, Tasking, and Assignment 6
  3533.    Operators, Control Constructs, and
  3534.       Assignment 2                          Advanced Topics
  3535. 1HPlease type a space to go on, or B to go back.                                        2866 328B326$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                   RECURSION
  3536.  
  3537. Ada procedures and functions may call themselves, directly or indirectly.  This
  3538. process is called recursion{;4}m.  While recursion often uses a little extra memory
  3539. and execution time, for certain types of problems it pays large dividends in
  3540. program simplicity.  That's a very worthwhile exchange!
  3541.  
  3542. For example, let's write a function to compute the factorial of a positive
  3543. integer.  The factorial of an integer is the product of all the integers from
  3544. that number down to one.  Thus, FACTORIAL(5) = 5 * 4 * 3 * 2 * 1 = 120.
  3545. Although we could easily write this function with a for{;4}m loop, we'll use
  3546. recursion instead.  Note that if N = 1, then FACTORIAL(N) = 1; otherwise,
  3547. FACTORIAL(N) = N * FACTORIAL(N - 1).
  3548.  
  3549.              function FACTORIAL(N : in POSITIVE) return POSITIVE is
  3550.                 ANSWER : POSITIVE := 1;
  3551.              begin
  3552.                 if N > 1 then
  3553.                    ANSWER := N * FACTORIAL(N - 1);
  3554.                 end if;
  3555.                 return ANSWER;
  3556.              end FACTORIAL;
  3557. 1HPlease type a space to go on, or B to go back.          3069 329B327$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             function FACTORIAL(N : in POSITIVE) return POSITIVE is
  3558.                 ANSWER : POSITIVE := 1;
  3559.              begin
  3560.                 if N > 1 then
  3561.                    ANSWER := N * FACTORIAL(N - 1);{;4}m
  3562.                 end if;
  3563.                 return ANSWER;
  3564.              end FACTORIAL;
  3565.  
  3566. The highlighted line shows where this function calls itself.  Recursive
  3567. subprograms always call themselves conditionally{;4}m; otherwise the program would
  3568. run out of memory, no matter how large the machine.  Here the recursive call is
  3569. inside an if{;4}m block.
  3570.  
  3571. Note that ANSWER is initialized to 1.  If the function is called with N = 1,
  3572. the if{;4}m statement is FALSE, ANSWER isn't modified, and 1{;4}m is returned as the
  3573. value of the function.  If the function is called with N = 2, the if{;4}m statement
  3574. is TRUE, and the highlighted line is executed.  The machine starts to compute
  3575. the expression as 2 * ..., and then FACTORIAL is called with N = 1.  It's as if
  3576. the machine made another copy of the code for FACTORIAL and called that.
  3577. Actually there's only one copy of the code, but the machine maintains multiple
  3578. pointers{;4}m to it.
  3579. 1HPlease type a space to go on, or B to go back.       2916 330B328$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             function FACTORIAL(N : in POSITIVE) return POSITIVE is
  3580.                 ANSWER : POSITIVE := 1;
  3581.              begin
  3582.                 if N > 1 then
  3583.                    ANSWER := N * FACTORIAL(N - 1);{;4}m
  3584.                 end if;
  3585.                 return ANSWER;
  3586.              end FACTORIAL;
  3587.  
  3588. When the recursive call is made, the system allocates additional memory for new
  3589. versions of any local variables like ANSWER.  Also, the arguments like N are
  3590. separate for each recursive call.
  3591.  
  3592. Suppose the main program calls FACTORIAL with N = 2.  Then, in computing the
  3593. expression, FACTORIAL calls itself with N = 1.  In this second call, a new
  3594. local variable ANSWER is created, separate from the one in the first call.
  3595. Also, argument N is 1 in the second call, but 2 in the first call.  In the
  3596. second call, the if{;4}m statement is FALSE, and 1 is returned.  In the first call,
  3597. the calculation of the expression is completed, using the value 1 returned by
  3598. the second call.  Thus, ANSWER becomes 2 * 1 = 2, and the first call returns
  3599. the answer 2 to the main program.
  3600. 1HPlease type a space to go on, or B to go back.                                                            3026 331B329$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             function FACTORIAL(N : in POSITIVE) return POSITIVE is
  3601.                 ANSWER : POSITIVE := 1;
  3602.              begin
  3603.                 if N > 1 then
  3604.                    ANSWER := N * FACTORIAL(N - 1);{;4}m
  3605.                 end if;
  3606.                 return ANSWER;
  3607.              end FACTORIAL;
  3608.  
  3609. If the main program calls FACTORIAL with N = 3, the function starts to compute
  3610. the expression as ANSWER := 3 * ..., and calls FACTORIAL with N = 2.  In this
  3611. second call, the function starts to compute ANSWER := 2 * ..., and calls
  3612. FACTORIAL with N = 1.  In this third call, the if{;4}m statement is FALSE, and the
  3613. answer 1 is returned to the second call.  The second call finishes the
  3614. computation of the expression ANSWER := 2 * 1, and returns the answer 2 to the
  3615. first call.  Finally, the first call finishes computing the expression with
  3616. ANSWER := 3 * 2, and returns the answer 6 to the main program.
  3617.  
  3618. This simple function wouldn't have been complicated even without recursion.  In
  3619. a moment we'll discuss the Tower of Hanoi problem.  The recursive solution is
  3620. very simple, but a solution without recursion would be very complicated indeed.
  3621. 1HPlease type a space to go on, or B to go back.                                                  24502332033313333333B330$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QIn this question, function A calls B, and B conditionally calls A.  The
  3622. specification of function B is given early so that A can call it.
  3623.  
  3624.                  function B (I : in INTEGER) return INTEGER;
  3625.  
  3626.                  function A (I : in INTEGER) return INTEGER is
  3627.                  begin
  3628.                     return B(I - 1) + 1;
  3629.                  end A;
  3630.  
  3631.                  function B (I : in INTEGER) return INTEGER is
  3632.                     ANS : INTEGER := 0;
  3633.                  begin
  3634.                     if I > 0 then
  3635.                        ANS := A(I);
  3636.                     end if;
  3637.                     return ANS;
  3638.                  end B;
  3639.  
  3640. If the main program calls function A with an argument equal to 2, what value
  3641. will A return:  0, 1, 2, or 3?  You may need pencil and paper to figure this
  3642. one out.
  3643. 1HPlease press 0, 1, 2, or 3, or B to go back.                          2649 334B331Q331$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 function B (I : in INTEGER) return INTEGER;
  3644.  
  3645.                  function A (I : in INTEGER) return INTEGER is
  3646.                  begin
  3647.                     return B(I - 1) + 1;
  3648.                  end A;
  3649.  
  3650.                  function B (I : in INTEGER) return INTEGER is
  3651.                     ANS : INTEGER := 0;
  3652.                  begin
  3653.                     if I > 0 then
  3654.                        ANS := A(I);
  3655.                     end if;
  3656.                     return ANS;
  3657.                  end B;
  3658.  
  3659. You're right!{;4}m  When the main program calls A(2), A starts to evaluate
  3660. B(1) + 1.  The if{;4}m statement in B is TRUE, so B simply calls A(1).  The call
  3661. A(1) starts to evaluate B(0) + 1.  The if{;4}m statement in this call to B is FALSE,
  3662. so B(0) simply returns 0, and the call A(1) returns 0 + 1 = 1.  The call B(1)
  3663. returns the same answer, so the call A(2) returns 1 + 1 = 2.
  3664. 1HPlease type a space to go on, or B or Q to go back to the question.                           2624 334B331Q331$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 function B (I : in INTEGER) return INTEGER;
  3665.  
  3666.                  function A (I : in INTEGER) return INTEGER is
  3667.                  begin
  3668.                     return B(I - 1) + 1;
  3669.                  end A;
  3670.  
  3671.                  function B (I : in INTEGER) return INTEGER is
  3672.                     ANS : INTEGER := 0;
  3673.                  begin
  3674.                     if I > 0 then
  3675.                        ANS := A(I);
  3676.                     end if;
  3677.                     return ANS;
  3678.                  end B;
  3679.  
  3680. No, when the main program calls A(2), A starts to evaluate B(1) + 1.  The if{;4}m
  3681. statement in B is TRUE, so B simply calls A(1).  The call A(1) starts to
  3682. evaluate B(0) + 1.  The if{;4}m statement in this call to B is FALSE, so B(0) simply
  3683. returns 0, and the call A(1) returns 0 + 1 = 1.  The call B(1) returns the same
  3684. answer, so the call A(2) returns 1 + 1 = 2.
  3685. 1HPlease type a space to go on, or B or Q to go back to the question.                                                    3026 335B331$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                           THE TOWER OF HANOI PROBLEM
  3686.  
  3687. The "Tower of Hanoi" is a solitaire puzzle that was named when Hanoi was the
  3688. capital of a free country: French Indochina.  There are three pegs labeled A,
  3689. B, and C; one of them has a tower of N doughnut-shaped disks of decreasing
  3690. size, like this:
  3691.  
  3692.                |                       |                       |
  3693.                |                       |                       |
  3694.               =|=                      |                       |
  3695.              ==|==                     |                       |
  3696.             ===|===                    |                       |
  3697.            ====|====                   |                       |
  3698.           =====|=====                  |                       |
  3699.        -----------------       -----------------       -----------------
  3700.                A                       B                       C
  3701.  
  3702. The object is to move the entire tower from one peg to another, say, from A to
  3703. B.  Only one disk may be moved at a time, and a larger disk may never be placed
  3704. on top of a smaller one.  The shortest solution to the puzzle with N disks
  3705. requires 2**N - 1 moves.
  3706. 1HPlease type a space to go on, or B to go back.                                                  3160 336B334$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$For example, we can move five disks from A to B with the following 31 moves:
  3707. (Read them from left to right, not in columns.)
  3708.  
  3709. A to B,  A to C,  B to C,  A to B,  C to A,  C to B,  A to B,  A to C,  B to C,
  3710. B to A,  C to A,  B to C,  A to B,  A to C,  B to C,  A to B,  C to A,  C to B,
  3711. A to B,  C to A,  B to C,  B to A,  C to A,  C to B,  A to B,  A to C,  B to C,
  3712. A to B,  C to A,  C to B,  A to B.
  3713.  
  3714.                |                       |                       |
  3715.                |                       |                       |
  3716.                |                       |                       |
  3717.                |                       |                       |
  3718.               =|=                      |                       |
  3719.            ====|====                   |                       |
  3720.           =====|=====               ===|===                  ==|==
  3721.        -----------------       -----------------       -----------------
  3722.                A                       B                       C
  3723.                     (The Puzzle After the First Five Moves)
  3724.  
  3725. Writing a program to print this series of moves would be very complicated
  3726. without recursion.  Let's develop a recursive solution; we'll see that the
  3727. resulting Ada program is surprisingly simple!
  3728. 1HPlease type a space to go on, or B to go back.                3245 337B335$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$When we developed a recursive solution for the FACTORIAL function:
  3729.  
  3730.                  if N = 1,  FACTORIAL(N) = 1
  3731.                  otherwise, FACTORIAL(N) = N * FACTORIAL(N - 1)
  3732.  
  3733. we expressed FACTORIAL(N) in terms of FACTORIAL(N - 1), and gave the trivial
  3734. solution for N = 1.  The Ada program was easily written from the above.
  3735.  
  3736. For the Tower of Hanoi problem, let's develop a solution for N disks in terms
  3737. of a solution for N - 1 disks.  Suppose we want to move five disks from A to B,
  3738. using C as a spare peg.  We first move four{;4}m disks from A to C{;4}m, then move one
  3739. disk from A to B, and finally move four disks from C to B.  In general, to move
  3740. N disks from a source peg to a destination peg, we first move N - 1 disks from
  3741. the source to the spare, then move one disk from the source to the destination,
  3742. and finally move N - 1 disks from the spare to the destination.
  3743.  
  3744. To move the one{;4}m disk from the source to the destination, our program will
  3745. simply print out the move.  To move N - 1 disks, the program will call itself.
  3746. The solution for zero disks is trivial indeed: the program will do nothing!
  3747.  
  3748. The following program is extremely simple: three executable statements inside
  3749. an if{;4}m block.  Yet it can print out a very complicated series of moves!
  3750. 1HPlease type a space to go on, or B to go back.                               2862 338B336$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       with TEXT_IO; use TEXT_IO;
  3751.        procedure HANOI(N : in NATURAL; FROM, TO, SPARE : in CHARACTER) is
  3752.        begin
  3753.           if N > 0 then
  3754.              HANOI(N - 1, FROM, SPARE, TO);
  3755.              PUT_LINE(FROM & " to " & TO);
  3756.              HANOI(N - 1, SPARE, TO, FROM);
  3757.           end if;
  3758.        end HANOI;{;4}m
  3759.  
  3760. To move five disks from A to B, using C as a spare, we would call
  3761. HANOI(5, 'A', 'B', 'C');{;4}m.
  3762.  
  3763. Note that when HANOI is called with N = 0, it does nothing.  When called with
  3764. N = 1, the if{;4}m statement is true, and the three lines within the if{;4}m block are
  3765. executed.  But the first and third lines do nothing, because they call HANOI
  3766. with N = 0.  The second line prints, for example, A to B{;4}m.
  3767.  
  3768. When called with a larger value of N, the first line within the if{;4}m block moves
  3769. N - 1 disks from the source to the spare peg.  The second line prints the move
  3770. of one disk from the source to the destination, and the third line moves N - 1
  3771. disks from the spare peg to the destination.
  3772. 1HPlease type a space to go on, or B to go back.              2663 339B337$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Most implementations of Ada won't allow HANOI to be a main program, because it
  3773. has arguments.  A short main program to call HANOI is shown here.  A slightly
  3774. longer program could get N and the names of the three pegs from the user.
  3775.  
  3776.                           with HANOI;
  3777.                           procedure DEMO is
  3778.                           begin
  3779.                              HANOI(5, 'A', 'B', 'C');
  3780.                           end DEMO;{;4}m
  3781.  
  3782. In summary, our first example of recursion, FACTORIAL, was very simple.
  3783. However, that program would have been simple even without recursion.  Our
  3784. second example, HANOI, also was very simple, but the program would have been
  3785. quite complicated without recursion.
  3786.  
  3787. Our fourth Outside Assignment will be to write a Fibonacci function FIB, using
  3788. recursion.  As with FACTORIAL, this function would be easy to write even
  3789. without recursion.  However, as an exercise we'll write it using recursion.
  3790. 1HPlease type a space to go on, or B to go back.             2918 340B338$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A                  OUTSIDE ASSIGNMENT 4 - EXERCISE IN RECURSION
  3791.  
  3792. Your fourth Outside Assignment is to write, using recursion, a function
  3793. specified by
  3794.  
  3795.                  function FIB(N : in POSITIVE) return POSITIVE;{;4}m
  3796.  
  3797. Fibonacci was a mathematician in the Middle Ages.  The so-called Fibonacci
  3798. Series{;4}m is a series of integers.  Each number in the series is the sum of the
  3799. two previous numbers.  The first two Fibonacci numbers are both 1.
  3800.  
  3801.      N:    1  2  3  4  5  6   7   8   9  10  11   12   13   14   15   16 ...
  3802.    FIB(N): 1  1  2  3  5  8  13  21  34  55  89  144  233  377  610  987 ...
  3803.  
  3804. Note that if N = 1 or N = 2, then FIB(N) = 1; otherwise,
  3805. FIB(N) = FIB(N - 1) + FIB(N - 2).  Writing this function in Ada will be an easy
  3806. and short assignment.  A test driver is provided in FIBTEST.ADA{;4}m; a listing is
  3807. on page 12 of your printed course notes.  As before, if all tests are passed,
  3808. it prints "Congratulations, you completed the assignment!"  If there's an
  3809. error, it prints the test case, the answer from your function, and the right
  3810. answer.
  3811. 1HPlease type a space to go on, or B to go back.                                                          2041 341B339$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A dummy solution is in FIB.DUM{;4}m.  As before, you shouldn't change the lines
  3812. highlighted{;4}m here:
  3813.  
  3814.                 -- Dummy solution to Outside Assignment 4
  3815.                 separate (FIBTEST)
  3816.                 function FIB(N : in POSITIVE) return POSITIVE is
  3817.                 begin{;4}m
  3818.                    return 4;
  3819.                 end FIB;{;4}m
  3820.  
  3821.  
  3822. The steps to follow for Outside Assignment 4 are similar to those of the last
  3823. two Outside Assignments.  They're in your printed course notes on page 13:
  3824. 1HPlease type a space to go on, or B to go back.                                   2468 342B340$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$1.  Compile the test driver FIBTEST.ADA.  Also, make a copy of the dummy
  3825.     solution by typing COPY FIB.DUM FIB.ADA{;4}m.  You need do this step only once.
  3826.  
  3827. 2.  Edit FIB.ADA to become your real solution.  You can skip this step the
  3828.     first time through, to see error messages from the test driver.
  3829.  
  3830. 3.  Compile FIB.ADA.  If there are compiler errors, go back to step 2.
  3831.  
  3832. 4.  Link with the name of the main program FIBTEST.  Then execute.  If the test
  3833.     driver prints error messages, go back to step 2.
  3834.  
  3835. 5.  When the message "Congratulations, you completed the assignment!" is
  3836.     printed, you'll have a chance to compare your solution with ours.
  3837.  
  3838.  
  3839. Please type X to exit ADA-TUTR{;4}m temporarily, and try Outside Assignment 4.  Work
  3840. at your own pace; there's no deadline.  Good luck!
  3841. 1HPlease type X to exit, a space to go on, or B to go back.        2832 343B341$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              Congratulations on Completing Outside Assignment 4!{;4}m
  3842.  
  3843.              -- Our solution to Outside Assignment 4 (in FIB.ANS):
  3844.              separate (FIBTEST)
  3845.              function FIB(N : in POSITIVE) return POSITIVE is
  3846.                 ANSWER : POSITIVE := 1;
  3847.              begin
  3848.                 if N > 2 then
  3849.                    ANSWER := FIB(N - 1) + FIB(N - 2);
  3850.                 end if;
  3851.                 return ANSWER;
  3852.              end FIB;
  3853.  
  3854. Your solution is probably quite similar to ours.  Perhaps you used else{;4}m and
  3855. didn't initialize ANSWER in the declarative region.  Perhaps you had some other
  3856. minor variation.  Our solution is probably no "better" than yours, if the test
  3857. driver said, "Congratulations, you completed the assignment!"
  3858.  
  3859. Was this assignment too{;4}m easy?  We promise that Outside Assignment 5 will be
  3860. much more challenging!  But first we need to discuss procedures and functions
  3861. in more detail, as well as packages and information hiding, access types, and
  3862. exceptions.
  3863. 1HPlease type a space to go on, or B to go back.                                            2136 344B342$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  3864.  
  3865.    Introduction                             Records, Arrays, and Assignment 3
  3866.  
  3867.    The Format of an Ada Program             Recursion and Assignment 4
  3868.  
  3869.    Generic Instantiation and             >  SUBPROGRAMS AND PACKAGES{;4}m
  3870.       Assignment 1
  3871.                                             Additional Types, Exceptions,
  3872.    Simple Declarations and Simple              TEXT_IO, and Assignment 5
  3873.       Attributes
  3874.                                             Generics, Tasking, and Assignment 6
  3875.    Operators, Control Constructs, and
  3876.       Assignment 2                          Advanced Topics
  3877. 1HPlease type a space to go on, or B to go back.                                        2655 345B343$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                            PROCEDURES AND FUNCTIONS
  3878.  
  3879. When we compiled procedures HELLO and ADD into the library, we made it possible
  3880. for other units to with{;4}m them and call them.  (We don't use{;4}m procedures and
  3881. functions, because dot notation doesn't apply to them.)  We can also compile
  3882. just a specification{;4}m, supplying the body later.  For example, we could compile
  3883.  
  3884.          function UPPER_CASE(S : in STRING) return STRING;{;4}m
  3885.  
  3886. When we later write the body, it must agree with that specification:
  3887.  
  3888.          function UPPER_CASE(S : in STRING) return STRING is{;4}m
  3889.             ANSWER : STRING(S'RANGE) := S;
  3890.          begin
  3891.             for I in S'RANGE loop
  3892.                if S(I) in 'a' .. 'z' then
  3893.                   ANSWER(I) := CHARACTER'VAL(CHARACTER'POS(S(I)) - 32);
  3894.                end if;
  3895.             end loop;
  3896.             return ANSWER;
  3897.          end UPPER_CASE;
  3898. 1HPlease type a space to go on, or B to go back.                     2648 346B344$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Functions and procedures may also be declared locally, in which case they must
  3899. follow any simple declarations like I : INTEGER;{;4}m or S : STRING(1 .. 5);{;4}m.
  3900.  
  3901.        with TEXT_IO; use TEXT_IO;
  3902.        procedure GREETING is
  3903.           S : STRING(1 .. 5) := "Hello";
  3904.           function UPPER_CASE(S : in STRING) return STRING is
  3905.              ANSWER : STRING(S'RANGE) := S;
  3906.           begin
  3907.              for I in S'RANGE loop
  3908.                 if S(I) in 'a' .. 'z' then
  3909.                    ANSWER(I) := CHARACTER'VAL(CHARACTER'POS(S(I)) - 32);
  3910.                 end if;
  3911.              end loop;
  3912.             return ANSWER;
  3913.           end UPPER_CASE;{;4}m
  3914.        begin
  3915.           PUT_LINE(UPPER_CASE(S));
  3916.        end GREETING;
  3917.  
  3918. As we've seen, we can declare local functions and procedures to be separate{;4}m.
  3919. These subprograms can in turn declare separate{;4}m subprograms, to any depth:
  3920. 1HPlease type a space to go on, or B to go back.                            2337 347B345$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                  procedure MAIN is
  3921.                      function A return FLOAT is separate;
  3922.                   begin
  3923.                      ...
  3924.                   end MAIN;
  3925.  
  3926.                   separate (MAIN){;4}m
  3927.                   function A return FLOAT is
  3928.                      procedure B is separate;
  3929.                   begin
  3930.                      ...
  3931.                   end A;
  3932.  
  3933.                   separate (MAIN.A){;4}m
  3934.                   procedure B is
  3935.                      procedure C(I : in INTEGER) is separate;
  3936.                   begin
  3937.                      ...
  3938.                   end B;
  3939.  
  3940.                   separate (MAIN.A.B){;4}m
  3941.                   procedure C(I : in INTEGER) is ... (etc.)
  3942. 1HPlease type a space to go on, or B to go back.                                       2828 348B346$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$However, is separate{;4}m may be used only at the outermost level.  The example
  3943. below is legal as it stands, but we may not make procedure B separate unless we
  3944. make function A separate, thus bringing function A to the outermost level:
  3945.  
  3946.                          procedure MAIN is
  3947.                             F : FLOAT;
  3948.                             function A return FLOAT is
  3949.                                ANSWER : FLOAT;
  3950.                                procedure B is
  3951.                                begin
  3952.                                   ...
  3953.                                end B;
  3954.                             begin
  3955.                                ...
  3956.                                return ANSWER;
  3957.                             end A;
  3958.                          begin
  3959.                             ...
  3960.                          end MAIN;
  3961.  
  3962. A program that begins separate ({;4}m...){;4}m must be compiled after the program that
  3963. says is separate{;4}m, because a separate subprogram depends on its "parent."
  3964. 1HPlease type a space to go on, or B to go back.                                                2971 349B347$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A procedure or function specification gives the name, mode, and type of each
  3965. argument.  A function specification also gives the type of the result.  The
  3966. mode can be in{;4}m, out{;4}m, or in out{;4}m.  If the mode is omitted, it's assumed to be in{;4}m.
  3967. Thus, these two lines have the same effect:
  3968.  
  3969.         procedure HANOI(N : in NATURAL; FROM, TO, SPARE : in CHARACTER);
  3970.         procedure HANOI(N : NATURAL;    FROM, TO, SPARE : CHARACTER);{;4}m
  3971.  
  3972. The arguments of a function{;4}m must always be of mode in{;4}m, never out{;4}m or in out{;4}m.
  3973.  
  3974. Note that when several arguments have the same mode and type, they can be
  3975. placed in one list, separated by commas.  The lists themselves are separated by
  3976. semicolons.  This specification has the same effect as the two above:
  3977.  
  3978. procedure HANOI(N : NATURAL; FROM: CHARACTER; TO: CHARACTER; SPARE: CHARACTER);{;4}m
  3979.  
  3980. In any event, the arguments in a call{;4}m to a procedure or function are always
  3981. separated by commas{;4}m:
  3982.  
  3983.                             HANOI(5, 'A', 'B', 'C');{;4}m
  3984. 1HPlease type a space to go on, or B to go back.     16614350135123523353B348$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q   1.  procedure P(A; B; C : in INTEGER);
  3985.  
  3986.    2.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  3987.  
  3988.    3.  function  F(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  3989.  
  3990.    4.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT);
  3991.  
  3992.  
  3993. Which one of the above is legal{;4}m?
  3994. 1HPlease press 1, 2, 3, or 4, or B to go back.               2367 354B349Q349$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   1.  procedure P(A; B; C : in INTEGER);
  3995.  
  3996.    2.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  3997.  
  3998.    3.  function  F(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  3999.  
  4000.    4.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT);{;4}m
  4001.  
  4002. You're right!{;4}m  In a subprogram specification, the items of a list are separated
  4003. by commas, and the lists are separated by semicolons.  In a list, the mode may
  4004. be omitted; it's assumed to be in{;4}m.
  4005.  
  4006. In number 1, the items should be separated by commas.  Number 2 has a return{;4}m
  4007. clause in a procedure{;4}m specification, and number 3 has a mode other than in{;4}m in a
  4008. function{;4}m specification.
  4009. 1HPlease type a space to go on, or B or Q to go back to the question.         2117 354B349Q349$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   1.  procedure P(A; B; C : in INTEGER);
  4010.  
  4011.    2.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  4012.  
  4013.    3.  function  F(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  4014.  
  4015.    4.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT);
  4016.  
  4017. No, in number 1 the items should be separated by commas, not semicolons.  In a
  4018. subprogram specification, the items in a list are separated by commas, and the
  4019. lists are separated by semicolons.  Here a "list" means a collection of
  4020. arguments sharing the same mode and type (in INTEGER{;4}m).
  4021. 1HPlease type a space to go on, or B or Q to go back to the question.                                                           1843 354B349Q349$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   1.  procedure P(A; B; C : in INTEGER);
  4022.  
  4023.    2.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  4024.  
  4025.    3.  function  F(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  4026.  
  4027.    4.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT);
  4028.  
  4029. No, number 2 is illegal because a return{;4}m clause applies only to a function
  4030. specification, not a procedure specification.
  4031. 1HPlease type a space to go on, or B or Q to go back to the question.                                 1764 354B349Q349$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   1.  procedure P(A; B; C : in INTEGER);
  4032.  
  4033.    2.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  4034.  
  4035.    3.  function  F(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  4036.  
  4037.    4.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT);
  4038.  
  4039. No, number 3 is illegal because all arguments of a function must have mode in{;4}m.
  4040. 1HPlease type a space to go on, or B or Q to go back to the question.            2215 355B349$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Recall that type conversion from FLOAT to INTEGER in Ada rounds to the nearest
  4041. integer.  The Ada standard doesn't specify which way rounding occurs when the
  4042. fractional part is exactly 0.5.  This function FLOOR computes the largest
  4043. integer less than or equal to a given FLOAT, always rounding toward negative
  4044. infinity:
  4045.  
  4046.                  function FLOOR(X : in FLOAT) return INTEGER is
  4047.                     ANSWER : INTEGER := INTEGER(X);
  4048.                  begin
  4049.                     if FLOAT(ANSWER) > X then
  4050.                        ANSWER := ANSWER - 1;
  4051.                     end if;
  4052.                     return ANSWER;
  4053.                  end FLOOR;
  4054. 1HPlease type a space to go on, or B to go back.                                                             2031 356B354$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Similarly, this function TRUNCATE converts from FLOAT to INTEGER, always
  4055. truncating toward zero:
  4056.  
  4057.                function TRUNCATE(X : in FLOAT) return INTEGER is
  4058.                   ANSWER : INTEGER := INTEGER(X);
  4059.                begin
  4060.                   if ANSWER > 0 and FLOAT(ANSWER) > X then
  4061.                      ANSWER := ANSWER - 1;
  4062.                   elsif ANSWER < 0 and FLOAT(ANSWER) < X then
  4063.                      ANSWER := ANSWER + 1;
  4064.                   end if;
  4065.                   return ANSWER;
  4066.                end TRUNCATE;
  4067. 1HPlease type a space to go on, or B to go back.                                             3146 357B355$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                               DEFAULT PARAMETERS
  4068.  
  4069. The in{;4}m parameters of a subprogram specification may be given default values.
  4070. Suppose, for example, that the package INTEGER_IO is instantiated for the type
  4071. INTEGER.  Here's a simplified version of the specification for the procedure
  4072. PUT (the actual specification can be found in section 14.3.10 of the LRM):
  4073.  
  4074.                     procedure PUT(ITEM  : in INTEGER;
  4075.                                   WIDTH : in INTEGER := 6;
  4076.                                   BASE  : in INTEGER := 10);{;4}m
  4077.  
  4078. This means that, in calls to PUT, the WIDTH and BASE arguments are optional.
  4079. If WIDTH is omitted, it's assumed to be 6, and if BASE is omitted, it's assumed
  4080. to be 10.  If either of these arguments is given in the call, the default value
  4081. is overridden.  (The default value for WIDTH is shown here as 6.  Actually, it
  4082. depends on the implementation of Ada.  Of course, the default value for BASE is
  4083. always 10.)
  4084.  
  4085. Default parameters let us make our Ada subprograms both flexible{;4}m and easy to{;4}m
  4086. use{;4}m.  In other languages, we'd often have to choose between these two
  4087. qualities.  For example, suppose J is an integer.  Here are some calls to PUT:
  4088. 1HPlease type a space to go on, or B to go back.                              3135 358B356$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    procedure PUT(ITEM  : in INTEGER;
  4089.                                   WIDTH : in INTEGER := 11;
  4090.                                   BASE  : in INTEGER := 10);
  4091.  
  4092.                     PUT(J);
  4093.                     PUT(J, WIDTH => 4);
  4094.                     PUT(J, BASE => 16);
  4095.                     PUT(J, BASE => 16, WIDTH => 4);{;4}m
  4096.  
  4097. The first argument in each call could have been given as ITEM => J{;4}m, but
  4098. everyone remembers that the first argument of PUT is the item, so named
  4099. notation seems unnecessary for this argument.  However, WIDTH and BASE are used
  4100. less frequently.  We used named notation for these arguments so the reader of
  4101. our code wouldn't have to remember which argument comes second and which comes
  4102. third.  Note that if we omit the second argument and specify the third, we must{;4}m
  4103. use named notation for the third argument; we're not allowed to write
  4104. PUT(J, ,16); as in some languages.
  4105.  
  4106. If we were writing PUT in another language, we'd have to choose either making
  4107. the user specify the width and the base in every call, giving flexibility, or
  4108. writing PUT with only one argument, giving ease of use.  In Ada, default
  4109. parameters give us both flexibility and ease of use!
  4110. 1HPlease type a space to go on, or B to go back.                                         2651 359B357$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$TEXT_IO.NEW_LINE has one parameter, SPACING, defaulted to 1.  Thus, we can call
  4111. NEW_LINE;{;4}m to get one CR-LF, or, for example, NEW_LINE(3);{;4}m to get three.
  4112.  
  4113. Default values may also be given in record definitions.  If we write
  4114.  
  4115.      type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  4116.      subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  4117.      type DATE is
  4118.         record
  4119.            DAY   : DAY_SUBTYPE;
  4120.            MONTH : MONTH_TYPE;
  4121.            YEAR  : INTEGER := 1776{;4}m;
  4122.         end record;
  4123.      USA : DATE;
  4124.  
  4125. then USA.YEAR{;4}m is set to 1776 when the line declaring USA{;4}m is elaborated.  Every
  4126. time an object of type DATE is declared, its YEAR field is set to 1776.
  4127. However, there's a difference between default values in records and default
  4128. parameters in subprograms.  We can't write USA := (4, JUL); all three fields of
  4129. the record must be specified.
  4130. 1HPlease type a space to go on, or B to go back.                         1751236013613362B358$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q                    procedure PUT(ITEM  : in INTEGER;
  4131.                                   WIDTH : in INTEGER := 11;
  4132.                                   BASE  : in INTEGER := 10);
  4133.  
  4134. Which one of these is legal{;4}m?
  4135.  
  4136.                           1.  PUT(ITEM => 23, 5, 10);
  4137.  
  4138.                           2.  PUT(23, 5);
  4139.  
  4140.                           3.  PUT(23; 5; 10);
  4141. 1HPlease press 1, 2, or 3, or B to go back.                         2113 363B359Q359$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    procedure PUT(ITEM  : in INTEGER;
  4142.                                   WIDTH : in INTEGER := 11;
  4143.                                   BASE  : in INTEGER := 10);
  4144.  
  4145.  
  4146.                           1.  PUT(ITEM => 23, 5, 10);
  4147.  
  4148.                           2.  PUT(23, 5);{;4}m
  4149.  
  4150.                           3.  PUT(23; 5; 10);
  4151.  
  4152.  
  4153. You're right!{;4}m  The third argument may be omitted because it has a default
  4154. value.  In number 1, positional notation follows named, which isn't allowed,
  4155. and in number 3, the separators should be commas.
  4156. 1HPlease type a space to go on, or B or Q to go back to the question.                                                               1848 363B359Q359$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    procedure PUT(ITEM  : in INTEGER;
  4157.                                   WIDTH : in INTEGER := 11;
  4158.                                   BASE  : in INTEGER := 10);
  4159.  
  4160.  
  4161.                           1.  PUT(ITEM => 23, 5, 10);
  4162.  
  4163.                           2.  PUT(23, 5);
  4164.  
  4165.                           3.  PUT(23; 5; 10);
  4166.  
  4167.  
  4168. No, number 1 is illegal because positional notation may not follow named.
  4169. 1HPlease type a space to go on, or B or Q to go back to the question.                            1918 363B359Q359$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    procedure PUT(ITEM  : in INTEGER;
  4170.                                   WIDTH : in INTEGER := 11;
  4171.                                   BASE  : in INTEGER := 10);
  4172.  
  4173.  
  4174.                           1.  PUT(ITEM => 23, 5, 10);
  4175.  
  4176.                           2.  PUT(23, 5);
  4177.  
  4178.                           3.  PUT(23; 5; 10);
  4179.  
  4180.  
  4181. No, number 3 is illegal because in a call, the arguments are always separated
  4182. with commas, not semicolons.
  4183. 1HPlease type a space to go on, or B or Q to go back to the question.                                                          2962 364B359$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    PACKAGES
  4184.  
  4185. A package{;4}m lets us group related declarations, procedures, and functions.  A
  4186. program can with{;4}m the package and gain access to all of these.  However, as
  4187. we'll see, packages have many other advantages.  Usually library units are
  4188. packages rather than individual procedures and functions.
  4189.  
  4190. By way of example, consider a very simple procedure and a very simple function:
  4191.  
  4192.           procedure DOUBLE(NUMBER : in INTEGER; ANSWER : out INTEGER);
  4193.           function TWICE(NUMBER : in INTEGER) return INTEGER;{;4}m
  4194.  
  4195. We could compile these individually, or we could put them in a package{;4}m and
  4196. compile that instead.  Here's the package specification{;4}m:
  4197.  
  4198.         package SIMPLE_MATH is{;4}m
  4199.            procedure DOUBLE(NUMBER : in INTEGER; ANSWER : out INTEGER);{;4}m
  4200.            function TWICE(NUMBER : in INTEGER) return INTEGER;{;4}m
  4201.         end SIMPLE_MATH;{;4}m
  4202.  
  4203. The package body{;4}m must contain the bodies of all the procedures and functions
  4204. declared in the package specification:
  4205. 1HPlease type a space to go on, or B to go back.              2628 365B363$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       package body SIMPLE_MATH is{;4}m
  4206.           procedure DOUBLE(NUMBER : in INTEGER; ANSWER : out INTEGER) is{;4}m
  4207.           begin
  4208.              ANSWER := NUMBER * 2;
  4209.           end DOUBLE;
  4210.  
  4211.           function TWICE(NUMBER : in INTEGER) return INTEGER is{;4}m
  4212.           begin
  4213.              return NUMBER * 2;
  4214.           end TWICE;
  4215.        end SIMPLE_MATH;{;4}m
  4216.  
  4217. The package body could optionally declare either or both subprograms to be
  4218. separate{;4}m:
  4219.  
  4220.   package body SIMPLE_MATH is{;4}m
  4221.      procedure DOUBLE(NUMBER : in INTEGER; ANSWER : out INTEGER) is separate;{;4}m
  4222.      function TWICE(NUMBER : in INTEGER) return INTEGER is separate;{;4}m
  4223.   end SIMPLE_MATH;{;4}m
  4224.  
  4225. Here's an example of a calling program that with{;4}ms the package and makes use of
  4226. the two subprograms declared in the package specification:
  4227. 1HPlease type a space to go on, or B to go back.                                                3134 366B364$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     with SIMPLE_MATH; use SIMPLE_MATH;{;4}m
  4228.      procedure PACKAGE_DEMO is
  4229.         I, J : INTEGER := 10;
  4230.      begin
  4231.         DOUBLE{;4}m(NUMBER => I, ANSWER => J);  -- This line sets J to 20.
  4232.         J := TWICE{;4}m(I);                     -- This line also sets J to 20.
  4233.      end PACKAGE_DEMO;
  4234.  
  4235. The package specification must be compiled first, but either the calling
  4236. program or the package body may be compiled second.  The calling program
  4237. depends only on the package specification{;4}m, not the package body{;4}m.  Similarly,
  4238. the package body depends on the package specification.  If the package body
  4239. declares any subprograms to be separate{;4}m, these must be compiled after the
  4240. package body, because any separate{;4}m subprogram depends on its "parent."
  4241.  
  4242. A package specification that declares no subprograms (only objects, types,
  4243. etc.) doesn't need a package body.
  4244.  
  4245. The main program can never be inside a package.  It must be a procedure or
  4246. function compiled directly into the library, such as HELLO or ADD.  In most
  4247. implementations of Ada, that procedure or function can't have any arguments.
  4248. Usually the main program is a procedure rather than a function.
  4249. 1HPlease type a space to go on, or B to go back.                                          2611 367B365$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A package body may optionally have initialization code, introduced by the word
  4250. begin{;4}m.  This code is executed only once, the first time another program
  4251. elaborates the package by with{;4}ming it.  For example, this package uses
  4252. initialization code to initialize the array B:
  4253.  
  4254.                package P is
  4255.                   function F return FLOAT;
  4256.                end P;
  4257.  
  4258.                package body P is
  4259.                   A : array(1 .. 10) of FLOAT := (others => 0.0);
  4260.                   B : array(1 .. 10, 1 .. 10) of INTEGER;
  4261.                   function F return FLOAT is
  4262.                      ...
  4263.                   end F;
  4264.                begin
  4265.                   for I in 1 .. 10 loop
  4266.                      for J in 1 .. 10 loop
  4267.                         B(I, J) := I*J*J;
  4268.                      end loop;
  4269.                   end loop;{;4}m
  4270.                end P;
  4271. 1HPlease type a space to go on, or B to go back.                                                                 3142 368B366$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Declarations made inside a package specification{;4}m are said to be exported{;4}m and
  4272. are available to programs outside the package that with{;4}m the package.  However,
  4273. declarations made inside the package body{;4}m are available only inside the
  4274. package.  The package body doesn't even have to be written before outside
  4275. programs that with{;4}m the package.  In this example, programs outside and inside
  4276. the package may use type ANSWER, array A, and procedure R, but only procedures
  4277. P, Q and R may use type QUESTION and array B.  Procedure P may be called only
  4278. by Q and R (and itself), and procedure Q is available only to R (and itself).
  4279.  
  4280.                       package X is
  4281.                          type ANSWER is (YES, NO, MAYBE);
  4282.                          A : array(1 .. 10) of FLOAT;
  4283.                          procedure R;
  4284.                       end X;
  4285.  
  4286.                       package body X is
  4287.                          type QUESTION is (WHY, WHO, HOW);
  4288.                          B : array(1 .. 10) of INTEGER;
  4289.                          procedure P is separate;
  4290.                          procedure Q is separate;
  4291.                          procedure R is separate;
  4292.                       end X;
  4293. 1HPlease type a space to go on, or B to go back.                                  2157T369F370B367$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q                      package X is
  4294.                          type ANSWER is (YES, NO, MAYBE);
  4295.                          A : array(1 .. 10) of FLOAT;
  4296.                          procedure R;
  4297.                       end X;
  4298.  
  4299.                       package body X is
  4300.                          type QUESTION is (WHY, WHO, HOW);
  4301.                          B : array(1 .. 10) of INTEGER;
  4302.                          procedure P is separate;
  4303.                          procedure Q is separate;
  4304.                          procedure R is separate;
  4305.                       end X;
  4306.  
  4307. True or False?  In this example, procedure P may call R.
  4308. 1HPlease press T for true or F for false, or B to go back.                   2358 371B368Q368$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      package X is
  4309.                          type ANSWER is (YES, NO, MAYBE);
  4310.                          A : array(1 .. 10) of FLOAT;
  4311.                          procedure R;
  4312.                       end X;
  4313.  
  4314.                       package body X is
  4315.                          type QUESTION is (WHY, WHO, HOW);
  4316.                          B : array(1 .. 10) of INTEGER;
  4317.                          procedure P is separate;
  4318.                          procedure Q is separate;
  4319.                          procedure R is separate;
  4320.                       end X;
  4321.  
  4322. You're right!{;4}m  R is declared in the package specification, so any program
  4323. inside X (and any program outside X that with{;4}ms the package) may call R.
  4324. 1HPlease type a space to go on, or B or Q to go back to the question.                  2336 371B368Q368$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      package X is
  4325.                          type ANSWER is (YES, NO, MAYBE);
  4326.                          A : array(1 .. 10) of FLOAT;
  4327.                          procedure R;
  4328.                       end X;
  4329.  
  4330.                       package body X is
  4331.                          type QUESTION is (WHY, WHO, HOW);
  4332.                          B : array(1 .. 10) of INTEGER;
  4333.                          procedure P is separate;
  4334.                          procedure Q is separate;
  4335.                          procedure R is separate;
  4336.                       end X;
  4337.  
  4338. True.  R is declared in the package specification, so any program inside X (and
  4339. any program outside X that with{;4}ms the package) may call R.
  4340. 1HPlease type a space to go on, or B or Q to go back to the question.                                        3043 372B368$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                         FUNCTIONS WITH INFIX NOTATION
  4341.  
  4342.                   +   -   *   /   **   &   =   <   >   <=   >=
  4343.  
  4344.                      and   or   xor   abs   not   mod   rem{;4}m
  4345.  
  4346. Ada allows us to overload any of the above operators by enclosing the operator
  4347. in quotes following the word function{;4}m.  For example, having defined type DATE,
  4348. we may want to define what it means for one date to be "less than" another.  We
  4349. could write function "<"(LEFT, RIGHT : in DATE) return BOOLEAN;{;4}m.  Then, our
  4350. program could declare D1, D2 : DATE;{;4}m and test if D1 < D2 then{;4}m ...  This test
  4351. would call our function "<", because <{;4}m is used between two objects of type
  4352. DATE.  Similarly, we can overload "*" to give the dot product of two vectors:
  4353.  
  4354.               type VECTOR is array(INTEGER range <>) of FLOAT;
  4355.               V1, V2 : VECTOR(1 .. 100);
  4356.               X : FLOAT;
  4357.               function "*"(LEFT, RIGHT : in VECTOR) return FLOAT is{;4}m
  4358.                  ...
  4359.               end "*";{;4}m
  4360.               ...
  4361.               X := V1 * V2;  -- This calls our function "*".{;4}m
  4362. 1HPlease type a space to go on, or B to go back.                                 3165 373B371$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                  +   -   *   /   **   &   =   <   >   <=   >=
  4363.  
  4364.                      and   or   xor   abs   not   mod   rem{;4}m
  4365.  
  4366. There are some restrictions when using infix notation.  First, all of the
  4367. operators above (except abs{;4}m, not{;4}m, +{;4}m, and -{;4}m) must be used between two arguments,
  4368. and thus the function specification must have exactly two arguments.
  4369. Traditionally, the two arguments are called LEFT and RIGHT.  The operators abs{;4}m
  4370. and not{;4}m must have one argument on the right, and +{;4}m and -{;4}m may have one or two
  4371. arguments.  This restriction comes from the way the compiler handles operators.
  4372. For example, the compiler can handle X := - X;{;4}m, but it's not designed to handle
  4373. X := * X;{;4}m.
  4374.  
  4375. Second, the function "=" must return type BOOLEAN, its two arguments must be of
  4376. the same type, and that type must be a limited private type, to be discussed
  4377. later.  For all the types discussed so far, function "=" is already defined{;4}m by
  4378. Ada.  Two records are equal if each of their corresponding fields is equal, and
  4379. two arrays are equal if they have the same length and each of their
  4380. corresponding elements is equal.
  4381. 1HPlease type a space to go on, or B to go back.           2567 374B372$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                  +   -   *   /   **   &   =   <   >   <=   >=
  4382.  
  4383.                      and   or   xor   abs   not   mod   rem{;4}m
  4384.  
  4385. Note that we can't redefine function "/=".  However, if we redefine "=" for
  4386. some limited private type, we can use /={;4}m.  Ada will call our function "=" and
  4387. negate the result.  For example,
  4388.  
  4389.           type TEXT is limited private;  -- to be discussed later
  4390.           T1, T2 : TEXT;
  4391.           function "="(LEFT, RIGHT : in TEXT) return BOOLEAN is{;4}m
  4392.              ...
  4393.           end "=";{;4}m
  4394.           ...
  4395.           if T1 /= T2{;4}m then  -- Calls our "=" and reverses the result.{;4}m
  4396.              ...
  4397.           end if;
  4398.  
  4399. Also, we can't redefine in{;4}m, not in{;4}m, and then{;4}m, or else{;4}m, or :={;4}m.  Technically,
  4400. these aren't operators.
  4401. 1HPlease type a space to go on, or B to go back.         3049 375B373$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Finally, functions using infix notation can't be compiled directly into the
  4402. library.  They must either be declared locally inside a procedure or function,
  4403. or placed inside a package.  This is done because many implementations of Ada
  4404. create files with names based on the function, procedure, or package being
  4405. compiled.  Since many of the operators are punctuation marks, they would create
  4406. file names that are incompatible with most systems.
  4407.  
  4408. For the same reason, two functions or procedures with the same name can't be
  4409. compiled directly into the library; on many systems that would attempt to give
  4410. the same name to several files.  For example, the package specification below
  4411. is legal.  However, the package body can't declare both DISPLAYs separate{;4}m, and
  4412. it can't declare either "*" separate{;4}m.
  4413.  
  4414.            package P is
  4415.               type COMPLEX is ...
  4416.               type VECTOR is ...
  4417.               procedure DISPLAY(C : in COMPLEX);
  4418.               procedure DISPLAY(V : in VECTOR);
  4419.               function  "*"(LEFT, RIGHT : in COMPLEX) return COMPLEX;
  4420.               function  "*"(LEFT, RIGHT : in VECTOR)  return FLOAT;{;4}m
  4421.            end P;
  4422. 1HPlease type a space to go on, or B to go back.                           23602376037713773378437853786378B374$$$$$$$$$$$$$$$$$$$$$$$$$$$Q           package K is
  4423.               type COMPLEX is
  4424.                  record
  4425.                     RE, IM : FLOAT;
  4426.                  end record;
  4427.               type VECTOR is array(INTEGER range <>) of FLOAT;
  4428.               function  "+"(LEFT, RIGHT : in COMPLEX) return COMPLEX;
  4429.               function  "*"(LEFT, RIGHT : in COMPLEX) return COMPLEX;
  4430.               function  "*"(LEFT, RIGHT : in VECTOR)  return FLOAT;
  4431.               function  CONJUGATE(C : in COMPLEX) return COMPLEX;
  4432.               procedure DISPLAY(C : in COMPLEX);
  4433.               procedure DISPLAY(V : in VECTOR);
  4434.            end K;
  4435.  
  4436. The above is a package specification.  In the package body, how many
  4437. subprograms could be made separate{;4}m:  0, 1, 2, 3, 4, 5, or 6?
  4438. 1HPlease press 0, 1, 2, 3, 4, 5, or 6, or B to go back.                2745 379B375Q375$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       package body{;4}m K is
  4439.           function  "+"(LEFT, RIGHT : in COMPLEX) return COMPLEX is ...
  4440.           function  "*"(LEFT, RIGHT : in COMPLEX) return COMPLEX is ...
  4441.           function  "*"(LEFT, RIGHT : in VECTOR)  return FLOAT is ...
  4442.           function  CONJUGATE(C : in COMPLEX) return COMPLEX is separate;{;4}m
  4443.           procedure DISPLAY(C : in COMPLEX) is ...
  4444.           procedure DISPLAY(V : in VECTOR) is separate;{;4}m
  4445.        end K;
  4446.  
  4447.        separate (K)
  4448.        function CONJUGATE(C : in COMPLEX) return COMPLEX is{;4}m
  4449.        ...
  4450.        end CONJUGATE;{;4}m
  4451.  
  4452.        separate (K)
  4453.        procedure DISPLAY(V : in VECTOR) is{;4}m
  4454.        ...
  4455.        end DISPLAY;{;4}m
  4456.  
  4457. You're right!{;4}m  Only function CONJUGATE and at most one DISPLAY can be made
  4458. separate{;4}m.  Functions using infix notation can't be made separate{;4}m, and the name
  4459. DISPLAY is overloaded.
  4460. 1HPlease type a space to go on, or B or Q to go back to the question.                               2516 379B375Q375$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$           package K is
  4461.               type COMPLEX is
  4462.                  record
  4463.                     RE, IM : FLOAT;
  4464.                  end record;
  4465.               type VECTOR is array(INTEGER range <>) of FLOAT;
  4466.               function  "+"(LEFT, RIGHT : in COMPLEX) return COMPLEX;
  4467.               function  "*"(LEFT, RIGHT : in COMPLEX) return COMPLEX;
  4468.               function  "*"(LEFT, RIGHT : in VECTOR)  return FLOAT;
  4469.               function  CONJUGATE(C : in COMPLEX) return COMPLEX;
  4470.               procedure DISPLAY(C : in COMPLEX);
  4471.               procedure DISPLAY(V : in VECTOR);
  4472.            end K;
  4473.  
  4474. No, the function CONJUGATE can be made separate{;4}m, because its name isn't
  4475. overloaded and it doesn't use infix notation.  Also, one, but not both, DISPLAY
  4476. procedures can be made separate.{;4}m
  4477. 1HPlease type a space to go on, or B or Q to go back to the question.                                                            2460 379B375Q375$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$           package K is
  4478.               type COMPLEX is
  4479.                  record
  4480.                     RE, IM : FLOAT;
  4481.                  end record;
  4482.               type VECTOR is array(INTEGER range <>) of FLOAT;
  4483.               function  "+"(LEFT, RIGHT : in COMPLEX) return COMPLEX;
  4484.               function  "*"(LEFT, RIGHT : in COMPLEX) return COMPLEX;
  4485.               function  "*"(LEFT, RIGHT : in VECTOR)  return FLOAT;
  4486.               function  CONJUGATE(C : in COMPLEX) return COMPLEX;
  4487.               procedure DISPLAY(C : in COMPLEX);
  4488.               procedure DISPLAY(V : in VECTOR);
  4489.            end K;
  4490.  
  4491. No, only function CONJUGATE and at most one DISPLAY can be made separate{;4}m.
  4492. Functions using infix notation can't be made separate{;4}m, and the name DISPLAY is
  4493. overloaded.
  4494. 1HPlease type a space to go on, or B or Q to go back to the question.                2349 380B375$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                       INFORMATION HIDING: PRIVATE TYPES
  4495.  
  4496. Information hiding has nothing to do with secrecy; it means containing certain
  4497. programming details to a package so that the parts of the program outside the
  4498. package can't depend on them.  Thus, when these details change, other parts of
  4499. the program aren't affected.
  4500.  
  4501. Let's write the specification (only) for a graphics CRT controller package
  4502. without information hiding.  Then we'll improve on it by using a private type.
  4503.  
  4504. The package will let us create arrays in memory representing screens.  We can
  4505. create as many of these "virtual screens" as we like, and draw dots, lines, and
  4506. boxes on them in memory.  We can also display any virtual screen.  Here's the
  4507. package specification:
  4508. 1HPlease type a space to go on, or B to go back.                           2955 381B379$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$package CRT_CONTROLLER is
  4509.    type COLOR_TYPE  is (WHITE, BLACK, RED, YELLOW, GREEN, BLUE);
  4510.    type SCREEN_TYPE is array(0 .. 299, 0 .. 399) of COLOR_TYPE;
  4511.    procedure DISPLAY (SCREEN : in SCREEN_TYPE);
  4512.    procedure CLEAR   (SCREEN : in out SCREEN_TYPE; TO: in COLOR_TYPE := BLACK);
  4513.    type POINT is
  4514.       record
  4515.          ROW    : INTEGER range 0 .. 299;
  4516.          COLUMN : INTEGER range 0 .. 399;
  4517.       end record;
  4518.    procedure DOT     (SCREEN : in out SCREEN_TYPE; PLACE : in POINT;
  4519.                       COLOR : in COLOR_TYPE);
  4520.    procedure LINE    (SCREEN : in out SCREEN_TYPE; FROM, TO : in POINT;
  4521.                       COLOR : in COLOR_TYPE);
  4522.    procedure BOX     (SCREEN : in out SCREEN_TYPE; CORNER1, CORNER2 : in POINT;
  4523.                       COLOR : in COLOR_TYPE);
  4524. end CRT_CONTROLLER;{;4}m
  4525.  
  4526. Note that this package assumes that the resolution of the CRT is 300 vertically
  4527. by 400 horizontally.  A screen is represented in memory by a two-dimensional
  4528. array, each element of which contains one of six possible colors.  Procedures
  4529. to draw other figures (circles, etc.) could have been added to the package.
  4530. 1HPlease type a space to go on, or B to go back.                     2831 382B380$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$That package specification makes the calling program very clear!  For example,
  4531.  
  4532.     with CRT_CONTROLLER; use CRT_CONTROLLER;
  4533.     procedure CRT_DEMO is
  4534.        S1, S2 : SCREEN_TYPE;
  4535.     begin
  4536.        CLEAR(S1);
  4537.        CLEAR(S2, TO => WHITE);
  4538.        LINE(S1, FROM => (150, 100), TO => (150, 300), COLOR => GREEN);
  4539.        DOT(S1, PLACE => (150, 200), COLOR => RED);
  4540.        DISPLAY(S1);
  4541.        BOX(S2, CORNER1 => (240, 100), CORNER2 => (60, 300), COLOR => BLUE);
  4542.        DOT(S2, PLACE => (150, 200), COLOR => YELLOW);
  4543.        DISPLAY(S2);
  4544.     end CRT_DEMO;{;4}m
  4545.  
  4546. The first executable line clears memory for screen S1 to all black, because of
  4547. the default parameter in the specification of CLEAR.  The next line clears S2
  4548. to all white.  The next three lines draw a line and a dot on S1 and display S1.
  4549. The program then draws a box and a dot on S2 and displays S2.  Named notation
  4550. could optionally have been used for the first argument of each call, and for
  4551. the objects of type POINT, e.g., (ROW => 150, COLUMN => 100){;4}m.
  4552. 1HPlease type a space to go on, or B to go back.                                             1854138323843384B381$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QAt a sacrifice in clarity (not recommended!), the calling program CRT_DEMO
  4553. could draw a dot in the center of screen S1 without calling DOT.  Which of the
  4554. following statements would accomplish the same thing as
  4555.  
  4556.                     DOT(S1, PLACE => (150, 200), COLOR => RED);
  4557.  
  4558.  
  4559.                 1.  S1(150, 200) := RED;
  4560.  
  4561.                 2.  S1(ROW => 150, COLUMN => 200) := RED;
  4562.  
  4563.                 3.  Either of the above would work.
  4564. 1HPlease press 1, 2, or 3, or B to go back.                      2034 385B382Q382$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    DOT(S1, PLACE => (150, 200), COLOR => RED);{;4}m
  4565.  
  4566.  
  4567.                 1.  S1(150, 200) := RED;{;4}m
  4568.  
  4569.                 2.  S1(ROW => 150, COLUMN => 200) := RED;
  4570.  
  4571.                 3.  Either of the above would work.
  4572.  
  4573.  
  4574. You're right!{;4}m  At a sacrifice in clarity, the appropriate element of S1 can be
  4575. set directly to RED to draw a dot in the center of the screen.  Number 2 is
  4576. wrong because the names ROW and COLUMN apply to type POINT, not to subscripts
  4577. of the array.
  4578. 1HPlease type a space to go on, or B or Q to go back to the question.                                          1758 385B382Q382$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    DOT(S1, PLACE => (150, 200), COLOR => RED);
  4579.  
  4580.  
  4581.                 1.  S1(150, 200) := RED;
  4582.  
  4583.                 2.  S1(ROW => 150, COLUMN => 200) := RED;
  4584.  
  4585.                 3.  Either of the above would work.
  4586.  
  4587.  
  4588. No, the names ROW and COLUMN apply to type POINT, not to subscripts of the
  4589. array.  For this reason number 2 won't compile.
  4590. 1HPlease type a space to go on, or B or Q to go back to the question.                  3152 386B382$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Although the calling program is very clear, there's one disadvantage that can
  4591. be eliminated by using a private type: if the resolution of the screen is
  4592. changed, the calling program is affected.  For example, the two calls to DOT
  4593. are each intended to draw a dot in the center of the screen.  These calls will
  4594. have to be changed when the resolution changes, or the dot will no longer be in
  4595. the center.  Also, nothing prevents CRT_DEMO from saying S1(150, 200) := RED;{;4}m
  4596. directly, instead of calling DOT.  This is a disadvantage, because accessing
  4597. the elements of the array directly makes CRT_DEMO very susceptible to changes
  4598. in the package.
  4599.  
  4600. It would be better to force CRT_DEMO to call our procedure DOT, and make it
  4601. impossible for CRT_DEMO to use the fact the a screen is represented by a
  4602. two-dimensional array.  Then the representation of a screen can change without
  4603. affecting the correctness of CRT_DEMO.
  4604.  
  4605. We'll improve our package specification and calling program to make SCREEN_TYPE
  4606. a private{;4}m type, so that its details can be used only inside the package.  Since
  4607. the screen resolution won't be available outside the package, we'll normalize
  4608. ROW and COLUMN, making them floating point numbers in the range 0.0 .. 1.0.
  4609. 1HPlease type a space to go on, or B to go back.                        2660 387B385$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Here's our improved package specification:
  4610.  
  4611. package CRT_CONTROLLER is
  4612.    type COLOR_TYPE  is (WHITE, BLACK, RED, YELLOW, GREEN, BLUE);
  4613.    type SCREEN_TYPE is private;{;4}m
  4614.    procedure DISPLAY (SCREEN : in SCREEN_TYPE);
  4615.    procedure CLEAR   (SCREEN : in out SCREEN_TYPE; TO: in COLOR_TYPE := BLACK);
  4616.    type POINT is
  4617.       record
  4618.          ROW    : FLOAT range 0.0 .. 1.0{;4}m;
  4619.          COLUMN : FLOAT range 0.0 .. 1.0{;4}m;
  4620.       end record;
  4621.    procedure DOT     (SCREEN : in out SCREEN_TYPE; PLACE : in POINT;
  4622.                       COLOR : in COLOR_TYPE);
  4623.    procedure LINE    (SCREEN : in out SCREEN_TYPE; FROM, TO : in POINT;
  4624.                       COLOR : in COLOR_TYPE);
  4625.    procedure BOX     (SCREEN : in out SCREEN_TYPE; CORNER1, CORNER2 : in POINT;
  4626.                       COLOR : in COLOR_TYPE);
  4627. private
  4628.    type SCREEN_TYPE is array(0 .. 299, 0 .. 399) of COLOR_TYPE;{;4}m
  4629. end CRT_CONTROLLER;
  4630. 1HPlease type a space to go on, or B to go back.                2469 388B386$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        package CRT_CONTROLLER is
  4631.            ...
  4632.            type SCREEN_TYPE is private;{;4}m
  4633.            procedure DISPLAY (SCREEN : in SCREEN_TYPE);
  4634.            procedure CLEAR   (SCREEN : in out SCREEN_TYPE; ... );
  4635.            ...
  4636.         private
  4637.            type SCREEN_TYPE is array(0 .. 299, 0 .. 399) of COLOR_TYPE;{;4}m
  4638.         end CRT_CONTROLLER;
  4639.  
  4640. Outside the package, there are only four things a calling program may do with
  4641. objects of a private type like SCREEN_TYPE:
  4642.  
  4643. 1.  Create them:{;4}m  S1, S2 : SCREEN_TYPE;
  4644.  
  4645. 2.  Assign them:{;4}m  S1 := S2;
  4646.  
  4647. 3.  Test them for equality and inequality:{;4}m  if S1 = S2 ...   if S1 /= S2 ...
  4648.  
  4649. 4.  Use any procedures, functions, and infix operators provided by the package:{;4}m
  4650.     CLEAR(S1);   DISPLAY(S2);   etc.
  4651. 1HPlease type a space to go on, or B to go back.       2925 389B387$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        With objects of a private type, outside the package we may only:{;4}m
  4652.  1.  Create     2.  Assign     3.  Test  =  /=     4.  Call package subprograms{;4}m
  4653.  
  4654. Note that the calling program, outside the package, can no longer say
  4655. S1(150, 200) := RED;{;4}m, because that's not one of the four things listed above.
  4656. The calling program is forced to call DOT.  The information that SCREEN_TYPE is
  4657. an array can be used by code only inside{;4}m the package.  Of course, the compiler{;4}m
  4658. uses this information when compiling code outside or inside the package.
  4659. That's why the definition of SCREEN_TYPE must be in the package specification,
  4660. not the body.  But the programmer{;4}m isn't allowed to use this information outside
  4661. the package.
  4662.  
  4663. Inside{;4}m the package there are no restrictions.  To write the bodies of the
  4664. subprograms, we'll have to use the structure of SCREEN_TYPE and write
  4665. statements similar to S1(150, 200) := RED;{;4}m.
  4666.  
  4667. Here's our calling program, revised to agree with the improved package
  4668. specification:
  4669. 1HPlease type a space to go on, or B to go back.                                                   3170 390B388$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   with CRT_CONTROLLER; use CRT_CONTROLLER;
  4670.    procedure CRT_DEMO is
  4671.       S1, S2 : SCREEN_TYPE;
  4672.    begin
  4673.       CLEAR(S1);
  4674.       CLEAR(S2, TO => WHITE);
  4675.       LINE(S1, FROM => (0.5{;4}m, 0.25{;4}m), TO => (0.5{;4}m, 0.75{;4}m), COLOR => GREEN);
  4676.       DOT(S1, PLACE => (0.5{;4}m, 0.5{;4}m), COLOR => RED);
  4677.       DISPLAY(S1);
  4678.       BOX(S2, CORNER1 => (0.8{;4}m, 0.25{;4}m), CORNER2 => (0.2{;4}m, 0.75{;4}m), COLOR => BLUE);
  4679.       DOT(S2, PLACE => (0.5{;4}m, 0.5{;4}m), COLOR => YELLOW);
  4680.       DISPLAY(S2);
  4681.    end CRT_DEMO;
  4682.  
  4683. Now, if a change is made only to the private part of the package specification,
  4684. CRT_DEMO won't have to be revised.  It will{;4}m have to be recompiled, because the
  4685. Ada compiler needs the information in the private part of the package
  4686. specification.  (The linker won't link with obsolete units, but will tell us
  4687. what me must recompile.)  Also, the package body may have to be rewritten.  But
  4688. if CRT_DEMO was correct before, it will remain correct without any revision!
  4689. The effects of the change are confined to the package.  Containing the effects
  4690. of changes by means of information hiding is one of Ada's greatest features.
  4691. 1HPlease type a space to go on, or B to go back.      1438F391T392B389$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QTrue or False?  If the private part of a package specification is changed, the
  4692. calling program must be recompiled before the package body is recompiled.
  4693. 1HPlease press T for true or F for false, or B to go back.                                      1551 393B390Q390$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$You're right!{;4}m  The package body and the calling program both depend on the
  4694. package specification, but not on each other.  They can be compiled in either
  4695. order after the package specification is compiled.
  4696. 1HPlease type a space to go on, or B or Q to go back to the question.                         1537 393B390Q390$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$False.  The package body and the calling program don't depend on each other,
  4697. but only on the package specification.  Thus they can be compiled in either
  4698. order after the package specification is compiled.
  4699. 1HPlease type a space to go on, or B or Q to go back to the question.                                       2474 394B390$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$If a package exports a constant of a private type, the constant is declared in
  4700. the "public" part of the package specification, but it can't be assigned a
  4701. value until we get to the private part.  This is called a deferred constant{;4}m.
  4702. For example,
  4703.  
  4704. package CRT_CONTROLLER is
  4705.    type COLOR_TYPE  is (WHITE, BLACK, RED, YELLOW, GREEN, BLUE);
  4706.    type SCREEN_TYPE is private;
  4707.    FLAG_OF_ITALY : constant SCREEN_TYPE;{;4}m
  4708.    procedure DISPLAY (SCREEN : in SCREEN_TYPE);
  4709.    ...
  4710. private
  4711.    type SCREEN_TYPE is array(0 .. 299, 0 .. 399) of COLOR_TYPE;
  4712.    FLAG_OF_ITALY : constant SCREEN_TYPE :=
  4713.        (others => (0 .. 132 => GREEN, 133 .. 266 => WHITE, 267 .. 399 => RED));{;4}m
  4714. end CRT_CONTROLLER;
  4715.  
  4716. CRT_DEMO could then say S1 := FLAG_OF_ITALY;{;4}m or DISPLAY(FLAG_OF_ITALY);{;4}m.
  4717. 1HPlease type a space to go on, or B to go back.  2957 395B393$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      TYPE TEXT AND LIMITED PRIVATE TYPES
  4718.  
  4719. Earlier we remarked that Ada strings are of fixed length.  Section 7.6 of the
  4720. LRM suggests that we create a type TEXT to get around this restriction.
  4721. Instead of declaring objects to be STRINGs, we'll declare them to be of type
  4722. TEXT, which will simulate variable-length strings.  Then we'll see how this
  4723. creates a need for limited private types.
  4724.  
  4725. The package specification in section 7.6 of the LRM makes use of discriminated
  4726. records.  Since we haven't yet covered that topic, we'll give a simplified
  4727. presentation here.  Let's declare
  4728.  
  4729.                     type TEXT is
  4730.                        record
  4731.                           LEN : INTEGER range 0 .. 80 := 0;
  4732.                           VAL : STRING(1 .. 80);
  4733.                        end record;{;4}m
  4734.  
  4735. Any appropriate maximum length may be used in place of 80.  It isn't necessary
  4736. to initialize the VAL field to all blanks, because the LEN field keeps track of
  4737. how much of the VAL field is significant.  The LEN field is given a default
  4738. value of 0, so that objects of type TEXT will be initialized to empty.
  4739. 1HPlease type a space to go on, or B to go back.                   2543 396B394$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    type TEXT is
  4740.                        record
  4741.                           LEN : INTEGER range 0 .. 80 := 0;
  4742.                           VAL : STRING(1 .. 80);
  4743.                        end record;{;4}m
  4744.  
  4745. For example, we could declare T1 : TEXT;{;4}m.  We could then set T1.LEN := 5;{;4}m and
  4746. T1.VAL(1 .. 5) := "Hello";{;4}m.  The fact that the last 75 characters of T1.VAL
  4747. might contain garbage is of no consequence, because T1.LEN tells our program
  4748. to consider only the first 5 characters of T1.VAL.  Since T1.LEN is a variable,
  4749. we've simulated variable-length strings.
  4750.  
  4751. A minor disadvantage is that, for each object of type TEXT, we reserve enough
  4752. memory for the longest possible length (80 in this example).  Discriminated
  4753. records, to be covered in the Advanced Topics section, can overcome this
  4754. disadvantage.
  4755. 1HPlease type a space to go on, or B to go back.                                 2836 397B395$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Type TEXT will be much easier to use if we write some subprograms.  First, we
  4756. need to convert between types TEXT and STRING.  Conversion in both directions
  4757. is very simple:
  4758.  
  4759.                    function STR(T : in TEXT) return STRING is
  4760.                    begin
  4761.                       return T.VAL(1 .. T.LEN);
  4762.                    end STR;
  4763.  
  4764.                    function TXT(S : in STRING) return TEXT is
  4765.                       ANSWER : TEXT;
  4766.                    begin
  4767.                       ANSWER.LEN := S'LENGTH;
  4768.                       ANSWER.VAL(1 .. ANSWER.LEN) := S;
  4769.                       return ANSWER;
  4770.                    end TXT;{;4}m
  4771.  
  4772. Now we can write, for example, T1 : TEXT := TXT("Hello");{;4}m and we don't even
  4773. have to count the characters of "Hello".  Later, the program might execute
  4774. T1 := TXT("Type TEXT is very convenient.");{;4}m showing that T1 simulates a
  4775. variable-length string.  If we with{;4}m and use{;4}m TEXT_IO in our program, we can
  4776. write PUT_LINE(STR(T1));{;4}m.
  4777. 1HPlease type a space to go on, or B to go back.                                        2922 398B396$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$It would be convenient to overload the &{;4}m operator to concatenate two TEXTs, or
  4778. a TEXT with a STRING.  We can also overload four of the relational operators:
  4779.  
  4780.       function "&"  (LEFT, RIGHT : in TEXT)               return TEXT;
  4781.       function "&"  (LEFT : in TEXT;   RIGHT : in STRING) return TEXT;
  4782.       function "&"  (LEFT : in STRING; RIGHT : in TEXT)   return TEXT;
  4783.       function "<"  (LEFT, RIGHT : in TEXT)               return BOOLEAN;
  4784.       function ">"  (LEFT, RIGHT : in TEXT)               return BOOLEAN;
  4785.       function "<=" (LEFT, RIGHT : in TEXT)               return BOOLEAN;
  4786.       function ">=" (LEFT, RIGHT : in TEXT)               return BOOLEAN;{;4}m
  4787.  
  4788. The bodies of these subprograms are very simple!  For example:
  4789.  
  4790.              function "&"(LEFT, RIGHT : in TEXT) return TEXT is
  4791.              begin
  4792.                 return TXT(STR(LEFT) & STR(RIGHT));
  4793.              end "&";
  4794.  
  4795.              function "<"(LEFT, RIGHT : in TEXT) return BOOLEAN is
  4796.              begin
  4797.                 return STR(LEFT) < STR(RIGHT);
  4798.              end "<";{;4}m
  4799. 1HPlease type a space to go on, or B to go back.                                                      1837F399T400B397$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q                   function TXT(S : in STRING) return TEXT is
  4800.                       ANSWER : TEXT;
  4801.                    begin
  4802.                       ANSWER.LEN := S'LENGTH;
  4803.                       ANSWER.VAL(1 .. ANSWER.LEN) := S;
  4804.                       return ANSWER;
  4805.                    end TXT;
  4806.  
  4807.  
  4808. True or False?  A call to TXT with the null string, TXT(""){;4}m, will raise a
  4809. CONSTRAINT_ERROR.
  4810. 1HPlease press T for true or F for false, or B to go back.                                       2147 401B398Q398$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   function TXT(S : in STRING) return TEXT is
  4811.                       ANSWER : TEXT;
  4812.                    begin
  4813.                       ANSWER.LEN := S'LENGTH;
  4814.                       ANSWER.VAL(1 .. ANSWER.LEN) := S;
  4815.                       return ANSWER;
  4816.                    end TXT;{;4}m
  4817.  
  4818.  
  4819. You're right!{;4}m  The first executable statement will set ANSWER.LEN to 0, and
  4820. the second executable statement will do nothing.  The check for
  4821. CONSTRAINT_ERROR is suppressed when a null slice is involved.  Thus the
  4822. function will work correctly even for the null string.
  4823. 1HPlease type a space to go on, or B or Q to go back to the question.                             2071 401B398Q398$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   function TXT(S : in STRING) return TEXT is
  4824.                       ANSWER : TEXT;
  4825.                    begin
  4826.                       ANSWER.LEN := S'LENGTH;
  4827.                       ANSWER.VAL(1 .. ANSWER.LEN) := S;
  4828.                       return ANSWER;
  4829.                    end TXT;
  4830.  
  4831.  
  4832. False.  The function will work correctly even for the null string.  The first
  4833. executable statement will set ANSWER.LEN to 0, and the second executable
  4834. statement will do nothing.  The check for CONSTRAINT_ERROR is suppressed when a
  4835. null slice is involved.
  4836. 1HPlease type a space to go on, or B or Q to go back to the question.     3330 402B398$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    type TEXT is
  4837.                        record
  4838.                           LEN : INTEGER range 0 .. 80 := 0;
  4839.                           VAL : STRING(1 .. 80);
  4840.                        end record;
  4841.  
  4842. There are two problems with type TEXT.  The way Ada assigns arrays is less than
  4843. ideal when assigning objects of type TEXT, and the way Ada tests for equality
  4844. is totally unacceptable.  Suppose we have T1, T2 : TEXT;{;4}m and then we execute
  4845. T1 := TXT("Hello");{;4}m and then T2 := T1;{;4}m.  In doing the assignment, Ada will
  4846. copy all 80 characters of T1.VAL, even though the last 75 characters contain
  4847. garbage and only the first 5 characters (and the LEN field) need be copied.
  4848. Perhaps we could live with this inefficiency, but Ada's test for equality of
  4849. arrays creates a more serious problem.
  4850.  
  4851. Suppose we execute T1 := TXT("aaaaaaaaaa");{;4}m and T2 := TXT("bbbbbbbbbb");{;4}m and
  4852. then T1 := TXT("Hello");{;4}m and T2 := TXT("Hello");{;4}m.  If we now ask Ada to test
  4853. if T1 = T2{;4}m, Ada will compare the entire VAL fields and conclude that T1 /= T2.
  4854. Note that T1.VAL(6 .. 10) is "aaaaa" while T2.VAL(6 .. 10) is "bbbbb", even
  4855. though only the first five characters of T1 and T2 should be considered.  (Both
  4856. LEN fields are 5.)  We of course want Ada to say that T1 = T2.
  4857. 1HPlease type a space to go on, or B to go back.                                              3017 403B401$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$We could try to get around this problem by writing our own function EQUAL:
  4858.  
  4859.                function EQUAL(T1, T2 : in TEXT) return BOOLEAN is
  4860.                begin
  4861.                   return STR(T1) = STR(T2);
  4862.                end EQUAL;
  4863.  
  4864. This function would work, but we might forget to write if EQUAL(T1, T2){;4}m and
  4865. write if T1 = T2{;4}m instead.  Similarly, we could write a procedure to assign
  4866. TEXTs efficiently, and forget to use it and write T2 := T1;{;4}m.  But Ada will
  4867. prevent us from assigning TEXTs and testing them for equality if we create a
  4868. package and make type TEXT limited private{;4}m.  Outside the package there are
  4869. only two{;4}m things we may do with objects of a limited private type:
  4870.  
  4871. 1.  Create them:{;4}m  T1, T2 : TEXT;
  4872.  
  4873. 2.  Use any procedures, functions, and infix operators provided by the package:{;4}m
  4874.     T1 & T2   etc.
  4875.  
  4876. We can't test for equality and inequality unless the package includes a
  4877. function "=".  Also, Ada won't let us write T2 := T1;{;4}m, but the package could
  4878. provide a procedure to assign TEXTs.  Here's our package specification:
  4879. 1HPlease type a space to go on, or B to go back.                                                           2773 404B402$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             package TEXT_HANDLER is
  4880.                 type TEXT is limited private;{;4}m
  4881.                 function STR(T : in TEXT) return STRING;
  4882.                 function TXT(S : in STRING) return TEXT;
  4883.                 function "&"(LEFT, RIGHT : in TEXT) return TEXT;
  4884.                 ...
  4885.                 function "="(LEFT, RIGHT : in TEXT) return BOOLEAN;{;4}m
  4886.                 function "<"(LEFT, RIGHT : in TEXT) return BOOLEAN;
  4887.                 ...
  4888.                 procedure SET(TARGET : in out TEXT; TO : in TEXT);
  4889.              private{;4}m
  4890.                 type TEXT is
  4891.                    record
  4892.                       LEN : INTEGER range 0 .. 80 := 0;
  4893.                       VAL : STRING(1 .. 80);
  4894.                    end record;
  4895.              end TEXT_HANDLER;
  4896.  
  4897. Note that we write type TEXT is limited private{;4}m, but we still introduce the
  4898. private part of the package simply with the word private{;4}m.
  4899.  
  4900. The two new subprograms are as easy to write as the others:
  4901. 1HPlease type a space to go on, or B to go back.   2350 405B403$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             function "="(LEFT, RIGHT : in TEXT) return BOOLEAN is
  4902.              begin
  4903.                 return STR(LEFT) = STR(RIGHT);
  4904.              end "=";
  4905.  
  4906.              procedure SET(TARGET : in out TEXT; TO : in TEXT) is
  4907.              begin
  4908.                 TARGET.LEN := TO.LEN;
  4909.                 TARGET.VAL(1 .. TARGET.LEN) := TO.VAL(1 .. TO.LEN);
  4910.              end SET;{;4}m
  4911.  
  4912. In summary, we used limited private{;4}m for type TEXT because Ada's definitions of
  4913. equality and assignment weren't appropriate for that type, and we wanted to
  4914. provide our own definitions.  However, Ada's definitions were{;4}m appropriate for
  4915. SCREEN_TYPE, so we made that a private{;4}m type to contain the effects of changes.
  4916. 1HPlease type a space to go on, or B to go back.                          265824061407B404$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q           package STACKS is
  4917.               type STACK is ?{;4}m
  4918.               procedure PUSH (S : in out STACK; ITEM : in  INTEGER);
  4919.               procedure POP  (S : in out STACK; ITEM : out INTEGER);
  4920.            private
  4921.               type IVECTOR is array(INTEGER range <>) of INTEGER;
  4922.               type STACK is
  4923.                  record
  4924.                     SP : INTEGER range 1 .. 11 := 1;
  4925.                     ST : IVECTOR(1 .. 10);
  4926.                  end record;
  4927.            end STACKS;
  4928.  
  4929. Suppose we want to write a package that lets us create objects of type STACK,
  4930. and push and pop integers on them.  The stacks will be last in, first out.
  4931. (For now, ignore the possibilities of stack underflow and overflow.)  Should
  4932. type STACK be private{;4}m or limited private{;4}m?
  4933.  
  4934.                    1.  Type STACK should be private{;4}m.
  4935.  
  4936.                    2.  Type STACK should be limited private{;4}m.
  4937. 1HPlease press 1 or 2, or B to go back.                  2519 408B405Q405$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$           package STACKS is
  4938.               type STACK is limited private;{;4}m
  4939.               procedure PUSH (S : in out STACK; ITEM : in  INTEGER);
  4940.               procedure POP  (S : in out STACK; ITEM : out INTEGER);
  4941.            private
  4942.               type IVECTOR is array(INTEGER range <>) of INTEGER;
  4943.               type STACK is
  4944.                  record
  4945.                     SP : INTEGER range 1 .. 11 := 1;
  4946.                     ST : IVECTOR(1 .. 10);
  4947.                  end record;{;4}m
  4948.            end STACKS;
  4949.  
  4950. You're right!{;4}m  Similar to type TEXT, only part of the array in type STACK (the
  4951. part up through SP - 1) is significant; the rest contains garbage.  Thus, Ada's
  4952. test for equality is unsatisfactory for the same reason, and type STACK should
  4953. be limited private{;4}m.
  4954. 1HPlease type a space to go on, or B or Q to go back to the question.                                                         2436 408B405Q405$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$           package STACKS is
  4955.               type STACK is ?{;4}m
  4956.               procedure PUSH (S : in out STACK; ITEM : in  INTEGER);
  4957.               procedure POP  (S : in out STACK; ITEM : out INTEGER);
  4958.            private
  4959.               type IVECTOR is array(INTEGER range <>) of INTEGER;
  4960.               type STACK is
  4961.                  record
  4962.                     SP : INTEGER range 1 .. 11 := 1;
  4963.                     ST : IVECTOR(1 .. 10);
  4964.                  end record;
  4965.            end STACKS;
  4966.  
  4967. No, type STACK is similar to type TEXT in that only part of the array (the part
  4968. up through SP - 1) is significant; the rest contains garbage.  Thus, Ada's test
  4969. for equality is unsatisfactory for the same reason, and type STACK should be
  4970. limited private{;4}m.
  4971. 1HPlease type a space to go on, or B or Q to go back to the question.                                        2150 409B405$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  4972.  
  4973.    Introduction                             Records, Arrays, and Assignment 3
  4974.  
  4975.    The Format of an Ada Program             Recursion and Assignment 4
  4976.  
  4977.    Generic Instantiation and                Subprograms and Packages
  4978.       Assignment 1
  4979.                                          >  ADDITIONAL TYPES, EXCEPTIONS,{;4}m
  4980.    Simple Declarations and Simple              TEXT_IO, AND ASSIGNMENT 5{;4}m
  4981.       Attributes
  4982.                                             Generics, Tasking, and Assignment 6
  4983.    Operators, Control Constructs, and
  4984.       Assignment 2                          Advanced Topics
  4985. 1HPlease type a space to go on, or B to go back.                          2740 410B408$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                  ACCESS TYPES
  4986.  
  4987. Access types are sometimes called "pointers" in other languages.  However, the
  4988. name "pointer" fell into disrepute, because of "dangling reference" problems.
  4989. With Ada's access types, dangling references are impossible, unless we
  4990. deliberately instantiate UNCHECKED_DEALLOCATION (discussed in the Advanced
  4991. Topics section).
  4992.  
  4993. If we define type DATE as before, and write USA : DATE;{;4}m then USA has three
  4994. fields, DAY, MONTH, and YEAR.  However, if we write
  4995.  
  4996.                              type P is access DATE;
  4997.                              D1, D2 : P;{;4}m
  4998.  
  4999. then D1 and D2 are capable of pointing to{;4}m objects of type DATE.  In most
  5000. implementations of Ada, this means that D1 and D2 can each contain the machine
  5001. address of the start of a record of type DATE.  However, this detail depends on
  5002. the implementation of Ada.  D1 and D2 themselves don't have fields, but the
  5003. objects they can point to have fields.
  5004. 1HPlease type a space to go on, or B to go back.                                    3273 411B409$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                             type P is access DATE;
  5005.                              D1, D2 : P;{;4}m
  5006.  
  5007. At present D1 and D2 point to nothing.  However, if we execute
  5008.  
  5009.                                 D1 := new DATE;{;4}m
  5010.  
  5011. then, at run time, enough memory for one record of type DATE is allocated, and
  5012. D1 is made to point to it.  This new object of type DATE doesn't have a name;
  5013. only the pointer, D1, has a name.  By contrast, when we elaborate USA : DATE;{;4}m
  5014. we create an object that has a name (USA), but nothing can point to it.
  5015.  
  5016. We can refer to the fields of the nameless object pointed to by D1 as if D1
  5017. itself had fields.  Thus, we can write D1.DAY, D1.MONTH, and D1.YEAR, and use
  5018. these on either side of an assignment: D1.DAY := 12;{;4}m.  The entire object
  5019. pointed to by D1 is D1.all{;4}m, so we could write D1.all := (12, OCT, 1492);{;4}m.  Note
  5020. that D1.DAY{;4}m is simply an abbreviation for D1.all.DAY{;4}m.
  5021.  
  5022. We can execute D2 := new DATE'(4, JUL, 1776);{;4}m giving the new object a value
  5023. when it's created.  We can also declare D3 : P := new DATE;{;4}m to make D3 point to
  5024. an object when D3 is created, or even write D3 : P := new DATE'(4, JUL, 1776);{;4}m
  5025. to make D3 point to an object and also give the object a value.
  5026. 1HPlease type a space to go on, or B to go back.   3574 412B410$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$We can write D3 := null;{;4}m to make D3 point nowhere.  When a pointer is declared
  5027. and no initialization is shown, it's automatically initialized to null{;4}m, so
  5028. D4 : P;{;4}m means D4 : P := null;{;4}m.  When a pointer is null, trying to reference the
  5029. object pointed to (D4.DAY{;4}m or D4.all{;4}m, etc.) will raise a CONSTRAINT_ERROR.  We
  5030. can test to see if a pointer is null: if D4 = null then{;4}m ...
  5031.  
  5032. Copying a pointer isn't the same as copying the object pointed to.  If we
  5033. execute D1.all := (12, OCT, 1492);{;4}m and then D2.all := D1.all;{;4}m, the entire
  5034. record is copied.  If we change D1.DAY with D1.DAY := 13;{;4}m, D2.DAY is still 12.
  5035.  
  5036. However, is we execute D1.all := (12, OCT, 1492);{;4}m and then D2 := D1;{;4}m, then the
  5037. address in D1 is copied to D2, so that D2 now points to the same place as D1.
  5038. Thus, if we change D1.DAY with D1.DAY := 13;{;4}m, then D2.DAY is also 13, because
  5039. it references the same memory location.
  5040.  
  5041. If we have D1 := new DATE'(12, OCT, 1492);{;4}m and D2 := new DATE'(4, JUL, 1776);{;4}m
  5042. and then execute D2 := D1;{;4}m, D2 now points where D1 points, and nothing any
  5043. longer points to the object containing (4, JUL, 1776).  Most systems will later
  5044. reclaim the memory occupied by that object, if the memory is needed.  This
  5045. process is called garbage collection{;4}m.  It's automatic, and normally need not
  5046. concern the programmer.
  5047. 1HPlease type a space to go on, or B to go back.  3035 413B411$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A simple linked list{;4}m can be thought of as a chain.  Each link contains some
  5048. useful data (perhaps an integer, perhaps pages of information), and a pointer
  5049. to the next item in the chain.  There's also a pointer, usually called HEAD,
  5050. that points to the first link in the chain.  The last link points nowhere.
  5051.  
  5052. A linked list of integers might look something like this:
  5053.          ____       __________          __________          __________
  5054.         |  --|---->| INT   10 |   ,--->| INT   27 |   ,--->| INT   34 |
  5055.         |____|     | NEXT  ---|---'    | NEXT  ---|---'    | NEXT null|
  5056.          HEAD      |__________|        |__________|        |__________|{;4}m
  5057.  
  5058. To add another integer to the chain, keeping the integers in ascending order,
  5059. we simply break the chain at the appropriate point and insert another link.
  5060.  
  5061. To set up our linked list, we'd like to write type P is access LINK;{;4}m and write
  5062.  
  5063.                              type LINK is
  5064.                                 record
  5065.                                    INT  : INTEGER;
  5066.                                    NEXT : P;
  5067.                                 end record;{;4}m
  5068. 1HPlease type a space to go on, or B to go back.                                         2730 414B412$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$However, the declaration of type P involves LINK, and the declaration of type
  5069. LINK involves P, so neither declaration can come first!  Ada provides a special
  5070. means of solving this problem.  We can write
  5071.  
  5072.                              type LINK;
  5073.                              type P is access LINK;
  5074.                              type LINK is
  5075.                                 record
  5076.                                    INT  : INTEGER;
  5077.                                    NEXT : P;
  5078.                                 end record;{;4}m
  5079.  
  5080. The first line is called an incomplete type declaration{;4}m.  It simply tells the
  5081. compiler that type LINK exists.  That's all the information the compiler needs
  5082. to compile the second line.  The second line tells the compiler that objects of
  5083. type P will contain pointers, but for this line the compiler doesn't need to
  5084. know details of the objects pointed to.  The second line must be followed by
  5085. the full definition of type LINK.
  5086. 1HPlease type a space to go on, or B to go back.                                              2222241514163416B413$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q                    type PERSON is
  5087.                        record
  5088.                           NAME : STRING(1 .. 10);
  5089.                           AGE  : NATURAL;
  5090.                        end record;
  5091.                     type P is access PERSON;
  5092.                     P1 : P := new PERSON'("Susan     ", 21);
  5093.                     P2 : P := new PERSON'("John      ", 35);
  5094.                     ...
  5095.                     P2 := P1;
  5096.                     P1.AGE := 22;
  5097.  
  5098.  
  5099.                                What is P2.AGE?
  5100.  
  5101.                                1.  P2.AGE is 21.
  5102.  
  5103.                                2.  P2.AGE is 22.
  5104.  
  5105.                                3.  P2.AGE is 35.
  5106. 1HPlease press 1, 2, or 3, or B to go back.                                                      2150 417B414Q414$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    type PERSON is
  5107.                        record
  5108.                           NAME : STRING(1 .. 10);
  5109.                           AGE  : NATURAL;
  5110.                        end record;
  5111.                     type P is access PERSON;
  5112.                     P1 : P := new PERSON'("Susan     ", 21);
  5113.                     P2 : P := new PERSON'("John      ", 35);
  5114.                     ...
  5115.                     P2 := P1;
  5116.                     P1.AGE := 22;
  5117.  
  5118.  
  5119. You're right!{;4}m  The last line changed P1.AGE to 22.  Since the previous line
  5120. made P2 point where P1 points, P2.AGE is also 22.
  5121. 1HPlease type a space to go on, or B or Q to go back to the question.                          2125 417B414Q414$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    type PERSON is
  5122.                        record
  5123.                           NAME : STRING(1 .. 10);
  5124.                           AGE  : NATURAL;
  5125.                        end record;
  5126.                     type P is access PERSON;
  5127.                     P1 : P := new PERSON'("Susan     ", 21);
  5128.                     P2 : P := new PERSON'("John      ", 35);
  5129.                     ...
  5130.                     P2 := P1;
  5131.                     P1.AGE := 22;
  5132.  
  5133.  
  5134. No, the last line changed P1.AGE to 22.  Since the previous line made P2 point
  5135. where P1 points, P2.AGE is also 22.
  5136. 1HPlease type a space to go on, or B or Q to go back to the question.                                                   3130 418B414$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Let's use an access type to write a program that gets integers in random order
  5137. from the terminal, maintaining a linked list of them.  When 0{;4}m is input, the
  5138. program outputs the integers in ascending order.  This program will be a good
  5139. stepping-stone to Outside Assignment 5.  To simplify inserting an integer into
  5140. the linked list, HEAD will point to an unused LINK, which will in turn point to
  5141. the first actual link in the chain:
  5142.  
  5143.  ____      __________         __________         __________         __________
  5144. |  --|--->| INT      |   ,-->| INT   10 |   ,-->| INT   27 |   ,-->| INT   34 |
  5145. |____|    | NEXT  ---|---'   | NEXT  ---|---'   | NEXT  ---|---'   | NEXT null|
  5146.  HEAD     |__________|       |__________|       |__________|       |__________|{;4}m
  5147.  
  5148. We could create our linked list using arrays rather than an access type.
  5149. However, we'd have to specify the size of the arrays, placing a limit on the
  5150. number of integers the program can handle.  With the access type, the only
  5151. limit is the amount of available memory.  We'll be able to move our program to
  5152. a larger machine to increase this limit, without changing any code - not even
  5153. one line to specify the size of an array.
  5154.  
  5155. Here's our program ...
  5156. 1HPlease type a space to go on, or B to go back.                                              2423 419B417$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        with TEXT_IO; use TEXT_IO;
  5157.         procedure LL_DEMO is
  5158.            package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  5159.            type LINK;
  5160.            type P is access LINK;
  5161.            type LINK is
  5162.               record
  5163.                  INT  : INTEGER;
  5164.                  NEXT : P;
  5165.               end record;
  5166.            HEAD : P := new LINK;
  5167.            I    : INTEGER;
  5168.            procedure ADD_I_TO_LINKED_LIST is separate;
  5169.            procedure DISPLAY_LINKED_LIST is separate;{;4}m
  5170.         begin
  5171.            PUT("Type an integer: ");  GET(I);
  5172.            while I /= 0 loop
  5173.               ADD_I_TO_LINKED_LIST;
  5174.               PUT("Type an integer: ");  GET(I);
  5175.            end loop;
  5176.            DISPLAY_LINKED_LIST;{;4}m
  5177.         end LL_DEMO;
  5178. 1HPlease type a space to go on, or B to go back.                                                     2763 420B418$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ separate (LL_DEMO)
  5179.  procedure DISPLAY_LINKED_LIST is
  5180.     TMP : P := HEAD.NEXT;          -- Skip unused link at the head of the list.
  5181.  begin
  5182.     while TMP /= null loop
  5183.        PUT(TMP.INT);  NEW_LINE;           -- Print integer in the current link.
  5184.        TMP := TMP.NEXT;                         -- Go to next link in the list.
  5185.     end loop;
  5186.  end DISPLAY_LINKED_LIST;
  5187.  
  5188.  separate (LL_DEMO)
  5189.  procedure ADD_I_TO_LINKED_LIST is
  5190.     TMP : P := HEAD;       -- Begin search of where to insert at start of list.
  5191.  begin
  5192.     while TMP /= null and then TMP.NEXT /= null and then TMP.NEXT.INT < I loop
  5193.        TMP := TMP.NEXT;  -- Note use of "and then" to avoid trying to reference
  5194.     end loop;            -- the object pointed to when the pointer is null.
  5195.     TMP.NEXT := new LINK'(I, TMP.NEXT);  -- Create new link and insert in list.
  5196.  end ADD_I_TO_LINKED_LIST;{;4}m
  5197.  
  5198. The best way to follow these two subprograms is to draw a linked list on a
  5199. piece of scrap paper and "hand execute" the subprograms.
  5200. 1HPlease type a space to go on, or B to go back.             202544211422242334245425B419$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q                   type LINK;  -- 1{;4}m
  5201.                    type P is access LINK;
  5202.                    type LINK is
  5203.                       record
  5204.                          F : FLOAT;  -- 2{;4}m
  5205.                          S : STRING(1 .. 10);  -- 3{;4}m
  5206.                          A : array(1 .. 10) of INTEGER;  -- 4{;4}m
  5207.                       end record;
  5208.                    L1 : LINK;  -- 5{;4}m
  5209.                    P1 : P;
  5210.  
  5211. Which commented line in the above is illegal{;4}m?
  5212. 1HPlease press 1, 2, 3, 4, or 5, or B to go back.                                                   2421 426B420Q420$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   type LINK;  -- 1
  5213.                    type P is access LINK;
  5214.                    type LINK is
  5215.                       record
  5216.                          F : FLOAT;  -- 2
  5217.                          S : STRING(1 .. 10);  -- 3
  5218.                          A : array(1 .. 10) of INTEGER;  -- 4{;4}m
  5219.                       end record;
  5220.                    L1 : LINK;  -- 5
  5221.                    P1 : P;
  5222.  
  5223.  
  5224. You're right!{;4}m  Inside a record definition, the name of a field must be
  5225. followed by a type name, not array{;4}m.  We would first have to say something like
  5226. type LIST is array(INTEGER range <>) of INTEGER;{;4}m, and then change the field
  5227. definition to
  5228.  
  5229.                          A : LIST(1 .. 10);{;4}m
  5230. 1HPlease type a space to go on, or B or Q to go back to the question.                                                       2121 426B420Q420$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   type LINK;  -- 1
  5231.                    type P is access LINK;
  5232.                    type LINK is
  5233.                       record
  5234.                          F : FLOAT;  -- 2
  5235.                          S : STRING(1 .. 10);  -- 3
  5236.                          A : array(1 .. 10) of INTEGER;  -- 4
  5237.                       end record;
  5238.                    L1 : LINK;  -- 5
  5239.                    P1 : P;
  5240.  
  5241.  
  5242. No, the first line is legal.  Ada allows an incomplete type declaration to
  5243. precede the declaration of an access type, provided the complete type
  5244. declaration follows.
  5245. 1HPlease type a space to go on, or B or Q to go back to the question.                                                       2034 426B420Q420$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   type LINK;  -- 1
  5246.                    type P is access LINK;
  5247.                    type LINK is
  5248.                       record
  5249.                          F : FLOAT;  -- 2
  5250.                          S : STRING(1 .. 10);  -- 3
  5251.                          A : array(1 .. 10) of INTEGER;  -- 4
  5252.                       end record;
  5253.                    L1 : LINK;  -- 5
  5254.                    P1 : P;
  5255.  
  5256.  
  5257. No, the declaration of F inside the record definition is legal, because Ada
  5258. records may contain fields of any type.
  5259. 1HPlease type a space to go on, or B or Q to go back to the question.                                          2034 426B420Q420$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   type LINK;  -- 1
  5260.                    type P is access LINK;
  5261.                    type LINK is
  5262.                       record
  5263.                          F : FLOAT;  -- 2
  5264.                          S : STRING(1 .. 10);  -- 3
  5265.                          A : array(1 .. 10) of INTEGER;  -- 4
  5266.                       end record;
  5267.                    L1 : LINK;  -- 5
  5268.                    P1 : P;
  5269.  
  5270.  
  5271. No, the declaration of S inside the record definition is legal, because Ada
  5272. records may contain fields of any type.
  5273. 1HPlease type a space to go on, or B or Q to go back to the question.                                          2267 426B420Q420$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   type LINK;  -- 1
  5274.                    type P is access LINK;
  5275.                    type LINK is
  5276.                       record
  5277.                          F : FLOAT;  -- 2
  5278.                          S : STRING(1 .. 10);  -- 3
  5279.                          A : array(1 .. 10) of INTEGER;  -- 4
  5280.                       end record;
  5281.                    L1 : LINK;  -- 5
  5282.                    P1 : P;
  5283.  
  5284.  
  5285. No, the declaration of L1 as type LINK is legal.  Even though type P was
  5286. declared to be access LINK{;4}m and we ordinarily would declare objects to be of
  5287. type P, we may also directly declare objects to be of type LINK.  Of course,
  5288. nothing can point to such objects.
  5289. 1HPlease type a space to go on, or B or Q to go back to the question.         3236 427B420$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                       USER DEFINED TYPES AND PORTABILITY
  5290.  
  5291. In some implementations of Ada, INTEGERs are represented by 32-bit two's
  5292. complement numbers, giving the range -2_147_483_648 .. 2_147_483_647.  Other
  5293. implementations use 16-bit two's complement INTEGERs, giving the range
  5294. -32768 .. 32767.  However, some of the 16-bit implementations also provide a
  5295. 32-bit type called LONG_INTEGER.
  5296.  
  5297. Suppose we need a variable called NUMBER to count from zero to one million.  We
  5298. could declare NUMBER: INTEGER;{;4}m for the 32-bit implementation, and change this
  5299. to NUMBER : LONG_INTEGER;{;4}m when we port the program to a machine running a
  5300. 16-bit version that provides LONG_INTEGER.  However, we could also declare
  5301.  
  5302.                      type COUNTER is range 0 .. 1_000_000;
  5303.                      NUMBER : COUNTER;{;4}m
  5304.  
  5305. and both implementations of Ada will automatically select the appropriate
  5306. internal representation for our type COUNTER!  The 32-bit Ada will select
  5307. INTEGER, and the 16-bit Ada will select LONG_INTEGER.  This gives us the
  5308. advantage that no code has to be changed when the program is ported.  COUNTER
  5309. is called a user-defined type{;4}m.  Of course, we must use explicit type
  5310. conversion to mix objects of type COUNTER with objects of other types.
  5311. 1HPlease type a space to go on, or B to go back.                                        2671 428B426$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Similarly, different implementations of Ada provide different representations
  5312. for type FLOAT, and some provide a type LONG_FLOAT.  We can declare
  5313.  
  5314.                              type REAL is digits 8;
  5315.                              F : REAL;{;4}m
  5316.  
  5317. and be certain that F will have at least 8 digits of accuracy on any machine
  5318. that accepts this type declaration.  A range constraint is optional.
  5319.  
  5320. User defined types also apply to fixed point numbers; these will be discussed
  5321. in the Advanced Topics section.
  5322.  
  5323. It's possible to make a declaration that will be accepted by only some
  5324. implementations of Ada.  For example, if we declare
  5325.  
  5326.                     type X is digits 30 range 0.0 .. 100.0;{;4}m
  5327.  
  5328. some implementations of Ada might have to report that there's no available type
  5329. that gives at least 30 digits of accuracy.
  5330.  
  5331. No language can give perfectly portable programs, but Ada truly advanced the
  5332. state of the art in portability.
  5333. 1HPlease type a space to go on, or B to go back.     2860 429B427$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                 DERIVED TYPES
  5334.  
  5335. Derived types are created to prevent accidental mixing of objects.  Unlike
  5336. subtypes, derived types are separate types.  For example,
  5337.  
  5338.                type NO_OF_APPLES  is new INTEGER;
  5339.                type NO_OF_ORANGES is new INTEGER range 0 .. 100;
  5340.                NOA : NO_OF_APPLES;
  5341.                NOO : NO_OF_ORANGES;
  5342.                I   : INTEGER;{;4}m
  5343.                ...
  5344.                NOA := NOA + NOO;  -- illegal
  5345.                NOA := NOA + NOA;
  5346.                NOA := NOA + I;  -- illegal
  5347.                NOA := NOA + NO_OF_APPLES(I);
  5348.                NOA := NOA + NO_OF_APPLES(NOO);{;4}m
  5349.  
  5350. A derived type is denoted by the reserved word new{;4}m followed by an existing type
  5351. like INTEGER.  The operations that Ada knows for INTEGERs, such as addition,
  5352. are "inherited" by the derived types so that, for example, Ada knows how to add
  5353. two objects of type NO_OF_ORANGES.  As the examples above show, we can't mix
  5354. types accidentally, but we can deliberately mix them by converting first.
  5355. 1HPlease type a space to go on, or B to go back.                2158 430B428$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In summary,
  5356.  
  5357.  
  5358.            Subtypes{;4}m are usually created to provide range constraints:
  5359.  
  5360.                  subtype DAY_SUBTYPE is INTEGER range 1 .. 31;{;4}m
  5361.  
  5362.  
  5363.         Derived types{;4}m are usually created to prevent accidental mixing:
  5364.  
  5365.                     type NO_OF_APPLES  is new INTEGER;
  5366.                     type NO_OF_ORANGES is new INTEGER{;4}m ... ;{;4}m
  5367.  
  5368.  
  5369.           User-defined types{;4}m are usually created to gain portability:
  5370.  
  5371.                      type COUNTER is range 0 .. 1_000_000;
  5372.                      type REAL    is digits 8;{;4}m
  5373. 1HPlease type a space to go on, or B to go back.                  2325143124323433B429$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q type METERS            is new FLOAT;
  5374.  type SECONDS           is new FLOAT;
  5375.  type METERS_PER_SECOND is new FLOAT;
  5376.  ...
  5377.  function "*"(LEFT : in METERS_PER_SECOND; RIGHT : in SECONDS) return METERS is
  5378.  begin
  5379.     return METERS(LEFT) * METERS(RIGHT);
  5380.  end "*";
  5381.  function "*"(LEFT : in SECONDS; RIGHT : in METERS_PER_SECOND) return METERS is
  5382.  begin
  5383.     return RIGHT * LEFT;
  5384.  end "*";
  5385.  function "/"(LEFT : in METERS; RIGHT : in SECONDS) return METERS_PER_SECOND is
  5386.  begin
  5387.     return METERS_PER_SECOND(LEFT) / METERS_PER_SECOND(RIGHT);
  5388.  end "/";
  5389.  
  5390.                  The above program segment is an example of ...
  5391.                  1.  derived types.
  5392.                  2.  user-defined types.
  5393.                  3.  subtypes.
  5394. 1HPlease press 1, 2, or 3, or B to go back.                                                   1661 434B430Q430$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ type METERS            is new{;4}m FLOAT;
  5395.  type SECONDS           is new{;4}m FLOAT;
  5396.  type METERS_PER_SECOND is new{;4}m FLOAT;
  5397.  
  5398.  
  5399. You're right!{;4}m  The reserved word new{;4}m in the segment above tells us that we're
  5400. defining derived types.
  5401. 1HPlease type a space to go on, or B or Q to go back to the question.               1637 434B430Q430$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ type METERS            is new FLOAT;
  5402.  type SECONDS           is new FLOAT;
  5403.  type METERS_PER_SECOND is new FLOAT;
  5404.  
  5405.  
  5406. No, examples of user-defined types are
  5407.  
  5408.                      type COUNTER is range 0 .. 1_000_000;
  5409.                      type REAL    is digits 8;
  5410. 1HPlease type a space to go on, or B or Q to go back to the question.                                       1515 434B430Q430$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ type METERS            is new FLOAT;
  5411.  type SECONDS           is new FLOAT;
  5412.  type METERS_PER_SECOND is new FLOAT;
  5413.  
  5414.  
  5415. No, subtypes are usually created to provide range constraints.
  5416. 1HPlease type a space to go on, or B or Q to go back to the question.                                                             3065 435B430$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                   EXCEPTIONS
  5417.  
  5418. When an error occurs during the elaboration or execution of a statement, Ada is
  5419. said to raise an exception{;4}m.  Ordinarily this stops the program, but Ada
  5420. programs can trap exceptions and execute a special block of code when one
  5421. occurs.  This code is called an exception handler{;4}m.
  5422.  
  5423. We can define our own exceptions, but five of them are predefined by Ada:
  5424.  
  5425. CONSTRAINT_ERROR{;4}m
  5426.      This is the exception encountered most often by beginners, because it can
  5427. be caused by a number of different things.  It can be raised by a subscript out
  5428. of range, a subtype out of range (USA.DAY := 32;), an attribute used improperly
  5429. (INTEGER'VALUE("12X3") or MONTH_TYPE'VAL(13)), assigning an array of one length
  5430. to a destination of another (H : STRING(1 .. 5) := "Hi";), or by attempting to
  5431. access an object with a null pointer.  The newest versions of Ada also raise
  5432. CONSTRAINT_ERROR on an arithmetic overflow or an attempt to divide by zero.
  5433.  
  5434. NUMERIC_ERROR{;4}m
  5435.      Many versions of Ada raise this on an arithmetic overflow or an attempt to
  5436. divide by zero.  The newest versions of Ada raise CONSTRAINT_ERROR instead.
  5437. 1HPlease type a space to go on, or B to go back.           3037 436B434$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$PROGRAM_ERROR{;4}m
  5438.      This is rarely encountered by beginners, but it can be raised by skipping
  5439. around the return{;4}m statement in a function and running into the end{;4}m statement.
  5440.  
  5441. STORAGE_ERROR{;4}m
  5442.      This is raised by running out of memory, as with a recursive program
  5443. calling itself unconditionally or an attempt to create an infinitely large
  5444. linked list.
  5445.  
  5446. TASKING_ERROR{;4}m
  5447.      This will be discussed in the section on Tasking.
  5448.  
  5449. An exception handler is introduced by the reserved word exception{;4}m; its
  5450. structure is similar to that of a case{;4}m construct.  We'll see an example in a
  5451. moment.  Unlike a case{;4}m construct, an exception handler need not account for all
  5452. the possibilities.
  5453.  
  5454. An exception handler can be placed in a subprogram, in the initialization code
  5455. of a package, in a task (to be discussed in the section on Tasking), or in a
  5456. block (to be discussed later in this section).  Here's a procedure with an
  5457. exception handler that handles an exception, WRONG{;4}m, that we declare ourselves,
  5458. as well as the built-in exception NUMERIC_ERROR{;4}m:
  5459. 1HPlease type a space to go on, or B to go back.                                       2267 437B435$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ with TEXT_IO; use TEXT_IO;
  5460.  procedure EXCEPTION_DEMO is
  5461.     package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  5462.     I     : INTEGER;
  5463.     WRONG : exception;{;4}m
  5464.  begin
  5465.     loop
  5466.        NEW_LINE(2);  PUT("Type a positive integer. ");  GET(I);
  5467.        if I <= 0 then
  5468.           raise WRONG;{;4}m
  5469.        end if;
  5470.        PUT("The square is ... ");
  5471.        PUT(I*I); -- Raises CONSTRAINT_ERROR or NUMERIC_ERROR if I is too large.{;4}m
  5472.     end loop;
  5473.  exception
  5474.     when CONSTRAINT_ERROR | NUMERIC_ERROR =>{;4}m
  5475.        PUT(" ... too big.");
  5476.     when WRONG =>{;4}m
  5477.        NEW_LINE;
  5478.        PUT("I said POSITIVE integer!");
  5479.  end EXCEPTION_DEMO;
  5480. 1HPlease type a space to go on, or B to go back.         3863 438B436$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$We can deliberately raise an exception (either user-defined or built-in) with
  5481. the raise{;4}m statement, as in raise WRONG;{;4}m or raise CONSTRAINT_ERROR;{;4}m.  Also,
  5482. ordinary statements can raise exceptions.  In our sample program, PUT(I*I);{;4}m
  5483. raises CONSTRAINT_ERROR or NUMERIC_ERROR if I is too large.  When an executable
  5484. statement raises an exception, the exception handler is executed instead of{;4}m the
  5485. rest of the procedure, function, etc.  Our program keeps asking for integers
  5486. and printing their squares until an exception is raised.  Then, the exception
  5487. handler is executed, and there's no way to get back into the procedure to ask
  5488. for another integer (short of a recursive call).  Even a goto{;4}m from the
  5489. exception handler to the main part of the procedure is forbidden.  Soon we'll
  5490. show how the block construct can overcome this problem, so that our program
  5491. will continue to ask for more integers even after an exception is handled.
  5492.  
  5493. As with case{;4}m constructs, an exception handler may use the vertical bar to
  5494. denote multiple choices (when CONSTRAINT_ERROR | NUMERIC_ERROR =>{;4}m block of
  5495. code), and it may say when others =>{;4}m to handle all cases not covered earlier.
  5496. But there's no way to test, inside the exception handler, which line{;4}m raised the
  5497. exception.  We can only test which kind{;4}m of exception was raised.
  5498.  
  5499. Don't use exceptions where a simple if{;4}m will do.  In our program, trapping the
  5500. arithmetic overflow was OK, but the if{;4}m could have handled I <= 0 without
  5501. raising WRONG.  This exception was declared only to give a simple example.
  5502. 1HPlease type a space to go on, or B to go back.             184314392440344144425443B437$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q                              1.  CONSTRAINT_ERROR
  5503.  
  5504.                               2.  NUMERIC_ERROR
  5505.  
  5506.                               3.  PROGRAM_ERROR
  5507.  
  5508.                               4.  STORAGE_ERROR
  5509.  
  5510.                               5.  TASKING_ERROR
  5511.  
  5512.  
  5513. Assuming RAINBOW_COLOR and TRAFFIC_LIGHT_COLOR are defined as before, which of
  5514. the above exceptions would be raised by RAINBOW_COLOR'VALUE("AMBER"){;4}m?
  5515. 1HPlease press 1, 2, 3, 4, or 5, or B to go back.                                 1814 444B438Q438$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              1.  CONSTRAINT_ERROR{;4}m
  5516.  
  5517.                               2.  NUMERIC_ERROR
  5518.  
  5519.                               3.  PROGRAM_ERROR
  5520.  
  5521.                               4.  STORAGE_ERROR
  5522.  
  5523.                               5.  TASKING_ERROR
  5524.  
  5525.  
  5526. You're right!{;4}m  Using an attribute improperly in this way will raise
  5527. CONSTRAINT_ERROR.
  5528. 1HPlease type a space to go on, or B or Q to go back to the question.                                                              1755 444B438Q438$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              1.  CONSTRAINT_ERROR
  5529.  
  5530.                               2.  NUMERIC_ERROR
  5531.  
  5532.                               3.  PROGRAM_ERROR
  5533.  
  5534.                               4.  STORAGE_ERROR
  5535.  
  5536.                               5.  TASKING_ERROR
  5537.  
  5538.  
  5539. No, NUMERIC_ERROR is usually raised by arithmetic overflow, or attempted
  5540. division by zero.
  5541. 1HPlease type a space to go on, or B or Q to go back to the question.                     1769 444B438Q438$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              1.  CONSTRAINT_ERROR
  5542.  
  5543.                               2.  NUMERIC_ERROR
  5544.  
  5545.                               3.  PROGRAM_ERROR
  5546.  
  5547.                               4.  STORAGE_ERROR
  5548.  
  5549.                               5.  TASKING_ERROR
  5550.  
  5551.  
  5552. No, PROGRAM_ERROR is usually raised by skipping around the return{;4}m statement in
  5553. a function.
  5554. 1HPlease type a space to go on, or B or Q to go back to the question.       1717 444B438Q438$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              1.  CONSTRAINT_ERROR
  5555.  
  5556.                               2.  NUMERIC_ERROR
  5557.  
  5558.                               3.  PROGRAM_ERROR
  5559.  
  5560.                               4.  STORAGE_ERROR
  5561.  
  5562.                               5.  TASKING_ERROR
  5563.  
  5564.  
  5565. No, STORAGE_ERROR is raised by running out of memory.
  5566. 1HPlease type a space to go on, or B or Q to go back to the question.                                                           1756 444B438Q438$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              1.  CONSTRAINT_ERROR
  5567.  
  5568.                               2.  NUMERIC_ERROR
  5569.  
  5570.                               3.  PROGRAM_ERROR
  5571.  
  5572.                               4.  STORAGE_ERROR
  5573.  
  5574.                               5.  TASKING_ERROR
  5575.  
  5576.  
  5577. No, TASKING_ERROR is raised only by programs using tasking, which we haven't
  5578. yet discussed.
  5579. 1HPlease type a space to go on, or B or Q to go back to the question.                    2935 445B438$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A block construct lets us declare objects in the executable{;4}m region of the
  5580. program.  For example, in the following, I and F come into existence where
  5581. they're declared, and go out of existence at the following end{;4}m statement:
  5582.  
  5583.                             procedure BLOCK_DEMO is
  5584.                                Q : FLOAT;
  5585.                             begin
  5586.                                Q := 0.0;
  5587.                                declare
  5588.                                   I : INTEGER;
  5589.                                   F : FLOAT;
  5590.                                begin
  5591.                                   I := 5;
  5592.                                   F := Q;
  5593.                                end;{;4}m
  5594.                                Q := Q + 3.0;
  5595.                             end BLOCK_DEMO;
  5596.  
  5597. However, the usual use of a block is to localize an exception handler, not to
  5598. bring objects into existence in the executable region of a program.  The
  5599. declarative part of the block is optional.  For example, let's rewrite
  5600. EXCEPTION_DEMO to make use of a block with an exception handler.
  5601. 1HPlease type a space to go on, or B to go back.                                         2448 446B444$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       with TEXT_IO; use TEXT_IO;
  5602.        procedure EXCEPTION_DEMO is
  5603.           package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  5604.           I     : INTEGER;
  5605.           WRONG : exception;
  5606.        begin
  5607.           loop
  5608.              begin{;4}m
  5609.                 NEW_LINE(2);  PUT("Type a positive integer. ");  GET(I);
  5610.                 if I <= 0 then
  5611.                    raise WRONG;
  5612.                 end if;
  5613.                 PUT("The square is ... ");
  5614.                 PUT(I*I);
  5615.              exception{;4}m
  5616.                 when CONSTRAINT_ERROR | NUMERIC_ERROR =>
  5617.                    PUT(" ... too big.");
  5618.                 when WRONG =>
  5619.                    NEW_LINE;  PUT("I said POSITIVE integer!");
  5620.              end;{;4}m
  5621.           end loop;
  5622.        end EXCEPTION_DEMO;
  5623. 1HPlease type a space to go on, or B to go back.                            3553 447B445$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Note that in our rewritten program, a block with an exception handler has been
  5624. created inside the loop.  Now, if an exception occurs, the handler will be
  5625. executed instead of the rest of the block{;4}m, not the rest of the procedure{;4}m.
  5626. Thus, the loop will still be executed, and the program will continue to ask
  5627. for integers after an exception is handled.
  5628.  
  5629. There are two advantages to confining exception handlers to small blocks.
  5630. First, we narrow down the range of statements that might have raised the
  5631. exception.  Recall that the handler can't test which line raised the exception,
  5632. but it must have been one of the lines in the block.  (If an exception is
  5633. raised outside the block, our program provides no handler for it.)  Second,
  5634. program execution will continue after the end of the block.
  5635.  
  5636. If an exception occurs for which there's no handler, the exception reaches the
  5637. next higher level.  For example, if the block in EXCEPTION_DEMO somehow raises
  5638. STORAGE_ERROR and doesn't handle it, an exception handler for the whole
  5639. procedure would get a chance to handle it.  (In our case, there is none.)  If
  5640. it's still unhandled, it's as if the call{;4}m to EXCEPTION_DEMO raised
  5641. STORAGE_ERROR.  If the caller doesn't handle it, the exception reaches the
  5642. caller's caller, etc.  If the exception reaches the main program and is still
  5643. unhandled, the program is stopped and the system prints the name of the
  5644. exception.  However, exceptions that are handled don't reach the caller.
  5645. 1HPlease type a space to go on, or B to go back.                       3219 448B446$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In the unusual case of an exception raised in the declarative{;4}m region, the unit
  5646. raising the exception (subprogram, block, etc.) is not{;4}m given a chance to handle
  5647. it.  Exceptions raised in the declarative region immediately reach the next
  5648. higher level.
  5649.  
  5650. In a handler, the word raise{;4}m may be used without a name of an exception to
  5651. re-raise whatever exception brought control to the handler.  This is especially
  5652. useful after when others =>{;4}m, because any one of a number of exceptions might
  5653. have transferred control there.  For example,
  5654.  
  5655.                  when others =>
  5656.                     PUT_LINE("I don't know what went wrong.");
  5657.                     -- Close files and do general cleanup.
  5658.                     raise;{;4}m
  5659.  
  5660. This lets us do some processing of the error, and still lets the next higher
  5661. level do additional processing.  Note that it's superfluous to say simply when
  5662. others => raise;{;4}m because the exception will reach the next higher level even if
  5663. that code is omitted.  Any unhandled exception reaches the next higher level.
  5664.  
  5665. An error occurring in an exception handler{;4}m is unhandled and reaches the next
  5666. higher level (unless it occurs in a block with its own exception handler).
  5667. 1HPlease type a space to go on, or B to go back.                                                         234524491450B447$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q          with TEXT_IO; use TEXT_IO;             separate (ONE)
  5668.           procedure ONE is                       procedure TWO is
  5669.              procedure TWO is separate;             CAIN : exception;
  5670.           begin                                  begin
  5671.              TWO;                                   raise CAIN;
  5672.           exception                              exception
  5673.              when others =>                         when others =>
  5674.                 PUT_LINE("1");                         PUT_LINE("2");
  5675.           end ONE;                               end TWO;
  5676.  
  5677.  
  5678.                        What will the above program print?
  5679.  
  5680.                        1.  The program will print 1.
  5681.  
  5682.                        2.  The program will print 2.
  5683. 1HPlease press 1 or 2, or B to go back.                               2328 451B448Q448$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$          with TEXT_IO; use TEXT_IO;             separate (ONE)
  5684.           procedure ONE is                       procedure TWO is
  5685.              procedure TWO is separate;             CAIN : exception;
  5686.           begin                                  begin
  5687.              TWO;                                   raise CAIN;{;4}m
  5688.           exception                              exception
  5689.              when others =>                         when others =>{;4}m
  5690.                 PUT_LINE("1");                         PUT_LINE("2");{;4}m
  5691.           end ONE;                               end TWO;
  5692.  
  5693.  
  5694. You're right!{;4}m  TWO handles the exception, so it never reaches ONE.
  5695. 1HPlease type a space to go on, or B or Q to go back to the question.                                                2225 451B448Q448$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$          with TEXT_IO; use TEXT_IO;             separate (ONE)
  5696.           procedure ONE is                       procedure TWO is
  5697.              procedure TWO is separate;             CAIN : exception;
  5698.           begin                                  begin
  5699.              TWO;                                   raise CAIN;
  5700.           exception                              exception
  5701.              when others =>                         when others =>
  5702.                 PUT_LINE("1");                         PUT_LINE("2");
  5703.           end ONE;                               end TWO;
  5704.  
  5705.  
  5706. No, TWO handles the exception, so it never reaches ONE.
  5707. 1HPlease type a space to go on, or B or Q to go back to the question.                                                   3132 452B448$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                               MORE ABOUT TEXT_IO
  5708.  
  5709. We're almost ready for Outside Assignment 5.  For that assignment, we had to
  5710. cover type TEXT, access types, and exceptions.  We also need to learn a little
  5711. more about TEXT_IO before we do the assignment.
  5712.  
  5713. TEXT_IO is used for input and output to and from text files as well as input
  5714. and output to and from the terminal.  Text files are files that can be listed
  5715. at the terminal.  (Binary files and random access files are handled with the
  5716. packages SEQUENTIAL_IO and DIRECT_IO, which will be discussed in the Advanced
  5717. Topics section.)
  5718.  
  5719. The full specification of TEXT_IO appears in section 14.3.10 of the LRM.  It's
  5720. rather long, and some of the procedures and functions are rarely used.  So
  5721. there's a simplified specification of TEXT_IO in your printed course notes,
  5722. starting on page 14.  Please consult your printed course notes during the
  5723. following discussion.
  5724.  
  5725. Note that there's a limited private type called FILE_TYPE.  For each file that
  5726. our program will use, we must create an object of this type, for example,
  5727. F1, F2 : FILE_TYPE;{;4}m.  We can then use these objects in the procedures CREATE
  5728. and OPEN, to associate file names with the objects of type FILE_TYPE.
  5729. 1HPlease type a space to go on, or B to go back.                                            3468 453B451$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Note that the I/O procedures, such as NEW_LINE, PUT, and GET, have one version
  5730. for use with the terminal, and another version for use with a file.  The file
  5731. version takes an object of type FILE_TYPE, not{;4}m the name of the file.  The file
  5732. must first have been CREATEd or OPENed.
  5733.  
  5734. The exception STATUS_ERROR is raised by trying to do I/O on a closed file.
  5735. MODE_ERROR is raised by trying to read from a file opened or created with mode
  5736. OUT_FILE, or by trying to write to a file of mode IN_FILE.  NAME_ERROR is
  5737. raised by trying to OPEN a file that doesn't exist, or by trying to CREATE a
  5738. file with a name not allowed by the system.  END_ERROR is raised by trying to
  5739. read past an end-of-file.
  5740.  
  5741. NEW_LINE creates one or more blank lines on output{;4}m, and SKIP_LINE skips one or
  5742. more lines of input{;4}m.  We can PUT characters and strings, and we can PUT_LINE a
  5743. string.  We can GET a character, and GET_LINE a string.  Note that when we
  5744. GET_LINE a string, the procedure returns the number of characters that were in
  5745. the line.  Thus, if we have S : STRING(1 .. 80);  LEN : INTEGER;{;4}m and we execute
  5746. GET_LINE(S, LEN);{;4}m and the user types Hello{;4}m, LEN will be set to 5, S(1 .. 5)
  5747. will be set to "Hello", and the rest of S will be unmodified.
  5748.  
  5749. The generic package INTEGER_IO can be instantiated for any integer type,
  5750. including user-defined types and derived types like COUNTER and NO_OF_APPLES.
  5751. 1HPlease type a space to go on, or B to go back.        2825 454B452$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$When we call PUT in our instantiation of INTEGER_IO, we can optionally specify
  5752. the width and the base.
  5753.  
  5754. The generic package FLOAT_IO can be instantiated for any floating point type,
  5755. such as FLOAT and the user-defined type REAL that we created earlier.  PUT
  5756. allows us optionally to specify the number of places before and after the
  5757. decimal point, and the size of the optional exponent field.
  5758.  
  5759. The generic package ENUMERATION_IO can be instantiated for any enumeration
  5760. type.  PUT allows us optionally to specify the width.
  5761.  
  5762. TEXT_IO contains another generic package FIXED_IO for fixed point types, not
  5763. shown in our simplified version.  Fixed point types will be discussed in the
  5764. Advanced Topics section.
  5765.  
  5766. To illustrate the use of TEXT_IO, here's a simple program that prompts for the
  5767. names of an old input file and a new output file, and copies the input file to
  5768. the output.  It's assumed that the input file is an ASCII text file no wider
  5769. than 80 characters, and that it contains no special control characters such as
  5770. form feeds:
  5771. 1HPlease type a space to go on, or B to go back.                                                   2631 455B453$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$         with TEXT_IO; use TEXT_IO;
  5772.          procedure FILECOPY is
  5773.             F1, F2 : FILE_TYPE;
  5774.             S      : STRING(1 .. 80);
  5775.             LEN    : INTEGER;
  5776.          begin
  5777.             PUT("Input file: ");  GET_LINE(S, LEN);
  5778.             OPEN(FILE => F1, MODE => IN_FILE, NAME => S(1 .. LEN));
  5779.             PUT("Output file: ");  GET_LINE(S, LEN);
  5780.             CREATE(FILE => F2, MODE => OUT_FILE, NAME => S(1 .. LEN));
  5781.             while not END_OF_FILE(F1) loop
  5782.                GET_LINE(F1, S, LEN);
  5783.                PUT_LINE(F2, S(1 .. LEN));
  5784.             end loop;
  5785.             CLOSE(F1);
  5786.             CLOSE(F2);
  5787.          end FILECOPY;{;4}m
  5788.  
  5789. In many systems, all files are closed automatically when the main program
  5790. terminates, and this program would work even without CLOSE(F1);{;4}m and CLOSE(F2);{;4}m.
  5791.  
  5792. This program also appears on page 16 of your printed course notes.
  5793. 1HPlease type a space to go on, or B to go back.                                             2548 456B454$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$As this is written (December, 1988), there's no way to test whether a file
  5794. already exists without trying to OPEN it and trapping the NAME_ERROR if the
  5795. file doesn't exist.  There's talk of enhancing TEXT_IO with the next revision
  5796. (9X) of the Ada standard.
  5797.  
  5798. The following function determines whether a file name represents an existing
  5799. file.  It appears on page 16 of your printed course notes:
  5800.  
  5801.             with TEXT_IO; use TEXT_IO;
  5802.             function EXISTS(FILE_NAME : in STRING) return BOOLEAN is
  5803.                F      : FILE_TYPE;
  5804.                ANSWER : BOOLEAN := TRUE;
  5805.             begin
  5806.                begin
  5807.                   OPEN(F, IN_FILE, FILE_NAME);
  5808.                   CLOSE(F);
  5809.                exception
  5810.                   when NAME_ERROR => ANSWER := FALSE;
  5811.                end;
  5812.                return ANSWER;
  5813.             end EXISTS;{;4}m
  5814. 1HPlease type a space to go on, or B to go back.                            16211457245834594460B455$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q                                1.  STATUS_ERROR
  5815.  
  5816.                                 2.  MODE_ERROR
  5817.  
  5818.                                 3.  NAME_ERROR
  5819.  
  5820.                                 4.  END_ERROR
  5821.  
  5822.  
  5823.       Which exception is raised by attempting to do I/O on a closed file?
  5824. 1HPlease press 1, 2, 3, or 4, or B to go back.                                                       1714 461B456Q456$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                1.  STATUS_ERROR{;4}m
  5825.  
  5826.                                 2.  MODE_ERROR
  5827.  
  5828.                                 3.  NAME_ERROR
  5829.  
  5830.                                 4.  END_ERROR
  5831.  
  5832.  
  5833. You're right!{;4}m  STATUS_ERROR is raised by an attempt to do I/O on a closed file.
  5834. 1HPlease type a space to go on, or B or Q to go back to the question.                                                              1720 461B456Q456$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                1.  STATUS_ERROR
  5835.  
  5836.                                 2.  MODE_ERROR
  5837.  
  5838.                                 3.  NAME_ERROR
  5839.  
  5840.                                 4.  END_ERROR
  5841.  
  5842.  
  5843. No, MODE_ERROR is raised by an attempt to read from a file of mode OUT_FILE, or
  5844. write to a file of mode IN_FILE.
  5845. 1HPlease type a space to go on, or B or Q to go back to the question.                                                        1720 461B456Q456$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                1.  STATUS_ERROR
  5846.  
  5847.                                 2.  MODE_ERROR
  5848.  
  5849.                                 3.  NAME_ERROR
  5850.  
  5851.                                 4.  END_ERROR
  5852.  
  5853.  
  5854. No, NAME_ERROR is raised by an attempt to OPEN a file that doesn't exist, or
  5855. CREATE a file with an illegal name.
  5856. 1HPlease type a space to go on, or B or Q to go back to the question.                                                        1637 461B456Q456$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                1.  STATUS_ERROR
  5857.  
  5858.                                 2.  MODE_ERROR
  5859.  
  5860.                                 3.  NAME_ERROR
  5861.  
  5862.                                 4.  END_ERROR
  5863.  
  5864.  
  5865. No, END_ERROR is raised by an attempt to read past an end-of-file.
  5866. 1HPlease type a space to go on, or B or Q to go back to the question.                                       3440 462B456$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A              OUTSIDE ASSIGNMENT 5 - WRITING A SIMPLE LINE EDITOR
  5867.  
  5868. We're finally ready for the next Outside Assignment!  This assignment will give
  5869. you a chance to write a program of greater complexity than the previous
  5870. assignments.  By the time you've completed Outside Assignment 5, you should
  5871. feel comfortable with Ada.  The full set of requirements for the line editor we
  5872. want you to write are in your printed course notes, starting on page 17.  We'll
  5873. discuss them briefly here.  No test driver is supplied, but after you've
  5874. written the program, we'll give you some tests to perform manually on your line
  5875. editor.  You've completed the assignment when your editor passes all the tests.
  5876.  
  5877. Imagine that your screen editor is unavailable to a particular user, perhaps
  5878. because he's dialing your computer from a remote location, and your screen
  5879. editor writes directly to the screen.  You want to write a line editor.  While
  5880. your computer already has a line editor called EDLIN, it's difficult to learn
  5881. to use.  The line editor you'll write, called LEDIT, will take almost no effort
  5882. to learn.  The only commands are LIST and EXIT.
  5883.  
  5884. The user begins each line of text with a line number, similar to Basic.  Line
  5885. numbers must be integers between 1 and 29999.  Regardless of the order in which
  5886. lines are entered, LEDIT maintains a linked list of lines in order by number,
  5887. so that it can LIST the text in order, or write it to a file.
  5888. 1HPlease type a space to go on, or B to go back.                                    2038 463B461$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Line numbers need not be consecutive, and they may be preceded by any number of
  5889. spaces.  For example, if we type
  5890.  
  5891. 40 -- This is a comment.
  5892.    20 begin
  5893. 10 with TEXT_IO; use TEXT_IO;
  5894.       30 end ADD;{;4}m
  5895.  
  5896. and then type LIST{;4}m, the editor displays
  5897.  
  5898.    10 with TEXT_IO; use TEXT_IO;
  5899.    20 begin
  5900.    30 end ADD;
  5901.    40 -- This is a comment.
  5902.  
  5903. To insert{;4}m lines, we merely type lines with intermediate line numbers.  In our
  5904. example, if we now type
  5905.  
  5906. 15 procedure HELLO is
  5907. LIST{;4}m
  5908.  
  5909. we'll see
  5910. 1HPlease type a space to go on, or B to go back.                                      1920 464B462$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   10 with TEXT_IO; use TEXT_IO;
  5911.    15 procedure HELLO is
  5912.    20 begin
  5913.    30 end ADD;
  5914.    40 -- This is a comment.
  5915.  
  5916. To replace{;4}m a line, we simply retype the line with the same line number as the
  5917. line to be replaced, and to delete{;4}m a line, we type only the line number.  If
  5918. we now type
  5919.  
  5920. 15 procedure ADD is
  5921. 40
  5922. LIST{;4}m
  5923.  
  5924. we'll see
  5925.  
  5926.    10 with TEXT_IO; use TEXT_IO;
  5927.    15 procedure ADD is
  5928.    20 begin
  5929.    30 end ADD;
  5930. 1HPlease type a space to go on, or B to go back.                                                        2558 465B463$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Thus the user can insert, replace, and delete lines by line numbers, without
  5931. learning any commands!  If the user forgets the space after the line number, no
  5932. harm is done; LEDIT takes 20begin{;4}m the same as 20 begin{;4}m.  However, the user can
  5933. indent code by adding extra{;4}m spaces after the line number.  The following
  5934. example has three extra{;4}m spaces after each line number (four spaces total):
  5935.  
  5936. 24    PUT(2 + 2);
  5937. 26    NEW_LINE;
  5938. 18    package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  5939. LIST{;4}m
  5940.  
  5941.    10 with TEXT_IO; use TEXT_IO;
  5942.    15 procedure ADD is
  5943.    18    package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  5944.    20 begin
  5945.    24    PUT(2 + 2);
  5946.    26    NEW_LINE;
  5947.    30 end ADD;
  5948.  
  5949. When LISTing, LEDIT always allows exactly five spaces for the line number, so
  5950. that the text lines up correctly:
  5951. 1HPlease type a space to go on, or B to go back.                  2458 466B464$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$LIST{;4}m
  5952.  
  5953.     2 This is a sample listing,
  5954.    20 showing how the text
  5955.   200 lines up, even when
  5956.  2000 some line numbers are
  5957. 20000 longer than others.
  5958.  
  5959. When we type EXIT{;4}m, LEDIT writes the output file without{;4}m the line numbers.  The
  5960. text above would all start in column 1 of the output file.
  5961.  
  5962. For LEDIT to be useful with files larger than a page, it must be possible to
  5963. list a range of lines:
  5964.  
  5965. LIST 20 - 30{;4}m
  5966.  
  5967. This is only a summary of the requirements for LEDIT.  Please refer to pages
  5968. 17-21 of your printed course notes for the actual requirements.  As a point of
  5969. reference, our solution requires about 180 lines of Ada on four pages.
  5970.  
  5971. Here are the steps to follow for Outside Assignment 5.  They can also be found
  5972. in the printed course notes on page 22:
  5973. 1HPlease type a space to go on, or B to go back.                  2422 467B465$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$1.  Carefully read the requirements starting on page 17 of the printed course
  5974.     notes.  Take your time.
  5975.  
  5976. 2.  Write the Ada code, compile, and link.  Call the main program LEDIT.  If
  5977.     you have any questions about what LEDIT should do, you can compile and run
  5978.     our solution, which is in LEDIT.ANS.
  5979.  
  5980. 3.  Refer to pages 23-25 of the printed course notes for instructions on
  5981.     testing your line editor.  If any tests are failed, go back to step 2.
  5982.  
  5983. 4.  When all the tests are passed, you've completed the assignment and will
  5984.     have a chance to compare your solution with ours.
  5985.  
  5986.  
  5987. Please type X to exit ADA-TUTR{;4}m temporarily, and try Outside Assignment 5.  It
  5988. will probably take several days.  Take your time; there's no deadline.  Good
  5989. luck!
  5990. 1HPlease type X to exit, a space to go on, or B to go back.                                                      2137 468B466$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              Congratulations on Completing Outside Assignment 5!{;4}m
  5991.  
  5992. If you like, you can compare your solution with ours, which is in LEDIT.ANS.  A
  5993. listing starts on page 26 of your printed course notes.  Note that a single
  5994. procedure handles adding, deleting, and replacing lines.  Replacing is done by
  5995. first deleting, then adding a line.
  5996.  
  5997. Your solution might be very different from ours, but if it passed all the
  5998. tests, consider it correct.
  5999.  
  6000. Early in this course we used the generic package INTEGER_IO.  Let's now learn
  6001. how to write our own generic packages, procedures, and functions.
  6002. 1HPlease type a space to go on, or B to go back.                                       2136 469B467$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  6003.  
  6004.    Introduction                             Records, Arrays, and Assignment 3
  6005.  
  6006.    The Format of an Ada Program             Recursion and Assignment 4
  6007.  
  6008.    Generic Instantiation and                Subprograms and Packages
  6009.       Assignment 1
  6010.                                             Additional Types, Exceptions,
  6011.    Simple Declarations and Simple              TEXT_IO, and Assignment 5
  6012.       Attributes
  6013.                                          >  GENERICS, TASKING, AND ASSIGNMENT 6{;4}m
  6014.    Operators, Control Constructs, and
  6015.       Assignment 2                          Advanced Topics
  6016. 1HPlease type a space to go on, or B to go back.                                        2934 470B468$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    GENERICS
  6017.  
  6018. It would be easy to write a package that creates a single stack of 10 INTEGERs,
  6019. and lets us PUSH and POP on it.  However, the code would be about the same
  6020. regardless of the size of the stack, and regardless of the type of objects on
  6021. the stack.  For example, a second package that creates a stack of 50 DATEs
  6022. would look about the same.  We can write one generic{;4}m package, and instantiate
  6023. it for any size and almost any type we need.  The specification is:
  6024.  
  6025.                      generic
  6026.                         SIZE : POSITIVE;
  6027.                         type DUMMY is private;
  6028.                      package STACK_PACKAGE is
  6029.                         procedure PUSH(OBJECT : in DUMMY);
  6030.                         function POP return DUMMY;
  6031.                      end STACK_PACKAGE;{;4}m
  6032.  
  6033. Since both SIZE and type DUMMY are generic, both must be specified when we
  6034. instantiate the package:
  6035.  
  6036.         package STACK_OF_10_INTEGERS is new STACK_PACKAGE(10, INTEGER);
  6037.         package STACK_OF_50_DATES    is new STACK_PACKAGE(50, DATE);{;4}m
  6038. 1HPlease type a space to go on, or B to go back.                                          3645 471B469$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$If the generic part says type DUMMY is private;{;4}m then the subprogram or package
  6039. body may do only three things with objects of type DUMMY: create them, assign
  6040. them, and test them for equality or inequality.  Note that this is similar to
  6041. the list of things we may do with a private type outside{;4}m an ordinary package.
  6042. In this case, we're listing what we can do inside{;4}m the generic package.  Calling
  6043. the package's subprograms isn't on our list, because they're not written yet!
  6044. We're listing the things we can do when we write the body of the package.  Of
  6045. course, once we write some subprograms, other subprograms can call them.
  6046.  
  6047. Although we can do only three things with objects of a private type inside a
  6048. generic package, we can instantiate that package with almost any type at all.
  6049. Our STACK_PACKAGE can be instantiated for DATEs, STRINGs (see the next
  6050. paragraph), RAINBOW_COLORs, FLOATs, and any type for which we can assign
  6051. objects and test them for equality.  That means any type except a limited
  6052. private type.  We can't instantiate STACK_PACKAGE for type TEXT_IO.FILE_TYPE
  6053. (a limited private type), because in our package we're allowed to assign and
  6054. test for equality objects of type DUMMY.
  6055.  
  6056. Since we can't create objects of an unconstrained array type, if we want to
  6057. instantiate STACK_PACKAGE for STRINGs, we must use a constrained subtype of
  6058. STRING.  For example, we could write subtype NAME is STRING(1 .. 30);{;4}m and then
  6059. write package STACK_OF_50_NAMES is new STACK_PACKAGE(50, NAME);{;4}m.
  6060. 1HPlease type a space to go on, or B to go back.                               3171 472B470$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$We could instantiate our package even for limited private types like
  6061. TEXT_IO.FILE_TYPE if the generic part had said type DUMMY is limited private;{;4}m.
  6062. However, the only thing our package could do with objects of that type is
  6063. create them.  Ordinarily, that's not very useful.
  6064.  
  6065. If the generic part says type DUMMY is ( <> );{;4}m then we can instantiate the
  6066. package (or subprogram) for any discrete type.  That means any enumeration or
  6067. integer type: CHARACTER, BOOLEAN, COUNTER, NO_OF_APPLES, etc.  Inside the
  6068. package, attributes like 'FIRST are available.
  6069.  
  6070. If the generic part says type DUMMY is range <>;{;4}m then we can instantiate for
  6071. any integer type.  Inside the package, we can do things that can be done with
  6072. all integer types, such as add, etc.
  6073.  
  6074. If the generic part says type DUMMY is delta <>;{;4}m then we can instantiate for
  6075. any fixed point type, to be discussed in the Advanced Topics section.
  6076.  
  6077. Finally, if the generic part says type DUMMY is digits <>;{;4}m then we can
  6078. instantiate for any floating point type, such as FLOAT or the REAL we created.
  6079.  
  6080. The specification of a generic subprogram must be given separately from the
  6081. body.  For example, we can't eliminate the highlighted line in this function:
  6082. 1HPlease type a space to go on, or B to go back.     2431 473B471$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        generic
  6083.            type DUMMY_FLOAT is digits <>;
  6084.            type DUMMY_VECTOR is array (INTEGER range <>) of DUMMY_FLOAT;
  6085.         function SUM(V : in DUMMY_VECTOR) return DUMMY_FLOAT;{;4}m
  6086.         function SUM(V : in DUMMY_VECTOR) return DUMMY_FLOAT is
  6087.           ANSWER : DUMMY_FLOAT := 0.0;
  6088.         begin
  6089.            for I in V'RANGE loop
  6090.               ANSWER := ANSWER + V(I);
  6091.             end loop;
  6092.            return ANSWER;
  6093.         end SUM;
  6094.  
  6095. We can instantiate SUM and call it as follows:
  6096.  
  6097.                 type VECTOR is array(INTEGER range <>) of FLOAT;
  6098.                 V1 : VECTOR(1 .. 10);
  6099.                 X  : FLOAT;
  6100.                 function SUMV is new SUM(FLOAT, VECTOR);{;4}m
  6101.                 ...
  6102.                 X := SUMV(V1);{;4}m
  6103. 1HPlease type a space to go on, or B to go back.                                             2031347414752476B472$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q         generic
  6104.             type DUMMY is range <>;
  6105.          procedure DISPLAY(ITEM : in DUMMY);
  6106.  
  6107.          type NO_OF_APPLES is new INTEGER;
  6108.          type COUNTER is range 0 .. 1_000_000;
  6109.          type ANSWER is (YES, NO, MAYBE);
  6110.          procedure DISPLAY_APPLES   is new DISPLAY(NO_OF_APPLES);  -- 1
  6111.          procedure DISPLAY_COUNTERS is new DISPLAY(COUNTER);       -- 2
  6112.          procedure DISPLAY_ANSWERS  is new DISPLAY(ANSWER);        -- 3
  6113.  
  6114.  
  6115.          Which commented line in the above program segment is illegal{;4}m?
  6116. 1HPlease press 1, 2, or 3, or B to go back.                                             2264 477B473Q473$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$         generic
  6117.             type DUMMY is range <>;
  6118.          procedure DISPLAY(ITEM : in DUMMY);
  6119.  
  6120.          type NO_OF_APPLES is new INTEGER;
  6121.          type COUNTER is range 0 .. 1_000_000;
  6122.          type ANSWER is (YES, NO, MAYBE);
  6123.          procedure DISPLAY_APPLES   is new DISPLAY(NO_OF_APPLES);  -- 1
  6124.          procedure DISPLAY_COUNTERS is new DISPLAY(COUNTER);       -- 2
  6125.          procedure DISPLAY_ANSWERS  is new DISPLAY(ANSWER);        -- 3{;4}m
  6126.  
  6127.  
  6128. You're right!{;4}m  When the generic part says type DUMMY is range <>;{;4}m, the
  6129. procedure may be instantiated for any integer type.  ANSWER is a discrete type,
  6130. but not an integer type.
  6131. 1HPlease type a space to go on, or B or Q to go back to the question.            2243 477B473Q473$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$         generic
  6132.             type DUMMY is range <>;
  6133.          procedure DISPLAY(ITEM : in DUMMY);
  6134.  
  6135.          type NO_OF_APPLES is new INTEGER;
  6136.          type COUNTER is range 0 .. 1_000_000;
  6137.          type ANSWER is (YES, NO, MAYBE);
  6138.          procedure DISPLAY_APPLES   is new DISPLAY(NO_OF_APPLES);  -- 1
  6139.          procedure DISPLAY_COUNTERS is new DISPLAY(COUNTER);       -- 2
  6140.          procedure DISPLAY_ANSWERS  is new DISPLAY(ANSWER);        -- 3
  6141.  
  6142.  
  6143. No, when the generic part says type DUMMY is range <>;{;4}m, the procedure may be
  6144. instantiated for any integer type.  NO_OF_APPLES is a type derived from
  6145. INTEGER, so it's an integer type.
  6146. 1HPlease type a space to go on, or B or Q to go back to the question.                                 2322 477B473Q473$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$         generic
  6147.             type DUMMY is range <>;
  6148.          procedure DISPLAY(ITEM : in DUMMY);
  6149.  
  6150.          type NO_OF_APPLES is new INTEGER;
  6151.          type COUNTER is range 0 .. 1_000_000;
  6152.          type ANSWER is (YES, NO, MAYBE);
  6153.          procedure DISPLAY_APPLES   is new DISPLAY(NO_OF_APPLES);  -- 1
  6154.          procedure DISPLAY_COUNTERS is new DISPLAY(COUNTER);       -- 2
  6155.          procedure DISPLAY_ANSWERS  is new DISPLAY(ANSWER);        -- 3
  6156.  
  6157.  
  6158. No, when the generic part says type DUMMY is range <>;{;4}m, the procedure may be
  6159. instantiated for any integer type.  The definition of the user-defined type
  6160. COUNTER has the word range{;4}m, so COUNTER is an integer type.
  6161. 1HPlease type a space to go on, or B or Q to go back to the question.                                                      3136 478B473$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    TASKING
  6162.  
  6163. Here are two versions of a program with two parallel tasks.  Since the main
  6164. program is a task, these two versions are equivalent.
  6165.  
  6166.          with TEXT_IO; use TEXT_IO;         with TEXT_IO; use TEXT_IO;
  6167.          procedure TASK_DEMO is                procedure TASK_DEMO is
  6168.             task A;                            task A;
  6169.             task body A is                     task body A is
  6170.             begin                              begin
  6171.                PUT_LINE("a");                     PUT_LINE("a");
  6172.                PUT_LINE("a");                     PUT_LINE("a");
  6173.             end A;                             end A;{;4}m
  6174.          begin                                 task B;
  6175.             PUT_LINE("b");                     task body B is
  6176.             PUT_LINE("b");                     begin{;4}m
  6177.          end TASK_DEMO;                           PUT_LINE("b");
  6178.                                                   PUT_LINE("b");
  6179.                                                end B;{;4}m
  6180.                                             begin
  6181.                                                null;
  6182.                                             end TASK_DEMO;
  6183. 1HPlease type a space to go on, or B to go back.                                        2762 479B477$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Our program could have specified as many tasks as we like.  Also, our tasks
  6184. could have declarations between task body{;4}m and begin{;4}m.  If the computer has
  6185. several processors, and the Ada compiler makes use of that fact, the tasks
  6186. could actually run simultaneously.  Otherwise, the compiler may (but doesn't
  6187. have to) write code to time slice{;4}m among the tasks, making them appear{;4}m to run
  6188. simultaneously.  One version of Ada we tried time slices, and the output of the
  6189. program looked something like this:
  6190.  
  6191. ba
  6192.  
  6193. ba
  6194.  
  6195.  
  6196. This happened because PUT_LINE is equivalent to PUT plus NEW_LINE, and thus
  6197. PUT_LINE can get interrupted before the CR-LF is output.  Here one task printed
  6198. "b", the other task printed "a", and then both tasks sent CR-LF.
  6199.  
  6200. Another implementation of Ada we tried won't time-slice unless told to with a
  6201. pragma{;4}m, covered in the Advanced Topics section.  So the output of the same
  6202. program with that version of Ada looked like this:
  6203. 1HPlease type a space to go on, or B to go back.              2453 480B478$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$a
  6204. a
  6205. b
  6206. b
  6207.  
  6208. In this case one task ran to completion before the other task started.  The
  6209. point is that both versions of Ada ran our program correctly, but with
  6210. different results.
  6211.  
  6212. When data is passed between tasks, we often don't want the process interrupted.
  6213. For example, suppose one task updates a record with several fields, such as a
  6214. DATE.  Another task reads the record.  We don't want the second task to
  6215. interrupt the first in the middle of updating a record.  Otherwise, the second
  6216. task might read an updated DAY field, an updated MONTH field, and an old YEAR
  6217. field, which would be meaningless.  Ada has an elegant solution to this
  6218. problem, called the rendezvous{;4}m.
  6219.  
  6220. In this example, we assume that the main program created both procedure CALLER
  6221. and task SERVER, and defined type DATE:
  6222. 1HPlease type a space to go on, or B to go back.                       3244 481B479$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$      procedure CALLER is          task SERVER is
  6223.          D : DATE;                    entry UPDATE(ITEM : in out DATE);
  6224.                                    end SERVER;
  6225.       begin                        task body SERVER is
  6226.          -----;{;4}m                    begin
  6227.          -----;  -- Block 1           -----;  -- Block 3
  6228.          -----;                       -----;
  6229.                                       accept UPDATE(ITEM : in out DATE) do
  6230.          SERVER.UPDATE(D);               -----;  -- Block 4
  6231.                                          -----;
  6232.          -----;                       end UPDATE;
  6233.          -----;  -- Block 2           -----;  -- Block 5
  6234.          -----;                       -----;{;4}m
  6235.       end CALLER;                  end SERVER;
  6236.  
  6237. Code blocks 1 and 3 run in parallel (perhaps simultaneously, as discussed).
  6238. Then CALLER waits at the call to SERVER.UPDATE while SERVER executes block 4.
  6239. Block 4 is called the critical section of code, where records might be updated,
  6240. etc.  When this rendezvous{;4}m is over, blocks 2 and 5 run in parallel.  If CALLER
  6241. reaches the call before SERVER reaches accept{;4}m, CALLER will wait patiently
  6242. there for SERVER.  If SERVER reaches accept{;4}m first, it will wait patiently there
  6243. for a caller.
  6244. 1HPlease type a space to go on, or B to go back.                                3553 482B480$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$      procedure CALLER is          task SERVER is
  6245.          D : DATE;                    entry{;4}m UPDATE(ITEM : in out DATE);
  6246.                                    end SERVER;
  6247.       begin                        task body SERVER is
  6248.          -----;                    begin
  6249.          -----;  -- Block 1           -----;  -- Block 3
  6250.          -----;                       -----;
  6251.                                       accept{;4}m UPDATE(ITEM : in out DATE) do{;4}m
  6252.          SERVER.UPDATE(D);{;4}m               -----;  -- Block 4
  6253.                                          -----;
  6254.          -----;                       end UPDATE;
  6255.          -----;  -- Block 2           -----;  -- Block 5
  6256.          -----;                       -----;
  6257.       end CALLER;                  end SERVER;
  6258.  
  6259. The call to UPDATE looks like a procedure call.  We can't use{;4}m a task, so the
  6260. call requires dot notation.  The entry{;4}m statement looks like a procedure
  6261. specification, with entry{;4}m replacing procedure{;4}m.  The task specification may have
  6262. any number of entry{;4}m statements; if it has none, we write simply task SERVER;{;4}m.
  6263. The accept{;4}m block looks like a procedure without declarations, but accept{;4}m
  6264. replaces procedure{;4}m, and do{;4}m replaces is begin{;4}m.  An accept{;4}m with no arguments and
  6265. no statements may be written simply as accept UPDATE;{;4}m.
  6266. 1HPlease type a space to go on, or B to go back.                       2546F483T484B481$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q             procedure MASTER is              task SLAVE is
  6267.                                                  entry SYNC;
  6268.                                               end SLAVE;
  6269.                                               task body SLAVE is
  6270.              begin                            begin
  6271.                 -----;                           -----;
  6272.                 -----;  -- Block 1               -----;  -- Block 3
  6273.                 -----;                           -----;
  6274.                 SLAVE.SYNC;                      accept SYNC;
  6275.                 -----;                           -----;
  6276.                 -----;  -- Block 2               -----;  -- Block 4
  6277.                 -----;                           -----;
  6278.              end MASTER;                      end SLAVE;
  6279.  
  6280.  
  6281. True or False?  Statements in blocks 1 and 4 could execute simultaneously.
  6282. 1HPlease press T for true or F for false, or B to go back.                              2868 485B482Q482$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             procedure MASTER is              task SLAVE is
  6283.                                                  entry SYNC;
  6284.                                               end SLAVE;
  6285.                                               task body SLAVE is
  6286.              begin                            begin
  6287.                 -----;                           -----;
  6288.                 -----;  -- Block 1               -----;  -- Block 3
  6289.                 -----;                           -----;
  6290.                 SLAVE.SYNC;                      accept SYNC;{;4}m
  6291.                 -----;                           -----;
  6292.                 -----;  -- Block 2               -----;  -- Block 4
  6293.                 -----;                           -----;
  6294.              end MASTER;                      end SLAVE;
  6295.  
  6296.  
  6297. You're right!{;4}m  MASTER will wait at SLAVE.SYNC{;4}m for SLAVE to reach accept{;4}m, or
  6298. SLAVE will wait at accept{;4}m for MASTER to reach SLAVE.SYNC;{;4}m.  Therefore, blocks 1
  6299. and 4 can't execute simultaneously.
  6300. 1HPlease type a space to go on, or B or Q to go back to the question.        2833 485B482Q482$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             procedure MASTER is              task SLAVE is
  6301.                                                  entry SYNC;
  6302.                                               end SLAVE;
  6303.                                               task body SLAVE is
  6304.              begin                            begin
  6305.                 -----;                           -----;
  6306.                 -----;  -- Block 1               -----;  -- Block 3
  6307.                 -----;                           -----;
  6308.                 SLAVE.SYNC;                      accept SYNC;
  6309.                 -----;                           -----;
  6310.                 -----;  -- Block 2               -----;  -- Block 4
  6311.                 -----;                           -----;
  6312.              end MASTER;                      end SLAVE;
  6313.  
  6314.  
  6315. False.  MASTER will wait at SLAVE.SYNC{;4}m for SLAVE to reach accept{;4}m, or SLAVE will
  6316. wait at accept{;4}m for MASTER to reach SLAVE.SYNC;{;4}m.  Therefore, blocks 1 and 4
  6317. can't execute simultaneously.
  6318. 1HPlease type a space to go on, or B or Q to go back to the question.                                           2617 486B482$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$If several tasks call an entry before the server reaches accept{;4}m, the calls are
  6319. queued first-in, first-out.
  6320.  
  6321. We can write a select{;4}m block to accept any of several different calls:
  6322.  
  6323.                          select{;4}m
  6324.                             accept A;
  6325.                          or{;4}m
  6326.                             accept B(I : in INTEGER) do
  6327.                                -----;
  6328.                             end B;
  6329.                          or{;4}m
  6330.                             accept C;
  6331.                          end select;{;4}m
  6332.  
  6333. When select{;4}m is reached, the task waits for a call to A or B or C.  If calls to
  6334. more than one entry are pending, one will be chosen arbitrarily.
  6335.  
  6336. A delay{;4}m statement, used in ordinary code, will delay a specified number of
  6337. seconds (plus any system overhead).  For example,
  6338. 1HPlease type a space to go on, or B to go back.                                                           2732 487B485$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                   A;
  6339.                                    delay 5.0;{;4}m
  6340.                                    B;
  6341.  
  6342. will call A, delay five seconds (plus system overhead), and then call B.
  6343. However, when used in a select{;4}m block, the meaning is a bit different.  It's
  6344. used to implement an impatient server{;4}m.  For example,
  6345.  
  6346.                                  select{;4}m
  6347.                                     accept A;
  6348.                                  or{;4}m
  6349.                                     accept B;
  6350.                                  or
  6351.                                     delay 5.0;{;4}m
  6352.                                     C;
  6353.                                  end select;{;4}m
  6354.  
  6355. will wait up to five seconds for a call to A or B.  If no call is received, C
  6356. will be called.
  6357.  
  6358. Guards{;4}m can be used to switch alternatives of a select{;4}m block on and off.  For
  6359. example,
  6360. 1HPlease type a space to go on, or B to go back.                                            3225 488B486$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                J : INTEGER;
  6361.                                 ...
  6362.                                 select
  6363.                                    when J = 1 =>{;4}m
  6364.                                    accept A;
  6365.                                 or
  6366.                                    when J = 2 =>{;4}m
  6367.                                    accept B;
  6368.                                 end select;{;4}m
  6369.  
  6370. Here A is an alternative only if the condition (J = 1) is true; B is an
  6371. alternative only if J = 2.  If J /= 1, then no call to A will be accepted, even
  6372. if one is pending.  If every branch of a select{;4}m block has a guard and all
  6373. guards are false, PROGRAM_ERROR is raised.
  6374.  
  6375. Tasks "die" in three ways.  The least elegant way is for a task to abort{;4}m it,
  6376. e.g., abort SERVER;{;4}m.  This is drastic, because SERVER might be doing anything.
  6377. A better way is for a family of tasks each to include terminate;{;4}m as one
  6378. alternative in a select{;4}m block.  (A "family" of tasks is the set of tasks
  6379. created by one "parent," for example, the main program.)  When calls to the
  6380. entries in the tasks all cease, all tasks in the family will reach the
  6381. terminate{;4}m alternative, and all will die together.
  6382. 1HPlease type a space to go on, or B to go back.                                                   3327 489B487$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$But the most orderly way for a task to die is for it simply to reach its last
  6383. statement.  For example, task T below will continue to accept calls to T.A and
  6384. T.B until a task calls T.SHUTDOWN.  At that time, T will die.
  6385.  
  6386.            task T is                      task body T is
  6387.               entry A;                       DONE : BOOLEAN := FALSE;{;4}m
  6388.               entry B;                    begin
  6389.               entry SHUTDOWN;                while not DONE loop{;4}m
  6390.            end T;                               select{;4}m
  6391.                                                    accept A do
  6392.                                                       -----;
  6393.                                                    end A;
  6394.                                                 or{;4}m
  6395.                                                    accept B do
  6396.                                                       -----;
  6397.                                                    end B;
  6398.                                                 or
  6399.                                                    accept SHUTDOWN;
  6400.                                                    DONE := TRUE;
  6401.                                                 end select;
  6402.                                              end loop;{;4}m
  6403.                                           end T;
  6404. 1HPlease type a space to go on, or B to go back.                                                 3028 490B488$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Trying to call an entry of a task that has died will raise TASKING_ERROR.
  6405. Also, a task can't terminate until all the tasks it creates terminate.  In
  6406. particular, the main program can't return to the operating system until all
  6407. tasks in the program have died.  Programmers must be careful to avoid possible
  6408. deadlocks.  Ada solves many problems that plague other languages, but
  6409. unfortunately the deadlock problem remains unsolved.
  6410.  
  6411. A select{;4}m block may have an else{;4}m alternative.  Here's an example of a very
  6412. impatient server.  If a call to A or B is pending it will be served, otherwise,
  6413. C will be called:
  6414.  
  6415.                                  select{;4}m
  6416.                                     accept A do
  6417.                                        -----;
  6418.                                     end A;
  6419.                                  or{;4}m
  6420.                                     accept B do
  6421.                                        -----;
  6422.                                     end B;
  6423.                                  else{;4}m
  6424.                                     C;
  6425.                                  end select;{;4}m
  6426. 1HPlease type a space to go on, or B to go back.                                                3263T491F492B489$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Qtype DATE is ...                     task body DATA_PROTECTOR is
  6427. task DATA_PROTECTOR is                  SAVE_D : DATE;
  6428.    entry READ_DATE(D : out DATE);       DONE   : BOOLEAN := FALSE;
  6429.    entry WRITE_DATE(D : in DATE);    begin
  6430.    entry SHUTDOWN;                      accept WRITE_DATE(D : in DATE) do
  6431. end DATA_PROTECTOR;                        SAVE_D := D:
  6432.                                         end WRITE_DATE;
  6433.                                         while not DONE loop
  6434.                                            select
  6435.                                               accept READ_DATE(D : out DATE) do
  6436.                                                  D := SAVE_D;
  6437.                                               end READ_DATE;
  6438.                                            or
  6439.                                               accept WRITE_DATE(D : in DATE) do
  6440.                                                  SAVE_D := D;
  6441. True or False?  This task must                end WRITE_DATE;
  6442. serve at least one call to                 or
  6443. WRITE_DATE before it will                     accept SHUTDOWN;
  6444. accept calls to READ_DATE.                    DONE := TRUE;
  6445.                                            end select;
  6446.                                         end loop;
  6447.                                      end DATA_PROTECTOR;
  6448. 1HPlease press T for true or F for false, or B to go back.             3434 493B490Q490$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$type DATE is ...                     task body DATA_PROTECTOR is
  6449. task DATA_PROTECTOR is                  SAVE_D : DATE;
  6450.    entry READ_DATE(D : out DATE);       DONE   : BOOLEAN := FALSE;
  6451.    entry WRITE_DATE(D : in DATE);    begin
  6452.    entry SHUTDOWN;                      accept WRITE_DATE(D : in DATE) do{;4}m
  6453. end DATA_PROTECTOR;                        SAVE_D := D:
  6454.                                         end WRITE_DATE;{;4}m
  6455.                                         while not DONE loop
  6456.                                            select
  6457.                                               accept READ_DATE(D : out DATE) do
  6458.                                                  D := SAVE_D;
  6459.                                               end READ_DATE;{;4}m
  6460.                                            or
  6461.                                               accept WRITE_DATE(D : in DATE) do
  6462.                                                  SAVE_D := D;
  6463. You're right!{;4}m  The extra accept{;4}m               end WRITE_DATE;{;4}m
  6464. block outside the loop forces us           or
  6465. to call WRITE_DATE at least once              accept SHUTDOWN;
  6466. before we can call READ_DATE.                 DONE := TRUE;
  6467.                                            end select;
  6468.                                         end loop;
  6469.                                      end DATA_PROTECTOR;
  6470. 1HPlease type a space to go on, or B or Q to go back to the question.                                          3324 493B490Q490$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$type DATE is ...                     task body DATA_PROTECTOR is
  6471. task DATA_PROTECTOR is                  SAVE_D : DATE;
  6472.    entry READ_DATE(D : out DATE);       DONE   : BOOLEAN := FALSE;
  6473.    entry WRITE_DATE(D : in DATE);    begin
  6474.    entry SHUTDOWN;                      accept WRITE_DATE(D : in DATE) do
  6475. end DATA_PROTECTOR;                        SAVE_D := D:
  6476.                                         end WRITE_DATE;
  6477.                                         while not DONE loop
  6478.                                            select
  6479.                                               accept READ_DATE(D : out DATE) do
  6480.                                                  D := SAVE_D;
  6481.                                               end READ_DATE;
  6482.                                            or
  6483.                                               accept WRITE_DATE(D : in DATE) do
  6484.                                                  SAVE_D := D;
  6485. True.  The extra accept{;4}m block                 end WRITE_DATE;
  6486. outside the loop forces us to              or
  6487. call WRITE_DATE at least once                 accept SHUTDOWN;
  6488. before we can call READ_DATE.                 DONE := TRUE;
  6489.                                            end select;
  6490.                                         end loop;
  6491.                                      end DATA_PROTECTOR;
  6492. 1HPlease type a space to go on, or B or Q to go back to the question.                                                    2657 494B490$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The select{;4}m block can be used in a caller as well as a server.  The following
  6493. block waits up to five seconds to call entry A in task T.  If T isn't ready to
  6494. accept the call in five seconds, the block calls procedure B instead.  This is
  6495. called an impatient customer:
  6496.  
  6497.                                  select
  6498.                                     T.A;
  6499.                                  or
  6500.                                     delay 5.0;
  6501.                                     B;
  6502.                                  end select;{;4}m
  6503.  
  6504. A very impatient customer can be implemented with else{;4}m.  This block calls T.A
  6505. only if T is ready to accept the call immediately, otherwise, it calls B.
  6506.  
  6507.                                   select
  6508.                                      T.A;
  6509.                                   else
  6510.                                      B;
  6511.                                   end select;{;4}m
  6512. 1HPlease type a space to go on, or B to go back.                   2512 495B493$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Task types{;4}m may be declared.  This permits us to create an array of tasks, and
  6513. it lets us bring tasks into existence via access types.  Tasks begin executing
  6514. as soon as they're brought into existence.  For example,
  6515.  
  6516.                             task type X is
  6517.                                entry E;
  6518.                             end X;
  6519.                             type P is access X;
  6520.                             X1 : P;
  6521.                             A : array(1 .. 10) of X;
  6522.                             task body X is{;4}m
  6523.                                ...
  6524.                             end X;{;4}m
  6525.  
  6526. Entries to these tasks are called thus:
  6527.  
  6528.                             A(5).E;
  6529.                             X1 := new X;
  6530.                             X1.all.E;{;4}m or just X1.E;{;4}m
  6531. 1HPlease type a space to go on, or B to go back.                                                                2456 496B494$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Ada comes with a package CALENDAR; the specification is in section 9.6 of the
  6532. LRM.  The part that concerns us here is shown below.  Type DURATION is a fixed
  6533. point type built into Ada; the delay{;4}m statement discussed earlier takes an
  6534. object of type DURATION.
  6535.  
  6536.         package CALENDAR is
  6537.            type TIME is private;
  6538.            function CLOCK return TIME;
  6539.            function "+"(LEFT : TIME; RIGHT : DURATION) return TIME;
  6540.            function "-"(LEFT : TIME; RIGHT : TIME)     return DURATION;{;4}m
  6541.            ...
  6542.         end CALENDAR;{;4}m
  6543.  
  6544. Not shown are a few other operators, and subprograms to convert between type
  6545. TIME and the year, month, day, and number of seconds since midnight.
  6546.  
  6547. Let's write a program segment that uses CALENDAR and calls A every five
  6548. seconds:
  6549. 1HPlease type a space to go on, or B to go back.                    2662 497B495$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                       with CALENDAR; use CALENDAR;{;4}m
  6550.                        ...
  6551.                        NEXT_EVENT : TIME := CLOCK + 5.0;{;4}m
  6552.                        ...
  6553.                        loop
  6554.                           delay NEXT_EVENT - CLOCK;
  6555.                           A;
  6556.                           NEXT_EVENT := NEXT_EVENT + 5.0;
  6557.                        end loop;{;4}m
  6558.  
  6559. Note that this loop accounts for the time required to call A.  Instead of
  6560. delaying 5.0, we calculate the time of the next call in NEXT_EVENT, and delay
  6561. that time minus the current time, which we obtain by calling CLOCK.  Thus the
  6562. program will go through the loop once every 5.0 seconds, even if it takes a
  6563. little time to call A.
  6564.  
  6565. The -{;4}m and +{;4}m operators inside the loop both use infix functions from CALENDAR.
  6566.  
  6567. We're now ready for Outside Assignment 6!  It will be much simpler than Outside
  6568. Assignment 5.
  6569. 1HPlease type a space to go on, or B to go back.              2944 498B496$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A                   OUTSIDE ASSIGNMENT 6 - EXERCISE IN TASKING
  6570.  
  6571. On page 30 of your printed course notes is a listing of TASKING.DUM{;4}m.  This
  6572. program calls a task entry to print Tick!{;4}m on the screen every five seconds
  6573. until it has been printed nine times.
  6574.  
  6575. Every time delay{;4}m is executed, there's a call to NEW_LINE, so that the delay
  6576. will be visible on the screen.  The program is entirely in lower case, because
  6577. your assignment is to modify it.  If you make your modifications in upper case,
  6578. it will be easy to see what you have changed.
  6579.  
  6580. We want you to change the declaration of T from a single task to an array{;4}m of
  6581. three tasks.  The tasks are numbered 1, 2, and 3.  Task 1 is to be activated
  6582. every two{;4}m five-second intervals.  Task 2 is to be activated every three{;4}m five-
  6583. -second intervals, and task 3, every four{;4}m.  Also, instead of printing Tick!{;4}m,
  6584. each task will identify itself by number, for example, Task number 3 is
  6585. starting{;4}m.  Output should look as shown on page 32 of your printed notes.
  6586. 1HPlease type a space to go on, or B to go back.                                2246 499B497$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$We recommend that you create an array of three counters.  Each counter counts
  6587. down from its period (2, 3, or 4) to zero by one count every interval.  When a
  6588. counter reaches zero, the corresponding task entry is called, and the counter
  6589. is reset to its period.  All three counters should be initialized to zero, so
  6590. that all three tasks print their messages immediately upon activation of the
  6591. program.  You should use the rendezvous mechanism to inform each task of its
  6592. number (1, 2, or 3).  Your program should do an orderly shutdown of all three
  6593. tasks at the end.
  6594.  
  6595. Here are the steps to follow for Outside Assignment 6.  They're also in your
  6596. printed course notes on page 31:
  6597. 1HPlease type a space to go on, or B to go back.                              2355 500B498$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$1.  Make a copy of TASKING.DUM by typing COPY TASKING.DUM TASKING.ADA{;4}m.
  6598.     Compile, link, and execute the program to make sure it prints Tick!{;4}m nine
  6599.     times.
  6600.  
  6601. 2.  Edit TASKING.ADA to become your solution.  Make your changes in upper case.
  6602.  
  6603. 3.  Compile TASKING.ADA, link, and execute.
  6604.  
  6605. 4.  Compare your output with page 32 of the printed course notes.  If there are
  6606.     any errors, go back to step 2.
  6607.  
  6608. 5.  When your output agrees with the printed course notes, you've finished the
  6609.     assignment and will have a chance to compare your solution with ours.
  6610.  
  6611.  
  6612. Please type X to exit ADA-TUTR{;4}m temporarily, and try Outside Assignment 6.  Work
  6613. at your own pace; there's no deadline.  Good luck!
  6614. 1HPlease type X to exit, a space to go on, or B to go back.                     1869 501B499$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              Congratulations on Completing Outside Assignment 6!{;4}m
  6615.  
  6616. If you like, you can compare your solution with ours, which is in TASKING.ANS.
  6617. A listing is on page 33 of your printed course notes.  Your solution might be
  6618. different from ours, but if your output{;4}m agrees with page 32 of the printed
  6619. notes, your solution is correct.
  6620.  
  6621. You've learned a great deal of Ada!  Let's go on to discuss some advanced
  6622. topics.
  6623. 1HPlease type a space to go on, or B to go back.       2136 502B500$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  6624.  
  6625.    Introduction                             Records, Arrays, and Assignment 3
  6626.  
  6627.    The Format of an Ada Program             Recursion and Assignment 4
  6628.  
  6629.    Generic Instantiation and                Subprograms and Packages
  6630.       Assignment 1
  6631.                                             Additional Types, Exceptions,
  6632.    Simple Declarations and Simple              TEXT_IO, and Assignment 5
  6633.       Attributes
  6634.                                             Generics, Tasking, and Assignment 6
  6635.    Operators, Control Constructs, and
  6636.       Assignment 2                       >  ADVANCED TOPICS{;4}m
  6637. 1HPlease type a space to go on, or B to go back.                                        2760 503B501$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    RENAMING
  6638.  
  6639. A subprogram can be renamed in Ada.  This allows us to avoid the dot notation
  6640. without a use{;4}m clause.  For example, if our program with{;4}ms TEXT_IO, we can write:
  6641.  
  6642.          procedure PRINT(OBJECT : in STRING) renames TEXT_IO.PUT_LINE;{;4}m
  6643.  
  6644. We can now call PRINT instead of TEXT_IO.PUT_LINE.  The old name is still
  6645. available.  Note that renaming can change the names of the formal parameters
  6646. ("dummy arguments").  Renaming may also add, delete, or change default values.
  6647. When used in a package, a renaming declaration like the above goes in the
  6648. specification{;4}m, not the body.
  6649.  
  6650. We can also rename task entries as procedures.  This is the only way to avoid
  6651. the dot notation when calling a task entry.
  6652.  
  6653. A function can be renamed as an infix operator, if it has the right number and
  6654. types of arguments.  Also, an infix operator can be renamed as a function.  For
  6655. example, earlier we defined type VECTOR and wrote:
  6656. 1HPlease type a space to go on, or B to go back.                2759 504B502$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              function "*"(LEFT, RIGHT : in VECTOR) return FLOAT;{;4}m
  6657.  
  6658. This could be renamed as follows:
  6659.  
  6660.         function DOT_PRODUCT(X, Y : in VECTOR) return FLOAT renames "*";{;4}m
  6661.  
  6662. Renaming can get around the restriction that library subprograms can't be infix
  6663. operators.  We can use a normal function name for the library, and rename it as
  6664. an infix operator for our program.  Similarly, we can get around the rule that
  6665. library subprograms can't overload each other.  We can give subprograms
  6666. different names in the library, and rename them in our program to overload each
  6667. other.
  6668.  
  6669. An attribute that takes an argument, such as PRED{;4}m and SUCC{;4}m, can be renamed as a
  6670. function.  Record components can be renamed.  If D{;4}m is of the type DATE{;4}m we had
  6671. earlier, we can write J : INTEGER renames D.YEAR;{;4}m.  Exceptions can also be
  6672. renamed, as in
  6673.  
  6674.                   OOPS : exception renames TEXT_IO.NAME_ERROR;{;4}m
  6675. 1HPlease type a space to go on, or B to go back.                 3470 505B503$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          PACKAGES STANDARD AND ASCII
  6676.  
  6677. Ada comes with a package STANDARD.  However, unlike all the other packages,
  6678. STANDARD is needed by every{;4}m Ada compilation unit.  Therefore, STANDARD is
  6679. automatically with{;4}med and use{;4}md in every compilation.  It need not be mentioned
  6680. in a context clause.  STANDARD contains the definitions built into the Ada
  6681. language, such as type BOOLEAN is (FALSE, TRUE);{;4}m.  A listing of the package
  6682. specification is in Appendix C of the LRM.  Thus, the full name for the type
  6683. BOOLEAN is STANDARD.BOOLEAN, the full name for INTEGER is STANDARD.INTEGER,
  6684. etc.  Naturally, this normally need not concern the programmer.  The dot
  6685. notation is automatic because STANDARD is automatically use{;4}md in every
  6686. compilation.
  6687.  
  6688. However, inside package STANDARD is a package ASCII.  Since this package is
  6689. part of STANDARD, we never have to write a with{;4}m clause for it.  But ASCII isn't
  6690. automatically use{;4}md.  If we want the dot notation for ASCII to be automatic, we
  6691. have to provide a use{;4}m clause.  As the listing in the LRM shows, ASCII contains
  6692. names for all the unprintable ASCII characters, such as BEL, ESC, etc.  It also
  6693. provides names for many punctuation marks, in case your terminal or printer
  6694. doesn't have them.  For example, DOLLAR, AT_SIGN, etc.  Finally, it provides
  6695. names for all lower case letters, from LC_A to LC_Z.
  6696. 1HPlease type a space to go on, or B to go back.      2237 506B504$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$For example, either of the following programs will print a@b{;4}m and ring the bell
  6697. or beep the terminal:
  6698.  
  6699.        with TEXT_IO; use TEXT_IO;
  6700.        procedure AB is
  6701.        begin
  6702.           PUT_LINE(ASCII.LC_A & ASCII.AT_SIGN & ASCII.LC_B & ASCII.BEL{;4}m);
  6703.        end AB;
  6704.  
  6705.        with TEXT_IO; use TEXT_IO;
  6706.        procedure AB is
  6707.           use ASCII;{;4}m
  6708.        begin
  6709.           PUT_LINE(LC_A & AT_SIGN & LC_B & BEL{;4}m);
  6710.        end AB;
  6711.  
  6712. Note the placement of use ASCII;{;4}m in the second example.  It's similar to the
  6713. placement of use MY_INT_IO;{;4}m in ADD.ADA, which we discussed early in the course.
  6714. 1HPlease type a space to go on, or B to go back.                                       2962 507B505$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                        AN ALTERNATIVE TO INFIX NOTATION
  6715.  
  6716. Earlier we learned to define and use infix operators like
  6717.  
  6718.               type VECTOR is array(INTEGER range <>) of FLOAT;
  6719.               function "*"(LEFT, RIGHT : in VECTOR) return FLOAT;{;4}m
  6720.               A, B : VECTOR(1 .. 10);
  6721.               F    : FLOAT;
  6722.               ...
  6723.               F := A * B;{;4}m
  6724.  
  6725. An alternative notation equivalent to F := A * B;{;4}m is F := "*"(A, B);{;4}m.  Why
  6726. would anyone want to use this clumsier notation?  If our function is in a
  6727. package MATH that the calling program with{;4}ms but for some reason doesn't use{;4}m, we
  6728. could use dot notation and write F := MATH."*"(A, B);{;4}m.  But we couldn't use dot
  6729. notation directly with infix operators, as in F := A MATH.* B; or even
  6730. F := A MATH."*" B;.  Both of those are illegal.  The alternative notation is
  6731. also used to emphasize that an operator comes from package STANDARD.  For
  6732. example, if I, J, and K are INTEGERs, we could write I := STANDARD."*"(J, K);{;4}m,
  6733. which is equivalent to I := J * K;{;4}m.
  6734. 1HPlease type a space to go on, or B to go back.              1565250815093510B506$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QAssuming X, Y, and Z have been declared FLOAT, which one of the following is
  6735. illegal{;4}m?
  6736.  
  6737.                           1.  X := Y / Z;
  6738.  
  6739.                           2.  X := Y STANDARD."/" Z;
  6740.  
  6741.                           3.  X := STANDARD."/"(Y, Z);
  6742. 1HPlease press 1, 2, or 3, or B to go back.           1771 511B507Q507$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          1.  X := Y / Z;
  6743.  
  6744.                           2.  X := Y STANDARD."/" Z;{;4}m
  6745.  
  6746.                           3.  X := STANDARD."/"(Y, Z);
  6747.  
  6748.  
  6749. You're right!{;4}m  The syntax of number 2 is illegal.  To specify the package
  6750. STANDARD, we have to use the syntax of number 3.  Normally, of course, the
  6751. syntax of number 1 is used.
  6752. 1HPlease type a space to go on, or B or Q to go back to the question.     1614 511B507Q507$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          1.  X := Y / Z;
  6753.  
  6754.                           2.  X := Y STANDARD."/" Z;
  6755.  
  6756.                           3.  X := STANDARD."/"(Y, Z);
  6757.  
  6758.  
  6759. No, number 1 is the syntax that would ordinarily be used for division, and is
  6760. legal.
  6761. 1HPlease type a space to go on, or B or Q to go back to the question.                                                              1564 511B507Q507$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          1.  X := Y / Z;
  6762.  
  6763.                           2.  X := Y STANDARD."/" Z;
  6764.  
  6765.                           3.  X := STANDARD."/"(Y, Z);
  6766.  
  6767.  
  6768. No, number 3 is the correct way to specify package STANDARD explicitly.
  6769. 1HPlease type a space to go on, or B or Q to go back to the question.            2665 512B507$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    RECORD DISCRIMINANTS AND RECORD VARIANTS
  6770.  
  6771. The definition of a record type can have discriminants{;4}m, which have the same
  6772. form as formal parameters ("dummy arguments") of subprograms, except that the
  6773. mode is omitted.  Default values may be supplied.  For example,
  6774.  
  6775.        type MATRIX is array(INTEGER range <>, INTEGER range <>) of FLOAT;
  6776.        type SQUARE_MATRIX(SIZE : POSITIVE := 9){;4}m is
  6777.           record
  6778.              SQ : MATRIX(1 .. SIZE, 1 .. SIZE){;4}m;
  6779.           end record;
  6780.  
  6781. Although objects of type MATRIX can be rectangular, objects of type
  6782. SQUARE_MATRIX must be square.  In declaring these objects, we use the same
  6783. syntax as a subprogram call, with either positional or named notation:
  6784.  
  6785.     A : SQUARE_MATRIX(7);  -- a 7-by-7 matrix
  6786.     B : SQUARE_MATRIX(SIZE => 5);  -- a 5-by-5 matrix
  6787.     C : SQUARE_MATRIX;  -- a 9-by-9 matrix, using the default value of SIZE{;4}m
  6788. 1HPlease type a space to go on, or B to go back.           2952 513B511$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Of course, subtypes of discriminated records can be declared.  For example,
  6789.  
  6790.                 subtype CHESS_BOARD is SQUARE_MATRIX(SIZE => 8);{;4}m
  6791.  
  6792. A record discriminant is used in the definition of type TEXT in the
  6793. TEXT_HANDLER package specification of section 7.6 of the LRM:
  6794.  
  6795.                   MAXIMUM : constant := ... ;
  6796.                   subtype INDEX is INTEGER range 0 .. MAXIMUM;
  6797.                   ...
  6798.                   type TEXT(MAXIMUM_LENGTH : INDEX) is
  6799.                      record
  6800.                         POS   : INDEX := 0;
  6801.                         VALUE : STRING(1 .. MAXIMUM_LENGTH);
  6802.                      end record;{;4}m
  6803.  
  6804. With the simplified version of type TEXT presented earlier, every object of
  6805. type TEXT occupied enough memory for the longest string we expected to handle
  6806. (e.g., 80 characters).  With this version, each object of type TEXT that we
  6807. create can have just the MAXIMUM_LENGTH we need, and its effective length POS
  6808. can vary from zero to that MAXIMUM_LENGTH.  The record discriminant complicates
  6809. the package specification only very slightly; see section 7.6 of the LRM.
  6810. 1HPlease type a space to go on, or B to go back.                        3036 514B512$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The definition of a record type can have a variant{;4}m, which also has the same
  6811. form as a subprogram formal parameter without the mode.  However, the syntax of
  6812. a case{;4}m construct is used to specify part of the record.  Although a record can
  6813. have several discriminants, it can have only one variant, and the variant part
  6814. must appear last in the record.  For example,
  6815.  
  6816.                         type SEX_TYPE is (MALE, FEMALE);
  6817.                         type PERSON(SEX : SEX_TYPE){;4}m is
  6818.                            record
  6819.                               AGE : NATURAL;
  6820.                               case SEX is
  6821.                                  when MALE =>
  6822.                                     BEARDED => BOOLEAN;
  6823.                                  when FEMALE =>
  6824.                                     CHILDREN : NATURAL;
  6825.                               end case;{;4}m
  6826.                            end record;
  6827.  
  6828. If the sex of the person is MALE, we want the record to include a BOOLEAN
  6829. showing whether he's bearded, but if the sex is FEMALE, we want the record to
  6830. include an INTEGER (subtype NATURAL), showing the number of children she has.
  6831. 1HPlease type a space to go on, or B to go back.                                        2749 515B513$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                        type SEX_TYPE is (MALE, FEMALE);
  6832.                         type PERSON(SEX : SEX_TYPE) is
  6833.                            record
  6834.                               AGE : NATURAL;
  6835.                               case SEX is
  6836.                                  when MALE =>
  6837.                                     BEARDED  : BOOLEAN;
  6838.                                  when FEMALE =>
  6839.                                     CHILDREN : NATURAL;
  6840.                               end case;
  6841.                            end record;
  6842.  
  6843. Objects are declared and given values as we'd expect:
  6844.  
  6845.    JOHN : PERSON(SEX => MALE) := (SEX => MALE, AGE => 21, BEARDED => FALSE);
  6846.    MARY : PERSON(SEX => FEMALE) := (SEX => FEMALE, AGE => 18, CHILDREN => 0);{;4}m
  6847.  
  6848. Attempting to access JOHN.CHILDREN or MARY.BEARDED will raise CONSTRAINT_ERROR.
  6849. Subtypes may be declared as follows:
  6850.  
  6851.                         subtype MAN is PERSON(MALE);
  6852.                         subtype WOMAN is PERSON(FEMALE);{;4}m
  6853. 1HPlease type a space to go on, or B to go back.                           216325161517B514$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Qtype COMPUTER_SIZE is (HANDHELD,LAPTOP,PORTABLE,DESKTOP,MAINFRAME,CLUSTER);
  6854. type COMPUTER(SIZE : COMPUTER_SIZE) is
  6855.    record
  6856.       K_MEM : POSITIVE;
  6857.       DISKS : NATURAL;
  6858.       case SIZE is
  6859.          when CLUSTER =>
  6860.             NUMBER_OF_UNITS : POSITIVE;
  6861.             DATA_RATE       : FLOAT;
  6862.          when others =>
  6863.             null;
  6864.       end case;
  6865.    end record;
  6866. MY_PC       : COMPUTER(DESKTOP) := (DESKTOP, K_MEM => 640, DISKS => 2);    -- 1{;4}m
  6867. COMPANY_LAN : COMPUTER(CLUSTER) := (CLUSTER, K_MEM => 24576, DISKS => 8);  -- 2{;4}m
  6868.  
  6869. Which commented declaration in the above program is illegal{;4}m?
  6870. 1HPlease press 1 or 2, or B to go back.             2263 518B515Q515$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$type COMPUTER_SIZE is (HANDHELD,LAPTOP,PORTABLE,DESKTOP,MAINFRAME,CLUSTER);
  6871. type COMPUTER(SIZE : COMPUTER_SIZE) is
  6872.    record
  6873.       K_MEM : POSITIVE;
  6874.       DISKS : NATURAL;
  6875.       case SIZE is
  6876.          when CLUSTER =>
  6877.             NUMBER_OF_UNITS : POSITIVE;
  6878.             DATA_RATE       : FLOAT;
  6879.          when others =>
  6880.             null;
  6881.       end case;
  6882.    end record;
  6883. MY_PC       : COMPUTER(DESKTOP) := (DESKTOP, K_MEM => 640, DISKS => 2);    -- 1
  6884. COMPANY_LAN : COMPUTER(CLUSTER) := (CLUSTER, K_MEM => 24576, DISKS => 8);  -- 2{;4}m
  6885.  
  6886. You're right!{;4}m  The initialization of COMPANY_LAN fails to include fields for
  6887. NUMBER_OF_UNITS and DATA_RATE.
  6888. 1HPlease type a space to go on, or B or Q to go back to the question.             2362 518B515Q515$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$type COMPUTER_SIZE is (HANDHELD,LAPTOP,PORTABLE,DESKTOP,MAINFRAME,CLUSTER);
  6889. type COMPUTER(SIZE : COMPUTER_SIZE) is
  6890.    record
  6891.       K_MEM : POSITIVE;
  6892.       DISKS : NATURAL;
  6893.       case SIZE is
  6894.          when CLUSTER =>
  6895.             NUMBER_OF_UNITS : POSITIVE;
  6896.             DATA_RATE       : FLOAT;
  6897.          when others =>
  6898.             null;
  6899.       end case;
  6900.    end record;
  6901. MY_PC       : COMPUTER(DESKTOP) := (DESKTOP, K_MEM => 640, DISKS => 2);    -- 1
  6902. COMPANY_LAN : COMPUTER(CLUSTER) := (CLUSTER, K_MEM => 24576, DISKS => 8);  -- 2
  6903.  
  6904. No, the declaration of MY_PC and its initialization are correct.  The others{;4}m
  6905. clause of the case{;4}m applies, so there are only two fields in the record when
  6906. SIZE is DESKTOP.
  6907. 1HPlease type a space to go on, or B or Q to go back to the question.              2848 519B515$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                        FIXED POINT AND UNIVERSAL TYPES
  6908.  
  6909. The only fixed point type defined in package STANDARD is DURATION.  However,
  6910. Ada lets us define our own fixed point types.  We specify the accuracy with the
  6911. reserved word delta{;4}m, and a range constraint is required.  For example,
  6912.  
  6913.                 type VOLTAGE is delta 0.01 range -20.0 .. 20.0;{;4}m
  6914.  
  6915. This guarantees that the objects of type VOLTAGE will be represented with at
  6916. least an accuracy of 1/100.  Since the computer is binary, Ada will choose an
  6917. internal representation at least as accurate as 1/128.  It might use even
  6918. greater accuracy, for example, 1/256.  In any event, it's guaranteed that the
  6919. accuracy is at least as good as that requested.
  6920.  
  6921. It's possible to make a request that a particular implementation of Ada can't
  6922. handle.  For example, if we write
  6923.  
  6924.                type VOLTAGE is delta 1.0E-10 range 0.0 .. 1.0E9;{;4}m
  6925.  
  6926. the version of Ada we're using may have to report that it has no internal
  6927. representation that satisfies this requirement.
  6928. 1HPlease type a space to go on, or B to go back.                            2842 520B518$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                type VOLTAGE is delta 0.01 range -20.0 .. 20.0;
  6929.  
  6930. The set of numbers that can be represented exactly by any Ada that accepts a
  6931. type definition like the above is called the model numbers{;4}m of that type.  This
  6932. applies to floating types as well as fixed, for example,
  6933.  
  6934.                      type W is digits 5 range 0.0 .. 100.0;{;4}m
  6935.  
  6936. A particular implementation may represent additional numbers exactly; these are
  6937. called safe numbers{;4}m.  The safe numbers are a superset of the model numbers;
  6938. their range usually is a little larger.
  6939.  
  6940. We can add and subtract objects of a fixed point type.  However, if we multiply
  6941. or divide them, we must immediately convert the result to the same or another
  6942. numeric type before we can store it.  For example,
  6943.  
  6944.                        V1, V2, V3 : VOLTAGE;{;4}m
  6945.                        ...
  6946.                        V1 := V2 + V3;  -- legal
  6947.                        V1 := V2 * V3;  -- illegal
  6948.                        V1 := VOLTAGE(V2 * V3);  -- legal{;4}m
  6949. 1HPlease type a space to go on, or B to go back.                                  2837 521B519$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$TEXT_IO contains a generic package FIXED_IO for I/O of fixed point types.
  6950.  
  6951. When we declare a variable in Ada, we give its type.  But when we declare a
  6952. constant, we may or may not give its type.  For example,
  6953.  
  6954.                     L  : constant INTEGER := 30;
  6955.                     M  : constant := 1000;
  6956.                     E  : constant FLOAT := 2.718281828;
  6957.                     PI : constant := 3.141592654;{;4}m
  6958.  
  6959. Also, when we write a number, such as 3.0 or 29_999, we usually don't qualify
  6960. it with a type (for example, FLOAT'(3.0){;4}m).
  6961.  
  6962. Suppose an implementation of Ada provides types INTEGER, LONG_INTEGER, FLOAT,
  6963. and LONG_FLOAT.  How can Ada determine the types of M, PI, 3.0, and 29_999?  M
  6964. and 29_999 are said to be of type universal_integer{;4}m; they can assume any
  6965. integer type as required.  PI and 3.0 are said to be of type universal_real{;4}m and
  6966. can assume any floating or fixed point type as required.
  6967.  
  6968. We can't explicitly declare objects to be of universal types.  However, we can
  6969. write
  6970. 1HPlease type a space to go on, or B to go back.                                       2860 522B520$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                         M  : constant := 1000;
  6971.                          PI : constant := 3.141592654;
  6972.                          I : INTEGER;
  6973.                          J : LONG_INTEGER;
  6974.                          F : FLOAT;
  6975.                          G : LONG_FLOAT;{;4}m
  6976.                          ...
  6977.                          I := M;  J := M;
  6978.                          I := 29_999;  J := 29_999;
  6979.                          F := PI;  G := PI;
  6980.                          F := 3.0;  G := 3.0;{;4}m
  6981.  
  6982. and in each case the constant assumes the correct type.  The result of
  6983. multiplying or dividing two numbers of a fixed point type is said to be of type
  6984. universal_fixed{;4}m.  This result must be explicitly converted to some numeric
  6985. type before it can be stored.
  6986.  
  6987. Most of the attributes that produce integer results, like POS{;4}m, are of type
  6988. universal_integer.  For example, with the declarations above, we could write
  6989.  
  6990.                             I := CHARACTER'POS('A');
  6991.                             J := CHARACTER'POS('A');{;4}m
  6992. 1HPlease type a space to go on, or B to go back.                16433523152425254526B521$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QWhich one of the following declarations is illegal{;4}m?
  6993.  
  6994.  
  6995.               1.   type RATE is digits 6;
  6996.  
  6997.               2.   type DISTANCE is digits 6 range 0.0 .. 1.0E6;
  6998.  
  6999.               3.   type CURRENT is delta 0.1;
  7000.  
  7001.               4.   type TEMP is delta 0.05 range -200.0 .. 450.0;
  7002. 1HPlease press 1, 2, 3, or 4, or B to go back.                                 1740 527B522Q522$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.   type RATE is digits 6;
  7003.  
  7004.               2.   type DISTANCE is digits 6 range 0.0 .. 1.0E6;
  7005.  
  7006.               3.   type CURRENT is delta 0.1;{;4}m
  7007.  
  7008.               4.   type TEMP is delta 0.05 range -200.0 .. 450.0;
  7009.  
  7010.  
  7011. You're right!{;4}m  A fixed point type declaration must have a range constraint.
  7012. 1HPlease type a space to go on, or B or Q to go back to the question.                                    1730 527B522Q522$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.   type RATE is digits 6;
  7013.  
  7014.               2.   type DISTANCE is digits 6 range 0.0 .. 1.0E6;
  7015.  
  7016.               3.   type CURRENT is delta 0.1;
  7017.  
  7018.               4.   type TEMP is delta 0.05 range -200.0 .. 450.0;
  7019.  
  7020.  
  7021. No, number 1 is legal.  A user defined floating point type need not have a
  7022. range constraint.
  7023. 1HPlease type a space to go on, or B or Q to go back to the question.                                              1725 527B522Q522$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.   type RATE is digits 6;
  7024.  
  7025.               2.   type DISTANCE is digits 6 range 0.0 .. 1.0E6;
  7026.  
  7027.               3.   type CURRENT is delta 0.1;
  7028.  
  7029.               4.   type TEMP is delta 0.05 range -200.0 .. 450.0;
  7030.  
  7031.  
  7032. No, number 2 is legal.  A user defined floating point type may have a range
  7033. constraint.
  7034. 1HPlease type a space to go on, or B or Q to go back to the question.                                                   1722 527B522Q522$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.   type RATE is digits 6;
  7035.  
  7036.               2.   type DISTANCE is digits 6 range 0.0 .. 1.0E6;
  7037.  
  7038.               3.   type CURRENT is delta 0.1;
  7039.  
  7040.               4.   type TEMP is delta 0.05 range -200.0 .. 450.0;
  7041.  
  7042.  
  7043. No, number 4 is legal.  A fixed point type declaration must have a range
  7044. constraint.
  7045. 1HPlease type a space to go on, or B or Q to go back to the question.                                                      3528 528B522$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                MORE ATTRIBUTES
  7046.  
  7047. Ada provides a wide variety of attributes.  All of them are listed and defined
  7048. in Appendix A of the LRM.  The most important ones that we haven't yet
  7049. discussed are these:
  7050.  
  7051. FIRST{;4}m and LAST{;4}m can be used with any scalar type or subtype (including floating
  7052. and fixed), not just discrete types and subtypes.  For example, FLOAT'LAST{;4}m is
  7053. the highest number your particular Ada represents with type FLOAT.
  7054.  
  7055. For any real type or subtype (floating or fixed), SMALL{;4}m and LARGE{;4}m are the
  7056. smallest and largest positive model numbers.  Thus FLOAT'SMALL{;4}m is the
  7057. difference between zero and the next larger number in type FLOAT.  Also, for
  7058. any floating point (sub)type, EPSILON{;4}m is the difference between one{;4}m and the
  7059. next larger number.  We'll use EPSILON{;4}m in a generic function later.
  7060.  
  7061. For a floating point (sub)type, DIGITS{;4}m returns the value given for digits{;4}m in
  7062. the declaration, and for a fixed point (sub)type, DELTA{;4}m returns the value given
  7063. for delta{;4}m in the declaration.  These attributes may not seem too useful,
  7064. because the programmer already knows what he wrote in the declarations.
  7065. However, they're used in generic packages and subprograms.  For example, if the
  7066. generic part says type DUMMY is delta <>;{;4}m, the body can use DUMMY'DELTA{;4}m.
  7067. 1HPlease type a space to go on, or B to go back.                                                3743 529B527$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$For any discrete (sub)type, WIDTH{;4}m gives the maximum length that the attribute
  7068. IMAGE{;4}m can produce.  BOOLEAN'WIDTH{;4}m is 5 because "FALSE" has length 5.  With our
  7069. earlier definition of RAINBOW_COLOR, RAINBOW_COLOR'WIDTH{;4}m is 6.  For versions of
  7070. Ada using 16-bit INTEGERs, INTEGER'WIDTH{;4}m is also 6, the length of "-32768".
  7071.  
  7072. COUNT{;4}m is used with the name of a task entry.  It returns the number of calls
  7073. presently queued on the entry.  TERMINATED{;4}m is of type BOOLEAN.  It's used with
  7074. a task name, and tells if the task is terminated.
  7075.  
  7076. Let's write a generic function to compute the square root for any floating
  7077. point type, using Newton-Raphson iteration.  This method simply says that if G
  7078. is a guess of the square root of X, the next guess is the average of G and X/G.
  7079. For example, if we want to compute the square root of 9.0 and our first guess
  7080. is 9.0, successive guesses are 5.0, 3.4, 3.02352941, 3.00009155, 3.00000000.
  7081. Note that convergence is very rapid.  However, the problem in writing a program
  7082. is knowing when to stop the iteration.  We'll use the attribute EPSILON{;4}m.  Since
  7083. G*G/X should be 1.0, we'll quit when the absolute value of the difference
  7084. between G*G/X and 1.0 is less than or equal to 3.0 times EPSILON.  Recall that
  7085. DUMMY'EPSILON{;4}m is the difference between 1.0 and the next higher number for type
  7086. DUMMY.  If we use 1.0 times EPSILON, the loop might never terminate, and if we
  7087. use 10.0 times EPSILON, we might not get full precision.  So we'll use 3.0
  7088. times EPSILON.  Here's our function:
  7089. 1HPlease type a space to go on, or B to go back.                                 2361 530B528$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$  generic
  7090.      type DUMMY is digits <>;
  7091.   function SQRT(X :in DUMMY) return DUMMY;
  7092.   function SQRT(X :in DUMMY) return DUMMY is
  7093.      GUESS : DUMMY := X;
  7094.   begin
  7095.      if X < 0.0 then
  7096.         raise CONSTRAINT_ERROR;
  7097.      end if;
  7098.      while X /= 0.0 and then abs(GUESS*GUESS/X - 1.0) > 3.0*DUMMY'EPSILON loop
  7099.         GUESS := (X/GUESS + GUESS) * 0.5;
  7100.      end loop;
  7101.      return GUESS;
  7102.   end SQRT;{;4}m
  7103.  
  7104. We tested our SQRT with a version of Ada having types FLOAT, LONG_FLOAT, and
  7105. LONG_LONG_FLOAT.  The last gives at least 33 decimal digits of precision.  SQRT
  7106. was instantiated for all three floating point types, as was FLOAT_IO to display
  7107. the results.  When tested with the three types, all displayed digits of the
  7108. answers were correct.
  7109. 1HPlease type a space to go on, or B to go back.               3256 531B529$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          SEQUENTIAL_IO AND DIRECT_IO
  7110.  
  7111. TEXT_IO creates, reads and writes text files that can be typed on the screen or
  7112. printed.  Ada also provides packages SEQUENTIAL_IO{;4}m and DIRECT_IO,{;4}m which create,
  7113. read, and write binary files.  These files usually can't be typed or printed,
  7114. but they tend to be more efficient than text files, because the computer
  7115. doesn't have to convert numbers between its internal representation and ASCII
  7116. to read and write binary files.
  7117.  
  7118. SEQUENTIAL_IO and DIRECT_IO are both generic, and can be instantiated for any
  7119. type.  The specifications are in sections 14.2.3 and 14.2.5 of the LRM.  Like
  7120. TEXT_IO, they have procedures to CREATE, OPEN, and CLOSE files, but the I/O
  7121. procedures are called READ and WRITE, rather than PUT, GET, PUT_LINE, and
  7122. GET_LINE.  SEQUENTIAL_IO always reads and writes sequentially, but DIRECT_IO is
  7123. capable of random access.  In DIRECT_IO, an optional extra argument in READ and
  7124. WRITE tells the procedure the position in the file to read FROM or write TO.
  7125.  
  7126. TEXT_IO and instantiations of SEQUENTIAL_IO and DIRECT_IO each define their own{;4}m
  7127. FILE_TYPE, so we can't open a file with one package and then do I/O with
  7128. another.  DIRECT_IO provides a FILE_MODE of INOUT_FILE as well as the usual
  7129. IN_FILE and OUT_FILE.
  7130. 1HPlease type a space to go on, or B to go back.                    2750 532B530$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$If you like, you can examine the file ADA-TUTR.ADA for an example of the use of
  7131. DIRECT_IO.  ADA-TUTR{;4}m creates a subtype for a block of characters and then
  7132. instantiates DIRECT_IO for that subtype.  It then opens ADA-TUTR.DAT with mode
  7133. IN_FILE so that it can read blocks of characters by random access.  This
  7134. enables ADA-TUTR{;4}m to find and display any screen quickly.  The preliminary
  7135. comments in ADA-TUTR.ADA describe the format of the data file ADA-TUTR.DAT in
  7136. detail.
  7137.  
  7138. You may also want to examine the files DAT2TXT.ADA and TXT2DAT.ADA.  These two
  7139. programs are used when installing ADA-TUTR{;4}m on non-PC computers.  Their use is
  7140. described on page 39 of your printed course notes.  They with{;4}m both TEXT_IO and
  7141. DIRECT_IO, because they access a text file as well as a random access file.
  7142. However, to avoid confusion between the two packages, they use{;4}m neither TEXT_IO
  7143. nor the instantiation of DIRECT_IO.  Dot notation is used instead.
  7144. 1HPlease type a space to go on, or B to go back.                          1867153325343535B531$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QWhich commented line is illegal{;4}m?
  7145.  
  7146.     with TEXT_IO, SEQUENTIAL_IO; use TEXT_IO, SEQUENTIAL_IO;  -- 1{;4}m
  7147.     procedure IO is
  7148.        subtype LINE is STRING(1 .. 80);
  7149.        type SCREEN is array(1 .. 24) of LINE;
  7150.        package LINE_IO is new SEQUENTIAL_IO(LINE); use LINE_IO;  -- 2{;4}m
  7151.        package SCREEN_IO is new SEQUENTIAL_IO(SCREEN); use SCREEN_IO;  -- 3{;4}m
  7152.     begin
  7153.        null;
  7154.     end IO;
  7155. 1HPlease press 1, 2, or 3, or B to go back.         2233 536B532Q532$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    with TEXT_IO, SEQUENTIAL_IO; use TEXT_IO, SEQUENTIAL_IO;  -- 1{;4}m
  7156.     procedure IO is
  7157.        subtype LINE is STRING(1 .. 80);
  7158.        type SCREEN is array(1 .. 24) of LINE;
  7159.        package LINE_IO is new SEQUENTIAL_IO(LINE); use LINE_IO;  -- 2
  7160.        package SCREEN_IO is new SEQUENTIAL_IO(SCREEN); use SCREEN_IO;  -- 3
  7161.     begin
  7162.        null;
  7163.     end IO;
  7164.  
  7165. You're right!{;4}m  We can't use{;4}m a generic package, only its instantiations,
  7166. because we can't call the subprograms in a generic package.  The first line
  7167. should read
  7168.  
  7169.                 with TEXT_IO, SEQUENTIAL_IO; use TEXT_IO;  -- 1{;4}m
  7170. 1HPlease type a space to go on, or B or Q to go back to the question.                                           1912 536B532Q532$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    with TEXT_IO, SEQUENTIAL_IO; use TEXT_IO, SEQUENTIAL_IO;  -- 1
  7171.     procedure IO is
  7172.        subtype LINE is STRING(1 .. 80);
  7173.        type SCREEN is array(1 .. 24) of LINE;
  7174.        package LINE_IO is new SEQUENTIAL_IO(LINE); use LINE_IO;  -- 2
  7175.        package SCREEN_IO is new SEQUENTIAL_IO(SCREEN); use SCREEN_IO;  -- 3
  7176.     begin
  7177.        null;
  7178.     end IO;
  7179.  
  7180. No, the instantiation of SEQUENTIAL_IO for the subtype LINE is correct.
  7181. 1HPlease type a space to go on, or B or Q to go back to the question.                                                                1911 536B532Q532$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    with TEXT_IO, SEQUENTIAL_IO; use TEXT_IO, SEQUENTIAL_IO;  -- 1
  7182.     procedure IO is
  7183.        subtype LINE is STRING(1 .. 80);
  7184.        type SCREEN is array(1 .. 24) of LINE;
  7185.        package LINE_IO is new SEQUENTIAL_IO(LINE); use LINE_IO;  -- 2
  7186.        package SCREEN_IO is new SEQUENTIAL_IO(SCREEN); use SCREEN_IO;  -- 3
  7187.     begin
  7188.        null;
  7189.     end IO;
  7190.  
  7191. No, the instantiation of SEQUENTIAL_IO for the type SCREEN is correct.
  7192. 1HPlease type a space to go on, or B or Q to go back to the question.                                                                 3020 537B532$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      SUBPROGRAM PARAMETERS WITH GENERICS
  7193.  
  7194. The generic part of a subprogram or package can specify a dummy subprogram{;4}m as
  7195. well as a dummy type{;4}m.  This is similar to using subprograms as arguments
  7196. (parameters) in Algol and Pascal, and to using the little-known keyword
  7197. EXTERNAL in Fortran.  In Ada, we simply precede the dummy subprogram
  7198. specification with the keyword with{;4}m in the generic part.  This use of the word
  7199. with{;4}m has nothing to do with context clauses.  Here's the specification of a
  7200. generic function that has one dummy function specification in the generic part:
  7201.  
  7202.  generic
  7203.     with function DUMMY(X : in FLOAT) return FLOAT;
  7204.  function DEFINITE_INTEGRAL(LOWER_LIMIT, UPPER_LIMIT : in FLOAT) return FLOAT;{;4}m
  7205.  
  7206. We could then write a function COS, instantiate DEFINITE_INTEGRAL for it, and
  7207. use the instantiation as follows:
  7208.  
  7209.  ANSWER : FLOAT;
  7210.  function COS(X : in FLOAT) return FLOAT:
  7211.  function DEFINITE_INTEGRAL_OF_COS is new DEFINITE_INTEGRAL(COS);{;4}m
  7212.  ...
  7213.  ANSWER := DEFINITE_INTEGRAL_OF_COS(LOWER_LIMIT => 0.0, UPPER_LIMIT => 1.5708);{;4}m
  7214. 1HPlease type a space to go on, or B to go back.                                                        2754 538B536$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$generic
  7215.    with function DUMMY(X : in FLOAT) return FLOAT;{;4}m
  7216. function DEFINITE_INTEGRAL(LOWER_LIMIT, UPPER_LIMIT : in FLOAT) return FLOAT;
  7217.  
  7218. function DEFINITE_INTEGRAL(LOWER_LIMIT, UPPER_LIMIT : in FLOAT) return FLOAT is
  7219.    MULT : array(0 .. 6) of FLOAT := (1.0, 4.0, 2.0, 4.0, 2.0, 4.0, 1.0);
  7220.    SUM  : FLOAT := 0.0;
  7221.    X    : FLOAT;  -- the independent variable
  7222. begin
  7223.    for I in 0 .. 6 loop
  7224.       X   := LOWER_LIMIT + (FLOAT(I) / 6.0) * (UPPER_LIMIT - LOWER_LIMIT);
  7225.       SUM := SUM + MULT(I) * DUMMY(X){;4}m;
  7226.    end loop;
  7227.    return SUM * (UPPER_LIMIT - LOWER_LIMIT) / 18.0;
  7228. end DEFINITE_INTEGRAL;
  7229.  
  7230. This is one possible body for the generic function DEFINITE_INTEGRAL.  (The
  7231. specification is repeated for reference.)  This function integrates the
  7232. function DUMMY between the two limits by evaluating DUMMY at seven points and
  7233. using Simpson's rule.  (DEFINITE_INTEGRAL could be improved by making the
  7234. number of points a generic parameter, instead of fixing it at seven.)
  7235. 1HPlease type a space to go on, or B to go back.                      2833 539B537$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                        REPRESENTATION CLAUSES AND SYSTEM
  7236.  
  7237. Ada normally represents an enumeration type internally with successive integers
  7238. starting at zero.  For example, if we write
  7239.  
  7240.                  type COMMAND is (LEFT, RIGHT, FORWARD, BACK);{;4}m
  7241.  
  7242. the compiler will normally represent LEFT with 0, RIGHT with 1, etc.  Usually
  7243. this doesn't concern the programmer.  However, after the above declaration, we
  7244. can specify the internal representation with a representation clause{;4}m like this:
  7245.  
  7246.        for COMMAND use (LEFT => 1, RIGHT => 2, FORWARD => 4, BACK => 8);{;4}m
  7247.  
  7248. We might want to do that if, for example, we're sending a value of type COMMAND
  7249. to some hardware which will interpret the bit patterns.  The values must be
  7250. assigned in increasing order with no duplications, but gaps are permitted.  The
  7251. attributes SUCC, PRED, POS, and VAL are not{;4}m affected.  Thus COMMAND'POS(BACK){;4}m
  7252. is still 3.
  7253.  
  7254. We can specify the SIZE{;4}m, in bits, of the objects of a given type:
  7255. 1HPlease type a space to go on, or B to go back.                                           2921 540B538$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          type NUM is range 0 .. 100;
  7256.                           for NUM'SIZE use 8;{;4}m
  7257.  
  7258. We can specify the STORAGE_SIZE{;4}m (in bits!{;4}m) for a task and for a collection of
  7259. access{;4}med objects like a linked list.  If MONITOR{;4}m is a task and the
  7260. specification for our linked list says type P is access LINK;{;4}m, we can write
  7261.  
  7262.                      for MONITOR'STORAGE_SIZE use 16_384*8;
  7263.                      for P'STORAGE_SIZE use 32_768*8;{;4}m
  7264.  
  7265. The attributes SIZE and STORAGE_SIZE can also be used in the usual way:
  7266.  
  7267.                       I : INTEGER := MONITOR'STORAGE_SIZE;{;4}m
  7268.  
  7269. We can specify the attribute SMALL for a fixed point type:
  7270.  
  7271.                 type VOLTAGE is delta 0.01 range -20.0 .. 20.0;
  7272.                 for VOLTAGE'SMALL use 1.0/128.0;{;4}m
  7273.  
  7274. Before discussing the remaining types of representation clauses, we must
  7275. briefly mention the package SYSTEM{;4}m that comes with Ada.  SYSTEM{;4}m contains
  7276. implementation dependent specifications.
  7277. 1HPlease type a space to go on, or B to go back.                                                       3158 541B539$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A brief outline of package SYSTEM is in section 13.7 of the LRM.  However, the
  7278. full package specification should appear in the documentation that came with
  7279. your compiler.  For all compilers that meet the Ada Standard, the description
  7280. of implementation dependent features (including the specification of package
  7281. SYSTEM) is always in Appendix F of the documentation.  Of interest here is the
  7282. type ADDRESS.  In our examples, we'll assume that SYSTEM.ADDRESS is some
  7283. integer type.
  7284.  
  7285. Representation clauses can use the reserved word at{;4}m followed by a constant of
  7286. type SYSTEM.ADDRESS to specify the absolute address of a variable, a constant,
  7287. a task entry, a procedure, or a package.  The package SYSTEM must be visible.
  7288. This feature is useful for memory-mapped I/O and interrupt handlers, etc.  For
  7289. example:
  7290.  
  7291.                      MODEM_CONTROL : INTEGER;
  7292.                      for MODEM_CONTROL use at 16#FC00#;{;4}m
  7293.                      task INTERRUPT_HANDLER is
  7294.                         entry CLOCK_INTERRUPT;
  7295.                         for CLOCK_INTERRUPT use at 16#100#;{;4}m
  7296.                      end INTERRUPT_HANDLER;
  7297.                      procedure KEYSTROKE;
  7298.                      for KEYSTROKE use at 16#200#;{;4}m
  7299. 1HPlease type a space to go on, or B to go back.                  2851 542B540$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Finally, we can use at{;4}m, mod{;4}m, and range{;4}m to specify how records are stored.
  7300. For example,
  7301.  
  7302.                    type VERY_SHORT_INTEGER is range 0 .. 15;
  7303.                    type PACKED is
  7304.                       record
  7305.                          A, B, C, D : VERY_SHORT_INTEGER;
  7306.                       end record;
  7307.                    for PACKED use
  7308.                       record at mod 2;
  7309.                          A at 0 range 0 .. 3;
  7310.                          B at 0 range 4 .. 7;
  7311.                          C at 1 range 0 .. 3;
  7312.                          D at 1 range 4 .. 7;
  7313.                       end record;{;4}m
  7314.  
  7315. This forces A and B to be stored in bits 0 .. 3 and 4 .. 7 of byte 0 of the
  7316. record, and C and D to be packed into byte 1.  The optional clause record at
  7317. mod 2;{;4}m specifies that all records of type PACKED will begin at even addresses.
  7318.  
  7319. An implementation of Ada need not accept most representation clauses to meet
  7320. the standard.  If any clause is rejected, an error message will be printed.
  7321. 1HPlease type a space to go on, or B to go back.                         146625431544B541$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Q                type ANSWER is (YES, NO, MAYBE);
  7322.                 for ANSWER use (YES => 1, NO => 2, MAYBE => 4);
  7323.  
  7324. What is ANSWER'VAL(2)?
  7325.  
  7326.  
  7327. 1.  ANSWER'VAL(2) is NO.
  7328.  
  7329. 2.  ANSWER'VAL(2) is MAYBE.
  7330. 1HPlease press 1 or 2, or B to go back.          1729 545B542Q542$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                type ANSWER is (YES, NO, MAYBE);{;4}m
  7331.                 for ANSWER use (YES => 1, NO => 2, MAYBE => 4);
  7332.  
  7333.  
  7334. You're right!{;4}m  The representation clause doesn't affect the attributes POS and
  7335. VAL, and positions are numbered from zero.  So ANSWER'VAL(2){;4}m is MAYBE{;4}m.
  7336. 1HPlease type a space to go on, or B or Q to go back to the question.                                               1626 545B542Q542$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                type ANSWER is (YES, NO, MAYBE);
  7337.                 for ANSWER use (YES => 1, NO => 2, MAYBE => 4);
  7338.  
  7339.  
  7340. No, the representation clause doesn't affect the attributes POS and VAL, and
  7341. positions are numbered from zero.  So ANSWER'VAL(2) is MAYBE.
  7342. 1HPlease type a space to go on, or B or Q to go back to the question.                                                  2854 546B542$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                UNCHECKED CONVERSION AND UNCHECKED DEALLOCATION
  7343.  
  7344. Ada comes with a generic function UNCHECKED_CONVERSION{;4}m and a generic procedure
  7345. UNCHECKED_DEALLOCATION{;4}m.  They can be instantiated for any type.  Both are
  7346. somewhat dangerous to use, but we'll describe them briefly.  Their
  7347. specifications are:
  7348.  
  7349.             generic
  7350.                type SOURCE is limited private;
  7351.                type TARGET is limited private;
  7352.             function UNCHECKED_CONVERSION(S : SOURCE) return TARGET;
  7353.  
  7354.             generic
  7355.                type OBJECT is limited private;
  7356.                type NAME   is access OBJECT;
  7357.             procedure UNCHECKED_DEALLOCATION(X : in out NAME);{;4}m
  7358.  
  7359. UNCHECKED_CONVERSION "converts" from one type to another without doing any
  7360. arithmetic or bit manipulation.  In other words, it lets us look at an object
  7361. of one type as if it were of another type.  The effect is similar to the use
  7362. of EQUIVALENCE in Fortran.  The results may be unpredictable unless the two
  7363. types occupy the same amount of storage.
  7364. 1HPlease type a space to go on, or B to go back.                      3271 547B545$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$One use of UNCHECKED_CONVERSION might be to allow us to and{;4}m two INTEGERs.  Some
  7365. Ada compilers come with a package that enables us to do that, but many
  7366. compilers have no such package.  Suppose that types INTEGER and BOOLEAN occupy
  7367. the same amount of storage.  If our program says with UNCHECKED_CONVERSION;{;4}m we
  7368. could write
  7369.  
  7370.       function INT_TO_BOOL is new UNCHECKED_CONVERSION(INTEGER, BOOLEAN);
  7371.       function BOOL_TO_INT is new UNCHECKED_CONVERSION(BOOLEAN, INTEGER);
  7372.       function "and"(LEFT, RIGHT : in INTEGER) return INTEGER is
  7373.       begin
  7374.          return BOOL_TO_INT(INT_TO_BOOL(LEFT) and INT_TO_BOOL(RIGHT));
  7375.       end "and";{;4}m
  7376.  
  7377. Using UNCHECKED_CONVERSION usually destroys program portability.
  7378.  
  7379. UNCHECKED_DEALLOCATION allows us to free the memory occupied by an object
  7380. associated with a pointer.  Normally, the system reclaims memory when it's
  7381. needed.  However, the execution time for that so-called garbage collection{;4}m
  7382. tends to be long and unpredictable.  Suppose we have type P is access LINK;{;4}m and
  7383. HEAD : P;{;4}m.  Also suppose that we no longer need the object pointed to by HEAD{;4}m,
  7384. and we're sure that no other pointer points to the same object as HEAD.  If our
  7385. program says with UNCHECKED_DEALLOCATION;{;4}m we can write
  7386. 1HPlease type a space to go on, or B to go back.     2121 548B546$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             procedure FREE is new UNCHECKED_DEALLOCATION(LINK, P);{;4}m
  7387.              ...
  7388.              FREE(HEAD);{;4}m
  7389.  
  7390. This will release the memory occupied by the object pointed to by HEAD{;4}m, and
  7391. then set HEAD{;4}m to null{;4}m.  But there's a danger.  If there's another pointer that
  7392. pointed to the same object, it now points to released memory.  A reference to
  7393. that pointer will have unpredictable results.  In general, it's best to let the
  7394. system handle the reclaiming of memory.  That way there's no danger of dangling
  7395. references.
  7396. 1HPlease type a space to go on, or B to go back.                                                       3215 549B547$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    PRAGMAS
  7397.  
  7398. A pragma{;4}m is a message to the compiler.  The pragmas that are predefined by Ada
  7399. are all described in Appendix B of the LRM; we'll discuss the most important
  7400. ones here.  A particular version of Ada need not implement all the predefined
  7401. pragmas, and it may add some of its own.  (One version of Ada adds a pragma
  7402. TIME_SLICE, used with tasking.)  Unlike representation clauses, unimplemented
  7403. predefined pragmas do not{;4}m cause error messages; the compiler simply ignores
  7404. them.  This enhances program portability.  Any additional pragmas added by a
  7405. particular implementation of Ada will be explained in Appendix F of the
  7406. compiler documentation.  The most important predefined pragmas are these:
  7407.  
  7408. The statements pragma LIST(ON);{;4}m and pragma LIST(OFF);{;4}m turn on and off the
  7409. compiler listing.  Also, pragma PAGE;{;4}m will cause the compiler listing to start
  7410. a new page, if the listing is turned on.  These pragmas are allowed almost
  7411. anywhere in the program.
  7412.  
  7413. Within the declarative region we can write pragma OPTIMIZE(TIME);{;4}m or pragma
  7414. OPTIMIZE(SPACE);{;4}m to ask the compiler to optimize the program for minimum
  7415. execution time or minimum memory usage.
  7416. 1HPlease type a space to go on, or B to go back.                                                             3474 550B548$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$We can write pragma INLINE({;4}m...);{;4}m with the name of a subprogram to ask the
  7417. compiler to write inline code in place of every call to the subprogram.  Even
  7418. versions of Ada that implement this pragma will ignore it if the subprogram is
  7419. recursive.
  7420.  
  7421. We can interface a subprogram written in another language by writing pragma
  7422. INTERFACE({;4}m...,{;4}m ...);{;4}m after the subprogram specification.  The two arguments are
  7423. the name of the language and the subprogram name.  Consult the compiler
  7424. documentation for information on bringing the object file into the Ada library.
  7425.  
  7426. We can ask the compiler to minimize memory occupied by a record or array by
  7427. writing, after the type declaration, pragma PACK({;4}m...);{;4}m with the name of the
  7428. type.  Note that the specification for package STANDARD (in Appendix C of the
  7429. LRM) contains pragma PACK(STRING);{;4}m after the definition of type STRING.
  7430.  
  7431. Package SYSTEM defines a subtype of INTEGER called PRIORITY.  We can assign a
  7432. priority to a task by writing, in the specification, pragma PRIORITY({;4}m...);{;4}m with
  7433. an argument of subtype SYSTEM.PRIORITY.  Higher numbers denote greater urgency.
  7434.  
  7435. The pragma SUPPRESS{;4}m can be used to ask the compiler to turn off certain checks,
  7436. such as CONSTRAINT_ERROR.  It's dangerous and shouldn't be used unless
  7437. absolutely necessary because of time or memory constraints.
  7438. 1HPlease type a space to go on, or B to go back.  1521255115523553B549$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$QIn the author's opinion, which one of these is not{;4}m dangerous?
  7439.  
  7440.  
  7441.                       1.  UNCHECKED_DEALLOCATION
  7442.  
  7443.                       2.  pragma PACK
  7444.  
  7445.                       3.  pragma SUPPRESS
  7446. 1HPlease press 1, 2, or 3, or B to go back.                                                       1970 554B550Q550$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      1.  UNCHECKED_DEALLOCATION
  7447.  
  7448.                       2.  pragma PACK{;4}m
  7449.  
  7450.                       3.  pragma SUPPRESS
  7451.  
  7452.  
  7453. You're right!{;4}m  The worst pragma PACK{;4}m could do is slow the program down, and
  7454. this pragma is used in package STANDARD.  UNCHECKED_DEALLOCATION could allow a
  7455. pointer to point to memory that has been released, with unpredictable results.
  7456. SUPPRESS could allow a program to use a subscript that's out of range, etc.
  7457. 1HPlease type a space to go on, or B or Q to go back to the question.      1652 554B550Q550$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      1.  UNCHECKED_DEALLOCATION
  7458.  
  7459.                       2.  pragma PACK
  7460.  
  7461.                       3.  pragma SUPPRESS
  7462.  
  7463.  
  7464. No, UNCHECKED_DEALLOCATION is dangerous because it could allow a pointer to
  7465. point to memory that has been released, with unpredictable results.
  7466. 1HPlease type a space to go on, or B or Q to go back to the question.                        1612 554B550Q550$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      1.  UNCHECKED_DEALLOCATION
  7467.  
  7468.                       2.  pragma PACK
  7469.  
  7470.                       3.  pragma SUPPRESS
  7471.  
  7472.  
  7473. No, SUPPRESS is dangerous because it could allow a program to use a subscript
  7474. that's out of range, etc.
  7475. 1HPlease type a space to go on, or B or Q to go back to the question.                                                                3420 555B550$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                            LOOSE ENDS AND PITFALLS
  7476.  
  7477. In this final section, we cover some miscellaneous topics that were omitted
  7478. earlier for simplicity.  We also mention some common errors made by Ada
  7479. programmers.  Beginners aren't expected to understand every paragraph until
  7480. they've gained more experience, and we won't ask questions in this section.
  7481.  
  7482. Some terminals and printers don't support the entire ASCII character set.  In
  7483. an Ada program, the vertical bar |{;4}m may be replaced with the exclamation mark !{;4}m,
  7484. as in when 3 ! 5 =>{;4}m.  Also, a pair of sharp signs #{;4}m may be replaced with a pair
  7485. of colons :{;4}m, as in 16:FC03:{;4}m.  The quotation marks around a string constant may
  7486. be replaced with percent signs if the string doesn't contain any quotation
  7487. marks.  In that case, any percent signs within the string must be doubled.
  7488. These character replacements shouldn't be used in programs if the equipment
  7489. will support the standard characters.
  7490.  
  7491. An expression is called static{;4}m if it can be evaluated at compile time.  In
  7492. almost every case where a constant normally appears, a static expression may
  7493. also be used.  For example, an address representation clause normally takes
  7494. a constant of type SYSTEM.ADDRESS.  A static expression of this type is also
  7495. acceptable, as in for CLOCK_INTERRUPT use at 16*16;{;4}m.
  7496. 1HPlease type a space to go on, or B to go back.                                                        3841 556B554$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The unary minus is always an operator and never part of a constant.  Thus -5{;4}m
  7497. is actually a static expression and not a constant.  Normally, this doesn't
  7498. concern the programmer, because, as we just said, static expressions can
  7499. usually appear where a constant appears.  However, in a few special situations
  7500. we can get into trouble.  For example, we can write for I in 10 .. 20 loop{;4}m and
  7501. A : array(10 .. 20) of FLOAT;{;4}m but we can't omit the words INTEGER range{;4}m in
  7502. for I in INTEGER range -10 .. 10 loop{;4}m and A : array(INTEGER range -10 .. 10) of
  7503. FLOAT;{;4}m!  Also, if a package P declares type COUNT is new INTEGER;{;4}m then the
  7504. unary minus operator for that type is part of the package.  If our program
  7505. with{;4}ms but doesn't use{;4}m P, we can write A : P.COUNT := 1;{;4}m but not
  7506. B : P.COUNT := -1;{;4}m.  We either have to use{;4}m the package, rename{;4}m P."-", or write
  7507. B : P.COUNT := P."-"(1);{;4}m.
  7508.  
  7509. The operators have precedence, so that 1 + 2 * 3 means 1 + (2 * 3).  The
  7510. precedence of all the operators is given in section 4.5 of the LRM.  A
  7511. programmer should never have to look these up, because parentheses should be
  7512. used for any cases that aren't obvious.  Unary minus has a low precedence, so
  7513. -A mod B{;4}m means -(A mod B){;4}m.
  7514.  
  7515. If we write A, B : array(1 .. 5) of FLOAT;{;4}m then A and B have different{;4}m
  7516. anonymous types, and we can't write A := B;{;4}m.  To fix this, write
  7517. type VECTOR5 is array(1 .. 5) of FLOAT;{;4}m and then A, B : VECTOR5;{;4}m.
  7518. 1HPlease type a space to go on, or B to go back.                                   2844 557B555$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Ada will automatically convert from a universal type to a named type, but not
  7519. from a named type to a universal.  For example,
  7520.  
  7521.                     C1 : constant INTEGER := 1;  -- legal
  7522.                     C2 : constant INTEGER := 2;  -- legal
  7523.                     C3 : constant := C1 + C2;    -- illegal{;4}m
  7524.  
  7525. When arrays are assigned, the subscripts don't have to match; only the lengths
  7526. and types need match.  But if a formal parameter ("dummy argument") of a
  7527. subprogram is a constrained array, the subscripts in the call to the subprogram
  7528. must match.  For example, the last line here will raise CONSTRAINT_ERROR:
  7529.  
  7530.                       subtype NAME is STRING(1 .. 30);
  7531.                       JOHN : NAME;
  7532.                       LINE : STRING(1 .. 80);
  7533.                       procedure DISPLAY(PERSON : in NAME);{;4}m
  7534.                       ...
  7535.                       JOHN := LINE(51 .. 80);   -- legal
  7536.                       DISPLAY(LINE( 1 .. 30));  -- legal
  7537.                       DISPLAY(LINE(51 .. 80));  -- illegal{;4}m
  7538. 1HPlease type a space to go on, or B to go back.                                2960 558B556$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$When a subprogram formal parameter is an un{;4}mconstrained array, beginners often
  7539. wrongly assume that the subscripts will start with one.  For example,
  7540.  
  7541.                       LINE : STRING(1 .. 80);
  7542.                       procedure DISPLAY(S : in STRING) is
  7543.                       begin
  7544.                          for I in 1 .. S'LENGTH loop{;4}m
  7545.                             ... S(I){;4}m ...
  7546.  
  7547. This will raise CONSTRAINT_ERROR if we call DISPLAY(LINE(51 .. 80));{;4}m.  The for{;4}m
  7548. statement should be changed to say for I in S'RANGE loop{;4}m.
  7549.  
  7550. Remember that elaboration occurs at run time.  The following raises
  7551. PROGRAM_ERROR by trying to activate a task before elaborating its body:
  7552.  
  7553.                            task type T is{;4}m ... end T;
  7554.                            type P is access T;
  7555.                            T1 : P := new T;
  7556.                            task body T is{;4}m ... end T;{;4}m
  7557.  
  7558. The third line should be changed to T1 : P;{;4}m and the statement T1 := new T;{;4}m
  7559. should be placed in the executable region.
  7560. 1HPlease type a space to go on, or B to go back.                2654 559B557$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Similarly, this procedure tries to activate a function before elaborating its
  7561. body.  The initialization of J should be moved to the executable region:
  7562.  
  7563.                  procedure TEST is
  7564.                     function X return INTEGER;
  7565.                     J : INTEGER := X;  -- Raises PROGRAM_ERROR.
  7566.                     function X return INTEGER is
  7567.                     begin
  7568.                        return 5;
  7569.                     end X;
  7570.                  begin
  7571.                     null;
  7572.                  end TEST;{;4}m
  7573.  
  7574. A return{;4}m statement in a function is used with an object: return ANSWER;{;4}m.
  7575. However, return{;4}m may also appear without an object in a procedure{;4}m; we simply
  7576. write return;{;4}m.  Normally, a procedure returns after executing its last
  7577. statement, but an early return is possible by this method.  Well structured
  7578. programs don't use this feature of Ada.
  7579. 1HPlease type a space to go on, or B to go back.                      3016 560B558$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Some implementations of Ada provide a package LOW_LEVEL_IO{;4}m which includes
  7580. overloaded procedures SEND_CONTROL{;4}m and RECEIVE_CONTROL{;4}m to interface various
  7581. hardware devices directly.  This package is completely implementation
  7582. dependent, so you'll have to consult Appendix F of your compiler documentation.
  7583.  
  7584. Many implementations of Ada allow you to insert machine code{;4}m into a program.
  7585. Some implementations do this with a pragma, such as pragma NATIVE{;4}m, which can be
  7586. inserted in the middle of a procedure, function, etc.  Other implementations
  7587. provide a package called MACHINE_CODE{;4}m which usually contains a rather complex
  7588. record definition representing the format of a machine instruction.  In this
  7589. case, we can write a procedure or function that with{;4}ms MACHINE_CODE.  In place
  7590. of the usual Ada statements in the executable region, we write record
  7591. aggregates, each one representing a machine code instruction.  Since the method
  7592. of inserting machine code into a program varies from one implementation to the
  7593. next, you'll have to consult the compiler documentation.
  7594. 1HPlease type a space to go on, or B to go back.                                                            2824 561B559$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In the unusual case of a for{;4}m loop index hiding an explicitly declared object of
  7595. the same name, the explicitly declared object can be accessed inside the loop.
  7596. Simply use dot notation with the name of the compilation unit (procedure,
  7597. function, etc.)  For example, the following is legal:
  7598.  
  7599.                            procedure MAIN is
  7600.                               IX : FLOAT;
  7601.                               J  : INTEGER;
  7602.                            begin
  7603.                               IX := 3.2;
  7604.                               for IX in 1 .. 10 loop
  7605.                                  MAIN.IX{;4}m := 6.0;
  7606.                                  J := IX;
  7607.                               end loop;
  7608.                            end MAIN;
  7609.  
  7610. Inside{;4}m the loop, IX{;4}m refers to the loop index, and the explicitly declared
  7611. object can be accessed by writing MAIN.IX{;4}m.  Outside{;4}m the loop, IX{;4}m refers to the
  7612. explicitly declared object, and the loop index doesn't exist.
  7613. 1HPlease type a space to go on, or B to go back.                                                    2171 562B560$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In the rare case of an aggregate containing just one element, we must use named
  7614. notation rather than positional notation.  For example, the last line is
  7615. illegal in the following program segment, because the right hand side is a
  7616. FLOAT rather than an array of one FLOAT.
  7617.  
  7618.                 type VECTOR is array(INTEGER range <>) of FLOAT;
  7619.                 A : VECTOR(1 .. 1);{;4}m
  7620.                 ...
  7621.                 A := (1 => 2.3);  -- legal
  7622.                 A := (2.3);  -- illegal{;4}m
  7623.  
  7624. It's OK to use positional notation in calls to subprograms with only one
  7625. argument, for example, PUT_LINE("Hello");{;4}m.
  7626. 1HPlease type a space to go on, or B to go back.     3042 101B561$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Well, we haven't covered all{;4}m there is to know about Ada, but this has been a
  7627. very thorough course.  If you've come this far and completed the six Outside
  7628. Assignments, you should be a very good Ada programmer.  To be an excellent Ada
  7629. programmer, start doing all your casual programming in Ada.  If you need a
  7630. simple program to balance your checkbook, write it in Ada!  At this point,
  7631. switching to Ada for all your programming will do you much more good than
  7632. further instruction from a tutor program.
  7633.  
  7634. The best way to answer any remaining questions about Ada is to "ask the
  7635. compiler" by writing a brief test program, especially if your compiler is
  7636. validated.  You can also look in the LRM, which, by definition, does cover all{;4}m
  7637. of the Ada language.  However, the LRM isn't easy reading!
  7638.  
  7639. The best way to debug a short program is often to execute it by hand, with
  7640. pencil and paper.  You can also add extra statements to the program to display
  7641. intermediate results, and remove them later.
  7642.  
  7643. We wish you success with Ada, and welcome your comments and suggestions!
  7644.  
  7645. Now, you can press B to go back,
  7646.  
  7647.                   or, for one last time ...
  7648. 1H                          ... type a space to go on.