************************************************************ ******* UK-PRACT.TXT By K.C.GOLDIE-MORRISON. 1 12.81 ****** ************************************************************ PRACTICAL PROGRAMMING IN STOIC. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The object of this file is to give a practical synoptic view of STOIC programming to augment, but not displace, the very exaustive treatment in UKSTOIC.DOC and the other DOC files covering the DICTIONARY and ASSEMBLER. These should be read to fill out the elementary treatment here. The following conventions have been used to make the exercises clearer: 1. The User entries have been tabbed to the right to disting- uish them from the Machine output. 2. Lower-case letters enclosed in < and > indicate the key to be pressed. e.g. means "press the return key". 3. Words with particular significance in Stoic are shown in upper-case in these descriptions. Copy UKSTOICB.COM onto a fresh disc, place in A drive and enter the following :- Machine You A> UKSTOICB 0> SZSTOIC STOIC IS 65 DECIMAL PAGES LONG 0> UKSTOICB loads the basic STOIC DICTIONARY and responds with the Prompt 0> which means "awaiting entry" (equivalent to"READY" in Basic). SZSTOIC tells you the length of the DICTIONARY in CP/M pages (256 bytes). Keyboard editing keys such as may be used up to , which is the executive instruction to act. STOIC can operate in any RADIX, but three ( HEX, DECIMAL and OCTAL) are STOIC WORDS to call those radices. Make sure you are in the right one by calling it. 0> DECIMAL 0> There are two types of entries - definitions, that is compiling and adding new WORDS to the DICTIONARY - and interactive commands, where the line is compiled and immediately executed. There are only three classes of words that can be used in STOIC. 1. STOIC WORDS (WORDS for short). These are names of functions already defined in the dictionary, such as SZSTOIC above. 2. INTEGER LITERALS (NUMBERS for short). Integer numbers of 16 bits, that is from 32767 to -32768, or 0 to 65535 unsigned. They must be expressed in ASCII characters suitable to the current radix. i.e. -1234 24000 (Decimal) 0FF AC9E (Hex) 011011 11100 (Binary) 23,000 (Illegal, no punctuation allowed) 3. STRING LITERALS (STRINGS for short). Strings of any ASCII characters, except certain key-function ones such as for which special rules apply (see "&"). A STRING must :- Start with a single quote and end with a space 'STRING 'AB612N '%%%%# Or be enclosed in double quotes or backslashes "THIS IS A STRING" \SO IS THIS\ Note that all STOIC WORDS in UKSTOICB have been defined in upper-case letters. This is not obligatory but advisable because Words must be called as defined. There is no punctuation in STOIC, most of the ASCII char- acters are WORDS.e.g. : and ; start and end a definition and must of course be separated from others by a space. If you undersatand how STOIC handles the input, it will make clear why "postfix" or "reverse polish" notation is necessary. When is entered, STOIC acts as follows: 1. Reads the first word, looks it up in the DICTIONARY, if found it is copied into a buffer (COMPILE BUFFER). 2. If not found, tests if it is a NUMBER, if so converts it to binary, enters in compile buffer with code that pushes it on the STACK when executed. 3. If not a NUMBER, tests for a STRING. If so, copies it into the compile buffer with code that pushes the address of the string on the STACK when executed. 4. If none of these, the line is deleted and an error message printed, indicating where the entry was illegal. 5. When the end of the line is reached, the compile buffer contents are executed or transferred to the end of the DICTIONARY, depending on whether in command or defining mode. This is an over-simplification in order to make the process clear. The first "pass" prepares the line for definition or execution, and then either transfers it to the DICT- IONARY or carries out the commands. 0> TASK UNDEFINED TASK 0> 'TASK : "THIS IS DEFINITION OF TASK" MSG ; 0> TASK THIS IS DEFINITION OF TASK 0> TASK was not in DICTIONARY, was not a NUMBER nor a STRING so was illegal. TASK was then defined by you (note the ' in front of TASK, it is a STRING). The definition was accepted and then you called it. : and ; started and ended the definition, MSG means pop the address off the TOP and print the STRING to which it points. TYO is a similar WORD but prints the ASCII character whose number is popped off the stack :- 0> 'A MSG A 0> 65 TYO % 65 is ASCII number of 'A' A 0> Note that the script after % is ignored - like REM in Basic - so that you may annotate your .STC files. "=" is a WORD meaning "Pop the NUMBER on TOP, convert it to the current radix and print it" 0> 1234 % This puts 1234 in binary on STACK 0> HEX 0> = % This converts TOP to HEX and prints it. 4D2 0> You have converted 1234 to HEX. Now for simple arithmatic. + - * / are STOIC WORDS which pop the top two numbers, operate on them and push the answer back on TOP. 0> DECIMAL 0> = = = STACK EMPTY 0> Puts us back in right radix and makes sure the stack is empty. Note - we have stopped showing where it is obvious. 0> 1 2 3 + + = 6 0> 1 2 - = % Note order and result -1 0> 2 1 - = 1 0> 6 2 / = 3 0> 2 3 4 * * = 24 0> There is no need for parentheses, or for changing the order of the operands, only the operators affect the result. 0> 1 2 + 3 4 + * = % (1+2)(3+4) 21 0> 1 2 3 * + 4 + = % 1+2x3+4 11 0> 1 2 3 4 + * + = % 1+2(3+4) 15 Do a number of practice runs using the four arithmetic operators. You will find it best to visualise the STACK after each operator. Although it is not necessary to change the order for arithmetic operations, the use of the STACK for general parameter storage often leaves the entries in the wrong order. STOIC is rich in WORDS to rearrange the STACK. The most useful are :- 0> -2 -1 0 DROP = = -1 -2 0> The TOP has been removed and the rest of the entries moved up one place. Note. -2 -1 0 puts 0 at TOP, -1 at TOP-1, -2 at TOP-2. So you can see where they have moved. = = = prints TOP, then TOP-1, then TOP-2. 0> -2 -1 0 SWAP = = = -1 0 -2 0> -2 -1 0 DUP = = = = 0 0 -1 -2 0> -2 -1 0 OVER = = = = -1 0 -1 -2 0> -2 -1 0 +ROT = = = -1 -2 0 0> Most WORDS pop their arguments from the STACK and in the process they are lost, so if you need them later, they must either be duplicated on the STACK or put into a variable. As you have seen, DUP copies the entry on TOP, DDUP does both TOP and TOP-1 :- 0> -1 0 DDUP = = = = 0 -1 0 -1 0> We will now define a WORD which will let us examine the top three STACK entries and still leave the STACK unchanged, very useful when testing a new line. We will use the WORDS ( and ) which mean "do what is inside the brackets N times, N being the number on TOP". 0> 5 ( 65 TYO ) AAAAA 0> 'EXSTACK : 3 ( DUP = +ROT ) ; 0> -2 -1 0 EXSTACK 0 -1 -2 0> = = = % See if they are still there 0 -1 -2 0> The WORD "EXSTACK" rotates the stack 3 times to where they were, printing as it goes. Work out what the definition is doing. As you can see the STACK is unchanged. The Dictionary has a more sophisticated WORD - "=S" - which prints all STACK contents, regardless of how many, in the order TOP-N to TOP, leaving the STACK unchanged. 0> 5 4 3 2 1 0> =S 5 4 3 2 1 0> = = = = = 1 2 3 4 5 0> =S STACK EMPTY 0> Put =S in several places when you are trying out a new definition which has several STACK operations. When reading a new DEFINITION, as opposed to a COMMAND, STOIC replaces the STACK operation with instructions to carry out those operations when the DEFINITION is called. Thus a DEFINITION can be accepted as legal but still not work as you wished. So you must delete the DEFINITION and try again. To do so you use FORGET, which deletes all DEFS down to the designated WORD. 0> 'TASK FORGET % Note the ' 0> TASK UNDEFINED TASK 0> Remember, we defined TASK earlier, so it was in the DICTIONARY. EXSTACK will also have been deleted, as a later entry. 0> EXSTACK UNDEFINED EXSTACK 0> So be careful - 'RETCPM FORGET will delete the entire DICTIONARY !. CONSTANTS, VARIABLES and ARRAYS The STACK is used for all temporary storage because it is fast, economical of memory, and a must when "recursing". All the same, the above three longer-term storage types are available. 0> 32 'GRAVITY CONSTANT 0> GRAVITY = 32 0> CONSTANT takes the value at TOP-1, and stores it under the name whose address is at TOP, by creating a WORD in the DIC- TIONARY. When that WORD is called, it pushes the value on TOP. 0> 370 'TORYMPS VARIABLE 0> TORYMPS = 21561 0> VARIABLE is like CONSTANT at definition stage, but when called it pushes the address on TOP, not the value at that address. The WORD @ exhanges the address at TOP with the value at that address :- 0> TORYMPS @ = 370 0> TORYMPS ? % ? is same as @ = 370 0> 290 TORYMPS ! % this stores 290 0> TORYMPS ? 290 0> ARRAY names a space in the DICTIONARY of length in 16 bit words equal to the number at TOP :- 0> 6 'ALIST ARRAY 0> 100 ALIST ! 0> 200 ALIST 2 + ! 0> 300 ALIST 4 + ! 0> ALIST 2 - 3 ( 2 + DUP ? ) DROP 100 200 300 0> ALIST 2 - pushes the address of the start of the array minus 2 (one word length). 2 + DUP ? adds 2 to TOP and then duplicates it and prints it, thus leaving just one address on TOP. 3 ( .......) DROP repeats the process 3 times and then drops the address still on TOP at the end. LOOPS We have used one form of loop, the brackets ( and ). Two others are available :- 0> 6 0 DO 65 TYO LOOP AAAAAA 0> 6 0 DO 66 TYO 2 +LOOP BBB 0> The first form counts from the number at TOP up to the number at TOP-1 and each time executes the WORDs between "DO" and "LOOP". The second form is the same except that the count is in steps of the number at TOP when +LOOP is reached. The loop count variable is accessible to the programmer but the rules are rather complicated. Within any loop the count for that loop is pushed on the STACK by the WORD "I" and that of the next two outer loops in which it is nested by WORDS J and K. 0> 5 0 DO I = LOOP 0 1 2 3 4 0> 10 1 DO I = 10 1 DO I J * = LOOP CR LOOP 1 1 2 3 4 5 6 7 8 9 2 2 4 6 8 10 12 14 16 18 3 3 6 9 etc upto 9 9 18 27 36 45 54 63 72 81 0> This is the multiplication tables of 1 to 9. CR prints a . Note the I in the first loop and the J in the second is the same counter. The inverse of the count is also available by using the WORDS I' J' and K'. 0> 5 0 DO I = LOOP CR 5 0 DO I' = LOOP 0 1 2 3 4 4 3 2 1 0 0> In parenthesis loops, I may be used but it counts down to 1. I' may not be used. 0> 9 ( I = ) 9 8 7 6 5 4 3 2 1 0> 10 1 DO I' = LOOP 9 8 7 6 5 4 3 2 1 0> This is the end of the practice run, because the explanations will get more complicated. The UKSTOIC.DOC file should be studied and should now be more intelligible. If you wish to save all the definitions you have made :- 0> SZSTOIC STOIC IS 69 DECIMAL PLACES LONG 0> RETCPM % This returns you to CP/M A> Save 69 MYEFFORT.COM A> You can return to where you finished by calling MYEFFORT, which will load UKSTOICB.COM with your definitions added. Thus, programs can be saved in two ways, by saving the whole lot, that is the STOIC Dictionary and the new definitions, as above. The program can also be written in source code and saved as an STC file :- % This is a Titling File 'TITLE : "This file was written by Joe Doe and Copyright" MSG ; ;F This could be saved as TITLE.STC using ED or the STOIC editor. A> 'UKSTOICB 0> 'TITLE CPMLD 0> TITLE This file was written by Joe Doe and Copyright 0> Note. ";F" tells STOIC that this is end of program file and "CPMLD" tells STOIC to load the File TITLE.STC and compile it onto end of Dictionary. Do NOT put in the "STC" when using CPMLD. Use this procedure to compile in files such as STOICFLT.STC A> UKSTOICB 0> 'STOICFLT CPMLD 0> SZSTOIC STOIC IS 71 DECIMAL PAGES LONG 0> RETCPM A> Save 71 floating.com A> You now have a floating-point STOIC - Quite simple - isn't it ?. ***EOF***