1 HELP The COD (COmponent Definition) program is intended to fill two roles: First, it can be used interactively as a reverse-Polish calculator using all the functions described in the 'dictionary' section. Second, it can be used to test COD programs as described in the 'files' section. In all cases, COD will accept several commands on a single line. 1 dictionary The following functions are built-in to the current version of COD: 2 + Add the top two numbers in the stack. Example: 5.0 2.0 COD> + 7.0 2 - Subtract the top two numbers in the stack. Example: 5.0 2.0 COD> - 3.0 2 * Multiply the top two numbers in the stack. Example: 5.0 2.0 COD> * 10.0 2 / Divide the previously entered number by the number on the top of the stack. Example: 5.0 2.0 COD> / 2.5 2 ^ Raise the previously entered number to the power given by the top number in the stack. Example: 5.0 2.0 COD> ^ 25.0 2 DEPth Leave the number of values contained in the stack (not counting the result). Example: 5.0 4.0 COD> DEP 5.0 4.0 2.0 2 DRop Drop the stack pointer so that the number at the top of the stack is lost. Example: 5.0 4.0 COD> DROP 5.0 2 DUP Duplicate the number on the top of the stack (equivalent to 1 PICK). Example: 5.0 2.0 COD> DUP 5.0 2.0 2.0 2 OVer Duplicate the second number on the stack (equivalent to 2 PICK). Example: 5.0 4.0 COD> OVER 5.0 4.0 5.0 2 PICK Duplicate the nth number on the stack (not counting n itself), where n is the top number on the stack. Note: 1 PICK does the same thing as DUP, and 2 PICK does the same thing as OVER. Example: 100. 200. 300. 400. COD> 3 PICK 100. 200. 300. 400. 200. 2 ROLL Rotate the nth number (not counting n itself) to the top of the stack, where n the top number in the stack. Note: 2 ROLL does the same thing as SWAP; 3 ROLL does the same thing as ROT; and n must be greater than 1.0. Example: 100. 200. 300. 400. COD> 4 ROLL 200. 300. 400. 100. 2 ROT Rotate the third number to the top of the stack (equivalent to 3 ROLL). Example: 100. 200. 300. 400. COD> ROT 100. 300. 400. 200. 2 SWap Swap the top two numbers on the stack (equivalent to 2 ROLL). Example: 5.0 2.0 COD> SWap 2.0 5.0 2 ?Dup Duplicate the number at the top of the stack only if it is non-zero. Example: 5.0 0.0 COD> ?DUP 5.0 0.0 COD> 1.0 ?DUP 5.0 0.0 1.0 1.0 2 ABS Take the absolute value of the top number in the stack. Example: 5.0 -2.0 COD> ABS 5.0 2.0 2 NEG Negate the top number in the stack. Example: 5.0 2.0 COD> NEG 5.0 -2.0 2 1/ Compute the inverse of the top number in the stack. Example: 5.0 2.0 COD> 1/ 5.0 0.50 2 PI Push the value of PI into the stack. Example: 5.0 COD> PI 5.0 3.141593 2 LN Take the natural log of the top number in the stack. Example: 5.0 2.0 COD> LN 5.0 0.6931472 2 EXP Compute the exponential of the top number in the stack. Example: 5.0 1.0 COD> EXP 5.0 2.718282 2 LOG Take the base-10 logarithm of the top number in the stack. Example: 5.0 2.0 COD> LN 5.0 0.3010300 2 ALog Compute 10. raised to the power of the top number in the stack. Example: 5.0 2.0 COD> ALog 5.0 100.0 2 SQrt Compute the square-root of the top number in the stack. Example: 5.0 2.0 COD> SQrt 5.0 1.414214 2 COS Compute the cosine of the top number in the stack. Example: 5.0 0.5 COD> COS 5.0 0.8775826 2 SIN Compute the sine of the top number in the stack. Example: 5.0 0.5 COD> SIN 5.0 0.4794255 2 TAN Compute the tangent of the top number in the stack. Example: 5.0 0.5 COD> TAN 5.0 0.5463025 2 ACos Compute the arc-cosine of the top number in the stack. Example: 5.0 0.5 COD> ACos 5.0 1.047198 2 ASin Compute the arc-sine of the top number in the stack. Example: 5.0 0.5 COD> ASin 5.0 0.5235988 2 ATan Compute the arc-tangent of the top number in the stack. Example: 5.0 0.5 COD> ATan 5.0 0.4636476 2 A2tn Compute the arc-tangent if the top two numbers in the stack represent an x,y pair. Example: 1.0 2.0 COD> A2tn 1.570796 2 HCos Compute the hyperbolic-cosine of the top number in the stack. Example: 5.0 0.5 COD> HCos 5.0 1.127626 2 HSin Compute the hyperbolic-sine of the top number in the stack. Example: 5.0 0.5 COD> HSin 5.0 0.5210953 2 HTan Compute the hyperbolic-tangent of the top number in the stack. Example: 5.0 0.5 COD> HTan 5.0 0.4621172 2 INT Compute the integer portion of the top number in the stack. Example: 5.0 0.9 COD> INT 5.0 0.0 2 NInt Compute nearest integer to the top number in the stack. Example: 5.0 0.9 COD> NInt 5.0 1.0 2 MOD Compute the Fortran MOD function (of the previous number, modulo the top number in the stack. Example: 2.0 3.0 COD> MOD 2.0 COD> ABO 3.0 3.0 3.0 3.0 COD> MOD 0.0 2 /MOD Replace the top two numbers in the stack with the remainder and quotient of the previous number divided by the top number in the stack. Example: 23.1 10.0 COD> /MOD 3.1 2.0 2 TSig Transfer the sign of the top number in the stack to the absolute value of the previous number. Example: 2.0 -5.0 COD> TSig -2.0 2 DTor Convert decimal degrees to radians. Example: 5.0 90.0 COD> DTor 5.0 1.570796 2 RTod Convert radians to decimal degrees. Example: 5.0 1.0 COD> RTod 5.0 57.29578 2 DMsd Convert a number of the form DDDMMSS.S to decimal degrees. Example: 123000.0 COD> DMsd 12.5 2 DDms Convert a number in decimal degrees to the form DDDMMSS.S . Example: 12.5 COD> DMsd 123000.0 2 < Replace the top two numbers in the stack with 1.0 if the previous number is less than the top number, 0.0 otherwise. Example: 1.0 2.0 COD> < 1.0 2 = Replace the top two numbers in the stack with 1.0 if the numbers are equal, 0.0 otherwise. Example: 1.0 2.0 COD> = 0.0 2 > Replace the top two numbers in the stack with 1.0 if the previous number is greater than the top number, 0.0 otherwise. Example: 1.0 2.0 COD> > 0.0 2 0< Replace the top number in the stack with 1.0 if it is less than zero, 0.0 otherwise. Example: -1.0 COD> 0< 1.0 2 0= Replace the top number in the stack with 1.0 if it equals zero, 0.0 otherwise. Example: -1.0 COD> 0= 0.0 2 0> Replace the top number in the stack with 1.0 if it is greater than zero, 0.0 otherwise. Example: -1.0 COD> 0> 0.0 2 NOT Replace the top number in the stack with 1.0 if it is zero, 0.0 otherwise. Example: 1.0 COD> NOT 0.0 2 . Print the number at the top of the stack, and decrement stack pointer by one. The sequence 'DUP .' can be inserted anywhere into COD programs to print the number at the top of the stack. This may help you figure out what the program is doing. Example: 1.0 2.0 3.0 4.0 5.0 COD> . 5.0 1.0 2.0 3.0 4.0 2 1+ Add one to the number at the top of the stack. Example: 3.0 5.0 COD> 1+ 3.0 6.0 2 1- Subtract one from the number at the top of the stack. Example: 3.0 5.0 COD> 1- 3.0 4.0 2 2+ Add two to the number at the top of the stack. Example: 3.0 5.0 COD> 2+ 3.0 7.0 2 2- Subtract two from the number at the top of the stack. Example: 3.0 5.0 COD> 2- 3.0 3.0 2 MIN Replace the top two numbers in the stack with the minimum of the two numbers. Example: 1.0 3.0 5.0 COD> MIN 1.0 3.0 2 MAX Replace the top two numbers in the stack with the maximum of the two numbers. Example: 1.0 3.0 5.0 COD> MAX 1.0 5.0 2 STO Store the previous number at the address given by the number at the top of the stack. Although it is easy to determine the address associated with a given variable, and hence use that address directly, it is advisable to always use a variable name to load an address into the stack before using STO. Example: 1.0 COD> VAR TMP 1.0 COD> 5 TMP STO 1.0 COD> TMP RCL 1.0 5.0 2 +STO Add the previous number to the number at the address given by the number at the top of the stack. Although it is easy to determine the address associated with a given variable, and hence use that address directly, it is advisable to always use a variable name to load an address into the stack before using +STO. Example: COD> VAR TMP 5 TMP STO TMP RCL 5.0 COD> TMP +STO COD> TMP RCL 10.0 2 RCL Replace the address at the top of the stack with the number at that address. See the STO topic for an example of how RCL is used. 2 ? Display the number stored at the address given at the top of the stack. Although it is easy to determine the address associated with a given variable, and hence use that address directly, it is advisable to always use a variable name to load an address into the stack before using ?. Example: 1.0 2.0 COD> VAR TMP 5 TMP STO 1.0 2.0 COD> TMP ? 5.0 1.0 2.0 2 VAR Define the following token to be a new variable name. When that variable is used in the future, it will cause the address of that variable to be loaded into the stack (for use with a following STO or RCL command). Example: COD> VAR 2PI 2 PI * 2PI STO COD> 2PI RCL 6.283185 2 : Begin a new colon definition. In COD, colon definitions define new dictionary words (i.e., new functions). The token following the : is taken to be the name of the function. All words typed after the : are compiled (stored) into memory. A semicolon ; terminates the colon definition and returns the state from compile to execute mode. The name must not match any existing COD keyword. The interactive COD program does not print the stack when the internal state is compiling (i.e., during a colon definition). Example: COD> : X2 DUP * ; COD> 5 5.0 COD> X2 25.0 2 ; Terminate the current colon definition and return state from compile to execute mode. See the : topic for an example. 2 ABOrt Reset the stack pointer. This deletes all numbers in the stack and can be very useful in the interactive mode to clean out the stack. If this command occurs while a COD program is running, the program exits and a NO data function value is returned. 2 program_words The following words can only be used inside COD programs: 3 X Push the current X value into the stack. 3 IF If the condition is true, execute statements up to the corresponding ELSE/THEN statement. If the condition is false, pass control to the first statement following the ELSE if it exists, otherwise to the first statement following the THEN. IF structures can be nested. Examples: X 1 < IF ! do these statements if X<1 THEN X 1 > IF ! do these statements if X>1 ELSE ! do these statements if X<=1 THEN 3 ELSE If the condition was false when the IF statement executed, then transfer control to the first statement following the ELSE. If the condition was true then the program executes code down to the ELSE statement and then skips to the first statement following the THEN statement. This statement must be preceeded by an IF statement. 3 THEN Terminate an IF structure. See the IF topic for and example of use. 3 FOR Set up a FOR..LOOP or a FOR..+LOOP structure using the top two numbers in the stack to denote the range. The index for the FOR loop is an INTEGER*2, hence the maximum value is 32767. Example: COD> : TMP 4 1 FOR I . LOOP ; COD> TMP 1.0 2.0 3.0 4.0 Warning to people who know Forth: The COD FOR statement is similar to the Forth DO statement; however, there is an important difference concerning the two numbers that precede the FOR. In COD, these represent the upper and lower index values respectfully; in Forth, the first number is one greater than the upper index value. 3 LOOP Terminate a COD FOR loop. When this statement executes, one is added to the current index value. If the current index is less than or equal to the maximum index, then control is transferred to the first statement following the corresponding FOR statement. Otherwise, control passes to the statement following the LOOP statement. See the FOR topic for an example of use. 3 +LOOP Terminate a COD FOR loop. When this statement executes, the number at the top of the stack is added to the current index. The loop terminates when the index passes the limit value. The +LOOP statement allows for loops in which the index value can either increase or decrease. Example: COD> : TMP 0 2 FOR I . -1 +LOOP ; COD> TMP 2.0 1.0 0.0 COD> : DOUBLE 100 1 FOR I . I +LOOP ; COD> DOUBLE 1.0 2.0 4.0 8.0 16.0 32.0 64.0 COD> 3 I Push the index value of the innermost FOR loop onto the stack. This statement can only be used inside FOR loops. See the FOR topic for an example of use. 3 J Push the index value of the nest outer FOR loop onto the stack. This statement can only be used inside FOR loops. Example: COD> : TMP 2 1 FOR COD> 5 4 FOR COD> J . LOOP LOOP ; COD> TMP 1.0 1.0 2.0 2.0 3 LEAVE Immediately exit the current FOR loop. The next statement to execute will the the one that follows the LOOP (or +LOOP) statement. 3 BEGIN Begin a BEGIN..UNTIL or a BEGIN..WHILE..REPEAT structure. See either the UNTIL or WHILE topics for examples of use. 3 UNTIL Terminate a BEGIN..UNTIL block. UNTIL pops one number off the stack. If that number is false (=0.0), the program jumps back to the first statement following the BEGIN statement. Otherwise execution continues with the statement following the UNTIL statement. Example: The following function (TEST) starts with the number 2.0 and squares it until it exceeds 1.E10 (note the last number is not printed). COD> VAR Y COD> : TEST 2 Y STO COD> BEGIN COD> Y RCL . ! Print the number COD> Y RCL DUP * Y STO ! Square it and store new value COD> Y RCL 1.E10 > ! Test COD> UNTIL ; COD> TEST 2.0 4.0 16.O 256.0 4.2949673E+9 3 WHILE The WHILE statement pops one number off the stack. If that number is true (<>0.0), the statement following the WHILE will be executed. If the number is false then control passes to the first statement following the REPEAT statement. This statement can only be used inside a BEGIN..REPEAT loop. Example: The following program starts with the number 2, and continues to square that number WHILE it is less than 1.E10. COD> VAR Y COD> : TEST 2 Y STO COD> BEGIN COD> Y RCL . ! Print the number COD> Y RCL 1.E10 < WHILE ! Recall number and test for <1.E10 COD> Y RCL DUP * Y STO ! Square and store new value COD> REPEAT ; COD> TEST 2.0 4.0 16.O 256.0 4.2949673E+9 1.8446744E+19 3 REPEAT Terminate a BEGIN..WHILE..REPEAT loop. When this statement executes, control is always passed to the first statement following the BEGIN statement. See the WHILE topic for an example of use. 3 EXIT Immediately terminate the current colon function. Since the stack is un-affected, check to verify that the stack is left in the same state no matter how the colon function is terminated (otherwise obscure and nasty bugs result). The Surgeon General wishes to remind you that using EXIT will destroy the structured nature of your program and therefore is hazardous to your health. 1 files COD can be used to read COD program files from disk. These files, called COD files, simply contain a sequence of COD built-in functions. This sequence of functions is called a COD program. As an example, assume the file TEST.COD contains the following lines: ! COD program to calculate a line. ! P1 + P2*X : LINE P1 X P2 * + ; All lines that begin with '!' are considered comment lines and are ignored by COD (currently comment lines are listed on your terminal when the file is read in). The third line contains the program itself. P1 and P2 are parameter values and when used with the PLT/FIT routine can be adjusted to minimize chi**2. When writing COD programs that use parameters, you must use consecutive numbers starting with one, i.e., do not leave any holes in the sequence. The following example demonstrates how the above file can be used. COD> GET TEST ! Read the test file, note comment lines are echoed. ! COD program to calculate a line. ! P1 + P2*X NTERMS= 2 COD> NEW 1 1. ! Set parameter 1 to 1.0 COD> NEW 2 1. ! Set parameter 2 to 1.0 COD> 5 ! Place the number 5.0 in the stack 5.0 COD> RUN ! Run the program with an X value of 5.0 6.0 ! The final result The COD file must contain a colon definition. Code not contained in a colon definition are run as the file is read in. Assume the TMP.COD file contains the following lines: VAR 2PI 2 PI * 2PI STO : FUNC X 2PI RCL * P1 / COS ; While this file is being read, the variable 2PI is created and loaded with the value of 2*PI. The function FUNC can now access and use this variable. If the file contains several : definitions, then it is always the last definition that the fitting routine in PLT uses. 1 forth People who have used the Forth (Forth is a registered trademark of Forth, Inc.) computer language will recognize certain similarities with COD. This is partly by accident since both COD and Forth were created to solve the problem of making a very fast interpreted language. Given the similarity, it would be pointless for similar functions to be implemented differently in the two languages. Therefore, it is the intention of the current author to add new COD functions using Forth as the model. Thus, with time, COD will evolve into a dialect of Forth. THERE IS NO INTENTION TO MAKE COD 100 PERCENT COMPATIBLE WITH FORTH. Forth is designed to be a computer language in its own right, whereas, COD is designed to handle advance mathematical functions. Since COD programmers will spend most of their time working in other languages, it will be important that COD programs are clear and straight forward. 2 differences Forth uses an integer stack, whereas COD will always use a real stack. Forth ! +! and @ The ! character denotes a comment in the PLT parser. For consistency this has not been changed. If @ is the first character on a line then it denotes a request to read an indirect file. To avoid potential conflicts, these three functions have been called STO +STO and RCL (which have the side effect of making COD programs more readable to outsiders). Forth DO The termination condition of Forth DO loops differs from the convention used in Fortran, BASIC, Pascal, Ada, Modula, C, etc. In order to avoid potential problems COD does not implement DO but rather a FOR statement. Forth ( ) In Forth comments are enclosed in ( and ) tokens. With the PLT parser comments begin with ! and continue to the end of the line. Forth NEGATE VARIABLE In COD these are called NEG and VAR. 2 implementation Currently COD like Forth implements an INTEGER*2 return stack. COD uses the return stack slightly differently than Forth. The top number on the return stack is always the address of the word that loaded the stack. Hence the FOR statement pushes onto the return stack, the maximum, the index and also the address of the FOR statement. This has two beneficial effects. First, the LOOP word can quickly find the address to LOOP to and second, the EXIT statement can correctly unwind the return stack. The COD words . and ? print a single number followed by a carriage return linefeed. This makes it difficult to do formatted IO. In the future a buffer command will be added (see the 'future' topic). The COD words that require forward jumps (IF ELSE WHILE) are implemented using two memory locations. When the program is first loaded, the second location is loaded with zero. The first time COD executes the forward jump, it searches through the program to find the target address. This address is then stored in the second memory location. In the future when the word is executed, the jump is made much quicker since no search is required. COD does not allow you to redefine dictionary words the way Forth does. For example, in Forth you could redefine the word "+" to subtract the top two numbers on the stack. Redefining keywords, is OK for single one-off programs, but in the long run tend to cause more harm than good. 2 omissions 79-STANDARD Due to the Forth INTEGER stack and COD's REAL stack, COD will never completely agree with any Forth standard. D+ DNEGATE D< */ */MOD In Forth a 'double precision' denotes an INTEGER*4 number. These double precision operators were provided to overcome the limitations of trying to do useful calculations on an INTEGER*2 stack. (If 'double precision' numbers are ever implemented in COD, then it is likely that these numbers would use a different stack.) U* U/MOD U< U. These words allow Forth to manipulate INTEGER*2 numbers as unsigned numbers in the range 0..65535. Again the main purpose of these words are to allow users to do something useful with INTEGER*2 numbers. >R R< R@ In Forth users can use the return stack as a temporary place to hold numbers. New users are advised to be very careful as the return stack is used by the system for system booking. Experts use the the return stack to write very obscure programs. Due to the fact that in COD the main stack is REAL*4 and the return stack is INTEGER*2, using the return stack as a temporary storage location would not work. Currently COD does not allow the user to directly manipulate the return stack to encourage cleaner code. FORTH CONTEXT CURRENT DEFINITIONS VOCABULARY These words provide Forth a way to give the same word different meanings in different 'modes'. This can result in very confusing programs, not to mention very obscure bugs and therefore will not be implemented in COD. 1 future The current plans are to include a more Forth words into COD. Users are invited to suggest changes direct to the author at Span address SSL::TENNANT . CONSTANT CREATE DOES> ALLOT These words will allow the creation of more general data structures. AND OR XOR In Forth these words preform bitwise logical operations on INTEGER*2 number. Bitwise logical operations would be rather useless on REAL numbers, hence COD will use these functions solely as logical tests. For example, if the top two numbers on the stack are A and B then A B AND will return 1.0 if (A.NE.0 .AND. B.NE.0) otherwise 0.0 is returned. FORGET This word causes all definitions to be erased back to and including the word . This will provide a way for interactive users of COD to 'erase' their most recent attempts. ." This will be added to print out strings. When this is done then COD files will no longer echo when they are read in. Instead it will be up to the programmer to put in ." statements, to print out as the file is read, that document the file. New COD words: .< >. It is impossible to implement Forth style IO in Standard Fortran. The current plans are to implement a buffer command. When buffering is on then the . word will output to the buffer. When the buffer is filled, or a line termination condition is set then the buffer will be displayed on the users terminal. This will allow ways on doing formatted IO. The current plans are to use .< to start buffering and >. to end. Hence, .< . . . >. would print three numbers on the same line. Once this command is implemented then several Forth IO words will follow. [ ] LITERAL These words provide a way of doing a quick calculation inside a colon definition, but only storing (and using) the result. The interactive COD program will be improved. You should be allowed to single step any colon definition. You should be allowed to save the current program. You should be allowed to insert and delete lines from the current program. You should be allowed to set break points. At this stage it is unclear whether the user should make changes in 'text' space or 'compiled code' space or both. Working in text space would preserve the structure and comments of the original COD file that was read. Working in code space will give the user greater control. Comments welcome. 1 GEt Reads in a COD program. Example, COD> GET POWERMOD will read in the file POWERMOD.COD from your current directory. The GET command completely resets all COD internal parameters. All existing colon definitions and variables are forgotten. Note, COD words not inside colon definitions will be executed as the file is being read. 1 List List can be used to list out the current COD program or the list the current parameter values. 2 Code This option lists the compiled form of the COD program. COD> List C ! will list the entire COD program COD> List C 10,20 ! will list lines 10 to 20 of the current COD program 2 Dictionary List all the currently available built-in functions. 2 Equations WARNING: This function can fail. Do not use blindly. This option can be used to view the COD program as a sequence of equations. In this format, it is sometimes easier to spot bugs. If the equation is longer than 40 characters then to prevent a character array overflow, this function define a variable Tx (where x is a number). This variable is printed out as Tx=={definition}. For the rest of the equation the variable Tx is used. Note this use of temporary variables is used only by the listing program and does not affect the way the function is evaluated. Example, consider the following COD program: : TST P1 X P2 * + ; COD> LIST E P1+X*P2 2 Par The List Par command is used to list out all the current parameter values. 1 Newpar Allows you to enter new parameter values when testing a COD program. Example: COD> GET TEST ! reads in the program in TEST.COD COD> NEW 1 2.0 ! sets parameter 1 equal to 2.0 COD> NEW 2 3.0 ! sets parameter 2 equal to 3.0 COD> RUN ! runs program TEST with the current parameter values. 1 Quit Exit from the COD program. 1 RUn Runs the COD program that was read in with the GEt command. The top number in the stack is stored in X. The stack is then cleared and the program is run. If the COD file contains any parameters then you should set these using the Newpar command. You can also run a COD program just by entering the name of the colon definition. However, this is not quite the same, and the Run command clears the stack, whereas if you use the name, the stack is unaffected when the program starts. Also, when using just the name, the X constant is not loaded. Run should be used to test COD files before use in PLT/FIT as Running the program will produce the same effect as calling it from FIT. If your file contains several colon definitions then Run (and the FIT program) will always run the last definition in the file. Note, interactively adding more colon definitions does not affect the program that is run with the Run command. 1 Step Single step the current COD program. The first single step in the program will read an X value of the top of the stack and then reset the stack. These actions are the same as when you RUn a COD program. You are not allowed to Step past a math error or the end of the program. Step Init This will reset the program counter to the current entry point. This has the effect of restarting the program and is the same thing that the Run command does before starting. Step [Init] # Will generate # single Step operations, hence Step 10 will take 10 steps and Step I 20 will run the first 20 program steps. 1 version 2005-Apr-22 - Add gamma function called gamm. 2005-Apr-22 - 0 ^ X now returns 0 if X is non-zero.