Welcome to A D A - T U T R The Interactive Ada Tutor by John J. Herro, Ph.D. Software Innovations Technology These are the printed course notes. Ver. 1.20, 21 Dec. 1988 Copyright 1988 John J. Herro Software Innovations Technology 1083 Mandarin Dr. NE, Palm Bay, FL 32905-4706 (407)951-0233 You may make copies of these notes, in printed or machine-readable form. You may also copy the computer program. Please see page 1 for details. Page i TABLE OF CONTENTS Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . . ii Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Registration and Licenses - What is Shareware? . . . . . . . . . . 2 Before You Run ADA-TUTR on Your PC . . . . . . . . . . . . . . . . 3 The Ada Reserved Words . . . . . . . . . . . . . . . . . . . . . . 4 Steps for Outside Assignment 1, Preparing to Run Ada . . . . . . . 5 Listings of HELLO.ADA and ADD.ADA . . . . . . . . . . . . . . . . 6 Listing of TRITEST.ADA . . . . . . . . . . . . . . . . . . . . . . 7 Steps for Outside Assignment 2, Exercise in Enumeration Types . . 9 Listing of NEXTDATE.ADA . . . . . . . . . . . . . . . . . . . . . 10 Steps for Outside Assignment 3, Exercise in Records . . . . . . . 11 Listing of FIBTEST.ADA . . . . . . . . . . . . . . . . . . . . . . 12 Steps for Outside Assignment 4, Exercise in Recursion . . . . . . 13 Simplified Specification for TEXT_IO . . . . . . . . . . . . . . . 14 Listings of Procedure FILECOPY and Function EXISTS . . . . . . . . 16 Requirements for the Program LEDIT . . . . . . . . . . . . . . . . 17 Steps for Outside Assignment 5, Writing a Simple Line Editor . . . 22 How to Test LEDIT . . . . . . . . . . . . . . . . . . . . . . . . 23 Listing of LEDIT.ANS . . . . . . . . . . . . . . . . . . . . . . . 26 Listing of TASKING.DUM . . . . . . . . . . . . . . . . . . . . . . 30 Steps for Outside Assignment 6, Exercise in Tasking . . . . . . . 31 Output from TASKING.EXE After Modification of TASKING.ADA . . . . 32 Listing of TASKING.ANS . . . . . . . . . . . . . . . . . . . . . . 33 Appendix A: Special Offer to Companies, Schools, Etc. . . . . . . 34 Appendix B: Note to Compiler Companies . . . . . . . . . . . . . 35 Appendix C: Some Ada Compilers Available for the PC . . . . . . . 36 Appendix D: Do You Need a Screen Editor / Word Processor? . . . . 38 Appendix E: Installing ADA-TUTR on Other Computers . . . . . . . 39 Appendix F: We Listen! New Features of ADA-TUTR . . . . . . . . 44 Appendix G: Disclaimer of Warranty . . . . . . . . . . . . . . . 45 Page ii ACKNOWLEDGEMENTS The following trademarks are used in these notes and in the accompanying files: AdaStarter Meridian Software Systems, Inc. AdaVantage Meridian Software Systems, Inc. Alsys Ada Alsys, Inc. IBM International Business Machines Corp. IntegrAda Aetech, Inc. Janus/Ada R & R Software, Inc. PC-Write Quicksoft TeleGen Telesoft Corporation Turbo Pascal Borland International UNIX AT & T VAX Digital Equipment Corporation VMS Digital Equipment Corporation The file ONECHAR.C was sent to us by Mr. David Hill, 7549 Wynford Street, Salt Lake City, UT 84121. We're very grateful to Mr. Hill for giving us permission to include it in ADA-TUTR. This file, used with UNIX.ADA, makes it possible to run the Tutor on UNIX based machines without having to strike ENTER after each response. See pages 39-43. The programs in this version of ADA-TUTR were compiled with Meridian AdaStarter, and the .EXE files contain Meridian's runtime. Page 1 INTRODUCTION ADA-TUTR, the Interactive Ada Tutor, will make you an excellent Ada programmer in minimum time. You'll learn good Ada program design techniques, not just Ada syntax. ADA-TUTR runs on PCs as well as large mainframes. On PCs an Ada compiler is helpful, but not required. The PC needs a hard disk, and can have a monochrome or a color monitor. These printed notes aren't meant to be a complete course, or even a summary, of Ada. They merely accompany the program ADA-TUTR, which is a complete course. You can't "study" these printed notes alone. For now, just read through page 3. ADA-TUTR lets you learn at your own pace. So that you don't feel pressured, ADA-TUTR doesn't keep track of the number of right and wrong answers. It simply tells you whether your answers are correct, and why. Also, there's no time limit for answering the questions or completing the Outside Assignments. Because I want every programmer to have a chance to learn the best programming language, I made ADA-TUTR available very inexpensively as Shareware. Shareware isn't the same as public domain, and ADA-TUTR isn't free. But you may TRY it for free, and register or buy a license only if you use it. Please see pages 2 and 34 for details. Whether or not you use ADA-TUTR and register (or buy a license), you're encouraged to make unmodified copies and give them away. Please put ADA-TUTR on computer bulletin boards, distribute copies at club meetings, give them to companies, etc. You may charge a small fee to copy the program, provided you make it clear that the fee is only for the copy, and doesn't pay for the Shareware. (Companies that copy Shareware usually charge about $2 to $10 per diskette.) Bulletin boards may carry ADA-TUTR even if they charge for access. Please contact us for permission to include ADA-TUTR with commercial products, such as Ada compilers (see page 35). You may use file compression, library, and archive programs on ADA-TUTR; we won't interpret that as "modifying" the program. You may also add your own files. (The files included with ADA-TUTR are briefly described in ED.DIR.) If you register, you can earn substantial money distributing ADA-TUTR; please see page 2 for details. Ada will become more and more important, since the Department of Defense mandated its use in mission-critical systems, and is now making it very hard to obtain waivers. Although learning Ada takes real effort, you'll be able to write software that's more reliable and easier to modify a month or a year later. New features of this version of ADA-TUTR are described on page 44. Please send me your comments and suggestions. I wish you success using ADA-TUTR! John J. Herro, Ph.D., Software Innovations Technology 1083 Mandarin Drive NE, Palm Bay, FL 32905-4706 (407)951-0233 Page 2 REGISTRATION AND LICENSES - WHAT IS SHAREWARE? Shareware is a way of marketing a program. It lets you try the program before spending money for it. If you decide to use the program, you send a small payment to register your copy or buy a license. We give you several incentives to do so, explained below. You're on your honor; you know whether you're "using" ADA-TUTR or only "trying" it. To use ADA-TUTR, individuals register as described below. Companies, schools, and other organizations can register each individual who uses the program, or buy a Multi-User License as described on page 34. INDIVIDUALS: Register your copy for only $25. When you register, please give us the serial number from the ADA-TUTR opening screen. We'll assign you a new serial number. Then run CHANGESN to put your new number into the program, and give copies to individuals, schools, companies, clubs, computer bulletin boards, etc. We'll send you a commission of $5 for each individual who registers from one of your copies, and TEN PERCENT for each Multi-User License sold from one of your copies! As you can see from page 34, you can earn up to $240 per license sold! Commissions are paid quarterly. If you like, print the file AD.TXT and use copies as an advertisement. Registration includes the right to use ADA-TUTR as long as you like, and it includes technical support for one year. While you have technical support, we'll inform you of any important updates to ADA-TUTR, and send you updated copies for only $5 each ($10 if you prefer a 3.5" diskette, free if you send us a blank, formatted, 360K 5.25" diskette or 720K 3.5" diskette with a stamped, addressed diskette mailer). We're planning a major update of ADA-TUTR with the next revision (9X) of the Ada language. You can renew technical support for only $10 a year. Even if you don't renew, you'll continue to receive commissions. When you register, you may order the current version of ADA-TUTR, with your serial number. The price is $5 for a 5.25" diskette, $10 for a 3.5" diskette, or free with your formatted diskette and a stamped, addressed diskette mailer. If you would like an order form or a price list, please print the file INVOICE.TXT. We offer a Customization Kit that lets you edit, add, and delete ADA-TUTR screens, questions, etc. (even whole topics), producing a new ADA-TUTR.DAT file. Please see page 34 for details. Note that the Customization Kit is not Shareware. We sell anywhere in the Free World. Outside the U.S., please remit in U.S. funds and contact us about extra postal charges on diskettes. COMPANIES, SCHOOLS, AND OTHER ORGANIZATIONS: Please see our special offer for Multi-User Licenses, on page 34. Page 3 BEFORE YOU RUN ADA-TUTR ON YOUR PC Give the command TYPE READ.ME on your PC. If one word appears brighter than the rest, you can skip this page. However, if your screen shows strange characters like "[1m", you need to read this. ADA-TUTR uses ANSI (American National Standards Institute) escape sequences for highlighting, cursor positioning, reverse video, etc. Before ADA-TUTR will work correctly on a PC, you must install the device driver ANSI.SYS. To install ANSI.SYS, do the following: 1. If there's a file CONFIG.SYS in the root directory of the disk from which you boot, type it and look for a line saying "DEVICE=ANSI.SYS" (without the quotes), in either upper or lower case. If that line is not present, add it to CONFIG.SYS anywhere in the file, using an ordinary text editor or word processor in the non-document mode. If there's no CONFIG.SYS file, create one containing the single line "DEVICE=ANSI.SYS" (without the quotes). 2. If there's no file ANSI.SYS in your root directory, copy ANSI.SYS from from your system distribution diskette to the root directory of the disk from which you boot. 3. Reboot the computer. ADA-TUTR should then work correctly. Page 4 THE ADA RESERVED WORDS The 63 reserved words are listed in the Language Reference Manual in section 2.9, and are repeated here for convenience. abort declare generic of select abs delay goto or separate accept delta others subtype access digits if out all do in task and is package terminate array pragma then at else private type elsif limited procedure end loop begin entry raise use body exception range exit mod record when rem while new renames with case for not return constant function null reverse xor Page 5 STEPS FOR OUTSIDE ASSIGNMENT 1, PREPARING TO RUN ADA For the first Outside Assignment, learn enough about your Ada compiler to compile and run the two simple programs HELLO.ADA and ADD.ADA. Obviously, you have to do this before you can do the remaining Outside Assignments. 1. Compile HELLO.ADA. On most systems, after the Ada compiler is installed and your library is created, this only involves typing ADA HELLO or ADA HELLO.ADA. On some systems, the compiler is invoked from a menu or "APSE" (Ada Programming Support Environment). 2. Link, giving the name of the main program, HELLO. This usually involves typing LINK HELLO or BIND HELLO, perhaps with some options. On one system, the command is BAMP HELLO, for Build Ada Main Program! 3. Run the program. If your Ada compiler produces native code on a PC, it created a file HELLO.EXE, and this step simply involves typing HELLO. On other systems, the command RUN HELLO is appropriate. On some systems, you have to invoke an interpreter to run the program. 4. Now compile, link, and run ADD.ADA. If your compiler implements a subset of Ada, you may have to modify the programs in this and later Outside Assignments to get them to compile. Some compilers don't allow "separate" compilation (used in later assignments), and you'll have to include the "separate" subprograms inside the main program and compile them as one. Some compilers don't allow generic instantiation, and have another way of displaying integers. In that case, you'll have to modify ADD.ADA. If you're using a validated compiler, you won't have to worry about any of this, because all of the Outside Assignments are written in standard Ada. Page 6 HELLO.ADA --------- with TEXT_IO; use TEXT_IO; procedure HELLO is begin PUT_LINE("Hello!"); end HELLO; ADD.ADA ------- with TEXT_IO; use TEXT_IO; procedure ADD is package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO; begin PUT(2 + 2); NEW_LINE; end ADD; Page 7 TRITEST.ADA ----------- with TEXT_IO; use TEXT_IO; procedure TRITEST is PASSED : BOOLEAN := TRUE; type TRIANGLE is (EQUILATERAL, ISOSCELES, SCALENE, NOT_A_TRIANGLE); function TRITYPE(LEN1, LEN2, LEN3 : in INTEGER) return TRIANGLE is separate; procedure COMPARE(A, B, C: in INTEGER; RIGHT_ANSWER : in TRIANGLE) is separate; begin COMPARE( 3, 4, 5, SCALENE); COMPARE( 6, 3, 4, SCALENE); COMPARE( 4, 3, 6, SCALENE); COMPARE( 3, 3, 3, EQUILATERAL); COMPARE( 3, 3, 4, ISOSCELES); COMPARE( 3, 4, 3, ISOSCELES); COMPARE( 4, 3, 3, ISOSCELES); COMPARE( 7, 7, 4, ISOSCELES); COMPARE( 7, 4, 7, ISOSCELES); COMPARE( 4, 7, 7, ISOSCELES); COMPARE( 1, 1, 1, EQUILATERAL); COMPARE( 0, 4, 4, NOT_A_TRIANGLE); COMPARE( 4, 0, 4, NOT_A_TRIANGLE); COMPARE( 4, 4, 0, NOT_A_TRIANGLE); COMPARE( 0, 4, 3, NOT_A_TRIANGLE); COMPARE( 3, 0, 4, NOT_A_TRIANGLE); COMPARE( 4, 3, 0, NOT_A_TRIANGLE); COMPARE(-1, 4, 4, NOT_A_TRIANGLE); COMPARE( 4, -1, 4, NOT_A_TRIANGLE); COMPARE( 4, 4, -1, NOT_A_TRIANGLE); COMPARE(-1, 4, 3, NOT_A_TRIANGLE); COMPARE( 3, -1, 4, NOT_A_TRIANGLE); COMPARE( 4, 3, -1, NOT_A_TRIANGLE); COMPARE( 2, 4, 6, NOT_A_TRIANGLE); COMPARE( 1, 3, 2, NOT_A_TRIANGLE); COMPARE( 3, 1, 2, NOT_A_TRIANGLE); COMPARE( 1, 2, 4, NOT_A_TRIANGLE); COMPARE( 1, 4, 2, NOT_A_TRIANGLE); COMPARE( 4, 1, 2, NOT_A_TRIANGLE); COMPARE( 0, 0, 0, NOT_A_TRIANGLE); COMPARE( 0, 0, 4, NOT_A_TRIANGLE); COMPARE( 0, 4, 0, NOT_A_TRIANGLE); COMPARE( 4, 0, 0, NOT_A_TRIANGLE); COMPARE( 3, 3, 7, NOT_A_TRIANGLE); COMPARE( 3, 7, 3, NOT_A_TRIANGLE); COMPARE( 6, 3, 3, NOT_A_TRIANGLE); COMPARE(-3, -4, -5, NOT_A_TRIANGLE); if PASSED then PUT_LINE("Congratulations, you completed the assignment!"); end if; end TRITEST; -- continued -- Page 8 separate(TRITEST) procedure COMPARE(A, B, C: in INTEGER; RIGHT_ANSWER : in TRIANGLE) is package INT_IO is new INTEGER_IO(INTEGER); use INT_IO; package TRI_IO is new ENUMERATION_IO(TRIANGLE); use TRI_IO; MY_ANSWER : TRIANGLE := TRITYPE(A, B, C); begin if MY_ANSWER /= RIGHT_ANSWER then PUT("Sides:"); PUT(A, WIDTH => 3); PUT(B, WIDTH => 3); PUT(C, WIDTH => 3); PUT(" My answer: "); PUT(MY_ANSWER, WIDTH => 14); PUT(" Right answer: "); PUT(RIGHT_ANSWER); NEW_LINE; PASSED := FALSE; end if; end COMPARE; Page 9 STEPS FOR OUTSIDE ASSIGNMENT 2, EXERCISE IN ENUMERATION TYPES 1. Compile the test driver TRITEST.ADA. Also, make a copy of the dummy solution by typing COPY TRITYPE.DUM TRITYPE.ADA. You need do this step only once. 2. Edit TRITYPE.ADA to become your real solution. You can skip this step the first time through, to see error messages from the test driver. 3. Compile your solution TRITYPE.ADA. If there are compiler errors, go back to step 2. 4. Link with the name of the main program TRITEST. Then execute. If the test driver prints error messages, go back to step 2. 5. When the message "Congratulations, you completed the assignment!" is printed, you'll have a chance to compare your solution with ours. Page 10 NEXTDATE.ADA ------------ with TEXT_IO; use TEXT_IO; procedure NEXTDATE is type MONTH_TYPE is (JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC); subtype DAY_SUBTYPE is INTEGER range 1 .. 31; type DATE is record DAY : DAY_SUBTYPE; MONTH : MONTH_TYPE; YEAR : POSITIVE; end record; PASSED : BOOLEAN := TRUE; function TOMORROW(TODAY : in DATE) return DATE is separate; procedure DISPLAY (S : in STRING; D : in DATE) is package INT_IO is new INTEGER_IO(INTEGER); use INT_IO; begin PUT(S); PUT(D.DAY, WIDTH => 3); PUT(" " & MONTH_TYPE'IMAGE(D.MONTH)); PUT(D.YEAR, WIDTH => 5); NEW_LINE; end DISPLAY; procedure COMPARE(TODAY, RIGHT_ANSWER : in DATE) is MY_ANSWER : DATE := TOMORROW(TODAY); begin if MY_ANSWER /= RIGHT_ANSWER then DISPLAY("Today: ", TODAY); DISPLAY("My answer: ", MY_ANSWER); DISPLAY("Right answer:", RIGHT_ANSWER); NEW_LINE; PASSED := FALSE; end if; end COMPARE; begin COMPARE((12,DEC,1815), (13,DEC,1815)); -- ordinary date COMPARE(( 3,FEB,1986), ( 4,FEB,1986)); -- ordinary date in Feb. COMPARE((30,JUN,1981), ( 1,JUL,1981)); -- last day of 30-day month COMPARE((30,SEP,3999), ( 1,OCT,3999)); -- last day of 30-day month COMPARE((31,MAR,1876), ( 1,APR,1876)); -- last day of 31-day month COMPARE((31,AUG,1984), ( 1,SEP,1984)); -- last day of 31-day month COMPARE((31,DEC,1966), ( 1,JAN,1967)); -- last day of year COMPARE((28,FEB,1980), (29,FEB,1980)); -- leap year COMPARE((28,FEB,1600), (29,FEB,1600)); -- century leap year COMPARE((28,FEB,2200), ( 1,MAR,2200)); -- century non-leap year COMPARE((28,FEB,1982), ( 1,MAR,1982)); -- non-leap year COMPARE((29,FEB,1980), ( 1,MAR,1980)); -- leap day in leap year if PASSED then PUT_LINE("Congratulations, you completed the assignment!"); end if; end NEXTDATE; Page 11 STEPS FOR OUTSIDE ASSIGNMENT 3, EXERCISE IN RECORDS 1. Compile the test driver NEXTDATE.ADA. Also, make a copy of the dummy solution by typing COPY TOMORROW.DUM TOMORROW.ADA. You need do this step only once. 2. Edit TOMORROW.ADA to become your real solution. You can skip this step the first time through, to see error messages from the test driver. 3. Compile TOMORROW.ADA. If there are compiler errors, go back to step 2. 4. Link with the name of the main program NEXTDATE. Then execute. If the test driver prints error messages, go back to step 2. 5. When the message "Congratulations, you completed the assignment!" is printed, you'll have a chance to compare your solution with ours. Page 12 FIBTEST.ADA ----------- with TEXT_IO; use TEXT_IO; procedure FIBTEST is PASSED : BOOLEAN := TRUE; function FIB(N : in POSITIVE) return POSITIVE is separate; procedure COMPARE (N : in POSITIVE; RIGHT_ANSWER : in POSITIVE) is package INT_IO is new INTEGER_IO(INTEGER); use INT_IO; MY_ANSWER : POSITIVE := FIB(N); begin if MY_ANSWER /= RIGHT_ANSWER then PUT("N:"); PUT(N); PUT(" My answer:"); PUT(MY_ANSWER); PUT(" Right answer:"); PUT(RIGHT_ANSWER); NEW_LINE; PASSED := FALSE; end if; end COMPARE; begin COMPARE(1,1); COMPARE(2,1); COMPARE(3,2); COMPARE(4,3); COMPARE(5,5); COMPARE(6,8); COMPARE(7,13); COMPARE(10,55); COMPARE(15,610); COMPARE(20,6765); if PASSED then PUT_LINE("Congratulations, you completed the assignment!"); end if; end FIBTEST; Page 13 STEPS FOR OUTSIDE ASSIGNMENT 4, EXERCISE IN RECURSION 1. Compile the test driver FIBTEST.ADA. Also, make a copy of the dummy solution by typing COPY FIB.DUM FIB.ADA. You need do this step only once. 2. Edit FIB.ADA to become your real solution. You can skip this step the first time through, to see error messages from the test driver. 3. Compile FIB.ADA. If there are compiler errors, go back to step 2. 4. Link with the name of the main program FIBTEST. Then execute. If the test driver prints error messages, go back to step 2. 5. When the message "Congratulations, you completed the assignment!" is printed, you'll have a chance to compare your solution with ours. Page 14 SIMPLIFIED SPECIFICATION FOR TEXT_IO ------------------------------------ package TEXT_IO is type FILE_TYPE is limited private; type FILE_MODE is (IN_FILE, OUT_FILE); type COUNT is ... (a user-defined type similar to INTEGER); STATUS_ERROR, MODE_ERROR, NAME_ERROR, END_ERROR : exception; procedure CREATE (FILE : in out FILE_TYPE; MODE : in FILE_MODE := OUT_FILE; NAME : in STRING); procedure OPEN (FILE : in out FILE_TYPE; MODE : in FILE_MODE; NAME : in STRING); procedure CLOSE (FILE : in out FILE_TYPE); procedure DELETE (FILE : in out FILE_TYPE); procedure NEW_LINE (SPACING : in COUNT := 1); procedure NEW_LINE (FILE : in FILE_TYPE; SPACING : in COUNT := 1); procedure SKIP_LINE (SPACING : in COUNT := 1); procedure SKIP_LINE (FILE : in FILE_TYPE; SPACING : in COUNT := 1); function END_OF_FILE (FILE : in FILE_TYPE) return BOOLEAN; procedure PUT (ITEM : in CHARACTER); procedure PUT (FILE : in FILE_TYPE; ITEM : in CHARACTER); procedure GET (ITEM : out CHARACTER); procedure GET (FILE : in FILE_TYPE; ITEM : out CHARACTER); procedure PUT (ITEM : in STRING); procedure PUT (FILE : in FILE_TYPE; ITEM : in STRING); procedure PUT_LINE (ITEM : in STRING); procedure PUT_LINE (FILE : in FILE_TYPE; ITEM : in STRING); procedure GET_LINE (ITEM : out STRING; LAST : out NATURAL); procedure GET_LINE (FILE : in FILE_TYPE; ITEM : out STRING; LAST : out NATURAL); generic type NUM is range <>; package INTEGER_IO is procedure GET (ITEM : out NUM); procedure GET (FILE : in FILE_TYPE; ITEM : out NUM); procedure PUT (ITEM : in NUM; WIDTH : in INTEGER := ...; BASE : in INTEGER := 10); procedure PUT (FILE : in FILE_TYPE; ITEM : in NUM; WIDTH : in INTEGER := ...; BASE : in INTEGER := 10); end INTEGER_IO; -- continued -- Page 15 generic type NUM is digits <>; package FLOAT_IO is procedure GET (ITEM : out NUM); procedure GET (FILE : in FILE_TYPE; ITEM : out NUM); procedure PUT (ITEM : in NUM; FORE : in INTEGER := 2; AFT : in INTEGER := ...; EXP : in INTEGER := 3); procedure PUT (FILE : in FILE_TYPE; ITEM : in NUM; FORE : in INTEGER := 2; AFT : in INTEGER := ...; EXP : in INTEGER := 3); end FLOAT_IO; generic type ENUM is (<>); package ENUMERATION_IO is procedure GET (ITEM : out ENUM); procedure GET (FILE : in FILE_TYPE; ITEM : out ENUM); procedure PUT (ITEM : in ENUM; WIDTH : in INTEGER := 0); procedure PUT (FILE : in FILE_TYPE; ITEM : in ENUM; WIDTH : in INTEGER := 0); end ENUMERATION_IO; private type FILE_TYPE is ... (implementation dependent); end TEXT_IO; Page 16 Program to copy a simple text file: ----------------------------------- with TEXT_IO; use TEXT_IO; procedure FILECOPY is F1, F2 : FILE_TYPE; S : STRING(1 .. 80); LEN : INTEGER; begin PUT("Input file: "); GET_LINE(S, LEN); OPEN(FILE => F1, MODE => IN_FILE, NAME => S(1 .. LEN)); PUT("Output file: "); GET_LINE(S, LEN); CREATE(FILE => F2, MODE => OUT_FILE, NAME => S(1 .. LEN)); while not END_OF_FILE(F1) loop GET_LINE(F1, S, LEN); PUT_LINE(F2, S(1 .. LEN)); end loop; CLOSE(F1); CLOSE(F2); end FILECOPY; Function to test if a text file exists: --------------------------------------- with TEXT_IO; use TEXT_IO; function EXISTS(FILE_NAME : in STRING) return BOOLEAN is F : FILE_TYPE; ANSWER : BOOLEAN := TRUE; begin begin OPEN(F, IN_FILE, FILE_NAME); CLOSE(F); exception when NAME_ERROR => ANSWER := FALSE; end; return ANSWER; end EXISTS; Page 17 REQUIREMENTS FOR THE PROGRAM LEDIT This assignment will give you practice in writing a program of greater complexity than the previous programs you've written. Imagine that your screen editor is unavailable to a particular user, perhaps because he's dialing your computer from a remote location, and your screen editor writes directly to the screen. You want to write a very simple line editor, LEDIT, that could be used in such circumstances. While your computer already has a line editor called EDLIN, it's difficult to learn to use. LEDIT will take almost no effort to learn. The only commands are LIST and EXIT! The line editor edits by means of line numbers, similar to the Basic language. The user begins each line of text that he types with a line number from 1 to 29999. Line numbers must be integers. The upper limit 29999 was chosen so that the simple type INTEGER could be used - in any implementation of Ada. Regardless of the order in which lines are typed, LEDIT maintains a linked list of lines in order by number. Also, line numbers may be preceded by any number of spaces. For example, if the user types 40 -- This is a comment. 20 begin 10 with TEXT_IO; use TEXT_IO; 30 end ADD; and then types LIST, the editor will type 10 with TEXT_IO; use TEXT_IO; 20 begin 30 end ADD; 40 -- This is a comment. To INSERT lines, the user merely types lines with intermediate line numbers. For example, if he types 15 procedure HELLO is and then types LIST, LEDIT will type 10 with TEXT_IO; use TEXT_IO; 15 procedure HELLO is 20 begin 30 end ADD; 40 -- This is a comment. To REPLACE an existing line, the user merely types a line with the same line number as the line to be replaced. For example, if he typed 15 procedure ADD is LIST -- continued -- Page 18 LEDIT would then show 10 with TEXT_IO; use TEXT_IO; 15 procedure ADD is 20 begin 30 end ADD; 40 -- This is a comment. Finally, to DELETE a line, the user merely types the number of the line to be deleted, followed immediately by a carriage return. Typing 40 LIST would then produce 10 with TEXT_IO; use TEXT_IO; 15 procedure ADD is 20 begin 30 end ADD; Thus the user can INSERT, REPLACE, and DELETE lines, all by line numbers, without learning any commands. Note that in this simple editor there is no "cursor" or "current line." The space is not required after the line number. These two lines have exactly the same effect: 20 begin 20begin Of course, if the text of the line begins with a digit, a space will be required to separate it from the line number. In any event, LEDIT always leaves one blank space after the line number when LISTing, for readability. It always allows exactly five spaces for the line number itself. However, any EXTRA spaces typed after the line number are significant. The three lines below each contain three EXTRA spaces after the line number, for a total of four spaces. 24 PUT(2 + 2); 26 NEW_LINE; 18 package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO; They have the effect of indenting the text three spaces. LIST now shows -- continued -- Page 19 10 with TEXT_IO; use TEXT_IO; 15 procedure ADD is 18 package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO; 20 begin 24 PUT(2 + 2); 26 NEW_LINE; 30 end ADD; Although typing a line number followed immediately by a carriage return deletes a line (if there is a line by that number), typing a line number followed by a single space causes an empty line to be introduced into the file. For example, typing 12 followed by a single space and a carriage return would then cause LIST to type 10 with TEXT_IO; use TEXT_IO; 12 15 procedure ADD is 18 package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO; 20 begin 24 PUT(2 + 2); 26 NEW_LINE; 30 end ADD; When LEDIT is run, it prompts for the names of the input and output files. If the input file exists, LEDIT prints "File found" and reads the file into its linked list, assigning line numbers starting with 10 and incrementing by 10. If the file does not exist, LEDIT prints "File not found," and the linked list is initially empty. In any event, LEDIT creates an output file. When the EXIT command is given, LEDIT writes the contents of the linked list to the output file. In doing so, LEDIT removes the line numbers and the first blank after each line number. In the example above, let us assume that the user typed ADD.ADA for an output file name. When he types EXIT, the new file ADD.ADA created by LEDIT will contain: with TEXT_IO; use TEXT_IO; procedure ADD is package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO; begin PUT(2 + 2); NEW_LINE; end ADD; (Note that the file contains one empty line.) Your program is not allowed to add any trailing blanks of its own in the output file. If the user again runs LEDIT and specifies ADD.ADA as an input file, the editor will type "File found" and read the file. LIST will show -- continued -- Page 20 10 with TEXT_IO; use TEXT_IO; 20 30 procedure ADD is 40 package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO; 50 begin 60 PUT(2 + 2); 70 NEW_LINE; 80 end ADD; When he EXITs, the new file will contain modified text. The old file will still be present until it is deleted. The two commands LIST and EXIT must be accepted in either upper or lower case, but for simplicity, they need not be accepted in a mixture of cases. They may be preceded by any number of spaces. The LIST command must be accepted in any of the following forms: LIST (Lists all lines, if any, otherwise does nothing.) list 30 (Lists line 30, if it exists.) list 25 - 35 (Lists all lines between 25 and 35 inclusive, if any.) LIST - 35 (Lists all lines numbered 35 or less, if any.) list 25 - (Lists all lines numbered 25 or more, if any.) Furthermore, all spaces are optional in the LIST command provided that LIST is written solid, so that LIST25-35 is equivalent to the third example above. Any other forms of LIST should be flagged as an error. In particular, all of these should give error messages: LIST - list 2A LIST 30 - 50 - list 30 - -50 list 30-A LIST XYZ The EXIT command must stand alone; unlike LIST, EXIT is never followed by anything. Except for the LIST and EXIT commands, every line typed must begin with a number between 1 and 29999. (Of course, the user should be able to type just a carriage return with no effect.) LEDIT should check that line numbers are in range when adding or replacing lines. The LIST command need not check the range of the line numbers, because it should be impossible to create lines with improper numbers. Your program need not handle input files so long that 29999 would be exceeded when it assigns line numbers starting at 10 with an increment of 10. Your LEDIT must prompt for input and output file names at the start, and it may print a prompt for each line that the user types. You may assume some maximum length for an input line (e.g., 80), and assume that no file will have lines longer than the maximum. You may also assume that no file will have special characters like form feeds. -- continued -- Page 21 For simplicity, there's no way to edit a line except by retyping it. Also, there's no way to copy or move a line or a block of lines, and no way to delete a block of lines except one line at a time. There's no RENUMBER command. The user can renumber the entire file starting at 10 with an increment of 10 by EXITing and then rerunning LEDIT. There's no AUTO command to make the editor type the line numbers automatically while text is being typed from the keyboard, and there's no means of recovering from a system crash that occurs during an edit. Additionally, there's no way to search for a string, or replace one string with another. These features would all be desirable, but we feel that Outside Assignment 5 is challenging as it stands. You're encouraged to use of Ada's "separate" compilation feature, so that you don't have to recompile the entire program when developing a module. As a point of reference, our solution to this assignment consists of about 180 lines of code on four pages. If you have any questions about what LEDIT should do, you can compile and run our solution, which is in LEDIT.ANS. The following declarations are offered by way of suggestion only, and you should use them only if you feel comfortable with them: MAX_LENGTH : constant INTEGER := 80; type TEXT is record LEN : INTEGER range 0 .. MAX_LENGTH; VAL : STRING(1 .. MAX_LENGTH); end record; type LINK; type P is access LINK; type LINK is record NUM : POSITIVE; LINE : TEXT; NEXT : P; end record; function STR(T : in TEXT) return STRING; In our solution, we used type TEXT as above. However, we didn't write a TEXT_HANDLER package, because it didn't seem to be needed. We used a one-page main program with several "separate" subprograms. Page 22 STEPS FOR OUTSIDE ASSIGNMENT 5, WRITING A SIMPLE LINE EDITOR 1. Carefully read the requirements starting on page 17 of these notes. Take your time. 2. Write the Ada code, compile, and link. Call the main program LEDIT. If you have any questions about what LEDIT should do, you can compile and run our solution, which is in LEDIT.ANS. 3. Refer to pages 23-25 of these notes for instructions on testing your line editor. If any tests are failed, go back to step 2. 4. When all the tests are passed, you've completed the assignment and will have a chance to compare your solution with ours. Page 23 HOW TO TEST LEDIT 1. Run LEDIT and give the name of an input file that doesn't exist. LEDIT should say "File not found." Give another name of a file that doesn't exist for an output file. 2. Type "LIST" (without the quotes) to make sure that LEDIT can handle the LIST command when no text has been entered. 3. Type "EXI". The program should NOT exit. If it exits, it's probably because the "T" was left in the input buffer from the LIST command. Your program is checking the first four characters of the input buffer without checking the length of the typed command. 4. Type "ABC". The program should print a message about an illegal or unrecognized command, or syntax error. 5. Type "0X" (zero followed by X). The program should reject this line, printing a message about an invalid line number. Type "0 X". The same thing should happen. Try "30000X", then "30000 X", and then "3000000000 X". The program should reject these, as well. 6. Type "-1 X" and "-1X". The program should reject these lines, printing a message either about an unrecognized command (or syntax error), or an invalid line number. 7. Type a simple carriage return. There should be no effect, except for any prompt being repeated. 8. Type the following exactly as shown. Note that lines 1000 and 100 each contain four spaces: 30 X 1 The 29999 ZZZZZZZZ 1000 used 100 is 10000 to test 30file -- 1 This 29999 LEDIT. 9. Type "list". You should see the following, lined up exactly as shown. There should be exactly five spaces for the line numbers. 1 This 30 file -- 100 is 1000 used 10000 to test 29999 LEDIT. -- continued -- Page 24 10. Try a line of text beginning with a number: "20000 123 45". Then type " LIST" with three leading spaces. You should see 1 This 30 file -- 100 is 1000 used 10000 to test 20000 123 45 29999 LEDIT. 11. Insert an empty line by typing "15000 ". Then type "LIST". You should see 1 This 30 file -- 100 is 1000 used 10000 to test 15000 20000 123 45 29999 LEDIT. 12. Type "EXIT ABC". LEDIT should print a error message and NOT exit. The requirements say that the EXIT command must stand alone. 13. Type " exit". LEDIT should exit, and you should have a new file with the output file name you gave in step 1. Type the file with the TYPE command. You should see exactly this, starting in column 1: This file -- is used to test 123 45 LEDIT. 14. Run LEDIT again, using for an input file the name of the OUTPUT file you specified in step 1. This time the program should say "File found." Choose yet another name for an output file for this step. Type "list". You should see the following, exactly as shown: 10 This 20 file -- 30 is 40 used 50 to test 60 70 123 45 80 LEDIT. -- continued -- Page 25 15. Type " LIST 30". You should see only line 30. Type "list25-45". You should see only lines 30 and 40. Type "LIST - 40". You should see lines 10 through 40. Type "list35 -". You should see lines 40 through 80. Type "list 15". The program should either do nothing or print a message that line 15 doesn't exist. Try "list 30000" and "list 3000000000". Again, the program should either do nothing or print an error message. Now type "list" and check that the result is the same as in step 14. 16. Try each of the following. In each case, LEDIT should print an error message: LIST - list 2A list 30 - 50 - list 30 - -50 list 30-A LIST XYZ 17. Type "70" to delete line 70. Type "LIST". You should see 10 This 20 file -- 30 is 40 used 50 to test 60 80 LEDIT. 18. Delete line 60. Do not list. Now delete line 80 and list. You should see 10 This 20 file -- 30 is 40 used 50 to test 19. Delete line 10 and list. You should see lines 20 through 50 above. Delete line 50 and list. You should see lines 20 through 40. Delete line 30 and list. You should see lines 20 and 40. Delete line 40 and list. You should see only line 20. Delete line 20 and list. The result should be the same as in step 2. Type "EXIT". 20. If your program passed all these tests, sincere congratulations! You've completed a difficult assignment. We hope that you feel comfortable with Ada now. If you like, you can compare your solution with ours, starting on page 26 of these notes. When you go back to ADA-TUTR, you'll learn to write your own generic packages, procedures, and functions. Page 26 LEDIT.ANS --------- -- Our solution to Outside Assignment 5: with TEXT_IO; use TEXT_IO; procedure LEDIT is MAX_LENGTH : constant := 80; MAX_LINE_NUMBER : constant := 29_999; type TEXT is record LEN : INTEGER range 0 .. MAX_LENGTH := 0; VAL : STRING(1 .. MAX_LENGTH); end record; type LINK; type P is access LINK; type LINK is record NUM : POSITIVE; LINE : TEXT; NEXT : P; end record; HEAD : P := new LINK; TEMP : P; INPUT_FILE, OUTPUT_FILE : FILE_TYPE; INPUT : TEXT; FINISHED : BOOLEAN := FALSE; LINE_NUM : NATURAL := 10; function STR(T : in TEXT) return STRING is separate; procedure READ_INPUT_FILE is separate; procedure DO_COMMAND is separate; begin PUT("Input file: "); GET_LINE(INPUT.VAL, INPUT.LEN); READ_INPUT_FILE; PUT("Output file: "); GET_LINE(INPUT.VAL, INPUT.LEN); CREATE(OUTPUT_FILE, NAME => STR(INPUT)); -- Get and process commands. while not FINISHED loop PUT("> "); GET_LINE(INPUT.VAL, INPUT.LEN); DO_COMMAND; end loop; -- Write the output file. TEMP := HEAD.NEXT; -- Skip unused link at start of linked list. while TEMP /= null loop PUT_LINE(OUTPUT_FILE, STR(TEMP.LINE)); -- Write line of text. TEMP := TEMP.NEXT; -- Get next link. end loop; CLOSE(OUTPUT_FILE); end LEDIT; -- continued -- Page 27 separate(LEDIT) function STR(T : in TEXT) return STRING is begin return T.VAL(1 .. T.LEN); end STR; separate (LEDIT) procedure READ_INPUT_FILE is begin -- If the input file exists, print a message and read it in. OPEN(INPUT_FILE, IN_FILE, STR(INPUT)); PUT_LINE("File found."); TEMP := HEAD; while not END_OF_FILE(INPUT_FILE) loop GET_LINE(INPUT_FILE, INPUT.VAL, INPUT.LEN); -- Read a line. TEMP.NEXT := new LINK'(LINE_NUM, INPUT, null); -- Add to list. TEMP := TEMP.NEXT; -- Advance pointer to next link. LINE_NUM := LINE_NUM + 10; end loop; CLOSE(INPUT_FILE); exception -- If the input file doesn't exist, just print a message. when NAME_ERROR => PUT_LINE("File not found."); end READ_INPUT_FILE; separate(LEDIT) procedure DO_COMMAND is procedure DELETE_FIRST_CHARACTER(T : in out TEXT) is separate; procedure GET_LEADING_INTEGER(N : out NATURAL) is separate; procedure STRIP_LEADING_SPACES_FROM_INPUT is separate; procedure ADD_DELETE_REPLACE_LINE is separate; procedure LIST is separate; begin STRIP_LEADING_SPACES_FROM_INPUT; if STR(INPUT) = "exit" or STR(INPUT) = "EXIT" then FINISHED := TRUE; elsif INPUT.LEN >= 4 and (INPUT.VAL(1 .. 4) = "list" or INPUT.VAL(1 .. 4) = "LIST") then LIST; elsif INPUT.LEN > 0 and INPUT.VAL(1) not in '0' .. '9' then PUT_LINE("Unrecognized command."); elsif INPUT.LEN > 0 then GET_LEADING_INTEGER(LINE_NUM); if LINE_NUM not in 1 .. MAX_LINE_NUMBER then PUT_LINE("Illegal line number."); else ADD_DELETE_REPLACE_LINE; end if; end if; exception when NUMERIC_ERROR | CONSTRAINT_ERROR => PUT_LINE("Line number too large."); end DO_COMMAND; -- continued -- Page 28 separate(LEDIT.DO_COMMAND) procedure ADD_DELETE_REPLACE_LINE is INP : TEXT := INPUT; begin if INP.LEN > 0 and INP.VAL(1) = ' ' then -- Treat "9x" like "9 x". DELETE_FIRST_CHARACTER(INP); end if; TEMP := HEAD; -- Find where this number belongs in linked list. while TEMP /= null and then TEMP.NEXT /= null and then TEMP.NEXT.NUM <= LINE_NUM loop if TEMP.NEXT.NUM = LINE_NUM then TEMP.NEXT := TEMP.NEXT.NEXT; -- Delete line. else TEMP := TEMP.NEXT; -- Advance to next link in list. end if; end loop; if INPUT.LEN > 0 then -- Add line. TEMP.NEXT := new LINK'(LINE_NUM, INP, TEMP.NEXT); end if; end ADD_DELETE_REPLACE_LINE; separate(LEDIT.DO_COMMAND) procedure DELETE_FIRST_CHARACTER(T : in out TEXT) is begin T.VAL(1 .. T.LEN - 1) := T.VAL(2 .. T.LEN); T.LEN := T.LEN - 1; end DELETE_FIRST_CHARACTER; separate(LEDIT.DO_COMMAND) procedure GET_LEADING_INTEGER(N : out NATURAL) is ANS: INTEGER := 0; begin while INPUT.LEN > 0 and INPUT.VAL(1) in '0' .. '9' loop ANS := ANS*10 + CHARACTER'POS(INPUT.VAL(1)) -CHARACTER'POS('0'); DELETE_FIRST_CHARACTER(INPUT); end loop; N := ANS; end GET_LEADING_INTEGER; separate(LEDIT.DO_COMMAND) procedure STRIP_LEADING_SPACES_FROM_INPUT is begin while INPUT.LEN > 0 and INPUT.VAL(1) = ' ' loop DELETE_FIRST_CHARACTER(INPUT); end loop; end STRIP_LEADING_SPACES_FROM_INPUT; -- continued -- Page 29 separate(LEDIT.DO_COMMAND) procedure LIST is package IIO is new INTEGER_IO(INTEGER); use IIO; START, FINISH : NATURAL; VALID : BOOLEAN := TRUE; begin INPUT.LEN := INPUT.LEN - 4; -- Delete the name of the command. INPUT.VAL(1 .. INPUT.LEN) := INPUT.VAL(5 .. INPUT.LEN + 4); STRIP_LEADING_SPACES_FROM_INPUT; if INPUT.LEN = 0 then -- For "LIST" alone, list all lines. START := 0; FINISH := MAX_LINE_NUMBER + 1; else GET_LEADING_INTEGER(START); -- Get number after "LIST". STRIP_LEADING_SPACES_FROM_INPUT; if INPUT.LEN = 0 then -- For "LIST n", list only line n. FINISH := START; elsif INPUT.VAL(1) /= '-' then -- Else "-" must follow n. VALID := FALSE; else DELETE_FIRST_CHARACTER(INPUT); -- Delete the "-". STRIP_LEADING_SPACES_FROM_INPUT; GET_LEADING_INTEGER(FINISH); -- Get number after "-". STRIP_LEADING_SPACES_FROM_INPUT; if FINISH = 0 and START = 0 then -- "LIST -" isn't valid. VALID := FALSE; elsif FINISH = 0 then -- For "LIST n -", list n through end. FINISH := MAX_LINE_NUMBER + 1; end if; VALID := VALID and INPUT.LEN = 0; -- No trailing garbage. end if; end if; if not VALID then PUT_LINE("Illegal syntax for LIST."); else TEMP := HEAD.NEXT; -- Skip unused link at start of linked list. while TEMP /= null and then TEMP.NUM <= FINISH loop if TEMP.NUM >= START then PUT(TEMP.NUM, WIDTH => 5); -- Print line number, width 5. PUT_LINE(' ' & STR(TEMP.LINE)); -- Print text of line. end if; TEMP := TEMP.NEXT; -- Get next link. end loop; end if; exception when NUMERIC_ERROR | CONSTRAINT_ERROR => PUT_LINE("Line number too large in LIST."); end LIST; Page 30 TASKING.DUM ----------- with text_io, calendar; use text_io, calendar; procedure tasking is interval : constant duration := 5.0; total_intervals : constant positive := 9; start_time : constant time := clock; quitting_time : constant time := start_time + total_intervals*interval; next_time : time := start_time; task type tick is entry make_noise; entry shutdown; end tick; t : tick; task body tick is quit : boolean := false; begin while not quit loop select accept make_noise do put_line("Tick!"); end make_noise; or accept shutdown; quit := true; end select; end loop; end tick; begin while next_time < quitting_time loop t.make_noise; next_time := next_time + interval; delay next_time - clock; new_line; end loop; t.shutdown; end tasking; Page 31 STEPS FOR OUTSIDE ASSIGNMENT 6, EXERCISE IN TASKING 1. Make a copy of TASKING.DUM by typing COPY TASKING.DUM TASKING.ADA. Compile, link, and execute the program to make sure it prints "Tick!" nine times. 2. Edit TASKING.ADA to become your solution. Make your changes in upper case. 3. Compile TASKING.ADA, link, and execute. 4. Compare your output with page 32 of these notes. If there are any errors, go back to step 2. 5. When your output agrees with these notes, you've finished the assignment and will have a chance to compare your solution with ours. Page 32 OUTPUT FROM TASKING.EXE AFTER MODIFICATION OF TASKING.ADA C>tasking Task number 1 is starting. Task number 2 is starting. Task number 3 is starting. Task number 1 is starting. Task number 2 is starting. Task number 1 is starting. Task number 3 is starting. Task number 1 is starting. Task number 2 is starting. Task number 1 is starting. Task number 3 is starting. C> Page 33 TASKING.ANS ----------- -- Our solution to Outside Assignment 6: with text_io, calendar; use text_io, calendar; procedure tasking is interval : constant duration := 5.0; total_intervals : constant positive := 9; start_time : constant time := clock; quitting_time : constant time := start_time + total_intervals*interval; next_time : time := start_time; task type tick is ENTRY IDENTIFY(TASK_NUMBER : IN NATURAL); entry shutdown; end tick; T : ARRAY(1 .. 3) OF TICK; PERIOD : CONSTANT ARRAY(T'RANGE) OF POSITIVE := (2, 3, 4); TIMER : ARRAY(T'RANGE) OF NATURAL := (OTHERS => 0); task body tick is quit : boolean := false; begin while not quit loop select ACCEPT IDENTIFY(TASK_NUMBER : IN NATURAL) DO PUT_LINE("Task number" & INTEGER'IMAGE(TASK_NUMBER) & " is starting."); END IDENTIFY; or accept shutdown; quit := true; end select; end loop; end tick; begin while next_time < quitting_time loop FOR I IN T'RANGE LOOP IF TIMER(I) = 0 THEN T(I).IDENTIFY(I); TIMER(I) := PERIOD(I); END IF; TIMER(I) := TIMER(I) - 1; END LOOP; next_time := next_time + interval; delay next_time - clock; new_line; end loop; FOR I IN T'RANGE LOOP T(I).SHUTDOWN; END LOOP; end tasking; Page 34 APPENDIX A: SPECIAL OFFER TO COMPANIES, SCHOOLS, ETC. ADA-TUTR can be of great benefit to your company, school, or other organization. We let you try ADA-TUTR before paying for it, and you may install ADA-TUTR on your mainframes as well as your PCs! Instructions are on page 39. If you decide to use the program, you could register each individual user, as described on page 2. But if you have more than 18 users, you can save money by buying a Multi-User License, as described here. You're on your honor; you know whether you're "using" ADA-TUTR or only "trying" it. Multi-User Licenses are reasonably priced, as follows: Number of Users: Price of License: Up to 100 only $450 A license may always be Up to 500 only $725 upgraded for only the Up to 2000 only $950 difference in price. Unlimited only $2400 A Multi-User License gives the specified number of people the right to use ADA-TUTR as long as you like, on all your computers (from small PCs to large mainframes), at all your locations. (Note: If 100 people use ADA-TUTR now and 100 others use it later, that counts as 200 users, not 100.) Sales commissions are NOT paid to Multi-User Licensees. Send $5 extra for a copy of the latest version of ADA-TUTR on a 5.25" diskette, $10 extra if you prefer a 3.5" diskette. A Multi-User License includes one year of technical support, which can be renewed for only 10% of the price of the license per year. While you have technical support, we'll inform you of any important updates to ADA-TUTR, and send you an updated copy on a 5.25" diskette for only $5 ($10 for a 3.5" diskette). The update is free if you send your own blank, formatted, diskette and a stamped, addressed diskette mailer. We're planning a major update of ADA-TUTR with the next revision (9X) of the Ada language. Please print the file INVOICE.TXT, or use your own form. When ordering, please give us the serial number from the opening screen of your copy of ADA-TUTR. With Shareware, you never have to worry about software piracy, because your people are ENCOURAGED to copy and distribute the program! If you prefer, however, a conventional (non-Shareware) version of ADA-TUTR is available at the same prices. If you buy a license, we'll be happy to do minor customization of ADA-TUTR for you at no charge. For example, we can add your company name to the opening screen. If you'd like major customization, contact us for terms, or buy our Customization Kit for $195. Using any text editor on a PC or mainframe, this kit lets you edit, add, and delete screens, questions, etc. (even whole topics), producing a new ADA-TUTR.DAT file. It's not Shareware, but you may copy it for use throughout your organization as required. We sell anywhere in the Free World. Outside the U.S., please remit in U.S. funds and contact us about extra postal charges on diskettes. Page 35 APPENDIX B: NOTE TO COMPILER COMPANIES A commercial version of ADA-TUTR is available, without the Shareware notices and without the list of Ada compilers. You can greatly increase the sales appeal and value of your Ada compiler by including the commercial version of ADA-TUTR with your product. Please contact us for terms. Page 36 APPENDIX C: SOME ADA COMPILERS AVAILABLE FOR THE PC Here's a brief list of Ada compilers available for the IBM PC and compatibles. For this course, an Ada compiler is helpful, but not required. There are six Outside Assignments; most of them ask you to write and compile a short Ada program. If you don't have access to an Ada compiler, just skip the Outside Assignments. As of this writing (December, 1988), we have no financial interest in any company mentioned here. (That may change; see the note to compiler companies on page 35.) If you know of an Ada compiler for the PC that you think should be on this list, please contact us. 1. At the low end of the scale is Augusta. This compiler is in the public domain, and can be found on many computer bulletin boards. It's a very small subset of Ada with no packages. It translates Ada to a P-code, and then interprets the P-code. Some of the syntax is non-standard, such as "elseif" where Ada uses "elsif." Older versions of Augusta require Turbo Pascal. 2. ADA/Ed-C is a full Ada "translator" available from NYUADA Project, New York University, 251 Mercer St., New York, NY 10012, for $95. Phone 212-460-7482. It translates Ada to an intermediate code and then interprets. On a PC/XT, programs larger than a few hundred lines run out of memory, but on a PC/AT, the translator passes all the tests of the validation suite. Although this is a full Ada, no utility packages are provided. 3. AdaVantage is sold by Meridian Software, Inc., 23141 Verdugo Dr., Suite 105, Laguna Hills, CA 92653. Phone 800-221-2522 (in CA, 714-380-9800). It's validated and produces native code; no interpreter is needed. The full-sized version is $795. However, an "AdaStarter" version which compiles small programs is sold for $95 through Programmer's Connection, 7249 Wipple Ave. NW, North Canton, OH 44720, phone 800-336-1166. Utility packages are extra on both compilers. 4. Lattice Corp., 2500 S. Highland Ave., Suite 300, Lombard, IL 60148, will, in mid 1989, offer a validated Ada compiler with an intermediate code interpreter for about $100. Phone 312-916-1600. Lattice Ada will have a full Ada Programming Support Environment (APSE) with a source code symbolic debugger, and utility packages will be included. A compiler that also produces native code will follow later at higher cost. 5. Janus/Ada is now validated, and is sold by R & R Software, Box 1512, Madison, WI 53701, for $129. Phone 800-722-3248. Utility packages are available at considerable extra expense. Janus/Ada produces native code. -- continued -- Page 37 6. IntegrAda is sold by Aetech, Inc., 380 Stevens Ave., Solana Beach, CA 92075, for $495, including utility packages. Phone 619-755-1277. The compiler is validated and produces native code. 7. At the high end of the scale is Alsys Ada, sold by Alsys, Inc., 1432 Main St., Waltham, MA 02154, for $3300. Phone 617-890-0030. It's a validated Ada that requires a PC/AT (or compatible), but can produce native code for the PC/XT. The price includes an extra memory board for the AT. Page 38 APPENDIX D: DO YOU NEED A SCREEN EDITOR / WORD PROCESSOR? The Outside Assignments will be much easier if you have a good screen editor. We've looked at many, and found PC-Write, a Shareware program by Quicksoft of Seattle, WA to be the best screen editor as well as word processor. There's lots of on-line help, and the 50000-word spelling checker can be turned on for editing letters and documents, and off for editing source code. We liked the idea of having to learn only ONE program for both kinds of editing. Unlike ADA-TUTR, PC-Write runs only on PCs and compatibles, not on mainframes, etc. We have no connection with Quicksoft, except for being a registered user of PC-Write. However, we'll be happy to send you a free copy of the latest version of that excellent program, if you send us THREE blank, formatted, 360K 5.25" diskettes or TWO 720K 3.5" diskettes, and a stamped, addressed diskette mailer. Or send us $15 for three 5.25" diskettes, or $20 for two 3.5" diskettes. The diskettes or fee covers only our expenses; you must register your copy of PC-Write with Quicksoft if you use it after a free trial. We're sorry, but we're not allowed to send copies of PC-Write outside North America. If you do use PC-Write to edit Ada programs, you may find the file ED.ADA, included with ADA-TUTR, to be helpful. It allows typing many Ada reserved words with a single keystroke. For example, you can type "procedure" by striking Alt-P. See the file ED.ADA for more details. PC-Write will automatically invoke ED.ADA whenever you edit a file with the extension .ADA. Page 39 APPENDIX E: INSTALLING ADA-TUTR ON OTHER COMPUTERS Because source code is included with ADA-TUTR, you can install ADA-TUTR on almost any computer that has an Ada compiler - from compact units to large mainframes. ADA-TUTR is written in Ada (of course!), and Ada programs tend to be very portable. The screen should have at least 24 rows of 80 characters each, and should support the ANSI escape sequences for highlighting, reverse video, cursor positioning, etc. Almost all computers qualify. You need a way to send text files from your PC to the other computer. Files are usually sent to large mainframes with the program KERMIT, which is in the public domain. One version of KERMIT runs on the PC, another on the mainframe. The two communicate with each other. Sometimes XMODEM or another protocol is used instead of KERMIT. If a communications program is available on the PC but not on the other computer, you can still send text files, but not as efficiently. Connect your PC as a terminal and tell the other computer to copy the keyboard to a new file. For example, on a VAX computer running VMS, the command is "COPY TT: filename.ext" (without the quotes). Then tell your communications program to send (or "upload") the file, using ASCII protocol, and stripping line feeds. After the file is sent, type the appropriate end-of-file character for the other computer. On a VAX running VMS, you would type Control-Z. Since this method of file transfer doesn't do error checking, you may have to send each file twice using two different names, and compare the two files with each other on the other computer. It's far better to use a communications program on the other computer, if one is available. OK, you have some means of sending text files. You won't have to send other kinds of files. To install ADA-TUTR on the other computer, just follow these steps: 1. Type DAT2TXT on the PC. This will read the file ADA-TUTR.DAT, which is not a text file, and create a new text file TUTOR.TXT, which can be sent to the other computer. DAT2TXT will probably take several minutes to run. Don't try to bypass this step even if you're able to send non-text files. It's important that you send TUTOR.TXT and not ADA-TUTR.DAT, because the PC version of ADA-TUTR.DAT doesn't work on some systems. 2. Decide where ADA-TUTR will reside on the other computer, so that it will be accessible by all users. For example, on a VAX computer running VMS, the tutor is usually placed in SYS$INSTRUCTION. It could also be placed in SYS$MANAGER, etc. -- continued -- Page 40 3. Send to the other computer all the files that come with ADA-TUTR, except ADA-TUTR.DAT and the files ending in .EXE. Be sure to send TUTOR.TXT, created in step 1. Don't try to send ADA-TUTR.DAT and the .EXE files, because they're not text files. Also note that ADA-TUTR creates a file ADA-TUTR.USR the first time it's run. Do NOT send that file, because it also is not a text file. If our file names are illegal on the other system, you'll have to rename them as they're sent. (We haven't seen a system where our file names are illegal.) 4. If any of the file names ADA-TUTR.DAT, ADA-TUTR.USR, or TUTOR.TXT are illegal on your system, edit the files ADA-TUTR.ADA, CHANGESN.ADA, and TXT2DAT.ADA to show new, legal file names. Search for the old file names and replace them with the new ones. 5. Note that each user will probably run ADA-TUTR from his own file directory. There will be a file ADA-TUTR.USR in each user's directory, but all the other files will reside in a common area, such as SYS$INSTRUCTION, etc. Therefore, edit the files ADA-TUTR.ADA, CHANGESN.ADA, and TXT2DAT.ADA to show the full path name of the file ADA-TUTR.DAT. On a VAX system, for example, you might search for the name ADA-TUTR.DAT and replace it with SYS$INSTRUCTION:ADA-TUTR.DAT. 6. On one system we encountered, Ada source file names must end in .a rather than .ADA. If that's the case on your system, rename all the .ADA files. 7. On the other computer, compile, link, and run TXT2DAT.ADA. Some systems call the linking step "binding." This program will read TUTOR.TXT and create ADA-TUTR.DAT on the other system. If you wish, you may then delete TUTOR.TXT. 8. If you're using VAX Ada, skip to page 42. If you're using a UNIX based system that has a C compiler with the ability to link into Ada programs, skip to page 43. Otherwise, continue with the next page. If you're not certain, continue with the next page. -- continued -- Page 41 9. Compile VANILLA.ADA, but don't try to link or run it. This "plain vanilla" file will work with any standard Ada compiler. 10. Compile ADA-TUTR.ADA. 11. Link, giving the name of the main program, ADA_TUTR (with an underline). This will produce an executable file, which on most systems will be called ADA_TUTR.EXE (with an underline). Rename this file. On most systems, the appropriate new name is ADA-TUTR.EXE (with a hyphen). 12. Run ADA-TUTR. Note that, on some systems, you'll have to strike ENTER (or RETURN or NEW-LINE) after each response, even though the program says, "You need not hit ENTER." The reason is that some systems require you to strike ENTER when they read the keyboard through TEXT_IO. However, with recent versions of TeleGen Ada, you don't have to hit ENTER. Also note that some of the tutorial text refers to commands that are meant for a PC, such as COPY and PRINT. These commands may have to be varied slightly to work on your system. 13. Define a command so that each user will be able to run ADA-TUTR easily. We'll be happy to help you install ADA-TUTR and get it running, even if you haven't registered or bought a license. We want you to try ADA-TUTR before paying for it. Page 42 SPECIAL INSTRUCTIONS FOR VAX ADA 9. If you're using VAX Ada, compile VAX.ADA, but don't try to link or run it. The file VANILLA.ADA would work, but VAX.ADA makes it unnecessary to strike RETURN after each response. The reason is that VAX.ADA gets characters from the keyboard by calling the System Service routines, without going through TEXT_IO. 10. Compile ADA-TUTR.ADA. 11. Link, giving the name of the main program, ADA_TUTR (with an underline). The command is ACS LINK ADA_TUTR. This will produce an executable file, ADA_TUTR.EXE (with an underline). Rename that file to ADA-TUTR.EXE (with a hyphen). 12. Run ADA-TUTR. Note that some of the tutorial text refers to commands that are meant for a PC, such as COPY and PRINT. These commands may have to be varied slightly to work on your system. For example, when the text says to type COPY TRITYPE.DUM TRITYPE.ADA, your users might have to type COPY SYS$INSTRUCTION:TRITYPE.DUM TRITYPE.ADA. 13. Define a command so that each user will be able to run ADA-TUTR easily. For example, you might add the following line to SYLOGIN.COM: $ TEACHADA :== "RUN SYS$INSTRUCTION:ADA-TUTR" We'll be happy to help you install ADA-TUTR and get it running, even if you haven't registered or bought a license. We want you to try ADA-TUTR before paying for it. Page 43 SPECIAL INSTRUCTIONS FOR UNIX BASED SYSTEMS 9. If you're using a UNIX based system with a C compiler, and your Ada compiler can link with modules produced by C, compile ONECHAR.C with the C compiler. 10. Compile UNIX.ADA, but don't try to link or run it. The file VANILLA.ADA would work, but UNIX.ADA, when used with ONECHAR.C, makes it unnecessary to strike RETURN after each response. The reason is that ONECHAR.C gets characters directly from the keyboard, without going through TEXT_IO. 11. Compile ADA-TUTR.ADA. 12. Link, giving the name of the main program, ADA_TUTR (with an underline). Include the object file from the C compiler in the link. This will create an executable file, called ADA_TUTR (with an underline) on most systems. (On one system we encountered, the file created was named a.out.) Rename that file to an appropriate name, such as ada-tutr or ADA-TUTR or ADA-TUTR.EXE. Here are sample steps 9 through 12 for two UNIX based systems: ON A UNISYS 5000/80: ON A HARRIS HCX: cc -c onechar.c cc -c onechar.c ada unix.ada ada-tutr.ada ada unix.a ada-tutr.a ald -p'onechar' ada_tutr a.ld ada_tutr onechar.o mv a.out ada-tutr 13. Run ADA-TUTR. Note that some of the tutorial text refers to commands that are meant for a PC, such as COPY and PRINT. These commands may have to be varied slightly to work on your system. 14. Define a command so that each user will be able to run ADA-TUTR easily. We'll be happy to help you install ADA-TUTR and get it running, even if you haven't registered or bought a license. We want you to try ADA-TUTR before paying for it. Page 44 APPENDIX F: WE LISTEN! NEW FEATURES OF ADA-TUTR Our sincere thanks to all of you who registered your copies of versions 1.00 and 1.01 of ADA-TUTR! (Version 1.01 corrected some minor typographical errors in version 1.00.) We asked for your comments and suggestions, and you responded. Thank you very much! That's why we created this version 1.2 of ADA-TUTR. You asked that the Tutor automatically remember where you leave off when you exit the program, so that you won't have to write down the screen number. You suggested that ADA-TUTR tell you the approximate percentage through the course, and that it tell you when you come to the start of a major section. You suggested that ADA-TUTR be able to go back to the last question and to the last Outside Assignment. You wanted to be able to select colors. We added all these features, including color, without sacrificing the ability to run ADA-TUTR on mainframes. You can strike S at any time to set the foreground, background, and border colors. The Tutor remembers your color choices and remembers where you leave off. When you strike X, ADA-TUTR tells you the current screen number and the approximate percentage through the course. It then gives you a chance to exit, go back to where you were, go back to the last question, go back to the last Outside Assignment, or go to a screen number of your choice. A special screen tells you when you come to the start of each major section. We're very grateful to Mr. David Hill, 7549 Wynford Street, Salt Lake City, UT 84121, for sending us the file ONECHAR.C and giving us permission to include it in ADA-TUTR. This file (used with UNIX.ADA) makes it possible to run the Tutor on UNIX based machines without having to strike ENTER after each response. See pages 39-43. Starting with version 1.20 of ADA-TUTR, we offer customized versions of ADA-TUTR, and a new Customization Kit. Details are on page 34. Also, ADA-TUTR is now available on 3.5" diskettes. We're planning a major update of ADA-TUTR with the next revision (9X) of the Ada language. Please continue to send us your comments and suggestions. We want to produce the very best Ada Tutor possible! Page 45 APPENDIX G: DISCLAIMER OF WARRANTY We hate legal mumbo jumbo, but we have to say the following to protect ourselves: Software Innovations Technology makes no warranty of any kind, expressed or implied, including any warranties of merchantability or fitness for a particular purpose. We shall not be liable for any damages, whether direct, indirect, incidental, special, or consequential, arising from a failure of this program to operate in a manner desired by the user. We shall not be liable for any damage to data or property which may be caused directly or indirectly by use of this program. IN NO EVENT SHALL SOFTWARE INNOVATIONS TECHNOLOGY BE LIABLE FOR ANY DAMAGES, INCLUDING ANY LOST PROFITS, LOST SAVINGS, OR OTHER INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THIS PROGRAM, OR FOR ANY CLAIM BY ANY OTHER PARTY.