Mercurial > hg > Members > kono > nitros9-code
annotate docs/basic09/basic09.docbook @ 1504:d3a421a9f13f
added shell+ features
author | boisy |
---|---|
date | Tue, 13 Jan 2004 21:56:38 +0000 (2004-01-13) |
parents | 958740284209 |
children |
rev | line source |
---|---|
649 | 1 <?xml version="1.0" ?> |
2 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" | |
3 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [ | |
1015 | 4 <!ENTITY b09 "BASIC09"> |
5 <!ENTITY CPU "6809"> | |
6 <!ENTITY os9level "OS-9 Level One"> | |
7 <!ENTITY os9version "Version 02.01.01 BETA1"> | |
8 <!ENTITY vendor "The CoCo Community"> | |
9 <!ENTITY make "TRS-80/Tandy Color Computer"> | |
10 <!ENTITY mdash "—"> | |
11 <!ENTITY gfxapp SYSTEM "gfx.appendix"> | |
12 <!ENTITY gfx2app SYSTEM "gfx2.appendix"> | |
24 | 13 ]> |
14 <book id="basic09" lang="en"> | |
15 <bookinfo> | |
16 <title>&b09;</title> | |
17 <subtitle>Programming Language Reference Manual</subtitle> | |
18 <titleabbrev>&b09; Reference Manual</titleabbrev> | |
19 | |
20 <copyright> | |
21 <year>1983</year> | |
1015 | 22 <holder>Microware Systems Corporation. |
24 | 23 All Rights Reserved. |
1094 | 24 Basic09 is a trademark of Microware Systems Corporation and Motorola Inc. |
24 | 25 </holder> |
26 | |
27 </copyright> | |
28 <revhistory> | |
29 <revision> | |
1015 | 30 <revnumber>A</revnumber> |
31 <date>March 2003</date> | |
32 <revremark>Updated for OS-9 Level One Version 02.01.01</revremark> | |
24 | 33 </revision> |
34 </revhistory> | |
35 </bookinfo> | |
36 | |
37 | |
38 | |
39 <chapter> | |
40 <title>Introduction</title> | |
41 <subtitle>Introduction to &b09; Programming</subtitle> | |
42 <sect1> | |
43 <title>Comments on &b09;</title> | |
44 <para> | |
45 &b09; is an enhanced structured Basic language programming | |
1015 | 46 system specially created for the &CPU; Advanced Microprocessor |
47 used by the &make;. | |
24 | 48 In addition to the standard BASIC language statements and functions, |
49 &b09; includes many of the useful elements of the PASCAL | |
50 programming language so that programs can be modular, | |
51 well-structured, and use sophisticated data structures. | |
52 It also permits full access | |
53 to almost all of the OS-9 Operating System commands and functions so it | |
54 can be used as a systems programming language. | |
55 These features make &b09; an ideal language for many applications: | |
56 scientific, business, industrial control, education and more. | |
57 </para> | |
58 <para> | |
59 &b09; is unusual in that it is an <emphasis>Interactive Compiler</emphasis> that | |
60 has the best of both kinds of language system: it gives | |
61 the fast execution speed typical of compiler languages plus the ease of use | |
62 and memory space efficiency typical of interpreter languages. | |
1094 | 63 &b09; is a complete <emphasis>programming system</emphasis> that |
24 | 64 includes a powerful text editor, multi-pass compiler, |
65 run-time interpreter, high-level interactive debugger, and a system | |
66 executive. Each of these components was carefully integrated | |
67 to give the user a | |
68 friendly, highly interactive programming resource. that provides all the tools | |
69 and helpful "extra" facilities needed for fast, accurate creation and testing of | |
70 structured programs. | |
71 </para> | |
72 | |
73 <highlights> | |
74 <para> | |
75 &b09; Features | |
76 | |
77 <itemizedlist mark="bullet"> | |
78 | |
79 <listitem> | |
80 <para> | |
81 Structured, recursive BASIC with Pascal-type enhancements: | |
82 <itemizedlist mark="dash"> | |
83 <listitem><para>allows multiple, independent, named procedures</para></listitem> | |
84 <listitem><para>procedures called by name with parameters</para></listitem> | |
85 <listitem><para>multi-character, upper or lower case identifiers</para></listitem> | |
86 <listitem><para>variables and line numbers local to procedures</para></listitem> | |
87 <listitem><para>line numbers optional</para></listitem> | |
88 <listitem><para>automatic linkage to ROM or RAM "library" procedures</para></listitem> | |
89 <listitem><para>PACK command compacts program and provides security</para></listitem> | |
90 <listitem><para>PRINT USING with FORTRAN-like format specifications</para></listitem> | |
91 </itemizedlist> | |
92 </para> | |
93 </listitem> | |
94 | |
95 | |
96 <listitem> | |
97 <para> | |
98 Extended data structures: | |
99 <itemizedlist mark="dash"> | |
100 <listitem><para>Five Basic data types: BYTE, INTEGER, REAL, BOOLEAN, and STRING</para></listitem> | |
101 <listitem><para>One, two, or three dimensional arrays</para></listitem> | |
102 <listitem><para>User-defined complex structures and data types</para></listitem> | |
103 </itemizedlist> | |
104 </para> | |
105 </listitem> | |
106 | |
107 | |
108 <listitem> | |
109 <para> | |
110 Extended Control Structures (with Unique Closure Elements): | |
111 </para> | |
112 </listitem> | |
113 | |
114 | |
115 <listitem> | |
116 <para> | |
1015 | 117 Graphics Interface Module for Access to &make; Color |
24 | 118 Graphics Functions |
119 </para> | |
120 </listitem> | |
121 | |
122 | |
123 <listitem> | |
124 <para> | |
125 Powerful interactive debugging and editing features: | |
126 <itemizedlist mark="dash"> | |
127 <listitem><para>Integral, full-featured text editor</para></listitem> | |
128 <listitem><para>Syntax error check upon line entry and procedure compile</para></listitem> | |
129 <listitem><para>Trace mode reproduces original source statements</para></listitem> | |
130 <listitem><para>Renumber command for line numbered procedures</para></listitem> | |
131 </itemizedlist> | |
132 </para> | |
133 </listitem> | |
134 | |
135 | |
136 <listitem> | |
137 <para> | |
138 High-speed, high-accuracy math: | |
139 <itemizedlist mark="dash"> | |
140 <listitem><para>9 decimal-digit 40 bit binary floating point</para></listitem> | |
141 <listitem><para>Full set of transcendentals (SIN, ASN, ACS, LOG, etc.)</para></listitem> | |
142 </itemizedlist> | |
143 </para> | |
144 </listitem> | |
145 </itemizedlist> | |
146 | |
147 </para> | |
148 </highlights> | |
149 </sect1> | |
150 <sect1> | |
151 <title>The History of &b09;</title> | |
152 <para> | |
153 &b09; was conceived in 1978 as a high-performance | |
1015 | 154 programming language to demonstrate the capabilities of the &CPU; |
24 | 155 microprocessor to efficiently run high-level languages. &b09; |
1015 | 156 was developed at the same time as the &CPU; under the auspices of the |
157 architects of the &CPU;. The project covered | |
24 | 158 almost two years, and incorporated the results of research in such areas as |
159 interactive compilation, fast floating point arithmetic algorithms, storage | |
160 management, high-level symbolic debugging, and structured language | |
161 design. These innovations give &b09; its speed, power, and | |
162 unique flavor. | |
163 </para><para> | |
164 &b09; was commissioned by Motorola, Inc., Austin, Texas, | |
165 and developed by Microware Systems Corporation, Des Moines, Iowa. | |
166 Principal designers of &b09; were Larry Crane, Robert | |
167 Doggett, Ken Kaplan, and Terry Ritter. The first release was in February, | |
168 1980. | |
169 </para><para> | |
170 Excellent feedback, thoughtful suggestions, and carefully documented bug | |
171 reports from &b09; users all over the world have been | |
172 invaluable to the designers in their efforts to achieve the degree of | |
173 sophistication and reliability &b09; has today. | |
174 </para> | |
175 </sect1> | |
176 </chapter> | |
177 | |
178 | |
179 | |
180 <chapter> | |
181 <title>Introduction to &b09; Programming</title> | |
182 <para> | |
183 | |
184 This section is intended for persons who have not previously | |
185 written computer programs. If you are familiar with programming in | |
186 general or BASIC programming specifically, this section can give you | |
187 a "feel" for the &b09; interactive environment. | |
188 | |
189 </para> | |
190 <sect1><title>What is a Program?</title> | |
191 <para> | |
192 A computer works something like a pocket calulator. With a | |
193 calculator you push a button, some calculation occurs, and the | |
194 result is displayed. On some calculators you can write a program | |
195 which is just a list of the buttons you want pushed, in the order | |
196 you want them pushed. This is very similar to a computer program, | |
197 but most computer languages use command names instead of buttons. | |
198 </para> | |
199 | |
200 <para> | |
201 To get results from a computer, you must first put into the | |
202 computer the list of commands you want executed in the order you | |
203 want them executed. Each command will mean "do this thing" or "do | |
204 that thing", but the computer only has certain commands which it | |
205 will understand. A computer can do things like "add" or "save the | |
206 result into memory". Typing "get me a taco" to a computer won't | |
207 get it; similarly, on a calculator you can't push buttons which | |
208 aren't there. After you have stored a list of commands into the | |
209 computer, you can tell it to perform those operations. This is like | |
210 actually pushing the buttons on a hand calculator. Then, if you | |
211 remembered to have the compuer display your results, you get to see | |
212 them. Generaly, a computer does not automatically display results | |
213 like a hand calculator. More calculations occur in a computer then | |
214 in a calculator, and displaying all these results would simply be | |
215 overwhelming. | |
216 </para> | |
217 | |
218 <para> | |
219 You enter a program into a computer by using the computer | |
220 itself as a "text editor", to store the commands you type in. Some | |
221 editors allow you to enter any text you want. Other editors will | |
222 only store valid computer commands. Even if the computer does store | |
223 all the text you type in, it can only execute those commands it | |
224 knows. If during program execution, &b09; finds a word which does | |
225 not correspond to a command it will probably stop and print out an | |
226 "error message". Other editors check each command as you enter it | |
227 (usually after the carriage-return ending each line) and print error | |
228 messages immediately for invalid commands. After typing in your | |
229 list of commands, there are ways to display that list, to modify the | |
230 commands you have typed in, and to insert others. But simpy | |
231 entering a computer program does not get results any more than | |
232 thinking which buttons to push will get results on a calculator. | |
233 You store your program by typing it into a computer, but no results | |
234 are available until after you start the program running. | |
235 </para> | |
236 <para> | |
237 Even though programming is conceptually simple, it is easy to | |
238 misspell commands which &b09; will not interpret correctly. | |
239 Unlike humans, &b09; does not infer anything: Every command must | |
240 be perfectly spelled and punctuated or it is wrong. Even after | |
241 spelling errors are eliminated, it is likely that the sequence of | |
242 commands you have entered will not do the job you wanted it to do. | |
243 The meaning of the program to &b09; is often quite different than | |
244 was intended by the programmer, biut good intentions just don't push | |
245 the right buttons. After you get the program to run without obvious | |
246 error, you must test the program with sample input and see that it | |
247 produces results which are known correct. If the results are incorrect, | |
248 the program must be modified and tested until it does | |
249 produce correct results. This is known as testing and | |
250 debugging. Computer malfunctions are rare, and if the computer | |
251 works to store the program, it is probably working perfectly. If the | |
252 program does not work, you need to puzzle out how the computer is | |
253 doing something hich you didn't realize that you told it to do. | |
254 Programming can be frustrating, but if you enter the right commands, | |
255 the computer will do the right things for you. | |
256 </para></sect1> | |
257 <sect1><title>A Simple &b09; Program</title> | |
258 <para> | |
259 Probably the easiest way to explain programming is by example. | |
260 This simple program sometimes keeps kids happy for hours. First, | |
261 the program asks the user for his name. Then the computer types out | |
262 "Hi", then the name, then "see you later". This may not seem like | |
263 much, but it is great fun to type in things which are not your name, | |
264 and see if they will be printed out. They will, of course. | |
265 </para> | |
266 <para> | |
267 When you turn on the &b09; computer it will print some heading | |
268 information. If the prompt is "OS9: ", enter the "basic09" (and | |
269 a carriage-return) to get to the prompt "B:". When you have the | |
270 prompt "B:", it means that the system is in the &b09; "command | |
271 mode". While in the command mode, you can do several things, like: | |
272 list, kill, or create programs (called "procedures" in &b09;). | |
273 &b09; lets you keep several different programs in memory at the | |
274 same time. Each procedure is identified by a name you give it when | |
275 you create the procedure.</para> | |
276 <para> | |
277 To create a new procedure you command the system to enter the | |
278 "edit mode" by typing a simpl "e" (in upper or lower case) and a | |
279 carriage-return (the ENTER or RETURN key). The Editor lets you | |
280 enter or change programs and actually checks for many common errors | |
281 as you type in your program. This automatic checking feature is one | |
282 of the nicest things about &b09;. Because it's always "looking | |
283 over your shoulder" to catch mistakes, it saves a lot of debugging | |
284 time! If you're not 100% sure about how something works - you can | |
285 go ahead and try it instead of digging through this manual. If you | |
286 guess wrong &b09; will usually show you where and why. | |
287 </para> | |
288 <para> | |
289 Because you did not specify a particular procedure name, | |
290 &b09; will automatically select the name "PROGRAM" for you, and | |
291 will respond by printing out "PROCEDURE PROGRAM"; this means that | |
292 you will be editing a procedure which is named PROGRAM. Later you | |
293 will see that you can enter many different procedures and give them | |
294 different names (just type the name you want to use for the program | |
295 after the "e"). | |
296 </para> | |
297 <para> | |
298 The computer output so far is a follows: | |
299 <programlisting> | |
300 B:e | |
301 PROCEDURE PROGRAM | |
302 * | |
303 E: | |
304 </programlisting> | |
305 The asterisk (*) indicates the "current edit line" in the procedure | |
306 being edited. In this case the current line is empty since you have | |
307 not yet entered anything. The asterisk is handy, since you will be | |
308 moving back and forth between different lines to edit them. Later | |
309 you will be "opening" existing procedures for modification, and the | |
310 first line will be displayed automatically, helping identify that | |
311 you are editing the correct program. | |
312 </para> | |
313 <para> | |
314 When &b09; responds with the edit prompt "E:", it is in the | |
315 edit mode. Now you can enter "edit commands" which help us enter | |
1094 | 316 the computer program. While in edit mode, <emphasis>&b09; always takes the |
317 first character of every line as an edit command.</emphasis> | |
318 Some of the basic edit commands are: | |
24 | 319 <programlisting> |
320 <space> <program statement> <cr> insert line | |
321 ? <cr> go to next line down (just <cr> also does the same) | |
322 - <cr> move back to previous line | |
323 L <cr> list current line | |
324 d <cr> delete current line | |
325 </programlisting> | |
326 The most-important edit command is the (invisible) space character; | |
327 this means "save the following line of text", The "space" command | |
328 is the way most text is entered into the system. you must type an | |
329 edit command at the start of each line. If a line is to be entered, | |
330 you must type a space before the rest of the line. If you forget to | |
331 type an edit command, &b09; will respond with "WHAT?". Another | |
332 useful edit command is "L*" (or "l*", since the editor accepts | |
333 either upper or lower case) which will display the whole procedure. | |
334 This allows you to watch the procedure develop as lines are entered. | |
335 </para> | |
336 <para> | |
337 You use the "space" command to enter the following line: | |
338 <programlisting> | |
339 E: print "type your name" | |
340 * | |
341 </programlisting> | |
342 When &b09; executes procedure PROGRAM, this line will tell it to | |
343 print on the screen all of the characters between the quotes. | |
344 </para> | |
345 <para> | |
346 As mentioned before, &b09; checks for errors at the end of | |
347 each line and again when the edit is finished. These errors are, in | |
348 general, anything &b09; cannot identify or things that don't | |
349 conform to the rules of the language. An error could be a bad | |
350 character, mismatched parenthesis, or one of many other things. | |
351 &b09; will print out an "error code" to identify the error and | |
352 print an up arrow character under the place in the line where it | |
353 detected the error. The error codes are listed at the end of this | |
354 manual. If the error was detected at the end of the edit session, | |
355 the I-code location of the error will also be printed. This cryptic | |
356 information is all &b09; knows about the problem, hopefully, it | |
357 will help you to find and fix the error. | |
358 </para> | |
359 <para> | |
360 In the same way that you entered the first line, enter the | |
361 following lines. Remember that the first character entered must be | |
362 a space to get &b09; to save the rest of the line. Example: | |
363 <programlisting> | |
364 E: input name$ | |
365 * | |
366 E: print "Hi ";name$;", see you later." | |
367 * | |
368 E: end | |
369 * | |
370 </programlisting> | |
371 The second line ("input name$"), when executed, commands &b09; to | |
372 wait for a line of text to come in from the keyboard (this will | |
373 happen after the user reads the message printed out in the first | |
374 line). &b09; will accumulate text from the keyboard character-by-character | |
375 until a carriage-return ends the line. This text is | |
376 placed in memory corresponding to the variable "name$". The dollar-sign | |
377 ($) on the end of the variable tells &b09; that you want to | |
378 store a sequence of characters as opposed to a number. | |
379 </para> | |
380 <para> | |
381 The third line of procedure PROGRAM (print "Hi ";name$;", see | |
382 you later."), starts out like the first line. The command "print" | |
383 causes &b09; to print out the various values which come after it. | |
384 When this line is executed, the characters H, i, and "space" are | |
385 printed out since the are enclosed in double-quotes. Next, without | |
386 additional spaces, &b09; prints out the line which was typed in by | |
387 the user and saved in the memory corresponding to "name$" and prints | |
388 out " see you later". When a PRINT statement contains multiple values, | |
389 it will print them out one after the other. If the separator | |
390 is a comma, &b09; will move to the next 16-column "tab stop" | |
391 before printing the next value. However, if the separator between | |
392 print values is a semicolon, absolutely no space will separate the | |
393 values. The last line of the procedure ("END") tells &b09; to | |
394 stop executing the program and return to the command mode (B:). | |
395 You have not yet EXECUTED the procedure, you are just EDITING. If | |
396 you type in l* the whole program will be listed, as follows: | |
397 <programlisting> | |
398 E:l* | |
399 PROCEDURE PROGRAM | |
400 0000 PRINT "type your name" | |
401 0012 INPUT name$ | |
402 0017 PRINT "Hi ";name$;", see you later." | |
403 0035 END | |
404 * | |
405 E: | |
406 </programlisting> | |
407 Notice that the editor has added some information which you did not | |
408 type in. You can use this listing to show exactly what to type in | |
409 to run this program, but the editor only wants the relevant | |
410 information. | |
411 </para> | |
412 <para> | |
413 The numbers to the left are "I-code addresses". These are the | |
414 actual memory locations relative to the start of the procedure where | |
415 each line begins. These numbers may look strange because they are in | |
416 hexadecimal (base 16). These values are important, since the | |
417 compiler may find errors at some I-code location and will try to | |
418 convey that information it has to the programmer. I-code addresses | |
419 are supplied automatically by &b09;. | |
420 </para> | |
421 <para> | |
422 The space between the "I-code addresses" and the beginning of | |
423 the program line is reserved for "line numbers". Line numbers are | |
424 required in many versions of BASIC (although not in &b09;). | |
425 Notice that although the program was typed in lower case some words | |
426 are printed in upper case. &b09; identifies valid command | |
427 "keywords" and converts them to upper case automatically. | |
428 </para> | |
429 <para> | |
430 Now let's run it. First type "q" to quit the editor. We are | |
431 nowback in "command mode" ( B:). Now type "run". &b09; | |
432 remembers the procedure edited (PROGRAM) and starts to execute | |
433 it. | |
434 <screen> | |
435 E:q | |
436 READY | |
437 B:run | |
438 type your name | |
439 ? tex | |
440 Hi tex, see you later. | |
441 READY | |
442 B: | |
443 </screen> | |
444 The question mark (?) is the normal input prompt to tell the user | |
445 that the program is waiting for input. | |
446 </para> | |
447 <para> | |
448 This program is extremely simple, but younger kids can get | |
449 grat fun from it. Its action is especially amusing to young people | |
450 who are learning a computer language for the first time because a | |
451 machine is "responding" to them, and because the machine is too | |
452 easily "fooled" if you do not type in a real name. | |
453 </para></sect1> | |
454 <sect1><title>Basic Programming Techniques: Loops and Arithmetic</title> | |
455 <para> | |
456 Another simple program that most of us can identify with is a | |
457 program to print out multiplication tables. | |
458 <programlisting> | |
459 PROCEDURE multable | |
460 FOR i=1 TO 9 | |
461 FOR j=1 TO 9 | |
462 PRINT i*j; TAB(5*j); | |
463 NEXT j | |
464 NEXT i | |
465 </programlisting> | |
466 First, open the editor by typing "e multable", as follows: | |
467 <screen> | |
468 B: e multable | |
469 PROCEDURE multable | |
470 * | |
471 E: | |
472 </screen> | |
473 Next, type in the program line-by-line staring with "FOR i=1 TO 9" | |
474 (lower-case is perfectly fine). If you loose your way, type "L*" to | |
475 see where you are. This will display the entire procedure and put | |
476 an asterisk at the left of the current line. If you make a mistake, | |
477 use "+" or "-" to mode to that line, use "d" to delete the line, and | |
478 use the space command to enter the line over. Make sure that there | |
479 are no errors and then type "q". When you have the program running, | |
480 try adding a statement before "FOR i=1 TO 9" as follows: "DIM | |
481 i,j:INTEGER". | |
482 </para> | |
483 <para> | |
484 The FOR i=1 TO 9 and NEXT i constitute the start and end of a | |
485 control structure or "loop". A control structure is used to cause | |
486 repeated or conditional execution of the statement(s) it surrounds. | |
487 A control structure usually has one entry at the top and one exit at | |
488 the bottom. In this way, the entire structure take on the properties | |
489 of a single statement. The beginning statement of the | |
490 FOR...NEXT structure (FOR...) provides a "loop initialization", places | |
491 the value 1 in the storage called "i", and sets up the operation of | |
492 the following NEXT (every FOR must have a NEXT). When "NEXT i" is | |
493 executed, the value in "i" is increased by 1 (which is the default | |
494 STEP size) and compared to the value 9 (which is the ending value | |
495 for this loop). If the resulting "i" is less than or equal to 9, | |
496 the statement(s) following that FOR... is (are) executed. | |
497 </para> | |
498 <para> | |
499 Loops can be "nested" to execute the enclosed statements even | |
500 more times. For example, the PRINT statement in "multable" is | |
501 executed 81 times; once for each of 9 values of "j" and this number | |
502 (9 times) for each of 9 values of "i". The ability to tremendously | |
503 increase the number of times some code is executed is at the heart | |
504 of both computer programming and computer errors. It means that | |
505 a vary small portion of a program can often be made to do the vast | |
506 majority of the work. But a few remaining special cases may require | |
507 individual handling and may consume more programming and code than | |
508 that which "usually" works. Unfortunately, "usually" is not | |
509 sufficient. A special case which occurs once in a thousand times | |
510 may occur once a second, and if the error stops the program, further | |
511 processing of normal values also stops. Experience has indicated | |
512 that the programmer should know what is happening in the first and | |
513 second pass, and the next-to-the-last and last pass through each | |
514 loop in the program. | |
515 </para></sect1> | |
516 <sect1><title>Listing Procedure Names</title> | |
517 <para> | |
518 The "DIR" command causes &b09; to display the names and sizes | |
519 of all procedures in memory. This command is used so frequently | |
520 that there is a quick shorthand for DIR: a simple <cr> when in | |
521 command mode does the same thing. You will see | |
522 a table of all procedure names and two numbers next to each | |
523 name. The first column, "proc size", is the size of the corresponding | |
524 procedure. The "data size" column shows the amount of memory that the | |
525 procedure requires for its variables. | |
526 On the last line this command shows the amount of free bytes of workspace memory | |
527 remaining. You can use this information to estimate how much memory | |
528 your program needs to run. You must have at least as much free memory as | |
529 the <emphasis>data size</emphasis> of the procedure(s) to be run. If a data size number is | |
530 followed by a question mark, you need more memory. | |
531 </para> | |
532 </sect1> | |
533 <sect1> | |
534 <title>Requesting More Memory</title> | |
535 <para> | |
536 &b09; automatically get 4K of workspace memory from | |
537 OS-9 when it starts up. There is almost always more than this | |
538 available, but &b09; does not grab it all so other tasks running | |
539 on your computer can have memory too. If you are not multitasking | |
540 and need more memory, the MEM command can get it if available. | |
541 Just type MEM and the amount of memory you want. Depending on your | |
542 computer and how it is configured, you can usually get at least 24K | |
543 in OS-9 Level One Systems or 40K in OS-9 Level Two systems. For | |
544 example: | |
545 <programlisting> | |
546 MEM 20000 | |
547 </programlisting> | |
548 | |
549 requests 20.000 (20K) bytes of memory. &b09; will always round the | |
550 amount you request up to the next highest multiple of 256 bytes. If MEM | |
551 responds with "WHAT?", this means that much memory is not | |
552 available. There is another convenient way to do the same thing | |
553 when you first call up &b09; from OS-9. OS-9 has a | |
554 "#" <emphasis>memory size option</emphasis> on command lines | |
555 that let you specify how much memory to give the program. | |
556 To call &b09; with 16K of memory to start with, you can type: | |
557 <programlisting> | |
558 OS9: basic #16k | |
559 </programlisting> | |
560 </para> | |
561 </sect1> | |
562 <sect1> | |
563 <title>Storing and Recalling Programs</title> | |
564 <para> | |
565 Nobody wants to retype a whole program every time it is to be | |
566 run. Two commands, SAVE and LOAD, are used to store programs and | |
567 recall previously "SAVEd" programs to or from OS-9 disk files. The | |
568 simples way to use SAVE is by itself. It will store the procedure | |
569 last edited or run on a disk file having the same name. For | |
570 example: | |
571 <programlisting> | |
572 B: save | |
573 </programlisting> | |
574 If our procedure name was the default name "PROGRAM", &b09; will | |
575 create a file called "PROGRAM" to hold it. OS-9 won't let you have | |
576 two files of the same name because unique names are necesary to | |
577 identify the specific file you want. Therefore if a file called | |
578 "PROGRAM" already exists, &b09; will ask you: | |
579 <screen> | |
580 Overwrite? | |
581 </screen> | |
582 If you respond "Y" for YES, it will replace the file previously | |
583 stored on that file with the program to be saved. This is OK if | |
584 what you want to save is a never version of the same program. But if | |
585 not you will permanently erase another program you may have wanted | |
586 to keep. If this is the case answer "N" for NO. Fortunately, there | |
587 is a simple way to store the procedure on a file using a different | |
588 name: just type SAVE, a ">", and a different file name of your | |
589 choice. The file can consist of any combination of up to | |
590 thirty-one letters, numbers, periods, or underscores ("_"). The only | |
591 restriction is that the name must start with a letter A-Z or a-z. | |
592 For example: | |
593 <programlisting> | |
594 save >newprogram5 | |
595 </programlisting> | |
596 will save the program on a file called "newprogram5". There are | |
597 several useful variations of the SAVE command that let you save | |
598 various combinations of programs on the same file. See the SAVE | |
599 command description for more information. You should also read | |
600 Chapter 2 of the "OS-9 Users Manual" to learn about the OS-9 | |
601 commands that deal with disk files. | |
602 </para> | |
603 <para> | |
604 If you exit from &b09;, it will not automatically save your | |
605 programs. You must make sure to save them before you quit, or they | |
606 will be lost unless the were saved at some time before! | |
607 </para> | |
608 <para> | |
609 The LOAD command, as it's name implies, reads in a previously | |
610 save program from a file. You must give the name of the file with | |
611 the command. For example: | |
612 <informalexample> | |
613 <programlisting> | |
614 load program | |
615 </programlisting> | |
616 </informalexample> | |
617 If you just started &b09; and have not created any procedures, | |
618 the command is very straightforward. As the procedure(s) stored in | |
619 the file are loaded, &b09; displays their name(s) as they are | |
620 brought in. Once the program is loaded, you can edit and/or run | |
621 it. But if you have a procedure in &b09; that has the same name | |
622 as a procedure stored in the file, &b09; will replace it with the | |
623 new version loaded from the file. If this kind of conflict exists | |
624 you could loose your old program, so be sure to save or RENAME it | |
625 before loading a new one (remember that &b09; can keep several | |
626 procedures in memory at the same time as long as they have different | |
627 names). If you want to permanently erase all other procedures | |
628 before loading new ones, you can type: | |
629 <programlisting> | |
630 B: kill* | |
631 </programlisting> | |
632 This tells &b09; to "kill" all procedures in memory and has the | |
633 same effect as completely resetting &b09;. | |
634 </para> | |
635 </sect1> | |
636 <sect1> | |
637 <title>How to Print Program Listings</title> | |
638 <para> | |
639 If your computer is equipped with a printer, you will want to | |
640 make hard-copy listings of your programs. This is easy to do - just | |
641 type: | |
642 <programlisting> | |
643 B: LIST* /p | |
644 </programlisting> | |
645 This tells &b09; to LIST all procedures in memory to the output | |
646 device "/p" which is the printer device name in most OS-9 systems. | |
647 Like the SAVE command, LIST has several useful variations. If you | |
648 want to list just one procedure (if there are more than on in | |
649 memory) you can type: | |
650 <programlisting> | |
651 B: LIST procedurename >/P | |
652 </programlisting> | |
653 If you want, you can put two or more procedure names (seperated by | |
654 spaces) before the semicolon and those specific procedures will be | |
655 listed. | |
656 </para> | |
657 <para> | |
658 Notice that if you omit the "/p" or ">/p" from the commands above, | |
659 the programs will be listed on your display instead of the printer. | |
660 This is the same as the "L*" command in Edit Mode. You will also | |
661 notice that the listing will be automatically "pretty-printed", | |
662 e.g. program levels within loops are indented for easy reading. | |
663 </para></sect1> | |
664 <sect1><title>&b09;'s Four Modes:</title> | |
665 <para> | |
666 At any given time, &b09; is in one of four modes: | |
667 | |
668 <literallayout> | |
669 SYSTEM MODE: Used for executing system commands. | |
670 EDIT MODE: Used for creating/editing procedures. | |
671 EXECUTION MODE: Used for running procedures. | |
672 DEBUG MODE: Used for testing procedures for errors. | |
673 </literallayout> | |
674 So far, you have been exposed to System Mode (SAVE, LOAD, etc.), | |
675 Edit Mode (the editor), and Execution Mode (RUN). A section of this | |
676 manual is devoted to each mode. The chart below shows how various | |
677 commands in each mode causes changes to other modes. | |
678 | |
679 <figure> | |
680 <title>&b09; Mode Change Possibilities</title> | |
681 <screen> | |
682 OS-9 SYSTEM MODE EDIT MODE | |
683 ---------- ------------ ------------ | |
684 | | | | | + | | |
685 | | | $ | | - | | |
686 | | <-----+--<eof> | | <cr> | | |
687 | | <-----+--BYE | | <line#> | | |
688 | | | CHD | | <space> | | |
689 | | | CHX | | c | | |
690 | | | DIR | | d | | |
691 | | | EDIT----+-------> | l | | |
692 | | | KILL | <-------+-q | | |
693 | | | LIST | | r | ------------ | |
694 |BASIC09-+-----> | LOAD | | s | | TRON | | |
695 | | | MEM | ------------ | TROFF | | |
696 | | | PACK | <--------------------------+ END or Q | | |
697 | | | RENAME | | DEG/RAD | | |
698 | | | RUN-----+-------> ------------ | STATE | | |
699 | | | SAVE | <-------+-END | | $ | | |
700 | | | | <-------+-<CTRL Q> | | BREAK | | |
701 | | ------------ <-------+-STOP | <-----+-CONT | | |
702 |BASIC09 | | PAUSE----+-----> | DIR | | |
703 |AUTORUN-+--------------------------> | ERROR----+-----> | LET | | |
704 | | | <CTRL C>-+-----> | LIST | | |
705 | | <--------------------------+-BYE | | PRINT | | |
706 | | | PROGRAM | <-----+-STEP | | |
707 ---------- ------------ ------------ | |
708 EXECUTION MODE DEBUG MODE | |
709 </screen> | |
710 </figure> | |
711 </para> | |
712 </sect1> | |
713 <sect1><title>More about the Workspace...</title> | |
714 <para> | |
715 The workspace concept is important because &b09; and OS-9 are | |
716 both highly modular systems, and the workspace is a way to logically | |
717 group a set of procedures (i.e. modules) which are applicable to a | |
718 particular line of study or development. Modular software | |
719 development lets the programmer divide a large and complex project | |
720 into smaller, more manageable, and individually testable sections. | |
721 Modularity also lets programmers accumulate and use libraries of | |
722 commonly used routines. | |
723 </para> | |
724 <para> | |
725 As the software is written and debugged, &b09; makes it easy | |
726 to deal with the procedures that comprise an overall project, either | |
727 individually or as a group. For example, you can save all procedures | |
728 on the wrkspace to a single mass stoarage file or load a | |
729 file containing multiple procedures. Usually all procedures | |
730 associated witha project exists inside the workspace. However, you | |
731 can also call library procedures which are "outside" the workspace | |
732 in OS-9 memory module format. The library procedures can be written | |
733 in &b09; or machine language, can be in RAM or ROM memory, and can | |
734 even be shared by several users. | |
735 </para> | |
736 <para> | |
737 &b09; always reserves approximately 1.2K bytes of the workspace | |
738 for internal use. All remaining space is used for storage of | |
739 procedures and for procedure variable storage during execution. | |
740 &b09; will not run a procedure if there is not enough space for | |
741 variables. If you run out of workspace area, you can use the MEM | |
742 command to enlarge the workspace or you can kill procedures in the | |
743 workspace that are not needed. The "MEM" command can be used at any | |
744 time to change the size of the workspace. The size of the workspace | |
745 can be increased (subject to availability of free memory) or | |
746 decreased (but not below the minimal amount needed to store the | |
747 present workspace). | |
748 </para> | |
749 </sect1> | |
750 <sect1> | |
751 <title>Where to go From Here?</title> | |
752 <para> | |
753 A good way to learn &b09; is to use it! Try typing in and | |
754 running some of the example programs in the back of the book. Look | |
755 at and study the function of each program statement. Read the chapters | |
756 on the EDIT and DEBUG modes and experiment with more advanced | |
757 commands. Also, &b09; and the OS-9 Operating System are so intimately | |
758 connected, a basic understanding of OS-9 is important. See | |
759 Chapter 2 of the "OS-9 User's Manual". | |
760 </para> | |
761 </sect1> | |
762 </chapter> | |
763 <chapter> | |
764 <title>System Mode</title> | |
765 <para> | |
766 System mode includes commands to save, load, examine procedures; | |
767 commands to interact with OS-9; and other commands to | |
768 control the workspace environment. A complete list of system commands | |
769 is given below. | |
770 <table frame="none"> | |
771 <title>System Mode Commands</title> | |
772 <tgroup cols="5"> | |
773 <tbody> | |
774 <row> | |
775 <entry>$</entry> | |
776 <entry>CHX</entry> | |
777 <entry>EDIT</entry> | |
778 <entry>LOAD</entry> | |
779 <entry>RENAME</entry> | |
780 </row> | |
781 <row> | |
782 <entry>BYE</entry> | |
783 <entry>DIR</entry> | |
784 <entry>KILL</entry> | |
785 <entry>MEM</entry> | |
786 <entry>RUN</entry> | |
787 </row> | |
788 <row> | |
789 <entry>CHD</entry> | |
790 <entry>E</entry> | |
791 <entry>LIST</entry> | |
792 <entry>PACK</entry> | |
793 <entry>SAVE</entry> | |
794 </row> | |
795 </tbody> | |
796 </tgroup> | |
797 </table> | |
798 </para> | |
799 <para> | |
800 The system commands are processed by the &b09; "command interpreter" | |
801 which always identifies itself with the "B:" prompt. It is entered | |
802 automatically when &b09; is started up and | |
803 whenever you exit any other mode. Commands can be entered in either upper or | |
804 lower-case letters. | |
805 Commands such as DIR, MEM, "$", and BYE don't operate on specific | |
806 procedures, but may have optional or required parameters. Other commands | |
807 (such as SAVE, LOAD, PACK, KILL, and LIST) can operate on a specific | |
808 procedure or on ALL procedures within the workspace. | |
809 If the command is used with a specific procedure name, the command is | |
810 applied to only that procedure. For example: | |
811 <informalexample> | |
812 <programlisting> | |
813 list pete | |
814 </programlisting> | |
815 </informalexample> | |
816 will display the procedure named "pete". | |
817 The asterisk is a special name that means "all procedures in the | |
818 workspace". Therefore, if the command is given follwed by an asterisk it | |
819 is applied to all procedures. For example: | |
820 <programlisting> | |
821 list* | |
822 </programlisting> | |
823 will display all of the procedures in the workspace. | |
824 </para> | |
825 <para> | |
826 If the command is given without any name at all, the "current" working | |
827 procedure is used. This means the name of the procedure | |
828 last given in another command. The DIR command prints an asterisk | |
829 before its name so it can be found at any time. | |
830 If you have not yet given a name in any command, | |
831 the name "PROGRAM" is automatically used. Some commands that require a file | |
832 name as well as (one or | |
833 more) procedure names require that a ">" | |
834 precede the file name so it is not mistaken for a procedure name. If | |
835 you omit the file name, the name of the (first) procedure is used instead. | |
836 In this manual, the phrase file name means an OS-9 "pathlist" | |
837 which can describe either a file or device. | |
838 </para> | |
839 <para> | |
840 Here are some examples: | |
841 <programlisting> | |
842 SAVE tom bill >myfile | |
843 SAVE* big_file | |
844 </programlisting> | |
845 or | |
846 <programlisting> | |
847 SAVE tic tac toe | |
848 </programlisting> | |
849 which is exactly equivalent to | |
850 <programlisting> | |
851 SAVE tic,tac,toe >tic | |
852 </programlisting> | |
853 | |
854 Another class of commands use only one procedure name, or the | |
855 current working name if a name is omitted. These commands change | |
856 the mode of &b09; by exiting the command mode and entering another mode. | |
857 These commands are: | |
858 <informaltable frame="none"> | |
859 <tgroup cols="2"> | |
649 | 860 <colspec colwidth="1in"/> |
24 | 861 <tbody> |
862 <row> | |
863 <entry>RUN</entry> | |
864 <entry>which enters Execution Mode to run a procedure</entry> | |
865 </row> | |
866 <row> | |
867 <entry>EDIT</entry> | |
868 <entry>which enters Edit Mode to create or change a procedure</entry> | |
869 </row> | |
870 </tbody> | |
871 </tgroup> | |
872 </informaltable> | |
873 The one other mode, Debug Mode, cannot be entered directly from the | |
874 system mode — more on this later. | |
875 </para> | |
876 <bridgehead renderas="sect2"> | |
877 Syntax Notation Used in System Command Descriptions</bridgehead> | |
878 <para> | |
879 Individual descriptions of the available commands in each mode follow. In | |
880 order to precisely describe their formats, the syntax notation shown below | |
881 is used. | |
882 | |
883 <informaltable frame="none"> | |
884 <tgroup cols="2"> | |
649 | 885 <colspec colwidth="1.3in"/> |
24 | 886 <tbody> |
887 <row> | |
888 <entry>[ ]</entry> | |
889 <entry>things in brackets are optional.</entry> | |
890 </row> | |
891 <row> | |
892 <entry>{ }</entry> | |
893 <entry>things in braces can be optionally repeated.</entry> | |
894 </row> | |
895 <row> | |
896 <entry><procname></entry> | |
897 <entry>means a procedure name</entry> | |
898 </row> | |
899 <row> | |
900 <entry><pathlist></entry> | |
901 <entry>An OS-9 file name</entry> | |
902 </row> | |
903 <row> | |
904 <entry><number></entry> | |
905 <entry>A decimal or hex number</entry> | |
906 </row> | |
907 </tbody> | |
908 </tgroup> | |
909 </informaltable> | |
910 </para> | |
911 <sect1> | |
912 <title>System Mode Commands</title> | |
913 <para> | |
914 <cmdsynopsis> | |
915 <command>$ [<text>] ("Shell" Command)</command> | |
916 </cmdsynopsis> | |
917 This command calls the OS-9 Shell command interpreter to process an OS-9 | |
918 command or to run another program. Running the OS-9 command does not | |
919 cause &b09; or its workspace to be disturbed. | |
920 </para> | |
921 <para> | |
922 If the "$" is followed by text, the Shell is called to process the | |
923 text as a single OS-9 command line. After the command is executed, | |
924 &b09; is immediately re-entered. | |
925 </para> | |
926 <para> | |
927 If no text is specified, &b09; is suspended, and the OS-9 Shell is called to | |
928 process multiple command lines individually entered from the keyboard. | |
929 Control is returned to &b09; when an end-of-file character (usually ESCAPE) is | |
930 entered. The contents of the &b09; workspace is not affected. This is a | |
931 convenient way to temporarily leave &b09; to manipulate files or perform | |
932 other housekeeping tasks. | |
933 </para> | |
934 <para> | |
935 This command is the "gateway" to OS-9 from inside &b09;. It allows access to | |
936 any OS-9 command or to other programs. It also permits creation of | |
937 concurrent processes and other real-time functions. | |
938 </para> | |
939 <para> | |
940 Examples: | |
941 <informalexample> | |
942 <literallayout> | |
943 B: $copy file1 file2 Calls the OS-9 copy command | |
944 B: $asm sourcefile& Calls the assembler as a <emphasis>background</emphasis> task | |
945 B: $basic09 fourier(20)& Starts <emphasis>another</emphasis> concurrent &b09; program | |
946 </literallayout> | |
947 </informalexample> | |
948 </para> | |
949 <cmdsynopsis><command>BYE (or ESCAPE character)</command> | |
950 </cmdsynopsis> | |
951 <para> | |
952 Exits &b09; and returns to OS-9 or the program that called &b09;. | |
953 Any procedures in the workspace are lost if not previously saved. The | |
954 escape key (technically speaking, an end-of-file character condition on | |
955 &b09;'s standard input path) does the same thing. | |
956 </para> | |
957 <cmdsynopsis><command>CHD <pathlist> or CHX <pathlist></command> | |
958 </cmdsynopsis> | |
959 <para> | |
960 | |
961 Changes the current OS-9 user Data | |
962 or Execution Directory to the specified pathlist | |
963 which must be a directory file. &b09; uses the Data Directory to LOAD or | |
964 SAVE procedures. The Execution Directory is used to | |
965 PACK or auto-load packed modules. | |
966 </para> | |
967 <para> | |
968 Example: | |
969 <informalexample> | |
970 <programlisting> | |
971 CHD /d1/joe/games | |
972 </programlisting> | |
973 </informalexample> | |
974 | |
975 | |
976 </para> | |
977 <cmdsynopsis><command>DIR [<pathlist>]</command> | |
978 </cmdsynopsis> | |
979 <para> | |
980 Displays the name, size, and variable storage requirement of each | |
981 procedure presently in the workspace. The current working procedure has | |
982 an asterisk before its name. All packed procedures have a dash before their | |
983 name (see PACK). The available free memory within the workspace is also | |
984 given. If a pathlist is specified, output is directed to that file or device. | |
985 </para> | |
986 <para> | |
987 A question mark next to a data storage size means the workspace does not | |
988 have enough free memory to run that procedure. | |
989 </para> | |
990 <para> | |
991 Note: This command should not be confused with the OS-9 "DIR" command. | |
992 They have completely different functions. | |
993 </para> | |
994 | |
995 <cmdsynopsis> | |
996 <command>EDIT [<procname>]</command> | |
649 | 997 <sbr/> |
24 | 998 <command>E [<procname>]</command> |
999 </cmdsynopsis> | |
1000 <para> | |
1001 Exits command mode and enters the text editor/compiler mode. If the specified | |
1002 procedure does not exist, a new one is created. See the Chapter 4 for a | |
1003 complete description of how edit mode works. | |
1004 </para> | |
1005 <para> | |
1006 Examples: | |
1007 <informalexample> | |
1008 <programlisting> | |
1009 E newprog | |
1010 EDIT printreport | |
1011 </programlisting> | |
1012 </informalexample> | |
1013 | |
1014 </para> | |
1015 <cmdsynopsis> | |
1016 <command>KILL [<procname> {,<procname>}]</command> | |
649 | 1017 <sbr/> |
24 | 1018 <command>KILL*</command> |
1019 </cmdsynopsis> | |
1020 <para> | |
1021 Erases the procedure(s) specified. KILL* clears the | |
1022 entire workspace. The process may take some time if there are many | |
1023 procedures in the workspace. | |
1024 </para> | |
1025 <para> | |
1026 Examples: | |
1027 | |
1028 <informalexample> | |
1029 <programlisting> | |
1030 kill formulas | |
1031 kill prog1, prog2, prog7 | |
1032 </programlisting> | |
1033 </informalexample> | |
1034 </para> | |
1035 | |
1036 <cmdsynopsis> | |
1037 <command>LIST [<procname> {,<procname>}] [> <pathlist>]</command> | |
649 | 1038 <sbr/> |
24 | 1039 <command>LIST* [<pathlist>]</command> |
1040 </cmdsynopsis> | |
1041 <para> | |
1042 Prints a formatted "pretty printed" listing of one or more procedures. | |
1043 The listing includes | |
1044 the relative I-code storage addresses in hexadecimal format in the first | |
1045 column. The second column is reserved for program line numbers (if line | |
1046 numbers are used). | |
1047 </para> | |
1048 <para> | |
1049 If a pathlist is given, the listing is output to that file or device. This option | |
1050 is commonly used to print hard-copy listings of programs. | |
1051 | |
1052 The LIST, SAVE and PACK commands all have identical syntax, except | |
1053 that LIST prints on the OS-9 standard error path (#2) if no pathlist is given. | |
1054 The files produced are formatted differently, but the function is similar. | |
1055 | |
1056 <important> | |
1057 <para> | |
1058 If an "*" is used with LIST, SAVE or PACK, the file name | |
1059 immediately follows WITHOUT a greater-than sign ">" before it! | |
1060 </para> | |
1061 </important> | |
1062 | |
1063 Examples: | |
1064 | |
1065 <informalexample> | |
1066 <programlisting> | |
1067 list* /p | |
1068 list prog2,prog3 >/p | |
1069 list prog5 >temp | |
1070 </programlisting> | |
1071 </informalexample> | |
1072 | |
1073 </para> | |
1074 | |
1075 <cmdsynopsis> | |
1076 <command>LOAD <pathlist></command> | |
1077 </cmdsynopsis> | |
1078 <para> | |
1079 Loads all procedures from the specified file into the workspace. As | |
1080 procedures are loaded, their names are displayed. If any of the procedures | |
1081 being loaded have the same name as a procedure already in the workspace, | |
1082 the existing procedures are erased and replaced with the procedure | |
1083 being loaded. | |
1084 </para> | |
1085 <para> | |
1086 If the workspace fills up before the last procedure in the file is loaded, an | |
1087 error (#32) is given. In this case, not all procedures may have been loaded, | |
1088 and the one being loaded when the workspace became full may not be | |
1089 completely loaded. You should KILL the last procedure, use the MEM | |
1090 command to get more memory or KILL unnecessary procedure(s) to free | |
1091 up space, and then LOAD the file again. | |
1092 </para> | |
1093 <para> | |
1094 Example: | |
1095 | |
1096 <informalexample> | |
1097 <programlisting> | |
1098 load quadratics | |
1099 </programlisting> | |
1100 </informalexample> | |
1101 | |
1102 </para> | |
1103 <cmdsynopsis> | |
1104 <command>MEM</command> | |
649 | 1105 <sbr/> |
24 | 1106 <command>MEM [<number>]</command> |
1107 </cmdsynopsis> | |
1108 <para> | |
1109 MEM used without a number displays the present total workspace size in | |
1110 (decimal) bytes. If a number is given, &b09; asks OS-9 to expand or | |
1111 contract the workspace to that size. A hex value can be used if preceded by | |
1112 a dollar sign. If MEM responds with What?, you either asked for more | |
1113 memory than is available, tried to give back too much memory (there has | |
1114 to be enough to store all procedures in the workspace), or gave an | |
1115 invalid number. | |
1116 </para> | |
1117 <para> | |
1118 Example: | |
1119 | |
1120 <informalexample> | |
1121 <programlisting> | |
1122 MEM 18000 | |
1123 </programlisting> | |
1124 </informalexample> | |
1125 | |
1126 </para> | |
1127 <cmdsynopsis> | |
1128 <command>PACK [<procname> {,<procname>}] [> <pathlist>]</command> | |
649 | 1129 <sbr/> |
24 | 1130 <command>PACK* [<pathlist>]</command> |
1131 </cmdsynopsis> | |
1132 <para> | |
1133 This command | |
1094 | 1134 causes an extra compiler pass on the procedure(s) specified, which |
24 | 1135 removes names, line numbers, non-executable statements, etc. The result is |
1094 | 1136 a smaller, faster procedure(s) that <emphasis>cannot</emphasis> be edited or debugged but can be |
24 | 1137 executed by &b09; or by the &b09; run-time-only program called "RunB". |
1138 If a pathlist is not given, the name of the first procedure in the list will be | |
1139 used as a default pathname. | |
1140 The procedure is written to the file/device specified in OS-9 memory | |
1141 module format suitable for loading in ROM or RAM outside the | |
1142 workspace. | |
1094 | 1143 <emphasis>The resulting file cannot be loaded into the workspace later on,</emphasis> |
24 | 1144 so you should always perform a regular SAVE before PACKing a procedure! |
1145 </para> | |
1146 <para> | |
1147 &b09; will automatically load the packed procedure when you try | |
1148 to run it later. Here is an example sequence that demonstrates packing a | |
1149 procedure: | |
1150 | |
1151 <informaltable frame="none"> | |
1152 <tgroup cols="2"> | |
649 | 1153 <colspec colwidth="2in"/> |
24 | 1154 <tbody> |
1155 <row> | |
1156 <entry>pack sort</entry> | |
1157 <entry>packs procedure sort and creates a file</entry> | |
1158 </row> | |
1159 <row> | |
1160 <entry>kill sort</entry> | |
1161 <entry>kills procedure inside the workspace</entry> | |
1162 </row> | |
1163 <row> | |
1164 <entry>run sort</entry> | |
1165 <entry>run (sort is loaded outside of the workspace)</entry> | |
1166 </row> | |
1167 <row> | |
1168 <entry>kill sort</entry> | |
1169 <entry>done; delete "sort" from outside memory</entry> | |
1170 </row> | |
1171 </tbody> | |
1172 </tgroup> | |
1173 </informaltable> | |
1174 | |
1175 The last step (kill) does not have to be done immediately if you will use the | |
1176 procedure again later, but you should kill it when you are done so its | |
1177 memory can be used for other purposes. | |
1178 </para> | |
1179 <para> | |
1180 Examples: | |
1181 | |
1182 <informalexample> | |
1183 <programlisting> | |
1184 pack proc1,proc2 >packed.programs | |
1185 | |
1186 pack* packedfile | |
1187 </programlisting> | |
1188 </informalexample> | |
1189 </para> | |
1190 | |
1191 <cmdsynopsis> | |
1192 <command>RENAME <procname>,<new procname></command> | |
1193 </cmdsynopsis> | |
1194 <para> | |
1195 | |
1196 Changes the name of a procedure. Can be used to allow two | |
1197 copies of the same procedure in the workspace under different names. | |
1198 </para> | |
1199 <para> | |
1200 Example: | |
1201 | |
1202 <informalexample> | |
1203 <programlisting> | |
1204 rename thisproc thatproc | |
1205 </programlisting> | |
1206 </informalexample> | |
1207 </para> | |
1208 | |
1209 <cmdsynopsis> | |
1210 <command>RUN [<procname> [ ( <expr> , {<expr>} ) ]]</command> | |
1211 </cmdsynopsis> | |
1212 <para> | |
1213 Runs the procedure specified. Technically speaking, &b09; then | |
1214 leaves Command mode and enters Execution mode. | |
1215 </para> | |
1216 <para> | |
1217 A parameter list can be used to pass expected parameters to the procedure | |
1218 in the same way a RUN statement inside a | |
1219 procedure calls another procedure except for the restriction that all | |
1220 parameters must be constants or expressions without variables. See the | |
1221 PARAM statement description. | |
1222 Assembly language procedures cannot be run from command mode. | |
1223 </para> | |
1224 <para> | |
1225 The procedure called can be normal or "packed". If the procedure is not | |
1226 found inside &b09;'s workspace, &b09; will call OS-9 to attempt to LINK | |
1227 to an external (outside the workspace) module. If this fails, &b09; | |
1228 attempts to LOAD the procedure from a file of the same name. | |
1229 </para> | |
1230 <para> | |
1231 Examples: | |
1232 | |
1233 <informalexample> | |
1234 <programlisting> | |
1235 run getdata | |
1236 | |
1237 run invert("the string to be inverted") | |
1238 | |
1239 run power(12,354.06) | |
1240 | |
1241 run power($32, sin(pi/2)) | |
1242 </programlisting> | |
1243 </informalexample> | |
1244 </para> | |
1245 | |
1246 <cmdsynopsis> | |
1247 <command>SAVE [<procname> { <procname>} [> <pathlist>]]</command> | |
649 | 1248 <sbr/> |
24 | 1249 <command>SAVE* [<pathlist>]</command> |
1250 </cmdsynopsis> | |
1251 <para> | |
1252 Writes the procedure(s) (or all procedures) to an output | |
1253 file or device in source format. SAVE is similar to the LIST command | |
1254 except the output is not formatted and I-code addresses are not included. If | |
1255 a pathlist is not specified, it defaults to the name of the first | |
1256 procedure listed. | |
1257 </para> | |
1258 <para> | |
1259 If a file of the same name already exists, SAVE will prompt with: | |
1260 <screen> | |
1261 rewrite? | |
1262 </screen> | |
1263 You may answer "Y" for yes which causes the existing file to be rewritten | |
1264 with the new procedure(s); or "N" to cancel the SAVE command. | |
1265 </para> | |
1266 <para> | |
1267 Examples: | |
1268 | |
1269 <informalexample> | |
1270 <programlisting> | |
1271 save proc2 proc3 proc4 >monday.work | |
1272 | |
1273 save* newprogram | |
1274 | |
1275 save | |
1276 | |
1277 save >testprogram | |
1278 </programlisting> | |
1279 </informalexample> | |
1280 </para> | |
1281 </sect1> | |
1282 </chapter> | |
1283 <chapter> | |
1284 <title>Edit Mode</title> | |
1285 <para> | |
1286 Edit Mode (also called "The Editor") is used to enter or modify | |
1287 &b09; procedures. It is entered from Command Mode by the EDIT (or E) command. | |
1288 As soon as Edit Mode is entered, prompts change from "B:" to "E:" | |
1289 If you have used a | |
1290 text editor before, you will find the &b09; editor similar to many others | |
1291 except for these two differences: | |
1292 | |
1293 <orderedlist numeration="arabic"> | |
1294 <listitem> | |
1295 <para> | |
1296 The editor is both "string" and "line number" oriented. The use of line numbers | |
1297 is optional and text can be corrected without re-typing the entire line. | |
1298 </para> | |
1299 </listitem> | |
1300 | |
1301 <listitem> | |
1302 <para> | |
1303 The editor is interfaced to the &b09; compiler and "decompiler". This | |
1304 lets &b09; do continuous syntax error checking and permits | |
1305 programs to be stored in memory in a more compact, compiled form. | |
1306 </para> | |
1307 </listitem> | |
1308 </orderedlist> | |
1309 | |
1310 </para> | |
1311 <sect1><title>Overview of Edit Commands</title> | |
1312 <para> | |
1313 The Editor includes the following commands. Each command is described | |
1314 in detail later in this chapter. | |
1315 | |
1316 <table frame="none"> | |
1317 <title>Edit Mode Commands</title> | |
1318 <tgroup cols="2"> | |
649 | 1319 <colspec colwidth="2in"/> |
24 | 1320 <tbody> |
1321 <row> | |
1322 <entry><cr></entry> | |
1323 <entry>move edit pointer forward</entry> | |
1324 </row> | |
1325 <row> | |
1326 <entry>+</entry> | |
1327 <entry>move edit pointer forward</entry> | |
1328 </row> | |
1329 <row> | |
1330 <entry>+*</entry> | |
1331 <entry>move edit pointer to end of text</entry> | |
1332 </row> | |
1333 <row> | |
649 | 1334 <entry>-</entry> |
24 | 1335 <entry>move edit pointer backward</entry> |
1336 </row> | |
1337 <row> | |
649 | 1338 <entry>-*</entry> |
24 | 1339 <entry>move edit pointer to beginning of text</entry> |
1340 </row> | |
1341 <row> | |
1342 <entry><space> <text></entry> | |
1343 <entry>insert unnumbered line</entry> | |
1344 </row> | |
1345 <row> | |
1346 <entry><line#> <text></entry> | |
1347 <entry>insert or replace numbered line</entry> | |
1348 </row> | |
1349 <row> | |
1350 <entry><line#> <cr></entry> | |
1351 <entry>find numbered line</entry> | |
1352 </row> | |
1353 <row> | |
1354 <entry>c</entry> | |
1355 <entry>change string</entry> | |
1356 </row> | |
1357 <row> | |
1358 <entry>c*</entry> | |
1359 <entry>change all occurence of string</entry> | |
1360 </row> | |
1361 <row> | |
1362 <entry>d</entry> | |
1363 <entry>delete line</entry> | |
1364 </row> | |
1365 <row> | |
1366 <entry>d*</entry> | |
1367 <entry>delete all lines</entry> | |
1368 </row> | |
1369 <row> | |
1370 <entry>l</entry> | |
1371 <entry>list line(s)</entry> | |
1372 </row> | |
1373 <row> | |
1374 <entry>l*</entry> | |
1375 <entry>list all lines</entry> | |
1376 </row> | |
1377 <row> | |
1378 <entry>q</entry> | |
1379 <entry>quit editing</entry> | |
1380 </row> | |
1381 <row> | |
1382 <entry>r</entry> | |
1383 <entry>renumber line</entry> | |
1384 </row> | |
1385 <row> | |
1386 <entry>r*</entry> | |
1387 <entry>renumber all lines</entry> | |
1388 </row> | |
1389 <row> | |
1390 <entry>s</entry> | |
1391 <entry>search for string</entry> | |
1392 </row> | |
1393 <row> | |
1394 <entry>s*</entry> | |
1395 <entry>search for all occurence of string</entry> | |
1396 </row> | |
1397 </tbody> | |
1398 </tgroup> | |
1399 </table> | |
1400 | |
1401 </para></sect1> | |
1402 <sect1><title>How the Editor Works</title> | |
1403 <para> | |
1404 In order to understand how the editor works it is helpful to | |
1405 have a general idea of what goes on inside &b09; while you are | |
1406 editing procedures. &b09; programs are always stored in memory | |
1407 in a compiled form called | |
1408 "I-code" (short for "Intermediate Code"). I-code is a complex binary coding | |
1409 system for programs that lies between your original "source" program and | |
1410 the computer's native "machine language". I-code is relatively compact, can | |
1411 be executed rapidly, and most importantly, can be reconstructed almost exactly | |
1412 back to the original source program. The Editor is closely connected to the | |
1413 "compiler" and "decompiler" systems within &b09; that translate source code | |
1414 to I-Code and vice-versa. | |
1415 It is this innovative system that gives &b09; its most powerful and unusual | |
1416 abilities. | |
1417 </para> | |
1418 <para> | |
1419 Whenever you enter (or change) a program line and "return", the | |
1420 compiler instantly translates this text to the internal I-code form. When | |
1421 &b09; needs to display program lines back, it uses the decompiler to translate the | |
1422 I-code back to the original "source" format. These processes are completely | |
1423 automatic and do not require any special action on your part. | |
1424 </para> | |
1425 <para> | |
1426 This technique has several advantages. First, | |
1427 it allows the text editor to report many (syntax) errors immediately so | |
1428 you can correct them instantly. Secondly, | |
1429 the I-code representation of a program is more compact (by about 30%) | |
1430 than its original form, so you can have have larger programs in any | |
1431 given amount of available memory. | |
1432 </para> | |
1433 <para> | |
1434 When programs are listed by &b09;, it is possible they will have a | |
1435 slightly different appearance than the | |
1436 way they were originally typed in, but they will | |
1437 <emphasis>always</emphasis> be functionally | |
1438 identical to the original form. This can happen if the | |
1439 original program had extraneous spaces between keywords, unnecessary | |
1440 parentheses in expressions, etc. &b09; keywords are always automatically | |
1441 capitalized. | |
1442 </para> | |
1443 <para> | |
1444 When you have finished editing the procedure, use the "q" (for "quit") | |
1445 command to | |
1446 exit edit mode and return to the command mode. When you give the "q" command, | |
1447 the compiler performs another "pass" over the entire procedure again. | |
1448 At this time syntax | |
1449 that extends over multiple lines is checked and errors reported. Examples | |
1450 of these errors are: GOTO or GOSUB to a non-existent line, | |
1451 missing variable or array declarations, improperly constructed loops, etc. | |
1452 These errors are reported using an error code and the hexadecimal I-code | |
1453 address of the error. For example: | |
1454 <screen> | |
1455 01FC ERR #043 | |
1456 </screen> | |
1457 This message means that error number 43 was detected in the line that | |
1458 included I-code address 01FC (hexadecimal). The LIST command gives | |
1459 the I-code addresses so you can locate lines with errors reported during the | |
1460 compiler's second pass. | |
1461 </para></sect1> | |
1462 <sect1><title>Line-Number Oriented Editing</title> | |
1463 <para> | |
1464 As mentioned previously, the editor has the capability to work | |
1465 on programs with or without line numbers (or both). | |
1466 Line numbers must be positive whole numbers in the range of 1 to 32767. | |
1467 </para> | |
1468 <para> | |
1469 If you have experience with another version of the BASIC language, this is the kind of | |
1470 editing you probably used. However, well-structured programs seldom | |
1471 really need line numbers. If you don't have to use line numbers, don't. | |
1472 Your programs will be shorter, faster, and easier to read. | |
1473 </para> | |
1474 <para> | |
1475 The line-number oriented commands are: | |
1476 | |
1477 <informaltable frame="none"> | |
1478 <tgroup cols="2"> | |
649 | 1479 <colspec colwidth="2in"/> |
24 | 1480 <tbody> |
1481 <row> | |
1482 <entry><line#> <text></entry> | |
1483 <entry>insert or replace numbered line</entry> | |
1484 </row> | |
1485 <row> | |
1486 <entry><line#> <cr></entry> | |
1487 <entry>find numbered line</entry> | |
1488 </row> | |
1489 <row> | |
1490 <entry>d</entry> | |
1491 <entry>delete line</entry> | |
1492 </row> | |
1493 <row> | |
1494 <entry>r</entry> | |
1495 <entry>renumber line</entry> | |
1496 </row> | |
1497 <row> | |
1498 <entry>r*</entry> | |
1499 <entry>renumber all lines</entry> | |
1500 </row> | |
1501 </tbody> | |
1502 </tgroup> | |
1503 </informaltable> | |
1504 </para> | |
1505 <para> | |
1506 To enter or replace a numbered line, simply type in the line | |
1507 number and statement. Numbered lines can be entered in any order, but will | |
1508 be automatically stored in ascending sequence. To move to a numbered | |
1509 line, type the line number followed by a carriage return. The editor will move | |
1510 to that line (or the line with the next higher number if the specified number | |
1511 is not found) and print it. The line may be deleted using the "d" command. | |
1512 </para> | |
1513 <para> | |
1514 The "r" renumber command will uniformly resequence all numbered lines and | |
1515 lines that refer to numbered lines. Its formats are: | |
1516 <programlisting> | |
1517 r [ <beg line #> [,<incr> ] ] <CR> | |
1518 r*[ <beg line #> [,<incr> ] ] <CR> | |
1519 </programlisting> | |
1520 | |
1521 The first format renumbers the program starting at the current line and | |
1522 forward. Lines are renumbered using | |
1523 <beg line#> as the initial line number. <incr> is added to the previous line | |
1524 number for the next line's number. For example, | |
1525 <programlisting> | |
1526 r 200,5 | |
1527 </programlisting> | |
1528 will give the first line number 200, the second 205, the third 210, etc. | |
1529 If <beg line#> and/or <incr> are not | |
1530 specified, the values 100 and 10, respectively, are assumed. | |
1531 The second form of the command is identical exect it renumbers all lines in the procedure. | |
1532 | |
1533 </para></sect1> | |
1534 <sect1><title>String-Oriented Editing</title> | |
1535 <para> | |
1536 Most editor commands are string-oriented. This means that you can enter or | |
1537 change whole or partial lines without using line numbers at all. You will | |
1538 find that string-oriented editing is generally faster and more convenient. | |
1539 </para> | |
1540 <para> | |
1541 Because line numbers are not used, there has to be another way | |
1542 to tell &b09; what place in the program to work on. To do this, | |
1543 the editor maintains an "edit pointer" that | |
1544 indicates which line is the present working location within the procedure, | |
1545 and commands start workin at this point. | |
1546 The editor shows you the location of the edit pointer by displaying an | |
1547 "*" at the left side of the program line where the edit pointer is | |
1548 presently located. | |
1549 </para> | |
1550 <sect2><title>Moving the Edit Pointer</title> | |
1551 <para> | |
649 | 1552 The "+" and "-" are used to reposition the edit pointer: |
24 | 1553 |
1554 <informaltable frame="none"> | |
1555 <tgroup cols="2"> | |
649 | 1556 <colspec colwidth="2in"/> |
24 | 1557 <tbody> |
1558 <row> | |
649 | 1559 <entry>-</entry> |
24 | 1560 <entry>moves backward one line</entry> |
1561 </row> | |
1562 <row> | |
649 | 1563 <entry>- <number></entry> |
24 | 1564 <entry>moves backward n lines</entry> |
1565 </row> | |
1566 <row> | |
649 | 1567 <entry>-*</entry> |
24 | 1568 <entry>moves to the beginning of the procedure</entry> |
1569 </row> | |
1570 <row> | |
1571 <entry>+</entry> | |
1572 <entry>moves forward one line</entry> | |
1573 </row> | |
1574 <row> | |
1575 <entry>+ <number></entry> | |
1576 <entry>moves forward N lines</entry> | |
1577 </row> | |
1578 <row> | |
1579 <entry>+*</entry> | |
1580 <entry>moves to the end of procedure</entry> | |
1581 </row> | |
1582 </tbody> | |
1583 </tgroup> | |
1584 </informaltable> | |
1585 | |
1586 The number indicates how many lines to move. Backward means | |
1587 towards the first line of the procedure. If the number is omitted, | |
1588 a count of one is used (this is true of most edit commands). | |
1589 A line consisting of a carriage return only also moves the pointer forward one | |
1590 line, which makes it easy to step through a program one line at a time. | |
1591 Therefore, the following commands all do the same thing: | |
1592 | |
1593 <programlisting> | |
1594 <CR> | |
1595 + <CR> | |
1596 +1 <CR> | |
1597 </programlisting> | |
1598 | |
1599 | |
1600 </para></sect2> | |
1601 <sect2><title>Inserting Lines</title> | |
1602 <para> | |
1603 The Insert Line function consists of a "space" followed by a &b09; statement | |
1604 line. The statement is inserted just ahead of the edit pointer position. (the | |
1605 space itself is not inserted). | |
1606 </para></sect2> | |
1607 <sect2><title>Deleting Lines</title> | |
1608 <para> | |
1609 | |
1610 | |
1611 The "d" command is used to delete one or more lines. Its format is: | |
1612 | |
1613 <programlisting> | |
1614 d [<number>] <CR> | |
1615 d* | |
1616 </programlisting> | |
1617 | |
1618 The first form deletes the <number> of lines starting at the current edit | |
1619 pointer location. | |
1620 The second form deletes ALL lines in the procedure (caution!). | |
1621 The editor accepts | |
649 | 1622 "+*" and "-*" to mean to the end, or to the beginning of the procedure |
1094 | 1623 respectively. If the number is negative, that many lines <emphasis>before</emphasis> the |
24 | 1624 current line is deleted. |
1625 If a line number is omitted, only the current line is deleted. | |
1626 </para></sect2> | |
1627 <sect2><title>Listing Lines</title> | |
1628 <para> | |
1629 The "l" command is used to display one or more lines. | |
1630 It also has the forms: | |
1631 <programlisting> | |
1632 l [<number>] <CR> | |
1633 l* | |
1634 </programlisting> | |
1635 The first form will display the <number> of lines starting at the current | |
1094 | 1636 edit pointer position. If the number is <emphasis>negative</emphasis>, previous lines |
24 | 1637 will be listed. |
1638 | |
1639 The second form displays the entire procedure. Neither change the | |
1640 edit pointer's position. The line that is the present position of the edit | |
1641 pointer is displayed with a leading asterisk. | |
1642 | |
1643 </para></sect2> | |
1644 <sect2><title>Search: Finding Strings</title> | |
1645 <para> | |
1646 What's a string? A string is a sequence of one or more characters that | |
1647 can include letters, numbers, or punctuation in any combination. Strings | |
1648 are very usefull because they allow you to change or locate just part | |
1649 of a statement without having to type the whole thing. | |
1650 | |
1651 In the Editor, strings must be surrounded by two matching punctuation | |
1652 characters (called <emphasis>delimiters</emphasis>) so the editor | |
1653 knows where the string begins and ends. | |
1654 The characters used for delimiters are not considered part of the string | |
1655 and cannot also appear within the string. | |
1656 Strings used by the Editor should not be confused with &b09;'s data type | |
1657 which is also called STRING — they are different creatures. | |
1658 </para> | |
1659 <para> | |
1660 The "s" command may be used to locate the next occurrence or all | |
1661 occurrences of a string. The format for this command is: | |
1662 | |
1663 <programlisting> | |
1664 s <delim> <match str> [<delim>] <CR> | |
1665 s*<delim> <match str> [<delim>] <CR> | |
1666 </programlisting> | |
1667 | |
1668 The first format searches for the <match str> starting on the current | |
1669 edit pointer line onward. If any line at or following the edit pointer | |
1670 includes a sequence of characters that match the search string, the edit | |
1671 pointer is moved to that line and the line is displayed. If the string | |
1672 cannot be located, the message: | |
1673 | |
1674 <screen> | |
1675 CAN'T FIND: "<match str>" | |
1676 </screen> | |
1677 will be displayed and the edit pointer will remain at its original | |
1678 position. The "s*" variation searches for all occurrences of the string | |
1679 in the procedure starting at the present edit pointer and displays all | |
1680 lines it is found in. The edit pointer ends up at the last line the | |
1681 string occurred in. | |
1682 </para> | |
1683 <para> | |
1684 Here are some examples: | |
1685 | |
1686 <informalexample> | |
1687 <programlisting> | |
1688 E:s/counter/ Looks for the string: counter | |
1689 | |
1690 E:s.1/2. Looks for the string: 1/2 | |
1691 | |
1692 E:s?three blind mice? Looks for the string: three blind mice | |
1693 </programlisting> | |
1694 </informalexample> | |
1695 </para></sect2> | |
1696 <sect2><title>Change: String Substitution</title> | |
1697 <para> | |
1698 The "c" change string function is a very handy tool that | |
1699 can eliminate a tremendous amount of typing. | |
1700 It allows strings within lines to be located, removed, and replaced by | |
1701 another string. This command is very commonly used for things like: | |
1702 fixing lines with errors | |
1703 without having to retype the entire line, changing a variable name | |
1704 throughout a program, etc. Its formats are: | |
1705 <programlisting> | |
1706 c <delim> <match str> <delim> <repl str> [<delim>] <CR> | |
1707 c*<delim> <match str> <delim> <repl str> [<delim>] <CR> | |
1708 </programlisting> | |
1709 In the first form, the editor looks for the first occurrence of the | |
1710 match string starting at the present edit pointer position. If found, | |
1711 the match string is removed from the line and the replacement string is | |
1712 inserted in its place. The second form works the same way, but changes | |
1713 ALL occurrences of the match string in the procedure starting at the | |
1714 present edit pointer position. | |
1715 </para> | |
1716 <para> | |
1717 The "c*" command will stop anytime it finds or causes a line with an error. | |
1718 It cannot be used to find or change line numbers. | |
1719 </para> | |
1720 <para> | |
1721 A word of warning: | |
1722 sometimes you can inadvertently change a line you did't | |
1723 intend to change because the match string is imbedded in a longer string. | |
1724 For example, if you attempt to change "no" to "yes" and the word "normal" | |
1725 occurs before the "no" you are looking for, "normal" will change to "yesrmal". | |
1726 </para> | |
1727 <para> | |
1728 Examples: | |
1729 | |
1730 <informalexample> | |
1731 <programlisting> | |
1732 c/xval/yval/ | |
1733 c*,GOSUB 5300,GOSUB 5500 | |
1734 </programlisting> | |
1735 </informalexample> | |
1736 </para> | |
1737 </sect2> | |
1738 </sect1> | |
1739 </chapter> | |
1740 | |
1741 | |
1742 <chapter> | |
1743 <title>Execution Mode</title> | |
1744 | |
1745 <sect1><title>Running Programs</title> | |
1746 <para> | |
1747 To run a &b09; procedure, enter: | |
1748 | |
1749 <programlisting> | |
1750 RUN <procname> | |
1751 </programlisting> | |
1752 | |
1753 If the procedure you want to run was the last procedure edited, listed, | |
1754 saved, etc., you can type RUN without giving a procedure name (the | |
1755 "*" shown in the DIR command identifies this procedure). | |
1756 </para> | |
1757 <para> | |
1758 If the procedure expects <emphasis>parameters</emphasis> (see Chapter 7), | |
1759 they can be given on the same | |
1760 command line, however they must all be constant numbers or strings, as | |
1761 appropriate, and must be given in the correct order. For example: | |
1762 | |
1763 <programlisting> | |
1764 RUN add(4,7) | |
1765 </programlisting> | |
1766 | |
1767 is used to call a program that expects parameter, such as | |
1768 <programlisting> | |
1769 PROCEDURE add | |
1770 PARAMETER a,b a,b will receive the values 4,7 | |
1771 PRINT a+b | |
1772 END | |
1773 </programlisting> | |
1774 | |
1775 The ability to pass parameters to a program allows you to specifically | |
1776 initialize program variables. Sometimes certain procedures are parts of a | |
1777 larger software system and are designed to be called from other | |
1778 procedures. You can use this feature to individually test such procedures by | |
1779 passing them test values as parameters. | |
1780 </para> | |
1781 <para> | |
1782 The RUN statement causes &b09; to enter <emphasis>Execution Mode</emphasis>, | |
1783 causing the procedure to run until one of the these things happen: | |
1784 <orderedlist numeration="arabic"> | |
1785 <listitem><para>an END or STOP statement is executed</para></listitem> | |
1786 <listitem><para>you type [Ctrl-E]</para></listitem> | |
1787 <listitem><para>a run-time error occurs</para></listitem> | |
1788 <listitem><para>you type [Ctrl-C] (keyboard interrupt)</para></listitem> | |
1789 </orderedlist> | |
1790 In cases 1 and 2, you will return to system mode. In | |
1791 cases 3 and 4, you will enter DEBUG mode. | |
1792 </para></sect1> | |
1793 <sect1><title>Execution Mode: Technically Speaking</title> | |
1794 <para> | |
1795 | |
1796 | |
1797 The RUN statement is simple and normally you do not need to know what | |
1798 is happening inside &b09; when you use it. The technical description of | |
1799 execution mode that follows is given for the benefit of advanced | |
1800 &b09; programmers. | |
1801 </para> | |
1802 <para> | |
1803 Execution mode is &b09;'s state when you run any procedure. It involves | |
1804 executing the I-code of one or more procedures inside or outside the | |
1805 workspace. Many procedures can be in use because they can call each | |
1806 other (or themselves) and nest exactly like subroutines. | |
1807 | |
1808 You can enter execution mode in a number of ways: | |
1809 <orderedlist numeration="arabic"> | |
1810 <listitem><para>By means of the RUN system command.</para></listitem> | |
1811 <listitem><para>By &b09;'s auto-run feature.</para></listitem> | |
1812 </orderedlist> | |
1813 The Auto-run feature allows &b09; to get the name of a file to load and | |
1814 run from the same command line used to call &b09;. The file loaded and run | |
1815 can be either a SAVED file (in the data directory), or a PACKED file (in the | |
1816 execution directory). The file may contain several procedures; the one | |
1817 executed is the one with the same name as the file. Parameters may be | |
1818 passed following the pathname specified. For | |
1819 example, the following OS-9 command lines use this feature: | |
1820 | |
1821 <programlisting> | |
1822 OS9: &b09; printreport("Past Due Accounts") | |
649 | 1823 OS9: &b09; evaluate(COS(7.8814)/12.075,-22.5,129.055) |
24 | 1824 </programlisting> |
1825 | |
1826 </para> | |
1827 </sect1> | |
1828 </chapter> | |
1829 | |
1830 | |
1831 <chapter> | |
1832 <title>Debug Mode</title> | |
1833 <sect1><title>Overview of Debug Mode</title> | |
1834 <para> | |
1835 One of &b09;'s outstanding features is its set of powerful <emphasis>symbolic | |
1836 debugging</emphasis> commands. What is Symbolic Debugging? Simply | |
1837 stated, it is testing and manipulation of programs using the | |
1838 actual names and program statements used in the program. | |
1839 In this chapter you will learn how Debug Mode can let you watch your | |
1840 program run in slow motion you can observe each statement as | |
1841 it is executed. As a bonus, you will also learn how to use the Debug Mode as | |
1842 a calculator. | |
1843 </para> | |
1844 <para> | |
1845 Debug mode is entered from execution mode in one of three ways: | |
1846 <orderedlist numeration="arabic"> | |
1847 <listitem> | |
1848 <para> | |
1849 When an error occurs during execution of a procedure (that is not | |
1850 intercepted by an ON ERROR GOTO statement within the program). | |
1851 </para> | |
1852 </listitem> | |
1853 <listitem> | |
1854 <para> | |
1855 When a procedure executes a PAUSE statement. | |
1856 </para> | |
1857 </listitem> | |
1858 <listitem> | |
1859 <para> | |
1860 When a keyboard interrupt (control-C) occurs. | |
1861 </para> | |
1862 </listitem> | |
1863 </orderedlist> | |
1864 </para> | |
1865 <para> | |
1866 When any of the above happen, Debug Mode announces itself by | |
1867 displaying the suspended procedure name like this: | |
1868 <programlisting> | |
1869 BREAK: PROCEDURE test5 | |
1870 D: | |
1871 </programlisting> | |
1872 </para> | |
1873 <para> | |
1874 Notice that | |
1875 Debug Mode displays a "D:" prompt when it is awaiting a | |
1876 command. Any debug mode commands can the be used to examine or | |
1877 change variables, turn trace mode on/off, etc. Depending on which | |
1878 commands are used, execution of the program can be terminated, resumed, | |
1879 or executed one source line at a time. | |
1880 </para></sect1> | |
1881 <sect1><title>Debug Mode Commands</title> | |
1882 <para> | |
1883 <cmdsynopsis> | |
1884 <command>$ <text></command> | |
1885 </cmdsynopsis> | |
1886 Calls OS-9's Shell command interpreter to run a program or OS-9 | |
1887 command. Exactly the same as the System Mode "$" command. | |
1888 | |
1889 <cmdsynopsis> | |
1890 <command>BREAK <proc name></command> | |
1891 </cmdsynopsis> | |
1892 Sets up a "breakpoint" at the procedure named. This command is used | |
1893 when procedures call each other, and provides a way to re-enter Debug | |
1894 Mode when returning to a specific procedure. | |
1895 To illustrate how BREAK works, suppose there are three procedures in the | |
1896 workspace: PROC1, PROC2, and PROC3. Assume that PROC1 calls PROC2, which in | |
1897 turn calls PROC3. While PROC3 is executing, you type Control-C to enter | |
1898 debug mode. You can now enter: | |
1899 <programlisting> | |
1900 D: BREAK proc1 | |
1901 ok | |
1902 D: | |
1903 </programlisting> | |
1904 Notice that BREAK responds with "ok" if the procedure was found on the | |
1905 current RUN stack. If you wish you can use the STATE command to verify that the | |
1906 three procedures are "nested" as expected. | |
1907 Now, you can resume execution of PROC3 by typing CONT. After PROC3 terminates, | |
1908 control passes back to PROC2, which eventually returns to PROC1. As soon as | |
1909 this happens, the breakpoint you set is encountered, PROC1 is suspended, | |
1910 and Debug Mode is reentered. | |
1911 </para> | |
1912 <para> | |
1913 There are three characteristics of BREAK you should note: | |
1914 <orderedlist numeration="arabic"> | |
1915 <listitem> | |
1916 <para> | |
1917 The breakpoint is removed as soon as it occurs. | |
1918 </para> | |
1919 </listitem> | |
1920 | |
1921 <listitem> | |
1922 <para> | |
1923 You can use one breakpoint for each active procedure. | |
1924 </para> | |
1925 </listitem> | |
1926 | |
1927 <listitem> | |
1928 <para> | |
1929 You can't put a breakpoint on a procedure unless it has been called but | |
1930 not yet returned to. Hence, BREAK cannot be used on procedures | |
1931 that have not yet been run. | |
1932 </para> | |
1933 </listitem> | |
1934 </orderedlist> | |
1935 | |
1936 <cmdsynopsis> | |
1937 <command>CONT</command> | |
1938 </cmdsynopsis> | |
1939 The command causes program execution to continue at the next | |
1940 statement. It may resume | |
1941 programs suspended by Control-C, PAUSE statements, BREAK command | |
1942 breakpoints, or after non-fatal run-time errors. | |
1943 | |
1944 <cmdsynopsis> | |
1945 <command>DEG</command> | |
649 | 1946 <sbr/> |
24 | 1947 <command>RAD</command> |
1948 </cmdsynopsis> | |
1949 These commands select either degrees or radians as the angle unit | |
1950 measure used by trigonometric functions. These commands only affect | |
1951 the procedure currently being debugged or run. | |
1952 | |
1953 <cmdsynopsis> | |
1954 <command>DIR [<path>]</command> | |
1955 </cmdsynopsis> | |
1956 Displays the workspace procedure directory in exactly the same way as the | |
1957 System Mode DIR command. | |
1958 | |
1959 <cmdsynopsis> | |
1960 <command>END or Q</command> | |
1961 </cmdsynopsis> | |
1962 Termintes execution of all procedures and exits Debug Mode by | |
1963 returning to System Mode. Any open paths are closed at this point. | |
1964 | |
1965 | |
1966 <cmdsynopsis> | |
1967 <command>LET <var> := <expr></command> | |
1968 </cmdsynopsis> | |
1969 This command is essentially the same as the &b09; LET program statement, | |
1970 which allows the value of a procedure variable to be set to a new value | |
1971 using the result of the evaluated expression. The variable names used | |
1972 in this command must be the same as in the original "source" program; | |
1973 otherwise, an error is generated. LET does not work on user-defined | |
1974 data structures. | |
1975 | |
1976 | |
1977 <cmdsynopsis> | |
1978 <command>LIST</command> | |
1979 </cmdsynopsis> | |
1980 Displays a formatted source listing of the suspended procedure with I-code | |
1981 addresses. An asterisk is printed to the left of the statement where | |
1982 the procedure is suspended. Only list the current procedure may be listed. | |
1983 | |
1984 | |
1985 <cmdsynopsis> | |
1986 <command>PRINT [#<expr>,] [USING <expr>,] <expr list></command> | |
1987 </cmdsynopsis> | |
1988 This is exactly the same as the &b09; PRINT statement and can be used | |
1989 to examine the present value of variables in the suspended program. All | |
1990 variable names must be the same as in the original program, and no | |
1991 new variable names can be used. User-defined data structures cannot | |
1992 be printed. | |
1993 | |
1994 | |
1995 <cmdsynopsis> | |
1996 <command>STATE</command> | |
1997 </cmdsynopsis> | |
1998 | |
1999 | |
2000 | |
2001 This command | |
2002 lists the calling ("nesting") order of all active procedures. The | |
2003 highest-level procedure is always shown at the bottom of the calling list, | |
2004 and the lowest-level procedure will always be the suspended procedure. | |
2005 An example: | |
2006 <informalexample> | |
2007 <programlisting> | |
2008 D:state | |
2009 PROCEDURE DELTA | |
2010 CALLED BY BETA | |
2011 CALLED BY ALPHA | |
2012 CALLED BY PROGRAM | |
2013 </programlisting> | |
2014 </informalexample> | |
2015 | |
2016 | |
2017 <cmdsynopsis> | |
2018 <command>STEP [<number>] or <CR></command> | |
2019 </cmdsynopsis> | |
2020 This command allows the suspended procedure to be executed one or | |
2021 more source statements at a time. | |
2022 For example, "STEP 5" would execute the equivalent of the next 5 source | |
2023 statements. A debug command line which is just a carriage return is | |
2024 considered the same as "STEP 1". The STEP command is most commonly | |
2025 used with the trace | |
2026 mode on, so the original source lines can be seen as they | |
2027 are executed. | |
2028 </para> | |
2029 <para> | |
2030 Note: because compiled I-code contains actual statement memory addresses, | |
2031 the "top" or "bottom" statements of loop structures are usually executed | |
2032 just once. For example, in FOR...NEXT loops the FOR statement is executed | |
2033 once, so the statement that appears to be the top of the loop is actually | |
2034 the one following the "FOR" statement. | |
2035 | |
2036 <cmdsynopsis> | |
2037 <command>TRON</command> | |
649 | 2038 <sbr/> |
24 | 2039 <command>TROFF</command> |
2040 </cmdsynopsis> | |
2041 These commands turn the suspended procedure's trace mode on and off. In | |
2042 trace mode, the compiled code of each equivalent statement line is | |
2043 reconstructed to source statements and displayed before the statement | |
2044 is executed. If the statement causes the evaluation of one or more | |
2045 expressions, an equal sign and the expression result(s) are displayed | |
2046 on the following line(s). | |
2047 </para> | |
2048 <para> | |
2049 Trace mode is local to a procedure. If the suspended procedure calls | |
2050 another, no tracing occurs until control returns back | |
2051 (unless of course, other called procedure(s) have trace mode on). | |
2052 </para></sect1> | |
2053 <sect1><title>Debugging Techniques</title> | |
2054 <para> | |
2055 | |
2056 If your program does not do what you expect it to, it is bound to show | |
2057 one of two symptoms: incorrect results, or premature termination due to | |
2058 an error. The second case will automatically send you into Debug Mode. | |
2059 In the first case, you have to force the program into Debug Mode either | |
2060 by hitting Control-C | |
2061 (assuming you have time to do so), or by using Edit Mode to put | |
2062 one or more PAUSE statements in the program. Once you're in Debug Mode, | |
2063 you can bring its powerful commands to bear on the problem. | |
2064 </para> | |
2065 <para> | |
2066 Usually the first step after an error stops the program is to place | |
2067 a PAUSE statement at the beginning of the suspected procedure or at a place | |
2068 within it where you think things begin to go amiss, and the you | |
2069 rerun the program. When the program hits the PAUSE statement, and enters | |
2070 DEBUG mode, it is time to turn the trace mode on and actually | |
2071 watch your program run. To do so, just type: | |
2072 <programlisting> | |
2073 D: TRON | |
2074 </programlisting> | |
2075 | |
2076 After you have done this, you hit the carriage return key once for every | |
2077 statement. You will see the original source statement, and if expressions | |
2078 are evaluated by the statement, Debug Mode will print an equal sign and | |
2079 the result of the expression. Notice that some statements such as FOR | |
2080 and PRINT may cause more than one expression to be evaluated. Using this | |
2081 technique, you can watch your program run one step at a time until you see | |
2082 where it goes wrong. But what if in the process of tracing, you encounter | |
2083 a loop that works OK, but executes 200 statements repetitively? That's | |
2084 a lot of carriage returns. In this case, turn the trace off (if you | |
2085 want) and use the STEP command to quickly run through the loop. Then, | |
2086 turn trace mode back on, and resume single-step debugging. The command | |
2087 sequence for this example is: | |
2088 | |
2089 <programlisting> | |
2090 D: TROFF | |
2091 D: STEP 200 | |
2092 D: TRON | |
2093 </programlisting> | |
2094 </para> | |
2095 <para> | |
2096 Don't forget that trace mode is "local" to one procedure only. If the procedure | |
2097 under test returns to another procedure you need to use the BREAK | |
2098 command or put a PAUSE statement in the procedure to enter Debug Mode. | |
2099 If you call another procedure from the procedure being debugged, tracing will | |
2100 stop when it is called until it returns. If you also want to trace the called | |
2101 procedure, it will need its own PAUSE statement. | |
2102 | |
2103 </para></sect1> | |
2104 <sect1><title>Debug Mode as a Desk Calculator</title> | |
2105 <para> | |
2106 The simple program listed below turns Debug Mode into a powerful desk | |
2107 calculator. It's function is simple: it declares 26 working variables, | |
2108 then goes into Debug Mode so you can use interactive PRINT and LET statements. | |
2109 | |
2110 <programlisting> | |
2111 PROCEDURE Calculator | |
2112 DIM a,b,c,d,e,f,g,h,i,j,k,l,m | |
2113 DIM n,o,p,q,r,s,t,u,v,w,x,y,z | |
2114 PAUSE | |
2115 END | |
2116 </programlisting> | |
2117 | |
2118 Recall that while in debug mode, you cannot create new variables, | |
2119 hence the DIM statements that pre-define 26 working variables for you. | |
2120 If you wish yu can add more or fewer variables. | |
2121 The PAUSE statement causes Debug Mode to be entered. Here's a sample session: | |
2122 <programlisting> | |
2123 B: run calculator | |
2124 BREAK: PROCEDURE Calculator | |
2125 D:let x:=12.5 | |
2126 D:print sin(pi/2) | |
2127 .7071606781 | |
2128 D:let y:=exp(4+0.5) | |
2129 D:print x,y | |
2130 12.5 90.0171313 | |
2131 D:Q | |
2132 B: | |
2133 </programlisting> | |
2134 </para> | |
2135 <para> | |
2136 Don't forget that | |
2137 the Debug Mode PRINT command can use PRINT USING to | |
2138 produce formatted output (including hexadecimal). | |
2139 </para> | |
2140 <para> | |
2141 By adding less than a dozen statements to the program, you can | |
2142 make it store its variables on a disk file so they're remembered | |
2143 from session to session. There are also many other enhancement | |
2144 possibilities | |
2145 </para> | |
2146 </sect1> | |
2147 </chapter> | |
2148 | |
2149 | |
2150 | |
2151 <chapter> | |
2152 <title>Data Types, Variables and Data Structures</title> | |
2153 | |
2154 <sect1><title>Why are there different data types?</title> | |
2155 <para> | |
2156 A computer program's primary function is to | |
2157 process data. The performance of the computer, and even | |
2158 sometimes whether or not a computer can handle a particular problem, | |
2159 depends on how the software stores data in memory and operates on it. | |
2160 &b09; offers many possibilities for organizing and manipulating data. | |
2161 </para> | |
2162 <para> | |
2163 Complicating matters somewhat is the fact that there are many kinds | |
2164 of data. Some data are numbers used for counting or measuring. Another | |
2165 example is textual data composed of letters, punctuation, etc., such | |
2166 as your name. Seldom can they be mixed (for example multiplication is | |
2167 meaningless to anything but numbers), and they have different storage | |
2168 size requirements. Even within the same general kind of data, it is | |
2169 frequently advantageous to have different ways to represent data. For | |
2170 example, &b09; lets you chose from three different ways to represent | |
2171 numbers - each having its own advantages and disadvantages. The decision | |
2172 to use one depends entirely on the specific program you are writing. In | |
2173 order for you to select the most appropiate way to store data variables, | |
2174 &b09; provides five different basic data types. &b09; also lets you create | |
2175 new customized data types based on combinations of the five basic types. | |
2176 A good analogy is to consider the five basic types to be atoms, and the | |
2177 new types you create as molecules. This is why the five basic types are | |
2178 called <emphasis>atomic data types</emphasis>. | |
2179 </para></sect1> | |
2180 <sect1><title>Data Structures</title> | |
2181 <para> | |
2182 A <emphasis>data structure</emphasis> refers to storage for | |
2183 more than one data item under a single name. Data | |
2184 structures are often the most practical and convenient way to organize large | |
2185 amounts of similar data. | |
2186 The simplest kind of data structure is the <emphasis>array</emphasis>, | |
2187 which is a table of values. | |
2188 The table has a single name, and the storage space for each individual | |
2189 value is numbered. Arrays are created by DIM statements. | |
2190 For example, to create an array having five storage spaces called "AGES", | |
2191 we can use the statement: | |
2192 | |
2193 <programlisting> | |
2194 DIM AGES(5):INTEGER | |
2195 </programlisting> | |
2196 "(5)" tells &b09; how many spaces to reserve. The ":INTEGER" part | |
2197 indicates the array's data type. To assign a value of 22 to the third | |
2198 storage space in the array we can use the statement: | |
2199 | |
2200 <programlisting> | |
2201 LET AGES(3):=22 | |
2202 </programlisting> | |
2203 | |
2204 As you shall see, &b09; lets you create complex arrays and | |
2205 even arrays that have different data types combined. | |
2206 </para> | |
2207 <sect2><title>Atomic Data Types</title> | |
2208 <para> | |
2209 &b09; includes five atomic data types: BYTE, INTEGER, REAL, | |
2210 STRING and BOOLEAN. The first three types are used to represent | |
2211 numbers, The STRING type is used to represent character data, and | |
2212 the BOOLEAN type is used to represent the logical values of either | |
2213 TRUE or FALSE. Arrays of any of these data types can be created | |
2214 using one, two, or three dimensions. The table below gives an | |
2215 overview of the characteristics of each type: | |
2216 | |
2217 <table frame="none"> | |
2218 <title>&b09; Atomic Data Type Summary</title> | |
2219 <tgroup cols="3"> | |
649 | 2220 <colspec colwidth="1.2in"/> |
2221 <colspec colwidth="2.1in"/> | |
24 | 2222 <thead> |
2223 <row> | |
2224 <entry>Type:</entry> | |
2225 <entry>Allowable values:</entry> | |
2226 <entry>Memory requirement:</entry> | |
2227 </row> | |
2228 </thead> | |
2229 <tbody> | |
2230 <row> | |
2231 <entry>BYTE</entry> | |
2232 <entry>Whole Numbers 0 to 255</entry> | |
2233 <entry>One byte</entry> | |
2234 </row> | |
2235 <row> | |
2236 <entry>INTEGER</entry> | |
649 | 2237 <entry>Whole Numbers -32768 to 32767</entry> |
24 | 2238 <entry>Two bytes</entry> |
2239 </row> | |
2240 <row> | |
2241 <entry>REAL</entry> | |
649 | 2242 <entry>Floating Point +/- 1*10^38</entry> |
24 | 2243 <entry>Five bytes</entry> |
2244 </row> | |
2245 <row> | |
2246 <entry>STRING</entry> | |
2247 <entry>Letters, digits, punctuation</entry> | |
2248 <entry>One byte/character</entry> | |
2249 </row> | |
2250 <row> | |
2251 <entry>BOOLEAN</entry> | |
2252 <entry>True or False</entry> | |
2253 <entry>One byte</entry> | |
2254 </row> | |
2255 </tbody> | |
2256 </tgroup> | |
2257 </table> | |
2258 Why are there three different ways to represent numbers? Although REAL | |
2259 numbers appear to be the most versatile because they have the greatest | |
2260 range and are floating-point, arithmetic operations involving them are | |
2261 relatively slower (by a factor of about four) compared to the INTEGER | |
2262 or BYTE types. Thus using INTEGER values for loop counters, indexing | |
2263 arrays, etc. can significantly speed up your programs. The BYTE type | |
2264 is not appreciably faster than INTEGER, it conserves memory space in | |
2265 some cases and serves as a building block for complex data types in | |
2266 other cases. If you neglect to specify the type of a variable, &b09; | |
2267 will automatically use the REAL data type. | |
2268 </para></sect2> | |
2269 <sect2><title>Type BYTE</title> | |
2270 <para> | |
2271 BYTE variables hold integer values in the range 0 through 255 | |
2272 (unsigned 8-bit data) which are | |
2273 stored as a single byte. BYTE values are always converted to another type | |
2274 (16-bit integer | |
2275 values and/or real values) for computation, thus they have no speed | |
2276 advantage over other numeric types. However, BYTE variables require | |
2277 only half of the storage used by integers, and an 1/5 of that used by reals. | |
2278 Attempting to store an integer value outside the BYTE range to a BYTE | |
2279 variable results in the storage of the least-significant 8-bits (the value | |
2280 modulo 256) without error. | |
2281 | |
2282 </para></sect2> | |
2283 <sect2><title>Type INTEGER</title> | |
2284 <para> | |
2285 INTEGER variables consist of two bytes of storage, and hold a | |
649 | 2286 numeric value in the range -32768 through 32767 as |
24 | 2287 signed 16-bit data. Decimal points are not allowed. INTEGER constants |
2288 may also be represented as hexadecimal values in the range $0000 | |
2289 through $FFFF to facilitate address calculations. INTEGER values | |
2290 are printed without a decimal point. INTEGER arithmetic is faster and | |
2291 requires less storage than REAL values. | |
2292 </para> | |
2293 <para> | |
2294 Arithmetic which results in values outside the INTEGER range does not | |
2295 cause run-time errors but instead "wraps around" modulo 65536; i.e., | |
649 | 2296 32767 + 1 yields -32768. Division of an integer by another integer |
24 | 2297 yields an integer result, and any remainder is discarded. The programmer |
2298 should be aware that numeric comparisons made on values in the range | |
2299 32767 through 65535 will actually be dealing with negative numbers, | |
2300 so it may be desirable to limit such comparisons to tests for equality | |
2301 or non-equality. Additionally, certain functions (LAND, LNOT, LOR, LXOR) | |
2302 use integer values, but produce results on a non-numeric bit-by-bit basis. | |
2303 </para></sect2> | |
2304 <sect2><title>Type REAL</title> | |
2305 <para> | |
2306 The REAL data type is the default type for undeclared variables. However, | |
2307 a variable may be explicitly typed REAL (for example, twopi:REAL) to | |
2308 improve a program's internal documentation. REAL-type values are | |
2309 always printed with a decimal point, and only those constants which | |
2310 include a decimal point are actually stored as REAL values. | |
2311 </para> | |
2312 <para> | |
2313 REAL numbers are stored in 5 consecutive memory bytes. The | |
2314 first byte is the (8-bit) exponent in binary two's-complement | |
2315 representation. The next four bytes are the binary sign-and-magnitude | |
2316 representation of the mantissa; the mantissa in the first 31 bits, | |
2317 and the sign of the mantissa in the last (least significant) bit of | |
2318 the last byte of the real quantity. | |
2319 <figure> | |
2320 <title>Internal Representation of REAL Numbers</title> | |
2321 | |
2322 <literallayout> | |
2323 +--------+--------+--------+--------+--------+ | |
2324 |exponent| | | | |S| <- mant. sign | |
2325 +--------+--------+--------+--------+--------+ | |
2326 byte: +0 +1 +2 +3 +4 | |
2327 </literallayout> | |
2328 </figure> | |
2329 | |
2330 </para> | |
2331 <para> | |
649 | 2332 The exponent covers the range 2.938735877 * 10^-39 (2^-128) |
24 | 2333 through 1.701411835 * 10^38 (2^127) as powers of 2. Operations which |
2334 result in values out of the representation range cause overflow or | |
2335 underflow errors (which may be handled automatically by the ON ERROR | |
2336 command). The mantissa covers the range from 0.5 through .9999999995 | |
2337 in steps of 2^-31. This means that REAL numbers can represent values | |
2338 on the number line about .0000000005 apart. Operations which cause | |
2339 results between the representable points are rounded to the nearest | |
2340 representable number. | |
2341 </para> | |
2342 <para> | |
2343 Floating point arithmetic is inherently inexact, thus a sequence of | |
2344 operations can produce a cumulative error. Proper rounding (as | |
2345 implemented in &b09;) reduces this effect but cannot eliminate it. | |
2346 Programmers using comparisons on REAL quantities should use caution | |
2347 with strict comparisons (i.e., = or <>), since | |
2348 the exact desired value may not occur during program execution. | |
2349 | |
2350 </para></sect2> | |
2351 <sect2><title>Type STRING</title> | |
2352 <para> | |
2353 | |
2354 | |
2355 A STRING is a variable length sequence of characters or nil (an empty | |
2356 string). A variable may be defined as a STRING either explicitly (e.g., | |
2357 DIM title:STRING) or implicitly by appending a dollar-sign character to | |
2358 the variable name (title$ := "My First Program."). The default maximum | |
2359 length allocated to each string is 32 characters, but each string may | |
2360 be dimensioned less (e.g., DIM A:STRING [4]) for memory savings or more | |
2361 (e.g., DIM long:STRING [2880]) to allow long strings. Notice that | |
2362 strings are inherently variable-length entities, and dimensioning the | |
2363 storage for a string only defines the maximum-length string which can | |
2364 be stored there. When a STRING value is assigned to a STRING variable, | |
2365 the bytes composing the string are copied into the variable storage | |
2366 byte-by-byte. The beginning of a string is always character number one, | |
1094 | 2367 and this is <emphasis>not</emphasis> affected by the BASE0 or BASE1 statements. Operations |
24 | 2368 which result in strings too long to fit in the dimensioned storage |
2369 truncate the string on the right and no error is generated. | |
2370 </para> | |
2371 <para> | |
2372 Normally the internal representation of the string is hidden. A string | |
2373 is stored in a fixed-size storage area and is represented by a sequence | |
2374 of bytes terminated by the value zero or by the maximum length allocated | |
2375 to the STRING variable. Any remaining "unused" storage after the zero | |
2376 byte allows the stored string to expand and contract during execution. | |
2377 | |
2378 The example below shows the internal storage of a variable dimensioned as | |
2379 STRING[6] and assigned a value of "SAM". Notice the byte at +3 contains | |
2380 the zero string terminator, and the two following bytes are not used. | |
2381 <informalfigure> | |
2382 <literallayout> | |
2383 +--------+--------+--------+--------+--------+--------+ | |
2384 | S | A | M | 00 | | | | |
2385 +--------+--------+--------+--------+--------+--------+ | |
2386 byte: +0 +1 +2 +3 +4 +5 | |
2387 </literallayout> | |
2388 </informalfigure> | |
2389 If the value "ROBERT" is assigned to the variable, the zero byte terminator | |
2390 is not needed because the STRING fills the storage exactly: | |
2391 <informalfigure> | |
2392 <literallayout> | |
2393 +--------+--------+--------+--------+--------+--------+ | |
2394 | R | O | B | E | R | T | | |
2395 +--------+--------+--------+--------+--------+--------+ | |
2396 byte: +0 +1 +2 +3 +4 +5 | |
2397 </literallayout> | |
2398 </informalfigure> | |
2399 </para></sect2> | |
2400 <sect2><title>Type BOOLEAN</title> | |
2401 <para> | |
2402 A BOOLEAN quantity can have only two values: TRUE or FALSE. A variable | |
2403 may be typed BOOLEAN (e.g., DIM done_flag:BOOLEAN ). BOOLEAN quantities | |
2404 are stored as single byte values, but they may not be used for numeric | |
2405 computation. BOOLEAN values print out as the character strings: "TRUE" | |
2406 and "FALSE." | |
2407 | |
2408 BOOLEAN values result from comparisons (comparing two compatible types), | |
2409 and are appropriate for logical flags and expressions. ( result:=a AND | |
2410 b AND c ). | |
2411 | |
2412 Do not confuse BOOLEAN operations AND, OR, XOR, and NOT (which operate | |
1094 | 2413 on the Boolean values TRUE end FALSE) with the logical functions LAND, |
24 | 2414 LOR, LXOR, and LNOT (which use integer values to produce results on a |
2415 bit-by-bit basis). Attempting to store a non-BOOLEAN value in a BOOLEAN | |
2416 variable (or the reverse) will cause a run-time error. | |
2417 </para></sect2> | |
2418 <sect2><title>Automatic Type Conversion</title> | |
2419 <para> | |
2420 Expressions that mix numeric data types (BYTE, INTEGER, or REAL) are | |
2421 automatically and temporarily converted to the largest type necessary to | |
2422 retain accuracy. In addition, certain &b09; functions also perform | |
2423 automatic type conversions as necessary. Thus, numeric quantities of | |
2424 mixed types may be used in most cases. | |
2425 Type-mismatch errors happen when an expression includes types that | |
2426 cannot legally be mixed. These errors are reported by the second compiler | |
2427 pass which automatically occurs when you leave EDIT mode. Type | |
2428 conversions can take time. Therefore, you should use expressions | |
2429 containing all values of a single type wherever possible. | |
2430 </para></sect2> | |
2431 </sect1> | |
2432 <sect1><title>Constants</title> | |
2433 <para> | |
2434 Constants are frequently used in program statements and in expressions to | |
2435 assign values to variables. &b09; has rules that allow you to specify | |
2436 constants that correspond to the five basic data types. | |
2437 </para> | |
2438 <sect2><title>Numeric Constants</title> | |
2439 <para> | |
2440 Numeric constants can be either REAL or INTEGER. If a number constant | |
2441 includes a decimal point or uses the "E format" exponential form, | |
2442 it forces &b09; to | |
2443 store the number in REAL format even if the value could have been | |
2444 stored in INTEGER or BYTE format. | |
2445 Thus, if you specifically want to specify a REAL constant, | |
2446 use a decimal point (for example, 12.0). | |
2447 This is sometimes done if all other values in an expression are of type | |
2448 REAL so &b09; does not have to do a time-consuming type conversion | |
2449 at run-time. | |
2450 | |
2451 Numbers that do not have a decimal point but are too large to be | |
2452 represented as integers are also stored in REAL format. The following are | |
2453 examples of REAL values: | |
2454 | |
2455 <informaltable frame="none"> | |
2456 <tgroup cols="2"> | |
2457 <tbody> | |
2458 <row> | |
2459 <entry>1.0</entry> | |
2460 <entry>9.8433218</entry> | |
2461 </row> | |
2462 <row> | |
649 | 2463 <entry>-.01</entry> |
2464 <entry>-999.000099</entry> | |
24 | 2465 </row> |
2466 <row> | |
2467 <entry>100000000</entry> | |
2468 <entry>5655.34532</entry> | |
2469 </row> | |
2470 <row> | |
2471 <entry>1.95E+12</entry> | |
649 | 2472 <entry>-99999.9E-33</entry> |
24 | 2473 </row> |
2474 </tbody> | |
2475 </tgroup> | |
2476 </informaltable> | |
2477 | |
2478 | |
2479 </para> | |
2480 <para> | |
2481 | |
2482 Numbers that do not have a decimal point and are in the range of | |
649 | 2483 -32768 to +32767 are treated as INTEGER numbers. |
24 | 2484 &b09; will also accept integer constants in hexadecimal in the range 0 to |
2485 $FFFF. Hex numbers must have a leading dollar sign. Here are some | |
2486 examples of INTEGER constants: | |
2487 | |
2488 <informaltable frame="none"> | |
2489 <tgroup cols="3"> | |
2490 <tbody> | |
2491 <row> | |
2492 <entry>12</entry> | |
649 | 2493 <entry>-3000</entry> |
24 | 2494 <entry>64000</entry> |
2495 </row> | |
2496 <row> | |
2497 <entry>$20</entry> | |
2498 <entry>$FFFE</entry> | |
2499 <entry>$0</entry> | |
2500 </row> | |
2501 <row> | |
2502 <entry>0</entry> | |
649 | 2503 <entry>-12</entry> |
2504 <entry>-32768</entry> | |
24 | 2505 </row> |
2506 </tbody> | |
2507 </tgroup> | |
2508 </informaltable> | |
2509 | |
2510 </para></sect2> | |
2511 <sect2><title>Boolean Constants</title> | |
2512 <para> | |
2513 The two legal boolean constants are "TRUE" and "FALSE". | |
2514 </para> | |
2515 <para> | |
2516 Example: | |
2517 <programlisting> | |
2518 DIM flag, state: BOOLEAN | |
2519 flag := TRUE | |
2520 state := FALSE | |
2521 </programlisting> | |
2522 | |
2523 </para></sect2> | |
2524 <sect2><title>String Constants</title> | |
2525 <para> | |
2526 String constants consist of a sequence of any characters enclosed in | |
2527 double quote characters. The binary value of each character byte can be | |
2528 1 to 255. Double quote characters to be included in the string use two | |
2529 characters in a row to represent one double quote. | |
2530 | |
2531 The null string "" is important because it represents a string having no | |
2532 characters. It is analogous to the numeric zero. Here are some examples | |
2533 of string constants: | |
2534 | |
2535 <programlisting> | |
2536 "&b09; is a new microcomputer language" | |
2537 "AABBCCDD" | |
2538 "" (a null string) | |
2539 "An ""older man"" is wiser" | |
2540 </programlisting> | |
2541 | |
2542 </para></sect2> | |
2543 </sect1> | |
2544 <sect1><title>Variables</title> | |
2545 <para> | |
2546 Each &b09; variable is "local" to the procedure where it is defined. This | |
2547 means that it is only known to the program statements within that | |
2548 procedure. You can use the same variable name in several procedures and | |
2549 the variables will be completely independent. If you want other procedures | |
2550 to be able to share a variable, you must use the RUN and PARAM statements | |
2551 to pass the variable when a procedure calls another procedure. | |
2552 </para> | |
2553 <para> | |
2554 Storage for variables is allocated from the &b09; workspace when | |
2555 the procedure is called. It is not possible to force a variable to | |
2556 occupy a particular absolute address in memory. When the procedure | |
2557 is exited, variable storage is given back and the values stored in | |
2558 it are lost. Procedures can call themselves (this is referred to as | |
2559 <emphasis>recursion</emphasis>) which causes another separate | |
2560 storage space for variables to be allocated. | |
2561 | |
2562 | |
2563 <warning> | |
2564 <para> | |
2565 &b09; does not automatically initialize | |
2566 variables. When a procedure is run, all variables, arrays, and | |
2567 structures will have random values. Your program must assign | |
2568 any initial value if needed. | |
2569 </para> | |
2570 </warning> | |
2571 | |
2572 </para></sect1> | |
2573 <sect1><title>Parameter Variables</title> | |
2574 <para> | |
2575 Procedures may pass variables to other procedures. When this occurs, the | |
2576 variables passed to the called procedure are called "parameters". | |
2577 Parameters may be passed either "by reference", | |
2578 allowing values to be returned from the called procedure, or | |
2579 "by value", which protects the values in the calling procedure such | |
2580 that they may not be changed by the procdure which is called. | |
2581 </para> | |
2582 <para> | |
2583 Parameters are usually passed "by reference"; this is done by enclosing | |
2584 the names of the variables to be sent to the called procedure in | |
2585 parentheses as part of the RUN statement. The storage address of each | |
2586 parameter variable is evaluated and sent to the called procedure, which | |
2587 then associates those addresses with names in a local PARAM statement. | |
2588 The called procedure uses this storage as if it had been created locally | |
2589 (although it may have a new name) and can change the values stored there. | |
2590 Parameters passed by reference allow called procedures to return values | |
2591 to their callers. | |
2592 </para> | |
2593 <para> | |
2594 Parameters may be passed "by value" by writing the value to be passed | |
2595 as an expression which is evaluated at the time of the call. Useful | |
2596 expression-generators that do not alter values are +0 for numbers or +"" | |
2597 for strings. For example: | |
2598 | |
2599 <informalexample> | |
2600 <programlisting> | |
2601 RUN inverse(x) passes x by reference. | |
2602 RUN inverse(x+0) passes x by value. | |
2603 RUN translate(word$) passes word$ by reference. | |
2604 RUN translate(word$+"") passes word$ by value. | |
2605 </programlisting> | |
2606 </informalexample> | |
2607 </para> | |
2608 <para> | |
2609 When parameters are passed by value, a temporary variable is created | |
2610 when the expression is evaluated. The result is placed in this new temporary | |
2611 storage. The address of this temporary storage is sent to the called | |
2612 procedure. Therefore, the value actually given to the called procedure is a | |
2613 <emphasis>copy</emphasis> of the result, and the called procedure can't | |
2614 accidentially (or otherwise) change the variable(s) in the calling program. | |
2615 </para> | |
2616 <para> | |
2617 Notice that expressions containing numeric constants are either of type | |
2618 INTEGER or of type REAL; there is no type BYTE constant. Thus, BYTE-type | |
2619 VARIABLES may be sent to a procedure as parameters; but expressions will | |
2620 be of types INTEGER or REAL. For example, a RUN statement may evaluate | |
2621 an INTEGER as a parameter and send it to the called procedure. If the | |
2622 called procedure is expecting a BYTE-type variable, it uses only the | |
2623 high-order byte of the (two-byte) INTEGER (which, if the value was | |
2624 intended to be in BYTE-range, will probably be zero!). | |
2625 </para></sect1> | |
2626 <sect1><title>Arrays</title> | |
2627 <para> | |
2628 The DIM statement can create arrays of from 1 to 3 dimensions | |
2629 (a one-dimensional array is often called a "vector", while a 2 or 3 | |
2630 dimensional array is called a "matrix" ). The sizes of each dimension are | |
2631 defined when the array is typed (e.g., DIM plot(24,80):BYTE) by including | |
2632 the number of elements in each dimension. Thus, a table dimensioned | |
2633 (24,80) has 24 rows (1-24) of 80 columns (1 - 80) when accessed in the | |
2634 default (BASE 1) mode. You may elect to access the elements of an array | |
2635 starting at zero (BASE 0), in which case there are still 24 rows (now | |
2636 0-23) and 80 columns (now 0-79). Arrays may be composed of atomic data | |
2637 types, complex data types, or other arrays. | |
2638 </para></sect1> | |
2639 <sect1><title>Complex Data Types</title> | |
2640 <para> | |
2641 The TYPE statement can be used to define a new data type as a "vector" (a | |
2642 one-dimensional array) of any atomic or previously-defined types. | |
2643 For example: | |
2644 | |
2645 <informalexample> | |
2646 <programlisting> | |
2647 TYPE employee_rec = name:STRING; number(2):INTEGER; malesex:BOOLEAN | |
2648 </programlisting> | |
2649 </informalexample> | |
2650 | |
2651 This structure differs from an array in that the various elements may be of | |
2652 mixed types, and the elements are accessed by a <emphasis>field name</emphasis> | |
2653 instead of an array index. For example: | |
2654 | |
2655 <informalexample> | |
2656 <programlisting> | |
2657 DIM employee_file(250): employee_rec | |
2658 employee_file(1).name := "Tex" | |
2659 employee_file(20).number(2) := 115 | |
2660 </programlisting> | |
2661 </informalexample> | |
2662 </para> | |
2663 <para> | |
2664 The complex structure gives the programmer the ability to store and | |
2665 manipulate related values that are of many types, to create "new" | |
2666 types in addition to the five atomic data types, or to create data | |
2667 structures of unusual "shape" or size. Additionally, the position of | |
2668 the desired element in complex-type storage is known and defined at | |
2669 "compile time" and need not be calculated at "run time". Therefore, | |
2670 complex structure accesses may be slightly faster than array accesses. | |
2671 The elements of a complex structure may be copied to another similar | |
2672 structure using a single assignment operator (:= ). An entire structure | |
2673 may be written to or read from mass storage as a single entity (e.g., | |
2674 PUT #2, employee_file). Arrays or complex structures may be elements | |
2675 of subsequent complex structures or arrays. | |
2676 </para> | |
2677 </sect1> | |
2678 </chapter> | |
2679 | |
2680 | |
2681 <chapter> | |
2682 <title>Expressions, Operators, and Functions</title> | |
2683 | |
2684 <sect1> | |
2685 <title>Evaluation of Expressions</title> | |
2686 <para> | |
2687 Many &b09; statements evaluate <emphasis>expressions</emphasis>. The | |
2688 result of an evaluation is just a value of some atomi type (e.g., REAL, | |
2689 INTEGER, STRING, or BOOLEAN). The expression itself may consist of values | |
2690 and operators. For example, the expression "5+5" results in an integer | |
2691 with a value of ten. | |
2692 </para> | |
2693 <para> | |
2694 A "value" can be a constant value (e.g, 5.0, 5 , "5" , or TRUE), a | |
2695 variable name, or a function (e.g, SIN(x) ) which "returns" the result as | |
2696 a value. An <emphasis>operator</emphasis> combines values (typically, | |
2697 those adjacent to the operator) and also returns a result. | |
2698 </para> | |
2699 <para> | |
2700 In the course of evaluating an expression, each value is copied to an | |
2701 "expression stack" where functions and operators take their input values | |
2702 and return results. If (as is often the case) the expression is to be | |
2703 used in an assignment statement, only when the result of the entire | |
2704 expression has been found is the assignment made. This allows | |
2705 the variable which is being modified (assigned to) to be one of the | |
2706 values in the expression. The same principles apply for numeric, string, | |
2707 and boolean operators. These principles make assignment statements such | |
2708 as "X=X+1" legal in all cases, even though it would not make sense in a | |
2709 mathematical context. | |
2710 </para> | |
2711 <para> | |
2712 Any expression evaluates to one of the five "atomic" data types, i.e., | |
2713 real, integer, byte, boolean, or string. This does not mean, however, | |
2714 that all the operators and operands in expressions have to be of an | |
2715 identical type. Often types are mixed in expressions because the RESULT | |
2716 of some operator or function has a different type than its operands. | |
2717 An example is the "less than" operator. Here is an example: | |
2718 | |
2719 <informalexample> | |
2720 <programlisting> | |
2721 24 < 100 | |
2722 </programlisting> | |
2723 </informalexample> | |
2724 | |
2725 The "<" operator compares two numeric operands. The result of the | |
2726 comparison is of type BOOLEAN; in this case, the value TRUE. | |
2727 </para> | |
2728 <para> | |
2729 &b09; allows intermixing of the three numeric types because it performs | |
2730 automatic type conversion of operands. If different types are used in an | |
2731 expression, the "result" will be the same type as the operand(s) | |
2732 having the largest representation. As a rule, any numeric type operand | |
2733 may be used in a expression that is expected to produce a result of | |
2734 type REAL. Expressions that must produce BYTE or INTEGER results must | |
2735 evaluate to a value that is small enough to fit the representation. &b09; | |
2736 has a complete set of functions that can perform compatible type | |
2737 conversion. Type-mismatch errors are reported by the second compiler | |
2738 pass when leaving Edit mode. | |
2739 </para> | |
2740 </sect1> | |
2741 <sect1> | |
2742 <title>Operators</title> | |
2743 <para> | |
2744 Operators take two operands (except negation) and cause some operation | |
2745 to be performed producing a result, which is generally the same type | |
2746 as the operands (except comparisons). The table below lists the operators | |
2747 available and the types they accept and produce. | |
2748 "NUMERIC" refers to either BYTE, INTEGER, or REAL types. | |
2749 <table frame="none"> | |
2750 <title>&b09; Expression Operators</title> | |
2751 <tgroup cols="4"> | |
649 | 2752 <colspec colwidth="0.8in"/> |
24 | 2753 <thead> |
2754 <row rowsep="1"> | |
2755 <entry>Operator</entry> | |
2756 <entry>Function</entry> | |
2757 <entry>Operand type</entry> | |
2758 <entry>Result type</entry> | |
2759 </row> | |
2760 </thead> | |
2761 <tbody> | |
2762 <row> | |
649 | 2763 <entry>-</entry> |
24 | 2764 <entry>Negation</entry> |
2765 <entry>NUMERIC</entry> | |
2766 <entry>NUMERIC</entry> | |
2767 </row> | |
2768 <row> | |
2769 <entry>^ or **</entry> | |
2770 <entry>Exponentiation</entry> | |
2771 <entry>NUMERIC (positive)</entry> | |
2772 <entry>NUMERIC</entry> | |
2773 </row> | |
2774 <row> | |
2775 <entry>*</entry> | |
2776 <entry>Multiplication</entry> | |
2777 <entry>NUMERIC</entry> | |
2778 <entry>NUMERIC</entry> | |
2779 </row> | |
2780 <row> | |
2781 <entry>/</entry> | |
2782 <entry>Division</entry> | |
2783 <entry>NUMERIC</entry> | |
2784 <entry>NUMERIC</entry> | |
2785 </row> | |
2786 <row> | |
2787 <entry>+</entry> | |
2788 <entry>Addition</entry> | |
2789 <entry>NUMERIC</entry> | |
2790 <entry>NUMERIC</entry> | |
2791 </row> | |
2792 <row> | |
649 | 2793 <entry>-</entry> |
24 | 2794 <entry>Subtraction</entry> |
2795 <entry>NUMERIC</entry> | |
2796 <entry>NUMERIC</entry> | |
2797 </row> | |
2798 <row> | |
2799 <entry>NOT</entry> | |
2800 <entry>Logical Negation</entry> | |
2801 <entry>BOOLEAN</entry> | |
2802 <entry>BOOLEAN</entry> | |
2803 </row> | |
2804 <row> | |
2805 <entry>AND</entry> | |
2806 <entry>Logical AND</entry> | |
2807 <entry>BOOLEAN</entry> | |
2808 <entry>BOOLEAN</entry> | |
2809 </row> | |
2810 <row> | |
2811 <entry>OR</entry> | |
2812 <entry>Logical OR</entry> | |
2813 <entry>BOOLEAN</entry> | |
2814 <entry>BOOLEAN</entry> | |
2815 </row> | |
2816 <row> | |
2817 <entry>XOR</entry> | |
2818 <entry>Logical EXCLUSIVE OR</entry> | |
2819 <entry>BOOLEAN</entry> | |
2820 <entry>BOOLEAN</entry> | |
2821 </row> | |
2822 <row> | |
2823 <entry>+</entry> | |
2824 <entry>Concatenation</entry> | |
2825 <entry>STRING</entry> | |
2826 <entry>STRING</entry> | |
2827 </row> | |
2828 <row> | |
2829 <entry>=</entry> | |
2830 <entry>Equal to</entry> | |
2831 <entry>ANY</entry> | |
2832 <entry>BOOLEAN</entry> | |
2833 </row> | |
2834 <row> | |
2835 <entry><> or ><</entry> | |
2836 <entry>Not equal to</entry> | |
2837 <entry>ANY</entry> | |
2838 <entry>BOOLEAN</entry> | |
2839 </row> | |
2840 <row> | |
2841 <entry><</entry> | |
2842 <entry>Less than</entry> | |
2843 <entry>NUMERIC, STRING*</entry> | |
2844 <entry>BOOLEAN</entry> | |
2845 </row> | |
2846 <row> | |
2847 <entry><= or =<</entry> | |
2848 <entry>Less than or Equal</entry> | |
2849 <entry>NUMERIC, STRING*</entry> | |
2850 <entry>BOOLEAN</entry> | |
2851 </row> | |
2852 <row> | |
2853 <entry>></entry> | |
2854 <entry>Greater than</entry> | |
2855 <entry>NUMERIC, STRING*</entry> | |
2856 <entry>BOOLEAN</entry> | |
2857 </row> | |
2858 <row> | |
2859 <entry>>= or =></entry> | |
2860 <entry>Greater than or Equal</entry> | |
2861 <entry>NUMERIC, STRING*</entry> | |
2862 <entry>BOOLEAN</entry> | |
2863 </row> | |
2864 </tbody> | |
2865 </tgroup> | |
2866 </table> | |
2867 When comparing strings, the ASCII collating sequence is used, so that | |
2868 0 < 1 < ... < 9 < A < B< ... < Z < a < b< | |
2869 ... < z | |
2870 </para> | |
2871 <sect2> | |
2872 <title>Operator Precedence</title> | |
2873 <para> | |
2874 Operators have "precedence". This means they are evaluated in a specific | |
2875 order. (i.e., multiplications performed before addition). Parentheses can | |
2876 be used to override natural precedence, however, extraneous parentheses | |
2877 may be removed by the compiler. The legal operators are listed below, | |
2878 in precedence order from highest to lowest. | |
2879 | |
2880 <informaltable frame="none"> | |
2881 <tgroup cols="7"> | |
649 | 2882 <colspec colname="c1"/> |
2883 <colspec colname="c2"/> | |
2884 <colspec colname="c3"/> | |
2885 <colspec colnum="7" colname="c7"/> | |
2886 <spanspec spanname="firstop" namest="c2" nameend="c2"/> | |
2887 <spanspec spanname="secondop" namest="c3" nameend="c7"/> | |
2888 <spanspec spanname="onlyop" namest="c2" nameend="c7"/> | |
2889 <spanspec spanname="all" namest="c1" nameend="c7"/> | |
24 | 2890 <tbody> |
2891 <row> | |
2892 <entry spanname="all">Highest Precedence</entry> | |
2893 </row> | |
2894 <row> | |
2895 <entry spanname="firstop">NOT</entry> | |
649 | 2896 <entry spanname="secondop">-(negate)</entry> |
24 | 2897 </row> |
2898 <row> | |
2899 <entry spanname="firstop">^</entry> | |
2900 <entry spanname="secondop">**</entry> | |
2901 </row> | |
2902 <row> | |
2903 <entry spanname="firstop">*</entry> | |
2904 <entry spanname="secondop">/</entry> | |
2905 </row> | |
2906 <row> | |
2907 <entry spanname="firstop">+</entry> | |
649 | 2908 <entry spanname="secondop">-</entry> |
24 | 2909 </row> |
2910 <row> | |
2911 <entry spanname="firstop">></entry> | |
2912 <entry><</entry> | |
2913 <entry><></entry> | |
2914 <entry>=</entry> | |
2915 <entry>>=</entry> | |
2916 <entry><=</entry> | |
2917 </row> | |
2918 <row> | |
2919 <entry spanname="onlyop">AND</entry> | |
2920 </row> | |
2921 <row> | |
2922 <entry spanname="firstop">OR</entry> | |
2923 <entry spanname="secondop">XOR</entry> | |
2924 </row> | |
2925 <row> | |
2926 <entry spanname="all">Lowest Precedence</entry> | |
2927 </row> | |
2928 </tbody> | |
2929 </tgroup> | |
2930 </informaltable> | |
2931 </para> | |
2932 <para> | |
2933 Operators of equal precedence are shown on the same line, and are | |
2934 evaluated left to right in expressions. The only exception to this rule is | |
2935 exponentiation, which is evaluated right to left. Raising a negative number | |
2936 to a power is not legal in &b09;. | |
2937 </para> | |
2938 <para> | |
2939 In the examples below, &b09; expressions on the left are evaluated as | |
2940 indicated on the right. Either form may be entered, | |
2941 but the simpler form on the left will always be generated by the decompiler. | |
2942 <informaltable frame="none"> | |
2943 <tgroup cols="2"> | |
2944 <tbody> | |
2945 <row> | |
2946 <entry>&b09; representation</entry> | |
2947 <entry>Equivalent form</entry> | |
2948 </row> | |
2949 <row> | |
2950 <entry>a:= b+c**2/d</entry> | |
2951 <entry>a:= b+((c**2)/d)</entry> | |
2952 </row> | |
2953 <row> | |
2954 <entry>a:= b>c AND d>e OR c=e</entry> | |
2955 <entry>a:= ((b>c) AND (d>e)) OR (c=e)</entry> | |
2956 </row> | |
2957 <row> | |
2958 <entry>a:= (b+c+d)/e</entry> | |
2959 <entry>a:= ((b+c)+d)/e</entry> | |
2960 </row> | |
2961 <row> | |
2962 <entry>a:= b**c**d/e</entry> | |
2963 <entry>a:= (b**(c**d))/e</entry> | |
2964 </row> | |
2965 <row> | |
649 | 2966 <entry>a:= -(b)**2</entry> |
2967 <entry>a:= (-b)**2</entry> | |
24 | 2968 </row> |
2969 <row> | |
2970 <entry>a:=b=c</entry> | |
2971 <entry>a:= (b=c) (returns BOOLEAN value)</entry> | |
2972 </row> | |
2973 </tbody> | |
2974 </tgroup> | |
2975 </informaltable> | |
2976 | |
2977 | |
2978 </para></sect2></sect1> | |
2979 <sect1><title>Functions</title> | |
2980 <para> | |
2981 Functions take one or more <emphasis>arguments</emphasis> enclosed in | |
2982 parentheses, perform some operation, and return a value. They may be used | |
2983 as operands in expressions. Functions expect that the arguments passed | |
2984 to them be expressions, constants, or variables of a certain type and | |
2985 return a result of a certain type. Giving a function, an argument of an | |
2986 incompatible type will result in an error. | |
2987 </para> | |
2988 <para> | |
2989 In the descriptions of functions that follow, the following notation | |
2990 describes the type required for the parameter expressions: | |
2991 | |
2992 <informaltable frame="none"> | |
2993 <tgroup cols="2"> | |
2994 <tbody> | |
2995 <row> | |
2996 <entry><num></entry> | |
2997 <entry>means any numeric-result expression.</entry> | |
2998 </row> | |
2999 <row> | |
3000 <entry><str></entry> | |
3001 <entry>means any string-result expression.</entry> | |
3002 </row> | |
3003 <row> | |
3004 <entry><int></entry> | |
3005 <entry>means any integer-result expression.</entry> | |
3006 </row> | |
3007 </tbody> | |
3008 </tgroup> | |
3009 </informaltable> | |
3010 | |
3011 The functions below return REAL results. Accuracy of transcendental | |
3012 functions is 8+ decimal digits. Angles can be either degrees or radians (see | |
3013 DEG/RAD statement descriptions). | |
3014 | |
3015 <informaltable frame="none"> | |
3016 <tgroup cols="2"> | |
649 | 3017 <colspec colwidth="1.5in"/> |
24 | 3018 <tbody> |
3019 <row> | |
3020 <entry>SIN(<num>)</entry> | |
3021 <entry>trigonometric sine of <num></entry> | |
3022 </row> | |
3023 <row> | |
3024 <entry>COS(<num>)</entry> | |
3025 <entry>trigonometric cosine of <num></entry> | |
3026 </row> | |
3027 <row> | |
3028 <entry>TAN(<num>)</entry> | |
3029 <entry>trigonometric tangent of <num></entry> | |
3030 </row> | |
3031 <row> | |
3032 <entry>ASN(<num>)</entry> | |
3033 <entry>trigonometric arcsine of <num></entry> | |
3034 </row> | |
3035 <row> | |
3036 <entry>ACS(<num>)</entry> | |
3037 <entry>trigonometric arcosine of <num></entry> | |
3038 </row> | |
3039 <row> | |
3040 <entry>ATN(<num>)</entry> | |
3041 <entry>trigonometric arctangent of <num></entry> | |
3042 </row> | |
3043 <row> | |
3044 <entry>LOG(<num>)</entry> | |
3045 <entry>natural logarithm (base e) of <num></entry> | |
3046 </row> | |
3047 <row> | |
3048 <entry>LOG10(<num>)</entry> | |
3049 <entry>logarithm (base 10) of <num></entry> | |
3050 </row> | |
3051 <row> | |
3052 <entry>EXP(<num>)</entry> | |
3053 <entry>e (2.71828183) raised to the power <num>, which must be a | |
3054 positive number</entry> | |
3055 </row> | |
3056 <row> | |
3057 <entry>FLOAT(<num>)</entry> | |
3058 <entry><num> converted to type REAL (from BYTE or INTEGER)</entry> | |
3059 </row> | |
3060 <row> | |
3061 <entry>INT(<num>)</entry> | |
3062 <entry>truncates all digits to the right of | |
3063 the decimal point of a REAL <num></entry> | |
3064 </row> | |
3065 <row> | |
3066 <entry>PI</entry> | |
3067 <entry>the constant 3.14159265.</entry> | |
3068 </row> | |
3069 <row> | |
3070 <entry>SQR(<num>)</entry> | |
3071 <entry>square root of <num>, which must be positive.</entry> | |
3072 </row> | |
3073 <row> | |
3074 <entry>SQRT(<num>)</entry> | |
3075 <entry>square root of <num>; same as SQR.</entry> | |
3076 </row> | |
3077 <row> | |
3078 <entry morerows="2">RND(<num>)</entry> | |
3079 <entry>if <num>=0, returns random x, 0 <= x < 1.</entry> | |
3080 </row> | |
3081 <row> | |
3082 <entry>if <num>>0, returns random x, 0 <= x < <num>.</entry> | |
3083 </row> | |
3084 <row> | |
3085 <entry>if <num><0, use ABS(<num>) as new random number seed.</entry> | |
3086 </row> | |
3087 </tbody> | |
3088 </tgroup> | |
3089 </informaltable> | |
3090 | |
3091 The following functions can return any numeric type, depending on the | |
3092 type of the input parameter(s). | |
3093 | |
3094 <informaltable frame="none"> | |
3095 <tgroup cols="2"> | |
649 | 3096 <colspec colwidth="1.5in"/> |
24 | 3097 <tbody> |
3098 <row> | |
3099 <entry>ABS(<num>)</entry> | |
3100 <entry>absolute value of <num></entry> | |
3101 </row> | |
3102 <row> | |
3103 <entry>SGN(<num>)</entry> | |
649 | 3104 <entry>signum of <num>: -1 if <num> < 0; 0 if <num> = 0; or 1 if <num> > 0</entry> |
24 | 3105 </row> |
3106 <row> | |
3107 <entry>SQ(<num>)</entry> | |
3108 <entry><num> squared</entry> | |
3109 </row> | |
3110 <row> | |
3111 <entry>VAL(<str>)</entry> | |
3112 <entry>convert type string to type numeric</entry> | |
3113 </row> | |
3114 </tbody> | |
3115 </tgroup> | |
3116 </informaltable> | |
3117 | |
3118 | |
3119 The following functions can return results of type INTEGER or BYTE: | |
3120 | |
3121 <informaltable frame="none"> | |
3122 <tgroup cols="2"> | |
649 | 3123 <colspec colwidth="1.5in"/> |
24 | 3124 <tbody> |
3125 <row> | |
3126 <entry>FIX(<num>)</entry> | |
3127 <entry>round REAL <num> and convert to type INTEGER.</entry> | |
3128 </row> | |
3129 <row> | |
3130 <entry>MOD(<num1>,<num2>)</entry> | |
3131 <entry>modulus (remainder) function. <num1> mod <num2>.</entry> | |
3132 </row> | |
3133 <row> | |
3134 <entry>ADDR(<name>)</entry> | |
3135 <entry>absolute memory address of variable, array, or structure named <name>.</entry> | |
3136 </row> | |
3137 <row> | |
3138 <entry>SIZE(<name>)</entry> | |
3139 <entry>storage size in bytes of variable, array, or structure named <name>.</entry> | |
3140 </row> | |
3141 <row> | |
3142 <entry>ERR</entry> | |
3143 <entry>error code of most recent error, automatically resets to zero when referenced.</entry> | |
3144 </row> | |
3145 <row> | |
3146 <entry>PEEK(<int>)</entry> | |
3147 <entry>value of byte at memory address <int>.</entry> | |
3148 </row> | |
3149 <row> | |
3150 <entry>POS</entry> | |
3151 <entry>current character position of PRINT buffer.</entry> | |
3152 </row> | |
3153 <row> | |
3154 <entry>ASC(<str>)</entry> | |
3155 <entry>numeric value of first character of <str>.</entry> | |
3156 </row> | |
3157 <row> | |
3158 <entry>LEN(<str>)</entry> | |
3159 <entry>length of string <str>.</entry> | |
3160 </row> | |
3161 <row> | |
3162 <entry>SUBSTR(<str1>,<str2>)</entry> | |
3163 <entry>substring search: returns starting position of first occurrence of <str1> in | |
3164 <str2>, or 0 if not found.</entry> | |
3165 </row> | |
3166 </tbody> | |
3167 </tgroup> | |
3168 </informaltable> | |
3169 | |
3170 The following functions perform bit-by-bit logical operations on integer | |
1094 | 3171 or byte data types and return integer results. They should <emphasis>not</emphasis> be confused |
24 | 3172 with the BOOLEAN-type operators. |
3173 | |
3174 <informaltable frame="none"> | |
3175 <tgroup cols="2"> | |
649 | 3176 <colspec colwidth="1.5in"/> |
24 | 3177 <tbody> |
3178 <row> | |
3179 <entry>LAND(<num>,<num>)</entry> | |
3180 <entry>Logical AND</entry> | |
3181 </row> | |
3182 <row> | |
3183 <entry>LOR(<num>,<num>)</entry> | |
3184 <entry>Logical OR</entry> | |
3185 </row> | |
3186 <row> | |
3187 <entry>LXOR(<num>,<num>)</entry> | |
3188 <entry>Logical EXCLUSIVE OR</entry> | |
3189 </row> | |
3190 <row> | |
3191 <entry>LNOT(<num>)</entry> | |
3192 <entry>Logical NOT</entry> | |
3193 </row> | |
3194 </tbody> | |
3195 </tgroup> | |
3196 </informaltable> | |
3197 | |
3198 These functions return a result of type STRING: | |
3199 | |
3200 <informaltable frame="none"> | |
3201 <tgroup cols="2"> | |
649 | 3202 <colspec colwidth="1.7in"/> |
24 | 3203 <tbody> |
3204 <row> | |
3205 <entry>CHR$(<int>)</entry> | |
3206 <entry>ASCII char. equivalent of <int></entry> | |
3207 </row> | |
3208 <row> | |
3209 <entry>DATE$</entry> | |
3210 <entry>date and time, format: "yy/mm/dd hh:mm:ss"</entry> | |
3211 </row> | |
3212 <row> | |
3213 <entry>LEFT$(<str>,<int>)</entry> | |
3214 <entry>leftmost <int> characters of <str>.</entry> | |
3215 </row> | |
3216 <row> | |
3217 <entry>RIGHT$(<str>,<int>)</entry> | |
3218 <entry>rightmost <int> characters of <str>.</entry> | |
3219 </row> | |
3220 <row> | |
3221 <entry>MID$(<str>,<int1>,<int2>)</entry> | |
3222 <entry>middle <int2> characters of <str> starting at | |
3223 character position <int1>.</entry> | |
3224 </row> | |
3225 <row> | |
3226 <entry>STR$(<num>)</entry> | |
3227 <entry>converts numeric type <num> to displayable characters of type | |
3228 STRING representing the number converted.</entry> | |
3229 </row> | |
3230 <row> | |
3231 <entry>TRIM$(<str>)</entry> | |
3232 <entry><str> with trailing spaces removed.</entry> | |
3233 </row> | |
3234 </tbody> | |
3235 </tgroup> | |
3236 </informaltable> | |
3237 | |
3238 The following functions return BOOLEAN values: | |
3239 | |
3240 | |
3241 <informaltable frame="none"> | |
3242 <tgroup cols="2"> | |
649 | 3243 <colspec colwidth="1.5in"/> |
24 | 3244 <tbody> |
3245 <row> | |
3246 <entry>TRUE</entry> | |
3247 <entry>always returns TRUE.</entry> | |
3248 </row> | |
3249 <row> | |
3250 <entry>FALSE</entry> | |
3251 <entry>always returns FALSE.</entry> | |
3252 </row> | |
3253 <row> | |
3254 <entry>EOF(#<num>)</entry> | |
3255 <entry>End-of-file test on disk file path <num>, returns TRUE if | |
3256 end-of-file condition</entry> | |
3257 </row> | |
3258 </tbody> | |
3259 </tgroup> | |
3260 </informaltable> | |
3261 | |
3262 </para> | |
3263 </sect1> | |
3264 </chapter> | |
3265 <chapter> | |
3266 <title>Program Statements and Structure</title> | |
3267 <sect1><title>Program Structure</title> | |
3268 <para> | |
3269 Each &b09; can be a complete program in itself, or several procedures | |
3270 that call each other can be used to create an application program. It is | |
3271 up to the programmer to decide which approach to take. One procedure | |
3272 may suffice for small programs but large programs are easier to write | |
3273 and test if divided into separate modules (procedures) according to the | |
3274 program's natural flow. These suggestions reflect sound structured | |
3275 programming practice. Nonetheless, you can use a single large procedure | |
3276 for your program if you so desire. | |
3277 </para> | |
3278 <para> | |
3279 A procedure consists of any number of program statement lines. Each line | |
3280 can have an optional line number, and more than one program statement can be | |
3281 placed on the same line if separated by "\" characters. For | |
3282 example, the following statements are equivalent: | |
3283 | |
3284 <informaltable frame="none"> | |
3285 <tgroup cols="2"> | |
3286 <tbody> | |
3287 <row> | |
3288 <entry>GOSUB 550 \ PRINT X,Y \ RETURN</entry> | |
3289 <entry><literallayout>GOSUB 550 | |
3290 PRINT X,Y | |
3291 RETURN | |
3292 </literallayout></entry> | |
3293 </row> | |
3294 </tbody> | |
3295 </tgroup> | |
3296 </informaltable> | |
3297 The maximum input line length is 255 characters. Line feeds can | |
3298 be used to make a single long line into shorter lines to fit display | |
3299 screens better. This is especially useful when working on hard-copy | |
3300 terminals. | |
3301 </para> | |
3302 <para> | |
3303 Program statements can be in any order consistent with program logic | |
3304 Progra readability is improved if all variables are declared with | |
3305 DIM statements at the beginning of the procedure, but this is not mandatory. | |
3306 The program can be terminated with END or STOP statements, which are also | |
3307 optional. | |
3308 </para></sect1> | |
3309 <sect1><title>Line Numbers</title> | |
3310 <para> | |
3311 Line numbers are optional. They can be any integer number in the range of | |
3312 1 to 32767. Only use line numbers where absolutely necessary (such as | |
3313 with GOSUB). They make programs harder to understand, use additional | |
3314 memory space, and increase compile time considerably. Line numbers are | |
3315 local to procedures. That is, the same line number can be used in different | |
3316 procedures without conflict. | |
3317 </para></sect1> | |
3318 <sect1><title>Assignment Statements</title> | |
3319 <para> | |
3320 Assignment statements are used for computing or initializing of variables. | |
3321 </para> | |
3322 <sect2><title>LET Statement</title> | |
3323 <para> | |
3324 Syntax: | |
3325 <cmdsynopsis> | |
3326 <command>[LET] <var> := <expr></command> | |
649 | 3327 <sbr/> |
24 | 3328 <command>[LET] <var> = <expr></command> |
649 | 3329 <sbr/> |
24 | 3330 <command>[LET] <struct> := <struct></command> |
649 | 3331 <sbr/> |
24 | 3332 <command>[LET] <struct> = <struct></command> |
3333 </cmdsynopsis> | |
3334 | |
3335 </para> | |
3336 <para> | |
3337 This statement | |
3338 evaluates an expression and stores the result in <var> which may be a | |
3339 simple variable or data structure element. The result of the expression | |
3340 must be of the same or compatible type as <var>. | |
3341 &b09; will accept either "=" or ":=" as an assignment operator, however, the | |
3342 second form ( := ) is preferred because it distinguishes the assignment | |
3343 operation from a comparison (the test for equality). The ":=" operator is | |
3344 the same as used in PASCAL. | |
3345 </para> | |
3346 <para> | |
3347 Another use of the assignment statement is to copy the entire value | |
3348 of an array or complex data structure to another array or complex | |
3349 data structure. The data structures do not have to have the same type | |
3350 or "shape". The only restriction is that the size of the destination | |
3351 structure be the same or larger than the source structure. In fact this | |
3352 type of assignment can be used to perform unusual type conversions. | |
3353 For example, a string variable of 80 characters can be copied to a | |
3354 one-dimensional array of 80 bytes. | |
3355 </para> | |
3356 <para> | |
3357 Examples: | |
3358 | |
3359 <informalexample> | |
3360 <programlisting> | |
3361 A := 0.1 | |
3362 | |
3363 value := temp/sin(x) | |
3364 | |
3365 DIM array1(100), array2(100) | |
3366 array1 := array2 | |
3367 | |
3368 LET AUTHOR$ := FIRST_NAME$ + LAST_NAME$ | |
3369 | |
3370 DIM truth,lie:BOOLEAN | |
3371 lie := 100 < 1 | |
3372 truth := NOT lie | |
3373 | |
3374 count = total-adjustment | |
3375 matrix(2).coefficient(n+2) := matrix(1).coefficient(n) | |
3376 </programlisting> | |
3377 </informalexample> | |
3378 | |
3379 </para></sect2> | |
3380 <sect2><title>POKE Statement</title> | |
3381 <para> | |
3382 | |
3383 Syntax: | |
3384 <cmdsynopsis> | |
3385 <command>POKE <integer expr> , <byte expr></command> | |
3386 </cmdsynopsis> | |
3387 This statement allows a program to store data at a specific memory | |
3388 address. The first expression is used as the absolute address to store | |
3389 the type BYTE result of the second expression. This statement can alter | |
3390 any memory address so care must be taken when using it. | |
3391 </para> | |
3392 <para> | |
3393 Examples: | |
3394 | |
3395 <informalexample> | |
3396 <programlisting> | |
3397 POKE ADDR(buffer)+5,ASC("A") | |
3398 | |
3399 POKE 1200,14 | |
3400 | |
3401 POKE $1C00,$FF | |
3402 | |
3403 POKE pointer,PEEK(pointer+1) | |
3404 | |
3405 (* alternative to: alphabet$ := "ABCDEFGHIJKLMNOPQRSTUVWXYZ" *) | |
3406 FOR i=0 to 25 | |
3407 POKE ADDR(alphabet$)+i,$40+i | |
3408 NEXT i | |
3409 POKE ADDR(alphabet$)+26,$FF | |
3410 </programlisting> | |
3411 </informalexample> | |
3412 | |
3413 </para></sect2></sect1> | |
3414 | |
3415 <sect1><title>Control Statements</title> | |
3416 <para> | |
3417 This class of statements affect the (usually) sequential execution of | |
3418 program statements. They are used to construct loops or make decisions | |
1094 | 3419 that alter program flow. &b09; provides a selection of looping statements |
24 | 3420 that allow you to create any kind of loop using sound structured |
3421 programming style. | |
3422 </para> | |
3423 <sect2><title>IF Statement: Type 1</title> | |
3424 <para> | |
3425 Syntax: | |
3426 | |
3427 <cmdsynopsis> | |
3428 <command>IF <bool expr> THEN <line #></command> | |
3429 </cmdsynopsis> | |
3430 This form of the if statement causes execution to be transferred | |
3431 to the statement having the line number specified if the | |
3432 result of the expression is TRUE, otherwise the next sequential | |
3433 statement is executed. For example: | |
3434 <programlisting> | |
3435 IF payment < balance then 400 | |
3436 </programlisting> | |
3437 </para> | |
3438 </sect2> | |
3439 <sect2><title>IF Statement: Type 2</title> | |
3440 <para> | |
3441 Syntax: | |
3442 <cmdsynopsis> | |
3443 <command>IF <bool expr> THEN <statements></command> | |
649 | 3444 <sbr/> |
24 | 3445 <command>[ ELSE <statements> ]</command> |
649 | 3446 <sbr/> |
24 | 3447 <command>ENDIF</command> |
3448 </cmdsynopsis> | |
3449 This kind of IF structure evaluates the expression to a BOOLEAN | |
3450 value. If the result is TRUE the statement(s) immediately following | |
3451 the THEN are executed. If an ELSE clause exists, statements between | |
3452 the ELSE and ENDIF are skipped. If the expression is evaluated to | |
3453 FALSE control is transferred to the first statement following the | |
3454 ELSE, if present, or otherwise to the statement following the ENDIF. | |
3455 </para> | |
3456 <para> | |
3457 Examples: | |
3458 | |
3459 <informalexample> | |
3460 <programlisting> | |
3461 IF a < b THEN | |
3462 PRINT "a is less than b" | |
3463 PRINT "a:";a;" b:";b | |
3464 ENDIF | |
3465 | |
3466 IF a < b THEN | |
3467 PRINT "a is less than b" | |
3468 ELSE | |
3469 IF a=b THEN | |
3470 PRINT "a equals b" | |
3471 ELSE | |
3472 PRINT "a is greater than b" | |
3473 ENDIF | |
3474 ENDIF | |
3475 </programlisting> | |
3476 </informalexample> | |
3477 | |
3478 </para></sect2> | |
3479 <sect2><title>FOR/NEXT Statement</title> | |
3480 <para> | |
3481 Syntax: | |
3482 <cmdsynopsis> | |
3483 <command>FOR <var> = <expr> TO <expr> [ STEP <expr> ]</command> | |
649 | 3484 <sbr/> |
24 | 3485 <command>NEXT <var></command> |
3486 </cmdsynopsis> | |
3487 Creates a loop that usually executes a specified number of times | |
3488 while automatically increasing or decreasing a specified counter variable. | |
3489 The first expression is evaluated and the result is stored in <var> which | |
3490 must be a simple integer or real variable. The second expression is | |
3491 evaluated and stored in a temporary variable. | |
3492 If the STEP clause is used, the expression following is evaluated | |
3493 and used as the loop increment. If it is negative, the loop will count down. | |
3494 </para> | |
3495 <para> | |
3496 The "body" of the loop (i.e. statements between the "FOR" and "NEXT" are | |
3497 executed until the counter variable is larger than the terminating | |
3498 expression value. For negative STEP values, the loop will execute until the | |
3499 loop counter is less than the termination value. If the initial value of <var> | |
3500 is beyond the terminating value the body of the loop is never executed. | |
3501 It is legal to jump out of FOR/NEXT loops. The is no limit to the nesting | |
3502 of FOR/NEXT loops. | |
3503 </para> | |
3504 <para> | |
3505 Examples: | |
3506 | |
3507 <informalexample> | |
3508 <programlisting> | |
3509 FOR counter = 1 to 100 step .5 | |
3510 PRINT counter | |
3511 NEXT counter | |
3512 | |
3513 | |
649 | 3514 FOR var = min-1 TO min+max STEP increment-adjustment |
24 | 3515 PRINT var |
3516 NEXT var | |
3517 | |
3518 | |
649 | 3519 FOR x = 1000 TO 1 STEP -1 |
24 | 3520 PRINT x |
3521 NEXT x | |
3522 </programlisting> | |
3523 </informalexample> | |
3524 </para></sect2> | |
3525 <sect2><title>WHILE..DO Statement</title> | |
3526 <para> | |
3527 Syntax: | |
3528 <cmdsynopsis> | |
3529 <command>WHILE <bool expr> DO</command> | |
649 | 3530 <sbr/> |
24 | 3531 <command>ENDWHILE</command> |
3532 </cmdsynopsis> | |
3533 This is a loop construct with the test at the "top" of the | |
3534 loop. Statements within the loop are executed as long as <bool | |
3535 expr> is TRUE. The body of the loop will not be executed if the | |
3536 boolean expression evaluates to FALSE when first executed. | |
3537 </para> | |
3538 <para> | |
3539 Examples: | |
3540 | |
3541 <informalexample> | |
3542 <programlisting> | |
3543 WHILE a<b DO is equivalent to 100 IF a>=b THEN 500 | |
3544 PRINT a PRINT a | |
3545 a := a+1 a := a+1 | |
3546 ENDWHILE GOTO 100 | |
3547 500 REM | |
3548 | |
3549 DIM yes:BOOLEAN | |
3550 yes=TRUE | |
3551 WHILE yes DO | |
3552 PRINT "yes! "; | |
3553 yes := POS<50 | |
3554 ENDWHILE | |
3555 | |
3556 REM reverse the letters in word$ | |
3557 backward$ := "" | |
3558 INPUT word$ | |
3559 WHILE LEN(word$) > 0 DO | |
3560 backward$ := backward$ + RIGHT$(word$,1) | |
649 | 3561 word$ := LEFT$(word$,LEN(word$)-1) |
24 | 3562 ENDWHILE |
3563 word$ := backward$ | |
3564 PRINT word$ | |
3565 </programlisting> | |
3566 </informalexample> | |
3567 | |
3568 </para></sect2> | |
3569 <sect2><title>REPEAT..UNTIL Statement</title> | |
3570 <para> | |
3571 Syntax: | |
3572 <cmdsynopsis> | |
3573 <command>REPEAT</command> | |
649 | 3574 <sbr/> |
24 | 3575 <command>UNTIL <bool expr></command> |
3576 </cmdsynopsis> | |
3577 This is a loop that has its test at the bottom of the loop. The | |
3578 statement(s) within the loop are executed until the result of <bool expr> is | |
3579 TRUE. The body of the loop is always executed at least one time. | |
3580 </para> | |
3581 <para> | |
3582 Examples: | |
3583 <informalexample> | |
3584 <programlisting> | |
3585 x = 0 is the same as x=0 | |
3586 REPEAT 100 PRINT x | |
3587 PRINT x x=x+1 | |
3588 x=x+1 IF X <= 10 THEN 100 | |
3589 UNTIL x>10 | |
3590 | |
3591 (* compute factorial: n! *) | |
3592 temp := 1. | |
3593 INPUT "Factorial of what number? ",n | |
3594 REPEAT | |
3595 temp := temp * n | |
649 | 3596 n := n-1 |
24 | 3597 UNTIL n <= 1.0 |
3598 PRINT "The factorial is "; temp | |
3599 </programlisting> | |
3600 </informalexample> | |
3601 </para></sect2> | |
3602 <sect2><title>LOOP and ENDLOOP/EXITIF and ENDEXIT Statements</title> | |
3603 <para> | |
3604 Syntax: | |
3605 <cmdsynopsis> | |
3606 <command>LOOP</command> | |
649 | 3607 <sbr/> |
24 | 3608 <command>ENDLOOP</command> |
3609 </cmdsynopsis> | |
3610 | |
3611 <cmdsynopsis> | |
3612 <command>EXITIF <bool expr> THEN <statements></command> | |
649 | 3613 <sbr/> |
24 | 3614 <command>ENDEXIT</command> |
3615 </cmdsynopsis> | |
3616 These related types of statements can be used to construct | |
3617 loops with test(s) located anywhere in the body of the loop. | |
3618 The LOOP and ENDLOOP statements define the body of the loop. | |
3619 EXITIF clauses can be inserted anywhere inside the loop to leave the loop | |
3620 if the result of its test is true. | |
3621 Note that if there is no EXITIF clause, you will create a loop that never ends. | |
3622 </para> | |
3623 <para> | |
3624 The EXITIF clause evaluates an expression to a boolean result. If the | |
3625 result is FALSE, the statement following the ENDEXIT is executed next. | |
1094 | 3626 Otherwise, the statement(s) between the EXITIF and ENDEXIT are |
24 | 3627 executed, then control is transferred to the statement following |
3628 the body of the loop. This exit clause | |
3629 is often used to perform some specific function upon termination of the | |
3630 loop which depends on where the loop terminated. | |
3631 </para> | |
3632 <para> | |
3633 EXITIF statements are almost always used when LOOP..ENDLOOP is | |
3634 used, but they can also be useful in ANY type of &b09; loop | |
3635 construct (e.g., FOR/NEXT, REPEAT... UNTIL, etc.). Examples: | |
3636 | |
3637 <informalexample> | |
3638 <programlisting> | |
3639 LOOP is equivalent to 100 REM top of loop | |
3640 count=count+1 count=count+1 | |
3641 EXITIF count >100 THEN IF COUNT <= 100 then 200 | |
3642 done = TRUE done = TRUE | |
3643 ENDEXIT GOTO 300 | |
3644 PRINT count 200 PRINT count | |
3645 x = count/2 x = count/2 | |
3646 ENDLOOP GOTO 100 | |
3647 300 REM out of loop | |
3648 | |
3649 INPUT x,y | |
3650 LOOP | |
3651 PRINT | |
3652 EXITIF x < 0 THEN | |
3653 PRINT "x became zero first" | |
3654 ENDEXIT | |
649 | 3655 x := x-1 |
24 | 3656 EXITIF y < 0 THEN PRINT "y became zero first" |
3657 ENDEXIT | |
649 | 3658 y := y-1 |
24 | 3659 ENDLOOP |
3660 </programlisting> | |
3661 </informalexample> | |
3662 | |
3663 </para></sect2> | |
3664 <sect2><title>GOTO Statement</title> | |
3665 <para> | |
3666 Syntax: | |
3667 <cmdsynopsis> | |
3668 <command>GOTO <line #></command> | |
3669 </cmdsynopsis> | |
3670 The GOTO unconditionally transfers execution flow to the line having the | |
3671 specified number. Note that the line number is a constant, not an expression | |
3672 or a variable. | |
3673 </para> | |
3674 <para> | |
3675 Example: | |
3676 <informalexample> | |
3677 <programlisting> | |
3678 GOTO 1000 | |
3679 </programlisting> | |
3680 </informalexample> | |
3681 | |
3682 </para></sect2> | |
3683 <sect2><title>GOSUB/RETURN Statements</title> | |
3684 <para> | |
3685 Syntax: | |
3686 <cmdsynopsis> | |
3687 <command>GOSUB <line #></command> | |
649 | 3688 <sbr/> |
24 | 3689 <command>RETURN</command> |
3690 </cmdsynopsis> | |
3691 The GOSUB statement | |
3692 transfers program execution to a subroutine starting at the specified | |
3693 line number. The subroutine is executed until a RETURN statement is | |
3694 encountered, which causes execution to resume at the statement following | |
3695 the calling GOSUB. Subroutines may be "nested" to any depth. | |
3696 </para> | |
3697 <para> | |
3698 Example: | |
3699 <informalexample> | |
3700 <programlisting> | |
3701 FOR n := 1 to 10 | |
3702 x := SIN(n) | |
3703 GOSUB 100 | |
3704 NEXT n | |
3705 FOR m := 1 TO 10 | |
3706 x := COS(m) | |
3707 GOSUB 100 | |
3708 NEXT m | |
3709 STOP | |
3710 | |
3711 100 x := x/2 | |
3712 PRINT x | |
3713 RETURN | |
3714 </programlisting> | |
3715 </informalexample> | |
3716 </para></sect2> | |
3717 <sect2><title>ON GOTO/GOSUB Statement</title> | |
3718 <para> | |
3719 Syntax: | |
3720 <cmdsynopsis> | |
3721 <command>ON <int expr> GOTO <line #> {,<line #>}</command> | |
649 | 3722 <sbr/> |
24 | 3723 <command>ON <int expr> GOSUB <line #> {,<line #>}</command> |
3724 </cmdsynopsis> | |
3725 These statements evaluate an integer expression and use the result to select | |
3726 a corresponding line number from an ordered list. Control is then | |
3727 transferred to that line number unconditionally in ON GOTO statements or | |
3728 as a subroutine in ON GOSUB statements. | |
3729 These statements are similar to CASE statements in other languages. | |
3730 </para> | |
3731 <para> | |
3732 The expression must evaluate to a positive INTEGER-type result | |
3733 having a value between 1 and n, n being the amount of line numbers in the | |
3734 list. If the result has any other result, no line number is selected | |
3735 and the next sequential statement is executed. | |
3736 </para> | |
3737 <para> | |
3738 Example: | |
3739 | |
3740 <informalexample> | |
3741 <programlisting> | |
3742 (* spell out the digits 0 to 9 *) | |
3743 DIM digit:INTEGER | |
3744 A$="one digit only, please" | |
3745 INPUT "type in a digit"; digit | |
3746 ON digit+1 GOSUB 10,11,12,13,14,15,16,17,18,19 | |
3747 PRINT A$ | |
3748 STOP | |
3749 | |
3750 (* names of digits *) | |
3751 10 A$ := "ZERO" | |
3752 RETURN | |
3753 11 A$ := "ONE" | |
3754 RETURN | |
3755 12 A$ := "TWO" | |
3756 RETURN | |
3757 13 A$ := "THREE" | |
3758 RETURN | |
3759 14 A$ := "FOUR" | |
3760 RETURN | |
3761 15 A$ := "FIVE" | |
3762 RETURN | |
3763 16 A$ := "SIX" | |
3764 RETURN | |
3765 17 A$ := "SEVEN" | |
3766 RETURN | |
3767 18 A$ := "EIGHT" | |
3768 RETURN | |
3769 19 A$ := "NINE" | |
3770 RETURN | |
3771 </programlisting> | |
3772 </informalexample> | |
3773 </para></sect2> | |
3774 <sect2><title>ON ERROR GOTO Statement</title> | |
3775 <para> | |
3776 Syntax: | |
3777 <cmdsynopsis> | |
3778 <command>ON ERROR [ GOTO <line #> ]</command> | |
3779 </cmdsynopsis> | |
3780 This statement sets a "trap" that transfers control to the line | |
3781 number given when a non-fatal run-time error occurs. If no ON ERROR GOTO has | |
3782 been executed in a procedure before an error occurs, the procedure will stop | |
3783 and enter DEBUG mode. The error trap can be turned of by executing ON | |
3784 ERROR without a GOTO. | |
3785 </para> | |
3786 <para> | |
3787 This statement is often used in conjunction with the ERR function, | |
3788 which returns the specific error code, and the ERROR statement | |
3789 which artificially generates "errors". Note: the ERR function | |
3790 automatically resets to zero any time it is called. | |
3791 </para> | |
3792 <para> | |
3793 Example: | |
3794 <informalexample> | |
3795 <programlisting> | |
3796 (* List a file *) | |
3797 | |
3798 DIM path,errnum: INTEGER, name: STRING[45], line: STRING[80] | |
3799 ON ERROR GOTO 10 | |
3800 INPUT "File name? "; name | |
3801 OPEN #path,name:READ | |
3802 LOOP | |
3803 READ #path, line | |
3804 PRINT line | |
3805 ENDLOOP | |
3806 | |
3807 10 errnum=ERR | |
3808 IF errnum = 211 THEN | |
3809 (* end-of-file *) | |
3810 PRINT "Listing complete." | |
3811 CLOSE #path | |
3812 END | |
3813 ELSE | |
3814 (* other errors *) | |
3815 PRINT "Error number "; errnum | |
3816 END | |
3817 ENDIF | |
3818 </programlisting> | |
3819 </informalexample> | |
3820 </para></sect2></sect1> | |
3821 <sect1><title>Execution Statements</title> | |
3822 <para> | |
3823 Execution statements run procedures, stop execution of procedures, create | |
3824 shells, or affect the current execution of the procedure. | |
3825 </para> | |
3826 <sect2><title>Run Statement</title> | |
3827 <para> | |
3828 Syntax: | |
3829 <cmdsynopsis> | |
3830 <command>RUN <proc name> [ ( <param> {,<param>} ) ]</command> | |
649 | 3831 <sbr/> |
24 | 3832 <command>RUN <string var> [ ( <param> {,<param>} ) ]</command> |
3833 </cmdsynopsis> | |
3834 This statement | |
3835 calls a procedure by name; when that procedure ends, control will pass | |
3836 to the next statement after the RUN. It is most often used to call a | |
3837 procedure inside the workspace, but it can also be used to call a previously | |
1015 | 3838 compiled (by the PACK command) procedure or a &CPU; machine language |
24 | 3839 procedure outside the |
3840 workspace. The name can be optionally taken from a string variable. | |
3841 </para></sect2> | |
3842 <sect2><title>Parameter Passing</title> | |
3843 <para> | |
3844 The RUN statement | |
3845 can include a list of parameters enclosed in parentheses to be passed to | |
3846 the called procedure. The called procedure must have PARAM statements | |
3847 of the same size and order to match the parameters passed to it by the | |
3848 calling procedure. | |
3849 </para> | |
3850 <para> | |
3851 The parameters can be variables, constants, or the names of entire arrays or | |
3852 data structures. They can be of any type, (EXCEPT variable of type BYTE | |
3853 but BYTE arrays are O.K.). | |
3854 If a parameter is a constant or expression, it is passed "by value", i.e., | |
3855 it is evaluated and placed in a temporary storage | |
3856 location, and the address of the temporary storage is passed to the called | |
3857 procedure. Parameters passed by value can be changed by the receiving | |
3858 procedure, but the changes are not reflected in the calling procedure. | |
3859 </para> | |
3860 <para> | |
3861 If the parameter is the name of a variable, array, or data structure, it is | |
3862 passed by "reference", i.e., the address of that storage | |
3863 is sent to the called procedure and thus the value in that storage may be | |
3864 changed by the receiving procedure. These changes are reflected in the | |
3865 calling procedure. | |
3866 </para></sect2> | |
3867 <sect2><title>Calling External Procedures</title> | |
3868 <para> | |
3869 If the procedure named by RUN can't be found in the workspace, &b09; | |
3870 will check to see if it was loaded by OS-9 outside the workspace. If it isn't | |
3871 found there, &b09; will try to find a disk file having the same name in the | |
3872 current execution directory, load it, and run it. | |
3873 In either case, &b09; checks to see if the called procedure is a &b09; | |
1015 | 3874 I-code module or a &CPU; machine language module, and executes it |
3875 accordingly. If it is a &CPU; machine language module, &b09; executes a | |
3876 JSR instruction to its entry point and the module is executed as &CPU; | |
24 | 3877 native code. The machine language routine can return to the original |
3878 calling procedure by executing an RTS instruction. The diagram on the | |
3879 next page shows what the stack frame passed to machine-language | |
3880 subroutines looks like. | |
3881 </para> | |
3882 <para> | |
3883 After an external procedure has been called but is no longer needed, the | |
3884 KILL statement should be used to get rid of it so its memory space can be | |
3885 used for other purposes. | |
3886 <figure> | |
3887 <title>Stack Frame Passed to Machine Language Procedures</title> | |
1094 | 3888 <screen> |
24 | 3889 +----------------------+ ^ |
3890 | | | | |
3891 higher addresses | |
3892 | |
3893 | more parameters | | |
3894 | |
3895 | | | |
3896 +----------------------+ --- | |
3897 | | | | |
3898 | size of 1st param | | | |
3899 + - - - - - - - + 4 bytes | |
3900 | addr of 1st param | | | |
3901 | | | | |
3902 +----------------------+ --- | |
3903 | | | | |
3904 | parameter count | 2 bytes | |
3905 | | | | |
3906 +----------------------+ --- | |
3907 | | | | |
3908 | return address | 2 bytes | |
3909 | | | | |
1015 | 3910 +----------------------+ --- <- &CPU; Stack Pointer |
24 | 3911 Register value |
1094 | 3912 </screen> |
24 | 3913 </figure> |
3914 </para> | |
3915 <para> | |
3916 Machine language modules return error status by setting the "C" | |
3917 bit of the MPU condition codes register, and by setting the B | |
3918 register to the appropiate error code. For an example of a machine | |
1094 | 3919 language subroutine ("INKEY"), See <xref linkend="sample-programs"/>. |
24 | 3920 </para> |
3921 <para> | |
3922 Example of use of the RUN statement: | |
3923 | |
3924 <informalexample> | |
3925 <programlisting> | |
3926 PROCEDURE trig_table | |
3927 num1 := 0 \ num2 := 0 | |
3928 REPEAT | |
3929 RUN display(num1,SIN(num1)) | |
3930 RUN display(num2,COS(num2)) | |
3931 PRINT | |
3932 UNTIL num1 > 1 | |
3933 END | |
3934 | |
3935 PROCEDURE display | |
3936 PARAM passed,funcval | |
3937 PRINT passed;":";funcval, | |
3938 passed := passed + 0.1 | |
3939 END | |
3940 </programlisting> | |
3941 </informalexample> | |
3942 | |
3943 </para></sect2> | |
3944 <sect2><title>KILL Statement</title> | |
3945 <para> | |
3946 Syntax: | |
3947 <cmdsynopsis> | |
3948 <command>KILL <str expr></command> | |
3949 </cmdsynopsis> | |
3950 | |
3951 This statement is used to | |
3952 "unlink" an external procedure, possibly returning system memory, | |
3953 and remove it from &b09;'s procedure directory. If the procedure is | |
3954 inside the workspace, nothing happens and no error is generated. KILL can | |
3955 be used with auto-loading PACKed procedures as an alternative to CHAIN | |
3956 when program overlay is desired. | |
3957 <warning> | |
3958 <orderedlist numeration="arabic"> | |
3959 <listitem> | |
3960 <para> | |
3961 It can be fatal to OS-9 to KILL a procedure that is still "active". | |
3962 </para> | |
3963 </listitem> | |
3964 <listitem> | |
3965 <para> | |
1094 | 3966 When KILL is used together with a RUN statement, the RUN statement <emphasis>must</emphasis> use the |
24 | 3967 same string variable which contains the name of the procedure. |
3968 See the first example below: | |
3969 </para> | |
3970 </listitem> | |
3971 </orderedlist> | |
3972 </warning> | |
3973 Examples: | |
3974 <informalexample> | |
3975 <programlisting> | |
3976 LET procname$="average" | |
3977 RUN procname$ | |
3978 KILL procname$ | |
3979 | |
3980 INPUT "Which test do you want to run? ",test$ | |
3981 RUN test$ | |
3982 KILL test$ | |
3983 </programlisting> | |
3984 </informalexample> | |
3985 </para></sect2> | |
3986 <sect2><title>CHAIN Statement</title> | |
3987 <para> | |
3988 Syntax: | |
3989 <cmdsynopsis> | |
3990 <command>CHAIN <str expr></command> | |
3991 </cmdsynopsis> | |
3992 The CHAIN statement | |
3993 performs an OS-9 "chain" operation on the SHELL, passing the specified | |
3994 string as an argument. This causes &b09; to be exited, unlinked, | |
3995 and its memory returned to OS-9. The string should evaluate to the | |
3996 name of an executable module (such as &b09;), passing parameters if | |
3997 appropriate. | |
3998 </para> | |
3999 <para> | |
4000 CHAIN | |
4001 can begin execution of any module, not just &b09;. It executes the | |
4002 module indirectly through the Shell in order to take advantage of Shell's | |
4003 parameter processing. This has the side-effect of | |
4004 leaving an extra "incarnation" of the Shell active. Programs that | |
4005 repeatedly chain to each other eventually find all of memory filled with | |
4006 waiting shells. This can be prevented by using the "ex" option of the Shell. | |
4007 Consult the OS-9 User's Guide for more details on the capabilities of the shell. | |
4008 </para> | |
4009 <para> | |
4010 Files that are open when a CHAIN occurs are not closed. | |
4011 However, the OS-9 Fork call will only pass the standard I/O paths | |
4012 (0,1,2) to a child process. Therefore, if it is necesary to pass | |
4013 an open path to another program segment, the "ex" option of Shell | |
4014 must be used. | |
4015 </para> | |
4016 <para> | |
4017 Examples: | |
4018 | |
4019 <informalexample> | |
4020 <programlisting> | |
4021 CHAIN "ex &b09; menu" | |
4022 | |
4023 CHAIN "&b09; #10k sort (""datafile"",""tempfile"")" | |
4024 | |
4025 CHAIN "DIR /D0" | |
4026 | |
4027 CHAIN "Dir; Echo *** Copying Directory ***; ex basic09 copydir" | |
4028 </programlisting> | |
4029 </informalexample> | |
4030 | |
4031 </para></sect2> | |
4032 <sect2><title>SHELL Statement</title> | |
4033 <para> | |
4034 Syntax: | |
4035 <cmdsynopsis> | |
4036 <command>SHELL <str expr></command> | |
4037 </cmdsynopsis> | |
4038 This statement | |
4039 allows &b09; programs to run any OS-9 command or program. | |
4040 This gives access to virtually any OS-9 function including | |
4041 multiprogramming, utility commands, terminal, and I/O control, | |
4042 and more. | |
4043 Consult the "OS-9 User's Guide" for a detailed | |
4044 discussion of OS-9 standard commands. | |
4045 </para> | |
4046 <para> | |
4047 The SHELL statement requests OS-9 to create a new process, initially | |
4048 executing the "shell", which is the OS-9 command interpreter. The | |
4049 shell can then call any program in the system (subject to the normal | |
4050 security functions). The string expression is evaluated and passed to the | |
4051 shell to be executed as a command line. (just as if it had | |
4052 been typed in). If the string is null, &b09; is temporarily | |
4053 suspended and the shell process displays prompts | |
4054 and accepts commands in its normal manner. When the shell process | |
4055 terminates, &b09; becomes active again and resumes execution at the | |
4056 statement following the SHELL statement. | |
4057 </para> | |
4058 <para> | |
4059 Here are a few examples of using the shell from &b09;: | |
4060 | |
4061 <informalexample> | |
4062 <programlisting> | |
4063 SHELL "copy file1 file2" sequential execution | |
4064 | |
4065 SHELL "copy file1 file2&" concurrent execution | |
4066 | |
4067 SHELL "edit document" calling text editor | |
4068 | |
4069 SHELL "asm source o=obj ! spool &" concurrent assembly | |
4070 | |
4071 N:=5 | |
4072 SHELL "kill "+STR$(N) | |
4073 | |
4074 file$ := "/d1/batch_jobs" concurrent execution of a | |
4075 SHELL file$ + " -p >/p &" batch procedure file | |
4076 </programlisting> | |
4077 </informalexample> | |
4078 </para></sect2> | |
4079 <sect2><title>END Statement</title> | |
4080 <para> | |
4081 Syntax: | |
4082 <cmdsynopsis> | |
4083 <command>END [<output list>]</command> | |
4084 </cmdsynopsis> | |
4085 This statement | |
4086 ends execution of the procedure and returns to the calling procedure, | |
4087 or to &b09; command mode if it was the highest level procedure. If an | |
4088 output list is given, it also works the same as the PRINT statement. | |
4089 END is an executable statement and can be used several times in the same | |
4090 procedure. END is optional: it is not required at the "bottom" of a procedure. | |
4091 </para> | |
4092 <para> | |
4093 Examples: | |
4094 | |
4095 <informalexample> | |
4096 <programlisting> | |
4097 END | |
4098 | |
4099 END "I have finished execution" | |
4100 </programlisting> | |
4101 </informalexample> | |
4102 </para></sect2> | |
4103 <sect2><title>Stop Statement</title> | |
4104 <para> | |
4105 Syntax: | |
4106 <cmdsynopsis> | |
4107 <command>STOP [<output list>]</command> | |
4108 </cmdsynopsis> | |
4109 This statement | |
4110 immediately terminates execution of all procedures and returns to the | |
4111 command mode. If an output list is given it also works like a | |
4112 PRINT statement. | |
4113 </para></sect2> | |
4114 <sect2><title>BYE Statement</title> | |
4115 <para> | |
4116 Syntax: | |
4117 <cmdsynopsis> | |
4118 <command>BYE</command> | |
4119 </cmdsynopsis> | |
4120 | |
4121 This statement | |
4122 ends execution of the procedure and terminates &b09;. Any open files | |
4123 are closed, and any unsaved procedures or data in the workspace will be lost. | |
4124 This command is especially useful for creating PACKed programs and/or | |
4125 programs to be called from OS-9 procedure files. | |
4126 <warning> | |
4127 <para> | |
4128 This command causes &b09; to abort. | |
4129 It should only be used if the program has been saved before it is tested! | |
4130 </para> | |
4131 </warning> | |
4132 </para></sect2> | |
4133 <sect2><title>ERROR Statement</title> | |
4134 <para> | |
4135 Syntax: | |
4136 <cmdsynopsis> | |
4137 <command>ERROR(<integer expr>)</command> | |
4138 </cmdsynopsis> | |
4139 This statement | |
4140 generates an error having the error code specified by the result of | |
4141 evaluation of the expression. ERROR is often used for testing error routines. | |
4142 For details on error handling see the ON ERROR GOTO statement description. | |
4143 </para></sect2> | |
4144 <sect2><title>PAUSE Statement</title> | |
4145 <para> | |
4146 Syntax: | |
4147 <cmdsynopsis> | |
4148 <command>PAUSE [<output list>]</command> | |
4149 </cmdsynopsis> | |
4150 PAUSE suspends execution of the procedure and causes &b09; to enter | |
4151 Debug Mode. If an output list is given it also works like a PRINT | |
4152 statement. | |
4153 <programlisting> | |
4154 <output> BREAK IN PROCEDURE <procedure name> | |
4155 </programlisting> | |
4156 The Debug Mode "CONT" command can be used to resume procedure | |
4157 execution at the following statement. | |
4158 </para> | |
4159 <para> | |
4160 Examples: | |
4161 | |
4162 <informalexample> | |
4163 <programlisting> | |
4164 PAUSE | |
4165 | |
4166 PAUSE "now outside main loop" | |
4167 </programlisting> | |
4168 </informalexample> | |
4169 | |
4170 </para></sect2> | |
4171 <sect2><title>CHD and CHX Statements</title> | |
4172 <para> | |
4173 Syntax: | |
4174 <cmdsynopsis> | |
4175 <command>CHD <str expr></command> | |
649 | 4176 <sbr/> |
24 | 4177 <command>CHX <str expr></command> |
4178 </cmdsynopsis> | |
4179 These statements | |
4180 change the current default Data or Execution directory, | |
4181 respectively. The string must specify the pathlist of a file | |
4182 which has the DIR attribute. | |
4183 For more information on the OS-9 directory structure, consult | |
4184 the OS-9 User's Guide. | |
4185 </para></sect2> | |
4186 <sect2><title>DEG and RAD Statements</title> | |
4187 <para> | |
4188 Syntax: | |
4189 <cmdsynopsis> | |
4190 <command>DEG</command> | |
649 | 4191 <sbr/> |
24 | 4192 <command>RAD</command> |
4193 </cmdsynopsis> | |
4194 These statements | |
4195 set the procedure's state flag to assume angles stated in | |
4196 degrees or radians in SIN, COS, TAN, ACS, ASN, and ATN functions. | |
4197 This flag applies only to the currently active procedure. The default state | |
4198 is radians. | |
4199 </para></sect2> | |
4200 <sect2><title>BASE 0 and BASE 1 Statements</title> | |
4201 <para> | |
4202 Syntax: | |
4203 <cmdsynopsis> | |
4204 <command>BASE 0</command> | |
649 | 4205 <sbr/> |
24 | 4206 <command>BASE 1</command> |
4207 </cmdsynopsis> | |
4208 | |
4209 These statements indicate whether a particular procedure's lowest array | |
4210 or data structure index (subscript) is zero or one. The | |
4211 default is one. These statements do not affect the string operations | |
4212 (e.g., MID$, RIGHT$, OR LEFT$) where the beginning character of a string | |
4213 is always index one. | |
4214 </para></sect2> | |
4215 <sect2><title>TRON and TROFF Statements</title> | |
4216 <para> | |
4217 Syntax: | |
4218 <cmdsynopsis> | |
4219 <command>TRON</command> | |
649 | 4220 <sbr/> |
24 | 4221 <command>TROFF</command> |
4222 </cmdsynopsis> | |
4223 These statements turn the trace mode on or off, and are useful for debugging. | |
4224 When trace mode is turned on, each statement is decompiled and printed | |
4225 before execution. Also, the result of each expression evaluation is printed as | |
4226 it occurs. | |
4227 </para></sect2> | |
4228 <sect2><title>Comment Statements</title> | |
4229 <para> | |
4230 Syntax: | |
4231 <cmdsynopsis> | |
4232 <command>REM <chars></command> | |
649 | 4233 <sbr/> |
24 | 4234 <command>(* <chars> [ *) ]</command> |
4235 </cmdsynopsis> | |
4236 These statements are used to put comments in programs. The second form | |
4237 of the statement is for compatibility with PASCAL programs. Comments | |
4238 are retained in the I-code but are removed by the PACK compile command. | |
4239 The "!" character can be typed in place of the keyword | |
4240 REM when editing programs. The compiler trims away extra spaces | |
4241 following REM to conserve memory space. | |
4242 </para> | |
4243 <para> | |
4244 Examples: | |
4245 <informalexample> | |
4246 <programlisting> | |
4247 REM this is a comment | |
4248 | |
4249 (* This is also a comment *) | |
4250 | |
4251 (* This is another kind of comment | |
4252 </programlisting> | |
4253 </informalexample> | |
4254 </para></sect2></sect1> | |
4255 <sect1><title>Declarative Statements</title> | |
4256 <para> | |
4257 The DIM, PARAM, and TYPE statements are called | |
4258 <emphasis>declarative statements</emphasis> because | |
4259 they are used to define and/or declare variables, arrays, and complex data | |
4260 structures. The DIM and PARAM statements | |
4261 are almost identical, the difference being that DIM are used to | |
4262 declare storage used exclusively within the procedure, and the PARAM statement | |
4263 is used to declare variables <emphasis>received</emphasis> from another calling procedure. | |
4264 </para> | |
4265 <para> | |
4266 When do you need to use the DIM statement? | |
4267 You don't need to for simple variables of type REAL because | |
4268 this is the default format for undeclared variables. You also don't need to | |
4269 for 32-character STRING type variables (any name ending with a | |
4270 "$" is automatically assigned this type). Even though you don't have to | |
4271 declare variables in these two cases, you may want to anyway to | |
4272 improve your program's internal documentation. Those | |
4273 things you <emphasis>must</emphasis> declare are: | |
4274 <orderedlist numeration="arabic"> | |
4275 <listitem> | |
4276 <para>Any simple variables of type BYTE, INTEGER, or BOOLEAN.</para> | |
4277 </listitem> | |
4278 <listitem> | |
4279 <para>Any simple STRING variables shorter or longer than 32 characters.</para> | |
4280 </listitem> | |
4281 <listitem> | |
4282 <para>Arrays of any type.</para> | |
4283 </listitem> | |
4284 <listitem> | |
4285 <para>Complex data structures of any type.</para> | |
4286 </listitem> | |
4287 </orderedlist> | |
4288 </para> | |
4289 <para> | |
4290 The TYPE statement does not really create variable storage. Its purpose is to | |
4291 describe a <emphasis>new</emphasis> data structure type that can be used | |
4292 in DIM or PARAM statements in addition to the five atomic data | |
4293 types built-in to &b09;. | |
4294 Therefore, TYPE is only used in programs that use complex data structures. | |
4295 </para> | |
4296 <sect2><title>DIM Statement</title> | |
4297 <para> | |
4298 Syntax: | |
4299 <cmdsynopsis> | |
4300 <command>DIM <decl seq> {; <decl seq>}</command> | |
649 | 4301 <sbr/> |
24 | 4302 <command><decl seq> := <decl> {, <decl>} : <type>}</command> |
649 | 4303 <sbr/> |
24 | 4304 <command><decl> := <name> [, <subscript> ]</command> |
649 | 4305 <sbr/> |
24 | 4306 <command><subscr> := ( <const> [,<const> [,<const>]] )</command> |
649 | 4307 <sbr/> |
24 | 4308 <command><type> := BYTE | INTEGER | REAL | BOOLEAN | |
4309 STRING | STRING <max len> | <user defined type></command> | |
649 | 4310 <sbr/> |
24 | 4311 <command><user def> := user defined by TYPE statement</command> |
4312 </cmdsynopsis> | |
4313 The DIM statement is used to declare simple variables, | |
4314 arrays, or complex data structures of the five | |
4315 atomic types or any user-defined type. During compilation, &b09; assigns | |
4316 storage required for all variables declared in DIM statements. | |
4317 </para> | |
4318 <sect3><title>Declaring Simple Variables</title> | |
4319 <para> | |
4320 Simple variables are declared by using the variable name in a DIM | |
4321 statement without a subscript. If variables are not explicitly declared, they | |
4322 are automatically assumed to be REAL, or tpe STRING[32] | |
4323 if the variable name ends with a | |
4324 "$" character. Therefore all simple variables of other types | |
4325 must be explicitly declared. For example: | |
4326 | |
4327 <informalexample> | |
4328 <programlisting> | |
4329 DIM logical:BOOLEAN | |
4330 </programlisting> | |
4331 </informalexample> | |
4332 | |
4333 Several variables can be declared in sequence with a :<type> | |
4334 following a group of the same type: | |
4335 <informalexample> | |
4336 <programlisting> | |
4337 DIM a,b,c: STRING | |
4338 </programlisting> | |
4339 </informalexample> | |
4340 In addition, several different types can be declared in a single DIM | |
4341 statement by using a semicolon ";" to separate different types: | |
4342 | |
4343 <informalexample> | |
4344 <programlisting> | |
4345 DIM a,b,c:INTEGER; n,m:decimal; x,y,z:BOOLEAN | |
4346 </programlisting> | |
4347 </informalexample> | |
4348 | |
4349 In this example a, b, and c are type INTEGER, n and m are type "decimal" (a | |
4350 user-defined type), and x, y, and z are type BOOLEAN. | |
4351 String variables are declared the same way except an optional | |
4352 maximum string length can be specified. If a length is not explicitly | |
4353 given, 32 characters are assumed: | |
4354 | |
4355 <informalexample> | |
4356 <programlisting> | |
4357 DIM name:STRING[40]; address,city:STRING; zip:REAL | |
4358 </programlisting> | |
4359 </informalexample> | |
4360 | |
4361 In this case, "name" is a string variable of 40 characters maximum, "address" | |
4362 and "city" are string variables of 32 characters each, and "zip" is a | |
4363 real variable. | |
4364 </para></sect3> | |
4365 <sect3><title>Array Declarations</title> | |
4366 <para> | |
4367 Arrays can have one, two, or three dimensions. The DIM statement format | |
4368 (including type grouping) | |
4369 is the same as for simple variables except each name is followed by | |
4370 subscript(s) to indicate its size. The maximum subscript size is | |
4371 32767. Simple variable and array declarations can be mixed | |
4372 in the same DIM statement: | |
4373 | |
4374 <informalexample> | |
4375 <programlisting> | |
4376 DIM a(10),b(20,30),c:INTEGER; x(5,5,5):STRING[12] | |
4377 </programlisting> | |
4378 </informalexample> | |
4379 | |
4380 In the example above, "a" is an array of 10 integers, "b" is a 20 by 30 | |
4381 matrix of integers, "c" is a simple integer variable, and "x" is a | |
4382 three-dimensional array of 12-character strings. | |
4383 </para> | |
4384 <para> | |
4385 Arrays can be any atomic or user-defined type. By declaring arrays of | |
4386 user-defined types, structures of arbitrary complexity and shape can | |
4387 be generated. | |
4388 Here's an example declaration that generates a doubly-linked list | |
4389 of character strings. Each element of the array consists of the string | |
4390 containing the data and two integer "pointers". | |
4391 | |
4392 <informalexample> | |
4393 <programlisting> | |
4394 TYPE link_pointers = fwd,back: INTEGER | |
4395 TYPE element = data: STRING[64]; ptr: link_pointers | |
4396 DIM list(100): element | |
4397 | |
4398 (* make a circular list *) | |
4399 BASE0 | |
4400 FOR index := 0 TO 99 | |
4401 list(index).data := "secret message " + STR$(index) | |
4402 list(index).ptr.fwd := index+1 | |
649 | 4403 list(index).ptr.back := index-1 |
24 | 4404 NEXT index |
4405 (* fix the ends *) | |
4406 list(0).ptr.back := 99 | |
4407 list(99).ptr.fwd := 0 | |
4408 | |
4409 (* Print the list *) | |
4410 index=0 | |
4411 REPEAT | |
4412 PRINT list(index).data | |
4413 index := list(index).ptr.fwd | |
4414 UNTIL index=0 | |
4415 END | |
4416 </programlisting> | |
4417 </informalexample> | |
4418 </para></sect3></sect2> | |
4419 <sect2><title>PARAM Statement</title> | |
4420 <para> | |
4421 Syntax: Same as DIM statement | |
4422 </para> | |
4423 <para> | |
4424 PARAM is identical to the DIM statement, but it does not create | |
4425 variable storage. Instead, it describes what parameters the "called" procedure | |
4426 expects to receive from the "calling" procedure. | |
4427 </para> | |
4428 <para> | |
4429 The programmer must insure that the total size of each | |
4430 parameter (as evaluated by the RUN statement in the calling procedure) | |
4431 conforms to the | |
4432 amount of storage expected for each parameter in the called procedure as | |
4433 specified by the PARAM statement. | |
4434 &b09; checks the size of each parameter (to prevent | |
4435 accidental access to storage other than the parameter) | |
1094 | 4436 but <emphasis>does not check type</emphasis>. However, in most cases the programmer |
24 | 4437 should ensure that the parameters evaluated in the RUN statement and |
4438 sent to the called procedure agree exactly with the PARAM statement | |
4439 specification with respect to: the number of parameters, their order, size, | |
4440 shape, and type. | |
4441 </para> | |
4442 <para> | |
4443 Because type-checking is not performed, if you really know what you are | |
4444 doing you can make the parameter passing operation perform useful but | |
4445 normally illegal type conversions of identically-sized data structures. For | |
4446 example, passing a string of 80 characters to a procedure expecting a | |
4447 BYTE array having 80 elements assigns the numeric value of each | |
4448 character in the string to the corresponding element of the byte array. | |
4449 </para></sect2> | |
4450 <sect2><title>TYPE Statement</title> | |
4451 <para> | |
4452 Syntax: | |
4453 | |
4454 <cmdsynopsis> | |
4455 <command>TYPE <type decl> {; <type decl>}</command> | |
649 | 4456 <sbr/> |
24 | 4457 <command><type decl> := <field name> . <decl> : <type>}</command> |
649 | 4458 <sbr/> |
24 | 4459 <command><decl> := <name> [, <subscript> ]</command> |
649 | 4460 <sbr/> |
24 | 4461 <command><subscript> := ( <const> [,<const> [,<const>]] )</command> |
649 | 4462 <sbr/> |
24 | 4463 <command><type> := BYTE | INTEGER | REAL | BOOLEAN | |
4464 STRING | STRING [<max len>] | <user defined></command> | |
649 | 4465 <sbr/> |
24 | 4466 <command><user defined> := user defined by TYPE statement</command> |
4467 </cmdsynopsis> | |
4468 | |
4469 This statement is used to define new data types. New data types are | |
4470 defined as a "vector" (a one-dimensional array) of previously | |
4471 defined types. This structure differs from an array in that the | |
4472 various elements may be of different types, and the elements are | |
4473 accessed by field name instead of an array index. | |
4474 Here's an example: | |
4475 <informalexample> | |
4476 <programlisting> | |
4477 TYPE cust_recd := name,address(3):STRING; balance | |
4478 </programlisting> | |
4479 </informalexample> | |
4480 | |
4481 This example creates a new data type called "cust_recd" which has three | |
4482 named fields: a field called "name" which is a string, a field | |
4483 called "address" which is a vector of three strings; and | |
4484 a field called "balance" which is a (default) REAL value | |
4485 </para> | |
4486 <para> | |
4487 The TYPE statement can include previously-defined types so very | |
4488 complex non-rectangular data structures can be created such as | |
4489 lists, trees, etc. This statement does not create any variable storage | |
4490 itself; the storage is created when the newly-defined type is used in a | |
4491 DIM statement. | |
4492 The example show below creates an array having 250 elements of type | |
4493 "cust_recd" that was defined above: | |
4494 | |
4495 <programlisting> | |
4496 DIM customer_file(250):cust_recd | |
4497 </programlisting> | |
4498 To access elements of the array in assignment statements, the field name | |
4499 is used as well as the index: | |
4500 <programlisting> | |
4501 name$ = customer_file(35).name | |
4502 customer_file(N+1).address(3) = "New York, NY" | |
4503 customer_file(X).balance= 125.98 | |
4504 </programlisting> | |
4505 | |
4506 The complex structure allows creation of data types appropriate to | |
4507 the job at hand by providing more natural organization and | |
4508 association of data. Additionally, the position of the desired | |
4509 element is known and defined at compilation-time and need not be | |
4510 calculated at run time, unlike arrays, and can therefore be accessed | |
4511 faster than arrays. | |
4512 </para> | |
4513 </sect2></sect1> | |
4514 </chapter> | |
4515 | |
4516 | |
4517 <chapter> | |
4518 <title>Input and Output Operations</title> | |
4519 | |
4520 | |
4521 <sect1><title>Files and Unified Input/Output</title> | |
4522 <para> | |
4523 A file is a logical concept for a sequence of data which is | |
4524 saved for convenience in use and storage. File data may be pure | |
4525 binary data, textual data (ASCII characters), or any other useful | |
4526 information. Hardware input/output ("I/O") devices used by OS-9 | |
4527 also work like files, so you can generally use any I/O facility | |
4528 regardless of whether you are | |
4529 working with disk files or I/O devices such as printers. This single | |
4530 interface standard for any device and simple communication facilities allow | |
4531 any device to be used with any other device. This concept is known as | |
4532 "unified I/O". Note that | |
4533 unified I/O can benefit routine programming. For example: | |
4534 file operations can be debugged by communicating with a terminal or | |
4535 printer instead of a storage device, and procedures which normally | |
4536 communicate with a terminal can be tested with data coming from and sent | |
4537 to a storage device. | |
4538 </para> | |
4539 <para> | |
4540 &b09; normally works with two types of files: | |
4541 sequential files and random-access files. | |
4542 </para> | |
4543 <para> | |
4544 A sequential file sends or receives (WRITE/READ) textual data only in | |
4545 order. It is not generally possible to start over at the beginning of | |
4546 a sequential file once a number of bytes have been accessed (many I/O | |
4547 devices such as printers are necessarily sequential). A sequential | |
4548 file contains only valid ASCII characters; the READ and WRITE commands | |
4549 perform format conversion similar to that done automatically in INPUT and | |
4550 PRINT commands. A sequential file contains record-delimiter characters | |
4551 (carriage return) which separate the data created by different WRITE | |
4552 operations. Each WRITE command will send a complete sequential-file | |
4553 record, which is an arbitrary number of characters terminated by a | |
4554 carriage return. Each READ reads all characters up to the next carriage | |
4555 return. | |
4556 </para> | |
4557 <para> | |
4558 A random-access file sends and receives (PUT/GET) data in binary form | |
4559 exactly as it is internally represented in &b09;. This minimizes both the | |
4560 time involved in converting the data to and from ASCII representation, | |
4561 as well as reducing the file space required to store the data. It is | |
4562 possible to PUT and GET individual bytes, or a substructure of many | |
4563 bytes (in a complex structure). The GET structure statement merely | |
4564 recovers the number of bytes associated with that type of structure. | |
4565 It is possible to move to a particular byte in a random-access file | |
4566 (using SEEK) and to begin to PUT or GET sequentially from that point (in | |
4567 general, "SEEK #path,0" is equivalent to the REWIND used in some forms | |
4568 of BASIC). Since the random-access file contains no record-separators | |
4569 to indicate the size of particular elements of the file, the programmer | |
4570 should use the SIZE function to determine the size of a single element, | |
4571 then use SEEK to move to the desired element within the file. | |
4572 </para> | |
4573 <para> | |
4574 A new file is made on a storage device by executing CREATE. Once a file | |
4575 exists, the OPEN command is used to notify the operating system to set up | |
4576 a channel to the desired device and return that path number to the &b09; | |
4577 program. This channel number is then used in file-access operations (e.g., | |
4578 READ, WRITE, GET, PUT, SEEK, etc.). When the programmer is finished with | |
4579 the file, it should be terminated by CLOSE to assure that the file system | |
4580 has updated all data back onto magnetic media. | |
4581 </para></sect1> | |
4582 <sect1><title>I/O Paths</title> | |
4583 <para> | |
4584 A "path" is a description of a "channel" through which data flows from a | |
4585 given program outward or from some device inward. In order for data to | |
4586 flow to or from a device, there must be an associated OS-9 device driver | |
4587 — see the OS9 Users Manual. When a path is created, OS-9 returns | |
4588 a unique number to identify the path in subsequent file operations. This | |
4589 "path number" is used by the I/O statements to specify the file to be | |
4590 used. Three path numbers have special meanings because they are "standard | |
4591 I/O paths" representing &b09;'s interactive input/output (your terminal). | |
4592 These are automatically "opened" for you and should not be closed except | |
4593 in very special circumstances. The standard I/O path numbers are: | |
4594 <informaltable frame="none"> | |
4595 <tgroup cols="2"> | |
649 | 4596 <colspec colwidth="0.3in"/> |
24 | 4597 <tbody> |
4598 <row> | |
4599 <entry>0</entry> | |
4600 <entry>Standard Input (Keyboard)</entry> | |
4601 </row> | |
4602 <row> | |
4603 <entry>1</entry> | |
4604 <entry>Standard Output (Display)</entry> | |
4605 </row> | |
4606 <row> | |
4607 <entry>2</entry> | |
4608 <entry>Standard Error/Status (Display)</entry> | |
4609 </row> | |
4610 </tbody> | |
4611 </tgroup> | |
4612 </informaltable> | |
4613 </para> | |
4614 <para> | |
4615 The table below is a summary of the I/O statements within &b09; and their | |
4616 general usage. This reflects typical usage; most statements can be used | |
4617 with any I/O device or file. Sometimes certain statements are used in | |
4618 unusual ways by advanced programmers to achieve certain special effects. | |
4619 <informaltable frame="none"> | |
4620 <tgroup cols="3"> | |
649 | 4621 <colspec colwidth="0.8in"/> |
24 | 4622 <thead> |
4623 <row> | |
4624 <entry>Statement</entry> | |
4625 <entry>Generally Used With</entry> | |
4626 <entry>Data Format (File Type)</entry> | |
4627 </row> | |
4628 </thead> | |
4629 <tbody> | |
4630 <row> | |
4631 <entry>INPUT</entry> | |
4632 <entry>Keyboard (interactive input)</entry> | |
4633 <entry>Text (Sequential)</entry> | |
4634 </row> | |
4635 <row> | |
4636 <entry>PRINT</entry> | |
4637 <entry>Terminals, Printers</entry> | |
4638 <entry>Text (Sequential)</entry> | |
4639 </row> | |
4640 <row> | |
4641 <entry>OPEN</entry> | |
4642 <entry>Disk Files and I/O Devices</entry> | |
4643 <entry>Any</entry> | |
4644 </row> | |
4645 <row> | |
4646 <entry>CREATE</entry> | |
4647 <entry>Disk Files and I/O Devices</entry> | |
4648 <entry>Any</entry> | |
4649 </row> | |
4650 <row> | |
4651 <entry>CLOSE</entry> | |
4652 <entry>Disk Files and I/O Devices</entry> | |
4653 <entry>Any</entry> | |
4654 </row> | |
4655 <row> | |
4656 <entry>DELETE</entry> | |
4657 <entry>Disk Files</entry> | |
4658 <entry>Any</entry> | |
4659 </row> | |
4660 <row> | |
4661 <entry>SEEK</entry> | |
4662 <entry>Disk Files</entry> | |
4663 <entry>Binary (Random)</entry> | |
4664 </row> | |
4665 <row> | |
4666 <entry>READ</entry> | |
4667 <entry>Disk Files</entry> | |
4668 <entry>Text (Sequential)</entry> | |
4669 </row> | |
4670 <row> | |
4671 <entry>WRITE</entry> | |
4672 <entry>Disk Files</entry> | |
4673 <entry>Text (Sequential)</entry> | |
4674 </row> | |
4675 <row> | |
4676 <entry>GET</entry> | |
4677 <entry>Disk Files and I/O Devices</entry> | |
4678 <entry>Binary (Random)</entry> | |
4679 </row> | |
4680 <row> | |
4681 <entry>PUT</entry> | |
4682 <entry>Disk Files and I/O Devices</entry> | |
4683 <entry>Binary (Random)</entry> | |
4684 </row> | |
4685 </tbody> | |
4686 </tgroup> | |
4687 </informaltable> | |
4688 | |
4689 </para> | |
4690 <sect2><title>INPUT Statement</title> | |
4691 <para> | |
4692 Syntax: | |
4693 <cmdsynopsis> | |
4694 <command>INPUT [#<int expr>,] ["<prompt>",] <input list></command> | |
4695 </cmdsynopsis> | |
4696 This statement accepts input during the execution of a program. The | |
4697 input is normally read from the standard input device (terminal) | |
4698 unless an optional path number is given. When the INPUT statement | |
4699 is encountered, program execution is suspended and a "?" prompt is | |
4700 displayed. If the optional prompt string is given, it is displayed | |
4701 instead of the normal "?" prompt. This means that the INPUT statement | |
4702 is really <emphasis>both</emphasis> | |
4703 an input and outout statement. Therefore, if a path other than the | |
4704 default standard input path is used, the path should be open in UPDATE | |
4705 mode. This makes INPUT dangerous if used on disk files, unless you like | |
4706 prompts in your data (use READ). | |
4707 </para> | |
4708 <para> | |
4709 The data entered is assigned in order to the variable names in the order | |
4710 they appear in the input list. The variables can be of any atomic type, | |
4711 and the input data must be of the same (or compatible) type. The line | |
4712 is terminated by a carriage return. There must be at least as many input | |
4713 items given as variables in the input list. The length of the input line | |
4714 cannot exceed 256 characters. | |
4715 </para> | |
4716 <para> | |
4717 If any error occurs (type mismatch, insufficient amount of data, etc.), | |
4718 the message: | |
4719 <screen> | |
649 | 4720 **INPUT ERROR - RETYPE** |
24 | 4721 </screen> |
4722 is displayed, followed by a new prompt. The entire input line must | |
4723 then be reentered. | |
4724 </para> | |
4725 <para> | |
4726 The INPUT statement | |
4727 uses OS-9's line input function (READLN) which performs line | |
4728 editing such as backspace, delete, end-of-file, etc. To perform input | |
4729 WITHOUT editing (i.e., to read pure binary data), use the GET statement. | |
4730 </para> | |
4731 <para> | |
4732 Examples: | |
4733 | |
4734 <informalexample> | |
4735 <programlisting> | |
4736 INPUT number,name$,location | |
4737 | |
4738 INPUT #14, "What is your selection", choice | |
4739 | |
4740 INPUT "What's your name? ",name$ | |
4741 </programlisting> | |
4742 </informalexample> | |
4743 Here's how to read a single character (without editing) from the terminal | |
4744 (path #0): | |
4745 <informalexample> | |
4746 <programlisting> | |
4747 DIM char:STRING[1] | |
4748 GET #0,char | |
4749 </programlisting> | |
4750 </informalexample> | |
4751 For a function to test if data is available from the keyboard without | |
4752 "hanging" the program, see the "INKEY" assembly language program included | |
1094 | 4753 in <xref linkend="sample-programs"/>. |
24 | 4754 </para></sect2> |
4755 <sect2><title>PRINT Statement</title> | |
4756 <para> | |
4757 Syntax: | |
4758 <cmdsynopsis> | |
4759 <command>PRINT <output list></command> | |
649 | 4760 <sbr/> |
24 | 4761 <command>PRINT #<int expr>, <output list></command> |
649 | 4762 <sbr/> |
24 | 4763 <command>PRINT USING <str expr>, <output list></command> |
649 | 4764 <sbr/> |
24 | 4765 <command>PRINT #<int expr>, USING <str expr>, <output list></command> |
4766 </cmdsynopsis> | |
4767 This statement outputs the values of the items given in the output list | |
4768 to the standard output device (path #1, the terminal) unless another | |
4769 path number is specified. | |
4770 </para> | |
4771 <para> | |
4772 The output list consists of one or more items separated by commas or | |
4773 semicolon characters. Each item can be a constant, variable, or expression | |
4774 of any atomic type. The PRINT statement evaluates each item and converts | |
4775 the result to corresponding ASCII characters which are then displayed. | |
4776 If the separator character following the item is a semicolon, the | |
4777 next item will be displayed without any spacing in between. If a comma | |
4778 is used, spaces are output so the next item starts at the next "tab" | |
4779 zone. The tab zones are 16 characters long starting at the beginning of | |
4780 the line. If the line is terminated by a semicolon, the usual carriage | |
4781 return following the output line is inhibited. | |
4782 </para> | |
4783 <para> | |
4784 The "TAB(expr)" function can be used as an item in the output list, which | |
4785 outputs the correct number of spaces to cause the next item to start | |
4786 in the print column specified by the result of the expression. If the | |
4787 output line is already past the desired tab position, the TAB is ignored. | |
4788 A related function, "POS", can be used in the program to determine | |
4789 the output position at any given time. The output columns are numbered | |
4790 from one to a maximum of 255. The size of &b09;'s output buffer varies | |
4791 according to stack size at the moment. A prectical values is at least | |
4792 512 characters. | |
4793 </para> | |
4794 <para> | |
4795 The PRINT USING form of this statement is described at the end of | |
4796 this chapter. | |
4797 </para> | |
4798 <para> | |
4799 Examples: | |
4800 | |
4801 <informalexample> | |
4802 <programlisting> | |
4803 PRINT value,temp+(n/2.5),location$ | |
4804 | |
4805 PRINT #printer_path,"The result is "; n | |
4806 | |
4807 PRINT "what is " + name$ + "'s age? "; | |
4808 | |
4809 PRINT "index: ";i;TAB(25);"value: ";value | |
4810 | |
4811 PRINT USING "R10.2,X2,R5.3",x,y | |
4812 | |
4813 PRINT #outpath USING fmt$,count,value | |
4814 | |
649 | 4815 (* print an 80-character line of all dashes *) |
24 | 4816 REPEAT |
649 | 4817 PRINT "-"; |
24 | 4818 UNTIL POS >= 80 |
4819 PRINT | |
4820 </programlisting> | |
4821 </informalexample> | |
4822 | |
4823 </para></sect2> | |
4824 <sect2><title>OPEN Statement</title> | |
4825 <para> | |
4826 Syntax: | |
4827 <cmdsynopsis> | |
4828 <command>OPEN #<int var>,"<str expr>" [ : <access mode> ]</command> | |
649 | 4829 <sbr/> |
24 | 4830 <command><access mode> := <mode> ! <mode> + <access mode></command> |
649 | 4831 <sbr/> |
24 | 4832 <command><mode> := READ ! WRITE ! UPDATE ! EXEC ! DIR</command> |
4833 </cmdsynopsis> | |
4834 This statement issues a request to OS-9 to open an I/O path to an existing | |
4835 file or device. The STRING expression is evaluated and passed to OS-9 as | |
4836 the descriptive pathlist.The variable name specified must be DIMensioned | |
4837 as type INTEGER or BYTE and is used "receive" the "path number" assigned | |
4838 to the path by OS-9. This path number is used to reference the specific | |
4839 file/device in subsequent input/output statements. | |
4840 </para> | |
4841 <para> | |
4842 The OPEN statement may also specify the path's desired "access mode" which | |
4843 can be READ, WRITE, UPDATE, EXEC, or DIR. This defines which direction I/O | |
4844 transfers will occur. If no access mode is specified, UPDATE is assumed | |
4845 and both reading and writing are permitted. The DIR mode allows OS-9 | |
1094 | 4846 directory type-files to be accessed but should <emphasis>not</emphasis> be used in combination |
24 | 4847 with WRITE or UPDATE modes. The EXEC mode causes the current execution |
4848 directory to be used instead of the current data directory. Refer to the | |
4849 "OS-9 User's Guide" for more information on how files access modes. | |
4850 </para> | |
4851 <para> | |
4852 Examples: | |
4853 | |
4854 <informalexample> | |
4855 <programlisting> | |
4856 DIM printer_path:BYTE; name:STRING[24] | |
4857 name="/p" | |
4858 OPEN #printer_path,name:WRITE | |
4859 PRINT #printer_path,"Mary had a little lamb" | |
4860 CLOSE #printer_path | |
4861 | |
4862 DIM inpath:INTEGER | |
4863 dev$="/winchester/" | |
4864 INPUT name$ | |
4865 OPEN #inpath,dev$+name$:READ | |
4866 | |
4867 OPEN #path:userdir$:READ+DIR | |
4868 | |
4869 OPEN #path,name$:WRITE+EXEC | |
4870 </programlisting> | |
4871 </informalexample> | |
4872 | |
4873 </para></sect2> | |
4874 <sect2><title>CREATE Statement</title> | |
4875 <para> | |
4876 Syntax: | |
4877 <cmdsynopsis> | |
4878 <command>CREATE #<int var>,"<str expr>" [ : <access mode> ]</command> | |
649 | 4879 <sbr/> |
24 | 4880 <command><access mode> := <mode> ! <mode> + <access mode></command> |
649 | 4881 <sbr/> |
24 | 4882 <command><mode> := WRITE ! UPDATE ! EXEC</command> |
4883 </cmdsynopsis> | |
4884 The CREATE statement is used to create a new file on a multifile mass storage | |
4885 device such as disk or tape. If the device is not of multifile type, | |
4886 this statement works like an "OPEN" statement. | |
4887 The variable name is used to receive the path number assigned by | |
4888 OS-9 and must be of BYTE or INTEGER type. The STRING expression is | |
4889 evaluated and passed to OS-9 to be used as the descriptive pathlist. | |
4890 </para> | |
4891 <para> | |
4892 The "access mode" defines the direction of subsequent I/O transfers and | |
4893 should be either WRITE or UPDATE. "UPDATE" mode allows the file to be | |
4894 either read or written. | |
4895 </para> | |
4896 <para> | |
4897 OS-9 has a single file type that can be accessed both sequentially OR at | |
4898 random. Files are byte-addressed, so no explicit "record" length need be | |
4899 given (see GET and PUT statements). When a new file is created, it has an | |
4900 initial length of zero. Files are expanded automatically by PRINT, WRITE, | |
4901 or PUT statements that write beyond the current "end of file". | |
4902 File size may be set explicitly using the OS9 statement. | |
4903 </para> | |
4904 <para> | |
4905 Examples: | |
4906 <informalexample> | |
4907 <programlisting> | |
4908 CREATE #trans,"transactions":UPDATE | |
4909 | |
4910 CREATE #spool,"/user4/report":WRITE | |
4911 | |
4912 CREATE #outpath,name$:UPDATE+EXEC | |
4913 </programlisting> | |
4914 </informalexample> | |
4915 </para></sect2> | |
4916 <sect2><title>Close Statement</title> | |
4917 <para> | |
4918 Syntax: | |
4919 <cmdsynopsis> | |
4920 <command>CLOSE #<int expr> {,#<int expr>}</command> | |
4921 </cmdsynopsis> | |
4922 The CLOSE statement notifies OS-9 that one or more I/O paths are no longer | |
4923 needed. The paths are specified by their number(s). If the path closed | |
4924 used a non-sharable device (such as a printer), the device is released | |
4925 and can be assigned to another user. The path must have been previously | |
4926 established by means of the OPEN or CREATE statements. | |
4927 </para> | |
4928 <para> | |
4929 Paths #0, #1, and #2 (the standard I/O paths) should never be closed | |
4930 unless the user immediately opens a new path to take over the Standard | |
4931 Path number. | |
4932 </para> | |
4933 <para> | |
4934 Examples: | |
4935 | |
4936 <informalexample> | |
4937 <programlisting> | |
4938 CLOSE #master,#trans,#new_master | |
4939 | |
4940 CLOSE #5,#6,#9 | |
4941 | |
4942 CLOSE #1 \(* closes standard output path *) | |
4943 OPEN #path,"/T1" \(* Permanently redirects Std Output *) | |
4944 | |
4945 CLOSE #0 \(* closes standard input path *) | |
4946 OPEN #path,"/TERM" \(* Permanently redirects Std Input *) | |
4947 </programlisting> | |
4948 </informalexample> | |
4949 </para></sect2> | |
4950 <sect2><title>DELETE Statement</title> | |
4951 <para> | |
4952 Syntax: | |
4953 <cmdsynopsis> | |
4954 <command>DELETE <str expr></command> | |
4955 </cmdsynopsis> | |
4956 This statement is used to delete a mass storage file. The file's name | |
4957 is removed from the directory and all its storage is deallocated, so any | |
4958 data on the file is permanently lost. The string expression is evaluated | |
4959 and passed to OS-9 as the descriptive pathlist of the file. | |
4960 </para> | |
4961 <para> | |
4962 The user must have write permission for the file to be deleted. See | |
4963 the "OS-9 User's Guide" for more information. | |
4964 </para> | |
4965 <para> | |
4966 Examples: | |
4967 | |
4968 <informalexample> | |
4969 <programlisting> | |
4970 DELETE "/D0/old_junk" | |
4971 | |
4972 name$="file55" | |
4973 DELETE name$ | |
4974 DELETE "/D2/"+name$ (deletes file named "/D2/file55") | |
4975 </programlisting> | |
4976 </informalexample> | |
4977 | |
4978 | |
4979 </para></sect2> | |
4980 <sect2><title>SEEK Statement</title> | |
4981 <para> | |
4982 Syntax: | |
4983 <cmdsynopsis> | |
4984 <command>SEEK #<int expr num>,<real expr></command> | |
4985 </cmdsynopsis> | |
4986 SEEK changes the file pointer address of a mass storage file, | |
4987 which is the address of the next data byte(s) that are to be read or | |
4988 written next. Therefore, this statement is essential for random access | |
4989 of data on files using the GET and PUT statements. | |
4990 </para> | |
4991 <para> | |
4992 The first expression specifies the path number of | |
4993 the file and must evaluate to a byte value. The second expression specifies | |
4994 the desired file pointer address, and must evaluate to a REAL | |
4995 value in the range 0 <= result <= 2,147,483,648. Any fractional | |
4996 part of the result is truncated. Of course, the actual maximum file size | |
4997 depends on the capacity of the device. | |
4998 </para> | |
4999 <para> | |
5000 Although SEEK is normally used with random-access files, it can be used | |
5001 to "rewind" sequential files. For example: | |
5002 | |
5003 <programlisting> | |
5004 SEEK #path,0 | |
5005 </programlisting> | |
5006 is the same as a "rewind" or "restore" function. This is the only form of | |
5007 the SEEK statement that is generally useful for files accessed by READ | |
5008 and WRITE statements. These statements use variable-length records, so | |
5009 it is difficult to know the address of any particular record in the file. | |
5010 </para> | |
5011 <para> | |
5012 Examples: | |
5013 | |
5014 <informalexample> | |
5015 <programlisting> | |
5016 SEEK #fileone,filptr*2 | |
5017 | |
5018 SEEK #outfile,208894 | |
5019 | |
649 | 5020 SEEK #inventory,(part_num - 1) * SIZE(inv_rcd) |
24 | 5021 </programlisting> |
5022 </informalexample> | |
5023 | |
5024 </para></sect2> | |
5025 <sect2><title>WRITE Statement</title> | |
5026 <para> | |
5027 Syntax: | |
5028 <cmdsynopsis> | |
5029 <command>WRITE #<int expr>,<output list></command> | |
5030 </cmdsynopsis> | |
5031 This statement writes data in ASCII character format on a file/device. The | |
5032 first expression specifies the number of a path that was previously | |
5033 opened by a OPEN or CREATE statement in WRITE or UPDATE mode. | |
5034 </para> | |
5035 <para> | |
5036 The output list consists of one or more expressions separated by commas. | |
5037 Each expression can evaluate to any expression type. The result is then | |
5038 converted to an ASCII character string and written on the specified path | |
5039 beginning at the present file pointer which is updated as data is written. | |
5040 </para> | |
5041 <para> | |
5042 If the output list has more than one item, ASCII null characters ($00) | |
5043 are written between each output string. The last item is followed by a | |
5044 carriage return character. | |
5045 </para> | |
5046 <para> | |
5047 Note that this statement creates variable-length ASCII records. | |
5048 </para> | |
5049 <para> | |
5050 Examples: | |
5051 | |
5052 <informalexample> | |
5053 <programlisting> | |
5054 WRITE #outpath,cat,dog,mouse | |
5055 | |
5056 WRITE #xfile,LEFT$(A$,n),count/2 | |
5057 </programlisting> | |
5058 </informalexample> | |
5059 </para></sect2> | |
5060 <sect2><title>READ Statement</title> | |
5061 <para> | |
5062 Syntax: | |
5063 <cmdsynopsis> | |
5064 <command>READ #<int expr num>,<input list></command> | |
5065 </cmdsynopsis> | |
5066 This statement causes input data in ASCII character format to be read | |
5067 from a file or device. The first expression specifies a path number. | |
5068 The path number which must have been previously opened by an OPEN or CREATE | |
5069 statement in READ or UPDATE access mode (except the standard input path #0). | |
5070 Data is read starting at the path's current file pointer address which | |
5071 is updated as data is read. | |
5072 </para> | |
5073 <para> | |
5074 This statement calls OS-9 to read a variable length ASCII | |
5075 record. Individual data items within the record are converted to &b09;'s | |
5076 internal binary format. These results are assigned in order to the | |
5077 variables given in the input list. The input data must match the | |
5078 number and type of the variables in the input list. | |
5079 </para> | |
5080 <para> | |
5081 The individual data items in the input record are separated by ASCII | |
5082 null characters. Numeric items can also be delimited by commas or space | |
5083 characters. The input record is terminated by a carriage return character. | |
5084 </para> | |
5085 <para> | |
5086 Examples: | |
5087 | |
5088 <informalexample> | |
5089 <programlisting> | |
5090 READ #inpath,name$,address$,city$,state$,zip | |
5091 | |
5092 PRINT #1,"height,weight? " | |
5093 READ #0,height,weight | |
5094 </programlisting> | |
5095 </informalexample> | |
5096 | |
5097 <note> | |
5098 <para> | |
5099 READ is also used to read lists of expressions in the program. | |
5100 See the DATA statement section for details. | |
5101 </para> | |
5102 </note> | |
5103 </para></sect2> | |
5104 <sect2><title>GET/PUT Statement</title> | |
5105 <para> | |
5106 Syntax: | |
5107 <cmdsynopsis> | |
5108 <command>GET #<expr>,<struct name></command> | |
649 | 5109 <sbr/> |
24 | 5110 <command>PUT #<expr>,<struct name></command> |
5111 </cmdsynopsis> | |
5112 The GET and PUT statements read and write fixed-size binary data records | |
5113 to files or devices. These are the primary I/O statements | |
5114 used for random access input and output. | |
5115 </para> | |
5116 <para> | |
5117 The first expression is evaluated and used as the number of the | |
5118 I/O path which must have previously been opened by an OPEN or CREATE | |
5119 statement. Paths used by PUT statements must have been opened in WRITE | |
5120 or UPDATE access modes, and paths used by GET statements must be in READ | |
5121 or UPDATE mode. | |
5122 </para> | |
5123 <para> | |
5124 The statement uses exactly one name which can be the name of a variable, | |
5125 array, or complex data structure. Data is written from, or read into, the | |
5126 variable or structure named. The data is transferred in &b09;'s internal | |
5127 binary format without conversion which affords very high throughput | |
5128 compared to READ and WRITE statements. Data is transferred beginning | |
5129 at the current position of the path's file pointer (see SEEK statement) | |
5130 which is automatically updated. | |
5131 </para> | |
5132 <para> | |
5133 OS-9's file system does not inherently impose record structures on | |
5134 random-access files. All files are considered to be continuous sequences of | |
5135 addressable binary bytes. A byte or group of bytes located anywhere in the | |
5136 file can be read or written in any order. Therefore the | |
5137 <emphasis>programmer</emphasis> is free to use the basic file access | |
5138 system to create any record structure desired. | |
5139 </para> | |
5140 <para> | |
5141 Record I/O in &b09; is associated with data structures defined by DIM | |
5142 and TYPE statements. The GET and PUT statements write entire data | |
5143 structures or parts of data structures. A PUT statement, for example, | |
5144 can write a simple variable, an entire array, or a complex data structure | |
5145 in one operation. To illustrate how this works, here is an example | |
5146 based on a simple inventory system that requires a random access file | |
5147 having 100 records. Each record must include the following information: | |
5148 the name of the item (a 25-byte character string), the item's list price | |
5149 and cost (both real numbers), and the quantity on hand (an integer). | |
5150 </para> | |
5151 <para> | |
5152 First it is necesary to use the TYPE statement to define a new | |
5153 data type that describes such a record. For example: | |
5154 <informalexample> | |
5155 <programlisting> | |
5156 TYPE inv_item=name:STRING[25];list,cost:REAL;qty:INTEGER | |
5157 </programlisting> | |
5158 </informalexample> | |
5159 This statement describes a new record type called "inv_item" but does not | |
5160 cause variable storage to be assigned for it. The next step is to create | |
5161 two data structures: an array of 100 "records" of type "inv_item" to be called | |
5162 "inv_array" and a single working record called "work_rec": | |
5163 <programlisting> | |
5164 DIM inv_array(100):inv_item | |
5165 DIM work_rec:inv_item | |
5166 </programlisting> | |
5167 You can manually count the number of bytes assigned for each type to | |
5168 calculate the total size of each record. Sometimes these can become | |
5169 complicated and error-prone. Also, any change in a TYPE definition | |
5170 could require recalculation. Fortunately, &b09; has a built-in | |
5171 function: | |
5172 | |
5173 <programlisting> | |
5174 SIZE(<name>) | |
5175 </programlisting> | |
5176 that returns the number of bytes assigned to any variable, array, or | |
5177 complex data structure. In our example, SIZE(work_rec) will return the number | |
5178 37, and SIZE(inv_array) will return 3700. The size function is often | |
5179 used in conjunction with the SEEK statement to position a file pointer | |
5180 to a specific record's address. | |
5181 </para> | |
5182 <para> | |
5183 The procedure below creates a file called "inventory" and initializes it | |
5184 with zeroes and nulls: | |
5185 | |
5186 <programlisting> | |
5187 PROCEDURE makefile | |
5188 TYPE inv_item = name:STRING[25]; list,cost:REAL; qty:INTEGER | |
5189 DIM inv_array(100):inv_item | |
5190 DIM work_rec:inv_item | |
5191 DIM path:byte | |
5192 CREATE #path,"inventory" | |
5193 work_rec.name = "" | |
5194 work_rec.list := 0. | |
5195 work_rec.cost := 0. | |
5196 work_rec.qty := 0 | |
5197 FOR n = 1 TO 100 | |
5198 PUT #path,work_rec | |
5199 NEXT n | |
5200 END | |
5201 </programlisting> | |
5202 | |
5203 Notice that the assignment statements referenced each named "field" of | |
5204 work_rec by name, but PUT referenced the record as a whole. | |
5205 </para> | |
5206 <para> | |
5207 The subroutine below asks for a record number, then asks for data, and | |
5208 writes it in the file at the specified record: | |
5209 | |
5210 <programlisting> | |
5211 INPUT "Record number ?",recnum | |
5212 INPUT "Item name? ",work_rec.name | |
5213 INPUT "List price? ",work_rec.list | |
5214 INPUT "Cost price? ",work_rec.cost | |
5215 INPUT "Quantity? ",work_rec.qty | |
649 | 5216 SEEK #path, (recnum - 1) * SIZE(work_rec) |
24 | 5217 PUT #path,work_rec |
5218 </programlisting> | |
5219 This routine below uses a loop to read the entire file into the array | |
5220 "inv_array": | |
5221 | |
5222 <programlisting> | |
5223 SEEK #path,0 \ (* "rewind" the file *) | |
5224 FOR k = 1 TO 100 | |
5225 GET #path,inv_array(k) | |
5226 NEXT k | |
5227 </programlisting> | |
5228 | |
5229 Because ENTIRE STRUCTURES can be read, we can eliminate the FOR/NEXT | |
5230 loop and do exactly the same thing by: | |
5231 | |
5232 <programlisting> | |
5233 SEEK #path,0 | |
5234 GET #path,inv_array | |
5235 </programlisting> | |
5236 | |
5237 The above example is a very simple case, but it illustrates the combined | |
5238 power of &b09; complex data structures and the random access I/O | |
5239 statements. When fully exploited, this system has the following important | |
5240 characteristics: | |
5241 <orderedlist numeration="arabic"> | |
5242 <listitem> | |
5243 <para> | |
5244 It is self-documenting. You can clearly see what a program does because | |
5245 structures have descriptive, named sub-structures. | |
5246 </para> | |
5247 </listitem> | |
5248 | |
5249 <listitem> | |
5250 <para> | |
5251 It is extremely fast. | |
5252 </para> | |
5253 </listitem> | |
5254 | |
5255 <listitem> | |
5256 <para> | |
5257 Programs are simplified and require fewer statements to perform I/O | |
5258 functions than in other BASICs. | |
5259 </para> | |
5260 </listitem> | |
5261 | |
5262 <listitem> | |
5263 <para> | |
5264 It is versatile. By creating appropriate data structures you can read | |
5265 or write almost any kind of data in any file, including files created by | |
5266 other programs or languages. | |
5267 </para> | |
5268 </listitem> | |
5269 </orderedlist> | |
5270 | |
5271 These advantages are possible because a single GET or PUT statement can | |
5272 move any amount of data, organized any way you want. | |
5273 </para></sect2></sect1> | |
5274 <sect1><title>Internal Data Statements</title> | |
5275 <sect2><title>DATA/READ/RESTORE Statements</title> | |
5276 <para> | |
5277 Syntax: | |
5278 <cmdsynopsis> | |
5279 <command>READ <input list></command> | |
649 | 5280 <sbr/> |
24 | 5281 <command>DATA <expr> , { <expr> }</command> |
649 | 5282 <sbr/> |
24 | 5283 <command>RESTORE [ <line number> ]</command> |
5284 </cmdsynopsis> | |
5285 These statements provide an efficient way to build constant tables | |
5286 within a program. DATA statements provide values, the READ statement | |
5287 assign the values to variables, and RESTORE statements can be used to | |
5288 set which data statement is to be read next. | |
5289 </para> | |
5290 <para> | |
5291 The DATA statements have one or more expressions separated by commas. | |
5292 They can be located anywhere in a program. The expressions are evaluated | |
5293 each time the data statements are read and can evaluate to any type. | |
5294 Here are some examples: | |
5295 <informalexample> | |
5296 <programlisting> | |
5297 DATA 1.1,1.5,9999,"CAT","DOG" | |
5298 DATA SIN(temp/25), COS(temp*PI) | |
5299 DATA TRUE,FALSE,TRUE,TRUE,FALSE | |
5300 </programlisting> | |
5301 </informalexample> | |
5302 </para> | |
5303 <para> | |
5304 The READ statement has a list of one or more variable names. When | |
5305 executed, it gets "input" by evaluating the current expression in the | |
5306 current data statement. The result must match the type of the variable. When | |
5307 all the expressions in a DATA statement have been evaluated, the next | |
5308 DATA statement (in sequential order) is used. If there are no more DATA | |
5309 statements following, processing "wraps around" to the first data statement | |
5310 in the program. | |
5311 </para> | |
5312 <para> | |
5313 The RESTORE statement used without a line number causes the first DATA | |
5314 statement in the program to be used next. If it is used with a line | |
5315 number, the data statement having that line number is used next. | |
5316 </para> | |
5317 <para> | |
5318 Examples: | |
5319 <informalexample> | |
5320 <programlisting> | |
5321 DATA 1,2,3,4 | |
5322 DATA 5,6,7,8 | |
5323 100 DATA 9,10,11,12 | |
5324 FOR N := 1 TO X | |
5325 READ ARRAY(N) | |
5326 NEXT N | |
5327 RESTORE 100 | |
5328 READ A,B,C,D | |
5329 </programlisting> | |
5330 </informalexample> | |
5331 </para></sect2></sect1> | |
5332 <sect1><title>Formatted Output: The Print Using Statement</title> | |
5333 <para> | |
5334 &b09; has a powerful output editing capability useful for report generation | |
5335 and other applications where formatted output is required. The | |
5336 output editing uses the PRINT USING statement which has the following | |
5337 syntax: | |
5338 <cmdsynopsis> | |
5339 <command>PRINT [<expr#>,] USING <str expr> , <output list></command> | |
5340 </cmdsynopsis> | |
5341 The optional path number expression can be used to specify the path | |
5342 number of any output file or device. If it is omitted, the output is | |
5343 written to the standard output path (usually the terminal). | |
5344 </para> | |
5345 <para> | |
5346 The string expression is evaluated and used as a "format specification" | |
5347 which contains specific formatting directives for each item in the "output | |
5348 list". The items in the output list can be constants, variables, or | |
1094 | 5349 expressions of any atomic type. <emphasis>Blanks are not allowed in format strings!</emphasis> |
24 | 5350 As each output item is processed, it is matched up with a specification |
5351 in the format list. The type of each expression result must be compatible | |
5352 with the corresponding format specification. If there are fewer format | |
5353 specifications than items in the output list, the format specification | |
5354 list is repeated again from its beginning as many times as necessary. | |
5355 </para> | |
5356 <para> | |
5357 A format string has one or more format specifications which are separated | |
5358 by commas. There are two kinds of specifications: ones that control | |
5359 output editing of an item from the output list, and ones that cause an | |
5360 output function by themselves (such as tabbing and spacing). There are | |
5361 six basic output editing directives. Each has a corresponding one-letter | |
5362 identifier: | |
5363 | |
5364 <informaltable frame="none"> | |
5365 <tgroup cols="2"> | |
649 | 5366 <colspec colwidth="0.6in"/> |
24 | 5367 <tbody> |
5368 <row> | |
5369 <entry>R</entry> | |
5370 <entry>real format</entry> | |
5371 </row> | |
5372 <row> | |
5373 <entry>E</entry> | |
5374 <entry>exponential format</entry> | |
5375 </row> | |
5376 <row> | |
5377 <entry>I</entry> | |
5378 <entry>integer format</entry> | |
5379 </row> | |
5380 <row> | |
5381 <entry>H</entry> | |
5382 <entry>hexadecimal format</entry> | |
5383 </row> | |
5384 <row> | |
5385 <entry>S</entry> | |
5386 <entry>string format</entry> | |
5387 </row> | |
5388 <row> | |
5389 <entry>B</entry> | |
5390 <entry>boolean format</entry> | |
5391 </row> | |
5392 </tbody> | |
5393 </tgroup> | |
5394 </informaltable> | |
5395 The identifier letter is followed by a constant number called the "field | |
5396 width". This number indicates the exact number of print columns the | |
1094 | 5397 output is to occupy and must allow for the data <emphasis>and</emphasis> "overhead" character |
24 | 5398 positions such as sign characters, decimal points, exponents, etc. |
5399 Some formats have additional mandatory or optional parameters that | |
5400 control subfields or select editing options. One of these options is | |
5401 "justification" which specifies whether the output is to "line up" on | |
5402 the left, right side, or center of the output field. Fields are commonly | |
5403 right-justified in reports because it arranges them into neat columns | |
5404 with decimal points aligned in the same position. | |
5405 </para> | |
5406 <para> | |
5407 The abbreviations and symbols used in the syntax specifications are: | |
5408 | |
5409 <informaltable frame="none"> | |
5410 <tgroup cols="3"> | |
649 | 5411 <colspec colwidth="0.4in"/> |
24 | 5412 <tbody> |
5413 <row> | |
5414 <entry>w</entry> | |
5415 <entry>Total field width</entry> | |
5416 <entry>1 <= w <= 255</entry> | |
5417 </row> | |
5418 <row> | |
5419 <entry>f</entry> | |
5420 <entry>Fraction field</entry> | |
5421 <entry>1 <= w <= 9</entry> | |
5422 </row> | |
5423 <row> | |
5424 <entry>j</entry> | |
5425 <entry>OPTIONAL justification</entry> | |
5426 <entry>< (left) > (right) ^ (center)</entry> | |
5427 </row> | |
5428 </tbody> | |
5429 </tgroup> | |
5430 </informaltable> | |
5431 | |
5432 </para> | |
5433 <sect2><title>Real Format</title> | |
5434 <para> | |
5435 Syntax: | |
5436 <cmdsynopsis> | |
5437 <command>Rw.fj</command> | |
5438 </cmdsynopsis> | |
5439 This format can be used for numbers of types REAL, INTEGER, or | |
5440 BYTE. The total field width specification must include two overhead | |
5441 positions for the sign and decimal point. The "f" specifies how many | |
5442 fractional digits to the right of the decimal point are to be | |
5443 displayed. If the number has more significant digits than the field | |
5444 allows for, the undisplayed places are used to round the displayed digits. For | |
5445 example: | |
5446 | |
5447 <programlisting> | |
5448 PRINT USING "R8.2", 12.349 gives 12.35 | |
5449 </programlisting> | |
5450 | |
5451 The justification modes are: | |
5452 | |
5453 <informaltable frame="none"> | |
5454 <tgroup cols="2"> | |
649 | 5455 <colspec colwidth="0.3in"/> |
24 | 5456 <tbody> |
5457 <row> | |
5458 <entry><</entry> | |
5459 <entry>Left justify with leading sign and trailing spaces. (default if | |
5460 justification mode omitted)</entry> | |
5461 </row> | |
5462 <row> | |
5463 <entry>></entry> | |
5464 <entry>right justify with leading spaces and sign.</entry> | |
5465 </row> | |
5466 <row> | |
5467 <entry>^</entry> | |
5468 <entry>right justify with leading spaces and trailing sign | |
5469 (financial format)</entry> | |
5470 </row> | |
5471 </tbody> | |
5472 </tgroup> | |
5473 </informaltable> | |
5474 | |
5475 | |
5476 Examples: | |
5477 | |
5478 <informalexample> | |
5479 <programlisting> | |
5480 PRINT USING "R8.2<",5678.123 5678.12 | |
5481 PRINT USING "R8.2>",12.3 12.30 | |
649 | 5482 PRINT USING "R8.2<",-555.9 -555.90 |
5483 PRINT USING "10.2^",-6722.4599 6722.46- | |
24 | 5484 PRINT USING "R5.1","9999999" ***** |
5485 </programlisting> | |
5486 </informalexample> | |
5487 </para></sect2> | |
5488 <sect2><title>Exponential Format</title> | |
5489 <para> | |
5490 Syntax: | |
5491 <cmdsynopsis> | |
5492 <command>Ew.fj</command> | |
5493 </cmdsynopsis> | |
5494 This format prints numbers of types REAL, INTEGER, or BYTE | |
5495 in the scientific notation format using a mantissa and decimal exponent. | |
5496 The syntax and behavior of this format is similar to the REAL format | |
5497 except the "w" field width must allow for eight overhead positions for the | |
5498 mantissa sign, decimal point, and exponent characters. | |
5499 The "<" and ">" justification modes are allowed and work the same way. | |
5500 </para> | |
5501 <para> | |
5502 Example: | |
5503 | |
5504 <informalexample> | |
5505 <programlisting> | |
5506 PRINT USING "E12.3",1234.567 1.235E+03 | |
5507 | |
649 | 5508 PRINT USING "E12.6>",-0.001234 -1.234000E-3 |
24 | 5509 </programlisting> |
5510 </informalexample> | |
5511 | |
5512 </para></sect2> | |
5513 <sect2><title>Integer Format</title> | |
5514 <para> | |
5515 Syntax: | |
5516 <cmdsynopsis> | |
5517 <command>Iwj</command> | |
5518 </cmdsynopsis> | |
5519 This format is used to display numbers of types INTEGER or BYTE, | |
5520 and REAL numbers that are within range for automatic type conversion. | |
5521 The "w" field width must allow for one position overhead for the sign. | |
5522 The justification modes are: | |
5523 | |
5524 <informaltable frame="none"> | |
5525 <tgroup cols="2"> | |
649 | 5526 <colspec colwidth="0.3in"/> |
24 | 5527 <tbody> |
5528 <row> | |
5529 <entry><</entry> | |
5530 <entry>left justify with leading sign and trailing spaces (default)</entry> | |
5531 </row> | |
5532 <row> | |
5533 <entry>></entry> | |
5534 <entry>right justify with leading spaces and sign</entry> | |
5535 </row> | |
5536 <row> | |
5537 <entry>^</entry> | |
5538 <entry>right justify with leading spaces and zeroes</entry> | |
5539 </row> | |
5540 </tbody> | |
5541 </tgroup> | |
5542 </informaltable> | |
5543 Example: | |
5544 <informalexample> | |
5545 <programlisting> | |
5546 PRINT USING "I4<",10 10 | |
5547 | |
5548 PRINT USING "I4>",10 10 | |
5549 | |
5550 PRINT USING "I4^",10 010 | |
5551 </programlisting> | |
5552 </informalexample> | |
5553 | |
5554 | |
5555 </para></sect2> | |
5556 <sect2><title>Hexadecimal Format</title> | |
5557 <para> | |
5558 Syntax: | |
5559 <cmdsynopsis> | |
5560 <command>Hwj</command> | |
5561 </cmdsynopsis> | |
5562 This format can be used to display the internal binary representation | |
5563 of ANY data type, using hexadecimal characters. The "w" field width | |
5564 specification determines the number of hexadecimal characters to | |
5565 output. Justification modes are: | |
5566 | |
5567 <informaltable frame="none"> | |
5568 <tgroup cols="2"> | |
649 | 5569 <colspec colwidth="0.3in"/> |
24 | 5570 <tbody> |
5571 <row> | |
5572 <entry><</entry> | |
5573 <entry>left justify with trailing spaces</entry> | |
5574 </row> | |
5575 <row> | |
5576 <entry>></entry> | |
5577 <entry>right justify, leading spaces</entry> | |
5578 </row> | |
5579 <row> | |
5580 <entry>^</entry> | |
5581 <entry>center justify</entry> | |
5582 </row> | |
5583 </tbody> | |
5584 </tgroup> | |
5585 </informaltable> | |
5586 | |
5587 Because the number of bytes of memory used to represent data varies | |
5588 according to type, the following specification make the most sense for | |
5589 each data type: | |
5590 | |
5591 <informaltable frame="none"> | |
5592 <tgroup cols="2"> | |
649 | 5593 <colspec colwidth="0.5in"/> |
24 | 5594 <tbody> |
5595 <row> | |
5596 <entry>H2</entry> | |
5597 <entry>boolean, byte (one byte)</entry> | |
5598 </row> | |
5599 <row> | |
5600 <entry>H4</entry> | |
5601 <entry>integer (two bytes)</entry> | |
5602 </row> | |
5603 <row> | |
5604 <entry>H10</entry> | |
5605 <entry>real (five bytes)</entry> | |
5606 </row> | |
5607 <row> | |
5608 <entry>Hn*2</entry> | |
5609 <entry>string of length n</entry> | |
5610 </row> | |
5611 </tbody> | |
5612 </tgroup> | |
5613 </informaltable> | |
5614 | |
5615 | |
5616 Examples: | |
5617 | |
5618 <informalexample> | |
5619 <programlisting> | |
5620 PRINT USING "H4",100 00C4 | |
5621 | |
5622 PRINT USING "H4",-1 FFFF | |
5623 | |
5624 PRINT USING "H10",1.5 01D0000000 | |
5625 | |
5626 PRINT USING "H8","ABC" 414243 | |
5627 </programlisting> | |
5628 </informalexample> | |
5629 </para></sect2> | |
5630 <sect2><title>String Format</title> | |
5631 <para> | |
5632 Syntax: | |
5633 <cmdsynopsis> | |
5634 <command>Swj</command> | |
5635 </cmdsynopsis> | |
5636 This format is used to display string data of any length. The "w" field | |
5637 width specifies the total field size. If the string to be displayed is | |
5638 shorter than the field size, it is padded with spaces according to the | |
5639 justification mode. If it is too long, it will be truncated on the right side. | |
5640 The format specifications are: | |
5641 | |
5642 <informaltable frame="none"> | |
5643 <tgroup cols="2"> | |
649 | 5644 <colspec colwidth="0.3in"/> |
24 | 5645 <tbody> |
5646 <row> | |
5647 <entry><</entry> | |
5648 <entry>Left justify (default if mode omitted)</entry> | |
5649 </row> | |
5650 <row> | |
5651 <entry>></entry> | |
5652 <entry>right justify</entry> | |
5653 </row> | |
5654 <row> | |
5655 <entry>^</entry> | |
5656 <entry>Center justify</entry> | |
5657 </row> | |
5658 </tbody> | |
5659 </tgroup> | |
5660 </informaltable> | |
5661 | |
5662 Examples: | |
5663 | |
5664 <informalexample> | |
5665 <programlisting> | |
5666 PRINT USING "S8<","HELLO" HELLO | |
5667 | |
5668 PRINT USING "S8>","HELLO" HELLO | |
5669 | |
5670 PRINT USING "S8^","HELLO" HELLO | |
5671 </programlisting> | |
5672 </informalexample> | |
5673 | |
5674 | |
5675 </para></sect2> | |
5676 <sect2><title>Boolean Format</title> | |
5677 <para> | |
5678 Syntax: | |
5679 <cmdsynopsis> | |
5680 <command>Bwj</command> | |
5681 </cmdsynopsis> | |
5682 This format is used to display boolean data. The result of the boolean | |
5683 expression is converted to the strings "TRUE" and "FALSE". | |
5684 The specification is otherwise identical to the STRING format. | |
5685 </para></sect2> | |
5686 <sect2><title>Control Specifications</title> | |
5687 <para> | |
5688 Control specifications are useful for horizontal formatting of the output | |
5689 line. They are not matched with items in the output list and can be used | |
5690 freely. The control formats are | |
5691 | |
5692 <informaltable frame="none"> | |
5693 <tgroup cols="2"> | |
649 | 5694 <colspec colwidth="0.5in"/> |
24 | 5695 <tbody> |
5696 <row> | |
5697 <entry>Tn</entry> | |
5698 <entry>Tab to column n</entry> | |
5699 </row> | |
5700 <row> | |
5701 <entry>Xn</entry> | |
5702 <entry>Space n columns</entry> | |
5703 </row> | |
5704 <row> | |
5705 <entry>'str'</entry> | |
5706 <entry>Include constant string. The string must not include single or | |
5707 double quotes, backslash or carriage return characters.</entry> | |
5708 </row> | |
5709 </tbody> | |
5710 </tgroup> | |
5711 </informaltable> | |
5712 Warning: Control specifications at the end of the format | |
1094 | 5713 specification list will <emphasis>not</emphasis> be processed if all output items have |
24 | 5714 been exhausted. |
5715 </para> | |
5716 <para> | |
5717 Example | |
5718 | |
5719 <informalexample> | |
5720 <programlisting> | |
5721 PRINT USING "'addr',X2,H4,X2,'data',X2,H2",1000,100 prints | |
5722 | |
5723 addr 03E8 data C4 | |
5724 </programlisting> | |
5725 </informalexample> | |
5726 </para></sect2> | |
5727 <sect2><title>Repeat Groups</title> | |
5728 <para> | |
5729 Many times identical sequences of specifications are repeated in format | |
5730 specification lists. The repeated groups can be enclosed in parentheses and | |
5731 preceded by a repeat count. These repeat groups can be nested. | |
5732 Here are some examples: | |
5733 | |
5734 <informalexample> | |
5735 <programlisting> | |
5736 "2(X2,R10.5)" is the same as "X2,R10.5,X2,R10.5" | |
5737 | |
5738 "2(I2,2(X1,S4))" is the same as "I2,X1,S4,X1,S4,I2,X1,S4,X1,S4" | |
5739 </programlisting> | |
5740 </informalexample> | |
5741 </para> | |
5742 </sect2> | |
5743 </sect1> | |
5744 </chapter> | |
5745 | |
5746 <chapter> | |
5747 <title>Program Optimization</title> | |
5748 <sect1><title>General Execution Performance of &b09;</title> | |
5749 <para> | |
5750 The &b09; multipass compiler produces a compressed and | |
5751 optimized low-level "I-code" for execution. Compared to other BASIC | |
5752 languages program storage is greatly decreased and execution speed | |
5753 is increased. | |
5754 </para> | |
5755 <para> | |
5756 High-level language interpreters have a general reputation for slowness | |
5757 which is probably not deserved. Because the &b09; I-code is kept at | |
5758 a powerful level, a single, fast I-code interpretation will so that | |
5759 there is often result in many MPU instruction cycles (such as execution | |
5760 of floating-point arithmetic operations). Thus, for complex programs | |
5761 there is little performance difference between execution of I-code and | |
5762 straight machine-language instructions. This is generally not the case | |
5763 with traditional BASIC interpreters that have to "compile" from text as | |
5764 they run or even "tokenized" BASICs that must perform table-searching | |
5765 during execution. &b09; I-code instructions that reference variable | |
5766 storage, statements, labels, etc., contain the actual memory addresses | |
5767 so no table searching is ever required. Off course, &b09; fully exploits | |
1015 | 5768 the power of the &CPU;'s instruction set which was optimized for efficient |
24 | 5769 execution of compiler-produced code. |
5770 </para> | |
5771 <para> | |
5772 Because the &b09; I-code is interpreted, a variety of entry-time | |
5773 tests and run-time tests and development aids are available to help | |
5774 in program development; aids not available on most compilers. | |
5775 The editor reports errors immediately when they are entered, | |
5776 the debugger allows debugging using the original program source | |
5777 statements and names, and | |
5778 the I-code interpreter performs run-time error checking of things such | |
5779 as array bound errors, subroutine nesting, arithmetic errors, and other | |
5780 errors that are not detected (and usually crash) native-compiler-generated | |
5781 code. | |
5782 | |
5783 </para></sect1> | |
5784 <sect1><title>Optimum Use of Numeric Data Types</title> | |
5785 <para> | |
5786 Because &b09; includes several different numeric representations | |
5787 (i.e., REAL, INTEGER, and BYTE) and does "automatic type conversions" | |
5788 between them, it is easy to write expressions or loops that take at | |
5789 least ten times longer to execute than is necessary. Some particular | |
649 | 5790 &b09; numeric operators (+, -, *, /) and control structures (FOR..NEXT) |
24 | 5791 include versions for both REAL and INTEGER values. The INTEGER versions, |
5792 off course, are much faster and may have slightly different properties | |
5793 (e.g., INTEGER divides discard any remainder). Type conversions takes | |
5794 time so expressions whose operands and operators are of the same type | |
5795 are more efficient. | |
5796 </para> | |
5797 <para> | |
5798 &b09;'s REAL (floaing point) math package provides excellent | |
5799 performance. A special 40-bit binary floating point representation | |
5800 designed for speed and accuracy was developed especially for &b09; | |
5801 after exhaustive research. The new CORDIC technique is used to derive | |
5802 all transcendental functions (SIN, TAN, LOG, EXP, etc.). This integer | |
5803 shit-and-add technique is faster and more consistantly accurate than | |
5804 the commonly used series-expansion approximations. | |
5805 </para> | |
5806 <para> | |
5807 Nonetheless, INTEGER operations are faster because they generally have | |
1015 | 5808 corresponding &CPU; machine-language instructions. Overall program speed |
24 | 5809 will increase and storage requirements will decrease if INTEGERs are used |
5810 whenever possible. INTEGER arithmetic operations use the same symbols as | |
5811 REAL but &b09; automatically selects the INTEGER operations when working | |
5812 with an integer-value result. Only if all operands of an expression are | |
5813 of types BYTE or INTEGER will the result also be INTEGER. | |
5814 </para> | |
5815 <para> | |
5816 Sometimes, similar or identical results can be obtained in a number | |
5817 of different ways at various execution speeds. For example, if the | |
5818 variable "value" is an integer, then "value*2" will be a fast integer | |
5819 operation. However, if the expression is "value*2.0" the value "2.0" | |
5820 will be represented as a REAL number, and the multiplication will be a | |
5821 REAL multiplication. This will also require that the variable "value" | |
5822 will have to be transformed into a REAL value, and finally the result of | |
5823 the expression will have to be transformed back to an INTEGER value if | |
5824 it is to be assigned to a variable of that type. Thus a single decimal | |
5825 point will slow this particular operation down by about ten times! | |
5826 <table frame="none"> | |
5827 <title>Arithmetic Functions Ranked by Speed</title> | |
5828 <tgroup cols="2"> | |
649 | 5829 <colspec colwidth="3in"/> |
5830 <colspec colwidth="2in"/> | |
24 | 5831 <thead> |
5832 <row> | |
5833 <entry>Operation</entry> | |
5834 <entry>Typical Speed (MPU Cycles)</entry> | |
5835 </row> | |
5836 </thead> | |
5837 <tbody> | |
5838 <row> | |
5839 <entry>INTEGER ADD OR SUBTRACT</entry> | |
5840 <entry>150</entry> | |
5841 </row> | |
5842 <row> | |
5843 <entry>INTEGER MULTIPLY</entry> | |
5844 <entry>240</entry> | |
5845 </row> | |
5846 <row> | |
5847 <entry>REAL ADD</entry> | |
5848 <entry>440</entry> | |
5849 </row> | |
5850 <row> | |
5851 <entry>REAL SUBTRACT</entry> | |
5852 <entry>540</entry> | |
5853 </row> | |
5854 <row> | |
5855 <entry>INTEGER DIVIDE</entry> | |
5856 <entry>960</entry> | |
5857 </row> | |
5858 <row> | |
5859 <entry>REAL MULTIPLY</entry> | |
5860 <entry>990</entry> | |
5861 </row> | |
5862 <row> | |
5863 <entry>REAL DIVIDE</entry> | |
5864 <entry>3870</entry> | |
5865 </row> | |
5866 <row> | |
5867 <entry>REAL SQUARE ROOT</entry> | |
5868 <entry>7360</entry> | |
5869 </row> | |
5870 <row> | |
5871 <entry>REAL LOGARITM OR EXPONENTIAL</entry> | |
5872 <entry>20400</entry> | |
5873 </row> | |
5874 <row> | |
5875 <entry>REAL SINE OR COSINE</entry> | |
5876 <entry>32500</entry> | |
5877 </row> | |
5878 <row> | |
5879 <entry>REAL POWER (^)</entry> | |
5880 <entry>39200</entry> | |
5881 </row> | |
5882 </tbody> | |
5883 </tgroup> | |
5884 </table> | |
5885 </para> | |
5886 <para> | |
5887 This table can be used to deduce some interesting points. For | |
5888 example, "value*2" is not optimum - "value+value" can produce the | |
5889 same result in less time because multiplication takes longer than | |
1094 | 5890 addition. Similarly, "value*value" or "SQ(value)" is <emphasis>much</emphasis> faster |
24 | 5891 than the equivalent "value^2". Another interesting case is "x/2.0". |
5892 The REAL divide will cost 3870 cycles, but REAL multiplcation takes | |
5893 only 990 cycles. The mathematical equivalent to division by a | |
5894 constant is multiplication by the inverse of the constant. | |
5895 Therefore, using "X*0.5" instead is almost four times faster! | |
5896 </para></sect1> | |
5897 | |
5898 <sect1><title>Looping Quickly</title> | |
5899 <para> | |
5900 When &b09; identifies a FOR..NEXT loop structure with an INTEGER | |
5901 loop counter variable, it uses a special integer version of the FOR..NEXT | |
5902 loop. This is much faster than the REAL-type version and is generally | |
5903 preferable. Other kinds of loops also run faster if INTEGER type variables | |
5904 are used for loop counters. | |
5905 </para> | |
5906 <para> | |
1094 | 5907 When writing program loops, remember that statements <emphasis>inside</emphasis> the loop |
5908 may be executed many times for each single execution <emphasis>outside</emphasis> the loop. | |
24 | 5909 Thus, any value which can be computed before entering a loop will increase |
5910 program speed. | |
5911 </para></sect1> | |
5912 <sect1><title>Optimum Use of Arrays and Data Structures</title> | |
5913 <para> | |
5914 &b09; internally uses INTEGER numbers to index arrays and complex data | |
5915 structures. If the program uses subscripts that are REAL type variables | |
5916 or expressions, &b09; has to convert them to INTEGERs before they can | |
5917 be used. This takes additional time, so use INTEGER expressions for | |
5918 subscripts whenever you can. | |
5919 </para> | |
5920 <para> | |
5921 Note that the assignment statement (LET) can copy identically sized data | |
5922 structures. This feature is much faster than copying arrays or structures | |
5923 element-by-element inside a loop. | |
5924 </para></sect1> | |
1094 | 5925 <sect1 id="pack" xreflabel="PACK"><title>The PACK Command</title> |
24 | 5926 <para> |
5927 The PACK command produces a compressed version of a &b09; | |
5928 procedure. Depending on the number of comments, line numbers, etc., | |
5929 programs will execute from 10% to 30% faster after being packed. Minimizing | |
5930 use of line numbers will even speed up procedures that are unPACKed. | |
5931 </para></sect1> | |
5932 <sect1><title>Eliminating Constant Expressions and Sub-Expressions</title> | |
5933 <para> | |
5934 Consider the expression: | |
5935 <programlisting> | |
5936 x = x+SQRT(100)/2 | |
5937 </programlisting> | |
5938 | |
5939 is exactly the same as the expression: | |
5940 <programlisting> | |
5941 x = x+5 | |
5942 </programlisting> | |
5943 The subexpression "SQRT(100)/2" consists of constants only, so its result | |
5944 will not vary regardless of the rest of the program. But every time the | |
5945 program is run, the computer must evaluate it. This time can be significant, | |
5946 especially if the statement is within a loop. Constant expressions or | |
5947 subexpressions should be calculated by the programmer while writing the program | |
5948 (using DEBUG mode or a pocket calculator). | |
5949 </para></sect1> | |
5950 <sect1><title>Fast Input and Output Functions</title> | |
5951 <para> | |
5952 Reading or writing data a line or record at a time is much faster than a | |
5953 character at a time. Also, the GET and PUT statements are much faster | |
5954 than READ and WRITE statements when dealing with disk files. This is | |
5955 because GET and PUT use the exact binary format used internally by | |
5956 &b09;. READ, WRITE, PRINT, and INPUT must perform binary-to-ASCII or | |
5957 ASCII-to-binary conversions which take time. | |
5958 </para></sect1> | |
5959 <sect1><title>Professional Programming Techniques</title> | |
5960 <para> | |
5961 One sure way to make a program faster is to use the most | |
5962 efficient algorithms possible. There are many good programming | |
5963 "cookbooks" that explain useful algorithms with examples in BASIC or PASCAL. | |
5964 Thanks to &b09;'s rich vocabulary you can use algorithms written in either | |
5965 language with little or no adaptation. | |
5966 </para> | |
5967 <para> | |
5968 &b09; also eliminates any possible excuse for not using good | |
5969 structured programming style that produces | |
5970 efficient, reliable, readable, and maintainable software. &b09; generates | |
1015 | 5971 optimized code to be executed by the &CPU; which is the most |
24 | 5972 powerful 8-bit processor in existence at the time of this writing. |
5973 But a computer can only execute what | |
5974 it is told to execute, and no language implementation can make up for an | |
5975 inefficient program. An inefficient program is evidence of a lack of | |
5976 understanding of the problem. The result is likely to be hard to understand | |
5977 and hard to update if program specifications change (they always do). The | |
5978 identification of efficient algorithms and their clear, structured | |
5979 expression is indicative of professionalism in software design and is a goal | |
5980 in itself. | |
5981 </para> | |
5982 </sect1> | |
5983 </chapter> | |
5984 | |
5985 | |
5986 | |
1094 | 5987 <appendix id="sample-programs"> |
24 | 5988 <title>Sample Programs</title> |
5989 <para> | |
5990 <programlisting> | |
5991 PROCEDURE fibonacci | |
5992 REM computes the first ten Fibonacci numbers | |
5993 DIM x,y,i,temp:INTEGER | |
5994 | |
5995 x:=0 \y:=0 | |
5996 FOR i=0 TO 10 | |
5997 temp:=y | |
5998 | |
5999 IF i<>0 THEN | |
6000 y:=y+x | |
6001 ELSE y:=1 | |
6002 ENDIF | |
6003 | |
6004 x:=temp | |
6005 PRINT i,y | |
6006 NEXT i | |
6007 </programlisting> | |
6008 | |
6009 <programlisting> | |
6010 PROCEDURE fractions | |
6011 REM by T.F. Ritter | |
649 | 6012 REM finds increasingly-close rational approximations |
24 | 6013 REM to the desired real value |
6014 DIM m:INTEGER | |
6015 | |
6016 desired:=PI | |
6017 last:=0 | |
6018 | |
6019 FOR m=1 TO 30000 | |
6020 n:=INT(.5+m*desired) | |
6021 trial:=n/m | |
649 | 6022 IF ABS(trial-desired)<ABS(last-desired) THEN |
24 | 6023 PRINT n; "/"; m; " = "; trial, |
649 | 6024 PRINT "difference = "; trial-desired; |
24 | 6025 PRINT |
6026 last:=trial | |
6027 ENDIF | |
6028 NEXT m | |
6029 </programlisting> | |
6030 | |
6031 <programlisting> | |
6032 PROCEDURE prinbi | |
6033 REM by T.F. Ritter | |
6034 REM prints the integer parameter value in binary | |
6035 PARAM n:INTEGER | |
6036 DIM i:INTEGER | |
6037 | |
649 | 6038 FOR i=15 TO 0 STEP -1 |
24 | 6039 IF n<0 THEN |
6040 PRINT "1"; | |
6041 ELSE PRINT "0"; | |
6042 ENDIF | |
6043 n:=n+n | |
6044 NEXT i | |
6045 PRINT | |
6046 | |
6047 END | |
6048 </programlisting> | |
6049 | |
6050 <programlisting> | |
6051 PROCEDURE hanoi | |
6052 REM by T.F. Ritter | |
6053 REM move n discs in Tower of Hanoi game | |
6054 REM See BYTE Magazine, Oct 1980, pg. 279 | |
6055 | |
6056 PARAM n:INTEGER; from,to_,other:STRING[8] | |
6057 | |
6058 IF n=1 THEN | |
6059 PRINT "move #"; n; " from "; from; " to "; to_ | |
6060 ELSE | |
649 | 6061 RUN hanoi(n-1,from,other,to_) |
24 | 6062 PRINT "move #"; n; " from "; from; " to "; to_ |
649 | 6063 RUN hanoi(n-1,other,to_,from) |
24 | 6064 ENDIF |
6065 | |
6066 END | |
6067 </programlisting> | |
6068 | |
6069 <programlisting> | |
6070 PROCEDURE roman | |
6071 REM prints integer parameter as Roman Numeral | |
6072 PARAM x:INTEGER | |
6073 DIM value,svalu,i:INTEGER | |
6074 DIM char,subs:STRING | |
6075 | |
6076 char:="MDCLXVI" | |
6077 subs:="CCXXII " | |
6078 DATA 1000,100,500,100,100,10,50,10,10,1,5,1,1,0 | |
6079 | |
6080 FOR i=1 TO 7 | |
6081 READ value | |
6082 READ svalu | |
6083 | |
6084 WHILE x>=value DO | |
6085 PRINT MID$(char,i,1); | |
649 | 6086 x:=x-value |
24 | 6087 ENDWHILE |
6088 | |
649 | 6089 IF x>=value-svalu THEN |
24 | 6090 PRINT MID$(subs,i,1); MID$(char,i,1); |
649 | 6091 x:=x-value+svalu |
24 | 6092 ENDIF |
6093 | |
6094 NEXT i | |
6095 END | |
6096 </programlisting> | |
6097 | |
6098 <programlisting> | |
6099 PROCEDURE eightqueens | |
649 | 6100 REM originally by N. Wirth; here re-coded from Pascal |
24 | 6101 REM finds the arrangements by which eight queens |
6102 REM can be placed on a chess board without conflict | |
6103 DIM n,k,x(8):INTEGER | |
6104 DIM col(8),up(15),down(15):BOOLEAN | |
6105 BASE 0 | |
6106 | |
6107 (* initialize empty board *) | |
6108 n:=0 | |
6109 FOR k:=0 TO 7 \col(k):=TRUE \NEXT k | |
6110 FOR k:=0 TO 14 \up(k):=TRUE \down(k):=TRUE \NEXT k | |
6111 RUN generate(n,x,col,up,down) | |
6112 END | |
6113 | |
6114 PROCEDURE generate | |
6115 PARAM n,x(8):INTEGER | |
6116 PARAM col(8),up(15),down(15):BOOLEAN | |
6117 DIM h,k:INTEGER \h:=0 | |
6118 BASE 0 | |
6119 | |
6120 REPEAT | |
649 | 6121 IF col(h) AND up(n-h+7) AND down(n+h) THEN |
24 | 6122 (* set queen on square [n,h] *) |
6123 x(n):=h | |
649 | 6124 col(h):=FALSE \up(n-h+7):=FALSE \down(n+h) := FALSE |
24 | 6125 n:=n+1 |
6126 IF n=8 THEN | |
6127 (* board full; print configuration *) | |
6128 FOR k=0 TO 7 | |
6129 PRINT x(k); " "; | |
6130 NEXT k | |
6131 PRINT | |
6132 ELSE RUN generate(n,x,col,up,down) | |
6133 ENDIF | |
6134 | |
6135 (* remove queen from square [n,h] *) | |
649 | 6136 n:=n-1 |
6137 col(h):=TRUE \up(n-h+7):=TRUE \down(n+h):=TRUE | |
24 | 6138 ENDIF |
6139 h:=h+1 | |
6140 UNTIL h=8 | |
6141 END | |
6142 </programlisting> | |
6143 | |
6144 <programlisting> | |
6145 PROCEDURE electric | |
649 | 6146 REM re-programmed from "ELECTRIC" |
24 | 6147 REM by Dwyer and Critchfield |
649 | 6148 REM Basic and the Personal Computer (Addison-Wesley, 1978) |
24 | 6149 REM provides a pictorial representation of the |
6150 REM resultant electrical field around charged points | |
6151 DIM a(10),b(10),c(10) | |
6152 DIM x,y,i,j:INTEGER | |
6153 xscale:=50./78. | |
6154 yscale:=50./32. | |
6155 | |
6156 INPUT "How many charges do you have? ",n | |
649 | 6157 PRINT "The field of view is 0-50,0-50 (x,y)" |
24 | 6158 FOR i=1 TO n |
6159 PRINT "type in the x and y positions of charge "; | |
6160 PRINT i; | |
6161 INPUT a(i),b(i) | |
6162 NEXT i | |
6163 PRINT "type in the size of each charge:" | |
6164 FOR i=1 TO n | |
6165 PRINT "charge "; i; | |
6166 INPUT c(i) | |
6167 NEXT i | |
6168 | |
6169 REM visit each screen position | |
649 | 6170 FOR y=32 TO 0 STEP -1 |
24 | 6171 FOR x=0 TO 78 |
6172 REM compute field strength into v | |
6173 GOSUB 10 | |
6174 z:=v*50. | |
6175 REM map z to valid ASCII in b$ | |
6176 GOSUB 20 | |
6177 REM print char (proportional to field) | |
6178 PRINT b$; | |
6179 NEXT x | |
6180 PRINT | |
6181 NEXT y | |
6182 END | |
6183 | |
6184 10 v=1. | |
6185 FOR i=1 TO n | |
649 | 6186 r:=SQRT(SQ(xscale*x-a(i))+SQ(yscale*y-b(i))) |
24 | 6187 EXITIF r=.0 THEN |
6188 v:=99999. | |
6189 ENDEXIT | |
6190 v:=v+c(i)/r | |
6191 NEXT i | |
6192 RETURN | |
6193 | |
6194 20 IF z<32 THEN b$:=" " | |
6195 ELSE | |
6196 IF z>57 THEN z:=z+8 | |
6197 ENDIF | |
6198 IF z>90 THEN b$:="*" | |
6199 ELSE | |
6200 IF z>INT(z)+.5 THEN b$:=" " | |
6201 ELSE b$:=CHR$(z) | |
6202 ENDIF | |
6203 ENDIF | |
6204 ENDIF | |
6205 RETURN | |
6206 </programlisting> | |
6207 | |
6208 <programlisting> | |
6209 PROCEDURE qsort1 | |
6210 REM quicksort, by T.F. Ritter | |
6211 PARAM bot,top,d(1000):INTEGER | |
6212 DIM n,m:INTEGER; btemp:BOOLEAN | |
6213 | |
6214 n:=bot | |
6215 m:=top | |
6216 | |
6217 LOOP \REM each element gets the once over | |
649 | 6218 REPEAT \REM this is a post-inc instruction |
24 | 6219 btemp:=d(n)<d(top) |
6220 n:=n+1 | |
6221 UNTIL NOT (btemp) | |
649 | 6222 n:=n-1 \REM point at the tested element |
24 | 6223 EXITIF n=m THEN |
6224 ENDEXIT | |
6225 | |
649 | 6226 REPEAT \REM this is a post-dec instruction |
6227 m:=m-1 | |
24 | 6228 UNTIL d(m)<=d(top) OR m=n |
6229 EXITIF n=m THEN | |
6230 ENDEXIT | |
6231 | |
6232 RUN exchange(d(m),d(n)) | |
649 | 6233 n:=n+1 \REM prepare for post-inc |
24 | 6234 EXITIF n=m THEN |
6235 ENDEXIT | |
6236 | |
6237 ENDLOOP | |
6238 | |
6239 IF n<>top THEN | |
6240 IF d(n)<>d(top) THEN | |
6241 RUN exchange(d(n),d(top)) | |
6242 ENDIF | |
6243 ENDIF | |
6244 | |
649 | 6245 IF bot<n-1 THEN |
6246 RUN qsort1(bot,n-1,d) | |
24 | 6247 ENDIF |
6248 IF n+1<top THEN | |
6249 RUN qsort1(n+1,top,d) | |
6250 ENDIF | |
6251 | |
6252 END | |
6253 | |
6254 PROCEDURE exchange | |
6255 PARAM a,b:INTEGER | |
6256 DIM temp:INTEGER | |
6257 | |
6258 temp:=a | |
6259 a:=b | |
6260 b:=temp | |
6261 | |
6262 END | |
6263 | |
6264 PROCEDURE prin | |
6265 PARAM n,m,d(1000):INTEGER | |
6266 DIM i:INTEGER | |
6267 | |
6268 FOR i=n TO m | |
6269 PRINT d(i); | |
6270 NEXT i | |
6271 PRINT | |
6272 | |
6273 END | |
6274 | |
6275 PROCEDURE sortest | |
6276 REM This procedure is used to test Quicksort | |
6277 REM It fills the array "d" with randomly generated | |
6278 REM numbers and sorts them. | |
6279 DIM i,d(1000):INTEGER | |
6280 | |
6281 FOR i=1 TO 1000 | |
6282 d(i):=INT(RND(100)) | |
6283 NEXT i | |
6284 | |
6285 RUN prin(1,1000,d) | |
6286 | |
6287 RUN qsort1(1,1000,d) | |
6288 | |
6289 RUN prin(1,1000,d) | |
6290 | |
6291 END | |
6292 </programlisting> | |
6293 | |
6294 <programlisting> | |
6295 PROCEDURE structst | |
6296 | |
6297 REM example of intermixed array and record structures | |
6298 REM note that structure d contains 200 real elements | |
6299 | |
6300 TYPE a=one(2):REAL | |
6301 TYPE b=two(10):a | |
6302 TYPE c=three(10):b | |
6303 DIM d,e:c | |
6304 | |
6305 FOR i=1 TO 10 | |
6306 FOR j=1 TO 10 | |
6307 FOR k=1 TO 2 | |
6308 PRINT d.three(i).two(j).one(k) | |
6309 d.three(i).two(j).one(k):=0. | |
6310 PRINT e.three(i).two(j).one(k) | |
6311 PRINT | |
6312 NEXT k | |
6313 NEXT j | |
6314 NEXT i | |
6315 | |
6316 REM this is a complete structure assignment | |
6317 e:=d | |
6318 | |
6319 FOR i=1 TO 10 | |
6320 FOR j=1 TO 10 | |
6321 FOR k=1 TO 2 | |
6322 PRINT e.three(i).two(j).one(k); | |
6323 NEXT k | |
6324 PRINT | |
6325 NEXT j | |
6326 NEXT i | |
6327 | |
6328 END | |
6329 </programlisting> | |
6330 | |
6331 <programlisting> | |
6332 PROCEDURE pialook | |
6333 REM display PIA at address (T.F. Ritte) | |
6334 REM made understandable by K. Kaplan | |
6335 | |
6336 DIM address:INTEGER | |
6337 INPUT "Enter PIA address: "; address | |
6338 RUN side(address) | |
6339 RUN side(adress+2) | |
6340 END | |
6341 | |
6342 PROCEDURE side | |
6343 REM display side of PIA at address | |
6344 PARAM address:INTEGER | |
6345 DIM data:INTEGER | |
6346 | |
6347 (* loop until control register input strobe | |
6348 (* flag (bit 7) is set | |
6349 REPEAT \ UNTIL LAND(PEEK(address+1),$80) <> 0 | |
6350 (* now read the data register | |
6351 data := PEEK(address) | |
6352 (* display data in binary | |
6353 RUN prinbyte(data) | |
6354 END | |
6355 | |
6356 PROCEDURE prinbyte | |
6357 REM print a byte as binary | |
6358 PARAM n: INTEGER | |
6359 DIM i: INTEGER | |
6360 | |
6361 n:= n*256 | |
649 | 6362 FOR i = 7 TO 0 STEP -1 |
24 | 6363 IF n < 0 THEN PRINT "1"; |
6364 ELSE PRINT "0"; | |
6365 ENDIF | |
6366 n:= n + 1 | |
6367 NEXT i | |
6368 | |
6369 PRINT | |
6370 END | |
6371 </programlisting> | |
6372 | |
6373 </para> | |
6374 <para> | |
6375 The following procedures demonstrate multiple-precision arithmetic, in | |
6376 this case using five integers to represent a twenty decimal digit number, with | |
6377 four fractional places. | |
6378 </para> | |
6379 <para> | |
6380 | |
6381 | |
6382 <programlisting> | |
6383 PROCEDURE mpadd | |
6384 REM a+b=>c:five_integer_number (T.F. Ritter) | |
6385 PARAM a(5),b(5),c(5):INTEGER | |
6386 DIM i,carry:INTEGER | |
6387 | |
6388 carry:=0 | |
649 | 6389 FOR i=5 TO 1 STEP -1 |
24 | 6390 c(i):=a(i)+b(i)+carry |
6391 IF c(i)>=10000 THEN | |
649 | 6392 c(i):=c(i)-10000 |
24 | 6393 carry:=1 |
6394 ELSE carry:=0 | |
6395 ENDIF | |
6396 NEXT i | |
6397 </programlisting> | |
6398 | |
6399 <programlisting> | |
6400 | |
6401 PROCEDURE mpsub | |
6402 PARAM a(5),b(5),c(5):INTEGER | |
6403 DIM i,borrow:INTEGER | |
6404 | |
6405 borrow:=0 | |
649 | 6406 FOR i=5 TO 1 STEP -1 |
6407 c(i):=a(i)-b(i)-borrow | |
24 | 6408 IF c(i)<0 THEN |
6409 c(i):=c(i)+10000 | |
6410 borrow:=1 | |
6411 ELSE borrow:=0 | |
6412 ENDIF | |
6413 NEXT i | |
6414 </programlisting> | |
6415 | |
6416 <programlisting> | |
6417 | |
6418 PROCEDURE mprint | |
6419 PARAM a(5):INTEGER | |
6420 DIM i:INTEGER; s:STRING | |
6421 | |
6422 FOR i=1 TO 5 | |
6423 IF i=5 THEN PRINT "."; | |
6424 ENDIF | |
6425 s:=STR$(a(i)) | |
6426 PRINT MID$("0000"+s,LEN(s)+1,4); | |
6427 NEXT i | |
6428 </programlisting> | |
6429 | |
6430 <programlisting> | |
6431 PROCEDURE mpinput | |
6432 PARAM a(5):INTEGER | |
6433 DIM n,i:INTEGER | |
6434 | |
649 | 6435 INPUT "input ultra-precision number: ",b$ |
24 | 6436 n:=SUBSTR(".",b$) |
6437 | |
6438 IF n<>0 THEN | |
6439 a(5):=VAL(MID$(b$+"0000",n+1,4)) | |
649 | 6440 b$:=LEFT$(b$,n-1) |
24 | 6441 ELSE a(5):=0 |
6442 ENDIF | |
6443 | |
6444 b$:="00000000000000000000"+b$ | |
6445 n:=1+LEN(b$) | |
649 | 6446 FOR i=4 TO 1 STEP -1 |
6447 n:=n-4 | |
24 | 6448 a(i):=VAL(MID$(b$,n,4)) |
6449 NEXT i | |
6450 </programlisting> | |
6451 | |
6452 <programlisting> | |
6453 | |
6454 PROCEDURE mptoreal | |
6455 PARAM a(5):INTEGER; b:REAL | |
6456 DIM i:INTEGER | |
6457 | |
6458 b:=a(1) | |
6459 FOR i=2 TO 4 | |
6460 b:=b*10000 | |
6461 b:=b+a(i) | |
6462 NEXT i | |
6463 b:=b+a(5)*.0001 | |
6464 </programlisting> | |
6465 | |
6466 <programlisting> | |
6467 PROCEDURE Patch | |
6468 (* Program to examine and patch any byte of a disk file *) | |
6469 (* Written by L. Crane *) | |
6470 DIM buffer(256):BYTE | |
6471 DIM path,offset,modloc:INTEGER; loc:REAL | |
6472 DIM rewrite:STRING | |
6473 INPUT "pathlist? ",rewrite | |
6474 OPEN #path,rewrite:UPDATE | |
6475 LOOP | |
6476 INPUT "sector number? ",rewrite | |
6477 EXITIF rewrite="" THEN ENDEXIT | |
6478 loc=VAL(rewrite)*256 | |
6479 SEEK #path,loc | |
6480 GET #path,buffer | |
6481 RUN DumpBuffer(loc,buffer) | |
6482 LOOP | |
6483 INPUT "change (sector offset)? ",rewrite | |
6484 EXITIF rewrite="" THEN | |
6485 RUN DumpBuffer(loc,buffer) | |
6486 ENDEXIT | |
6487 EXITIF rewrite="S" OR rewrite="s" THEN ENDEXIT | |
6488 offset=VAL(rewrite)+1 | |
6489 LOOP | |
6490 EXITIF offset>256 THEN ENDEXIT | |
649 | 6491 modloc=loc+offset-1 |
6492 PRINT USING "h4,' - ',h2",modloc,buffer(offset); | |
24 | 6493 INPUT ":",rewrite |
6494 EXITIF rewrite="" THEN ENDEXIT | |
6495 IF rewrite<>" " THEN | |
6496 buffer(offset)=VAL(rewrite) | |
6497 ENDIF | |
6498 offset=offset+1 | |
6499 ENDLOOP | |
6500 ENDLOOP | |
6501 INPUT "rewrite sector? ",rewrite | |
6502 IF LEFT$(rewrite,1)="Y" OR LEFT$(rewrite,1)="y" THEN | |
6503 SEEK #path,loc | |
6504 PUT #path,buffer | |
6505 ENDIF | |
6506 ENDLOOP | |
6507 CLOSE #path | |
6508 BYE | |
6509 | |
6510 PROCEDURE DumpBuffer | |
6511 (* Called by PATCH *) | |
6512 TYPE buffer=char(8):INTEGER | |
6513 PARAM loc:REAL; line(16):buffer | |
6514 DIM i,j:INTEGER | |
6515 WHILE loc>65535. DO | |
649 | 6516 loc=loc-65536. |
24 | 6517 ENDWHILE |
6518 FOR j=1 TO 16 | |
649 | 6519 PRINT USING "h4",FIX(INT(loc))+(j-1)*16; |
24 | 6520 PRINT ":"; |
6521 FOR i=1 TO 8 | |
6522 PRINT USING "X1,H4",line(j).char(i); | |
6523 NEXT i | |
6524 RUN printascii(line(j)) | |
6525 PRINT | |
6526 NEXT j | |
6527 | |
6528 PROCEDURE PrintASCII | |
6529 TYPE buffer=char(16):BYTE | |
6530 PARAM line:buffer | |
6531 DIM ascii:STRING; nextchar:BYTE; i:INTEGER | |
6532 ascii="" | |
6533 FOR i=1 TO 16 | |
6534 nextchar=line.char(i) | |
6535 IF nextchar>127 THEN | |
649 | 6536 nextchar=nextchar-128 |
24 | 6537 ENDIF |
6538 IF nextchar<32 OR nextchar>125 THEN | |
6539 ascii=ascii+" " | |
6540 ELSE | |
6541 ascii=ascii+CHR$(nextchar) | |
6542 ENDIF | |
6543 NEXT i | |
6544 PRINT " "; ascii; | |
6545 </programlisting> | |
6546 | |
6547 <programlisting> | |
6548 PROCEDURE MakeProc | |
649 | 6549 (* Generates an OS-9 command file to apply a command *) |
24 | 6550 (* Such as copy, del, etc., to all files in a directory *) |
6551 (* or directory system. Author: L. Crane *) | |
6552 | |
6553 DIM DirPath,ProcPath,i,j,k:INTEGER | |
6554 DIM CopyAll,CopyFile:BOOLEAN | |
6555 DIM ProcName,FileName,ReInput,ReOutput,response:STRING | |
6556 DIM SrcDir,DestDir,DirLine:STRING[80] | |
6557 DIM Function,Options:STRING[60] | |
6558 DIM ProcLine:STRING[160] | |
6559 | |
6560 ProcName="CopyDir" | |
6561 Function="Copy" | |
6562 Options="#32k" | |
6563 REPEAT | |
6564 PRINT "Proc name ("; ProcName; ")"; | |
6565 INPUT response | |
6566 IF response<>"" THEN | |
6567 ProcName=TRIM$(response) | |
6568 ENDIF | |
6569 | |
6570 ON ERROR GOTO 100 | |
6571 SHELL "del "+ProcName | |
6572 100 ON ERROR | |
6573 INPUT "Source Directory? ",SrcDir | |
6574 SrcDir=TRIM$(SrcDir) | |
6575 ON ERROR GOTO 200 | |
6576 SHELL "del procmaker...dir" | |
6577 200 ON ERROR | |
6578 SHELL "dir "+SrcDir+" >procmaker...dir" | |
6579 OPEN #DirPath,"procmaker...dir":READ | |
6580 CREATE #ProcPath,ProcName:WRITE | |
6581 PRINT "Function ("; Function; ")"; | |
6582 INPUT response | |
6583 IF response<>"" THEN | |
6584 Function=TRIM$(response) | |
6585 ENDIF | |
6586 INPUT "Redirect Input? ",response | |
6587 IF response="y" OR response="Y" THEN | |
6588 ReInput="<" \ ELSE \ReInput="" | |
6589 ENDIF | |
6590 INPUT "Redirect Output? ",response | |
6591 IF response="y" OR response="Y" THEN | |
6592 ReOutput=">" \ ELSE \ReOutput="" | |
6593 ENDIF | |
6594 PRINT "Options ("; Options; ")"; | |
6595 INPUT response | |
6596 IF response<>"" THEN | |
6597 Options=TRIM$(response) | |
6598 ENDIF | |
6599 INPUT "Destination Directory? ",DestDir | |
6600 DestDir=TRIM$(DestDir) | |
6601 WRITE #ProcPath,"t" | |
649 | 6602 WRITE #ProcPath,"TMode .1 -pause" |
24 | 6603 READ #DirPath,DirLine |
6604 INPUT "Use all files? ",response | |
6605 CopyAll=response="y" OR response="Y" | |
6606 WHILE NOT(EOF(#DirPath)) DO | |
6607 READ #DirPath,DirLine | |
6608 i=LEN(TRIM$(DirLine)) | |
6609 IF i>0 THEN | |
6610 j=1 | |
6611 REPEAT | |
6612 k=j | |
6613 WHILE j<=i AND MID$(DirLine,j,1)<>" " DO | |
6614 j=j+1 | |
6615 ENDWHILE | |
649 | 6616 FileName=MID$(DirLine,k,j-k) |
24 | 6617 IF NOT(CopyAll) THEN |
6618 PRINT "Use "; FileName; | |
6619 INPUT response | |
6620 CopyFile=response="y" OR response="Y" | |
6621 ENDIF | |
6622 IF CopyAll OR CopyFile THEN | |
6623 ProcLine=Function+" "+ReInput+SrcDir+"/"+FileName | |
6624 IF DestDir<>"" THEN | |
6625 ProcLine=ProcLine+" "+ReOutput+DestDir+"/"+FileName | |
6626 ENDIF | |
6627 ProcLine=ProcLine+" "+Options | |
6628 WRITE #ProcPath,ProcLine | |
6629 ENDIF | |
6630 WHILE j<i AND MID$(DirLine,j,1)=" " DO | |
6631 j=j+1 | |
6632 ENDWHILE | |
6633 UNTIL j>=i | |
6634 ENDIF | |
6635 ENDWHILE | |
6636 WRITE #ProcPath,"TMode .1 pause" | |
6637 WRITE #ProcPath,"Dir e "+SrcDir | |
6638 IF DestDir<>"" THEN | |
6639 WRITE #ProcPath,"Dir e "+DestDir | |
6640 ENDIF | |
6641 CLOSE #DirPath | |
6642 CLOSE #ProcPath | |
6643 SHELL "del procmaker...dir" | |
6644 PRINT | |
6645 INPUT "Another ? ",response | |
6646 UNTIL response<>"Y" AND response<>"y" | |
6647 IF response<>"B" AND response<>"b" THEN | |
6648 BYE | |
6649 ENDIF | |
6650 </programlisting> | |
6651 | |
6652 <programlisting> | |
6653 *************** | |
6654 * INKEY - a subroutine for BASIC09 by Robert Doggett | |
6655 | |
6656 * Called by: RUN INKEY(StrVar) | |
6657 * RUN INKEY(Path, StrVar) | |
6658 * Inkey determines if a key has been typed on the given path | |
6659 * (Standard Input if not specified), and if so, returns the next | |
6660 * character in the String Variable. If no key has been type, the | |
6661 * null string is returned. If a path is specified, it must be | |
6662 * either type BYTE or INTEGER. | |
6663 | |
6664 0021 TYPE set SBRTN+OBJCT | |
6665 0081 REVS set REENT+1 | |
6666 | |
6667 0000 87CD005E mod InKeyEnd,InKeyNam,TYPE,REVS | |
6668 ,InKeyEnt,0 | |
6669 000D 496E6B65 InKeyNam fcs "Inkey" | |
6670 D 0000 org 0 Parameters | |
6671 D 0000 Return rmb 2 Return addr of caller | |
6672 D 0002 PCount rmb 2 Num of params following | |
6673 D 0004 Param1 rmb 2 1st param addr | |
6674 D 0006 Length1 rmb 2 size | |
6675 D 0008 Param2 rmb 2 2nd param addr | |
6676 D 000A Length2 rmb 2 size | |
6677 0012 3064 InKeyEnt leax Param1,S | |
6678 0014 EC62 ldd PCount,S Get parameter count | |
6679 0016 10830001 cmpd #1 just one parameter? | |
6680 001A 2717 beq InKey20 ..Yes; default path A=0 | |
6681 001C 10830002 cmpd #2 Are there two params? | |
6682 0020 2635 bne ParamErr No, abort | |
6683 0022 ECF804 ldd [Param1,S] Get path number | |
6684 0025 AE66 ldx Length1,S | |
6685 0027 301F leax -1,X byte available? | |
6686 0029 2706 beq InKey10 ..Yes; (A)=Path number | |
6687 002B 301F leax -1,X Integer? | |
6688 002D 2628 bne ParamErr ..No; abort | |
6689 002F 1F98 tfr B,A | |
6690 0031 3068 InKey10 leax Param2,S | |
6691 0033 EE02 InKey20 ldu 2,X length of string | |
6692 0035 AE84 ldx 0,X addr of string | |
6693 0037 C6FF ldb #$FF | |
6694 0039 E784 stb 0,X Initialize to null str | |
6695 003B 11830002 cmpu #2 at least two-byte str? | |
6696 003F 2502 blo InKey30 ..No | |
6697 0041 E701 stb 1,X put str terminator | |
6698 0043 C601 InKey30 ldb #SS.Ready | |
6699 0045 103F8D OS9 I$GetStt is there an data ready? | |
6700 0048 2508 bcs InKey90 ..No; exit | |
6701 004A 108E0001 ldy #1 | |
6702 004E 103F89 OS9 I$Read Read one byte | |
6703 0051 39 rts | |
6704 0052 C1F6 InKey90 cmpb #E$NotRdy | |
6705 0054 2603 bne InKeyErr | |
6706 0056 39 rts (carry clear) | |
6707 0057 C638 ParamErr ldb #E$Param Parameter Error | |
6708 0059 43 InKeyErr coma | |
6709 005A 39 rts | |
6710 005B 1A6926 emod | |
6711 005E InKeyEnd equ * | |
6712 </programlisting> | |
6713 | |
6714 </para> | |
6715 </appendix> | |
6716 <appendix> | |
6717 <title>Quick Reference</title> | |
6718 <para> | |
6719 | |
6720 | |
6721 <table frame="none"> | |
6722 <title>System Mode Commands</title> | |
6723 <tgroup cols="5"> | |
6724 <tbody> | |
6725 <row> | |
6726 <entry>$</entry> | |
6727 <entry>CHX</entry> | |
6728 <entry>EDIT</entry> | |
6729 <entry>LOAD</entry> | |
6730 <entry>RENAME</entry> | |
6731 </row> | |
6732 <row> | |
6733 <entry>BYE</entry> | |
6734 <entry>DIR</entry> | |
6735 <entry>KILL</entry> | |
6736 <entry>MEM</entry> | |
6737 <entry>RUN</entry> | |
6738 </row> | |
6739 <row> | |
6740 <entry>CHD</entry> | |
6741 <entry>E</entry> | |
6742 <entry>LIST</entry> | |
6743 <entry>PACK</entry> | |
6744 <entry>SAVE</entry> | |
6745 </row> | |
6746 </tbody> | |
6747 </tgroup> | |
6748 </table> | |
6749 | |
6750 | |
6751 <table frame="none"> | |
6752 <title>Edit Mode Commands</title> | |
6753 <tgroup cols="5"> | |
6754 <tbody> | |
6755 <row> | |
6756 <entry>+</entry> | |
6757 <entry><cr></entry> | |
6758 <entry>c*</entry> | |
6759 <entry>l*</entry> | |
6760 <entry>r*</entry> | |
6761 </row> | |
6762 <row> | |
6763 <entry>+*</entry> | |
6764 <entry><line #></entry> | |
6765 <entry>d</entry> | |
6766 <entry>q</entry> | |
6767 <entry>s</entry> | |
6768 </row> | |
6769 <row> | |
6770 <entry>-</entry> | |
6771 <entry><space></entry> | |
6772 <entry>d*</entry> | |
6773 <entry>r</entry> | |
6774 <entry>s*</entry> | |
6775 </row> | |
6776 <row> | |
6777 <entry>-*</entry> | |
6778 <entry>c</entry> | |
6779 <entry>l</entry> | |
6780 <entry></entry> | |
6781 <entry></entry> | |
6782 </row> | |
6783 </tbody> | |
6784 </tgroup> | |
6785 </table> | |
6786 | |
6787 | |
6788 <table frame="none"> | |
6789 <title>Debug Mode Commands</title> | |
6790 <tgroup cols="5"> | |
6791 <tbody> | |
6792 <row> | |
6793 <entry>$</entry> | |
6794 <entry>DEG</entry> | |
6795 <entry>LET</entry> | |
6796 <entry>Q</entry> | |
6797 <entry>STEP</entry> | |
6798 </row> | |
6799 <row> | |
6800 <entry>BREAK</entry> | |
6801 <entry>DIR</entry> | |
6802 <entry>LIST</entry> | |
6803 <entry>RAD</entry> | |
6804 <entry>TROFF</entry> | |
6805 </row> | |
6806 <row> | |
6807 <entry>CONT</entry> | |
6808 <entry>END</entry> | |
6809 <entry>PRINT</entry> | |
6810 <entry>STATE</entry> | |
6811 <entry>TRON</entry> | |
6812 </row> | |
6813 </tbody> | |
6814 </tgroup> | |
6815 </table> | |
6816 | |
6817 | |
6818 | |
6819 <table frame="none"> | |
6820 <title>Program Reserved Words</title> | |
535
30480200b0f1
Some attributes were not quote, so xmlto complained about them
roug
parents:
101
diff
changeset
|
6821 <tgroup cols="5"> |
24 | 6822 <tbody> |
6823 <row> | |
6824 <entry>ABS</entry> | |
6825 <entry>DIR</entry> | |
6826 <entry>INT</entry> | |
6827 <entry>PEEK</entry> | |
6828 <entry>SQR</entry> | |
6829 </row> | |
6830 <row> | |
6831 <entry>ACS</entry> | |
6832 <entry>DO</entry> | |
6833 <entry>INTEGER</entry> | |
6834 <entry>PI</entry> | |
6835 <entry>SQRT</entry> | |
6836 </row> | |
6837 <row> | |
6838 <entry>ADDR</entry> | |
6839 <entry>ELSE</entry> | |
6840 <entry>KILL</entry> | |
6841 <entry>POKE</entry> | |
6842 <entry>STEP</entry> | |
6843 </row> | |
6844 <row> | |
6845 <entry>AND</entry> | |
6846 <entry>END</entry> | |
6847 <entry>LAND</entry> | |
6848 <entry>POS</entry> | |
6849 <entry>STOP</entry> | |
6850 </row> | |
6851 <row> | |
6852 <entry>ASC</entry> | |
6853 <entry>ENDEXIT</entry> | |
6854 <entry>LEFT$</entry> | |
6855 <entry>PRINT</entry> | |
6856 <entry>STR$</entry> | |
6857 </row> | |
6858 <row> | |
6859 <entry>ASN</entry> | |
6860 <entry>ENDIF</entry> | |
6861 <entry>LEN</entry> | |
6862 <entry>PROCEDURE</entry> | |
6863 <entry>STRING</entry> | |
6864 </row> | |
6865 <row> | |
6866 <entry>ATN</entry> | |
6867 <entry>ENDLOOP</entry> | |
6868 <entry>LET</entry> | |
6869 <entry>PUT</entry> | |
6870 <entry>SUBSTR</entry> | |
6871 </row> | |
6872 <row> | |
6873 <entry>BASE</entry> | |
6874 <entry>ENDWHILE</entry> | |
6875 <entry>LNOT</entry> | |
6876 <entry>RAD</entry> | |
6877 <entry>TAB</entry> | |
6878 </row> | |
6879 <row> | |
6880 <entry>BOOLEAN</entry> | |
6881 <entry>EOF</entry> | |
6882 <entry>LOG</entry> | |
6883 <entry>READ</entry> | |
6884 <entry>TAN</entry> | |
6885 </row> | |
6886 <row> | |
6887 <entry>BYE</entry> | |
6888 <entry>ERR</entry> | |
6889 <entry>LOG10</entry> | |
6890 <entry>REAL</entry> | |
6891 <entry>THEN</entry> | |
6892 </row> | |
6893 <row> | |
6894 <entry>BYTE</entry> | |
6895 <entry>ERROR</entry> | |
6896 <entry>LOOP</entry> | |
6897 <entry>REM</entry> | |
6898 <entry>TO</entry> | |
6899 </row> | |
6900 <row> | |
6901 <entry>CHAIN</entry> | |
6902 <entry>EXEC</entry> | |
6903 <entry>LOR</entry> | |
6904 <entry>REPEAT</entry> | |
6905 <entry>TRIM$</entry> | |
6906 </row> | |
6907 <row> | |
6908 <entry>CHD</entry> | |
6909 <entry>EXITIF</entry> | |
6910 <entry>LXOR</entry> | |
6911 <entry>RESTORE</entry> | |
6912 <entry>TROFF</entry> | |
6913 </row> | |
6914 <row> | |
6915 <entry>CHR$</entry> | |
6916 <entry>EXP</entry> | |
6917 <entry>MID$</entry> | |
6918 <entry>RETURN</entry> | |
6919 <entry>TRON</entry> | |
6920 </row> | |
6921 <row> | |
6922 <entry>CHX</entry> | |
6923 <entry>FALSE</entry> | |
6924 <entry>MOD</entry> | |
6925 <entry>RIGHT$</entry> | |
6926 <entry>TRUE</entry> | |
6927 </row> | |
6928 <row> | |
6929 <entry>CLOSE</entry> | |
6930 <entry>FIX</entry> | |
6931 <entry>NEXT</entry> | |
6932 <entry>RND</entry> | |
6933 <entry>TYPE</entry> | |
6934 </row> | |
6935 <row> | |
6936 <entry>COS</entry> | |
6937 <entry>FLOAT</entry> | |
6938 <entry>NOT</entry> | |
6939 <entry>RUN</entry> | |
6940 <entry>UNTIL</entry> | |
6941 </row> | |
6942 <row> | |
6943 <entry>CREATE</entry> | |
6944 <entry>FOR</entry> | |
6945 <entry>ON</entry> | |
6946 <entry>SEEK</entry> | |
6947 <entry>UPDATE</entry> | |
6948 </row> | |
6949 <row> | |
6950 <entry>DATA</entry> | |
6951 <entry>GET</entry> | |
6952 <entry>OPEN</entry> | |
6953 <entry>SGN</entry> | |
6954 <entry>USING</entry> | |
6955 </row> | |
6956 <row> | |
6957 <entry>DATE$</entry> | |
6958 <entry>GOSUB</entry> | |
6959 <entry>OR</entry> | |
6960 <entry>SHELL</entry> | |
6961 <entry>VAL</entry> | |
6962 </row> | |
6963 <row> | |
6964 <entry>DEG</entry> | |
6965 <entry>GOTO</entry> | |
6966 <entry>PARAM</entry> | |
6967 <entry>SIN</entry> | |
6968 <entry>WHILE</entry> | |
6969 </row> | |
6970 <row> | |
6971 <entry>DELETE</entry> | |
6972 <entry>IF</entry> | |
6973 <entry>PAUSE</entry> | |
6974 <entry>SIZE</entry> | |
6975 <entry>WRITE</entry> | |
6976 </row> | |
6977 <row> | |
6978 <entry>DIM</entry> | |
6979 <entry>INPUT</entry> | |
6980 <entry></entry> | |
6981 <entry>SQ</entry> | |
6982 <entry>XOR</entry> | |
6983 </row> | |
6984 </tbody> | |
6985 </tgroup> | |
6986 </table> | |
6987 | |
6988 | |
6989 <table frame="none"> | |
6990 <title>&b09; Statements</title> | |
6991 <tgroup cols="5"> | |
6992 <tbody> | |
6993 <row> | |
6994 <entry>BASE 0</entry> | |
6995 <entry>ELSE</entry> | |
6996 <entry>GOTO</entry> | |
6997 <entry>OPEN</entry> | |
6998 <entry>RETURN</entry> | |
6999 </row> | |
7000 <row> | |
7001 <entry>BASE 1</entry> | |
7002 <entry>END</entry> | |
7003 <entry>IF/THEN</entry> | |
7004 <entry>PARAM</entry> | |
7005 <entry>RUN</entry> | |
7006 </row> | |
7007 <row> | |
7008 <entry>BYE</entry> | |
7009 <entry>ENDEXIT</entry> | |
7010 <entry>INPUT</entry> | |
7011 <entry>PAUSE</entry> | |
7012 <entry>SEEK</entry> | |
7013 </row> | |
7014 <row> | |
7015 <entry>CHAIN</entry> | |
7016 <entry>ENDIF</entry> | |
7017 <entry>KILL</entry> | |
7018 <entry>POKE</entry> | |
7019 <entry>SHELL</entry> | |
7020 </row> | |
7021 <row> | |
7022 <entry>CHD</entry> | |
7023 <entry>ENDLOOP</entry> | |
7024 <entry>LET</entry> | |
7025 <entry>PRINT</entry> | |
7026 <entry>STOP</entry> | |
7027 </row> | |
7028 <row> | |
7029 <entry>CHX</entry> | |
7030 <entry>ENDWHILE</entry> | |
7031 <entry>LOOP</entry> | |
7032 <entry>PUT</entry> | |
7033 <entry>TROFF</entry> | |
7034 </row> | |
7035 <row> | |
7036 <entry>CLOSE</entry> | |
7037 <entry>ERROR</entry> | |
7038 <entry>NEXT</entry> | |
7039 <entry>RAD</entry> | |
7040 <entry>TRON</entry> | |
7041 </row> | |
7042 <row> | |
7043 <entry>CREATE</entry> | |
7044 <entry>EXITIF/THEN</entry> | |
7045 <entry>ON ERROR GOTO</entry> | |
7046 <entry>READ</entry> | |
7047 <entry>TYPE</entry> | |
7048 </row> | |
7049 <row> | |
7050 <entry>DATA</entry> | |
7051 <entry>FOR/TO/STEP</entry> | |
7052 <entry>ON/GOSUB</entry> | |
7053 <entry>REM</entry> | |
7054 <entry>UNTIL</entry> | |
7055 </row> | |
7056 <row> | |
7057 <entry>DEG</entry> | |
7058 <entry>GET</entry> | |
7059 <entry>ON/GOTO</entry> | |
7060 <entry>REPEAT</entry> | |
7061 <entry>WHILE/DO</entry> | |
7062 </row> | |
7063 <row> | |
7064 <entry>DELETE</entry> | |
7065 <entry>GOSUB</entry> | |
7066 <entry></entry> | |
7067 <entry>RESTORE</entry> | |
7068 <entry>WRITE</entry> | |
7069 </row> | |
7070 <row> | |
7071 <entry>DIM</entry> | |
7072 <entry></entry> | |
7073 <entry></entry> | |
7074 <entry></entry> | |
7075 <entry></entry> | |
7076 </row> | |
7077 </tbody> | |
7078 </tgroup> | |
7079 </table> | |
7080 | |
7081 | |
7082 <table frame="none"> | |
7083 <title>Transcendental Functions</title> | |
7084 <tgroup cols="4"> | |
7085 <tbody> | |
7086 <row> | |
7087 <entry>ACS (x)</entry> | |
7088 <entry>COS (x)</entry> | |
7089 <entry>LOG10 (x)</entry> | |
7090 <entry>SIN (x)</entry> | |
7091 </row> | |
7092 <row> | |
7093 <entry>ASN (x)</entry> | |
7094 <entry>EXP (x)</entry> | |
7095 <entry>PI</entry> | |
7096 <entry>TAN (x)</entry> | |
7097 </row> | |
7098 <row> | |
7099 <entry>ATN (x)</entry> | |
7100 <entry>LOG (x)</entry> | |
7101 </row> | |
7102 </tbody> | |
7103 </tgroup> | |
7104 </table> | |
7105 | |
7106 | |
7107 <table frame="none"> | |
7108 <title>Numeric Functions</title> | |
7109 <tgroup cols="4"> | |
7110 <tbody> | |
7111 <row> | |
7112 <entry>ABS (x)</entry> | |
7113 <entry>LAND (m,n)</entry> | |
7114 <entry>MOD (m,n)</entry> | |
7115 <entry>SQ (x)</entry> | |
7116 </row> | |
7117 <row> | |
7118 <entry>FIX (x)</entry> | |
7119 <entry>LNOT (m,n)</entry> | |
7120 <entry>RND (x)</entry> | |
7121 <entry>SQR (x)</entry> | |
7122 </row> | |
7123 <row> | |
7124 <entry>FLOAT (m)</entry> | |
7125 <entry>LOR (m,n)</entry> | |
7126 <entry>SGN (x)</entry> | |
7127 <entry>SQRT (x)</entry> | |
7128 </row> | |
7129 <row> | |
7130 <entry>INT (x)</entry> | |
7131 <entry>LXOR (m,n)</entry> | |
7132 </row> | |
7133 </tbody> | |
7134 </tgroup> | |
7135 </table> | |
7136 | |
7137 <table frame="none"> | |
7138 <title>String Functions</title> | |
7139 <tgroup cols="4"> | |
7140 <tbody> | |
7141 <row> | |
7142 <entry>ASC (char$)</entry> | |
7143 <entry>LEFT$ (str$,m)</entry> | |
7144 <entry>RIGHT$ (str$,m)</entry> | |
7145 <entry>TRIM$ (str$)</entry> | |
7146 </row> | |
7147 <row> | |
7148 <entry>CHR$ (m)</entry> | |
7149 <entry>LEN (str$)</entry> | |
7150 <entry>STR$ (x)</entry> | |
7151 <entry>VAL(str$)</entry> | |
7152 </row> | |
7153 <row> | |
7154 <entry>DATE$</entry> | |
7155 <entry>MID$ (str$,m,n)</entry> | |
7156 <entry>SUBSTR(st1$,st2$)</entry> | |
7157 </row> | |
7158 </tbody> | |
7159 </tgroup> | |
7160 </table> | |
7161 | |
7162 <table frame="none"> | |
7163 <title>Miscellaneous Functions</title> | |
7164 <tgroup cols="4"> | |
7165 <tbody> | |
7166 <row> | |
7167 <entry>ADDR (var)</entry> | |
7168 <entry>FALSE</entry> | |
7169 <entry>POS</entry> | |
7170 <entry>TAB (m)</entry> | |
7171 </row> | |
7172 <row> | |
7173 <entry>EOF (#path)</entry> | |
7174 <entry>PEEK (addr)</entry> | |
7175 <entry>SIZE (var)</entry> | |
7176 <entry>TRUE</entry> | |
7177 </row> | |
7178 <row> | |
7179 <entry>ERR</entry> | |
7180 </row> | |
7181 </tbody> | |
7182 </tgroup> | |
7183 </table> | |
7184 | |
7185 <table frame="none"> | |
7186 <title>Operator Precedence</title> | |
7187 <tgroup cols="7"> | |
649 | 7188 <colspec colname="c1"/> |
7189 <colspec colname="c2"/> | |
7190 <colspec colname="c3"/> | |
7191 <colspec colnum="7" colname="c7"/> | |
7192 <spanspec spanname="firstop" namest="c2" nameend="c2"/> | |
7193 <spanspec spanname="secondop" namest="c3" nameend="c7"/> | |
7194 <spanspec spanname="onlyop" namest="c2" nameend="c7"/> | |
7195 <spanspec spanname="all" namest="c1" nameend="c7"/> | |
24 | 7196 <tbody> |
7197 <row> | |
7198 <entry>highest -></entry> | |
7199 <entry spanname="firstop">NOT</entry> | |
649 | 7200 <entry spanname="secondop">-(negate)</entry> |
24 | 7201 </row> |
7202 <row> | |
7203 <entry spanname="firstop">^</entry> | |
7204 <entry spanname="secondop">**</entry> | |
7205 </row> | |
7206 <row> | |
7207 <entry spanname="firstop">*</entry> | |
7208 <entry spanname="secondop">/</entry> | |
7209 </row> | |
7210 <row> | |
7211 <entry spanname="firstop">+</entry> | |
649 | 7212 <entry spanname="secondop">-</entry> |
24 | 7213 </row> |
7214 <row> | |
7215 <entry spanname="firstop">></entry> | |
7216 <entry><</entry> | |
7217 <entry><></entry> | |
7218 <entry>=</entry> | |
7219 <entry>>=</entry> | |
7220 <entry><=</entry> | |
7221 </row> | |
7222 <row> | |
7223 <entry spanname="onlyop">AND</entry> | |
7224 </row> | |
7225 <row> | |
7226 <entry>lowest -></entry> | |
7227 <entry spanname="firstop">OR</entry> | |
7228 <entry spanname="secondop">XOR</entry> | |
7229 </row> | |
7230 </tbody> | |
7231 </tgroup> | |
7232 </table> | |
7233 | |
7234 | |
7235 </para> | |
7236 </appendix> | |
7237 <appendix> | |
7238 <title>&b09; Error Codes</title> | |
7239 <para> | |
7240 <literallayout> | |
649 | 7241 10 - Unrecognized Symbol |
7242 11 - Excessive Verbage (too many keywords or symbols) | |
7243 12 - Illegal Statement Construction | |
7244 13 - I-code Overflow (need more workspace memory) | |
7245 14 - Illegal Channel Reference (bad path number given) | |
7246 15 - Illegal Mode (Read/Write/Update/Dir only) | |
7247 16 - Illegal Number | |
7248 17 - Illegal Prefix | |
7249 18 - Illegal Operand | |
7250 19 - Illegal Operator | |
7251 | |
7252 20 - Illegal Record Field Name | |
7253 21 - Illegal Dimension | |
7254 22 - Illegal Literal | |
7255 23 - Illegal Relational | |
7256 24 - Illegal Type Suffix | |
7257 25 - Too-Large Dimension | |
7258 26 - Too-Large Line Number | |
7259 27 - Missing Assignment Statement | |
7260 28 - Missing Path Number | |
7261 29 - Missing Comma | |
7262 | |
7263 30 - Missing Dimension | |
7264 31 - Missing DO Statement | |
7265 32 - Memory Full (need more workspace memory) | |
7266 33 - Missing GOTO | |
7267 34 - Missing Left Parenthesis | |
7268 35 - Missing Line Reference | |
7269 36 - Missing Operand | |
7270 37 - Missing Right Parenthesis | |
7271 38 - Missing THEN statement | |
7272 39 - Missing TO | |
7273 | |
7274 40 - Missing Variable Reference | |
7275 41 - No Ending Quote | |
7276 42 - Too Many Subscripts | |
7277 43 - Unknown Procedure | |
7278 44 - Multiply-Defined Procedure | |
7279 45 - Divide by Zero | |
7280 46 - Operand Type Mismatch | |
7281 47 - String Stack Overflow | |
7282 48 - Unimplemented Routine | |
7283 49 - Undefined Variable | |
7284 | |
7285 50 - Floating Overflow | |
7286 51 - Line with Compiler Error | |
7287 52 - Value out of Range for Destination | |
7288 53 - Subroutine Stack Overflow | |
7289 54 - Subroutine Stack Underflow | |
7290 55 - Subscript out of Range | |
7291 56 - Parameter Error | |
7292 57 - System Stack Overflow | |
7293 58 - I/O Type Mismatch | |
7294 59 - I/O Numeric Input Format Bad | |
7295 | |
7296 60 - I/O Conversion: Number out of Range | |
7297 61 - Illegal Input Format | |
7298 62 - I/O Format Repeat Error | |
7299 63 - I/O Format Syntax Error | |
7300 64 - Illegal Path Number | |
7301 65 - Wrong Number of Subscripts | |
7302 66 - Non-Record-Type Operand | |
7303 67 - Illegal Argument | |
7304 68 - Illegal Control Structure | |
7305 69 - Unmatched Control Structure | |
7306 | |
7307 70 - Illegal FOR Variable | |
7308 71 - Illegal Expression Type | |
7309 72 - Illegal Declarative Statement | |
7310 73 - Array Size Overflow | |
7311 74 - Undefined Line Number | |
7312 75 - Multiply-Defined Line Number | |
7313 76 - Multiply-Defined Variable | |
7314 77 - Illegal Input Variable | |
7315 78 - Seek Out of Range | |
7316 79 - Missing Data Statement | |
7317 80 - Print Buffer Overflow | |
24 | 7318 </literallayout> |
7319 | |
7320 Error codes above 80 are those used by OS-9 or other external programs. | |
7321 Consult the "OS-9 User's Guide" for a list of error codes and explanations. | |
7322 </para> | |
7323 </appendix> | |
7324 | |
7325 | |
1015 | 7326 &gfxapp; |
973 | 7327 &gfx2app; |
24 | 7328 </book> |