Compaq BASIC for OpenVMS
Alpha and VAX Systems
DECLARE LONG rec-num
MAP (cusrec) WORD cus_num &
STRING cus_nam=20, cus_add=20, cus_city=10, cus_zip=9
OPEN "CUS_ACCT.DAT" FOR INPUT AS #1, &
RELATIVE FIXED, &
ACCESS MODIFY &
INPUT "Which record number would you like to delete";rec_num
FIND #1, RECORD rec_num, WAIT
The FIX function truncates a floating-point value at the decimal point
and returns the integer portion represented as a floating-point value.
- The FIX function returns the integer portion of a floating-point
value, not an integer value.
- BASIC expects the argument of the FIX function to be a real
expression. When the argument is a real expression, BASIC
returns a value of the same floating-point size. When the argument is
not a real expression, BASIC converts the argument to the
default floating-point size and returns a value of the default
- If real-exp is negative, FIX returns the negative integer
portion. For example, FIX(-5.2) returns -5.
DECLARE SINGLE result
result = FIX(-3.333)
PRINT FIX(24.566), result
The FNEND statement is a synonym for the END DEF statement. See the END
statement for more information.
The FNEXIT statement is a synonym for the EXIT DEF statement. See the
EXIT statement for more information.
The FOR statement repeatedly executes a block of statements, while
incrementing a specified control variable for each execution of the
statement block. FOR loops can be conditional or unconditional, and can
modify other statements.
- Num-unsubs-var must be a numeric, unsubscripted variable.
Num-unsubs-var cannot be a record field.
- Num-unsubs-var is the loop variable. It is incremented
each time the loop executes.
- In unconditional FOR loops, num-exp1 is the initial value
of the loop variable; num-exp2 is the maximum value.
- In conditional FOR loops, num-exp1 is the initial value of
the loop variable, while the cond-exp in the WHILE or UNTIL
clause is the condition that controls loop iteration.
- Num-exp3 in the STEP clause is the value by which the loop
variable is incremented after each execution of the loop.
- There is a limit to the number of inner loops you can contain
within a single outer loop. This number varies according to the
complexity of the loops. If you exceed the limit, BASIC signals
an error message.
- An inner loop must be entirely within an outer loop; the loops
- You cannot use the same loop variable in nested FOR loops. For
example, if the outer loop uses FOR I = 1 TO 10, you cannot
use the variable I as a loop variable in an inner loop.
- The default for num-exp3 is 1 if there is no STEP clause.
- You can transfer control into a FOR loop only by returning from a
invocation, a subprogram call, a subroutine call, or an error handler
that was invoked in the loop.
- The starting, incrementing, and ending values of the loop do not
change during loop execution.
- The loop variable can be modified inside the FOR loop.
- BASIC converts num-exp1, num-exp2, and
num-exp3 to the data type of the loop variable before storing
- When an unconditional FOR loop ends, the loop variable contains the
value last used in the loop, not the value that caused loop termination.
- During each iteration of a conditional loop, BASIC tests
the value of cond-exp before it executes the loop.
- If you specify a WHILE clause and cond-exp is false (value
zero), BASIC exits from the loop. If the cond-exp is
true (value nonzero), the loop executes again.
- If you specify an UNTIL clause and cond-exp is true (value
nonzero), BASIC exits from the loop. If the exp is
false (value zero), the loop executes again.
- When FOR is used as a statement modifier, BASIC executes
the statement until the loop variable equals or exceeds
num-exp2 or until the WHILE or UNLESS condition is satisfied.
- Each FOR statement must have a corresponding NEXT statement or
BASIC signals an error. (This is not the case if the FOR
statement is used as a statement modifier.)
DECLARE LONG course_num, STRING course_nam
FOR I = 3 TO 12 STEP 3
INPUT "Course number";course_num
INPUT "Course name";course_nam
Course number? 221
Course name? Botany
Course number? 231
Course name? Organic Chemistry
Course number? 237
Course name? Life Science II
Course number? 244
Course name? Programming in BASIC
!Unconditional Statement Modifier
DECLARE INTEGER counter
PRINT "This is an unconditional statement modifier" FOR counter = 1 TO 3
This is an unconditional statement modifier
This is an unconditional statement modifier
This is an unconditional statement modifier
!Conditional Statement Modifier
DECLARE INTEGER counter, &
INPUT "Try and guess my name";my_name FOR counter = 1 UNTIL my_name = "BASIC"
PRINT "You guessed it!"
Try and guess my name? VAX PASCAL
Try and guess my name? VAX SCAN
Try and guess my name? BASIC
You guessed it!
The FORMAT$ function converts an expression to a formatted string.
The rules for building a format string are the same as those for
printing numbers with the PRINT USING statement. See the description of
the PRINT USING statement for more information.
It is recommended that you use compile-time constant expressions for
string expressions whenever possible. When you do this, the
BASIC compiler compiles the string at compilation time rather
than at run time, thus improving the performance of your code.
DECLARE STRING result, &
num_exp = 12345
result = FORMAT$(num_exp,"##,###")
The FREE statement unlocks all records and buckets associated with a
Chnl-exp is a numeric expression that specifies a channel
number associated with a file. It must be immediately preceded by a
number sign (#).
- The file specified by chnl-exp must be open.
- You cannot use the FREE statement with files not on disk.
- If there are no locked records or buckets on the specified channel,
the FREE statement has no effect and BASIC does not signal an
- The FREE statement does not change record buffers or pointers.
- After a FREE statement has executed, your program must execute a
GET or FIND statement before a PUT, UPDATE, or DELETE statement can
OPEN "CUST_ACCT.DAT" FOR INPUT AS #3
INPUT "Enter customer record number to retrieve";cust_rec_num
In this example, CUST_ACCT.DAT is opened for input. The FREE statement
unlocks all records associated with the specified channel contained in
the file. Once the FREE statement successfully executes, the user can
then obtain a record with either a FIND or GET statement.
The FSP$ function returns a string describing an open file on a
- A file must be open on chnl-exp.
- The FSP$ function must come immediately after the OPEN statement
for the file.
- Use the FSP$ function with files opened as ORGANIZATION UNDEFINED.
Then use multiple MAP statements to interpret the returned data.
- See the Compaq BASIC for OpenVMS Alpha and VAX Systems User Manual and the OpenVMS Record Management Services Reference Manual for more information
about FSP$ values.
BASIC supports the FSP$ function for compatibility with
BASIC-PLUS-2. It is recommended that you use the USEROPEN routine to
identify file characteristics.
10 MAP (A) STRING A = 32
MAP (A) BYTE org, rat, WORD mrs, LONG alq, &
WORD bks_bls, num_keys,LONG mrn
OPEN "STUDENT.DAT" FOR INPUT AS #1%, &
ORGANIZATION UNDEFINED, &
RECORDTYPE ANY, ACCESS READ
A = FSP$(1%)
PRINT "RMS organization = ";org
PRINT "RMS record attributes = ";rat
PRINT "RMS maximum record size = ";mrs
PRINT "RMS allocation quantity = ";alq
PRINT "RMS bucket size = ";bks_bls
PRINT "Number of keys = ";num_keys
PRINT "RMS maximum record number = ";mrn
RMS organization = 2
RMS record attributes = 2
RMS maximum record size = 5
RMS allocation quantity = 1
RMS bucket size = 0
Number of keys = 0
RMS maximum record number = 0
The FUNCTION statement marks the beginning of a FUNCTION subprogram and
defines the subprogram's parameters.
- Note that both Alpha BASIC and VAX BASIC are able to pass
actual parameters by value, but only Alpha BASIC allows formal
parameters to be passed in by value. This means that while
Alpha BASIC can use BY VALUE in a definition and a call,
VAX BASIC can use BY VALUE only in a call. It cannot define a
function that takes parameters BY VALUE.
- Func-name names the FUNCTION subprogram.
- Func-name can be from 1 through 31 characters. The first
character must be an alphabetic character (A to Z). The remaining
characters, if present, can be any combination of letters, digits (0 to
9), dollar signs ($), periods (.), or underscores (_).
- Data-type can be any BASIC data type keyword or a
data type defined in the RECORD statement. Data type keywords, size,
range, and precision are listed in Table 1-2.
- The data type that precedes the func-name specifies the
data type of the value returned by the function.
- Formal-param specifies the number and type of parameters
for the arguments the function expects to receive when invoked.
- Empty parentheses indicate that the function has no parameters.
- Data-type specifies the data type of a parameter. If you
do not specify a data type, parameters are of the default data type and
size. When you do specify a data type, all following parameters are of
that data type until you specify a new data type.
If the data type
is STRING and the passing mechanism is by reference (BY REF), the
=int-const clause allows you to specify the length of the
- Parameters defined in formal-param must agree in number
and type with the arguments specified in the function invocation.
BASIC allows you to specify from 1 to 255 formal parameters.
- Pass-mech specifies the parameter-passing mechanism by
which the FUNCTION subprogram receives arguments when invoked. A
pass-mech clause should be specified only when the FUNCTION
subprogram is being called by a non BASIC program or when the FUNCTION
receives a string or array by reference.
- A pass-mech clause outside the parentheses applies by
default to all function parameters. A pass-mech clause in the
formal-param list overrides the specified default and applies
only to the immediately preceding parameter.
- Exp specifies the function result, which supersedes any
function assignment. Exp must be compatible with the
function's data type.
- The FUNCTION statement must be the first statement in the FUNCTION
- Every FUNCTION statement must have a corresponding END FUNCTION or
- Any BASIC statement except END, PICTURE, END PICTURE,
PROGRAM, END PROGRAM, SUB, SUBEND, END SUB, or SUBEXIT can appear in a
- FUNCTION subprograms must be declared with the EXTERNAL statement
before your BASIC program can invoke them.
- FUNCTION subprograms receive parameters by reference, by
descriptor, or by value.
- BY REF specifies that the function receives the argument's address.
- BY DESC specifies that the function receives the address of a
BASIC descriptor. For information about the format of a
BASIC descriptor for strings and arrays, see the Compaq BASIC for OpenVMS Alpha and VAX Systems User Manual;
for information about other types of descriptors, see the OpenVMS
- BY VALUE specifies that the function receives a copy of the
Alpha BASIC can use BY VALUE in both definitions
and calls. VAX BASIC can use BY VALUE only in calls; it cannot
define a function that takes parameters BY VALUE.
- By default, FUNCTION subprograms receive numeric unsubscripted
variables by reference, and all other parameters by descriptor. You can
override these defaults with a BY clause:
- If you specify a string length with the =int-const clause,
you must also specify BY REF. If you specify BY REF and do not specify
a string length, BASIC uses the default string length of 16.
- If you specify array bounds, you must also specify BY REF.
- All variables and data, except virtual arrays, COMMON areas, MAP
areas, and EXTERNAL variables, in a FUNCTION subprogram, are local to
- BASIC initializes local numeric variables to zero and local
variables to the null string each time the FUNCTION subprogram is
- If an exception is not handled within the FUNCTION subprogram,
control is transferred back to the main program that invoked the
FUNCTION REAL sphere_volume (REAL R)
IF R < 0 THEN EXIT FUNCTION
sphere_volume = 4/3 * PI *R **3
The FUNCTIONEND statement is a synonym for the END FUNCTION statement.
See the END statement for more information.
The FUNCTIONEXIT statement is a synonym for the EXIT FUNCTION
statement. See the EXIT statement for more information.
The GET statement copies a record from a file to a record buffer and
makes the data available for processing. GET statements are valid on
sequential, relative, and indexed files.
- Chnl-exp is a numeric expression that specifies a channel
number associated with a file. It must be immediately preceded by a
number sign (#).
- If you specify a lock-clause, it must follow the
position-clause. If the lock-clause precedes the
position-clause, BASIC signals an error.
- If you specify the REGARDLESS lock-clause, you cannot
specify another lock-clause in the same GET statement.
- Position-clause specifies the position of a record in a
file. BASIC signals an error if you specify a
position-clause and chnl-exp is not associated with a
If you do not specify a position-clause, GET retrieves records
sequentially. Sequential record access is valid on all files.
- The RFA position-clause allows you to randomly retrieve
records by specifying the record file address (RFA); you specify the
disk address of a record, and RMS retrieves the record at that address.
All file organizations can be accessed by RFA.
the RFA position-clause is an expression of the RFA data type
that specifies the record's file address. An RFA expression must be a
variable of the RFA data type or the GETRFA function. Use the GETRFA
function to obtain the RFA of a record.
- The RECORD position-clause allows you to randomly retrieve
records in relative and sequential fixed files by specifying the record
- Num-exp in the RECORD position-clause specifies
the number of the record you want to retrieve. It must be between 1 and
the number of the record with the highest number in the file.
- When you specify a RECORD clause, chnl-exp must be a
channel associated with an open relative or sequential fixed file.
- The KEY position-clause allows you to randomly retrieve
records in indexed files by specifying a key of reference, a relational
test, or a key value.
- An RFA value is valid only for the life of a specific version of a
file. If a new version of a file is created, the RFA values may change.
- Attempting to access a record with an invalid RFA value results in
a run-time error.
- Lock-clause allows you to control how a record is locked
to other access streams, to override lock checking when accessing
shared files that may contain locked records, or to specify what action
to take in the case of a locked record.
- The type of lock you impose on a record remains in effect until you
explicitly unlock it with a FREE or UNLOCK statement, until you close
the file, or until you perform a GET, FIND, UPDATE or DELETE on the
same channel (unless you specified UNLOCK EXPLICIT).
- The REGARDLESS lock-clause specifies that the GET
statement can override lock checking and read a record locked by
- When you specify a REGARDLESS lock-clause, BASIC
does not impose a lock on the retrieved record.
- If you specify an ALLOW lock-clause, the file associated
with chnl-exp must have been opened with the UNLOCK EXPLICIT
clause or BASIC signals the error "Illegal record locking
- The ALLOW allow-clause can be one of the following:
- ALLOW NONE denies access to the record. This means that other
access streams cannot retrieve the record unless they bypass lock
checking with the REGARDLESS clause.
- ALLOW READ provides read access to the record. This means that
other access streams can retrieve the record, but cannot DELETE or
UPDATE the record.
- ALLOW MODIFY provides both read and write access to the record.
This means that other access streams can GET, FIND, DELETE, or UPDATE
- If you do not open a file with ACCESS READ or specify an ALLOW
lock-clause, locking is imposed as follows:
- If the file associated with chnl-exp was opened with
UNLOCK EXPLICIT, BASIC imposes the ALLOW NONE lock on the
retrieved record and the next GET or FIND statement does not unlock the
previously locked record.
- If the file associated with chnl-exp was not opened with
UNLOCK EXPLICIT, BASIC locks the retrieved record and unlocks
the previously locked record.
- The WAIT lock-clause accepts an optional int-exp.
Int-exp represents a timeout value in seconds.
Int-exp must be from 0 to 255 or BASIC issues a
- WAIT followed by a timeout value causes RMS to wait for a locked
record for a given period of time.
- WAIT followed by no timeout value indicates that RMS should wait
indefinitely for the record to become available.
- If you specify a timeout value and the record does not become
available within that period, BASIC signals the run-time error
"Keyboard wait exhausted" (ERR=15). VMSSTATUS and RMSSTATUS
then return RMS$_TMO. For more information about these functions, see
the RMSSTATUS and VMSSTATUS functions in this chapter and the
Compaq BASIC for OpenVMS Alpha and VAX Systems User Manual.
- If you attempt to wait for a record that another user has locked,
and consequently that user attempts to wait for the record you have
locked, a deadlock condition occurs. When a deadlock condition persists
for a period of time (as defined by the SYSGEN parameter
DEADLOCK_WAIT), RMS signals the error "RMS$_DEADLOCK" and
BASIC signals the error "Detected deadlock error while
waiting for GET or FIND" (ERR=193).
- If you specify a WAIT clause followed by a timeout value that is
less than the SYSGEN parameter DEADLOCK_WAIT, then BASIC
signals the error "Keyboard wait exhausted" (ERR=15) even
though a deadlock condition may exist.
- If you specify a WAIT clause on a GET operation to a unit device,
the timeout value indicates how long to wait for the input to complete.
This is equivalent to the WAIT statement.
- In a key-clause, int-exp1 is the target key of
reference. It must be an integer value in the range of zero to the
highest-numbered key for the file. The primary key is #0, the first
alternate key is #1, the second alternate key is #2, and so on.
Int-exp1 must be preceded by a number sign (#) or
BASIC signals an error.
- When you specify a key-clause, chnl-exp must be a
channel associated with an open indexed file.
- Rel-op specifies how key-exp is to be compared
with int-exp1 in the key-clause.
- EQ means "equal to"
- NXEQ means "next or equal to"
- GE means "greater than or equal to" (a synonym for NXEQ)
- NX means "next"
- GT means "greater than" (a synonym for NX)
- With an exact key match (EQ), a successful GET operation retrieves
the first record in the file that equals the key value specified in
key-exp. If the key expression is a str-exp whose
length is less than the key length, characters specified by the
str-exp are matched approximately rather than exactly. That
is, if you specify a string expression ABC and the key length is six
characters, BASIC matches the first record that begins with
ABC. If you specify ABCABC, BASIC matches only a record with
the key ABCABC. If no match is possible, BASIC signals the
error "Record not found" (ERR=155).
- If you specify a next or equal to key match (NXEQ), a successful
GET operation retrieves the first record that equals the key value
specified in key-exp. If no exact match exists, BASIC
retrieves the next record in the key sort order. If the keys are in
ascending order, the next record will have a greater key value. If the
keys are in descending order, the next record will have a lesser key
- If you specify a greater than key match (GT), a successful GET
operation retrieves the first record with a value greater than
key-exp. If no such record exists, BASIC signals the
error "Record not found" (ERR=155).
- If you specify a next key match (NX), a successful GET operation
retrieves the first record that follows the key expression in the key
sort order. If no such record exists, BASIC signals the error
"Record not found" (ERR=155).
- If you specify a greater than or equal to key match (GE), the
behavior is identical to that of next or equal to (NXEQ). Likewise, the
behavior of GT is identical to NX. However, the use of GE in a
descending key file may be confusing because GE will retrieve the next
record in the key sort order, but the next record will have a lesser
key value. For this reason, it is recommended that you use NXEQ in new
program development, especially if you are using descending key files.
- Int-exp2 in the key-clause specifies an integer
value to be compared with the key value of a record.
- Str-exp in the key-clause specifies a string
value to be compared with the key value of a record. The string
expression can contain fewer characters than the key of the record you
want to retrieve but it cannot be a null string.
cannot contain more characters than the key of the record you want to
locate. If str-exp does contain more characters than the key,
BASIC signals "Key size too large" (ERR = 145).
- Decimal-exp in the key-clause specifies a packed
decimal value to be compared with the key value of a record.
- Quadword-exp in the key-clause specifies a record
or group exactly 8 bytes long to be compared with the key value of a
- The file specified by chnl-exp must be opened with ACCESS
READ or ACCESS MODIFY or SCRATCH before your program can execute a GET
statement. The default ACCESS clause is MODIFY.
- If the last I/O operation was a successful FIND operation, a
sequential GET operation retrieves the current record located by the
FIND operation and sets the next record pointer to the record logically
succeeding the pointer.
- If the last I/O operation was not a FIND operation, a sequential
GET operation retrieves the next record and sets the record logically
succeeding the record pointer to the current record.
- For sequential files, a sequential GET operation retrieves the next
record in the file.
- For relative files, a sequential GET operation retrieves the record
with the next higher cell number.
- For indexed files, a sequential GET operation retrieves the next
record in the current key of reference.
- A successful random GET operation by RFA or by record retrieves the
record specified by rfa-exp or int-exp.
- A successful random GET operation by key retrieves the first record
whose key satisfies the key-clause comparison.
- A successful random GET operation by RFA, record, or key sets
the value of the current record pointer to the record just read. The
next record pointer is set to the next logical record.
- An unsuccessful GET operation leaves the record pointers and the
record buffer in an undefined state.
- If the retrieved record is smaller than the receiving buffer,
BASIC fills the remaining buffer space with nulls.
- If the retrieved record is larger than the receiving buffer,
BASIC truncates the record and signals an error.
- A successful GET operation sets the value of the RECOUNT variable
to the number of bytes transferred from the file to the record buffer.
- You should not use a GET statement on a terminal-format or virtual