HP OpenVMS Systems Documentation |
HP BASIC for OpenVMS
|
Previous | Contents | Index |
HP BASIC supplies functions to return the date and time in numeric or string format. The following sections discuss these functions.
Note that you can also use certain system services and Run-Time Library
routines for more sophisticated date and time functions. See the
HP OpenVMS System Services Reference Manual and the VMS Run-Time Library Routines Volume for more information.
10.1.5.1 DATE$ Function
The DATE$ function returns a string containing a day, month, and year in the form dd-Mmm-yy. The date integer argument to the DATE$ function can have up to six digits in the form yyyddd, where yyy specifies the number of years since 1970 and ddd specifies the day of that year. If the numeric expression is zero, DATE$ returns the current date.
PRINT DATE$(0) PRINT DATE$(126) PRINT DATE$(6168) END |
15-Jun-85 06-May-70 16-Jun-76 |
If you supply an invalid date (for example, day 370 of the year 1973), the results are undefined.
See Section 10.1.5.2 for the recommended replacement for DATE$, which has
a two-digit year field in the result string.
10.1.5.2 DATE4$ Function
The DATE4$ function is strongly recommended as replacement for the DATE$ function to avoid problems in the year 2000 and beyond. It functions the same as the DATE$ function except that the year portion of the result string contains two more digits indicating the century. For example:
PRINT 32150, DATE$ (32150), DATE4$ (32150) |
Produces the following output:
32150 30-May-02 30-May-2002 |
See the description of the DATE$ function for more information.
10.1.5.3 TIME$ Function
The TIME$ function returns a string displaying the time of day in the form hh:mm AM or hh:mm PM. TIME$ returns the time of day at a specified number of minutes before midnight. If you specify zero in the numeric expression, TIME$ returns the current time of day. For example:
PRINT TIME$(0) PRINT TIME$(1) PRINT TIME$(1440) PRINT TIME$(721) END |
03:53 PM 11:59 PM 12:00 AM 11:59 AM |
The TIME function requests time and usage information from the operating system and returns it to your program. The information returned by the TIME function depends on the value of the argument passed to it. The values and the information they return are as follows:
Value | Information Returned |
---|---|
0 | Returns the number of seconds elapsed since midnight |
1 | Returns the current job's CPU time in tenths of a second |
2 | Returns the current job's connect time in minutes |
3 | Returns zero |
4 | Returns zero |
All other arguments to TIME are undefined and cause HP BASIC to
signal "Not implemented" (ERR=250).
10.1.6 Terminal Control Functions
HP BASIC provides several terminal control functions. These functions let you:
The CTRLC function enables Ctrl/C trapping, and the RCTRLC function disables Ctrl/C trapping. When Ctrl/C trapping is enabled, control is transferred to the program's error handler when Ctrl/C is detected at the controlling terminal.
Ctrl/C trapping is asynchronous. The trap can occur in the middle of an executing statement, and a statement so interrupted leaves variables in an undefined state. For example, the statement A$ = "ABC", if interrupted by Ctrl/C, could leave the variable A$ partially set to "ABC" and partially left with its previous contents.
For example, if you type Ctrl/C to the following program when Ctrl/C trapping is enabled, an "ABORT" message prints to the file open on channel #1. This lets you know that the program did not end correctly.
WHEN ERROR USE error_handler Y% = CTRLC . . . END WHEN HANDLER error_handler IF ERR = 28 THEN PRINT #1%, "Abort" . . . END HANDLER |
When you trap Ctrl/C with an error handler, your program might be in an inconsistent state; therefore, you should handle the Ctrl/C error and exit the program as quickly as possible. |
The NOECHO function disables echoing on a specified channel. Echoing is the process by which characters typed at the terminal keyboard appear on the screen.
If you specify channel #0 (your terminal) as the argument, the characters typed on the keyboard are still accepted as input; however, they do not appear on the screen.
The ECHO function enables echoing on a specified channel and cancels the effect of the NOECHO function on that channel.
If you do not use these functions, ECHO is the default. The following program shows a password routine in which the password does not echo:
Y% = NOECHO(0%) INPUT "PASSWORD"; pword$ IF pword$=="PLUGH" THEN PRINT "THAT IS CORRECT" END IF Y% = ECHO(0%) END |
Note that the Y% = ECHO(0%) statement is necessary to turn the echo
back on. If this statement were not included, then all subsequent user
inputs would not echo to the terminal screen.
10.1.6.3 INKEY$ Function
The INKEY$ function reads a single keystroke from a terminal opened on a specified channel and returns the typed character.
If you specify a channel that is not open, HP BASIC signals the error "I/O channel not open" (ERR=9). If a file or a device other than a terminal is open on the channel, HP BASIC signals the error "Illegal operation" (ERR=141).
Once you have specified a channel, HP BASIC allows you to specify an optional WAIT clause. A WAIT clause followed by no value tells HP BASIC to wait indefinitely for input to become available. A WAIT clause followed by a value from 1 to 255 tells HP BASIC to wait the specified number of seconds for input.
DECLARE STRING KEYSTROKE Inkey_Loop: WHILE 1% KEYSTROKE = INKEY$(1%,WAIT) SELECT KEYSTROKE CASE '26'C PRINT "Ctrl/Z to exit" EXIT Inkey_Loop CASE CR,LF,VT,FF,ESC PRINT "Line terminator" CASE "PF1" TO "PF4" PRINT "P key" CASE "E1" TO "E6" PRINT "VT200 Function key" CASE "KP0" TO "KP9" PRINT "Application keypad key" CASE < SP PRINT "Control character" CASE '127'C PRINT "<DEL>" CASE ELSE PRINT "Character is "; KEYSTROKE END SELECT NEXT |
The DEF statement lets you create your own single-line or multiline functions.
In HP BASIC, a function name consists of the following:
Integer function names must end with a percent sign (%), and string function names must end with a dollar sign ($); therefore, the function name can have up to 31 characters. If the function name ends with neither a percent sign nor a dollar sign, the function returns a real number.
You can create user-defined functions using these function naming rules; however, it is recommended that you use explicit data typing when defining functions for new program development. See Chapter 12 for an example of an explicitly declared function. Note that the function name must start with FN only if the function is not explicitly declared, and a function reference lexically precedes the function definition.
DEF functions can be either single-line or multiline. Whether you use the single-line or multiline format for function definitions depends on the complexity of the function you create. In general, multiline DEF functions perform more complex functions than single-line DEF functions and are suitable for recursive operations.
If you want to pass values to a function, the function definition
requires a formal parameter list. These formal parameters are the
variables used to calculate the value returned by the function. When
you invoke a function, you supply an actual parameter list; the values
in the actual parameter list are copied into the formal parameter at
this time. DEF functions allow up to 255 formal parameters. You can
specify variables, constants, or array elements as formal parameters,
but you cannot specify an entire array as a parameter to a DEF function.
10.2.1 Single-Line DEF Functions
In a single-line DEF, the function name, the formal parameter list, and the defining expression all appear on the same line. The defining expression specifies the calculations that the function performs. You can pass up to 255 arguments to this function through the formal parameter list. These parameters are variables local to the function definition, and each formal parameter can be preceded by a data type keyword.
The following example creates a function named fnratio. This function has two formal parameters: numer and denomin, whose ratio is returned as a REAL value.
When the function is invoked, HP BASIC does the following:
The PRINT statement then prints the returned value.
DEF REAL fnratio (numer, denomin) = numer / denomin PRINT fnratio(5.6, 7.8) END |
.717949 |
Note that the actual parameters you supply must agree in number and data type with those in the formal parameter list; you must supply numeric values for numeric variables, and string values for string variables.
The defining expression for a single-line function definition can contain any constant, variable, HP BASIC built-in function, or any user-defined function except the function being defined. The following examples are valid function definitions:
DEF FN_A(X) = X^2 + 3 * X + 4 DEF FN_B(X) = FN_A(X) / 2 + FN_A(X) DEF FN_C(X) = SQR(X+4) + 1 DEF CUBE(X) = X ^ 3 |
Note that the name of the last function defined does not begin with FN. This is valid as long as no reference to the function lexically precedes the function definition.
You can also define a function that has no formal parameters. The following function definition uses three HP BASIC built-in functions to return an integer corresponding to the day of the month:
DEF INTEGER fnday_number = VAL% (SEG$(DATE$(0%), 1%, 2%)) |
The DEF statement can also define multiline functions. Multiline DEF functions are useful for expressing complicated functions. Note that multiline DEF functions do not have the equal sign and defining expression on the first line. Instead, this expression appears in the function block, assigned to the function name.
If a multiline DEF function contains DATA statements, they are global to the program unit. |
Multiline function definitions can contain any constant, variable, HP BASIC built-in function, or user-defined function. In HP BASIC, the function definition can contain a reference to the function you are defining. Therefore, a multiline DEF function can be recursive, or invoke itself; however, HP BASIC does not detect infinitely recursive DEF functions during compilation. If your program invokes an infinitely recursive DEF function, HP BASIC will eventually signal a fatal run-time error, typically the error "Access violation."
You can use either the END DEF or EXIT DEF statements to exit from a user-defined function. The EXIT DEF statement is equivalent to an unconditional transfer to the END DEF statement.
The following example shows a multiline DEF function that uses both the EXIT and END DEF statements. The defining expression of the function is in the ELSE clause. This assigns a value to the function if A is less than 10. The second set of output shows what happens when A is greater than 10; HP BASIC prints "OUT OF RANGE" and executes the EXIT DEF statement. The function returns zero because control is transferred to the END DEF statement before a value was assigned. In this way, this example tests the arguments before the function is evaluated.
DEF fn_discount(A) IF A > 10 THEN PRINT "OUT OF RANGE" EXIT DEF ELSE fn_discount = A^A END IF END DEF INPUT Z PRINT fn_discount(Z) END |
? 4 256 |
? 12 OUT OF RANGE 0 |
If you do not explicitly declare the function with the DECLARE statement, the restrictions for naming a multiline DEF function are the same as those for the single-line DEF function; however, explicitly declaring a DEF function can make a program easier to read and understand. For instance, Example 1 concatenates two strings and Example 2 returns a number in a specified modulus.
DECLARE STRING FUNCTION concat (STRING, STRING) !Declare the function . . . DEF STRING concat (STRING Y, STRING Z) concat = Y + Z !Define the function FNEND . . . new_string$ = concat(A$, B$) !Invoke the function . . . END |
DECLARE REAL FUNCTION mdlo (REAL, INTEGER) DEF mdlo( REAL argument, INTEGER modulus ) !Check for argument equal to zero EXIT DEF IF argument = 0 !Check for modulus equal to zero, modulus equal to absolute !value of argument, and modulus greater than absolute !value of argument. SELECT modulus CASE = 0% EXIT DEF CASE > ABS( argument ) EXIT DEF CASE = ABS( argument ) mdlo = argument EXIT DEF END SELECT !If argument is negative, set flag negative% and set argument !to its absolute value. IF argument < 0 THEN argument = ABS( argument ) negative% = -1% END IF UNTIL argument < modulus argument = argument - modulus !If this calculation ever results in zero, mdlo returns zero IF argument = modulus THEN mdlo = 0 EXIT DEF END IF NEXT !Argument now contains the right number, but the sign might be wrong. !If the negative argument flag was set, make the result negative. IF negative% THEN mdlo = - argument ELSE mdlo = argument END IF END DEF INPUT "PLEASE INPUT THE VALUE AND THE MODULUS"; X,Y PRINT mdlo(X,Y) END |
PLEASE INPUT THE VALUE AND THE MODULUS? 7, 5 2 |
Because these functions are declared in DECLARE statements, the function names do not have to conform to the traditional HP BASIC rules for naming functions.
Recursion occurs when a function calls itself. The following example defines a recursive function that returns a number's factorial value:
DECLARE INTEGER FUNCTION factor ( INTEGER ) DEF INTEGER factor ( INTEGER F ) IF F <= 0% THEN factor = 1% ELSE factor = factor(F - 1%) * F END IF END DEF INPUT "INPUT N TO FIND N FACTORIAL"; N% PRINT "N! IS"; factor(N%) END |
INPUT N TO FIND N FACTORIAL? 5 N! IS 120 |
Any variable accessed or declared in the DEF function and not in the formal parameter list is global to the program unit. When HP BASIC evaluates the user-defined function, these global variables contain the values last assigned to them in the surrounding program module.
To prevent confusion, variables declared in the formal parameter list should not appear elsewhere in the program. Note that if your function definition actually uses global variables, these variables cannot appear in the formal parameter list.
You cannot transfer control into a multiline DEF function except by invoking it. You should not transfer control out of a DEF function except by way of an EXIT DEF or END DEF statement. This means that:
A DEF function never changes the value of a parameter passed to it. Also, because formal parameters are local to the function definition, you cannot access the values of these variables from outside the DEF statement. These variable names are known only inside the DEF statement.
In the following example, the variable first is declared only in the function fn_sum. When HP BASIC sees the second PRINT statement, it assumes that first is a new variable that is not declared in the main program. If you try to run this example, HP BASIC signals the error "Explicit declaration of first required." If you do not specify the OPTION TYPE = EXPLICIT statement, HP BASIC assumes that first is a new variable and initializes it to zero.
OPTION TYPE = EXPLICIT DECLARE INTEGER A, B DEF fn_sum(INTEGER first, INTEGER second) = first + second A = 50 B = 25 PRINT fn_sum(A, B) PRINT first END |
Previous | Next | Contents | Index |