| Home | Why Omnibasic | Features | FAQ | Examples |
|---|---|---|---|---|
| Reviews | Keyword/Syntax | On-Line Manual | Download Manual | ScreenShots |
Chapter 10 Part 1Standard Statements and FunctionsDIMThe DIM statement is used to declare and define variables for use in the program. If a variable is used that has not been DIMensioned, it has a default type of LONG unless the name ends in “$” or “_Str” in which case the default is type STRING[32]. If the -d command line option is invoked, there are no default data types and each variable must be DIMensioned. The DIM statement may appear anywhere in a main program, but must appear before being referenced. The DIM statement may not appear in a subroutine. The general syntax of the DIM statement is as follows:
The syntax of the DIM statement is slightly different for string variables and is as follows:
The DIM keyword is followed by the variable name. The optional array size is then stated (in parentheses). There may be 1, 2, or 3 diminsions for arrays. A comma separates these diminsions. This is followed by a mandatory “:” or “AS”. The data type is then specified. (“DIM X:LONG” or “DIM X as LONG”). Next the optional modifiers are declared. The valid data types are BOOLEAN or LOGICAL, BYTE or CHAR, SHORT, INT, or WORD (16 bit integer), LONG or INTEGER (32 bit integer), FLOAT or REAL (floating point) , FILE, and STRING (also OBJECT and FORM for GUI versions). The valid modifiers are EXTERNAL, GLOBAL, ADDRESS or POINTER, and VECTOR. The BOOLEAN data type is eight bits in length and is capable of two states: TRUE and FALSE. The BYTE data type is an 8-bit integer. The SHORT data type is a 16-bit integer, while the LONG type is a 32-bit integer. The EXTERNAL modifier means the actual variable is in another module so no space will be allocated for it. The GLOBAL modifier makes the variable known to other modules. The ADDRESS modifier causes the variable to become an ADDRESS Pointer of the data type specified (see section on Address Pointers). The VECTOR modifier causes the variable to be assigned to a special 12-byte vector. A VECTOR (like a pointer) cannot be used until an address is assigned to it. Once an address is assigned, (SETVEC VarName=Addr) the VECTOR behaves just as an ordinary variable and requires no special syntax. Now for some examples: DIM Test(4) AS INTEGER \ creates an integer array of 4 elements called Test TYPEThe TYPE statement allows the user to define custom data types for the application at hand. Once a TYPE statement defines a data type it may be DIMinsioned like a standard data type. The TYPE statement may not appear inside a function or subroutine. The general syntax of the TYPE statement is as follows:
The TypeName then becomes a new user defined data type. The new data type is then DIMensioned like any other variable and the resultant variable is accessed by the variable name followed by a period followed by the field name. The data types used within the TYPE statement must be of the standard types described above in the DIM section (not other user defined types). The fields within the TYPE may be simple or arrays and the variables later DIMensioned of data type TypeName may be simple or arrays. An example of a TYPE declaration, DIMensioning of the resultant data type, and the use of the variable follow:
The TYPE statement may also be expressed as a group, which is terminated by END TYPE or ENDTYPE.
BEEPThe BEEP statement causes an audible beep. There are no arguments to this statement. RANDOMIZEThe RANDOMIZE statement is used to change seed of the random number generator.
If IntVar is ommited, the timer is used as the seed. PROGRAMThe PROGRAM Statement is used to tell the compiler where the code section of the program is to begin. It is almost never required because the compiler “knows” when the code is to begin EXCEPT if the first line of code is C or Assembler. If the first line of code is C, C++ or Assembler, use the program statement immediately preceding the first line of code. HEXOUTThis statement allows control over the output of the Hex$() function. In the examples below, the compiler checks only the first letter. The default is Motorola ($ffff). HEXOUT motorola (preceeds hex value with “s”) GOTO, GOSUB, RETURNThe GOTO and GOSUB Statements are used in conjunction with labels to transfer program control. Both statements unconditionally transfer control to the designated label but the GOSUB statement saves the address of the next sequential statement on a stack so that the RETURN statement (in the called subroutine) causes control to resume where it left of when the GOSUB occurred. Structured programming techniques do not encourage the use of the GOTO statement, but rather prefer the IF/ ENDIF, WHILE/ENDWHILE and PROCEDURE constructs as well as others. The following is an example of the use of the GOTO statement:
The GOSUB (GO SUBROUTINE) statement is used when it is required for the program to resume where it left off after the called subroutine is finished and executes a RETURN statement. The RETURN statement should only be used to terminate a subroutine or function. At the end of the compilation process an accounting of all unresolved references to labels is given. Labels being referenced outside the module must be declared. This is accomplished by using the label name (in column #1) followed by the word “EXTERNAL”. This will satisfy the compiler but if the label is not really used in another module to be linked, a linker error will occur. What actually occurs is that the label is put into the symbol table but no code is generated. Once a label is declared as EXTERNAL it cannot also be a local label and if it is a linker error will occur. Also, if there is a GOSUB to a particular subroutine, that subroutine must exist. IMPORTANT!The last statement of a subroutine must be a RETURN. Any RETURN statement before the end of a subroutine must be inside a control structure such as a FOR loop or WHILE/ENDWHILE block. Violations of these rules will result in a “nesting” error. The RETURN statement transfers control back to the caller and is also used to return integer or floating point data to the caller in the case of integer or floating point functions. For example:
There are also special “computed” GOTO and GOSUB statements as well as run-time error vectoring. Refer to the sections on ON GOTO, ON GOSUB and ON ERROR GOTO for a detailed description of these statements. ON...GOTO, ON...GOSUB, ON ERRORThe ON...GOTO and ON...GOSUB statements are used to branch or branch to subroutine based on the value of and integer expression. The general syntax is as follows:
The value X is any integer-valued expression. The list of Labels is ordered list of vectors which are invoked based upon the value of X and the Label’s position in the list. For example, if X evaluates too 2, then the program will GOTO or (GOSUB) to Label2 in the list. If X evaluates to less then 1 or more than the position of the last Label in the list, the next statement in line will be executed. These statements are sometimes referred to as Computed GOTO or Computed GOSUB. An example of the Computed GOTO follows:
An equivalent program not using the Computed GOTO follows:
The ON ERROR statement is used to trap any run-time error and vector control to the Label specified in the statement. An ON ERROR statement without a GOTO turns off the trap.
FOR, TO, STEP, NEXTThe FOR loop control structure begins with the FOR statement followed by the loop variable (an integer) followed by the TO verb followed by the limit expression (an integer) followed by an optional STEP verb with its step expression (an integer) followed by the loop body followed by the NEXT statement which includes the loop variable. The loop variable following the NEXT is optional. The body of a FOR loop will not execute at all if the loop variable has exceeded the limit variable. The comparison is a >= test (<= if step is negative). As with all control structures, the FOR loop structure may also be exited with the EXITIF statement. It is good programming practice to indent statements within the structure for better readability. Some examples follow:
The above example is equivalent to:
IF, THEN, ELSE, ENDIFThe IF, ELSE, and ENDIF statements are used to test conditions and direct program flow based on the result of the test. The statements are normally used together in a control structure (ELSE is optional) except in one special case in which, the THEN is followed by a LABEL. In this case (which is provided for compatibility with older Basics) there is no assumed structure to follow such as ELSE or ENDIF. ENDIF may also be expressed as END IF. Except in the case where THEN is followed by a LABEL (or line number), the THEN clause may be ommited. The following is an example of the special case mentioned above:
In this example there is no control structure. Each time the IF statement is encountered, the variable A is tested and if it is less than 100 the program loops back to the label Loop. In the control structure case the structure begins with the IF statement, is optionally followed by the ELSE statement, and ends with the ENDIF statement. It is good programming practice to indent statements within the structure for better readability. For example:
IF statements may also be used in conjunction with the boolean operators AND and OR. In addition, IF statements may be nested. Also the control structure may be exited before the ENDIF statement is reached by using the EXITIF statement. For example:
The compiler keeps track of the control structures and reports an error if there are any unbalanced control structures in the program. SELECT CASE, CASE, END SELECTThe SELECT CASE, CASE, and END SELECT statements form a control structure, which is useful for testing a number of cases of a test variable. ENDSELECT may also be expressed as END SELECT. A numerical example:
A string example:
ENDCASE may also be expressed as END CASE. (ENDCASE IS OPTIONAL) WHILE, DO, ENDWHILEThe WHILE/DO/ENDWHILE control structure begins with the WHILE statement followed by the test condition followed by the DO verb followed by the body followed by the ENDWHILE statement. The DO verb is optional. ENDWHILE may also be expressed as END WHILE or WEND. In this control structure, the condition is tested before any code in the body is executed. At each pass through the structure, the condition as tested and as long as the condition is true, the code body is executed. As with all control structures, the WHILE/DO/ENDWHILE structure may also be exited with the EXITIF statement. It is good programming practice to indent statements within the structure for better readability. For example:
The WHILE statement may also contain the boolean operators AND and OR. For Example:
An equivalent to the above example would be:
REPEAT, UNTILThe REPEAT/UNTIL control structure begins with the REPEAT statement followed by the body followed by the UNTIL statement where a condition is tested. If the condition is true, the program proceeds to the next statement after the UNTIL statement. If the condition is false, control goes to the statement following the REPEAT statement. As with all control structures, the REPEAT/UNTIL structure may also be exited with the EXITIF statement. It is good programming practice to indent statements within the structure for better readability. For example:
In the above example the user will be prompted to enter data to the INPUT statement until a value of 4 is entered. When a 4 is entered “done” will be printed on the CRT. Since the condition is tested at the “bottom” of the control structure, the statement(s) in the body of the structure will always be executed at least once. The UNTIL statement may also contain the boolean operators AND and OR.
An equivalent to the above example would be:
LOOP, LOOP COUNT, ENDLOOP, EXITIF, ENDEXIT, CONTINUEThe LOOP/ENDLOOP control structure is an unconditional loop, which will never end unless an EXITIF statement is used in the body of the loop (or a GOTO statement leaves the loop). While the GOTO statement will cause the loop to be exited, it is considered bad (or at least unstructured) programming practice. ENDLOOP may also be expressed as END LOOP. The general use of the LOOP/ENDLOOP control structure is as follows:
In the example above, the variable A is decremented until it reaches a value of 0 at which time the control structure is exited. Using the LOOP COUNT statement an equivalent structure can be made as follows:
There are some restrictions on the use of the LOOP COUNT statement: As many LOOP/COUNT’s may be active as desired, but care must be taken to exit “gracefully” by letting the count expire or by using the EXITIF statement because the LOOP/COUNT (unlike the other control structures) uses a stack for nesting purposes. Therefore, jumping into the middle of a LOOP/COUNT structure will also cause a stack imbalance. The EXITIF statement may also be used with an optional THEN followed by a body of code followed by an ENDEXIT statement. This form allows the coding of an “end event” before exiting the structure. ENDEXIT may also be expressed as END EXIT. For example:
The CONTINUE statement may be used in any of the OmniBasic control structures to start the next iteration without completing the current one. CONTINUE must be followed by IF. For example:
This may be used with:
The effect is to do the next iteration inside the control structure. DATA, RESTORE, READThe DATA statement is used to build tables of constants. The constants may be integer (long), string, boolean, or floating point. The first DATA statement in a list or table must be a labeled statement so that the RESTORE statement can set the DATA read pointer at the beginning of the list. The data in the list is read using READ statements until the data is exhausted at which time the read pointer is reset to the value of the last RESTORE statement. The general syntax for the DATA statement is as follows:
The Label is required on the first line of a data list and is referenced by the RESTORE statement. The term “Element” refers to an integer, floating point, boolean, or string constant. Integer constants may be expressed as compiler variables which will assume the value of the last #SET directive for that compiler variable. Commas separate the Elements. The RESTORE statement in OmniBasic requires the label argument, which is used to point to the beginning if the DATA table to be read. The general syntax of the RESTORE statement is as follows:
This statement causes the read data pointer to point to the data at Label. It should be noted here that the RESTORE statement will point to any Label it is instructed to whether there are DATA statements there or not. The READ statement accesses the data sequentially through the data table and assigns the data to the variables specified in the READ statement. It is important to maintain a correspondence between the order of the data in the DATA statements and the variables in the READ statement. The general syntax of the READ statement is as follows:
The READ keyword is followed by a space followed by a list of variables separated by commas. The data type of the variables should correspond to the implied data type of the data in the DATA list being read. For instance reading a quoted string into an integer variable would have unpredictable and possibly disastrous effect. The following is an example using the DATA, RESTORE, and READ statements:
In the above example we read the data into arrays of corresponding data type. The FOR loop terminates before the data in the data-table runs out. In the following example the reading of the data in the data table will terminate by detecting a flag in the data itself.
LET, ERR, STATUS, NextArg, POS, XferCount, ProgramNameThe LET statement is used to assign a value to a variable. There is also a form of the LET statement, which is referred to as the IMPLIED LET statement. The IMPLIED LET statement is simply a LET statement in which the LET keyword is omitted. Most programs and programmers opt for the IMPLIED LET form. The general syntax is as follows:
The IMPLIED LET form is:
The expression (Expr) must be of the same data class as the variable (Var) or a type mismatch error will occur. If the variable is a BYTE type and the expression is a SHORT OR LONG type, the expression result is demoted to the BYTE type. The same type of demotion occurs if the variable is a SHORT type and the expression is a LONG type. If the variable is a LONG type and the expression is a BYTE or SHORT type, the expression is promoted etc. When a result is demoted, the result is truncated to the destination data size. The special variable ERR is set when an error occurs to the code of that error. If the program has set up an ON ERROR GOTO trap, the trap can test this variable to see what type of error has occurred. ERR is synonymous with error (the standard C error variable). The special variable STATUS contains the status of the last input/output operation. Using the STATUS prefix to an input/output operation may circumvent error trapping. The special variable XferCount is set to the value of STATUS after a successful I/O operation.
The special variable NextArg is a variable of type STRING. It may be “read” but cannot be set. The use of NextArg involves setting a STRING variable to NextArg. Each time a STRING is assigned NextArg, the next argument of the command line is extracted. Each time an argument is extracted, the user should check the length to determine if this argument is the last. The arguments use “space” as a delimiter. The following example prints the arguments of the command line. Keep in mind that the arguments may be scanned only once in a program.
The special variable POS is set by the PRINT statement to the last print position reached. It is of data type LONG. The special variable XferCount is used to determine the number of bytes transferred on the last I/O operation. It is of data type LONG. The special use of the ProgramName is set when the program is loaded for execution by the system.
BUFFER, BUFADR(), BUFSIZ(), SETBUFADRThe BUFFER statement in conjunction with the BUFADR and BUFSIZ functions allows the use of dynamically allocated memory buffers with OmniBasic. The primary use of this capability is when it is not known what size (volume) the data will be at compile time. An example of this condition might be when using OmniBasic to write an editor program. When a command is encountered to read a file into the edit buffer the size of that file is unknown at compile time. Therefore the program could be written to check the file size and allocate an appropriately sized memory buffer. The explanation in the use of memory buffers necessarily involves the use of pointer variables or vectors (not a part of ordinary BASIC(s)) so a study of data types may be in order. The general syntax of the BUFFER statement is as follows:
BufName is any valid OmniBasic symbol name and must be unique from any other symbol name used in the program including variables, labels, etc. If the BufName has not been used already in the program, it will be added to the symbol table. The equal sign is required and is followed by an integer expression. The system will (at run time) attempt to allocate BufSize bytes to the program. If the spare memory is not available, a system error will be returned. Also the BUFSIZ function may be used to verify the amount of memory actually granted. The amount of the memory may be rounded up to an integral of the system minimum allocation value. If and when the program is done with the memory buffer, the buffer may be returned to system memory. The syntax for accomplishing this is the same as the BUFFER statement already shown with two exceptions. The BufSize is set to zero (0) and must be a constant (not a variable). An example of this is as follows:
Or
An example of setting up a memory buffer and assigning a pointer variable to it follows:
It is important to avoid re-assigning buffers before releasing them or going out of bounds. The SETBUFADR statement allows just one buffer structure to control any number of buffers by maintaining a table of open buffers and then closing any buffer by:
(NOTICE: This is for advanced programmers; be advised that an invalid SETBUFADR can cause a system crash or data loss.) INC, DEC, INDEX(), SETVECThe INC and DEC statements are used to add or subtract one to or from the integer variable specified. Also the INC and DEC statements may be used to add or subtract the size of the data type pointed to by a pointer variable. This allows pointer variables to sequentially scan arrays. The INDEX() function is used to index pointer variables and is useful to randomly access arrays in memory. The General form of the INC and DEC statements is as follows:
Examples of the INC and DEC statements follow:
Note that the INC and DEC statements do not work with data type float. The general form of the INDEX() function is as follows:
For example:
The SETVEC statement is used to assign an address to a VECTOR. SETVEC VarName=Addr |
Home || Why Omnibasic || Features || FAQ || Examples
Reviews || Links || Privacy Statement || Top of Page
Innomation Systems, Inc.
117 Morrison Ave. Morrison, MO 65061 (573) 294-6130
OmniBasic is a
trademark of Innomation Systems, Inc., other trademarks are the property of their
respective owners.
Innomation Systems, Inc. reserves the right to change prices and specifications without prior notice.
Copyright © 2000, 2001, 2002 Innomation Systems, Inc.