Digital PDFs
Documents
Guest
Register
Log In
AD-HY16A-T1
July 1988
1432 pages
Original
35MB
view
download
Document:
VAX BASIC Reference Manual
Order Number:
AD-HY16A-T1
Revision:
000
Pages:
1432
Original Filename:
OCR Text
VAX BASIC Reference Manual Order Number: Al-HY 16A-TE, AD-HY 16A-T 1 July 1988 This manual provides reference material and syntax for VAX BASIC language elements. Operating System and Version: VMS Version 5.0 or higher Software Version: digital equipment corporation maynard, massachusetts VAX BASIC Version 3.3 First Printing, August 1 986 Updated, July 1988 The information in this document is subject to change without notice and should not be construed as a commitment by Digital Equipment Corporation. Digital Equipment Corporation assumes no responsibility for any errors that may appear in this document. The software described in this document is furnished under a license and may be used or copied only in accordance with the terms of such license. No responsibility is assumed for the use or reliability of software on equipment that is not supplied by Digital Equipment Corporation or its affiliated companies. Copyright © 1986, 1988 by Digital Equipment Corporation All Rights Reserved. Printed in U.S.A. The postpaid Reader's Comments forms at the end of this document request the user's critical evaluation to assist in preparing future documentation. The following are trademarks of Digital Equipment Corporation: DEC DEC/CMS DEC/MMS DECnet DECsystem-10 DECSYSTEM-20 DEC US DEC writer DIBOL EduSystem IAS MASS BUS PDP PDT RSTS RSX UNIBUS VAX VAXcluster VMS VT ~urnuo~u™ ZK4773 Contents PREFACE xv SUMMARY OF TECHNICAL CHANGES xxi PROGRAM ELEMENTS AND STRUCTURE 1-1 COMPONENTS OF PROGRAM LINES 1.1.1 Line Numbers 1 . 1 . 1. 1 Programs With Line Numbers • 1-2 1. 1. 1 .2 Programs Without Line Numbers • 1-2 1.1.2 Labels 1.1.3 Statements 1. 1.3.1 Keywords • 1-5 1.1.3.2 Identifying Program Units • 1-6 1.1.3.3 Single-Statement Lines and Continued Statements • 1-7 1.1.3.4 Multi-Statement Lines • 1-8 1.1.4 Compiler Directives 1.1.5 Line Terminators 1.1.6 Lexical Order 1-1 1-2 1-10 1 -11 1-11 1.2 VAX BASIC CHARACTER SET 1-11 1.3 VAX BASIC DATA TYPES Implicit Data Typing 1.3.1 1.3.2 Explicit Data Typing 1-12 1-15 1-16 1.4 VARIABLES 1.4.1 Variable Names 1.4.2 Implicitly Declared Variables 1.4.3 Explicitly Declared Variables 1.4.4 Subscripted Variables and Arrays 1.4.5 Initialization of Variables 1-17 1-18 1-19 1-20 1-21 1-23 CHAPTER 1 1.1 July 1988 1-3 1-4 iii 1.5 1.6 CONSTANTS Numeric Constants 1.5.1 1. 5. 1. 1 Floating-Point Constants • 1-25 1.5. 1.2 Integer Constants • 1-27 1.5. 1.3 Packed Decimal Constants • 1-28 String Constants 1.5.2 Named Constants 1.5.3 1.5.3. 1 Naming Constants Within a Program Unit • 1-30 1.5.3.2 Naming Constants External to a Program Unit • 1-31 Explicit Literal Notation 1.5.4 1.5.5 Predefined Constants 1-24 1-25 EXPRESSIONS Numeric Expressions Floating-Point and Integer Promotion 1.6. 1. 1 Rules• 1-40 1.6. 1.2 DECIMAL Promotion Rules • 1-42 1.6.2 String Expressions Conditional Expressions 1.6.3 1.6.3.1 Numeric Relational Expressions • 1-44 1.6.3.2 String Relation~! Expressions • 1-46 1.6.3.3 Logical Expre~.. sions • 1-48 Evaluating Expressions 1.6.4 1-37 1-38 PROGRAM DOCUMENTATION 1.7 .1 Comment Fields 1.7.2 REM Statements 1-55 1-55 1-57 1.6.1 1.7 iv 1-28 1-30 1-32 1-35 1-43 1-44 1-52 CHAPTER 2 2-1 BASIC ENVIRONMENT COMMANDS ! your-comment 2-2 $ system-command 2-4 APPEND 2-6 ASSIGN 2-8 COMPILE 2-10 CONTINUE 2-20 DELETE 2-21 EDIT 2-23 EXIT 2-26 HELP 2-27 IDENTIFY 2-29 INQUIRE 2-30 LIST AND LISTNH 2-31 LOAD 2-33 LOCK 2-35 NEW 2-36 OLD 2-38 RENAME 2-39 REPLACE 2-41 RESEQUENCE 2-43 RUN 2-46 SAVE 2-49 SCALE 2-51 SCRATCH 2-53 SEQUENCE 2-54 SET 2-56 SHOW 2-58 UNSAVE 2-60 v CHAPTER 3 CHAPTER 4 vi COMPILER DIRECTIVES 3-1 %ABORT 3-2 %CROSS 3-3 %DECLARED 3-4 %1DENT 3-6 %1F-%THEN-%ELSE-%END %IF 3-8 %INCLUDE 3-10 %LET 3-14 %LIST 3-16 %NOCROSS 3-17 %NOLIST 3-19 %PAGE 3-20 %PRINT 3-21 %REPORT 3-22 %SBTTL 3-22.2 %TITLE 3-24 %VARIANT 3-26 4-1 STATEMENTS AND FUNCTIONS ABS 4-2 ABS% 4-4 ASCII 4-5 ATN 4-6 BUFSIZ 4-8 CALL 4-9 CAUSE ERROR 4-14 CCPOS 4-16 CHAIN 4-18 CHANGE 4-20 CHR$ 4-23 CLOSE 4-24 COMMON 4-26 COMP% 4-31 July 1988 CONTINUE 4-33 cos 4-35 CTR LC 4-36 CVTSS 4-38 CVTXX 4-39 DATA 4-42 DATES 4-44 DECIMAL 4-46 DECLARE 4-48 DEF 4-53 DEF* 4-58 DELETE 4-63 DET 4-65 DIFS 4-67 DIMENSION 4-69 ECHO 4-74 EDITS 4-76 END 4-78 ERL 4-82 EANS 4-84 ERR 4-86 EATS 4-88 EXIT 4-90 EXP 4-93 EXTERNAL 4-95 FIELD 4-100 FIND 4-102 FIX 4-109 FNEND 4-111 FNEXIT 4-112 FOR 4-113 FORMATS 4-117 FREE 4-118 vii viii FSPS 4-120 FUNCTION 4-122 FUNCTION END 4-125 FUNCTION EXIT 4-126 GET 4-127 GETRFA 4-134 GOSUB 4-136 GOTO 4-138 HANDLER 4-140 IF 4-142 IN KEYS 4-145 INPUT 4-148 INPUT LINE 4-151 INSTR 4-154 INT 4-156 INTEGER 4-158 ITERATE 4-160 KILL 4-162 LBOUND 4-163 LEFTS 4-165 LEN 4-167 LET 4-168 LINPUT 4-170 LOC 4-173 LOG 4-175 LOG10 4-177 LSET 4-179 MAG 4-181 MAGTAPE 4-183 MAP 4-185 MAP DYNAMIC 4-189 MAR 4-192 MARGIN 4-193 MAT 4-195 MAT INPUT 4-200 MAT LINPUT 4-203 MAT PRINT 4-206 MAT READ 4-209 MAX 4-212 MIDS 4-214 MIN 4-217 MOD 4-219 MOVE 4-221 NAME ... AS 4-224 NEXT 4-226 NO ECHO 4-228 NOMARGIN 4-229 NUM 4-231 NUM2 4-233 NUMS 4-235 NUM1$ 4-237 ON ERROR GO BACK 4-239 ON ERROR GOTO 4-241 ON ERROR GOTO 0 4-244 ON ... GOSUB 4-246 ON ... GOTO 4-248 OPEN 4-250 OPTION 4-263 PLACES 4-268 POS 4-271 PRINT 4-273 PRINT USING 4-277 PRODS 4-284 PROGRAM 4-287 PUT 4-289 QUO$ 4-292 ix RAD$ RANDOMIZE RCTRLC RCTRLO READ REAL RECORD RECOUNT REM REMAP RESET RESTORE RESUME RETRY RETURN RIGHT$ RMSSTATUS RND RSET SCRATCH SEG$ SELECT SET PROMPT SGN SIN SLEEP SPACE$ SQR STATUS STOP STR$ STRING$ SUB x 4-295 4-297 4-299 4-300 4-302 4-304 4-306 4-311 4-313 4-315 4-320 4-321 4-323 4-325 4-327 4-328 4-330 4-333 4-335 4-336 4-338 4-340 4-343 4-345 4-346 4-347 4-348 4-349 4-350 4-352 4-354 4-356 4-358 ~PPENDIX A SUBEND 4-361 SUBEXIT 4-362 SUMS 4-363 SWAP% 4-365 TAB 4-366 TAN 4-368 TIME 4-369 TIMES 4-371 TRMS 4-372 UBOUND 4-373 UNLESS 4-375 UNLOCK 4-376 UNTIL 4-378 UPDATE 4-380 VAL 4-382 VAL% 4-384 VMSSTATUS 4-386 WAIT 4-388 WHEN ERROR 4-390 WHILE 4-395 XLATES 4-397 TRANSPORTING PROGRAMS BETWEEN VAX BASIC AND BASIC-PLUS-2 A-1 A.1 OVERVIEW A-1 A.2 LANGUAGE-SPECIFIC FUNCTIONALITY A-2 A.3 1/0 DIFFERENCES A.3.1 The MAGTAPE Function A.3.2 The OPEN Statement A.3.3 The PUT Statement A-3 A-3 A-4 A-6 xi A.4 PROCEDURE CALLING A.4.1 The CALL Statement A.4.2 The CHAIN Statement A.4.3 SYS and FIP SYS Calls A-7 A-7 A-7 A-8 A.5 GENERATED ERRORS A-9 A.6 MISCELLANEOUS DIFFERENCES A.6.1 Data Types A.6.2 The DEF and DEF* Statements A.6.3 Default Integer Size A.6.4 Integer Overflow A.6.5 Line Numbers and Labels A.6.6 The MAP and COMMON Statements A.6.7 The MAP DYNAMIC Statement A.6.8 The PRINT Statement A.6.9 The PRINT USING Statement A.6.10 The REPLACE Command A.6.11 The SPEC% and PEEK Functions A.6.12 String Comparisons A.6.13 Assigning Symbols A.6.14 The TIME Function A.6.15 The TIMES Function A-10 A-10 A-10 A-11 A-11 A-11 A-11 A-12 A-12 A-13 A-13 A-13 A-13 A-13 A-14 A-14 APPENDIX B ANSI MINIMAL BASIC xii B-1 B.1 INTRODUCTION B-1 B.2 THE /ANSLSTANDARD QUALIFIER B-2 B.3 EXTENSIONS TO ANSI MINIMAL BASIC STANDARD X3.60-1978 B.3.1 Program Format B. 3. 2 Statements B.3.3 Delimiters B.3.4 Variables B.3.5 Numeric Constants B-2 B-2 B-3 B-3 B-3 B-4 B.3.6 Data Input B.3.6.1 B.3.6.2 B.3.7 8.3.8 B.3.9 B.4 B-4 Unquoted String Data • B-5 Null Input • B-6 User-Defined Functions (the DEF Statement) Built-In Functions Arrays IMPLEMENTATION-DEFINED FEATURES B.4.1 Initial Values for Variables Retention of Long Strings B.4.2 Accuracy of Evaluation of Numeric Expressions B.4.3 B.4.4 Machine Infinitesimal Machine Infinity 8.4.5 B.4.6 Precision For Numeric Values Exrad-Width For Printing Numeric Representations 8.4.7 8.4.8 Significance-Width For Printing Numeric Representations 8.4.9 Print Zone Length B.4.10 Margin for Output Line B.4.11 Pseudorandom Number Sequence B.4.12 Unique Line Numbers B.4.13 Input Prompt B.4.14 End of Input Reply B.4.15 End of Print Line B.4.16 Exponentiation Operator 8-6 8-6 B-7 8-7 8-8 8-8 8-8 8-8 8-8 8-9 B-9 8-9 8-9 8-10 8-10 8-10 8-10 8-10 8-11 B-11 APPENDIX C ASCII CHARACTER CODES C-1 APPENDIX D VAX BASIC KEYWORDS D-1 INDEX July 1988 xiii FIGURES 1-1 Truth Tables 1-50 1-1 Keyword Space Requirements 1-5 1-2 VAX BASIC Data Types 1-14 1-3 Numbers in E Notation 1-26 1-4 Predefined Constants 1-36 1-5 Arithmetic Operators 1-38 1-6 Result Data Types in VAX BASIC Expressions 1-41 1-7 VAX BASIC Result Data Types 1-41 1-8 Result Data Types for DECIMAL Data 1-43 1-9 Numeric Relational Operators 1-45 1-10 String Relational Operators 1-47 TABLES xiv 1-11 Logical Operators 1-49 1-12 Numeric Operator Precedence 1-53 4-1 VAX BASIC Parameter-Passing Mechanisms 4-10 4-2 Fl LL Item Formats and Storage Allocations 4-28 4-3 EDITS Values 4-76 4-4 MAGTAPE Functionality in VAX BASIC 4-184 4-5 Rounding and Truncation of 123456.654321 4-269 4-6 VAX BASIC STATUS Bits 4-351 4-7 TIME Function Values 4-370 A-1 MAGTAPE Functionality in VAX BASIC A-4 A-2 RSTS/E Disk MODE Values and Corresponding BASIC Statements A-6 A-3 VAX BASIC Subset of RSTS/E SYS Calls A-8 A-4 VAX BASIC Subset of RSTS/E FIP SYS Calls A-8 A-5 Fatal Errors in VAX BASIC That Are Warnings in BASIC-PLUS-2 A-10 A-6 VAX BASIC and BASIC-PLUS-2 TIME Function Differences A-14 C-1 ASCII Codes C-2 Preface Intended Audience This manual describes the language elements and syntax of VAX BASIC. Readers are presumed to be familiar with VAX BASIC programming techniques. This manual provides reference material to be used in conjunction with the other two manuals in the documentation set. Associated Documents This manual is one of three manuals that form the VAX BASIC document set. The other two manuals are as follows: VAX BASIC User Manual Provides tutorial material for VAX BASIC language constructs and information pertaining to programming with VAX BASIC on VAX/VMS systems Programming with VAX BASIC Graphics Provides tutorial and reference material on VAX BASIC graphics capabilities You may also be interested in the following supplementary manuals: • • • • VAX BASIC Syntax Summary Introduction to BASIC BASIC for Beginners More BASIC for Beginners July 1988 xv Document Structure This manual consists of four chapters and four appendixes. Chapter 1 Summarizes VAX BASIC program elements and structure Chapter 2 Describes VAX BASIC environment commands Chapter 3 Describes VAX BASIC compiler directives Chapter 4 Describes VAX BASIC statements and functions Appendix A Summarizes transportability issues between BASIC-PLUS-2 and VAX BASIC Appendix B Explains how VAX BASIC conforms to the ANSI Minimal Standard for BASIC Appendix C Lists the ASCII codes Appendix D Lists VAX BASIC keywords In Chapters 2, 3, and 4, the VAX BASIC language elements are arranged in alphabetical order within each part; each language element begins on a separate page. These chapters provide reference material on each VAX BASIC language element. The descriptions are arranged in alphabetical order and include the following sections: xvi Overview An overview of what the statement or command does. Format The required syntax for the language element. Syntax Rules Any rules governing the use of parameters, separators, or other syntax items, effect of the statement or command on program execution, and any restrictions governing its use. Example One or more examples of the statement in a partial program. Where appropriate, explanatory text and program output are included. July 1988 Conventions Used in This Document This manual uses case of text, symbols, and mnemonics in syntactical diagrams. This symbology aids in providing more concise and exact descriptions of syntatic variables, rules, and format. Convention Meaning $ BASIC In command-line examples, the user's response to a system prompt is printed in red; system prompts are printed in black. UPPERCASE letters Uppercase letters are used for VAX BASIC keywords and must be coded exactly as shown. lowercase letters Lowercase letters are used to indicate user-supplied names or characters. [] Brackets enclose an optional portion of a format. Brackets around vertically stacked items indicate that you can select one of the enclosed items. You must include all punctuation as it appears in the brackets. {} Braces enclose a mandatory portion of a format. Braces around vertically stacked items indicate that you must choose one of the enclosed items. You must include all punctuation as it appears in the braces. A vertical ellipsis indicates that code which would normally be present is not shown. An ellipsis indicates that the immediately preceding item can be repeated. An ellipsis following a format unit enclosed in brackets or braces means that you can repeat the entire unit. If repeated items or format units must be separated by commas, the ellipsis is preceded by a comma ( ,... ). xvii The following mnemonics are used in the syntax diagrams: Mnemonic Meaning angle array An angle in radians or degrees chnl An 1/0 channel associated with a file com Specific to a COMMON block cond Conditional expression; indicates that an expression can be either logical or relational canst A constant value data-type A data type keyword def Specific to a DEF function exp file-spec An expression func Specific to a FUNCTION subprogram int int-exp An integer value int-var A variable that contains an integer value label An alphanumeric statement label lex line line-num Lexical; used to indicate a component of a compiler directive lit log-exp xviii An array; syntax rules specify whether the bounds or dimensions can be specified A file specification An expression that represents an integer value A statement line; may or may not be numbered A statement line number A literal value, in quotation marks Logical expression map matrix Specific to a MAP statement name A name or identifier; indicates the declaration of a name or the name of a VAX BASIC structure, such as a SUB subprogram A two-dimensional array Mnemonic Meaning num A numeric value pa ram-list pass-mech real A parameter list, such as for a SUB subprogram rel-exp Relational expression str str-exp str-var A character string An expression that represents a character string sub Specific to a SUB subprogram target The target point of a branch statement; either a line number or a label unsubs-var Unsubscripted variable, as opposed to an array element var A variable A valid VAX BASIC passing mechanism A floating-point value A variable that contains a character string xix Summary of Technical Changes Summary of New and Changed Features for Version 3.3 Version 3.3 of VAX BASIC includes support for the CDD/Plus Version 4.0 CDO-format dictionaries while continuing to provide full support for the DMU-format dictionaries associated with previous versions of the CDD. Both types of dictionaries can coexist on a system and a program can access data definitions in both formats. This new functionality is implemented as follows: • • • Addition of the /DEPENDENCY_DATA qualifier to the DCL command, BASIC Addition of the lexical directive, %REPORT %DEPENDENCY Modification of the lexical directive, %INCLUDE %FROM %CDD Descending keys are now supported on both primary and alternate keys. This new functionality is implemented by allowing the choice of ASCENDING or DESCENDING on key definition clauses in the OPEN statement. In addition, this documentation update contains numerous corrections and clarifications to previous documentation; these documentation changes do not reflect new features. July 1988 xxi Summary of New and Changed Features for Version 3.0 Version 3.0 of VAX BASIC includes extensive graphics capabilities, structured error handling techniques, enhancements to file 1/0 and other new features. All of these features are documented in this manual and the VAX BASIC User Manual except for the graphics features, which are documented in Programming with VAX BASIC Graphics. This section summarizes all of the major changes for this release. Graphics Capabilities VAX BASIC supports extensive graphics capabilities based on VAX GKS. The new graphics capabilities are available to you if you have the full or run-time VAX GKS kit installed on your system (Version 2.0 or later) and if you use supported graphics hardware. The main features of VAX BASIC graphics are as follows: • • • • • • • • A short learning period Convenient default values for attributes Statements consisting of English words in simple constructs Window and viewport settings that are easy to alter Graphics subprograms that can be invoked with a variety of transformation functions Input statements for interactive graphics programs Programs that can run on multiple devices Programs that run on any hardware supported by VAX GKS Structured Error Handling VAX BASIC supports structured error handling with WHEN ERROR constructs. When an error occurs during execution of statements in a protected block of code, the error is handled by the associated attached or detached handler. The following new statements and functions enhance error-handling capabilities: • • • • • • xxii WHEN ERROR RETRY CONTINUE HANDLER, EXIT HANDLER, and END HANDLER OPTION HANDLE CAUSE ERROR • RMSSTATUS and VMSSTATUS Although the new WHEN ERROR constructs are the preferred method for error handling, ON ERROR statements are supported for compatibility with previous versions of BASIC. Optional Line Numbers Line numbers are no longer required in VAX BASIC programs. A VAX BASIC program can have no line numbers at all, or it can use the traditional line numbered statements; both are valid. A program wHh a line number on the first nonblank line is treated as a line-numbered program by the compiler. In the BASIC environment, programs with no line numbers must be created with a text editor or copied into the environment with the OLD command. Array Bounds You can now specify the lower bound for any or all dimensions of nonvirtual arrays. Previously, VAX BASIC arrays could only be zero-based. In addition, two new functions, LBOUND and UBOUND, allow you to retrieve the lower and upper bounds of array dimensions. Improvements for Procedure Invocations This version of VAX BASIC includes additional flexibility for procedure invocations: • • • If an external function is called as a procedure, VAX BASIC performs parameter validation exactly as if the declared function had been invoked as a function. The new keywords ANY and OPTIONAL ease parameter passing to non-BASIC routines. Additional functionality has been added to the LOC function so that the address of an external function can be accessed. PRINT USING Format Strings Constant PRINT USING format strings are precompiled at compile time. Significant run-time performance gains can be achieved by recompiling programs that use constant format strings. xxiii Single Keystroke Input The new function INKEY$ allows you to detect a single keystroke typed at a terminal. Function and keypad keys return a descriptive text string, for example, "Fl 7'', and control characters return a single ASCII code. 1/0 Enhancements The following features have been added to enhance I/O capabilities: • STREAM files are accessible with the OPEN statement. • A WAIT clause can be added to the GET and FIND statements. This clause instructs VAX BASIC to wait on locked records rather than immediately returning the error RECBUCLOC (ERR= 154). • The new keywords NX (next) and NXEQ (next or equal to) are synonyms for GT and GE respectively. These keywords make the GET and FIND statements more meaningful if' an indexed file is accessed with descending keys. Miscellaneous Features • The new PROGRAM statement allows you to optionally name a main program unit. This name becomes the module name of the compiled source. • You can return a procedure value or the status of an image upon exiting with the following statements: END /EXIT PROGRAM - • END/EXIT FUNCTION END /EXIT DEF By default, VAX BASIC calls VAX EDT from the environment. The user or the system manager can select callable VAX EDT, the VAX Text Processing Utility (VAXTPU), or the VAX Language Sensitive Editor as the default editor. Start-up time for editing files within the environment is shorter as it is no longer necessary to spawn a subprocess to access editors that are callable. • System managers can prevent users escaping to DCL level from the environment by setting the user's subprocess limit (PRCLM) to zero. A subprocess limit of 1 was previously required so that a user could use an editor within the environment. • New extensions to the OPTION statement include the following: OPTION ANGLE = degrees-or-radians OPTION HANDLE = severity-level xxiv • • • • • • • • • - OPTION CONSTANT TYPE = data-type - OPTION OLD VERSION = CDD The MID$ function can now be on the left side of an assignment statement. This feature allows partial string replacement. VAX BASIC statements, compiler directives, labels, and comment lines can now start in column 1. You can include files from a text library with the %INCLUDE directive. The suffixes $ (for strings) and % (for integers) are allowed on explicitly declared variables and constants. Extensions to the REMAP and MAP DYNAMIC statements allow you to redefine the storage allocated to a previously declared static string variable. New functions MAX and MIN are provided for the comparison of a series of arguments. The new MOD function divides one numeric argument by another and returns the remainder. The new compiler directive %PRINT allows you to print a message during the compilation of a source program without aborting the compilation. The new lexical directive %DECLARED allows you to determine whether or not a lexical variable has been declared. xxv Chapter 1 Program Elements and Structure The building blocks of a VAX BASIC program are as follows: • • • • • • Program lines and their components The VAX BASIC character set VAX BASIC data types Variables and constants Expressions Program documentation These building blocks are described in the following sections. 1. 1 Components of Program Lines A VAX BASIC program is a series of program lines that contain instructions for the VAX BASIC compiler. These instructions are in the form of statements that contain keywords, operators, and operands. All VAX BASIC program lines can contain the following: • • • • • Statements Line numbers or labels Compiler directives Comment fields A line terminator (carriage return) Program Elements and Structure 1-1 Only a line terminator is required in a program line. The other elements are optional. 1.1. 1 Line Numbers Line numbers are no longer required in VAX BASIC programs; you can compile, link, and execute a program with or without line numbers. There are, however, different rules for writing programs with line numbers and for writing programs without line numbers. These differences are described in the following sections. 1. 1. 1. 1 Programs With Line Numbers If you are entering program lines directly into the BASIC environment in line mode, then only those statements with line numbers are allowed to start in the first column. Also, any programs entered in line mode must have an initial line number associated with the first program line. A VAX BASIC line number must be a unique integer from 1 through 32767, and must be terminated by a space or tab. VAX BASIC ignores leading spaces, tabs, and zeros in line numbers. Embedded spaces, tabs, and commas cause VAX BASIC to signal an error. In line mode, a line number followed by a carriage return does not constitute a VAX BASIC program line. A program line entered in line mode must contain a statement or a comment field. (Comment fields are discussed in Section 1.7.1). A new line number or a carriage return terminates a VAX BASIC program line. A program line can contain any number of text lines; however, a text line cannot exceed 255 characters. 1. 1. 1.2 Programs Without Line Numbers VAX BASIC searches for a line number on the first line of program text when you • • Load a program into the BASIC environment with the OLD command Edit a program in the BASIC environment If no line number is found, then the following rules apply: • 1-2 No line numbers are allowed in that program module. Program Elements and Structure • • • References to the ERL function and a RESUME statement to a line number are not allowed. A subroutine will signal the same errors as it would if it were compiled with the /NOLINES qualifier. If an error is resignaled back to the caller, ERL gives the line number of the calling site, rather than the line number of the actual error in the subprogram. The REM statement is not allowed. If your program contains multiple units, the point at which VAX BASIC breaks each program unit is determined by the placement of the statement that terminates each program unit. Any text that follows the program terminator becomes associated with the following program unit. A program terminator can be any END statement, such as an END PROGRAM statement followed by any valid expression. You cannot use the APPEND command in the BASIC environment, or a plus sign (+)at DCL level, to concatenate programs without line numbers. Note that when you compile a program from DCL, or when you copy a program into the BASIC environment with the OLD command, program statements can begin in the first column. Instead of line numbers, you can use labels to identify and reference program lines. 1. 1.2 Labels A label is a 1- to 31-character name that identifies a statement or block of statements. The label name must begin with a letter; the remaining characters, if any, can be any combination of letters, digits, dollar signs ( $ ), underscores ( _ ), or periods (. ). If the program is being entered in line mode, and therefore contains line numbers, then only line numbers and immediate mode statements can begin in the first character position. A label name must be separated from the statement it identifies with a colon ( : ). For example: Yes_routine: PRINT "Your answer is YES." The colon is not part of the label name. It informs VAX BASIC that the label is being defined rather than referenced. Consequently, the colon is not allowed when you use a label to reference a statement. For example: 200 GOTO Yes_routine Program Elements and Structure 1-3 You can reference a label almost anywhere you can reference a line number. However, there are the following exceptions: • • You cannot compare a label with the value returned by the ERL function. You cannot reference a label in an IF ... THEN ... ELSE statement without using the keyword GOTO or GO TO. You can use the implied GOTO form only to reference a line number. In the following example, the GOTO keyword is not required in statement 100 because the reference is to a line number. Because statement 200 references labels, the GOTO keyword is required. Example 100 IF AY. = BY. THEN 1000 ELSE 1050 200 IF A$ = "YES" THEN GOTO Yes ELSE GOTO No 1.1.3 Statements A VAX BASIC statement consists of a statement keyword and optional operators and operands. For example, both of these statements are valid: LET AY. = 534Y. + (SUMY. - DIFY.) PRINT AY. VAX BASIC statements can be either executable or nonexecutable: • • Executable statements perform operations (for example, PRINT, GOTO, and READ). Nonexecutable statements describe the characteristics and arrangement of data, specify usage information, and serve as comments in the source program (for example, DATA, DECLARE, and REM). VAX BASIC can accept and process one statement on a line of text, several statements on a line of text, multiple statements on multiple lines of text, and single statements continued over several lines of text. Each line of program text is associated with the last specified line number, and each must contain a keyword. 1-4 Program Elements and Structure 1. 1.3. 1 Keywords Every VAX BASIC statement except LET and empty statements must begin with a keyword. A keyword is a reserved element of the VAX BASIC language. Keywords are used to • • • Define data and user identifiers Perform operations Invoke built-in functions NOTE Keywords are reserved words and cannot be used as user identifiers, such as variable names, labels, or names for MAP or COMMON areas. Keywords cannot be used in any context other than as VAX BASIC keywords. The assignment STRING$ = "YES", for example, is invalid because STRING$ is a reserved VAX BASIC keyword and therefore cannot be used as a variable. Appendix D in this manual contains a list of the VAX BASIC keywords. A VAX BASIC keyword cannot have embedded spaces and cannot be split across lines of text. There must be a space, tab, or special character such as a comma between the keyword and any other variable or operator. Some keywords use two words. In this case, their spacing requirements vary, as shown in Table 1-1. Table 1-1: Optional Space Keyword Space Requirements Required Space No Space GO TO BY DESC FNEND GO SUB BY REF FNEXIT ON ERROR BY VALUE FUNCTIONEND END DEF FUNCTIONEXIT END FUNCTION NOECHO END GROUP NO MARGIN END IF SUBEND END PROGRAM SUB EXIT Program Elements and Structure 1-5 Table 1-1 (Cont.): Optional Space Keyword Space Requirements Required Space No Space END RECORD END SELECT END SUB EXIT DEF EXIT FUNCTION EXIT SUB INPUT LINE MAP DYNAMIC MAT INPUT MAT LINPUT MAT PRINT MAT READ 1. 1.3.2 Identifying Program Units You can delimit a main program compilation unit with the PROGRAM and END PROGRAM statements. This allows you to identify a program with a name other than the file name. The PROGRAM name must not be the same as that of any SUB, FUNCTION, or PICTURE subprogram. Example PROGRAM Sort_out END PROGRAM If you include the PROGRAM statement in your program, the name you specify becomes the module name of the compiled source. This feature is useful when you use object libraries, because the librarian stores modules by their module names rather than by their file names. Similarly, module names are used by the VAX/VMS Debugger and the VAX/VMS Linker. For more information about program units, see the VAX BASIC User Manual. 1-6 Program Elements and Structure 1. 1.3.3 Single-Statement Lines and Continued Statements A single-statement line consists of one statement on one numbered line, or one statement continued over two or more text lines. For example: 30 PRINT B * C I 12 This single-statement line has a line number, the keyword (PRINT), the operators (*, /), and the operands (B, C, 12). You can have a single statement span several text lines by typing an ampersand ( & ) and the RETURN key. Note that only spaces or tabs are valid between the ampersand and the carriage return. For example: OPEN "SAMPLE.DAT" AS FILE 2Y., .tlRETI SEQUENTIAL VARIABLE, .t RET MAP ABC The ampersand continuation character may be used but is not required for continued REM statements. The following example is valid: REM This is a remark And this is also a remark You can continue any VAX BASIC statement, but you cannot continue a string literal or VAX BASIC keyword. The following example generates the error message "Unterminated string literal". PRINT "IF-THEN-ELSE- .t END-IF" This example is valid: PRINT 11 IF- 11 ; "THEN-"; "ELSE-"; "END- 11 ; "IF" .t .t .t .t A more efficient way to continue string literals is to use the string concatenation operator ( + ): PRINT "IF- 11 + "THEN-" + "ELSE-" + "END-" + "IF" .t .t .t .t Program Elements and Structure 1-7 VAX BASIC concatenates the four string literals at compilation and stores them as one string. When the PRINT statement executes, VAX BASIC displays the one concatenated string literal rather than four separate string literals, thereby causing your program to execute faster and more efficiently. 1. 1.3.4 Multi-Statement Lines Multi-statement lines contain several statements on one line of text or multiple statements on separate lines of text. All the statements on a multi-statement line are associated with a single line of code. Multiple statements on one line of text must be separated by backslashes ( \ ). For example: 40 PRINT A \ PRINT V \ PRINT G Because all statements are on the same program line, any reference to line number 40 refers to all three statements and execution begins with the first statement on the line. For example, VAX BASIC cannot execute the second statement without executing the first statement. You can also write a multi-statement program line that associates all statements with a single line number by placing each statement on a separate line. VAX BASIC assumes that such an unnumbered line of text is either a new statement or an IF statement clause. In the following example, each line of text begins with a VAX BASIC statement and each statement is associated with line number 400. Example 400 PRINT A PRINT B PRINT "FINISHED" VAX BASIC also recognizes IF statement keywords on a new line of text and associates such keywords with the preceding IF statement. 1-8 Program Elements and Structure Example 100 REM Determine if the user's response was YES or NO. 200 IF (A$ = "YES") OR (A$ = "Y") THEN PRINT "You typed YES" ELSE PRINT "You typed NO" STOP END IF The VAX BASIC compiler assigns listing line numbers to the statements as they occur physically in the program. Example 1 100 2 3 200 4 5 6 7 REM Determine if the user's response was YES or NO. IF (A$ = "YES") OR (A$ = "Y") THEN PRINT "You typed YES" ELSE PRINT "You typed NO" STOP END IF You cannot use listing line numbers as targets of branch statements. The target of a branch statement such as GOTO must be a line number or a label. See the VAX BASIC User Manual for more information on listing file formats. You can use any VAX BASIC statement in a multi-statement line. Since the VAX BASIC compiler ignores all text following a REM keyword until it reaches a new line number, a REM statement must be the last statement on a multi-statement line. REM statements are disallowed in programs without line numbers. In the environment, a leading space or tab not followed by a line number implies a new statement in a multi-statement line, compiler commands and immediate mode statements cannot be preceded by a space, tab, or line number. If you enter a compiler command or immediate mode statement, you cannot add more continuation lines to the last program line. If you attempt to do so, VAX BASIC signals the error "Unknown command input." Program Elements and Structure 1-9 1.1.4 Compiler Directives Compiler directives are instructions for the VAX BASIC compiler. These instructions cause the VAX BASIC compiler to perform certain operations as it compiles the program. By including compiler directives in a program, you can: • • • • • • • • • Place program titles and subtitles in the header that appears on each page of the listing file Place a program version identification string in both the listing file and object module Start or stop the inclusion of listing information for selected parts of a program Start or stop the inclusion of cross reference information for selected parts of a program Include VAX BASIC code from another source file or a text library Conditionally compile parts of a program Terminate compilation Include CDD record definitions in a VAX BASIC program Display messages during the compilation Follow these rules when using compiler directives: • • • • Compiler directives must begin with a percent sign Compiler directives must be the only text on the line (except for %IF-% THEN-%ELSE-%END-%IF) Compiler directives cannot appear within a quoted string Compiler directives can be preceded by an optional line number See the VAX BASIC User Manual and Chapter 3 in this manual for more information on compiler directives. 1-1 0 Program Elements and Structure 1. 1.5 Line Terminators In the BASIC environment, a program line ends with a carriage return/line feed combination (the RETURN key) followed by an optional space or tab or a new line number. An ampersand followed by a carriage return ends a line of text, but not the program line. Note that spaces and tabs are valid between the ampersand and the carriage return; no other characters are valid. When line numbers are present, all statements between the first line number and the next line number are associated with the first line number. 1. 1.6 Lexical Order Lexical order refers to the order in which the statements in a program are compiled. In general terms, VAX BASIC compiles program lines in sequential order: multiple statements on a line of text are processed from left to right, and lines of text are processed from top to bottom. Note that certain VAX BASIC statements can alter this flow of compilation, for example GOSUB and GOTO. Some VAX BASIC statements, such as comments and MAP declarations, are nonexecutable. If program control passes to a nonexecutable statement, the VAX BASIC compiler executes the first statement that lexically follows the nonexecutable statement. 1.2 VAX BASIC Character Set VAX BASIC uses the full ASCII character set. This includes • • • The letters A through Z, both upper- and lowercase The digits 0 through 9 Special characters Appendix C in this manual lists the full ASCII character set and character values. The VAX BASIC compiler does not distinguish between upper- and lowercase letters except in string literals or within a DATA statement. The VAX BASIC compiler does not process characters in REM statements or comment fields, nor does it process nonprinting characters unless they are part of a string literal. Program Elements and Structure 1-11 In string literals, VAX BASIC processes: • • Lowercase letters as lowercase Nonprinting characters The ASCII character NUL (ASCII code 0) and line terminators cannot appear in a string literal. Use the CHR$ function or explicit literal notation to use these characters and terminators. You can use nonprinting characters in your program, for example, in string constants, but to do so you must use one of the following: • • • A predefined constant such as ESC or DEL The CHR$ function to specify an ASCII value Explicit literal notation See Section 1.5.4 for more information on explicit literal notation. 1.3 VAX BASIC Data Types Each unit of data in a VAX BASIC program has a specific data type that determines how that unit of data is to be interpreted and manipulated by the VAX BASIC compiler. This data type also determines how many storage bits make up the unit of data. VAX BASIC recognizes five primary data types: • • • • • Integer Floating-point Character string Packed decimal Record's file address Integer data is stored as binary values in a byte, word, or longword. These values correspond to the VAX BASIC data type keywords BYTE, WORD, and LONG; these are all subtypes of the type INTEGER. Floating-point values are stored using a signed exponent and a binary fraction. VAX BASIC allows four floating-point formats: single, double, G_floating, and H_floating. These formats correspond to the VAX BASIC data type keywords SINGLE, DOUBLE, GFLOAT, AND HFLOAT; these are all subtypes of the type REAL. 1-12 Program Elements and Structure VAX BASIC packed decimal data is stored in a string of bytes. Refer to Chapter 19 of the VAX BASIC User Manual for more information on the storage of packed decimal data. Character data consists of strings of bytes containing ASCII code as binary data. The first character in the string is stored in the first byte, the second character is stored in the second byte, and so on. VAX BASIC allows up to 65535 characters for a STRING data element. In addition to this data type, VAX BASIC also recognizes a special RFA data type to provide information about a record's file address. An RFA uniquely specifies a record in a file: you can access RMS files of any organization by record's file address. By specifying the disk address of a record, RMS retrieves the record at that address. Accessing records by RFA is more efficient and faster than other forms of random record access. The RFA data type can only be used for • • • • • RFA operations (the GETRFA function and the GET and FIND statements) Assignments to other variables of the RFA data type Comparisons with other variables of the RFA data type with the equal to ( =) and not equal to ( < > ) relational operators Formal and actual parameters DEF and function results You cannot declare a constant of the RFA data type, nor can you use RFA variables for any arithmetic operations. The RFA data type requires 6 bytes of information. See the VAX BASIC User Manual for more information on Record File Addresses and the RFA data type. For the DECIMAL(d,s) data type, you can specify the total number of digits ( d) in the data type and the number of digits to the right of the decimal point ( s ). For instance, DECIMAL(l0,3) specifies decimal data with a total of 10 digits, 3 of which are to the right of the decimal point. Table 1-2 lists VAX BASIC data type keywords and summarizes VAX BASIC data types. July 1988 Program Elements and Structure 1-13 Table 1-2: Data Type Keyword VAX BASIC Data Types Size Range Precision (decimal) (digits) 8 bits -128 to +127 NA Integer BYTE WORD 16 bits -32768 to +32767 NA LONG 32 bits -2147483648 to +2147483647 NA SINGLE 32 bits 6 DOUBLE 64 bits GFLOAT 64 bits HFLOAT 128 bits .29 * 10- 38 to 1.7 * 1038 .29 * 10- 38 to 1.7 * 1038 .56 * 10- 308 to .90 * 10308 .84 * 10- 4932 to .59 * 104932 0 to 16 bytes 1 * 10- 31 to 1 * 1031 NA One character per byte Max= 65535 NA 6 bytes NA NA Real 16 15 33 Decimal DECIMAL(d,s) String STRING RFA RFA In Table 1-2, REAL and INTEGER are generic data type keywords that specify floating-point and integer storage, respectively. If you use the REAL or INTEGER keywords to type data, the actual data type (SINGLE, DOUBLE, GFLOAT, HFLOAT, BYTE, WORD, or LONG) depends on the current default. If you do not explicitly type one of the appropriate 1-14 Program Elements and Structure subtypes, VAX BASIC uses the current subtype defaults for REAL and INTEGER. You can specify data type defaults in the BASIC environment with the SET and COMPILE commands, or from DCL level with the DCL command BASIC. You can also specify whether program values are to be typed implicitly or explicitly. The following sections discuss data type defaults and implicit and explicit data typing. 1.3. 1 Implicit Data Typing You can implicitly assign a data format to program values by adding a suffix to the variable name or constant value. If you do not specify any suffix, the variable or constant is assigned the current default data type. The following rules apply for implicit data typing: • • • A dollar sign suffix ( $) specifies STRING storage. A percent sign suffix ( % ) specifies INTEGER storage. No special suffix character specifies storage of the default type, which can be INTEGER, REAL, or DECIMAL. With implicit data typing, the range and precision for program values are determined by the corresponding default data sizes or subtypes: • • • BYTE, WORD, or LONG for INTEGER values SINGLE, DOUBLE, GFLOAT, or HFLOAT for REAL values The default (d,s) values for DECIMAL values The default data type is determined by one of the following: • • • • The system default (REAL) The data type set for the BASIC environment with the SET or COMPILE compiler command The data type set for the BASIC environment with the BASIC statement OPTION The data type set for VAX BASIC with a qualifier for the DCL command BASIC The VAX BASIC qualifiers for the SET and COMPILE commands are described in Chapter 2 of this manual. The qualifiers for the DCL command BASIC are listed in the VAX BASIC User Manual. Program Elements and Structure 1-15 Note that if you compile your program with the /TYPE_DEFAULT= EXPLICIT qualifier (on either the DCL command BASIC or VAX BASIC command COMPILE), you can still add the appropriate suffixes to your variable names or constant values. The suffixes are useful because they identify the data type of the variable or constant immediately; the reader does not have to refer to the declarations at the top of the program to see which data type applies to a particular program value. However, with the /TYPE_DEFAULT=EXPLICIT qualifier, you must still explicitly assign data types to all program values or VAX BASIC signals an error. It is considered good programming practice to use explicit data typing because implicit data typing is dependent on compilation defaults. These defaults may change, thereby affecting the precision of the program values. 1.3.2 Explicit Data Typing Explicit data typing means that you use a declarative statement to specify the type, range, and precision of your program values. Declarative statements associate attributes such as data type and value with user identifiers. In the following example, the first DECLARE statement associates the constant value 03060 and the STRING data type with a constant named zip_code. The second DECLARE statement associates the STRING data type with emp_name, the DOUBLE data type with with_tax, and the SINGLE data type with int_rate. No constant values are associated with identifiers in the second DECLARE statement because they are variable names. Example DECLARE STRING CONSTANT zip_code = 11 03060 11 DECLARE STRING emp_name, DOUBLE with_tax, SINGLE int_rate With explicit data typing, each program variable within a program can have a different range and precision. You can explicitly assign data types to variables, constants, arrays, parameters, and functions; therefore, integer data does not have to take the compilation default types. Explicit data typing gives you more control over your program. Using the REAL and INTEGER keywords to explicitly type program values allows you to write programs that are transportable across systems, because these data type keywords specify that all floating-point and integer data take the current defaults for REAL and INTEGER. The data 1-16 Program Elements and Structure type INTEGER, for example, specifies only that the constant or variable is an integer. The actual subtype (BYTE, WORD, or LONG) depends on the default set with the COMPILE or SET command, the DCL command BASIC, or with the OPTION statement. You can also specify a particular data type size for values declared INTEGER or REAL with compilation qualifiers. The /DOUBLE qualifier, for instance, specifies that all data typed REAL is to be treated as double-precision data. The /TYPE_DEFAULT=EXPLICIT qualifier or OPTION TYPE=EXPLICIT statement allows you to specify that all program data must be explicitly typed. Compiling a program with /TYPE_DEFAULT= EXPLICIT or specifying OPTION TYPE=EXPLICIT means that any program value not explicitly declared causes VAX BASIC to signal an error. For new applications, DIGITAL recommends using VAX BASIC's explicit data typing features. See the VAX BASIC User Manual for more information. 1.4 Variables A variable is a named quantity whose value can change during program execution. Each variable name refers to a location in the program's storage area. Each location can hold only one value at a time. Variables of all data types can have subscripts that indicate their position in an array. You can declare variables implicitly or explicitly. Depending on the program operations specified, the value of a variable can change from statement to statement. VAX BASIC uses the most recently assigned value when performing calculations. This value remains in effect until a new value is assigned to the variable. VAX BASIC accepts these general types of variables: • • • • • • Floating-point Integer String RFA Packed decimal Record Program Elements and Structure 1-1 7 See the VAX BASIC User Manual for more information on RFA variables and RECORD data structures. 1.4.1 Variable Names The name given to a variable depends on whether the variable is internal or external to the program and whether the variable is implicitly or explicitly declared. All variable names must conform to the following rules: • • • • • • The name can have from 1 to 31 characters. The name has no embedded spaces. The first character of the name must be an upper- or lowercase alphabetic character (A through Z). The last character of the name can be either a dollar sign ( $ ) to indicate a string variable or a percent sign ( % ) to indicate an integer variable. If the last character is neither a dollar sign nor a percent sign, the name indicates a variable of the default type. The remaining characters, if present, can be any combination of upperor lowercase letters (A through Z), numbers (0 through 9), dollar signs ( $ ), underscores ( _ ), or periods (. ). The use of underscores in variable names helps improve readability and is preferred to the use of periods. The name of an external, explicitly declared variable in VAX BASIC must follow the rules for naming any explicitly declared variable. Note that a program cannot have external, implicitly declared variables since all implicitly declared names except SUB subprogram names are internal to the program. 1-18 Program Elements and Structure 1.4.2 Implicitly Declared Variables VAX BASIC accepts three types of implicitly declared variables: • • • Integer String Floating-point (or the default data type) The name of an implicitly declared variable defines its data type. Integer variables end with a percent sign ( % ), string variables end with a dollar sign ( $ ), and variables of the default type (usually floating-point) end with any allowable character except a percent sign or dollar sign. All three types of variables must conform to the rules listed in Section 1.4.1 for naming variables. The current data type default (INTEGER, REAL, or DECIMAL) determines the data type of implicitly declared variables that do not end in a percent sign or dollar sign. A floating-point variable is a named location that stores a single floatingpoint value. The current default size for floating-point numbers (SINGLE, DOUBLE, GFLOAT or HFLOAT) determines the data type of the floatingpoint variable. The following are valid floating-point variable names: c L ... 5 JD_NUMBER Ml BIG47 STORAGE_LOCATIQN _FQR_)(X F67LJ Z2. STRESS_VALUE If a numeric value of a different data type is assigned to a floating-point variable, VAX BASIC converts the value to a floating-point number. An integer variable is a named location that stores a single integer value. The current default size for integers (BYTE, WORD, or LONG) determines the data type of an integer variable. The following are valid integer variable names: ABCDEFG% C_8% RECORD_NUMBER% 8% D6E7% THE_VALUE_LWANT% If the default data type is INTEGER, the percent suffix (%)is not necessary. Program Elements and Structure 1-19 If you assign a floating-point or decimal value to an integer variable, VAX BASIC truncates the fractional portion of the value. It does not round to the nearest integer. For example: 100 BY,= -5.7 VAX BASIC assigns the value -5 to the integer variable, not -6. A string variable is a named location that stores strings. The following are valid string variable names: Cl$ M$ EMPLOYEE_NAME$ L_6$ F34G$ TARGELRECORD$ ABC1$ T..$ STORAGE_SHELLIDENTIFIER$ Strings have both value and length. VAX BASIC sets all string variables to a default length of zero before program execution begins, with the exception of those variables in a COMMON, MAP, virtual array, or record definition. See the COMMON statement and the MAP statement in Chapter 4 of this manual for information on string length in COMMON and MAP areas. See the VAX BASIC User Manual for information on default string length in virtual arrays. During execution, the length of a character string associated with a string variable can vary from zero (signifying a null or empty string) to 65535 characters. 1.4.3 Explicitly Declared Variables VAX BASIC lets you explicitly assign a data type to a variable or an array. For example: DECLARE DOUBLE Interest_rate Data type keywords are described in Section 1.1.3.1. For more information on explicit declaration of variables, see the sections on the COMMON, DECLARE, DIMENSION, DEF, FUNCTION, EXTERNAL, MAP, and SUB statements in Chapter 4 of this manual. See also the VAX BASIC User Manual. 1-20 Program Elements and Structure 1.4.4 Subscripted Variables and Arrays A subscripted variable references part of an array. Arrays can be of any valid data type. Subscripted variables and arrays follow the same naming conventions as unsubscripted variables. Subscripts follow the variable name in parentheses and define the variable's position in the array. When you create an array, you specify the maximum size of the array (the bounds) in parentheses following the array name. In the following example, the DECLARE statement sets the bounds of the array emp_name to 1000. Therefore, the maximum value for an emp_name subscript is 1000. The bounds of the array define the maximum value for a subscript of that array. Example DECLARE STRING emp_name(1000) FOR IY. = 0% TO 1000% INPUT "Employee name";emp_name(IY.) NEXT !Y. Subscripts can be any positive LONG integer value between 0 and 2147483647. NOTE By default, VAX BASIC signals an error if a subscript is bigger than the allowable range. Note, however, that the amount of storage the system can allocate depends on available memory. Therefore, very large arrays may cause an internal allocation error even though the subscript is still within the specified range. An array is a set of data ordered in any number of dimensions. A onedimensional array, like emp_name(lOOO), is called a list or vector. A two-dimensional array, like payrol1-data(5,5), is called a matrix. An array of more than two dimensions, like big_array(l5,9,2), is called a tensor. As a default, VAX BASIC arrays are always zero-based. The number of elements in any dimension includes element number zero. For example, the array emp_name contains 1001 elements, since VAX BASIC allocates element zero. Payrol1-data(5,5) contains 36 elements because VAX BASIC allocates row and column zero. Program Elements and Structure 1-21 Often, however, applications call for arrays that are not zero-based. In VAX BASIC, you can define arrays that are not zero-based by specifying a lower bound, as well as an upper bound, for the subscripts. In this way, you can create an array with arbitrary starting and ending points. For example, you might want to create array birth_rate that holds the annual birth rate statistics for the years 1950 through 1985: DECLARE birth_rate(1960 TO 1986) Lower bounds are not allowed with virtual arrays or arrays used in MAT statements. However, you can specify lower bounds for any or all dimensions of a compile-time dimensioned array. If a multi-dimensional array is declared with lower bounds specified for some dimensions and not others, zero will be used for those dimensions without lower bounds. You can use the UBOUND and LBOUND functions to determine the upper and lower bounds of an array. For a description of these funtions, see Chapter 4 of this manual. For all arrays except virtual arrays, the total number of array elements cannot exceed 2147483647. Note, however, that this is a theoretical value; the actual maximum size of an array which you can declare depends on the configuration of your system. VAX BASIC arrays can have up to 32 dimensions. You can specify the type of data the array contains with data type keywords. Table 1-2 lists VAX BASIC data types. An element in a one-dimensional array has a variable name followed by one subscript in parentheses. There can be a space between the array name and the subscripts. For example: A(6%) B (6%) C$ (6%) A(6%) refers to the seventh item in this list: A(OY.) A(1%) A(2Y.) A(3%) A(4%) A(6%) A(6Y.) An element in a two-dimensional array has two subscripts, in parentheses, following the variable name. The first subscript specifies the row number and the second subscript specifies the column. Use a comma to separate the subscripts. You can include a space between the array name and the subscripts if you like. For example: A (7%,2%) 1-22 AY.(4Y.,6Y.) Program Elements and Structure A$ (10%,10%) In the following figure, the arrow points to the element specified by the subscripted variable A %(4%,6%): COLUMNS 0123456 RO 01 W2 S3 4 0000000 0000000 0 0 00 0 0 0 0000000 0 0 0 0 0 0 0 . . - A%(4%,6%) ZK-5549-86 An element in an array has as many subscripts as there are dimensions. Although a program can contain a variable and an array with the same name, this is poor programming practice. Variable A and the array A(3%,3%) are separate entities and are stored in completely separate locations, so it is a good idea to give them different names. Note that a program cannot contain two arrays with the same name but a different number of subscripts. For example, the arrays A(3 %) and A(3%,3%) are invalid in the same program. VAX BASIC arrays can be redimensioned at run time. See the VAX BASIC User Manual for more information on arrays. 1.4.5 Initialization of Variables VAX BASIC sets variables to zero or null values at the start of program execution. Variables initialized by VAX BASIC include: • • • Numeric variables and in-storage array elements (except those in MAP or COMMON statements). String variables (except those in MAP or COMMON statements). Variables in subprograms. Subprogram variables are initialized to zero or the null string each time the subprogram is called. Program Elements and Structure 1-23 VAX BASIC does not initialize the following: • • Virtual arrays Variables in MAP and COMMON areas 1.5 Constants A constant is a numeric or character literal that does not change during program execution. A constant can also be named and associated with a data type. VAX BASIC allows the following types of constants: • • Numeric: Floating-point Integer Packed decimal String (ASCII characters enclosed in quotation marks) A constant of any of the above data types can be named with the DECLARE CONSTANT statement. You can then refer to the constant by name in your program. Refer to Section 1.5.3 for information on naming constants. You can use the OPTION statement to declare a default data type for all constants in your program. This statement allows you to specify a data type for only the constants in your program; you can specify a different data type for variables. You can also use a special numeric literal notation to specify the value and data type of a numeric literal. Numeric literal notation is discussed in Section 1.5.4. If you do not specify a data type for a numeric constant with the DECLARE CONSTANT statement or with numeric literal notation, the type and size of the constant is determined by the default REAL, INTEGER, or DECIMAL type set with the DCL command BASIC, the VAX BASIC SET or COMPILE commands, or the OPTION statement. To simplify the representation of certain ASCII characters and mathematical values, VAX BASIC also supplies some predefined constants. The following sections discuss numeric and string constants, named constants, numeric literal notation, and predefined constants. 1-24 Program Elements and Structure 1.5.1 Numeric Constants A numeric constant is a literal or named constant whose value never changes. In VAX BASIC, a numeric constant can be a floating-point number, an integer, or a packed decimal number. The type and size of a numeric constant is determined by • • • • • • The system default values The defaults set by the qualifiers for the DCL command BASIC The data type qualifiers specified with the COMPILE command The defaults set by the SET command The data type specified in a DECLARE CONSTANT or OPTION statement Numeric literal notation If you use a declarative statement to name and declare the data type of a numeric constant, the constant is of the type and size specified in the statement. For example: DECLARE BYTE CONSTANT age = 12 This example associates the numeric literal 12 and the BYTE data type with the identifier age. To specify a data type for an unnamed numeric constant, you must use the numeric literal notation format described in Section 1.5.4. 1.5.1.1 Floating-Point Constants A floating-point constant is a literal or named constant with one or more decimal digits, either positive or negative, with an optional decimal point and an optional exponent (E notation). If the default data type is integer, VAX BASIC will treat the literal as an INTEGER unless it contains a decimal point or the character E. If the default data type is DECIMAL, an Eis required or VAX BASIC treats the literal as a packed decimal value. The following table contains examples of floating-point literals with REAL, INTEGER, and DECIMAL default data types. Program Elements and Structure 1-25 REAL INTEGER -8.738 -8.738 DECIMAL -8.738 239.21£-6 239.21£-6 239.21£-6 .79 .79 .79E 299 299E 299E Very large and very small numbers can be represented in E (exponential) notation. If a positive number appears in E notation, it can be preceded by an optional plus sign ( + ). A negative number in E notation must be preceded by a minus sign ( - ). A number can be carried to a maximum of 6 decimal places for SINGLE precision, 16 decimal places for DOUBLE precision, 15 decimal places for GFLOAT precision, and 33 places for HFLOAT precision. To indicate E notation, a number must be followed by the letter E. It also must be followed by an exponent sign and an exponent. The exponent sign indicates if the exponent is either positive or negative and is optional only if you are specifying a· positive exponent. The exponent is an integer constant (the power of 10). Table 1-3 compares numbers in standard and E notation. Table 1-3: Numbers in E Notation Standard Notation E Notation .0000001 .lE-06 1,000,000 .1E+07 -10,000,000 -.1E+08 100,000,000 .1E+09 1,000,000,000,000 .1E+13 The range and precision of floating-point constants are determined by the current default data types or the explicit data type used in the DECLARE CONSTANT statement. However, there are limits to the range allowed for numeric data types. Table 1-2 lists VAX BASIC data types and ranges. VAX BASIC signals the fatal error "Floating point error or overflow" (ERR=48) when your program attempts to specify a constant value outside of the allowable range for a floating-point data type. 1-26 Program Elements and Structure 1.5.1.2 Integer Constants An integer constant is a literal or named constant, either positive or negative, with no fractional digits and an optional trailing percent sign ( % ). The percent sign is required for integer literals only if the default type is not INTEGER. In the following table, the values are all integer constants. The presence of the percent sign varies depending on the default data type. INTEGER REAL or DECIMAL 81257 81257% -3477 -3477% 79 79% The range of allowable values for integer constants is determined by either the current default data type or the explicit data type used in the DECLARE CONSTANT statement. Table 1-2 lists VAX BASIC data types and ranges. VAX BASIC signals an error for a number outside the applicable range. If you want VAX BASIC to treat numeric literals as integer numbers, you must do one of the following: • • • Set the default data type to INTEGER Make sure the literal has a percent sign suffix Use explicit literal notation The VAX BASIC compiler must convert numeric literals when assigning them to integer variables. This means that your program runs somewhat slower than it would if integer values were explicitly declared. You can prevent this conversion step by using one of the following: • • • Percent signs for integer constants Numeric literal notation Named integer constants NOTE You cannot use percent signs in integer constants that appear in DATA statements. An attempt to do so causes VAX BASIC to signal "Data format error" (ERR=SO). Program Elements and Structure 1-27 1.5. 1.3 Packed Decimal Constants A packed decimal constant is a number, either positive or negative, that has a specified number of digits and a specified decimal point position (scale). You specify the number of digits ( d) and the position of the decimal point ( s) when you declare the constant as a DECIMAL(d,s). If the constant is not declared, the number of digits and the position of the decimal is determined by the representation of the constant. For example, when the default data type is DECIMAL, 1.234 is a DECIMAL(4,3) constant, regardless of the default decimal size. Likewise, using numeric literal notation, "1.234"P is a DECIMAL(4,3) constant, regardless of the default data type and default DECIMAL size. Numeric literal notation is described in Section 1.5.4. 1.5.2 String Constants String constants are either string literals or named constants. A string literal is a series of characters enclosed in string delimiters. Valid string delimiters are: • • Double quotation marks ("text") Single quotation marks ('text') You can embed double quotation marks within single quotation marks ('this is a "text" string') and vice versa ("this is a 'text' string"). Note, however, that VAX BASIC does not accept incorrectly paired quotation marks and that only the outer quotation marks must be paired. The following character strings, for example, are valid: "The record number does not exist." "I'm here!" "The terminating 'condition' is equal to A$. 11 "REPORT 543" The following strings are not valid: "Quotation marks that do not match' "No closing quotation mark Characters in string constants can be letters, numbers, spaces, tabs, 8bit data characters, or the NUL character (ASCII code 0). If you need a string constant that contains a NUL, you should use the NUL predefined constant. See Section 1.5.4 in this manual for information on explicit literal notation. 1-28 Program Elements and Structure The VAX BASIC compiler determines the value of the string constant by scanning all its characters. For example, because of the number of spaces between the delimiters and the characters, these two string constants are not the same: END-OF-FILE REACHED "END-OF-FILE REACHED" VAX BASIC stores every character between delimiters exactly as you type it into the source program, including: • • • • Lowercase letters (a-z) Leading, trailing, and embedded spaces Tabs Special characters The delimiting quotation marks are not printed when the program is executing. The value of the string constant does not include the delimiting quotation marks. Example PRINT "END-OF-FILE REACHED" END Output END-OF-FILE REACHED Note, however, that VAX BASIC prints double or single quotation marks when they are enclosed in a second paired set: Example PRINT 'FAILURE CONDITION: "RECORD LENGTH"' END Output FAILURE CONDITION: "RECORD LENGTH" Program Elements and Structure 1-29 1.5.3 Named Constants VAX BASIC allows you to name constants. You can assign a name to a constant that is either internal or external to your program and refer to the constant by name throughout the program. This naming feature is useful for the following reasons: • If a commonly used constant must be changed, you need to make only • one change in your program. A logically named constant makes your program easier to understand. You can use named constants anywhere you can use a constant, for example, to specify the number of elements in an array. You cannot change the value of an explicitly named constant during program execution. To change the value of a constant, you must change the program statement that names the constant and declares its value, and then recompile the program. 1.5.3.1 Naming Constants Within a Program Unit You name constants within a program unit with the DECLARE statement. Example DECLARE DOUBLE CONSTANT preferred_rate = .147 DECLARE SINGLE CONSTANT normal_rate = .162 DECLARE DOUBLE CONSTANT risky_rate = .175 new_bal = old_bal * (1 + preferred_rate)-years_payment When interest rates change, only three lines have to be changed rather than every line that contains an interest rate constant. Constant names must conform to the rules for naming internal, explicitly declared variables listed in Section 1.4.1. Note that constant names cannot have embedded spaces. The value associated with a named constant can be a compile-time expression as well as a literal value, as shown in the following example. 1-30 Program Elements and Structure Example DECLARE STRING CONSTANT Congrats = t "+--------------------+" + LF + CR + t "I Congratulations! I" +CR+ CR+ t "+--------------------+" PRINT Congrats PRINT Congrats Named constants can save you programming time because you do not have to retype the value every time you want to display it. Named constants can save you execution time because the named constant is known at compilation time. Valid operators in DECLARE CONSTANT expressions include all valid arithmetic, relational, and logical operators except exponentiation. You cannot use built-in functions in DECLARE CONSTANT expressions. VAX BASIC allows constants of all data types except RFA to be named as expressions. Because you cannot declare a constant of the RFA data type you cannot name one as an expression. The following example illustrates the concept of naming constants as expressions: DECLARE DOUBLE CONSTANT min_value = 0, max_value = PI/2 t t You can specify only one data type in a DECLARE CONSTANT statement. To declare a constant of a different data type, you must use a second DECLARE CONSTANT statement. 1.5.3.2 Naming Constants External to a Program Unit To declare constants outside the program unit, use the EXTERNAL statement. Program Elements and Structure 1-31 Example EXTERNAL LONG CONSTANT SS$_NORMAL EXTERNAL WORD CONSTANT IS_SUCCESS The first line declares the VAX/VMS status code SS$_NORMAL to be an external LONG constant. The second line declares IS_SUCCESS, a success code, to be an external WORD constant. Note that VAX BASIC allows only external BYTE, WORD, LONG, and SINGLE constants. The VAX/VMS Linker supplies the values for the constants specified in EXTERNAL statements. External constant names cannot exceed 31 characters and must conform to the rules for naming external variables listed in Section 1.4.1. No external constant name can have embedded spaces. In VAX BASIC, the named constant might be a system status code or a global constant declared in a VAX MACRO or VAX BLISS program. 1.5.4 Explicit Literal Notation You can specify the value and data type of numeric literals by using a special notation called explicit literal notation. The format of this notation is as follows: [radix] "num-str-lit" [data-type] Radix specifies an optional base, which can be any of the following: D Decimal (base 10) B Binary (base 2) 0 Octal (base 8) x Hexadecimal (base 16) A ASCII The VAX BASIC default radix is decimal. Binary, octal, and hexadecimal notation allow you to set or clear individual bits in the representation of an integer. This feature is useful in forming conditional expressions and in using logical operations. The ASCII radix causes VAX BASIC to translate a single ASCII character to its decimal equivalent. This decimal equivalent is an INTEGER value; you specify whether the INTEGER subtype should be BYTE, WORD, or LONG. 1-32 Program Elements and Structure Num-str-lit is a numeric string literal. It can be the digits 0 and 1 when the radix is binary, the digits 0 through 7 when the radix is octal, the digits 0 through F when the radix is hexadecimal, and the digits 0 through 9 when the radix is decimal. When the radix is ASCII, num-str-lit can be any valid ASCII character. Data-type is an optional single letter that corresponds to a data type keyword, excluding INTEGER and REAL: B BYTE w WORD L LONG F SINGLE D DOUBLE G GFLOAT H HFLOAT p DECIMAL c CHARACTER Note that data-type for the ASCII radix is limited to BYTE, WORD, or LONG. For example: D"255"L Specifies a LONG decimal constant with a value of 255 "4000"F Specifies a SINGLE decimal constant with a value of 4000 -"125"B Specifies a BYTE decimal constant with a value of -125 A"M"L Specifies a LONG integer constant with a value of 77 A"m"B Specifies a BYTE integer constant with a value of 109 A quoted numeric string alone, without a radix and a data type, is a string literal, not a numeric literal. For example: "255"W Specifies a WORD decimal constant with a value of 255 "255" Is a string literal Program Elements and Structure 1-33 If you specify a binary, octal, or hexadecimal radix, data-type must be an integer. If you do not specify a data type, VAX BASIC uses the default integer data type. For example: B"llllllll"B Specifies a BYTE binary constant with a value of -1 B"l 1111111 "W Specifies a WORD binary constant with a value of 255 B"ll 111111" Specifies a binary constant of the default data type (BYTE, WORD, or LONG) B"llllllll"F Is illegal because F is not an integer data type X"FF"B Specifies a BYTE hexadecimal constant with a value of -1 X"FF"W Specifies a WORD hexadecimal constant with a value of 255 X"FF"D Is illegal because D is not an integer data type 0"377"B Specifies a BYTE octal constant with a value of -1 0"377"W Specifies a WORD octal constant with a value of 255 0"377"G Is illegal because G is not an integer data type When you specify a radix other than decimal, overflow checking is performed as if the numeric string were an unsigned integer. However, when this value is assigned to a variable or used in an expression, the VAX BASIC compiler treats it as a signed integer. In the following example, VAX BASIC sets all 8 bits in storage location A. Because A is a BYTE integer, it has only 8 bits of storage. Because the 8-bit two's complement of 1 is 11111111, its value is -1. If the data type were W (WORD), VAX BASIC would set the bits to 0000000011111111, and its value would be 255. Example DECLARE BYTE A A = B"11111111"B PRINT A Output -1 NOTE In VAX BASIC, a D can appear in both the radix position and the data type position. D in the radix position specifies that the numeric string is to be treated as a decimal number (base 10). D in the data type position specifies that the value is to be treated as a double-precision, floating-point constant. P in 1-34 Program Elements and Structure the data type position specifies a packed decimal constant. For example: "255"0 Specifies a double-precision constant with a value of 255 "255.55"P Specifies a DECIMAL constant with a value of 255.55 You can use explicit literal notation to represent a single-character string in terms of its 8-bit ASCII value. For example: [radix] num-str-lit C The letter C is an abbreviation for CHARACTER. The value of the numeric string must be from 0 through 255. This feature lets you create your own compile-time string constants containing nonprinting characters. The following example declares a string constant named control_g (ASCII decimal value 7). When VAX BASIC executes the PRINT statement, the terminal bell sounds. Example DECLARE STRING CONSTANT control_g = "7"C PRINT control_g 1.5.5 Predefined Constants Predefined constants are symbolic representations of either ASCII characters or mathematical values. They are also called compile-time constants because their value is known at compilation rather than at run time. Predefined constants help you • • Format program output to improve readability Make source code easier to understand Table 1-4 lists the predefined constants supplied by VAX BASIC, their ASCII values, and their functions. Program Elements and Structure 1-35 Table 1-4: Predefined Constants Constant Decimal ASCII Value Function BEL (Bell) 7 Sounds the terminal bell BS (Backspace) 8 Moves the cursor one position to the left HT (Horizontal Tab) 9 Moves the cursor to the next horizontal tab stop LF (Line Feed) 10 Moves the cursor to the next line VT (Vertical Tab) 11 Moves the cursor to the next vertical tab stop FF (Form Feed) 12 Moves the cursor to the start of the next page CR (Carriage Return) 13 Moves the cursor to the beginning of the current line SO (Shift Out) 14 Shifts out for communications networking, screen formatting, and alternate graphics SI (Shift In) 15 Shifts in for communications networking, screen formatting, and alternate graphics ESC (Escape) 27 Marks the beginning of an escape sequence SP (Space) 32 Inserts one blank space in program output DEL (Delete) 127 Deletes the last character entered PI None Represents the number PI with the precision of the default floating-point data type You can use predefined constants in many ways. For instance, the following example shows how to print and underline a word on a hard copy terminal. 1-36 Program Elements and Structure Example PRINT "NAME:" +BS+ BS+ BS+ BS+ BS+ "-----" END Output NAME: The following example shows how to print and underline a word on a VTl 00 video display terminal. Example PRINT ESC + "[4mNAME:" + ESC + "[Om" END Output NAME: Note that the "m" in the above example must be lowercase. You can also create your own predefined constants with the DECLARE CONSTANT statement. In the following example, the first DECLARE statement defines underlined_name as a string constant. The second DECLARE statement defines o_pI as a DOUBLE constant equal to the predefined constant PI. If the de- fault REAL data size is SINGLE, the program can use both single-precision PI and double-precision v_pI. Example DECLARE STRING CONSTANT underlined_name = ESC + "[4mNAME:" + ESC + 11 [0m 11 DECLARE DOUBLE CONSTANT D_PI = PI PRINT underlined_name PRINT D_PI, , PI 1.6 Expressions VAX BASIC expressions consist of operands (numbers, strings, constants, variables, functions, and array elements) separated by arithmetic, string, relational, and logical operators. Program Elements and Structure 1-37 Almost all VAX BASIC expressions yield numeric values. The only exceptions are string concatenation expressions and invocations of stringvalued functions. By using different combinations of numeric operators and operands, and by using the resulting values, you can produce • • • Numeric expressions String expressions Conditional expressions VAX BASIC evaluates expressions according to operator precedence and uses the results in program execution. Parentheses can be used to group operands and operators, thus controlling the order of evaluation. The following sections explain the types of expressions you can create and the way VAX BASIC evaluates expressions. 1.6.1 Numeric Expressions Numeric expressions consist of floating-point, integer, or packed decimal operands separated by arithmetic operators and optionally grouped by parentheses. Table 1-5 shows how numeric operators work in numeric expressions. Table 1-5: Arithmetic Operators Operator Example + A+B Add B to A A-B Subtract B from A * A*B Multiply A by B I A/B Divide A by B KB Raise A to the power B ** A**B Raise A to the power B Use In general, two arithmetic operators cannot occur consecutively in the same expression. Exceptions are the unary plus and unary minus. The following expressions are valid. 1-38 Program Elements and Structure A* + B A* - B A * (-B) A* + - + - B The following expression is not valid: A- * B An operation on two numeric operands of the same data type yields a result of that type. For example: A% +B% Yields an integer value of the default type G3 *MS Yields a floating-point value if the default type is REAL If the result of the operation exceeds the range of the data type, VAX BASIC signals an overflow error message. The following example causes VAX BASIC to signal the error "Integer error or overflow" because the sum of A and B (254) exceeds the range of -128 to +127 for BYTE integers. Similar overflow errors occur for REAL and DECIMAL data types whenever the result of a numeric operation is outside the range of the corresponding data type. Example DECLARE BYTE A, B A = 127 B = 127 PRINT A + B END It is possible to assign a value of one data type to a variable of a different data type. When this occurs, the data type of the variable overrides the data type of the assigned value. The following example assigns the value 32 to the integer variable A% even though the floating-point value of the expression is 32.13. Example AY. = 5.1 * 6.3 Program Elements and Structure 1-39 1.6.1.1 Floating-Point and Integer Promotion Rules When an expression contains operands with different data types, the data type of the result is determined by VAX BASIC's data type promotion rules: • • With one exception, VAX BASIC promotes operands with different data types to the lowest common data type that can hold the largest or most precise possible value of either operand's data type. VAX BASIC then performs the operation using that data type, and yields a result of that data type. The exception is that when an operation involves SINGLE and LONG data types, VAX BASIC promotes the LONG data type to SINGLE rather than DOUBLE, performs the operation, and yields a result of the SINGLE data type. Note that VAX BASIC does sign extension when converting BYTE and WORD integers to a higher INTEGER data type (WORD or LONG). The high order bit (the sign bit) determines how the additional bits are set when the BYTE or WORD is converted to WORD or LONG. If the high order bit is zero (positive), all higher-order bits in the converted BYTE or WORD are set to zero. If the high order bit is 1 (negative), all higher-order bits in the converted BYTE or WORD are set to 1. Table 1-6 lists the data type results possible in numeric expressions that combine BYTE, WORD, LONG, SINGLE, and DOUBLE data. Table 1-7 lists the data type results possible in numeric expressions that combine the data types GFLOAT and HFLOAT. When the operands are DOUBLE and GFLOAT, VAX BASIC promotes both values to HFLOAT, and returns an HFLOAT value. The promotion of DOUBLE and GFLOAT to HFLOAT is necessary because a DOUBLE value is more precise than a GFLOAT value, but cannot contain the largest possible GFLOAT value. Consequently, VAX BASIC promotes these data types to a data type that can hold the largest and most precise value of either operand. 1-40 Program Elements and Structure Table 1-6: Result Data Types in VAX BASIC Expressions BYTE WORD LONG SINGLE DOUBLE BYTE BYTE WORD LONG SINGLE DOUBLE WORD WORD WORD LONG SINGLE DOUBLE LONG LONG LONG LONG SINGLE DOUBLE SINGLE SINGLE SINGLE SINGLE SINGLE DOUBLE DOUBLE DOUBLE DOUBLE DOUBLE DOUBLE DOUBLE For example, if one operand is SINGLE and one operand is DOUBLE, VAX BASIC promotes the SINGLE value to DOUBLE, performs the specified operation, and returns the result as a DOUBLE value. This promotion is necessary because the SINGLE data type has less precision than the DOUBLE value, whereas the DOUBLE data type can represent all possible SINGLE values. If VAX BASIC did not promote the SINGLE value and the operation yielded a result outside of the SINGLE range, loss of precision and significance would occur. The data types BYTE, WORD, LONG, SINGLE, and DOUBLE form a simple hierarchy: if all operands in an expression are of these data types, the result of the expression is the highest data type used in the expression. Table 1-7: BYTE VAX BASIC Result Data Types GFLOAT HFLOAT GFLOAT HFLOAT WORD GFLOAT HFLOAT LONG GFLOAT HFLOAT SINGLE GFLOAT HFLOAT DOUBLE HFLOAT HFLOAT GFLOAT GFLOAT HFLOAT HFLOAT HFLOAT HFLOAT Program Elements and Structure 1-41 1.6.1.2 DECIMAL Promotion Rules VAX BASIC allows the DECIMAL(d,s) data type. The number of digits ( d) and the scale or position of the decimal point ( s) in the result of DECIMAL operations depends on the data type of the other operand. If one operand is DECIMAL and the other is DECIMAL or INTEGER, the d and s values of the result are determined as follows: • • If both operands are typed DECIMAL, and if both operands have the same digit ( d) and scale ( s) values, no conversions occur and the result of the operation has exactly the same d and s values as the operands. Note, however, that overflow can occur if the result exceeds the range specified by the d value. If both operands are DECIMAL but have different digit and scale values, VAX BASIC uses the larger number of specified digits for the result. In the following example, variable A allows three digits to the left of the decimal point and two digits to the right. Variable B allows one digit to the left of the decimal point and three digits to the right. Example DECLARE DECIMAL(6,2) A DECLARE DECIMAL(4,3) B • The result allows three digits to the left of the decimal point and three digits to the right. If one operand is DECIMAL and one is INTEGER, the INTEGER value is converted to a DECIMAL(d,s) data type as follows: BYTE is converted to DECIMAL(3,0). - WORD is converted to DECIMAL(S,O). - LONG is converted to DECIMAL(lO,O). VAX BASIC then determines the d and s values of the result by evaluating the d ands values of the operands as described above. Note that only INTEGER data types are converted to the DECIMAL data type. If one operand is DECIMAL and one is floating-point, the DECIMAL value is converted to a floating-point value. The total number of digits ( d) in the DECIMAL value determines its new data type, as shown in Table 1-8. 1-42 Program Elements and Structure Table 1-8: Result Data Types for DECIMAL Data Number of DECIMAL Digits in Operand SINGLE DOUBLE GFLOAT 1-6 SINGLE DOUBLE GFLOAT HFLOAT 7-15 DOUBLE DOUBLE GFLOAT HFLOAT 16 DOUBLE DOUBLE HFLOAT HFLOAT 17-31 HFLOAT HFLOAT HFLOAT HFLOAT Floating-Point Operands HFLOAT If the value of dis between 7 and 15, the operand is converted to: • • • DOUBLE if the floating-point operand is SINGLE or DOUBLE GFLOAT if the floating-point operand is GFLOAT HFLOAT if the floating-point operand is HFLOAT Thus, a DECIMAL(8,5) operand is converted to DOUBLE if the other operand is SINGLE or DOUBLE, to GFLOAT if the other operand is GFLOAT, and to HFLOAT if the other operand is HFLOAT. Note also that exponentiation of a DECIMAL data type returns a REAL value. See the VAX BASIC User Manual for tutorial information on data type interactions, conversions, and promotion rules in VAX BASIC numeric expressions. 1.8.2 String Expressions String expressions are string entities separated by the plus sign ( + ). When used in a string expression, the plus sign concatenates strings. Example INPUT "Type two words to be combined";A$, B$ C$ = A$ + B$ PRINT C$ END Program Elements and Structure 1-43 Output Type two words to be combined? long ? word longword Ready 1.6.3 Conditional Expressions Conditional expressions can be either relational or logical expressions. Numeric relational expressions compare numeric operands to determine whether the expression is true or false. String relational expressions compare string operands to determine which string expression occurs first in the ASCII collating sequence. Logical expressions contain integer operands and logical operators. VAX BASIC determines whether the specified logical expression is true or false by testing the numeric result of the expression. Note that in conditional expressions, as in any numeric expression, when BYTE and WORD operands are converted to WORD and LONG, the specified operation is performed in the higher data type, and the result returned is also of the higher data type. When one of the operands is a negative value, this conversion will produce accurate but perhaps confusing results, because VAX BASIC performs a sign extension when converting BYTE and WORD integers to a higher integer data type. See Section 1.6.1.1 for information on integer conversion rules. 1.6.3. 1 Numeric Relational Expressions Operators in numeric relational expressions compare the values of two operands and returns either a -1 if the relation is true, or a zero if the relation is false. The data type of the result is the default integer type. 1-44 Program Elements and Structure Example 1 A = 10 B = 15 X% = (A <> B) IF X% = -1% THEN PRINT 'Relationship is true' ELSE IF X% = 0 THEN PRINT 'Relationship is false' END IF END IF Output 1 Relationship is true Example 2 A = 10 B = 15 X% = A = B IF X% = -1% THEN PRINT 'Relationship is true' ELSE IF X% = 0 THEN PRINT 'Relationship is false' END IF END IF Output 2 Relationship is false Table 1-9 shows how numeric operators work in numeric relational expressions. Table 1-9: Operator Numeric Relational Operators Example Meaning A=B A is equal to B. < A <B A is less than B. > A> B A is greater than B. <=or=< A <= B A is less than or equal to B. Program Elements and Structure 1-45 Table 1-9 (Cont.): Operator Example Meaning >=or=> A>= B A is greater than or equal to B. <> or A<> B A is not equal to B. A== B A and B will PRINT the same if they are equal to six significant digits. However, if one value prints in explicit notation and the other value prints in E format notation, the relation will always be false. > < 1.6.3.2 Numeric Relational Operators String Relational Expressions Operators in string relational expressions determine how VAX BASIC compares strings. The VAX BASIC compiler determines the value of each character in the string by converting it to its ASCII value. ASCII values are listed in Appendix C in this manual. VAX BASIC compares the strings character by character, left to right, until it finds a difference in ASCII value. In the following example, VAX BASIC compares A$ and B$ character by character. The strings are identical up to the third character. Because the ASCII value of Z (90) is greater than the ASCII value of C (67), A$ is less than B$. VAX BASIC evaluates the expression A$ < B$ as true (-1) and prints "ABC comes before ABZ". Example A$ = 'ABC' B$ = 'ABZ' IF A$ < B$ THEN PRINT 'ABC comes before ABZ' ELSE IF A$ == B$ THEN PRINT 'The strings are identical' ELSE IF A$ > B$ THEN PRINT 'ABC comes after ABZ' ELSE PRINT 'Strings are equal but not identical' END IF END IF END IF END 1-46 Program Elements and Structure July 1988 If two strings of differing lengths are identical up to the last character in the shorter string, VAX BASIC pads the shorter string with spaces (ASCII value 32) to generate strings of equal length, unless the operator is the double equal sign ( == ). If the operator is the double equal sign, VAX BASIC does not pad the shorter string. Program Elements and Structure 1-46.1 In the following program, VAX BASIC compares "ABCDE" to ABC " to determine which string comes first in the collating sequence. "ABC " comes before ABCDE" because the ASCII value for space (32) is lower than the ASCII value of D (68). Then VAX BASIC compares "ABC with ABC" using the double equal sign and determines that the strings do not match exactly without padding. The third comparison uses the single equal sign. VAX BASIC pads "ABC" with spaces and determines that the two strings match with padding. /1 /1 /1 11 Example A$ = 'ABCDE' B$ = 'ABC' PRINT 'B$ comes before A$' IF B$ < A$ PRINT 'A$ comes before B$' IF A$ < B$ C$ = 'ABC I IF B$ == C$ THEN PRINT 'B$ exactly matches C$' ELSE PRINT 'B$ does not exactly match C$' END IF IF B$ = C$ THEN PRINT 'B$ matches C$ with padding' ELSE PRINT 'B$ does not match C$' END IF Output B$ comes before A$ B$ does not exactly match C$ B$ matches C$ with padding Table 1-10 shows how numeric operators work in string relational expressions. Table 1-10: String Relational Operators Operator Example Meaning A$= B$ < B$ Strings A$ and B$ are identical after the shorter string has been padded with spaces to equal the length of the longer string. < A$ > A$> B$ String A$ occurs after string B$ in ASCII sequence. <=or=< A$ <= B$ String A$ is identical to or precedes string B$ in ASCII sequence. String A$ occurs before string B$ in ASCII sequence. Program Elements and Structure 1-47 Table 1-10 (Cont.): String Relational Operators Operator Example Meaning >=or=> A$>= B$ String A$ is identical to or follows string B$ in ASCII sequence. <> or A$ B$ > < <> A$== B$ String A$ is not identical to string B$. Strings A$ and B$ are identical in composition and length, without padding. VAX BASIC treats unquoted strings typed in response to the INPUT statement differently from quoted strings; it does so by ignoring leading and trailing spaces and tabs. For example, it evaluates the quoted strings "ABC" and "ABC " as equal but not identical because the == operator does not pad the shorter string with spaces. When you input those same strings as unquoted strings in response to the INPUT prompt, VAX BASIC evaluates them as equal and identical because it ignores the trailing spaces. The LINPUT statement, on the other hand, treats unquoted strings as string literals, so the trailing spaces are part of the string, and VAX BASIC evaluates the strings as equal, but not identical. 1.6.3.3 Logical Expressions A logical expression can have one of the following formats: • • • A unary logical operator and one integer operand Two integer operands separated by a binary logical operator One integer operand Logical expressions are valid only when the operands are integers. If the expression contains two integer operands of differing data types, the resulting integer has the same data type as the higher integer operand. For instance, the result of an expression that contains a BYTE integer and a WORD integer would be a WORD integer. Table 1-6 shows how integer data types interact with each other in expressions. VAX BASIC determines whether the condition is true or false by testing the result of the logical expression to see whether any bits are set. If no bits are set, the value of the expression is zero and it is evaluated as false; if any bits are set, the value of the expression is nonzero, and the expression is evaluated as true. VAX BASIC generally accepts any nonzero value in logical expressions as true. However, logical operators can return 1-48 Program Elements and Structure unanticipated results unless -1 is specified for true values and zero for false. Table 1-11 lists the logical operators. NOTE i"i'~ DIGITAL recommends that you use logical operators on the results of relational expressions to avoid obtaining unanticipated results. Table 1-11: Logical Operators Operator Example Meaning NOT NOT A% The bit-by-bit complement of A%. If A% is true (-1), NOT A% is false (0). AND A% AND B% The logical product of A% and B%. A% AND B% is true only if both A% and B% are true. OR A% ORB% The logical sum of A% and B%. A% OR B% is false only if both A% and B% are false; otherwise, A% OR B% is true. XOR A% XOR B% The logical exclusive OR of A% and B%. A% XOR B% is true if either A% or B% is true but not if both are true. EQV A% EQV B% The logical equivalence of A% and B%. A% EQV B% is true if A% and B% are both true or both false; otherwise the value is false. IMP A%IMPB% The logical implication of A% and B%. A% IMP B% is false only if A% is true and B% is false; otherwise, the value is true. The truth tables in Figure 1-1 summarize the results of these logical operations. Zero is false; -1 is true. Program Elements and Structure 1-49 Figure 1-1: Truth Tables A% NOTA% A% 8% 0 -1 0 0 0 0 0 -1 -1 -1 -1 -1 -1 -1 -1 -0 A% OR 8% A% 8% A% AND 8% A% 8% A% EQV 8% 0 0 0 0 0 0 -1 -1 -1 -1 -1 0 0 0 0 -1 A% 8% 0 0 -1 -1 0 0 0 -1 -1 -1 -1 -1 A% XOR 8% A% 8% A%1MP8% 0 0 -1 -1 -1 0 -1 -1 0 0 0 -1 0 0 -1 -1 0 -1 -1 -1 ZK-5548-86 The operators XOR and EQV are logical complements. In the following example, the values of A% and B% both test as true because they are nonzero values. However, the logical AND of these two variables returns an unanticipated result of false. 1-50 Program Elements and Structure Example AY. = 2% BY. = 4% IF AY. THEN PRINT 'AY. IS TRUE' IF BY. THEN PRINT 'BY. IS TRUE' IF AY. AND BY. THEN PRINT 'AY. AND BY. IS TRUE' ELSE PRINT 'AY. AND BY. IS FALSE' END Output AY. IS TRUE BY. IS TRUE AY. AND BY. IS FALSE The program returns this seemingly contradictory result because logical operators work on the individual bits of the operands. The 8-bit binary representation of 2% is 0 0 0 0 0 0 1 0 The 8-bit binary representation of 4% is 0 0 0 0 0 1 0 0 Each value tests as true because it is nonzero. However, the AND operation on these two values sets a bit in the result only if the corresponding bit is set in both operands. Therefore, the result of the AND operation on 4% and 2% is 0 0 0 0 0 0 0 0 No bits are set in the result, so the value tests as false (zero). If the value of B% is changed to 6%, the resulting value tests as true (nonzero) because both 6% and 2% have the second bit set. Therefore, VAX BASIC sets the second bit in the result and the value tests as nonzero and true. The 8-bit binary representation of -1 is 1 1 1 1 1 1 1 1 The result of -1 % AND -1 % is -1 % because VAX BASIC sets bits in the result for each corresponding bit that is set in the operands. The result tests as true because it is a nonzero value. Program Elements and Structure 1-51 Example A'/. = -1'/. B'I. = -1'/. IF A'/. THEN PRINT 'A'/. IS TRUE' IF B'/. THEN PRINT 'BY. IS TRUE' IF AY. AND BY. THEN PRINT 'AY. AND B'/, IS TRUE' ELSE PRINT 'AY. AND B'/. IS FALSE' END Output A'/, IS TRUE B'/. IS TRUE AY. AND BY. IS TRUE Your program may also return unanticipated results if you use the NOT operator with a nonzero operand that is not -1. In the following example, VAX BASIC evaluates both A% and B% as true because they are nonzero. NOT A% is evaluated as false (zero) because the binary complement of -1 is zero. NOT B% is evaluated as true because the binary complement of 2 has bits set and is therefore a nonzero value. Example AY.=-1Y. BY.=2 IF AY. THEN PRINT 'AY. IS TRUE' ELSE PRINT 'AY. IS FALSE' IF BY. THEN PRINT 'BY. IS TRUE' ELSE PRINT 'BY. IS FALSE' IF NOT AY. THEN PRINT 'NOT AY. IS TRUE' ELSE PRINT 'NOT AY. IS FALSE' IF NOT BY. THEN PRINT 'NOT BY. IS TRUE' ELSE PRINT 'NOT BY. IS FALSE' END Output AY. IS TRUE BY. IS TRUE NOT AY. IS FALSE NOT BY. IS TRUE 1.8.4 Evaluating Expressions VAX BASIC evaluates expressions according to operator precedence. Each arithmetic, relational, and string operator in an expression has a position in the hierarchy of operators. The operator's position informs VAX BASIC 1-52 Program Elements and Structure of the order in which to perform the operation. Parentheses can change the order of precedence. Table 1-12 lists all operators as VAX BASIC evaluates them. Note that • • • Operators with equal precedence are evaluated logically from left to right. VAX BASIC evaluates expressions enclosed in parentheses first, even when the operator in parentheses has a lower precedence than that outside the parentheses. The addition ( +) and multiplication ( •) operators are evaluated in algebraic order. Table 1-12: Numeric Operator Precedence Operator Precedence ** or 1 - (unary minus) or + (unary plus) 2 *or/ 3 +or - 4 + (concatenation) 5 all relational operators 6 NOT 7 AND 8 OR, XOR 9 IMP 10 EQV 11 For example, VAX BASIC evaluates the expression A= 15"2 + 12"2 (35 • 8) in five steps: 1. 15~2 = 225 Exponentiation (leftmost expression) 2. 1r2 = 144 Exponentiation 3. 225 + 144 = 369 Addition 4. (35 * 8) = 280 Multiplication 5. 369 - 280 = 89 Subtraction Program Elements and Structure 1-53 There is one exception to this order of precedence: when an operator that does not require operands on either side of it (such as NOT) immediately follows an operator that does require operands on both sides (such as the addition operator ( + )), VAX BASIC evaluates the second operator first. For example: AY. + NOT BY. + CY. This expression is evaluated as (AY. + (NOT BY.)) + CY. VAX BASIC evaluates the expression NOT B before it evaluates the expression A + NOT B. When the NOT expression does not follow the addition ( +) expression, the normal order of precedence is followed: NOT AY. + BY. + CY. This expression is evaluated as: NOT ((AY. + BY.) + C %) VAX BASIC evaluates the two expressions (A%+ B%) and ((A%+ B%) + C%) because the+ operator has a higher precedence than the NOT operator. VAX BASIC evaluates nested parenthetical expressions from the inside out. In the following program, VAX BASIC evaluates the parenthetical expression A quite differently from expression B. For expression A, VAX BASIC evaluates the innermost parenthetical expression (25 + 5) first, then the second inner expression (30 / 5), then (6 * 7), and finally (42 + 3). For expression B, VAX BASIC evaluates (5 / 5) first, then (1 * 7), then (25 + 7 + 3) to obtain a different value. Example A = ((((25 + 5) I 5) * 7) + 3) PRINT A B = 25 + 5 I 5 * 7 + 3 PRINT B Output 45 35 1-54 Program Elements and Structure 1. 7 Program Documentation Documentation within a program clarifies and explains source program structure. These explanations, or comments, can be combined with code to create a more readable program without affecting program execution. Comments can appear in two forms: • • Comment fields (including empty statements) REM statements 1. 7. 1 Comment Fields A comment field begins with an exclamation point ( ! ) and ends with a carriage return. You supply text after the exclamation point to document your program. You can specify comment fields while creating VAX BASIC programs at DCL level as well as in the BASIC environment. In both cases, VAX BASIC does not execute text in a comment field. Example ! FOR loop to initialize list Q FOR I = 1 TO 10 Q{I) = 0 ! This is a comment NEXT I ! List now initialized VAX BASIC executes only the FOR ... NEXT loop. The comment fields, preceded by exclamation points, are not executed. Comment fields help make your program more readable and allow you to format your program into readily visible logical blocks. They can also serve as target lines for GOTO and GOSUB statements. Program Elements and Structure 1-55 Example ! Square root program ! INPUT 'Enter a number';A PRINT 'SQR of ';A;'is ';SQR(A) ! ! More square roots? ! INPUT 'Type "Y" to continue, press RETURN to quit' ;ANS$ GOTO 10 IF ANS$ = 11 Y11 END You can also use an exclamation point to terminate a comment field, but this practice is not recommended. You should make sure that there are no exclamation points in the comment field itself; otherwise, VAX BASIC treats the text remaining on the line as source code. NOTE Comment fields in DATA statements are invalid; the VAX BASIC compiler treats the comments as additional data. Empty statements consist of a line number and an exclamation point. Empty statements can make your program more legible by increasing the amount of "white space" and visually separating logical program segments. In the following example, lines 100 and 300 are empty statements: Example 100 ! FOR loop to initialize list Q ! 200 FOR I = 1 TO 10 Q(I) = 0 ! This is a comment NEXT I 300 ! List is now initialized In general, empty statements can be used to make a program more legible and organized. 1-56 Program Elements and Structure 1.7.2 REM Statements A REM statement begins with the REM keyword and ends when VAX BASIC encounters a new line number. The text you supply between the REM keyword and the next line number documents your program. Like comment fields, REM statements do not affect program execution. VAX BASIC ignores all characters between the keyword REM and the next line number. Therefore, the REM statement can be continued without the ampersand continuation character and should be the only statement on the line or the last of several statements in a multi-statement line: Example REM This is an example A=5 8=10 REM A equals 6 B equals 10 PRINT A, B The REM statement is nonexecutable. When you transfer control to a REM statement, VAX BASIC executes the next executable statement that lexically follows the referenced statement. NOTE Because VAX BASIC treats all text between the REM statement and the next line number as commentary, REM should be used very carefully in programs that follow the implied continuation rules. REM statements are disallowed in programs without line numbers. In the following example, the conditional GOTO statement in line 20 transfers program control to line 10. VAX BASIC ignores the REM comment on line 10 and continues program execution at line 20. Example 10 REM ** Square root program INPUT 'Enter a number';A PRINT 'SQR of ';A;'is ';SQR(A) INPUT 'Type "Y" to continue, press RETURN to quit';ANS$ GOTO 10 IF ANS$ = "Y" 40 END 20 Program Elements and Structure 1-5 7 Chapter 2 BASIC Environment Commands Environment commands are commands that you use in the BASIC environment. With environment commands, you can display, edit, and merge VAX BASIC programs, set compiler defaults, move VAX BASIC source programs to and from storage, and execute programs. This chapter lists alphabetically all of the compiler commands that can be used within the BASIC environment. For information on immediate mode and calculator mode statements, see the VAX BASIC User Manual. BASIC Environment Commands 2-1 ! your-comment ! your-comment You can enter comments while in the BASIC environment by typing an exclamation point ( ! ) and the comment. Format your-comment Syntax Rules 1. 2. The exclamation point must be the first character on the line. You cannot continue a comment over more than one line. Remarks None. Examples Example 1 Ready ! Comments here 2-2 BASIC Environment Commands ! your-comment Example 2 $ TYPE BUILD_SPECIAL.COM $ SET VERIFY $ BASIC !+ ! Set the compilation options by uncommenting ! the appropriate ones. !! SET LIST SET WORD SET DEBUG !+ ! Get the source module. !- OLD SPECIAL !+ ! Compile it. !- COMPILE !+ ! All done. !- EXIT BASIC Environment Commands 2-3 S system-command Ssystem-command You can execute a DCL command while in the BASIC environment by typing a dollar sign ( $) before the command. VAX BASIC passes the command to the operating system for execution. The context of the BASIC environment and the program currently in memory do not change. Format $ system-command Syntax Rules VAX BASIC passes system-command directly to the VAX/VMS operating system without checking for validity. Remarks 1. The terminal displays any error messages or output that the command generates. 2. Control returns to the BASIC environment after the command executes. The context (source file status, loaded modules, and so on) of the BASIC environment and the program currently in memory do not change unless the command causes the operating system to abort VAX BASIC or log you out. 3. The command you specify executes within the context of a subprocess. Consequently, commands such as the DCL command SET execute only within the subprocess and do not affect the process running VAX BASIC. 2-4 BASIC Environment Commands S system-command Example Ready $ SHOW PROTECTION SYSTEM=RWED, OWNER=RWED, GROUP=RWED, WORLD=RE Ready BASIC Environment Commands 2-5 APPEND APPEND The APPEND command merges an existing VAX BASIC source program with the program currently in memory. Format APPEND [file-spec] Syntax Rules File-spec is the name of the VAX BASIC program you want to merge with the program currently in memory. The default file type is BAS. Remarks 1. 2. You cannot specify the APPEND command on programs that do not contain line numbers. If you type APPEND without specifying a file name, VAX BASIC prompts with Append file name-- 3. 2-6 You should respond with a file name. If you respond with a carriage return and no file name, VAX BASIC searches for a file named NONAME.BAS. If the VAX BASIC compiler cannot find NONAME.BAS, VAX BASIC signals the error "Can't find file or account" (ERR=S). You can append the contents of file-spec to a source program that is either called into memory with the OLD command or created in the BASIC environment. If there is no program in memory, VAX BASIC appends the file to an empty program with the default file name NON AME. BASIC Environment Commands APPEND 4. If file-spec contains a VAX BASIC line with the same line number as a line of the program in memory, the line in the appended file replaces the line of the program in memory. Otherwise, VAX BASIC inserts appended lines into the program in memory in sequential, ascending line number order. 5. The APPEND command does not change the name of the program in memory. 6. If you have not saved the appended version of the program, VAX BASIC signals the warning "Unsaved change has been made, CTRL/Z or EXIT to exit" the first time you try to leave the BASIC environment. Example Ready New FIRST_TRY.BAS Ready 10 PRINT "First program" APPEND NEW_PROG.BAS Ready LIST 10 PRINT "First Program" 20 PRINT "This section has been appended" BASIC Environment Commands 2-7 ASSIGN ASSIGN The ASSIGN command equates a logical name to a complete file specification, a device, or another logical name within the context of the BASIC environment. Format ASSIGN equiv-name[:] log-name[:] Syntax Rules Equiv-name specifies the file specification, device, or logical name to be assigned a logical name. If you specify a physical device name, you must terminate it with a colon (: ). 2. Log-name is the 1- to 63-character logical name to be associated with equiv-name. You can specify a logical name for any portion of a file specification. If the logical name translates to a device name, and will be used in place of a device name in a file specification, you must terminate it with a colon (: ). 3. If log-name has more than 63 characters, VAX BASIC signals the error "Invalid logical name". 1. Remarks 1. 2. 2-8 When the logical name assignment supersedes another logical name previously assigned, VAX BASIC displays the message "Previous logical name assignment replaced". Logical names assigned with the ASSIGN command are placed in the process logical name table and remain there until you exit the BASIC environment. BASIC Environment Commands ASSIGN Example ASSIGN [HENRY.BAS] PRO: BASIC Environment Commands 2-9 COMPILE COMPILE The COMPILE command converts a VAX BASIC source program to an object module and writes the object file to disk. Format COMPILE [file-spec] [/qualifier]. .. Command Qualifiers /[NO]ANSLST ANDARD /[NO]AUDIT [ sep text-entry ] /[NO]BOUNDS_CHECK /BYTE /[NO]CROSS_REF [ sep [NO]KEYWORDS ] /[NO]DEBUG /DECIMAL_SIZE sep (d,s) /DOUBLE /[NO]FLAG [ sep (flag-clause, ... ) ] /GFLOAT /HFLOAT /[NO]LINES /[NO]LIST /LONG /[NO]MACHINE_CODE /[NO]OBJECT /[NO]OVERFLOW [ sep (data-type, ... ) ] /[NO]ROUND /[NO]SETUP /[NO]SHOW [ sep (show-item, ... ) ] /SINGLE /[NO]SYNT AX _CHECK /[NO]TRACEBACK /TYPE_DEFAULT sep default-clause /VARIANT sep int-const /[NO]W ARNINGS [ sep warn-clause ] /WORD 2-10 BASIC Environment Commands Defaults /NOANSl_ST ANDARD /NO AUDIT /BOUNDS_CHECK /LONG /NOCROSS_REF /NODE BUG /DECIMAL _SIZE=( 15 ,2) /SINGLE /NOFLAG /SINGLE /SINGLE /LINES /NOLIST /LONG /NOMA CHINE /OBJECT /OVERFLOW=(INTEGER,DECIMAL) /NOROUND /SETUP /SHOW /SINGLE /NOSYNT AX_CHECK /TRACEBACK /TYPE_DEFAULT=REAL /VARIANT=O /WARNINGS /LONG COMPILE Syntax Rules 1. 2. 3. 4. 5. File-spec specifies a name for the output file or files. If you do not provide a file-spec, the VAX BASIC compiler uses the name of the program currently in memory for the file name, a default file type of OBJ for the object file, and a default file type of LIS for the listing file, if a listing file is requested. File-spec can precede or follow any qualifier. /Qualifier specifies a qualifier keyword that sets a VAX BASIC default. You can abbreviate all positive qualifiers to the first three letters of the qualifier keyword. You can abbreviate a negative qualifier to NO and the first three letters of the qualifier keyword. In cases of ambiguous or erroneous qualifiers, VAX BASIC signals "Unknown qualifier", and the program does not compile. When qualifiers conflict, VAX BASIC compiles the program using the last specified conflicting qualifier. For example, the following command line causes VAX BASIC to compile the program currently in memory but does not cause VAX BASIC to create an OBJ file. COMPILE/OBJ/NOOBJ 6. There must be a program in memory, or the COMPILE command does not execute; VAX BASIC does not signal an error or warning. 1. If an object file for the program already exists in your directory, VAX BASIC creates a new version of the OBJ file. You should not specify both a file name and file type. For example, if you enter the following command line, VAX BASIC creates two versions of NEWOBJ.FIL: Remarks 2. COMPILE NEWOBJ.FIL/LIS/OBJ 3. The first version, NEWOBJ.FIL;l, is the listing file; the second version, NEWOBJ.FIL;2, is the object file. If you specify only a file name, VAX BASIC uses the OBJ and LIS file type defaults when creating these files. Use the COMPILE/NOOBJECT command to check your program for errors without producing an object file. BASIC Environment Commands 2-11 COMPILE 4. When you exit from the BASIC environment, all options set with qualifiers return to the system default values. Use the SHOW command to display your system defaults before setting any qualifiers. Command Qualifiers /[NO]ANSLSTANDARD The / ANSI_STANDARD qualifier causes VAX BASIC to compile programs according to the ANSI Minimal BASIC standard and to flag syntax that does not conform to the standard. The /NOANSI_STANDARD qualifier causes VAX BASIC not to compile the program according to the ANSI Minimal BASIC standard. The default is /NOANSI_STANDARD. See the VAX BASIC User Manual for more information on the ANSI Minimal BASIC Standard. /[NO]AUDIT [ { : } { s!r-lit } ] file-spec The /AUDIT qualifier causes VAX BASIC to include a history list entry in the COD data base when a COD definition is extracted. Str-lit is a quoted string. File-spec is a text file. The history entry includes = • The contents of str-lit, or up to the first 64 lines in the file specified by file-spec • • • • The name of the program module, process, user name, and user UIC that accessed the COD The time and date of the access A note that access was made by the VAX BASIC compiler A note that access was an extraction If you specify /NOAUDIT VAX BASIC does not include a history list entry. /NOAUDIT is the default. /[NO]BOUNDS_CHECK The /BOUNDS_CHECK qualifier causes VAX BASIC to perform range checks on array subscripts. With bounds checking enabled, VAX BASIC checks that all subscript references are within the array boundaries set when the array was declared. If the subscript bounds are not within the bounds initially declared for the array, VAX BASIC signals an error message. If you specify /NOBOUNDS_CHECK VAX BASIC does not check that all subscript references are within the array bounds set. /BOUNDS_ CHECK is the default. 2-12 BASIC Environment Commands COMPILE /BYTE The /BYTE qualifier causes VAX BASIC to allocate 8 bits of storage as the default for all integer data not explicitly typed in the program. Untyped integer values are treated as BYTE values and must be in the BYTE range or VAX BASIC signals the error "Integer error or overflow." Table 1-2 in this manual lists VAX BASIC data types and ranges. By default, the VAX BASIC compiler allocates 32 bits of storage. /[NO]CROSS_REFERENCE [ { ~ } [NO]KEYWORDS] If you use the /CROSS-REFERENCE qualifier with the /LIST qualifier when you compile your program, the VAX BASIC compiler includes crossreference information in the program listing file. If you specify /CROSS_ REFERENCE=KEYWORDS, VAX BASIC also cross-references VAX BASIC keywords used in the program. If you specify /NOCROSS-REFERENCE, VAX BASIC does not include a cross reference section in the compiler listing. The default is /NOCROSS-REFERENCE. /[NO]DEBUG The /DEBUG qualifier appends to the object file information on symbolic references and line numbers. This information is used by the VAX/VMS Debugger when you debug your program. When you specify the /DEBUG qualifier on the COMPILE command, you cause the debugger to be invoked automatically when the program is run at DCL level (unless you specify RUN/NODEBUG). If you specify COMPILE/NODEBUG, information on program symbols and line numbers is not included in the object file. The default is /NODEBUG. See the VAX BASIC User Manual for more information on using the VAX/VMS Debugger. /DECIMAL_S/ZE { ~ } (d,s} The /DECIMAL _SIZE qualifier allows you to specify the default size and precision for all DECIMAL data not explicitly assigned size and precision in the program. You specify the total number of digits (d) and the number of digits to the right of the decimal point (s). VAX BASIC signals the error "Decimal error or overflow" (ERR=181) when DECIMAL values are outside the range specified with this qualifier. See Table 1-2 in this manual for more information on the storage and range of packed decimal data. The default is /DECIMAL_SIZE=(lS,2). BASIC Environment Commands 2-13 COMPILE /DOUBLE The /DOUBLE qualifier causes VAX BASIC to allocate 64 bits of storage in D_floating format as the default size for all floating-point data not explicitly typed in the program. Untyped floating-point values are treated as DOUBLE values and must be in the DOUBLE range or VAX BASIC signals the error "Floating-point error or overflow." Table 1-2 in this manual lists VAX BASIC data types and ranges. The default is /SINGLE. 1rNo, 1FLAG [ IL' J { : TIBILITY } ) ] = } { { [NO]BP2COMPA [NOJDECLINING , ... The /FLAG qualifier causes VAX BASIC to provide compile-time information about program elements that are not compatible with BASIC-PLUS-2 or that DIGITAL designates as not recommended for new program development. For more information on source code that is incompatible with with BASIC-PLUS-2, see Appendix A in this manual. If you specify the DECLINING clause, VAX BASIC will flag the following source code as declining: • • • • • CVT$$ (use EDIT$) CVT$%, CVT$F, CVT%$, CVTF$, AND SWAP% (use multiple MAP statements) DEF• functions (use DEF functions) FIELD statements (use MAP DYNAMIC and REMAP) GOTO line-num % (do not use the integer suffix with a line number) The default is /NOFLAG. /GFLOAT The /GFLOAT qualifier causes VAX BASIC to allocate 64 bits of storage in G_floating format as the default size for all floating-point data not explicitly typed in the program. Untyped floating-point values are treated as G_floating values and must be in the G_floating range or VAX BASIC signals "Floating-point error or overflow." Table 1-2 in this manual lists VAX BASIC data types and ranges. The default is /SINGLE. /HFLOAT The /HFLOAT qualifier causes VAX BASIC to allocate 128 bits of storage in H_floating format as the default size for all floating-point data not explicitly typed in the program. Untyped floating-point values are treated as H_floating values and must be in the H_floating range or VAX BASIC signals "Floating-point error or overflow." Table 1-2 in this manual lists VAX BASIC data types and ranges. The default is /SINGLE. 2-14 BASIC Environment Commands COMPILE /[NO]LINES The /LINES qualifier includes line number information in object modules. If you specify /NOLINES VAX BASIC does not include line number information in object modules. If you specify /NOLINES in a program containing a RESUME statement or the run-time ERL function, VAX BASIC issues a warning that the /NOLINES qualifier has been overridden. The default is /LINES. /[NO]LIST The /LIST qualifier causes VAX BASIC to produce a compiler listing file. This compiler listing generated by the /LIST qualifier contains a memory allocation map. By default, the name of the listing file is the same as the name of the first program module specified, and has a default file type of LIS. If you specify /NOLIST VAX BASIC does not generate a compiler listing. /NOLIST is the default. /LONG The /LONG qualifier causes VAX BASIC to allocate 32 bits of storage as the default size for all integer data not explicitly typed in the program. Untyped integer values are treated as LONG values and must be in the LONG range or VAX BASIC signals the error "Integer error or overflow." Table 1-2 in this manual lists VAX BASIC data types and ranges. /LONG is the default. /[NO]MACHINE_CODE When you specify the /MACHINE_CODE qualifier with the /LIST qualifier in the COMPILE command, VAX BASIC includes the machine code generated by the compilation in the program listing file. If you specify /NOMACHINE_CODE, VAX BASIC does not include a machine code section in the listing file. /NOMACHINE_CODE is the default. /[NOJOBJECT The /OBJECT qualifier generates an object module with the same file name as the program and a default file type of OBJ. The /NOOBJECT qualifier allows you to check your program for errors without creating an object file. /OBJECT is the default. = ( INTEGER } , ... ) ] /[NOJOVERFLOW [ { : } { DECIMAL The /OVERFLOW qualifier causes VAX BASIC to report arithmetic overflow for operations on integer or packed decimal data, or both. If you specify /NOOVERFLOW, VAX BASIC does not report arithmetic overflows. The default is /OVERFLOW=(INTEGER,DECIMAL). BASIC Environment Commands 2-15 COMPILE /[NO]ROUND The /ROUND qualifier causes VAX BASIC to round rather than truncate DECIMAL values. If you specify /NOROUND, VAX BASIC truncates DECIMAL values. The default is /NOROUND. /[NO]SETUP The /SETUP qualifier causes VAX BASIC to make calls to the Run-Time Library to set up the stack for VAX BASIC variables, set up dynamic string and array descriptors, initialize variables, and enable VAX BASIC error handling. If you specify the /NOSETUP qualifier, VAX BASIC will attempt to optimize your program by omitting these calls. If your program contains any of the following elements, VAX BASIC provides an informational diagnostic and does not optimize your program: • • • • • • • • • • • • • • • • CHANGE statements DEF or DEF• statements Dynamic string variables Executable DIM statements EXTERNAL string functions MAT statements MOVE statements for an entire array ON ERROR statements READ statements REMAP statements RESUME statements WHEN blocks All graphics statements String concatenation Built-in string functions Virtual array declarations Note that program modules compiled with the /NOSETUP qualifier cannot perform 1/0 and have no error-handling capabilities. If an error occurs in such a module, the error is resignaled to the calling program. The default is /SETUP. 2-16 BASIC Environment Commands l COMPILE [NO]CDD_DEFINITIONS [NO]ENVIRONMENT /[NO]SHOW [ { ~ } ( [NO]INCLUDE , ... ) ] [NO]MAP [NO]OVERRIDE The /SHOW qualifier (when used with the /LIST qualifier) tells VAX BASIC what to include in the compiler listing file. You can specify the following /SHOW qualifier items: I • • • • • CDD_DEFINITIONS causes VAX BASIC to include a section of translated COD definitions ENVIRONMENT causes VAX BASIC to include a list compilation qualifiers in effect INCLUDE causes VAX BASIC to include a section on the contents of any %INCLUDE files MAP causes VAX BASIC to include a storage allocation map section OVERRIDE cancels the effect of all %NOLIST directives in the source program For example, if you specify the following command, VAX BASIC includes a storage allocation map section in the compiler listing: COMPILE/LIST/SHOW=MAP If you specify a /SHOW qualifier but do not specify any /SHOW items, VAX BASIC includes all the aforementioned sections in the listing. If you specify /NOSHOW, VAX BASIC does not add any additional sections to the compiler listing. The default is /SHOW. /SINGLE The /SINGLE qualifier causes VAX BASIC to allocate 32 bits of storage in F_floating format as the default size for all floating-point data not explicitly typed in the program. Untyped floating-point values are treated as SINGLE values and must be in the SINGLE range or VAX BASIC signals the error "Floating-point error or overflow." Table 1-2 in this manual lists VAX BASIC data types and ranges. The default is /SINGLE. /[NO]SYNTAJLCHECK The /SYNTAX_CHECK qualifier causes VAX BASIC to perform syntax checking after each program line is typed. If you specify /NOSYNTAX_ CHECK, VAX BASIC does not perform syntax checking after each program line is typed. The default is /NOSYNTAX_CHECK. BASIC Environment Commands 2-17 COMPILE /[NO]TRACEBACK The /TRACEBACK qualifier causes VAX BASIC to include traceback information in the object file that allows reporting of the sequence of calls that transferred control to the statement where an error occurred. The /NOTRACEBACK qualifier tells VAX BASIC not to include traceback information in the object file. The default is /TRACEBACK. /TYPE DEFAULT { : } { :::GER } = DECIMAL EXPLICIT The /TYPE_DEFAULT qualifier sets the default data type (REAL, INTEGER, or DECIMAL) for all data not explicitly typed in your program or specifies that all data must be explicitly typed (EXPLICIT). • • • • REAL specifies that all data not explicitly typed is floating-point data of the default size (SINGLE, DOUBLE, GFLOAT, or HFLOAT). INTEGER specifies that all data not explicitly typed is integer data of the default size (BYTE, WORD, or LONG). DECIMAL specifies that all data not explicitly typed is packed decimal data of the default size. EXPLICIT specifies that all data in a program must be explicitly typed. Implicitly declared variables cause VAX BASIC to signal an error. The default is TYPE_DEFAULT=REAL. /VAR/ANT { ~ } int-canst The /VARIANT qualifier establishes int-const as a value to be used in compiler directives. The variant value can be referenced in a lexical expression with the lexical function, %VARIANT. Int-const always has a data type of LONG. The default is /VARIANT=O. : } { [NO]WARNINGS } /[NO]WARNINGS [ { = [NO]INFORMA TIONALS ] The /WARNINGS qualifier causes VAX BASIC to display warning or informational messages, or both. If you specify /WARNINGS but do not specify a warning clause, VAX BASIC displays both warnings and informational messages. If you specify /NOWARNINGS, VAX BASIC does not display warning and informational messages. The default is /WARNINGS. 2-18 BASIC Environment Commands COMPILE /WORD The /WORD qualifier causes VAX BASIC to allocate 16 bits of storage as the default for all integer data not explicitly typed in the program. Untyped integer values are treated as WORD values and must be in the range -32768 to 32767 or VAX BASIC signals the error "Integer error or overflow." Table 1-2 in this manual lists VAX BASIC data types and ranges. The default is /LONG. In the following example, VAX BASIC compiles the program LETSGO and creates a new version of the object file as well as a listing file. In addition, VAX BASIC allocates 64 bits of storage in DJLOAT format as the default for all floating point data not explicitly typed in the program. Example COMPILE LETSGO/DOUBLE/LIST BASIC Environment Commands 2-19 CONTINUE CONTINUE The CONTINUE command continues program execution after VAX BASIC executes a STOP statement or encounters a CTRL/C. Format CONTINUE Syntax Rules None. Remarks 1. 2. After a STOP statement or a CTRL/C, you can enter immediate mode commands and resume program execution with the CONTINUE command. After a STOP statement or a CTRL/C, you cannot resume program execution if you have made source code changes or additions. Example Y.BAS-I-STO, Stop -BAS-I-FROLINMOD, from line 25 in module ABC Ready CONTINUE 2-20 BASIC Environment Commands DELETE DELETE The DELETE command removes a specified line or range of lines from the program currently in memory. Format DELETE . [ -,. line-num ] ... lme-num ,1me-num... Syntax Rules None. Remarks 1. You cannot specify the DELETE command on programs that do not contain line numbers. 2. The separator characters (comma or hyphen) allow you to delete individual lines or a block of lines. • If you separate line numbers with commas, VAX BASIC deletes each specified line number. • If you separate line numbers with a hyphen, VAX BASIC deletes the inclusive range of lines. The lower line number must be specified first. If it is not specified first, the DELETE command has no effect. 3. You can combine individual line numbers and line ranges in a single DELETE command. Note, however, that a line number range must be followed by a comma and not another hyphen, or VAX BASIC signals an error. 4. VAX BASIC signals an error if there are no lines in the specified range or if you specify an illegal line number. BASIC Environment Commands 2-21 DELETE Examples Example 1 DELETE 50 Example 2 DELETE 70-80, 110, 124 Example 3 DELETE 50,60,90-110 2-22 BASIC Environment Commands EDIT EDIT The EDIT command allows you to edit individual program lines in the BASIC environment while invoking an editor. EDIT with no arguments invokes a text editor and reads the current program into the editor's buffer. Format EDIT [ line-num search-clause [replace-clause]] search-clause: delim unq-str 1 delim replace-clause: [ unq-str2] [ delim [ int-const1] [ ,int-const2]] Syntax Rules 1. Line-num specifies the line to be edited. 2. Search-clause specifies the text you want to remove or replace. Unqstr1 is the search string you want to remove or replace. 3. Replace-clause specifies the replacement text and the occurrence of the search string you want to replace. • Unq-str2 is the replacement string. • lnt-constl specifies the occurrence of unq-str1 you want to replace. If you do not specify an occurrence, VAX BASIC replaces the first occurrence of unq-str1. • lnt-const2 specifies the line number of a block of program code where you want VAX BASIC to begin the search. 4. Delim can be any printing character not used in unq-str1 or unq-str2. The examples for this command use the slash (/)as a delimiter. BASIC Environment Commands 2-23 EDIT Remarks 1. 2. 3. 4. 5. 6. 7. The delim characters in search-clause must match, or VAX BASIC signals an error. If the delimiter you use to signal the end of replace-clause does not match the delimiter used in search-clause, VAX BASIC does not signal an error and treats the end delimiter as part of unq-str2. VAX BASIC replaces or removes text in a program line as follows: • If unq-str1 is found, VAX BASIC replaces it with unq-str2. • If unq-str1 is not found, VAX BASIC signals an error. • If unq-str1 is null, VAX BASIC signals "No change made". • If unq-str2 is null, VAX BASIC deletes unq-str1. • VAX BASIC matches and replaces strings exactly as you type them. If unq-str1 is uppercase, VAX BASIC searches for an uppercase string. If it is lowercase, VAX BASIC searches for a lowercase string. VAX BASIC displays the edited line with changes after the EDIT command successfully executes. If you specify a line number with no text parameters, VAX BASIC displays the line. The EDIT command followed by a carriage return causes VAX BASIC to save your current source file in BASEDITMP.BAS and automatically invoke VAX EDT as the default text editor. At DCL level, you can override the default text editor. To do this, assign the logical name BASIC$EDIT to another editor such as VAXTPU or Language-Sensitive Editor before entering the BASIC environment. For instance, in the following example, BASIC$EDIT is defined to be TPU$EDIT. The EDIT command followed by a carriage return will then invoke VAXTPU as the default text editor. $ DEFINE BASIC$EDIT TPU$EDIT 8. If you define BASIC$EDIT to be an editor other than VAX EDT, VAXTPU, or Language-Sensitive Editor, VAX BASIC spawns a subprocess to invoke the editor assigned to BASIC$EDIT. 2-24 BASIC Environment Commands EDIT 9. When you finish editing your program and exit from the editor, the edited program is the program currently in memory, and the context of the BASIC environment is unchanged. Note that VAX BASIC deletes all versions of BASEDITMP.BAS when you return to VAX BASIC from the editor. Example Ready LIST 100 100 NEW_STRING$ = LEFT$(STRING$,12) EDIT 100 /LEFT$/RIGHT$/3,2 LIST 100 100 NEW_STRING$ = RIGHT$(STRING$,12) BASIC Environment Commands 2-25 EXIT EXIT The EXIT command or CTRL/Z clears the memory and returns control to the operating system. Format EXIT Syntax Rules None. Remarks If you type EXIT after creating a new program or editing an old program without first typing SAVE or REPLACE, VAX BASIC signals "Unsaved change has been made, CTRL/Z or EXIT to exit". The message warns you that the new or revised program will be lost if you do not SAVE or REPLACE it. If you type EXIT again, VAX BASIC exits from the BASIC environment whether you have saved your changes or not. Example EXIT Y.BASIC-W-CHANGES, unsaved change has been made, CTRL/Z or EXIT to exit Ready SAVE EXIT Ready 2-26 BASIC Environment Commands HELP HELP The HELP command displays online documentation for VAX BASIC commands, keywords, statements, functions, and conventions. Format HELP [ unq-str] ... Syntax Rules 1. 2. 3. 4. Unq-str is a VAX BASIC topic, keyword, command, statement, function, or convention. The first unq-str must be one of the topics described in the HELP file. If it is not, VAX BASIC displays a list of topics for you to choose from. You can specify a subtopic after the topic. Separate one unq-str from another with a space. You can use the asterisk ( •) wildcard character in unq-str. VAX BASIC then matches any portion of the specified topic. Remarks 1. If you type HELP with no parameters, VAX BASIC displays a list of statements, functions, compiler directives, compiler commands and language topics. 2. If the unq-str you specify is not a unique topic or subtopic, VAX BASIC displays information on all topics or subtopics beginning with unq-str. 3. An asterisk ( •) indicates that you want to display information that matches any portion of the topic you specify. For example, if you type HELP GO•, VAX BASIC displays information on the GOSUB statement and the GOTO statement. BASIC Environment Commands 2-27 HELP 4. When information on a particular topic or subtopic is not available, VAX BASIC signals the message "Sorry, no documentation on unq-str" and provides a list of alternative HELP topics to choose from. Example Ready Help GO* GO SUB The GOSUB statement transfers control to a specified line number or label and stores the location of the GOSUB statement for eventual return from the subroutine. Example 200 GOSUB 1100 Additional information available: Syntax GOTO The GOTO statement transfers control to a specified line number or label. Example 20 GOTO 200 Additional information available: Syntax Topic? 2-28 BASIC Environment Commands IDENTIFY IDENTIFY The IDENTIFY command displays an identification header on the controlling terminal. The header contains the name and version number of VAX BASIC. Format IDENTIFY Syntax Rules None. Remarks The message displayed by the IDENTIFY command includes the name of the VAX BASIC compiler and the version number. Example IDENTIFY VAX BASIC V3.0 BASIC Environment Commands 2-29 INQUIRE INQUIRE The INQUIRE command is a synonym for the HELP command. See the HELP command for more information. 2-30 BASIC Environment Commands LIST and LISTNH LIST and LISTNH The LIST command displays the program lines of the program currently in memory. Line numbers are sequenced in ascending order. The LISTNH command displays program lines without the program header. Format LIST[NH] . [ - line-num ] ] ... [ lme-num ,l'me-num... Syntax Rules A line-num followed by a hyphen (-) and a carriage return displays the specified line and all remaining lines in the program. Remarks 1. The LIST command displays program lines, along with a header containing the program name, the current time, and the date. To suppress the program header, type LISTNH. 2. LIST without parameters displays the entire program. 3. The separator characters (comma or hyphen) allow you to display individual lines or a block of lines. • If you separate line numbers with commas, VAX BASIC displays each specified line number. • If you separate line numbers with hyphens, VAX BASIC displays the inclusive range of lines. The lower line number must come first. If it does not, LIST has no effect. BASIC Environment Commands 2-31 LIST and LISTNH 4. 5. 6. You can combine individual line numbers and line ranges in a single LIST command. Note, however, that a line number range must be followed by a comma and not another hyphen, or VAX BASIC signals an error. A hyphen between the list command and line-num causes VAX BASIC to signal an error. VAX BASIC displays the source program lines in the order you specify in the command line. VAX BASIC displays line 100 before line 10 if you type LIST 100,10. Example Example LIST 200-300 Output 200 Y.IF %VARIANT = 2 Y.THEN %ABORT 300 Y.END Y.IF 2-32 BASIC Environment Commands LOAD LOAD The LOAD command makes a previously created object module or modules available for execution with the RUN command. Format LOAD file-spec [ + file-spec ] ... Syntax Rules File-spec must be a VAX BASIC object module or VAX BASIC signals an error. OBJ is the default file type. If you specify only the file name, VAX BASIC searches for an OBJ file in the current default directory. Remarks 1. Each device and directory specification applies to all following file specifications until you specify a new directory or device. 2. The LOAD command accepts multiple device, directory, and file specifications. 3. VAX BASIC does not process the loaded object files until you issue the RUN command. Consequently, errors in the loaded modules may not be detected until you execute them. 4. VAX BASIC signals an error in the following cases: • If the file is not found • If the file specification is not valid • If the file is not a VAX BASIC object module • If run-time memory is exceeded Errors do not change the program currently in memory. BASIC Environment Commands 2-33 LOAD 5. 6. The LOAD command clears all previously loaded object modules from memory. Typing the LOAD command does not change the program currently in memory. Example LOAD PROGA + PROGB + PROGC 2-34 BASIC Environment Commands LOCK LOCK The LOCK command changes default values for COMPILE command qualifiers. It is a synonym for the SET command. See the SET command for more information. BASIC Environment Commands 2-35 NEW NEW The NEW command clears VAX BASIC memory and allows you to assign a name to a new program. Format NEW [ prog-name ] Syntax Rules Prag-name is the name of the program you want to create. VAX BASIC allows program names to contain a maximum of 39 characters. You can use any combination of alphanumeric characters in your program name, as well as the dollar sign ( $ ), hyphen ( - ), and underscore (-) characters. Remarks 1. VAX BASIC signals an error if prog-name exceeds 39 characters. 2. VAX BASIC signals "error in program name" if you specify a file type. 3. If you do not specify a prog-name, VAX BASIC prompts with: New file name-- The default name is NONAME. If you do not provide a prog-name in response to the prompt, VAX BASIC assigns the file name NONAME to your program. 5. When you type the NEW command, the program currently in memory is cleared. Program modules loaded with the LOAD command remain unchanged. 4. 2-36 BASIC Environment Commands NEW Example NEW PROG1 BASIC Environment Commands 2-37 OLD OLD The OLD command brings a previously created VAX BASIC program into memory. Format OLD [file-spec] Syntax Rules 1. If you do not name a file-spec, VAX BASIC prompts for one. If you do 2. not enter a file-spec in response to the prompt, VAX BASIC searches for a file named NONAME.BAS in the current default directory. The default file type is BAS. 1. If the VAX BASIC compiler cannot find the file you specify, VAX 2. BASIC signals the error "File not found". When the specified file is found, it is placed in memory and any program currently in memory is erased. If VAX BASIC does not find the specified file, the program currently in memory does not change. Remarks Example OLD CHECK Ready 2-38 BASIC Environment Commands RENAME RENAME The REN AME command allows you to assign a new name to the program currently in memory. VAX BASIC does not write the renamed program to a file until you save the program with the REPLACE or SAVE command. Format RENAME [ prog-name] Syntax Rules 1. Prog-name specifies the new program name. VAX BASIC allows program names to contain a maximum of 39 characters. You can use any combination of alphanumeric characters in your program name, as well as the dollar sign ( $ ), hyphen ( - ), and underscore ( _) characters. 2. If you specify a file type, VAX BASIC signals the error "Error in program name." Remarks The program you want to rename must be in memory. If you type RENAME with no program in memory, VAX BASIC renames the default program, NONAME, to the specified prog-name. 2. If you do not specify a prog-name, VAX BASIC renames the program currently in memory NONAME. 3. You must type SAVE or REPLACE to write the renamed program to a file. If you do not type SAVE or REPLACE, VAX BASIC does not save the renamed program. 4. The RENAME command does not affect the original saved version of the program. 1. BASIC Environment Commands 2-39 Example OLD TEST Ready RENAME NEWTEST Ready LIST NEWTEST 29-JUL-1985 13:50 PRINT "This program is a simple test" Ready SAVE Y.BASIC-1-FILEWRITE, NEWTEST written to file: USER$$DISK: [SMITH.COMS]NEWTEST.BAS;5 Ready In this example, the OLD command calls the program named TEST into memory. The RENAME command renames TEST to NEWTEST and the SAVE command writes NEWTEST.BAS to a file. The original file, TEST.BAS is not changed and is not deleted from your account. 2-40 BASIC Environment Commands REPLACE REPLACE The REPLACE command writes the current program back to the file specified by the last OLD command. Format REPLACE Syntax Rules None. Remarks 1. If you do not have write access to the directory containing the original file, VAX BASIC signals an error message. 2. VAX BASIC creates and saves a new version of the file, incrementing the version number by 1 unless you supplied a specific version number with the OLD command. 3. A REPLACE command following a NEW command or a SCRATCH command causes VAX BASIC to write the program in memory to the current default directory. 4. A REPLACE command following a REN AME command writes the file to the directory specified in the OLD command with the file name specified in the RENAME command. BASIC Environment Commands 2-41 REPLACE Example $DIR NODE::USER$$DISK: [BASICUSER]TEST.BAS Directory USER$$DISK:[BASICUSER] TEST.BAS;! Total of 1 file. $ BASIC VAX BASIC V3.0 Ready OLD NODE::USER$$DISK:[BASICUSER]TEST.BAS; Ready REPLACE Y.BASIC-I-FILEWRITE, TEST written to file: USER$$DISK:[BASICUSER]TEST.BAS;2 Ready EXIT $DIR NODE: :USER$$DISK:[BASICUSER]TEST.BAS Directory USER$$DISK:[BASICUSER] TEST.BAS;! TEST.BAS;2 Total of 2 files . • 2-42 BASIC Environment Commands RESEQUENCE RESEQUENCE In a program with line numbers, the RESEQUENCE command allows you to resequence the line numbers of the program currently in memory. VAX BASIC also changes all references to the old line numbers so they reference the new line numbers. Format RESEQUENCE [ line-num 1 [ - line-num2] [ line-num3]] [STEP int-canst] Syntax Rules 1. 2. 3. Line-num1 is the line number in the program currently in memory where resequencing begins. The default for line-num1 is the first line of the program module. Line-num2 is the optional end of the range of line numbers to be resequenced. If you specify a range, VAX BASIC begins resequencing with line-num1 and resequences through line-num2. If you do not specify line-num2, VAX BASIC resequences the specified line. If you do not specify either line-num1 or line-num2, VAX BASIC resequences the entire program. Line-num3 specifies the new first line number; the default number for the new first line is 100. You can specify line-num3 only when resequencing a range of lines. If line-num3 causes existing lines to be deleted or surrounded, VAX BASIC signals an error. 4. Int-canst specifies the numbering increment for the resequencing operation. The default for int-canst is 10. BASIC Environment Commands 2-43 RESEQUENCE Remarks 1. You cannot specify the RESEQUENCE command on programs that do not contain line numbers. 2. VAX BASIC signals an error when you try to resequence a program that contains a %IF directive. VAX BASIC also signals an error when you try to resequence a program that has a %INCLUDE directive if the file to be included contains a reference to a line number. 3. Before the RESEQUENCE command executes, VAX BASIC verifies the syntax of the program. If the program is not syntactically valid, the RESEQUENCE command does not execute. 4. VAX BASIC sorts the renumbered program in ascending order when the RESEQUENCE command executes. 5. If the renumbering creates a line number greater than the maximum line number of 32767, VAX BASIC signals an error. 6. VAX BASIC signals an error if resequencing causes a change in the order in which program statements are to execute and does not resequence the program. 7. VAX BASIC signals the error "Undefined line number" in the case of undefined line numbers and does not resequence the program. 8. VAX BASIC corrects all line numbers for statements that transfer control. 9. VAX BASIC does not modify the program currently in memory when the RESEQUENCE command generates an error. 10. In general, the RESEQUENCE command is not recommended for programs containing error handlers that test the value of ERL. However, the RESEQUENCE command correctly modifies the program if the tests that reference ERL are of this form: ERL relational-operator int-lit The RESEQUENCE command does not correctly renumber programs if the test compares ERL with an expression or a variable, or if ERL follows the relational operator. The following line number references, for example, would not be correctly renumbered: IF ERL = 1000 + A% THEN IF 1000 >ERL THEN ... 2-44 BASIC Environment Commands RESEQUENCE Example 10 INPUT "Enter a numeric value 11 ;A% 20 IF A% = 20 30 THEN PRINT "Bye" 40 GOTO done 50 ELSE GOTO 10 60 END IF Output 15 INPUT "Enter a numeric value 11 ;A% 25 IF A% = 20 35 THEN PRINT "Bye" 45 GOTO done 55 ELSE GOTO 10 65 END IF In this example, the command RESEQUENCE 10-60 STEP 5 causes VAX BASIC to resequence lines 10 through 60, incrementing each new line number by 5. BASIC Environment Commands 2-45 RUN RUN The RUN command allows you to execute a program from the BASIC environment without first invoking the VAX/VMS Linker to construct an executable image. In addition, the RUN command allows you to access user specified and system shareable image libraries for undefined symbols. Format RUN[NH] [file-spec] Syntax Rules None. Remarks 1. 2-46 Executing a Program • If you specify only the file name, VAX BASIC searches for a file with a BAS file type in the current default directory. • If you do not supply a file-spec, VAX BASIC executes the program currently in memory. • VAX BASIC signals the warning message "No main program" if you do not supply a file-spec and do not have a program currently in memory. • The RUNNH command is identical to RUN, except that it does not display the program header, current date, and time. • When you specify a file-spec with the RUN command, VAX BASIC brings the program into memory and then executes it. You do not have to bring a program into memory with the OLD command in order to run it. The RUN command executes just as if the program had been brought into memory with the OLD command. BASIC Environment Commands RUN • • • • • • If your program calls a subprogram, the subprogram must be compiled and placed in memory with the LOAD command. If your program tries to call a subprogram that has not been compiled and loaded, VAX BASIC signals an error. The RUN command does not create an object module file or a list file. When VAX BASIC encounters a STOP statement in the program, the program stops executing and control passes to the BASIC environment immediate mode. Any VAX BASIC statement that does not require the creation of new storage can be entered in immediate mode to debug the program. You cannot create new variables in immediate mode. Type the CONTINUE command to resume program execution. The RUN command uses whatever qualifiers have been set, with the exception of those that have no effect on a program running in the BASIC environment. These qualifiers are as follows: NOCROSS NODEBUG NO LIST NO MACHINE NOOBJECT These qualifiers are always in effect when you run a program in the environment. 2. Accessing Shareable Images • To automatically access shareable image libraries, you must make an assignment to the logical name BASIC$LIBn. For example: $ ASSIGN DBAO: [BABCOCK]TESTLIB.OLB BASIC$LIBO • • • • After you enter a command line, VAX BASIC will automatically access your library to resolve undefined program symbols. If you have more than one library for the VAX/VMS Linker to search, you must assign the first one as BASIC$LIBO, the second one as BASIC$LIB1, the third as BASIC$LIB2, and so on. If you do not number libraries consecutively, the VAX/VMS Linker does not search past the first missing logical name. As long as routines are contained in shareable images in libraries, they are not required to.be written in VAX BASIC to be accessed with the RUN command. BASIC Environment Commands 2-47 RUN • • VAX BASIC provides no default file specification for user-supplied shareable image libraries; the current default device and the directory are used. After all possible shareable image libraries have been accessed, VAX BASIC will subsequently search the default library SYS$LIBRARY:.OLB with the logical name IMAGELIB to resolve any additional undefined program symbols. Example RUN PROG1 PROG1 29-JUL-1986 13:52 1 3 6 10 Ready RUNNH PROG1 1 3 6 10 Ready 2-48 BASIC Environment Commands SAVE SAVE The SAVE command writes the VAX BASIC source program currently in memory to a file on the default or specified device. Format SA VE [ file-spec ] Syntax Rules None. Remarks 1. If you do not supply a file-spec, VAX BASIC saves the file with the name of the program currently in memory and the BAS default file type. 2. If you specify only the file name, VAX BASIC saves the program with the default file type in the current default directory. 3. When you type the SAVE command, VAX BASIC writes a new version of the program. 4. VAX BASIC stores the sorted program in ascending line number order. 5. You can store the program on a specified device. For example: SAVE DUA1:NEWTEST.PRO VAX BASIC saves the file NEWTEST.PRO on disk DUAl:. BASIC Environment Commands 2-49 SAVE Example SAVE PROG_SAMP.BAS Y.BASIC-I-FILEWRITE, PROG_SAMP written to file: USER$$DISK[BASICUSER]PROG_SAMP.BAS;2 2-50 BASIC Environment Commands SCALE SCALE The SCALE command allows you to control accumulated round-off errors by multiplying numeric values by 10 raised to the scale factor before storing them. Format SCALE int-canst Syntax Rules Int-const specifies the power of 10 you want to use as the scaling factor. Int-const must be an integer from 0 through 6 or VAX BASIC signals the error "Illegal argument for command". Remarks 1. 2. 3. SCALE with no argument causes VAX BASIC to signal the error "Illegal argument for command". SCALE affects only values of the data type DOUBLE. VAX BASIC multiplies values using the scale factor you specify. The value 2.488888, for example, is rounded as follows: Scale Value Produced for 2.488888 0 2.48889 1 2.4 2 2.48 3 2.488 4 2.4888 BASIC Environment Commands 2-51 SCALE Scale Value Produced for 2.488888 5 2.48888 6 2.48889 Example SCALE 2 2-52 BASIC Environment Commands SCRATCH SCRATCH The SCRATCH command clears any program currently in memory, removes any object files loaded with the LOAD command, and resets the program name to NONAME. Format SCRATCH Syntax Rules None. Remarks None. Example SCRATCH BASIC Environment Commands 2-53 SEQUENCE SEQUENCE The SEQUENCE command causes VAX BASIC to automatically generate line numbers for your program text. VAX BASIC supplies line numbers for your text until you end the procedure or reach the maximum line number of 32767. Format [ line-num] [,int-canst] SEQUENCE Syntax Rules Line-num specifies the line number where sequencing begins. 2. Int-const specifies the line number increment for your program. If you do not specify an increment, VAX BASIC defaults to the int-const 1. specified in the last SEQUENCE command; if there is no previous SEQUENCE command, the default is 10. Remarks 1. 2. 3. 4. You cannot specify the SEQUENCE command on programs that do not contain line numbers. If you do not specify a line-num, the VAX BASIC default is the last line inserted by a SEQUENCE command; if there is no previous SEQUENCE command, the default is line number 100. If you specify a line-num that already contains a statement, or if the sequencing operation generates a line number that already contains a statement, VAX BASIC signals "Attempt to sequence over existing statement", and returns to normal input mode. Type your program text in response to the line number prompt; the carriage return ends each line and causes VAX BASIC to generate a new line number. 2-54 BASIC Environment Commands SEQUENCE 5. 6. 7. If you press CTRL/Z in response to the line number prompt, VAX BASIC terminates the sequencing operation and prompts for another command. When the maximum line number of 32767 is reached, VAX BASIC terminates the sequencing process and returns to normal input mode. VAX BASIC does not check syntax during the sequencing process. Example SEQUENCE 100,10 100 INPUT "Enter a numeric value";A'/, 110 IF A'/. = 20 Here, if you enter the command SEQUENCE 100,10, the SEQUENCE command causes VAX BASIC to automatically generate line numbers into the program text, beginning with the line number 100 and incrementing each line by 10. BASIC Environment Commands 2-55 SET SET The SET command allows you to specify VAX BASIC defaults for all VAX BASIC qualifiers. Qualifiers control the compilation process and the runtime environment. The defaults you set remain in effect for all subsequent operations until they are reset or until you exit from the compiler. Format SET [/qualifier]. .. Syntax Rules 1. 2. /Qualifier specifies a qualifier keyword that sets a VAX BASIC defaul.t. See the COMPILE command for a list of all VAX BASIC qualifiers and their defaults. VAX BASIC signals the error "Unknown qualifier" if you do not separate multiple qualifiers with commas (,) or slashes ( / ), or if you mix commas and slashes on the same command line. The same error is signaled if you separate qualifiers with a slash but do not prefix the first qualifier with a slash. Remarks If you do not specify any qualifiers, VAX BASIC resets all defaults to the defaults specified with the DCL command BASIC. 2-56 BASIC Environment Commands SET Examples Example 1 SET /DOUBLE/BYTE/LIST Example 2 SET DOUBLE,BYTE,LIST In both examples, the VAX BASIC compiler is set to allocate 64 bits of storage for all floating-point data, and to allocate 8 bits of storage for all integer data. Also, a source listing file is created. BASIC Environment Commands 2-57 SHOW SHOW The SHOW command displays the current defaults for the VAX BASIC compiler on your terminal. Format SHOW Syntax Rules None. Remarks None. Example SHOW VAX BASIC 3.0 Current Environment Status 30-0CT-1986 10:05:66.67 DEFAULT DATA TYPE INFORMATION: LISTING FILE INFORMATION INCLUDES: Data type : REAL NO List NO Cross reference Real size : SINGLE Integer size : LONG CDD Definitions Decimal size : (16,2) Environment Scale factor : 0 NO Override of Y.NOLIST NO Round decimal numbers NO Machine code Map COMPILATION QUALIFIERS IN EFFECT: Object file RS: Overflow check integers Overflow check decimal numbers Bounds checking 2-58 BASIC Environment Commands INCLUDE files FLAGGE NO Declining features NO BASIC PLUS 2 subset SHOW NO Syntax checking Lines Variant : 0 Warnings Informationals Setup Object Libraries Ready DEBUG INFORMATION: Traceback records NO Debug symbol records NONE BASIC Environment Commands 2-59 UNSAVE UNSAVE The UNSAVE command.deletes a specified file from storage. Format UNSAVE [ file-spec] Syntax Rules None. Remarks 1. 2. 3. If you do not supply a file-spec, VAX BASIC deletes a file that has the file name of the program currently in memory and a file type of BAS. If you do not supply a file-spec and do not have a program in memory, VAX BASIC searches for the default file NONAME.BAS. If you do not specify a complete file name with a file type, VAX BASIC deletes the file with the specified name and the BAS file type from the default device and directory. Other file types with the same file name are not deleted. Example UNSAVE DB2:CHECK.DAT 2-60 BASIC Environment Commands Chapter 3 Compiler Directives Compiler directives are instructions that cause VAX BASIC to perform certain operations as it translates the source program. This chapter describes all of the compiler directives supported by VAX BASIC. The directives are listed and discussed alphabetically. Compiler Directives 3-1 %ABORT %ABORT The %ABORT directive terminates program compilation and displays a fatal error message that you can supply. Format %ABORT [ str-lit] Syntax Rules None. Remarks 1. Only a line number or a comment field can appear on the same physical line as the %ABORT directive. 2. VAX BASIC stops the compilation and terminates the listing file as soon as it encounters a %ABORT directive. An optional str-lit is displayed on the terminal screen and in the compilation listing, if a listing has been requested. Example XIF XVARIANT = 2 XTHEN XABORT "Cannot compile with variant 2" XEND UF 3-2 Compiler Directives %CROSS %CROSS The %CROSS directive causes VAX BASIC to begin or resume accumulating cross-reference information for the listing file. Format %CROSS Syntax Rules None. Remarks 1. Only a line number or a comment field can appear on the same physical line as the %CROSS directive. 2. The %CROSS directive has no effect unless you request both a listing file and a cross-reference. For more information on listing file format, see the VAX BASIC User Manual. 3. When a cross-reference is requested, the VAX BASIC compiler starts or resumes accumulating cross-reference information immediately after encountering the %CROSS directive. Example XCROSS Compiler Directives 3-3 %DECLARED %DECLARED The %DECLARED directive is a built-in lexical function that allows you to determine whether a lexical variable has been defined with the %LET directive. If the lexical variable named in the %DECLARED function is defined in a previous %LET directive, the %DECLARED function returns the value -1. If the lexical variable is not defined in a previous %LET directive, the %DECLARED function returns the value 0. Format %DECLARED (lex-var) Syntax Rules The %DECLARED function can appear only in a lexical expression. 2. The lex-var is the name of a lexical variable. Lexical variables are always LONG integers. 3. Lex-var must be enclosed in parentheses. 1. Remarks None. 3-4 Compiler Directives %DECLARED Example + Use the following code in XINCLUDE files which reference constants that may be already defined. ! - Y.IF XJ)ECLARED CY.TRUE_FALSE_DEFINED) = 0 Y.THEN DECLARE LONG CONSTANT True = -1, False = 0 Y.LET Y.TRUE_FALSE_DEFINED = -1 Y.END UF Compiler Directives 3-5 o/olDENT %1DENT The %!DENT directive lets you identify the version of a program module. The identification text is placed in the object module and printed in the listing header. Format %1DENT str-lit Syntax Rules Str-lit is the identification text. Str-lit can consist of up to 31 ASCII characters. If it has more than 31 characters, VAX BASIC truncates the extra characters and signals a warning message. Remarks 1. Only a line number or a comment field can appear on the same physical line as the %!DENT directive. 2. The VAX BASIC compiler inserts the identification text in the first 31 character positions of the second line on each listing page. VAX BASIC also includes the identification text in the object module, if the compilation produces one, and in the map file created by the VAX/VMS Linker. 3. The %IDENT directive should appear at the beginning of your program if you want the identification text to appear on the first page of your listing. If the %!DENT directive appears after the first program statement, the text will appear on the next page of the listing file. 3-6 Compiler Directives o/olDENT 4. You can use the %IDENT directive only once in a module. If you specify more than one %IDENT directive in a module, VAX BASIC signals a warning and uses the identification text specified in the first directive. 5. No default identification text is provided. Example Y.IDENT "Version 10" Output TIME$MAIN Version 10 1 10 Y.IDENT "Version 10" Compiler Directives 3-7 o/olF-o/oTHEN-o/oELSE-o/oEND o/olF %IF-%THEN-%ELSE-%END %IF The %IF-% THEN-%ELSE-%END %IF directive lets you conditionally include source code or execute another compiler directive. Format %IF lex-exp %THEN code [%ELSE code] %END %IF Syntax Rules 1. 2. Lex-exp is always a LONG integer. Lex-exp can be: • • • • 3. 3-8 Compiler Directives A lexical constant named in a %LET directive. An integer literal, with or without the percent sign suffix. A lexical built-in function. Any combination of the above, separated by valid lexical operators. Lexical operators include logical operators, relational operators, and the arithmetic operators for addition ( + ), subtraction ( - ), multiplication ( • ), and division ( / ). Code is VAX BASIC program code. It can be any VAX BASIC statement or another compiler directive, including another %IF directive. You can nest %IF directives to eight levels. %1F-%THEN-%ELSE-%END %IF lemarks 1. 2. 3. 4. The %IF directive can appear anywhere in a program where a space is allowed, except within a quoted string. This means that you can use the %IF directive to make a whole statement, part of a statement, or a block of statements conditional. %THEN, %ELSE, and %END %IF do not have to be on the same physical line as %IF. If lex-exp is true, VAX BASIC processes the %THEN clause. If lexexp is false, VAX BASIC processes the %ELSE clause. If there is no %ELSE clause, VAX BASIC processes the %END %IF clause. The VAX BASIC compiler includes statements in the %THEN or %ELSE clause in the source program and executes directives in order of occurrence. You must include the %END %IF clause. Otherwise, VAX BASIC assumes the remainder of the program is part of the last %THEN or %ELSE clause and signals the error "MISENDIF, missing END IF directive" when compilation ends. :xample %IF (%VARIANT = 2) %THEN DECLARE SINGLE hourly_pay(100) %ELSE %IF (%VARIANT = 1) %THEN DECLARE DOUBLE salary_pay(100) %ELSE %ABORT "Can't compile with specified variant" %END %IF %END %IF PRINT %IF (%VARIANT = 2) %THEN 'Hourly Wage Chart' GOTO Hourly_routine %ELSE 'Salaried Wage Chart' GOTO Salary_routine %END %IF July 1988 Compiler Directives 3-9 %INCLUDE %INCLUDE The %INCLUDE directive lets you include VAX BASIC source text from another program file in the current program compilation. VAX BASIC also lets you access record definitions in the VAX Common Data Dictionary (COD) and access commonly used routines from text libraries. Format Including a File %INCLUDE str-lit Including a COD Definition %INCLUDE %FROM %COD str-lit Including a File from a Text Library %INCLUDE str-lit %FROM %LIBRARY [str-lit] Syntax Rules 1. Including a File Str-lit must be a valid file specification for the file to be included. 2. Including a COD Definition Str-lit specifies a VAX COD path name enclosed in quotation marks. The path name can be in either DMU or COO format. This directive lets you extract a RECORD definition from the dictionary. 3. Including a File from a Text Library • Str-lit specifies a particular module to be included. • The optional str-lit identifies a specific text library in which the included module resides. If the library name is not specified, VAX BASIC uses the default library name BASIC$LIBRARY. 3-10 Compiler Directives July 1988 %INCLUDE Remarks 1. 2. 3. 4. 5. 6. 7. 8. 9. Any statement that appears after an END statement inside an included file causes VAX BASIC to signal an error. Only a line number or a comment field can appear on the same physical line as the %INCLUDE directive. The VAX BASIC compiler includes the specified source file in the program compilation at the point of the %INCLUDE directive and prints the included code in the program listing file if the compilation produces one. The included file cannot contain line numbers. If it does, VAX BASIC signals the error "Line number may not app~ar in %INCLUDE file". All statements in the accessed file are associated with the line number of the program line that contains the %INCLUDE directive. This means that a %INCLUDE directive cannot appear before the first line number in a source program if you are using line numbers. A file accessed by %INCLUDE can itself contain a %INCLUDE directive. All %IF directives in an included file must have a matching %END %IF directive in the file. You can control whether or not included text appears in the compilation listing with the /[NO]SHOW:INCLUDE qualifier to the COMPILE command. When you specify /SHOW:INCLUDE, the compilation listing file identifies any text obtained from an included file by placing a mnemonic in the first character position of the line on which the text appears. The "n" specifies that the text was either accessed from a source file or from a text library. The "I" tells you that the text was accessed with the %INCLUDE directive and n is a number that tells you the nesting level of the included text. See the VAX BASIC User Manual for more information on listing mnemonics. Including a File If you do not specify a complete file specification, VAX BASIC uses the default device and directory and the file type BAS. 10. Including a COD Definition • In versions prior to VAX CDD/Plus Version 4.0, there are two types of CDD path names: full and relative. A full path name begins with CDD$TOP and specifies the complete path to the record July 1988 Compiler Directives 3-11 %INCLUDE • • • • • • • • • 3-12 Compiler Directives definition. A relative path name begins with any string other than CDD$TOP and is appended to the current CDD$DEFAULT. In VAX CDD/Plus Version 4.0 or higher, the pathnames described previously are known as DMU pathnames, as distinct from CDO pathnames. You can specify either a full DMU pathname, a full CDO pathname, or a relative pathname. A full pathname consists of a dictionary origin followed by a dictionary path. A full DMU pathname has CDD$TOP as its origin. A full CDO pathname has an anchor as its origin. See CDD /Plus documentation for detailed information on pathnames. If the record definition being accessed is in a CDO-format dictionary, you can create a dependency relationship in the dictionary between a dictionary representation of your program and the record definitions that you include in the program. The dictionary representation of the program is called a compiled module entity. If you specify the /DEPENDENCY_DATA qualifier to the compiler and your CDD$DEFAULT points to a CDO-format dictionary, a compiled module entity is created for each compilation unit at compile time in CDD$DEFAULT. No compiled module entity is created if both conditions are not true. If a compiled module entity exists for the program, an %INCLUDE %FROM %CDD directive specifying a record description in a CDO-format dictionary creates a relationship between the compiled module entity and the CDO-format record definition. If the record description specified in the pathname exists, it is copied to the program, whether a compiled module entity can be created or not. When you use the %INCLUDE directive to extract a record definition from the CDD, VAX BASIC translates the CDD definition to the syntax of the VAX BASIC RECORD statement. You can use the /SHOW:CDD_DEFINITIONS qualifier to specify that translated CDD definitions (in RECORD statement syntax) are included in the compilation listing file. VAX BASIC places a "C" in column 1 when the translated RECORD statement appears in the listing file. When you specify /SHOW:NOCDD_DEFINITIONS, VAX BASIC does not include the CDD definition in the listing file. However, VAX BASIC still includes the names, data types, and offsets of the CDD record components in the program listing's allocation map. See the VAX BASIC User Manual and the CDD/Plus documentation for more information on dictionary data definitions. July 1988 %INCLUDE 11. Including a File from a Text Library • The VAX BASIC compiler searches through the specified text library for the module named and compiles the module upon encountering the %INCLUDE directive. • VAX BASIC allows only 16 text libraries to be opened at one time. Therefore, you cannot have %INCLUDE directives from a text library nested more than 16 levels deep. If you exceed this maximum, VAX BASIC signals an error message. • If you do not specify a directory name and file type, VAX BASIC uses the default device and directory and the file type TLB. • VAX BASIC provides the text library BASIC$STARLET. BASIC$STARLET contains condition codes and other symbols defined in the system object and shareable image libraries. Using the definitions from BASIC$STARLET allows you to reference condition codes and other system-defined symbols as local, rather than global symbols. To create your own text libraries using the VAX/VMS Librarian Utility, see the VMS Librarian Utility Manual. Examples Example 1 !Including a File %INCLUDE "YESNO" Example 2 !Including a CDD Definition %INCLUDE %FROM %COD 11 CDD$TOP.EMPLOYEE 11 Example 3 !Including a COD Definition with a CDO-format pathname %INCLUDE %FROM %CDD "MYNODE: :MY$DISK: [MY_DIR]PERSONNEL.EMPLOYEE" !The anchor is MYNODE: :MY$DISK: [MY_DIR] Example 4 !Including a File from a Text Library %INCLUDE 11 EOF_CHECK 11 %FROM %LIBRARY 11 SYS$LIBRARY:BASIC_LIB.TLB" July 1988 Compiler Directives 3-13 %LET %LET The %LET directive declares and provides values for lexical variables. You can use lexical variables only in conditional expressions in the %IF%THEN-%ELSE directive and in lexical expressions in subsequent %LET directives. Format %LET %/ex-var= /ex-exp Syntax Rules Lex-var is the name of a lexical variable. Lexical variables are always LONG integers. 2. Lex-var must be preceded by a percent sign(%) and cannot end with a dollar sign ( $) or percent sign. 3. Lex-exp can be any of the following: • A lexical variable named in a previous %LET directive . • An integer literal, with or without the percent sign suffix . • A lexical built-in function . • Any combination of the above, separated by valid lexical operators. Lexical operators can be logical operators, relational operators, and the arithmetic operators for addition ( + ), subtraction ( - ), multiplication ( * ), and division ( / ). 1. 3-14 Compiler Directives %LET Remarks 1. 2. Only a line number or a comment field can appear on the same physical line as the %LET directive. You cannot change the value of lex-var within a program unit once it has been named in a %LET directive. For more information on coding conventions see the VAX BASIC User Manual. Example Y.LET YJ>EBUG_ON = 1Y. Compiler Directives 3-15 %LIST %LIST The %LIST directive causes the VAX BASIC compiler to start or resume accumulating compilation information for the program listing file. Format %LIST Syntax Rules None. Remarks 1. Only a line number or a comment field can appear on the same physical line as the %LIST directive. 2. The %LIST directive has no effect unless you requested a listing file. For more information on listing file format, see the VAX BASIC User Manual. 3. As soon as it encounters the %LIST directive, the VAX BASIC compiler starts or resumes accumulating information for the program listing file. Thus, the directive itself appears as the next line in the listing file. Example Y.LIST 3-16 Compiler Directives %NOCROSS %NOCROSS The %NOCROSS directive causes the VAX BASIC compiler to stop accumulating cross-reference information for the program listing file. Format %NOCROSS Syntax Rules None. Remarks 1. Only a line number or a comment field can appear on the same physical line as the %NOCROSS directive. 2. The VAX BASIC compiler stops accumulating cross-reference information for the program listing file immediately after encountering the %NOCROSS directive. 3. The %NOCROSS directive has no effect unless you request a listing file and cross-reference information. 4. DIGITAL recommends that you do not embed a %NOCROSS directive within a statement. Embedding a %NOCROSS directive within a statement makes the accumulation of cross-reference information unpredictable. For more information on listing file format, see the VAX BASIC User Manual. Compiler Directives 3-17 %NOCROSS Example Y.NOCROSS 3-18 Compiler Directives %NOLIST %NOLIST The %NOLIST directive causes the VAX BASIC compiler to stop accumulating compilation information for the program listing file. Format %NOLIST Syntax Rules None. Remarks 1. Only a line number or a comment field can appear on the same physical line as the %NOLIST directive. 2. As soon as it encounters the %NOLIST directive, the VAX BASIC compiler stops accumulating information for the program listing file. Thus, the directive itself does not appear in the listing file. 3. The %NOLIST directive has no effect unless you requested a listing file. 4. In VAX BASIC, you can override all %NOLIST directives in a program with the /SHOW:OVERRIDE qualifier. For more information on listing file format, see the VAX BASIC User Manual. Example 1.NOLIST Compiler Directives 3-19 %PAGE %PAGE The %PAGE directive causes VAX BASIC to begin a new page in the program listing file immediately after the line that contains the %PAGE directive. Format %PAGE Syntax Rules None. Remarks 1. Only a line number or a comment field can appear on the same physical line as the %PAGE directive. 2. The %PAGE directive has no effect unless you request a listing file. Example Y.PAGE 3-20 Compiler Directives %PRINT %PRINT The %PRINT directive lets you insert a message into your source code that the VAX BASIC compiler prints during compilation. Format %PRINT str-lit Syntax Rules None. Remarks 1. 2. Only a line number or a comment field can appear on the same physical line as the %PRINT directive. VAX BASIC will print the message specified as soon as it encounters a %PRINT directive. Str-lit is displayed on the terminal screen and in the compilation listing. Example %IF %DEBUG = 1% %THEN %PRINT "This is a debug compilation" Output %BASIC-S-USERPRINT, This is a debug compilation Compiler Directives 3-21 %REPORT %REPORT The %REPORT directive lets you record a dependency relationship between the compiled module entity for your program and the data definitions in CDD /Plus dictionaries. The data definitions are not copied into the program. format %REPORT %DEPENDENCY str-lit [relationship-type] Syntax Rules 1. 2. str-lit specifies a path name in a CDO-format dictionary. It can be either a DMU-format pathname or a CDO-format pathname, enclosed in quotation marks. This specifies a dictionary entity, such as a form definition or an Rdb /VMS database, that the program references. relationship-type specifies a valid CDD /Plus protocol; it must be enclosed in quotation marks if specified. The default relationship-type is CDD$COMPILED_DEPENDS_ON. Remarks 1. 2. 3. 3-22 Compiler Directives For this directive to be meaningful, you must specify the /DEPENDENCY_DATA qualifier at compile time. If /DEPENDENCY is not specified, the compiler· will simply check syntax and otherwise ignore the %REPORT directive. Your current CDD$DEFAULT and str-lit must refer to CDO-format dictionaries (not necessarily the same one). If you specify the /DEPENDENCY_DATA qualifier to the compiler, and if CDD$DEFAULT points to a CDO-format dictionary, a compiled module entity is created in CDD$DEFAULT for each compilation unit. No compiled module entity is created if both conditions are not true. July 1988 %REPORT 4. The %REPORT %DEPENDENCY directive creates a dependency relationship in the dictionary between the compiled module entity for the program and the CDO-format dictionary entity to which it refers. Example !Establish access to the form PINK_SLIP in a dictionary !on a specified node, and report the program's dependency !relationship with the form. %REPORT %DEPENDENCY "MYNODE: :MY$DISK: [MYDIR]PERSONNEL.FORMS.PINK_SLIP" !Relationship is CDD$COMPILED_DEPENDS_ON, the default. July 1988 Compiler Directives 3-22.1 o/oSBTTL %SBTTL The %SBTTL directive lets you specify a subtitle for the program listing file. Format %SBTTL str-lit Syntax Rules Str-lit can contain up to 45 characters. Remarks 1. 2. 3. 4. 5. VAX BASIC truncates extra characters from str-lit and does not signal a warning or error. Only a line number or a comment field can appear on the same physical line as the %SBTTL directive. The specified subtitle appears underneath the title on the second line of all pages of source code in the listing file until the VAX BASIC compiler encounters another %SBTTL or % TITLE directive. VAX BASIC clears the subtitle field before the allocation map section of the listing is generated. This way, you only get a subtitle on the listing pages that contain source code. Because VAX BASIC associates a subtitle with a title, a new %TITLE directive sets the current subtitle to the null string. In this case, no subtitle appears in the listing until VAX BASIC encounters another %SBTTL directive. If you want a subtitle to appear on the first page of your listing, the %SBTTL directive should appear at the beginning of your program, immediately after the % TITLE directive. Otherwise, the subtitle will start to appear only on the second page of the listing. 3-22.2 Compiler Directives %SBTIL 6. If you want the subtitle to appear on the page of the listing that contains the %SBTTL directive, the %SBTTL directive should immediately follow a %PAGE directive or a %TITLE directive that follows a %PAGE directive. 7. The %SBTTL directive has no effect unless you request a listing file. Example 100 200 iTITLE "Learning to Program in VAX BASIC" isBTTL "Using FOR-NEXT Loops" REM THIS PROGRAM IS A SIMPLE TEST DATA 1, 2, 3, 4 300 NEXT !Y. END Output TEST$MAIN 1 2 3 4 Learning to Program in VAX BASIC Using FOR-NEXT Loops 100 200 %TITLE "Learning to Program in VAX BASIC" lSBTTL "Using FOR-NEXT Loops" REM THIS PROGRAM IS A SIMPLE TEST DATA 1, 2, 3, 4 300 NEXT !Y. END 10 11 Compiler Directives 3-23 %TITLE %TITLE The %TITLE directive lets you specify a title for the program listing file. Format %TITLE str-lit Syntax Rules Str-lit can contain up to 45 characters. Remarks 1. VAX BASIC truncates extra characters from str-lit and does not signal a warning or error. 2. Only a line number or a comment field can appear on the same physical line as the %TITLE directive. 3. The specified title appears on the first line of every page of the listing file until VAX BASIC encounters another %TITLE directive in the program. 4. The %TITLE directive should appear on the first line of your program, before the first statement, if you want the specified title to appear on the first page of your listing. 5. If you want the specified title to appear on the page that contains the %TITLE directive, the %TITLE directive should immediately follow a %PAGE directive. 6. Because VAX BASIC associates a subtitle with a title, a new %TITLE directive sets the current subtitle to the null string. 7. The %TITLE directive has no effect unless you request a listing file. 3-24 Compiler Directives %TITLE Example 100 %TITLE "Learning to Program in VAX BASIC" REM THIS PROGRAM IS A SIMPLE TEST 200 DATA 1, 2, 3, 4 300 NEXT IX END Output TEST$MAIN Learning to Program in VAX BASIC 1 2 3 4 100 200 Y.TITLE "Learning to Program in VAX BASIC" Y.SBTTL "Using FOR-NEXT Loops" REM THIS PROGRAM IS A SIMPLE TEST DATA 1, 2, 3, 4 10 11 300 NEXT IX END Compiler Directives 3-25 %VARIANT %VARIANT The %VARIANT directive is a built-in lexical function that allows you to conditionally control program compilation. %VARIANT returns an integer value when you reference it in a lexical expression. You set the variant value with the /VARIANT qualifier when you compile the program or with the SET %VARIANT command. Format %VARIANT Syntax Rules None. Remarks 1. The %VARIANT function can appear only in a lexical expression. 2. The %VARIANT function returns the integer value specified either with the COMPILE /VARIANT command, the SET /VARIANT command, or the DCL command BASIC. The returned integer always has a data type of LONG. 3-26 Compiler Directives %VARIANT Example XLET XVAX = 0 XLET USX = 1 XLET XRSTS = 2 XIF XVARIANT = XVAX X!HEN XELSE XIF XVARIANT = XRSX OR XVARIANT = XRSTS XTHEN XELSE Y.ABORT "Illegal compilation variant" XEND X!F XEND X!F Compiler Directives 3-27 Chapter 4 Statements and Functions This chapter provides reference material on all of the VAX BASIC statements and functions. The statements and functions are listed in alphabetical order and each description contains the following sections: Definition A description of what the statement does. Format The required syntax for the statement. Syntax Rules Any rules governing the use of parameters, separators, or other syntax items. Remarks Explanatory remarks concerning the effect of the statement on program execution and any restrictions governing its use. Example One or more examples of the statement in a VAX BASIC program. Where appropriate, sample output is also shown. Statements and Functions 4-1 ABS ABS The ABS function returns a floating-point number that equals the absolute value of a specified floating-point expression. Format real-var= ABS (real-exp) Syntax Rules None. Remarks 1. 2. 4-2 The argument of the ABS function must be a real expression. When the argument is a real expression, VAX BASIC returns a value of the same floating-point size. When the argument is not a real expression, VAX BASIC converts the argument to the default floating-point size and returns a value of the default floating-point size. The returned floating-point value is always greater than or equal to zero. The absolute value of zero is zero. The absolute value of a positive number equals that number. The absolute value of a negative number equals that number multiplied by -1. Statements and Functions ABS Example G = 6.1273 A = ABS(-100 * G) B = -39 PRINT ABS(B), A Output 39 612.73 Statements and Functions 4-3 ABS% ABSo/o The ABS% function returns an integer that equals the absolute value of a specified integer expression. Format int-var= ABS% (int-exp) Syntax Rules None. Remarks 1. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to an integer of the default integer size. 2. The returned value is always greater than or equal to zero. The absolute value of zero is zero. The absolute value of a positive number equals that number. The absolute value of a negative number equals that number multiplied by -1. Example GY, = 5.1273 A = ABSY.(-100% * GY,) B = -39 PRINT ABSY.(B), A Output 39 4-4 Statements and Functions 512 ASCII ASCII The ASCII function returns the ASCII value in decimal of a string's first character. Format int-var={ ASC } (str-exp) ASCII Syntax Rules None. Remarks 1. 2. The ASCII value of a null string is zero. The ASCII function returns an integer value of the default size between 0 and 255. Example DECLARE STRING time_out time_out = "Friday" PRINT ASCII(time_out) Output 70 Statements and Functions 4-5 AYN ATN The ATN function returns the arctangent (that is, angular value) of a specified tangent in radians or degrees. Format real-var= ATN (real-exp) Syntax Rules None. Remarks 1. 2. 3. 4-6 ATN returns a value from -PI/2 through PI/2. The returned angle is expressed in radians or degrees, depending on which angle clause you choose with the OPTION statement. The argument of the ATN function must be a real expression. When the argument is a real expression, VAX BASIC returns a value of the same floating-point size. When the argument is not a real expression, VAX BASIC converts the argument to the default floating-point size and returns a value of the default floating-point size. Statements and Functions July 1988 AYN Example OPTION ANGLE = RADIANS DECLARE SINGLE angle_rad, angle_deg, T INPUT "Tangent value";T angle_rad = ATN(T) PRINT "The smallest angle with that tangent is" ;angle_rad; "radians" angle_deg = angle_rad/(PI/180) PRINT "and"; angle_deg; "degrees" Output Tangent value? 2 The smallest angle with that tangent is 1.10715 radians and 63.435 degrees Statements and Functions 4-7 BUFSIZ BUFSIZ The BUFSIZ function returns the record buffer size, in bytes, of a specified channel. Format int-var= BUFSIZ (chnl-exp) Syntax Rules 1. 2. Chnl-exp is a numeric expression that specifies a channel number. The value assigned to int-var is a LONG integer. Remarks 1. If the specified channel is closed, BUFSIZ returns a value of zero. 2. BUFSIZ of channel #0 always returns the value 132. Example DECLARE LONG buffer_size buffer_size = BUFSIZ(O) PRINT "Buffer size equals";buffer_size Output Buff er size equals 132 4-8 Statements and Functions CALL CALL The CALL statement transfers control to a subprogram, external function, or other callable routine. You can pass arguments to the routine and can optionally specify passing mechanisms. When the called routine finishes executing, control returns to the calling program. Format CALL routine [ pass-mech] [ ( actual-param ,... ) ] routine: sub-name } { any-callable-routine pass-mech: BY VALUE } BY REF { BY DESC actual-param: exp } { array ( Lr'J••• ) [pass-mech] Syntax Rules 1. Routine is the name of a SUB subprogram or any other callable 2. procedure, such as a system service or an RTL routine you want to call. It cannot be a variable name. See the VAX BASIC User Manual for more information on using system services, RTL routines, and other procedures. Pass-mech specifies how arguments are passed to the called routine. If you do not specify a pass-mech, VAX BASIC passes arguments as indicated in Table 4-1. • BY VALUE specifies that VAX BASIC passes the argument's 32-bit value. Statements and Functions 4-9 CALL • • BY REF specifies that VAX BASIC passes the argument's address. This is the default for all arguments except strings and entire arrays. BY DESC specifies that VAX BASIC passes the address of a VAX BASIC descriptor. For information about the format of a VAX BASIC descriptor for strings and arrays, see Appendix C. For more information on other types of descriptors, see the VAX Architecture Handbook. Table 4-1: VAX BASIC Parameter-Passing Mechanisms BY VALUE BY REF BY DESC Variables Yes Yes Yes Constants Yes Local copy I Local copy Expressions Yes Local copy 1 Local copy Elements of a nonvirtual array Yes Yes 1 Yes Virtual array elements Yes Local copy 1 Local copy Non virtual en tire array No Yes Yes 1 Virtual entire array No No No Variables No Yes Yes Constants No Local copy 1 Local copy Expressions No Local copy 1 Local copy Non virtual array elements No Yes 1 Yes Parameter Integer and Real Data Packed Decimal Data 1 4-10 Specifies the default parameter-passing mechanism. Statements and Functions CALL Table 4-1 (Cont.): Parameter VAX BASIC Parameter-Passing Mechanisms BY VALUE BY REF BY DESC Packed Decimal Data Virtual array elements No Local copy 1 Local copy Non virtual entire arrays No Yes Yes 1 Virtual entire arrays No No No Variables No Yes Yes Constants No Local copy Local copy 1 Expressions No Local copy Local copy 1 Non virtual array elements No Yes Yes 1 Virtual array elements No Local copy Local copy 1 Non virtual entire arrays No Yes Yes 1 Virtual entire arrays No No No RECORD variables No Yes 1 No RF A variables No Yes 1 No String Data Other Parameters 1 Specifies the default parameter-passing mechanism. 3. You should use parameter-passing mechanisms only when calling non-BASIC routines or when a subprogram expects to receive a string or entire array by reference. Statements and Functions 4-11 CALL 4. 5. 6. 7. 8. 9. When pass-mech appears before the parameter list, it applies to all arguments passed to the called routine. You can override this passing mechanism by specifying a pass-mech for individual arguments in the actual-param list. Actual-param lists the arguments to be passed to the called routine. You can pass expressions or entire arrays. Optional commas in parentheses after the array name specify the dimensions of the array. The number of commas is equal to the number of dimensions 1. Thus, no comma specifies a one-dimensional array, one comma specifies a two-dimensional array, two commas specify a threedimensional array, and so on. You cannot pass entire virtual arrays. The name of the routine can be from 1 to 31 characters and must conform to the following rules: • The first character of an unquoted name must be an alphabetic character (A through Z). The remaining characters, if present, can be any combination of letters, digits (0 through 9), dollar signs ( $ ), periods (. ), or underscores (-). • A quoted name can consist of any combination of printable ASCII characters. VAX BASIC allows you to pass up to 255 parameters. Remarks You can specify a null argument as an actual-param for non-BASIC routines by omitting the argument and the pass-mech, but not the commas or parentheses. This forces VAX BASIC to pass a null argument and allows you to access system routines from VAX BASIC. 2. Arguments in the actual-param list must agree in data type and number with the formal parameters specified in the subprogram. 3. An argument is modifiable when changes to it are evident in the calling program. Changing a modifiable parameter in a subprogram means the parameter is changed for the calling program as well. Variables and entire arrays passed by descriptor or by reference are modifiable. 1. 4-12 Statements and Functions CALL 4. An argument is nonmodifiable when changes to it are not evident in the calling program. Changing a nonmodifiable argument in a subprogram does not affect the value of that argument in the calling program. Arguments passed by value, constants, and expressions are nonmodifiable. Passing an argument as an expression (by placing it in parentheses) changes it from a modifiable to a nonmodifiable argument. Virtual array elements passed as parameters are nonmodifiable. 5. VAX BASIC will automatically convert numeric actual parameters to match the declared data type. If the actual parameter is a variable, VAX BASIC signals the informational message "Mode for parameter <n> of routine <name> changed to match declaration" and passes the argument by local copy. This prevents the called routine from modifying the contents of the variable. 6. For expressions and virtual array elements passed by reference, VAX BASIC makes a local copy of the value, and passes the address of this local copy. For dynamic string arrays, VAX BASIC passes a descriptor of the array of string descriptors. The compiler passes the address of the argument's actual value for all other arguments passed by reference. 7. Only BYTE, WORD, LONG, and SINGLE values can be passed by value. BYTE and WORD values passed by value are converted to LONG values. 8. If you attempt to call an external function, VAX BASIC treats the function as if it were invoked normally and validates all parameters. Note that you cannot call a STRING, HFLOAT, or RFA function. See the EXTERNAL statement for more information on how to invoke functions. Example EXTERNAL SUB LIB$PUT_OUTPUT (string) DECLARE STRING msg_str msg_str = "Successful call to LIB$PUT_OUTPUT!" CALL LIB$PUT_OUTPUT (msg_str) Output Successful call to LIB$PUT_OUTPUT! Statements and Functions 4-13 CAUSE ERROR CAUSE ERROR The CAUSE ERROR statement allows you to artificially generate a VAX BASIC run-time error and transfer program control to a VAX BASIC error handler. Format CAUSE ERROR err-num Syntax Rules Err-num must be a valid VAX BASIC run-time error number. Remarks All error numbers are listed in the VAX BASIC User Manual. Example WHEN ERROR IN CAUSE ERROR 11% USE SELECT ERR 4-14 Statements and Functions CAUSE ERROR CASE = 11 PRINT "End of file" CONTINUE CASE ELSE EXIT HANDLER END SELECT END WHEN Statements and Functions 4-1 5 CCPOS CCPOS The CCPOS function returns the current character or cursor position of the output record on a specified channel. Format int-var= CCPOS (chnl-exp) Syntax Rules Chnl-exp must specify an open file or terminal. Remarks 1. 2. 3. 4. 4-16 If chnl-exp is zero, CCPOS returns the current character position of the controlling terminal. The int-var returned by the CCPOS function is of the default integer size. The CCPOS function counts only characters. If you use cursor addressing sequences such as escape sequences, the value returned will not be the cursor position. The first character position on a line is zero. Statements and Functions CCPOS Example DECLARE LONG curs_pos PRINT "Hello"; curs_pos = CCPOS (0) PRINT curs_pos Output Hello 6 Statements and Functions 4-1 7 CHAIN CHAIN The CHAIN statement transfers control from the current program to another executable image. CHAIN closes all files, then requests that the new program begin execution. Control does not return to the original program when the new image finishes executing. NOTE The CHAIN statement is not recommended for new program development. DIGITAL recommends that you use subprograms, external functions and pictures for program segmentation. Format CHAIN str-exp Syntax Rules Str-exp represents the file specification of the program to which control is passed. It can be a quoted or unquoted string. Remarks 1. Str-exp must refer to an executable image or VAX BASIC signals an error. 2. If you do not specify a file type, VAX BASIC searches for an EXE file type. 3. You cannot chain to a program on another node. 4. Execution starts at the beginning of the specified program. 5. Before chaining takes place, all active output buffers are written, all open files are closed, and all storage is released. 4-18 Statements and Functions CHAIN 6. Because a CHAIN statement passes control from the executing image, the values of any program variables are lost. This means that you can pass parameters to a chained program only by using files or a system-specific feature such as LIB$GET_COMMON and LIB$PUT_ COMMON. Example DECLARE STRING time_out time_out = "Friday" PRINT ASCII(time_out) CHAIN "CCPOS" Output 70 The current cursor position is 0 In this example, control is passed from the executing image, ASCII.EXE to the chained program, CCPOS.EXE. The value that results from ASCII.EXE is 70. The second line of output reflects the value that results from CCPOS.EXE. , Statements and Functions 4-19 CHANGE CHANGE The CHANGE statement either converts a string of characters to their ASCII integer values or converts a list of numbers to a string of ASCII characters. Format String Variable to Array CHANGE str-exp TO num-array-name Array to String Variable CHANGE num-array-name TO str-var Syntax Rules 1. 2. Str-exp is a string expression. Num-array-name should be a one-dimensional array. If you specify a two-dimensional array, VAX BASIC converts only the first row of that array. VAX BASIC does not support conversion to or from arrays of more than two dimensions. Remarks 1. VAX BASIC does not support RECORD elements as a destination string or as a source or destination array for the CHANGE statement. 2. String Variable to Array • This format converts each character in the string to its ASCII value. • VAX BASIC assigns the value of the string's length to the first element of the array. 4-20 Statements and Functions CHANGE • VAX BASIC assigns the ASCII value of the first character in the string to the second element, ( 1) or (0, l), of the array, the ASCII value of the second character to the third element, ( 2) or (0,2), and so on. • If the string is longer than the bounds of the array, VAX BASIC does not translate the excess characters, and signals the error "Subscript out of range" (ERR=55). The first element of array still contains the length of the string. 3. Array to String Variable • This format converts the elements of the array to a string of characters. • The length of the string is determined by the value in the zero element, ( 0) or (0,0), of the array. If the value of element zero is greater than the array bounds, VAX BASIC signals the error "Subscript out of range" (ERR=55). • VAX BASIC changes the first element, ( 1) or (0,1), of array to its ASCII character equivalent, the second element, ( 2) or (0,2), to its ASCII equivalent, and so on. The length of the returned string is determined by the value in the zero element of the array. For example, if the array is dimensioned as ( 10 ), but the zero element ( 0 ) contains the value 5, VAX BASIC changes only elements ( 1 ), ( 2 ), ( 3 ), ( 4 ), and ( 5 ) to string characters. • VAX BASIC truncates floating-point values to integers before converting them to characters. • Values in array elements are treated modulo 256. Statements and Functions 4-21 CHANGE Example DECLARE STRING ABCD, A DIM INTEGER array_changes(6) ABCD = "ABCD 11 CHANGE ABCD TO array_changes FOR IY. = 0 TO 4 PRINT array_changes(IY.) NEXT IY. CHANGE array_changes TO A PRINT A Output 4 65 66 67 68 ABCD 4-22 Statements and Functions CHRS CHRS The CHR$ function returns a 1-character string that corresponds to the ASCII value you specify. Format str-var = CHR$ (int-exp) Syntax Rules None. Remarks 1. 2. 3. CHR$ returns the character whose ASCII value equals int-exp. If int-exp is greater than 255, VAX BASIC treats it modulo 256. For example, CHR$(325) is the same as CHR$(69). All arguments between 0 and 255 are considered unsigned 8-bit integers. For example, -1 is treated as 255. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to an integer of the default size. Example DECLARE INTEGER num_exp INPUT "Enter the ASCII value you wish to be converted";num_exp PRINT "The equivalent character is ";CHR$(num_exp) Output Enter the ASCII value you wish to be converted? 89 The equivalent character is Y Statements and Functions 4-23 CLOSE CLOSE The CLOSE statement ends I/O processing to a device or file on the specified channel. Format CLOSE [# ]chnl-exp, ... Syntax Rules Chnl-exp is a numeric expression that specifies a channel number associated with a file. It can be preceded by an optional number sign ( # ). Remarks 1. VAX BASIC writes the contents of any active output buffers to the file or device before it closes that file or device. 2. Channel #0 (the controlling terminal) cannot be closed. An attempt to do so has no effect. 3. If you close a magnetic tape file that is open for output, VAX BASIC writes an end-of-file on the magnetic tape. 4. If you try to close a channel that is not currently open, VAX BASIC does not signal an error and the CLOSE statement has no effect. 4-24 Statements and Functions CLOSE Example OPEN "COURSE_REC.DAT" FOR INPUT AS #2 INPUT #2, course_nam, course_num, course_desc, course_instr CLOSE #2 In this example, COURSE_REC.DAT is opened for input. Once the user inputs all of the required information, the file is closed. Statements and Functions 4-25 COMMON COMMON The COMMON statement defines a named, shared storage area called a COMMON block or program section (PSECT). VAX BASIC program modules can access the values stored in the COMMON block by specifying a COMMON block with the same name. Format COM } { COMMON [ (com-name)] ([data-type] com-item), ... num-unsubs-var num-array-name ( [ int-const1 TO] int-const2 ,... ) str-unsubs-var =int-canst str-array-name ( [ int-const1 TO] int-const2, ... ) [=int-canst] record-var FILL [ (int-canst)][= int-canst] FILL% [ (int-canst)] FILL$ [ (int-canst)][= int-canst] com-item: Syntax Rules 1. A COMMON block can have the same name as a program variable. 2. A COMMON block and a map in the same program module cannot have the same name. 3. All COMMON elements must be separated with commas. 4. Com-name is optional. If you specify a com-name, it must be in parentheses. If you do not specify a com-name, the default is "$BLANK". 5. Com-name can be from 1 through 31 characters. The first character of the name must be an alphabetic character (A through Z). The remaining characters, if present, can be any combination of letters, digits (0 through 9), dollar signs ( $ ), periods ( . ), or underscores (- ). 4-26 Statements and Functions COMMON Data-type can be any VAX 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 in this manual. 7. When you specify a data type, all following com-items, including FILL items, are of that data type until you specify a new data type. 8. If you do not specify any data type, com-items take the current default data type and size. 9. Com-item declares the name and format of the data to be stored. • Num-unsubs-var and num-array-name specify a numeric variable or a numeric array. • Record-var specifies a record instance. • Str-unsubs-var and str-array-name specify a fixed-length string variable or array. You can specify the number of bytes to be reserved for the variable with the =int-canst clause. The default string length is 16. • When you specify either a numeric or a string array, VAX BASIC allows you to declare both lower and upper bounds. The upper bound is required; the lower bound is optional. Int-const1 specifies the lower bounds of the array. Int-const2 specifies the upper bounds of the array and, when accompanied by int-const1, must be preceded by the keyword TO. Int-const1 must be less than or equal to int-const2. If you do not specify int-const1, VAX BASIC uses zero as the default lower bound. Int-const1 and int-const2 can be either negative or positive values. • The FILL, FILL%, and FILL$ keywords allow you to reserve parts of the record buffer within or between data elements and to define the format of the storage. Int-const specifies the number of FILL items to be reserved. The =int-const clause allows you to specify the number of bytes to be reserved for string FILL items. Table 4-2 describes FILL item format and storage allocation. 6. NOTE In the applicable formats of FILL, (int-const) represents a repeat count, not an array subscript. FILL (n) represents n elements, not n + 1. Statements and Functions 4-27 COMMON Table 4-2: 4-28 FILL Item Formats and Storage Allocations FILL Format Storage Allocation FILL Allocates storage for one element of the default data type unless preceded by a data-type; the number of bytes allocated depends on the default or the specified data type. FILL(int-const) Allocates storage for the number of floating-point elements specified by int-canst unless preceded by a data type; the number of bytes allocated for each element depends on the default floating-point data size or the specified data type. FILL% Allocates storage for one integer element; the number of bytes allocated depends on the default integer size. FILL %(int-const) Allocates storage for the number of integer elements specified by intcanst; the number of bytes allocated for each element depends on the default integer size. FILL$ Allocates 16 bytes of storage for a string element. The dollar sign can be omitted if the FILL keyword is preceded by the STRING data type. FILL$(int-const) Allocates 16 bytes of storage for the number of string elements specified by int-canst. The dollar sign can be omitted if the FILL keyword is preceded by the STRING data type. Statements and Functions COMMON Table 4-2 (Cont.): FILL Item Formats and Storage Allocations FILL Format Storage Allocation FILL$=int-const Allocates the number of bytes of storage specified by int-canst for a string element. The dollar sign can be omitted if the FILL keyword is preceded by the STRING data type. FILL$(int-constl)=int-const2 Allocates the number of bytes of storage specified by int-const2 for the number of string elements specified by int-constl. The dollar sign can be omitted if the FILL keyword is preceded by the STRING data type. Remarks 1. 2. 3. 4. 5. 6. Variables in a common are not initialized by VAX BASIC. A COMMON area and a MAP area with the same name, in different program modules, specify the same storage area. VAX BASIC does not execute COMMON statements. The COMMON statement allocates and defines the data storage area at compilation time. When you link your program, the size of the COMMON area is the size of the largest COMMON area with that name. VAX BASIC concatenates COMMON statements with the same com-name within a single program module into a single PSECT. The total space allocated is the sum of the space allocated in the concatenated COMMON statements. If you specify the same com-name in several program modules, the size of the PSECT will be determined by the program module that has the greatest amount of space allocated in the concatenated COMMON statements. The COMMON statement must lexically precede any reference to variables declared in it. A COMMON area can be accessed by more than one program module, as long as you define the com-name in each module that references the COMMON area. Statements and Functions 4-29 COMMON 7. 8. Variable names in a COMMON statement in one program module need not match those in another program module. Variables and arrays declared in a COMMON statement cannot be declared elsewhere in the program by any other declarative statements. The data type specified for com-items or the default data type and size determines the amount of storage reserved in a COMMON block: • BYTE integers reserve 1 byte. • WORD integers reserve 2 bytes. • LONG integers reserve 4 bytes. • SINGLE floating-point numbers reserve 4 bytes. • DOUBLE floating-point numbers reserve 8 bytes. • GFLOAT floating-point numbers reserve 8 bytes. • HFLOAT floating-point numbers reserve 16 bytes. • DECIMAL( d,s) packed decimal numbers reserve ( d+ 1 )/2 bytes. • STRING reserves 16 bytes (the default) or the number of bytes you specify with =int-const. 10. For multi-dimensional arrays, values are assigned in row-column order. 9. Example COMMON (sales_rec) DECIMAL net_sales (1966 TO 1976) STRING row = 2, report_name = 24 DOUBLE FILL, LONG part_bins 4-30 Statements and Functions COMP% COMP% The COMP% function compares two numeric strings and returns a -1, 0, or 1, depending on the results of the comparison. Format int-var= COMP% (str-exp1, str-exp2) Syntax Rules Str-exp1 and str-exp2 are numeric strings. They must have one of the following formats: • • An optional minus sign ( - ), ASCII digits, and an optional decimal point (.) An optional minus sign, ASCII digits, an optional decimal point, the letter E, an optional minus sign, and a 2-digit exponent Remarks 1. If str-exp1 is greater than str-exp2, COMP% returns a 1. 2. If the string expressions are equal, COMP% returns a 0. 3. If,str-exp1 is less than str-exp2, COMP% returns a -1. 4. The value returned by the COMP% function is an integer of the default size. Statements and Functions 4-31 COMP% Example DECLARE STRING num_string, old_num_string, & INTEGER result num_string = "-24.5" old_num_string = "33" result = COMPY.(num_string, old_num_string) PRINT "The value is ";result Output The value is -1 4-32 Statements and Functions CONTINUE CONTINUE The CONTINUE statement causes VAX BASIC to clear an error condition and resume execution at the statement following the statement that caused the error or at the specified target. Format CONTINUE [target] Syntax Rules If you specify a target, it must be a label or line number that appears either inside the associated protected region, inside a WHEN block protected region that surrounds the current protected region, or in an unprotected region of code. Remarks 1. 2. CONTINUE with no target causes VAX BASIC to transfer control to the statement immediately following the statement that caused the error. The next remark is an exception to this rule. If an error occurs on a FOR, NEXT, WHILE, UNTIL, SELECT or CASE statement, control is transferred to the statement immediately following the corresponding NEXT or END SELECT statement. For example: July 1988 Statements and Functions 4-33 CONTINUE 10 WHEN ERROR IN A=10 B=1 20 FOR I=A TO B STEP 2 GET #1 30 40 C=1 NEXT I C=O 50 USE CONTINUE END WHEN If an error occurs on line 20, the CONTINUE statement transfers control to line 50. If an error occurs on line 30, program control resumes at line 40. 3. 4. The CONTINUE statement must be lexically inside of a handler. If you specify a CONTINUE statement within a detached handler, you cannot specify a target. Example WHEN ERROR USE err_handler END WHEN HANDLER err_handler SELECT ERR CASE = 50 PRINT "Insufficient data" CONTINUE CASE ELSE EXIT HANDLER END SELECT END HANDLER 4-34 Statements and Functions July 1988 cos cos The COS function returns the cosine of an angle in radians or degrees. Format real-var= COS (real-exp) Syntax Rules None. Remarks 1. 2. The returned value is between -1 and 1. This value is expressed in either radians or degrees depending on which angle clause you choose with the OPTION statement. VAX BASIC expects the argument of the COS function to be a real expression. When the argument is a real expression, VAX BASIC returns a value of the same floating-point size. When the argument is not a real expression, VAX BASIC converts the argument to the default floating-point size and returns a value of the default floating-point size. Example DECLARE SINGLE cos_value cos_value = 26 PRINT COS(cos_value) Output .646919 Statements and Functions 4-35 CTR LC CTR LC The CTRLC function enables CTRL/C trapping. When CTRL/C trapping is enabled, a CTRL/C typed at the terminal causes control to be transferred to the error handler currently in effect. Format int-var= CTR LC Syntax Rules None. Remarks 1. When VAX BASIC encounters a CTRL/C, control passes to the error handler currently in effect. If there is no error handler in a program, the program aborts. 2. In a series of linked subprograms, setting CTRL/C for one subprogram enables CTRL/C trapping for all subprograms. 3. When you trap a CTRL/C with an error handler, your program may be in an inconsistent state; therefore, you should handle the CTRL/C error and exit the program as quickly as possible. 4. CTRL/C trapping is asynchronous; that is, VAX BASIC suspends execution and signals "Programmable ~c trap" (ERR=28) as soon as it detects a CTRL/C. Consequently, a statement can be interrupted while it is executing. A statement so interrupted may be only partially executed and variables may be left in an undefined state. 5. VAX BASIC can trap more than one CTRL/C error in a program as long as the error does not occur while the error handler is executing. If a second CTRL/C is detected while the error handler is processing the first CTRL/C, the program aborts. 6. The CTRLC function always returns a value of zero. 4-36 Statements and Functions July 1988 CTR LC 7. The function RCTRLC disables CRTL/C trapping. See the description of the RCTRLC function for further details. July 1988 Statements and Functions 4-36.1 CTR LC Example WHEN ERROR USE repair_work Y% = CTRLC END WHEN HANDLER repair_work IF (ERR=28) THEN PRINT "Interrupted by CTRLC!" END HANDLER Statements and Functions 4-37 CVTSS CVTSS The CVT$$ function is a synonym for the EDIT$ function. See the EDIT$ function for more information. NOTE DIGITAL recommends that you use the EDIT$ function rather than the CVT$$ function for new program development. Format str-var = CVT$$ (str-exp, int-exp) 4-38 Statements and Functions CVTxx CVTxx The CVT$ % function maps the first two characters of a string into a 16-bit integer. The CVT%$ function translates a 16-bit integer into a 2character string. The CVT$F function maps a 4- or 8-character string into a floating-point variable. The CVTF$ function translates a floating-point number into a 4- or 8-byte character string. The number of characters translated depends on whether the floating-point variable is single- or double-precision. NOTE CVT functions are supported only for compatibility with BASIC-PLUS. DIGITAL recommends that you use VAX BASIC's dynamic mapping feature or multiple MAP statements for new program development. Format int-var= CVT$% (str-var) real-var= CVT$F (str-var) str-var = CVT%$ (int-var) str-var = CVTF$ (real-var) Syntax Rules CVT functions reverse the order of the bytes when moving them to or from a string. Therefore, you can mix MAP and MOVE statements, but you cannot use FIELD and CVT functions on a file if you also plan to use MAP or MOVE statements. Statements and Functions 4-39 CVTxx Remarks 1. CVT$% • • • 2. • • CVT$F maps 4 characters when the program is compiled with /SINGLE and eight characters when the program is compiled with /DOUBLE. If str-var has fewer than four or eight characters, VAX BASIC pads the string with nulls. The real-var returned by the CVT$F function is the default floating-point size. If the default size is GFLOAT or HFLOAT, VAX BASIC signals the error "Floating CVT illegal for GFLOAT or HFLOAT". CVTF$ • • 4-40 Only two bytes of data are inserted into str-var. If you specify a floating-point variable for int-var, VAX BASIC truncates it to an integer of the default size. If the default size is BYTE and the value of int-var exceeds 127, VAX BASIC signals an error. CVT$F • 4. The value returned by the CVT$% function is an integer of the default size. CVT%$ • • 3. If the CVT$% str-var has fewer than two characters, VAX BASIC pads the string with nulls. If the default data type is LONG, only two bytes of data are extracted from str-var; the high-order byte is sign-extended into a longword. The CVTF$ function maps single-precision numbers to a 4character string and double-precision numbers to an 8-character string. VAX BASIC expects the argument of the CVTF$ function to be a real expression. When the argument is a real expression, VAX BASIC returns a value of the same floating-point size~ When the argument is not a real expression, VAX BASIC converts the argument to the default floating-point size and returns a value of the default floating-point size. If the default floating-point size is GFLOAT or HFLOAT, VAX BASIC signals the error "Floating CVT illegal for GFLOAT or HFLOAT". Statements and Functions CVTxx Examples Example 1 DECLARE STRING test_string, another_string DECLARE LONG first_number, next_number test_string = "AT" PRINT CVT$%(test_string) another_string = "at" PRINT CVT$%(another_string) first_number = 16724 PRINT CVT%$(first_number) next_number = 24948 PRINT CVT%$(next_number) END Output 1 16724 24948 AT at Example 2 DECLARE STRING test_string, another_string DECLARE SINGLE first_num, second_num test_string = "DESK" first_num = CVT$F(test_string) PRINT first_num another_string = "desk" second_num = CVT$F(another_string) PRINT second_num PRINT CVTF$(first_num) PRINT CVTF$(second_num) END Output 2 .218256E+12 .466242E+31 DESK desk Statements and Functions 4-41 DATA DATA The DATA statement creates a data block for the READ statement. Format DATA num-lit ] str-lit ,... [ unq-str Syntax Rules 1. 2. 3. 4. Num-lit specifies a numeric literal. Str-lit is a character string that starts and ends with double or single quotation marks. The quotation marks must match. Unq-str is a character sequence that does not start or end with double quotation marks and does not contain a comma. Commas separate data elements. If a comma is part of a data item, the entire item must be enclosed in quotation marks. Remarks 1. 2. 3. 4. 4-42 Because VAX BASIC treats comment fields in DATA statements as part of the DATA sequence, you should not include comments. A DATA statement must be the last or the only statement on a physical line. DATA statements must end with a line terminator. When a DATA statement is continued with an ampersand ( & ), VAX BASIC interprets all characters between the keyword DATA and the ampersand as part of the data. Any code that appears on a noncontinued line is considered a new statement. Statements and Functions DATA 5. You cannot use the percent sign suffix for integer constants that appear in DATA statements. An attempt to do so causes VAX BASIC to signal the error, "Data format error" (ERR=SO). 6. DATA statements are local to a program module. 7. VAX BASIC does not execute DATA statements. Instead, control is passed to the next executable statement. 8. A program can have more than one DATA statement. VAX BASIC assembles data from all DATA statements in a single program unit into a lexically ordered single data block. 9. VAX BASIC ignores leading and trailing blanks and tabs unless they are in a string literal. 10. Commas are the only valid data delimiters. You must use a quoted string literal if a comma is to be part of a string. 11. VAX BASIC ignores DATA statements without an accompanying READ statement. 12. VAX BASIC signals the error "Data format error" if the DATA item does not match the data type of the variable specified in the READ statement or if a data element that is to be read into an integer variable ends with a percent sign ( % ). If a string data element ends with a dollar sign ( $ ), VAX BASIC treats the dollar sign as part of the string. Example 10 DECLARE INTEGER A,B,C READ A,B,C DATA 1,2,3 PRINT A + B + C Output 6 Statements and Functions 4-43 DATES DATES The DATE$ function returns a string containing a day, month, and year in the form dd-Mmm-yy. Format str-var =DATE$ (int-exp) Syntax Rules Int-exp can have up to six digits in the form yyyddd, where the characters yyy specify the number of years since 1970 and the characters ddd specify the day of that year. 2. You must fill all three of the d positions with digits or zeros before you can fill the y positions. For example: • DATE$(121) returns the date Ol-May-70, day 121 of the year 1970. • DATE$(1201) returns the date 20-Jul-71, day 201 of the year 1971. • DATE$(12001) returns the date Ol-Jan-82, day one of the year 1982. • DATE$(10202) returns the date 21-Jul-80, day 202 of the year 1980. 1. 4-44 Statements and Functions DATES Remarks 1. 2. 3. 4. If int-exp equals zero, DATE$ returns the current date. The str-var returned by the DATE$ function consists of nine characters and expresses the day, month, and year in the form dd-Mmm-yy. If you specify an invalid date, such as day 385, results are unpredictable. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to an integer of the default size. Example DECLARE STRING todays_date todays_date = DATE$(0) PRINT todays_date Output 26-Aug-86 Statements and Functions 4-45 DECIMAL DECIMAL The DECIMAL function converts a numeric expression or numeric string to the DECIMAL data type. Format decimal-var= DECIMAL (exp[, int-const1, int-const2]) Syntax Rules 1. Int-const1 specifies the total number of digits (the precision) and intconst2 specifies the number of digits to the right of the decimal point (the scale). If you do not specify these values, VAX BASIC uses the d (digits) and s (scale) defaults for the DECIMAL data type. 2. Int-const1 and int-const2 must be positive integers from 1 through 31. Int-const2 cannot exceed the value of int-const1. 3. Exp can be either numeric or numeric string. If a numeric string, it can contain the ASCII digits 0 through 9, uppercase E, a plus sign ( + ), a minus sign ( - ), and a period (. ). Remarks 4-46 1. If exp is a string, VAX BASIC ignores leading and trailing spaces and 2. tabs. The DECIMAL function returns a zero when a string argument contains only spaces and tabs, or when it is null. Statements and Functions DECIMAL Example DECLARE STRING CONSTANT format_string = "##.###" DECLARE STRING num_value, DECIMAL(6,3) B INPUT "Enter a numeric value";num_value B = DECIMAL(num_value,6,3) PRINT USING format_string, B Output Enter a numeric value? 6 6.000 Statements and Functions 4-4 7 DECLARE DECLARE The DECLARE statement explicitly assigns a name and a data type to a variable, an entire array, a function, or a constant. Format Variables DECLARE data-type { decl-item [,[data-type] decl-item }), ... DEF Functions DECLARE data-type FUNCTION {def-name [ ( [ def-param ], ... ) ] ), ... Named Constants DECLARE data-type CONSTANT {canst-name= canst-exp), ... decl-item: array-name ( [ int-const1 TO] int-const2, ... ) } record-var { unsubs-var def-param: data-type Syntax Rules Data-type can be any VAX BASIC data type keyword or a data type defined by a RECORD statement. Data type keywords, size, range, and precision are listed in Table 1-2 in this manual. 2. Variables • Deel-item names an array, a record, or a variable. • A decl-item named in a DECLARE statement cannot be named in another DECLARE statement, or in a DEF, EXTERNAL, FUNCTION, SUB, COMMON, MAP, DIM, HANDLER, or PICTURE statement. 1. 4-48 Statements and Functions DECLARE Each decl-item is associated with the preceding data type. A data type is required for the first decl-item. • Deel-items of data type STRING are dynamic strings. • When you declare an array, VAX BASIC allows you to specify both lower and upper bounds for each dimension of the array. The upper bound is required; the lower bound is optional. lnt-const1 specifies the lower bounds of the array. Int-const2 specifies the upper bounds of the array and, when accompanied by int-const1, must be preceded by the keyword TO. Int-constl must be less than or equal to int-const2. If you do not specify int-const1, VAX BASIC uses zero as the default lower bound. Int-const1 and int-const2 can be any combination of negative or positive values or zero. 3. DEF Functions • Def-name names the DEF function. • Data-type specifies the data type of the value the function returns. • Def-params specify the number and, optionally, the data type of the DEF parameters. Parameters define the arguments the DEF expects to receive when invoked. When you specify a data type, all following parameters are of that data type until you specify a new data type. If you do not specify any data type, parameters take the current default data type and size. The number of parameters equals the number of commas plus 1. For example, empty parentheses specify one parameter of the default type and size; one comma inside the parentheses specifies two parameters of the default type and size; and so on. One data type inside the parentheses specifies one parameter of the specified data type; two data types separated by one comma specifies two parameters of the specified type, and so on. • Statements and Functions 4-49 DECLARE 4. Named Constants • Const-name is the name you assign to the constant. • Data-type specifies the data type of the constant. The value of the canst must be numeric if the data type is numeric and string if the data type is STRING. If the data type is STRING, canst must be a quoted string or another string constant. • Const-exp cannot be of the RFA data type. • String constants cannot exceed 498 characters. • VAX BASIC allows canst-exp to be an expression for all data types except DECIMAL. Expressions are not allowed as values when you name DECIMAL constants. • Allowable operators in DECLARE CONSTANT expressions include all valid arithmetic, relational, and logical operators except exponentiation. Built-in functions cannot be used in DECLARE CONSTANT expressions. The following examples use valid expressions as values: DECLARE DOUBLE CONSTANT max_value = (PI/2) DECLARE STRING CONSTANT left_arrow = "<-----" + LF + CR Remarks 1. 2. The DECLARE statement is not executable. The DECLARE statement must lexically precede any reference to the variables, functions, or constants named in it. 3. To declare a virtual or run-time array, use the DIMENSION statement. 4. Variables • Subsequent decl-items are associated with the specified data type until you specify another data type. • All variables named in a DECLARE statement are initialized to zero if numeric or to the null string if string. 5. DEF Functions • The DECLARE FUNCTION statement allows you to name a function defined in a DEF or DEF• statement, specify the data type of the value the function returns, and declare the number and data type of the DEF parameters. • Data type keywords must be separated by commas. 4-50 Statements and Functions DECLARE • The first specification of a data type for a def-param is the default for subsequent arguments until you specify another def-param. For example: DECLARE DOUBLE FUNCTION interest(DOUBLE,SINGLE,,) This example declares two parameters of the default type and size, one DOUBLE parameter, and three SINGLE parameters for the function named interest. 6. Named Constants • The DECLARE CONSTANT statement allows you to name a constant value and assign a data type to that value. Note that you can specify only one data type in a DECLARE CONSTANT statement. To declare a constant of another data type, you must use a second DECLARE CONSTANT statement. • During program execution, you cannot change the value assigned to the constant. • The specified data-type determines the data type of the constant. For example: DECLARE LONG CONSTANT True = -1, False = 0 DECLARE REAL CONSTANT ZZZ = 123.0 DECLARE BYTE CONSTANT YYY = '123'L PRINT True, False, ZZZ, YYY Output -1 0 123 123 In this example, VAX BASIC truncates the LONG value assigned to YYY to a BYTE variable. NOTE Data types specified in a DECLARE statement override any defaults specified in COMPILE command qualifiers or OPTION statements. Statements and Functions 4-51 DECLARE Examples Example 1 !DEF Functions DECLARE INTEGER FUNCTION amount(,,DOUBLE,BYTE,,) Example 2 !Named Constants DECLARE DOUBLE CONSTANT interest_rate = 15.22 4-52 Statements and Functions DEF DEF The DEF statement lets you define a single- or multi-line function. Format Single-line DEF DEF [data-type] def-name [ ( [data-type] var, ... ) ] =exp Multi-Line DEF DEF [data-type] def-name [ ( [data-type var], ... ) ] [statement]... [ statement ] ... END DEF } { FNEND [exp] Syntax Rules Data-type can be any VAX 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 in this manual. 2. The data type that precedes the def-name specifies the data type of the value returned by the DEF function. 3. Def-name is the name of the DEF function. The def-name can contain from 1 to 31 characters. 4. If the def-name also appears in a DECLARE FUNCTION statement, the following rules apply: • A function data type is required. • The first character of the def-name must be an alphabetic character (A through Z). The remaining characters can be any combination of letters, digits (0 through 9), dollar signs ( $ ), underscores (- ), or periods (. ). 1. Statements and Functions 4-53 DEF 5. If the def-name does not appear in a DECLARE FUNCTION statement, but the DEF statement appears before the first reference to the de/name, the following rules apply: • The function data type is optional. • The first character of the def-name must be an alphabetic letter (A through Z). The remaining characters can be any combination of letters, digits, dollar signs, underscores, or periods. • If a function data type is not specified, the last character in the def-name must be a percent sign for an INTEGER function, or a dollar sign for a STRING function. 6. If the def-name does not appear in a DECLARE FUNCTION statement, and the DEF statement appears after the first reference to the def-name, the following rules apply: • The function data type cannot be present. • The first two characters of the def-name must be FN. The remaining characters can be any combination of letters, digits, dollar signs, underscores, or periods, with one restriction: the last character must be a percent sign for an INTEGER function, or a dollar sign for a STRING function. • There must be at least one character between the FN characters and the ending dollar sign or percent character. FN$ and FN% are not valid function names. 7. Var specifies optional formal DEF parameters. Because the parameters are local to the DEF function, any reference to these variables outside the DEF body creates a different variable. 8. You can specify the data type of DEF parameters with a data type keyword or with a data type defined in a RECORD statement. If you do not include a data type, the parameters are of the default type and size. Parameters that follow a data type keyword are of the specified type and size until you specify another data type. 9. You can specify up to 255 parameters in a DEF statement. 10. Single-Line DEF Exp specifies the operations the function performs. 11. Multi-Line DEF • Statements specifies the operations the function performs. • The END DEF or FNEND statement is required to end a multi-line DEF. 4-54 Statements and Functions DEF • • VAX BASIC does not allow you to specify any statements that indicate the beginning or end of any SUB, FUNCTION, PICTURE, HANDLER (attached handlers are legal), PROGRAM or DEF in a function definition. Exp specifies the function result. Exp must be compatible with the DEF data type. Remarks 1. When VAX BASIC encounters a DEF statement, control of the program passes to the next executable statement after the DEF. 2. The function is invoked when you use the function name in an expression. 3. You cannot specify how parameters are passed. When you invoke a function, VAX BASIC evaluates parameters from left to right and passes parameters to the function so that they cannot be modified. Numeric parameters are passed by value and string parameters are passed by descriptor, where the descriptor points to a local copy. DEF functions can reference variables in the main program, but they cannot reference variables in other DEF or DEF* functions. A DEF function can, therefore, modify other variables in the program, but not variables within another DEF function. 4. A DEF function is local to the program, subprogram, function, or picture that defines it. 5. You can declare a DEF either by defining it, by using the DECLARE FUNCTION statement, or by implicitly declaring it with a reference to the function in an expression. 6. If your program invokes a function with a name that does not start with FN before the DEF statement defines the function, VAX BASIC signals an error. 7. If the number of parameters, types of parameters, or type of result declared in the invocation disagree with the number or types of parameters defined in the DEF statement, VAX BASIC signals an error. 8. DATA statements in a multi-line DEF are not local to the function; they are local to the program module containing the function definition. 9. The function value is initialized to zero or the null string each time you invoke the function. Statements and. Functions 4-55 DEF 10. You can invoke a DEF function within an attached or detached handler. 11. DEF definitions cannot appear inside a protected region. However, a DEF can contain one or more protected regions. 12. In DEF definitions that contain handlers, the following rules apply: • If the function was invoked from a protected region, the EXIT HANDLER statement transfers control to the handler specified for that protected region. • If the function was not invoked from a protected region, the EXIT HANDLER statement transfers control to the default error handler. 13. If an exception is not handled within a DEF function, control is transferred to the module that invoked the DEF function. 14. ON ERROR statements within a DEF function are local to the function. 15. A CONTINUE, GOTO, GOSUB, ON ERROR GOTO, or RESUME statement in a multi-line function definition must refer to a line number or label in the same function definition. 16. You cannot transfer control into a multi-line DEF except by invoking the function. 17. DEF functions can be recursive. Examples Example 1 !Single-Line DEF DEF DOUBLE add (DOUBLE A, B, SINGLE C, D, E) = A + B + C + D + E INPUT 'Enter five numbers to be added' ;V,W,X,Y,Z PRINT 'The sum is' ;ADD(V,W,X,Y,Z) Output 1 Enter five numbers to be added? 1,2,3,4,5 The sum is 15 4-56 Statements and Functions July 1988 DEF Example 2 PROGRAM I_want_a_raise OPTION TYPE= EXPLICIT, CONSTANT TYPE = DECIMAL, SIZE = DECIMAL (6,2) DECLARE DECIMAL CONSTANT Overtime_factor = 0.60 DECLARE DECIMAL My_hours, My_rate, Overtime DECLARE DECIMAL FUNCTION Calculate_pay (DECIMAL.DECIMAL) INPUT "Your hours this week";My_hours INPUT "Your hourly rate";My_rate PRINT "My pay this week is"; Calculate_pay ( My_hours, My_rate ) DEF DECIMAL Calculate_pay (DECIMAL Hours, Rate) IF Hours = 0.0 THEN EXIT DEF 0.0 END IF Overtime = Hours - 40.0 IF Overtime < 0.0 THEN Overtime = 0.0 END IF END DEF (Hours * Rate) + (Overtime * (Overtime_factor * Rate) ) END PROGRAM Output 2 Your hours this week? 45.7 Your pay rate? 20.35 Your pay for the week is 987.96 Statements and Functions 4-5 7 The DEF• statement lets you define a single- or multi-line function. NOTE The DEF• statement is not recommended for new program development. DIGITAL recommends that you use the DEF statement for defining single- and multi-line functions. Format Single-line DEF* DEF• [data-type] def-name [ ( [data-type] var, ... ) ] =exp Multi-Line DEF* DEF• [data-type] def-name [ ( [data-type] var, ... ) ] [statement]... [ statement ]. .. DEF } { END FNEND [ exp ] Syntax Rules Data-type can be any VAX 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 in this manual. 2. The data type that precedes the def-name specifies the data type of the value returned by the DEF• function. 3. Def-name is the name of the DEF• function. The def-name can contain from 1 to 31 characters. 4. If the def-name also appears in a DECLARE FUNCTION statement, the following rules apply: • A function data type is required. 1. 4-58 Statements and Functions The first character of the def-name must be an alphabetic character (A through Z). The remaining characters can be any combination of letters, digits (0 through 9), dollar signs ( $ ), underscores (- ), or periods (. ). 5. If the def-name does not appear in a DECLARE FUNCTION statement, but the DEF• statement appears before the first reference to the def-name, the following rules apply: • The function data type is optional. • The first character of the def-name must be an alphabetic character (A through Z). The remaining characters can be any combination of letters, digits, dollar signs, underscores, or periods. • If a function data type is not specified, the last character in the def-name must be a percent sign for an INTEGER function, or a dollar sign for a STRING function. 6. If the def-name does not appear in a DECLARE FUNCTION statement, and the DEF• statement appears after the first reference to the defname, the following rules apply: • The function data type cannot be present. • The first two characters of the def-name must be FN. The remaining characters can be any combination of letters, digits, dollar signs, underscores, or periods, with one restriction: the last character must be a percent sign for an INTEGER function, or a dollar sign for a STRING function. • There must be at least one character between the FN characters and the ending dollar sign or percent character. FN$ and FN% are not valid function names. 7. Var specifies optional formal function parameters. 8. You can specify the data type of function parameters with a data type keyword. If you do not specify a data type, parameters are of the default type and size. Parameters that follow a data type are of the specified type and size until you specify another data type. 9. You can specify up to 8 parameters in a DEF• statement. 10. Single-Line DEF• • Exp specifies the operations the function performs. 11. Multi-Line DEF• • Statements specifies the operations the function performs. • The END DEF or FNEND statement is required to end a multi-line DEF•. Statements and Functions 4-59 DEF* • • VAX BASIC does not allow you to specify any statements that indicate the beginning or end of any SUB, FUNCTION, PICTURE, HANDLER, PROGRAM or DEF in a function definition. Exp specifies the function result. Exp must be compatible with the DEF data type. Remarks 1. When VAX BASIC encounters a DEF• statement, control of the program passes to the next executable statement after the DEF•. 2. A function defined by the DEF• statement is invoked when you use the function name in an expression. 3. You cannot specify how parameters are passed. When you invoke a DEF• function, VAX BASIC evaluates parameters from left to right and passes parameters to the function so that they cannot be modified. Numeric parameters are passed by value, and string parameters are passed by descriptor, where the descriptor points to a local copy. DEF• functions can reference variables in the main program, but they cannot reference variables in other DEF or DEF• functions. A DEF• function can, therefore, modify variables in the program, but not variables within another DEF• function. 4. The following differences exist between DEF• and DEF statements: • You can use the GOTO, ON GOTO, GOSUB, and ON GOSUB statements to a branch outside a multi-line DEF•, but they are not recommended. • Although other variables used within the body of a DEF• function are not local to the DEF• function, DEF• formal parameters are. However, if you change the value of formal parameters within a DEF• function and then transfer control out of the DEF• function without executing the END DEF or FNEND statement, variables outside the DEF• that have the same names as DEF• formal parameters are also changed. • You can pass up to 255 parameters to a DEF function. DEF• functions accept a maximum of 8 parameters. • A DEF• function value is not initialized when the DEF• function is invoked. Therefore, if a DEF• function is invoked, and no new function value is assigned, the DEF• function returns the value of its previous invocation. 4-60 Statements and Functions DEF* • The error handler of the program module that contains the DEF* is the default error handler for a DEF* function. Parameters return to their original values when control passes to the error handler. 5. A DEF* is local to the program or subprogram that defines it. 6. You can declare a DEF* either by defining it, by using the DECLARE FUNCTION statement, or by implicitly declaring it with a reference to the function in an expression. 7. If the number of parameters, types of parameters, or type of result declared in the invocation disagree with the number or types of parameters defined in the DEF* statement, VAX BASIC signals an error. 8. DEF* functions can be recursive. 9. DATA statements in a multi-line DEF* are not local to the function; they are local to the program module containing the function definition. 10. You can invoke a DEF* function within an attached or detached handler. 11. DEF* definitions cannot appear inside a protected region, but they can contain one or more protected regions. 12. In DEF* functions that contain handlers, the following rules apply: • If the function was invoked from a protected region, the EXIT HANDLER statement transfers control to the handler specified for that protected region. • If the function was not invoked from a protected region, the EXIT HANDLER statement transfers control to the default error handler. Examples Example 1 !Single-Line DEF* DEF* STRING CONCAT(STRING A,B) = A + B DECLARE STRING word1,word2 INPUT "Enter two words";word1,word2 PRINT CONCAT (word1,word2) July 1988 Statements and Functions 4-61 DEF* Output 1 Enter two words? TO ? DAY TODAY Example 2 !Multi-Line DEF* DEF* DOUBLE example(DOUBLE A, B, SINGLE C, D, E) EXIT DEF IF B = 0 example = (A/B) + C - (D*E) END DEF INPUT "Enter 5 numbers";V,W,X,Y,Z PRINT example(V,W,X,Y,Z) Output 2 Enter 5 numbers? 2,4,6,8,1 -1. 5 4-62 Statements and Functions DELETE DELETE The DELETE statement removes a record from a relative or indexed file. Format DELETE #chnl-exp Syntax Rules Chnl-exp is a numeric expression that specifies a channel number associated with a file. It must be immediately preceded by a number sign (# ). Remarks The DELETE statement removes the current record from a file. Once the record is removed, you cannot access it. 2. The file specified by chnl-exp must have been opened with ACCESS MODIFY or WRITE. 3. You can delete a record only if the last 1/0 statement executed on the specified channel was a successful GET or FIND operation. 4. The DELETE statement leaves the current record pointer undefined and the next record pointer unchanged. 5. VAX BASIC signals an error when the 1/0 channel is illegal or not open, when no current record exists, when access is illegal or illogical, or when the operation is illegal. 1. Statements and Functions 4-63 DELETE Example DECLARE STRING record_num OPEN "COS.DAT" FOR INPUT AS #1, RELATIVE FIXED ACCESS MODIFY, RECORDSIZE 40 INPUT "WHICH RECORD WOULD YOU LIKE TO EXAMINE";record_num GET #1, RECORD record_num DELETE #1 Here, CVS.DAT is opened for input with ACCESS MODIFY. Once you enter the number of the record you want to retrieve and the GET statement executes successfully, the current record number is deleted. 4-64 Statements and Functions DET DEY The DET function returns the value of the determinant of the last matrix inverted with the MAT INV function. Format real-var = DET Syntax Rules None. Remarks 1. 2. 3. When a matrix is inverted with the MAT INV statement, VAX BASIC calculates the determinant as a by-product of the inversion process. The DET function retrieves this value. If your program does not contain a MAT INV statement, the DET function returns a value of zero. The value returned by the DET function is a floating-point value of the default size. Statements and Functions 4-65 DET Example MAT INPUT first_array(3,3) MAT PRINT first_array; PRINT MAT inv_array = INV (first_array) determinant = DET MAT PRINT inv_array; PRINT PRINT determinant PRINT MAT mult_array = first_array * inv_array MAT PRINT mult_array; Output ? 1.0.0.0.1.0.0.0.1 1 0 0 0 1 0 0 0 1 1 0 0 0 1 0 0 0 1 1 1 0 0 0 1 0 0 0 1 4-66 Statements and Functions DIFS DIFS The DIF$ function returns a numeric string whose value is the difference between two numeric strings. Format str-var = DIFS (str-exp 1, str-exp2) Syntax Rules Each str-exp can contain up to 54 ASCII digits, an optional decimal point, and an optional leading sign. Remarks 1. VAX BASIC subtracts str-exp2 from str-exp1 and stores the result in str-var. 2. The difference between two integers takes the precision of the larger integer. 3. The difference between two decimal fractions takes the precision of the more precise fraction, unless trailing zeros generate that precision. 4. The difference between two floating-point numbers takes precision as follows: • The difference of the integer parts takes the precision of the larger part. • The difference of the decimal fraction part takes the precision of the more precise part. 5. VAX BASIC truncates leading and trailing zeros. Statements and Functions 4-67 DIFS Example PRINT DIF$ ("689","-231") Output 920 4-68 Statements and Functions DIMENSION DIMENSION The DIMENSION statement creates and names a static, dynamic, or virtual array. The array subscripts determine the dimensions and the size of the array. You can specify the data type of the array and associate the array with an I/O channel. Format Nonvirtual, Nonexecutable { ~:=ENSION } {[data-type] array-name ( [ int-const1 TO} int-canst2, ... ), ... ) Executable { ~:=ENSION } {[ data-type ] array-name ( [ int-var1 TO ] int-var2, ... ) ), ... Virtual { ~:=ENSION } #chnl-exp, { [ data-type ] array-name (int-canst, ... ) [=int-canst]), ... Syntax Rules 1. 2. An array name in a DIM statement cannot also appear in a COMMON, MAP, or DECLARE statement. Data-type can be any VAX BASIC data type keyword or a data type defined in a RECORD statement. Data type keywords, size, range, and precision are listed in Table 1-2 in this manual. Statements and Functions 4-69 DIMENSION If you do specify a data type and the array name ends in a percent sign ( % ) or dollar sign ( $) suffix character, the variable must be a string or integer data type. 4. If you do not specify a data type, the array name determines the type of data the array holds. If the array name ends in a percent sign, the array stores integer data of the default integer size. If the array name ends in a dollar sign, the array stores string data. Otherwise, the array stores data of the default type and size. 5. An array can have up to 32 dimensions. Nonvirtual array sizes are limited by the virtual memory limits of your system. 6. When you declare a nonvirtual array, VAX BASIC allows you to specify both lower and upper bounds. The upper bound is required; the lower bound is optional. • Int-constl or int-varl specifies the lower bounds of the array. • Int-const2 or int-var2 specifies the upper bounds of the array and, when accompanied by int-constl or int-varl, must be preceded by the keyword TO. • Int-constl must be less than or equal to int-const2. Int-varl must be less than or equal to int-var2. • If you do not specify int-constl or int-varl, VAX BASIC uses zero as the default lower bound. • Array dimensions can have either positive or negative values. 7. Nonvirtual, Nonexecutable • When all the dimension specifications are integer constants, as in DIM A(lS,10,20), the DIM statement is nonexecutable and the array size is static. A static array cannot appear in another DIM statement because VAX BASIC determines storage requirements at compilation time. • A nonexecutable DIM statement must lexically precede any reference to the array it dimensions. That is, you must dimension a static array before you can reference array elements. 8. Virtual • The virtual array must be dimensioned and the file must be open before you can reference the array. 3. 4-70 Statements and Functions DIMENSION • When the data type is STRING, the =int-canst clause specifies the length of each array element. The default string length is 16 characters. Virtual string array lengths are rounded to the next higher power of 2. Therefore, specifying an element length of 12 results in an actual length of 16. For example: DIM #1, STRING vir_array(100) = 12 OPEN "STATS.BAS" FOR OUTPUT as #1, VIRTUAL Output Y.BASIC-W-STRLENINC, virtual array string VIR_ARRAY length increased from 12 to 16 9. Executable When any of the dimension specifications are integer variables as in DIM A(10%,20%,Y%), the DIM statement is executable and the array is dynamic. A dynamic array can be redimensioned with a DIM statement any number of times because VAX BASIC allocates storage at run time when each DIM statement is executed. Remarks You can create an array implicitly by referencing an array element without using a DIM statement. This causes VAX BASIC to create an array with dimensions of ( 10 ), (10, 10), (10, 10, 10), and so on, depending on the number of bounds specifications in the referenced array element. You cannot create virtual or executable arrays implicitly. 2. VAX BASIC allocates storage for arrays by row, from right to left. 3. Nonvirtual, Nonexecutable • You can declare arrays with the COMMON, MAP, and DECLARE statements. Arrays so declared cannot be redimensioned with the DIM statement. Furthermore, string arrays declared with a COMMON or MAP statement are always fixed-length. • If you reference an array element declared in an array whose subscripts are smaller than the lower bound or larger than the upper bound specified in the DIM statement, VAX BASIC signals the error "Subscript out of range" (ERR=55). 1. Statements and Functions 4-71 DIMENSION 4. Virtual • For new development, DIGITAL does not recommend virtual arrays. • When the rightmost subscript varies faster than the subscripts to the left, fewer disk accesses are necessary to access array elements in virtual arrays. • Using the same DIM statement for multiple virtual arrays allocates all arrays in a single disk file. The arrays are stored in the order they were declared. • Any program or subprogram can access a virtual array by declaring it in a virtual DIMENSION statement. For example: DIM #1, A(10) DIM #1, B(10) In this example, array B overlays array A. You must specify the same channel number, data types, and limits in the same order as they occur in the DIM statement that created the virtual array. • VAX BASIC stores a string in a virtual array by padding it with trailing nulls to the length of the array element. It removes these nulls when it retrieves the string from the virtual array. Remember that string array element sizes are always rounded to the next power of 2. • The OPEN statement for a virtual array must include the ORGANIZATION VIRTUAL clause for the channel specified in the DIMENSION statement. • VAX BASIC does not initialize virtual arrays and treats them as statically allocated arrays. You cannot redimension virtual arrays. • Refer to the VAX BASIC User Manual for more information on virtual arrays. 5. Executable • You create an executable, dynamic array by using integer variables for array bounds, as in DIM A(Y%,X%). This eliminates the need to dimension an array to its largest possible size. Array bounds in an executable DIM statement can be constants or variables, but not expressions. At least one bound must be a variable. • You cannot reference an array named in an executable DIM statement until after the DIM statement executes. 4-72 Statements and Functions DIMENSION • • • • You can redimension a dynamic array to make the bounds of each dimension larger or smaller, but you cannot change the number of dimensions. For example, you cannot redimension a four-dimensional array to be a five-dimensional array. The executable DIM statement cannot be used to dimension virtual arrays, arrays received as formal parameters, or arrays declared in COMMON, MAP, or nonexecutable DIM statements. An executable DIM statement always reinitializes the array to zero (for numeric arrays) or to the null string if string. If you reference an array element declared in an executable DIM statement whose subscripts are not within the bounds specified in the last execution of the DIM, VAX BASIC signals the error "Subscript out of range" (ERR=SS). Examples Example 1 !Nonvirtual, Nonexecutable DIM STRING name_list(20 TO 100), BYTE age(100) Example 2 !Virtual DIM 11%, STRING name_list(500), REAL amount(10,10) Example 3 !Executable DIM DOUBLE inventory(base,markup) DIM DOUBLE inventory (new_base,new_markup) Statements and Functions 4-73 ECHO ECHO The ECHO function causes characters to be echoed at a terminal that is opened on a specified channel. Format int-var= ECHO (chnl-exp) Syntax Rules Chnl-exp must specify a terminal. Remarks 1. The ECHO function is the complement of the NOECHO function; each function disables the effect of the other. 2. The ECHO function has no effect on an unopened channel. 3. The ECHO function always returns a value of zero. Example DECLARE INTEGER Y, STRING pass_word Y = NOECHO(OY.) SET NO PROMPT INPUT "Enter your password: ";pass_word Y = ECHO ( OY.) IF pass_word = "Darlene" THEN PRINT CR+LF+"YOU ARE CORRECT !" END IF 4-74 Statements and Functions ECHO Output Enter your password? YOU ARE CORRECT ! Statements and Functions 4-75 EDITS EDITS The EDIT$ function performs one or more string editing functions, depending on the value of its integer argument. Format str-var =EDIT$ (str-exp, int-exp) Syntax Rules None. Remarks 1. 2. 3. 4. VAX BASIC edits str-exp to produce str-var. The editing that VAX BASIC performs depends on the value of int-exp. Table 4-3 describes EDIT$ values and functions. All values are additive; for example, you can perform the editing functions of values 8, 16, and 32 by specifying a value of 56. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to an integer of the default size. Table 4-3: 4-76 EDIT$ Values Value Edit Performed 1 Discards each character's parity bit (bit 7) 2 Discards all spaces and tabs 4 Discards all carriage returns <CR> , line feeds <LF> , form feeds <FF> , deletes <DEL> , escapes <ESC> , and nulls <NUL> 8 Discards leading spaces and tabs Statements and Functions EDITS Table 4-3 (Cont.): EDIT$ Values Value Edit Performed 16 Converts multiple spaces and tabs to a single space 32 Converts lowercase letters to uppercase letters 64 Converts left bracket ( [) to left parenthesis [(] and right bracket (]) to right parenthesis [)] 128 Discards trailing spaces and tabs (same as TRM$ function) 256 Suppresses all editing for characters within quotation marks; if the string has only one quotation mark, VAX BASIC suppresses all editing for the characters following the quotation mark Example DECLARE STRING old_string, new_string old_string = "a value of 32 converts lowercase letters to uppercase" new_string = EDIT$(old_string,32) PRINT new_string Output A VALUE OF 32 CONVERTS LOWERCASE LETTERS TO UPPERCASE Statements and Functions 4-77 END END The END statement marks the physical and logical end of a main program, a program module, or a block of statements. Format END [block] DEF[ exp] FUNCTION[ exp] GROUP RECORD VARIANT IF block: HANDLER PICTURE PROGRAM[ int-exp] SELECT WHEN SUB Syntax Rules None. 4-78 Statements and Functions END Remarks 1. 2. 3. 4. 5. The END statement with no block keyword marks the end of a main program. The END or END PROGRAM statement must be the last statement on the last lexical line of the main program. The END statement followed by a block keyword marks the end of a program, a VAX BASIC SUB, FUNCTION, or PICTURE subprogram, a DEF, an IF, a HANDLER, a PROGRAM, a SELECT statement block or a WHEN block. END RECORD, END GROUP, and END VARIANT mark the end of a RECORD statement, or a GROUP component or VARIANT component of a RECORD statement. END DEF and END FUNCTION • When VAX BASIC executes an END DEF or an END FUNCTION statement, it returns the function value to the statement that invoked the function and releases all storage associated with the DEF or FUNCTION. • If you specify an optional expression with the END DEF or END FUNCTION statement, the expression must be compatible with the DEF or FUNCTION data type. The expression is the function result unless an EXIT DEF or EXIT FUNCTION statement is executed. This expression supersedes all function assignments. • The END DEF statement restores the error handler in effect when the DEF was invoked (this is not true of the DEF• statement). • The END FUNCTION statement does not affect 1/0 operations or files. END HANDLER The END HANDLER statement causes VAX BASIC to transfer control to the statement following the WHEN block with the exception cleared. 6. END PROGRAM • The END PROGRAM statement allows you to end a program module. • An optional integer expression specifies the exit status of the program that is reported to DCL. This status is overridden by a status expression in an EXIT PROGRAM statement. • You can specify an END PROGRAM statement without a matching PROGRAM statement. Statements and Functions 4-79 END END WHEN • The END WHEN statement ends a WHEN block and transfers control to the statement following the WHEN block. • If the END WHEN statement ends an attached handler, control is transferred to the statement following the WHEN block with the exception cleared. 8. END SUB • The END SUB statement does not affect I/O operations or files. • The END SUB statement releases the storage allocated to local variables and returns control to the calling program. • The END SUB statement cannot be executed in an error handler unless the END SUB is in a subprogram called by the error handler of another routine. 9. When an END or END PROGRAM statement marking the end of a main program executes, VAX BASIC closes all files and releases all program storage. 10. If you use ON ERROR error handling, you must clear any errors with the RESUME statement before executing an END PROGRAM, END SUB, END FUNCTION or END PICTURE statement. 11. Except for the END PROGRAM statement, VAX BASIC signals an error when a program contains an END block statement with no corresponding and preceding block keyword. 7. Example 10 INPUT "Guess a number";AY. IF AY. = 24 THEN PRINT, "YOU GUESSED IT! " END IF 4-80 Statements and Functions END IF A'I. < 24 THEN PRINT, "BIGGER IS BETTER! " GOTO 10 END IF IF A'I. > 24 THEN PRINT, "SMALLER IS BETTER!" GOTO 10 END IF END PROGRAM Statements and Functions 4-81 ERL ERL The ERL function returns the number of the BASIC line where the last error occurred. Format int-var= ERL Syntax Rules The value of int-var returned by the ERL function is a LONG integer. Remarks 1. If the ERL function is used before an error occurs or after an error is handled, the results are undefined. 2. The ERL function overrides the /NOLINE qualifier. If a program compiled with the /NOLINE qualifier in effect contains an ERL function, VAX BASIC signals the message "ERL overrides NOLINE". 4-82 Statements and Functions ERL Example 10 DECLARE LONG int_exp WHEN ERROR USE error_routine 20 INPUT "Enter an integer expression";int_exp 30 PRINT DATE$(int_exp) END WHEN HANDLER error_routine IF ERL = 20 THEN PRINT "Invalid input ... try again 11 RETRY ELSE PRINT "UNEXPECTED ERROR" EXIT HANDLER END IF END HANDLER END PROGRAM Output Enter an integer expression? ABCD Error occurred on line 20 Enter an integer expression? 3211 30-Jul-73 Statements and Functions 4-83 ERNS ERNS The ERN$ function returns the name of the main program, subprogram, or DEF function that was executing when the last error occurred. Format str-var = ERN$ Syntax Rules None. Remarks 1. If the ERN$ function executes before an error occurs or after an error is handled, ERN$ returns a null string. 2. If you call a subprogram or function compiled with /NOSETUP or containing an OPTION INACTIVE=SETUP statement, the ERN$ function will not have a valid value if an exception occurs in the called procedure. Example 10 DECLARE LONG int_exp !This module's name is DATE WHEN ERROR IN INPUT "Enter an number";int_exp USE PRINT "Error in module ";ERN$ RETRY END WHEN PRINT Date$(int_exp) END 4-84 Statements and Functions ERNS Output Enter a number? ABCD Error in module DATE Enter a number? 0 21-May-86 Statements and Functions 4-85 ERR ERR The ERR function returns the error number of the current run-time error. Format int-var= ERR Syntax Rules The value of int-var returned by the ERR function is always a LONG integer. Remarks If the ERR function is used before an error occurs or after an error is handled, the results are undefined. Example 10 DECLARE LONG int_exp WHEN ERROR USE error_routine 20 INPUT "Enter an integer expression";int_exp PRINT DATE$(int_exp) END WHEN HANDLER error_routine: PRINT "Error num.ber";ERR IF ERR = 50 THEN PRINT "DATA FORMAT ERROR" ELSE PRINT "UNEXPECTED ERROR" END IF RETRY END HANDLER END 4-86 Statements and Functions ERR Output Enter an integer expression? ABCD Error number 60 DATA FORMAT ERROR Enter an integer expression? 0 03-Aug-86 Statements and Functions 4-87 ERTS ERTS The ERT$ function returns explanatory text associated with an error number. Format str-var = ERT$ (int-exp) Syntax Rules Int-exp is a VAX BASIC error number. The error number must be in the range 0 through 255. Remarks 1. 2. The ERT$ function can be used at any time to return the text associated with a specified error number. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to an integer of the default size. Example 10 DECLARE LONG int_exp WHEN ERROR USE error_routine 20 INPUT "Enter an integer expression";int_exp PRINT DATE$(int_exp) END WHEN HANDLER error_routine PRINT "Error number";ERR PRINT ERT$(ERR) RETRY END HANDLER END 4-88 Statements and Functions ERTS Output Enter an integer expression? ABCD Error number 60 Y.Data format error Enter an integer expression? 70 03-Feb-70 Statements and Functions 4-89 EXIT EXIT The EXIT statement lets you exit from a main program, a SUB, FUNCTION, or PICTURE subprogram, a multi-line DEF, a statement block, or a handler. Format EXIT block DEF[ exp] FUNCTION[ exp] SUB HANDLER PICTURE PROGRAM[ int-exp] label block: Syntax Rules The DEF, FUNCTION, SUB, HANDLER, and PROGRAM keywords specify the type of subprogram, multi-line DEF, or handler from which VAX BASIC is to exit. 2. If you specify an optional expression with the EXIT DEF statement or with the EXIT FUNCTION statement, the expression becomes the function result and supercedes any function assignment. It also overrides any expression specified on the END DEF or END FUNCTION statement. Note that the expression must be compatible with the FUNCTION or DEF data type. 3. Label specifies a statement label for an IF, SELECT, FOR, WHILE, or UNTIL statement block. 1. 4-90 Statements and Functions EXIT Remarks 1. 2. 3. 4. 5. 6. An EXIT SUB, EXIT FUNCTION, EXIT PROGRAM, EXIT DEF, or EXIT PICTURE statement is equivalent to an unconditional branch to an equivalent END statement. Control then passes to the statement that invoked the DEF or to the statement following the statement that called the subprogram. The EXIT HANDLER statement causes VAX BASIC to transfer control to a specified area. • If the current WHEN block is nested, control transfers to the handler associated with the next outer protected region. • If an ON ERROR statement is in effect and the current WHEN block is not nested, control transfers to the target of the ON ERROR statement. • If neither of the previous conditions is true, an EXIT HANDLER statement transfers control to the calling program or DCL. This action is the equivalent of the ON ERROR GO BACK statement. The EXIT PROGRAM statement causes VAX BASIC to exit from a main program module. • An optional integer expression on an EXIT PROGRAM statement specifies the exit status of the program that is reported to DCL. • The expression specified by an EXIT PROGRAM statement overrides any integer expression specified by an END PROGRAM statement. • VAX BASIC allows you to specify an EXIT PROGRAM statement without a matching PROGRAM statement. · The EXIT label statement is equivalent to an unconditional branch to the first statement following the end of the IF, SELECT, FOR, WHILE, or UNTIL statement labeled by the specified label. An EXIT FUNCTION, EXIT SUB or EXIT PROGRAM statement cannot be used within a multi-line DEF function. When the EXIT FUNCTION, EXIT SUB or EXIT PROGRAM statement executes, VAX BASIC releases all storage allocated to local variables and returns control to the calling program. Statements and Functions 4-91 EXIT Example DEF emp.bonus(A) IF A > 10 THEN PRINT "OUT OF RANGE" EXIT DEF 0 ELSE emp.bonus =A * 4 END IF END DEF INPUT A PRINT emp.bonus(A) END Output ? 11 OUT OF RANGE 0 4-92 Statements and Functions EXP EXP The EXP function returns the value of the mathematical constant e raised to a specified power. Format real-var= EXP (real-exp) Syntax Rules None. Remarks 1. 2. 3. The EXP function returns the value of e raised to the power of real-exp. VAX BASIC expects the argument of the EXP function to be a real expression. When the argument is a real expression, VAX BASIC returns a value of the same floating-point size. When the argument is not a real expression, VAX BASIC converts the argument to the default floating-point size and returns a value of the default floating-point size. When the default REAL size is SINGLE or DOUBLE, EXP allows arguments between -88 and 88. If the default REAL size is GFLOAT, EXP allows arguments between -709 and 709. If the default REAL size is HFLOAT, the arguments can be in the range -11356 to 11355. When the argument exceeds the upper limit of a range, VAX BASIC signals an error. When the argument exceeds the lower limit of a range, the EXP function returns a zero and VAX BASIC does not signal an error. Statements and Functions 4-93 EXP Example DECLARE SINGLE num_val num_val = EXP(4.6) PRINT num_val Output 99.4843 4-94 Statements and Functions EXTERNAL EXTERNAL The EXTERNAL statement declares constants, variables, functions, and subroutines external to your program. You can describe parameters for external functions and subroutines. Format External Constants EXTERNAL data-type CONSTANT const-name, ... External Variables EXTERNAL data-type unsubs-var, ... External Functions EXTERNAL data-type FUNCTION {tune-name [ pass-mech] [ ( external-param , ... ) ] ), ... External Subroutines EXTERNAL SUB {sub-name [ pass-mech] [ ( external-param ,... ) ] ), ... BY VALUE } BY REF { BY DESC pass-mech: external-param: [OPTIONAL] [ param-data-type] [DIM ( [,]. .. ) ] [=int-canst] [ pass-mech] External Pictures EXTERNAL PICTURE pie-name [ ( param-list)] Statements and Functions 4-95 EXTERNAL Syntax Rules For external constants, data-type can be BYTE, WORD, LONG, SINGLE, INTEGER (any size), or REAL (if the default size is SINGLE). 2. For external variables, the data type can be any valid numeric data type. 3. For external functions and subroutines, the data type can be BYTE, WORD, LONG, SINGLE, DOUBLE, GFLOAT, HFLOAT, DECIMAL, STRING, INTEGER, REAL, RFA, or a data type defined with the RECORD statement. See Table 1-2 in this manual for more information on data type size, range and precision. 4. The name of an external constant, variable, function, or subroutine can be from 1 through 31 characters. 5. For all external routine declarations, the name must be a valid VAX BASIC identifier and must not be the same as any other SUB, FUNCTION, PICTURE, or PROGRAM name. 6. Param-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. 7. Param-list is identical to external-param except that no OPTIONAL parameter is allowed. 8. Parameters in the param-list must agree in number and data type with the parameters in the invocation. Param-data-type includes ANY, BYTE, WORD, LONG, INTEGER, SINGLE, DOUBLE, GFLOAT, HFLOAT, READ, a user-defined RECORD type, STRING, or RFA. 1. For more information on external pictures, see Programming with VAX BASIC Graphics. 9. 4-96 External Functions and Subroutines • The data type that precedes the keyword FUNCTION defines the data type of the function result. • Pass-mech specifies how parameters are to be passed to the function or subroutine. A pass-mech clause outside the parentheses applies to all parameters. A pass-mech clause inside the parentheses overrides the previous pass-mech and applies only to the specific parameter. Statements and Functions EXTERNAL • External-param defines the form of the arguments passed to the external function or subprogram. Empty parentheses indicate that the subprogram expects zero parameters. Missing parentheses indicate that the 'EXTERNAL statement does not define parameters. 10. Using ANY as a VAX BASIC Data Type • The ANY data type should only be used for calling non-BASIC procedures. Therefore, the ANY data type is illegal in a PICTURE declaration. • If you specify ANY, VAX BASIC does not perform data type checking or conversions. If no passing mechanism is specified, VAX BASIC uses the default passing mechanism for the data type passed in a given invocation. • When you specify a data type, all following parameters that are not specifically declared default to the last specified data type. Similarly, when you specify ANY, all following unspecified parameters default to the data type ANY until a new declaration is provided. For example: EXTERNAL SUB allocate (LONG.ANY, 11. Passing Optional Parameters • The OPTIONAL keyword should be used only for calling nonBASIC procedures. • If you specify the keyword OPTIONAL, VAX BASIC treats all following parameters as optional. In the following example, the last three parameters are optional. EXTERNAL SUB queue(STRING, OPTIONAL STRING, LONG, ANY) • • • • When a procedure is called, the argument pointer (@AP) contains the number of actual parameters specified. VAX BASIC still performs type checking and conversion on optional parameters. If you want to omit an optional parameter that appears in the middle of a parameter list, VAX BASIC requires you to insert a comma placeholder. However, if you want to omit an optional parameter that appears at the end of a parameter list, you can omit that parameter without inserting any placeholder. You can specify the keyword OPTIONAL only once in any one parameter list. Statements and Functions 4-97 EXTERNAL 12. Declaring Array Dimensions The DIM keyword indicates that the parameter is an array. Commas specify array dimensions. The number of dimensions is equal to the number of commas plus 1. For example: EXTERNAL STRING FUNCTION new (DOUBLE, STRING DIM(,), DIM()) This statement declares a function named new that has three parameters. The first is a double-precision floating-point value, the second is a two-dimensional string array, and the third is a one-dimensional string array. The function returns a string result. Remarks 1. 2. 3. 4. 5. 6. 4-98 The EXTERNAL statement must precede any program reference to the constant, variable, function, subroutine or picture declared in the statement. The EXTERNAL statement is not executable. A name declared in an EXTERNAL CONSTANT statement can be used in any nondeclarative statement as if it were a constant. A name declared in an EXTERNAL FUNCTION statement can be used as a function invocation in an expression. In addition, you can invoke a function with the CALL statement unless the function data type is DECIMAL, HFLOAT, or STRING. A name declared in an EXTERNAL SUB statement can be used in a CALL statement. The optional pass-mech clauses in the EXTERNAL FUNCTION and EXTERNAL SUB statements tell VAX BASIC how to pass arguments to a non-BASIC function or subprogram. Table 4-1 describes VAX BASIC parameter-passing mechanisms. • BY VALUE specifies that VAX BASIC passes the argument's 32-bit value. • BY REF specifies that VAX BASIC passes the argument's address. This is the default for all arguments except strings and entire arrays. If you know the size of string parameters and the dimensions of array parameters, you can improve run-time performance by passing strings and arrays by reference. Statements and Functions EXTERNAL • 7. BY DESC specifies that VAX BASIC passes the address of a VAX BASIC descriptor. For information about the format of a VAX BASIC descriptor for strings and arrays, see Appendix C in this manual. If you do not specify the data type ANY or declare parameters as optional, the arguments passed to external functions and subroutines should match the external parameters declared in the EXTERNAL FUNCTION or EXTERNAL SUB statement in number, type, and passing mechanism. VAX BASIC forces arguments to be compatible with declared parameters. If they are not compatible, VAX BASIC signals an error. Examples Example 1 !External Constant EXTERNAL LONG CONSTANT SS$_NORMAL Example 2 !External Variable EXTERNAL WORD SYSNUM Example 3 !External Function EXTERNAL DOUBLE FUNCTION USR$2(WORD,LONG,ANY) Example 4 !External Subroutine EXTERNAL SUB calc BY DESC (STRING DIM(,). BYTE BY REF) Statements and Functions 4-99 FIELD FIELD The FIELD statement dynamically associates string variables with all or parts of a record buffer. FIELD statements do not move data. Instead, they permit direct access through string variables to sections of a specified record buffer. NOTE The FIELD statement is supported only for compatibility with BASIC-PLUS. Because data defined in the FIELD statement can be accessed only as string data, you must use the CVTxx functions to process numeric data; therefore, you must convert string data to numeric after you move it from the record buffer. Then, after processing, you must convert numeric data back to string data before transferring it to the record buffer. DIGITAL recommends that you use VAX BASIC's dynamic mapping feature or multiple maps instead of the FIELD statement and CVTxx functions. Format FIELD #chnl-exp, int-exp AS str-var[, int-exp AS str-var ]... Syntax Rules 1. Chnl-exp is a numeric expression that specifies a channel number 2. associated with a file. It must be immediately preceded by a number sign ( # ). A file must be open on the specified channel or VAX BASIC signals an error. Int-exp specifies the number of characters in str-var. However, a subsequent int-exp cannot depend on the return string from a previous int-exp. For example, the following statement is illegal because the second int-exp depends on the return string A$: FIELD #1%, 1% AS A$, ASCII(A$) AS B$ 4-100 Statements and Functions July 1988 FIELD Remarks 1. A FIELD statement is executable. You can change a buffer description at any time by executing another FIELD statement. For example: FIELD #1%, 40% AS whole_field$ FIELD #1%, 10% AS A$, 10% AS B$, 10% AS C$, 101. AS D$ 2. 3. 4. 5. The first FIELD statement associates the first 40 characters of a buffer with the variable whole-field$. The second FIELD statement associates the first 10 characters of the same buffer with A$, the second 10 characters with B$, and so on. Later program statements can refer to any of the variables named in the FIELD statements to access specific portions of the buffer. You cannot define virtual array strings as string variables in a FIELD statement. A variable named in a FIELD statement cannot be used in a COMMON or MAP statement, as a parameter in a CALL or SUB statement, or in a MOVE statement. Using the FIELD statement on a virtual file that contains a virtual array causes VAX BASIC to signal "Illegal or illogical access" (ERR=136). If you name an array in a FIELD statement, you cannot use MAT statements of the format MAT array-name1 = array-name2 MAT array-name1 = NUL$ where array-namel is named in the FIELD statement. An attempt to do so causes VAX BASIC to signal a compile-time error. Example FIELD #8%, 2% AS U$, 2% AS CL$, 4% AS X$, 4% AS Y$ LSET U$ = CVT%$(U%) LSET CL$ = CVTY.$(CL%) LSET X$ = CVTF$(X) LSET Y$ = CVTF$(Y) U"/. = CVT$% (U$) CU = CVT$% (CL$) X = CVT$F(X$) Y = CVT$F(Y$) Statements and Functions 4-1 01 FIND FIND The FIND statement locates a specified record in a disk file and makes it the current record for a GET, UPDATE, or DELETE operation. FIND statements are valid on RMS sequential, relative, and indexed files. Format FIND #chnl-exp [,position-clause][, lock-clause] position-clause: RFA rfa-exp } RECORD num-exp { KEY# key-clause lock-clause: { WAIT [int-exp] ALLOWallow-clause [,WAIT [int-exp 11 } REGARDLESS allow-clause: { =~:~ MODIFY key-clause: rel-op: int-exp 1 rel-op key-exp EQ GE NXEQ GT NX 4-102 Statements and Functions } FIND l int-exp2 str-exp decimal-exp quadword-exp key-exp: l Syntax Rules 1. 2. 3. 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, VAX BASIC signals an error. If you specify the REGARDLESS lock-clause, you cannot specify another lock-clause in the same FIND statement. Remarks 1. Position-clause • Position-clause specifies the position of a record in a file. VAX BASIC signals an error if you specify a position-clause and the channel is not associated with a disk file. If you do not specify a position-clause, FIND locates records sequentially. Sequential record access is valid on all files. • The RFA position-clause allows you to randomly locate records by specifying the record file address (RFA) of a record. You specify the disk address of a record, and RMS locates the record at that address. All file organizations can be accessed by RFA. Rfa-exp in the RFA position-clause is a variable of the RFA data type that specifies the record's file address. Note that an RFA expression can only be a variable of the RFA data type or the GETRFA function. Use the GETRFA function to find the RFA oLa record. Statements and Functions 4-103 FIND The RECORD position-clause allows you to randomly locate records in relative and sequential fixed files by specifying the record number. Num-exp in the RECORD position-clause specifies the number of the record you want to locate. 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 locate records in indexed files by specifying a key of reference, a relational test, and 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. 2. Lock-clause • • • • • • 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 FIND statement can override lock checking and locate a record locked by another program. When you specify a REGARDLESS lock-clause, VAX BASIC does not impose a lock on the retrieved record. The ALLOW lock-clause lets you control how a record is locked to other users and access streams. The file associated with the specified channel must have been opened with the UNLOCK EXPLICIT clause or VAX BASIC signals the error "Illegal record locking clause". 4-104 Statements and Functions July 1988 FIND • 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 GET REGARDLESS clause. ALLOW READ provides read access to the record. This means that other access streams can retrieve the record but cannot use the DELETE or UPDATE statements on the record. Statements and Functions 4-104.1 FIND • • ALLOW MODIFY provides read and write to the record. This means that other access streams can use the GET, FIND, DELETE, and UPDATE statements on the record. If you do not open a file with the ACCESS READ clause or specify an allow-clause, locking is imposed as follows: If the file associated with the specified channel was opened with UNLOCK EXPLICIT, VAX BASIC imposes the ALLOW NONE lock on the retrieved record and the next GET or FIND operation does not unlock the previously locked record. If the file associated with the specified channel was not opened with UNLOCK EXPLICIT, VAX 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 through 255 or VAX BASIC signals a warning message. 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, VAX BASIC signals the the runtime error "Keyboard wait exhausted" (ERR=15). VMSSTATUS and RMSSTATUS then return RMS$_TMO. For more information on the RMSSTATUS and VMSSTATUS functions, see this chapter and the VAX BASIC 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 VAX 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, VAX BASIC signals the error "Keyboard wait exhausted" (ERR=15) even though a deadlock condition may exist. Statements and Functions 4-105 FIND Key-clause • In a key-clause, int-exp1 is the target key of reference. It must be an integer in the range of zero through the highest-numbered key for the file. The primary key is #0, the first alternate key is #l, the second alternate key is #2, and so on. Int-exp1 must be preceded by a number sign (#)or VAX BASIC signals an error. • When you specify a key-clause, the specified channel must be a channel associated with an open indexed file. 4. Rel-op • Rel-op is a relational operator that 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 next" (a synonym for NXEQ) NX means "next" GT means "greater than" (a synonym for NX) • A successful random FIND operation by key locates the first record whose key satisfies the key-clause comparison: With an exact key match (EQ), a successful FIND locates the first record in the file that equals the key value specified in key-exp. However, if the characters specified by a str-exp key expression are less than the key length, characters specified by str-exp are matched approximately rather than exactly. For example, if you specify "ABC" and the key length is six characters, VAX BASIC locates the first record that begins with ABC. If you specify "ABCABC", VAX BASIC locates only a record with the key "ABCABC". If no match is possible, VAX BASIC signals the error "Record not found" (ERR=155). If you specify a next or equal to record key match (NXEQ), a successful FIND locates the next record that equals the key length specified in int-exp or str-exp. If no exact match exists, VAX BASIC locates 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 value. 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, since GE will retrieve the next record in the key sort order but 3. 4-106 Statements and Functions July 1988 FIND 5. 6. 7. 8. the next record will have a lesser key value. For this reason, DIGITAL recommends that you use NXEQ in new program development, especially if you are using descending key files. If you specify a next key match (NX), a successful FIND locates the first record that follows the relational operator in the sort order. If no such record exists, VAX BASIC signals the error "Record not found" (ERR=155). Key-exp • Int-exp2 specifies an integer value to be compared with the key value of a record. • Str-exp specifies a string value to be compared with the key value of a record. Str-exp can contain fewer characters than the key of the record you want to locate, but cannot be a null string. • 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 a record or group which is exactly 8 bytes long that is to be compared with the key value of a record. The file on the specified channel must have been opened with ACCESS MODIFY, ACCESS READ, or SCRATCH before your program can execute a FIND operation. FIND does not transfer any data to the record buffer. To access the contents of a record, use the GET statement. A successful sequential FIND operation updates both the current record pointers and next record pointers. • For sequential files, a successful FIND operation locates the 'next sequential record (the record pointed to by the next record pointer) in the file, changes the current record pointer to the record just found, and the next record pointer to the next sequential record. If the current record pointer points to the last record in a file, a sequential FIND operation causes VAX BASIC to signal "Record not found" (ERR=155). • For relative files, a successful FIND operation locates the record that exists with the next higher record number (or cell number), makes it the current record, and changes the next record pointer to the current record pointer plus 1. • For indexed files, a successful FIND operation locates the next existing logical record in the current key of reference, makes this the current record and changes the next record pointer to the current record pointer plus 1. Statements and Functions 4-107 FIND 9. A successful random access FIND operation by RFA or by record changes the current record pointer to the record specified by rfa-exp or int-exp, but leaves the next record pointer unchanged. 10. A successful random access FIND operation by key changes the current record pointer to the first record whose key satisfies the key-clause comparison and leaves the next record pointer unchanged. 11. When a random access FIND operation by RFA, record, or key is not successful, VAX BASIC signals "Record not found" (ERR=155). The values of the current record pointer and next record pointer are undefined. 12. You should not use a FIND statement on a terminal-format or virtual array file. Example DECLARE LONG rec-num MAP (cusrec) WORD cus_num & STRING cus_nam=20, cus_add=20, cus_city=10, cus_zip=9 OPEN 11 CUS_ACCT.DAT 11 FOR INPUT AS #1, & RELATIVE FIXED, & ACCESS MODIFY & MAP cusrec INPUT "Which record number would you like to delete";rec_num FIND #1, RECORD rec_num, WAIT DELETE #1 CLOSE #1 END 4-1 08 Statements and Functions July 1988 FIX FIX The FIX function truncates a floating-point value at the decimal point and returns the integer portion represented as a floating-point value. Format real-var= FIX (real-exp) Syntax Rules None. Remarks 1. 2. 3. The FIX function returns the integer portion of a floating-point value, not an integer value. VAX BASIC expects the argument of the FIX function to be a real expression. When the argument is a real expression, VAX BASIC returns a value of the same floating-point size. When the argument is not a real expression, VAX BASIC converts the argument to the default floating-point size and returns a value of the default floating-point size. If real-exp is negative, FIX returns the negative integer portion. For example, FIX(-5.2) returns -5. Statements and Functions 4-109 FIX Example DECLARE SINGLE result result = FIX(-3.333) PRINT FIX(24.666), result Output 24 4-11 0 Statements and Functions -3 FNEND FNEND The FNEND statement is a synonym for the END DEF statement. See the END statement for more information. Format FNEND [exp] Statements and Functions 4-111 FNEXIT FNEXIT The FNEXIT statement is a synonym for the EXIT DEF statement. See the EXIT statement for more information. Format FN EXIT 4-112 [ exp ] Statements and Functions FOR FOR 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. Format Unconditional FOR num-unsubs-var = num-exp1 TO num-exp2 [STEP num-exp3] [ statement ]. .. NEXT num-unsubs-var Conditional FOR num-unsubs-var = num-exp1 [STEP num-exp3] { ~~~~~ } cond-exp [ statement ]. .. NEXT num-unsubs-var Unconditional Statement Modifier statement FOR num-unsubs-var = num-exp 1TO num-exp2 [STEP num-exp3] Conditional Statement Modifier statement FOR num-unsubs-var = num-exp 1 [ STEP num-exp3] { ~~~~~ } cond-exp Statements and Functions 4-113 FOR Syntax Rules 1. 2. Num-unsubs-var must be a numeric, unsubscripted variable. Num-unsubs-var is the loop variable. It is incremented each time the loop executes. 3. In unconditional FOR loops, num-expl is the initial value of the loop variable; num-exp2 is the maximum value. 4. In conditional FOR loops, num-expl 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. 5. Num-exp3 in the STEP clause is the value by which the loop variable is incremented after each execution of the loop. Remarks 1. 2. 3. 4. 5. 6. 7. 8. 9. 4- 114 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, VAX BASIC signals an error message. An inner loop must be entirely within an outer loop; the loops cannot overlap. 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 function 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. VAX BASIC converts num-expl, num-exp2, and num-exp3 to the data type of the loop variable before storing them. When an unconditional FOR loop ends, the loop variable contains the value last used in the loop, not the value that caused loop termination. Statements and Functions FOR 10. During each iteration of a conditional loop, VAX 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), VAX 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), VAX BASIC exits from the loop. If the exp is false (value zero), the loop executes again. 11. When FOR is used as a statement modifier, VAX BASIC executes the statement until the loop variable equals or exceeds num-exp2 or until the WHILE or UNLESS condition is satisfied. 12. Each FOR statement must have a corresponding NEXT statement or VAX BASIC signals an error. (This is not the case if the FOR statement is used as a statement modifier.) Examples Example 1 !Unconditional DECLARE LONG course_num, STRING course_nam FOR I = 3 TO 12 STEP 3 INPUT "Course number";course_num INPUT "Course name";course_nam NEXT I Output 1 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 VAX BASIC Example 2 !Unconditional Statement Modifier DECLARE INTEGER counter PRINT "This is an unconditional statement modifier" FOR counter = 1 TO 3 END Statements and Functions 4-11 5 FOR Output 2 This is an unconditional statement modifier This is an unconditional statement modifier This is an unconditional statement modifier Example 3 !Conditional Statement Modifier DECLARE INTEGER counter, & STRING my_name INPUT "Try and guess my name";my_name FOR counter PRINT "You guessed it!" Output 3 Try and guess my name? VAX PASCAL Try and guess my name? VAX SCAN Try and guess my name? VAX BASIC You guessed it! 4...:116 Statements and Functions 1 UNTIL my_name "VAX BASIC" FORMATS FORMATS The FORMAT$ function converts an expression to a formatted string. Format str-var =FORMAT$ (exp, str-exp) Syntax Rules 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. Remarks DIGITAL recommends that you use compile-time constant expressions for string expressions whenever possible. When you do this, the VAX BASIC compiler compiles the string at compilation time rather than at run time, thus improving the performance of your code. Example DECLARE STRING result, t INTEGER num_exp num_exp = 12345 result = FORMAT$(num_exp, 11 ##,### 11 ) PRINT result Output 12,345 Statements and Functions 4-117 FREE FREE The FREE statement unlocks all records and buckets associated with a specified channel. Format FREE #chnl-exp Syntax Rules Chnl-exp is a numeric expression that specifies a channel number associated with a file. It must be immediately preceded by a number sign {# ). Remarks 1. The file specified by chnl-exp must be open. 2. You cannot use the FREE statement with files not on disk. 3. If there are no locked records or buckets on the specified channel, the FREE statement has no effect and VAX BASIC does not signal an error. 4. The FREE statement does not change record buffers or pointers. Moreover, the position of the record pointers is undefined. 5. After a FREE statement has executed, your program must execute a GET or FIND statement before a PUT, UPDATE, or DELETE statement can execute successfully. 4- 11 8 Statements and Functions FREE Example OPEN "CUST_ACCT.DAT" FOR INPUT AS #3 INPUT "Enter customer record number to retrieve";cust_rec_num FREE #3 GET #3 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. Statements and Functions 4-119 FSPS FSPS The FSP$ function returns a string describing an open file on a specified channel. Format str-var = FSP$ (chnl-exp) Syntax Rules 1. 2. A file must be open on chnl-exp. The FSP$ function must come immediately after the OPEN statement for the file. Remarks Use the FSP$ function with files opened as ORGANIZATION UNDEFINED. Then use multiple MAP statements to interpret the returned data. 2. See the VAX BASIC User Manual and the VAX Record Management Services Reference Manual for more information on FSP$ values. 1. NOTE VAX BASIC supports the FSP$ function for compatibility with BASIC-PLUS-2. DIGITAL recommends that you use a USEROPEN routine to identify file characteristics. 4-120 Statements and Functions FSPS Example 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= ";mm & & & Output 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 Statements and Functions 4-121 FUNCTION FUNCTION The FUNCTION statement marks the beginning of a FUNCTION subprogram and defines the subprogram's parameters. Format FUNCTION data-type tune-name [ pass-mech] [([ farmal-param ], ... ) ] [ statement ] ... END FUNCTION [exp] } { FUNCTIONEND [exp] pass-mech: BY REF } { BY DESC unsubs-var formal param: [ data-tvne] ,,., { array-name ( [ int-canst ] ,... I [=int-canst][ pass-mech] Syntax Rules 1. Fune-name names the FUNCTION subprogram. 2. Fune-name can be from 1 through 31 characters. The first character must be an alphabetic character (A through Z). The remaining characters, if present, can be any combination of letters, digits (0 through 9), dollar signs ( $ ), periods (. ), or underscores (-). 3. Data-type can be any VAX 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 in this manual. 4..,..122 Statements and Functions FUNCTION The data type that precedes the func-name specifies the data type of the value returned by the function. 5. 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. 4. 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 string. Parameters defined in formal-param must agree in number and type with the arguments specified in the function invocation. VAX BASIC allows you to specify from 1 through 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. • 6. 7. 8. Remarks 1. 2. 3. The FUNCTION statement must be the first statement in the FUNCTION subprogram. Every FUNCTION statement must have a corresponding END FUNCTION or FUNCTIONEND statement. Any VAX BASIC statement except END, PICTURE, END PICTURE, PROGRAM, END PROGRAM, SUB, SUBEND, END SUB, or SUBEXIT can appear in a FUNCTION subprogram. Statements and Functions 4-123 FUNCTION 4. 5. 6. 7. 8. 9. FUNCTION subprograms must be declared with the EXTERNAL statement before your VAX BASIC program can invoke them. FUNCTION subprograms receive parameters by reference or by descriptor. • BY REF specifies that the function receives the argument's address. • BY DESC specifies that the function receives the address of a VAX BASIC descriptor. For information about the format of a VAX BASIC descriptor for strings and arrays, see the VAX BASIC User Manual; for information on other types of descriptors, see the VAX Architecture Handbook. 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, VAX 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 the subprogram. VAX BASIC initializes local numeric variables to zero and local string variables to the null string each time the FUNCTION subprogram is invoked. If an exception is not handled within the FUNCTION subprogram, control is transferred back to the main program that invoked the function. Example FUNCTION REAL sphere_volume (REAL R) IF R < 0 THEN EXIT FUNCTION sphere_volume = 4/3 * PI *R **3 END FUNCTION 4-124 Statements and Functions July 1988 FUNCTIONEND FUNCTIONEND The FUNCTIONEND statement is a synonym for the END FUNCTION statement. See the END statement for more information. Format FUNCTIONEND [exp] Statements and Functions 4-12 5 FUNCTION EXIT FUNCTIONEXIT The FUNCTIONEXIT statement is a synonym for the EXIT FUNCTION statement. See the EXIT statement for more information. Format FUNCTIONEXIT [exp] 4-126 Statements and Functions GET GET The GET statement moves 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. Format GET #chnl-exp [,position-clause] [, lock-clause] position-clause: RFA rfa-exp } RECORD num-exp { KEY# key-clause Jock-clause: ALLOWallow-clause [,WAIT[ int-exp]] } WAIT [int-exp] { REGARDLESS allow-clause: { =~:: MODIFY key-clause: rel-op: } int-exp 1 rel-op key-exp EQ GE NXEQ GT NX Statements and Functions 4-127 GET l int-exp2 str-exp decimal-exp quadword-exp key-exp l Syntax Rules 1. Chnl-exp is a numeric expression that specifies a channel number associated with a file. It must be immediately preceded by a number sign{#). 2. If you specify a lock-clause, it must follow the position-clause. If the lock-clause precedes the position-clause VAX BASIC signals an error. 3. If you specify the REGARDLESS lock-clause, you cannot specify another lock-clause in the same GET statement. Remarks 1. Position-clause • Position-clause specifies the position of a record in a file. VAX BASIC signals an error if you specify a position-clause and chnlexp is not associated with a disk file. 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. Rfa-exp in 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. 4-128 Statements and Functions GET The RECORD position-clause allows you to randomly retrieve records in relative and sequential fixed files by specifying the record number. 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, clml-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. 2. Lock-clause • 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 another program. • When you specify a REGARDLESS lock-clause, VAX BASIC does not impose a lock on the retrieved record. • If you specify an ALLOW lock-clause the file associated with chnlexp must have been opened with the UNLOCK EXPLICIT clause or VAX BASIC signals the error "Illegal record locking clause". • 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. • July 1988 Statements and Functions 4-129 GET • • 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 the record. 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, VAX 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, VAX BASIC locks the retrieved record and unlocks the previously lockeQ. record. The WAIT lock-clause accepts an optional int-exp. Int-exp represents a timeout value in seconds. Int-exp must be from 0 through 255 or VAX BASIC issues a warning message. 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, VAX BASIC signals the the runtime error "Keyboard wait exhausted" (ERR=15). VMSSTATUS and RMSSTATUS then return RMS$_TMO. For more information on the RMSSTATUS and VMSSTATUS functions, see this chapter and the VAX BASIC 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 VAX 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 VAX BASIC signals the error "Keyboard wait exhausted" (ERR=15) even though a deadlock condition may exist. 4-130 Statements and Functions GET 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. Statements and Functions 4-130.1 GET 3. Key-clause • In a key-clause, int-exp1 is the target key of reference. It must be a integer value in the range of zero through the highest-numbered key for the file. The primary key is #0, the first alternate key is #l, the second alternate key is #2, and so on. Int-exp1 must be preceded by a number sign (#)or VAX BASIC signals an error. • When you specify a key clause, chnl-exp must be a channel associated with an open indexed file. 4. Rel-op • 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, VAX BASIC matches the first record that begins with ABC. If you specify "ABCABC", VAX BASIC matches only a record with the key "ABCABC". If no match is possible, VAX 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, VAX 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 value. If you specify a greater than key match (GT), a successful GET operation retrieves the first record with a value greater than keyexp. If no such record exists, VAX BASIC signals the error "Record not found" (ERR=155). Statements and Functions 4-131 GET • • 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, VAX BASIC signals the error "Record not found" (ERR=lSS). 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, DIGITAL recommends that you use NXEQ in new program development, especially if you are using descending key files. 5. Key-exp • 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. • 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 record. 6. 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. 7. 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. 8. 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. 4-132 Statements and Functions GET 9. A successful random GET operation by RFA or by record retrieves the record specified by rfa-exp or int-exp. 10. A successful random GET operation by key retrieves the first record whose key satisfies the key-clause comparison. 11. 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. 12. An unsuccessful GET operation leaves the record pointers and the record buffer in an undefined state. 13. If the retrieved record is smaller than the receiving buffer, VAX BASIC fills the remaining buffer space with nulls. 14. If the retrieved record is larger than the receiving buffer, VAX BASIC truncates the record and signals an error. 15. A successful GET operation sets the value of the RECOUNT variable to the number of bytes transferred from the file to the record buffer. 16. You should not use a GET statement on a terminal-format or virtual array file. Example 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, & MAP CUSREC INPUT "Which record number would you like to view";rec_num GET #1, RECORD REC_NUM, REGARDLESS PRINT "The customer's number is ";CUS_NUM PRINT "The customer's name is ";cus_nam PRINT "The customer's address is ";cus_add PRINT "The customer's city is ";cus_city PRINT "The customer's zip code is ";cus_zip CLOSE #1 END Statements and Functions 4-133 GETRFA GETRFA The GETRFA function returns the record's file address (RFA) of the last record accessed in an RMS file open on a specified channel. Format rfa-var = GETRFA (chnl-exp) Syntax Rules 1. Rfa-var is a variable of the RFA data type. Chnl-exp is the channel number of an open RMS file. You cannot include a number sign in the channel expression. 3. You must access a record in the file with a GET, FIND, or PUT statement before using the GETRFA function, or VAX BASIC signals "No current record" (ERR=131). 2. Remarks 1. There must be a file open on the specified chnl-exp or VAX BASIC signals an error. 2. You can use the GETRFA function with RMS sequential, relative, indexed, and block I/O files. 3. The RFA value returned by the GETRFA function can be used only for assignments to and comparisons with other variables of the RFA data type. Comparisons are limited to equal to(=) and not equal to ( < > ) relational operations. 4. RFA values cannot be printed or used for any arithmetic operations. 4-134 Statements and Functions GETRFA Example DECLARE RFA R_ARRAY(1 TO 100) FOR IY. = 1% TO 100% PUT #1 R_ARRAY(IY.) = GETRFA{1) NEXT IY. Statements and Functions 4-135 GOSUB GOSUB The GOSUB statement transfers control to a specified line number or label and stores the location of the GOSUB statement for eventual return from the subroutine. Format GO SUB } { GOSUB target Syntax Rules 1. 2. Target must refer to an existing line number or label in the same program unit as the GOSUB statement or VAX BASIC signals an error. Target cannot be inside a block structure such as a FOR ... NEXT, WHILE, or UNTIL loop or a multi-line function definition unless the GOSUB statement is also within that block or function definition. Remarks 1. You can use the GOSUB statement from within protected regions of a WHEN block. GOSUB statements can also contain protected regions themselves. 2. If you fail to handle an exception that occurs while a statement contained in the body of a subroutine is executing, the exception is handled by the default error handler. The exception is not handled by any WHEN block surrounding the statement that invoked the subroutine. 4-136 Statements and Functions GOSUB Example GOSUB subroutine_1 subroutine_1: RETURN Statements and Functions 4-137 GOTO GOTO The GOTO statement transfers control to a specified line number or label. Format GO TO } { GOTO target Syntax Rules 1. 2. Target must refer to an existing line number or label in the same program unit as the GOTO statement or VAX BASIC signals an error. Target cannot be inside a block structure such as a FOR ... NEXT, WHILE, or UNTIL loop or a multi-line function definition unless the GOTO statement is also inside that loop or function definition. Remarks 1. 2. 4-138 You can specify the GOTO statement inside a WHEN block if the target is in the same protected region, an outer level protected region, or in a nonprotected region. You cannot specify the GOTO statement inside a WHEN block if the target already resides in another protected region that does not contain the innermost current protected region. Statements and Functions GOTO Example IF answer = 0 THEN GOTO done END IF done: EXIT PROGRAM Statements and Functions 4-139 HANDLER HANDLER The handler statement marks the beginning of a detached handler. Format HANDLER handler-name Syntax Rules Handler-name must be a valid VAX BASIC identifier and must not be the same as any label, DEF, DEF•, SUB, FUNCTION or PICTURE name. Remarks 1. 2. 3. 4. 5. 4- 140 A detached handler must be delimited by a HANDLER statement and an END HANDLER statement. A detached handler can be used only with VAX BASIC's exceptionhandling mechanism. If you attempt to branch into a detached handler for example with the GOTO statement, VAX BASIC signals a compile-time error. To exit from a detached handler, you must use either END HANDLER, EXIT HANDLER, RETRY or CONTINUE. See these statements for more information. Within a handler, VAX BASIC allows you to specify user-defined function references and procedure invocations as well as VAX BASIC statements. The following statements are illegal inside a handler: • EXIT PROGRAM, FUNCTION, SUB, or PICTURE • GOTO to a target outside the handler • GOSUB to a target outside the handler Statements and Functions HANDLER • ON ERROR • RESUME Example WHEN ERROR USE err_handler END WHEN HANDLER err_handler IF ERR = 50 THEN PRINT "Insufficient data" RETRY ELSE EXIT HANDLER END IF END HANDLER Statements and Functions 4-141 IF IF The IF statement evaluates a conditional expression and transfers program control depending on the resulting value. Format Conditional IF cond-exp THEN statement... [ELSE statement... ] END IF Statement Modifier statement IF cond-exp Syntax Rules 1. Conditional • Cond-exp can be any valid conditional expression. • All statements between the THEN keyword and the next ELSE, line number, or END IF are part of the THEN clause. All statements between the keyword ELSE and the next line number or END IF are part of the ELSE clause. • VAX BASIC assumes a GOTO statement when the keyword ELSE is followed by a line number. When the target of a GOTO statement is a label, the keyword GOTO is required. The use of this syntax is not recommended for new program development. • The END IF statement terminates the most recent unterminated IF statement. • A new line number terminates all unterminated IF statements. 2. Statement Modifier • IF can modify any executable statement except a block statement such as FOR, WHILE, UNTIL, or SELECT. • Cond-exp can be any valid conditional expression. 4- 142 Statements and Functions IF Remarks 1. Conditional • VAX BASIC evaluates the conditional expression for truth or falsity. If true (nonzero), VAX BASIC executes the THEN clause. If false (zero), VAX BASIC skips the THEN clause and executes the ELSE clause, if present. • The keyword NEXT cannot be in a THEN or ELSE clause unless the FOR or WHILE statement associated with the keyword NEXT is also part of the THEN or ELSE clause. • If a THEN or ELSE clause contains a block statement such as a FOR, SELECT, UNTIL, or WHILE, then a corresponding block termination statement such as a NEXT or END, must appear in the same THEN or ELSE clause. • IF statements can be nested to 12 levels. • Any executable statement is valid in the THEN or ELSE clause, including another IF statement. You can include any number of statements in either clause. • Execution continues at the statement following the END IF or ELSE clause. If the statement does not contain an ELSE clause, execution continues at the next statement after the THEN clause. 2. Statement Modifier • VAX BASIC executes the statement only if the conditional expression is true (nonzero). Statements and Functions 4-143 IF Example IF Update_flag = True THEN Weekly_salary = New_rate * 40.0 UPDATE #1 IF Dept <> New_dept THEN GET #1, KEY #1 EQ New_dept Dept_employees = Dept_employees + 1 UPDATE #1 END IF PRINT "Update complete" ELSE PRINT "Skipping update for this employee" END IF 4- 144 Statements and Functions IN KEYS IN KEYS The INKEY$ function reads a single keystroke from a terminal opened on a specified channel and returns the typed character. Format string-var= INKEY$ (chnl-exp [,WAIT [int-exp]]) Syntax Rules 1. Chnl-exp must be the channel number of a terminal. 2. Int-exp represents the timeout value in seconds and must be from 0 through 255. Values beyond this range cause VAX BASIC to signal a compile-time or run-time error. Remarks 1. 2. 3. Before using the INKEY$ function, specify the DCL command SET TERMINAL/HOSTSYNC. This command controls whether the system can synchronize the flow of input from the terminal. If you specify SET TERMINAL/HOSTSYNC, the system generates a CTRL/S or a CTRL/Q to enable or disable the reception of input. This prevents the typeahead buffer from overflowing. If you do not use this command and the typeahead buffer overflows, VAX BASIC signals the error "Data overflow" (ERR=289). Before using the INKEY$ function on a VT200-series terminal, set your terminal to VT200 mode with 7 bit controls. Before using the INKEY$ function, either your termirial or VMS, but not both, must enable screen wrapping. To enable terminal screen wrapping, use the Set-Up key on your terminal's keyboard to set the terminal to Auto Wrap. Then disable VMS screen wrapping by entering the DCL SET TERMINAL /NOWRAP command. To enable VMS screen wrapping, enter the DCL SET TERMINAL /WRAP Statements and Functions 4-145 IN KEYS command. Then disable terminal screen wrapping by using the Set-Up key to set the terminal to No Auto Wrap. 4. The INKEY$ function behaves as if the terminal were in APPLICATION _KEYPAD mode. 5. If the channel is not open, VAX 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, VAX BASIC signals the error "Illegal operation" (ERR=141). 6. The optional WAIT clause specifies a timeout interval during which the command will await terminal input. If you specify WAIT int-exp, the timeout period will be the specified number of seconds. If you specify a WAIT clause followed by no timeout value, VAX BASIC waits indefinitely for terminal input. 7. VAX BASIC always examines the typeahead buffer first and retrieves the next keystroke in the buffer if the buffer is not empty. If the typeahead buffer is empty and an optional WAIT clause was specified, VAX BASIC waits for a keystroke to be typed for the specified timeout interval (indefinitely if WAIT was specified with no timeout interval). If the typeahead buffer is empty, and the waiting period is either not specified or expired, VAX BASIC returns the error message "Keyboard wait exhausted" (ERR=15). 8. The escape character (ASCII code 27) is not valid as INKEY$ input. If you enter an escape character, normal program execution resumes when the INKEY$ times out. Without a specified timeout value, the program execution cannot resume without error. 9. VAX BASIC returns the error message "Keyboard wait exhausted" (ERR=15) when any key is pressed after the escape character if no timeout is specified or if the specified timeout has not yet occurred. 10. INKEY$ turns off all line editing. As a result, control of all line-editing characters and the arrow keys is passed back to the user. 11. Non-editing characters normally intercepted by the VAX/VMS terminal driver are not returned. These include the CTRL/C, CTRL/Y, CTRL/S, CTRL Y/0 characters (unless CTRL/C trapping is enabled). They are handled by the device driver just as in normal input. 12. All ASCII characters are returned in a 1-byte string. 13. All keystrokes that result in an escape sequence are translated to mnemonic strings based on the following key names: • PF1-PF4 • El-E6 • F7-F20 4-146 Statements and Functions July 1988 IN KEYS • • LEFT RIGHT • UP • DOWN Statements and Functions 4-146. 1 IN KEYS • • • • • KPO to KP9 KPKP, KP . ENTER Example PROGRAM Inkey_demo DECLARE STRING KEYSTROKE Inkey_Loop: WHILE 11. KEYSTROKE = INKEY$(0%,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 function key" CASE "E1 II TO "E6". "F7" TO "F9". "F10" TO "F20" PRINT "VT200 function key" CASE "KPO" TO "KP9" PRINT "Application keypad key" CASE < SP PRINT "Control character" CASE I 127'C PRINT "<DEL>" CASE ELSE PRINT 'Character is "' · KEYSTROKE; '"' END SELECT NEXT END PROGRAM Statements and Functions 4-14 7 INPUT INPUT The INPUT statement assigns values from your terminal or from a terminal-format file to program variables. Format INPUT [ #chnl-exp,] [ str-const1 { ; } ] var1 [ { ; } [ str-const2 { ; } ] var2 ]... Syntax Rules You must supply an argument to the INPUT statement. Otherwise, VAX BASIC signals an error message. 2. Chnl-exp is a numeric expression that specifies a channel number associated with a file. It must be immediately preceded by a number sign(#). 3. You can include more then one string constant in an INPUT statement. Str-constl is issued for str-varl, str-const2 for str-var2, and so on. 4. Str-varl and str-var2 cannot be a DEF function names unless the INPUT statement is inside the multi-line DEF that defines the function. 5. The separator (comma or semicolon) that directly follows str-varl and str-var2 has no formatting effect. VAX BASIC always advances to a new line when you terminate input with a carriage return. 6. The separator that directly follows str-constl and str-const2, determines where the question mark prompt (if requested) is displayed and where the cursor is positioned for input. 1. A comma causes VAX BASIC to skip to the next print zone and display the question mark unless a SET NO PROMPT statement has been executed. For example: DECLARE STRING your_name INPUT "What is your name",your_name 4- 148 Statements and Functions INPUT Output What is your name ? A semicolon causes VAX BASIC to display the question mark next to str-const unless a SET NO PROMPT statement has been executed. For example: DECLARE STRING your_name INPUT "What is your name";your_name Output What is your name? 7. VAX BASIC always advances to a new line when you terminate input with a carriage return. Remarks 1. If you do not specify a channel, the default chnl-exp is #0 (the controlling terminal). If a chnl-exp is specified, a file must be open on that channel with ACCESS READ or MODIFY before the INPUT statement can execute. 2. If input comes from a terminal, VAX BASIC displays the contents of str-const1, if present. If the terminal is open on channel #0, VAX BASIC also displays a question mark (? ). 3. You can disable the question mark prompt by using the SET NO PROMPT statement. See the SET PROMPT statement for more information. 4. When VAX BASIC receives a line terminator or a complete record, it checks each data element for correct data type and range limits, then assigns the values to the corresponding variables. 5. If you specify a string variable to receive the input text, and the user enters an unquoted string in response to the prompt, VAX BASIC ignores the string's leading and trailing spaces and tabs. An unquoted string cannot contain any commas. 6. If there is not enough data in the current record or line to satisfy the variable list, VAX BASIC takes one of the following actions: • If the input device is a terminal and you have not specified SET NO PROMPT, VAX BASIC repeats the question mark but not the str-const, on a new line until sufficient data is entered. Statements and Functions 4-149 INPUT • 7. 8. If the input device is not a terminal, VAX BASIC signals "Not enough data in record" (ERR=59). If there are more data items than variables in the INPUT response, VAX BASIC ignores the excess. If there is an error while data is being converted or assigned (for example, string data being assigned to a numeric variable), VAX BASIC takes one of the following actions: • If there is no error handler in effect and the input device is a terminal, VAX BASIC signals a warning, reexecutes the INPUT statement, and displays str-const and the input prompt. • If there is an error handler in effect and the input device is not a terminal, VAX BASIC signals "Illegal number" (ERR=52) or "Data format error" (ERR=SO). 9. When a RETRY, CONTINUE or RESUME statement transfers control to an INPUT statement, the INPUT statement retrieves a new record or line regardless of any data left in the previous record or line. 10. After a successful INPUT statement, the RECOUNT variable contains the number of characters transferred from the file or terminal to the record buffer. 11. If you terminate input text with CTRL/Z, VAX BASIC assigns the value to the variable and signals "End of file on device" (ERR=ll) when the next terminal input statement executes. If you are in the BASIC environment and there is no subsequent INPUT, INPUT LINE, or LINPUT statement in the program, the CTRL/Z is passed to VAX BASIC as a signal to exit the BASIC environment. VAX BASIC signals "Unsaved changes have been made, CTRL/Z or EXIT to exit" if you have made changes to your program or are running a program that has never been saved. If you have not made changes, VAX BASIC exits from the BASIC environment and does not signal an error. Example DECLARE STRING var_1, & INTEGER var_2 INPUT "The first variable";var_1, "The second variable";var_2 Output The first variable? name The second variable? 4 4-150 Statements and Functions INPUT LINE INPUT LINE The INPUT LINE statement assigns a string value (including the line terminator in some cases) from a terminal or terminal-format file to a string variable. Format [ #chnl-exp,] [ str-const1 { ; } ] str-var1 INPUT LINE [statement]. .. [ { ; } [ str-const2 { ; } ] str-var2 ]. .. Syntax Rules Chnl-exp is a numeric expression that specifies a channel number associated with a file. It must be immediately preceded by a number sign ( # ). 2. Str-varl or str-var2 cannot be a DEF function name unless the INPUT LINE statement is inside the multi-line DEF that defines the function. 3. You can include more than 1 string constant in an INPUT LINE statement. Str-constl is issued for str-varl, str-const2 for str-var2, and so on. 4. The separator (comma or semicolon) that directly follows str-varl and str-var2 has no formatting effect. VAX BASIC always advances to a new line when you terminate input with a carriage return. 5. The separator that directly follows str-constl and str-const2 determines where the question mark (if requested) is displayed and where the cursor is positioned for input. Specifically: • A comma causes VAX BASIC to skip to the next print zone and display the question mark unless a SET NO PROMPT statement has been executed. For example: 1. DECLARE STRING your_name INPUT LINE "Name", your_name July 1988 Statements and Functions 4-151 INPUT LINE Output Name • ? A semicolon causes VAX BASIC to display the question mark next to str-const unless a SET NO PROMPT statement has been executed. For example: DECLARE STRING your_name INPUT LINE "Name";your_name Output Name? 6. VAX BASIC always advances to a new line when you terminate input with a carriage return. Remarks The default chnl-exp is #0 (the controlling terminal). If a channel is specified, a file must be open on that channel with ACCESS READ before the INPUT LINE statement can execute. 2. VAX BASIC signals an error if the INPUT LINE statement has no argument. 3. If input comes from a terminal, VAX BASIC displays the contents of str-const1, if present. If the terminal is open on channel #0, VAX BASIC also displays a question mark (? ). 4. You can disable the question mark prompt by using the SET NO PROMPT statement. See the SET PROMPT statement for more information. 5. The INPUT LINE statement assigns all input characters to string variables. In addition, the INPUT LINE statement places the following line terminator characters in the assigned string if they are part of the string value: 1. 4-152 Statements and Functions July 1988 INPUT LINE 6. 7. Hex code ASCII char Character name OA OB LF Line Feed VT Vertical Tab oc FF Form Feed OD ODOA CR Carriage Return CRLF Carriage Return/Line Feed 1B ESC Escape Any other line terminator, such as CRTL/D and CTRL/F when line editing is turned off, is not included in the assigned string. When a RETRY, CONTINUE or RESUME statement transfers control to an INPUT LINE statement, the INPUT LINE statement retrieves a new record or line regardless of any data left in the previous record or line. After a successful INPUT LINE statement, the RECOUNT variable contains the number of characters transferred from the file or terminal to the record buffer. July 1988 Statements and Functions 4-152.1 INPUT LINE 8. If you terminate input text with CTRL/Z, VAX BASIC assigns the value to the variable and signals "End of file on device" (ERR=l 1) when the next terminal input statement executes. If you are in the BASIC environment and there is no next INPUT, INPUT LINE, or LINPUT statement in the program, the CTRL/Z is passed to VAX BASIC as a signal to exit the BASIC environment. VAX BASIC signals "Unsaved changes have been made, CTRL/Z or EXIT to exit" if you have made changes to your program. If you have not made changes, VAX BASIC exits from the BASIC environment and does not signal an error. Example DECLARE STRING Z,N,record_string INPUT LINE "Type two words", Z$,'Type your name';N$ INPUT LINE #4%, record_string$ Statements and Functions 4-153 INSTR INSTR The INSTR function searches for a substring within a string. It returns the position of the substring's starting character. Format int-var= INSTR (int-exp, str-exp 1, str-exp2) Syntax Rules 1. Int-exp specifies the character position in the main string at which 2. 3. VAX BASIC starts the search. Str-exp1 specifies the main string. Str-exp2 specifies the substring. Remarks The INSTR function searches str-exp1, the main string, for the first occurrence of a substring, str-exp2, and returns the position of the substring's first character. 2. INSTR returns the character position in the main string at which VAX BASIC finds the substring, except in the following situations: • If only the substring is null, and if int-exp is less than or equal to zero, INSTR returns a value of 1. • If only the substring is null, and if int-exp is equal to or greater than 1 and less than or equal to the length of the main string, INSTR returns the value of int-exp. • If only the substring is null, and if int-exp is greater than the length of the main string, INSTR returns the main string's length plus 1. • If the substring is not null, and if int-exp is greater than the length of the main string, INSTR returns a value of zero. 1. 4-154 Statements and Functions INSTR • • If only the main string is null, INSTR returns a value of zero. If both the main string and the substring are null, INSTR returns a 1. 3. If VAX BASIC cannot find the substring, INSTR returns a value of zero. 4. If int-exp does not equal 1, VAX BASIC still counts from the beginning of the main string to calculate the starting position of the substring. That is, VAX BASIC counts character positions starting at position 1, regardless of where you specify the start of the search. For example, if you specify 10 as the start of the search and VAX BASIC finds the substring at position 15, INSTR returns the value 15. 5. If int-exp is less than l, VAX BASIC assumes a starting position of 1. 6. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to an integer of the default size. Example DECLARE STRING alpha, & INTEGER result 11 11 alpha = ABCDEF result = INSTR(1,alpha,"DEF") PRINT result Output 4 Statements and Functions 4-155 INT INT The INT function returns the floating-point value of the largest whole number less than or equal to a specified expression. Format real-var= INT (real-exp) Syntax Rules VAX BASIC expects the argument of the INT function to be a real expression. When the argument is a real expression, VAX BASIC returns a value of the same floating-point size. When the argument is not a real expression, VAX BASIC converts the argument to the default floating-point size and returns a value of the default floating-point size. Remarks If real-exp is negative, VAX BASIC returns the largest whole number less than or equal to real-exp. For example, INT(-5.3) is -6. Examples Example 1 DECLARE SINGLE any_num, result any_num = 6.667 result = INT(any_num) PRINT result Output 1 6 4-156 Statements and Functions INT Example 2 !This example contrasts the INT and FIX functions DECLARE SINGLE test_num test_num = -32.7 PRINT "INT OF -32.7 IS: 11 • INT(test_num) PRINT "FIX OF -32.7 IS: "; FIX(test_num) Output 2 INT OF -32.7 IS: -33 FIX OF -32.7 IS: -32 Statements and Functions 4-15 7 INTEGER INTEGER The INTEGER function converts a numeric expression or numeric string to a specified or default INTEGER data type. Format int-var= INTEGER (exp ,BYTE ] , WORD [ ,LONG Syntax Rules Exp can be either numeric or string. A string expression can contain the ASCII digits 0 through 9, a plus sign ( +), or a minus sign ( - ). Remarks 1. VAX BASIC evaluates exp, then converts it to the specified INTEGER size. If you do not specify a size, VAX BASIC uses the default INTEGER size. 2. If exp is a string, VAX BASIC ignores leading and trailing spaces and tabs. 3. The INTEGER function returns a value of zero when a string argument contains only spaces and tabs, or when it is null. 4. The INTEGER function truncates the decimal portion of REAL and DECIMAL numbers. 4-158 Statements and Functions INTEGER Example INPUT "Enter a floating-point number";F_P PRINT INTEGER(F_P, WORD) Output Enter a floating-point number? 76.99 76 Statements and Functions 4-159 ITERATE ITERATE The ITERATE statement allows you to explicitly reexecute a loop. Format ITERATE [label] Syntax Rules 1. 2. Label is the label of the first statement of a FOR. .. NEXT, WHILE, or UNTIL loop. Label must conform to the rules for naming variables. Remarks 1. 2. 4-160 ITERATE is equivalent to an unconditional branch to the current loop's NEXT statement. If you supply a label, ITERATE transfers control to the NEXT statement in the specified loop. If you do not supply a label, ITERATE transfers control to the current loop's NEXT statement. The ITERATE statement can be used only within a FOR. .. NEXT, WHILE, or UNTIL loop. Statements and Functions ITERATE Example WHEN ERROR IN Date_loop: WHILE 1Y. = 1Y. GET #1 ITERATE Date_loop IF Day$ <> Today$ ITERATE Date_loop IF Month$ <> This_month$ ITERATE Date_loop IF Year$ <> This_year$ PRINT Item$ NEXT USE IF ERR = 11 THEN CONTINUE DONE ELSE EXIT HANDLER END IF END WHEN Done: END Statements and Functions 4-161 KILL KILL The KILL statement deletes a disk file, removes the file's directory entry, and releases the file's storage space. Format KILL file-spec Syntax Rules File-spec can be a quoted string constant, a string variable, or a string expression. It cannot be an unquoted string constant. Remarks 1. The KILL statement marks a file for deletion but does not delete the file until all users have closed it. 2. If you do not specify a complete file specification, VAX BASIC uses the default device and directory. If you do not specify a file version, VAX BASIC deletes the highest version of the file. 3. The file must exist, or VAX BASIC signals an error. 4. You can delete a file in another directory if you have access to that directory and privilege to delete the file. Example KILL "TEMP.DAT" 4-162 Statements and Functions LBOUND LBOUND The LBOUND function returns the lower bounds of a compile-time or run-time dimensioned array. Format num-var = LBOUND (array-name [, num-exp ]) Syntax Rules 1. Array-name must specify an array that has been either explicitly or implicitly declared. 2. Num-exp specifies the number of the dimension for which you have requested the lower bound. Remarks 1. 2. 3. If you do not specify a dimension, VAX BASIC automatically returns the lower bounds of the first dimension. If you specify a numeric expression that is less than or equal to zero, VAX BASIC signals an error. If you specify a numeric expression that exceeds the number of dimensions, VAX BASIC signals an error. Statements and Functions 4-163 LBOUND Example DECLARE INTEGER CONSTANT B = 5 DIM A(B) account_num = 1 FOR dim_num = LBOUND (A) TO 5 A(dim_num) = account_num account_num = account_num + 1 PRINT A(dim_num) NEXT dim_num Output 1 2 3 4 5 6 4- 164 Statements and Functions LEFTS LEFTS The LEFT$ function extracts a specified substring from a string's left side, leaving the main string unchanged. Format str-var =LEFT[$] (str-exp, int-exp) Syntax Rules Int-exp specifies the number of characters to be extracted from the left side of str-exp. 2. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to an integer of the default size. 1. Remarks 1. The LEFT$ function extracts a substring from the left of the specified str-exp and stores it in str-var. 2. If int-exp is less than l, LEFT$ returns a null string. 3. If int-exp is greater than the length of str-exp, LEFT$ returns the entire string. Statements and Functions 4-165 LEFTS Example DECLARE STRING sub_string, main_string main_string = "1234667" sub_string = LEFT$(main_string, 4) PRINT sub_string Output 1234 4-166 Statements and Functions LEN LEN The LEN function returns an integer value equal to the number of characters in a specified string. Format int-var= LEN (str-exp) Syntax Rules None. Remarks 1. If str-exp is null, LEN returns a value of zero. 2. The length of str-exp includes leading, trailing, and embedded blanks. Tabs in str-exp are treated as a single space. 3. The value returned by the LEN function is a LONG integer. Example DECLARE STRING alpha, ~ INTEGER length alpha = "ABCDEFG" length = LEN(alpha) PRINT length Output 7 Statements and Functions 4-167 LET LET The LET statement assigns a value to one or more variables. Format [LET] var,... = exp Syntax Rules 1. Var cannot be a DEF or FUNCTION name unless the LET statement occurs inside that DEF block or in that FUNCTION subprogram. 2. The keyword LET is optional. Remarks 1. You cannot assign string data to a numeric variable or unquoted numeric data to a string variable. 2. The value assigned to a numeric variable is converted to the variable's data type. For example, if you assign a floating-point value to an integer variable, VAX BASIC truncates the value to an integer. 3. For dynamic strings, the destination string's length equals the source string's length. 4. When you assign a value to a fixed-length string variable (a variable declared in a COMMON, MAP, or RECORD statement), the value is left-justified and padded with spaces or truncated to match the length of the string variable. 4-168 Statements and Functions LET Example DECLARE STRING alpha, t INTEGER length LET alpha = "ABCDEFG" LET length = LEN(alpha) PRINT length Output 7 Statements and Functions 4-169 LINPUT LIN PUT The LINPUT statement assigns a string value, without line terminators, from a terminal or terminal-format file to a string variable. Format LINPUT [ #chn/-exp, J[ str-const1 { ; } ] str-var1 [ { ; } [ str-const2 { ; } ] str-var2 ]... Syntax Rules 1. Chnl-exp is a numeric expression that specifies a channel number associated with a file. It must be immediately preceded by a number sign(#). 2. Str-varl and str-var2 cannot be DEF function names unless the LINPUT statement is inside the multi-line DEF that defines the function. 3. You can include more than one string constant in a LINPUT statement. Str-constl is issued for str-varl, str-const2 for str-var2, and so on. 4. The separator (comma or semicolon) that directly follows str-varl and str-var2 has no formatting effect. VAX BASIC always advances to a new line when you terminate input with a carriage return. 5. The separator character that directly follows str-constl and str-const2 determines where the question mark (if requested) is displayed and where the cursor is positioned for input. • A comma causes VAX BASIC to skip to the next print zone to display the question mark unless a SET NO PROMPT statement has been executed. For example: DECLARE STRING your_name LINPUT "Name",your_name 4-170 Statements and Functions LINPUT Output Name • ? A semicolon causes VAX BASIC to display the question mark next to str-const unless a SET NO PROMPT statement has been executed. For example: DECLARE STRING your_name LINPUT "What is your name";your_name Output What is your name? 6. VAX BASIC always advances to a new line when you terminate input with a carriage return. Remarks 1. 2. 3. 4. 5. 6. 7. The default chnl-exp is #0 (the controlling terminal). If you specify a channel, the file associated with that channel must have been opened with ACCESS READ or MODIFY. VAX BASIC signals an error if the LINPUT statement has no argument. If input comes from a terminal, VAX BASIC displays the contents of str-const1, if present. If the terminal is open on channel #0, VAX BASIC also displays a question mark (? ). You can disable the question mark prompt by using the SET NO PROMPT statement. See the SET PROMPT statement for more information. The LINPUT statement assigns all characters, except any line terminator's to str-varl and str-var2. Single and double quotation marks, commas, tabs, leading and trailing spaces, or other special characters in the string are part of the data. If the RETRY, CONTINUE or RESUME statement transfers control to a LINPUT statement, the LINPUT statement retrieves a new record regardless of any data left in the previous record. After a successful LINPUT statement, the RECOUNT variable contains the number of bytes transferred from the file or terminal to the record buffer. Statements and Functions 4-171 LINPUT 8. If you terminate input text with CTRL/Z, VAX BASIC assigns the value to the variable and signals "End of file on device" (ERR=ll) when the next terminal input statement executes. If you are in the BASIC environment and there is no next INPUT, INPUT LINE, or LINPUT statement in the program, the CTRL/Z is passed to VAX BASIC as a signal to exit the BASIC environment. Example DECLARE STRING last_name LINPUT "ENTER YOUR LAST NAME";Last_name LINPUT #21., Last_name 4-172 Statements and Functions LDC LDC The LOC function returns either a longword integer specifying the virtual address of a simple or subscripted variable, or the address of an external function or subprogram. For dynamic strings, the LOC function returns the address of the descriptor rather than the address of the data. Format int-var= LDC ( { var . }) ext-routme Syntax Rules 1. Var can be any local or external, simple or subscripted variable. 2. 3. Var cannot be a virtual array element. 1. The LOC function always returns a LONG value. The LOC function is useful for passing the address of an external function as a parameter to a procedure. When passing a routine address as a parameter you should usually pass the address by value. For example, VAX/VMS system services expect to receive AST procedure entry masks by reference; therefore, the address of the entry mask should be in the argument list on the stack. Ext-routine can be the name of external function or subprogram. Remarks 2. July 1988 Statements and Functions 4-17 J LDC Example DECLARE INTEGER A, B A = 12 LDC(A) PRINT B B = Output 2146799372 4-174 Statements and Functions LOG LOG The LOG function returns the natural logarithm (base e) of a specified number. The LOG function is the inverse of the EXP function. format real-var= LOG (real-exp) Syntax Rules None. Remarks 1. Real-exp must be greater than zero. An attempt to find the logarithm of zero or a negative number causes VAX BASIC to signal "Illegal argument in LOG" (ERR=53). 2. The LOG function uses the mathematical constant e as a base. VAX BASIC approximates e to be 2.718281828459045 (double precision). 3. The LOG function returns the exponent to which e must be raised to equal real-exp. 4. VAX BASIC expects the argument of the LOG function to be a real expression. When the argument is a real expression, VAX BASIC returns a value of the same floating-point size. When the argument is not a real expression, VAX BASIC converts the argument to the default floating-point size and returns a value of the default floating-point size. Statements and Functions 4-17 5 LOG Example DECLARE SINGLE exponent exponent = LOG(98.6) PRINT exponent Output 4.59107 4-176 Statements and Functions LOG10 LOG10 The LOGlO function returns the common logarithm (base 10) of a specified number. Format real-var= LOG 10 (real-exp) Syntax Rules None. Remarks 1. Real-exp must be larger than zero. An attempt to find the logarithm of zero or a negative number causes VAX BASIC to signal "Illegal argument in LOG" (ERR=53). 2. The LOGlO function returns the exponent to which 10 must be raised to equal real-exp. 3. VAX BASIC expects the argument of the LOGlO function to be a real expression. When the argument is a real expression, VAX BASIC returns a value of the same floating-point size. When the argument is not a real expression, VAX BASIC converts the argument to the default floating-point size and returns a value of the default floating-point size. Statements and Functions 4-17 7 LOG10 Example DECLARE SINGLE exp_base_10 exp_base_10 = LOG10(260) PRINT exp_base_10 Output 2.39794 4-178 Statements and Functions LSET LSET The LSET statement assigns left-justified data to a string variable. LSET does not change the length of the destination string variable. Format LSET str-var, ... = str-exp Syntax Rules Str-var is the destination string. Str-exp is the string value assigned to str-var. 2. Str-var cannot be a DEF function or function name unless the LSET 1. statement is inside the multi-line DEF or function that defines the function. Remarks 1. 2. The LSET statement treats all strings as fixed length. LSET neither changes the length of the destination string nor creates new storage. Rather, it overwrites the current storage of str-var. If the destination string is longer than str-exp, LSET left-justifies strexp and pads it with spaces on the right. If smaller, LSET truncates characters from the right of str-exp to match the length of str-var. Statements and Functions 4-179 LSET Example DECLARE STRING alpha alpha = 11 ABCDE 11 LSET alpha = 11 FGHIJKLMN" PRINT alpha Output FGHIJ 4-180 Statements and Functions MAG MAG The MAG function returns the absolute value of a specified expression. The returned value has the same data type as the expression. Format var= MAG (exp) Syntax Rules None. Remarks 1. The returned value is always greater than or equal to zero. The absolute value of zero is zero. The absolute value of a positive number equals that number. The absolute value of a negative number equals that number multiplied by -1. 2. The MAG function is similar to the ABS function in that it returns the absolute value of a number. The ABS function, however, takes a floating-point argument and returns a floating-point value. The MAG function takes an argument of any numeric data type and returns a value of the same data type as the argument. DIGITAL recommends the use of the MAG function rather than the ABS and ABS% functions, because the MAG function returns a value using the data type of the argument. Statements and Functions 4-181 MAG Example DECLARE SINGLE A A = -34.6 PRINT MAG(A) Output 34.6 4-182 Statements and Functions MAGTAPE MAGTAPE The MAGTAPE function permits your program to control unformatted magnetic tape files. NOTE The MAGTAPE function is supported only for compatibility with BASIC-PLUS-2. DIGITAL recommends that you do not use the MAGTAPE function for new program development. Format int-var1 = MAGTAPE (tune-code, int-var, chnl-exp) Syntax Rules 1. Fune-code specifies the code for the MAGTAPE function you want to perform. VAX BASIC supports only function code 3, rewind tape. Table 4-4 explains how to perform other MAGTAPE functions with VAX BASIC. 2. Int-var is an integer parameter for function codes 4, 5, and 6. However, because VAX BASIC supports only function code 3, int-var is not used and always equals zero. 3. Chnl-exp is a numeric expression that specifies a channel number associated with the magnetic tape file. Statements and Functions 4-183 MAGTAPE Table 4-4: MAGTAPE Functionality in VAX BASIC Code Function VAX BASIC Action 2 Write EOF Close channel with the CLOSE statement 3 Rewind tape Use the RESTORE # statement, the REWIND clause on an OPEN statement, or the MAGTAPE function 4 Skip records Perform GET operations, ignore data until reaching desired record 5 Backspace Rewind tape, perform GET operations, ignore data until reaching desired record 6 Set density or set parity Use the DCL commands MOUNT /DENSITY and MOUNT /FOREIGN or the $MOUNT system service 7 Get status Use the RMSSTATUS function Remarks For more information on the MAGTAPE function, see Appendix A in this manual. Example I = MAGTAPE (3Y.,OY.,2Y.) 4-184 Statements and Functions MAP MAP The MAP statement defines a named area of statically allocated storage called a PSECT, declares data fields in the record, and associates them with program variables. Format MAP (map-name) { [data-type] map-item}, ... map-item: num-unsubs-var num-array-name ( [ int-const1 TO] int-const2, ... ) record-var str-unsubs-var [=int-canst] str-array-name ( [ int-const1 TO] int-const2, ... ) [=int-canst] FILL [ (int-canst)] [=int-canst] FILL% [ (int-canst)] FILL$ [ (int-canst)] [=int-canst] Syntax Rules 1. Map-name is global to the program and image. It cannot appear elsewhere in the program unit as a variable name. 2. Map-name can be from 1 through 31 characters. The first character of the name must be an alphabetic character (A through Z). The remaining characters, if present, can be any combination of letters, digits (0 through 9), dollar signs ( $ ), periods ( . ), or underscores (- ). 3. Data-type can be any VAX BASIC data type keyword or a data type defined by a RECORD statement. Data type keywords, size, range, and precision are listed in Table 1-2. 4. When you specify a data type, all following map-items, including FILL items, are of that data type until you specify a new data type. 5. If you specify a dollar sign ( $) or percent sign ( % ) suffix character, the variable must be a string or integer data type. Statements and Functions 4-185 MAP If you do not specify a data type, a map-item without a suffix character (% or$) takes the current default data type and size. 7. Map-item declares the name and format of the data to be stored. • Num-unsubs-var and num-array-name specify a numeric variable or a numeric array. • Record-var specifies a record instance. • Str-unsubs-var and str-array-name specify a fixed-length string variable or array. You can specify the number of bytes to be reserved for the variable with the =int-const clause. The default string length is 16. • The FILL, FILL%, and FILL$ keywords allow you to reserve parts of the record buffer within or between data elements and to define the format of the storage. Int-const specifies the number of FILL items to be reserved. The =int-const clause allows you to specify the number of bytes to be reserved for string FILL items. Table 4-2 describes FILL item format and storage allocation. • In the applicable formats of FILL, (int-const) represents a repeat count, not an array subscript. FILL (n), for example, represents n elements, not n + 1. 8. Variable names, array names and FILL items following a data type other than STRING cannot end with a dollar sign. Variable names, array names and FILL items following a data type other than BYTE, WORD, LONG or INTEGER, cannot end with a percent sign. 9. Variables and arrays declared in a MAP statement cannot be declared elsewhere in the program by any other declarative statements. 10. When you declare an array, VAX BASIC allows you to specify both lower and upper bounds. Upper bounds are required; lower bounds are optional. • Int-const2 specifies the upper bounds of the array and, when accompanied by int-const1, must be preceded by the keyword TO. • Int-const1 must be less than or equal to int-const2. • If you do not specify int-constl, VAX BASIC uses zero as the default lower bound. • lnt-constl and int-const2 can be any combination of negative and positive values. 6. 4-186 Statements and Functions MAP Remarks VAX BASIC does not execute MAP statements. The MAP statement allocates static storage and defines data at compilation time. 2. A program can have multiple maps with the same name. The allocation for each map overlays the others. Thus, data is accessible in many ways. The actual size of the data area is the size of the largest map. When you link your program, the size of the map area is the size of the largest map with that name. 3. Map-items with the same name can appear in different MAP statements with the same map name only if they match exactly in attributes such as data type, position, and so forth. If the attributes are not the same, VAX BASIC signals an error. For example: 1. MAP (ABC) LONG A, B MAP (ABC) LONG A, C MAP (ABC) LONG B, A MAP (ABC) WORD A, B 4. 5. 6. 7. 8. 9. This MAP statement is valid This MAP statement produces an error This MAP statement produces an error The third MAP statement causes VAX BASIC to signal the error "variable <name> not aligned in multiple references in MAP <name> ", while the fourth MAP statement generates the error "attributes of overlaid variable <name> don't match". The MAP statement should precede any reference to variables declared in it. Storage space for map-items is allocated in order of occurrence in the MAP statement. A MAP area can be accessed by more than one program module, as long as you define the map-name in each module that references the MAP. A COMMON area and a MAP area with the same name specify the same storage area and are not allowed in the same program module. However, a COMMON in one module can reference the storage declared by a MAP or COMMON in another module. Variables in a MAP statement are not initialized by VAX BASIC. A map named in an OPEN statement's MAP clause is associated with that file. The file's records and record fields are defined by that map. The size of the map determines the record size for file I/O, unless the OPEN statement includes a RECORDSIZE clause. Statements and Functions 4-187 MAP Example 4-188 MAP (BUF1) BYTE AGE, STRING emp_name = 20 SINGLE emp_num t MAP (BUF1) BYTE FILL, STRING last_name (11) = 12, FILL = 8, SINGLE FILL t Statements and Functions MAP DYNAMIC MAP DYNAMIC The MAP DYNAMIC statement names the variables and arrays whose size and position in a storage area can change at run time. The MAP DYNAMIC statement is used in conjunction with the REMAP statement. The REMAP statement defines or redefines the position in the storage area of variables named in the MAP DYNAMIC statement. Format (map-dyn-nameJ{[ data-type ]map-item}, ... MAP DYNAMIC map-dyn-name: map-name } { static-str-var num-unsubs-var num-array-name ( [int-canst 1 TO ] int-const2 ,... ) record-var str-unsubs-var str-array-name ( [int-canst 1 TO ] int-const2 ,.. .) map-item: Syntax Rules 1. Map-dyn-name can either be ~ map name or a static string variable. • Map-name is the storage area named in a MAP statement. • • • If you specify a map name, then a MAP statement with the same name must precede both the MAP DYNAMIC statement and the REMAP statement. When you specify a static string variable, the string must be declared before you can specify a MAP DYNAMIC statement or a REMAP statement. Static-str-var must specify a static string variable or a string parameter variable. Statements and Functions 4-189 MAP DYNAMIC • If you specify a static-str-var, the following restrictions apply: Static-str-var cannot be a string constant. Static-str-var cannot be the same as any previously declared map-item in a MAP DYNAMIC statement. Static-str-var cannot be a subscripted variable. Static-str-var cannot be a record component. Static-str-var cannot be a parameter declared in a DEF or DEF* 2. 3. 4. 5. 6. 7. 4-190 function. Map-item declares the name and data type of the items to be stored in the storage area. All variable pointers point to the beginning of the storage area until the program executes a REMAP statement. • Num-unsubs-var and num-array-name specify a numeric variable or a numeric array. • Record-var specifies a record instance. • Str-unsubs-var and str-array-name specify a string variable or array. You cannot specify the number of bytes to be reserved for the variable in the MAP DYNAMIC statement. All string items have a fixed length of zero until the program executes a REMAP statement. When you specify an array name, VAX BASIC allows you to specify both lower and upper bounds. The upper bound is required; the lower bound is optional. • Int-constl specifies the lower bounds of the array. • Int-const2 specifies the upper bounds of the array and, when accompanied by int-constl, must be preceded by the keyword TO. • Int-tonstl must be less than or equal to int-const2. • If you do not specify int-constl, VAX BASIC uses zero as the default lower bound. • Int-constl and int-const2 can be either negative or positive values. Data-type can be any VAX BASIC data type keyword or a data type defined with a RECORD statement. Data type keywords, size, range, and precision are listed in Table 1-2 in this manual. When you specify a data type, all following map-items are of that data type until you specify a new data type. If you do not specify any data type, map-items take the current default data type and size. Map-items must be separated with commas. Statements and Functions July 198E MAP DYNAMIC 8. If you specify a dollar sign or percent sign suffix, the variable must be a STRING data type or one of the integer data types. Statements and Functions 4-190.1 MAP DYNAMIC Remarks All variables and arrays declared in a MAP DYNAMIC statement cannot be declared elsewhere in the program by any other declarative statements. 2. The MAP DYNAMIC statement does not affect the amount of storage allocated to the map buffer declared in a previous MAP statement or the storage allocated to a static string. Until your program executes a REMAP statement, all variable and array element pointers point to the beginning of the MAP buffer or static string. 3. VAX BASIC does not execute MAP DYNAMIC statements. The MAP DYNAMIC statement names the variables whose size and position in the MAP or static string buffer can change and defines their data type. 4. Before you can specify a map name in a MAP DYNAMIC statement, there must be a MAP statement in the program unit with the same map name. Otherwise, VAX BASIC signals the error "Insufficient space for MAP DYNAMIC variables in MAP <name> ". Similarly, before you can specify a static string variable in the MAP DYNAMIC statement, the string variable must be declared. Otherwise, VAX BASIC signals the same error message. 5. A static string variable must be either a variable declared in a MAP or COMMON statement or a parameter declared in a SUB, FUNCTION, or PICTURE. It cannot be a parameter declared in a DEF or DEF* function. 6. If a static string variable is the same as a map name, VAX BASIC uses the map name if the name appears in a MAP DYNAMIC statement. 7. The MAP DYNAMIC statement must lexically precede the REMAP statement or VAX BASIC signals the error "MAP variable <name> referenced before declaration". 1. Example 100 MAP (MY.BUF) STRING DUMMY= 512 MAP DYNAMIC (MY.BUF) STRING LAST, FIRST, MIDDLE, BYTE AGE, STRING EMPLOYER, STRING CHARACTERISTICS July 1988 & & Statements and Functions 4-1 91 MAR MAR The MAR function returns the current margin width of a specified channel. Format int-var= MAR[%] (chnl-exp) Syntax Rules The file associated with chnl-exp must be open. Remarks 1. If chnl-exp specifies a terminal and you have not set a margin width with the MARGIN statement, the MAR function returns a value of zero. If you have set a margin width, the MAR function returns that number. 2. The value returned by the MAR function is a LONG integer. Example DECLARE INTEGER width MARGIN #0, 80 width = MAR(O) PRINT width Output 80 4-192 Statements and Functions MARGIN MARGIN The MARGIN statement specifies the margin width for a terminal or for records in a terminal-format file. Format MARGIN [ #chn/-exp,] int-exp Syntax Rules 1. 2. Chnl-exp is a numeric expression that specifies a channel number associated with a file. It must be immediately preceded by a number sign ( # ). Int-exp specifies the margin width. Remarks 1. If you do not specify a channel, VAX BASIC sets the margin on the con trolling terminal. 2. The file associated with chnl-exp must be an open terminal-format file or terminal. VAX BASIC signals the error "Illegal operation" (ERR=141) if the file associated with chnl-exp is not a terminal-format file. If chnl-exp does not correspond to a terminal, and if int-exp is zero, VAX BASIC sets the right margin to the size specified by the RECORDSIZE clause in the OPEN statement, if the clause is present. If no RECORDSIZE clause is present, VAX BASIC sets the margin to 72 (or, in the case of channel 0, to the width of SYS$0UTPUT). If chnl-exp is not present or if it corresponds to a terminal, and if int-exp is zero, VAX BASIC sets the right margin to the size specified by the RECORDSIZE clause in the OPEN statement, if the clause is present. If no RECORDSIZE clause is present, VAX BASIC sets the margin to 72. 3. 4. 5. July 1988 Statements and Functions 4-193 MARGIN 6. VAX BASIC prints as much of a specified record as the margin setting allows on one line before going to a new line. Numeric fields are never split across lines. 7. If you specify a margin larger than the channel's record size, VAX BASIC signals an error. The default record size for a terminal or terminal format file is 132. 8. The MARGIN statement applies to the specified channel only while the channel is open. If you close the channel and then reopen it, VAX BASIC uses the default margin. Example OPEN "EMP.DAT" FOR OUTPUT AS #1 MARGIN #1, 132 4-194 Statements and Functions MAT MAT The MAT statement lets you implicitly create and manipulate one- and two-dimensional arrays. You can use the MAT statement to assign values to array elements, or to redimension a previously dimensioned array. You can also perform matrix arithmetic operations such as multiplication, addition, and subtraction, and other matrix operations such as transposing and inverting matrices. Format Numeric Initialization MAT num-array = { ~DONN } [ ( int-exp1 [, int-exp2])] ZER String Initialization MAT str-array = NUL$ [ ( int-exp1 [, int-exp2])] Array Arithmetic MAT num-array1 = num-array2 [ { : } num-array3 l MAT num-array1 = num-array2 * num-array3 [ * num-array4] ,... Scalar Multiplication MAT num-array4 = ( num-exp ) * num-array5 Inversion and Transposition MAT num-array6 = { TRN } ( num-arrayl) INV Statements and Functions 4-195 MAT Syntax Rules Int-exp1 and int-exp2 define the upper bounds of the array being implicitly created or the new dimensions of an existing array. 2. If you are creating an array, int-exp1 and int-exp2 cannot exceed 10. 3. If you do not specify bounds, VAX BASIC creates the array and dimensions it to (0 TO 10) or (10 TO 10, 0 TO 10). 4. If you specify bounds, VAX BASIC creates the array with the specified bounds. If the bounds exceed (0 TO 10) or (10 TO 10, 0 TO 10), VAX BASIC signals "Redimensioned array" (ERR=lOS). 5. The lower bounds must be zero. 1. Remarks 1. To perform MAT operations on arrays larger than (10,10), create the input and output arrays with the DIM statement. 2. When the array exists, the following rules apply: • If you specify upper bounds, VAX BASIC redimensions the array to the specified size. However, MAT operations cannot increase the total number of array elements. • All arrays specified with the MAT statement must have lower bounds of zero. If you supply a nonzero value, VAX BASIC signals either a compile-time or a run-time error. • If you do not specify bounds, VAX BASIC does not redimension the array. • An array passed to a subprogram and redimensioned with a MAT statement remains redimensioned when control returns to the calling program, with two exceptions: - When the array is within a record and is passed by descriptor - When the array is passed by reference 3. You cannot use the MAT statement on arrays of more than two dimensions. 4. You cannot use the MAT statement on arrays of data type DECIMAL or on arrays named in a RECORD statement. 4-196 Statements and Functions MAT 5. Initialization • CON sets all elements of num-array to 1, except those in row and column zero. • IDN creates an identity matrix from num-array. The number of rows and columns in num-array must be identical. IDN sets all elements to zero except those on the diagonal from num-array(l,l) to num-array(n,n), which are set to 1. • ZER sets all array elements to zero, except those in row and column zero. • NUL$ sets all elements of a string array to the null string, except those in row and column zero. 6. Array Arithmetic • The equal sign ( =) assigns the results of the specified operation to the elements in num-arrayl. • If num-array3 is not specified, VAX BASIC assigns the values of num-array2's elements to the corresponding elements of numarrayl. Num-arrayl must have at least as many rows and columns as num-array2. • Use the plus sign ( +) to add the elements of two arrays. Numarray2 and num-array3 must have identical bounds. • Use the minus sign ( - ) to subtract the elements of two arrays. Num-array2 and num-array3 must have identical bounds. • Use the asterisk ( *) to perform matrix multiplication on the elements of num-array2 and num-array3 and to assign the results to num-arrayl. This operation gives the dot product of num-array2 and num-array3. All three arrays must be two-dimensional, and the number of columns in num-array2 must equal the number of rows in num-array3. VAX BASIC redimensions num-arrayl to have the same number of rows as num-array2 and the same number of columns as num-array3. • With matrix multiplication, you can specify more than two numeric arrays. However, each array must be two-dimensional. Moreover, in each dimension, the lower bound of each array must be zero and the upper bound must be 4. You can use the graphics transformation functions, which will automatically create arrays with these dimensions. See the DRAW statement in Programming with VAX BASIC Graphics for more information. 7. Scalar Multiplication • VAX BASIC multiplies each element of num-array5 by num-exp and stores the results in the corresponding elements of num-array4. Statements and Functions 4-197 MAT Inversion and Transposition • TRN transposes num-array7 and assigns the results to num-array6. If num-array7 has m rows and n columns, num-array6 will have n rows and m columns. Both arrays must be two-dimensional. • You cannot transpose a matrix to itself: MAT A = TRN(A) is invalid. • INV inverts num-array7 and assigns the results to num-array6. Num-array7 must be a two-dimensional array that can be reduced to the identity matrix with elementary row operations. The row and column dimensions must be identical. 9. You cannot increase the number of array elements or change the number of dimensions in an array when you redimension with the MAT statement. For example, you can redimension an array with dimensions ( 5,4) to ( 4,5) or ( 3,2 ), but you cannot redimension that array to ( 5,5) or to ( 10 ). The total number of array elements includes those in row and column zero. 10. If an array is named in both a DIM statement and a MAT statement, the DIM statement must lexically precede the MAT statement. 11. MAT statements do not operate on elements in the zero element (onedimensional arrays) or in the zero row or column (two-dimensional arrays). MAT statements use these elements to store results of intermediate calculations. Therefore, you should not depend on values in row and column zero if your program uses MAT statements. 8. Examples Example 1 !Numeric Initialization MAT CONVERT = zer(10,10) Example 2 !Initialization MAT na_me$ = NUL$(6,6) 4-198 Statements and Functions MAT Example 3 !Array Arithmetic MAT new_int = old_int - rslt_int Example 4 !Scalar Multiplication MAT Z40 = (4.24) * Z Example 5 !Inversion and Transposition MAT QY. = INV (Z) Statements and Functions 4-199 MAT INPUT MAT INPUT The MAT INPUT statement assigns values from a terminal or terminalformat file to array elements. Format MAT INPUT [#chnl-exp,] {array [ ( int-exp1 [, int-exp2])] ), ... Syntax Rules 1. 2. 3. 4. 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 associated with chnl-exp must be an open terminal-format file or terminal. If chnl-exp is not specified, VAX BASIC takes data from the controlling terminal. Int-expl and int-exp2 define the upper bounds of the array being implicitly created or the dimensions of an existing array. If you are creating an array, int-expl and int-exp2 cannot exceed 10. Remarks You cannot use the MAT INPUT statement on arrays of more than two dimensions. 2. You cannot use the MAT INPUT statement on arrays of data type DECIMAL or on arrays named in a RECORD statement. 3. All arrays specified with the MAT INPUT statement must have lower bounds of zero. 4. If you do not specify bounds, VAX BASIC creates the array and dimensions it to (10,10). 1. 4-200 Statements and Functions MAT INPUT If you do specify upper bounds, VAX BASIC creates the array with the specified bounds. If the bounds exceed ( 10) or (10, 10), VAX BASIC signals "Redimensioned array" (ERR=105). 6. To use the MAT INPUT statement with arrays larger than (10,10), create the input and output arrays with the DIM statement. 7. When the array exists, the following rules apply: • If you specify bounds, VAX BASIC redimensions the array to the specified size. However, MAT INPUT cannot increase the total number of array elements. • If you do not specify bounds, VAX BASIC does not redimension the array. 8. The MAT INPUT statement prompts with a question mark on terminals open on channel #0 only unless a SET NO PROMPT statement has been executed. See the description of the SET PROMPT statement for more information. 9. Use commas to separate data elements and a line terminator to end the input of data. Use an ampersand(&) before the line terminator to continue data over more than one line. 10. The MAT INPUT statement assigns values by row. For example, it assigns values to all elements in row 1 before beginning row 2. 11. The MAT INPUT statement assigns the row number of the last data element transferred into the array to the system variable NUM. 12. The MAT INPUT statement assigns the column number of the last data element transferred into the array to the system variable NUM2. 13. If there are fewer elements in the input data than there are array elements, VAX BASIC does not change the remaining array elements. 14. If there are more data elements in the input stream than there are array elements, VAX BASIC ignores the excess. 15. Row zero and column zero are not changed. 16. For information about graphics input, see the MAT LOCATE and the MAT GET statements in Programming with VAX BASIC Graphics. 5. Statements and Functions 4-201 MAT INPUT Example MAT INPUT XYZ(5,5) MAT PRINT XYZ; Output 4-202 ? 1,2,3,4,5 1 2 3 4 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Statements and Functions MAT LINPUT MATLINPUT The MAT LINPUT statement receives string data from a terminal or terminal-format file and assigns it to string array elements. Format MAT LINPUT [#chnl-exp,] { str-array [ ( int-exp1 [, int-exp2])] ), ... Syntax Rules 1. 2. 3. 4. Chnl-exp is a numeric expression that specifies a channel number associated with a file or terminal. It must be immediately preceded by a number sign ( # ). The file associated with chnl-exp must be an open terminal-format file or terminal. If a channel is not specified, VAX BASIC takes data from the controlling terminal. Int-expl and int-exp2 define the upper bounds of the array being implicitly created or the dimensions of an existing array. If you are creating an array, int-expl and int-exp2 cannot exceed 10. Remarks 1. 2. 3. 4. You cannot use the MAT LINPUT statement on arrays of more than two dimensions. You cannot use the MAT LINPUT statement on arrays of data type other than STRING or on arrays named in a RECORD statement. If you do not specify bounds, VAX BASIC creates the array and dimensions it to (10,10). If you do specify upper bounds, VAX BASIC creates the array with the specified bounds. If the bounds exceed ( 10) or (10,10), VAX BASIC signals "Redimensioned array" (ERR=105). Statements and Functions 4-203 MAT LINPUT 5. All arrays specified with the MAT LINPUT statement must have lower bounds of zero. 6. To use MAT LINPUT with arrays larger than (10,10), create the input and output arrays with the DIM statement. 7. When the array exists, the following rules apply: • If you specify bounds, VAX BASIC redimensions the array to the specified size. However, MAT LINPUT cannot increase the total number of array elements. • If you do not specify bounds, VAX BASIC does not redimension the array. 8. For terminals open on channel zero only, the MAT LINPUT statement prompts with a question mark (unless a SET NO PROMPT statement has been executed) for each string array element, starting with element ( 1,1 ). VAX BASIC assigns values to all elements of row 1 before beginning row 2. 9. The MAT LINPUT statement assigns the row number of the last data element transferred into the array to the system variable NUM. 10. The MAT LINPUT statement assigns the column number of the last data element transferred into the array to the system variable NUM2. 11. Typing only a line terminator in response to the question mark prompt causes VAX BASIC to assign a null string to that string array element. 12. MAT LINPUT does not change row and column zero. Example DIM cus_rec$(3,3) MAT LINPUT cus_rec$(2,2) PRINT cus_rec$(1,1) 4-204 Statements and Functions MATLINPUT PRINT cus_rec$(1,2) PRINT cus_rec$(2,1) PRINT cus_rec$(2,2) Output ? Babcock ? Santani ? Lloyd ? Kelly Babcock Santani Lloyd Kelly Statements and Functions 4-205 MAT PRINT MAT PRINT The MAT PRINT statement prints the contents of a one- or twodimensional array on your terminal or assigns the value of each array element to a record in a terminal-format file. Format MAT PRINT [ #chnl-exp, ] (array [ ( int-exp 1 [, int-exp2] ) ] [ ; ] }. .. Syntax Rules Chnl-exp is a numeric expression that specifies a channel number associated with a file or terminal. It must be immediately preceded by a number sign ( # ). 2. The file associated with chnl-exp must be an open terminal-format file or terminal. If you do not specify a channel, VAX BASIC takes data from the controlling terminal. 3. Int-exp1 and int-exp2 define the upper bounds of the array being implicitly created or the dimensions of an existing array. 4. The separator (comma or semicolon) determines the output format for the array: • If you use a comma, VAX BASIC prints each array element in a new print zone and starts each row on a new line. • If you use a semicolon, VAX BASIC separates each array element with a space and starts each row on a new line. • If you do not use a separator character, VAX BASIC prints each array element on its own line. 1. 4-206 Statements and Functions MAT PRINT Remarks 1. 2. 3. 4. 5. 6. 7. 8. You cannot use the MAT PRINT statement on arrays of more than two dimensions. You cannot use the MAT PRINT statement on arrays of data type DECIMAL or on arrays named in a RECORD statement. When you use the MAT PRINT statement to print more than one array, each array name except the last must be followed with either a comma or a semicolon. VAX BASIC prints a blank line between arrays. If the array does not exist, the following rules apply: All arrays specified with the MAT PRINT statement must have lower bounds of zero. • If you do not specify bounds, VAX BASIC creates the array and dimensions it to (10, 10). • If you specify upper bounds, VAX BASIC creates the array with the specified bounds. If the bounds exceed ( 10) or (10,10), VAX BASIC prints the elements ( 10) or (10,10), and signals "Subscript out of range" (ERR=SS). When the array exists, the following rules apply: • If the specified bounds are smaller than the maximum bounds of a dimensioned array, VAX BASIC prints a subset of the array, but does not redimension the array. For example, if you use the DIM statement to dimension A(20,20), and then MAT PRINT A(2,2), VAX BASIC prints elements ( l, l ), ( 1,2 ), ( 2, l ), and ( 2,2) only; array A(20,20) does not change. • If you do not specify bounds, VAX BASIC prints the entire array. The MAT PRINT statement does not print elements in row or column zero. The MAT PRINT statement cannot redimension an array. Statements and Functions 4-207 MAT PRINT Example DIM cus_rec$(3,3) MAT LINPUT cus_rec$(2,2) MAT PRINT cus_rec$(2,2) Output ? Babcock ? Santani ? Lloyd ? Kelly Babcock Santani Lloyd Kelly 4-208 Statements and Functions MAT READ MAT READ The MAT READ statement assigns values from DATA statements to array elements. Format MAT READ {array [ ( int-exp 1 [, int-exp2] ) ] ), ... Syntax Rules 1. 2. Int-expl and int-exp2 define the upper bounds of the array being implicitly created or the dimensions of an existing array. If you are creating an array, int-expl and int-exp2 cannot exceed 10. Remarks 1. 2. 3. 4. 5. If you do not specify bounds, VAX BASIC creates the array and dimensions it to (10) or (10,10). If you specify bounds, VAX BASIC creates the array with the specified bounds. If the bounds exceed ( 10) or (10,10), VAX BASIC signals "Redimensioned array" (ERR=lOS). To read arrays larger than (10,10), create the array with the DIM statement. All arrays specified with the MAT statement must have lower bounds of zero. When the array exists, the following rules apply: • If you specify upper bounds, VAX BASIC redimensions the array to the specified size. However, MAT READ cannot increase the total number of array elements. • If you do not specify bounds, VAX BASIC does not redimension the array. Statements and Functions 4-209 MAT READ 6. All the DATA statements must be in the same program unit as the MAT READ statement. 7. The MAT READ statement assigns data items by row. For example, it assigns data items to all elements in row 1 before beginning row 2. 8. The MAT READ statement does not read elements into row or column zero. 9. The MAT READ statement assigns the row number of the last data element transferred into the array to the system variable, NUM. 10. The MAT READ statement assigns the column number of the last data element transferred into the array to the system variable, NUM2. 11. If you use MAT READ for an existing array without specifying bounds, VAX BASIC does not redimension the array. If you use MAT READ for an existing array and specify bounds, VAX BASIC redimensions the array. 12. You cannot use the MAT READ statement on arrays of more than two dimensions. 13. You cannot use the MAT READ statement on arrays of data type DECIMAL or on arrays named in a RECORD statement. Example MAT READ A(3,3) MAT READ B(3,3) PRINT PRINT "Matrix A" PRINT MAT PRINT A; PRINT PRINT "Matrix B" PRINT MAT PRINT B; DATA 1,2,3,4,5,6 4-210 Statements and Functions MAT READ Output Matrix A 1 4 0 2 6 0 3 6 0 Matrix B 0 0 0 0 0 0 0 0 0 Statements and Functions 4-211 MAX MAX The MAX function compares the values of two or more numeric expressions and returns the highest value. Format num-var = MAX ( num-exp 1, num-exp2 [, num-exp3 ,...]) Syntax Rules VAX BASIC allows you to specify up to eight numeric expressions. Remarks 1. If you specify values with different data types, VAX BASIC performs data type conversions to maintain precision. 2. VAX BASIC returns a function result whose data type is compatible with the values you supply. Example DECLARE REAL John_grade, t Bob_grade, t Joe_grade, t highest_grade INPUT "John's grade";John_grade INPUT "Bob's grade";Bob_grade INPUT "Joe's grade";Joe_grade highest_grade = MAX(John_grade, Bob_grade, Joe_grade) PRINT "The highest grade is";highest_grade 4-212 Statements and Functions MAX Output John's grade? 90 Bob's grade? 96 Joe's grade? 79 The highest grade is 96 Statements and Functions 4-213 MIDS MIDS MID$ can be used either as a statement or as a function. The MID$ statement performs substring insertion into a string. The MID$ function extracts a specified substring from a string expression. Format MID$ statement MID[$] ( str-var, int-exp1 [, int-exp2]) = str-exp MID$ function str-var =MID[$] (str-exp, int-exp 1, int-exp2) Syntax Rules Int-expl specifies the position of the substring's first character. 2. Int-exp2 specifies the length of the substring. 1. Remarks If int-expl is less than l, VAX BASIC assumes a starting character position of 1. 2. If int-exp2 is less than or equal to zero, VAX BASIC assumes a length of zero. 3. If you specify a floating-point expression for int-expl or int-exp2, VAX BASIC truncates it to a LONG integer. 4. MID$ statement • The MID$ statement replaces a specified portion of str-var with 1. str-exp. • 4-214 If int-expl is greater than the length of str-var, str-var remains unchanged. Statements and Functions MIDS • The length of str-var does not change regardless of the value of int-exp2. • If the optional int-exp2 is not specified, VAX BASIC assumes intexp 2 to be the length of str-exp minimized by the length of str-var minus int-exp1. For example: A$ = "ABCDEFG" MID$ (A$,3) = 11 123456789 11 PRINT A$ Output "AB12345" • • • If int-exp2 is less than or equal to zero, str-var remains unchanged. If int-exp2 is greater than the length of str-var, VAX BASIC assumes int-exp2 to be equal to the length of str-var. Int-exp2 is always minimized against the length of str-var minus int-exp1. 5. MID$ function • The MID$ function extracts a substring from str-exp and stores it in str-var. • If int-exp1 is greater than the length of str-exp, MID$ returns a null string. • If int-exp2 is greater than the length of str-exp, VAX BASIC returns the string that begins at int-exp1 and includes all characters remaining in str-exp. • If int-exp2 is less than or equal to zero, MID$ returns a null string. Examples Example 1 !MID$ Function DECLARE STRING old_string, new_string old_string = 11 ABCD 11 new_string = MID$(old_string,1,3) PRINT new_string Output 1 ABC Statements and Functions 4-215 MIDS Example 2 !MID$ Statement DECLARE STRING old_string, replace_string old_string = "ABCD" replace_string = "123" PRINT old_string MID$(old_string,1,3) = replace_string PRINT old_string Output 2 ABCD 123D 4-216 Statements and Functions MIN MIN The MIN function compares the values of two or more numeric expressions and returns the smallest value. Format num-var =MIN ( num-exp1, num-exp2 [, num-exp3 ,... ]) Syntax Rules VAX BASIC allows you to specify up to eight numeric expressions. Remarks 1. 2. If you specify values with different data types, VAX BASIC performs data type conversions to maintain precision. VAX BASIC returns a function result whose data type is compatible with the values you supply. Example DECLARE REAL John_grade, ~ Bob_grade, ~ Joe_grade, ~ lowest_grade Statements and Functions 4-217 MIN INPUT "John's grade";John_grade INPUT "Bob's grade";Bob_grade INPUT "Joe's grade";Joe_grade lowest_grade = MIN(John_grade, Bob_grade, Joe_grade) PRINT "The lowest grade is";lowest_grade Output John's grade? 96 Bob's grade? 100 Joe's grade? 84 The lowest grade is 84 4-218 Statements and Functions MOD MOD The MOD function divides a numeric value by another numeric value and returns the remainder. Format num-var =MOD ( num-exp1, num-exp2) Syntax Rules Num-expl is divided by num-exp2. Remarks 1. If you specify values with different data types, VAX BASIC performs data type conversions to maintain precision. 2. VAX BASIC returns a function result whose data type is compatible with the values you supply. 3. The function result is either a positive or negative value, depending on the value of the first numeric expression. For example, if the first numeric expression is negative, then the function result will also be negative. Statements and Functions 4-219 MOO Example DECLARE REAL A,B A = 500 B = MOD(A,70) PRINT "The remainder equals";B Output The remainder equals 10 4-220 Statements and Functions MOVE MOVE The MOVE statement transfers data between a record buffer and a list of variables. Format MOVE { TO } FROM move-item: #chnl-exp, move-item, ... num-var num-array ( [,]... ) str-var [=int-exp] str-array ( [,]... ) [=int-exp] [data-type] FILL [ (int-exp)] [=int-canst] FILL% [ (int-exp)] FILL$ [ (int-exp)] [=int-exp] Syntax Rules 1. Chnl-exp is a numeric expression that specifies a channel number associated with a file. It must be immediately preceded by a number sign{#). 2. Move-item specifies the variable or array to which or from which data is to be moved. 3. Parentheses indicate the number of dimensions in a numeric array. The number of dimensions is equal to the number of commas plus 1. Empty parentheses indicate a one-dimensional array, one comma indicates a two-dimensional array, and so on. Statements and Functions 4-221 MOVE Str-var and str-array specify a fixed length string variable or array. · Parentheses indicate the number of dimensions in a string array. The number of dimensions is equal to the number of commas plus 1. You can specify the number of bytes to be reserved for the variable or array elements with the =int-exp clause. The default string length for a MOVE FROM statement is 16. For a MOVE TO statement, the default is the string's length. 5. The FILL, FILL%, and FILL$ keywords allow you to transfer fill items of a specific data type. Table 4-2 shows FILL item formats, representations, and storage requirements. • If you specify a data type before the FILL keyword, the fill is of that data type. If you do not specify a data type, the fill is of the default data type. Data-type can be any VAX BASIC data type keyword or a data type defined by a RECORD statement. Data type keywords, size, range, and precision are listed in Table 1-2 in this manual. • FILL items following a data type other than STRING cannot end with a dollar sign. FILL items following a data type other than BYTE, WORD, LONG or INTEGER, cannot end with a percent sign. • Int-exp specifies the number of FILL items to be moved. • FILL% indicates integer fill. FILL$ indicates string fill. The =intexp clause specifies the number of bytes to be moved for string FILL items. • In the applicable formats of FILL, (int-exp) represents a repeat count, not an array subscript. FILL (n), for example, represents n elements, not n + 1. 6. You cannot use an expression or function reference as a move-item. 4. Remarks 1. Before a MOVE FROM statement can execute, the file associated with chnl-exp must be open and there must be a record in the record buffer. 2. 4-222 A MOVE statement neither transfers data to or from external devices, nor invokes the VAX Record Management Services (RMS). Instead, it transfers data between user areas. Thus, a record should first be fetched with the GET statement before you use a MOVE FROM statement, and a MOVE TO statement should be followed by a PUT or UPDATE statement that writes the record to a file. Statements and Functions MOVE 3. 4. 5. 6. MOVE FROM transfers data from the record buffer to the move-item. MOVE TO transfers data from the move-item to the record buffer. The MOVE statement does not affect the record buffer's size. If a MOVE statement partially fills a buffer, the rest of the buffer is unchanged. If there is more data in the variable list than in the buffer, VAX BASIC signals "MOVE overflows buffer" (ERR=161). Each MOVE statement to or from a channel transfers data starting at the beginning of the buffer. For example: MOVE FROM #1Y., IY.. AS = IY. In this example, VAX BASIC assigns the first value in the record buffer to 1%; the value of 1% is then used to determine the length of A$. 7. If a MOVE statement operates on an entire array, the following conditions apply: • VAX BASIC transfers elements of row and column zero (in contrast to the MAT statements). • The storage size of the array elements and the size of the array determine the amount of data moved. A MOVE statement that transfers data from the buffer to a longword integer array transfers the first four bytes of data into the first element (for example, (0,0)), the next four bytes of data into element ( 0,1 ), and so on. 8. If the MOVE TO statement specifies an explicit string length, the following restrictions apply: • If the string is equal to or longer than the explicit string length, VAX BASIC moves only the specified number of characters into the buffer. • If the string is shorter than the explicit string length, VAX BASIC moves the entire string and pads it with spaces to the specified length. 9. VAX BASIC does not check the validity of data during the MOVE operation. :xample MOVE FROM #4Y., RUNSY., HITSY., ERRORSY., RBIY.. BAT_AVERAGE MOVE TO #9Y., FILLS = 10Y., AS = 10Y., BS = 30Y., CS = 2Y. Statements and Functions 4-223 NAME ... AS NAME ... AS The NAME ... AS statement renames the specified file. Format NAME file-spec 1 AS file-spec2 Syntax Rules 1. File-specl and file-spec2 must be string expressions. 2. There is no default file type in file-specl or file-spec2. If the file to be renamed has a file type, file-specl must include both the file name and the file type. 3. If you specify only a file name, VAX BASIC searches for a file with no file type. If you do not specify a file type for file-spec2, VAX BASIC names the file, but does not assign a file type. 4. You can include a directory name but not a device name. If you specify a directory name with file-spec2, the file will be placed in the specified directory. If you do not specify a directory name the default is the current directory. 5. File version numbers are optional. VAX BASIC renames the highest version of file-specl if you do not specify a version number. Remarks 1. If the file specified by file-specl does not exist, VAX BASIC signals "Can't find file or account" (ERR=S). 2. If you use the NAME ... AS statement on an open file, VAX BASIC does not rename the file until it is closed. 3. You cannot use the NAME ... AS statement to move a file between devices. You can only change the directory, name, type, or version number. 4-224 Statements and Functions NAME...AS :xample $Directory USER$$DISK:[BASIC_PROG] Directory USER$$DISK:[BASIC_PROG] FIRST_PROG.BAS;1 Total of 1 file. $ BASIC VAX BASIC V3.0 Ready NAME 11 FIRST_PROG.BAS 11 AS 11 SECOND_PROG.BAS 11 Ready EXIT $Directory USER$$DISK:[BASIC_PROG] Directory USER$$DISK: [BASIC_PROG] SECOND_PROG.BAS;1 Total of 1 file. Statements and Functions 4-225 NEXT NEXT The NEXT statement marks the end of a FOR, UNTIL, or WHILE loop. Format NEXT [ num-unsubs-var] Syntax Rules 1. 2. 3. Num-unsubs-var is required in a FOR. .. NEXT loop and must correspond to the num-unsubs-var specified in the FOR statement. Num-unsubs-var is not allowed in an UNTIL or WHILE loop. Num-unsubs-var must be a numeric, unsubscripted variable. Remarks Each NEXT statement must have a corresponding FOR, UNTIL, or WHILE statement or VAX BASIC signals an error. Example PROGRAM calculating_pay DECLARE INTEGER no_hours, & SINGLE weekly_pay, minimum_wage minimum_wage = 3.66 no_hours = 40 WHILE no_hours > 0 INPUT "Enter the number of hours you intend to work this week";no_hours weekly_pay = no_hours * minimum_wage PRINT "If you worked";no_hours;"hours, your pay would be";weekly_pay NEXT END PROGRAM 4-226 Statements and Functions NEXT Output Enter the number of hours you intend to work this week? 35 If you worked 35 hours, your pay would be 127.75 Enter the number of hours you intend to work this week? 23 If you worked 23 hours, your pay would be 83.95 Enter the number of hours you intend to work this week? 0 If you worked 0 hours your pay would be 0 Statements and Functions 4-227 NOE CHO NO ECHO The NOECHO function disables echoing of input on a terminal. Format int-var= NOECHO (chnl-exp) Syntax Rules Chnl-exp must specify a terminal. Remarks 1. 2. 3. If you specify NOECHO, VAX BASIC accepts characters typed on the terminal as input, but the characters do not echo on the terminal. The NOECHO function is the complement of the ECHO function; NOECHO disables the effect of ECHO and vice versa. NOECHO always returns a value of zero. Example DECLARE INTEGER Y, k STRING pass_word Y = NOECHO(O) INPUT "Enter your password";pass_word IF pass_word = "DARLENE" THEN PRINT "Confirmed" Y = ECHO(O) Output Enter your password? Confirmed 4-228 Statements and Functions NOMARGIN ~OMARGIN The NOMARGIN statement removes the right margin limit set with the MARGIN statement for a terminal or a terminal-format file. Format NOMARGIN [ #chnl-exp] Syntax Rules Chnl-exp is a numeric expression that specifies a channel number associated with a file. It must be immediately preceded by a number sign {# ). Remarks When you specify NOMARGIN, the right margin is set to 132. 2. Chnl-exp, if specified, must be an open terminal-format file or a terminal. 3. If you do not specify a channel, VAX BASIC sets the margin on the controlling terminal to 132. 4. The NOMARGIN statement applies to the specified channel only while the channel is open. If you close the channel and then reopen it, VAX BASIC uses the default margin of 72. 1. Statements and functions 4-229 NOMARGIN Example OPEN "EMF.DAT" FOR OUTPUT AS #1 NOMARGIN #1 4-230 Statements and Functions NUM NUM The NUM function returns the row number of the last data element transferred into an array by a MAT 1/0 statement. Format int-var= NUM Syntax Rules None. Remarks 1. 2. 3. NUM returns a value of zero if it is invoked before VAX BASIC has executed any MAT 1/0 statements. For a two-dimensional array, NUM returns an integer specifying the row number of the last data element transferred into the array. For a one-dimensional array, NUM returns the number of elements entered. The value returned by the NUM function is an integer of the default size. Statements and Functions 4-231 NUM Example OPEN "STU_ACCT" FOR INPUT AS #2 DIM stu_rec$(3,3) MAT INPUT #2, stu_rec$ PRINT "Row count =";NUM PRINT "Column number =";NUM2 Output Row count = 1 Column number = 1 4-232 Statements and Functions NUM2 NUM2 The NUM2 function returns the column number of the last data element transferred into an array by a MAT 1/0 statement. format int-var= NUM2 Syntax Rules None. Remarks 1. 2. 3. NUM2 returns a value of zero if it is invoked before VAX BASIC has executed any MAT 1/0 statements or if the last array element transferred was in a one-dimensional list. The NUM2 function returns an integer specifying the column number of the last data element transferred into an array. The value returned by the NUM2 function is an integer of the default size. Statements and Functions 4-233 NUM2 Example OPEN 11 STU_ACCT 11 FOR INPUT AS #2 DIM stu_rec$(3,3) MAT INPUT #2, stu_rec$ PRINT "Row count =11 ;NUM PRINT "Column number =";NUM2 Output Row count = 1 Column number = 1 4-234 Statements and Functions NUMS NUMS The NUM$ function evaluates a numeric expression and returns a string of characters in PRINT statement format, with leading and trailing spaces. Format str-var = NUM$ (num-exp) Syntax Rules None. Remarks 1. If num-exp is positive, the first character in the string expression is a space. If num-exp is negative, the first character is a minus sign ( - ). 2. The NUM$ function does not include trailing zeros in the returned string. If all digits to the right of the decimal point are zeros, NUM$ omits the decimal point as well. 3. When num-exp is a floating-point variable and has an integer portion of six decimal digits or less (for example, 1234.567), VAX BASIC rounds the number to six digits (1234.57). If num-exp has seven decimal digits or more, VAX BASIC rounds the number to six digits and prints it in E format. 4. When num-exp is between 0.1 and 1 and contains more than six digits, VAX BASIC rounds it to six digits. When num-exp is smaller than 0.1, VAX BASIC rounds it to six digits and prints it in E format. 5. If num-exp is a longword integer, the returned string can have up to 10 digits. 6. If num-exp is a DECIMAL value, the returned string can have up to 31 digits. 7. The last character in the returned string is a space. Statements and Functions 4-235 NUMS Example DECLARE STRING number number = NUM$(34.6600/31.8) PRINT number Output 1.08648 4-236 Statements and Functions NUM1S IUM1S The NUM1$ function changes a numeric expression to a numeric character string without leading and trailing spaces and without rounding. Format str-var = NUM1$ (num-exp) Syntax Rules None. Remarks The NUM1$ function returns a string consisting of numeric characters and a decimal point that corresponds to the value of num-exp. Leading and trailing spaces are not included in the returned string. 2. The NUM1$ function returns a maximum of • 3 digits for BYTE integers • 5 digits for SINGLE floating-point numbers and WORD integers • 10 digits for LONG integers • 16 digits for DOUBLE floating-point numbers • 15 digits for GFLOAT floating-point numbers • 33 digits for HFLOAT floating-point numbers • 31 digits for DECIMAL numbers 3. The NUM1$ function does not produce E notation. 1. Statements and Functions 4-237 NUM1$ Example DECLARE STRING number number = NUM1$(PI/2) PRINT number Output 1.5708 4-238 Statements and Functions ON ERROR GO BACK ON ERROR GO BACK Under certain conditions, an ON ERROR GO BACK statement executed in a subprogram or DEF function transfers control to the calling program. NOTE The ON ERROR GO BACK statement is supported for compatibility with other DIGITAL BASICs. For new program development, DIGITAL recommends that you use WHEN blocks. Format } GO BACK { ONERROR ON ERROR Syntax Rules The ON ERROR GO BACK statement is illegal inside a protected region or within an attached or detached handler. Use the EXIT HANDLER statement instead. Remarks 1. If there is no error outstanding, execution of an ON ERROR GO BACK statement causes subsequent errors to return control to the calling program's error handler. 2. If there is an error outstanding, execution of an ON ERROR GO BACK statement immediately transfers control to the calling program's error handler. 3. By default, DEF functions and subprograms re-signal errors to the calling program. Statements and Functions 4-239 ON ERROR GO BACK 4. The ON ERROR GO BACK statement remains in effect until the program unit completes execution, until VAX BASIC executes another ON ERROR statement, or until VAX BASIC enters a protected region. 5. An ON ERROR GO BACK statement executed in the main program is equivalent to an ON ERROR GOTO 0 statement. 6. If a main program calls a subprogram named SUBl, and SUBl calls the subprogram named SUB2, an ON ERROR GO BACK statement executed in SUB2 transfers control to SUBl's error handler when an error occurs in SUB2. If SUBl also has executed an ON ERROR GO BACK statement, VAX BASIC transfers control to the main program's error handling routine. 7. For current program development, see the WHEN ERROR statement. 8. DIGITAL does not recommend that you mix ON ERROR statements with protected regions in the same program unit. For more information, see the VAX BASIC User Manual. Example IF ERR = 11 THEN RESUME err_hand ELSE ON ERROR GO BACK END IF 4-240 Statements and Functions ON ERROR GOTO ON ERROR GOTO The ON ERROR GOTO statement transfers program control to a specified line or label in the current program unit when an error occurs under certain conditions. NOTE The ON ERROR GOTO statement is supported for compatibility with other DIGITAL BASICs. For new program development, DIGITAL recommends that you use WHEN blocks. Format ONERROR } { GO TO } { ON ERROR GOTO target Syntax Rules 1. You cannot specify an ON ERROR GOTO statement within a protected region or handler. 2. Target must be a valid VAX BASIC line number or label and must exist in the same program unit as the ON ERROR GOTO statement. 3. If an ON ERROR GOTO statement is in a DEF function, target must also be in that function definition. Statements and Functions 4-241 ON ERROR GOTO Remarks 1. 2. 3. 4. 5. 6. VAX BASIC transfers program control to a specified line number or label under two conditions: • If an error does not occur within the protected region of WHEN block. • If an error occurs within the protected region of a WHEN block and was propagated by the handler associated with the WHEN block. Execution of an ON ERROR GOTO statement causes subsequent errors to transfer control to the specified target. The ON ERROR GOTO statement remains in effect until the program unit completes execution or until VAX BASIC executes another ON ERROR statement. VAX BASIC does not allow recursive error handling. If a second error occurs during execution of an error-handling routine, control passes to the VAX BASIC error handler and the program stops executing. For current program development, see the WHEN ERROR statement. DIGITAL does not recommend that you mix ON ERROR statements with protected regions within the same program unit. For more information, see the VAX BASIC User Manual. Example SUB LIST (STRING A) DECLARE STRING B ON ERROR GOTO err_block OPEN A FOR INPUT AS FILE #1 Input_loop: LINPUT #1, B 4-242 Statements and Functions ON ERROR GOTO PRINT B GOTO Input_loop err_block: IF (ERR=11Y.) THEN CLOSE #1'X RESUME done ELSE ON ERROR GOTO 0 END IF done: END SUB Statements and Functions 4-243 ON ERROR GOTO 0 ON ERROR GOTO 0 The ON ERROR GOTO 0 statement disables ON ERROR error handling and passes control to the VAX BASIC error handler when an error occurs. NOTE The ON ERROR GOTO 0 statement is supported for compatibility with other DIGITAL BASICs. For new program development, DIGITAL recommends that you use WHEN blocks. Format ERROR } { GO TO } { ON ONERROR GOTO O Syntax Rules VAX BASIC does not allow you to specify an ON ERROR GOTO 0 statement within an attached or detached handler or within a protected region. Remarks 1. 2. If an error is outstanding, execution of an ON ERROR GOTO 0 statement immediately transfers control to the VAX BASIC error handler. The VAX BASIC error handler will report the error and exit the program. If there is no error outstanding, execution of an ON ERROR GOTO 0 statement causes subsequent errors to transfer control to the VAX BASIC error handler. 4-244 Statements and Functions ON ERROR GOTO 0 3. When an ON ERROR GOTO 0 statement is executed, control is transferred to the VAX BASIC error handler if an error did not occur within the protected region of a WHEN block. 4. If an error occurs within the protected region of a WHEN block and was propagated by the handler associated with the WHEN block, VAX BASIC transfers control to the specified line number or label contained in the subprogram or DEF. 5. For current program development, see the WHEN ERROR statement. 6. DIGITAL does not recommend that you mix ON ERROR statements with attached or detached handlers within the same program unit. For more information, see the VAX BASIC User Manual. Example ON ERROR GOTO err_routine FOR I = 1% TO 10% PRINT "Please type a number" INPUT A NEXT I err_routine: IF ERR = 50 THEN RESUME ELSE ON ERROR GOTO 0 END IF Output Please type a number ? ICTRL/ZI Y.BAS-F-ILLUSADEV, Illegal usage for device -BAS-I-ON_CHAFIL, on channel 0 for file SYS$INPUT: [TUTTI]SYSINPUT.DAT; at user PC 00000632 -RMS-F-DEV, error in device name or inappropriate device type for operation -BAS-I-FROLINMOD, from line 10 in module BADUSER Statements and Functions 4-245 ON ... GOSUB ON ... GOSUB The ON ... GOSUB statement transfers program control to one of several subroutines, depending on the value of a control expression. Format ON int-exp GOSUB target, ... [OTHERWISE target] Syntax Rules Int-exp determines which target VAX BASIC selects as the GOSUB argument. If int-exp equals 1, VAX BASIC selects the first target. If int-exp equals 2, VAX BASIC selects the second target, and so on. 2. Target must be a valid VAX BASIC line number or label and must exist 1. in the current program unit. Remarks Control cannot be transferred into a statement block (such as FOR ... NEXT, UNTIL.NEXT, WHILE ... NEXT, DEF ... END DEF, SELECT ... END SELECT, WHEN ... END WHEN, or HANDLER. .. END HANDLER). 2. If there is an OTHERWISE clause, and if int-exp is less than 1 or greater than the number of targets in the list, VAX BASIC selects the target of the OTHERWISE clause. 3. If there is no OTHERWISE clause, and if int-exp is less than 1 or greater than the number of targets in the list, VAX BASIC signals "ON statement out of range" (ERR=58). 4. If a target specifies a nonexecutable statement, VAX BASIC transfers control to the first executable statement that lexically follows the target. 5. You can only use the ON ... GOSUB statement inside a handler if all the targets are contained within the handler. 1. 4-246 Statements and Functions ON ... GOSUB 6. If you fail to handle an exception that occurs while an ON ... GOSUB statement in the body of a subroutine is executing, the exception is handled by the default error handler. The exception is not handled by any WHEN block surrounding the ON ... GOSUB statement that invoked the subroutine. 7. You can specify the ON ... GOSUB statement inside a WHEN block if the ON ... GOSUB target is in the same protected region, an outer protected region, or in a non-protected region. 8. You cannot specify an ON ... GOSUB statement inside a WHEN block if the ON ... GOSUB target already resides in another protected region that does not contain the most current protected region. 9. The target cannot be more than 32767 bytes away from the ON ... GOSUB statement. Example 100 INPUT "Please enter 1, 2 or 3"; A% ON A% GOSUB 1000, 2000, 3000, OTHERWISE err_routine GOTO done 1000 PRINT "That was a 1" RETURN PRINT "That was a 2" RETURN PRINT "That was a 3" RETURN 2000 3000 err_routine: PRINT "Out of range: RETURN done: END PROGRAM July 1988 Statements and Functions 4-24 7 ON ... GOTO ON ... GOTO The ON ... GOTO statement transfers program control to one of several lines or targets, depending on the value of a control expression. Format ON int-exp { GO TO } target, ... [OTHERWISE target] GOTO Syntax Rules 1. 2. Int-exp determines which target VAX BASIC selects as the GOTO argument. If int-exp equals 1, VAX BASIC selects the first target. If int-exp equals 2, VAX BASIC selects the second target, and so on. Target must be a valid VAX BASIC line number or a label and must exist in the current program unit. Remarks 1. 2. 3. 4. Control cannot be transferred into a statement block (such as FOR. .. NEXT, UNTIL.NEXT, WHILE ... NEXT, DEF ... END DEF, SELECT...END SELECT, WHEN ... END WHEN, or HANDLER ... END HANDLER). If there is an OTHERWISE clause, and if int-exp is less than one or greater than the number of targets in the list, VAX BASIC transfers control to the target of the OTHERWISE clause. If there is no OTHERWISE clause, and if int-exp is less than 1 or greater than the number of line numbers in the list, VAX BASIC signals "ON statement out of range" (ERR=58). If a target specifies a nonexecutable statement, VAX BASIC transfers control to the first executable statement that lexically follows the target. 4-248 Statements and Functions ON ... GOTO 5. 6. 7. You can only use the ON ... GOTO statement inside a handler if all the targets are contained within the handler. You can specify the ON ... GOTO statement inside a WHEN block if the ON ... GOTO target is in the same protected region, an outer protected region, or in a non-protected region. You cannot specify an ON ... GOTO statement inside a WHEN block if the ON ... GOTO target already resides in another protected region that does not contain the most current protected region. Example ON INDEX% GOTO 700,800,900 OTHERWISE finish finish: END PROGRAM Statements and Functions 4-249 OPEN OPEN The OPEN statement opens a file for processing. It transfers user-specified file characteristics to VAX Record Management Services (RMS) and verifies the results. Format OPEN file-spec 1 [ FOR INPUT ] AS [ FILE ] [#] chnl-exp FOR OUTPUT [, open-clause ]. .. open-clause: ACCESS ALLOW APPEND READ WRITE MODIFY SCRATCH I=~:~ l] WRITE MODIFY [ BUFFER int-exp4 ] [ CONTIGUOUS 1 [ DEFAULTNAME file-spec2 ] [ EXTENDSIZE int-exp5 ] [ FILESIZE int-exp2 ] 4-250 Statements and Functions OPEN [MAP map-name ] [ORGANIZATION] l [ ! I INDEXED RELATIVE SEQUENTIAL UNDEFINED VIRTUAL STREAM VARIABLE FIXED [ RECORDSIZE int-exp 1 ] RECORDTYPE { [ ~~JTRAN } NONE ANY [ TEMPORARY l [ UNLOCK EXPLICIT l [ USEROPEN tune-name l [ WINDOWSIZE int-exp3 ] Sequential Files Only [ BLOCKSIZE int-expB ] [ NOREWIND l [ NOSPAN l [SPAN l Relative and Indexed Files Only [ BUCKETSIZE int-exp9 ] July 1988 Statements and Functions 4-251 OPEN Indexed Files Only ALTERNATE [KEV] key-clause [DUPLICATES] [CHANGES] [ ASCENDING ] [ DESCENDING l [ CONNECT chnl-exp2 ] [PRIMARY [KEY] key-clause [DUPLICATES] [ key-clause: l ~~~~~~~~:G ] ] int-unsubs-var decimal-unsubs-var str-unsubs-var (str-unsubs-var1 ,... str-unsubs-varB) quad-record-group l Syntax Rules 1. File-specl specifies the file to be opened and associated with chnl-exp. It can be any valid string expression and must be a valid VMS file specification. VAX BASIC passes these values to RMS without editing, alteration, or validity checks. VAX BASIC does not supply any default file specifications, unless you include the DEFAULTNAME clause in the OPEN statement. 2. The FOR clause determines how VAX BASIC opens a file. • If you open a file with FOR INPUT, the file must exist or VAX BASIC signals an error. • If you open a file with FOR OUTPUT, VAX BASIC creates the file if it does not exist. If the file does exist, VAX BASIC creates a new version of the file. • If you do not specify either FOR INPUT or FOR OUTPUT, VAX BASIC tries to open an existing file. If there is no such file, VAX BASIC creates one. 4-252 Statements and Functions July 1988 OPEN 3. Chnl-exp is a numeric expression that specifies a channel number to be associated with the file being opened. It can be preceded by an optional number sign ( # ) and must be in the range of 1 through 119. Note that channels 100 through 119 are usually reserved for allocation by the RTL routines, LIB$GET_LUN and LIB$FREE_LUN. Statements and Functions 4-252.1 OPEN 4. A statement that accesses a file cannot execute until you open that file and associate it with a channel. Remarks 1. The OPEN statement does not retrieve records. 2. Channel #0, the terminal, is always open. If you try to open channel zero, VAX BASIC signals the error "Illegal I/O channel" (ERR=46). 3. If a program opens a file on a channel already associated with an open file, VAX BASIC closes the previously opened file and opens the new one. 4. The ACCESS clause determines how the program can use the file. • ACCESS READ allows only FIND, GET, or other input statements on the file. The OPEN statement cannot create a file if the ACCESS READ clause is specified. • ACCESS WRITE allows only PUT, UPDATE, or other output statements on the file. • ACCESS MODIFY allows any I/O statement except SCRATCH on the file. ACCESS MODIFY is the default. • ACCESS SCRATCH allows any I/O statement valid for a sequential or terminal-format file. • ACCESS APPEND is the same as ACCESS WRITE for sequential files, except that VAX BASIC positions the file pointer after the last record when it opens the file. You cannot use ACCESS APPEND on relative or indexed files. 5. The ALLOW clause can be used in the OPEN statement to specify file sharing of relative, indexed, sequential, and virtual files. • ALLOW NONE lets no other users access the file. This is the default if any access other than READ is specified. Note that you must have write access to the file in order to specify ALLOW NONE. • ALLOW READ lets other users have read access to the file. • ALLOW WRITE lets other users have write access to the file. • ALLOW MODIFY lets other users have unlimited access to the file. Statements and Functions 4-253 OPEN The BLOCKSIZE clause specifies the physical block size of magnetic tape files. The BLOCKSIZE clause can be used for magnetic tape files only. • The value of int-expB is the number of records in a block. Therefore, the block size in bytes is the product of the RECORDSIZE and the BLOCKSIZE value. • The default blocksize is one record. 7. The BUCKETSIZE clause applies only to relative and indexed files. It specifies the size of an RMS bucket in terms of the number of records one bucket should hold. • The value of int-exp9 is the number of records in a bucket. • The default is one record. 8. The BUFFER clause can be used with all file organizations except UNDEFINED. • For RELATIVE and INDEXED files, int-exp4 specifies the number of device or file buffers RMS uses for file processing. • For SEQUENTIAL files, int-exp4 specifies the size of the buffer; for example, BUFFER 8 for a SEQUENTIAL file sets the buffer size to eight 512-byte blocks. • DIGITAL recommends that you accept the system defaults or change the defaults with the DCL SET RMS_DEFAULT command. 6. 9. The CONTIGUOUS clause causes RMS to try to create the file as a contiguous-best-try sequence of disk blocks. The CONTIGUOUS clause does not affect existing files or nondisk files. The CONTIGUOUS clause does not guarantee that the file will occupy contiguous disk space. If RMS can locate the file in a contiguous area, it will do so. However, if there is not enough free contiguous space for a file, RMS allocates the largest possible contiguous space and does not signal an error. See the VAX Record Management Services Reference Manual for more information on contiguous disk allocation. 10. The CONNECT clause permits multiple record streams to be connected to the file. • The CONNECT clause must specify an INDEXED file already opened on chnl-exp2 with the primary OPEN statement. • You cannot connect to a connected channel; you can connect only to the initially opened channel. 4-254 Statements and Functions OPEN • • You can connect more than one stream to an open channel. All clauses of the two files to be connected must be identical except MAP, CONNECT, and USEROPEN. • Do not use the CONNECT clause when accessing files over DECnet or VAX BASIC will signal the error "Cannot open file" (ERR=l62). 11. The DEFAULTNAME clause lets you supply a default file specification. If file-spec1 is not a complete file specification, file-spec2 in the DEFAULTNAME clause supplies the missing parts. For example: 10 20 INPUT 'FILE NAME' ;fnam$ OPEN fnam$ FOR INPUT AS FILE #1%, & DEFAULTNAME 11 USER$$DISK:. DAT" If you type "ABC" for the file name, VAX BASIC tries to open USER$$DISK:[]ABC.DAT. 12. The EXTENDSIZE clause lets you specify the increment by which RMS extends a file after its initial allocation is filled. The value of int-exp5 is in 512-byte disk blocks. The EXTENDSIZE clause has no effect on an existing file. 13. The FILESIZE clause lets you pre-extend a new file to a specified size. • The value of int-exp2 is the initial allocation of disk blocks. • The FILESIZE clause has no effect on an existing file. 14. The MAP clause specifies that a previously declared map is associated with the file's record buffer. The MAP clause determines the record buffer's address and length unless overridden by the RECORDSIZE clause. • The size of the specified map must be as large or larger than the longest record length or maximum record size. For files with a fixed record size, the specified map must match exactly. • The size of the largest MAP with the same map name in the current program unit becomes the file's record size if the OPEN statement does not include a RECORDSIZE clause. • DIGITAL recommends that you do not use both the MAP and RECORDSIZE clauses in an OPEN statement. However, if you do use both the MAP and RECORDSIZE clauses in an OPEN statement, the following rules apply: The RECORDSIZE clause overrides the record size set by the MAP clause. July 1988 Statements and Functions 4-255 OPEN - The map must be as large or larger than the specified RECORDSIZE. • If there is no MAP clause, the record buffer space that VAX BASIC allocates is not directly accessible. Therefore, MOVE statements are needed to access data in the record buffer. • You must have a MAP clause when creating an indexed file; you cannot use KEY clauses without MAP statements because keys serve as offsets into the buffer. • The size of the specified map cannot exceed 32767 bytes. 15. The NOREWIND clause controls tape positioning on magnetic tape files. The NOREWIND clause can be used for magnetic tape files only. • If you specify NOREWIND, the OPEN statement does not position the tape at the beginning. Your program can search for records from the current position. • If you do not specify either ACCESS APPEND or NOREWIND, the OPEN statement positions the tape at its beginning and then searches for the file. 16. The NOSP AN clause specifies that sequential records cannot cross block boundaries. • SP AN specifies that records can cross block boundaries. SP AN is the default. • The NOSP AN clause does not affect nondisk files. 17. The ORGANIZATION clause specifies the file organization. When present, it must precede all other clauses. When you specify an ORGANIZATION clause, you must also specify one of the following organization options: VIRTUAL, UNDEFINED, INDEXED, SEQUENTIAL or RELATIVE. Specify ORGANIZATION UNDEFINED if you do not know the actual organization of the file. If you do not specify an ORGANIZATION clause VAX BASIC opens a terminal format file by default. • When you specify ORGANIZATION VIRTUAL, you create a sequentially fixed file with a record size of 512 (or a multiple of 512). You can then access the file with the FIND, GET, PUT, or UPDATE statements or through one or more virtual arrays. VAX BASIC allows you to overwrite existing records in a file not containing virtual arrays and opened as ORGANIZATION VIRTUAL by using the PUT statement with a RECORD clause. All other organizations require the UPDATE statement to change an existing record. DIGITAL recommends that you also use the 4-256 Statements and Functions July 1988 OPEN • • • UPDATE statement to change existing records in VIRTUAL files that do not contain virtual arrays. When you do not know the organization of a file, you can open a file for input and specify ORGANIZATION UNDEFINED. You can then use the FSP$ function or a USEROPEN routine to determine the attributes of the file. You will usually want to specify the RECORDTYPE ANY clause with the ORGANIZATION UNDEFINED clause. The combination of these two clauses should allow you to access any file sequentially. When you specify ORGANIZATION INDEXED, you create an indexed file whose data records are sorted in ascending or descending order according to a primary index key value. The index keys you specify determine the order in which records are stored. Index keys must be variables declared in a MAP statement associated with the OPEN statement for the file. VAX BASIC allows you to specify an indexed file as either variable or fixed length. When you specify ORGANIZATION SEQUENTIAL, you create a file that stores records in the order that they are written. Sequential files can contain records of any valid VAX BASIC record format: fixed-length, variable-length, or stream. If you open an existing file using stream as a record format option, the file must be one of the following stream record formats defined by RMS: • STREAM records can be delimited by any special character. • STREAM_LF must be delimited by a line-feed character. • STREAM_CR must be delimited by a carriage return. If the file is not one of these stream formats, VAX BASIC signals the error "RECATTNOT, record attributes not matched". • When you specify ORGANIZATION RELATIVE, you create a file that contains a series of records that are numbered consecutively. VAX BASIC allows you to specify either fixed-length or variablelength records. July 1988 Statements and Functions 4-257 OPEN • If you omit the ORGANIZATION clause entirely, a terminal- format file is opened. Terminal-format files are implemented as RMS sequential variable files and store ASCII characters in variable-length records. Carriage control is performed by the operating system; the record does not contain carriage returns or line feeds. You use essentially the same syntax to access terminal-format files as when reading from or writing to the terminal (INPUT and PRINT). 18. The PRIMARY KEY clause lets you specify an indexed file's key. You must specify a primary key when opening an indexed file. The ALTERNATE KEY clause lets you specify up to 254 alternate keys. The ALTERNATE KEY clause is optional. • RMS creates one index list for each primary and alternate key you specify. These indexes are part of the file and contain pointers to the records. Each key you specify corresponds to a sorted list of record pointers. • You can specify each key as ASCENDING or DESCENDING; ASCENDING is the default. In an ASCENDING key, lower key values occur toward the beginning of the index. In a DESCENDING key, higher key values occur toward the beginning of the index. • The keys you specify determine the order in which records in the file are stored. All keys must be variables declared in the file's corresponding MAP statement. The position of the key in the MAP statement determines its position in the record. The data type and size of the key are as declared in the MAP statement. • A key can be an unsubscripted string, a WORD, LONG, or packed decimal variable, or a record or group which is exactly eight bytes long. • You can also create a segmented index key for string keys by separating the string variable names with commas and enclosing them in parentheses. You can then reference a segment of the specified key by referencing one of the string variables instead of the entire key. A string key can have up to eight segments. • The order of appearance of keys determines key numbers. The primary key, which must appear first, is key #0. The first alternate key is #1, and so on. 4-258 Statements and Functions July 1988 OPEN • DUPLICATES in the PRIMARY and ALTERNATE key clauses specifies that two or more records can have the same key value. If you do not specify DUPLICATES, the key value must be unique in all records. • CHANGES in the ALTERNATE KEY clause specifies that you can change the value of an alternate key when updating records. If you do not specify CHANGES when creating the file, you cannot change the value of a key. You cannot specify CHANGES with the PRIMARY KEY clause. • KEY clauses are optional for existing files. If you do specify a key, it must match a key in the file. 19. The RECORDTYPE clause specifies the file's record attributes. • LIST specifies implied carriage control, <CR> . This is the default for all file organizations except VIRTUAL. Statements and Functions 4-258.1 OPEN • • FORTRAN specifies a control character in the record's first byte. NONE specifies no attributes. This is the default for VIRTUAL files. If you open a terminal-format file with RECORDTYPE NONE, you must explicitly insert carriage control characters into the records your program writes to the file. • ANY specifies a match with any file attributes when opening an existing file. If you create a new file, ANY is treated as LIST for all organizations except VIRTUAL. For VIRTUAL, it is treated as NONE. 20. The RECORDSIZE clause specifies the file's record size. Note that there are restrictions on the maximum record size allowed for various file and record formats. See the VAX Record Management Services Reference Manual for more information. • For fixed-length records, int-exp1 specifies the size of all records. • For variable-length records, int-exp1 specifies the size of the largest record. • DIGITAL recommends that you do not use both the MAP and RECORDSIZE clauses in an OPEN statement. However, if you do use both the MAP and RECORDSIZE clauses in an OPEN statement, the following rules apply: The RECORDSIZE clause overrides the record size set by the MAP clause. The map must be as large or larger than the specified RECORDSIZE. • If you specify a MAP clause but no RECORDSIZE clause, the record size is equal to the map size. • If there is no MAP clause, the RECORDSIZE clause determines the record size. • When creating a relative or indexed file, you must specify either a MAP or RECORDSIZE clause. Otherwise, VAX BASIC signals an error. • For fixed files, the record size must match exactly. • If you do not specify a RECORDSIZE clause when opening an existing file, VAX BASIC retrieves the record size value from the file. Statements and Functions 4-259 OPEN • When you print to a terminal-format file, you must supply a record size if the margin is to exceed 72 characters. For example, if you want to print a 132-character line, specify RECORDSIZE 132 or use the MARGIN and NOMARGIN statements. • When creating SEQUENTIAL files, VAX BASIC supplies a default record size of 132. • The record size is always 512 for VIRTUAL files, unless you specify a RECORDSIZE. 21. The TEMPORARY clause causes VAX BASIC to delete the output file as soon as the program closes it. 22. The UNLOCK EXPLICIT clause allows you to retain locks on records until they are explicitly unlocked. • The type of lock you impose on a record with a GET or FIND statement remains in effect until you explicitly unlock the record or file with a FREE or UNLOCK statement or until you close the file. • If you specify UNLOCK EXPLICIT, and do not specify an ALLOW clause with a GET or FIND statement, VAX BASIC imposes the ALLOW NONE lock by default and the next GET or FIND operation does not unlock the previously locked record. • You must open a file with UNLOCK EXPLICIT before you can explicitly lock records with the ALLOW clause on GET and FIND statements. See the sections on GET and FIND in this manual and the VAX BASIC User Manual for more information on explicit record locking and unlocking. 23. The USEROPEN clause lets you open a file with your own FUNCTION subprogram. • Fune-name must be a separately compiled FUNCTION subprogram and must conform to FUNCTION statement rules for naming subprograms. • You do not need to declare the useropen routine as an external function. • VAX BASIC calls the user program after it fills the FAB (File Access Block), the RAB (Record Access Block), and the XABs (Extended Attribute Blocks). The subprogram must issue the appropriate RMS calls, including $OPEN and $CONNECT, and return the RMS status as the value of the function. See the VAX BASIC User Manual for more information on the USEROPEN routine. 4-260 Statements and Functions OPEN NOTE Future releases of the Run-Time Library may alter the use of some VAX RMS fields. Therefore, you may have to alter your USEROPEN procedures accordingly. 24. The WINDOWSIZE clause followed by int-exp3 lets you specify the number of block retrieval pointers you want to maintain in memory for the file. Retrieval pointers are associated with the file header and point to contiguous blocks on disk. • By keeping retrieval pointers in memory you can reduce the I/O associated with locating a record, as the operating system does not have to access the file header for pointers as frequently. • The number of retrieval pointers in memory at any one time is determined by the system default or by the WINDOWSIZE clause. • The default number of retrieval pointers on VAX/VMS systems is 7. • A value of zero specifies the default number of retrieval pointers. A value of -1 means to map the entire file, if possible. Values from -128 through -2 are reserved. Examples Example 1 OPEN "FILE.DAT" AS FILE #4 Example 2 OPEN "INPUT.DAT" FOR INPUT AS FILE #4, ORGANIZATION SEQUENTIAL FIXED, RECORDSIZE 200, MAP ABC, ALLOW MODIFY, ACCESS MODIFY OPEN Newfile$ FOR OUTPUT AS FILE #3, INDEXED VARIABLE, MAP Emp_name, DEFAULTNAME "USER$$DISK:. DAT", PRIMARY KEY Last$ DUPLICATES, ALTERNATE KEY First$ CHANGES July 1988 & & & & & & & & & Statements and Functions 4-261 OPEN MAP (SEGKEY) STRING last_name = 15, MI = 1, first_name = 15 & OPEN "NAMES.IND" FOR OUTPUT AS FILE #1, ORGANIZATION INDEXED, PRIMARY KEY (last_name, first_name, MI), MAP SEGKEY & & & Example 3 MAP (OWNERKEYS) STRING owner_id = 6, dog_reg_no = 7, last_name = 25, first_name = 20 & OPEN "OWNERS. IND" FOR OUTPUT AS FILE #1, ORGANIZATION INDEXED, PRIMARY KEY (owner_id), ALTERNATE KEY (last_name) DUPLICATES CHANGES, ALTERNATE (dog_reg_no) DESCENDING, MAP OWNERKEYS & & & & & The MAP statement describes the three string variables used as index keys in the file OWNERS.IND. The OPEN statement declares an indexed file with two alternate keys in addition to the primary key. The alternate key dog_reg_no is a DESCENDING key; the other keys are ASCENDING by default. 4-262 Statements and Functions July 1988 OPTION OPTION The OPTION statement allows you to set compilation qualifiers such as default data type, size, and scale factor. You can also set compilation conditions such as severity of run-time errors to handle, constant type checking, subscript checking, overflow checking, decimal rounding, and setup in a source program. The options you set affect only the program module in which the OPTION statement occurs. Format OPTION option-clause, ... option-clause: ANGLE=angle-clause HAN DLE=handle-clause CONSTANT TYPE =canst-type-clause OLD VERSION = COD TYPE= type-clause SIZE=size-clause SCALE=int-const } = active-clause { ACTIVE INACTIVE angle-clause: handle-clause: DEGREES } { RADIANS BASIC SEVERE ERROR WARNING INFORMATIONAL Statements and Functions 4-263 OPTION } canst-type-clause.{ REAL INTEGER DECIMAL type-clause: ! l INTEGER REAL EXPLICIT DECIMAL size-clause: { size-item } (size-item, ... ) size-item: { INTEGER int-clause REAL real-clause DECIMAL(d,s) int-clause: {8YTE WORD } LONG l real-clause: rNGLE DOUBLE active-clause: { active-item } (active-item, ... ) GFLOAT HFLOAT 4-264 Statements and Functions } OPTION active-item: INTEGER OVERFLOW DECIMAL OVERFLOW SETUP DECIMAL ROUNDING SUBSCRIPT CHECKING Syntax Rules None. Remarks Option-clause specifies the compilation qualifiers to be in effect for the program module. 2. Angle-clause specifies whether angles are to be evaluated in radians or in degrees. If you do not specify an angle-clause, VAX BASIC uses radians as the default. 3. Handle-clause specifies the severity level of the errors which are to be handled by an error handler. • If you do not specify an OPTION HANDLE statement, VAX BASIC uses OPTION HANDLE = BASIC as the default. Only those errors that are trappable and that map onto a VAX BASIC ERR value will transfer control to the current error handler. See the VAX BASIC User Manual for a list of VAX BASIC run-time errors. • If you specify a severity level, all trappable and non-trappable errors of the specified severity or less transfer control to the current error handler. This includes non-BASIC errors. For example, OPTION HANDLE = ERROR implies ERROR, WARNING, and INFORMATIONAL errors but not SEVERE errors. • If you specify OPTION HANDLE= SEVERE, you can handle fatal errors. However, in most cases, a fatal error indicates that the program environment is badly corrupted and you should not continue program execution. 1. Statements and Functions 4-265 OPTION Const-type-clause specifies the data type for all constants that do not end in a data type suffix or are not in explicit literal notation with a data type supplied. 5. Type-clause sets the default data type for variables that have not been explicitly declared and for constants if no constant type clause is specified. You can specify only one type-clause in a program module. 6. Size-clause sets the default data subtypes for floating-point, integer, and packed decimal data. Size-item specifies the data subtype you want to set. You can specify an INTEGER, REAL or DECIMAL sizeitem, or an combination. Multiple size-items in an OPTION statement must be enclosed in parentheses and separated by commas. 7. SCALE controls the scaling of double precision floating-point variables. Int-const specifies the power of 10 you want as the scaling factor. It must be an integer between 0 and 6 or VAX BASIC signals an error. See the description of the SCALE command in Chapter 2 of this manual for more information on scaling. 8. OLD VERSION= CDD is provided for compatibility with previous versions of BASIC. When bounds are specified in the CDD array, VAX BASIC changes the lower bound to zero and adjusts the upper bound of the array. By default, if you do not specify OLD VERSION= CDD, VAX BASIC compiles the program with the bounds specified in the CDD data definition. 9. Active-clause specifies the decimal rounding, integer and decimal overflow checking, setup, and subscript checking conditions you want in effect for the program module. Active-item specifies the conditions you want to set. Multiple active-items in an OPTION statement must be enclosed in parentheses and separated by commas. 10. You can have more than one option in an OPTION statement, or you can use multiple OPTION statements in a program module. However, each OPTION statement must lexically precede all other source code in the program module, with the exception of comment fields, REM, PICTURE, PROGRAM, SUB, FUNCTION, and OPTION statements. 11. OPTION statement specifications apply only to the program module in which the statement appears and affect all variables in the module, including SUB and FUNCTION parameters. 12. VAX BASIC signals an error in the case of conflicting options. For example, you cannot specify more than one type-clause or SCALE factor in the same program unit. 13. If you do not specify a type-clause or a subtype-clause, VAX BASIC uses the current environment default data types. 4. 4-266 Statements and Functions OPTION 14. If you do not specify a scale factor, VAX BASIC uses the current environment default scale factor. 15. ACTIVE specifies the conditions that are to be in effect for a particular program module. INACTIVE specifies the conditions that are not to be in effect for a particular program module. If a condition does not appear in an active-clause, VAX BASIC uses the current environment default for the condition. See the description of the COMPILE command in Chapter 2 of this manual and the VAX BASIC User Manual for more information on the INTEGER_OVERFLOW, DECIMAL_OVERFLOW, SETUP, DECIMAL_ ROUNDING, and SUBSCRIPT_CHECKING compilation qualifiers. These qualifiers correspond to active-clause conditions (INTEGER OVERFLOW, DECIMAL OVERFLOW, SETUP, DECIMAL ROUNDING, and SUBSCRIPT CHECKING). Example FUNCTION REAL DOUBLE monthly_payment, (DOUBLE interest_rate, LONG no_of_payments, DOUBLE principle) OPTION TYPE = REAL, SIZE= (REAL DOUBLE, INTEGER LONG), SCALE = 4 Statements and Functions 4-267 PLACES PLACES The PLACE$ function explicitly changes the precision of a numeric string. PLACE$ returns a numeric string, truncated or rounded, according to the value of an integer argument you supply. Format str-var =PLACE$ (str-exp, int-exp) Syntax Rules 1. Str-exp specifies the numeric string you want to process. It can have one of the following: • An optional minus sign (-),ASCII digits, and an optional decimal point (.) • An optional minus sign, ASCII digits, an optional decimal point, the letter E, an optional minus sign, and a 2-digit exponent 2. Int-exp specifies the numeric precision of str-exp. Table 4-5 shows examples of rounding and truncation and the values of int-exp that produce them. Remarks 1. If str-exp has more than 60 characters, VAX BASIC signals the error "Illegal number" (ERR=52). 2. Str-exp is rounded or truncated, or both, according to the value of int-exp. 3. If int-exp is between -60 and 60, rounding and truncation occur as follows: • For positive integer expressions, rounding occurs to the right of the decimal place. For example, if int-exp is 1, rounding occurs one digit to the right of the decimal place (the number is rounded to the nearest tenth). If int-exp is 2, rounding occurs two digits 4-268 Statements and Functions PLACES 4. 5. 6. 7. to the right of the decimal place (the number is rounded to the nearest hundredth), and so on. • If int-exp is zero, VAX BASIC rounds to the nearest unit. • For negative integer expressions, rounding occurs to the left of the decimal point. If int-exp is -1, for example, VAX BASIC moves the decimal point one place to the left, then rounds to units. If int-exp is -2, rounding occurs two places to the left of the decimal point; VAX BASIC moves the decimal point two places to the left, then rounds to tens. If int-exp is between 9940 and 10,060, truncation occurs as follows: • If int-exp is 10,000, VAX BASIC truncates the number at the decimal point. • If int-exp is greater than 10,000 (10,000 plus n) VAX BASIC truncates the numeric string n places to the right of the decimal point. For example, if int-exp is 10,001 (10,000 plus 1), VAX BASIC truncates the number starting one place to the right of the decimal point. If int-exp is 10,002 (10,000 plus 2), VAX BASIC truncates the number starting two places to the right of the decimal point, and so on. • If int-exp is less than 10,000 (10,000 minus n), VAX BASIC truncates the numeric string n places to the left of the decimal point. For example, if int-exp is 9999 (10,000 minus 1), VAX BASIC truncates the number starting one place to the left of the decimal point. If 9998 (10,000 minus 2), VAX BASIC truncates starting two places to the left of the decimal point, and so on. If int-exp is not between -60 and 60 or 9940 and 10,060, VAX BASIC returns a value of zero. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to an integer of the default size. Table 4-5 shows examples of rounding and truncation and the values of int-exp that produce them. The number used is 123456.654321: Table 4-5: Rounding and Truncation of 123456.654321 Int-exp Effect Value Returned -5 -4 Rounded to 100,000s and truncated 1 Rounded to 10,000s and truncated 12 -3 Rounded to 1OOOs and truncated 123 Statements and Functions 4-269 PLACES Table 4-5 (Cont.): Rounding and Truncation of 123456.654321 Int-exp Effect Value Returned -2 Rounded to lOOs and truncated 1235 -1 Rounded to 10s and truncated 12346 0 Rounded to units and truncated 123457 1 Rounded to tenths and truncated 123456.7 2 Rounded to hundredths and truncated 123456.65 3 Rounded to thousandths and truncated 123456.654 4 Rounded to ten-thousandths and truncated 123456.6543 5 Rounded to hundred-thousandths and truncated 123456.65432 9,995 Truncated to 100,000s 1 9,996 Truncated to 10,000s 12 9,997 Truncated to 1000s 123 9,998 Truncated to lOOs 1234 9,999 Truncated to 10s 12345 10,000 Truncated to units 123456 10,001 Truncated to tenths 12345.6 10,002 Truncated to hundredths 123456.65 10,003 Truncated to thousandths 123456.654 10,004 Truncated to ten-thousandths 123456.6543 10,005 Truncated to hundred-thousandths 123456.65432 Example DECLARE STRING str_exp, str_var str_exp = "9999.9999" str_var = PLACE$(str_exp,3) PRINT str_var Output 10000 4-270 Statements and Functions POS POS The POS function searches for a substring within a string and returns the substring's starting character position. Format int-var= POS (str-exp 1, str-exp2, int-exp) Syntax Rules 1. 2. 3. Str-exp1 specifies the main string. Str-exp2 specifies the substring. Int-exp specifies the character position in the main string at which VAX BASIC starts the search. Remarks The POS function searches str-exp1, the main string, for the first occurrence of str-exp2, the substring, and returns the position of the substring's first character. 2. If int-exp is greater than the length of the main string, POS returns a value of zero. 3. POS always returns the character position in the main string at which VAX BASIC finds the substring, with the following exceptions: • If only the substring is null, and if int-exp is less than or equal to zero, POS returns a value of 1. • If only the substring is null, and if int-exp is equal to or greater than 1 and less than or equal to the length of the main string, POS returns the value of int-exp. • If only the substring is null and if int-exp is greater than the length of the main string, POS returns the main string's length plus 1. 1. Statements and Functions 4-271 POS 4. 5. 6. 7. 8. • If only the main string is null, POS returns a value of zero. • If both the main string and the substring are null, POS returns 1. If VAX BASIC cannot find the substring, POS returns a value of zero. If int-exp is less than 1, VAX BASIC assumes a starting position of 1. If int-exp does not equal l, VAX BASIC still counts from the string's beginning to calculate the starting position of the substring. That is, VAX BASIC counts character positions starting at position l, regardless of where you specify the start of the search. For example, if you specify 10 as the start of the search and VAX BASIC finds the substring at position 15, POS returns the value 15. If you know that the substring is not near the beginning of the string, specifying a starting position greater than 1 speeds program execution by reducing the number of characters VAX BASIC must search. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to an integer of the default size. Example DECLARE STRING main_str, & sub_str DECLARE INTEGER f irst_char main_str = 11 ABCDEFG 11 sub_str = "DEFG" first_char = POS(main_str, sub_str, 1) PRINT first_char Output 4 4-272 Statements and Functions PRINT PRINT The PRINT statement transfers program data to a terminal or a terminalformat file. Format PRINT [ #chnl-exp,] [output-list] output-list: [exp] [ { ; } exp]. .. [ ; ] Syntax Rules 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 do not specify a channel, VAX BASIC prints to the controlling terminal. 2. Output-list specifies the expressions to be printed and the print format to be used. 3. Exp can be any valid expression. 4. A separator character (comma or semicolon) must separate each exp. Separator characters control the print format as follows: • A comma (,) causes VAX BASIC to skip to the next print zone before printing the expression. • A semicolon (;) causes VAX BASIC to print the expression immediately after the previous expression. 1. Statements and Functions 4-273 PRINT Remarks 1. 2. 3. 4. 5. 6. 7. A terminal or terminal-format file must be open on the specified channel. (Your current terminal is always open on channel #0.) A PRINT line has an integral number of print zones. Note, however, that the number of print zones in a line differs from terminal to terminal. The right margin setting, if set by the MARGIN statement, controls the width of the PRINT line. The default right margin is 72. The PRINT statement prints string constants and variables exactly as they appear, with no leading or trailing spaces. VAX BASIC prints quoted string literals exactly as they appear. Therefore, you can print quotation marks, commas, and other characters by enclosing them in quotation marks. A PRINT statement with no output-list prints a blank line. An expression in the output-list can be followed by more than one separator character. That is, you can omit an expression and specify where the next expression is to be printed by the use of multiple separator characters. For example: PRINT "Name",,"Address and ";"City" Output Name Address and City In this example, the double commas after "Name" cause VAX BASIC to skip two print zones before printing "Address and ". The semicolon causes the next expression, "City", to be printed immediately after the preceding expression. Multiple semicolons have the same effect as a single semicolon. 8. When printing numeric fields, VAX BASIC precedes each number with a space or minus sign ( - ) and follows it with a space. 9. VAX BASIC does not print trailing zeros to the right of the decimal point. If all digits to the right of the decimal point are zeros, VAX BASIC omits the decimal point as well. 10. For REAL numbers (SINGLE, DOUBLE, GFLOAT, and HFLOAT), VAX BASIC does not print more than six digits in explicit notation. If a number requires more than six digits, VAX BASIC uses E format and precedes positive exponents with a plus sign ( + ). VAX BASIC rounds a floating-point number with a magnitude between 0.1 and 1.0 4-274 Statements and Functions PRINT to six digits. For magnitudes smaller than 0.1, VAX BASIC rounds the number to six digits and prints it in E format. 11. The PRINT statement can print up to • 3 digits of precision for BYTE integers • 5 digits of precision for WORD integers • 10 digits of precision for LONG integers • 31 digits of precision for DECIMAL numbers • The string length for STRING values VAX BASIC prints both INTEGER and DECIMAL values according to the previous rules. However, for REAL values, VAX BASIC displays a maximum of 6 digits. 12. If there is a comma or semicolon following the last item in output-list, VAX BASIC does the following: • When printing to a terminal, VAX BASIC does not generate a line terminator after printing the last item. The next item printed with a PRINT statement is printed at the position specified by the separator character following the last item in the first PRINT statement. • When printing to a terminal-format file, VAX BASIC does not write out the record until a PRINT statement without trailing punctuation executes. 13. If no punctuation follows the last item in the output-list VAX BASIC does the following: • When printing to a terminal, VAX BASIC generates a line terminator after printing the last item. • When printing to a terminal-format file, VAX BASIC writes out the record after printing the last item. 14. If a string field does not fit on the current line VAX BASIC does the following: • When printing string elements to a terminal, VAX BASIC prints as much as will fit on the current line and prints the remainder on the next line. • When printing string elements to a terminal-format file, VAX BASIC prints the entire element on the next line. Statements and Functions 4-275 PRINT 15. If a numeric field is the first field in a line, and the numeric field spans more than one line, VAX BASIC prints part of the number on one line and the remainder on the next. Otherwise, numeric fields are never split across lines. If the entire field cannot be printed at the end of one line, the number is printed on the next line. 16. When a number's trailing space does not fit in the last print zone, the number is printed without the trailing space. Example PRINT "name "; "age", "height "; "weight" Output name age 4-276 Statements and Functions height weight PRINT USING PRINT USING The PRINT USING statement generates output formatted according to a format string (either numeric or string) to a terminal or a terminal-format file. Format PRINT [ #chnl-exp] USING str-exp { ; } output-list output-list: [exp] [ { ; } exp]... [ ; ] Syntax Rules 1. 2. 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 do not specify a channel, VAX BASIC prints to the controlling terminal. Str-exp is the format string. It must contain at least one valid format field and must be followed by a separator (comma or semicolon) and at least one expression. NOTE DIGITAL recommends that you use compile-time constant expressions for str-exp whenever possible. When you do this, the VAX BASIC compiler compiles the string at compilation time rather than at run time, thus improving the performance of your program. 3. Output-list specifies the expressions to be printed. • Exp can be any valid expression. Statements and Functions 4-277 PRINT USING • • A comma or semicolon must separate each expression. A comma or semicolon is optional after the last expression in the list. Remarks 1. The PRINT USING statement can print up to • Three digits of precision for BYTE integers • Five digits of precision for WORD integers • Six digits of precision for SINGLE floating-point numbers • Ten digits of precision for LONG integers • Sixteen digits of precision for DOUBLE floating-point numbers • Fifteen digits of precision for GFLOAT floating-point numbers • Thirty-three digits of precision for HFLOAT floating-point numbers • Thirty-one digits of precision for DECIMAL numbers • The string length for STRING values 2. A terminal or terminal-format file must be open on the specified channel or VAX BASIC signals an error. 3. The separator characters (comma or semicolon) in the PRINT USING statement do not control the print format as in the PRINT statement. The print format is controlled by the format string. Therefore, it does not matter whether you use a comma or semicolon. 4. Formatting Numeric Output • The number sign ( #) reserves space for one sign or digit. • The comma(,) causes VAX BASIC to insert commas before every third significant digit to the left of the decimal point. In the format field, the comma must be to the left of the decimal point, and to the right of the rightmost dollar sign, asterisk, or number sign. A comma reserves space for a comma or digit. • The period ( . ) inserts a decimal point. The number of reserved places on either side of the period determines where the decimal point appears in the output. 4-278 Statements and Functions PRINT USING • • • • • • • The hyphen ( - ) reserves space for a sign and specifies trailing minus sign format. If present, it must be the last character in the format field. It causes VAX BASIC to print negative numbers with a minus sign after the last digit, and positive numbers with a trailing space. The hyphen ( - ) can be used as part of a dollar sign ( $$) format field. The letters CD (Credit/Debit) enclosed in angle brackets ( <CD> ) print CR (Credit Record) after negative numbers or zero and DR (Debit Record) after positive numbers. If present, they must be the last characters in the format field. The Credit/Debit format can be used as part of a dollar sign ( $$) format field. Four carets("'"'A) specify E notation for floating-point and DECIMAL numbers. They reserve four places for SINGLE, DOUBLE, GFLOAT, and DECIMAL values and five places for HFLOAT values. If present, they must be the last characters in the format field. Two dollar signs ( $$ ) reserve space for a dollar sign and a digit and cause VAX BASIC to print a dollar sign immediately to the left of the most significant digit. Two asterisks ( **) reserve space for two digits and cause VAX BASIC to fill the left side of the numeric field with leading asterisks. A zero enclosed in angle brackets ( < 0 > ) prints leading zeros instead of leading spaces. A percent sign enclosed in angle brackets ( < %> ) prints all spaces in the field if the value of the print item is zero. NOTE You cannot specify the dollar sign ( $$ ), asterisk-fill ( ** ), and zero-fill ( <O> ) formats within the same print field. Similarly, VAX BASIC does not allow you to specify the zero-fill ( <O> ) and the blank-if-zero ( < %> ) formats within the same print field. • An underscore (-) forces the next formatting character in the format string to be interpreted as a literal. It affects only the next character. If the next character is not a valid formatting character, the underscore has no effect and will itself be printed as a literal. 5. VAX BASIC interprets any other characters in a numeric format string as string literals. Statements and Functions 4-279 PRINT USING 6. Depending on usage, the same format string characters can be combined to form one or more print fields within a format string. For example: • When a dollar sign ( $$) or asterisk-fill ( *"') format precedes a number sign ( #) , it modifies the number sign format. The dollar sign or asterisk-fill format reserves two places, and with the number signs forms one print field. For example: • $$### Forms one field and reserves five spaces **## Forms one field and reserves four spaces When these formats are not followed by a number sign or a blank-if-zero ( <%> ) format, they reserve two places and form a separate print field. When a zero-fill ( <O> ) or blank-if-zero format precedes a number sign, it modifies the number sign format. The < 0 > or < % > reserves one place, and with the number signs forms one print field. For example: <O> #### <%> ### • ** 4-280 Forms one field and reserves four spaces When these formats are not followed by a number sign, they reserve one space and form a separate print field. When a blank-if-zero ( <%>)format follows a dollar sign or asterisk-fill format (**), it modifies the dollar sign ($$) or asterisk fill (**) format string. The blank-if-zero reserves one space, and with the dollar signs or asterisks forms one print field. For example: $$ < % 7. Forms one field and reserves five spaces > ### < % > ## Forms one field and reserves six spaces Forms one field and reserves five spaces When the blank-if-zero precedes the dollar signs or asterisks, it reserves one space and forms a separate print field. The comma (digit separator), dollar sign (currency symbol), and decimal point (radix point) are the defaults for U.S. currency. On VAX/VMS systems, you can change the digit separator, currency symbol and radix point by assigning the logical names SYS$DIGIT_ SEP, SYS$CURRENCY and SYS$RADIX_pOINT. Once you make each assignment, the PRINT USING statement accesses these logical names for these symbols. Statements and Functions PRINT USING 8. For E notation, PRINT USING left-justifies the number in the format field and adjusts the exponent to compensate, except when printing zero. When printing zero in E notation, VAX BASIC prints leading spaces, leading zeros, a decimal point, and zeros in the fractional portion if the PRINT USING string contains these formatting characters, and then the string "E+OO". 9. Zero cannot be negative. If a small negative number rounds to zero, it is represented as a positive zero. 10. If there are reserved positions to the left of the decimal point, and the printed number is less than 1, VAX BASIC prints one zero to the left of the decimal point and pads with spaces to the left of the zero. 11. If there are more reserved positions to the right of the decimal point than fractional digits, VAX BASIC prints trailing zeros in those positions. 12. If there are fewer reserved positions to the right of the decimal point than fractional digits, VAX BASIC rounds the number to fit the reserved positions. 13. If a number does not fit in the specified format field, VAX BASIC prints a percent sign warning symbol (% ), followed by the number in PRINT format. 14. Formatting String Output • Format string characters control string output and can be entered as either uppercase or lowercase characters. All format characters except the backslash and exclamation point must start with a single quotation mark ( ' ). A single quote by itself reserves one character position. A single quote followed by any format characters marks the beginning of a character format field and reserves one character position. • L reserves one character position. The number of Ls plus the leading single quote determines the field's size. VAX BASIC leftjustifies the print expression and pads with spaces if the print expression is less than or equal to the field's width. If the print expression is larger than the field, VAX BASIC left-justifies the expression and truncates its right side to fit the field. • R reserves one character position. The number of Rs plus the leading single quote determines the field's size. VAX BASIC rightjustifies the print expression and pads with spaces if the print expression is less than or equal to the field's width. If the print expression is larger than the field, VAX BASIC truncates the right side to fit the field. Statements and Functions 4-281 PRINT USING • C reserves one character position. The number of Cs plus the leading single quote determines the field's size. If the string does not fit in the field, VAX BASIC truncates its right side. Otherwise, VAX BASIC centers the print expression in this field. If the string cannot be centered exactly, it is offset one character to the left. • E reserves one character position. The number of Es plus the leading single quote determines the field's size. VAX BASIC leftjustifies the print expression if it is less than or equal to the field's width and pads with spaces. Otherwise, VAX BASIC expands the field to hold the entire print expression. • Two backslashes (\ \) when separated by n spaces reserve n+2 character positions. PRINT USING left-justifies the string in this field. VAX BASIC does not allow a leading quotation mark with this format. • An exclamation point ( ! ) creates a 1-character field. The exclamation point both starts and ends the field. VAX BASIC does not allow a leading quotation mark with this format. 15. VAX BASIC interprets any other characters in the format string as string literals and prints them exactly as they appear. 16. If a COMMA or semicolon follows the last item in output-list • When printing to a terminal, VAX BASIC does not generate a line terminator after printing the last item. The next item printed with a PRINT statement is printed at the position specified by the separator character following the last item in the first PRINT statement. • When printing to a terminal-format file, VAX BASIC does not write out the record until a PRINT statement without trailing punctuation executes. 17. If no punctuation follows the last item in output-list: • When printing to a terminal, VAX BASIC generates a line terminator after printing the last item. • When printing to a terminal-format file, VAX BASIC writes out the record after printing the last item. 4-282 Statements and Functions PRINT USING Examples Example 1 PRINT USING "###.###",-12.346 PRINT USING 11 ##.### 11 ,12.346 ·Output 1 -12.346 12.346 Example 2 INPUT "Your Name";Winner$ Jackpot = 10000.0 PRINT USING "CONGRATULATIONS, END 1 EEEEEEEEE, YOU WON$$#####.##", Winner$, Jackpot Output 2 Your Name? Hortense Corabelle CONGRATULATIONS, Hortense Corabelle, YOU WON $10000.00 Statements and Functions 4-283 PRODS PRODS The PROD$ function returns a numeric string that is the product of two numeric strings. The precision of the returned numeric string depends on the value of an integer argument. Format str-var =PROD$ (str-exp 1, str-exp2, int-exp) Syntax Rules 1. Str-expl and str-exp2 specify the numeric strings you want to multiply. A numeric string can have one of the following formats: • An optional minus sign (-),ASCII digits, and an optional decimal point (.) • An optional minus sign, ASCII digits, an optional decimal point, the letter E, an optional minus sign, and a 2-digit exponent 2. If str-exp consists of more than 60 characters, VAX BASIC signals the error "Illegal number" (ERR=52). 3. Int-exp specifies the numeric precision of str-exp. Table 4-5 shows examples of rounding and truncation and the values of int-exp that produce them. 4-284 Statements and Functions PRODS Remarks Str-exp is rounded or truncated, or both, according to the value of int-exp. 2. If int-exp is between -60 and 60, rounding and truncation occur as 1. follows: • For positive integer expressions, rounding occurs to the right of the decimal place. For example, if int-exp is 1, rounding occurs one digit to the right of the decimal place (the number is rounded to the nearest tenth). If int-exp is 2, rounding occurs two digits to the right of the decimal place •(the number is rounded to the nearest hundredth), and so on. • If int-exp is zero, VAX BASIC rounds to the nearest unit. • For negative integer expressions, rounding occurs to the left of the decimal point. If int-exp is -1, for example, VAX BASIC moves the decimal point one place to the left, then rounds to units. If int-exp is -2, rounding occurs two places to the left of the decimal point; VAX BASIC moves the decimal point two places to the left, then rounds to tens. 3. If int-exp is between 9940 and 10,060, truncation occurs as follows: • If int-exp is 10,000, VAX BASIC truncates the number at the decimal point. • If int-exp is greater than 10,000 (10000 plus n) VAX BASIC truncates the numeric string n places to the right of the decimal point. For example, if int-exp is 10,001 (10,000 plus 1), VAX BASIC truncates the number starting one place to the right of the decimal point. If int-exp is 10,002 (10,000 plus 2), VAX BASIC truncates the number starting two places to the right of the decimal point, and so on. • If int-exp is less than 10,000 (10,000 minus n), VAX BASIC truncates the numeric string n places to the left of the decimal point. For example, if int-exp is 9999 (10,000 minus 1), VAX BASIC truncates the number starting one place to the left of the decimal point. If 9998 (10,000 minus 2), VAX BASIC truncates starting two places to the left of the decimal point, and so on. Statements and Functions 4-285 PRODS 4. 5. If int-exp is not between -60 and 60 or 9940 and 10,060, VAX BASIC returns a value of zero. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to an integer of the default size. Example DECLARE STRING num_exp1, le num_exp2, le product num_exp1 = 11 34.555 11 num_exp2 = 11 297.676" product = PROD$(num_exp1, num_exp2, 1) PRINT product Output 10286.2 4-286 Statements and Functions PROGRAM PROGRAM The PROGRAM statement allows you to identify a main program with a name other than the file name. Format PROGRAM prog-name Syntax Rules 1. 2. 3. 4. Prag-name specifies the module name of the compiled source and cannot be the same as any SUB, FUNCTION or PICTURE name. Prag-name also defines the global entry point name for the main program. The first character of a prog-name must be an alphabetic character (A through Z). The remaining characters, if any, can be any combination of alphabetic characters, digits (0 through 9), dollar signs ( $ ), periods ( . ), and underscores (- ). Prag-name cannot be a quoted name. Remarks 1. 2. 3. The PROGRAM statement must be the first statement in a main program and can be preceded only by comment fields and lexical directives. If you insert the program into a text or object library or examine it using the VAX/VMS Debugger, the program name you specify will be the module name used. The PROGRAM statement is optional; VAX BASIC allows you to specify an END PROGRAM statement and an EXIT PROGRAM statement without a matching PROGRAM statement. July 1988 Statements and Functions 4-287 PROGRAM Example PROGRAM first_test END PROGRAM 4-288 Statements and Functions PUT PUT The PUT statement transfers data from the record buffer to a file. PUT statements are valid on RMS sequential, relative, and indexed files. You cannot use PUT statements on terminal-format files or virtual array files. Format PUT #chnl-exp [, RECORD num-exp [, COUNT int-exp]] Syntax Rules 1. 2. 3. 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 RECORD clause allows you to randomly write records to a relative or sequential fixed file by specifying the record number. Num-exp must be between 1 and the maximum record number allowed for the file. VAX BASIC does not allow you to use the RECORD clause on sequential variable, sequential stream, or indexed files. Int-exp in the COUNT clause specifies the record's size. If there is no COUNT clause, the record's size is that defined by the MAP or RECORDSIZE clause in the OPEN statement. The RECORDSIZE clause overrides the MAP clause. • If you write a record to a file with variable-length records, int-exp must be between zero and the maximum record size specified in the OPEN statement. • If you write a record to a file with fixed-length records, the COUNT clause serves no purpose. If used, int-exp must equal the record size specified in the OPEN statement. July 1988 Statements and Functions 4-289 PUT Remarks 1. 2. 3. 4. 5. For sequential access, the file associated with chnl-exp must be open with ACCESS WRITE, MODIFY, SCRATCH, or APPEND. To add records to an existing sequential file, open it with ACCESS APPEND. If you are not at the end of the file when attempting a PUT to a sequential file, VAX BASIC signals "Not at end of file" (ERR=149). After a PUT statement executes, there is no current record pointer. The next record pointer is set as follows: • For sequential files, variable and stream PUT operations set the next record pointer to the end of the file. • For relative files, a sequential PUT operation sets the next record pointer to the next record plus 1. • For relative and sequential fixed files, a random PUT operation leaves the next record pointer unchanged. • For indexed files, a PUT operation leaves the next record pointer unchanged. When you specify a RECORD clause, VAX BASIC evaluates num-exp and uses this value as the relative record number of the target cell. • If the target cell is empty or occupied by a deleted record, VAX BASIC places the record in that cell. • If there is a record in the target cell and the file has not been opened as a VIRTUAL file, the PUT statement fails, and VAX BASIC signals the error "Record already exists" (ERR=153). A PUT statement with no RECORD clause writes records to the file as follows: • For sequential variable and stream files, a PUT operation adds a record at the end of the file. • For relative and sequential fixed files, a PUT operation places the record in the empty cell pointed to by the next record pointer. If the file is empty, the first PUT operation places a record in cell number 1, the second in cell number 2, and so on. • For indexed files, RMS stores records in order of ascending primary key value and updates all indexes so that they point to the record. 4-290 Statements and Functions PUT 6. When you a open file as ORGANIZATION VIRTUAL, the file you open is a sequential fixed file with a record size that is a multiple of 512 bytes. You can then access the file with the FIND, GET, PUT, or UPDATE statements or through one or more virtual arrays. VAX BASIC allows you to overwrite existing records in a file not containing virtual arrays and opened as ORGANIZATION VIRTUAL by using the PUT statement with a RECORD clause. All other organizations require the UPDATE statement to change an existing record. DIGITAL recommends that you also use the UPDATE statement to change existing records in VIRTUAL files that do not contain virtual arrays. 7. If an existing record in an indexed file has a record with the same key value as the one you want to put in the file, VAX BASIC signals the error "Duplicate key detected" (ERR=134) if you did not specify DUPLICATES for the key in the OPEN statement. If you specified DUPLICATES, RMS stores the duplicate records in a first-in/first-out sequence. 8. The number specified in the COUNT clause determines how many bytes are transferred from the buffer to a file: • If you have not completely filled the record buffer before executing a PUT statement, VAX BASIC pads the record with nulls to equal the specified value. • If the specified COUNT value is less than the buffer size, the record is truncated to equal the specified value. • The number in the COUNT clause must not exceed the size specified in the MAP or RECORDSIZE clause in the OPEN statement or VAX BASIC signals "Size of record invalid" (ERR=156). • For files with fixed length records, the number in the COUNT clause must match the record size. Examples Example 1 !Sequential, Relative, Indexed, and Virtual Files PUT 13, COUNT 66Y. Example 2 !Relative and Virtual Files Only PUT 16, RECORD 133, COUNT 16% Statements and Functions 4-291 QUOS ouos The QUO$ function returns a numeric string that is the quotient of two numeric strings. The precision of the returned numeric string depends on the value of an integer argument. Format str-var =QUO$ (str-exp 1, str-exp2, int-exp) Syntax Rules 1. Str-expl and str-exp2 specify the numeric strings you want to divide. A numeric string can have one of the following formats: • An optional minus sign ( - ), ASCII digits, and an optional decimal point (.) • An optional minus sign, ASCII digits, an optional decimal point, the letter E, an optional minus sign, and a 2-digit exponent 2. Int-exp specifies the numeric precision of str-exp. Table 4-5 shows examples of rounding and truncation and the values of int-exp that produce them. Remarks 1. If str-exp consists of more than 60 characters, VAX BASIC signals the error "Illegal number" (ERR=52). 2. Str-exp is rounded or truncated, or both, according to the value of int-exp. 3. If int-exp is between -60 and 60, rounding and truncation occur as follows: • For positive integer expressions, rounding occurs to the right of the decimal place. For example, if int-exp is 1, rounding occurs one digit to the right of the decimal place (the number is rounded to the nearest tenth). If int-exp is 2, rounding occurs two digits 4-292 Statements and Functions ouos to the right of the decimal place (the number is rounded to the nearest hundredth), and so on. • If int-exp is zero, VAX BASIC rounds to the nearest unit. • For negative integer expressions, rounding occurs to the left of the decimal point. If int-exp is -1, for example, VAX BASIC moves the decimal point one place to the left, then rounds to units. If int-exp is -2, rounding occurs two places to the left of the decimal point; VAX BASIC moves the decimal point two places to the left, then rounds to tens. 4. If int-exp is between 9940 and 10,060, truncation occurs as follows: • If int-exp is 10000, VAX BASIC truncates the number at the decimal point. • If int-exp is greater than 10,000 (10,000 plus n) VAX BASIC truncates the numeric string n places to the right of the decimal point. For example, if int-exp is 10,001 (10,000 plus 1), VAX BASIC truncates the number starting one place to the right of the decimal point. If int-exp is 10,002 (10,000 plus 2), VAX BASIC truncates the number starting two places to the right of the decimal point, and so on. • If int-exp is less than 10,000 (10,000 minus n), VAX BASIC truncates the numeric string n places to the left of the decimal point. For example, if int-exp is 9999 (10,000 minus 1), VAX BASIC truncates the number starting one place to the left of the decimal point. If 9998 (10,000 minus 2), VAX BASIC truncates starting two places to the left of the decimal point, and so on. 5. If int-exp is not between -60 and 60 or 9940 and 10,060, VAX BASIC returns a value of zero. 6. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to an integer of the default size. Statements and Functions 4-293 DUOS Example DECLARE STRING num_str1, k num_str2, k quotient num_str1 "458996.43" num_str2 "123222.444" quotient = QUO$(num_str1, num_str2, 2) PRINT quotient Output 3.72 4-294 Statements and Functions RADS RADS The RAD$ function converts a specified integer in Radix-50 format to a 3-character string. NOTE The RAD$ function is supported only for compatibility with BASIC-PLUS-2. DIGITAL recommends that you do not use the RAD$ function for new program development. Format str-var =RAD$ (int-var) Syntax Rules None. Remarks 1. The RAD$ function converts int-var to a 3-character string in Radix-50 format and stores it in str-var. Radix-50 format allows you to store three characters of data as a 2-byte integer. 2. VAX BASIC supports the RAD$ function, but not its complement, the FSS$ function. 3. If you specify a floating-point variable for int-var, VAX BASIC truncates it to an integer of the default size. Statements and Functions 4-295 RADS Example DECLARE STRING radix radix = RAD$(999) 4-296 Statements and Functions RANDOMIZE RANDOMIZE The RANDOMIZE statement gives the random number function, RND, a new starting value. Format RANDOMIZE } { RANDOM Syntax Rules None. Remarks 1. Without the RANDOMIZE statement, successive runs of the same program generate the same random number sequence. 2. If you use the RANDOMIZE statement before invoking the RND function, the starting point changes for each run. Therefore, a different random number sequence appears each time. Example DECLARE REAL random_num RANDOMIZE FOR I = 1 TO 2 random_num = RND PRINT random_num NEXT I Statements and Functions 4-297 RANDOMIZE Output .379784 .311572 4-298 Statements and Functions RCTRLC RCTRLC The RCTRLC function disables CTRL/C trapping. Format int-var= RCTRLC Syntax Rules None. Remarks 1. 2. After VAX BASIC executes the RCTRLC function, a CTRL/C typed at the terminal returns you to DCL command level or to the BASIC environment. RCTRLC always returns a value of zero. Example Y = RCTRLC Statements and Functions 4-299 RCTRLO RCTRLO The RCTRLO function cancels the effect of a CTRL/O typed on a specified channel. Format int-var= RCTRLO (chnl-exp) Syntax Rules Chnl-exp must refer to a terminal. Remarks 1. If you type a CTRL/O to cancel terminal output, nothing is printed on the specified terminal until your program executes the RCTRLO or until you type another CTRL/O, at which time normal terminal output resumes. 2. The RCTRLO function always returns a value of zero. 3. RCTRLO has no effect if the specified channel is open to a device that does not use the CTRL/O convention. Example PRINT "A" FOR 1% = 1% TO 10% YY. = RCTRLO(OY.) PRINT "Normal output is resumed" 4-300 Statements and Functions RCTRLO Output A A A A )CTRL/Ol Output off Normal output is resumed Statements and Functions 4-301 READ READ The READ statement assigns values from a DATA statement to variables. Format READ var, ... Syntax Rules Var cannot be a DEF function name, unless the READ statement is inside the multi-line DEF body. Remarks 1. If your program has a READ statement without DATA statements, VAX BASIC signals a compile-time error. 2. When VAX BASIC initializes a program unit, it forms a data sequence of all values in all DATA statements. An internal pointer points to the first value in the sequence. 3. When VAX BASIC executes a READ statement, it sequentially assigns values from the data sequence to variables in the READ statement variable list. As VAX BASIC assigns each value, it advances the internal pointer to the next value. 4. VAX BASIC signals the error "Out of data" (ERR=57) if there are fewer data elements than READ statements. Extra data elements are ignored. 5. The data type of the value must agree with the data type of the variable to which it is assigned or VAX BASIC signals "Data format error" (ERR=SO). 6. If you read a string variable, and the DATA element is an unquoted string, VAX BASIC ignores leading and trailing spaces. If the DATA element contains any commas, they must be inside quotation marks. 4-302 Statements and Functions READ 7. VAX BASIC evaluates subscript expressions in the variable list after it assigns a value to the preceding variable, and before it assigns a value to the subscripted variable. For instance, in the following example, VAX BASIC assigns the value of 10 to variable A, then assigns the string, LESTER, to array element A$(A). READ A, A$(10) DATA 10, LESTER The string, LESTER, will be assigned to A$(10). Example DECLARE STRING A,B,C READ A,B,C DATA "X", "Y", "Z" PRINT A + B + C Output XYZ Statements and Functions 4-303 REAL REAL The REAL function converts a numeric expression or numeric string to a specified or default floating-point data type. Format ,SINGLE real-var= REAL (exp ' DOUBLE [ GFLOAT HFLOAT l ) I I Syntax Rules Exp can be either numeric or string. If a string, it can contain the ASCII digits 0 through 9, uppercase E, a plus sign ( + ), a minus sign ( -), and a period (. ). Remarks 1. 2. VAX BASIC evaluates exp, then converts it to the specified REAL size. If you do not specify a size, VAX BASIC uses the default REAL size. VAX BASIC ignores leading and trailing spaces and tabs if exp is a string. 3. The REAL function returns a value of zero when a string argument contains only spaces and tabs, or when the argument is null. 4-304 Statements and Functions REAL Example DECLARE STRING any_num INPUT "Enter a number";any_num PRINT REAL(any_num, DOUBLE) Output Enter a number? 123095959 .123096E+09 Statements and Functions 4-305 RECORD RECORD The RECORD statement lets you name and define data structures in a VAX BASIC program and provides the VAX BASIC interface to the VAX Common Data Dictionary (COD). You can use the defined RECORD name anywhere a VAX BASIC data type keyword is valid if all data types are valid in that context. Format RECORD rec-name rec-component END RECORD [rec-name] rec-component data-type rec-item [ ,... ] } group-clause { variant-clause rec-item: unsubs-var [=int-canst] } array ( [ int-const1 TO] int-const2 ,... ) [ = int-const] { FILL [ (int-canst)] [=int-canst] group-clause: GROUP group-name ( [ int-const1 TO] int-const2, ... ) ] rec-component END GROUP [group-name ] 4-306 Statements and Functions RECORD variant-clause: VARIANT case-clause END VARIANT case-clause: CASE [rec-component] Syntax Rules 1. Each line of text in a RECORD, GROUP, or VARIANT block can have an optional line number. 2. Data-type can be a VAX BASIC data type keyword or a previously defined RECORD name. Table 1-2 lists and describes VAX BASIC data type keywords. 3. If the data type of a rec-item is STRING, the string is fixed-length. You can supply an optional string length with the= int-const clause. If you do not specify a string length, the default is 16. 4. When you create an array of components with GROUP or create an array as a rec-item, VAX BASIC allows you to specify both lower and upper bounds. The upper bound is required; the lower bound is optional. • lnt-const1 specifies the lower bounds of the array. • lnt-const2 specifies the upper bounds of the array and when accompanied by int-const1, must be preceded by the keyword TO. • lnt-const1 must be less than or equal to int-const2. • If you do not specify int-const1, VAX BASIC uses zero as the default lower bound. Statements and Functions 4-307 RECORD Remarks 1. The total size of a RECORD cannot exceed 65 ,535 bytes. 2. The declarations between the RECORD statement and the END RECORD statement are called a RECORD block. 3. Variables and arrays in a RECORD definition are also called RECORD components. 4. The RECORD statement names and defines a data structure called a RECORD template, but does not allocate any storage. When you use the RECORD template as a data type in a statement such as DECLARE, MAP, or COMMON, you declare a RECORD instance. This declaration of the RECORD instance allocates storage for the RECORD. For example: DECLARE EMPLOYEE emp_rec This statement declares a variable named emp_rec, which is an instance of the user-defined data type EMPLOYEE. 5. Rec-item • The rec-name qualifies the group-name and the group-name qualifies the rec-item. You can access a particular rec-item within a record by specifying rec-name::group-name::rec-item. This specification is called a fully qualified reference. The full qualification of a rec-item is also called a component path name. • Rec-item must conform to the rules for naming VAX BASIC variables. • Whenever you access an elementary record component, that is, a variable named in a RECORD definition, you do it in the context of the record instance. Therefore, rec-item names need not be unique in your program. For example, you can have a variable called first _name in any number of different RECORD definitions. However, you cannot use a VAX BASIC reserved keyword as a rec-item name and you cannot have two variables or arrays with the same name at the same level in the RECORD or GROUP definition. • The group-name is optional in a rec-item specification unless there is more than one rec-item with the same name or the group-name has subscripts. For example: 4-308 Statements and Functions RECORD DECLARE EMPLOYEE Emp_rec RECORD Address STRING Street, City, State, Zip END RECORD Address RECORD Employee GROUP Emp_name STRING First = 16 STRING Middle = 1 STRING Last = 15 END GROUP Emp_name ADDRESS Work ADDRESS Home END RECORD Employee You can access the rec-item "Last" by specifying only "Emp_ rec::Last" because only one rec-item is named "Last". However, if you try to reference "Emp_rec::City", VAX BASIC signals an error because "City" is an ambiguous field, a component of both "Work" and "Home". To access "City", you must specify either "Emp_rec::Work::City" or "Emp_rec::Home::City". 6. Group-clause • The declarations between the GROUP keyword and the END GROUP keywords are called a GROUP block. The GROUP keyword is valid only within a RECORD block. • A subscripted group is similar to an array within the record. The group can have both lower and upper bounds for one or more dimensions. Each group element consists of all the record items contained within the including other groups. 7. Variant-clause • The declarations between the VARIANT keyword and the END VARIANT keywords are called a VARIANT block. • The amount of space allocated for a VARIANT field in a RECORD is equal to the space needed for the variant field requiring the most storage. • A variant defines the record items that overlay other items, allowing you to redefine the same storage one or more ways. 8. Case-clause • Each case in a variant starts at the position in the record where the variant begins. • The size of a variant is the size of the longest case in that variant. Statements and Functions 4-309 RECORD Example 1000 4-310 RECORD Employee GROUP Emp_name STRING Last = 16 STRING First = 14 STRING Middle = 1 END GROUP Emp_name GROUP Emp_address STRING Street = 16 STRING City = 20 STRING State = 2 DECIMAL(6,0) Zip END GROUP Emp_address STRING Wage_class = 2 VARIANT CASE GROUP Hourly DECIMAL(4,2) Hourly_wage SINGLE Regular_pay_ytd SINGLE Overtime_pay_ytd END GROUP Hourly CASE GROUP Salaried DECIMAL(7,2) Yearly_salary SINGLE Pay_ytd END GROUP Salaried CASE GROUP Executive DECIMAL(S,2) Yearly_salary SINGLE Pay_ytd SINGLE Expenses_ytd END GROUP Executive END VARIANT END RECORD Employee Statements and Functions RECOUNT RECOUNT The RECOUNT function returns the number of characters transferred by the last input operation. Format int-var= RECOUNT Syntax Rules None. Remarks 1. 2. 3. 4. 5. The RECOUNT value is reset by every input operation on any channel, including channel #0. • After an input operation from your terminal, RECOUNT contains the number of characters (bytes), including line terminators, transferred. • After accessing a file record, RECOUNT contains the number of characters in the record. Because RECOUNT is reset by every input operation on any channel, you should copy the RECOUNT value to a different storage location before executing another input operation. If an error occurs during an input operation, the value of RECOUNT is undefined. RECOUNT is unreliable after a CTRL/C interrupt because the CTRL/C trap may have occurred before VAX BASIC set the value for RECOUNT. The RECOUNT function returns a LONG value. Statements and Functions 4-311 RECOUNT Example DECLARE INTEGER character_count INPUT "Enter a sequence of numeric characters";character_count character_count = RECOUNT PRINT character_count;"characters received (including CR and LF)" Output Enter a sequence of numeric characters? 12346678 10 characters received (including CR and LF) 4-312 Statements and Functions REM REM The REM statement allows you to document your program. format REM [comment] Syntax Rules 1. REM must be the only statement on the line or the last statement on a multi-statement line. 2. VAX BASIC interprets every character between the keyword REM and the next line number as part of the comment. 3. VAX BASIC does not allow you to specify the REM statement in programs that do not contain line numbers. Remarks 1. Because the REM statement is not executable, you can place it anywhere in a program, except where other statements, such as SUB and END SUB, must be the first or last statement in a program unit. 2. When the REM statement is the first statement on a line-numbered line, VAX BASIC treats any reference to that line number as a reference to the next higher-numbered executable statement. 3. The REM statement is similar to the comment field that begins with an exclamation point, with one exception: the REM statement must be the last statement on a BASIC line. The exclamation point comment field can be ended with another exclamation point or a line terminator and followed by a VAX BASIC statement. See Chapter 1 of this manual for more information on the comment field. Statements and Functions 4-31 J REM Example 10 REM This is a multi-line comment All text up to BASIC line 20 is part of this REM statement. Any BASIC statements on line 10 are ignored. PRINT "This does not execute". 20 PRINT "This will execute" Output This will execute 4-314 Statements and Functions REMAP REMAP The REMAP statement defines or redefines the position in the storage area of variables named in the MAP DYNAMIC statement. Format REMAP (map-dyn-name) remap-item, ... map-dyn-name: map-name } { static-str-var remap-item: num-var num-array-name ( [int-exp, ... ] ) str-var [=int-exp] str-array-name ( [int-exp, ... ] )[=int-exp] [data-type] FILL [ (int-exp)] [=int-exp] FILL% [ (int-exp)] FILL$ [ (int-exp)][= int-exp] Syntax Rules 1. Map-dyn-name can be either a map name or a static string variable. • Map-name is the storage area named in a MAP statement. • If you specify a map name, then a MAP statement with the same name must precede both the MAP DYNAMIC statement and the REMAP statement. • When you specify a static string variable, the string must be declared before you can specify a MAP DYNAMIC statement or a REMAP statement. • If you specify a static-str-var, the following restrictions apply: Static-str-var cannot be a string constant. Statements and Functions 4-315 REMAP Static-str-var cannot be the same as any previously declared map-item in a MAP DYNAMIC statement. If static-str-var is a parameter to the subprogram containing the REMAP statement, static-str-var cannot be a RECORD component. Static-str-var cannot be a subscripted variable. Static-str-var cannot be a parameter declared in a DEF or DEF* function. 2. Remap-item names a variable, array, or array element declared in a preceding MAP DYNAMIC statement: • Num-var specifies a numeric variable or array element. Numarray-name followed by a set of empty parentheses specifies an entire numeric array. • Str-var specifies a string variable or array element. Str-array-name followed by a set of empty parentheses, specifies an entire fixedlength string array. You can specify the number of bytes to be reserved for string variables and array elements with the =int-exp clause. The default string length is 16. 3. Remap-item can also be a FILL item. The FILL, FILL%, and FILL$ keywords let you reserve parts of the record buffer. Int-exp specifies the number of FILL items to be reserved. The =int-exp clause allows you to specify the number of bytes to be reserved for string FILL items. Table 4-2 describes FILL item format and storage allocation. NOTE 4. 5. 4-316 In the FILL clause, (int-exp) represents a repeat count, not an array subscript. FILL (n), for example, represents n elements, not n + 1. All remap-items, except FILL items, must have been named in a previous MAP DYNAMIC statement, or VAX BASIC signals an error. Data-type can be any VAX BASIC data type keyword or a data type defined in a RECORD statement. Data type keywords and their size, range, and precision are listed in Table 1-2 in this manual. You can specify a data type only for FILL items. • When you specify a data type before a FILL keyword in a REMAP statement, the FILL item is of that data type. The specified data type applies only to that one FILL item. • If you do not specify any data type for a FILL item, the FILL item takes the current default data type and size. Statements and Functions July 198E REMAP 6. Remap-items must be separated with commas. Statements and Functions 4-316.1 REMAP Remarks 1. The REMAP statement does not affect the amount of storage allocated to the map area. 2. Each time a REMAP statement executes, VAX BASIC sets record pointers to the named map area for the specified variables from left to right. 3. The REMAP statement must be preceded by a MAP DYNAMIC statement or VAX BASIC signals the error "No such MAP area <name>". The MAP statement or static string variable creates a named area of static storage, the MAP DYNAMIC statement specifies the variables whose positions can change at runtime, and the REMAP statement specifies the new positions for the variables named in the MAP DYNAMIC statement. 4. Before you can specify a map name in a REMAP statement, there must be a MAP statement in the program unit with the same map name. Otherwise, VAX BASIC signals the error" <Name> is not a DYNAMIC MAP variable of MAP <name> ". Similarly, before you can specify a static string variable in a REMAP statement, the string variable must be declared. Otherwise, VAX BASIC signals the same error message. 5. If a static string variable is the same as a map name, VAX BASIC overrides the static string name and uses the map name. 6. Until the REMAP statement executes, all variables named in the MAP DYNAMIC statement point to the first byte of the MAP area and all string variables have a length of zero. When the REMAP statement executes, VAX BASIC sets the internal pointers as specified in the REMAP statement. For example: 100 MAP (DUMMY) STRING map_buff er = 60 MAP DYNAMIC (DUMMY) LONG A, STRING B, SINGLE C(7) REMAP (DUMMY) B=14, A, C() The REMAP statement sets a pointer to byte 1 of DUMMY for string variable B, a pointer to byte 15 for LONG variable A, and pointers to bytes 19, 23, 27, 31, 35, 39, 43, and 47 for the elements in SINGLE array C. Statements and Functions 4-317 REMAP 7. You can use the REMAP statement to redefine the pointer for an array element or variable more than once in a single REMAP statement. For example: MAP (DUMMY) STRING FILL = 48 MAP DYNAMIC (DUMMY) LONG A, B(10) REMAP (DUMMY) B(), B(O) 100 This REMAP statement sets a pointer to byte 1 in DUMMY for array B. Because array B uses a total of 44 bytes, the pointer for the first 8. element of array B, B(O) points to byte 45. References to array element B(O) will be to bytes 45 through 48. Pointers for array elements 1 through 10 are set to bytes 5, 9, 13, 17 and so forth. Because the REMAP statement is local to a program module, it affects pointers only in the program module in which it executes. Examples Example 1 DECLARE LONG CONSTANT emp_fixed_info = 4 + 9 + 2 MAP (emp_buffer) LONG badge, & STRING social_sec_num = 9, & BYTE name_length, & address_length, & FILL (60) MAP DYNAMIC (emp_buffer) STRING emp_name, emp_address & WHILE 1Y. GET #1 REMAP (emp_buffer) STRING FILL = emp_fixed_info, emp_name = name_length, emp_address = address_length 4-318 Statements and Functions & & REMAP PRINT emp_name PRINT emp_address PRINT NEXT END Example 2 SUB deblock (STRING input_rec, STRING item()) MAP DYNAMIC (input_rec) STRING A(1 TO 3) REMAP (input_rec) t A(1) = 6, t A(2) = 3, t A(3) = 4 FOR I = LBOUND(A) TO UBOUND(A) item(!) = A(I) NEXT I END SUB Statements and Functions 4-319 RESET RESET The RESET statement is a synonym for the RESTORE statement. See the RESTORE statement for more information. Format RESET [ #chnl-exp [, KEY #int-exp 11 4-320 Statements and Functions RESTORE RESTORE The RESTORE statement resets the DATA pointer to the beginning of the DATA sequence, or sets the record pointer to the first record in a file. Format RESTORE [ #chnl-exp [, KEY #int-exp 11 Syntax Rules 1. 2. Chnl-exp is a numeric expression that specifies a channel number associated with a file. It must be immediately preceded by a number sign(#). Int-exp must be between zero and the number of keys in the file minus 1. It must be immediately preceded by a number sign ( # ). Remarks 1. 2. 3. 4. 5. 6. If you do not specify a channel, RESTORE resets the DATA pointer to the beginning of the DATA sequence. RESTORE affects only the current program unit. Thus, executing a RESTORE statement in a subprogram does not affect the DATA pointer in the main program. If there is no channel specified, and the program has no DATA statements, RESTORE has no effect. The file specified by chnl-exp must be open. If chnl-exp specifies a magnetic tape file, VAX BASIC rewinds the tape to the first record in the file. The KEY clause applies to indexed files only. It sets a new key of reference equal to int-exp and sets the next record pointer to the first logical record in that key. Statements and Functions 4-321 RESTORE 7. For indexed files, the RESTORE statement without a KEY clause sets the next record pointer to the first logical record specified by the current key of reference. If there is no current key of reference, the RESTORE statement sets the next record pointer to the first logical record of the primary key. 8. If you use the RESTORE statement on any file type other than indexed, VAX BASIC sets the next record pointer to the first record in the file. 9. The RESTORE statement is not allowed on virtual array files or on files opened on unit record devices. 10. For information on the RESTORE GRAPHICS statement, see Programming with VAX BASIC Graphics. Example RESTORE #7Y,, KEY #4Y, 4-322 Statements and Functions RESUME RESUME The RESUME statement marks an exit point from an ON ERROR errorhandling routine. VAX BASIC clears the error condition and returns program control to a specified line number, label or to the program block in which the error occurred. NOTE The RESUME statement is supported for compatibility with other DIGITAL BASICs. For new program development, DIGITAL recommends that you use WHEN blocks. Format RESUME [target] Syntax Rules Target must be a valid VAX BASIC line number or label and must exist in the same program unit. Remarks 1. The following restrictions apply: • The RESUME statement cannot appear within a protected region, or within an attached or detached handler. • The target of a RESUME statement cannot exist within a protected region or handler. • The RESUME statement cannot be used in a multi-line DEF unless the target is also in the DEF function definition. • The execution of a RESUME with no target is illegal if there is no error active. Statements and Functions 4-323 RESUME • A RESUME statement cannot transfer control out of the current program unit. Therefore, a RESUME statement with no target cannot terminate an error handler if the error handler is handling an error that occurred in a subprogram or an external function, and the error was passed to the calling program's error handler by an ON ERROR GO BACK statement or by default. 2. When no target is specified in a RESUME statement, VAX BASIC transfers control based on where the error occurs. If the error occurs on a numbered line containing a single statement, VAX BASIC always transfers control to that statement. When the error occurs within a multi-statement line under the following conditions, VAX BASIC acts as follows: • Within a FOR, WHILE, or UNTIL loop, VAX BASIC transfers control to the first statement that follows the FOR, WHILE, or UNTIL statement. • Within a SELECT block, VAX BASIC transfers control to the start of the CASE block in which the error occurs. • After a loop or SELECT block, VAX BASIC transfers control to the statement that follows the NEXT or END SELECT statement. • If none of the above conditions occurs, VAX BASIC transfers control back to the statement that follows the most recent line number. 3. A RESUME statement with a specified line number transfers control to the first statement of a multi-statement line, regardless of which statement caused the error. 4. A RESUME statement with a specified label transfers control to the block of code indicated by that label. Example Error_routine: IF ERR = 11 THEN CLOSE #1 RESUME end_of_prog ELSE RESUME END IF end_of_prog: END 4-324 Statements and Functions RETRY RETRY The RETRY statement clears an error condition and reexecutes the statement that caused the error inside a protected region of a WHEN block. Format RETRY Syntax Rules The RETRY statement must appear lexically inside of a handler associated with a WHEN block. Remarks The following rules apply to errors that occur during execution of loop control statements (not the statements inside the loop body): • • • In FOR. .. NEXT loops, the RETRY statement reexecutes the FOR statement if the error occurs while VAX BASIC is evaluating the limit or increment values. In FOR. .. NEXT loops, if the error occurs while VAX BASIC is evaluating the index variable, the RETRY statement reexecutes the NEXT statement. In a FOR. .. UNTIL or FOR. .. WHILE loop, if an error occurs while VAX BASIC is evaluating the relational expression, the RETRY statement reexecutes the NEXT statement. Statements and Functions 4-325 RETRY Example 10 DECLARE LONG YOUR_AGE WHEN ERROR IN INPUT "Enter your age";your_age USE IF ERR = 60 THEN RETRY ELSE EXIT HANDLER END IF END WHEN 4-326 Statements and Functions RETURN RETURN The RETURN statement transfers control to the statement immediately following the most recently executed GOSUB or ON ... GOSUB statement in the current program unit. Format RETURN Syntax Rules None. Remarks 1. Once the RETURN is executed in a subroutine, no other statements in the subroutine are executed, even if they appear after the RETURN statement. 2. Execution of a RETURN statement before the execution of a GOSUB or ON ... GOSUB causes VAX BASIC to signal "RETURN without GOSUB" (ERR=72). Example GOSUB subroutine_1 subroutine_1: RETURN Statements and Functions 4-327 RIGHTS RIGHTS The RIGHT$ function extracts a substring from a string's right side, leaving the string unchanged. Format str-var =RIGHT[$] (str-exp, int-exp) Syntax Rules None. Remarks 1. The RIGHT$ function extracts a substring from str-exp and stores the substring in str-var. The substring begins with the character in the position specified by int-exp and ends with the rightmost character in the string. 2. If int-exp is less than or equal to zero, RIGHT$ returns the entire string. 3. If int-exp is greater than the length of str-exp, RIGHT$ returns a null string. 4. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to a LONG integer. 4-328 Statements and Functions RIGHTS Example DECLARE STRING main_str, & end_result main_str = "1234667" end_result = RIGHT$(main_str, 3) PRINT end_result Output 34667 Statements and Functions 4-329 RMSSTATUS RMSSTATUS The RMSSTATUS function returns the RMS status or the status value of the last I/O operation on a specified open I/O channel. Format long-var= RMSSTATUS ( chnl-exp ['STATUS ] ) I VALUE Syntax Rules 1. 2. Chnl-exp must be the number of a channel opened from a VAX BASIC routine. Chnl-exp cannot be zero. Remarks 1. If chnl-exp does not represent an open channel, VAX BASIC signals the error "I/O channel not open" (ERR=9). 2. If you do not specify either STATUS or VALUE, RMSSTATUS returns the STATUS value by default. 3. If you specify STATUS, RMSSTATUS returns the FAB$L_STS or the RAB$L_STS status value. However, if you specify VALUE, RMSSTATUS returns the FAB$L_STV or the RAB$L_STV status value. 4. Use the RMSSTATUS function to return the status of the following operations: • RESTORE • GET • PUT • UPDATE 4-330 Statements and Functions RMSSTATUS • • • • • • UNLOCK PRINT and PRINT USING INPUT, INPUT LINE, and LINPUT SCRATCH FREE Virtual array references To determine the reason for the failure of an OPEN, CLOSE, KILL, or NAME ... AS statement, use the VMSSTATUS function within an error handler. Examples Example 1 %TITLE "RMSSTATUS Example" Y.SBTTL "Reference Manual Examples" Y.IDENT "V1.0" PROGRAM Demo_RMSSTATUS_function OPTION CONSTANT TYPE = INTEGER OPEN "DOES_NOT_EXIST.LIS" FOR OUTPUT AS 1, SEQUENTIAL VARIABLE, RECORDSIZE 80 & & WHEN ERROR IN GET 11 USE PRINT "GET Operation failed" PRINT "RMS Status ="; RMSSTATUS(1,STATUS) PRINT "RMS Status Value ="; RMSSTATUS(1,VALUE) END WHEN END PROGRAM Example 2 OPTION TYPE=EXPLICIT EXTERNAL LONG CONSTANT RMS$_0K_DUP MAP (ORDER) LONG ORD_ENTRY, STRING ORD_CUST_NO = 6Y,, STRING ORD_REMARK = 60% & Statements and Functions 4-331 RMSSTATUS OPEN "ORD_DB" FOR INPUT AS FILE 1%, ORGANIZATION INDEXED FIXED, MAP ORDER, PRIMARY ORD_ENTRY NODUPLICATES, ALTERNATE ORD_CUST_NO DUPLICATES INPUT "Enter order number";ORD_ENTRY INPUT "Enter customer number";ORD_CUST_NO INPUT "Remark";ORD_REMARK Enter the order in the order database Check if the customer has other orders PUT #1% IF RMSSTATUS( 1%, STATUS ) = RMS$_0K_DUP THEN The customer has other orders; compute the customer's discount for other orders END IF CLOSE 1% END 4-332 Statements and Functions RND RND The RND function returns a random number greater than or equal to zero and less than 1. Format real-var= RND Syntax Rules None. Remarks 1. If the RND function is preceded by a RANDOMIZE statement, VAX BASIC generates a different random number or series of numbers each time a program executes. 2. The RND function returns a pseudorandom number if not preceded by a RANDOMIZE statement; that is, each time a program runs, VAX BASIC generates the same random number or series of random numbers. 3. The RND function returns a floating-point SINGLE value. 4. The RND function returns values over a uniform distribution between 0 and 1. For example, a value between 0 and .1 is as likely as a value between .5 and .6. Note the difference between this and a bell-curve distribution where the probability of values in the range .3 to .7 is higher than the outer ranges. July 1988 Statements and Functions 4-333 RND Example DECLARE REAL random_num RANDOMIZE FOR I = 1 TO 3 !FOR loop causes VAX BASIC to print three random numbers random_num = RND PRINT random_num NEXT I Output .865243 .477417 .734673 4-334 Statements and Functions RSET RSET The RSET statement assigns right-justified data to a string variable. RSET does not change a string variable's length. Format RSET str-var, ... = str-exp Syntax Rules Str-var cannot be a DEF function name unless the RSET statement is inside the DEF function definition. Remarks The RSET statement treats strings as fixed-length. It does not change the length of str-var, nor does it create new storage locations. 2. If str-var is longer than str-exp, RSET right-justifies the data and pads it with spaces on the left. 3. If str-var is shorter than str-exp, RSET truncates str-exp on the left. 1. Example DECLARE STRING test test = "ABCDE" RSET test = "123" PRINT "X" + test Output x 123 Statements and Functions 4-335 SCRATCH SCRATCH The SCRATCH statement deletes the current record and all following records in a sequential file. Format SCRATCH #chnl-exp Syntax Rules Chnl-exp is a numeric expression that specifies a channel associated with a file. It must be immediately preceded by a number sign ( # ). Remarks 1. 2. 3. 4. 5. 6. Before you execute the SCRATCH statement, the file must be opened with ACCESS SCRATCH. The SCRATCH statement applies to ORGANIZATION SEQUENTIAL files only. The SCRATCH statement has no effect on terminals or unit record devices. For disk files, the SCRATCH statement discards the current record and all that follows it in the file. The physical length of the file does not change. For magnetic tape files, the SCRATCH statement overwrites the current record with two end-of-file marks. Use of the SCRATCH statement on shared sequential files is not recommended. 4-336 Statements and Functions July 1988 SCRATCH SCRATCH #4% Statements and Functions . 4_ 337 SEGS SEGS The SEG$ function extracts a substring from a main string, leaving the original string unchanged. Format str-var = SEG$ (str-exp, int-exp1, int-exp2) Syntax Rules None. Remarks 1. 2. 3. 4. 5. 6. 4-338 VAX BASIC extracts the substring from str-exp, the main string, and stores the substring in str-var. The substring begins with the character in the position specified by int-expl and ends with the character in the position specified by int-exp2. If int-expl is less than l, VAX BASIC assumes a value of 1. If int-expl is greater than int-exp2 or the length of str-exp, the SEG$ function returns a null string. If int-expl equals int-exp2, the SEG$ function returns the character at the position specified by int-expl. Unless int-exp2 is greater than the length of str-exp, the length of the returned substring equals int-exp2 minus int-expl plus 1. If int-exp2 is greater than the length of str-exp, the SEG$ function returns all characters from the position specified by int-expl to the end of str-exp. If you specify a floating-point expression for int-expl or int-exp2, VAX BASIC truncates it to LONG integer. Statements and Functions SEGS Example DECLARE STRING alpha, center alpha = "ABCDEFGHIJK" center = SEG$(alpha, 4, 8) PRINT center Output DEFGH Statements and Functions 4-339 SELECT SELECT The SELECT statement lets you specify an expression, a number of possible values the expression may have, and a number of alternative statement blocks to be executed for each possible case. Format SELECT exp1 case-clause [ else-clause ] END SELECT case-clause: CASEcase-item, ... [ statement ]. .. case-item: [rel-op] exp2 } { exp3 TO exp4 [ ,exp5 TO exp6] ,... else-clause: CASE ELSE [ statement ]... 4-340 Statements and Functions SELECT Syntax Rules Exp1 is the expression to be tested against the case-clauses and the else-clause. It can be numeric or string. 2. Case-clause consists of the CASE keyword followed by a case-item and statements to be executed when the case-item is true. 3. Else-clause consists of the CASE ELSE keywords followed by statements to be executed when no previous case-item has been selected as 1. true. 4. Case-item is either an expression to be compared with exp1 or a range of values separated with the keyword TO. • Rel-op is a relational operator specifying how exp1 is to be compared to exp2. If you do not include a rel-op, VAX BASIC assumes the equals(=) operator. VAX BASIC executes the statements in the CASE block when the specified relational expression is true. • Exp3 and exp4 specify a range of numeric or string values separated by the keyword TO. Multiple ranges must be separated with commas. VAX BASIC executes the statements in the CASE block when exp1 falls within any of the specified ranges. 1. A SELECT statement can have only one else-clause. The else-clause is optional and, when present, must be the last CASE block in the SELECT block. Each statement in a SELECT block can have its own line number. The SELECT statement begins the SELECT BLOCK and the END SELECT keywords terminate it. VAX BASIC signals an error if you do not include the END SELECT keywords. Each CASE keyword establishes a CASE block. The next CASE or END SELECT keyword ends the CASE block. You can nest SELECT blocks within a CASE or CASE ELSE block. VAX BASIC evaluates exp1 when the SELECT statement is first encountered; VAX BASIC then compares expl with each case-clause in order of occurrence until a match is found or until a CASE ELSE block or END SELECT is encountered. Remarks 2. 3. 4. 5. 6. Statements and Functions 4-341 SELECT 7. The following conditions constitute a match: • Exp1 satisfies the relationship to exp2 specified by rel-op. • Exp1 is greater than or equal to exp3, but less than or equal to exp4, greater than or equal to expS but less than or equal to exp6, and so on. 8. When a match is found between exp1 and a case-item, VAX BASIC executes the statements in the CASE block where the match occurred. If ranges overlap, the first match causes VAX BASIC to execute the statements in the CASE block. After executing CASE block statements, control passes to the statement immediately following the END SELECT keywords. 9. If no CASE match occurs, VAX BASIC executes the statements in the else-clause, if present, and then passes control to the statement immediately following the END SELECT keywords. 10. If no CASE match occurs and you do not supply a case-else clause, control passes to the statement following the END SELECT keywords. Example 100 4-342 SELECT A% + B% + C% CASE = 100 PRINT 'THE VALUE IS EXACTLY 100' CASE 1 TO 99 PRINT 'THE VALUE IS BETWEEN 1 AND 99' CASE > 100 PRINT 'THE VALUE IS GREATER THAN 100' CASE ELSE PRINT 'THE VALUE IS LESS THAN 1' END SELECT Statements and Functions SET PROMPT SET PROMPT The SET PROMPT statement enables a question mark prompt to appear after VAX BASIC executes either an INPUT, LINPUT, INPUT LINE, MAT INPUT, or MAT LINPUT statement on channel #0. The SET NO PROMPT statement disables the question mark prompt. Format SET [NO] PROMPT Syntax Rules None. Remarks 1. If you do not specify a SET PROMPT statement, the default is SET PROMPT. 2. SET NO PROMPT disables VAX BASIC from issuing a question mark prompt for the INPUT, LINPUT, INPUT LINE, MAT INPUT, and MAT LINPUT statements on channel #0. 3. Prompting is reenabled when either a SET PROMPT statement or a CHAIN statement is executed, or when a NEW, OLD, RUN or SCRATCH command is executed in the BASIC environment. 4. The SET NO PROMPT statement does not affect the string constant you specify as the input prompt with the INPUT statement. Statements and Functions 4-343 SET PROMPT Example DECLARE STRING your_na.me, your_age, your_grade INPUT "Enter your na.me";your_na.me SET NO PROMPT INPUT "Enter your age";your_age SET PROMPT INPUT "Enter the last school grade you completed";your_grade Output Enter your name? Katherine Kelly Enter your age 15 Enter the last school grade you completed? 9 4-344 Statements and Functions SGN SGN The SGN function determines whether a numeric expression is positive, negative, or zero. It returns a 1 if the expression is positive, a -1 if the expression is negative, and zero if the expression is zero. Format int-var= SGN (real-exp) Syntax Rules None. Remarks 1. 2. 3. If real-exp does not equal zero, SGN returns MAG(real-exp)/real-exp. If real-exp equals zero, SGN returns a value of zero. SGN returns a LONG integer. Example DECLARE INTEGER sign sign = SGN(46/23) PRINT sign Output 1 Statements and Functions 4-345 SIN SIN The SIN function returns the sine of an angle in radians or degrees. Format real-var= SIN (real-exp) Syntax Rules Real-exp is an angle specified in radians or degrees depending upon which angle clause you choose with the OPTION statement. Remarks 1. 2. The returned value is between -1 and 1. VAX BASIC expects the argument of the SIN function to be a real expression. When the argument is a real expression, VAX BASIC returns a value of the same floating-point size. When the argument is not a real expression, VAX BASIC converts the argument to the default floating-point size and returns a value of the default floating-point size. Example OPTION ANGLE = RADIANS DECLARE REAL s1_angle s1_angle = SIN(PI/2) PRINT s1_angle Output 1 4-346 Statements and Functions SLEEP SLEEP The SLEEP statement suspends program execution for a specified number of seconds or until a carriage return is entered from the controlling terminal. Format SLEEP int-exp Syntax Rules 1. 2. Int-exp is the number of seconds VAX BASIC waits before resuming program execution. Int-exp must be between 0 and 2,147,483,647; if it is greater than 2,147,483,647, VAX BASIC signals the error "Integer error or overflow" (ERR=Sl). Remarks 1. 2. Pressing the RETURN key on the controlling terminal cancels the effect of the SLEEP statement. All characters typed while SLEEP is in effect, including a RETURN character entered to terminate the SLEEP statement, will remain in the typeahead buffer. Therefore, if you type RETURN without preceding data, an INPUT statement that follows the SLEEP will complete without data. Example SLEEP 120% July 1988 Statements and Functions 4-34 7 SPACES SPACES The SP ACE$ function creates a string containing a specified number of spaces. Format str-var =SPACE$ (int-exp) Syntax Rules Int-exp specifies the number of spaces in the returned string. Remarks 1. VAX BASIC treats an int-exp less than zero as zero. 2. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to a LONG integer. Example DECLARE STRING A, B A = "1234" B = "5678" PRINT A + SPACE$(5%) + B Output 1234 5678 4-348 Statements and Functions SOR SOR The SQR function returns the square root of a positive number. Format real-var= { SORT } (real-exp) SOR Syntax Rules None. Remarks 1. VAX BASIC signals the error "Imaginary square roots" (ERR=54) when real-exp is negative. 2. VAX BASIC assumes that the argument of the SQR function is a real expression. When the argument is a real expression, VAX BASIC returns a value of the same floating-point size. When the argument is not a real expression, VAX BASIC returns a value of the default floating-point size. Example DECLARE REAL root root = SQR(20•5) PRINT root Output 10 Statements and Functions 4-349 STATUS STATUS The STATUS function returns an integer value containing information about the last opened channel. Your program can test each bit to determine the status of the channel. NOTE The STATUS function is supported only for compatibility with other DIGITAL BASICs. DIGITAL recommends that you use the RMSSTATUS function for new program development. Format int-var= STATUS Syntax Rules None. Remarks The STATUS function returns a LONG integer. The value returned by the STATUS function is undefined until VAX BASIC executes an OPEN statement. 3. The STATUS value is reset by every input operation on any channel. Therefore, you should copy the STATUS value to a different storage location before your program executes another input operation. 4. If an error occurs during an input operation, the value of STATUS is undefined. When no error occurs, the six low-order bits of the returned value contain information about the type of device accessed by the last input operation. Table 4-6 lists STATUS bits set by VAX BASIC. 1. 2. 4-350 Statements and Functions STATUS Table 4-6: VAX BASIC STATUS Bits Bit Set Device Type 0 Record-oriented device 2 Terminal 3 Directory device 4 Single directory device 5 Sequential block-oriented device (magnetic tape) Carriage-control device Example 150 YY. = STATUS Statements and Functions 4-351 STOP STOP The STOP statement halts program execution allowing you to optionally continue execution. Format STOP Syntax Rules None. Remarks 1. The STOP statement cannot appear before a PROGRAM, SUB or FUNCTION statement. 2. The STOP statement does not close files. 3. When a STOP statement executes in a program executed with the RUN command in the BASIC environment, VAX BASIC prints the line number and module name associated with the STOP statement, then displays the Ready prompt. In response to the prompt, you can type immediate mode statements, CONTINUE to resume program execution, or any valid compiler command. See the VAX BASIC User Manual for more information on immediate mode. 4. When a STOP statement is in an executable image, the line number, module name, and a number sign ( # ) prompt are printed. In response to the prompt, you can type CONTINUE to continue program execution or EXIT to end the program. If the program module was compiled with the /NOLINE qualifier, no line number is displayed. 4-352 Statements and Functions STOP Example PROGRAM Stopper PRINT "Type CONTINUE when the program stops" INPUT "Do you want to stop now"; Quit$ IF Quit$ = "Y" THEN STOP ELSE PRINT "So what are you waiting for?" STOP END IF PRINT "You told me to continue ... thank you" END PROGRAM Output Do you want to stop now? CONTINUE So what are you waiting for? Statements and Functions 4-353 STRS STRS The STR$ function changes a numeric expression to a numeric character string without leading and trailing spaces. Format str-var = STR$ (num-exp) Syntax Rules None. Remarks 1. If num-exp is negative, the first character in the returned string is a minus sign ( - ). 2. The STR$ function does not return leading or trailing spaces. 3. When you print a floating-point number that has six decimal digits or more but the integer portion has six digits or less (for example, 1234.567), VAX BASIC rounds the number to six digits (1234.57). If a floating-point number's integer part is seven decimal digits or more, VAX BASIC rounds the number to six digits and prints it in E format. 4. When you print a floating-point number with magnitude between 0.1 and 1, VAX BASIC rounds it to six digits. When you print a number with magnitude smaller than 0.1, VAX BASIC rounds it to six digits and prints it in E format. 5. The STR$ function returns up to 10 digits for LONG integers and up to 31 digits for DECIMAL numbers. 4-354 Statements and Functions STRS Example DECLARE STRING new_num new_num = STR$(1543.659) PRINT new_num Output 1543.66 Statements and Functions 4-355 STRINGS STRINGS The STRING$ function creates a string containing a specified number of identical characters. Format str-var =STRING$ (int-exp1, int-exp2) Syntax Rules lnt-expl specifies the character string's length. 2. lnt-exp2 is the decimal ASCII value of the character that makes up the 1. string. This value is treated modulo 256. Remarks VAX BASIC signals the error "String too long" (ERR=227) if int-expl is greater than 65535. 2. If int-expl is less than or equal to zero, VAX BASIC treats it as zero. 3. VAX BASIC treats int-exp2 as an unsigned 8-bit integer. For example, -1 is treated as 255. 4. If either int-expl or int-exp2 is a floating-point expression, VAX BASIC truncates it to a LONG integer. 1. 4-356 Statements and Functions STRINGS Example DECLARE STRING output_str output_str = STRING$(10%, 60%) PRINT output_str !50 is the ASCII value of the !character "2" Output 2222222222 Statements and Functions 4-357 SUB SUB The SUB statement marks the beginning of a VAX BASIC subprogram and specifies the number and data type of its parameters. Format SUB sub-name [ pass-mech] [ ( [ farmal-param ], ... ) ] [ statement ] ... END SUB } { SU BEND pass-mech: BY REF } { BY DESC unsubs-var farmal-param: [ data-tvne] , ,., { array-name ( [ int-canst ] , ... ' [ = int-canst J [ pass-mech J Syntax Rules 1. Sub-name is the name of the separately compiled subprogram. 2. Formal-param specifies the number and type of parameters for the arguments the SUB subprogram expects to receive when invoked. • Empty parentheses indicate that the SUB subprogram has no parameters. 4-358 Statements and Functions SUB • 3. 4. 5. 6. 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. Data type keywords and their size, range, and precision are listed in Table 1-2 in this manual. Sub-name can have from 1 to 31 characters and must conform to the following rules: • The first character of an unquoted name must be an alphabetic character (A through Z). The remaining characters, if present, can be any combination of letters, digits (0 through 9), dollar signs ( $ ), periods (. ), or underscores (-)· • A quoted name can consist of any combination of printable ASCII characters. Data-type can be any VAX BASIC data type keyword or a data type defined by a RECORD statement. Pass-mech specifies the parameter passing mechanism by which the subprogram receives arguments. A pass-mech clause outside the parentheses applies by default to all SUB parameters. A pass-mech clause in the formal-param list overrides the specified default and applies only to the immediately preceding parameter. Remarks 1. The SUB statement must be the first statement in the SUB subprogram. 2. Compiler directives and comment fields created with an exclamation point ( ! ), can precede the SUB statement because they are not VAX BASIC statements. Note that REM is a VAX BASIC statement; therefore, it cannot precede the SUB statement. 3. Every SUB statement must have a corresponding END SUB statement or SUBEND statement. 4. If you do not specify a passing mechanism, the SUB program receives arguments by the default passing mechanisms, as shown in Table 4-1. 5. Parameters defined in formal-param must agree in number, type, ordinality, and passing mechanism with the arguments specified in the CALL statement of the calling program. Statements and Functions 4-359 SUB 6. 7. You can specify up to 255 parameters. Any VAX BASIC statement except those that refer to other program unit types (FUNCTION, PICTURE or PROGRAM) can appear in a SUB subprogram. 8. All variables, except those named in MAP and COMMON statements are local to that subprogram. 9. VAX BASIC initializes local variables to zero or the null string. 10. SUB subprograms receive parameters by reference or by descriptor. A SUB subprogram cannot receive any parameter BY VALUE. Table 4-1 lists and describes VAX BASIC parameter-passing mechanisms. • BY REF specifies that the subprogram receives the argument's address. • BY DESC specifies that the subprogram receives the address of a VAX BASIC descriptor. For information about the format of a VAX BASIC descriptor for strings and arrays, see the VAX BASIC User Manual. For information on other types of descriptors, see the VAX Architecture Handbook. 11. By default, VAX BASIC subprograms receive numeric unsubscripted variables by reference, and all other parameters by descriptor. You can override these defaults for strings and arrays with a BY clause: • If you specify a string length with the =int-canst clause, you must also specify BY REF. If you specify BY REF and do not specify a string length, VAX BASIC uses the default string length of 16. • If you specify array bounds, you must also specify BY REF. 12. Subprograms can be called recursively. Example SUB SUB3 BY REF (DOUBLE A, B, STRING Emp_nam BY DESC, wage(20)) END SUB 4-360 Statements and Functions t t SU BEND SU BEND The SUBEND statement is a synonym for the END SUB statement. See the END statement for more information. Format SU BEND Statements and Functions 4-361 SUB EXIT SUB EXIT The SUBEXIT statement is a synonym for the EXIT SUB statement. See the EXIT statement for more information. Format SUB EXIT 4-362 Statements and Functions SUMS SUMS The SUM$ function returns a string whose value is the sum of two numeric strings. Format str-var =SUM$ (str-exp1, str-exp2) Syntax Rules None. Remarks 1. 2. 3. 4. 5. 6. 7. Each string expression can contain up to 54 ASCII digits and an optional decimal point and sign. VAX BASIC adds str-exp2 to str-exp1 and stores the result instr-var. If str-exp1 and str-exp2 are integers, str-var takes the precision of the larger string unless trailing zeros generate that precision. If str-exp1 and str-exp2 are decimal fractions, str-var takes the precision of the more precise fraction, unless trailing zeros generate that precision. SUM$ omits trailing zeros to the right of the decimal point. The sum of two fractions takes precision as follows: • The sum of the integer parts takes the precision of the larger part. • The sum of the decimal fraction part takes the precision of the more precise part. SUM$ truncates leading and trailing zeros. Statements and Functions 4-363 SUMS Example DECLARE STRING A, 8, total = "46" = "87" total = SUM$(A,B) A B PRINT total Output 133 4-364 Statements and Functions SWAP% SWAP% The SWAP% function transposes a WORD integer's bytes. NOTE The SWAP% function is supported only for compatibility with BASIC-PLUS-2. DIGITAL recommends that you do not use the SWAP% function for new program development. Format int-var= SWAP% (int-exp) Syntax Rules None. Remarks 1. 2. SWAP% is a WORD function. VAX BASIC evaluates int-exp and converts it to the WORD data type, if necessary. VAX BASIC transposes the bytes of int-exp and returns a WORD integer. Example DECLARE INTEGER word_int word_int = SWAP%(23) PRINT word_int Output 5888 Statements and Functions 4-365 TAB TAB When used with the PRINT statement, the TAB function moves the cursor or print mechanism to a specified column. When used outside the PRINT statement, the TAB function creates a string containing the specified number of spaces. Format str-var =TAB(int-exp) Syntax Rules 1. 2. When used with the PRINT statement, int-exp specifies the column number of the cursor or print mechanism. When used outside the PRINT statement, int-exp specifies the number of spaces in the returned string. Remarks 1. You cannot tab beyond the current MARGIN restriction. 2. The leftmost column position is zero. 3. If int-exp is less than the current cursor position, the TAB function has no effect. 4. The TAB function can move the cursor or print mechanism only from the left to the right. 5. You can use more than one TAB function in the same PRINT statement. 6. Use semicolons to separate multiple TAB functions in a single statement. If you use commas, VAX BASIC moves to the next print zone before executing the TAB function. 4-366 Statements and Functions July 1988 TAB 7. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to LONG integer. Statements and Functions 4-366.1 TAB Example PRINT "Number 1"; TAB(16); "Number 2 11 ; TAB(30); "Number 3" Output Number 1 Number 2 Number 3 Statements and Functions 4-367 TAN TAN The TAN function returns the tangent of an angle in radians or degrees. Format real-var =TAN(real-exp) Syntax Rules Real-exp is an angle specified in radians or degrees, depending on which angle clause you choose with the OPTION statement. Remarks VAX BASIC expects the argument of the TAN function to be a real expression. When the argument is a real expression, VAX BASIC returns a value of the same floating-point size. When the argument is not a real expression, VAX BASIC converts the argument to the default floating-point size and returns a value of the default floating-point size. Example OPTION ANGLE = DEGREES DECLARE REAL tangent tangent = TAN(45.0) PRINT tangent Output 1 4-368 Statements and Functions TIME TIME The TIME function returns the time of day (in seconds) as a floatingpoint number. The TIME function can also return process CPU time and connect time. Format real-var =TIME(int-exp) Syntax Rules None. Remarks 1. The value returned by the TIME function depends on the value of int-exp. 2. If int-exp equals zero, TIME returns the number of seconds since midnight. 3. VAX BASIC also accepts values 1 and 2 and returns values as shown in Table 4-7. All other arguments to the TIME function are undefined and cause VAX BASIC to signal "Not implemented" (ERR=250). 4. The TIME function returns a SINGLE floating-point value. 5. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to a LONG integer. Statements and Functions 4-369 TIME Table 4-7: Argument Value: VAX BASIC Returns: 0 The amount of time elapsed since midnight in seconds 1 The CPU time of the current process in tenths of a second 2 The connect time of the current process in minutes Example PRINT TIME(O) Output 49671 4-370 TIME Function Values Statements and Functions TIMES TIMES The TIME$ function returns a string displaying the time of day in the form hh:mm AM or hh:mm PM. format str-var =11ME$(int-exp) Syntax Rules Int-exp specifies the number of minutes before midnight. Remarks 1. If int-exp equals zero, TIME$ returns the current time of day. 2. The value of int-exp must be between 0 and 1440 or VAX BASIC signals an error. 3. The TIME$ function uses a 12-hour, AM/PM clock. Before 12:00 noon, TIME$ returns hh:mm AM, and after 12:00 noon, hh:mm PM. 4. If you specify a floating-point expression for int-exp, VAX BASIC truncates it to a LONG integer. Example DECLARE STRING current_time current_time = TIME$(0) PRINT current_time Output 01:51 PM Statements and Functions 4-371 TRMS TRMS The TRM$ function removes all trailing blanks and tabs from a specified string. Format str-var =TRM$(str-exp) Syntax Rules None. Remarks The returned str-var is identical to str-exp, except that it has all the trailing blanks and tabs removed. Example DECLARE STRING old_string, new_string old_string = "ABCDEFG " new_string = TRM$(old_string) PRINT old_string;"XYZ" PRINT new_string;"XYZ" Output ABCDEFG ABCDEFGXYZ 4-372 Statements and Functions XYZ UBOUND UBOUND The UBOUND function returns the upper bounds of a compile-time or run-time dimensioned array. Format num-var = UBOUND (array-name [, num-exp ]) Syntax Rules 1. Array-name must specify an array that has been previously explicitly 2. or implicitly declared. Num-exp specifies the number of the dimension for which you have requested the upper bound. Remarks 1. If you do not specify a numeric expression, VAX BASIC automatically returns the upper bound of the first dimension. 2. If you specify a numeric expression that is less than or equal to zero, VAX BASIC signals an error message. 3. If you specify a numeric expression that exceeds the number of dimensions, VAX BASIC signals an error message. Statements and Functions 4-373 UBOUND Example DECLARE INTEGER CONSTANT B = 6 DIM A(B) account_num = 1 FOR dim_num = 0 TO UBOUND(A) A(dim_num) = account_num account_num = account_num + 1 PRINT A(dim_num) NEXT dim_num Output 1 2 3 4 6 6 4-374 Statements and Functions UNLESS UNLESS The UNLESS qualifier modifies a statement. VAX BASIC executes the modified statement only if a conditional expression is false. Format statement UN LESS cond-exp Syntax Rules None. Remarks 1. 2. The UNLESS statement cannot be used on nonexecutable statements or on statements such as SELECT, IF, and DEF that establish a statement block. VAX BASIC executes the statement only if cond-exp is false (value zero). Example PRINT "A DOES NOT EQUAL 3" UNLESS AY. = 3Y. Statements and Functions 4-375 UNLOCK UNLOCK The UNLOCK statement unlocks the current record or bucket locked by the last FIND or GET statement. Format UNLOCK #chnl-exp Syntax Rules Chnl-exp is a numeric expression that specifies a channel number associated with a file. It must be immediately preceded by a number sign (# ). Remarks 1. A file must be opened on the specified channel before UNLOCK can execute. 2. The UNLOCK statement only applies to files on disk. 3. If the current record is not locked by a previous GET or FIND statement, the UNLOCK statement has no effect and VAX BASIC does not signal an error. 4. The UNLOCK statement does not affect record buffers. 5. After VAX BASIC executes the UNLOCK statement, you cannot update or delete the current record. 6. Once the UNLOCK statement executes, the position of the current record pointer is undefined. 4-376 Statements and Functions UNLOCK Example UNLOCK #101. Statements and Functions 4-377 UNTIL UNTIL The UNTIL statement marks the beginning of an UNTIL loop or modifies the execution of another statement. Format Conditional UNTIL cond-exp [ statement ]... NEXT Statement Modifier statement UNTIL cond-exp Syntax Rules None. Remarks 1. Conditional • A NEXT statement must end the UNTIL loop . • VAX BASIC evaluates cond-exp before each loop iteration. If the expression is false (value zero), VAX BASIC executes the loop. If the expression is true (value nonzero), control passes to the first executable statement after the NEXT statement. 4-378 Statements and Functions UNTIL 2. Statement Modifier VAX BASIC executes the statement repeatedly until cond-exp is true. Examples Example 1 !Conditional UNTIL A >= 5 A = A + .01 TOTAL = TOTAL + 1 NEXT Example 2 !Statement Modifier A = A + 1 UNTIL A >= 200 Statements and Functions 4-379 UPDATE UPDATE The UPDATE statement replaces a record in a file with a record in the record buffer. The UPDATE statement is valid on sequential, relative, and indexed files. Format UPDATE #chnl-exp [,COUNT int-exp] Syntax Rules 1. 2. Chnl-exp is a numeric expression that specifies a channel number associated with a file. It must be immediately preceded by a number sign ( # ). Int-exp specifies the size of the new record. Remarks 1. 2. 3. 4. 4-380 The file associated with chnl-exp must be a disk file opened with ACCESS MODIFY. Each UPDATE statement must be preceded by a successful GET or FIND operation or VAX BASIC signals "No current record" (ERR=131). FIND locates but does not retrieve records. Therefore, you must specify a COUNT clause when retrieving variable-length records when the preceding operation was a FIND. Int-exp must exactly match the size of the old record. If you are updating a variable-length record, and the record that you want to write out is not the same size as the record you retrieved, you must use a COUNT clause. After an UPDATE statement executes, there is no current record pointer. The next record pointer is unchanged. Statements and Functions July 1988 UPDATE 5. The length of the new record must be the same as that of the existing record for all files with fixed-length records and for all sequential files. If you specify a COUNT clause, the int-exp must match the size of the existing record. 6. For relative files with variable-length records, the new record can be larger or smaller than the record it replaces. • The new record must be smaller than or equal to the maximum record size set with the MAP or RECORDSIZE clause when the file was opened. • You must use the COUNT clause to specify the size of the new record if it is different from that of the record last accessed by a GET operation on that channel. 7. For indexed files with variable-length records, the new record can be larger or smaller than the record it replaces. When the program does not permit duplicate primary keys, the new record can be no longer than the size specified by the MAP or RECORDSIZE clause when the file was opened. The record must include at least the primary key field. 8. An indexed file alternate key for the new record can differ from that of the existing record only if the OPEN statement for that file specified CHANGES for the alternate key. Example UPDATE #4%, COUNT 32 July 1988 Statements and Functions 4-381 VAL VAL The VAL function converts a numeric string to a floating-point value. NOTE DIGITAL recommends that you use the DECIMAL, REAL, and INTEGER functions to convert numeric strings to numeric data types. Format real-var= VAL (str-exp) Syntax Rules Str-exp can contain the ASCII digits 0 through 9, uppercase E, a plus sign ( + ), a minus sign ( - ), and a period ( . ). Remarks 1. 2. 3. The VAL function ignores spaces and tabs. If str-exp is null, or contains only spaces and tabs, VAL returns a value of zero. The value returned by the VAL function is of the default floating-point size. 4-382 Statements and Functions VAL Example DECLARE REAL real_num real_num = VAL("990.32") PRINT real_num Output 990.32 Statements and Functions 4-383 VAL% VAL% The VAL% function converts a numeric string to an integer. NOTE DIGITAL recommends that you use the DECIMAL, REAL, and INTEGER functions to convert numeric strings to numeric data types. Format int-var= VAL% (str-exp) Syntax Rules Str-exp can contain the ASCII digits 0 through 9, a plus sign ( + ), or a minus sign ( - ). Remarks 1. The VAL% function ignores spaces and tabs. 2. If str-exp is null or contains only spaces and tabs, VAL% returns a value of zero. 3. The value returned by the VAL% function is an integer of the default size. 4-384 Statements and Functions VALo/o Example DECLARE INTEGER ret_int ret_int = VAL7.("789") PRINT ret_int Output 789 Statements and Functions 4-385 VMSSTATUS VMSSTATUS VMSSTATUS returns the underlying VAX/VMS condition code when control is transferred to a VAX BASIC error handler. Format int-var= VMSSTATUS Syntax Rules None. Remarks If ERR contains the value 194, you can specify VMSSTATUS to examine the actual error that was signaled to VAX BASIC. 2. If an error is raised by an underlying system component such as the Run-Time Library, you can specify VMSSTATUS to determine the underlying error. 3. If you are writing a utility routine that may be called from languages other than VAX BASIC, you can specify VMSSTATUS in a call to LIB$SIGNAL to signal the underlying error to the caller of the utility routine. 4. When there is no error pending, VMSSTATUS remains undefined. 1. 4-386 Statements and Functions VMSSTATUS Example PROGRAM WHEN ERROR USE global_handler END WHEN HANDLER global_handler final_statusY, = VMSSTATUS END HANDLER END PROGRAM final_statusY. Statements and Functions 4-387 WAIT WAIT The WAIT statement specifies the number of seconds the program waits for terminal input before signaling an error. Format WAIT int-exp Syntax Rules Int-exp must be between 0 and 255; if it is greater than 255, VAX BASIC assumes a value of 255. Remarks 1. 2. 3. 4. 4-388 The WAIT statement mmt precede a GET operation to a terminal or an INPUT, INPUT LINE, LINPUT, MAT INPUT, or MAT LINPUT statement. Otherwise, it has no effect. Int-exp is the number of seconds VAX BASIC waits for input before signaling the error, "Keyboard wait exhausted" (ERR=lS). After VAX BASIC executes a WAIT statement, all input statements wait the specified amount of time before VAX BASIC signals an error. WAIT 0 disables the WAIT statement. Statements and Functions WAIT Example 10 DECLARE STRING your_name WAIT 60 INPUT "You have sixty seconds to type your name";your_name WAIT 0 Output You have sixty seconds to type your name? Y.BAS-F-KEYWAIEXH, Keyboard wait exhausted -BAS-I-ON_CHAFIL, on channel 0 for file SYS$INPUT:.; at user PC 00000644 -RMS-W-TMO, timeout period expired -BAS-I-FROLINMOD, from line 10 in module WAIT Y.TRACE-F-TRACEBACK, symbolic stack dump follows routine name module name line rel PC abs PC 00007334 00007334 ----- above condition handler called with exception 001A807C: %BAS-F-KEYWAIEXH, keyboard wait exhausted -BAS-I-ON_CHAFIL, on channel 0 for file SYS$INPUT:.; at user PC 00000644 -RMS-W-TMO, timeout period expired ----- end of exception message 00011618 00011618 OOOOF02F OOOOF02F OOOOE3F6 OOOOE3F6 0001387A 0001387A WAIT$MAIN WAIT$MAIN 00000044 00000644 3 Statements and Functions 4-389 WHEN ERROR WHEN ERROR The WHEN ERROR statement marks the beginning of a WHEN ERROR construct. The WHEN ERROR construct contains a protected region and can include an attached handler or identify a detached handler. Format With an Attached Handler WHEN ERROR IN protected-staterr1ent [ protected-staterr1ent,... ] USE handler-staterr1ent [ handler-staterr1ent, ... ] END WHEN With a Detached Handler WHEN ERROR USE handler-narr1e protected-staterr1ent [ protected-staterr1ent, ... ] END WHEN 4-390 Statements and Functions WHEN ERROR HANDLER handler-name handler-statement... END HANDLER Syntax Rules 1. 2. 3. 4. Protected-statement specifies a statement that appears within a protected region. A protected region is a special block of code that is monitored by VAX BASIC for the occurrence of a run-time error. Handler-statement specifies the statement that appears inside an error handler. With an Attached Handler • The keyword USE marks the start of handler statements. • An attached handler must be delimited by a USE and END WHEN statement. With a Detached Handler • The keyword USE names the associated handler for the protected region. • Handler-name must be a valid VAX BASIC identifier and cannot be the same as any label, DEF, DEF•, SUB, FUNCTION or PICTURE name within the same program unit. • A detached handler must be delimited by a HANDLER and END HANDLER statement. • You can specify the same detached handler with more than one WHEN ERROR USE statement. Statements and Functions 4-391 WHEN ERROR Remarks 1. The WHEN ERROR statement designates the start of a block of protected statements. 2. If an error occurs inside a protected region, VAX BASIC transfers control to the error handler associated with the WHEN ERROR statement. 3. VAX BASIC does not allow you branch into a WHEN block. 4. When VAX BASIC encounters an END WHEN statement for an attached handler or an END HANDLER statement for a detached handler, VAX BASIC clears the exception and transfers control to the following statement. 5. VAX BASIC allows you to nest WHEN blocks. If an exception occurs within a nested protected region, VAX BASIC transfers control to the handler associated with the innermost protected region in which the error occurred. 6. WHEN blocks cannot exist inside a handler. 7. WHEN blocks cannot cross other block structures. 8. You cannot specify a RESUME statement within a WHEN ERROR construct. 9. You cannot specify an ON ERROR statement within a protected region. 10. An attached handler must immediately follow the protected region of a WHEN ERROR IN block. 11. Exit from a handler must occur through a RETRY, CONTINUE, or EXIT HANDLER statement, or by reaching the end of the handler delimited by END WHEN or END HANDLER. 12. For more information about detached handlers, see the HANDLER statement. 4-392 Statements and Functions WHEN ERROR Examples Example 1 !With an attached handler PROGRAM salary DECLARE REAL hourly_rate, no_of_hours, weekly_pay WHEN ERROR IN INPUT "Enter your hourly rate";hourly_rate INPUT "Enter the number of hours you worked this week";no_of_hours weekly_pay = no_of_hours * hourly_rate PRINT "Your pay for this week is";weekly_pay USE SELECT ERR CASE 50 PRINT "Invalid data" RETRY CASE ELSE EXIT HANDLER END SELECT END WHEN END PROGRAM Output 1 Enter your hourly rate? 35.00 Enter the number of hours you worked this week? 45 Your pay for this week is 1575 Example 2 !With a detached handler PROGRAM salary DECLARE REAL hourly_rate, no_of_hours, weekly_pay WHEN ERROR USE patch_work INPUT "Enter your hourly rate";hourly_rate INPUT "Enter the number of hours you worked this week";no_of_hours weekly_pay = no_of_hours * hourly_rate PRINT "Your pay for this week is";weekly_pay END WHEN Statements and Functions 4-393 WHEN ERROR HANDLER patch_work SELECT ERR CASE = 60 PRINT "Invalid data" RETRY CASE ELSE EXIT HANDLER END SELECT END HANDLER END PROGRAM Output 2 Enter your hourly rate? Nineteen dollars and fifty cents Invalid data Enter your hourly rate? 19.60 Enter the number of hours you worked this week? 40 Your pay for this week is 780 4-394 Statements and Functions WHILE WHILE The WHILE statement marks the beginning of a WHILE loop or modifies the execution of another statement. Format Conditional WHILE cond-exp [ statement ]... NEXT Statement Modifier statement WHILE cond-exp Syntax Rules A NEXT statement must end the WHILE loop. Remarks 1. Conditional VAX BASIC evaluates cond-exp before each loop iteration. If the expression is true (value nonzero), VAX BASIC executes the loop. If the expression is false (value zero), control passes to the first executable statement after the NEXT statement. Statements and Functions 4-395 WHILE 2. Statement Modifier VAX BASIC executes the statement repeatedly as long as cond-exp is true. Examples Example 1 !Conditional WHILE X < 100 X = X + SQR(X) NEXT Example 2 !Statement Modifier XY. = XY. + 1Y. WHILE XY. < 1001. 4-396 Statements and Functions XLATES XLATES The XLATE$ function translates one string to another by referencing a table string you supply. Format str-var = XLATE[$] (str-exp1, str-exp2) Syntax Rules Str-exp1 is the input string. 2. Str-exp2 is the table string. 1. Remarks Str-exp2 can contain up to 256 ASCII characters, numbered from 0 to 255; the position of each character in the string corresponds to an ASCII value. Because 0 is a valid ASCII value (null), the first position in the table string is position zero. 2. XLATE$ scans str-exp1 character by character, from left to right. It finds the ASCII value n of the first character in str-exp1 and extracts the character it finds at position n in str-exp2. XLATE$ then appends the character from str-exp2 to str-var. XLATE$ continues this process, character by character, until the end of str-exp1 is reached. 3. The output string may be smaller than the input string for the following reasons: • XLATE$ does not translate nulls. If the character at position n in str-exp2 is a null, XLATE$ does not append that character to 1. str-var. • If the ASCII value of the input character is outside the range of positions in str-exp2, XLATE$ does not append any character to str-var. Statements and Functions 4-397 XLATES Example DECLARE STRING A, table, source A = "abcdefghijklmnopqrstuvwxyz" table = STRING$(65, 0) + A LINPUT "Type a string of uppercase letters"; source PRINT XLATE$(source, table) Output Type a string of uppercase letters? ABCDEFG abcdef g 4-398 Statements and Functions Appendix A Transporting Programs Between VAX BASIC and BASIC-PLUS-2 This appendix summarizes transportability issues between BASIC-PLUS-2 and VAX BASIC. A. 1 Overview This appendix is for users who want to write BASIC programs that can be used in both VAX BASIC and PDP-11 BASIC-PLUS-2. It describes functionality that is particular to one language, as well as statements and functions that appear the same in both languages, but produce different results. · Note that this appendix does not describe all the differences between VAX BASIC and BASIC-PLUS-2. To assist you in writing transportable programs, use the DCL command BASIC/FLAG=BP2COMPATIBILITY when you invoke VAX BASIC. This command causes VAX BASIC to signal an informational message whenever you use functionality that is not compatible with BASIC-PLUS-2. This appendix contains the following sections: • • • • • Language-specific functionality I/O differences Procedure calling Generated errors Miscellaneous differences Transporting Programs Between VAX BASIC and BASIC-PLUS-2 A-1 A.2 Language-Specific Functionality The following statements, functions, and clauses are available only in BASIC-PLUS-2: • • • • • • Specifying a line number with the CHAIN statement t The FSS$ function The ONECHR function (see the VAX BASIC INKEY$ function) The PEEK function t The SPEC% function t The CLUSTERSIZE and MODE clauses on the OPEN statement t VAX BASIC supports the following functionality which is not available in BASIC-PLUS-2: • • • • • • • • • Graphics Support for the VAX Language-Sensitive Editor Non-zero lower bounds for arrays WHEN blocks Return values on the END, EXIT DEF, END DEF, EXIT FUNCTION, and END FUNCTION statements Dollar sign ( $) and percent sign ( % ) suffixes in explicitly declared variables User-defined data types with the RECORD statement DECIMAL, GFLOAT, and HFLOAT data types Hexadecimal, binary, and octal literal notation The following statements, functions, and commands are available only in VAX BASIC: • • • • • • The %DECLARED directive The %INCLUDE %FROM %CDD directive The %INCLUDE %FROM %LIBRARY directive The %PRINT directive All graphics statements The CAUSE ERROR statement t Specific to BASIC-PLUS-2 on RSTS/E systems. A-2 Transporting Programs Between VAX BASIC and BASIC-PLUS-2 • • • • • • • • • • • • • • • • The FREE statement The FIND statement with the ALLOW, REGARDLESS, and WAIT clauses The GET statement with the ALLOW, REGARDLESS, and WAIT clauses The MID$ assignment statement The OPTION CONSTANT TYPE, OPTION HANDLE, and OPTION ANGLE statements The PROGRAM, END PROGRAM and EXIT PROGRAM statements The RECORD statement All WHEN block statements and clauses (WHEN ... END WHEN, HANDLER ... END HANDLER, CONTINUE, RETRY, and EXIT HANDLER) The DECIMAL function The INKEY$ function The LBOUND and UBOUND functions The LOC function The MARGIN and NOMARGIN functions The MAX, MIN, and MOD functions The VMSSTATUS and RMSSTATUS functions The ANY and OPTIONAL keywords in EXTERNAL routine declarations A.3 1/0 Differences This section discusses some I/O differences between VAX BASIC and BASIC-PLUS-2. A.3.1 The MAGTAPE Function VAX BASIC does not support the MAGTAPE function except for the rewind tape function (code 3). Table A-1 describes the VAX BASIC actions you can perform to obtain other MAGTAPE functionality. Transporting Programs Between VAX BASIC and BASIC-PLUS-2 A-3 Table A-1: MAGTAPE Functionality in VAX BASIC Code Function VAX BASIC Action 2 Write EOF Close channel with the CLOSE statement 3 Rewind tape Use the RESTORE # statement, the REWIND clause on an OPEN statement, or the MAGTAPE function 4 Skip records Perform GET operations, ignore data until reaching desired record 5 Backspace Rewind tape, perform GET operations, ignore data until reaching desired record 6 Set density or set parity Use the DCL commands MOUNT/DENSITY and MOUNT /FOREIGN or the $MOUNT system service 7 Get status Use the RMSSTATUS function A.3.2 The OPEN Statement The following differences exist in the OPEN statement when used in VAX BASIC and BASIC-PLUS-2: • • • In VAX BASIC, a map named in an OPEN statement is never initialized; in BASIC-PLUS-2, variables in the map are initialized to zero or to the null string. In VAX BASIC, an OPEN error causes the STATUS variable to be set to zero. In BASIC-PLUS-2, an OPEN error causes the STATUS variable to be set to the RMS STS field value. Use the VAX BASIC RMSSTATUS function to return the RMS STS field value. Both VAX BASIC and BASIC-PLUS-2 allow you to omit key clauses when opening an existing indexed fie. However, VAX BASIC requires that you explicitly specify FOR INPUT; BASIC-PLUS-2 does not. The following OPEN statement clauses produce different results when used in VAX BASIC and BASIC-PLUS-2: • The ALLOW Clause VAX BASIC requires that you have write access to a file in order to specify ALLOW NONE in an OPEN statement; BASIC-PLUS-2 does not. A-4 Transporting Programs Between VAX BASIC and BASIC-PLUS-2 • The CLUSTERSIZE Clause • The CLUSTERSIZE clause can be used with an OPEN statement on RSTS/E systems only. In VAX BASIC and BASIC-PLUS-2 on RSX systems, you can obtain functionality similar to the CLUSTERSIZE clause by using the EXTENDSIZE and WINDOWSIZE clauses. The EXTENDSIZE clause specifies the amount of space a file is extended after the existing space is full. The WINDOWSIZE clause specifies the number of block retrieval pointers that are kept in memory for the file. The CONTIGUOUS Clause • In VAX BASIC, using the CONTIGUOUS clause with an OPEN statement does not necessarily mean the file will occupy contiguous disk space. If there is not enough contiguous space available, RMS allocates the largest possible contiguous space and does not signal an error. In BASIC-PLUS-2, if there is not enough contiguous space available, RMS signals an error. The MODE Clause The MODE clause cannot be used with an OPEN statement in VAX BASIC. In BASIC-PLUS-2 on RSX systems, the MODE clause is ignored except when used for device-specific 1/0. Table A-2 lists transportable BASIC statements that correspond to RSTS/E disk MODE values. You can use these statements in VAX BASIC as well as in BASIC-PLUS-2 on RSX systems. Transporting Programs Between VAX BASIC and BASIC-PLUS-2 A-5 Table A-2: RSTS/E Disk MODE Values and Corresponding BASIC Statements MODE Value Function Transportable Statement 0% Normal read/write Use OPEN with ACCESS MODIFY and ALLOW MODIFY 1% Update file Use OPEN with ACCESS MODIFY 2% Append to file Use OPEN with ACCESS APPEND 5% Update file Use OPEN with ACCESS MODIFY and ALLOW MODIFY 16% Create contiguous Use OPEN with CONTIGUOUS 32% Create tentative file Use OPEN with TEMPORARY 64% Create contiguous file con di tionall y Use OPEN with CONTIGUOUS 4096% Read only regardless Use GET or FIND with REGARDLESS 1 8192% Read Only Use OPEN with ACCESS READ l The REGARDLESS clause is not available in BASIC-PLUS-2. • The RECORDSIZE Clause In all VAX BASIC files and BASIC-PLUS-2 RMS files, the RECORDSIZE clause specifies the RMS logical record size. In BASICPLUS-2 virtual files, the RECORDSIZE clause specifies the size of the 1/0 buffer for the channel. A.3.3 The PUT Statement In VAX BASIC, a PUT statement with a count of zero to a variable length file creates a record with a length of zero; in BASIC-PLUS-2, the size of the record created is the size specified in the RECORDSIZE clause or, if no RECORDSIZE clause is specified, the length of the longest map. A-6 Transporting Programs Between VAX BASIC and BASIC-PLUS-2 A.4 Procedure Calling This section discusses some differences in procedure calling between VAX BASIC and BASIC-PLUS-2. A.4.1 The CALL Statement The following difference occur in the CALL statement when used in VAX BASIC and BASIC-PLUS-2: • • • • A.4.2 In VAX BASIC, you can use the CALL statement to call a procedure that is written in any language which supports the VAX Procedure Calling Standard. In BASIC-PLUS-2, you can use the CALL statement to call only BASIC-PLUS-2 and MACRO subprograms. In VAX BASIC, individual array element parameters (except virtual array elements) are passed by reference and are modifiable. In BASICPLUS-2, individual array element parameters are passed by local copy and are not modifiable. VAX BASIC does not allow passing of entire virtual arrays; BASICPLUS-2 allows passing of entire virtual arrays. In VAX BASIC, you can pass up to 255 parameters in each subprogram. In BASIC-PLUS-2, you can pass up to 8 parameters in each subprogram. The CHAIN Statement In VAX BASIC and in BASIC-PLUS-2 on RSX systems, you cannot specify a line number in a CHAIN statement. In BASIC-PLUS-2 on RSTS/E systems, line numbers are allowed. Transporting Programs Between VAX BASIC and BASIC-PLUS-2 A-7 A.4.3 SYS and FIP SYS Calls VAX BASIC supports a subset of RSTS/E SYS and FIP calls. These are summarized in Tables A-3 and A-4. Table A-3: Function VAX BASIC Subset of RSTS/E SYS Calls Code Function 0 Cancel CTRL/O effect on terminal 2 Enable echoing on terminal 3 Disable echoing on terminal 5 Exit with no prompt message 6 SYS call to the file processor 7 Get core common string 8 Put core common string 9 Exit and clear program 11 Cancel all type ahead Table A-4: Function VAX BASIC Subset of RSTS/E FIP SYS Calls Code Function -23 Terminate file name string scan -13 Change priority /run burst/job size -10 Begin file name string scan -7 Enable CTRL/C trap 9 Return error messages 10 Assign user logical 11 Deallocate a device or deassign user logical 12 Deallocate all devices 18 Obsolete (use function code 22) 22 Message send/receive Note that the FIP call for sending or receiving messages (code 22) produces different results when used in VAX BASIC and BASIC-PLUS-2 on A-8 Transporting Programs Between VAX BASIC and BASIC-PLUS-2 RSTS/E systems. In VAX BASIC, a receiver identification is removed from the receiver table when the image that declared it exits; in BASIC-PLUS-2 on RSTS /E systems, a receiver identification stays in the receiver table until it is explicitly removed or the job terminates. This difference causes incompatible behavior with chained programs, because in VAX BASIC the receiver identification is valid only for the program that declares it; whereas in BASIC-PLUS-2 on RSTS/E systems, the chained programs can share a receiver identification. DIGITAL recommends the use of mailboxes or DECnet task-to-task communication as a replacement for these FIP calls in VAX BASIC. A.5 Generated Errors In VAX BASIC and BASIC-PLUS-2, the same errors are handled differently or signal different error messages and numbers: • • • • • If you press CTRL/Z after responding to an INPUT statement, VAX BASIC makes the assignment and signals the error "End of file on device" (ERR=l 1) when the next INPUT statement executes; BASICPLUS-2 signals the same error, does not make the assignment, and terminates the current input line. When nonnumeric or floating-point data is input to an INPUT or READ statement expecting numeric or integer data, VAX BASIC signals the error "Data format error" (ERR=SO); BASIC-PLUS-2 signals the error "Illegal number" (ERR=52). When the integer index of a FOR loop exceeds the default integer size, VAX BASIC signals the error "Integer error or overflow" (ERR=Sl); BASIC-PLUS-2 signals the error "Integer overflow, FOR loop" (ERR=60). When a program opens channel 0, VAX BASIC signals the error "Illegal I/O channel" (ERR=46); BASIC-PLUS-2 signals the error "I/O channel already open at line <line number> " (ERR=7). If no error handler is active, the errors in Table A-5 are fatal errors in VAX BASIC, but warnings in BASIC-PLUS-2. Transporting Programs Between VAX BASIC and BASIC-PLUS-2 A-9 Table A-5: Error Number Message 48 Floating point error 51 Integer error 52 Illegal number 53 Illegal argument in LOG 54 Imaginary square roots 61 Division by zero • A.& Fatal Errors in VAX BASIC That Are Warnings in BASIC-PLUS-2 When a user has WRITE access to a block in a virtual file and a second user attempts to access that block, VAX BASIC and BASIC-PLUS-2 on RSX signal the error "Record/bucket locked" (ERR=154); BASICPLUS-2 on RSTS/E signals the error "Disk block is interlocked" (ERR=19). Miscellaneous Differences This section discusses some miscellaneous differences between VAX BASIC and BASIC-PLUS-2. A.6.1 Data Types VAX BASIC supports DECIMAL, HFLOAT, GFLOAT and user-defined data types; BASIC-PLUS-2 does not. In BASIC-PLUS-2, as an alternative to the DECIMAL data type, use the DOUBLE data type with the OPTION SCALE statement or the SCALE command to minimize floating-point inaccuracy. A.6.2 The DEF and DEF• Statements In VAX BASIC, you can specify a maximum of 255 parameters in a DEF statement and a maximum of 8 parameters in a DEF• statement; in BASICPLUS-2, you can specify a maximum of 8 parameters in both the DEF and DEF• statements. A-10 Transporting Programs Between VAX BASIC and BASIC-PLUS-2 A.6.3 Default Integer Size If you do not specify a default integer size when invoking VAX BASIC, the default integer size is LONGWORD; in BASIC-PLUS-2, the default integer size is WORD. In VAX BASIC, use the OPTION SIZE=INTEGER WORD statement or the COMPILE/WORD command to make BASIC-PLUS-2 programs transportable to VAX BASIC. A.6.4 Integer Overflow When performing integer arithmetic, VAX BASIC signals an error message if the size of the value returned exceeds the default integer size. BASICPLUS-2 does not signal an error message, truncates the result, and returns a signed integer quantity. To disable error checking for integer overflow in VAX BASIC, use the OPTION INACTIVE=INTEGER OVERFLOW statement or the DCL command BASIC/CHECK=NOOVERFLOW. A.6.5 Line Numbers and Labels In VAX BASIC, line numbers are optional. In BASIC-PLUS-2, you need at least one line number in each program. In a VAX BASIC program, labels, compiler directives, and comments can begin in column zero. In BASIC-PLUS-2, they cannot. A.6.6 The MAP and COMMON Statements The MAP and COMMON statements have different functionality when used in VAX BASIC and BASIC-PLUS-2. The differences are as follows: • In VAX BASIC, both COMMON areas and maps can have names containing a maximum of 31 characters and include underscore (-) characters. In BASIC-PLUS-2, COMMON areas and maps can have names containing a maximum of six characters; underscore characters are not allowed. Transporting Programs Between VAX BASIC and BASIC-PLUS-2 A-11 • If two strings overlap in a map, VAX BASIC performs string assignments as if no overlap exists; BASIC-PLUS-2 performs string assignments one character at a time from left to right. (Note that RSET assignment is performed from right to left.) For example: 10 MAP (FOO) A$ = 5 MAP (FOO) FILL$ = 2, B$ = 5 A$ = 'ABCDE' PRINT A$ B$ = A$ PRINT B$, A$ When you run this program in VAX BASIC, the following output is displayed: ABCDE ABCDE ABABC When you run this program in BASIC-PLUS-2, the following output is displayed: ABCDE ABABA ABABA A.&. 7 The MAP DYNAMIC Statement The following differences occur in the MAP DYNAMIC statement when used in VAX BASIC and BASIC-PLUS-2: • • A.6.8 If the MAP DYNAMIC statement is in an external subprogram or function, BASIC-PLUS-2 resets all pointers to the first byte each time the external module is called. VAX BASIC initializes the map area once when the external module is first called, and does not reset the variables pointers on subsequent calls. VAX BASIC allows you to specify a PSECT name or a static string variable in a MAP DYNAMIC statement; BASIC-PLUS-2 allows you to specify only a PSECT name. The PRINT Statement In VAX BASIC and RSX BASIC-PLUS-2, when you print to a terminalformat file and the line is to exceed 72 characters, you must either specify a record size, or a map, or use the VAX BASIC MARGIN function; this is not the case in BASIC-PLUS-2 on RSTS/E. A-12 Transporting Programs Between VAX BASIC and BASIC-PLUS-2 A.6.9 The PRINT USING Statement In VAX BASIC, the PRINT USING string formatting characters (L,R,C, and E) can be either uppercase or lowercase. In BASIC-PLUS-2, string formatting characters must be uppercase; otherwise, they are treated as string literals. A.6.10 The REPLACE Command In VAX BASIC, the REPLACE command writes the source program to the device and directory you specify in the OLD command. In BASICPLUS-2, the REPLACE command writes the source program to the current directory. A.6.11 The SPEC% and PEEK Functions You can use the SPEC% and PEEK functions only on RSTS /E systems. These functions are not transportable. A.6.12 String Comparisons When making string comparisons in all relational operations, VAX BASIC pads the shorter string with a blank space (ASCII value 32). BASIC-PLUS2 pads the shorter string with a blank space only on equals ( =) and not equals ( < > ) relational operations. A.6.13 Assigning Symbols In VAX BASIC, you use the logical name SYS$CURRENCY to change the currency symbol, SYS$RADIX _pQINT to change the radix point symbol, and SYS$DIGIT_SEP to change the separator symbol. In BASIC-PLUS-2, you select the symbols for currency, radix point, and separator when installing the compiler. Transporting Programs Between VAX BASIC and BASIC-PLUS-2 A-13 A.6.14 The TIME Function The numeric arguments to the TIME function have different results when used in VAX BASIC and BASIC-PLUS-2. These differences are summarized in Table A-6. Table A-6: VAX BASIC and BASIC-PLUS-2 TIME Function Differences TIME Argument oi Result In both VAX BASIC and BASIC-PLUS-2, TIME returns the number of seconds that elapsed since midnight. In VAX BASIC and BASIC-PLUS-2 on RSTS/E systems, TIME returns the current job's CPU time in tenths of a second. 2 In VAX BASIC and BASIC-PLUS-2 on RSTS/E systems, TIME returns the current job's connect time in minutes. 3 In VAX BASIC, TIME returns zero. In BASIC-PLUS-2 on RSTS/E systems, TIME returns kilo-core ticks. 4 In VAX BASIC, TIME returns zero. In BASIC-PLUS-2 on RSTS/E systems, TIME returns device time in minutes. 1 A.6.15 Zero is the only valid argument for TIME in BASIC-PLUS-2 on RSX systems. The TIMES Function In VAX BASIC, the value returned by the TIME$ function is always displayed in AM/PM format. In BASIC-PLUS-2, the time can be expressed in either AM/PM format or 24-hour format, depending on the option you select when installing BASIC-PLUS-2. A-14 Transporting Programs Between VAX BASIC and BASIC-PLUS-2 Appendix B ANSI Minimal BASIC This appendix explains the operation of the VAX BASIC compiler when used with the/ ANSl_STANDARD qualifier. B. 1 Introduction The American National Standard for Minimal BASIC (ANSI X3.601978) describes a nucleus of the BASIC programming language. This nucleus will be a part of any BASIC implementation that conforms to this standard. Thus, writing programs that conform to the ANSI Minimal BASIC standard helps assure that they will run under any standard implementation of BASIC. The ANSI Minimal BASIC Standard allows both extensions to the current standard and features whose behavior is defined by each implementation. This chapter describes these extensions and implementation-defined features. Many features of VAX BASIC are allowed as extensions to ANSI Minimal BASIC. For example, programs with 31-character variable names will compile correctly; however, VAX BASIC reports an informational message for each instance of a long variable name. This tells you that your program does not strictly conform to ANSI Minimal BASIC. Certain features of VAX BASIC are invalid in ANSI Minimal BASIC programs. For example, variables ending in a percent sign are invalid because ANSI Minimal BASIC does not allow integer variables. If you try to use this VAX feature in ANSI Minimal BASIC, VAX BASIC signals the error "Integer data type not supported in ANSI." For a thorough understanding of ANSI Minimal BASIC, read ANSI X3.60-1978. ANSI Minimal BASIC B-1 Note that the descriptions and explanations in this chapter apply only to programs compiled or run with the / ANSI_STANDARD qualifier in effect. B.2 The /ANSI-STANDARD Qualifier / ANSI_STANDARD is a qualifier to both the DCL command BASIC and to the SET command in the BASIC environment. When you specify this qualifier, the following qualifiers are not allowed: • • • • /SYNTAX_CHECK /SCALE /TYPE_DEFAULT /OPTIMIZE (/NOSETUP in the BASIC environment) VAX BASIC signals an error if you use any of these qualifiers in addition to the / ANSI_STANDARD qualifier. Note that you cannot use compiler directives in programs compiled with the / ANSI_STANDARD qualifier. In addition, you cannot use immediate mode statements while the/ ANSI_STANDARD qualifier is in effect. B.3 Extensions To ANSI Minimal BASIC Standard Xl.60-1978 The following items are extensions to the ANSI Minimal BASIC Standard. In order to write completely transportable programs, you should avoid these extensions and use only the capabilities allowed by the standard. In most cases VAX BASIC reports an informational error if you use any extensions. B.3.1 Program Format The ANSI Minimal BASIC Standard permits comments only with the REM statement. With the / ANSI_STANDARD qualifier in effect, VAX BASIC allows comment fields beginning with an exclamation point and ending with an exclamation point or a carriage return. VAX BASIC also allows explicit line continuation with ampersands. However, implicit line continuation is invalid. B-2 ANSI Minimal BASIC B.3.2 Statements The ANSI Minimal BASIC Standard requires that each program have an END statement. In VAX BASIC the END statement is optional. If your program does not have an END statement, VAX BASIC reports the informational message, "ENDSTAREQ, END statement required in ANSI." Also, the LET keyword is required in ANSI Minimal BASIC. VAX BASIC signals "LETKEYREQ, LET keyword required in ANSI" when it encounters an assignment statement without the LET keyword. B.3.3 Delimiters The ANSI Minimal BASIC Standard specifies that all keywords must be preceded by one space and followed by at least one space, if the keyword is not at the end of a line. With the /ANSI-STANDARD qualifier in effect, you can delimit keywords with either spaces or tabs. B.3.4 Variables The ANSI Minimal BASIC Standard limits variable names in the following ways: • • • String variables and string arrays can be named with only one alphabetic character, followed by a dollar sign. For example, valid identifiers for string variables are K$, T$, and Q$(17). Numeric arrays can be named with only one alphabetic character, followed by the subscript reference. For example, valid identifiers for numeric arrays are M(25), K(n), and A(n/2). Simple numeric variables can be named with a maximum of two characters: one alphabetic character, followed by an optional digit. For example, valid identifiers for simple numeric variables are RS, Kl, and T2. With the / ANSI_STANDARD qualifier in effect, VAX BASIC allows up to 31-character variable and array names. Names ending in a percent sign ( % ) are invalid, as are any explicitly declared variables. Note that VAX BASIC initializes all numeric variables to zero and all string variables to the null string. To conform to the minimal standard, you should explicitly initialize all variables in your program. ANSI Minimal BASIC B-3 All VAX BASIC keywords remain reserved words when the /ANSI_ STANDARD qualifier is in effect; you cannot use these reserved words as variable names. See Appendix D in this manual for a list of reserved keywords. B.3.5 Numeric Constants The ANSI Minimal BASIC Standard allows numeric constants of the following form: sd ... d Implicit point representation sd ... drd ... d Explicit point unscaled representation sd ... drd ... dEsd ... d Explicit point scaled representation sd ... dEsd ... d Implicit point scaled representation d Is a decimal digit. r Is a period. s Is an optional sign. E Is the explicit character E. In addition to constants of this form, VAX BASIC with the /ANSI_ STANDARD qualifier in effect allows integer constants that end in a percent sign ( % ) and explicitly typed numeric constants. B.3.6 Data Input VAX BASIC provides several extensions to the ANSI Minimal BASIC Standard for data input. B-4 ANSI Minimal BASIC B.3.6. 1 Unquoted String Data The ANSI Minimal BASIC Standard limits unquoted strings occurring in a DATA statment, or in response to the input prompt, to the following subset of ASCII characters: • • • • • • Uppercase letters ( A-Z) Digits ( 0-9 ) The period (.) The plus sign ( +) The minus sign ( - ) The space character In VAX BASIC, an unquoted string in a DATA statement can contain any ASCII character, with the following exceptions: • • • • The comma(,) The null character The form feed character An ampersand ( & ), if it is the last character on the line As input to the INPUT statement, VAX BASIC allows unquoted strings to contain any printable ASCII character (that is, all characters with an ASCII code greater than 31, except character code 127, the delete character). VAX BASIC also allows the following nonprinting characters in the INPUT statement: • • • • The back space character The horizontal tab The vertical tab The form feed character ANSI Minimal BASIC B-5 8.3.6.2 Null Input The ANSI Minimal BASIC Standard requires that the DATA statement consist of numeric constants, string constants, or unquoted strings. VAX BASIC allows these items, and also allows null items (that is, two successive commas not within a quoted string) as input in a DATA statement. A null item in a DATA statement results in the assignment of either a null string or a numeric value of zero to the corresponding variable in the READ statement. B.3. 7 User-Defined Functions (the DEF Statement) The ANSI Minimal BASIC Standard requires that user-defined functions accept a single parameter. The formal parameter in the DEF function must be an unsubscripted numeric variable. With the / ANSI_STANDARD qualifier in effect, VAX BASIC reports a syntax error for DEF functions that specify more than one parameter. The ANSI Minimal BASIC Standard makes no mention of DEFs with string parameters. VAX BASIC in ANSI Standard mode allows string DEFs but signals the informational error "String DEF not ANSI." DEF functions can be recursive. However, VAX BASIC does not detect infinitely recursive DEF functions. If your program invokes an infinitely recursive DEF function, your program will eventually terminate with a fatal error (typically, an access violation). B.3.8 Built-In Functions The ANSI Minimal BASIC Standard allows only the following implementation-supplied (built-in) functions: • • • • • • • • ABS ATN cos EXP INT LOG RND SGN B-6 ANSI Minimal BASIC July 1988 • • • SIN SQR TAN With the / ANSl_STANDARD qualifier in effect, if you use any built-in functions other than these, VAX BASIC reports an informational error "Language feature not ANSI." Further, VAX BASIC reports an error if you use any of the following functions in a program compiled with the/ ANSLSTANDARD qualifier: • • DECIMAL INTEGER ANSI Minimal BASIC B-6.1 • • B.3.9 REAL GETRFA Arrays The ANSI Minimal BASIC Standard requires that array declarations are valid only for numerics, and allows only one or two dimensions. With the / ANSLSTANDARD qualifier in effect, VAX BASIC allows multi-dimensional arrays of all data types, including strings. All arrays have a lower bound of zero unless an OPTION BASE statement specifies a lower bound of 1. The format of OPTION BASE is as follows: OPTION BASE n n Is either zero or 1. A value of zero specifies that the lower bound of arrays is either ( 0) or ( 0,0 ). A value of 1 specifies that the lower bound is either ( 1) or ( 1, 1 ). Although you can have arrays of any floating-point data type, you control this feature with qualifiers to the DCL command BASIC or the SET command. This means that all floating-point arrays in a single program are of the same data type. The ANSI Minimal BASIC Standard requires that all variables and arrays have unique names. However, VAX BASIC allows a variable and an array to have the same name. B.4 Implementation-Defined Features The ANSI Minimal BASIC Standard leaves the following features to be defined by the implementation. The behavior of these implementationdefined features in VAX BASIC is as described in the following sections. ANSI Minimal BASIC 8-7 8.4. 1 Initial Values for Variables The ANSI Minimal BASIC Standard recommends that all variables are "detectably undefined in the sense that an exception will result from any attempt to access the value of a variable before that variable is explicitly assigned a value." Therefore you should explicitly initialize all variables. VAX BASIC initializes all numeric variables to zero and all dynamic string variables to the null string. B.4.2 Retention of Long Strings The ANSI Minimal BASIC Standard states that string variables must be able to contain strings of at least 18 characters. VAX BASIC lets you use strings of up to 65535 characters. B.4.3 Accuracy of Evaluation of Numeric Expressions The ANSI Minimal BASIC Standard does not specify a minimum accuracy, but recommends at least six significant decimal digits of precision. In VAX BASIC, the accuracy of numeric expressions is always the same as that of the operands. This is specified with the /REAL _SIZE qualifier. B.4.4 Machine Infinitesimal The ANSI Minimal BASIC Standard recommends that machine infinitesimal be at most lE-38. For programs compiled with /REAL _SIZE of SINGLE or DOUBLE, machine infinitesimal is approximately 2.9E-39; with /REAL_SIZE=GFLOAT, machine infinitesimal is approximately 5.6E-308; and with /REAL_SIZE=HFLOAT, machine infinitesimal is approximately 8.4E-4933. B.4.5 Machine Infinity The ANSI Minimal BASIC Standard recommends that machine infinity be at least 1E38. For programs compiled with /REAL_SIZE of SINGLE or DOUBLE, machine infinity is approximately l.7E38; with /REAL_ SIZE=GFLOAT, machine infinity is approximately 9.0E309; and with /REAL _SIZE=HFLOAT, machine infinity is approximately 8.4E4933. B-8 ANSI Minimal BASIC B.4.8 Precision For Numeric Values The ANSI Minimal BASIC Standard recommends at least six significant decimal digits of precision. This corresponds to the SINGLE argument of the VAX BASIC REAL_SIZE qualifier. You can also specify DOUBLE or GFLOAT (up to 15 significant decimal digits of accuracy), or HFLOAT (up to 33 significant decimal digits of accuracy). See the VAX BASIC User Manual for more information. Note that the accuracy of numeric expressions is always the same as the precision specified with an argument to the REAL_SIZE qualifier. B.4. 7 Exrad-Width For Printing Numeric Representations The ANSI Minimal BASIC Standard requires at least two positions for the representation of the exrad component of a numeric representation. In VAX BASIC for programs compiled with /REAL_SIZE of SINGLE or DOUBLE, exrad-width is two. For programs compiled with /REAL_SIZE=GFLOAT, exrad-width is three. For programs compiled with /REAL _SIZE=HFLOAT, exrad-width is four. B.4.8 Significance-Width For Printing Numeric Representations The ANSI Minimal BASIC Standard specifies at least six positions for controlling the number of significant decimal digits printed in numeric representations. In VAX BASIC the PRINT statement provides up to six significant positions for numeric values, regardless of the floating-point data type in effect. B.4.9 Print Zone length VAX BASIC always has five 14-position print zones per print line. ANSI Minimal BASIC B-9 B.4.10 Margin for Output Line The ANSI Minimal BASIC Standard makes no recommendation for the width of the output line. With the /ANSI-STANDARD qualifier in effect, the margin width for the controlling terminal is 80 characters. Note that the margin width for the controlling terminal is infinite for programs compiled with the /NOANSl_STANDARD qualifier. B.4.11 Pseudorandom Number Sequence In VAX BASIC the RND function produces a pseudorandom sequence of numbers until the RANDOMIZE statement is executed. After RANDOMIZE executes, the RND function produces a random sequence of numbers. B.4.12 Unique Line Numbers VAX BASIC follows the ANSI Minimal BASIC Standard's recommendations for local editing of statement lines. Statement lines can be entered in any order; VAX BASIC sorts the program into the proper order. If you enter two lines with the same line number, VAX BASIC keeps the second line and deletes the first. VAX BASIC deletes any line containing only a line number; it also deletes any line containing only a line number and formatting characters (such as spaces or form feeds). B.4.13 Input Prompt The ANSI Minimal BASIC Standard recommends that the input prompt be a question mark followed by a single space. VAX BASIC conforms to this recommendation. Note that you cannot supply a string constant to be displayed as an input prompt. If you attempt to supply a string prompt, VAX BASIC signals "Language feature not ANSI." B.4.14 End of Input Reply In VAX BASIC, the end of input reply is a carriage return. B-10 ANSI Minimal BASIC B.4. 15 End of Print Line In VAX BASIC, the end of print line is a carriage return/line feed combination (ASCII code 13 and 10). B.4.16 Exponentiation Operator VAX BASIC accepts two asterisk characters (**) as the exponentiation operator. July 1988 ANSI Minimal BASIC B-11 Appendix C ASCII Character Codes ASCII is a 7-bit character code with an optional parity bit ( 8) added for many devices. Programs normally use seven bits internally with the eighth bit being zero; the extra bit is either stripped (on input) or added by a device driver (on output) so the program will operate with either parity- or nonparity-generating devices. The eighth bit is reserved for future standardization. The International Reference Version (IRV) of ISO Standard 646 is identical to the IRV in CCITT Recommendation V.3 (International alphabet No. 5). The character sets are the same as ASCII except that the ASCII dollar sign (hexadecimal 24) is the international currency sign, which looks like###. ISO Standard 646 and CCITT V.3 also specify the structure for national character sets, of which ASCII is the U.S. national set. Certain specific characters are reserved for national use. These are the values and symbols: Hexadecimal Value IRV ASCII 23 24 # # ### $ (General currency symbol vs. dollar sign) 40 @ @ SB [ [ SC \ \ SD ] ] SE 60 ASCII Character Codes C-1 Hexadecimal Value IRV ASCII (tbs) -- (Overline vs. tilde) 7B 7C 70 7E ISO Standard 646 and CCITT Recommendation V.3 (International Alphabet No. 5) are identical to ASCII except that the number sign ( 23) is represented as ## instead of#, and certain characters are reserved for nation al use. Table C-1: C-2 ASCII Codes Decimal Code 8-Bit Hexadecimal Code Character 0 00 NUL Null (tape feed) 1 01 SOH Start of heading (A A) 2 02 STX Start of text (end of address, AB) 3 03 ETX End of text ( AC ) 4 04 EOT End of transmission (shuts off the TWX machine AD) 5 05 ENQ Enquiry (WRU, AE) 6 06 ACK Acknowledge (RU, AF) 7 07 BEL Bell (AG) 8 08 BS Backspace ( AH ) 9 09 HT Horizontal tabulation (AI) Remarks 10 OA LF Line feed ( AJ ) 11 OB VT Vertical tabulation CK) 12 oc FF Form feed (page, AL) 13 OD CR Carriage return ( AM ) 14 OE so Shift out (AN) 15 OF SI Shift in (Ao) 16 10 OLE Data link escape CP) ASCII Character Codes Table C-1 (Cont.): ASCII Codes Decimal Code 8-Bit Hexadecimal Code Character Remarks 17 11 DCl Device control 1 ( AQ) 18 12 DC2 Device control 2 (AR) 19 13 DC3 Device control 3 (AS) 20 14 DC4 Device control 4 (AT) 21 15 NAK Negative acknowledge (ERR, AU) 22 16 SYN Synchronous idle ( AV) 23 17 ETB End-of-transmission block (AW) 24 18 CAN Cancel (AX) 25 19 EM End of medium ( Ay) 26 lA SUB Substitute (AZ) 27 1B ESC Escape (prefix of escape sequence) 28 lC FS File separator 29 1D GS Group separator 30 lE RS Record separator 31 lF us Unit separator SP 32 20 33 21 Exclamation point 34 22 Double quotation mark 35 23 # Number sign 36 24 $ Dollar sign 37 25 % Percent sign 38 26 & Ampersand 39 27 Apostrophe 40 28 Left (open) parenthesis 41 29 Right (close) parenthesis 42 2A * Space Asterisk ASCII Character Codes C-3 Table C-1 (Cont.): Decimal Code C-4 ASCII Codes 8-Bit Hexadecimal Code Character + Remarks Plus sign 43 2B 44 2C Comma 45 20 Minus sign, hyphen 46 2E Period (decimal point) 47 2F I Slash (slant) 48 30 0 Zero 49 31 1 One 50 32 2 Two 51 33 3 Three 52 34 4 Four 53 35 5 Five 54 36 6 Six 55 37 7 Seven 56 38 8 Eight 57 39 9 Nine 58 3A Colon 59 3B Semicolon 60 3C 61 30 < Less than(left angle bracket) Equal sign 62 3E > Greater than (right angle bracket) 63 3F ? Question mark 64 40 @ Commercial at 65 41 A Uppercase A 66 42 B Uppercase B 67 43 c Uppercase C 68 44 0 Uppercase 0 69 45 E Uppercase E ASCII Character Codes Table C-1 (Cont.): ASCII Codes Decimal Code 8-Bit Hexadecimal Code Character Remarks 70 46 F Uppercase F 71 47 G Uppercase G 72 48 H Uppercase H 73 49 Uppercase I 74 4A Uppercase J 7S 4B K Uppercase K 76 4C L Uppercase L 77 4D M Uppercase M 78 4£ N Uppercase N 79 4F Uppercase 0 80 so 0 p Uppercase P 81 Sl Q Uppercase Q 82 S2 R Uppercase R 83 S3 s Uppercase S 84 S4 T Uppercase T 8S SS u Uppercase U Uppercase V 86 S6 v 87 S7 w Uppercase W 88 S8 x Uppercase X 89 S9 y Uppercase Y 90 SA z Uppercase Z 91 SB 92 SC \ Backslash (reverse slant) 93 SD ] Right square bracket 94 SE Circumflex (caret) 9S SF Underscore (underline) 96 60 Grave accent Left square bracket ASCII Character Codes C-5 Table C-1 (Cont.): Decimal Code 97 C-6 ASCII Codes 8-Bit Hexadecimal Code Character Remarks a Lowercase a 98 61 62 b Lowercase b 99 63 c Lowercase c 10 64 d Lowercased 101 65 e Lowercase e 102 66 f Lowercase f 103 67 g Lowercase g 104 68 h Lowercase h 105 69 106 6A j Lowercase j 107 6B k Lowercase k Lowercase i 108 6C 109 60 m Lowercase m 110 6E n Lowercase n 111 6F 0 Lowercase o 112 70 p Lowercase p 113 71 q Lowercase q 114 72 r Lowercase r 115 73 s Lowercases 116 74 117 75 u Lowercase u 118 76 v Lowercase v ASCII Character Codes Lowercase 1 Lowercase t Table C-1 (Cont.): ASCII Codes Decimal Code 8-Bit Hexadecimal Code 119 120 Character Remarks 77 w Lowercase w 78 x Lowercase x 121 79 y Lowercase y 122 7A z Lowercase z 123 78 Left brace 124 7C Vertical line 125 7D Right brace 126 7E Tilde 127 7F DEL Delete (rubout) ASCII Character Codes C-7 Appendix D VAX BASIC Keywords The following is a list of the VAX BASIC keywords. Most of the keywords are reserved. The unreserved keywords are marked with a dagger. %ABORT %CDD t %CROSS %ELSE %END %FROM %IDENT %IF %INCLUDE %LET %LIBRARY %LIST %NOCROSS %NOLIST %PAGE %PRINT %SBTTL %THEN %TITLE %VARIANT ABORT ABS ABS% ACCESS ACCESS% ACTIVATE t Unreserved keyword. VAX BASIC Keywords D-1 ACTIVE ALIGNED ALLOW ALTERNATE AND ANGLE t ANY APPEND AREA t AS ASC ASCENDING ASCII ASK AT t ATN ATN2 BACK BASE BASIC BEL BINARY BIT BLOCK BLOCKSIZE BS BUCKETSIZE BUFFER BUFSIZ BY BYTE CALL CASE CAUSE CCPOS CHAIN CHANGE CHANGES CHECKING CHOICE t CHR$ CLEAR CLIP t t Unreserved keyword. D-2 VAX BASIC Keywords July 1988 CLK$ CLOSE CLUSTERSIZE COLOR t COM COMMON COMP% CON CONNECT CONSTANT CONTIGUOUS CONTINUE cos COT COUNT CR CTR LC CVTF$ CVT$F CVT$$ CVT$% CVT%$ DAT DAT$ DATA DATE$ DEACTIVATE DECIMAL DECLARE DEF DEFAULTNAME DEL DELETE DESC DESCENDING DET DEVICE DIF$ DIM DIMENSION DOUBLE DOUBLEBUF DRAW t Unreserved keyword. July 1988 VAX BASIC Keywords D-3 DUPLICATES DYNAMIC ECHO EDIT$ ELSE END EQ EQV ERL ERN$ ERR ERROR ERT$ ESC EXIT EXP EXPAND t EXPLICIT EXTEND EXTEND SIZE EXTERNAL FF FIELD FILE FILE SIZE FILL FILL$ FILL% FIND FIX FIXED FLUSH FNAME$ FNEND FNEXIT FONT t FOR FORMAT$ FORTRAN FREE FROM FSP$ FSS$ t Unreserved keyword. D-4 VAX BASIC Keywords FUNCTION FUNCTIONEND VAX BASIC Keywords D-4.1 FUNCTIONEXIT GE GET GETRFA GFLOAT GO GO BACK GOSUB GOTO GRAPH GRAPHICS t GROUP GT HANDLE HANDLER HEIGHT t HFLOAT HT IDN IF IFEND IFMORE IMAGE IMP IN t INACTIVE INDEX t INDEXED INFORMATIONAL INITIAL INKEY$ INPUT INSTR INT INTEGER INV INVALID ITERATE JSB JUSTIFY t KEY KILL LBOUND t Unreserved keyword. VAX BASIC Keywords 0-5 LEFT LEFT$ LEN LET LF LINE LINES t LINO LINPUT LIST LOC LOCKED LOG LOGlO LONG LSET MAG MAG TAPE MAP MAR MAR% MARGIN MAT MAX METAFILE t MID MID$ MIN MIX t MOD MOD% MODE MODIFY MOVE MULTIPOINT t NAME NEXT NO t NOCHANGES NO DATA NODUPLICATES NOECHO NO EXTEND t Unreserved keyword. D-6 VAX BASIC Keywords NO MARGIN NONE NOP AGE NO REWIND NOSPAN NOT NUL$ NUM NUM$ NUM1$ NUM2 NX NXEQ OF ON ONECHR ONERROR OPEN OPTION OPTIONAL OR ORGANIZATION OTHERWISE OUTPUT OVERFLOW PAGE PATH t PEEK PI PICTURE PLACE$ PLOT POINT t POINTS t POS POS% PPS% PRIMARY PRINT PRIORITY t PROD$ PROGRAM PROMPT t t Unreserved kevword. VAX BASIC Keywords 0-7 PUT QUO$ RAD$ RANDOM RANDOMIZE RANGEt RCTRLC RCTRLO READ REAL RECORD RECORDSIZE RECORDTYPE RECOUNT REF REGARDLESS RELATIVE REM REMAP RESET RESTORE RESUME RETRY RETURN RFA RIGHT RIGHT$ RMSSTATUS RND ROTATE ROUNDING RSET SCALE SCRATCH SEG$ SELECT SEQUENTIAL SET SETUP SEVERE SGN SHEAR SHIFT t Unreserved kevword. 0-8 VAX BASIC Keywords SI SIN SINGLE SIZE SLEEP so SP SPACE t SPACE$ SPAN SPEC% SQR SQRT STATUS STEP STOP STR$ STREAM STRING STRING$ STYLE t SUB SUBEND SUBEXIT SUBSCRIPT SUM$ SWAP% SYS TAB TAN TEMPORARY TERMINAL TEXT t THEN TIM TIME TIME$ TO TRAN t TRANSFORM TRANSFORMATION t TRM$ TRN t Unreserved keyword. VAX BASIC Keywords D-9 TYP TYPE TYPE$ UBOUND UNALIGNED UNDEFINED UNIT t UNLESS UNLOCK UNTIL UPDATE USAGE$ USER OPEN USING USR$ VAL VAL% VALUE VARIABLE VARIANT VFC VIEWPORT t VIRTUAL VPS% VT WAIT WARNING WHEN WHILE WINDOW t WINDOWSIZE WITH t WORD WRITE XLATE XLATE$ XOR ZER t Unreserved kevword. 0-10 VAX BASIC Keywords INDEX A %ABORT directive• 3-2 ABS% function• 4-4 ABS function• 4-2 Absolute value ABS% function• 4-4 ABS function• 4-2 MAG function • 4-181 ACCESS clause• 4-253, 4-290 ACTIVE clause• 4-267 ALLOW clause• 4-253 Alphanumeric label• 1-3 See also Labels AL TERNA TE KEY clause• 4-258 Ampersand (&) as a continuation character• 1-7, 1-8, 1-11 in DAT A statement• 4-42 Angle types with OPTION statement• 4-265 ANSI standards• B-1 to B-11 APPEND command• 2-6 to 2-7 Arc tangent• 4-6 Arithmetic operators• 1-37, 1-38 Array assigning values to• 4-197, 4-200, 4-209, 4-302 bounds• 4-70, 4-196, 4-200, 4-203, 4-207, 4-209 converting with CHANGE statement• 4-20 creating with COMMON statement• 4-27 creating with DECLARE statement• 4-48 creating with DIM statement• 4-69 creating with MAP statement• 4-1 86 Array (cont'd.) creating with MAT statement• 4-195, 4-200, 4-203, 4-206, 4-209 data type of• 4-69 dimensions of• 4-69 dynamic• 4-69, 4-71, 4-72 elements • 4-70 element zero•4-71, 4-198, 4-201, 4-204, 4-207, 4-210, 4-223 initialization of• 4-197 initializing• 4-73 inversion of• 4-198 redimensioning with MAT statement• 4-196, 4-198, 4-201, 4-204, 4-209 static• 4-69, 4-70 transposing • 4-198 virtual • 4-50, 4-69, 4-72, 4-101 Arrays• 1-20 array elements• 1-21 definition of• 1-21 dimensions of• 1-22 element zero• 1-21 naming• 1-21, 1-23 size limits• 1-22 virtual• 1-24 ASCII character codes• C-1 characters• 1-35, 1-46, 4-23, C-1 character set• 1-11 conversion• 4-20, 4-23 converting to • 4-5 radix• 1-32 ASCII function• 4-5 ASSIGN command• 2-8 to 2-9 lndex-1 Asterisk (•) in PRINT USING statement• 4-279 with HELP command• 2-27 A TN function• 4-6 BUFFER clause• 4-254 BUFSIZ function • 4-8 BYTE data type • 1-12 /BYTE qualfier • 2-12 B c Backslash ( ) in continued lines• 1-8 in multi-statement lines• 1-8 in PRINT USING statement• 4-282 statement separator• 1-8 BASIC-PLUS-2 compatibility• A-1 to A-14 transporting programs• A-1 to A-14 Binary radix • 1-32 Blank-if-zero field in PRINT USING statement• 4-279 Block 1/0 file finding records in• 4-107 opening• 4-256 retrieving records sequentially in• 4-132 writing records to• 4-290 BLOCKSIZE clause• 4-253 Block statement ending• 4-78 exiting• 4-91 Bounds• 1-21 default for implicit arrays• 4-71, 4-196, 4-200, 4-203, 4-207, 4-209 lower bounds with COMMON statement• 4-27 lower bounds with DECLARE statement• 4-49 lower bounds with DIM statement• 4-70 lower bounds with MAP DYNAMIC statement• 4-190 lower bounds with records• 4-307 maximum• 1-21 upper bounds with COMMON statement• 4-27 upper bounds with DECLARE statement• 4-49 upper bounds with DIM statement• 4-70 upper bounds with MAP DYNAMIC statement• 4-190 Bucket creating with BUCKETSIZE clause• 4-254 locking • 4-105, 4-133 unlocking• 4-105, 4-118, 4-133 BUCKETSIZE clause• 4-254 CALL statement • 4-9 to 4-13 with SUB subprograms• 4-359 Caret ( ·) in PRINT USING statement• 4-279 CASE clause • 4-341 CASE ELSE clause• 4-34 1 CAUSE ERROR statement• 4-14 to 4-15 CCPOS function • 4-16 COD including definitions from• 3-10 COD (Common Data Dictionary) and RECORD statement• 4-306 including definitions from• 1-10 CD formatting character in PRINT USING statement• 4-279 Centered field in PRINT USING statement• 4-281 C formatting character in PRINT USING statement• 4-281 CHAIN statement• 4-18 to 4-19 CHANGES clause• 4-258 CHANGE statement• 4-20 to 4-22 Character ASCII• 4-5, 4-23 formatting with PRINT USING statement • 4-278 to 4-283 lowercase• 4-281 uppercase• 4-281 CHARACTER data type• 1-35 Character position CCPOS function • 4-16 of substring• 4-154, 4-271 Characters ASCII• 1-35, 1-46 data type suffix • 1-15 lowercase• 2-24 nonprinting • 1-35 processing of• 1-11 uppercase• 2-24 wildcard • 2-27 2-lndex Character set translating with XLA TE$ function• 4-397 Character sets ASCII• 1-11 VAX BASIC • 1-11 CHR$ function• 4-23 Clauses ACCESS•4-107, 4-132, 4-253, 4-290 ACTIVE• 4-267 ALLOW•4-105, 4-129, 4-253 AL TERNA TE KEY• 4-258 BLOCKSIZE • 4-253 BUCKETSIZE • 4-254 BUFFER• 4-254 BY• 4-9, 4-98, 4-124, 4-360 CASE• 4-341 CASE ELSE• 4-341 CHANGES• 4-258 CONNECT• 4-254 CONTIGUOUS• 4-254 COUNT• 4-289, 4-380 DEFAULTNAME • 4-252, 4-255 DUPLICATES• 4-258, 4-291 ELSE• 4-142 END IF•4-142 EXTENDSIZE • 4-255 FILESIZE • 4-255 FOR •4-252 GROUP• 4-307 KEY•4-104, 4-129, 4-130, 4-321 MAP. 4-187 4-255 NOREWIND • 4-256 NOSPAN • 4-256 ORGANIZATION• 4-256 OTHERWISE• 4-246, 4-248 PRIMARY KEY• 4-258 RECORD•4-103, 4-128, 4-289, 4-290 RECORDSIZE • 4-187, 4-259, 4-289 RECORDTYPE • 4-258 REGARDLESS• 4-105, 4-129 RFA • 4-103, 4-128 STEP• 4-114 TEMPORARY• 4-260 UNLOCK EXPLICIT• 4-104, 4-105, 4-129, 4-260 UNTIL•4-115 USEROPEN • 4-260 VARI ANT• 4-307 I Clauses (cont'd.) WAIT•4-130 WHILE• 4-115 WINDOWSIZE • 4-261 CLOSE statement• 4-24 Colon(:) in labels• 1-3 Comma(,) in DAT A statement• 4-43 in DELETE command• 2-21 in INPUT LINE statement• 4-151 in INPUT statement • 4-148 in LINPUT statement• 4-170 in LIST command• 2-31 in MAT PRINT statement• 4-206 in PRINT statement• 4-273 in PRINT USING statement• 4-278 $ command•2-5 Command files for environment• 2-2 Command qualifiers• 2-10 to 2-38 VAX BASIC• 2-10 to 2-38 Comment field• 1-55 in DAT A statement• 1-56, 4-42 in REM statement • 4-313 processing of• 1-11 REM statement • 1-5 7 transferring control to• 1-55 ! comment• 2-3 Comment fields terminating• 1-56 Comments in environment command files• 2-2 processing of• 1-11 COMMON area size of• 4-29 COMMON statement• 4-26 to 4-30 with FIELD statement• 4-101 COMP% function• 4-31 Compilation conditional• 3-8, 3-26 controlling with OPTION statement• 4-265 control of• 1-10, 2-56 control of listing• 3-3, 3-16, 3-17, 3-19, 3-20, 3-21, 3-22, 3-24 including from COD• 1-10, 3-10 including from text library• 3-10 including source code • 1-10, 3-10 lndex-3 Compilation (cont'd.) listing• 2-10 terminating with %ABORT directive• 3-2 Compilation qualifiers• 2-10 to 2-38 VAX BASIC• 2-10 to 2-38 COMPILE command• 2-10 to 2-19 VAX BASIC qualifiers• 2-10 to 2-38 Compiler directives• 1-10 Concatenation of COMMON areas• 4-29 string• 1-7, 1-38, 1-43 Conditional branching IF statement• 4-142 ON ... GOSUB statement• 4-246 ON ... GOTO statement• 4-248 SELECT statement• 4-340 Conditional compilation• 1-10 % VARI ANT directive• 3-26 with %IF directive• 3-8 Conditional expression FOR statement • 4-114 IF statement• 4-142 UNLESS statement• 4-375 UNTIL statement• 4-378 WHILE statement• 4-395 Conditional expressions• 1-44 definition of• 1-44 in %LET directive• 3-14 Conditional loops•4-114, 4-379, 4-395 CON function• 4-197 CONNECT clause• 4-254 Constant declaring• 4-50 external• 4-96 with OPTION CONST ANT TYPE• 4-265 Constants• 1-24 declaring • 1-31 default data type• 1-24 definition of• 1-24 floating-point• 1-25 integer• 1-2 7 lexical • 3-8 named• 1-29 naming• 1-25, 1-30 numeric• 1-25 packed decimal• 1-28 string• 1-28 types of• 1-24 4-lndex CONTIGUOUS clause• 4-254 Continuation characters ampersand • 1-8 backslash • 1-8 CONTINUE command• 2-20 with RUN command• 2-4 7 CONTINUE statement • 4-33 Control transferring into DEF functions• 4-246, 4-248 transferring into FOR ... NEXT loops• 4-136, 4-138, 4-246, 4-248 transferring into SELECT blocks• 4-246, 4-248 transferring into UNTIL loops• 4-136, 4-138, 4-246, 4-248 transferring into WHILE loops• 4-136, 4-138, 4-246, 4-248 transferring to a label• 4-136, 4-138 transferring with CALL statement • 4-9 transferring with CHAIN statement• 4-18 transferring with GOSUB statement• 4-136 transferring with GOTO statement• 4-138 transferring with IF statement• 4-142 transferring with ON ... GOSUB statement• 4-246 transferring with ON ... GOTO statement• 4-248 transferring with RESUME statement• 4-152, 4-171, 4-324 transferring with RETURN statement• 4-327 Conversion array to string variable• 4-21 string variable to array• 4-20 Conversion functions CVT$% function• 4-39 CVT$F function• 4-39 CVT%$ function• 4-39 CVTF$ function• 4-39 DECIMAL function • 4-46 INTEGER function• 4-158 NUM 1$ function• 4-237 NUM$ function• 4-235 RAD$ function• 4-295 REAL function• 4-304 STR$ function• 4-354 VAL% function• 4-384 VAL function• 4-382 XLA TE$ function• 4-397 Copying VAX BASIC source text• 3-10 COS function• 4-35 Cosine• 4-35 COUNT clause• 4-289 with fixed-length records• 4-380 with variable-length records• 4-380 CPU time• 4-369 Credit-debit field in PRINT USING statement• 4-279 %CROSS directive• 3-3 Cross-reference table %CROSS directive• 3-3 %NOCROSS directive• 3-17 CTRL/C function trapping• 4-299 with RECOUNT function• 4-311 CTRL/C key• 4-36 CTRL/Z function• 2-26 with INPUT LINE statement• 4-152 with INPUT statement• 4-150 with LINPUT statement• 4-171 CTRLC function • 4-36 See also RCTRLC function Cursor position CCPOS function• 4-16 TAB function• 4-366 CVT$$ function• 4-38 See also EDIT$ function CVTxx function• 4-39 with FIELD statement• 4-100 D Data transferring with MOVE statement• 4-221 DAT A statement• 4-42 to 4-43 See also READ statement comment fields in• 1-56 in DEF• function• 4-61 in DEF function• 4-55 in multi-statement lines• 1-9 terminating • 4-42 with MAT READ statement• 4-209 with READ statement• 4-302 with RESTORE statement• 4-321 Data structures defining • 4-306 Data type defaults• 1-15, 1-16 constants• 1-24 Data type functions DECIMAL function• 4-46 INTEGER function• 4-158 REAL function• 4-304 Data type keywords • 1-12 Data types• 1-12, 1-13 BYTE• 1-12 CHARACTER• 1-35 DECIMAL• 1-13 decimal overflow checking• 4-266 defining with RECORD statement• 4-306 DOUBLE • 1-12 GFLOAT• 1-12 HFLOAT• 1-12 in LET statement • 4-168 in logical expressions• 1-48 in numeric expressions• 1-40 INTEGER• 1-12 integer overflow checking• 4-266 keywords• 1-12, 1-13 LONG• 1-12 numeric literal notation• 1-33 precision • 1-13 precision in PRINT statement• 4-275 precision in PRINT USING statement• 4-278 promotion rules• 1-40 range• 1-13 REAL• 1-12 results for DECIMAL data• 1-42 results for GFLOA T and HFLOA T • 1-41 results in expressions • 1-40 RFA • 1-13 setting defaults with OPTION statement• 4-266 SINGLE• 1-12 size• 1-13 storage of• 1-12, 1-13 STRING• 1-13 suffix characters• 1-15 WORD• 1-12 Data typing explicit • 1-16 implicit• 1-15 with declarative statements • 1-16 with suffix characters • 1-15 DA TE$ function• 4-44 Date and time functions TIME$ function• 4-371 TIME function • 4-369 lndex-5 DCL commands in environment• 2-4 Debit-credit field in PRINT USING statement• 4-279 /DEBUG qualifier with RUN command• 2-4 7 /DECIMAL_SIZE qualifier• 2-13 DECIMAL data type• 1-13 constants• 1-28 format of• 1-13 overflow checking• 4-266 promotion rules • 1-42 rounding• 4-266 storage of • 1-13 DECIMAL function• 4-46 Decimal radix• 1-32 Declarative statements COMMON statement • 4-30 DECLARE statement• 4-48 EXTERNAL statement• 4-95 MAP statement• 4-186 %DECLARED directive• 3-3 to 3-5 DECLARE statement• 4-48 to 4-52 CONSTANT• 1-31, 1-37 DEF• function error handling in • 4-61, 4-79 multi-line• 4-59 parameters• 4-59, 4-60 recursion in • 4-61 single-line• 4-59 DEF• statement• 4-58 to 4-62 Default BUCKETSIZE clause• 4-254 COMMON name• 4-26 data type• 4-266 DEF AUL TNAME clause• 4-255 error handling• 4-240 file name• 4-18, 4-252 overriding with DECLARE statement• 4-48, 4-51 overriding with EXTERNAL statement• 4-95 parameter-passing mechanisms• 4-10 to 4-11, 4-98, 4-124, 4-360 RECORDSIZE clause• 4-260 scale factor• 4-266 setting with OPTION statement• 4-263 WINDOWSIZE clause• 4-261 6-lndex DEF AUL TNAME clause• 4-252, 4-255 Defaults COMPILE command• 2-10 constants• 1-24 data type • 1-15, 1-16 displaying• 2-58 EDIT command• 2-23 file name•2-36, 2-38, 2-39, 2-41, 2-46, 2-49, 2-60 floating-point constants• 1-25 implicitly declared variables• 1-19 integer constants• 1-27 listing file• 2-10 LOAD command• 2-33 numeric constants• 1-25 object module name • 2-10 overriding with COMPILE command• 2-10 overriding with RUN command• 2-46 radix• 1-32 RESEQUENCE command• 2-43 SCALE command• 2-51 SEQUENCE command• 2-54 SET command• 2-56 SHOW command• 2-58 DEF function ending• 4-78 error handling in• 4-55, 4-239, 4-241, 4-323 exiting• 4-90 recursion in• 4-56 transferring control into• 4-56, 4-246, 4-248 with INPUT LINE statement• 4-151 with INPUT statement • 4-148 with LINPUT statement• 4-170 with READ statement • 4-302 DEF statement• 4-53 to 4-57 multi-line • 4-54 parameters• 4-54, 4-55 single-line • 4-54 DELETE command• 2-21 to 2-22 DELETE statement• 4-63 with UNLOCK statement• 4-376 Delimiter EDIT command• 2-23 in DAT A statement• 4-43 string literal• 1-28 Descriptor• 4-13, 4-98, 4-124, 4-360 Detached handler• 4-391 Determinant• 4-65 DET function• 4-65 DIF$ function• 4-67 Dimension of arrays • 4-69 Dimensions of arrays• 1-22 DIMENSION statement• 4-69 to 4-73 See also DIM statement DIM statement• 4-69 to 4-73 executable• 4-71, 4-72 nonvirtual, nonexecutable • 4-70 virtual• 4-70 with MAT statement• 4-196, 4-198, 4-201, 4-204, 4-207, 4-209 Documentation program• 1-55 Dollar sign ($) in DECLARE statement• 4-49 in DEF• statement names• 4-58 in DEF names• 4-53 in PRINT USING statement• 4-279 in variable names• 1-18, 1-19 suffix character• 1-15 DOUBLE data type• 1-12 /DOUBLE qualifier• 1-17, 2-14 DUPLICATES clause• 4-258, 4-291 Dynamic array• 4-69, 4-71, 4-72 Dynamic mapping• 4-100, 4-189, 4-315 Dynamic storage• 4-189, 4-315, 4-317 E ECHO function• 4- 7 4 See also NOECHO function EDIT$ function• 4-76 values•4-76 to 4-77 EDIT command• 2-23 to 2-25 E formatting character in PRINT USING statement• 4-282 Elementary record components• 4-308 ELSE clause• 4-142 E mathematical constant• 4-93 END statement• 4-78 to 4-81 SUB subprograms• 4-359 E notation• 1-26 field in PRINT USING statement• 4-279 numbers in• 1-26 E notation (cont'd.) with PRINT statement• 4-274 with STR$ function• 4-354 Environment comments in immediate mode• 2-2 Equivalence name• 2-7 ERL function• 4-82 with labels• 1-4 with RESEQUENCE command• 2-44 ERN$ function • 4-84 ERR function • 4-86 Error severity level• 4-265 Error condition clearing with CONTINUE statement• 4-33 Error handling disabling• 4-244 ERL function • 4-82 ERN$ function • 4-84 ERR function • 4-86 ERT$ function• 4-88 in DEF• functions • 4-61 in DEF functions• 4-55, 4-79, 4-239, 4-241 in FOR. .. NEXT loops• 4-324 in subprograms• 4-80, 4-91, 4-124, 4-240 in UNTIL loops• 4-324 in WHILE loops• 4-324 ON ERROR GO BACK statement• 4-239 ON ERROR GOTO 0 statement• 4-244 ON ERROR GOTO statement• 4-241 OPTION HANDLE• 4-265 recursion in• 4-242 RESUME statement• 4-323 Error handling functions CTRLC function • 4-36 ERL function• 4-82 ERN$ function • 4-84 ERR function • 4-86 ERT$ function• 4-88 RCTRLC function• 4-299 Error number• 4-86 Error text• 4-88 ERT$ function • 4-88 Evaluation of expressions• 1-52 of logical expressions• 1-50 of numeric relational expressions• 1-44 of operators • 1-52 lndex-7 Evaluation (cont'd.) of SELECT statement• 4-341 of string relational expressions • 1-46 Exclamation point (!) in comment fields• 1-55 in PRINT USING statement• 4-282 Executable statements• 1-4 Execution continuing• 2-20, 2-4 7 of multi-statement lines • 1-8 of statements • 1-8 of system commands• 2-4 program• 2-46 stopping• 2-20, 2-47, 4-352 suspending• 4-34 7, 4-388 EXIT command• 2-26 EXIT statement• 4-90 to 4-92 EXP function• 4-93 Explicit creation of arrays • 4-69 data typing• 1-16, 4-263 declaration of variables• 1-20 literal notation• 1-32 loop iteration • 4-160 record locking•4-63, 4-104, 4-105, 4-129, 4-133, 4-260 Exponential notation• 1-26, 4-274 in PRINT USING statement• 4-279 numbers in• 1-26 with PRINT statement• 4-2 7 4 Exponentiation• 4-93 Expressions• 1-37 conditional• 1-44 conditional in %LET directive• 3-14 definition of• 1-37 evaluation of• 1-52 lexical• 3-9, 3-14, 3-26 logical• 1-48 mixed-mode • 1-40 numeric• 1-38 numeric relational• 1-44 operator precedence in• 1-53 parentheses in• 1-53 relational • 1-44 string• 1-43 string relational • 1-46 types of• 1-38 8-lndex Extended field in PRINT USING statement• 4-282 EXTENDSIZE clause• 4-255 External constant• 4-96 function • 4-96 picture • 4-96 subprogram• 4-123 subroutine• 4-96 variable• 4-96 External constants • 1-31 naming • 1-32 EXTERNAL statement• 4-95 to 4-99 CONST ANT• 1-31 parameters • 4-96 External variables naming• 1-18 F FAB status • 4-330 Field asterisk-filled• 4-279 blank-if-zero• 4-279 centered• 4-281 credit or debit• 4-279 exponential• 4-279 extended• 4-282 floating dollar sign• 4-279 GROUP• 4-309 left-justified• 4-281 multiple fields within a format string• 4-279 one-character• 4-282 right-justified• 4-281 trailing minus sign• 4-278 VARIANT• 4-309 zero-filled• 4-279 Fields comment• 1-55 FIELD statement• 4-100 to 4-101 File attributes BLOCKSIZE clause• 4-253 CONTIGUOUS clause• 4-254 EXTENDSIZE clause• 4-255 FILESIZE clause• 4-255 magnetic tape• 4-253 File names CHAIN statement default• 4-18 COMPILE command default• 2-10 LOAD command default• 2-33 NEW command default• 2-36 OLD command default• 2-38 OPEN default• 4-252 RENAME command default• 2-39 REPLACE command default• 2-41 RUN command default• 2-46 SAVE command default• 2-49 UNSAVE command default• 2-60 File organization indexed• 4-25 7 relative• 4-25 7 sequential• 4-257 undefined• 4-256 virtual• 4-256 File-related functions BUFSIZ function • 4-8 CCPOS function • 4-16 FSP$ function• 4-120 GETRF A function • 4-134 MAR function• 4-192 RECOUNT function• 4-311 ST A TUS function• 4-350 Files accessing• 4-127 block l/0•4-107, 4-132, 4-256, 4-290 closing• 4-24 deleting• 2-60, 4-162, 4-260 deleting records in• 4-63, 4-336 finding buffer size• 4-8 %1NCLUDE•3-10, 3-11 %INCLUDE directive• 2-43 indexed•4-63, 4-107, 4-132, 4-254, 4-255, 4-256, 4-290, 4-321, 4-381 locating • 4-101 magnetic tape• 4-183, 4-253, 4-321 opening• 4-250 relative•4-63, 4-107, 4-132, 4-254, 4-256, 4-260, 4-290, 4-380 renaming• 4-224 restoring data• 4-321 sequential• 4-107, 4-132, 4-256, 4-260, 4-273, 4-290, 4-336, 4-380 Files (cont'd.) terminal-format• 4-148, 4-151, 4-170, 4-193, 4-200, 4-203, 4-206, 4-229, 4-259, 4-273 virtual• 4-260, 4-322 FILESIZE clause• 4-255 FILL• 4-186, 4-222, 4-316 FILL$•4-186, 4-222, 4-316 FILL$ keyword• 4-27 FILL%• 4-186, 4-222, 4-316 FILL% keyword• 4-27 FILL items formats and storage• 4-27 to 4-29 in COMMON statement• 4-27 in MAP statement• 4-186 in MOVE statement• 4-222 in REMAP statement• 4-316 FILL keyword• 4-27 FIND statement • 4-102 to 4-108 with UNLOCK statement• 4-376 with UPDATE statement• 4-380 FIX function • 4-109 compared with INT function • 4-156 Floating dollar sign field in PRINT USING statement• 4-279 Floating-point constants• 1-25 data types • 1-12 promotion rules• 1-40 variables • 1-19 FNEND statement• 4-111 See also END statement FNEXIT statement• 4-112 See also EXIT statement FOR. .. NEXT loops• 4-113 to 4-116, 4-226 conditional • 4-114 error handling in • 4-324 explicit iteration of• 4-160 nested• 4-114 transferring control into• 4-114, 4-136, 4-138, 4-246, 4-248 unconditional • 4-114 FOR_NEXT loops exiting • 4-91 FOR clause• 4-252 Format characters in PRINT USING statement• 4-278 lndex-9 Format (cont'd.) combination of characters in PRINT USING statement• 4-279 defaults for U.S. currency• 4-280 E • 4-274 exponential• 4-274 multiple print fields with PRINT USING statement• 4-279 of data in DATA statement• 4-43 of FILL items• 4-27 to 4-29 of keywords • 1-5 of labels• 1-3 of line numbers• 1-2 of multi-line REM statement• 4-313 of multi-statement lines• 1-8, 1-9 of program lines• 1-1 of statements• 1-4 Radix-50 • 4-295 FORMAT$ function• 4-117 FOR statement • 4-113 to 4-116 FREE statement• 4-118 FSP$ function• 4-120 Function declaring• 4-49, 4-53, 4-58 external • 4-96 initialization of• 4-55, 4-61 invocation of•4-55, 4-60 naming• 4-53, 4-58 parameters• 4-54, 4-59 user-defined• 4-53, 4-58 FUNCTION END statement• 4-125 See also END statement FUNCTIONEXIT statement• 4-126 See also EXIT statement Functions lexical• 3-8, 3-14, 3-26 FUNCTION statement• 4-122 to 4-124 FUNCTION subprograms naming• 4-122 parameters • 4-123 G GETRF A function • 4-134 GET statement• 4-127 to 4-133 with UNLOCK statement• 4-376 with UPDATE statement• 4-380 10-lndex GFLOA T data type• 1-12 /GFLOA T qualifier• 2-14 GOSUB statement • 4-136 inside WHEN blocks• 4-136 with RETURN statement• 4-327 GOTO statement• 4-138 inside WHEN blocks• 4-138 GROUP clause• 4-307 H Handler attached• 4-391 enter• 4-140 exit• 4-140 HANDLER statement • 4-140 to 4-141 HELP command• 2-27 to 2-28 Hexadecimal radix • 1-32 HFLOA T data type• 1-12 /HFLOA T qualifier• 2-14 Hyphen(-) in DELETE command• 2-21 in LIST command• 2-31 1/0 characters transferred• 4-311 closing files• 4-24, 4-80 deleting records • 4-63 dynamic mapping• 4-315 finding records• 4-103 locking records• 4-104, 4-105, 4-129, 4-260 matrix• 4-231, 4-233 moving data• 4-221 opening files• 4-250 retrieving records• 4-132 unlocking records• 4-118, 4-260, 4-376 updating records• 4-380 with CHAIN statement• 4-18 writing records• 4-290 %1DENT directive• 3-6 to 3-7 Identifiers PROGRAM statement• 1-6 IDENTIFY command• 2-29 Identity matrix• 4-197 ION function• 4-197 %1F ... %THEN ... %ELSE ... %END %IF directive with RESEQUENCE command• 2-43 IF ... THEN ... ELSE statement• 4-142 to 4-144 labels in• 1-4 multi-line format • 1-8 %IF-% THEN-%ELSE-%END %IF directive• 3-8 to 3-9 Immediate mode• 2-20, 2-47 Implicit continuation of lines• 1-8 creation of arrays• 4-71, 4-196, 4-200, 4-203, 4-207' 4-209 data typing • 1-1 5 declaration of variables• 1-18 %INCLUDE directive• 3-10 to 3-13 with RESEQUENCE command• 2-43 Indexed files• 4-257 AL TERNA TE KEY clause• 4-258 BUCKETSIZE clause• 4-254 CHANGES clause• 4-258 deleting records in • 4-63 DUPLICATES clause• 4-258 finding records in• 4-107 MAP clause• 4-255 opening• 4-256 PRIMARY KEY clause• 4-258 restoring data in• 4-321 retrieving records sequentially in• 4-132 segmented keys in• 4-258 updating• 4-381 writing records to• 4-290 Initialization in subprograms• 4-124, 4-360 of arrays• 4-197 of DEF• functions • 4-61 of DEF functions• 4-55 of dynamic arrays• 4-73 of variables• 1-23, 4-50 of variables in COMMON statement• 4-30 of virtual arrays• 4-7 2 INKEY$ function• 4-145 to 4-14 7 with WAIT clause• 4-145 INPUT LINE statement• 4-151 to 4-153 INPUT statement• 4-148 to 4-150 INQUIRE command• 2-30 See also HELP command Instance• 4-309 RECORD • 4-309 INSTR function • 4-154 to 4-155 See also POS function Integer constants• 1-27 data types • 1-12 overflow checking• 4-266 promotion rules • 1-40 suffix character• 1-1 5 variables • 1-19 INTEGER data type• 1-12 INTEGER function • 4-158 Internal constants naming• 1-30 Internal variables naming• 1-18 INT function• 4-156 INV function• 4-198 ITERATE statement• 4-160 Iteration of FOR loops • 4-114 of loops• 4-160 of UNTIL loops• 4-378 of WHILE loops• 4-395 K KEY clause• 4-104, 4-130 FIND statement • 4-105 GET statement • 4-129 RESTORE statement• 4-321 segmented keys• 4-258 Keywords data type • 1-1 2 definition of• 1-5 function of• 1-5 in RECORD• 4-307 list of• C-7 reserved and unreserved • C-7 restrictions• 1-5 spacing requirements• 1-5 KILL statement• 4-162 L Labels defining• 1-3 format of• 1-3 lndex-11 Labels (cont'd.) Lines (cont'd.) function of• 1-3 referencing• 1-3 transferring control to • 4-136, 4-138 with ITERATE statement• 4-160 LBOUND function • 4-163 LEFT$ function• 4-165 See also SEG$ function Left-justification PRINT USING statement• 4-281 with LSET statement• 4-179 LEN function• 4-167 Length of labels • 1-3 of STRING data• 1-13 variable names• 1-18 %LET directive• 3-14 to 3-15 LET statement• 4-168 Letters lowercase• 1-11, 2-24, 4-281 uppercase• 1-11, 2-24, 4-281 Lexical constants• 3-8 expressions• 3-9, 3-14, 3-26 functions• 3-8, 3-14, 3-26 operators• 3-4, 3-8, 3-14 order• 1-11 variables• 3-14 Lexical variables assigning values to• 3-14 naming• 3-14 L formatting character in PRINT USING statement• 4-281 Libraries text• 3-12 Line numbers automatic sequencing• 2-54 in %INCLUDE file• 2-43, 3-10 in RESEQUENCE command• 2-43 range of• 1-2 Lines continued • 1-8 displaying• 2-31 editing• 2-23 elements of• 1-1 format of• 1-1 length of• 1-2 multi-statement• 1-8 order of• 1-11, 2-43 single-statement • 1-7 terminating• 1-2, 1-11, 1-12 Line terminator• 1-2, 1-11, 1-12 with DAT A statement• 4-42 with INPUT LINE statement• 4-152 with INPUT statement• 4-149 with LINPUT statement • 4-1 71 LINPUT statement• 4-170 to 4-172 LIST command• 2-31 to 2-32 %LIST directive• 3-16 Listing file control of• 1-10, 3-3, 3-16, 3-17, 3-19, 3-20 %CROSS directive• 3-3 defaults•2-10 included code • 3-10 %LIST directive• 3-16 %NOCROSS directive• 3-17 %NOLIST directive• 3-19 %PAGE directive• 3-20 %PRINT directive• 3-21 %SBTTL directive• 3-22 subtitle• 3-22 title• 3-24 % TITLE directive• 3-24 version identification • 3-6 Listing line numbers• 1-9 LISTNH command• 2-31 See also LIST command Literal explicit notation • 1-32 numeric• 1-25 string• 1-7, 1-11, 1-28, 1-48, 4-279, 4-282 LOAD command• 2-33 to 2-34 with RUN command• 2-47 with SCRATCH command• 2-53 Local copy • 4-13 LOC function• 4-173 Lock checking REGARDLESS clause• 4-105, 4-129 WAIT clause • 4-130 LOCK command• 2-35 See also SET command LOG 10 function • 4-17 7 Logarithms common• 4-177 natural• 4-175 12-lndex LOG function • 4-1 7 5 Logical expressions • 1-48 compared with relational• 1-49, 1-50 data types in• 1-48 definition of• 1-44 evaluation of• 1-50 format of• 1-48 logical operators• 1-49 truth tables• 1-49 truth tests • 1-49 Logical name• 2- 7 Logical operators• 1-49 LONG data type • 1-12 /LONG qualifier• 2-15 Loops conditional • 4-114 exiting• 4-90 FOR ... NEXT • 4-113 iteration of•4-114, 4-160, 4-378, 4-395 nested FOR. .. NEXT• 4-114 unconditional• 4-114 UNTIL statement• 4-378 WHILE statement• 4-395 Lowercase letters in EDIT command• 2-24 in PRINT USING statement• 4-281 processing of• 1-11 LSET statement• 4-179 M MAG function• 4-181 Magnetic tape files BLOCKSIZE clause• 4-253 MAGT APE function • 4-183 NOREWIND clause• 4-256 RESTORE statement• 4-321 MAGT APE function• 4-183 to 4-184 performing functions in VAX BASIC• 4-183 to 4-184 MAP FILL item formats and storage• 4-27 to 4-29 MAP area naming• 4-185 MAP clause• 4-187, 4-255 MAP DYNAMIC statement• 4-189 to 4-191 with REMAP statement• 4-315, 4-317 MAP statement• 4-185 to 4-188 with FIELD statement• 4-101 with MAP DYNAMIC statement• 4-191 with REMAP statement• 4-315 MAR function• 4-192 Margin width•4-192, 4-193, 4-229, 4-274 MARGIN statement• 4-193 See also NOMARGIN statement with PRINT statement• 4-274 MAT with DET function• 4-65 MAT INPUT statement• 4-200 to 4-202 MAT LINPUT statement• 4-203 to 4-205 MAT PRINT statement• 4-206 to 4-208 MAT READ statement• 4-209 to 4-211 Matrix• 1-21 identity• 4-197 Matrix arithmetic• 4-197 Matrix functions DET function• 4-65 NUM2 function• 4-233 NUM function• 4-231 Matrix operations arithmetic• 4-197 assigning values• 4-200, 4-203, 4-209 1/0. 4-231, 4-233 inversion• 4-65, 4-198 printing• 4-206 redimensioning • 4-200, 4-203, 4-206, 4-209 scalar multiplication• 4-197 transposition • 4-198 MAT statement• 4-195 to 4-199 with FIELD statement• 4-101 MAX function• 4-212 to 4-213 Memory clearing with SCRATCH command• 2-53 MID$ function• 4-214 See also SEG$ function MIN function• 4-217 to 4-218 Minus sign (-) in PRINT USING statement• 4-278 Mixed-mode expressions• 1-40 MOD function• 4-219 to 4-220 Modifiable parameters• 4-12 Modifiers FOR statement• 4-113 lndex-13 Modifiers (cont'd.) IF statement• 4-142 UNLESS statement• 4-375 UNTIL statement• 4-379 WHILE statement• 4-396 Module names• 1-6 MOVE FILL item formats and storage• 4-27 to 4-29 MOVE statement• 4-221 to 4-223 with FIELD statement • 4-101 Multi-line DEF• functions• 4-59 DEF statement• 4-54 Multi-statement lines• 1-8 backslash in• 1-8 branching to• 1-9 execution of• 1-8 format of• 1-8, 1-9 implicit continuation• 1-8 transferring control to• 1-8 N NAME ... AS statement• 4-224 Named constants• 1-29 changing• 1-30 external• 1-31, 4-96 internal• 1-30, 4-50 NEW command• 2-36 to 2-37 NEXT statement• 4-226 with FOR statement• 4-115 with WHILE statement• 4-395 /[NO]ANSl _STANDARD qualifier• 2-12 /[NO]AUDIT qualifier• 2-12 /[NO]CROSS_REFERENCE qualifier• 2-13 /[NO]DEBUG qualfier • 2-13 /[NO]FLAG qualifier• 2-14 /[NO]LINE qualifier• 1-2, 4-82, 4-352 /[NO]LINES qualifier• 2-14 /[NO]MACHINE_CODE qualifier• 2-15 /[NO]OBJECT qualifier• 2-15 /(NO]OVERFLOW qualifier• 2-15 /(NO]ROUND qualifier• 2-16 /[NO]SETUP qualifier• 2-16 /[NO]SHOW qualifier• 2-17 CDD_DEFINITIONS • 3-11 %INCLUDE directive• 3-11 14-lndex /[NO]SYNTAX_CHECK qualifier• 2-17 /(NO]TRACEBACK qualifier• 2-18 /[NO]W ARNINGS qualifier• 2-18 %NOCROSS directive• 3-17 to 3-18 NOECHO function • 4-228 See also ECHO function %NOLIST directive• 3-19 NOMARGIN statement• 4-229 See also MARGIN statement Nonexecutable DIM statement• 4- 70 Nonexecutable statements• 1-4, 1-11 COMMON statement• 4-29 DAT A statement• 4-43 DECLARE statement• 4-50 DIM statement• 4-70 EXTERNAL statement• 4-98 MAP DYNAMIC statement• 4-191 MAP statement• 4-187 REM statement• 4-313 UNLESS statement• 4-375 Nonmodifiable parameters• 4-12 Nonprinting characters processing of• 1-11 using• 1-11 Nonvirtual DIM statement• 4- 70 NOREWIND clause• 4-256 NOSPAN clause• 4-256 Notation E • 1-26, explicit literal • 1-32 exponential• 1-26, 4-274 NOT operator evaluation of• 1-54 NUL$•4-197 NUM 1$ function• 4-23 7 NUM2 function • 4-233 after MAT INPUT statement• 4-201 after MAT LINPUT statement• 4-204 after MAT READ statement• 4-210 NUM$ function• 4-235 Numbers random• 4-297, 4-333 sign of• 4-345 Number sign (#) in PRINT USING statement• 4-278 Numbers in E notation• 1-26 Numeric constants• 1-25 Numeric conversion• 4-21 Numeric expressions• 1-38 format of• 1-38 promotion rules • 1-40 result data types• 1-40 results for DECIMAL data• 1-42 results for GFLOA T and HFLOA T • 1-41 Numeric functions• 4-39 ABS% function• 4-4 ABS function• 4-2 DECIMAL function• 4-46 FIX function• 4-109 INT function• 4-156 LOG 10 function• 4-177 LOG function• 4-175 MAG function• 4-181 RND function• 4-333 SGN function • 4-345 SOR function• 4-349 SW AP% function• 4-365 Numeric literal notation• 1-32 Numeric operator precedence• 1-53 Numeric precision with PRINT statement• 4-275 with PRINT USING statement• 4-278 Numeric relational expressions evaluation of• 1-44 operators • 1-45 Numeric string functions CHR$ function• 4-23 COMP% function• 4-31 DECIMAL function• 4-46 DIF$ function• 4-67 FORMAT$ function• 4-117 INTEGER function• 4-158 NUM 1$ function• 4-237 NUM$ function• 4-235 PLACE$ function• 4-268 PROD$ function• 4-284 QUO$ function• 4-292 REAL function • 4-304 STR$ function• 4-354 SUM$ function• 4-363 VAL% function• 4-384 VAL function• 4-382 Numeric strings comparing • 4-31 precision• 4-67, 4-268, 4-285, 4-292, 4-363 Numeric strings (cont'd.) rounding• 4-268, 4-285, 4-292 rounding and truncation values• 4-269 to 4-270 truncating• 4-268, 4-285, 4-292 NUM function• 4-231 after MAT INPUT statement• 4-201 after MAT LINPUT statement• 4-204 after MAT READ statement• 4-210 0 Object libraries module names in • 1-6 Object module creating• 2-10 default name• 2-10 loading• 2-33 version identification • 3-6 Octal radix• 1-32 OLD command• 2-38 with RUN command• 2-46 ON ... GOSUB ... OTHERWISE statement• 4-246 with RETURN statement• 4-327 ON ... GOSUB statement• 4-246 to 4-24 7 ON ... GOTO ... OTHERWISE statement• 4-248 ON ... GOTO statement• 4-248 to 4-249 ON ERROR GO BACK statement• 4-239 to 4-240 with END statement • 4-80 within a handler• 4-240 within protected regions• 4-240 ON ERROR GOTO 0 statement• 4-244 to 4-245 with END statement • 4-80 ON ERROR GOTO statement• 4-241 to 4-243 with END statement • 4-80 within a handler• 4-242, 4-245 within protected regions• 4-242, 4-245 with WHEN blocks• 4-242 Online documentation• 2-27 Opening files with USEROPEN clause• 4-260 OPEN statement• 4-250 to 4-262 with ST A TUS function• 4-350 Operator precedence• 1-38, 1-52, 1-53 Operators arithmetic• 1-37, 1-38 evaluation of• 1-52 lndex-15 Operators (cont'd.) lexical• 3-4, 3-8, 3-14 logical• 1-49 numeric operator precedence• 1-53 numeric relational• 1-45 precedence of• 1-38, 1-52, 1-53 string relational• 1-4 7 OPTIONAL with EXTERNAL statement• 4-97 OPTION statement• 4-263 to 4-267 ORGANIZATION clause• 4-256 OTHERWISE clause• 4-246, 4-248 Output formatting with FORMAT$ function • 4-117 formatting with PRINT USING statement• 4-277 to 4-281 Output listing cross-reference table • 3-3, 3-17 %LIST directive• 3-16 %NOLIST directive• 3-19 %PAGE directive• 3-20 %PRINT directive• 3-21 %SBTTL directive• 3-22 %TITLE directive• 3-24 Overflow checking• 4-266 p Packed decimal • 1-13 See also DECIMAL data type %PAGE directive• 3-20 Parameter-passing mechanisms DEF• functions• 4-60 DEF statement• 4-55 EXTERNAL statement• 4-98 FUNCTION statement• 4-124 SUB statement• 4-360 VAX BASIC• 4-10 to 4-11 Parameters DEF• functions• 4-59, 4-60 DEF statement• 4-54, 4-55 EXTERNAL statement• 4-96 function • 4-54, 4-59 FUNCTION subprograms• 4-123 modifiable• 4-12 nonmodifiable • 4-12 SUB subprograms• 4-358 16-lndex Parentheses in array names• 1-21 in expressions• 1-38, 1-53 Passing mechanisms with CALL statement• 4-9 Percent sign (%) in DATA statement• 1-27, 4-42 in DECLARE statement • 4-49 in PRINT USING statement• 4-279 in variable names• 1-18, 1-19 suffix character• 1-15 Period(.) in PRINT USING statement• 4-278 in variable names• 1-18 PLACE$ function• 4-268 to 4-270 rounding and truncation values• 4-269 to 4-270 Plus sign (+) in string concatenation• 1-43 POS function• 4-271 to 4-272 Precision in PRINT statement• 4-275 in PRINT USING statement• 4-278 NUM 1$ function• 4-237 NUM$ function• 4-235 of data types• 1-13 of numeric strings• 4-67, 4-268, 4-284, 4-292, 4-363 Predefined constants• 1-35 PRIMARY KEY clause• 4-258 %PRINT directive• 3-21 PRINT statement• 4-273 to 4-276 with TAB function• 4-366 PRINT USING statement• 4-277 to 4-283 Print zones in MAT PRINT statement• 4-206 in PRINT statement• 4-274 PROD$ function• 4-284 to 4-286 rounding and truncation values• 4-269 to 4-270 Program control statements END statement• 4-78 EXIT statement• 4-90 FOR statement • 4-113 GOSUB statement• 4-136 GOTO statement• 4-138 IF statement • 4-142 ITERATE statement• 4-160 Program control statements (cont'd.) ON ... GOSUB statement• 4-246 ON ... GOTO statement• 4-248 RESUME statement• 4-323 RETURN statement• 4-327 SELECT statement• 4-340 SLEEP statement• 4-34 7 STOP statement• 4-352 UNTIL statement• 4-378 WAIT statement• 4-388 WHILE statement• 4-395 Program documentation• 1-55 Program elements• 1-1 Program execution continuing• 2-20, 2-47 initiating with RUN command• 2-46 stopping• 2-20, 2-47, 4-352 suspending• 4-34 7 waiting for input• 4-388 Program input INPUT LINE statement• 4-151 INPUT statement• 4-148 LINPUT • 4-170 waiting for• 4-388 Program lines automatic sequencing• 2-54 deleting• 2-21 displaying• 2-31 editing• 2-23 elements of• 1-1 format of• 1-1 length of• 1-2 numbering• 1-2 order of• 1-11, 2-43 resequencing• 2-43 terminating• 1-2, 1-11 , 1-12 Programs compiling• 2-10 continuing• 2-20, 2-4 7 debugging• 2-4 7 deleting• 2-60 editing• 2-23 ending• 4-78 executing• 2-46 halting• 2-20, 2-4 7 merging• 2-5 naming• 2-36 renaming• 2-39 Programs (cont'd.) saving• 2-41, 2-49 stopping• 2-20, 2-47, 4-352 PROGRAM statement• 1-6, 4-287 to 4-288 Promotion rules data type • 1-40 DECIMAL• 1-42 floating-point• 1-40 integer• 1-40 Prompt after STOP statement• 4-352 INPUT LINE statement• 4-151 INPUT statement• 4-148 LINPUT statement• 4-170 MAT INPUT statement• 4-201 MAT LINPUT statement• 4-204 PSECT • 4-26, 4-185 PUT statement• 4-289 to 4-291 0 Qualifiers• 2-10 to 2-38 /BYTE• 2-12 /DEBUG• 2-47 /DECIMAL_SIZE • 2-13 /DOUBLE• 1-17, 2-14 /GFLOAT • 2-14 /HFLOAT • 2-14 /LONG•2-15 /[NO]ANSl_ST ANDARD • 2-12 /[NO]AUDIT • 2-12 /[NO]CROSS_REFERENCE • 2-13 /[NO]DEBUG • 2-13 /[NO]FLAG • 2-14 /[NO]LINE • 1-2, 4-82, 4-352 /[NO]LINES • 2-14 /[NO]MACHINE_CODE • 2-15 /[NO]OBJECT • 2-15 /[NO]OVERFLOW • 2-15 /[NO]ROUND • 2-16 /[NO]SETUP • 2-16 /[NO]SHOW • 2-17, 3-11 /[NO]SYNTAX_CHECK • 2-17 /[NO]TRACEBACK • 2-18 /[NO]W ARNINGS • 2-18 /SINGLE• 2-17 /TYPE• 1-15 lndex-17 Qualifiers (cont'd.) /TYPE_DEFAUL T • 2-18 /VARIANT• 2-18, 3-26 VAX BASIC command• 2-10 to 2-38 /WORD• 2-19 QUO$ function• 4-292 to 4-294 rounding and truncation values• 4-269 to 4-270 Quotation marks in string literals• 1-28 R RAB status• 4-330 RAD$ function • 4-295 to 4-296 Radix ASCII• 1-32 binary• 1-32 decimal• 1-32 hexadecimal• 1-32 in explicit literal notation• 1-32 octal• 1-32 Radix-50 • 4-295 RANDOMIZE statement• 4-297 to 4-298 See also RND statement Random numbers• 4-297, 4-333 Range of data types • 1-13 of subscripts• 1-21 RCTRLC function• 4-299 See also CTRLC function• 4-299 RCTRLO function • 4-300 to 4-301 READ statement • 4-302 to 4-303 See also DAT A statement with DAT A statement• 4-42, 4-43 REAL data type• 1-12 REAL function• 4-304 to 4-305 Record attributes MAP clause• 4-255 RECORDSIZE clause• 4-255, 4-259 RECORD TYPE clause• 4-258 Record buffer DAT A pointers• 4-321 MAP DYNAMIC pointers• 4-191, 4-317 moving data• 4-221 REMAP pointers• 4-315, 4-317 setting size• 4-254 18-lndex RECORD clause• 4-103, 4-128, 4-289, 4-290 Record File Address• 1-13, 4-103, 4-128, 4-134 RECORD items accessing • 4-308 Record Management Services See RMS Record pointers after FIND statement• 4-107, 4-108 after GET statement• 4-132, 4-133 after PUT statement• 4-290 after UPDATE statement• 4-380 REMAP statement • 4-317 RESTORE statement • 4-321 WINDOWSIZE clause• 4-261 Records deleting with DELETE statement • 4-63 deleting with SCRATCH statement• 4-336 finding RFA of•4-103, 4-129 locating by KEY• 4-107, 4-129, 4-133 locating by RECORD number• 4-128 locating by RFA•4-103, 4-107, 4-129, 4-132 locating randomly• 4-107 locating sequentially• 4-103, 4-107, 4-128, 4-132 locating with FIND statement • 4-102 locating with GET statement • 4-12 7 locking•4-104, 4-105, 4-133, 4-260 locking with GET statement• 4-129 processing• 4-127, 4-254 retrieving by KEY • 4-129, 4-133 retrieving by RECORD number• 4-128 retrieving by RF A • 4-128, 4-132 retrieving randomly• 4-133 retrieving sequentially• 4-128, 4-132 retrieving with GET statement• 4-127 size of• 4-289 stream• 4-257 unlocking•4-63, 4-105, 4-118, 4-133, 4-260 unlocking with UNLOCK statement• 4-376 writing by RECORD number• 4-289 writing sequentially• 4-290 writing with PRINT statement• 4-273 writing with PUT statement• 4-289 writing with UPDATE statement• 4-380 RECORDSIZE clause• 4-187, 4-259, 4-289 RECORD statement • 4-306 to 4-310 RECORD structures components of• 4-309 declaring• 4-309 RECORDTYPE clause• 4-258 RECOUNT function• 4-311 to 4-312 after GET statement• 4-133 after INPUT LINE statement• 4-152 after INPUT statement• 4-150 after LINPUT statement • 4-1 7 1 Recursion in DEF• functions• 4-61 in DEF functions• 4-56 in error handlers• 4-242 in subprograms• 4-360 Redimensioning arrays with executable DIM statement• 4- 71 REGARDLESS clause with FIND statement• 4-105 with GET statement• 4-129 Relational expressions• 1-44 compared with logical • 1-49, 1-50 definition of• 1-44 format of• 1-44 in SELECT statement• 4-34 1, 4-342 numeric• 1-44 string • 1-46 truth tests• 1-44, 1-46 Relational operators numeric• 1-45 string • 1-4 7 Relative files• 4-25 7 BUCKETSIZE clause• 4-254 deleting records in• 4-63 finding records in• 4-107 opening• 4-256 record size in• 4-260 retrieving records sequentially in • 4-132 updating• 4-380 writing records to• 4-290 REMAP statement• 4-315 to 4-319 FILL item formats and storage• 4-27 to 4-29 with MAP DYNAMIC statement• 4-191 REM statement• 4-313 to 4-314 in multi-statement lines• 1-9 multi-line format • 1-5 7, 4-313 terminating• 1-5 7, 4-313 transferring control to• 1-5 7 RENAME command• 2-39 to 2-40 REPLACE command• 2-41 to 2-42 with RENAME command• 2-39 RESEQUENCE command• 2-43 to 2-45 Reserved words • 1-5 RESET statement• 4-321 See also RESTORE statement RESTORE statement• 4-321 to 4-322 Result data types for DECIMAL data• 1-42 GFLOA T and HFLOA T • 1-41 mixed-mode expressions• 1-40 RESUME statement• 4-323 to 4-324 END statement • 4-80 ERL function • 4-82 ERN$ function • 4-84 ERR function• 4-86 INPUT LINE statement• 4-152 INPUT statement• 4-150 LINPUT statement• 4-171 RETRY statement• 4-325 to 4-326 with FOR. .. NEXT loops• 4-325 with FOR. .. UNTIL loops• 4-325 with FOR. .. WHILE loops• 4-325 RETURN statement• 4-327 RFA clause• 4-103, 4-128 RF A data type allowable operations• 1-13 storage of• 1-13 R formatting character in PRINT USING statement• 4-281 RIGHT$ function• 4-328 to 4-329 See also SEG$ function Right-justification PRINT USING statement• 4-281 with RSET statement• 4-335 RMS (Record Management Services) accessing records • 4-12 7 deleting records• 4-63 locating records• 4-101 opening files• 4-250 operations • 4-330 replacing records• 4-380 RMSST A TUS function• 4-330 to 4-332 RND function• 4-333 to 4-334 See also RANDOMIZE statement RSET statement• 4-335 RUN command• 2-46 to 2-48 lndex-19 RUNNH command• 2-46 See also RUN command s SAVE command• 2-49 to 2-50 with RENAME command• 2-39 %SBTTL directive• 3-22 to 3-23 SCALE command• 2-51 to 2-52 Scale factor setting with OPTION statement• 4-266 setting with SCALE command• 2-51 SCRATCH command• 2-53 SCRATCH statement• 4-336 to 4-337 SEG$ function• 4-338 to 4-339 Segmented keys• 4-258 SELECT transferring control into• 4-246, 4-248 SELECT statement• 4-340 to 4-342 Semicolon (:) in INPUT LINE statement• 4-152 in INPUT statement• 4-149 in LINPUT statement• 4-171 in MAT PRINT statement• 4-206 in PRINT statement• 4-273 SEQUENCE command• 2-54 to 2-55 Sequential files• 4-257 deleting records in• 4-336 finding records in• 4-107 fixed-length• 4-25 7 NOSPAN clause• 4-256 opening• 4-256 record size in• 4-260 retrieving records in• 4-132 stream• 4-257 updating • 4-380 variable-length• 4-257 writing records to• 4-273, 4-290 SET command• 2-56 to 2-5 7 VAX BASIC qualifiers• 2-10 to 2-38 SET PROMPT statement• 4-343 to 4-344 SGN function • 4-345 SHOW command• 2-58 to 2-59 Sine• 4-346 SIN function• 4-346 SINGLE data type• 1-12 20-lndex Single-line DEF• functions• 4-59 DEF statement • 4-54 loops•4-113, 4-378, 4-395 /SINGLE qualifier• 2-17 Single-statement lines• 1-7 Size of numeric data • 1-13 of STRING data• 1-13 SLEEP statement• 4-34 7 Source text copying • 1-10 SPACE$ function• 4-348 SOR function • 4-349 SQRT function • 4-349 Square roots • 4-349 Statement blocks exiting • 4-90 Statement modifiers FOR statement • 4-113 IF statement • 4-142 UNLESS statement• 4-375 UNTIL statement• 4-379 WHILE statement• 4-396 Statements backslash separator• 1-8 block• 4-78, 4-91, 4-114, 4-142, 4-307, 4-341 components of• 1-4 continued• 1-7 data typing • 1-16 declarative• 4-48 empty• 1-56 executable • 1-4 execution of• 1-8 format of• 1-4 labeling of• 1-3 multi-statement lines • 1-8 nonexecutable • 1-4, 1-11, 4-29, 4-43, 4-50, 4-70, 4-98, 4-187, 4-191, 4-313 order of• 1-11, 2-43 processing of• 1-11 single-line• 1-7 Static arrays• 4-70 mapping • 4-185 storage• 4-27, 4-185, 4-317 STATUS function• 4-350 to 4-351 STATUS function (cont'd.) String expressions (cont'd.) VAX BASIC ST A TUS bits• 4-350 to 4-351 STEP clause • 4-114 STOP statement• 4-352 to 4-353 See also CONTINUE statement with RUN command• 2-4 7 Storage allocating for FILL items• 4-316 allocating for FILL items• 4-222 allocating for RECORD structures• 4-309 allocating for VARIANT fields• 4-309 allocating with MAP DYNAMIC statement• 4-189 allocating with MAP statement• 4-186 allocating with REMAP statement• 4-315 COMMON area and MAP area• 4-29, 4-187 dynamic• 4-189, 4-315, 4-317 for arrays• 4-71 for FILL items• 4-27 to 4-29, 4-222 for record structures • 4-309 in COMMON statement• 4-30 in MAP statement• 4-187 of data • 1-13 of DECIMAL data• 1-13 of RF A data • 1-13 of STRING data• 1-13 shared• 4-26, 4-185 static• 4-27, 4-185, 4-317 STR$ function• 4-354 to 4-355 Stream format• 4-257 record• 4-257 STRING$ function• 4-356 to 4-357 String arithmetic functions DIF$ function• 4-67 PLACE$ function• 4-268 PROD$ function• 4-284 QUO$ function• 4-292 SUM$ function• 4-363 String constants• 1-28 processing of• 1-29 String data assigning with LSET statement• 4-179 assigning with RSET statement• 4-335 STRING data type • 1-13 length • 1-13 storage of• 1-13 String expressions• 1-43 relational • 1-46 String functions• 4-39 ASCII function• 4-5 EDIT$ function• 4-76 INSTR function • 4-154 LEFT$ function • 4-165 LEN function• 4-167 MID$ function• 4-214 POS function• 4-271 RIGHT$ function • 4-328 SEG$ function • 4-338 SPACE$ function • 4-348 STRING$ function• 4-356 TRM$ function• 4-372 XLATE$ function• 4-397 String literals• 1-48 continuing • 1-7 delimiter• 1-28 in PRINT USING statement• 4-282 processing of• 1-11 quotation marks in• 1-28 String relational expressions evaluation of• 1-46 operators • 1-47 padding • 1-46 Strings comparing• 1-46, 4-31 concatenating • 1-7, 1-38, 1-43 converting• 4-20 creating• 4-348, 4-356 editing• 4-76, 4-372 extracting substrings• 4-165, 4-214, 4-328, 4-338 finding length• 4-167 finding substrings• 4-154, 4-271 justifying with FORMAT$ function • 4-117 justifying with LSET statement• 4-179 justifying with PRINT USING statement• 4-281 justifying with RSET statement• 4-335 numeric• 4-31, 4-67, 4-158, 4-268, 4-284, 4-292, 4-304, 4-363, 4-382, 4-384 replacing substrings• 4-214 suffix character• 1-15 String variables• 1-20 formatting storage• 4-179, 4-335 in INPUT LINE statement• 4-152 in INPUT statement• 4-149 lndex-21 String variables (cont'd.) in LET statement • 4-168 in LINPUT statement• 4-171 SUBEND statement• 4-361 See also END statement SUBEXIT statement• 4-362 See also EXIT statement Subprograms calling• 4-9 declaring• 4-95 ending•4-78, 4-123, 4-359 error handling in• 4-80, 4-91, 4-124, 4-240 exiting• 4-90 FUNCTION statement • 4-122 naming• 4-9, 4-358 recursion in• 4-360 returning from• 4-327 SUB statement• 4-358 Subroutines external• 4-96 GOSUB statement• 4-136 RETURN statement• 4-327 Subscripted variables• 1-20 format of• 1-22 range checking• 4-266 subscript range• 1-21 Subscripts• 1-21 range of• 1-21 SUB statement• 4-358 to 4-360 parameters• 4-358 VAX BASIC parameter-passing mechanisms• 4-10 to 4-11 Substrings extracting• 4-214, 4-338 extracting with LEFT$ function• 4-165 extracting with MID$ function• 4-214 extracting with RIGHT$ function• 4-328 extracting with SEG$ function• 4-338 finding• 4-154, 4-271 replacing• 4-214 Suffix characters integer• 1-15 string• 1-15 SUM$ function • 4-363 to 4-364 SW AP% function• 4-365 SYS$CURRENCY • 4-280 SYS$DIGILSEP • 4-280 SYS$RADIX _POINT• 4-280 22-lndex System command• 2-4 $ system-command• 2-4 T TAB function• 4-366 to 4-367 TAN function• 4-368 Tangent• 4-368 TEMPORARY clause• 4-260 Tensor• 1-21 Terminal printing to• 4-273 Terminal control functions ECHO function• 4- 7 4 NOE CHO function• 4-228 RCTRLO function • 4-300 TAB function • 4-366 Terminal-format files• 4-259 input from• 4-148, 4-151, 4-170, 4-200, 4-203 margin• 4-193, 4-229 writing records to• 4-206, 4-273 Text libraries accessing • 3-12 TIME$ function• 4-371 TIME function• 4-369 to 4-370 function values• 4-369 to 4-370 %TITLE directive• 3-24 to 3-25 Trailing minus sign field in PRINT USING statement• 4-278 Trigonometric functions A TN function • 4-6 COS function• 4-35 SIN function • 4-346 TAN function• 4-368 TAM$ function• 4-372 TAN• 4-198 Truncation in numeric strings• 4-268, 4-269 to 4-270, 4-285, 4-292 in PRINT USING statement• 4-281 with FIX function • 4-109 Truth tables• 1-49 Truth tests in logical expressions• 1-49 in relational expressions • 1-44 in string relational expressions • 1-46 /TYPE_DEFAULT qualifier• 2-18 /TYPE qualifier• 1-15 u UBOUND function• 4-373 to 4-374 Unconditional branching with GOSUB statement • 4-136 with GOTO statement • 4-138 Unconditional loops• 4-114 Undefined files• 4-256 Underscore (_) in PRINT USING statement• 4-279 in variable names • 1-18 UNLESS statement• 4-375 UNLOCK EXPLICIT clause•4-104, 4-105, 4-129, 4-260 UNLOCK statement• 4-376 to 4-377 UNSAVE command• 2-60 UNTIL clause• 4-115 UNTIL loops• 4-226 error handling in• 4-324 exiting• 4-91 explicit iteration of• 4-160 transferring control into• 4-136, 4-138, 4-246, 4-248 UNTIL statement• 4-378 to 4-379 UPDATE statement• 4-380 to 4-381 with UNLOCK statement• 4-376 Upper bounds determining with UBOUND function• 4-373 Uppercase letters in EDIT command• 2-24 in PRINT USING statement• 4-281 processing of• 1-11 User-defined functions• 4-53, 4-58 USEROPEN clause• 4-260 v VAL% function• 4-384 to 4-385 VAL function• 4-382 to 4-383 Values assigning to array elements• 4-197, 4-200, 4-203, 4-209, 4-302 assigning to variables • 4-168 assigning with LET statement• 4-168 Values (cont'd.) assigning with LINPUT statement• 4-170 assigning with LSET statement• 4-179 assigning with MAT INPUT statement• 4-200 assigning with MAT LINPUT statement• 4-203 assigning with MAT READ statement• 4-209 assigning with READ statement • 4-302 assigning with RSET statement• 4-335 comparing • 4-106 Variable names in COMMON statement• 4-29 in MAP DYNAMIC statement• 4-191 in MAP statement• 4-186 in REMAP statement• 4-316 rules for• 1-17 Variables• 1-17 assigning values to• 4-148, 4-151, 4-168, 4-170, 4-302 comparing • 4-106 declaring • 4-48 definition of• 1-17 explicitly declared• 1-20 external • 4-96 floating-point • 1-19 implicitly declared • 1-18 initialization of• 1-23, 4-30, 4-50 in MOVE statement• 4-221 in SUB subprograms • 4-360 integer• 1-19 lexical • 3-14 loop• 4-114 naming • 1-17 string• 1-20, 4-149, 4-152, 4-168, 4-171 subscripted• 1-20 VARIANT clause• 4-307 %VARIANT directive• 3-26 to 3-27 in %IF directive• 3-8 in %LET directive• 3-14 /VARIANT qualifier• 2-18, 3-26 VAX BASIC character set• 1-11 VAX BASIC ST A TUS bits• 4-350 to 4-351 Vector• 1-21 Version identification• 3-6 Virtual address finding• 4-173 Virtual arrays• 4-50, 4-69, 4-72 initialization of• 1-24, 4-72 padding in• 4-72 lndex-23 Virtual arrays (cont'd.) with FIELD statement• 4-101 Virtual files• 4-256 record size• 4-260 with RESTORE statement• 4-322 VMSST A TUS function• 4-386 to 4-387 w WAIT clause with GET statement • 4-130 with INKEY$ function • 4-145 WAIT statement• 4-388 to 4-389 WHEN blocks with GOSUB statement• 4-136 with GOTO statement • 4-138 WHEN ERROR constructs with DEF• functions• 4-61 with DEF functions• 4-55 WHEN ERROR statement• 4-390 to 4-394 with a detached handler• 4-391 with an attached handler• 4-391 WHILE clause• 4-115 WHILE loops• 4-226 error handling in• 4-324 exiting • 4-91 explicit iteration of• 4-160 transferring control into• 4-136, 4-138, 4-246, 4-248 WHILE statement• 4-395 to 4-396 Width margin• 4-192, 4-193, 4-229 WINDOWSIZE clause• 4-261 WORD data type• 1-12 /WORD qualifier• 2-19 x XLA TE$ function• 4-397 to 4-398 y ! your-comment• 2-2 24-lndex z ZER function• 4-197 Zero array element• 1-21, 4-71, 4-198, 4-201, 4-204, 4-207, 4-210, 4-223 blank-if-zero field• 4-279 in PRINT USING statement• 4-279 Zero-fill field in PRINT USING statement• 4-279 Reader's Comments VAX BASIC Reference Manual Al-HY 16A-TE AD-HY 16A-T 1 Please use this postage-paid form to comment on this manual. If you require a written reply to a software problem and are eligible to receive one under Software Performance Report (SPR) service, submit your comments on an SPR form. Thank you for your assistance. I rate this manual's: Accuracy (software works as manual says) Completeness (enough information) Clarity (easy to understand) Organization (structure of subject matter) Figures (useful) Examples (useful) Index (ability to find topic) Page layout (easy to find information) Excellent Good Fair Poor D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D I would like to see more /less What I like best about this manual is What I like least about this manual is I found the following errors in this manual: Page Description Additional comments or suggestions to improve this manual: I am using Version _ _ _ of the software this manual describes. Name/Title Dept. Company Date Mailing Address Phone - Do Not Tear - Fold Here and Tape --------------ir---~-----------;;~;-if Mailed in the United States BUSINESS REPLY MAIL FIRST CLASS PERMIT NO. 33 MAYNARD MASS. POST AGE WILL BE PAID BY ADDRESSEE DIGIT AL EQUIPMENT CORPORATION Corporate User Publications-Spit Brook ZK01-3/J35 110 SPIT BROOK ROAD NASHUA, NH 03062-9987 111 ..... 11.11 .... 11 .... 1.11.1 .. 1.1 .. 1.. 1.1 ... 1.11 .. 1 - Do Not Tear - Fold Here - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Reader's Comments VAX BASIC Reference Manual Al-HY 16A-TE AD-HY 16A-T 1 Please use this postage-paid form to comment on this manual. If you require a written reply to a software problem and are eligible to receive one under Software Performance Report (SPR) service, submit your comments on an SPR form. Thank -vou for -vour assistance. I rate this manual's: Accuracy (software works as manual says) Completeness (enough information) Clarity (easy to understand) Organization (structure of subject matter) Figures (useful) Examples (useful) Index (ability to find topic) Page layout (easy to find information) Excellent Good Fair Poor D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D I would like to see more/less What I like best about this manual is What I like least about this manual is I found the following errors in this manual: Page Description Additional comments or suggestions to improve this manual: I am using Version ___ of the software this manual describes. Name/Title Dept. Company Date Mailing Address Phone 0 )o Not Tear - Fold Here and Tape --------------ir---------------~~~---m the United States BUSINESS REPLY MAIL FIRST CLASS PERMIT NO. 33 MAYNARD MASS. POSTAGE Will BE PAID BY ADDRESSEE DIGIT Al EQUIPMENT CORPORATION Corporate User Publications-Spit Brook ZK01-3/J35 110 SPIT BROOK ROAD NASHUA, NH 03062-9987 111 ..... 11.11 .... 11 .... 1.11.1 .. 1.1 .. 1.. 1.1 ... 1.11 .. 1 Do Not Tear - Fold Here VAX BASIC User Manual Order Number: Al-HY 15A-TE, AD-HY 15A-T2 July 1988 This manual describes how to develop VAX BASIC programs, describes the features of the language, and describes how to use VAX/VMS features from VAX BASIC programs. Operating System and Version: VMS Version 5.0 or higher Software Version: digital equipment corporation maynard, massachusetts VAX BASIC Version 3.3 First Printing, August 1986 Updated, April 1 987 Updated, July 1988 The information in this document is subject to change without notice and should not be construed as a commitment by Digital Equipment Corporation. Digital Equipment Corporation assumes no responsibility for any errors that may appear in this document. The software described in this document is furnished under a license and may be used or copied only in accordance with the terms of such license. No responsibility is assumed for the use or reliability of software on equipment that is not supplied by Digital Equipment Corporation or its affiliated companies. Copyright © 1986, 1987, 1988 by Digital Equipment Corporation All Rights Reserved. Printed in U.S.A. The postpaid Reader's Comments forms at the end of this document request the user's critical evaluation to assist in preparing future documentation. The following are trademarks of Digital Equipment Corporation: DEC DEC/CMS DEC/MMS DECnet DECsystem-10 DECSYSTEM-20 DECUS DECwriter . DIBOL EduSystem IAS MASS BUS PDP PDT RSTS RSX UNIBUS VAX VAXcluster VMS VT ~urnuo~u TM ZK4772 Contents PREFACE xxv SUMMARY OF TECHNICAL CHANGES xx ix DEVELOPING VAX BASIC PROGRAMS ON VAX/VMS CHAPTER 1 OVERVIEW OF THE VAX BASIC LANGUAGE 1-1 CHAPTER 2 INTRODUCTION TO THE VAX/VMS OPERATING SYSTEM 2-1 2.1 LOGGING IN AND OUT 2-2 2.2 ACCESSING THE HELP FACILITY 2-3 2.3 ENTERING AND EDITING DCL COMMANDS 2-4 2.4 UNDERSTANDING THE DIRECTORY STRUCTURE 2-5 2.5 USING DCL FILE-HANDLING COMMANDS 2.5.1 Displaying Files 2.5.2 Printing and Typing Files 2.5.3 Deleting Files 2.5.4 Purging Files 2.5.5 Renaming and Moving Files 2.5.6 Searching Files 2.5.7 Setting File Protection 2-8 2-9 2-10 2-10 2-11 2-11 2-12 2-12 July 1988 iii 2.6.1 2.6.2 2.6.3 2.6.4 USING COMMAND PROCEDURES Defining DCL Symbols and Logical Names Creating and Executing Command Procedures Sample Command Procedure Login Command Procedures 2-14 2-14 2-16 2-17 2-19 DCL COMMANDS FOR PROGRAM DEVELOPMENT 2-20 DEVELOPING PROGRAMS IN THE BASIC ENVIRONMENT 3-1 3.1 ENTERING THE ENVIRONMENT 3-1 3.2 CREATING AND RUNNING PROGRAMS 3-2 3.3 IMMEDIATE MODE 3-5 3.4 DEBUGGING IN IMMEDIATE MODE 3-8 3.5 COMPILER COMMANDS Entering Comments 3.5.1 3.5.2 Entering DCL Commands The APPEND Command 3.5.3 The ASSIGN Command 3.5.4 The COMPILE Command 3.5.5 The CONTINUE Command 3.5.6 The DELETE Command 3.5.7 The EDIT Command 3.5.8 The EXIT Command 3.5.9 The HELP Command 3.5.10 The IDENTIFY Command 3.5.11 The LIST and LISTNH Commands 3.5.12 The LOAD Command 3.5.13 The LOCK Command 3.5.14 The NEW Command 3.5.15 The OLD Command 3.5.16 The RENAME Command 3.5.17 The REPLACE Command 3.5.18 3-9 3-12 3-13 3-13 3-14 3-14 3-1S 3-1a 3-18 3-20 3-20 3-21 2.6 2.7 CHAPTER 3 iv 3-2~ 3-2~ 3-23 3-23 3-24 3-24 3-2!: 3.5.21 3.5.22 3.5.23 3.5.24 3.5.25 3.5.26 3.5.27 CHAPTER 4 The SAVE Command The SCALE Command The SCRATCH Command The SEQUENCE Command The SET Command The SHOW Command The UNSAVE Command DEVELOPING VAX BASIC PROGRAMS AT DCL COMMAND LEVEL 3-26 3-27 3-27 3-27 3-28 3-28 3-30 4-1 4.1 CREATING A VAX BASIC PROGRAM 4.1.1 Using VAX EDT 4.1 .2 Using VAXTPU 4.1.2.1 The EVE Interface• 4-3 4.1.2.2 The EDT Keypad Emulator Interface• 4-3 4-1 4-1 4-2 4.2 COMPILING A VAX BASIC PROGRAM 4.2.1 The BASIC Command 4.2.2 BASIC Command Qualifiers 4.2.3 Compiler Listings 4.2.3.1 Source Program Listing • 4-23 4.2.3.2 Cross-Reference Listing • 4-25 4.2.3.3 Allocation Map • 4-27 4.2.3.4 Qualifier Summary • 4-29 4.2.3.5 Machine Code Listing• 4-29 4-4 4-4 4-6 4-15 4.3 LINKING A VAX BASIC PROGRAM 4.3.1 The LINK Command 4.3.2 LINK Command Qualifiers 4.3.3 Linker Input Files 4.3.4 Linker Output Files 4.3.5 Using an Object Module Library 4.3.6 Linker Error Messages 4-32 4-32 4-33 4-35 4-35 4-36 4-37 4.4 RUNNING A VAX BASIC PROGRAM 4-38 v USING THE VAX/VMS DEBUGGER 5-1 5.1 OVERVIEW OF THE DEBUGGER 5-1 5.2 FEATURES OF THE DEBUGGER 5-3 5.3 GETTING STARTED WITH THE DEBUGGER 5-4 5.3.1 Compiling and Linking to Prepare for Debugging 5-4 5-5 5.3.2 Starting and Terminating a Debugging Session 5.3.3 Issuing Debugger Commands 5-6 5-8 5.3.4 Viewing Your Source Code 5.3.4. 1 Noscreen Mode• 5-8 5.3.4.2 Screen Mode• 5-8 5.3.5 Controlling and Monitoring Program Execution 5-10 5.3.5.1 Starting and Resuming Program Execution• 5-10 5.3.5.2 Determining the Current Location of the Program Counter • 5-12 5.3.5.3 Suspending Program Execution • 5-13 5.3.5.4 Tracing Program Execution • 5-15 5.3.5.5 Monitoring Changes in Variables• 5-16 5.3.6 Examining and Manipulating Data 5-17 5.3.6. 1 Displaying the Values of Variables• 5-18 5.3.6.2 Changing the Values of Variables • 5-19 5.3.6.3 Evaluating Expressions • 5-19 5.3.6.4 Stepping Into VAX BASIC Routines • 5-20 5.3. 7 Controlling Symbol References 5-22 5.3. 7. 1 Module Setting • 5-22 5.3. 7 .2 Resolving Multiply-Defined Symbols • 5-23 5.4 A SAMPLE DEBUGGING SESSION 5-24 5.5 DEBUGGER COMMAND SUMMARY 5-26 CHAPTER 5 vi VAX BASIC PROGRAMMING CONCEPTS GETTING STARTED WITH VAX BASIC 6-1 6.1.1 6.1.2 6.1.3 6.1.4 LINE NUMBERS Programs with Line Numbers Programs Without Line Numbers Labels Continuation of Long Program Statements 6-1 6-1 6-2 6-4 6-5 6.2 IDENTIFYING PROGRAM UNITS 6-6 6.3 THE VAX BASIC CHARACTER SET 6-7 6.4 PROGRAM DOCUMENTATION 6-7 6.5.1 6.5.2 DECLARATIONS AND DATA TYPES Implicit Data Typing Explicit Data Typing 6-9 6-9 6-10 6.6 CONSTANTS 6-11 6.7 VARIABLES Floating-Point Variables 6.7.1 6.7.2 Integer Variables Packed Decimal Variables 6.7.3 6.7.4 String Variables 6.7.5 Subscripted Variables 6-13 6-13 6-14 6-14 6-14 6-15 6.8 KEYWORDS AND RESERVED WORDS 6-16 6.9 OPERANDS, OPERATORS AND EXPRESSIONS 6-17 6.10 ASSIGNMENT STATEMENTS 6-17 CHAPTER 6 6.1 6.5 vii CHAPTER 7 SIMPLE INPUT AND OUTPUT 7.1 7-1 PROGRAM INPUT 7-1 Providing Input Interactively 7-1 7. 1. 1. 1 The INPUT Statement • 7-2 7.1.1.2 The INPUT LINE and LINPUT Statements• 7-4 7 .1.1.3 Enabling and Disabling the Question Mark Prompt• 7-5 7. 1 .2 Providing Input from the Source Program 7- 7 7.1.2.1 The READ and DATA Statements• 7-7 7 .1.2.2 The RESTORE Statement• 7-9 7.1.1 7.2 PROGRAM OUTPUT 7 .2.1 Print Zones-the Comma and the Semicolon 7 .2.2 Output Format for Numbers and Strings 7-10 7-11 7-14 7.3 TERMINAL-FORMAT FILES 7 .3.1 Opening and Closing a Terminal-Format File 7.3.2 Writing Records to a Terminal-Format File 7-16 7-17 7-17 ARRAYS 8-1 8.1 INTRODUCTION 8-1 8.2 CREATING ARRAYS EXPLICITLY 8.2.1 Creating Arrays with the DECLARE Statement 8.2.2 Creating Arrays with the DIM Statement 8.2.2.1 Declarative DIM Statements• 8-5 8.2.2.2 Executable DIM Statements• 8-6 8.2.3 Creating Arrays with the COMMON Statement Creating Arrays with the MAP Statement 8.2.4 8-3 8-4 8-4 8.3 DETERMINING THE BOUNDS OF AN ARRAY 8-8 8.4 CREATING ARRAYS IMPLICITLY 8-8 8.5 ASSIGNING AND DISPLAYING ARRAY VALUES 8.5.1 Assigning Values with the LET Statement 8-10 8-10 CHAPTER 8 viii 8-7 8-7 8.5.2 Listing Array Elements with the PRINT Statement 8-11 8.6 USING MAT STATEMENTS 8.6.1 The MAT Statement 8.6.2 The MAT READ Statement 8.6.3 The MAT INPUT[#] Statement 8.6.4 The MAT LINPUT [#] Statement 8.6.5 The MAT PRINT[#] Statement 8.6.6 Matrix 1/0 Functions (NUM and NUM2) 8-11 8-13 8-15 8-16 8-18 8-19 8-21 8.7 MATRIX OPERATORS 8. 7 .1 Arithmetic Matrix Operations 8. 7. 1. 1 Assignment • 8-22 8. 7. 1.2 Addition and Subtraction • 8-22 8.7.1.3 Multiplication• 8-23 8.7.2 Matrix Functions 8.7.2.1 The TRN Function• 8-24 8. 7 .2.2 The INV Function • 8-25 8. 7 .2.3 The DET Function • 8-26 8-21 8-22 DATA DEFINITION 9-1 9.1 DECLARATIVE STATEMENTS 9-1 9.2 DATA TYPES 9-2 9.3 SETTING THE DEFAULT DATA TYPE AND SIZE 9-5 9.4 DECLARING VARIABLES EXPLICITLY 9-6 9.5 DECLARING NAMED CONSTANTS EXPLICITLY 9.5.1 Declaring Constants Within a Program Unit 9.5.2 Declaring Constants External to the Program Unit 9.5.3 Declaring a Default Constant Type 9-7 9-8 9-8 9-9 9.6 OPERATIONS WITH MULTIPLE DATA TYPES 9-9 CHAPTER 9 8-24 ix 9.7 9.8 ALLOCATING STATIC STORAGE 9.7.1 The COMMON Statement 9.7.2 The MAP Statement 9.7.2.1 Single Maps • 9-15 9.7.2.2 Multiple Maps • 9-16 9.7.3 FILL Items 9.7.4 Using COMMON and MAP in Subprograms 9-12 9-13 9-14 DYNAMIC MAPPING 9-21 CHAPTER 10 CREATING AND USING DATA STRUCTURES 10.1 CHAPTER 11 x THE RECORD STATEMENT 10.1 .1 Grouping RECORD Components 10.1 .2 RECORD Variants 10.1.3 Accessing RECORD Components PROGRAM CONTROL 9-17 9-19 10-1 10-1 10-5 10-6 10-9 11-1 11.1 STATEMENT MODIFIERS 11.1.1 The IF Modifier 11.1.2 The UNLESS Modifier 11.1.3 The FOR Modifier 11.1.4 The UNTIL Modifier 11.1.5 The WHILE Modifier 11.1.6 Nesting Modifiers 11-1 11-2 11-2 11-2 11-2 11-3 11-3 11.2 LOOPS 11.2.1 11.2.2 11.2.3 11.2.4 11-4 11-4 11-7 11-8 11-9 FOR ... NEXT Loops WHILE ... NEXT Loops UNTIL.NEXT Loops Nesting Loops 11.3 UNCONDITIONAL BRANCHING (THE GOTO STATEMENT) 11-10 11.4 CONDITIONAL BRANCHING 11-10 11.4.1 11.4.2 11.4.3 The ON ... GOTO ... OTHERWISE Statement The IF ... THEN ... ELSE Statement The SELECT ... CASE Statement 11-11 11-12 11-14 11.5 THE EXIT AND ITERATE STATEMENTS 11-16 11.6 EXECUTING LOCAL SUBROUTINES 11.6.1 The GOSUB and RETURN Statements 11.6.2 The ON ... GOSUB ... OTHERWISE Statement 11-18 11-18 11-20 11.7 SUSPENDING AND HALTING PROGRAM EXECUTION 11. 7 .1 The SLEEP Statement 11 .7 .2 The WAIT Statement 11.7.3 The STOP Statement 11.7.4 The END Statement 11-21 11-21 11-22 11-22 11-23 CHAPTER 12 12.1 FUNCTIONS 12-1 BUILT-IN FUNCTIONS 12-1 12.1 .1 Numeric Functions 12-2 12.1.1.1 The ABS Function• 12-2 12. 1. 1.2 The INT and FIX Functions • 12-3 12. 1. 1.3 The SIN, COS, and TAN Functions • 12-3 12. 1. 1.4 The LOG 10 Function • 12-4 12. 1. 1.5 The EXP Function• 12-5 12.1.1.6 The RND Function• 12-6 12.1 .2 Data Conversion Functions 12-7 12. 1.2. 1 The ASCII Function • 12-7 12.1.2.2 The CHA$ Function • 12-8 12.1 .3 String Numeric Functions 12-9 12.1.3.1 The FORMAT$ Function• 12-9 12.1.3.2 The NUM$ and NUM1$ Functions• 12-9 12. 1.3.3 The VAL% and VAL Functions • 12-11 12.1 .4 String Arithmetic Functions 12-11 12.1.4.1 The SUM$ and DIF$ Functions• 12-12 12.1.4.2 The QUO$, PLACE$, and PROD$ Functions• 12-13 xi 12.1 .5 12.1.6 12.2 Date and Time Functions 12. 1.5. 1 The DATE$ Function • 12-16 12. 1.5.2 The TIME$ Function • 12-16 12.1.5.3 The TIME Function • 12-17 Terminal Control Functions 12.1.6.1 The CTRLC and RCTRLC Functions• 12-17 12. 1.6.2 The ECHO and NOECHO Functions • 12-18 12.1.6.3 The INKEY$ Function • 12-19 USER-DEFINED FUNCTIONS 12.2.1 Single-Line DEF Functions 12.2.2 Multi-Line DEF Functions CHAPTER 13 STRING HANDLING xii 12-15 12-17 12-20 12-21 12-22 13-1 13.1 INTRODUCTION 13-1 13.2 USING DYNAMIC STRINGS 13-2 13.3 USING FIXED-LENGTH STRINGS 13-4 13.4 USING STRING VIRTUAL ARRAYS 13-5 13.5 ASSIGNING STRING DATA 13.5.1 The LET Statement 13.5.2 The LSET Statement The RSET Statement 13.5.3 13.5.4 The MIDS Assignment Statement 13-6 13-6 13-7 13-8 13-10 13.6 MANIPULATING STRING DATA WITH STRING FUNCTIONS 13.6.1 The LEN Function The POS Function 13.6.2 13.6.3 The SEGS Function 13.6.4 The MIDS Function 13.6.5 The STRINGS Function The SPACES Function 13.6.6 13.6.7 The TRMS Function 13-11 13-11 13-12 13-14 13-16 13-17 13-18 13-18 13.6.8 13.7 The EDITS Function MANIPULATING STRING DATA WITH MULTIPLE MAPS CHAPTER 14 PROGRAM SEGMENTATION 13-19 13-20 14-1 14.1 VAX BASIC SUBPROGRAMS 14.1.1 SUB Subprograms 14.1 .2 FUNCTION Subprograms 14-2 14-3 14-4 14.2 DECLARING SUBPROGRAMS AND PARAMETERS 14-5 14.3 COMPILING SUBPROGRAMS 14-8 14.4 INVOKING SUBPROGRAMS 14.4.1 Invoking SUB Subprograms 14.4.2 Invoking FUNCTION Subprograms 14-9 14-10 14-10 14.5 RETURNING PROGRAM STATUS 14-11 CHAPTER 15 FILE INPUT AND OUTPUT 15-1 1 5.1 RECORD FORMATS 15.1.1 Fixed-Length Records 15.1.2 Variable-Length Records 15.1 .3 Stream Records 15-1 15-2 15-2 15-2 15.2 FILE ORGANIZATIONS 15.2.1 Terminal-Format Files 1 5.2.2 Sequential Files 15.2.3 Relative Files 15.2.4 Indexed Files 15.2.5 Virtual Files 15-3 15-3 15-3 15-4 15-4 15-5 15.3 RECORD ACCESS AND RECORD CONTEXT 15-5 xiii 15.4 1/0 AND RECORD BUFFERS 15-6 15.5 ACCESSING THE CONTENTS OF A RECORD 15.5.1 The MAP Statement The MAP DYNAMIC and REMAP Statements 15.5.2 15.5.3 The MOVE Statement 15-7 15-7 15-8 15-10 15.6 FILE AND RECORD OPERATIONS Opening Files 15.6.1 15.6.2 Creating Virtual Array Files Locating Records 15.6.3 15.6.4 Reading Records 15.6.5 Writing Records 15.6.6 Deleting Records Updating Records 15.6.7 15.6.8 Controlling Record Access 15.6.9 Gaining Access to Locked Records 15.6.10 Accessing Records by Record File Address 15.6.11 Transferring Data to Terminal-Format Files 15.6.12 Resetting the File Position 15.6.13 Truncating Files 15.6.14 Renaming Files 15.6.15 Closing Files and Ending 1/0 15.6.16 Deleting Files 15-12 15-12 15-15 15-16 15-18 15-20 15-22 15-23 15-25 15-27 15-29 15-31 15-32 15-32 15-33 15-33 15-34 15.7 FILE-RELATED FUNCTIONS 15.7.1 The FSPS Function 15.7.2 The RECOUNT Function The STATUS, VMSSTATUS, and RMSSTATUS 15.7.3 Functions 15-34 15-34 15-36 OPEN STATEMENT OPTIONS 15.8.1 The BUCKETSIZE Clause 15.8.2 The BUFFER Clause 15.8.3 The CONNECT Clause 15.8.4 The CONTIGUOUS Clause 15.8.5 The DEFAULTNAME Clause 15.8.6 The EXTENDSIZE Clause 15.8.7 The FILESIZE Clause 15-37 15-37 15-39 15-39 15-40 15-41 15-41 15-42 15.8 xiv 15-36 15.8.8 15.8.9 15.8.10 15.8.11 15.8.12 The NOSPAN Clause The RECORDTVPE Clause The TEMPORARY Clause The USEROPEN Clause The WINDOWSIZE Clause CHAPTER 16 FORMATTING OUTPUT WITH THE PRINT USING STATEMENT 15-42 15-43 15-43 15-44 15-46 16-1 16.1 INTRODUCTION 16-1 16.2 USING FORMAT STRINGS 16-2 16.3.1 16.3.2 16.3.3 PRINTING NUMBERS Specifying the Number of Digits Specifying Decimal Point Location Printing Numbers with Special Symbols 16.3.3.1 Commas • 16-9 16.3.3.2 Asterisk-Fill Fields • 16-10 16.3.3.3 Currency Symbols • 16-11 16.3.3.4 Negative Fields • 16-12 16.3.3.5 E (Exponential) Format • 16-12 16.3.3.6 Leading Zeros • 16-14 16.3.3.7 Blank-If-Zero Fields • 16-14 16.3.3.8 Debits and Credits • 16-15 16-4 16-4 16-6 16-7 16.4 PRINTING STRINGS 16.4.1 Left-Justified Format 16.4.2 Right-Justified Format 16.4.3 Centered Fields 16.4.4 Extended Fields 16-15 16-17 16-18 16-18 16-19 16.5 PRINT USING STATEMENT ERROR CONDITIONS 16-20 16.3 xv CHAPTER 17 HANDLING RUN-TIME ERRORS 17.1 DEFAULT ERROR HANDLING 17.2 USER-SUPPLIED ERROR HANDLERS 17-2 17.2.1 Protected Regions 17-3 17.2.2 Handlers 17-4 17.2.3 Exiting from Handlers 17-7 17 .2.3. 1 The RETRY Statement• 17-8 17 .2.3.2 The CONTINUE Statement • 17-9 17.2.3.3 The EXIT HANDLER Statement• 17-10 17-12 Selecting the Severity of Errors to Handle 17.2.4 17-12 Identifying Errors 17.2.5 17 .2.5. 1 Determining the Error Number (ERR) • 17-13 17 .2.5.2 Determining the Error Line Number (ERL) • 17-14 17.2. 5. 3 Determining Where the Error Occurred (ERN$) • 17-15 17 .2.5.4 Determining the Error Message Text (ERT$) • 17-15 17.2.5.5 Determining VAX/VMS Error Information• 17-16 17 .2.5.6 Determining RMS Error Information• 17-17 17-18 17.2.6 CTRL/C Trapping Handling Errors in Multiple-Unit Programs 17-20 17.2.7 17-22 Forcing Errors 17.2.8 17.3 USING THE ON ERROR STATEMENTS CHAPTER 18 COMPILER DIRECTIVES xvi 17-1 17-1 17-23 18-1 18.1 INTRODUCTION 18-1 18.2 CONTROLLING THE COMPILATION LISTING 18.2.1 The %TITLE and %SBTTL Directives 18.2.2 The %1DENT Directive 18.2.3 The %PAGE Directive 18.2.4 The %LIST and %NOLIST Directives 18.2.5 The %CROSS and %NOCROSS Directives 18-2 18-3 18-4 18-5 18-5 18-6 18.3 ACCESSING EXTERNAL SOURCE FILES 18-7 18.4 CONTROLLING COMPILATION 18.4.1 The %LET Directive 18.4.2 The %VARIANT Directive 18.4.3 The %ABORT Directive 18.4.4 The %PRINT Directive 18.4.5 The %1F-%THEN-%ELSE-%END %IF Directive 18-9 18-10 18-10 18-11 18-11 18-11 18.5 RECORD DEPENDENCY RELATIONSHIPS IN THE COD 18-13 USING VAX BASIC FEATURES ON VAX/VMS t:HAPTER 19 DATA REPRESENTATION 19.1 19-1 INTEGER FORMAT 19.1.1 Byte-Length Integer Format 19.1.2 Word-Length Integer Format 19.1.3 Longword Integer Format 19-1 19-1 19-2 19-2 19.2.1 19.2.2 19.2.3 19.2.4 REAL NUMBER FORMAT SINGLE Floating-Point Number Format (F_floating) DOUBLE Floating-Point Number Format (D_floating) _ GFLOAT Floating-Point Number Format (G_floating) _ HFLOAT Floating-Point Number Format (H_floating) . 19-3 19-3 19-4 19-5 19-6 19.3 PACKED DECIMAL NUMBER FORMAT 19-6 19.4 STRING AND ARRAY DESCRIPTOR FORMAT 19.4.1 Fixed-Length String Descriptor Format 19.4.2 Dynamic String Descriptor Format 19-7 19-8 19-8 19.5 ARRAY DESCRIPTORS 19.5.1 The Prototype Block 19.5.2 The Multiplier Block 19.5.3 The Bounds Block 19-9 19-10 19-11 19-11 19.6 DECIMAL SCALAR STRING DESCRIPTOR (PACKED DECIMAL STRING DESCRIPTOR) 19-12 19.2 July 1988 xvii CHAPTER 20 ADVANCED FILE INPUT AND OUTPUT xviii 20-1 20.1 INTRODUCTION 20-1 20.2 RMS 1/0 TO MAGNETIC TAPE 20.2.1 Allocating and Mounting a Tape 20.2.2 Opening a Tape File for Output 20.2.3 Opening a Tape File for Input 20.2.4 Positioning a Tape 20.2.5 Writing Records to a File 20.2.6 Reading Records from a File 20.2.7 Controlling Tape Output Format 20.2.8 Rewinding a Tape 20.2.9 Closing a File 20-2 20-2 20-2 20-3 20-3 20-4 20-5 20-5 20-7 20-7 20.3 DEVICE-SPECIFIC 1/0 20.3.1 Device-Specific 1/0 to Unit Record Devices 20 .• 3.2 Device-Specific 1/0 to Magnetic Tape Devices 20.3.2.1 Allocating and Mounting a Tape• 20-8 20.3.2.2 Opening a Tape File for Output • 20-9 20.3.2.3 Opening a Tape File for Input • 20-9 20.3.2.4 Writing Records to a File• 20-10 20.3.2.5 Reading Records from a File • 20-10 20.3.2.6 Rewinding a Tape • 20-11 20.3.2.7 Closing a Tape• 20-11 20.3.3 Device-Specific 1/0 to Disks 20.3.3.1 Assigning and Mounting a Disk• 20-12 20.3.3.2 Opening a Disk File for Output• 20-12 20.3.3.3 Opening a Disk File for Input• 20-13 20.3.3.4 Writing Records to a Disk File• 20-13 20.3.3.5 Reading Records from a Disk File• 20-14 20-7 20-8 20-8 20-12 20.4 1/0 TO MAILBOXES 20-14 20.5 NETWORK 1/0 20.5.1 Remote File Access 20.5.2 Task-to-Task Communication 20.5.3 Accessing an Rdb/VMS Database 20-16 20-17 20-17 20-19 CHAPTER 21 USING VAX BASIC IN THE COMMON LANGUAGE ENVIRONMENT 21-1 21.1 SPECIFYING PARAMETER-PASSING MECHANISMS 21 .1 .1 Passing Parameters by Reference 21 . 1 .2 Passing Parameters by Descriptor 21.1.3 Passing Parameters by Value 21.1.4 VAX BASIC Default Parameter-Passing Mechanisms 21 .1 . 5 · Creating Local Copies 21-2 21-2 21-2 21-3 21-3 21-5 21.2 CALLING EXTERNAL ROUTINES 21.2.1 Determining the Type of Call 21.2.2 Declaring an External Routine and Its Arguments 21.2.3 Calling the Routine 21-6 21-6 21-6 21-8 21.3 CALLING VAX BASIC SUBPROGRAMS FROM OTHER LANGUAGES 21-9 21.4 CALLING SYSTEM ROUTINES 21.4.1 VAX/VMS Run-Time Library Routines 21.4.2 System Service Routines 21.4.3 System Routine Arguments 21 .4.4 Including Symbolic Definitions 21.4.5 Condition Values 21-11 21-11 21-12 21-13 21-19 21-20 21.5 EXAMPLES OF CALLING SYSTEM ROUTINES 21-21 21.6 THE VAX PROCEDURE CALLING AND CONDITION HANDLING STANDARD 21.6.1 The Argument List 21.6.2 The Return of the Function Value 21.6.3 Register and Stack Usage 21-24 21-24 21-26 21-27 ADDITIONAL INFORMATION 21-28 21.7 xix CHAPTER 22 LIBRARIES AND SHAREABLE IMAGES 22-1 22.1 INTRODUCTION 22-1 22.2 SYSTEM-SUPPLIED LIBRARIES 22-2 22.3 CREATING USER-SUPPLIED OBJECT MODULE LIBRARIES 22.3.1 Accessing User-Supplied Object Module Libraries in the BASIC Environment 22.3.2 Accessing User-Supplied Object Module Libraries at DCL Level 22-3 SHAREABLE IMAGES 22.4.1 Accessing Shareable Images in the BASIC Environment 22.4.2 Accessing Shareable Images at DCL Level 22-5 22-6 22-7 EXTRACTING RECORD DEFINITIONS FROM THE VAX COMMON DATA DICTIONARY 23-1 23.1 INTRODUCTION TO THE COD 23-1 23.2 EXTRACTING COD DATA DEFINITIONS IN VAX BASIC 23-2 23.3 COD PATH NAMES 23-5 23.4 SPECIFYING A COD HISTORY LIST ENTRY 23-6 23.5 THE NAME FOR BASIC CLAUSE 23-7 23.6 COD ARRAYS 23-8 23.7 COD VARIANTS 23-9 23.8 COD DATA TYPES 23-11 22.4 CHAPTER 23 xx 22-3 22-4 July 1988 23.8.1 23.8.2 23.8.3 23.8.4 23.8.5 Character String Data Types Integer Data Types Floating-Point Data Types Decimal String Data Types Other Data Types HAPTER 24 COD/PLUS SUPPORT IN VAX BASIC 23-15 23-17 23-20 23-23 23-24 24-1 24.1 INTRODUCTION TO COD/PLUS 24-1 24.2 COD/PLUS CONCEPTS 24.2.1 Dictionary Formats 24.2.2 Dictionary Path Names 24.2.3 Dictionary Entities 24.2.4 Dictionary Relationships 24-2 24-3 24-4 24-5 24-6 24.3 USING COD/PLUS WITH VAX BASIC 24.3.1 The /DEPENDENCY_DATA Qualifier 24.3.2 Creating Relationships with Included Record Definitions 24-6 24-7 24.4 24.5 .PPENDIX A A.1 CREATING RELATIONSHIPS FOR REFERENCED DICTIONARY ENTITIES 24-10 SPECIFYING A COD HISTORY LIST ENTRY 24-11 COMPILE-TIME ERROR MESSAGES A-1 COMPILE-TIME ERRORS A-1 .PPENDIX B RUN-TIME ERROR MESSAGES B.1 uly 1988 24-7 VAX BASIC RUN-TIME ERRORS BY MNEMONIC B-1 B-1 xxi B.2 VAX BASIC RUN-TIME ERRORS BY NUMBER B-35 B.3 ERRORS NOT GENERATED BY VAX BASIC B-40 APPENDIX C OPTIONAL PROGRAMMING PRODUCTIVITY TOOLS C-1 C.1 C.2 USING LSE WITH VAX BASIC C.1.1 Entering Source Code Using Tokens and Placeholders C.1 .2 Compiling Source Code C.1 .3 Examples C. 1.3.1 FIND Statement • C-8 C.1.3.2 FOR Statement• C-9 C-1 C-2 C-4 C-5 USING THE VAX SOURCE CODE ANALYZER C-10 C.2.1 Setting Up an SCA Environment C-11 C.2. 1. 1 Creating an SCA Library • C-13 C.2. 1.2 Generating Data Analysis Files • C-13 C.2. 1.3 Selecting an SCA Library • C-13 C.2. 1.4 loading Data Analysis Files into a local library • C-14 C.2.2 Using SCA for Cross-Referencing C-14 C.2.3 Displaying Routine Calls with the VIEW CALL_TREE Command C-17 C.2.4 Identifying Routine Call Errors with the CHECK CALLS Command C-18 INDEX EXAMPLES 4-1 xx ii VAX BASIC Compiler Listing 4-17 FIGURES 2-1 Complete File Specification 2-5 2-2 2-7 2-3 A Directory Hierarchy DCL Commands for Developing Programs 2-20 3-1 Running Multiple-Unit Programs 3-4 5-1 Keypad Key Functions Predefined by the Debugger 5-7 9-1 Mixed-Mode Expression Results 9-12 9-2 Multiple Maps 9-17 19-1 Byte-Length Integer Format 19-2 19-2 Word-Length Integer Format 19-2 19-3 19-4 Longword Integer Format Single-Precision Real Number Format 19-3 19-4 19-5 Double-Precision Real Number Format 19-5 19-6 Fixed-Length String Descriptor Format 19-8 19-7 Dynamic String Descriptor Format 19-8 Array Descriptor Format 19-9 19-10 19-9 Decimal Scalar String Descriptor 19-12 21-1 Structure of a VAX Argument List 21-25 21-2 Example of a VAX Argument List Use of LSE and SCA for Multimodular Development 21-26 C-12 C-1 rABLES 2-1 File Protection User Categories 2-13 2-2 File Access Variations 2-13 3-1 VAX BASIC Compiler Commands 3-10 5-1 Debugger Command Summary 6-1 Predefined Constants 5-27 6-12 8-1 MAT Statements 8-13 8-2 MAT Statement Keywords 8-14 9-1 VAX BASIC Data Types 9-3 xxiii 9-2 9-3 12-1 12-2 13-1 13-2 15-1 15-2 15-3 15-4 16-1 16-2 21-1 21-2 21-3 21-4 21-5 23-1 23-2 xx iv Result Data Types in VAX BASIC Expressions FILL Item Formats, Representations, and Default Allocations String Arithmetic Functions Precision of String Arithmetic Functions String Modification EDITS Options Record Context After a FIND Operation Record Context After a GET Operation Record Context After a PUT Operation VAX RMS Control Structures Set for the USEROPEN Clause Format Characters for Numeric Fields Format Characters for String Fields Allowable Parameter-Passing Mechanisms Run-Time Library Facilities System Services VMS Usages VAX Register Usage Supported COD Data Types Unsupported COD Data Types 9-10 9-18 12-12 12-12 13-2 13-19 15-17 15-18 15-20 15-44 16-8 16-16 21-3 21-12 21-13 21-14 21-27 23-11 23-13 ~reface Intended Audience This manual presents tutorial information on VAX BASIC language features and describes how to develop and use VAX BASIC programs on VAX/VMS systems. Readers are presumed to have some previous knowledge of BASIC or another high-level programming language. This manual should be used with the other two manuals in the documentation set. Associated Documents This manual is one of three manuals that form the VAX BASIC document set. The other two manuals are: VAX BASIC Reference Manual Provides reference material and syntax for all VAX BASIC language elements except graphics capabilities Programming with VAX BASIC Graphics Provides tutorial and reference material for VAX BASIC graphics capabilities You may also be interested in the following supplementary manuals: • • • • VAX BASIC Syntax Summary Introduction to BASIC BASIC for Beginners More BASIC for Beginners xxv Structure of This Document This manual has 23 chapters and 2 appendixes. The chapters are grouped into three parts as follows: Developing VAX BASIC Programs on VAX/VMS Chapter 1 Provides a brief overview of VAX BASIC Chapter 2 Shows you how to get started on VAX/VMS Chapter 3 Describes how to develop programs in the BASIC environment Chapter 4 Describes how to develop programs from DCL command level and how to generate a compiler listing Chapter 5 Describes how to use the VAX/VMS Symbolic Debugger to debug VAX BASIC programs VAX BASIC Programming Concepts Chapter 6 xx vi Explains the elements of VAX BASIC programs Chapter 7 Explains simple input and output procedures Chapter 8 Shows how to use VAX BASIC arrays Chapter 9 Explains data definitions Chapter 10 Explains how to create user-defined data structures with the RECORD statement Chapter 11 Shows how to control the flow of program execution Chapter 12 Explains how to use VAX BASIC functions Chapter 13 Explains how to handle strings in VAX BASIC Chapter 14 Describes structured VAX BASIC programming techniques Chapter 15 Explains how to manage files Chapter 16 Describes how to format output with the PRINT USING statement Chapter 17 Explains error handling techniques Chapter 18 Shows how to use compiler directives Using VAX BASIC Features on VAX/VMS Chapter 19 Describes how to represent data on VAX/VMS systems Chapter 20 Describes additional I/O considerations on VAX/VMS systems Chapter 21 Describes System Services and Run-Time Library routines Chapter 22 Describes the use of user-supplied libraries and shareable images Chapter 23 Explains how definitions extracted from the VAX Common Data Dictionary are translated to RECORD statements in VAX BASIC Chapter 24 Explains how to use the dependency recording feature of CDD/Plus Version 4.0 in VAX BASIC programs Appendixes Appendix A Lists compile-time error messages Appendix B Lists run-time error messages Appendix C Describes how to use LSE and SCA with VAX BASIC Conventions Convention Meaning $ BASIC progl In command-line examples, the user's response to a prompt is printed in red; system prompts are printed in black. A vertical ellipsis indicates that code which would normally be present is not shown. July 1988 UPPERCASE letters Uppercase letters are used for VAX BASIC keywords and must be coded exactly as shown. lowercase letters . Lowercase letters are used to indicate user-supplied names or characters. xxvii Summary of Technical Changes Summary of New and Changed Features for Version 3.3 Version 3.3 of VAX BASIC includes support for the COD/Plus Version 4.0 CDO-format dictionaries while continuing to provide full support for the DMD-format dictionaries used in previous versions of CDD. Both types of dictionaries can coexist on a system and a program can access data definitions on both. This new functionality is implemented as follows: • • • Addition of the /DEPENDENCY_DATA qualifier to the DCL command, BASIC Addition of the lexical directive, %REPORT %DEPENDENCY Modification of the lexical directive, %INCLUDE %FROM %CDD Descending keys are now supported on both primary and alternate keys. This new functionality is implemented by allowing the choice of ASCENDING or DESCENDING on key definition clauses in the OPEN statement. In addition, this documentation update contains numerous corrections and clarifications to previous documentation; these documentation changes do not reflect new features. July 1988 xxix Summary of New and Changed Features for Version 3. 1 Version 3.1 of VAX BASIC includes support for the VAX Source Code Analyzer (SCA). SCA is a programming tool that can be used to crossreference and analyze VAX BASIC source code. See Appendix C of this manual for a description of how to use SCA with VAX BASIC. VAX BASIC Version 3.1 also corrects a number of problems and incompatibilities with previous versions. See the VAX BASIC online release notes for more information. The release notes are located in SYS$HELP:BASIC031.RELEASE_NOTES. Summary of New and Changed Features for Version 3.0 Version 3.0 of VAX BASIC includes extensive graphics capabilities, structured error handling techniques, enhancements to file IjO and other new features. All of these features are documented in the VAX BASIC Reference Manual and this manual except for the graphics features, which are documented in Programming with VAX BASIC Graphics. This section summarizes all of the major changes for this release. Graphics Capabilities VAX BASIC supports extensive graphics capabilities based on VAX GKS. The new graphics capabilities are available to you if you have the full or run-time VAX GKS kit installed on your system (Version 2.0 or later) and if you use supported graphics hardware. The main features of VAX BASIC graphics are as follows: • • • • • • • • xxx A short learning period Convenient default values for attributes Statements consisting of English words in simple constructs Window and viewport settings that are easy to alter Graphics subprograms that can be invoked with a variety of transformation functions Input statements for interactive graphics programs Programs that can run on multiple devices Programs that run on any hardware supported by VAX GKS Structured Error Handling VAX BASIC supports structured error handling with WHEN ERROR constructs. When an error occurs during execution of statements in a protected block of code, the error is handled by the associated attached or detached handler. The following new statements and functions enhance error handling capabilities: • • • • • • • WHEN ERROR RETRY CONTINUE HANDLER, EXIT HANDLER, and END HANDLER OPTION HANDLE CAUSE ERROR RMSSTATUS and VMSSTATUS Although the new WHEN ERROR constructs are the preferred method for error handling, ON ERROR statements are supported for compatibility with previous versions of BASIC. Optional Line Numbers Line numbers are no longer required in VAX BASIC programs. A VAX BASIC program can have no line numbers at all, or it can use the traditional line numbered statements; both are valid. A program with a line number on the first nonblank line is treated as a line-numbered program by the compiler. In the BASIC environment, programs with no line numbers must be created with a text editor or copied into the environment with the OLD command. Array Bounds You can now specify the lower bound for any or all dimensions of nonvirtual arrays. Previously, VAX BASIC arrays could only be zero-based. In addition, two new functions, LBOUND and UBOUND, allow you to retrieve the lower and upper bounds of array dimensions. xxxi Improvements for Procedure Invocations This version of VAX BASIC includes additional flexibility for procedure invocations: • • • If an external function is called as a procedure, VAX BASIC performs parameter validation exactly as if the declared function had been invoked as a function. The new keywords ANY and OPTIONAL ease parameter passing to non-BASIC routines. Additional functionality has been added to the LOC function so that the address of an external function can be accessed. PRINT USING Format Strings Constant PRINT USING format strings are precompiled at compile time. Significant run-time performance gains can be achieved by recompiling programs that use constant format strings. Single Keystroke Input The new function INKEY$ allows you to detect a single keystroke typed at a terminal. Function and keypad keys return a descriptive text string, for example, "F17'', and control characters return a single ASCII code. 1/0 Enhancements The following features have been added to enhance 1/0 capabilities: • • • xxxii STREAM files are accessible with the OPEN statement. A WAIT clause can be added to the GET and FIND statements. This clause instructs VAX BASIC to wait on locked records rather than immediately returning the error RECBUCLOC (ERR= 154). The new keywords NX (next) and NXEQ (next or equal to) are synonyms for GT and GE, respectively. These keywords make the GET and FIND statements more meaningful if an indexed file is accessed with descending keys. Miscellaneous Features • • • • • • • • • • • The new PROGRAM statement allows you to optionally name a main program unit. This name becomes the module name of the compiled source. You can return a procedure value or the status of an image upon exiting with the following statements: END /EXIT PROGRAM - END/EXIT FUNCTION - END/EXIT DEF By default, VAX BASIC calls VAX EDT from the environment. The user or the system manager can select callable VAX EDT, the VAX Text Processing Utility (VAXTPU), or the VAX Language-Sensitive Editor as the default editor. Start-up time for editing files within the environment is shorter as it is no longer necessary to spawn a subprocess to access editors that are callable. System managers can prevent users escaping to DCL level from the environment by setting the user's subprocess limit (PRCLM) to zero. A subprocess limit of 1 was previously required so that a user could use an editor within the environment. New extensions to the OPTION statement include the following: OPTION ANGLE = degrees-or-radians OPTION HANDLE = severity-level OPTION CONSTANT TYPE = data-type OPTION OLD VERSION = CDD The MID$ function can now be on the left side of an assignment statement. This feature allows partial string replacement. VAX BASIC statements, compiler directives, labels, and comment lines can now begin in column 1. You can include files from a text library with the %INCLUDE directive. The suffixes$ (for strings) and % (for integers) are allowed on explicitly declared variables and constants. Extensions to the REMAP and MAP DYNAMIC statements allow you to redefine the storage allocated to a previously declared static string variable. New functions MAX and MIN are provided for the comparison of a series of arguments. xxxiii • • • xxxiv The new MOD function divides one numeric argument by another and returns the remainder. A new compiler. directive, %PRINT, allows you to print a message during the compilation of a source program without aborting the compilation. The new lexical directive %DECLARED allows you to determine whether or not a lexical variable has been declared. DEVELOPING VAX BASIC PROGRAMS ON VAX/VMS Chapter 1 Overview of the VAX BASIC Language This brief overview highlights the features of the VAX implementation of BASIC. The features listed here are described fully in subsequent chapters of this manual, as well as in the other two manuals in the documentation set. BASIC was originally developed for students with little or no programming experience. Since then, BASIC has become one of the most widely used programming languages and is available on almost every computer system. The VAX implementation of BASIC has evolved beyond the original design;. however, VAX BASIC still supports all of the traditional features of the original language in addition to more recent programming techniques. It has become much more than a teaching tool, and is used in a wide variety of sophisticated applications. VAX BASIC is a powerful structured programming language designed for novice and application programmers alike. The language provides you with both a highly interactive programming environment and a highperformance development language. VAX BASIC supports such language constructs as • • • • • • • Code without line numbers (traditional line numbers are optional) Control structures, such as SELECT CASE Explicit variable declarations Capabilities for handling dynamic strings Adaptable file-handling capabilities for terminal-format files, and the full range of RMS facilities Global and local run-time error handling with WHEN ERROR blocks Compile-time directives Overview of the VAX BASIC Language 1-1 • • • A variety of data types, including packed-decimal and user-defined records Extensive error checking with meaningful error messages Thirty-one-character names for variables, labels, functions and subprograms VAX BASIC uses the VAX/VMS operating system to its full advantage and is integrated with many other DIGITAL products. In particular, VAX BASIC supports: • • • • • • • Interactive graphics 1 The VAX standard calling procedures Record definitions included from the VAX Common Data Dictionary Code analysis with the VAX Performance and Coverage Analyzer (PCA) Creation of code with the VAX Language-Sensitive Editor Extensive online language help Exchange of data with other systems using DECnet VAX BASIC supports the features of other BASICs, including PDP-11 BASIC-PLUS-2. VAX BASIC is a functional superset of BASIC-PLUS-2. Compatibility flags for BASIC-PLUS-2 and ANSI Minimal BASIC allow you to check whether your VAX BASIC programs will run on other systems. When you write programs in VAX BASIC, you can choose between two program development methods: developing programs at DCL command level, or developing programs from within the BASIC environment. When you develop programs at DCL level, you write your source program with a text editor, then compile, link, and run the program with commands to the VAX/VMS operating system. Alternatively, when you develop programs within the BASIC environment, you simply type the DCL command BASIC to enter the environment, enter your program, then execute it with the VAX BASIC command RUN. The chapters in Part I of this manual show you how to get started on the VAX/VMS system and how to develop programs both at DCL command level and within the BASIC environment. 1 The optional graphics capabilities are discussed in Programming with VAX BASIC Graphics. 1-2 Overview of the VAX BASIC Language Chapter 2 Introduction to the VAX/VMS Operating System When you develop VAX BASIC programs on the VAX/VMS operating system, you use commands that are part of the DIGITAL Command Language (DCL). This chapter explains how to use a VAX/VMS system. More specifically, this chapter discusses how to • • • • • • • Log in to and out of the VAX/VMS system Access the HELP facility Use DCL commands Create directories and subdirectories Use DCL file-handling commands Develop command procedures Develop VAX BASIC programs For a complete list of DCL commands, see the VAX/VMS DCL Dictionary. Introduction to the VAX/VMS Operating System 2-1 2.1 Logging In and Out Before you can log in to the VAX/VMS operating system, you must have an account set up in your name. Your system manager is generally the person responsible for establishing this account and will provide you with both your user name and password. Both of these are unique to your session and distinguish you from other users on the system. Once you are an authorized user, you can regularly access the system. When you log in, the system prompts you for your user name and password. When you enter your user name, each character is displayed, or echoed, at the terminal. However, when you enter your password, no characters are echoed. This enables you to protect your account from others who may try to access it. For example: IRETI Username: SMITH,RETI Password: RET •The system uses the dollar sign ( $ ) as a prompt. When this prompt is displayed, it indicates that the login procedure was successful and that you can begin entering commands. If you enter your user name or password incorrectly, the system displays an error message. To gain access to the system, you must repeat the login procedure. To change your password, type the SET PASSWORD command and press the RETURN key as shown in the following example. The system prompts you for your current password. The system then prompts you for your new password, which can have up to 31 characters with any combination of the letters A through Z, the numbers 0 through 9, a dollar sign ( $ ), and an underscore ( _ ). $ SET PASSWORD Old password: New password: Verification: To verify that you have entered your password correctly, the system prompts you to enter your new password again. If the two new passwords do not match, your original password remains in effect. To end the current session, enter the LOGOUT command: $ LOGOUT 2-2 Introduction to the VAX/VMS Operating System The system responds with the following message: SMITH logged out at DD-MMM-YYY HH:MM 2.2 Accessing the HELP Facility The VAX/VMS system has an online HELP facility that is useful if documentation on a particular command is not readily available. To gain access to the HELP facility, you use the DCL command HELP. For example: • HELP IRETI The system displays a list of topics for which help is available and prompts you for a topic. If you want information on a specific command, such as the DCL command BASIC, type that command after the topic prompt. For example: Topic? BASIC IRETI The system displays a description of the command, and lists all of the available VAX BASIC qualifiers, parameters and other topics for which help is available. It then prompts you for a subtopic. BASIC Subtopic? /SHOW IRETI If you already know which subtopic you want information on, you can type the HELP command followed by the BASIC topic and the subtopic you want help on. For example: • HELP BASIC/SHOW IRETI Note that all language HELP is available only from within the BASIC environment or from within the VAX Language-Sensitive Editor. To exit from the HELP facility, press CTRL/Z. Once the dollar sign prompt is displayed, the system is ready to accept a new command. Introduction to the VAX/VMS Operating System 2-3 2.3 Entering and Editing DCL Commands Once you have gained access to the system, you can use DCL commands to perform specific tasks. DCL commands are words, generally verbs, that describe the action they perform. Following are some of the most important rules for using DCL commands. Other rules are described in the VAX/VMS DCL Dictionary. • • You can typically truncate any command name or qualifier name to four characters. Fewer than four characters is acceptable if the truncated name is unique to the command that you want. You must precede each qualifier name with a single slash character (/). • • • • You can type commands in either upper- or lowercase letters. If you omit a required parameter (for example, a file specification), the DCL command interpreter will prompt you for it. You can type a command on as many lines as you wish, as long as you end each line (except the last) with a hyphen ( - ). After you have typed a complete command line, you must press RETURN to execute the command. If you enter a command incorrectly (for example, if you misspell a command or qualifier name), the command interpreter issues an error message and you must either retype the entire command or edit the command and then reenter it. Command line editing enables you to correct errors in lengthy command lines and saves you the trouble of retyping the entire line. To edit DCL command lines, you can use various control characters as well as keypad keys. The following list describes some of these editing functions: DELETE Moves the cursor back one character and erases that character. Up arrow /(CTRL/B) Displays the most recent command line entered. You can display up to twenty previously entered command lines by continuing to press CTRL/B or the up arrow key. To display command lines in the opposite direction, press the down arrow key. Left arrow /(CTRL/D) Moves the cursor one position to the left. 2-4 Introduction to the VAX/VMS Operating System Right arrow /(CTRL/F) Moves the cursor one position to the right. CTRL/U Deletes the current command line and issues a carriage return so you can reenter the entire command line. CTRL/C and CTRL/Y Cancels or interrupts an entire command line. 2.4 Understanding the Directory Structure A directory is a catalog of files. Each file is distinguished by its name, file type, and version number. It is not necessary to specify the complete file specification every time you compile, link, or run a source program. Under most conditions, it is necessary to specify only the file name. Figure 2-1 illustrates a complete file specification. Figure 2-1: Complete File Specification MYVAX: :USER$$DISK: [SMITH]FIRST_FROG.BAS;3 1--7/~T!\ o node 8 device e directory o file name 0 file type 0version ZK-5407-86 0 8 Specifies a computer system that is part of a DECnet network. Identifies the hardware device on which the file is either stored or written. C) Specifies the directory in which a file is cataloged. 8 Distinguishes a file from others contained in the same directory. A file name can have up to 39 characters. C) Identifies the type of data that a file contains. 0 Specifies the version number of a file. Each time a file is modified, its version number is incremented by 1. Introduction to the VAX/VMS Operating System 2-5 When you log in to the VAX/VMS operating system, you enter your default directory which generally has the same name as the account you log in to. This default directory is also called your main or top-level directory. The system allows you to create subdirectories from your main directory. Subdirectories are helpful in organizing files. For instance, if you are a multilanguage user, it may be helpful for you to keep all of your VAX BASIC programs separate from your VAX COBOL programs. To create a subdirectory, you issue the DCL command CREATE/DIRECTORY. In the following example, the directory BASJC_pROG.DIR is created. You can then specify the subdirectory name [SMITH.BASJC_pROG] in commands or programs. $ CREATE/DIRECTORY [SMITH.BASIC_PROG] To move from one directory to another, you use the SET DEFAULT command as shown in the following example: $ SET DEFAULT [SMITH.COBOL_PROG] The number of subdirectories you can create is limited only by the amount of disk space you have available. Figure 2-2 illustrates the concept of directory hierarchies. 2-6 Introduction to the VAX/VMS Operating System Figure 2-2: A Directory Hierarchy $DIRECTORY [000000] A volume's Master File Directory (MFD) contains entries for the user file directories (UFOs) on the volume. MALCOLM.DIR 301300.DIR HIGGINS.DIR 301301.DIR MFD LEVEL $DIRECTORY [HIGGINS] PAYROLL.DIR USER.DOC MEMO.LIS LOGIN.COM 0 Each UFD lists the files belonging to that directory, and can contain entries for additional directories, called subdirectories. $DIRECTORY (HIGGINS.PAYROLL] A subdirectory can catalog files INFO.COM and/or additional subdirectories. SOURCE.DIR The subdirectory file named LISTINGS.DIR (HIGGINS)PAYROLL.DIR DATA.DIR lists additional subdirectory files. DIRECT.DOC The subdirectory file named (HIGGINS.PAYROLL]DATA.DIR lists additional subdirectory files. $DIRECTORY (HIGGINS.PAYROLL.DATA)--------JANUARY.DIR $DIRECTORY [HIGGINS.PAYROLL.LISTINGS) $DIRECTORY (HIGGINS.PAYROLL.SOURCE) FICA.LIS TAXES.LIS FICA.BAS TAXES.MAR PAYROLL.BAS ~--_ ___,,__ $_0_1R_E_C_T_O_R_Y_(H_l-.GGINS.PA YROLL.DAT A.MARCH) FICA.DAT STATETAX.DAT FEDTAX.DAT EMPTTL.DAT FICA.DAT STATETAX.DAT FEDTAX.DAT EMPTTL.DAT FICA.DAT STATETAX.DAT FEDTAX.DAT EMPTTL.DAT nextlevel.DIR ZK 553686 Introduction to the VAX/VMS Operating System 2-7 Often, you may refer to files that are contained in your directory hierarchy but that are not contained in your current default directory. Two special symbols exist to make references easier: the ellipsis ( ... ) and the hyphen ( - ). The ellipsis is used to search down a directory hierarchy and the hyphen is used to search up a directory hierarchy. For instance, [SMITH ... ] refers to the directory [SMITH) and all of the subdirectories below [SMITH] in the hierarchy. The directory specification, [... BASIC_pRQG) refers to all subdirectories named BASIC_pRQG below the current default directory. You can specify the current default directory with empty brackets ( [] ), and you can refer to the entire hierarchy under your current default directory with [... ). Hyphens allow you to search up the hierarchy one directory at a time; each hyphen stands for one level. For example, if your current default directory is [SMITH.BASIC_pRQG), you can refer to [SMITH) by specifying [-). To delete a subdirectory, you must first remove any files that are contained in it and change the protection on the directory file. You can then delete the .DIR file. Note that you can use both square brackets and angle brackets interchangeably to refer to directories. For a more detailed discussion of the directory structure, see the Introduction to VAX/VMS. 2.5 Using DCL File-Handling Commands DCL file-handling commands allow you to modify and maintain your source programs. The following sections describe how to use DCL commands to perform common file operations such as displaying files, printing and typing files, deleting files, purging files, renaming and moving files, searching files, and setting file protection. For a complete list of qualifiers to each command and for more detailed information, see the VAX/VMS DCL Dictionary or type HELP at the DCL prompt followed by the name of the command. 2-8 Introduction to the VAX/VMS Operating System 2.5.1 Displaying Files To display a list of all of the files that are contained in a directory, you use the DCL command DIRECTORY. When you enter the DIRECTORY command with no parameters or qualifiers, the system displays an entire list of all of the files that are contained in your current directory. For example: $ DIRECTORY Directory USER$$DISK:[SMITH] PROGL DIA; 22 PROG1.EXE;2 PROG1.0BJ;60 PROG1.BAS;63 If you want to know how many versions of a specific file exist in your current directory, you enter the DIRECTORY command along with a specific file name and file type as shown in the following example: $DIRECTORY PROG1.BAS Directory USER$$DISK:[SMITH] PROG1.BAS;53 Total of 1 file. The system displays a list of all the versions of the file that currently exist. However, if you wish to view only a selected group of files that contain a specific file type, you can use an asterisk ( *) or a percent sign ( % ) as a wildcard character. The asterisk signifies any number of characters, including zero, whereas the percent sign signifies exactly one character. Therefore, •.BAS represents all files that end with the file type, BAS whereas 3%.BAS represents only those files that contain two characters for a file name, where 3 is the first character. For example: $DIRECTORY •.OBJ Directory USER$$DISK:[SMITH] PROG1.0BJ;63 PROG2.0BJ;64 PROG4.0BJ;66 Total of 3 files. The system displays only those files that end with the file type OBJ. Introduction to the VAX/VMS Operating System 2-9 2.5.2 Printing and Typing Files To examine the contents of a file, you can use either the DCL command PRINT or the DCL command TYPE. The PRINT command allows you to output the contents of a file to a line printer whereas the TYPE command allows you to output the contents of a file to your terminal screen. In the following example, the PRINT command outputs the file FIRST_ PROG.BAS to a printer: $ PRINT FIRST_PROG.BAS By default, the system prints the most current version of FIRST_ PROG.BAS. To print a specific version of FIRST_pRQG.BAS, you must specify a version number. For instance, in the following example, the system prints the second version of FIRST_pRQG.BAS: $ PRINT FIRST_PROG.BAS;2 With the PRINT command, you can specify command qualifiers. For example, the /AFTER qualifier specifies that the job not be printed until a specific time of day. For a complete list of all of the command qualifiers available with the PRINT command, see the VAX/VMS DCL Dictionary. With the TYPE command, you can display the contents of a file on your terminal screen. If you specify the /PAGE qualifier, you can display one screen of text at a time. If you do not specify the /PAGE qualifier, you can press CTRL/S to interrupt the display for closer examination of a particular section and then resume the display by pressing CTRL/Q. If your keyboard has a NOSCROLL or a HOLD SCREEN key, you can use it to toggle between interrupting and resuming the display. 2.5.3 Deleting Files To delete a file, you use the DCL command DELETE. With the DELETE command, you must specify the file name, the file type, and the version number of the file you want to delete. For instance, in the following example, the system deletes the first version of FIRST_pRQG.BAS. $DELETE FIRST_PROG.BAS;1 If you want to delete all versions of a file, you can use an asterisk ( • ) as a wildcard character. For example: $ DELETE FIRST_PROG.BAS;• 2-1 0 Introduction to the VAX/VMS Operating System Similarly, if you want to delete all files with a particular file type, you can use the asterisk ( • ) or the percent sign ( % ) as a wildcard character. For instance, in the following example, the system deletes all files that have the file type LIS: $DELETE *.LIS;* You can specify command qualifiers with the DELETE command. For instance, if you specify /CONFIRM, a request is issued before each individual DELETE operation so that you can confirm that the operation should be performed on a particular file. 2.5.4 Purging Files The DCL command PURGE deletes all but the most recently modified version of files. Unlike the DELETE command, you can specify the PURGE command without specifying a file name or file type. The system deletes all files except the most recent version in your current directory. $ PURGE By default, only the most recent version of each file is kept. You can, however, specify the number of versions that are kept by specifying the /KEEP qualifier. This command qualifier specifies the maximum number of versions of a specified file to be kept in your directory. For instance, in the following example, the system deletes all but the two highest versions of FIRST_pRQG.BAS. $ PURGE FIRST_PROG.BAS/KEEP=2 2.5.5 Renaming and Moving Files To change the identification of one or more files, use the DCL command RENAME. For instance, in the following example, FIRST_pRQG.BAS is changed to SECOND_pRQG.BAS. $ RENAME FIRST_PROG.BAS SECOND_PROG.BAS Note that because a version number is not specified, the most current version is renamed by default. Introduction to the VAX/VMS Operating System 2-11 You can also use the RENAME command to move a file from one directory to another. For instance, in the following example, the file SECOND_ PROG. BAS is moved from the directory [SMITH] to the subdirectory [SMITH.BASIC_pROG]: $ RENAME [SMITH]SECOND_PROG.BAS [SMITH.BASIC_PROG] To move an entire set of files that have common file name or file type, you can use the asterisk ( * ) as a wildcard character. For instance, the following command line changes the directory name of all files that contain the file name SECOND_pROG. $ RENAME [SMITH]SECOND_PROG.*;* [SMITH.BASIC_PROG]*.*;* 2.5.6 Searching Files To search a file or a group of files for a specified string, use the DCL command SEARCH. This command allows you to search the contents of a specified file or group of files for a particular string or strings and lists all of the lines in which the string or strings appear. In the following example, the directory [SMITH.BASIC_pROG] is searched for any files that contain the string "Course_Data": $SEARCH [SMITH.BASIC_PROG]*.*;* 11 Course_Data 11 2.5. 7 Setting File Protection To prevent others from gaining access to a file, you use the SET FILE/PROTECTION command. With this command, you specify user categories with access types. Table 2-1 lists the four user categories and Table 2-2 lists the four access types. 2-12 Introduction to the VAX/VMS Operating System Table 2-1: File Protection User Categories User Category Description OWNER The user who created the file GROUP All users, including the owner, who have the same group number in their user identification codes (UICS) as the owner of the file WORLD All users SYSTEM All users who have the same system privilege (SYSPRV), or low group numbers (usually from 1 through 10) Table 2-2: File Access Variations Access Description READ The ability to examine, print, or copy a file WRITE The ability to modify or write a file EXECUTE The ability to execute a file that contains executable program images DELETE The ability to delete a file When you specify the SET FILE/PROTECTION command, the class names and access types can be spelled out or abbreviated to the first letter. For example, you may want to give system users and your project members complete access to the file TEST.BAS, and give others read access only. To do this, you would enter the following command: $SET FILE TEST.BAS/PROTECTION = (S:RWED,O:RWED,G:RWED,W:R) Introduction to the VAX/VMS Operating System 2-13 2.6 Using Command Procedures A command procedure is a group of DCL commands in a file that can be executed by the DCL command interpreter. You can use command procedures to generate sequences of command lines that you type frequently. For example, you could create a command procedure that compiles, links, and runs your source programs while checking for error status. Moreover, you could create a command procedure that deletes all files that end with a particular file type. Instead of typing each command separately, you would execute the command procedure. The following sections briefly discuss the rules for defining DCL symbols and logical names as well as how to create and execute a command procedure. In addition, this section contains a sample command procedure and a sample LOGIN.COM file. For more information, see the Guide to Using DCL and Command Procedures on VAX/VMS. 2.6. 1 Defining DCL Symbols and Logical Names You define a symbol by placing the equal sign ( =) or the double equal sign ( == ) between the symbol and the string it represents. If you use the double equal sign operator, the system inserts the symbol in the global symbol table; if you use the equal sign operator, the system inserts the symbol in a local symbol table. When a symbol is local, it is recognized only within the procedure in which it is contained. However, when a symbol is global, it is recognized by many other procedures. For example, the following command defines the global symbol BASIC as a command to invoke the VAX BASIC compiler, with two added qualifiers: $ BASIC == "BASIC/DEBUG/LIST" Briefly, the VAX/VMS system creates a global symbol table for you when you log in. Then, each time you execute a command procedure, the system creates a new command level and a local symbol table for that level. If one command procedure executes another procedure, the system creates another new-lower-command level and another local symbol table, and so forth. Every command level can access the symbols in the global symbol table, as well as symbols in local symbol tables at higher command levels. In other words, you can define local symbols in a command procedure that ate available to lower-level procedures. The VAX/VMS DCL Dictionary describes ~ymbol tables in detail. 2-14 Introduction to the VAX/VMS Operating System Note that the system discards local symbols and their values when a procedure exits. A command procedure can create local symbols, but the symbols are deleted when the procedure ends. However, when you define local symbols at DCL command level, these symbols remain until you explicitly remove them or until you log out. You can pass information to a higher-level command procedure by defining a global symbol to contain the information. Because there is only one global symbol table, and it is accessible at all command levels, the higher-level command procedure can test the value of the symbol. To allow abbreviations of a symbol, insert an asterisk (*)in the symbol where you want to end the acceptable abbreviation. For example, if you wanted to abbreviate the command BASIC to BAS, you could define a symbol as follows: $ BAS*IC == "BASIC/DEBUG/LIST" Once you have defined this symbol, you can type BAS (plus any remaining letters in the command) to invoke the VAX BASIC compiler with the /DEBUG and /LIST qualifiers. Note that the double equal sign in this symbol definition causes the creation of a global symbol. You can determine the definition of a symbol by typing SHOW SYMBOL, followed by the symbol name. For example: $ SHOW SYMBOL BAS BAS*IC == "BASIC/DEBUG/LIST" To delete a symbol, type DELETE/SYMBOL, followed by the symbol name. If you do not specify a symbol table qualifier, /LOCAL is the default. If the symbol is in the global table, type DELETE/SYMBOL/GLOBAL followed by the symbol name. For example, you could delete the symbol BAS*IC that you had previously defined, by typing the following: $ DELETE/SYMBOL/GLOBAL BASIC To create a logical name, you use either the DCL command DEFINE or the DCL command ASSIGN. A logical name is a name that is equated to an equivalence string, or a list of equivalence strings. For example, the following command assigns the logical name INFO to the file specification USER$$DISK:[SMITH]INFO.DAT;12: $DEFINE INFO USER$$DISK:[SMITH]INFO.DAT;12 Introduction to the VAX/VMS Operating System 2-15 You can determine the definition of a logical name by typing SHOW LOGICAL, followed by the logical name. For example: $ SHOW LOGICAL INFO "INFO"= "USER$$DISK:[SMITH]INFO.DAT;12" (LNM$PROCESS_TABLE) When you create a logical name, it is maintained in a logical name table. For more information on logical name tables, see the VAX/VMS DCL Dictionary. You can keep a file of symbols and logical names for the system to define every time you log in, thus creating a set of personal commands for special purposes. For information on login command procedures, see Section 2.6.4. 2.6.2 Creating and Executing Command Procedures To create a command procedure, you can invoke a text editor or you can use the DCL command CREATE. If you use the default file type COM, you need not include the file type when you execute the procedure. Once you have created your command procedure, you can execute it either interactively or in batch. To execute a command procedure interactively, type the at sign (@) execute procedure command followed by the name of the file. In the following example, the procedure SAMPLE.COM is executed. $ <DSAMPLE To execute a command procedure in batch, you use the DCL command SUBMIT. This command allows you to submit your procedure to a system batch job queue for execution. Once the job completes, the system prints a log file indicating the status of the job and then deletes the log file from your directory. In the following example, SAMPLE.COM is placed in the system batch job queue. A log file entitled SAMPLE.LOG will be created. $ SUBMIT SAMPLE 2-16 Introduction to the VAX/VMS Operating System 2.6.3 Sample Command Procedure The following command procedure is included to help you understand how command procedures can aid in the programming process. This command procedure incorporates many of the DCL commands discussed throughout this chapter. Any text that follows an exclamation point ( ! ) is interpreted by the DCL command interpreter as a comment and is ignored. $ !The following command procedure tests to see if the file name you $ !input exists. If it does exist, the procedure will automatically $ !compile, link, and run your source program. If the file does not $ !exist, the procedure will ask you if you want to create the file. $ !If you respond YES, the default text editor is invoked so that you $ !can create the source file . •• $ IF P1 .EQS. "" THEN INQUIRE P1 "FILE NAME" $ FILETYPE =".BAS" $ FILESPEC = P1 + FILETYPE $ IF F$SEARCH(FILESPEC) .EQS. 1111 THEN GOTO MESSAGE $ SHOW SYMBOL FILESPEC tt • ! • ! • ! $ ON ERROR THEN GOTO PRINT_ROUTINE $WRITE SYS$0UTPUT "Compiling ... " $BASIC/LIST 'P1' • ! • ! $WRITE SYS$0UTPUT "Linking ... " $ LINK 'P1' • ! • ! • WRITE SYS$0UTPUT "Running ... II $ SET NOON $ DEFINE/USER_MODE SYS$INPUT SYS$COMMAND $RUN 'P1' $ GOTO END e • • ! Introduction to the VAX/VMS Operating System 2-17 $ PRINT_ROUTINE: WRITE SYS$0UTPUT "Error in program - processing stops" $ PRINT 'P1' $ END: $ • ! $ PURGE • ! $ EXIT • ! $ MESSAGE: $ WRITE SYS$0UTPUT "Can't find requested file" $ INQUIRE ANS "Do you want the file created?" $ IF ANS .EQS. "YES" THEN GOTO EDIT_ROUTINE $ EXIT • ! $ EDIT_ROUTINE: f) $ DEFINE/USER_MODE SYS$INPUT SYS$COMMAND $ WRITE SYS$0UTPUT "Invoking editor ... " $ EDIT FILESPEC $ EXIT 0 Marks the beginning of the command procedure and prompts the user for a source file name if the user has not supplied one. If the file is not found, control is transferred to a routine called MESSAGE. 8 Marks the start of the compilation process. The procedure outputs an informational message and invokes the VAX BASIC compiler. f) Marks the start of the linking process. Again, the procedure outputs an information message and invokes the VAX/VMS Linker. 0 Marks the start of the running process. Once again, the procedure outputs an informational message and runs the program. The input device is equated to the user's terminal to allow data to be entered. 9 Identifies the actions of the command procedure in the event an error occurs during execution. When an error does occur, control is transferred to this routine. The procedure outputs an informational message and prints the LIS file. 0 Marks the routine that alerts the user that the source file has not been found. If the user chooses to create the file, control is transferred to the routine called EDIT-ROUTINE. 8 Marks the start of the edit routine. Again, the input device is equated to the user's terminal to allow data to be entered. The procedure then outputs an informational message and creates the supplied source file by invoking the user's default text editor. 2-18 Introduction to the VAX/VMS Operating System 2.6.4 login Command Procedures If you are a frequent user of the VAX/VMS system, you may find that you are typing the same long command lines on a regular basis. To avoid such repetition, you can create a special command procedure that contains these commands and statements. This special command procedure is called a LOGIN.COM file. When you log in, the system automatically searches your default device and directory for a file named LOGIN.COM. If the file exists, the system automatically executes the commands within that file. A LOGIN.COM file might appear as follows: $ !If the current process is noninteractive then exit $ IF F$MODE() .NES. "INTERACTIVE" THEN EXIT • $ '******************************************* $ !• Convenient Commands * $ '******************************************* $ ! $ PURGE == "PURGE/KEEP=2/CONFIRM 11 $ ST == "SHOW TIME" $ QUE == "SHOW QUEUE" $ M*AIL == "MAIL" $ • '******************************************* $ !* Symbols for my directories * • !******************************************* $ ! $HOME== "SET DEFAULT [SMITH)" $WORK== "SET DEFAULT [SMITH.WORKSP]" $EXAMPLES== "SET DEFAULT [SMITH.PROG_EXAMPLES]" $ $ '********************************************************** $ !• Logical names for the people I frequently send mail to * $ '********************************************************** • ! $DEFINE JEN MYVAX::BROWN $ DEFINE SUE MYV AX: : KELLY $DEFINE BOB MYVAX::CONNELL $ EXIT For more information on creating a login command file, see the Guide to Using DCL and Command Procedures on VAX/VMS. Introduction to the VAX/VMS Operating System 2-19 2.7 DCL Commands for Program Development VAX BASIC can function as both a standard compiler or as a programming evironment. When using VAX BASIC as a standard compiler, you create programs at DCL command level. This section describes the DCL commands that are used to create, compile, link and run a VAX BASIC program on a VAX/VMS system. These commands are illustrated in Figure 2-3. For a more detailed description of each command, see Chapter 4. For more information on using VAX BASIC as a programming environment, see Chapter 3. Figure 2-3: DCL Commands for Developing Programs \ COMMANDS ACTION $ EDIT AVERAGE.BAS Use the file type of BAS to indicate the file contains a VAX BASIC program $ BASIC AVERAGE The BASIC command assumes the file type of an input file is BAS AVERAGE.BAS Compile the source program AVERAGE.OBJ (AVERAGE LIS) libraries (II you use the/LIST qualifier. the compiler creates a listing file.) $ LINK AVERAGE The LINK command assumes ihe file type of an input file INPUT/OUTPUT FILES Link the object module AVERAGE.EXE (AVERAGE MAP) IS OBJ. (II you use the IMAP qualifier. the linker creates a map file.) $ RUN AVERAGE The RUN command assumes the file type of an image 1s EXE Run the executable image ZK-5167-86 2-20 Introduction to the VAX/VMS Operating System The following example shows each of the commands shown in Figure 2-3 executed in sequence. $ EDIT/EDT FIRST_PROG.BAS $ BASIC FIRST_PROG $ LINK FIRST_PROG $ RUN FIRST_PROG To create a VAX BASIC source program at DCL level, you must invoke a text editor. In the example shown above, the VAX EDT editor is invoked to create the source program FIRST_pROG.BAS. You can, however, use another editor, such as the VAX Text Processing Utility (VAXTPU) or the VAX Language-Sensitive Editor. BAS is used as the file type to indicate that you are creating a VAX BASIC source program. BAS is the conventional file type for all VAX BASIC source programs. When you compile your program with the BASIC command, you do not have to specify the file type; VAX BASIC searches for BAS by default. If your source program compiles successfully, the VAX BASIC compiler creates an object file with the file type OBJ. However, if the VAX BASIC compiler detects errors in your source program, the system displays each error on your screen and then displays the DCL prompt. You can then reinvoke your text editor to correct each error. You can include command qualifiers with the BASIC command. Command qualifiers cause the VAX BASIC compiler to perform additional actions. For instance, in the following example, the /LIST qualifier causes the VAX BASIC compiler to produce a listing file. $ BASIC/LIST FIRST_PROG For a complete list and explanation of all of the command qualifiers available with the BASIC command, see Chapter 4. Once your program has compiled successfully, you invoke the VAX/VMS Linker to create an executable image file. The VAX/VMS Linker uses the object file produced by VAX BASIC as input to produce an executable image file as output. You can specify command qualifiers with the DCL command LINK. For a complete list and explanation of all the command qualifiers available with the LINK command, see Chapter 4. Once the executable image file has been created, you run your program with the DCL command RUN. Introduction to the VAX/VMS Operating System 2-21 Chapter 3 Developing Programs in the BASIC Environment The BASIC environment has capabilities and features that make the process of program development easier for both novice and expert users. This chapter describes how to work within the BASIC environment. 3.1 Entering the Environment To enter the BASIC environment, type the DCL command BASIC and press RETURN. VAX BASIC responds with an identification line and the Ready prompt. $ BASICIRETI VAX BASIC V3.0 Ready Once you are in the BASIC environment, you interact directly with the compiler. In this mode of operation, you can enter any of the following: • • • VAX BASIC program lines Immediate mode statements Compiler commands and qualifiers When you enter program statements, VAX BASIC stores them in ascending line number sequence as part of the current program in memory. If you enter a program line with the same line number as an existing program line, the new line replaces the old one. Developing Programs in the BASIC Environment 3-1 When you create a program in the environment, the first line of the program must have a line number. If you enter a subsequent program line without a line number, you must precede it with a space or a tab. Inside the environment, only those program lines that begin with line numbers can start in the first character position on a line. NOTE To develop programs in the environment that have no line numbers at all, you must use an editor or copy your program into the environment with the OLD command. If a program line is too long for one text line, you can continue it by typing an ampersand ( & ) and pressing RETURN. (Note that only spaces and tabs are valid between the ampersand and the carriage return.) See Section 3.3 for more information about immediate mode statements and Section 3.5 for more information about VAX BASIC compiler commands. 3.2 Creating and Running Programs Inside the BASIC environment, there are two ways to type in and edit a program. You can type in and edit the program directly using line mode, or you can use the compiler command EDIT to invoke a text editor when you are in the environment. The EDIT command invokes the default text editor for your system. After entering the BASIC environment, you can type the EDIT command, create your program with a text editor, and then exit from this editor back to the environment. At this point, the program you created is the current program in memory, and you can now type RUN or RUNNH to compile, link, and execute your program. (RUNNH suppresses header information such as the name of the program and the time of day.) You also have the option of creating your program with a text editor accessed from DCL. In this case, once you have created the program, you can either enter the BASIC environment and use the OLD command to read your program into memory, or compile your program at DCL level. Chapter 4 discusses how to compile your programs at DCL level. The following example shows a simple program being entered and run in the environment. The program accepts three numbers entered at the terminal, averages them, and displays the result. 3-2 Developing Programs in the BASIC Environment Example $ BASIC VAX BASIC V3.0 Ready NEW FIRSTTRY Ready 10 PRINT "Please enter three numbers" INPUT A, B, C PRINT "Their average is"; (A+ B + C) I 3 END RUN NH Output Please enter three numbers ? 5 ? 10.3 ? 4.7 Their average is 6.66667 Ready In the preceding example, the DCL command BASIC invokes VAX BASIC and places you in the BASIC environment. The compiler command NEW informs VAX BASIC that you want to create a new program and assigns the program a name. Here the program is named FIRSTTRY.BAS. If you do not enter a program name with the NEW command, VAX BASIC assigns the name NONAME by default. BAS is the default file type. The RUNNH command compiles, links, and executes the program you create. To save this program, enter the SAVE command at the Ready prompt. You can execute multiple-unit programs while in the BASIC environment. To execute multiple-unit programs, follow these steps: 1. Compile all subprograms to generate object modules 2. Use the OLD command to read the main program into memory 3. Use the LOAD command to read the subprogram object modules into memory 4. Type the RUN command Figure 3-1 illustrates how to execute multiple-unit programs. Developing Programs in the BASIC Environment 3-3 Figure 3-1: Running Multiple-Unit Programs Source Program (Subprogram One) Object Module r------, 1--~0~LD~---i.... COMPILE BASIC OLD COMPILE Source Program (Subprogram Two) BASIC RUN ZK-5169-86 The following is an example of a program that contains multiple units: Example 10 20 30 40 REM This program calls SUBPROGRAM S81 PRINT "NOW IN MAIN PROGRAM" CALL S81 PRINT "BACK IN MAIN PROGRAM" 50 END 10 20 30 SUB S81 PRINT "NOW IN SUBPROGRAM" SUBEND To execute this program in the BASIC environment, enter the following commands. J-4 Developing Programs in the BASIC Environment OLD SB1 Ready COMPILE Ready OLD MAIN Ready LOAD SB1 Ready RUN Output NOW IN MAIN PROGRAM NOW IN SUBPROGRAM BACK IN MAIN PROGRAM Ready If a STOP statement or CTRL/C is encountered in a module other than the currently compiled module, VAX BASIC signals "Compiled procedure is currently not active". At this point, you cannot use immediate mode statements. When you run multiple-unit programs in the BASIC environment, only one module is currently compiled. Nonnally, the currently compiled program is the one you read into memory with the OLD command. However, if a source file contains more than one program module, the last one (the one closest to the end of the source file) is the currently compiled module. In the previous example, MAIN is the currently compiled module. For more information on loading multiple object modules, see Section 3.4. 3.3 Immediate Mode You do not have to write a complete program in order to use VAX BASIC. Many statements are executable in immediate mode. Immediate mode statements are BASIC statements that are executed immediately after you press the RETURN key. Immediate mode statements cannot be preceded by a line number, space, or tab and can be used only if you are working directly in the environment. Developing Programs in the BASIC Environment J-5 In the following example, VAX BASIC interprets the first line as a comment because it begins with an exclamation point ( ! ). VAX BASIC interprets the second line as part of a larger program because it begins with a line number. This line will not execute until a RUN command is specified. The third line does not begin with a line number, a space, or an exclamation point. Therefore, VAX BASIC treats the line as an immediate mode statement and immediately displays the specified text. Example !In the environment, this is a commentlRETI 10 PRINT 'This is an executable VAX BASIC statement' IRETI PRINT 'THIS IS AN IMMEDIATE MODE STATEMENT' IRETI Output THIS IS AN IMMEDIATE MODE STATEMENT Ready The Ready prompt indicates that VAX BASIC is ready to receive compiler commands, immediate mode statements, or new program lines. You can precede each executable statement with a backslash(\). You can also have more than one VAX BASIC statement on a line if you separate them with a backslash. However, programs with backslashes are often difficult to read. Example Ready A = (54.37 I 1.25 ) \ B = ( 328.15~2) \ PRINT ( B I A ) 2475.69 Unless the compiler has executed a STOP statement, VAX BASIC compiles and executes each immediate mode statement as if it were a self-contained program. Example Ready PRINT PI * 67.3 211.421 Even if the current program has executed a STOP statement, you can still perform independent calculations. However, you should understand that after a stop, any immediate mode statement referencing program variables uses the values assigned in the program. Note that you cannot create new program variables after a STOP statement has been executed. 3-6 Developing Programs in the BASIC Environment If the current program has not executed a STOP statement, each immediate mode line exists by itself, and any variables used by the statements on that line are temporary. For example: Example Ready A = 2~5 \ PRINT A 32 READY PRINT A 0 The second PRINT statement causes VAX BASIC to display a zero because the compiler treats A as a new variable, and initializes it to zero. You can use the IF, WHILE, UNTIL, UNLESS, and FOR statement modifiers in immediate mode statements. The following example shows how you can generate a table of square roots by using the immediate mode statement: Example Ready PRINT I, SQR (I) FOR I = 1 TO 10 1 2 3 4 5 6 7 8 9 10 Ready 1 1.41421 1.73205 2 2.23607 2.44949 2.64576 2.82843 3 3.16228 Certain statements are invalid in immediate mode. In general, invalid statements are statements that require the allocation of new storage, or statements that make no sense in the context of a single line. If you try to execute such a statement, VAX BASIC signals the error "Illegal in immediate mode". Developing Programs in the BASIC Environment 3-7 3.4 Debugging in Immediate Mode To debug in immediate mode, you insert STOP statements in your program at the points where you wish to examine the values of variables. When VAX BASIC encounters a STOP statement, program execution is interrupted. At this point, you can use immediate mode statements to display the values of variables or to assign them new values. After changing or examining data, you can use the CONTINUE command to resume program execution. The following restrictions apply when you are debugging in immediate mode: • • You cannot continue execution if you have changed any program code; for example, you cannot create new variables after VAX BASIC has encountered a STOP statement. Neither can you use the CONTINUE command after you have inserted a STOP statement into your program in immediate mode. In both cases, you have changed program code and you must reexecute the program with the RUN command. You can debug only one module at a time; VAX BASIC lets you examine and change variables only in the current module (the most recently compiled module) of a multiple-unit program. When you are debugging multiple program units in the environment, you should follow these guidelines: • • Use the OLD command to read in the source file for the module you want to debug. This source file becomes the current module, that is, the one available for immediate mode debugging. Use the LOAD command to read in the object files for the remaining program modules. An object module is the file that results from compiling a source file; its format is an intermediate step between a source file and an executable image. The LOAD command removes any previously loaded object modules, whether or not the command specifies any object module files. Therefore, you must use a single LOAD command to specify all the object files you need. In addition, you must separate multiple object modules with plus signs. The object files are not linked with the current program or executed until you issue the RUN command. Therefore, run-time errors in the loaded modules are not detected until you execute the program. 3-8 Developing Programs in the BASIC Environment When you want to run a program, you can load all the object modules for that program and then execute the program with the RUN command. If you want to debug a program, you use the OLD command for the module you want to debug and then load the remaining program modules. The module to be debugged can be either a main program or a subprogram because when you enter the RUN command, VAX BASIC transfers control to the main program, whether it is in object-module format or sourceprogram format. For information on using the VAX/VMS Debugger, see Chapter 5. 3.5 Compiler Commands Compiling is the process of translating a source program to an object module. An object module is an intermediate step between source code and an executable image. It contains information that the linker uses to create an image. You can compile, link, and execute your programs in the environment simply by typing the RUN command. This greatly reduces the number of steps you have to go through to develop VAX BASIC programs. When you are satisfied with a portion of code, you can simply run that program to examine whether or not it functions as expected. If you use the COMPILE command instead, you can eliminate all compile-time errors before you link and execute the program. VAX BASIC has certain defaults that are in effect each time you enter the BASIC environment. Unless you explicitly override these defaults, they remain in effect until you leave the environment. You can see a listing of these defaults by typing the SHOW command when in the environment. The following example displays the standard BASIC environment defaults that are in effect when you enter the environment: SHOW Developing Programs in the BASIC Environment 3-9 VAX BASIC V3.0 Current Environment Status 22-JUN-1986 10:12:12.05 DEFAULT DATA TYPE INFORMATION: LISTING FILE INFORMATION INCLUDES: Data type : REAL NO Source Real size : SINGLE NO Cross reference Integer size : LONG CDD Definitions Decimal size : (15,2) Environment Scale factor : 0 NO Override of Y.NOLIST NO Round decimal numbers NO Machine code Map COMPILATION QUALIFIERS IN EFFECT: INCLUDE files Object file Overflow check integers FLAGGERS: Overflow check decimal numbers NO Declining features Bounds checking NO BASIC PLUS 2 subset NO Syntax checking Lines Variant : 0 Warnings Informationals Setup Object Libraries : NONE Ready DEBUG INFORMATION: Traceback records NO Debug symbol records You can override any of these defaults with qualifiers to the COMPILE or SET commands, or with the OPTION statement in your program. The following section lists and describes all the VAX BASIC compiler commands, including qualifiers to both the COMPILE and RUN commands. For more information on the OPTION statement, see the VAX BASIC Reference Manual. 3-10 Table 3-1: VAX BASIC Compiler Commands Command Description ! comment Identifies a comment. $ command Starts a subprocess to execute the specified DCL command. APPEND Merges the specified program with the program currently in memory. ASSIGN Assigns a logical name to a complete file specification (the equivalence name). COMPILE Generates an object module (file type OBJ) from a VAX BASIC source program. CONTINUE Resumes execution after a STOP statement or a CTRL/C. DELETE Erases the specified line or lines from a VAX BASIC source program. Developing Programs in the BASIC Environment Table 3-1 (Cont.): VAX BASIC Compiler Commands Command Description EDIT Changes source text or calls a text editor. EXIT Returns to DCL command level. HELP Displays HELP text. IDENTIFY Causes VAX BASIC to print an identification header on the terminal. LIST Displays the current source program on the terminal. LISTNH Displays the current source program without header information. LOAD Loads an object module into memory. LOCK Specifies default values for compiler command qualifiers (identical to the SET command). NEW Clears memory for the creation of a new program and assigns a new program name. OLD Reads a specified VAX BASIC source program into memory. RENAME Changes the name of the program currently in memory. REPLACE Replaces a stored program with the program currently in memory. RESEQUENCE Supplies new line numbers for the program currently in memory. RUN Executes the program currently in memory, or a specified VAX BASIC source program. The program in memory can be: • A VAX BASIC source program placed in memory with the OLD command • One or more object modules placed in memory with the LOAD command • A combination of the first two RUNNH Identical to RUN but does not display header information. SAVE Creates a copy of the current source program on a specified device. SCALE Controls accumulated round-off errors for numeric operations. Developing Programs in the BASIC Environment 3-11 Table 3-1 (Cont.): VAX BASIC Compiler Commands Command Description SCRATCH Erases the current program and any loaded object modules. SEQUENCE Generates line numbers for input text. SET Specifies default values for compiler command qualifiers. SHOW Displays the current default compiler qualifiers. UNSAVE Deletes a specified file. The following sections describe these compiler commands. For more detailed information, see the VAX BASIC Reference Manual. 3. 5. 1 Entering Comments VAX BASIC allows you to enter comments into the BASIC environment by specifying an exclamation point. Any text that follows the exclamation point ( ! ) is treated as a comment. For example: $ TYPE build_special.com $ SET VERIFY $ BASIC !+ ! Set the compilation unit options by uncommenting ! the appropriate ones !- !SET LIST SET WORD SET DEBUG !+ ! Get the source module. !- OLD SPECIAL !+ ! Compile it. !- COMPILE !+ ! All done. !- EXIT 3-12 Developing Programs in the BASIC Environment 3.5.2 Entering DCL Commands You can enter a DCL command while in the environment by preceding it with a dollar sign ( $ ). VAX BASIC passes the command to the DCL for execution. The program currently in memory does not change. VAX BASIC starts a subprocess to execute the command, and the command executes in the context of that subprocess. This can sometimes produce unexpected results. For example, a$ SET DEFAULT command typed in the BASIC environment sets the default for the subprocess but not for the process in which VAX BASIC executes. The newly set default exists only until control returns to VAX BASIC. 3.5.3 The APPEND Command The APPEND command merges a VAX BASIC source program with the program currently in memory. The program in memory must be a VAX BASIC source program that has been placed in memory with the OLD command and entered in the environment. The program must also contain at least one line number. If both programs contain a line with the same number, the appended program line replaces the current program line. If you type APPEND without specifying a file name, VAX BASIC prompts with: Append file name-- You should respond with a file name. If you respond by typing the RETURN key, VAX BASIC searches for a file called NONAME with the default file type of BAS. If the compiler cannot find the file, it signals an error. The APPEND command does not change the name of the program in memory. Developing Programs in the BASIC Environment 3-13 3.5.4 The ASSIGN Command The ASSIGN command equates a logical name to a complete file specification, a device, or another logical name. If the logical name translates to a device name and will be used in place of a device name in a file specification, terminate the equivalence name with a colon. This example uses the ASSIGN command to make the system HELP library available from within VAX BASIC: Ready ASSIGN SYS$HELP:HELPLIB HLP$LIBRARY The ASSIGN command does not support search lists. To assign a logical name to a search list from within the environment, use the $ systemcommand to execute the DCL command ASSIGN with the /JOB qualifier. For example: $ASSIGN/JOB DUAO: [MR.X] ,DUAO: [MR.Y] TWO$DIRECTORIES: 3.5.5 The COMPILE Command When you compile a program in the BASIC environment, there are three levels at which you can specify options for the compiler: • • • You can accept the defaults of the BASIC environment as options You can specify options with qualifiers to the COMPILE or SET command You can specify options in the source program with the OPTION statement The COMPILE command creates an object module from a source program in memory. You can control the compilation of your program with the COMPILE command and its qualifiers. These qualifiers duplicate many of the qualifiers available to the DCL command BASIC. You can abbreviate all COMPILE qualifiers to four letters. For example, you can compile a program currently in memory and specify the creation of a listing file: COMPILE/LIST 3-14 Developing Programs in the BASIC Environment July 1988 The following two commands both specify that a listing file should be created. Note that the SET command sets a particular default until you leave the BASIC environment or until you specify a different default for that value, whereas the qualifiers to the COMPILE command set the defaults only for that particular compilation. SET/LIST COMPILE/LIST Developing Programs in the BASIC Environment 3-14. 1 If you do not specify any qualifiers with the SET command, VAX BASIC resets the defaults to the values that were in effect when you entered the BASIC environment. The qualifiers to the COMPILE command are listed below. Note that you can also use many of these qualifiers with the SET command to establish these compiler options. The qualifiers are described fully in the VAX BASIC Reference Manual. • • • • • • • The /[NO]ANSL-5TANDARD qualifier causes VAX BASIC to compile the program according to ANSI Minimal BASIC rules and to flag statements that do not conform to the ANSI Minimal BASIC standard. The default is /NOANSI_STANDARD. The /[NO]AUDIT qualifier causes VAX BASIC to include a history entry in the Common Data Dictionary (CDD) data base when a CDD definition is extracted. The default is /NOAUDIT. The /[NO]BOUNDS_CHECK qualifier causes VAX BASIC to perform range checks on array subscripts. That is, it checks that all array references are to addresses within the array boundaries. The default is /BOUNDS_CHECK=(BOUNDS, OVERFLOW). The /BYTE qualifier specifies that integers not explicitly typed with a data type keyword use 8 bits of storage, which lets you use integer values between -128 and 127. The default is /INTEGER_SIZE=LONG. The /[NO]CROSS-REFERENCE[=[NO]KEYWORDS] qualifier causes VAX BASIC to generate a cross-reference listing. If you specify KEYWORDS, VAX BASIC provides a cross-reference list of VAX BASIC keywords. If you specify /CROSS-REFERENCE, the default is /CROSS-REFERENCE=NOKEYWORDS. The default is /NOCROSS_REFERENCE. The /[NO]DEBUG qualifier provides the debugger with local symbol definitions for program variables, constants, line numbers, and labels. The default is /DEBUG=(TRACEBACK, NOSYMBOLS). The /DECIMAL _SIZE qualifier specifies the default size and precision for all DECIMAL data not explicitly assigned size and precision in the program. You specify the total number of digits (d) and the number of digits to the right of the decimal point (s). VAX BASIC signals the error "Decimal error or overflow" (ERR=l 81) when DECIMAL values are outside the range specified with this qualifier. The default is /DECIMAL_SIZE=(l5,2). Developing Programs in the BASIC Environment 3-15 • • • • • • • • • • • 3-16 The /DOUBLE qualifier specifies that floating point data use 64 bits of storage in D_float format, which lets you use floating-point values in the range 2.9 • 10- 39 to 1.7 • 10 38 and with up to 16 digits of precision. The default is /REAL_SIZE=SINGLE. The /(NO]FLAG(=((NO]BP2COMP A TIBILITY, (NO]DECLINING)] qualifier causes VAX BASIC to issue informational messages when your program includes statements that are not compatible with the functionality you specify. You can specify a flag for BASICPLUS-2, and declining VAX BASIC language features. The default is /NO FLAG. The /GFLOA T qualifier specifies that floating-point data use 64 bits of storage in G_float format, which lets you use floating-point values in the range 5.6 • 10- 308 to 9.0 • 10309 and with up to 15 digits of precision. The default is /REAL _SIZE=SINGLE. The /HFLOAT qualifier specifies that floating-point data use 128 bits of storage in H_float format, which lets you use floating-point values in the range 8.4 • 10- 4933 to 5.9 • 104933 and with up to 33 digits of precision. The default is /REAL _SIZE=SINGLE. The /(NO)LINES qualifier enables the executing program to report the line number of statements causing errors and to use the RESUME statement without specifying a line number. The default is /LINES. The /(NO)LIST qualifier creates a program listing with a default file type of LIS. The default is /NOLIST. The /LONG qualifier specifies that untyped integers use 32 bits of storage, which lets you use integer values between -2147483648 and 2147483647. The default is /INTEGER_SIZE=LONG. The /(NO]MACHINE_CODE qualifier includes the compilergenerated assembly code listing. The default is /NOMACHINE_CODE. The /(NO]OBJECT qualifier generates a linkable object module. This object module has the same file name as the VAX BASIC source program and a default file type of OBJ. The default is /OBJECT. The /(NO)OVERFLOW(=((NO]INTEGER, (NO]DECIMAL)) qualifier enables the detection of arithmetic overflow on integer or packed decimal data. If you do not supply a value, OVERFLOW affects both data types. The default is /OVERFLOW=(INTEGER,DECIMAL). The /(NO)ROUND qualifier specifies whether VAX BASIC rounds or truncates packed decimal numbers. The default is /NOROUND. Developing Programs in the BASIC Environment • • • • • • • • • The /[NO]SETUP qualifier causes VAX BASIC to optimize the executable image by omitting certain calls to the Run-Time Library at the start and end of each program unit. Note that variables are not initialized when /NOSETUP is in effect. The default is /SETUP. The /[NO]SHOW qualifier allows you to specify what VAX BASIC should include in the listing file. For a list of items you can include in the listing file, see the VAX BASIC Reference Manual. The default is /SHOW. The /SINGLE qualifier specifies that floating-point data use 32 bits of storage, which lets you use floating-point values in the range 2.9 • 10- 39 to 1.7 • 10 38 and with up to 6 digits of precision. The default is /REAL _SIZE=SINGLE. The /[NO]SYNTAX_CHECK qualifier enables line-by-line syntax checking. Because VAX BASIC automatically performs syntax checking when you compile a program, you norm.ally use /SYNTAX_CHECK with the SET command to enable line-by-line syntax checking while you are typing program lines. The default is /NOSYNTAX_CHECK. The /[NO]TRACEBACK qualifier provides line numbers for the debugger and error reporter so they can translate virtual addresses into source program module names and line numbers. The default is /TRACEBACK. The /TYPE-DEFAULT qualifier allows you to specify the default data type for all data not explicitly typed in your program. See the VAX BASIC Reference Manual for a list of data types you can include. The default is /TYPE_DEFAULT=REAL. The /V ARIANT=value qualifier provides a value to be tested in conditional compilations. The default is /VARIANT=O. The /[NO]WARNINGS[=[NO]W ARNINGS, [NO]INFORMATIONALS] qualifier tells VAX BASIC whether to display warning or informational error messages. /NOWARNINGS means that VAX BASIC does not display any informational or warning errors. The default is /WARNINGS=WARNINGS, INFORMATIONALS. The /WORD qualifier specifies that all integer data not explicitly typed use 16 bits of storage, which lets you use integer values in the range -32768 to 32767. The default is /INTEGER_SIZE=LONG. Developing Programs in the BASIC Environment 3-17 If you use these qualifiers with the COMPILE command, the BASIC environment default values remain the same, but your program is compiled using the specified defaults. When you use these qualifiers with the SET command, you set the defaults for the period you are within the BASIC environment. You can also set compiler options from inside the source program by using the OPTION statement. See the VAX BASIC Reference Manual for more information on the OPTION statement. 3.5.6 The CONTINUE Command The CONTINUE command resumes program execution after VAX BASIC encounters a STOP statement or a CTRL/C. After a STOP statement or a CTRL/C is encountered in the BASIC environment, you can enter immediate mode statements to display or change program variables. Then, type CONTINUE to resume execution with the new values. 3.5. 7 The DELETE Command The DELETE command removes a specified line or lines from the source program currently in memory. If you separate line numbers with commas, VAX BASIC deletes only the specified program lines. If you separate line numbers with a hyphen ( - ), VAX BASIC deletes the specified program lines and all program lines between them. For example: DELETE 10 Removes line 10 from the program DELETE 50, 100 Removes lines 50 and 100 from the program DELETE 50, 100-190 Removes line 50 and lines 100 through 190 from the program If you do not specify a line number, the DELETE command is ignored. 3.5.8 The EDIT Command The EDIT command replaces text in the current program with text you supply in the command. If you type EDIT with no argument, VAX BASIC invokes a text editor and reads the current program into the editor's buffer. 3-18 Developing Programs in the BASIC Environment The following are examples of editing in line mode: EDIT 100 /LEFT$ /RIGHT$/ Replaces the first occurrence of LEFT$ with RIGHT$ on line 100. EDIT Invokes the default editor and reads the current program into the editor's buffer. EDIT 2000 Lists line 2000 (line 2000 becomes the default EDIT line). EDIT 30 /LEFT$/RIGHT$/,3 Starts the search on the third text line of program line 30 and replaces the first occurrence of LEFT$ with RIGHT$. EDIT 300 /LEFT$/ /2 Removes the second occurrence of the string LEFT$ from line 300. Note that you must specify delimiters around the null replacement string. Otherwise, the EDIT command would replace the first occurrence of LEFT$ with 2. Entering EDIT with no argument causes VAX BASIC to save your program temporarily in a file called BASEDITMP .BAS. The editor is then invoked and you can edit the program in the usual manner. Exiting from the editor causes the changed program to become the new current program. VAX BASIC then displays the Ready prompt. Note that VAX BASIC deletes all versions of BASEDITMP.BAS when control returns from the editor. VAX BASIC supports the following callable text editors: • • • VAX EDT VAX Text Processing Utility (VAXTPU) VAX Language-Sensitive Editor (LSE) The default editor for VAX BASIC is EDT. In DCL, you or your system manager can override this default by defining the logical name BASIC$EDIT. To find out if a system assignment exists, enter the following DCL command: $ SHOW LOGICAL BASIC$EDIT The name you assign to BASIC$EDIT must be in the form nnn$EDIT, where the characters nnn represent the acronym for the editor. For example, you can assign LSE to be the default editor with the following command: $ ASSIGN "LSE$EDIT" BASIC$EDIT Developing Programs in the BASIC Environment 3-19 If the translation of BASIC$EDIT does not conform to nnn$EDIT, VAX BASIC creates a temporary file containing your source code and spawns a subprocess. VAX BASIC passes the translation of BASIC$EDIT to the subprocess. 3.5.9 The EXIT Command The EXIT command clears memory and returns control to DCL command level. If you modify a program and issue the EXIT command before you copy it to disk with the SAVE or REPLACE command, VAX BASIC signals "Unsaved change has been made, CTRL/Z or EXIT to exit". This message warns you that any changes will be lost if you do not save the program. You can then store the program or retype the EXIT command (or press CTRL/Z) to exit from VAX BASIC. 3.5.10 The HELP Command The HELP command lets you display the contents of the VAX BASIC HELP library on the terminal. Entering HELP causes the HELP facility to display a long list of VAX BASIC commands and language topics for which there is help available. You are then prompted to name a command or topic with the following prompt: Topic? To obtain help on the environment commands, you can type COMMANDS at the "Topic?" prompt. A list of commands is displayed on your terminal followed by the prompt "COMMANDS Subtopic?". When you type a command name in response to this prompt, the HELP facility displays the following: • • • An explanation of the command's purpose An example of its use A list of any further subtopics available You can also display help text for VAX BASIC errors. The help texts for the VAX BASIC error messages are grouped under two categories: compile-time errors and run-time errors. A run-time error refers to any error that occurs during program execution. All other errors are referred to as compile-time errors. Typing HELP RUN displays a list of the 3to 9-character error mnemonics for the VAX BASIC list of run-time 3-20 Developing Programs in the BASIC Environment errors, and typing HELP COMPILE displays a list of the 3- to 9-character compile-time error mnemonics. For example, suppose your program invokes a user-defined DEF function with a null argument. This causes VAX BASIC to signal "Actual argument must be specified". The actual error message looks like this: Y.BASIC-E-ACTARGMUS, actual argument must be specified You display the help text by typing: HELP COMPILE ACTARGMUS The following text is then displayed on your screen. ACTARGMUS ERROR - A DEF function reference contains a null argument, for example FNA(1,,2). Specify all arguments when referencing a DEF function. You can access run-time errors with either the mnemonic or the error number. You specify the error number with the letters "ERR" followed by the error number. For example, you can display the HELP text for the end-of-file error by using the mnemonic as shown: HELP RUN ENDFILDEV If you know only the error number, type: HELP RUN ERR11 VAX BASIC displays the appropriate mnemonic for that error. 3.5.11 The IDENTIFY Command The IDENTIFY command prints a header containing the VAX BASIC compiler name and version number. For example: IDENTIFY VAX BASIC V3.0 Ready Developing Programs in the BASIC Environment 3-21 3.5.12 The LIST and LISTNH Commands The LIST and LISTNH commands display a specified line or lines. If you type LIST or LISTNH without specifying line numbers, VAX BASIC displays a copy of the source program currently in memory, in ascending line number order. The LIST command prints a header displaying the program name and the current time and date before displaying the specified lines. The LISTNH command suppresses the header information and prints the specified lines only. For example: 3.5.13 LIST 10 Displays header information, then displays line 10. LISTNH 50, 100 Displays lines 50 and 100. LIST 50, 90, 100-190 Displays header information, then displays lines 50, 90, and 100 through 190. The LOAD Command The LOAD command makes an object module available for execution with the RUN command. You can load only object files created by VAX BASIC. The LOAD command accepts multiple device, directory, and file specifications. The LOAD command deletes all previously loaded object files; therefore, to load several files at the same time, you must separate the file specifications with plus signs. Multiple file specifications separated with commas cause each file to be loaded separately, thereby deleting the previously loaded file. If you do not specify any file specification, the LOAD command erases any previously loaded object files. LOAD OLD1 + OLD2 + OLD3 Ready RUN The above example loads the files OLDl.OBJ, OLD2.0BJ, and OLD3.0BJ for execution. These object files are not linked with the current program or executed until you issue the RUN command. Therefore, run-time errors in the loaded modules are not detected until you execute the program. 3-22 Developing Programs in the BASIC Environment Each device and directory specification applies to all following file specifications until you specify a new directory or device. For example: LOAD DUA1:[SMITH]PROG3+[JONES]PROG4+DUA2:PROG6 This command loads three object files: • • • PROG3 from the directory SMITH on the device DUAl: PROG4 from the directory JONES on DUAl: PROGS from the directory JONES on DUA2: 3.5.14 The LOCK Command The LOCK command changes default values for COMPILE command qualifiers. It is equivalent to the SET command. The following command specifies that all subsequent compilations use double-precision floatingpoint numbers as the default. You can use any valid COMPILE command qualifier as an argument to LOCK. LOCK /DOUBLE Ready 3.5.15 The NEW Command The NEW command clears the memory and assigns a name to a program to be entered. The following command assigns the name PROGl to the program. You can then enter program lines. NEW PROG1 If you do not specify a name, VAX BASIC issues the following prompt: New file name-- You should respond with a name. If you press the RETURN key in response to the prompt, VAX BASIC assigns the name NONAME. Developing Programs in the BASIC Environment 3-23 3.5.16 The OLD Command The OLD command brings a previously created VAX BASIC source file into memory. The following command reads PROGl.BAS into memory. OLD PROG1 If you do not specify a file name, VAX BASIC issues the prompt: Old file name-- You should respond with a file name. If you do not specify a file type, VAX BASIC reads a file with the specified file name and the default file type. If you press the RETURN key in response to the prompt, VAX BASIC searches for a file with the default file name and default file type: NONAME.BAS. 3.5.17 The RENAME Command The RENAME command assigns a new name to the program currently in memory. For example, the following command sequence brings a program named PROGl into memory and changes its name and directory: OLD [KELLY]PROG1 Ready RENAME [MCKAY.BASIC]PROG2 The name of the program is changed to PROG2. If you perform a REPLACE operation, PROG2 is copied to the subdirectory [MCKAY.BASIC] instead of [KELLY]. The remaining portion of the specification is unchanged. If you do not specify a program name, VAX BASIC renames the current program NONAME. 3-24 Developing Programs in the BASIC Environment 3.5.18 The REPLACE Command The REPLACE command writes the program in memory to a specified device. The REPLACE command always writes a copy of the current program back to disk. It replaces it using the file specification specified in the last OLD command. Part or all of this file specification can be overwritten with the RENAME command; whatever parts are not specifically changed remain the same. RENAME is similar to SAVE except that while SAVE copies the current program to the default directory, REPLACE copies the current program to the location specified in the program's current file specification. After execution of a REPLACE command, VAX BASIC issues an informational message confirming the file specification. 3.5.19 The RESEQUENCE Command The RESEQUENCE command allows you to resequence the line numbers of the program currently in memory. VAX BASIC also changes all references to the old line numbers so they reference the new line numbers. You can specify a starting line number and a value by which to increase each subsequent line number. The following command resequences the line numbers from 10 to 10000, making the first line number 100 and increasing each subsequent line number by 20: RESEQUENCE 10-10000 100 STEP 20 The RESEQUENCE command is not allowed on programs without line numbers. 3.5.20 The RUN and RUNNH Commands The RUN command executes a program. This program can be any one of the following: • • • • The current program One or more object modules placed in memory with the LOAD command A combination of the first two A specified VAX BASIC source program July 1988 Developing Programs in the BASIC Environment 3-25 If you do not supply an alternative file specification, VAX BASIC executes the program in memory. Ready OLD Old file name--PROG1 Ready RUN The RUN command compiles, links, and executes PROGL It prints a header displaying the program name and the current date and time. To execute a program without displaying this header, type RUNNH. The RUN command does not create an object module file or a list file. It uses whatever qualifiers have been set. The following qualifiers are always in effect for the RUN and RUNNH commands: • • • • • • NOCROSS NODEBUG NO LIST NO MACHINE NOOBJECT SETUP The RUN command can invoke only VAX BASIC procedures and other procedures that reside in shareable image libraries. See Chapter 22 for more information on creating shareable images. 3.5.21 The SAVE Command The SAVE command copies a VAX BASIC source program from memory to a file. You can specify a storage device, a file name, and a file type in the SAVE file-spec. For example, if you type the following program, a SAVE command causes VAX BASIC to arrange the program in ascending line number order and copy it to a file on MTAl:, in the current default directory with file name TEST and the default file type of BAS. 3-26 Developing Programs in the BASIC Environment Example 10 REM THIS IS A TEST 30 PRINT "THIS IS A TEST" SAVE MTA1:TEST.BBB VAX BASIC saves the program on magnetic tape MTAl: in the current default directory with a file name of TEST and a file type of BBB. If the program in memory has no name and you issue the SAVE command with no argument, VAX BASIC copies the program to a file named NONAME with the default file type in your current default device and directory. Note that if you perform a RENAME operation, before you issue the SAVE command followed by no argument, VAX BASIC still copies the program to the current default directory. 3.5.22 The SCALE Command The SCALE command can overcome accumulated round-off errors by multiplying double-precision floating-point values by 10 raised to the specified scale factor before storing them. 3.5.23 The SCRATCH Command The SCRATCH command clears memory by doing one of the following: • • • 3.5.24 Resetting the program name to NONAME Removing any object files previously loaded with the LOAD command Removing the source file currently in memory The SEQUENCE Command The SEQUENCE command automatically generates line numbers for input text. After a SEQUENCE command, VAX BASIC prompts with a line number and prompts again after each source line you enter. If you press CTRL/Z (either in response to the line number prompt or at the end of a program line), VAX BASIC stops prompting and you can enter source text in the normal way. If you specify a starting line number that already contains a statement, VAX BASIC signals "Attempt to sequence over existing statement" and returns to normal input mode. Note that the SEQUENCE command is not allowed on programs without line numbers. Developing Programs in the BASIC Environment 3-27 3.5.25 The SET Command The SET command specifies defaults for compiler command qualifiers. For example: SET /SINGLE Ready This command makes /SINGLE the default for the COMPILE or RUN command, thereby making SINGLE the default data type for all untyped values. Typing SET with no arguments resets the defaults to their state when you entered into the BASIC environment. For a full list of options, see the COMPILE command. 3.5.26 The SHOW Command The SHOW command displays the current default qualifiers and user libraries. SHOW VAX BASIC V3.0 Current Environment Status 22-JUN-1986 10:12:12.06 DEFAULT DATA TYPE INFORMATION: LISTING FILE INFORMATION INCLUDES: Data type : REAL Source Real size : SINGLE NO Cross reference Integer size : LONG CDD Definitions Decimal size : (16,2) Environment Scale factor : 0 NO Override of Y.NOLIST NO Round decimal numbers NO Machine code Map COMPILATION QUALIFIERS IN EFFECT: Object file Overflow check integers NO Overflow check decimal numbers Bounds checking NO Syntax checking Lines Variant : 0 NO Warnings NO Informationals Setup Object Libraries NONE Ready 3-28 Developing Programs in the BASIC Environment INCLUDE files FLAGGERS: Declining features NO BASIC PLUS 2 subset DEBUG INFORMATION: Traceback records NO Debug symbol records This DEFAULT DATA TYPE INFORMATION display gives you the following information: • • • • The default data type is REAL. The default size for floating-point numbers is SINGLE, the default size for integers is LONG, and the default size for packed decimal numbers is (15,2). There is no scale factor in effect. Packed decimal numbers are truncated rather than rounded. The LISTING FILE INFORMATION display tells you which parts of the program listing are included if you create a compilation listing: • • • • • • • • The source program is listed. No cross-reference information is listed. COD definitions are displayed as RECORD statements. The qualifiers in effect when the program was compiled are listed. This means that the program listing contains the equivalent of this SHOW command. The %NOLIST compiler directive is not overridden. No compiler-generated machine code is listed. An allocation map is listed. This contains the sizes and offsets of any variables. Files accessed with the %INCLUDE directive are listed. The COMPILATION QUALIFIERS IN EFFECT section gives you the following information: • • • • • • • • • • An object file is produced. Overflow checking for integers is enabled. Overflow checking for packed decimal numbers is disabled. Bounds checking is enabled. Line-by-line syntax checking is disabled. Line number information is included in the object file. The VARIANT value is zero. No warning or informational error messages are displayed. VAX BASIC performs normal initialization calls at run time (SETUP). No user-supplied object module libraries are searched. Developing Programs in the BASIC Environment 3-29 The FLAGGERS section gives you the following information: • • Declining features are reported. BP2 compatibility issues are not reported. The DEBUG INFORMATION section gives you the following information: • • Traceback information is included in the object module. No debug records are included in the object module. This means you cannot access program symbols with the VAX/VMS Debugger. See Chapter 22 for more information about user libraries. 3.5.27 The UNSAVE Command The UNSAVE command deletes the specified version of a file from disk. If you do not specify a file, UNSAVE deletes the disk file associated with the program currently in memory. If you do not specify a version number, UNSAVE deletes the newest version. For example: OLD PROG1 Ready UNSAVE Ready The OLD command copies a program named PROGl.BAS from disk to memory. The UNSAVE command deletes the program from disk. You can delete a VAX BASIC source program other than the one in memory by specifying the program name. The following command deletes the most recent version of the file PROG2.BAS. UNSAVE PROG2 To delete a file other than a source program, specify the file name and file type. The following command deletes the newest version of the object module generated from the compilation of PROG2. UNSAVE PROG2.0BJ 3-30 Developing Programs in the BASIC Environment Chapter 4 Developing VAX BASIC Programs at DCL Command Level The process of developing a VAX BASIC program involves four steps: creating, compiling, linking, and running. You accomplish each of these steps using DCL commands. This chapter describes how to create, compile, link, and run a VAX BASIC program. 4.1 Creating a VAX BASIC Program To create and modify a VAX BASIC program, you must invoke a text editor. VAX/VMS provides you with two text editors: VAX EDT (EDT) and the VAX Text Processing Utility (VAXTPU). You may also have other editors that are supported on your system, such as the VAX LanguageSensitive Editor (LSE). The following sections describe briefly how to use both VAX EDT and VAXTPU. 4.1.1 Using VAX EDT EDT is an interactive general-purpose text editor that offers three editing modes: keypad, nokeypad, and line. Both keypad and nokeypad modes are screen editors. Keypad mode uses the numeric keypad that appears to the right of your main keyboard. With nokeypad mode, you enter commands on a command line, which EDT processes when you press RETURN. Line mode focuses on the line as the basic unit of text. The appearance of a line mode asterisk prompt ( *) indicates that you can enter a line mode command. When you begin your editing session, editing in Developing VAX BASIC Programs at DCL Command Level 4-1 line mode is the default. Unlike line mode, keypad mode and nokeypad mode continuously display the contents of the file on your screen. The following command line invokes the EDT editor and creates the file, PROG_l.BAS. $ EDIT/EDT PROG_1.BAS To change from line mode to keypad mode, enter the CHANGE command at the asterisk prompt. To return to line mode from keypad mode, press CTRL/Z. To change from line mode to nokeypad mode, enter the SET NOKEYP AD command and then enter the CHANGE command. If you are in the middle of an editing session and your system fails, you can recover your edits by reentering the EDIT command followed by the /RECOVER qualifier. EDT recreates your last editing session on your screen up to the point where it was interrupted. It uses the contents of a journal file that is maintained during the editing session. EDT provides an online HELP facility that you can access during an editing session. In line mode, you can enter the HELP command. EDT displays general information on EDT as well as detailed information on both line mode editing and nokeypad mode editing. In keypad mode, you can press the HELP key or the PF2 key. EDT displays a keypad diagram on your terminal screen, and a list of keypad editing keys. For help on a specific keypad function, press the key you want help on. For details on how to use the EDT editor, see the VAX EDT Reference Manual. 4.1.2 Using VAXTPU The VAX Text Processing Utility (VAXTPU) is a high-performance, programmable editor. With VAXTPU, you can use one of two editing interfaces to edit your VAX BASIC programs: the Extensible VAX Editor (EVE) and the VAXTPU EDT Keypad Emulator. You can also create your own interfaces. The following sections briefly describe how to use the EVE interface and the EDT Keypad Emulator interface. 4-2 Developing VAX BASIC Programs at DCL Command Level 4.1.2. 1 The EVE Interface The EVE editor is efficient and easy to use. You can execute common editing functions by using the EVE keypad, or execute more advanced functions by entering commands on the EVE command line. The following command line invokes the EVE editor and creates the file, PROG_l.BAS. $ EDIT/TPU PROG_1.BAS You can define a global symbol for the EDIT /TPU command by placing a symbol definition in your LOGIN.COM file. For more information on defining global symbols, see Chapter 2. Like EDT, VAXTPU provides you with an online HELP facility that you can access during your editing session. It also provides you with a journal facility. Unlike EDT, VAXTPU provides you with multiple windows. This feature allows you to view two files on your screen at the same time. VAXTPU also provides you with other advanced features. For more information on using the features of EVE, see the User's Guide to EVE. 4. 1.2.2 The EDT Keypad Emulator Interface The EDT Keypad Emulator interface provides all of the functions associated with EDT and uses the same keys to perform each function. To access the EDT Keypad Emulator, enter the following command line: $ EDIT/TPU/SECTION=EDTSECINI.GBL To minimize the number of characters you must enter each time you invoke the EDT Keypad Emulator, you can define a global symbol for the command line and place it in your LOGIN.COM file. See Chapter 2 for more information on defining global symbols. For details on how to use the EDT Keypad Emulator, see the VAXTPU EDT Keypad Emulator Quick Reference Guide. Developing VAX BASIC Programs at DCL Command Level 4-3 4.2 Compiling a VAX BASIC Program The primary functions of the VAX BASIC compiler are to • • • • Detect errors in your source program Generate any appropriate error messages Generate machine language instructions from the source statements Group these language instructions into an object module for the linker To invoke the VAX BASIC compiler, you use the DCL command BASIC. With the BASIC command, you can specify command qualifiers. The next two sections discuss in detail the BASIC command as well as all of the command qualifiers available with the command. 4.2.1 The BASIC Command When you compile your source program, use the BASIC command, which has the form BASIC [/qualifier ... ] [file-spec [/qualifier ... ]], ... /qualifier The name of a qualifier that indicates a specific action to be performed by the compiler on all files or specific files listed. When a qualifier appears directly after the BASIC command, it affects all files listed. file-spec Indicates the name of the input source file that contains the program or module to be compiled. You are not required to specify a file extension; the VAX BASIC compiler assumes the file to be of the default file type, BAS. If you enter the BASIC command with no parameters, you will enter the BASIC environment. For more information on the BASIC environment, see Chapter 3. Most of the command qualifiers to the BASIC command affect all files specified in the command line, no matter where the qualifiers are placed; these are called global qualifiers. However, the qualifiers /LISTING, /OBJECT, and /DIAGNOSTICS are positional qualifiers; that is, depending 4-4 Developing VAX BASIC Programs at DCL Command Level on their position in the command line, they can affect all or only some of the specified files. The rules for positional qualifiers are as follows: • • • • If the positional qualifier is located directly following the command name, it affects all the specified files. If the file specifications are separated by commas, then any positional qualifier directly following a file specification affects only that file. If the file specifications are separated by plus signs, then any positional qualifier directly following a list of file specifications affects only the resulting appended file. The rightmost qualifier overrides any conflicting qualifier previously specified in the command line. The placement of these positional qualifiers causes VAX BASIC to produce or not produce listing files, object files, and diagnostics files. For example: $ BASIC/LIST/OBJ PROG1/NOOBJ/DIAG,PROG2+PROG3/NOLIST This command does the following: • • • • • • Compiles PROGl and produces a listing file called PROGl.LIS Produces no object file for PROGl Produces a diagnostics file for PROGl called PROGl.DIA Appends PROG2 and PROG3 for compilation, producing a temporary source file called PROG2 Compiles the new PROG2 and produces an object file called PROG2.0BJ Produces no listing file for the new PROG2 Because VAX BASIC appends source files that are separated by plus signs, you should make sure that these files contain line numbers. VAX BASIC does not allow you to append programs without line numbers. You must also make sure that these files do not contain duplicate line numbers. If there are duplicate line numbers, VAX BASIC replaces the first instance of that numbered line with the second. You should be careful when using positional qualifiers inside a list of files separated with plus signs, because a positional qualifier specified for a single file affects all the files in that list. In the following example, the /NOOBJ positional qualifier appears to apply only to PROG2. However, since VAX BASIC appends PROGl, PROG2, and PROG3 to form one file Developing VAX BASIC Programs at DCL Command Level 4-5 called PROGl, the /NOOBJ qualifier applies to the new PROGl and VAX BASIC does not produce an object module. BASIC PROG1+PROG2/NOOBJ+PROG3 4.2.2 BASIC Command Qualifiers The following list represents all of the command qualifiers and their defaults available with the DCL command BASIC. The SINGLE, DOUBLE, WORD, and LONG qualifiers are supported for compatibility with older versions of VAX BASIC. However, DIGITAL recommends that you use the /TYPE_DEFAULT, /INTEGER_SIZE, /REAL-SIZE, and /DECIMAL _SIZE qualifiers to set the default data type and size. A description of each qualifier follows the list. Command Qualifier /[NO]ANAL YSIS_DA TA [ = file-spec ] /[NO]ANSl _STANDARD /[NO]AUDIT [ = text-entry ] /[NO]CHECK [ = (check-clause, ... ) ] /[NO]CROSS_REF [ = [NO]KEYWORDS ] /[NO]DEBUG [=(debug-clause, ... ) ] /DECIMAL_SIZE = (d,s) /[NO]DEPENDENCY_DAT A /[NO]DIAGNOSTICS [ = file-spec] /DOUBLE /[NO]FLAG [ = (flag-clause, ... ) ] /INTEGER_SIZE = data-type /[NO]LINES /[NO]LISTING [=file-spec ] /LONG /[NO]MACHINE_CODE /[NO]OBJECT [ = file-spec ] /[NO]OLD_VERSION=CDD_ARRA YS /REAL _SIZE = data-type /[NO]ROUND_DECIMAL 4-6 Developing VAX BASIC Programs at DCL Command Level Default /NO ANAL YSIS_DA TA /NOANSl_ST ANDARD /NO AUDIT /CHECK=(BOUNDS,OVERFLOW) /NOCROSS_REF /DEBUG=(TRACEBACK,NOSYMBOLS) /DECIMAL _SIZE=( 15 ,2) /NODEPENDENCY_DATA /NODIAGNOSTICS /FLAG = (NODECLINING, NOBP2COMPA TIBILITY) /INTEGER_SIZE = LONG /LINES /NOLISTING (from terminal) /LISTING (batch) /NOMACHINE_CODE /OBJECT /NOOLD_ VERSION /REAL_SIZE = SINGLE /NOROUND_DECIMAL July 1988 /SINGLE /[NO]SYNT AX _CHECK /TYPE_DEFAUL T =default-clause /VARIANT = int-const /[NO]WARNINGS [ = (warn-clause, ... ) ] /NOSYNT AX_CHECK /TYPE_DEFAULT =REAL /VARIANT= 0 /WARNINGS = (INFORMA TIONALS, WARNINGS) /WORD /[NO]ANSLSTANDARD The/ ANSI_STANDARD qualifier causes VAX BASIC to allow only statements valid for ANSI Minimal BASIC and to compile programs according to the ANSI Minimal BASIC rules. The /NOANSI_STANDARD qualifier causes VAX BASIC to allow extensions and implementation-defined features. The default is /NOANSI_STANDARD. See the VAX BASIC Reference Manual for more information about ANSI standard BASIC. /[NO]AUDIT= { str-lit } file-spec The /AUDIT qualifier causes VAX BASIC to include a history entry in the COD when extracting a COD definition. You can specify either a string literal or a file specification with the /AUDIT qualifier. If you specify a string literal, VAX BASIC includes it as part of the history entry. If you specify a file specification, VAX BASIC includes up to the first 64 lines of the specified file. When you specify/ AUDIT, VAX BASIC also includes the following information about the COD record extraction in the history entry: • • • • • The name of the program module making the extraction The time and date of the extraction A note that access was made by way of a VAX BASIC program A note that the access was an extraction The usemame and UIC of the process accessing the COD The /NOAUDIT qualifier causes VAX BASIC not to include a history entry in the COD when extracting a COD definition. The default is /NOAUDIT. Developing VAX BASIC Programs at DCL Command Level 4-7 [NO]BOUNDS /[NOJCHECK = [NO]OVERFLOW [=(INTEGER, DECIMAL)] } { ALL NONE The /CHECK qualifier causes VAX BASIC to test for arithmetic overflow and for array references outside array boundaries when the program executes. Specifying /CHECK=NOBOUNDS means that your program is smaller and runs faster. However, no error is signaled for an array reference outside the bounds of an array. This means that the program may get a memory management or access violation error at run time. Therefore, this option should be used only for programs that have been thoroughly debugged and whose execution time is critical. If you specify /CHECK=OVERFLOW, overflow checking is enabled for both integers and packed decimal numbers. Similarly, specifying /CHECK=NOOVERFLOW disables overflow checking for both types of numbers. The /NOCHECK qualifier causes VAX BASIC to not test for arithmetic overflow and for array references outside array boundaries when the program executes. /CHECK = ALL is the same as /CHECK = (BOUNDS, OVERFLOW). /CHECK = NONE is the same as /NOCHECK. The default is /CHECK= (BOUNDS, OVERFLOW). /[NO]CROSS_REFERENCE [= [NO]KEYWORDS} The /CROSS-REFERENCE qualifier causes VAX BASIC to generate a cross-reference listing. The cross-reference list shows program symbols, their class, and the program lines in which they are referenced. /CROSS_ REFERENCE=KEYWORDS specifies that the cross-reference listing includes all references to VAX BASIC keywords. If you specify /CROSS_ REFERENCE alone, the default is NOKEYWORDS. See Chapter 18 for more information on cross-reference listings. The /NOCROSS_REFERENCE qualifier specifies that no cross-reference listing be produced. The default is /NOCROSS-REFERENCE. [NO]SYMBOLS /[NO]DEBUG = [NO]TRACEBACK } { ALL NONE The /DEBUG qualifier causes VAX BASIC to provide information for the VAX/VMS Debugger and the system run-time error traceback mechanism. 4-8 Developing VAX BASIC Programs at OCL Command Level The default is /NOCROSS-REFERENCE. [NO]SYMBOLS } [NO]TRACEBACK { ALL NONE The /DEBUG qualifier causes VAX BASIC to provide information for the VAX/VMS Debugger and the system run-time error traceback mechanism. Neither TRACEBACK nor SYMBOLS affects a program's executable code. For more information on debugging, see Chapter 5. /[NO]DEBUG = The /NODEBUG qualifier causes VAX BASIC to suppress information for the VAX/VMS Debugger and the system run-time error traceback mechanism. /DEBUG = ALL is the same as /DEBUG = (TRACEBACK, SYMBOLS). /DEBUG =NONE is the same as /NODEBUG. The default is /DEBUG = (TRACEBACK, NOSYMBOLS). =( /DECIMAL_S/ZE d,s) The /DECIMAL _SIZE qualifier lets you specify the default size for packed decimal data. You specify the total number of digits in the number and the number of digits to the right of the decimal point. /DECIMAL-SIZE = (15,2) is the default. This default decimal size applies to all decimal variables for which the total number of digits and digits to the right of the decimal point are not explicitly declared. See the VAX BASIC Reference Manual for more information about packed decimal numbers. /[NO]DEPENDENCY_DATA If you have CDD /Plus Version 4.0 installed on your system, and if your current CDD$DEFAULT is a COO-format dictionary, the /DEPENDENCY_DATA qualifier generates a compiled module entity in the CDD$DEFAULT for each compilation unit. You must specify this qualifier if you want %INCLUDE %FROM %CDD and %REPORT %DEPENDENCY directives to establish dependency relationships. /NODEPENDENCY_DATA is the default. No compiled module entity is generated in this case. July 1988 Developing VAX BASIC Programs at OCL Command Level 4-9 = /[NO]DIAGNOSTICS [ file-spec] If you have the VAX Language-Sensitive Editor (LSE) installed on your system, you can use the /DIAGNOSTICS qualifier to create a diagnostics file containing compiler messages and diagnostic information. The diagnostics file is used by LSE to display diagnostic error messages and to position the cursor on the line and column where a source error exists. If you do not supply a file specification with the /DIAG qualifier, the diagnostics file has the same name as its corresponding source file and a file type of DIA. All other file specification attributes depend on the placement of the qualifier in the command. See the VAX/VMS documentation set for more information. The /NODIAGNOSTICS qualifier specifies that no diagnostics file will be created. The default is /NODIAGNOSTICS. [NO]BP2COMPA TIBILITY } [NO]DECLINING { ALL NONE The /FLAG qualifier lets you specify whether VAX BASIC warns you about declining features and compatibility with PDP-11 BASIC-PLUS-2. /[NO]FLAG = The /NOFLAG qualifier causes VAX BASIC to not warn you about declining features and compatibility with PDP-11 BASIC-PLUS-2. /FLAG = ALL is the same as /FLAG= (BP2COMPATIBILITY, DECLINING). /FLAG = NONE is the same as /NOFLAG. The default is /FLAG = (NODECLINING, NOBP2COMP ATIBILITY). BYTE } WORD LONG The /INTEGER_SIZE qualifier lets you specify the default size for integer data. /INTEGER_S/ZE = { The default is INTEGER-SIZE = LONG. The default integer size applies to all integer variables whose data type is not explicitly declared. See the VAX BASIC Reference Manual for more information about integer data types. /[NO]LINES The /LINES qualifier makes line number information available for the ERL function, the RESUME statement (with no target) and the VAX BASIC error reporter. If your program contains a RESUME statement with no 4-10 Developing VAX BASIC Programs at DCL Command Level target, or a reference to the error-handling function ERL, the compiler overrides NOLINES and signals "ERL overrides NOLINE" or "RESUME overrides NOLINE". Note that the VAX BASIC error reporting facility is separate from that of system traceback. The /NOLINES qualifier causes line number information to be unavailable for the ERL function, the RESUME statement (with no target) and the VAX BASIC error reporter. Specifying /NOLINES makes your program run faster and reduces program size (this eliminates five bytes of code and four bytes of data for each program line number). However, specifying /NOLINES causes the following restrictions to be in effect: • • You cannot use RESUME without a line number You cannot use the ERL function Developing VAX BASIC Programs at DCL Command Level 4-10.1 Therefore, this option should be used only for programs that have been thoroughly debugged and whose execution time is critical. The default is /LINES. /[NO]LIST/NG The /LISTING qualifier causes VAX BASIC to produce a source listing file. To produce a listing file with an explicit file specification, you must use the /LISTING qualifier in the form /LISTING= file-spec. Otherwise, the listing file has the same name as its corresponding source file and a file type of LIS. All other file specification attributes depend on the placement of the qualifier in the command. See the VAX/VMS DCL Concepts Manual for more information. Note that the /LISTING qualifier only controls whether or not VAX BASIC produces a listing file. The /SHOW qualifier controls which parts of the listing are produced. The /NOLISTING qualifier specifies that no source listing file be produced. At a terminat the default is /NOLISTING. In batch mode, the default is /LISTING. /[NO]MACH/NE_CODE The /MACHINE_CODE qualifier specifies that the listing file includes the compiler-generated object code. If /LISTING is not specified, /MACHINE_CODE causes VAX BASIC to produce a listing file containing only the compiler-generated object code. The /NOMACHINE_CODE qualifier specifies that the listing file not include compiler-generated object code. The default is /NOMACHINE_CODE. /[NO]OBJECT The /OBJECT qualifier causes VAX BASIC to produce an object module, and optionally specifies its file name. By default, VAX BASIC generates object files as follows: • • • If you specify one source file, VAX BASIC generates one object file. If you specify multiple source files separated by plus signs, VAX BASIC appends the files and generates one object file. If you specify multiple source files separated by commas, VAX BASIC compiles and generates a separate object file for each source file. Developing VAX BASIC Programs at OCL Command Level 4-11 • You can use both plus signs and commas in the same command line to produce different combinations of appended and separated object files. To produce an object file with an explicit file specification, you must use the /OBJECT qualifier in the form /OBJECT = file-spec. Otherwise, the object file has the same name as its corresponding source file and a file type of OBJ. All other file specification attributes depend on the placement of the qualifier in the command. See the VAX/VMS DCL Concepts Manual for more information. The /NOOBJECT qualifier suppresses the creation of an object file. During the early stages of program development, you may find it helpful to suppress the production of object files until your source program compiles without errors. The default is /OBJECT. /[NO]OLD_ VERSION=CDD_ARRA YS The /OLD_VERSION=CDD_ARRAYS qualifier is provided for compatibility with previous versions of BASIC. When you use the /OLD_ VERSION=CDD_ARRAYS qualifier, VAX BASIC changes the lower bound to zero and adjusts the upper bound of the array. For example, Array 2:5 in the CDD is translated by VAX BASIC to be an array with a lower bound of 0 and an upper bound of 3. VAX BASIC issues an informational message to confirm the array bounds. The /NOOLD_VERSION=CDD_ARRAYS qualifier causes VAX BASIC to extract an array from the Common Data Dictionary (CDD) with the bounds as specified in the data definition. For example, Array 2:5 in the CDD is translated by VAX BASIC to be an array with a lower bound of 2 and an upper bound of 5. The CDD assumes a default lower bound of 1, if none is specified. Therefore, if no lower bound is specified, VAX BASIC translates the CDD array to have a lower bound of 1. For example, Array 5 in the CDD is translated by VAX BASIC to be an array with a lower bound of 1 and an upper bound of 5. The default is /NOOLD_VERSION=CDD_ARRAYS. SINGLE } /REAL SIZE= DOUBLE { GFLOAT HFLOAT The /REAL _SIZE qualifier lets you specify the default size for floatingpoint data. 4- 12 Developing VAX BASIC Programs at DCL Command Level The default is /REAL _SIZE = SINGLE. The default floating-point size applies to all floating-point variables whose size is not explicitly declared. See the VAX BASIC Reference Manual for more information on floatingpoint data types. /[NO]ROUND_DECIMAL The /ROUND qualifier specifies that VAX BASIC is to round packed decimal numbers rather than truncate them. The /NOROUND qualifier causes VAX BASIC to truncate packed decimal numbers rather than round them. The default is /NOROUND. /SCALE= n The /SCALE qualifier specifies a scale factor between zero and six, inclusive. The scale factor affects only double-precision numbers. SCALE helps to control accumulated round-off errors by multiplying floating-point values by 10 raised to the scale factor before storing them in variables. /SCALE is ignored for all but double-precision floating-point numbers. /SCALE is provided for compatibility with existing programs and with other implementations of VAX BASIC. DIGITAL recommends that you do not use this feature for new program development. Accumulated roundoff errors can be better controlled with packed decimal numbers. See the VAX BASIC Reference Manual for more information on packed decimal numbers. The default is /SCALE = 0. [NO]CDD_DEFINITIONS [NO]ENVIRONMENT [NO]/NCLUDE /[NO]SHOW= [NO]MAP [NO]OVERRIDE ALL NONE The /SHOW qualifier determines which parts of the compilation listing are created. The /LISTING qualifier must be in effect for /SHOW to have any effect. The CDD_DEFINITIONS clause controls whether the translation of a CDD record is displayed in the listing. The ENVIRONMENT clause lets you display all defaults that were in effect when the program was compiled. This is the compilation listing equivalent of the SHOW command in the environment. The INCLUDE clause controls whether files accessed with the %INCLUDE directive are displayed in the listing. Developing VAX BASIC Programs at DCL Command Level 4-13 The MAP clause determines whether the listing contains an allocation map. The allocation map lists all program variables, their size and their data type. The OVERRIDE clause helps you debug code by disabling the effect of the %NOLIST directive. The /NOSHOW qualifier causes VAX BASIC to only display the source listing. /SHOW = ALL is the same as /SHOW = (CDD_DEFINITIONS, ENVIRONMENT, INCLUDE, MAP, OVERRIDE). /SHOW= NONE is the same as /NOSHOW. The default is /SHOW = (CDD_DEFINITIONS, ENVIRONMENT, INCLUDE, MAP, NOOVERRIDE). /{NO]SYNTAX_CHECK The /SYNTAX_CHECK qualifier causes VAX BASIC to perform lineby-line syntax checking. When syntax checking is enabled, VAX BASIC immediately checks the syntax of every text line as soon as you type a carriage return. When syntax checking is disabled, VAX BASIC does not perform syntax checking until you COMPILE or RUN the program. The /NOSYNTAX_CHECK qualifier causes VAX BASIC to suppress line-by-line syntax checking. The default is /NOSYNTAX_CHECK. _ /TYPE_DEFAUL T - { INTEGER } REAL DECIMAL EXPLICIT The /TYPE_DEFAULT qualifier lets you specify the default data type for numeric variables. Specifying EXPLICIT means that all program variables must be explicitly declared in DECLARE, EXTERNAL, COMMON, MAP or DIM statements. Specifying INTEGER, REAL, or DECIMAL means only that variables and data which are not explicitly declared default to integer, real or packed decimal. To specify the actual size of variables and data, use the INTEGER_SIZE, REAL_SIZE and DECIMAL_SIZE qualifiers. The default is /TYPE-DEFAULT= REAL. /VAR/ANT= int-const The /VARIANT qualifier lets you specify the value associated with the lexical function %VARIANT. See Chapter 18 in this manual for more information about VARIANT and the %VARIANT lexical function. 4-14 Developing VAX BASIC Programs at OCL Command level If /VARIANT is not specified, the default value is 0. If /VARIANT is specified without a value, the default is 1. [NO]WARNINGS /[NO]WARNINGS = [NO]INFORMA TIONALS } { ALL NONE The /WARNINGS qualifier lets you specify whether VAX BASIC displays informational and warning error messages. Specifying /WARNINGS=NOWARNINGS causes VAX BASIC to display informational errors but not warning errors. Specifying /WARNINGS=NOINFORMATIONALS causes VAX BASIC to display warning errors but not informational errors. The /NOWARNINGS qualifier causes VAX BASIC to suppress any informational or warning errors. /WARNINGS = ALL is the same as /WARNINGS= (INFORMATIONAL, WARNINGS). /WARNINGS = NONE is the same as /NOWARNINGS. The default is /WARNINGS= (INFORMATIONAL, WARNINGS). 4.2.3 Compiler Listings A compiler listing provides information that can help you debug your VAX BASIC program. To generate a listing file, specify the /LISTING qualifier when you compile your VAX BASIC program interactively. For example: $ BASIC/LISTING prog-name If the program is compiled as a batch job, the listing file is created by default; specify the /NOLISTING qualifier to suppress creation of the listing file. By default, the name of the listing file is the name of the source program followed by a file type of LIS. You can include a file specification with the /LISTING qualifier to override this default. A compiler listing generated by the /LISTING qualifier has the following major sections: • Source Program Listing The source program section contains the source code and line numbers generated by the compiler. Developing VAX BASIC Programs at OCL Command Level 4-15 • Allocation Map • The allocation map section contains summary information on program sections, variables, and arrays. Qualifier Summary The qualifier summary section lists the qualifiers used with the BASIC command and the compilation statistics. Example 4-1 illustrates a compiler listing generated by the following command: $ BASIC/LIST/CROSS_REFERENCE/MACHINE_CODE lister Sections that follow the example describe each major section of the listing file. The numbered explanations in each section correspond to the callouts in the example. 4-16 Developing VAX BASIC Programs at DCL Command Level Example 4-1: VAX BASIC Compiler Listing 0 • 8 LISTER$MAIN Listing Tester 19-MAY-1986 11:27:36 VAX BASIC V3.0 V1.5 Test 19-MAY-1986 11:10:56 MY$$DISK:[SMITH]LISTER.BAS;2 f) 10 1 0 G %INCLUDE "MAPS. DEF" I1 ! MAPS definition file 10 I1 11 I1 I1 STRING A = 16, LONG B, DOUBLE C, BYTE D DECLARE INTEGER INDEX DECLARE LONG CONSTANT TRUE = -1 DECLARE SINGLE Q(6) MAP (SHARED) I1 14 15 16 17 18 19 20 21 1 !This program only shows the format of a listing !file. It does no useful work. 9 12 13 Page 0 Y.TITLE "Listing Tester" Y.SBTTL "Test" Y.IDENT "Vi. 5" 2 3 4 5 6 7 0 & & & Y.IF Y.VARIANT = 2 Y.THEN DECLARE DOUBLE Z(10) Y.END Y.!F 0 F1 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 First_loop: FOR INDEX = 0 TO 6 PRINT Q(INDEX) NEXT INDEX Second_loop: WHILE TRUE INDEX = INDEX + 1 EXIT Second_loop IF INDEX => 6 NEXT 32767 END (Continued on next page) Developing VAX BASIC Programs at OCL Command Level 4-17 Example 4-1 (Cont.): LISTER$MAIN Listing Tester Cross Reference VAX BASIC Compiler Listing 19-MAY-1986 11:27:36 VAX BASIC V3.0 Page 2 19-MAY-1986 11:10:56 MY$$DISK: [SMITH]LISTER.BAS;2 G> User Identifier Cross Reference Datatype Symbol Name Type +--------------------------------------------------+ ! # Defining reference G Destructive reference P Parameter reference R Redefining reference ! +--------------------------------------------------+ A STR=16 MAP SHARED + 0 LONG MAP SHARED + 16 DOUBLE MAP SHARED + 20 BYTE MAP SHARED + 28 10 # B 11 # c 12 # D 13 # INDEX 14 # 25 QO LONG 26 27 31 G 32 SINGLE 16 # 26 15 # 30 LONG TRUE CONSTANT (Continued on next page) 4-18 Developing VAX BASIC Programs at OCL Command Level Example 4-1 (Cont.): LISTER$MAIN Cross Reference • VAX BASIC Compiler Listing Listing Tester 19-MAY-1986 11:27:36 VAX BASIC V3.0 Page 3 Map 19-MAY-1986 11:10:66 MY$$DISK:[SMITH]LISTER.BAS;2 Map Cross Reference Reterences Symbol MAP SHARED 10 # A STR=16 MAP SHARED + 0 LONG MAP SHARED + 16 DOUBLE MAP SHARED + 20 BYTE MAP SHARED + 28 10 ' B 11 ' c 12 # D • 13 # Label Cross Reference References Symbol FIRST_LOOP 24 # SECOND_LOOP LISTER$MAIN 29 ' Listing Tester ALLOCATION MAP 32 19-MAY-1986 11:27:36 VAX BASIC V3.0 Page 4 19-MAY-1986 11:10:66 MY$$DISK:[SMITH]LISTER.BAS;2 ti) Allocation information for MAP SHARED Name Offset A 0 16 20 28 B c D Size Type 16 Static string Long Double Byte 4 8 1 (Continued on next page) Developing VAX BASIC Programs at OCL Command Level 4-19 Example 4-1 (Cont.): VAX BASIC Compiler Listing 41) Named constants Name Type Value TRUE Long -1 e Allocation information for main program LISTER Off set based on (R11) Offset Size Type INDEX 111 4 Q 87 24 Long Single Name Dimensions : ( 0 TO 5 ) ~ PROGRAM SECTIONS Name 0 $PDATA 1 $CODE 2 $ARRAY 3 $DESC 4 SHARED Bytes Attributes 112 164 0 0 29 PIC CON REL LCL SHR NOEXE PIC CON REL LCL SHR EXE PIC CON REL LCL NOSHR NOEXE PIC CON REL LCL NOSHR NOEXE PIC OVR REL GBL SHR NOEXE RD NOWRT LONG RD NOWRT LONG RD WRT LONG RD WRT LONG RD WRT LONG 48 EXTERNAL REFERENCES OTS$LINKAGE BAS$PRINT BAS$LINKAGE BAS$IO_END BAS$INIT_R8 BAS$0UT_F_V_B BAS$END_R8 (Continued on next page) 4-20 Developing VAX BASIC Programs at DCL Command Level Example 4-1 LISTER$MAIN G> (Cont.): Listing Tester Qualifier summary VAX BASIC Compiler Listing 19-MAY-1986 11:27:36 VAX BASIC V3.0 Page 6 19-MAY-1986 11:10:66 MY$$DISK: [SMITH]LISTER.BAS;2 DEFAULT DATA TYPE INFORMATION: Data type : REAL Real size : SINGLE Integer size LONG Decimal size : (16,2) Scale factor : 0 NO Round decimal numbers COMPILATION QUALIFIERS IN EFFECT: Object file Overflow check integers Overflow check decimal numbers Bounds checking NO Syntax checking Line Variant : 0 Warnings Informationals Setup Object Libraries : NONE LISTER$MAIN Listing Tester ~ Generated code LISTING FILE INFORMATION INCLUDES: List Cross reference CDD Definitions Environment NO Override of Y.NOLIST Machine code Map INCLUDE files FLAGGERS: NO Declining features NO BASIC PLUS 2 subset DEBUG INFORMATION: Traceback records NO Debug symbol records 19-MAY-1986 11:27:36 VAX BASIC V3.0 Page 6 19-MAY-1986 11:10:66 MY$$DISK:[SMITH]LISTER.BAS;2 0000: 0000: 0000: 0000006F 0000: 0000005C 0004: 1C000103 0008: .TITLE .!DENT .PSECT .LONG .LONG .LONG LISTER$MAIN V1.6 $PDATA 96 92 469762307 (Continued on next page) Developing VAX BASIC Programs at DCL Command Level 4-21 Example 4-1 (Cont.): VAX BASIC Compiler Listing 00000058 00000000 00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000018 00000000 00000000 0000005F 0000005F 00000000 0000005F 0000006C 00000000 0000006C 00000060 52 45 54 53 49 4C 06 oc 00000002 OOOA 0016 7FFF 008E CFFC 52 FB AF 9E 50 00000004 OG 9E 51 50 DO 00000000 GG 16 FC AD FD AF 9E OOOC: 0010: 0014: 0018: 001C: 0020: 0024: 0028: 002C: 0030: 0034: 0038: 003C: 0040: 0044: 0048: 004C: 0050: 0054: 0058: 005C: 0063: 0063: 0064: 0064: 0064: 0068: 006A: 006C: 006E: 0070: 0000: 0000: 0000: 0002: 0006: OOOD: 0010: 0016: 0016: .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .ASCIC 88 0 1 0 0 0 0 0 0 24 0 0 95 95 0 95 108 0 108 96 "LISTER" Decimal constants .PACKED +O String constants ERL table .LONG 2 .WORD 10 .WORD 22 .WORD 32767 .WORD 142 .PSECT LISTER$MAIN : : .WORD MOVAB MOVAB MOVL JSB $!_0016: $L_10: MOVAB $CODE -M<R2,R3,R4,R5,R6,.R7 ,R8,R9,R10,R11, IV ,DV> .-3, R2 $PDATA+4, RO RO, R1 BAS$INIT_R8 $L_10, -4(FP) 0025 (Continued on next page) 4-22 Developing VAX BASIC Programs at DCL Command Level Example 4-1 (Cont.): FC AD FD AF 9E 6F AB 00 DO FC AD FD AF 9E 00 DD 00000000 GG 01 FB 6C 00 01 06 00 6F AB OA 7E 67 AB 4C 60 00000000 GG 01 FB 00000000 GG 00 FB FC AD FD AF 9E LISTER$MAIN Generated VAX BASIC Compiler Listing 001B: 001B: 0020: 0024: 0029: 002B: 0032: 003A: 003F: 0046: 004D: .-1, -4(FP) #0, INDEX(R11) .-1, -4(FP) #0 ; 0026 #1, BAS$PRINT INDEX(R11), #0, #6, #1, #0, R12 Q(R11)[R12], -(SP) #1, BAS$0UT_F_V_B #0, BAS$IO_END .-1, -4(FP) 0027 Listing Tester 19-MAY-1986 11:27:36 VAX BASIC V3.0 Page 7 19-MAY-1986 11:10:66 MY$$DISK:[SMITH]LISTER.BAS;2 CD 6F AB 06 F3 0062: 6F AB D7 0067: FC AD FD AF 9E 006A: 006F: FC AD FD AF 9E 006F: FC AD FD AF 9E 0064: FFFFFFFF SF D6 0069: 18 13 006F: 6C 6F AB 4E 0071: 6C 08 40 0075: 6F AB 6C 4A 0078: 5C 6F AB 4E 007C: 1A SC 61 0080: 02 19 0083: 02 11 0086: DB 11 0087: FC AD FD AF 9E 0089: 008E: 008E: FC AD FD AF 9E 008E: 60 00000004 OG 9E 0093: 00000000 GG 16 009A: 50 01 DO OOAO: 04 OOA3: OOA4: 4.2.3. 1 FIRST_LOOP: MOVAB MOVL $T_0024:MOVAB PUSHL CALLS INDEX MOVF CALLS CALLS $T_004D:MOVAB AOBLEQ #6, INDEX(R11), $T_0024 DECL INDEX(R11) $T_006A:MOVAB .-1, -4(FP) SECOND_LOOP: MOVAB .-1, -4(FP) $T_0064:MOVAB .-1, -4(FP) #-1 TSTL $T_0089 BEQL CVTLF INDEX(R11), R12 ADDF2 #8, R12 CVTFL R12, INDEX(R11) CVTLF INDEX(R11). R12 R12, #26 CMPF $T_0087 BLSS $T_0089 BRB $T_0087:BRB $!_0064 $T_0089:MOVAB .-1, -4(FP) $1_32767: MOVAB MOVAB JSB MOVL RET .END 0030 0031 0032 0033 0036 $L_32767, -4(FP) $PDATA+4, RO BAS$END_R8 #1, RO 0036 Source Program Listing The source program section of the compiler listing contains the source code plus listing line numbers generated by the compiler. Developing VAX BASIC Programs at DCL Command level 4-23 0 LISTER$MAIN Listing Tester V1.5 0 1 %TITLE "Listing Tester" Y.SBTTL "Test" Y.IDENT "V1.5" 10 1 0 e Page 19-MAY-1986 11:10:56 MY$$DISK:[SMITH]LISTER.BAS;2 Test 0 19-MAY-1986 11:27:36 VAX BASIC V3.0 2 3 4 5 6 7 8 9 10 11 12 13 !This program only shows the format of a listing !file. It does no useful work. Ci) %INCLUDE "MAPS . DEF" ! MAPS definition file MAP (SHARED) STRING A :: 16, LONG B, DOUBLE C, BYTE D DECLARE INTEGER INDEX DECLARE LONG CONSTANT TRUE = -1 DECLARE SINGLE Q(5) I1 I1 I1 I1 I1 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 Y.IF %VARIANT = 2 Y.THEN DECLARE DOUBLE Z(10) Y.END Y.!F 0 F1 First_loop: FOR INDEX = 0 TO 5 PRINT Q(INDEX) NEXT INDEX Second_loop: WHILE TRUE INDEX = INDEX + 1 EXIT Second_loop IF INDEX => 5 NEXT 33 34 35 36 & & & 32767 0 8 0 8 0 END The module name, which corresponds to the name in the program or module heading. The date (day, month, year) and time (hour, minute, second) of compilation. The VAX BASIC compiler name and version number. The page number. The date (day, month, year) and time (hour, minute, second) of source file creation. 4-24 Developing VAX BASIC Programs at DCL Command Level 0 0 The VAX/VMS file specification of the source file that is being compiled. The source code listing line numbers. 0 The compiler assigns unique line numbers to the lines of source code in a BASIC compilation unit. These line numbers appear in the leftmost column of the source code listing. The symbolic traceback that is printed if your program encounters an error at run time refers to these line numbers; in addition, the VAX/VMS Debugger uses these line numbers when controlling program execution. The %INCLUDE file information. 0 The "I" tells you that this code was extracted from a %INCLUDE file. The number following the "I" tells you the depth of nested %INCLUDE directives. Because this %INCLUDE directive occurs in the source program, the number is "1". If the %INCLUDE file itself contained a %INCLUDE directive, the code extracted from that file would be numbered "2", and so on. A true-false flag for the %IF ... THEN ... ELSE ... END .. .IF directives. Lines marked with "T" are compiled. Lines marked with "F" are not compiled. 4.2.3.2 Cross-Reference Listing If you specified the /CROSS_REFERENCE qualifier, your listing includes a section displaying a list of the names of every identifier, both predeclared and user-declared, and every label to which the source code refers. LISTER$MAIN Listing Tester Cross Reference 19-MAY-1986 11:27:36 VAX BASIC V3.0 Page 2 19-MAY-1986 11:10:66 MY$$DISK:[SMITH]LISTER.BAS;2 CD User Identifier Cross Reference Symbol Datatype Name Type +--------------------------------------------------+ ! Defining reference Destructive reference P Parameter reference R Redefining reference ! # ~ +--------------------------------------------------+ A STR=16 MAP SHARED + 0 LONG MAP SHARED + 16 10 # B 11 # Developing VAX BASIC Programs at DCL Command Level 4-25 c DOUBLE MAP SHARED + 20 BYTE MAP SHARED + 28 12 # D 13 # INDEX 14 # 25 16 # 26 15 # 30 LONG 26 Q() 27 31 ~ 32 SINGLE LONG TRUE LISTER$MAIN Cross Reference tD CONSTANT Listing Tester 19-MAY-1986 11:27:36 VAX BASIC V3.0 Page 3 Map 19-MAY-1986 11:10:56 MY$$DISK: [SMITH]LISTER.BAS;2 Map Cross Reference Symbol References SHARED MAP 10 # A STR=16 MAP SHARED + 0 LONG MAP SHARED + 16 DOUBLE MAP SHARED + 20 BYTE MAP SHARED + 28 10 # B 11 # c 12 # D 13 # 48 Label Cross Reference Symbol References FIRST_LOOP 24 # SECOND_LOOP 29 # 32 4D The cross-reference listing for variables and named constants. This tells you the variable names, the line number (if any) and statement at which they are referenced, their data type, the PSECT containing them (if any), and their offset from the start of the PSECT. tD The cross-reference listing for mapped variables. This tells you the variable names, the line number and statement number at which they are referenced, their data type, and their offset from the start of the MAP PSECT. 4-26 Developing VAX BASIC Programs at DCL Command level 48 The label cross-reference listing for labels. This tells you the label names and the line number and statement at which they are referenced. 4.2.3.3 Allocation Map The allocation map portion of a compiler listing contains summary information on program sections, variables, and arrays. If you specified the /CROSS_REFERENCE in addition to the /LISTING qualifier, the allocation map also contains the following cross reference information: • • • • LISTER$MAIN Listing lines where symbols are defined and initialized Listing lines where the values of symbols are modified Listing lines where symbols are actual arguments Number of times a symbol occurs in each line Listing Tester ALLOCATION MAP 19-MAY-1986 11:27:36 VAX BASIC V3.0 Page 4 19-MAY-1986 11:10:56 MY$$DISK:[SMITH]LISTER.BAS;2 41) Allocation information for MAP SHARED Name A B c D .., Off set Size Type 0 16 20 28 16 Static string Long Double Byte 4 8 1 Named constants Name Type Value TRUE Long -1 41 Allocation information for main program LISTER Offset based on (R11) Offset Size Type INDEX 111 Q 87 4 24 Long Single Name Dimensions : ( 0 TO 5 ) 4D PROGRAM SECTIONS Developing VAX BASIC Programs at DCL Command Level 4-27 Name Bytes Attributes 112 164 0 0 29 0 $PDATA 1 $CODE 2 $ARRAY 3 $DESC 4 SHARED PIC CON REL LCL SHR NOEXE PIC CON REL LCL SHR EXE PIC CON REL LCL NOSHR NOEXE PIC CON REL LCL NOSHR NOEXE PIC OVR REL GBL SHR NOEXE RD NOWRT LONG RD NOWRT LONG RD WRT LONG RD WRT LONG RD WRT LONG a> EXTERNAL REFERENCES OTS$LINKAGE BAS$PRINT BAS$LINKAGE BAS$IO_END BAS$INIT_R8 BAS$0UT_F_V_B BAS$END_R8 41> The allocation listing for the MAP named SHARED. This tells you the names of all variables in the MAP, their offset, in bytes, from the beginning of the MAP, their size in bytes, and their data type. 4D A list of named constants. This tells you the names of all explicitly declared constants, their data type, and the value assigned to them. 49 The allocation listing for dynamic variables. This part of the listing applies to variables that are neither parameters nor part of a COMMON or MAP PSECT. This tells you the names of the variables, their offset from R11, their size in bytes and their data type. ~ A list of the program sections (PSECTs). a> This tells you the names of the PSECTs, their size in bytes and their attributes. See the VAX/VMS Linker Reference Manual for more information on PSECT attributes. A list of all external references. This includes subprograms, external variables, constants, functions, and routines, and the RTL routines invoked to support VAX BASIC language elements. See the VAX/VMS Run-Time Library Routines Reference Manual for more information on these RTL routines. 4-28 Developing VAX BASIC Programs at DCL Command Level 4.2.3.4 Qualifier Summary The compilation summary lists the qualifiers used with the BASIC command and the compilation statistics. LISTER$MAIN 4D Listing Tester 19-MAY-1986 11:27:36 VAX BASIC V3.0 Page 6 19-MAY-1986 11:10:66 MY$$DISK:[SMITH]LISTER.BAS;2 Qualifier summary DEFAULT DATA TYPE INFORMATION: Data type : REAL Real size : SINGLE Integer size : LONG Decimal size : (16,2) Scale factor : 0 NO Round decimal numbers COMPILATION QUALIFIERS IN EFFECT: Object file Overflow check integers Overflow check decimal numbers Bounds checking NO Syntax checking Line Variant : 0 Warnings Informationals Setup Object Libraries : NONE LISTING FILE INFORMATION INCLUDES: List Cross reference COD Definitions Environment NO Override of Y.NOLIST Machine code Map INCLUDE files FLAGGERS: NO Declining features NO BASIC PLUS 2 subset DEBUG INFORMATION: Traceback records NO Debug symbol records 4D A list of the compiler defaults in effect when the program was compiled. 4.2.3.5 Machine Code Listing If you specified the /MACHINE qualifier, your listing includes a section displaying compiler-generated object code. LISTER$MAIN CD Listing Tester Generated code 19-MAY-1986 11:27:36 VAX BASIC V3.0 Page 6 19-MAY-1986 11:10:66 MY$$DISK:[SMITH]LISTER.BAS;2 0000006F 0000006C 1C000103 00000068 00000000 0000: 0000: 0000: 0000: 0004: 0008: OOOC: 0010: .TITLE .!DENT .PSECT .LONG .LONG .LONG .LONG .LONG LISTER$MAIN V1.6 $PDATA 96 92 469762307 88 0 Developing VAX BASIC Programs at OCL Command Level 4-29 00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000018 00000000 00000000 0000006F 0000006F 00000000 0000006F 0000006C 00000000 0000006C 00000060 0014: 0018: 001C: 0020: 0024: 0028: 002C: 0030: 0034: 0038: 003C: 0040: 0044: 0048: 004C: 0060: 0064: 0068: .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG .LONG 62 46 54 63 49 4C 06 .ASCIC FC AD FD AF 9E 6F AB 00 DO FC AD FD AF 9E 00 DD 006C: 0063: 0063: 0064: 0064: 0064: 0068: 006A: 006C: 006E: 0070: 0000: 0000: 0000: 0002: 0006: OOOD: 0010: 0016: 0016: 0018: 0018: 0020: 0024: 0029: .PSECT LISTER$MAIN: : .WORD MOVAB MOVAB MOVL JSB $!_0016: $L_10: MOVAB FIRST_LOOP: MOVAB MOVL $T_0024:MOVAB PUSHL 00000000 GG 01 FB 6C 00 01 06 00 6F AB OA 7E 67 AB 4C 60 00000000 GG 01 FB 00000000 GG 00 FB FC AD FD AF 9E 0028: 0032: 003A: 003F: 0046: 004D: CALLS INDEX MOVF CALLS CALLS $T_004D:MOVAB oc 00000002 OOOA 0016 7FFF 008E CFFC 62 FB AF 9E 50 00000004 OG 9E 61 60 DO 00000000 GG 16 FC AD FD AF 9E 4-30 1 0 0 0 0 0 0 24 0 0 96 96 0 96 108 0 108 96 "LISTER" Decimal constants .PACKED +O String constants ERL table .LONG 2 .WORD 10 .WORD 22 .WORD 32767 .WORD 142 Developing VAX BASIC Programs at DCL Command Level $CODE -M<R2,R3,R4,R6,R6,R7,R8,R9,R10,R11,IV,DV> .-3, R2 $PDATA+4, RO RO, R1 BAS$INIT_R8 $L_10, -4(FP) 0026 .-1, -4(FP) #0, INDEX(R11) .-1, -4{FP) #0 ; 0026 #1, BAS$PRINT INDEX(R11), #0, #6, #1, #0, R12 Q(R11)[R12], -(SP) #1, BAS$0UT_F_V_B #0, BAS$IO_END .-1,. -4{FP) 0027 LISTER$MAIN Generated Listing Tester 19-MAY-1986 11:27:36 VAX BASIC V3.0 Page 7 19-MAY-1986 11:10:56 MY$$DISK:[SMITH]LISTER.BAS;2 #5 INDEX (R11) INDEX(R11) .-1, -4(FP) CD 6F AB 05 F3 0052: 6F AB D7 0067: FC AD FD AF 9E 006A: 006F: FC AD FD AF 9E 006F: FC AD FD AF 9E 0064: FFFFFFFF SF D6 0069: 18 13 006F: 5C 6F AB 4E 0071: 5C 08 40 0075: AOBLEQ DECL $T_005A:MOVAB SECOND_LOOP: MOVAB $T_0064:MOVAB TSTL BEQL CVTLF ADDF2 .-1, -4(FP) .-1, -4(FP) #-1 $T_0089 INDEX(R11), R12 #8, R12 6F AB 5C 4A 0078: 5C 6F AB 4E 007C: 1A 6C 61 0080: 02 19 0083: 02 11 0085: DB 11 0087: FC AD FD AF 9E 0089: 008E: 008E: FC AD FD AF 9E 008E: 50 00000004 OG 9E 0093: 00000000 GG 16 009A: 50 01 DO OOAO: 04 OOA3: OOA4: CVTFL CVTLF CMPF BLSS BRB $T_0087:BRB $T_0089:MOVAB R12, INDEX(R11) INDEX(R11), R12 R12, #26 $!_0087 $T_0089 $!_0064 .-1, -4(FP) ~ $L_32767: MOVAB MOVAB JSB MOVL RET .END I I $!_0024 0030 0031 0032 0033 0036 $L_32767, -4(FP) $PDATA+4, RO BAS$END_R8 #1, RO 0036 A list of the compiler-generated machine code. For a thorough understanding of this code, you should be an experienced VAX MACRO programmer. The naming scheme for the compiler-generated labels is explained as follows: Symbols beginning with $L_n are line-number labels, where n is the line number. Symbols beginning with $T_n are compiler-generated labels, where n is the relative PC of the location. Note that these labels are used to improve the readability of the listing and are not accessible from the VAX/VMS Debugger. See the VAX/VMS Run-Time Library Routines Reference Manual for more information on BAS$ and OTS$ routines. Developing VAX BASIC Programs at DCL Command Level 4-31 4.3 Linking a VAX BASIC Program On VAX/VMS systems, the linker simplifies the job of each language compiler because the logic needed to resolve symbolic references need not be duplicated. The main advantage to a system that has a linker, however, is that individual program modules can be separately written and compiled, and then linked together. This includes object modules produced by different language compilers. The VAX/VMS Linker performs the following functions: • • • • Resolves local and global symbolic references in the object code Assigns values to the global symbolic references Signals an error message for any unresolved symbolic reference Produces an executable image When using the LINK command on development systems, you may want to use the /DEBUG qualifier when you link your program module. The /DEBUG qualifier appends to the image all the symbol and line number information appended to the object modules plus information on global symbols, and forces the image to run under debugger control when it is executed. The LINK command produces an executable image by default. However, you can also use the LINK command to obtain shareable images and system images. The /SHAREABLE qualifier directs the linker to produce a shareable image; the /SYSTEM qualifier a system image. See Section 4.3.2 for a complete description of these and other LINK command qualifiers. For a complete discussion of the VAX/VMS Linker, refer to the VAX/VMS Linker Reference Manual. 4.3.1 The LINK Co•mand Once you have compiled your source program or module, you link it by using the DCL command LINK. The LINK command combines your object modules into one executable image, which can then be executed by the VAX/VMS system. A source program or module cannot run on the VAX/VMS system until it is linked. The format of the LINK command is as follows: LINK[/command-qualifier] ... {file-spec[/file-qualifier ... ]}, ... 4-32 Developing VAX BASIC Programs at DCL Command Level /command-qualifier Specifies one or more output file options. file-spec Specifies the input file or files to be linked. /file-qualifier Specifies one or more input file options. If you specify more than one input file, you must separate the input file specifications with plus signs ( +) or commas (, ). By default, the linker creates an output file with the name of the first input file specified and the file type EXE. When you link more than one file, it is good practice to list the file containing the main program first. In this way, the name of your output file will have the same name as that of your main program module. The following command line links the object files DANCE.DBL CHACHA.OBJ, and SWING.OBJ to produce one executable image called DANCE.EXE: $LINK DANCE.OBJ, CHACHA.OBJ, SWING.OBJ 4.3.2 LINK Command Qualifiers The LINK command qualifiers can be used to modify the linker's output, as well as to invoke the debugging and traceback facilities. Linker output consists of an image file and an optional map file. Image file qualifiers, map file qualifiers, and debugging and traceback qualifiers are described in this section. The following list summarizes some of the most commonly used LINK command qualifiers. A brief description of each qualifier follows this list. For a complete list and description of LINK qualifiers, see the VAX/VMS Linker Reference Manual. Command Qualifier Default /BRIEF /[NO]CROSS_REFERENCE /[NO]DEBUG [= file-spec] [NO]EXECUT ABLE [= file-spec] /Default map /NOCROSS_REFERENCE /NODE BUG /EXECUTABLE Developing VAX BASIC Programs at DCL Command Level 4-33 /FULL /[NO]MAP [=file-spec] /[NO]SHAREABLE [= file-spec] /[NO]TRACEBACK /Default map /NOMAP /NOSHAREABLE /TRACEBACK /BRIEF The /BRIEF qualifier causes the linker to produce a summary of the image's characteristics and a list of contributing modules. /[NO]CROSS_REFERENCE The /CROSS-REFERENCE qualifier causes the linker to produce crossreference information for global symbols; the /NOCROSS-REFERENCE qualifier causes the linker to suppress cross-reference information. The default is /NOCROSS-REFERENCE. /[NO]DEBUG The /DEBUG qualifier causes the linker to include the VAX/VMS Debugger in the executable image and generates a symbol table; the /NODEBUG qualifier causes the linker to prevent debugger control of the program. The default is /NODEBUG. /[NO]EXECUTABLE The /EXECUTABLE qualifier causes the linker to produce an executable image; the /NOEXECUTABLE qualifier suppresses production of an image file. The default is /EXECUTABLE. /FULL The /FULL qualifier causes the linker to produce a summary of the image's characteristics, a list of contributing modules, listings of global symbols by name and by value, and a summary of characteristics of image sections in the linked image. /[NO]MAP The /MAP qualifier causes the linker to generate a map file; the /NOMAP qualifier suppresses the map. The default is /MAP in batch mode and /NOMAP in interactive mode. /[NOJSHAREABLE The /SHAREABLE qualifier causes the linker to create a shareable image; the /NOSHAREABLE qualifier generates an executable image. The default is /NOSHAREABLE. 4-34 Developing VAX BASIC Programs at OCL Command Level /[NO]TRACEBACK The /TRACEBACK qualifier causes the linker to generate symbolic traceback information when error messages are produced; the /NOTRACEBACK qualifier suppresses traceback information. The default is /TRACEBACK. 4.3.3 Linker Input Files You can specify the object modules to be included in an executable image in any of the following ways: • Specify input file specifications for the object modules. If no file type is specified, the linker assumes that an input file is an • object file with the file type OBJ. Specify one or more object module library files. • You can either specify the name of an object module library with the /LIBRARY qualifier, or specify the names of object modules contained in an object module library with the /INCLUDE qualifier. The uses of object module libraries are described in Section 4.3.5. Specify an options file. An options file can contain additional file specifications for the LINK command as well as special linker options. You must use the /OPTIONS qualifier to specify an options file. For more information on options files see the VAX/VMS Linker Reference Manual. The linker uses the following default file types for input files. File 4.3.4 File Type Object module OBJ Library OLB Options file OPT Linker Output Files When you enter the LINK command interactively and do not specify any qualifiers, the linker creates only an executable image file. By default, Developing VAX BASIC Programs at DCL Command level 4-35 the resulting image file has the same file name as the first object module specified, and a file type of EXE. In a batch job, the linker creates both an executable image file and a storage map file by default. The default file type for map files is MAP. To specify an alternative name for a map file or image file, or to specify an alternative output directory or device, you can include a file specification on the /MAP or /EXECUTABLE qualifier. For example: $ LINK UPDATE/MAP=TEST 4.3.5 Using an Object Module Library In a large development effort, the object modules for subprograms are often stored in an object module library. By using an object module library, you can make program modules contained in the library available to many other programmers. To link modules contained in a object module library, use the /INCLUDE qualifier and specify the specific modules you want to link. For example: $LINK GARDEN, VEGGIES/INCLUDE=(EGGPLANT,TOMATO,BROCCOLI,ONION) This example directs the linker to link the subprogram modules EGGPLANT, TOMATO, BROCCOLI, and ONION with the main program module GARDEN. Besides program modules, an object module library can also contain a symbol table with the names of each global symbol in the library, and the name of the module in which they are defined. You specify the name of the object module library containing symbol definitions with the /LIBRARY qualifier. When you use the /LIBRARY qualifier during a link operation, the linker searches the specified library for all unresolved references found in the included modules during compilation. In the following example, the linker uses the library RACQUETS to resolve undefined symbols in BADMINTON, TENNIS, and RACQUETBALL. $ LINK BADMINTON, TENNIS, RACQUETBALL, RACQUETS/LIBRARY You can define an object module library, such as LNK$LIBRARY, to be your default library by using the DCL command DEFINE. The linker searches default user libraries for unresolved references after it searches modules and libraries specified in the LINK command. See the VAX/VMS DCL Dictionary for more information about the DEFINE command. 4-36 Developing VAX BASIC Programs at DCL Command Level For more information about object module libraries, see the VAX/VMS Linker Reference Manual. 4.3.6 linker Error Messages If the linker detects any errors while linking object modules, it displays messages indicating the cause and severity of the error. If any error or fatal error conditions occur, (errors with severities of E or F) the linker does not produce an image file. The messages produced by the linker are descriptive, and you do not usually need additional information to determine the specific error. Some common errors that occur during linking are as follows: • • An object module has compilation errors. This error occurs when you attempt to link a module that has warnings or errors during compilation. You can usually link compiled modules for which the compiler generated messages, but you should verify that the modules will actually produce the output you expect. The input file has a file type other than OBJ and no file type was specified on the command line. • If you do not specify a file type, the linker assumes the file has a file type of OBJ by default. If the file is not an object file and you do not identify it with the appropriate file type, the linker signals an error message and does not produce an image file. You tried to link a nonexistent module. • The linker signals an error message if you misspell a module name on the command line or if the compilation contains fatal diagnostics. A reference to a symbol name remains unresolved. An error occurs when you omit required module or library names from the command line and the linker cannot locate the definition for a specified global symbol reference. For example, a main program module OCEAN.OBJ calls the subprograms REEF.OBJ, SHELLS.OBJ, and SEAWEED.OBJ. However, the following LINK command does not reference SEAWEED.OBJ: $ LINK OCEAN, REEF, SHELLS Developing VAX BASIC Programs at DCL Command Level 4-37 This example produces the following error messages: Y.LINK-W-NUDFSYMS, 1 undefined symbol Y.LINK-I-UDFSYMS, SEAWEED Y.LINK-W-USEUNDEF, module "OCEAN" references undefined symbol "SEAWEED" Y.LINK-W-DIAGISUED, completed but with diagnostics If an error occurs when you link modules, you can often correct the· error by reentering the command string and specifying the correct modules or libraries. See the VAX/VMS System Messages and Recovery Procedures Reference Manual for a complete list of linker messages. 4.4 Running a VAX BASIC Program Once you have linked your program, you use the DCL command RUN to execute it. The RUN command has the following format: RUN [/[NO]DEBUG] file-spec [/[NO]DEBUG] /[NO]DEBUG The /[NO]DEBUG qualifier is optional. Specify the /DEBUG qualifier to request the debugger if the image was not linked with it. You cannot use /DEBUG on images linked with the /NOTRACEBACK qualifier. If the image was linked with the /DEBUG qualifier and you do not want the debugger to prompt, use the /NODEBUG qualifier. The default action depends on whether the file was linked with the /DEBUG qualifier. file-spec The name of the file you want to run. The following example executes the image SAMPLE.EXE without invoking the debugger: $ RUN SAMPLE/NODEBUG See Chapter 5 for more information on debugging programs. During program execution, an image can generate a fatal error called an exception condition. When an exception condition occurs, VAX BASIC displays an error message. Run-time errors can also be issued by other facilities such as, the VAX/VMS operating system. For more information on run-time errors, see Appendix B. 4-38 Developing VAX BASIC Programs at OCL Command Level Chapter 5 Using the VAX/VMS Debugger This chapter is an introduction to using the VAX/VMS Debugger with VAX BASIC programs. Included in the chapter are the following: • • • • An overview of the debugger Enough information to get you started using the debugger A sample terminal session that demonstrates using the debugger to find a bug in a VAX BASIC program A list of the debugger commands by function For complete reference information on the VAX/VMS Debugger, see the VAX/VMS Debugger Reference Manual. Online HELP is available during debugging sessions. 5.1 Overview of the Debugger A debugger is a tool to help you locate run-time errors quickly. It is used with a program that has already been compiled and linked successfully, with no errors reported, but that does not run correctly. For example, the outf>ut may be obviously wrong, or the program goes into an infinite loop or terminates prematurely. The debugger enables you to observe and manipulate the program's execution interactively, step by step, until you locate the point at which the program stopped working correctly. The VAX/VMS Debugger is a symbolic debugger, which means that you can refer to program locations by the symbols (names) you used for those locations in your program-the names of variables, routines, labels, and so on. You do not have to use virtual addresses to refer to memory locations. Using the VAX/VMS Debugger 5-1 The debugger recognizes the syntax, expressions, data typing, and other constructs of VAX BASIC, as well as the following other VAX/VMSsupported languages: Ada® BLISS c COBOL DIBOL FORTRAN MACR0-32 PASCAL PL/I RPG II SCAN Therefore, if your program is written in more than one language, you can change from one language to another in the course of a debugging session. The current source language determines the format used for entering and displaying data, as well as other features that have languagespecific settings (for example, comment characters, operators and operator precedence, and case sensitivity or insensitivity). By issuing debugger commands at your terminal, you can • • • • • Start, stop, and resume the program's execution Trace the execution path of the program Monitor selected locations, variables, or events Examine and modify the contents of variables, or force events to occur Test the effect of some program modifications without having to edit, recompile, and relink the program Such techniques can enable you to isolate an error in your code much more quickly than you could without the debugger. Once you have found the error in the program, you can then edit the source code and compile, link, and run the corrected version. ® Ada is a registered trademark of the U.S. Government (Ada Joint Program Office). 5-2 Using the VAX/VMS Debugger 5.2 Features of the Debugger The VAX/VMS Debugger provides various features that help you to debug your programs: • • • • • • • • Online HELP. Online HELP is always available during a debugging session; it contains information on all of the debugger commands and selected topics. Source code display. The debugger lets you display lines of source code during a debugging session. Screen mode. In screen mode, you can display and capture various kinds of information in scrollable windows that can be moved around the screen and resized. Source, instruction, and register displays are automatically updated. You can selectively direct debugger input, output, and diagnostic messages to displays. (Screen mode is best displayed on VTlOO-series or VT200-series terminals or MicroVAX/VMS workstations.) Keypad mode. When you invoke the debugger, several commonly used debugger command sequences are assigned by default to the keys of the numeric keypad (if you have a VTlOO, VT52, or LK201 keypad). Using the keypad can be more efficient than typing commands because the keypad keys can save keystrokes. (See Figure 5-1 for a diagram of the keypad key functions.) Source editing. As you find errors during a debugging session, you can use the EDIT command to invoke any editor available on your system. You specify the editor you want with the SET EDITOR command. Command procedures. You can direct the debugger to execute a command procedure (a file of debugger commands) to recreate a debugging session, to continue a previous session, or to avoid typing the same debugger commands many times during a debugging session. Symbol definitions. You can define your own symbols to represent lengthy commands, address expressions, or values in abbreviated form. Initialization files. You can create an initialization file containing commands to set your default debugging modes, screen display definitions, keypad key definitions, symbol definitions, and so on. In addition, you may want to have special initialization files for debugging specific programs. When you invoke the debugger, those commands will be executed automatically. Using the VAX/VMS Debugger 5-3 • 5.3 Log files. You can record the commands you enter during a debugging session and the debugger's responses to those commands in a log file. You can use log files to keep track of your debugging efforts, or you can use them as command procedures in subsequent debugging sessions. Getting Started with the Debugger This section explains how to use the debugger and provides VAX BASIC examples. The intent is to get you started using the debugger; therefore, only basic functions are covered. For more detailed information, see the VAX/VMS Debugger Reference Manual. Remember that online HELP is immediately available to you during a debugging session when you type the HELP command at the DBG> prompt. 5.3. 1 Compiling and Linking to Prepare for Debugging The following example shows how to compile and link a VAX BASIC program (consisting of a single compilation unit named INVENTORY) so that subsequently you will be able to use the debugger. $ BASIC/DEBUG INVENTORY $ LINK/DEBUG INVENTORY The /DEBUG qualifier on the BASIC command causes the compiler to write the debug symbol records associated with INVENTORY into the object module, INVENTORY.OBJ. These records allow you to use the names of variables and other symbols declared in INVENTORY in debugger commands. (If your program has several compilation units, you must compile each unit that you want to debug with the /DEBUG qualifier). The /DEBUG qualifier on the LINK command causes the linker to include all symbol information that is contained in INVENTORY.OBJ in the executable image. The qualifier also causes the VAX/VMS image activator to start the debugger at run time. (If your program has several object modules, you may need to specify other modules in the LINK command). 5-4 Using the VAX/VMS Debugger 5.3.2 Starting and Terminating a Debugging Session To invoke the debugger, issue the DCL command RUN. The following message will appear on your screen. $ RUN INVENTORY VAX DEBUG Version 4.n %DEBUG-I-INITIAL, language is BASIC, module set to 1 INVENTORY$MAIN 1 DBG> The DBG > prompt indicates that you can now type debugger commands. At this point, if you type the GO command, program execution begins and continues until it is forced to pause or stop (for example, if the program prompts you for input, or an error occurs). The debugger suspends execution before the start of the main program, so that you can execute initialization code under debugger control. Typing the GO command will put you at the start of the main program. At that point, typing the GO command again will start program execution and continue it until it is forced to stop (for example, if the program prompts you for input, or an error occurs). To interrupt a debugging session while a debugging command is in progress, press CTRL/Y to return to DCL level. For example, if your program loops or otherwise fails to complete execution, press CTRL/Y to stop the debugging session and return to DCL level. After you have used CTRL/Y to interrupt a debugging session, you can resume the session by using the CONTINUE or DEBUG command at DCL level. In general, you use the CONTINUE command at DCL level to return to where you interrupted the debugging session. If you interrupted the session with CTRL/Y because of an infinite loop, you use the DCL command DEBUG instead of the CONTINUE command. The DEBUG command returns you to the debugger prompt so that you can type another command. For example: DBG> GO (infinite loop) ICTRL/YI Interrupt $ DEBUG DBG> Using the VAX/VMS Debugger 5-5 The following message indicates that your program has completed successfully: %DEBUG-I-EXITSTATUS, is 1 1.SYSTEM-S-NORMAL, normal successful completion' DBG> To end a debugging session, type the EXIT command at the DBG> prompt or press CTRL/Z: DBG> EXIT • 5.3.3 Issuing Debugger Commands You can issue debugger commands any time you see the debugger prompt (DBG> ). To enter a command, type it at the keyboard and press the RETURN key. You can issue several commands on a line by separating the command strings with semicolons (; ). As with DCL commands, you can continue a command string on a new line by ending the line with a hyphen(-). Alternatively, you can use the numeric keypad. In addition to the STEP, GO, SHOW CALLS, and EXAMINE commands, several functions that manipulate screen-mode displays are bound to the keys. Figure 5-1 identifies the predefined key functions. You can also redefine key functions with the DEFINE/KEY command. Most keypad keys have three predefined functions-DEFAULT, GOLD, and BLUE. (The PFl key is commonly known as the GOLD key, and the PF4 key is commonly known as the BLUE key.) To obtain a key's DEFAULT function, press the key. To obtain its GOLD function, first press the PFl (GOLD) key, and then the key. To obtain its BLUE function, first press the PF4 (BLUE) key, and then the key. In Figure 5-1, the DEFAULT, GOLD, and BLUE functions are listed within each key's outline, from top to bottom respectively. For example, pressing keypad key 0 issues the STEP command (DEFAULT function); pressing key PFl and then key 0 issues the STEP /INTO command (GOLD function); pressing key PF4 and then key 0 issues the STEP /OVER command (BLUE function). Type the HELP KEYPAD command to get help on the keypad key definitions. 5-6 Using the VAX/VMS Debugger Figure 5-1: r F17 Keypad Key Functions Predefined by the Debugger "" DEFAULT (SCROLL) F18 F19 MOVE F20 EXPAND CONTRACT (EXPAND •I !EXPAND -I """" "MOVE" MOVE/UP MOVE/UP:999 MOVE/UP:S ~ " / PF1 PF2 PF3 ~ PF4 GOLD HELP DEFAULT SET MODE SCREEN BLUE GOLD HELP GOLD SET MODE NOSCR BLUE GOLD HELP BLUE DISP•GENERATE BLUE re 7 DISP SRC.INST.OUT SCROLL'UP DISP INST.REG.OUT SCROLL'TOP ~ "' MOVE/DOWN:999 MOVE/DOWN:S ~ SCROLL LEFT EX SOU .0\ %PC SCROLL/RIGHT SCROLL/LEFT:255 SHOW CALLS SCROLL/RIGHT:255 SCROLL/LEFT... SHOW CALLS 3 SCROLL/RIGHT ... ~ ,2 ' SCROLL/DOWN SEL SCROLL next EXAM-(prev) SCROLL/BOTIOM SEL OUTPUT next SCROLL/DOWN ... SEL SOURCE next "' "EXPAND" EXPAND/UP EXPAND/UP:999 EXPAND/UP:5 ENTER 3 ...) GO SEL 'INST next ~ ""' "' EXAMINE 0 DISP next at FS ...) l's 1 MOVE/RIGHT: 10 DISP SRC. OUT 5 " MOVE/RIGHT:999 MOVE/DOWN DISPLAY next SCROLL/UP ... "4 MOVE/RIGHT MOVE/LEFT:999 - 9 """ MOVE/LEFT MOVE/LEFT· 10 . EXPAND/LEFT EXPAND/RIGHT EXPAND/LEFT 999 EXPAND/RIGHT:999 EXPAND/LEFT 10 EXPAND/RIGHT:10 ENTER STEP RESET STEP INTO RESET STEP OVER RESET EXPAND/DOWN EXPAND/DOWN:999 \.. EXPAND/DOWN:5 LK201 Keyboard: Press Keys 2.4,6,8 F17 SCROLL F18 MOVE F19 EXPAND F20 CONTRACT "CONTRACT" EXPAND/UP:-1 EXPAND/UP:·999 EXPAND/UP:-5 EXPAND/LEFT:-1 VT-100 Keyboard: Type Keys 2,4,6,8 SET KEY /ST A TE=DEF AULT SCROLL SET KEY /ST A TE=MOVE MOVE SET KEY /ST A TE=EXPAND EXPAND SET KEY /ST A TE=CONTRACT CONTRACT EXPAND/AIGHT:-1 EXPAND/LEFT -999 EXPAND/RIGHT:-999 EXPAND/LEFT:-10 EXPAND/RIGHT:-10 EXPAND/DOWN:-1 EXPAND/DOWN:-999 EXPAND/DOWN:-5 ZK-4774-85 Using the VAX/VMS Debugger 5-7 5.3.4 Viewing Your Source Code The debugger provides two methods for viewing source code: noscreen mode and screen mode. By default, when you invoke the debugger, you are in noscreen mode, but you may find that it is easier to view your source code with screen mode. Both modes are briefly described in the following sections. 5.3.4. 1 Noscreen Mode Noscreen mode is the default, line-oriented mode of displaying input and output. To get into noscreen mode from screen mode, type SET MODE NOSCREEN. See the sample debugging session in Section 5.4 for a demonstration of noscreen mode. In noscreen mode, you can use the TYPE command to display one or more source lines. For example, the following command displays line 3 of the module that is currently executing: DBG> TYPE 3 3: EXTERNAL SUB TRIPLE & DBG> The display of source lines is independent of program execution. You can use the TYPE command to display source code from a module other than the one currently executing. In that case, you need to use a path name to specify the module. For example, the following command displays lines 16 through 21 of module TEST: DBG> TYPE TEST\16:21 5.3.4.2 Screen Mode To invoke screen mode, press keypad key PF3. In screen mode, by default the debugger splits the screen into three displays named SRC, OUT, and PROMPT. 5-8 Using the VAX/VMS Debugger --SRC: module SAMPLE$MAIN -scroll-source-------------------------1: 10 !SAMPLE 2: 3: 4: 5: 6: -> 7: 8: 9: EXTERNAL SUB TRIPLE ,PRINT_SUB WHEN ERROR USE HANDLER_1 CALL TRIPLE CALL PRINT_SUB - OUT -output--------------------------------------------stepped to SAMPLE$MAIN\XLINE 7 - PROMPT -error-program-prompt---------------------------DBG> STEP DBG> The SRC display, at the top of the screen, shows the source code of the module (compilation unit) that is currently executing. An arrow in the left column points to the next line to be executed, which corresponds to the current location of the program counter (PC). The line numbers, which are assigned by the compiler, match those in a listing file. NOTE Note that VAX BASIC line numbers are treated as text by the debugger. In this chapter, line numbers refer to the sequential line numbers generated by the compiler. When a program includes or appends code from another file, the included lines of code are also numbered in sequence by the compiler. These line numbers are on the extreme left of a listing file. An explanation of the listing file format can be found in Chapter 4. The PROMPT display, at the bottom of the screen, shows the debugger prompt (DBG > ), your input, debugger diagnostic messages, and program output. In the illustration, it shows the two debugger commands that have been issued. The OUT display, in the center of the screen, captures the debugger's output in response to the commands that you issue. The SRC and OUT displays are scrollable so that you can see whatever information may scroll beyond the display window's edge. Use keypad key 8 to scroll up and keypad key 2 to scroll down. Use keypad key 3 to change the display to be scrolled (by default, the SRC display is scrolled). Scrolling a display does not affect program execution. Using the VAX/VMS Debugger 5-9 If the debugger cannot locate source lines for the currently executing module, it tries to display source lines in the next module down on the call stack for which source lines are available and issues the following message: Y.DEBUG-I-SOURCESCOPE, Source lines not available for .O\Y.PC. Displaying source in a caller of the current routine. Source lines may not be available for the following reasons: • • • 5.3.5 The PC is within a system routine, or a shareable image routine for which no source code is available. The PC is within a routine that was compiled without the /DEBUG compiler command qualifier (or with /NODEBUG). The source file was moved to a different directory after it was compiled (the location of source files is embedded in the object modules). Controlling and Monitoring Program Execution This section covers the following topics: • • • • • • 5.3.5.1 Starting and resuming program execution with the GO command Stepping through the program's code with the STEP command Determining the current location of the program counter (PC) with the SHOW CALLS command Suspending program execution with breakpoints Tracing program execution with tracepoints Monitoring changes in variables with watchpoints Starting and Resuming Program Execution There are two commands for starting or resuming program execution: GO and STEP. The GO command starts execution. The STEP command lets you execute a specified number of source lines or instructions. 5-10 Using the VAX/VMS Debugger The GO Command The GO command starts program execution, which continues until forced to stop. You will probably use the GO command most often in conjunction with breakpoints, tracepoints, and watchpoints. If you set a breakpoint in the path of execution and then type the GO command (or press the comma key on the keypad, which executes the GO command), execution will be suspended when the program reaches that breakpoint. If you set a tracepoint, the path of execution through that tracepoint will be monitored. If you set a watchpoint, execution will be suspended when the value of the watched variable changes. You can also use the GO command to test for an exception condition or an infinite loop. If an exception condition that is not handled by your program occurs, the debugger will take over and display the DBG > prompt so that you can issue commands. If you are using screen mode, the pointer in the source display will indicate where execution stopped. You can then use the SHOW CALLS command (explained in Section 5.3.5.2) to identify the currently active routine calls (the call stack). In the case of an infinite loop, the program will not terminate, so the debugger prompt will not reappear. To obtain the prompt, interrupt the program by pressing CTRL/Y and then issue the DCL command DEBUG. You can then look at the source display and a SHOW CALLS display to locate the PC. The STEP Command The STEP command (which you can use either by typing STEP or by pressing the keypad 0 key) allows you to execute a specified number of source lines or instructions, or to execute the program to the next instruction of a particular kind, for example, to the next CALL instruction. By default, the STEP command executes a single source line at a time. In the following example, the STEP command executes one line, reports the action ("stepped to ... "), and displays the line number (27) and source code of the next line to be executed: DBG> STEP stepped to TEST\COUNTER\Y.LINE 27 27: x =x + 1 DBG> Using the VAX/VMS Debugger 5-11 The PC is now at the first machine code instruction for line 27 of the module TEST; line 27 is in COUNTER, a routine within the module TEST. "TEST\ COUNTER\ %LINE 27" is a path name. The debugger uses path names to refer to symbols. (However, you do not need to use a path name in referring to a symbol, unless the symbol is not unique; in that case, the debugger will issue an error message. See Section 5.3.7.2 for more information on resolving multiply-defined symbols.) You can specify a number of lines for the STEP command to execute. In the following example, the STEP command executes three lines: DBG> STEP 3 Note that only those source lines for which code instructions were generated by the compiler are recognized as executable lines by the debugger. The debugger skips over any other lines-for example, comment lines. Also, if a line has more than one statement on it, the debugger will execute all the statements on that line as part of the single step. You can specify different stepping modes, such as stepping by instruction rather than by line (SET STEP INSTRUCTION). To resume to the default behavior, issue the SET STEP LINE command. Also, by default, the debugger steps over called routines-execution is not suspended within a called routine, although the routine is executed. By issuing the SET STEP INTO command, you tell the debugger to suspend execution within called routines as well as within the currently executing module. To resume the default behavior, issue the SET STEP OVER command. 5.3.5.2 Determining the Current Location of the Program Counter The SHOW CALLS command lets you determine the current location of the program counter (PC) (for example, after returning to the debugger following a CTRL/Y interrupt). The command shows a traceback that lists the sequence of calls leading to the currently executing routine. For example: DBG> SHOW CALLS module name •TEST •TEST •MY_PROG DBG> 5-12 Using the VAX/VMS Debugger routine name PRODUCT COUNTER MY_PROG line 18 47 21 rel PC abs PC 00000009 0000063C 00000009 00000647 00000000 00000663 For each routine (beginning with the currently executing routine), the debugger displays the following information: • • • • The name of the module that contains the routine The name of the routine The line number at which the call was made (or at which execution is suspended, in the case of the current routine) The corresponding PC addresses (the relative PC address from the start of the routine and the absolute PC address of the program) This example indicates that execution is currently at line 18 of routine PRODUCT (in module TEST), which was called from line 47 of routine COUNTER (in module TEST), which was called from line 21 of routine MY_pROG (in module MY_pROG). 5.3.5.3 Suspending Program Execution The SET BREAK command lets you select breakpoints, which are locations at which the program will stop running. When you reach a breakpoint, you can issue commands to check the call stack, examine the current values of variables, and so on. A typical use of the SET BREAK command is illustrated in the following example: DBG> SET BREAK COUNTER DBG> GO break at TEST\COUNTER 34: SUB COUNTER(LONG X,Y) DBG> In this example, the SET BREAK command sets a breakpoint on the subprogram COUNTER; the GO command starts execution. When the subprogram COUNTER is encountered, execution is suspended, the debugger announces that the breakpoint at COUNTER has been reached ("break at ... "), displays the source line (34) where execution is suspended, and prompts you for another command. At this breakpoint, you could step through the subprogram COUNTER, using the STEP command, and use the EXAMINE command (discussed in Section 5.3.6.1) to check on the current values of X and Y. Using the VAX/VMS Debugger 5-13 When using the SET BREAK command, you can specify program locations using various kinds of address expressions (for example, line numbers, routine names, instructions, virtual memory addresses, byte offsets). With high-level languages, you typically use routine names, labels, or line numbers, possibly with path names to ensure uniqueness. Routine names and labels should be specified as they appear in the source code. Line numbers may be derived from either a source code display or a listing file. When specifying a line number, use the prefix %LINE. (Otherwise, the debugger will interpret the line number as a memory location.) For example, the next command sets a breakpoint at line 41 of the currently executing module; the debugger will suspend execution when the PC is at the start of line 41. DBG> SET BREAK %LINE 41 Note that you can set breakpoints only on lines that resulted in machine code instructions. The debugger warns you if you try to do otherwise (for example, on a comment line). If you want to pick a line number in a module other than the one currently executing, you need to specify the module's name in a path name. For example: DBG> SET BREAK SCREEN_IO\%LINE 68 You do not always have to specify a particular program location, such as line 58 or COUNTER, to set a breakpoint. You can set breakpoints on events, such as exceptions. You can use the SET BREAK command with a qualifier, but no parameter, to break on every line, or on every CALL instruction, and so on. For example: DBG> SET BREAK/LINE DBG> SET BREAK/CALL You can conditionalize a breakpoint (with a WHEN clause) or specify that a list of commands be executed at the breakpoint (with a DO clause on the debugger command). For example, the next command sets a breakpoint on the label LOOP3. The DO (EXAMINE TEMP) clause causes the value of the variable TEMP to be displayed whenever the breakpoint is triggered. DBG> SET BREAK LOOP3 DO (EXAMINE TEMP) DBG> GO break at COUNTER\LOOP3 37: LOOP3: FOR I = 1 TO 10 COUNTER\TEMP: 284.19 DBG> 5-14 Using the VAX/VMS Debugger To display the currently active breakpoints, type the SHOW BREAK command: DBG> SHOW BREAK breakpoint at SCREEN_IO\%LINE 58 breakpoint at COUNTER\LOOP3 do (EXAMINE TEMP) DBG> To cancel a breakpoint, type the CANCEL BREAK command, specifying the program location exactly as you did when setting the breakpoint. The CANCEL BREAK/ ALL command cancels all breakpoints. 5.3.5.4 Tracing Program Execution The SET TRACE command lets you select tracepoints, which are locations for tracing the execution of your program without stopping its execution. After setting a tracepoint, you can start execution with the GO command and then monitor the PC's path, checking for unexpected behavior. By setting a tracepoint on a routine, you can also monitor the number of times the routine is called. As with breakpoints, every time a tracepoint is reached, the debugger issues a message and displays the source line. It can also display other information that you have specified (as shown in the last example in this section, in which the value of a specified variable is displayed). However, at tracepoints, unlike breakpoints, the program continues executing, and the debugger prompt is not displayed. For example: DBG> SET TRACE COUNTER DBG> GO trace at TEST\COUNTER 34: SUB COUNTER(LONG X,Y) When using the SET TRACE command, you specify address expressions, qualifiers, and optional clauses exactly as with the SET BREAK command. Using the VAX/VMS Debugger 5-15 The /LINE qualifier causes the SET TRACE command to trace every line and is a convenient means of checking the execution path. By default, lines are traced within all called routines as well as the currently executing routine. If you do not want to trace system routines or routines in shareable images, use the /NOSYSTEM or /NOSHARE qualifiers. For example: DBG> SET TRACE/LINE/NOSYSTEM/NOSHARE The /SILENT qualifier suppresses the trace message and source code display. This is useful when you want to use the SET TRACE command to execute a debugger command at the tracepoint. For example: DBG> SET TRACE\SILENT %LINE 83 DO (EXAMINE STATUS) DBG> GO SCREEN_!O\CLEAR\STATUS: 5.3.5.5 'OFF' Monitoring Changes in Variables The SET WATCH command lets you set watchpoints that will be monitored continuously as your program executes. If the program modifies the value of a watched variable, the debugger suspends execution and displays the old and new values. DBG> SET WATCH TOTAL Subsequently, every time the program modifies the value of TOTAL, the watchpoint is triggered. The debugger monitors watchpoints continuously during program execution. The next example shows what happens when your program modifies the contents of a watched variable. 5-16 Using the VAX/VMS Debugger July 1988 DBG> SET WATCH TOTAL DBG> GO watch of SCREEN_IO\TOTAL\%LINE 13 13: TOTAL = TOTAL + 1 old value: 16 new value: 17 break at SCREEN_IO.%LINE 14 14: CALL Pop_rtn(TOTAL) DBG> In this example, a watchpoint is set on the variable TOTAL and the GO command starts execution. When the value of TOTAL changes, execution is suspended. The debugger announces the event ("watch of ... "), identifying where TOTAL changed (line 13) and the associated source line. The debugger then displays the old and new values and announces that execution has been suspended at the start of the next line (14). (The debugger reports "break at ... ", but this is not a breakpoint; it is still the effect of the watchpoint.) Finally, the debugger prompts for another command. When a change in a variable occurs at a point other than the start of a source line, the debugger gives the line number plus the byte offset from the start of the line. 5.3.6 Examining and Manipulating Data This section explains how to use the EXAMINE, DEPOSIT, and EVALUATE commands to display and modify the contents of variables, and evaluate expressions in VAX BASIC programs. July 1988 Usmg the VAX/VMS Debugger 5-17 5.3.6.1 Displaying the Values of Variables To display the current value of a variable, use the EXAMINE command as follows: DBG>EXAMINE variable_name The debugger recognizes the compiler-generated data type of the specified variable and retrieves and formats the data accordingly. The following examples show some uses of the EXAMINE command. Examine a string variable: DBG> EXAMINE EMPLOYEE_NAME PAYROLL\EMPLOYEE_NAME: "Peter C. Lombardi" DBG> Examine three integer variables: DBG> EXAMINE WIDTH, LENGTH, AREA SIZE\WIDTH: 4 SIZE\LENGTH: 7 SIZE\AREA: 28 DBG> Examine a two-dimensional array of integers (three per dimension): DBG> EXAMINE INTEGER_ARRAY PROG2\INTEGER_ARRAY (0,0): 27 (0,1): 31 (0,2): 12 (1,0): (1, 1): (1, 2): DBG> 22 18 15 Examine element 4 of a one-dimensional string array: DBG> EXAMINE CHAR_ARRAY(4) PROG2\CHAR_ARRAY(4): 'm' DBG> Note that the EXAMINE command can be used with any kind of address expression (not just a variable name) to display the contents of a program location. The debugger associates certain default data types with untyped locations. You can override the defaults for typed and untyped locations if you want the data to be interpreted and displayed in some other data format. The debugger supports the data types and operators of VAX BASIC including RECORDs and RFAs. 5-18 Using the VAX/VMS Debugger See Section 5.3.6.3 for an explanation of how the EXAMINE and the EVALUATE commands differ. 5.3.6.2 Changing the Values of Variables To change the value of a variable, use the DEPOSIT command as follows: DBG>DEPOSIT variable_name = value The DEPOSIT command is like an assignment statement in VAX BASIC. In the following examples, the DEPOSIT command assigns new values to different variables. The debugger checks that the value assigned, which may be a language expression, is consistent with the data type and dimensional constraints of the variable. Deposit a string value (it must be enclosed in quotation marks or apostrophes): DBG> DEPOSIT PARTNUMBER = "WG-7619.3-84" Deposit an integer expression: DBG> DEPOSIT WIDTH = CURRENT_WIDTH + 10 Deposit element 12 of an array of characters (you cannot deposit an entire array aggregate with a single DEPOSIT command, only an element): DBG> DEPOSIT C_ARRAY(12) = 1 K1 You can specify any kind of address expression, not just a variable name, with the DEPOSIT command (as with the EXAMINE command). You can override the defaults for typed and untyped locations if you want the data to be interpreted in some other data format. 5.3.6.3 Evaluating Expressions To evaluate a language expression, use the EVALUATE command as follows: DBG> EVALUATE lang_exp The debugger recognizes the operators and expression syntax of the currently set language. In the following example, the value 45 is assigned to the integer variable WIDTH; the EVALUATE command then obtains the sum of the current value of WIDTH plus 7: Using the VAX/VMS Debugger 5-19 DBG> DEPOSIT WIDTH = 46 DBG> EVALUATE WIDTH + 7 62 DBG> Following is an example of how the EVALUATE and the EXAMINE commands are similar. When the expression following the command is a variable name, the value reported by the debugger is the same for either command: DBG> DEPOSIT WIDTH = 46 DBG> EVALUATE WIDTH 46 DBG> EXAMINE WIDTH SIZE\WIDTH: 46 Following is an example of how the EVALUATE and EXAMINE commands are different: DBG> EVALUATE WIDTH + 7 62 DBG> EXAMINE WIDTH + 7 SIZE\WIDTH: 131684 With the EVALUATE command, WIDTH+ 7 is interpreted as a language expression, which evaluates to 45 + 7, or 52. With the EXAMINE command, WIDTH+ 7 is interpreted as an address expression: 7 bytes are added to the address of WIDTH, and whatever value is in the resulting address is reported (in this instance, 131584). 5.3.6.4 Stepping Into VAX BASIC Routines This section provides details of the STEP /INTO command that are specific to VAX BASIC. In the following example, the debugger is waiting to proceed at source line 2. If you issue a STEP command at this point, the debugger will proceed to source line 3 without stopping during the execution of the function call. To examine the source code in the EXTERNAL FUNCTION extfun, you must use the STEP /INTO command. A STEP /INTO command entered while the debugger has stopped at source line 2, will cause the debugger to display the source code for extfun and stop execution at source code line 63. 5-20 Using the VAX/VMS Debugger 1 ->2 3 63 10 EXTERNAL REAL FUNCTION extfun (real) a = extfun (8) PRINT a 100 FUNCTION REAL extfun (a) extfun = a * 3 END FUNCTION The STEP /INTO command is useful for examining external functions. However, if you use this command to stop execution at an internal subroutine or a DEF, the debugger steps into Run-Time Library (RTL) routines, providing you with no useful information. For example, in the following partial program, the debugger has suspended execution at source line 8. If you now enter a STEP /INTO command, the debugger steps into the relevant RTL code and informs you that no source lines are available. 1 10 ->8 9 RANDOMIZE GOSUB Print_routine STOP 23 24 Print_routine: IF Competition = Done THEN PRINT "The winning ticket is #";Winning_ticket ELSE PRINT "The game goes on. 11 END IF 25 RETURN 20 21 22 As in the previous example, a STEP command alone will cause the debugger to proceed directly to source line 9. To examine the source code of subroutines or DEF functions, you should use the SET BREAK command. The SET BREAK command is described in Section 5.3.5.3. In this case, a breakpoint set at the label Print_routine allows you to examine the subroutine beginning at source line 20. Using the VAX/VMS Debugger 5-21 5.3. 7 Controlling Symbol References In most cases, the way the debugger handles symbols is transparent to you. However, the following areas may require action on your part: • • 5.3. 7 .1 Module setting Multiply-defined symbols Module Setting To facilitate symbol searches, the debugger loads symbol records from the executable image into a run-time symbol table (RST), where they can be accessed efficiently. Unless a symbol record is in the RST, the debugger cannot recognize or properly interpret that symbol. Because the RST takes up memory, the debugger loads it dynamically, anticipating what symbols you might want to reference in the course of execution. The loading process is called module setting, because all of the symbol records of a given module are loaded into the RST at one time. At debugger startup, only the module containing the image transfer address is set. As your program executes, whenever the debugger interrupts execution it sets the module surrounding the current PC location. This lets you reference the symbols that should be visible at the current PC location. If you try to reference a symbol in a module that has not been set, the debugger will warn you that the symbol is not in the RST. For example: DBG> EXAMINE K Y.DEBUG-W-NOSYMBOL, symbol 'K' is not in symbol table DBG> You must then use the SET MODULE command to set the module containing that symbol manually: DBG> SET MODULE MOD3 DBG> EXAMINE K MOD3\ROUT2\K: 26 DBG> The SHOW MODULE command lists the modules of your program and identifies which modules have been set. 5-22 Using the VAX/VMS Debugger A successful FIND or GET operation must precede the DELETE operation. These operations make the target record available for deletion. In the following example, the FIND statement locates record 67 in a relative file and the DELETE statement removes this record from the file. Because the cell itself is not deleted, you can use the PUT statement to write a record into that cell after deleting its contents. FIND #1%, RECORD 67% DELETE #1% NOTE There is no current record after a deletion. The next record pointer is unchanged. 15.6.7 Updating Records UPDATE writes a new record at the location indicated by the current record pointer. UPDATE is valid on RMS sequential, relative, and indexed files. The UPDATE statement operates on the current record, provided that you have write access to that record. In order to successfully update a variablelength record, you must know the exact size of the record you want to update. VAX BASIC has access to this information after a successful GET operation. If you have not performed a successful GET operation on the variable-length record, then you must specify a COUNT clause in the UPDATE statement that contains the record size information. If you are updating a variable length record, and the record that you want to write out is of different size than the record you retrieved, you must use a COUNT clause. An UPDATE will fail with the exception "No current record" (ERR= 131) if you have not previously established a current record with a successful GET or FIND. Therefore, when updating records you should include error trapping in your program to make sure all GET operations execute successfully. An UPDATE operation on a sequential file is valid only when: • • The file containing the record is on disk The new record is the same size as the one it is replacing July 1988 File Input and Output 15-23 • You have established a current record via a GET or FIND operation. Note that COUNT defaults to the size of the current record if a GET was performed. If a FIND operation was used to locate the current record, then you must supply a COUNT value. The following program searches to find a record in which the L_name field matches the specified Search_name$. Once this record is found and retrieved, the Rm_num field of that record is updated; the program then prompts for another Search_name$. If a match is not found, VAX BASIC prints the message No such record and prompts the user for another Search_name$. The program ends when the user enters a null string for the Search_name$ value. 11 11 Example MAP (AAA) STRING L_name = 60%, F_name = 20%, Rm_num = 8% OPEN 11 STU.DAT 11 FOR INPUT AS FILE #Q%, & ORGANIZATION SEQUENTIAL FIXED, MAP AAA INPUT "Last name";Search_name$ Search_name$ = EDIT$(Search_name$, -1%) IF Search_name$ = 1111 THEN GOTO 32010 END IF RESTORE #9% WHEN ERROR IN GET #9% WHILE Search_name$ <> L_name USE IF ERR=11 THEN PRINT "No such record" CONTINUE 50 ELSE EXIT HANDLER END IF END WHEN INPUT "Room number";Rm_num UPDATE #9% GOTO 50 CLOSE #9% PRINT "Update complete" END 20 30 50 55 60 65 70 75 80 90 100 32010 32030 32767 NOTE An UPDATE operation invalidates the value of the current record pointer. The next record pointer is unchanged. 15-24 File Input and Output When you update a record in a relative variable file, the new record can be larger or smaller than the record it replaces, provided that it is smaller than the maximum record size set for the file. When you update a record in an indexed variable file, the new record can also be larger or smaller than the record it replaces. The updated record: • • Can be no longer than the maximum record size, if specified Must include at least the primary key field File Input and Output 15-24.1 $ BASIC/LIST/DEBUG SAMPLE 0 $ LINK/DEBUG SAMPLE f) $ RUN SAMPLE VAX DEBUG Version 4.n %DEBUG-I-INITIAL, language is BASIC module set to 1 SAMPLE$MAIN' C) DBG> (STEP 2) 8 NUMBER SQUARE SQUARE ROOT stepped to SAMPLE$MAIN\Y.line 7 7: FOR Number = 10 TO 1 STEP -1 0 DBG> STEP 4 10 100 3.16228 stepped to SAMPLE$MAIN\Y.LINE 7 7: FOR Number = 10 TO 1 STEP -1 DBG> EXAMINE Number f) SAMPLE$MAIN\NUMBER: 10 0 DBG> STEP 4 CD 10 100 3.16228 stepped to SAMPLE$MAIN\Y.LINE 7 7: FOR Number = 10 TO 1 STEP -1 DBG> EXAMINE Number ~ SAMPLE$MAIN\NUMBER: 10 4J> DBG> DEPOSIT Number = 9 48 DBG> STEP 4 41) 9 81 3 stepped to SAMPLE$MAIN\Y.LINE 7 7: FOR Number = 10 TO 1 STEP -1 DBG> EXAMINE Number CD SAMPLE$MAIN\NUMBER: 9 G) DBG> STEP 9 81 3 stepped to SAMPLE$MAIN\Y.LINE 8 8: PRINT Number, NumberA2, SQR(Number) ~ DBG> STEP ~ stepped to SAMPLE$MAIN\Y.LINE 9 9: Number = Number + 1 4D DBG> EXIT G) ca e 0 Compile SAMPLE.BAS with the /LIST and /DEBUG qualifiers. The listing file may be useful while you are in the debugging session. f) Link SAMPLE.BAS with the /DEBUG qualifier. C) The debugger identifies itself and displays the debugger prompt after you invoke the debugger with the RUN command. G Step through 2 executable statements to the FOR statement. 0 The headers print successfully and the program reaches the FOR statement. ca Step through one iteration of the loop. f) Request the contents of the variable Number. 0 The debugger shows the contents of the loop index to be 10. Using the VAX/VMS Debugger 5-25 C> Step through another iteration of the loop. GD Examine the value of the loop index again. 41 The debugger shows that the loop index is still 10. The loop index has not changed from its initial setting in the FOR statement. • Deposit the correct value into Number. 48 Step through another iteration of the loop. 4D Examine the contents of Number again. 49 Observe that the number has not been changed yet. 48 Step through just one statement to discover what is interferring with the value of Number during execution of the loop. 4D Observe that this statement does not affect the value of Number. 4D Step through another statement in the loop. ~ Observe that this statement counteracts the change in the loop index. 9 Exit from the debugger. You can now edit the program to delete line 9 and reprocess the program. Alternatively, you could use the EDIT command while in the debugger environment. This debugging session shows that the FOR ... NEXT loop index (Number) is not being changed correctly. An examination of the statements in the loop shows that the variable Number is being decreased by one during each execution of the FOR statement, but incremented by one with each execution of the loop statements. From this you can determine that the loop index will not change at all and the program will loop indefinitely. To correct the problem, you must delete the incorrect statement and recompile the source program. 5.5 Debugger Command Summary Table 5-1 lists all of the debugger commands and any related DCL commands in functional groupings, along with brief descriptions. During a debugging session, you can get online HELP on any command and its qualifiers by typing the HELP command followed by the name of the command in question, in this format: HELP command 5-26 Using the VAX/VMS Debugger Table 5-1: Debugger Command Summary Command Description Starting and Terminating a Debugging Session ($) RUN 1 Invokes the debugger if LINK/DEBUG was used ($) RUN/[NO]DEBUG 1 Controls whether the debugger is invoked when the program is executed CTRL/Z or EXIT Ends a debugging session, executing all exit handlers QUIT Ends a debugging session without executing any exit handlers declared in the program CTRL/Y Interrupts a debugging session, returning you to DCL level CTRL/C Has the same effect as CTRL/Y, unless the program has a CTRL/C service routine ($) CONTINUE 1 Resumes a debugging session after a CTRL/Y interruption ($) DEBUG 1 Resumes a debugging session after a CTRL/Y interruption but returns you to the debugger prompt ATTACH Passes control of your terminal from the current process to another process (similar to the DCL command ATTACH) SPAWN Creates a subprocess; lets you issue DCL commands without interrupting your debugging context (similar to the DCL command SPAWN) 1 This is a DCL command, not a debugger command. Using the VAX/VMS Debugger 5-27 Table 5-1 (Cont.): Debugger Command Summary Description Command Controlling and Monitoring Program Execution GO Starts or resumes program execution STEP Executes the program up to the next line, instruction, or specified instruction {SET } STEP SHOW Establishes or displays the default qualifiers for the STEP command SET } BREAK SHOW CANCEL Sets, displays, or cancels breakpoints SET } TRACE SHOW CANCEL SET } WATCH SHOW CANCEL SET EXCEPTION CANCEL BREAK Sets, displays, or cancels tracepoints { { { { } Sets, displays, or cancels watchpoints Sets or cancels exception breakpoints SHOW CALLS Identifies the currently active routine calls SHOW STACK Gives additional information about the currently active routine calls CALL Calls a routine Examining and Manipulating Data 5-28 EXAMINE Displays the value of a variable or the contents of a program location DEPOSIT Changes the value of a variable or the contents of a program location EVALUATE Evaluates a language or address expression Using the VAX/VMS Debugger Table 5-1 (Cont.): Debugger Command Summary Command Description Controlling Type Selection and Symbolization SET SHOW RADIX { CANCEL } Establishes the radix for data entry and display, displays the radix, or restores the radix SET SHOW } TYPE { CANCEL Establishes the type to be associated with untyped program locations, displays the type, or restores the type SET MODE [NO]G_FLOAT Controls whether double-precision floatingpoint constants are interpreted as G_fLOAT or D_FLOAT SET MODE [NO]LINE Controls whether code locations are displayed in terms of line numbers or routine-name+ byte offset SET MODE [NO]SYMBOLIC Controls whether code locations are displayed symbolically or in terms of numeric addresses SYMBOLIZE Converts a virtual address to a symbolic address Controlling Symbol Lookup SHOW SYMBOL Displays symbols in your program SET } MODULE SHOW { CANCEL Sets a module by loading its symbol records into the debugger's symbol table, identifies a set module, or cancels a set module SET { ~~~~EL } IMAGE Sets a shareable image by loading data structures into the debugger's symbol table, identifies a set image, or cancels a set image SET MODE [NO]DYNAMIC Controls whether or not modules are set automatically when the debugger interrupts execution ALLOCATE Expands the debugger's memory pool to let you set more modules { SET } SHOW SCOPE CANCEL Establishes, displays, or restores the scope for symbol lookup Using the VAX/VMS Debugger 5-29 Table 5-1 (Cont.): Debugger Command Summary Command Description Displaying Source Code TYPE Displays lines of source code EXAMINE/SOURCE Displays the source code at the location specified by the address expression { Creates, displays, or cancels a source directory search list SET } SHOW SOURCE CANCEL SEARCH Searches the source code for the specified string } SEARCH { SET SHOW Establishes or displays the default qualifiers for the SEARCH command SET } { SHOW Establishes or displays the maximum number of source files that may be kept open at one time MAX_SOURCE_ FILES } MARGINS { SET SHOW Establishes or displays the left and right margin settings for displaying source code Using Screen Mode SET MODE [NO]SCREEN Enables or disables screen mode SET MODE [NO]SCROLL Controls whether an output display is updated line by line or once per command DISPLAY SET } DISPLAY { SHOW CANCEL SET } WINDOW SHOW { CANCEL Modifies an existing display Creates, identifies, or deletes a display Creates, identifies, or deletes a window definition SELECT Selects a display for a display attribute SHOW SELECT Identifies the displays selected for each of the display attributes SCROLL Scrolls a display 5-30 Using the VAX/VMS Debugger Table 5-1 (Cont.): Debugger Command Summary Command Description Using Screen Mode SAVE Saves the current contents of a display into another display EXTRACT Saves a display or the current screen state into a file EXPAND Expands or contracts a display MOVE Moves a display across the screen SET } TERMINAL { SHOW Establishes or displays the height and width of the screen CTRL/W or DISPLAY /REFRESH Refreshes the screen Editing Source Code EDIT Invokes an editor during a debugging session } EDITOR { SET SHOW Establishes or identifies the editor invoked by the EDIT command Defining Symbols DEFINE Defines a symbol as an address, command, or value DELETE or UNDEFINE Deletes symbol definitions } DEFINE { SET SHOW Establishes or displays the default qualifier for the DEFINE command SHOW SYMBOL/DEFINED Identifies symbols that have been defined Using Keypad Mode SET MODE [NO]KEYP AD Enables or disables keypad mode DEFINE/KEY Creates key definitions DELETE/KEY or UNDEFINE/KEY Deletes key definitions } KEY { SET SHOW Establishes the key definition state or displays key definitions Using the VAX/VMS Debugger 5-31 Table 5-1 (Cont.): Debugger Command Summary Command Description Using Command Procedures and Log Files DECLARE Defines parameters to be passed to command procedures } LOG { SET SHOW Specifies or identifies the debugger log file SET OUTPUT [NO]LOG Controls whether a debugging session is logged SET OUTPUT [NO]SCREEN _ LOG Controls whether, in screen mode, the screen contents are logged as the screen is updated SET OUTPUT [NO]VERIFY Controls whether debugger commands are displayed as a command procedure is executed SHOW OUTPUT Displays the current output options established by the SET OUTPUT command } ATSIGN { SET SHOW Establishes or displays the default file specification that the debugger uses to search for command procedures @file-spec Executes a command procedure Using Control Structures IF Executes a list of commands conditionally FOR Executes a list of commands repetitively REPEAT Executes a list of commands repetitively WHILE Executes a list of commands conditionally EXITLOOP Exits an enclosing WHILE, REPEAT, or FOR loop Miscellaneous Commands 5-32 SET OUTPUT [NO]TERMINAL Controls whether debugger output is displayed or suppressed, except for diagnostic messages } LANGUAGE { SET SHOW Establishes or displays the current language SET } { SHOW Establishes or identifies the current run-time facility for language-specific events Using the VAX/VMS Debugger EVENL FACILITY Table 5-1 (Cont.): Debugger Command Summary Command Description Miscellaneous Commands SHOW EXIT_HANDLERS Identifies the exit handlers declared in the program } TASK { SET SHOW Modifies the tasking environment or displays task information { DISABLE } ENABLE AST SHOW Disables the delivery of ASTs in the program, enables the delivery of ASTs, or identifies whether delivery is enabled or disabled Using the VAX/VMS Debugger 5-33 VAX BASIC PROGRAMMING CONCEPTS Chapter 6 Getting Started with VAX BASIC A VAX BASIC program is a series of instructions for the VAX BASIC compiler. These instructions, no matter how varied, are all built using the same fundamental elements of VAX BASIC. This chapter describes the elements or building blocks of VAX BASIC. 6.1 Line Numbers Traditionally, BASIC programs consisted of statements preceded by unique line numbers. However, VAX BASIC gives you the option of developing programs with traditional line numbers or programs with no line numbers at all. 6.1.1 Programs with Line Numbers If you use line numbers in your programs, you must follow these rules: • • • • • A line number must be a unique integer between 1 and 32767 (If your program has duplicate line numbers, the last line with that number replaces the previous one). A line number must begin in the first character position on the line. A line number can contain leading zeros; however, embedded spaces, tabs, and commas are invalid in line numbers. There must be a line number on the first line of the program If a source file contains subprograms, then each subprogram must begin on a numbered line. Getting Started with VAX BASIC 6-1 • • The line number of a subprogram must be greater than that of any preceding subprogram line number. Text following an END, END SUB, or END FUNCTION statement must begin on a numbered line. Note that in a multiple-unit program with line numbers, any comments following an END, END SUB, or END FUNCTION statement become a part of the previous subprogram during compilation unless they begin on a numbered line. This is not the case in multiple-unit programs without line numbers. Although line numbers are not required, you may want to use them on every line that can cause a run-time error, depending on the type of error handling you use. See Chapter 17 for more information about handling run-time errors. 6.1.2 Programs Without Line Numbers If you do not use line numbers in your programs, you must follow these rules: • • • • • • • Use a text editor to enter and edit the program; you cannot enter programs without line numbers directly in the environment. No line numbers are allowed anywhere in the program module. The ERL function is not allowed. Do not use the RESUME statement with a line number as a target. REM statements are not allowed. If a source file contains subprograms, any text following an END, END SUB, or END FUNCTION statement must begin on a new physical line. Other files cannot be appended, because appended files must contain at least one line number. Note that in a multiple-unit program without line numbers, any comments following an END, END SUB, or END FUNCTION statement become a part of the next subprogram during compilation (unless there is no next subprogram). This is not the case in multiple-unit programs with line numbers. 6-2 Getting Started with VAX BASIC Note that you can avoid all of these restrictions by placing a line number on the first line of your program; no additional line numbers are required. The line number on the first program line causes the VAX BASIC compiler to compile your program as a program with line numbers. When you enter a program with or without line numbers, you can begin your program statements in the first character position on a line. While these statements would be considered immediate mode statements if entered in the BASIC environment, they are valid in a program that is created with a text editor. For example, you can enter the following program directly into the environment: Example 10 !This is a short program that you can enter !and run in the BASIC environment PRINT "This program will convert pound weight to kilograms" INPUT "How many pounds";A !Here is the conversion step B = A * 2.2 PRINT "For ";A;" pounds, the kilogram weight is ";B END Output This program will convert pound weight to kilograms How many pounds? 10 For 10 pounds, the kilogram weight is 22 In order to develop the following program, you have to use a text editor, and you must observe the restrictions listed above. Getting Started with VAX BASIC 6-3 Example !This is a short program that does not contain any !VAX BASIC line numbers. !This program must be entered using a text editor; !it cannot be entered directly into the environment. ! PRINT "This program converts kilogram weight to pounds" INPUT "How many kilograms";A !This is the conversion factor B = A I 2.2 PRINT "For ";A;" kilograms, the pound weight is ";B END Output This program converts kilogram weight to pounds How many kilograms? 11 For 11 kilograms, the pound weight is 6 Note that you can use exclamation comment fields instead of REM statements to insert comments into programs without line numbers. An exclamation mark in column 1 in the environment causes the VAX BASIC compiler to ignore the rest of the line. You can also identify program statements in programs without line numbers by using labels. 6.1.3 Labels A label is a 1- to 31-character identifier that you use to identify a block of statements. All label names must begin with a letter; the remaining characters, if any, can be any combination of letters, digits, dollar signs ( $ }, underscores ( _) or periods ( . ). Labels have two advantages over line numbers: • • Meaningful label names provide documentation. You can use labels in programs with or without line numbers. When you use a label to mark a program location, you must end the label with a colon ( : ). The colon is used to show that the label name is being defined instead of referenced. When you reference the label, do not include the colon. In the following example, the label names end with colons when they mark a location, but the colons are not present when the labels are referenced. 6-4 Getting Started with VAX BASIC Example OPTION TYPE = EXPLICIT DECLARE INTEGER A ! Require declarations Outer_decision: IF A <> B THEN Inner_decision: IF B = C THEN A=A+ 1 GOTO Outer_loop ELSE B =B + 1 GOTO Inner_loop END IF END IF Labels have no effect on the order in which program lines are executed; they are used to identify a statement or block of statements. 8.1.4 Continuation of long Program Statements If a program line is too long for one line of text, you can continue the program line by typing an ampersand ( & ) and pressing the RETURN key at the end of the line. Note that only spaces and tabs are valid between the ampersand and the carriage return. A single statement that spans several text lines requires an ampersand at the end of each continued line. For example: OPEN "SAMPLE.DAT" AS FILE 12i, SEQUENTIAL VARIABLE, RECORDSIZE soi t t In an IF ... THEN ...ELSE construction, statement separators are not necessary. If a continuation line begins with THEN or ELSE, then no statement separator is necessary. Similarly, in a line following a THEN or ELSE, there is no statement separator. Getting Started with VAX BASIC 6-5 Example IF (A$ = 8$) THEN PRINT "The two values are equal" ELSE PRINT "The two values are different" END IF Several statements can be associated with a single program line. If there are several statements on one line, they must be separated by backslashes ( \ ). For example: PRINT A \ PRINT V \ PRINT G Because all statements are on the same program line, any reference to this program line refers to all three statements. In the preceding example, VAX BASIC cannot execute just one of the statements without executing the other two. 6.2 Identifying Program Units You can delimit a main program compilation unit with the PROGRAM and END PROGRAM statements. This allows you to identify a program with a name other than the file name. The program name must not duplicate the name of a SUB, FUNCTION, or PICTURE subprogram. PROGRAM Sort_out END PROGRAM If you include the PROGRAM statement in your program, the name you specify becomes the module name of the compiled source. This feature is useful when you use object libraries because the librarian stores modules by their module name rather than the file name. Similarly, module names are used by the VAX/VMS Debugger and the VAX/VMS Linker. For more information about PROGRAM units, see Chapter 14. 6-6 Getting Started with VAX BASIC 6.3 The VAX BASIC Character Set VAX BASIC uses the full ASCII character set, which includes the following: • • • The letters A through Z, both upper- and lowercase The digits 0 through 9 Special characters See the VAX BASIC Reference Manual for a complete list of the ASCII character set and character values. The VAX BASIC compiler does not distinguish between upper- and lowercase letters, except letters inside quotation marks (called string literals) or letters in a DATA statement. The compiler also does not process characters in a REM statement or comment field. You can use nonprinting characters in your program, for example, in string literals and constants, but to do so you must do one of the following: • • Use a predefined constant such as ESC or DEL Use the CHR$ function to specify an ASCII value See Section 6.6 for more information on predefined constants. See Chapter 13 for more information on the CHR$ function. 6.4 Program Documentation Documenting a program is the process of mixing text (comments) and code in a way that helps make the program more understandable. Program documentation does not affect the way a program executes. You can sprinkle comments liberally throughout a program; however, programs that are neatly structured need fewer comments. You can clarify your code by • • • Using meaningful variable names Including sufficient white space Indenting your program lines according to the structure of your code Getting Started with VAX BASIC 6-7 In VAX BASIC, a comment field starts with an exclamation point ( !) and ends with a carriage return. The following example contains both comments and program statements. VAX BASIC ignores any text that follows an exclamation point. Example PROGRAM sample !+ ! !- Require that all variables be declared !+ ! !- Set up error handler OPTION TYPE = EXPLICIT WHEN ERROR USE Error_routine !+ ! !- Declarations END PROGRAM You can also mix comments and code on the same line. Example DECLARE INTEGER Print_page, Print_line, Print_column Current page number Current line number Current column number In this case, VAX BASIC ignores all text between the exclamation point and the carriage return, with one exception: VAX BASIC still recognizes the ampersand. This is a continuation character that specifies that a single statement is being continued on the next line. Only spaces and tabs are valid between the ampersand and the carriage return. NOTE You can also terminate a comment field with an exclamation point. However, because VAX BASIC treats any text that follows the second exclamation point as part of your program code, this practice is not recommended. 6-8 Getting Started with VAX BASIC 6.5 Declarations and Data Types VAX BASIC offers two different methods for creating variables and specifying their data types: • • Implicit data typing Explicit data typing With implicit data typing, VAX BASIC creates and specifies a data type for a variable the first time you reference it in your program. With explicit data typing, you must use one of four declarative statements to name and type your program values. VAX BASIC has five data types: • • • • • Integer (INTEGER) Floating-point (REAL) String (STRING) Packed Decimal (DECIMAL) Record File Address (RFA) Within the INTEGER and REAL data types there are further subdivisions: BYTE, WORD, or LONG for INTEGER and SINGLE, DOUBLE, GFLOAT, or HFLOAT for REAL. Choosing one of these subtypes lets you control two things: • • The amount of storage required for the value; its "container size" The range and precision that the value can accept For more information about data types, see Chapter 9. 8.5.1 Implicit Data Typing With implicit data typing, VAX BASIC creates and specifies a data type for a variable the first time you reference it. You specify the data type of the variable by a suffix on the variable name: • • • A percent sign suffix (%)specifies the INTEGER data type. A dollar sign suffix ($)specifies the STRING data type. Any other ending character specifies a variable of the default data type. Getting Started with VAX BASIC 6-9 The VAX BASIC default data type is SINGLE; however, you can specify your own default at DCL command level, inside the BASIC environment, or with the OPTION statement in your program. For more information on establishing default data types, see Chapters 3 and 4 and the OPTION statement in the VAX BASIC Reference Manual. The first time VAX BASIC references one of these variables, it creates a variable with that name and data type and allocates storage for that variable. In the following example, VAX BASIC creates two INTEGER variables, A% and B%. Even though the values assigned to these variables are REAL, VAX BASIC converts these values to INTEGER to match the data type specified for the variables. The sum of these two values is therefore 30, not 30.6 as it would be if the variables were named simply A and B. Example AY. = 10.1 BY. = 20.5 PRINT AY. + BY. Output 30 With explicit data typing, you use a declarative statement to name and specify a data type for your program values. 8.5.2 Explicit Data Typing VAX BASIC has four declarative statements. These statements create variables and allocate storage. The statements are • • • • 6-10 DECLARE DIMENSION COMMON MAP Getting Started with VAX BASIC The statement you choose depends on the way in which you will use the variables: • • DECLARE and DIMENSION allocate dynamic storage for variables; storage is allocated when the program executes. COMMON and MAP statements allocate storage for variables statically; storage is allocated when the program is compiled. The difference between these types of storage is most apparent in the case of strings; string variables created with DECLARE can change their length during program execution, while those created with MAP and COMMON remain fixed in length. All four declarative statements associate a data type with a variable. For more information, see Chapter 9. 6.6 Constants A constant is a value that does not change during program execution. Constants can be either literals or named constants, and can be of any data type except RFA. You can use the DECLARE CONSTANT statement to create named constants. Constants can be of the following types: • • • Integer Floating-point String In addition, VAX BASIC provides predefined constants that are useful for: • • • Formatting program output to improve clarity Making source code easier to understand Using nonprinting characters without having to look up their ASCII values Table 6-1 lists all of the VAX BASIC predefined constants. Getting Started with VAX BASIC 6-11 Table 6-1: Predefined Constants Constant Decimal ASCII Value Purpose BEL (Bell) 7 Sounds the terminal bell BS (Backspace) 8 Moves cursor one position to the left HT (Horizontal Tab) 9 Moves cursor to the next horizontal tab stop LF (Line Feed) 10 Moves cursor to the next line VT (Vertical Tab) 11 Moves cursor to the next vertical tab stop FF (Form Feed) 12 Moves cursor to the start of the next page CR (Carriage Return) 13 Moves cursor to the beginning of the current line SO (Shift Out) 14 Shifts out for communications networking, screen formatting, and alternate graphics SI (Shift In) 15 Shifts in for communications networking, screen formatting, and alternate graphics ESC (Escape) Marks the beginning of an escape sequence DEL (Delete) 27 32 127 PI None Represents the number PI with the precision of the default floating-point data type SP (Space) Inserts one blank space in program output Deletes the last character entered These predefined constants simplify the task of using nonprinting characters in your programs. For example, the following statement causes a bell to sound on your terminal: PRINT BEL The following statement prints and underlines a word on a hard copy terminal: PRINT "NAME:" +BS+ BS+ BS+ BS+ BS+ "-----" To print and underline the same word on a VTlOO series video display terminal, use the following statement. Note that the "m" in the following example must be lowercase: PRINT ESC + "[4mNAME:" + ESC + "[Om" 6-12 Getting Started with VAX BASIC You can also create your own predefined constants with the DECLARE CONSTANT statement. The following statements define and print a constant that prints and underlines the string "NAME:": DECLARE STRING CONSTANT Underlined_word = ESC + "[4mNAME:" + ESC + "[Om" PRINT Underlined_word For more information on constants, see Chapter 9 and the VAX BASIC Reference Manual. 6.7 Variables A variable is a unique storage location that is referred to by a variable name. The most important property of variables is that their values can change during program execution. Each named location can hold only one value at a time. A variable name can have up to 31 characters. The name must begin with a letter; the remaining characters, if any, can be any combination of letters, digits, dollar signs ( $ ), underscores ( _ ), and periods ( . ). Variables can be grouped in an orderly series under a single name. These groups are called arrays. You refer to a single variable in an array by using one or more subscripts that specify the variable's position in the array. &. 7. 1 Floating-Point Variables A floating-point variable is a named location that stores a single floatingpoint value. The storage space required to hold the value depends on the variable's REAL subtype. For example, each SINGLE floating-point variable requires 32 bits (4 bytes) of storage, while each DOUBLE floatingpoint variable requires 64 bits (8 bytes) of storage. Note that if any integer value is assigned to a floating-point variable, VAX BASIC converts the value to a floating-point number. Getting Started with VAX BASIC 6-13 8. 7.2 Integer Variables An integer variable is a named location that stores a whole number. The storage space required to hold the value depends on the variable's INTEGER subtype. For example, each BYTE integer variable requires 8 bits (1 byte) of storage, while each LONG integer variable requires 32 bits (4 bytes) of storage. If you assign a floating-point value to an integer variable, VAX BASIC truncates the fractional portion of the value; it does not round to the nearest integer. In the following example, VAX BASIC assign the value -5 to the integer variable, not -6. BX= 8.7 .3 -5.7 Packed Decimal Variables A packed decimal (DECIMAL data type) variable is made up of several storage locations, the number of which depends on the declared size of the variable. However, a packed decimal variable is still referred to by a single variable name. When you declare a packed decimal variable, you specify the total number of digits and the number of digits to the right of the decimal place that you want. The following statement creates a packed decimal variable named My_decimal, which can contain up to eight digits: six digits to the left of the decimal point, and two digits to the right of the decimal point. OPTION TYPE = EXPLICIT DECLARE DECIMAL (8,2) My_decimal Packed decimal numbers are most useful for dollars-and-cents calculations. 8. 7.4 String Variables Unlike some of the numeric variables described so far, a string variable does not correspond to a single location in memory because a string variable is more likely to exceed a single location in memory. Therefore, the value of a string variable may be contained in any number of memory locations. However, a string variable is still referred to by a single name: DECLARE STRING Employee_name 6-14 Getting Started with VAX BASIC &. 7.5 Subscripted Variables A subscripted variable is a floating-point, integer, packed decimal, RFA, or string variable that is part of an array. Chapter 8 describes arrays in detail. An array is a set of data organized in one or more dimensions. A onedimensional array is called a list or vector. A two-dimensional array is called a matrix. VAX BASIC arrays can have up to 32 dimensions. When you create an array, its size is determined by the number of dimensions and the maximum size, called the bound, of ea~h dimension. Subscripts begin by default with 0, not 1. That is, when calculating the number of elements in a dimension, you count from zero to the bound specified. The following DECLARE statement creates an 11 by 11 array of integers (11 by 11 rather than 10 by 10, because VAX BASIC arrays are zero-based by default). Therefore the array contains a total of 121 array elements. DECLARE INTEGER My_array (10, 10) There are many applications where you need to reference data for a particular range of values. In order to do this, VAX BASIC lets you specify a lower bound other than zero for your arrays. The following example declares an array containing the birth rates for the years between 1945 and 1985: OPTION TYPE = EXPLICIT, SIZE = REAL SINGLE t DECLARE REAL Birth_rates(1946 TO 1986) Subscripts define the position of an element in an array; the expression Birth_rates(l 970) refers to the 26th value (represented by 1970) of the array Birth_rates. For more information on arrays, see Chapter 8. NOTE By default, the compiler signals an error if a subscript is larger than the allowable range. Also, the amount of storage that the system can allocate depends on available memory. Therefore, very large arrays may cause an internal allocation error. VAX BASIC sets variables to zero or null values at the start of program execution; that is, it initializes them. Variables initialized by VAX BASIC include the following. Getting Started with VAX BASIC 6-15 • • • • Numeric variables and array elements (except those in MAP or COMMON statements). String variables and array elements (except those in MAP or COMMON statements). Variables in subprograms. Subprogram variables (except those in MAP or COMMON statements) are initialized to zero or the null string each time the subprogram is called. Arrays created with an executable DIMENSION statement. VAX BASIC reinitializes the array each time the array is redimensioned. 6.8 Keywords and Reserved Words Keywords are elements of the VAX BASIC language. Keywords that are not reserved can be used as user identifiers such as labels, variable or constant names, or names of MAP or COMMON areas. Depending upon the location of the keyword in your program statement, the compiler will treat it as either a keyword or a user identifier. Your VAX BASIC programs use keywords and reserved words to • • • Define data Perform operations Invoke functions See the VAX BASIC Reference Manual for a list of VAX BASIC keywords and reserved words. Keywords determine whether the statement is executable or nonexecutable. Executable statements such as PRINT, GOTO, and READ perform operations. Nonexecutable statements such as DATA, DECLARE, and REM, describe the characteristics and arrangement of data, usage information, and comments. Every statement except LET and empty statements (lines that start with an exclamation point) must begin with a keyword. A VAX BASIC keyword cannot have embedded spaces or be split across lines of text. There must be a space or tab between the keyword and any other variables or operators. There are also phrases of keywords. In this case, the spacing requirements vary. 6-16 Getting Started with VAX BASIC 6.9 Operands, Operators and Expressions An operand is anything that contains a value. An operand can be a scalar, a subscripted variable, a named constant, a literal, and so on. An operator specifies a procedure to be carried out one or more operands. An expression consists of operands separated by operators. VAX BASIC has four types of operators: • • • • Arithmetic String Relational Logical When combined with operands, these operators can produce • • • Numeric expressions String expressions Conditional expressions For more information about operands, operators, and expressions, see the VAX BASIC Reference Manual. 6.10 Assignment Statements VAX BASIC has four statements that assign values to variables: • • • • LET INPUT LINPUT INPUT LINE LET and INPUT statements allow you to assign values to any type of variable, while LINPUT and INPUT LINE allow you to assign values to string variables. For example: LET A = 1.25 Getting Started with VAX BASIC 6-17 LET is an optional keyword. You can assign a value to more than one variable at a time, although this is not recommended. Instead, you should use a separate assignment statement each time you assign a value to a variable. Whenever you assign a value to a numeric variable, VAX BASIC converts the value to the data type of the variable. If you assign a floating-point value to an integer variable, VAX BASIC truncates the value at the decimal point. If you assign an integer value to a floating-point variable, VAX BASIC converts the value to floating-point format. You can also assign values to variables with the DATA and READ statements; however, this method requires that you know all input data values while you are coding your program. The INPUT, LINPUT, and INPUT LINE statements all assign values in the context of data being read into the program. These statements are discussed in Chapter 7. 6-18 Getting Started with VAX BASIC Chapter 1 Simple Input and Output This chapter explains how to use the VAX BASIC statements that move data to and from your program. 7.1 Program Input VAX BASIC programs receive data in three ways: • • • You can enter data interactively while the program runs. You do this with the INPUT, INPUT LINE, and LINPUT statements. If you know all the information your program will require, you can enter it as you write the program. You do this with the READ, DATA, and RESTORE statements, or you can name constants with the known values. You can read data from files outside the program. You do this with the INPUT#, INPUT LINE#, and LINPUT #statements. The following sections describe how to use these statements in detail. 7.1.1 Providing Input Interactively The INPUT, INPUT LINE, and LINPUT statements prompt a user for data while the program runs. Simple Input and Output 7-1 7. 1. 1.1 The INPUT Statement The INPUT statement interactively prompts the user for data. You can use the optional prompt string to clarify the input request by specifying the type and number of data elements required by the program. This is especially useful when the program contains many variables, or when someone else is running your program. Example INPUT PLEASE TYPE 3 INTEGERS" ;BY. ,CY. ,DY. AY. = BY. + CY. + DY. PRINT "THEIR SUM IS"; AY. END Output PLEASE TYPE 3 INTEGERS? 26,60,76IRETI THEIR SUM IS 160 When your program runs, VAX BASIC stops at each INPUT, LINPUT, or INPUT LINE statement, prints a string prompt, if specified, and an optional question mark ( ? ) followed by a space; it then waits for your input. By using either a comma or semicolon, you can affect the format of your string prompt. • • If you have a semicolon separating the input prompt string from the variable, VAX BASIC prints the question mark and space immediately after the input prompt string. If you have a comma separating the input prompt string from the variable, VAX BASIC prints the input prompt string, skips to the next print zone, and then prints the question mark and space. See Section 7.2.1 for more information about print zones. For more information on formatting string prompts, see Section 7.1.1.3. You must provide one value for each variable in the INPUT request. If you do not provide enough values, VAX BASIC prompts you again. 7-2 Simple Input and Output Example INPUT A,B END Output ? 51RETI ? 6 RET VAX BASIC interprets a carriage return (null input) as a zero value for numeric variables and as a null string for string variables. For example: ? j!REjl ? RET These responses assign the value 5 to variable A and zero to variable B. In contrast, if you provide more values than there are variables, VAX BASIC ignores the excess. In the following example, VAX BASIC ignores the extra value (8). Note that you can type multiple values if you separate them with commas. Because commas separate variables in the PRINT statement, VAX BASIC prints each variable at the start of a print zone. Example INPUT A,B,C PRINT A,B,C END Output 5,6,7,SIRETI ? 5 6 7 If you name a numeric variable in an INPUT statement, you must supply numeric data. If you supply string data to a numeric variable, VAX BASIC signals "Illegal number" (ERR=52). If you supply a floating-point number for an integer variable, VAX BASIC signals "Data format error" (ERR=SO). If you name a string variable in an INPUT statement, you can supply either numbers or letters, but VAX BASIC treats the data you supply as a string. Because digits and a decimal point are valid text characters, numbers can be interpreted as strings. Simple Input and Output 7-3 Example INPUT "Please type a number"; A$ PRINT A$ Output Please type a number? 25.5 25.5 VAX BASIC interprets the response as a four-character string instead of as a numeric value. You can type strings with or without quotation marks. However, if you want to input a string containing a comma, you should enclose the string in quotation marks or use the INPUT LINE or LINPUT statement. If you do not, VAX BASIC treats the comma as a delimiter and assigns only part of the string to the variable. If you use quotation marks, be sure to type both beginning and ending marks. If you leave out the end quotation mark, VAX BASIC signals "Data format error" (ERR=SO). 7 .1.1.2 The INPUT LINE and LINPUT Statements The INPUT LINE and LINPUT statements prompt you for string data while your program runs. You can respond with strings that contain commas, semicolons, and quotation marks, which are characters that the INPUT statement interprets as delimiters. The INPUT LINE statement accepts and stores all characters, including quotation marks, semicolons, and commas, up to and including the line terminator or terminators. LINPUT accepts all characters up to, but not including, the line terminator or terminators. In the following example, because both INPUT LINE and LINPUT treat your input as a string literal, VAX BASIC interprets quotation marks, commas, and semicolons as characters, not as string delimiters. When A$ is input with the INPUT LINE statement, the carriage return line terminator is stored as part of the string. The first PRINT statement tells VAX BASIC to print all three variables on one line, starting each one in a new print zone. However, when VAX BASIC prints the three strings, it prints the carriage return character at the end of string A$; this terminates the current line and causes 8$ to begin on a new line. 7-4 Simple Input and Output Example INPUT LINE A$ LINPUT B$ LINPUT C$ PRINT A$, B$, C$ PRINT "DONE" END Output ? SINGLE, DOUBLEIRETI ? "GFLOAT"lRETI ? HFLOAT; REAL Data TypeslRETI SINGLE, DOUBLE "GFLOAT" HFLOAT; REAL Data Types DONE The INPUT, INPUT LINE, and LINPUT statements can accept data from a terminal or a terminal-format file. See Section 7.3 for information on I/O to terminal-format files. 7. 1. 1.3 Enabling and Disabling the Question Mark Prompt With the SET PROMPT statement, VAX BASIC allows you to enable and disable the question mark prompt. By default, VAX BASIC displays the question mark prompt. For instance, the following example displays the default prompt string: Example INPUT "Please input 3 integer values";AY., BY., CY. Output Please input 3 integer values? You can, however, disable the question mark prompt by specifying the SET NO PROMPT statement. Simple Input and Output 7-5 Example SET NO PROMPT INPUT "Please input 3 integer values";AY., BY., CY. Output Please input 3 integer values When you disable the question mark prompt, you can specify your own prompt at the end of each prompt string. The following example inserts a colon at the end of the prompt string. Example SET NO PROMPT INPUT "Please enter your name: ";Employee_name$ Output Please enter your name: Now, if the SET PROMPT statement is specified, VAX BASIC displays both the colon and a question mark: Example SET PROMPT INPUT "Please enter your name: ";Employee_name$ Output Please enter your name: ? The SET [NO) PROMPT statement is valid for INPUT, LINPUT, INPUT LINE, and MAT INPUT statements. If the prompt is disabled, any one of the following commands re-enables it: • • • 7-6 The SET PROMPT statement The CHAIN statement The NEW, OLD, RUN, or SCRATCH compiler command Simple Input and Output 7.1.2 Providing Input from the Source Program The following sections describe the READ, DATA, and RESTORE statements. To use READ and DATA statements, you must know what data is required when writing the program. These statements do not stop to request data while the program runs. Therefore, your program runs faster than with the INPUT statements. The RESTORE statement lets you use the same data items more than once. 7. 1.2.1 The READ and DAT A Statements The READ statement reads values from a data block. A data pointer keeps track of the data read. Each time the READ statement requests data, VAX BASIC retrieves the next available constant from a DATA statement. The DATA statement contains the values that the READ statement reads. In a DATA statement, integer constants are whole numbers; they cannot be followed by a percent sign. In the following example, VAX BASIC signals an error because the integer constants in the DATA statement contain percent signs. Example 10 20 400 500 WHEN ERROR USE catch_it DATA 1%. 2Y., 3Y. READ AY., BY., CY. END WHEN HANDLER catch_it PRINT "ERROR NUMBER IS "; ERR PRINT "ERROR AT LINE "; ERL PRINT "ERROR MESSAGE IS "; ERT$(ERR) END HANDLER END Output ERROR NUMBER IS 50 ERROR AT LINE 20 ERROR MESSAGE IS Y.Data format error A READ statement is not valid without at least one DATA statement. If your program contains a READ statement but no DATA statement, VAX BASIC signals the compile-time error "READ without DATA 11 • READ statements can appear either before or after their corresponding DATA statements. The only restriction is that the DATA statements must be in the same order as their corresponding READ statements. Simple Input and Output 7-7 You can have more than one DATA statement in a program. DATA statements are ignored without at least one READ statement. You can use an ampersand to continue a DATA statement. For example: 10 DATA "ABRAMS", BAKER, CHRISTENSON, & DOBSON, "EISENSTADT", FOLEY Note that comment fields are not allowed in DATA statements. For example, the following statements cause A$ to contain the string ABC!COMMENT". II READ A$ DATA ABC !COMMENT When you compile a program, VAX BASIC creates one data block for each program unit. Each data block is local to the program or subprogram containing it; this means that you cannot share DATA statements between program modules. The data block contains the values in all DATA statements in that program unit. These values are stored in line number order. Each time VAX BASIC executes a READ statement, it retrieves the next value in the data block. VAX BASIC signals an error if you do one of the following: • • Assign alphabetic characters to a numeric variable. VAX BASIC signals "Data format error" (ERR=SO). Have more variables in the READ statements than there are values in the DATA statements. VAX BASIC signals "Out of data" (ERR=57). VAX BASIC ignores excess data in DATA statements. The following example of READ and DATA mixes string and floatingpoint data types. The first READ statement reads the first data item in the program: "The diameter is". The second READ statement reads the second data item: 40.5. 7-8 Simple Input and Output Example DATA "The diameter is" DATA 40.6 READ text$ READ radius DIAMETER = PI * radius * 2 PRINT text$; DIAMETER END Output The diameter is 264.469 7 .1.2.2 The RESTORE Statement The RESTORE statement lets you read the same data more than once. It has no effect without READ and DATA statements. RESTORE resets the data pointer to tl\e beginning of the first DATA statement in the program unit. You can then read data values again. Consider the following program. Example 10 READ B,C,D 20 RESTORE 30 READ E,F,G 40 DATA 6,3,4,7,9,2 60 END The READ statement in line 10 reads the first three values in the DATA statement: B=6 C=3 D=4 The RESTORE statement resets the pointer to the beginning of line 40. During the second READ statement (line 30), the first three values are read again: E=6 F=3 G=4 Simple Input and Output 7-9 Without the RESTORE statement, line 30 would assign the following values: E=7 F=9 G=2 7 .2 Program Output The PRINT statement displays data on your terminal during program execution. VAX BASIC evaluates expressions before displaying results. Note that you can also print and format data with the PRINT USING statement. For information about the PRINT USING statement, see Chapter 16. When you use the PRINT statement, VAX BASIC does the following: • Precedes positive numbers with a space and negative numbers with a minus sign Prints a space after every number Prints strings without leading or trailing spaces • • When an element in a list is not a simple variable or constant, VAX BASIC evaluates the expression before printing the value. Example A = 45 B = 55 PRINT A + B END Output 100 However, VAX BASIC interprets text inside quotation marks as a string literal. 7-10 Simple Input and Output Example A B = 46 = 66 PRINT "A + B" END Output A+ B The PRINT statement without an expression prints a blank line. Example PRINT "This example leaves a blank line" PRINT PRINT "between two lines." END Output This example leaves a blank line between two lines. 7.2.1 Print Zones-the Comma and the Semicolon A terminal line contains zones that are 14 character positions wide. The number of zones in a line depends on the width of your terminal: a 72character line contains 5 zones, which start in columns l, 15, 29, 43, and 57. A 132-character line has additional print zones starting at columns 71, 85, 99, and 113. The PRINT statement formats program output into these zones in different ways, depending on the character that separates the elements to be printed. If a comma precedes the PRINT item, VAX BASIC prints the item at the beginning of the next print zone. If the last print zone on a line is filled, VAX BASIC continues output at the first print zone on the next line. Simple Input and Output 7-11 Example INPUT A ,B ,C ,D ,E ,F PRINT A ,B ,C ,D ,E ,F END Output ? 6,10,16,20,25,30IRETI 6 30 10 16 20 26 VAX BASIC skips one print zone for each extra comma between list elements. For example, the following program prints the value of A in the first zone and the value of B in the third zone. Example A =5 B = 10 PRINT "first zone",,"third zone" PRINT A, ,B END Output first zone third zone 6 10 If you separate print elements with a semicolon, VAX BASIC does not move to the next print zone. In the following example, the first PRINT statement prints two numbers. (Printed numbers are preceded by a space or a minus sign and followed by one space.) The second PRINT statement prints two strings. Example PRINT 10; 20 PRINT "ABC"; "XYZ" END Output 10 20 ABCXYZ Whether you use a comma or a semicolon at the end of the PRINT statement, the cursor remains at its current position until VAX BASIC encounters another PRINT or INPUT statement. In the following example, VAX BASIC prints the current values of X, Y, and Z on one line because a comma follows the last item in the line PRINT X, Y. 7-12 Simple Input and Output Example INPUT X,Y,Z PRINT X,Y, PRINT Z END Output ? 5, 10, 15 IRETI 10 5 15 The following example shows PRINT statements using a comma, a semicolon, and no formatting character after the last print item. Example !No comma after IY.. so each element !Prints on its own line PRINT IY. FOR IY. = 11. TO 101. PRINT !A comma follows JY., so each !element prints in a separate zone ! PRINT JY., FOR JY. = 11. TO 10Y. PRINT ! !A semicolon follows KY., so print !elements are packed together ! PRINT KY.; FOR KY. = 11. TO 101. END Output 1 2 3 4 5 6 7 8 9 10 1 6 1 2 3 4 4 9 3 8 2 7 6 6 7 8 9 6 10 10 Simple Input and Output 7-13 Commas and semicolons also let you control the placement of string output: Example PRINT ":first zone",,"third zone",,":fi:fth zone" END Output :first zone third zone fi:f th zone The extra comma between strings causes VAX BASIC to skip another print zone. In the following example, the first string is longer than the print zone. When the two strings are printed, the second string begins in the third print zone because that is the next available print zone after the first string is printed. Example PRINT "abcde:fghijklmnopqrstuvwxyz".":foo" PRINT ":first zone","second zone","third zone" Output abcde:fghijklmnopqrstuvwxyz :first zone second zone 7.2.2 :foo third zone Output Format for Numbers and Strings VAX BASIC prints strings exactly as you type them, with no leading or trailing spaces. It does not print quotation marks unless they are delimited by another matching pair. Example PRINT 'PRINTING "QUOTATION" MARKS' END Output PRINTING "QUOTATION" MARKS VAX BASIC follows these rules for printing numbers: • 7-14 When you print numeric fields, VAX BASIC precedes each number with a space or a minus sign and follows it with a space. Simple Input and Output • • • VAX BASIC does not print trailing zeros to the right of the decimal point. If all digits to the right of the decimal point are zeros, VAX BASIC omits the decimal point as well. When you print LONG integers, VAX BASIC prints up to 10 significant digits. When you print DECIMAL values, VAX BASIC prints up to 31 digits. VAX BASIC follows these rules for printing floating-point numbers: • • • If a floating-point number can be represented exactly by six decimal digits (or fewer) and, optionally, a decimal point, VAX BASIC prints it that way. When you print a floating-point number whose integer portion is six decimal digits or less (for example, 1234.567), VAX BASIC rounds the number to six digits (1234.57). If the integer portion of the number is seven decimal digits or larger, VAX BASIC rounds the number to six digits and prints it in E format. See the VAX BASIC Reference Manual for more information about E format. When you print a floating-point number with magnitude between 0.1 and l, VAX BASIC rounds it to six digits. When you print a floatingpoint number with more than six digits, and with magnitude smaller than 0.1, VAX BASIC rounds it to six digits and prints it in E format. The PRINT statement displays only up to six digits of precision for floating-point numbers. This corresponds to the precision of the SINGLE data type. To display the extra digits in DOUBLE, GFLOAT and HFLOAT numbers, you must use the PRINT USING statement. See Chapter 16 for more information on PRINT USING. The following example shows how VAX BASIC prints various numbers with single precision: Example FOR I = 1 TO 20 PRINT 2·(-I),I,2·1 NEXT I END Output .6 .26 .126 .0625 .03125 1 2 3 4 5 2 4 8 16 32 Simple Input and Output 7-15 .015625 .78125E-02 .390625E-02 .195313E-02 .976563E-03 6 7 8 9 10 64 .488281E-03 .244141E-03 .12207E-03 .610352E-04 .305176E-04 11 12 13 14 15 2048 4096 8192 16384 32768 .152688E-04 .767939E-05 .38147E-05 .190735E-05 .953674E-06 16 17 18 19 20 66536 131072 262144 524288 .104858E+07 128 266 512 1024 7.3 Terminal-Format Files Terminal-format files let you perform simple 1/0 to disk files. The records in a terminal-format file must be accessed sequentially. That is, you must access the records in the file one by one, from the first to the last. You can add new records only at the end of the file. Just as the INPUT, LINPUT, and INPUT LINE statements receive information from a terminal, the INPUT#, LINPUT #,and INPUT LINE # statements receive information from a terminal-format file. And, as the PRINT statement sends information to the terminal, the PRINT# statement sends information to a terminal-format file. Terminal-format files are very useful for creating files to be printed on a line printer, or for supplying a program with moderate amounts of input. However, if you want to use the same file for both input and output, you should not use terminal-format files. Instead, use sequential, relative, or indexed files. For more information, see Chapter 15. Note that you do not have to use a program to create a terminal-format file. You can use a text editor to create a file and insert data, then use a VAX BASIC program to open the file and retrieve the data. 7-16 Simple Input and Output 7.3.1 Opening and Closing a Terminal-Format File You use the OPEN statement to create a file, or to gain access to an existing file. If you do not specify either FOR INPUT or FOR OUTPUT in the OPEN statement, VAX BASIC tries to open an existing file. If the file does not exist, VAX BASIC creates a new one. The channel specification lets you associate a number with the file for as long as the file is open. All 1/0 operations to or from the file use this number. When you are finished accessing a file, you close it with the CLOSE statement. 7.3.2 Writing Records to a Terminal-Format File The following example receives information from a terminal, then writes the information to a terminal-format file as a report: Example PRINT "This program creates a daily sales report tile named SALES.DAT" OPEN "SALES.DAT" FOR OUTPUT AS FILE #41. PRINT #4Y., "Salesperson","Sales Area","Items Sold" PRINT #41. INPUT "How many salespersons tor today's report"; salee_personsY. FOR IY. = 11. TO sales_pereoneY. INPUT "Salesperson's name"; e_name$ INPUT "Salee area"; area$ INPUT "Number ot items sold"; items_soldY. PRINT #41., s_name$, area$, items_soldY. NEXT lY. CLOSE HY. END Output This program creates a daily sales report tile named SALES.DAT How many salespersons tor today's report? 3 Salesperson's name? JONES Sales area? NJ Items sold? 6 Simple Input and Output 7-17 Salesperson's name? SMITH Sales area? NH Items sold? 6 Salesperson's name? BAINES Sales area? VT Items sold? 8 This program first prints a header explaining its purpose, then opens a terminal-format file on channel 4. After this file is opened, the two PRINT # statements place an explanatory header followed by a blank line into the file. The program then prompts you for the number of salespersons for which data is to be entered. The FOR ... NEXT loop prompts for the name, sales area, and items sold for each salesperson. Note that the FOR ... NEXT loop executes only as many times as there are salespersons. See Chapter 11 for more information about FOR ... NEXT loops. After the data has been entered for each salesperson, the program writes this information to the terminal-format file. Because the response to the first question was 3, the FOR ... NEXT loop executes three times. After the last item has been printed to the file, the program closes the file and ends. When you display the file with the DCL command TYPE, you see that the information is printed under the proper headers. You can also print the file on a line printer. Note that the PRINT # statement formats the output in print zones as the PRINT statement does. Example $TYPE SALES.DAT 7-18 Salesman Sales Area Items Sold JONES SMITH BAINES NJ NH 6 6 8 Simple Input and Output VT Chapter 8 Arrays An array is a set of data that is ordered in any number of dimensions. This chapter describes how to create and use VAX BASIC arrays. 8.1 Introduction A one-dimensional array is called a list or vector. A two-dimensional array is called a matrix. VAX BASIC arrays can have up to 32 dimensions, and a specific type of VAX BASIC arrays can be redimensioned at run time. In addition, you can specify the data type of the values in an array by using data type keywords or suffixes. The subscript of an element in an array defines that element's position in the array. When you create an array, you specify: • • The number of dimensions that the array contains The range of values for the subscripts in each dimension of the array VAX BASIC arrays are zero-based by default; that is, when calculating the number of elements in a dimension, you count from zero to the number of elements specified. For example, an array with an upper bound of 10 and no specified lower bound, has 11 elements: 0 through 10, inclusive. The array My_array(3,3) has 16 elements: 0 through 3 in each dimension, or 42. Arrays 8-1 VAX BASIC also lets you specify a lower bound for any or all dimensions in an array unless the array is a virtual array. By specifying lower and upper bounds for arrays, you can make your array subscripts meaningful. For example, the following array contains sales information for the years 1980 to 1985: DECLARE REAL Sales_data(1980 TO 1986) To refer to an element in the array Sales_data, you need only specify the year you are interested in. For example, to print the information for the year 1982, you would type: PRINT Sales_data(1982) You can create arrays either implicitly or explicitly. You implicitly create arrays having any number of dimensions by referencing an element of the array. If you implicitly create an array, VAX BASIC sets the upper bound to 10 and the lower bound to zero. Therefore, any array that you create implicitly contains 11 elements in each dimension. The following example refers to the array Student _grades. If the array has not been previously declared, VAX BASIC will create a one-dimensional array with that name. The array will contain 11 elements. Student_grades(S) = "B" You create arrays explicitly by declaring them in a DIM, DECLARE, COMMON, or MAP statement, or record declaration. Note that if you want to specify lower bounds for your array subscripts, you must declare the array explicitly. When you declare an array explicitly, the value that you give for the upper bound determines the maximum subscript value in that dimension. If you specify a lower bound, then that is the minimum subscript value in that dimension. If you do not specify a lower bound, VAX BASIC sets the lower bound in that dimension to zero. You can specify bounds as either positive or negative values. However, the lower bound of each dimension must always be less than or equal to the upper bound for that dimension. You can use MAT statements to create and manipulate arrays. However, MAT statements are valid only on arrays of one or two dimensions. In addition, the lower bounds of all dimensions in an array referenced in a MAT statement must be zero. 8-2 Arrays 8.2 Creating Arrays Explicitly You can create arrays explicitly with four VAX BASIC statements: DECLARE, DIMENSION, COMMON, and MAP. In addition, you can declare arrays as components of a record data type. See Chapter 10 for more information on records. Normally, you use the DECLARE statement to create arrays. However, in certain cases, you may want to create the array with another VAX BASIC statement: • • • You use the DIM statement to create virtual arrays and arrays that can be redimensioned at run time. You use the COMMON statement to create arrays that can l;>e shared among program modules or to create arrays of fixed-length strings. You use the MAP statement to create an array and associate it with a record buffer, or to overlay the storage for an array, thus accessing the same storage in different ways. When you create an array, the bounds you specify determine the array's size. The maximum value allowed for a bound can be as large as 2147483467; however, this number is actually limited by the amount of virtual storage available to you. Very large arrays and arrays with many dimensions can cause fatal errors at both compile time and run time. The following restrictions apply to arrays: • • • When referencing an array, you must use the same number of subscripts as was specified in the DIM statement. You can use identical names for a simple variable and an array; for example, A% and A%(5,5). However, this is not a recommended programming practice. If you use identical names for arrays with a different number of subscripts, for example, A(S), and A(l0,10), VAX BASIC prints the error "Inconsistent subscript usage" at compile time. If subscript checking is enabled, VAX BASIC signals the error "Subscript out of range" (ERR=SS) if you reference an array element whose subscripts are one of the following: Greater than the current upper bound of the array Less than the current lower bound of the array Less than zero where no lower bound was specified Arrays 8-3 8.2.1 Creating Arrays with the DECLARE Statement The DECLARE statement creates and names variables and arrays. All elements of arrays created with the DECLARE statement are initialized to zero or the null string. The following statement creates a longword integer array with 11 elements. DECLARE LONG FIRST_.ARRAY(1970 TO 1980) Note that the STRING data type with the DECLARE statement causes the creation of an array of dynamic strings. To create an array of fixed-length strings, declare the array in a COMMON or MAP statement or as part of a RECORD structure. 8.2.2 Creating Arrays with the DIM Statement The DIM statement creates and names one or more arrays. You should use the DIM statement to create an array only when you want to • • Redimension the array at run time Create a virtual array When creating arrays with DIM, you specify the data type of the array elements with a data type keyword, a special suffix on the array name, or both. The array name can be any valid variable name. If you do not supply a data type keyword, the data type is determined by the suffix of the array name: • • • If the array name ends in a dollar sign, the array stores string data. If the array name ends in a percent sign, the array stores integer data. If the array name does not end in either a percent sign or a dollar sign, the array stores data of the default type. The default type is single-precision floating-point unless you change the default. See Chapter 6 for more information on default data types. Even if the DIM statement contains a data type keyword, the array name can still end in the appropriate data type suffix. This makes the data type of the array immediately obvious. The DIM statement can be either executable or declarative. If the specified bounds are constants, the DIM statement is declarative. This means that the storage is allocated at compile time, and the array cannot appear in any other DIM statement. 8-4 Arrays However, if any of the specified bounds are variables (simple or subscripted), the DIM statement is executable. This means that the storage for the array is allocated at run time, and the array can be redimensioned with a DIM statement any number of times. NOTE In the DIM statement, bounds can be either constants or variables (simple or subscripted), but not expressions. When an array is redimensioned with the executable DIM statement, the array can become larger or smaller than it was. However, redimensioning an array in this way causes it to be reinitialized, and all data in the array is lost. In contrast, MAT statements let you redimension an array to be the same size or smaller than it was. However, MAT statements redimension arrays only when assigning values or performing matrix 1/0; therefore, the fact that MAT reinitializes the array does not matter. See Section 8.6 for more information on MAT statements. 8.2.2.1 Declarative DIM Statements Declarative DIM statements are those with integer constants as bounds. The percent sign is optional for bounds; however, VAX BASIC signals the error "Integer constant required" if a constant bound contains a decimal point. The following statement creates a 101-element virtual array containing string data. The elements of this array can each have a maximum length of 256 characters. DIM 111.. STRING VIRT_ARRAY(100) = 2561. The following restrictions apply to the use of declarative DIM statements: • • • A declarative DIM statement must lexically precede any reference to the array it dimensions. The lower bounds of all virtual array dimensions must be zero. You must open a VIRTUAL file on the specified channel before you can access elements of the virtual array. Arrays 8-5 8.2.2.2 Executable DIM Statements Executable DIM statements are those with at least one variable bound. Bounds can be constants or simple variables, but at least one bound must be a variable. Executable DIM statements let you redimension an array at run time. The bounds of the array can become larger or smaller, but the number of dimensions cannot change. For example, you cannot redimension a four-dimensional array to be five-dimensional. The executable DIM statement cannot be used on arrays in COMMON, MAP, DECLARE or declarative DIM statements, nor on virtual arrays or arrays received as formal parameters. Whenever an executable DIM statement executes, it reinitializes the array. If you change the values of an executable DIM statement, the initial values are reset each time the DIM statement is executed. In the following example, the second DIM statement reinitializes the array real_array; therefore, real_array(1) equals zero in the second PRINT statement. Example xx = 1ox YX = 20X DIM real_array(XX) real_array(1X) = 100 PRINT real_array(1X) DIM real_array(YX) PRINT real_array(1X) END Output 100 0 You cannot reference an array named in an executable DIM statement until after the DIM statement executes. If you reference an array element declared in an executable DIM statement whose subscripts are larger than the bounds specified in the last execution of the DIM statement, VAX BASIC signals the run-time error "Subscript out of range" (ERR = 55), provided subscript checking is enabled. 8-6 Arrays 8.2.3 Creating Arrays with the COMMON Statement You should create arrays with the COMMON statement when you need an array of fixed-length strings, or when you want to share an array among program modules. Program modules can share arrays in COMMON statements by defining a common block with the same name. The COMMON statements in the following programs create a 100-element array of fixed-length strings, each element 10 characters long. Because the main program and subprograms use the same common name, the storage for these arrays is overlaid when the programs are linked. Therefore, both programs can read and write data to the array. Example !Main Program COMMON (ABC) STRING access_list(1 TO 100) = 10 !Subprogram SUB SUB1 COMMON (ABC) STRING new_list(1 TO 100) = 10 8.2.4 Creating Arrays with the MAP Statement You should create arrays with the MAP statement only when you want the array to be part of a record buffer, or when you want to overlay the storage containing the array. Note that string arrays in maps are always fixed-length. You associate the array with a record buffer by naming the map in the MAP clause of the OPEN statement. In the following example, the MAP statement creates two arrays: an 11-element fixed-length string array named team and a 33-element array of WORD integers named bowling_scores. Because the OPEN statement specifies MAP ABC, the storage for these arrays is used as the record buffer for the open file. Example MAP (ABC) STRING team(10) = 20, WORD bowling_scores(O TO 32) OPEN "BOWLING.DAT" AS FILE liY., SEQUENTIAL VARIABLE, MAP ABC Arrays 8-7 8.3 Determining the Bounds of an Array VAX BASIC provides two built-in functions, LBOUND and UBOUND, that allow you to determine the lower and upper bounds, respectively, for any dimension in an array. The following example sets up four variables that contain the lower and upper bounds of both dimensions of the array Sales_data. These variables represent the years and months for which there is sales data available. The two FOR ... NEXT loops print all the sales information in the array, starting with the first year and month, and ending with the last year and month. Example DECLARE Sales_data(1900 TO 1986, 1 TO 12) Month_startY. = LBOUND (Sales_data, 2) Year_startY. = LBOUND (Sales_data, 1) Month_endY. = UBOUND (Sales_data, 2) Year_endY. = UBOUND (Sales_data, 1) FOR YearY. = Year_startY. TO Year_endY. FOR Month% = Month_startY. TO Month_endY. PRINT Sales_data(YearY., Month%) NEXT MonthY. NEXT YearY. Note that you cannot implicitly declare arrays with the LBOUND and UBOUND functions. These functions can be used only with arrays that have been previously declared. 8.4 Creating Arrays Implicitly There are two ways to create arrays implicitly: • • By referencing an element of an array that has not been explicitly declared By using MAT statements When VAX BASIC first creates an implicit array, the lower bound is zero and the upper bound is 10. An array created by referencing an element can have up to 32 dimensions in VAX BASIC. An array created with a MAT statement can have only one or two dimensions. 8-8 Arrays NOTE The ability to create arrays implicitly exists for compatibility with previous implementations of VAX BASIC. However, it is better programming practice to declare all arrays explicitly before using them. If you reference an element of an array that has not been explicitly declared, VAX BASIC creates a new array with the name you specify. Arrays created by reference have default subscripts of (0 TO 10), (0 TO 10, 0 TO 10), (0 TO 10, 0 TO 10, 0 TO 10) and so on, depending on the number of dimensions specified in the array reference. For example, the following program implicitly creates three arrays and assigns a value to one element of each. Example LET A(6,6,6) = 3.14169LET B%(3) = 33 LET C$(2,2) = "Russell Scott" END The first LET statement creates an 11 by 11 by 11 array that stores floating-point numbers and assigns the value 3.14159 to element (5,5,5). The second LET statement creates an 11-element list that stores integers and assigns the value 33 to element (3) and the third LET statement creates an 11 by 11 string array and assigns the value "Russell Scott" to element (2,2). When you create an implicit numeric array by referring to an element, VAX BASIC initializes all elements (except the one assigned a value) to zero. For implicit string arrays, VAX BASIC initializes all elements (except the one assigned a value) to a null string. When you implicitly create an array, you cannot specify a subscript greater than 10. An attempt to do so causes VAX BASIC to signal "Subscript out of range" (ERR = 55), provided that subscript checking is enabled. Note that you cannot create an array implicitly, then redimension the array with an executable DIM statement. The DIM statement must execute before any reference to the array. An array name cannot appear in a declarative statement after the array has been implicitly declared by a reference. The following DECLARE statement is therefore illegal and causes VAX BASIC to signal the compiletime error "illegal multiple definition of name NEW_ARRAY". new_array (6,6,6) = 1 DECLARE LONG new_array (16,10,6) Arrays 8-9 8.5 Assigning and Displaying Array Values You can assign values to array elements from within your program, from an external source, such as terminal input or from files, or with MAT statements. You can write data from an array with the following statements: • • LET PRINT The following sections tell you how to perform input and output operations on VAX BASIC arrays. 8.5.1 Assigning Values with the LET Statement The LET statement assigns values to individual array elements. Example DIM voucher_numY.(100) LET voucher_numY.(20) = 3263% END You can also assign values to a portion of an array with the LET statement and a FOR ... NEXT loop. In the following example, the FOR ... NEXT loop assigns zero to array elements (1,5) through (1,10), (2,5) through (2,10), and (3,5) through (3,10). 8-10 Arrays Example DIM po_numberY.(100,100) FOR IY. = 1Y. TO 3Y. FOR JY. = 6Y. TO 101. LET po_numberY.CIY.,JY.) = OY. NEXT JY. NEXT !Y. END 8.5.2 Listing Array Elements with the PRINT Statement You print individual array elements by naming those elements in the PRINT statement. For example: PRINT parts_list$(36Y.) With a FOR. .. NEXT loop, you can print all or part of an array: Example DIM capture_ratio(10,10) FOR YY. = 7Y. TO 10Y. FOR XY. = 7Y. TO 10Y. PRINT capture_ratio(XY.,YY.) NEXT XY. NEXT YY. 8.6 Using MAT Statements MAT statements let you assign values to or display entire arrays with a single statement. They also: • • • • Implicitly create arrays Assign names to arrays Specify array dimensions Redimension existing arrays (to equal or smaller sizes) Arrays 8-11 • • • Assign element values Print the contents of arrays Perform matrix arithmetic MAT statements are valid only on arrays of one or two dimensions. When MAT statements execute, they use row and column zero to store intermediate calculations. This means that MAT statements can overwrite data stored in row and column zero of your arrays, and you should not depend on data in these elements if your program uses MAT statements. NOTE MAT statements cannot be used with arrays that have lower bounds other than zero. An attempt to specify a lower bound other than zero for an array in a MAT statement results in a compile-time error. Note that the MAT statements discussed in this section are not related to the MAT GRAPH and MAT PLOT graphics statements. For more information on these statements, see Programming with VAX BASIC Graphics. The default subscripts for arrays created implicitly with MAT statements are (10) or (10,10). The default is two dimensions. This means that if you create an array with a MAT statement and do not specify any subscripts, VAX BASIC creates a two-dimensional, 11 by 11 array. If you specify a single subscript, VAX BASIC creates a one-dimensional array with 11 elements. Table 8-1 lists MAT statements and explains their functions. 8-12 Arrays Table 8-1: MAT Statements Statement Function MAT Assigns values of zero, l, or a null string to array elements. Also copies the values of one array to another and performs matrix arithmetic. MAT INPUT (#) Assigns values to array elements from your terminal or a terminal-format file. MAT LINPUT (#) Assigns string values to string array elements from your terminal or from a terminal-format file. MAT PRINT(#) Displays the contents of an array on your terminal, or writes array element values to a terminal-format file. MAT READ Assigns DATA statement values to array elements. In the following example, the first MAT statement creates the string array z_array$ with eight rows and eight columns and assigns a null string to all elements. The second MAT statement redimensions the array to six rows and six columns. The third MAT statement adds the values in each corresponding element of arrays B and C and stores the values in the corresponding elements of array A. Example MAT z_array$ = NUL$(7,7) MAT z_array$ = NUL$(6,6) MAT A = B + C END 8.8.1 The MAT Statement The MAT statement can create an array and optionally assign values to all elements in that array. By specifying one of the MAT statement keywords, you can initialize arrays in one of four ways. Table 8-2 lists the MAT statement keywords and their functions. Arrays 8-13 Table 8-2: MAT Statement Keywords MAT Keyword Function ZER Sets the value of all elements in a numeric array to zero. CON Sets the value of all elements in a numeric array to l, except those in row and column zero. IDN Sets the array to the identity matrix, that is, it sets the value of all elements in real or integer arrays to zero, except for those elements on the diagonal from element (1,1) to element (n,n), where n is the largest subscript in the array. The elements on the diagonal are set to 1. IDN applies to square arrays only. NUL$ Sets the value of all elements in a string array to the null string, except those in row and column zero. The array name can specify an existing array. MAT statements do not assign values to row and column zero. Note that the MAT statement does not require subscripts. In the case of existing arrays: • • If you do not specify subscripts, VAX BASIC does not change the current subscripts. If you specify subscripts, VAX BASIC redimensions the array to the specified subscripts. When redimensioning arrays with MAT, you cannot increase the total number of array elements (including those in row and column zero). When you are creating arrays with MAT: 8-14 Arrays • If you do not supply subscripts, VAX BASIC assigns two subscripts, • each with a value of 10. If you specify subscripts, they define the dimensions of the array being implicitly created. Subscript values cannot exceed 10. Example DIM A(10,10), B(15), C(20,20) MAT A = ZER !Sets all elements of A to 0 MAT B = CON(10) !Sets elements of B to 1; redimensions B MAT C = IDN(10,10) !Redimensions C to 10x10 identity matrix PRINT "ARRAY A:" MAT PRINT A; PRINT PRINT "ARRAY B:" MAT PRINT B; PRINT PRINT "ARRAY C:" MAT PRINT C; Output ARRAY A: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ARRAY B: 1 1 1 1 1 1 1 1 1 1 ARRAY C: 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 8.8.2 The MAT READ Statement The MAT READ statement assigns values from DATA statements to array elements. Subscripts define either the dimensions of the array being created or the new dimensions of an existing array; subscripts are optional in MAT READ statements. Arrays 8-15 If you do not provide enough data in DATA statements to fill the specified array, VAX BASIC leaves the remaining array elements unchanged. If you provide more data values than there are array elements, VAX BASIC assigns enough values to fill the array and leaves the DATA pointer at the next value. In the following example, VAX BASIC fills matrix B with the first four DATA items, fills matrix C with the next four DATA values, and leaves the DATA pointer at the ninth value in the DATA list. Example MAT READ B(2,2) MAT READ C(2,2) PRINT PRINT "MATRIX 8" PRINT PRINT MAT PRINT B; PRINT PRINT "MATRIX C" PRINT PRINT MAT PRINT C; DATA 1,2,3,4,6,6,7,8,9,10 END Output MATRIX B 1 2 3 4 MATRIX C 6 6 7 8 8.8.3 The MAT INPUT [#] Statement The MAT INPUT statement assigns values from your terminal to array elements. The MAT INPUT # statement reads data from a terminal-format file and writes it to an array. The optional subscripts in a MAT INPUT statement define either the dimensions of the array being created implicitly or the new dimensions of an existing array. If you are implicitly creating the array, the value of a subscript cannot exceed 10. 8-16 Arrays The MAT INPUT statement requests data from your terminal, as does the INPUT statement; it prints a question mark (?)prompt that you can disable with the SET NO PROMPT statement and then enable with the SET PROMPT statement. However, you cannot include a string prompt with the MAT INPUT statement. When you enter a series of values separated by commas, VAX BASIC enters the values you supply into successive array elements by row, starting with element (1,1) and filling row 1 before starting row 2. If you provide fewer data items than there are elements, the remaining elements are unchanged. If you provide more items than there are elements, VAX BASIC ignores the excess. The MAT INPUT# statement takes values from an open file and assigns them to the matrix elements by rows, starting with element (1,1). It fills the elements in row 1 before starting row 2. The file can have one or more values in each record; however, multiple values must be separated with commas. In the following example, the open file on channel 3 contains the following data: l, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13. The MAT INPUT # statement reads this data and uses it to fill the array A, filling in row 1 before beginning row 2. The MAT INPUT B(2,2) statement dimensions array B to 9 elements (0 to 2 in each dimension) and provides values for all the elements except those in row and column zero. Example MAT INPUT #3, A PRINT MAT PRINT A; MAT INPUT B(2,2) PRINT MAT PRINT B; Output 1 2 3 11 12 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 6 0 0 0 7 0 0 0 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 g 0 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 Arrays 8-17 ? 1,2,3,4IRETI 1 3 2 4 Note that the MAT PRINT statement does not print row and column zero. For more information on the MAT PRINT statement, see Section 8.6.5. The MAT INPUT statement can also redimension an existing array. Example DIM new_arrayY.(6,6) MAT INPUT new_arrayY.(2,4) MAT PRINT new_arrayY.; END Output ? 1,2,3,4,6,6,7,SIRETI 1 2 3 4 6 6 7 8 When entering values in response to MAT INPUT, you can enter an ampersand as the last character on the line and continue on the next line. 8.6.4 The MAT LINPUT [#] Statement The MAT LINPUT statement assigns string values to string array elements. The MAT LINPUT # statement reads string values from a terminal-format file and writes them to a string array. The MAT LINPUT statement prompts for individual array elements. It fills the array by rows, starting with element (1,1). It assigns the line you supply (including commas, semicolons, and quotation marks, but excluding the line terminator) to an array element. 8-18 Arrays Example DIM emp_nam$(6,6) MAT LINPUT emp_nam$(2,2) PRINT emp_nam$(1,1) PRINT emp_nam$(1,2) PRINT emp_nam$(2,1) PRINT emp_nam$(2,2) END Output By specifying the subscripts (2,2), MAT LINPUT redimensions the array to four elements and overwrites the old values. VAX BASIC then prompts for these elements. MAT LINPUT #also excludes line terminators when assigning values to string array elements. MAT LINPUT # places the values from the open file into the specified array, filling the array by rows, starting with element (1,1). If there are more values in the file than there are array elements, VAX BASIC ignores the excess. If there are fewer, VAX BASIC assigns a null string to the remaining elements. The following program reads 50 records from the open disk file and assigns them to the array named part_name$. If there are more than 50 records in the file, VAX BASIC ignores the excess. If there are fewer than 50 records, then VAX BASIC fills the remaining elements of the array with the null string. Example DIM part_name$(60) MAT LINPUT #1Y., part_name$ 8.6.5 The MAT PRINT[#] Statement The MAT PRINT statement prints some or all of an array's elements, excluding row and column zero. The MAT PRINT# statement takes Arrays 8-19 values from an array by row, starting with element (1,1), and writes each element to a sequential record in the terminal-format file. Subscripts are optional in MAT PRINT statements. If you do not specify subscripts, MAT PRINT displays the entire array, excluding row and column zero. If you specify subscripts, MAT PRINT displays the specified subset of the array. In the case of the MAT PRINT# statement, the subscripts determine how many array elements are written to the file. The MAT PRINT[#] statement does not redimension an existing array. If the last character in the MAT PRINT[#] array list is a semicolon, VAX BASIC begins each array row on a separate line. Data values on each line are packed together with no intermediate spaces. However, if the last character in the MAT PRINT[#] arrays list is a comma, VAX BASIC begins each array row on a separate line and each data value in a separate print zone. If there is neither a comma nor a semicolon after the array name, VAX BASIC prints each array element on a separate line. In the following example, the first MAT PRINT statement does not end in a comma or semicolon, so each element is printed on a separate line. The second MAT PRINT statement prints the elements twice, the first time starting each element in a new print zone, and the second time leaving a space before and after each value. The MAT PRINT# statement sends the last two lines of output to a terminal-format file. Example MAT INPUT A(5) PRINT MAT PRINT A PRINT MAT PRINT A, A; MAT PRINT #3, A, A; END Output ? 5IRETI 5 0 0 0 0 0 5 5 8-20 Arrays 0 0 0 0 0 0 0 8.8.8 Matrix 1/0 Functions (NUM and NUM2) MAT statements do not signal error messages when there are more data items than array elements to contain them or when there are fewer data items than array elements to contain them. VAX BASIC provides two functions that let you determine how much data the MAT statements transfer: NUM and NUM2. For two-dimensional arrays, the NUM function returns an integer value specifying the row number of the last data item transferred, whereas the NUM2 function returns an integer value specifying the column number of the last data item transferred. For one-dimensional arrays, the NUM function returns the number of items entered, whereas the NUM2 function returns a zero. With these functions, you can determine the number of items transferred from a terminal-format file. Note, however, that you cannot use the NUM and NUM2 functions to implicitly declare an array. In the following example, the terminal-format file EMP.DAT contains the values 1 through 17, inclusive. When these values are read using the MAT INPUT# statement, NUM and NUM2 represent the row and column number, respectively, of the last value read: Example OPEN "EMP.DAT" FOR INPUT AS FILE #3% DIM emp_name$(6,6) MAT INPUT #3%, emp_name$ PRINT NUM, NUM2 END Output 4 2 8. 7 Matrix Operators VAX BASIC provides a special set of MAT statements for array computations. These statements enable you to add, subtract, and multiply matrices, and to assign values to elements. Note that if you specify an array without subscripts (for example, MAT A), the default is two dimensions. Arrays 8-21 VAX BASIC also provides matrix functions to transpose and invert matrices, and to find the determinant of a matrix you invert. NOTE MAT operators do not operate on elements in row or column zero. 8. 7.1 Arithmetic Matrix Operations MAT operators perform matrix assignment, addition, subtraction, and multiplication. All of these operations use the keyword MAT, followed by an expression. If the array has not been previously dimensioned, these operations create an array. The created output array's dimensions depend on the operation performed, but must be (10,10) or smaller. NOTE You can use the MAT operators on arrays larger than (10,10) if the input and output arrays are explicitly created or received as a formal parameter. 8. 7. 1. 1 Assignment You can assign all values in one array to another array with the MAT statement. In the following example, each element of new_array is set to the corresponding element in old_array. The dimensions of new_array are also redimensioned to the dimensions of old_array. MAT new_array = old_array 8. 7. 1.2 Addition and Subtraction You can add the elements of two arrays. In the following statement, the two input lists, first_list% and second_list%, must have identical dimensions. The elements of the new list, sum_list%, equal the sum of the corresponding elements in the input lists. MAT sum_listY. = first_listY. + second_listY. You can also subtract the elements of two arrays. The following program subtracts one array from another. 8-22 Arrays Example DIM first_array(30,30) DIM second_array(30,30) DIM difference_array(30,30) MAT diff erence_array = f irst_array - second_array Each element of difference_array is the arithmetic difference of the corresponding elements of the input arrays. 8. 7. 1.3 Multiplication You can multiply the elements of two arrays, provided that the number of columns in the first array equals the number of rows in the second array. The resulting array contains the dot product of the two input arrays. Example DIM A(2,2), B(2,2), C(2,2) A(1,1) = 1 A(1,2) = 2 A(2,1) = 3 A(2,2) = 4 B(1,1) = 6 B(1,2) = 6 B(2,1) = 7 B(2,2) = 8 MAT C = A * B MAT PRINT C Output 19 22 43 60 You can also multiply a matrix by a scalar quantity. VAX BASIC multiplies each element of the input array by the scalar quantity you supply. The output array has the same dimensions as the input array. Enclose the scalar quantity in parentheses. The following example multiplies the elements of inch_array by the inch-to-centimeter conversion factor and places these values in cm_array. Arrays 8-23 Example DIM inch_array(6), cm_array(6) MAT READ inch_array DATA 1,12,36,100,39.37 MAT cm_array = (2.64) * inch_array MAT PRINT cm_array, END Output 2.64 8. 7.2 30.48 91.44 264 99.9998 Matrix Functions VAX BASIC provides three matrix functions: • • TRN INV • DET With these functions, you can transpose and invert matrices, and find the determinant of an inverted matrix. 8.7 .2.1 The TRN Function The TRN function transposes a matrix. When you transpose a matrix, VAX BASIC interchanges the array's dimensions. For example, a matrix with n rows and m columns is transposed to a matrix with m rows and n columns. The elements in the first row of the input matrix become the elements in the first column of the output matrix. You cannot transpose a matrix to itself; MAT A = TRN(A) is invalid. This example creates a 3 by 5 matrix, transposes it, and prints the results. 8-24 Arrays Example DIM 8(3,6) MAT READ B MAT A = TRN(B) DATA 1,2,3,4,6 DATA 6,7,8,9,10 DATA 11,12,13,14,16 MAT PRINT B; MAT PRINT A; END Output 1 2 3 4 6 6 7 8 9 10 11 12 13 14 16 1 6 2 7 3 8 4 9 6 10 8. 7 .2.2 11 12 13 14 16 The INV Function The INV function inverts a matrix. VAX BASIC can invert a matrix only if its subscripts are identical and it can be reduced to the identity matrix by elementary row operations. The input matrix multiplied by the output matrix (its inverse) always gives the identity matrix as a result. Example MAT INPUT first_array(3,3) MAT PRINT first_array; PRINT MAT inv_array = INV (first_array) MAT PRINT inv_array; PRINT MAT mult_array = first_array * inv_array MAT PRINT mult_array; Arrays 8-25 Output ? 4,0,0,0.0.2.o.a.o!RETI 4 0 0 0 0 8 0 2 0 .26 0 0 0 0 .126 0 .6 0 1 0 8.7.2.3 0 1 0 0 0 0 1 The DET Function The DET function returns the determinant of a matrix. The DET function returns a floating-point number that is the determinant of the last matrix inverted. If you use the DET function before inverting a matrix, the value of DET is zero. 8-26 Arrays Chapter 9 Data Definition This chapter describes how to define program objects, explicitly assign data types to program variables, and allocate and use data storage. 9. 1 Declarative Statements You use declarative statements to define objects in a VAX BASIC program. Objects can be variables, arrays, constants, and user-defined functions within a program module. They can also be routines, variables, and constants external to the program module. Declarative statements always assign names to the objects declared and usually assign other attributes, such as a data type, to them. Declarative statements can also be used to define user-defined data types (RECORD statements). See Chapter 10 in this manual for more information on the RECORD statement. You use declarative statements to assign data types to: • • • • Variables Arrays Named constants Values returned by functions By declaring the objects used in your program, you make the program much easier to understand, modify, and debug. Data Definition 9-1 9.2 Data Types At its most fundamental level, a data type is a format for information storage. All information is stored in the computer as bit patterns (groups of ones and zeros). Data types specify how the computer should interpret these patterns. VAX BASIC programs allow four general data types: integer, floatingpoint, string, and packed decimal. Each data type is suited for a particular type of task. For example, integers are useful for numeric computations involving whole numbers, strings provide a way to manipulate alphanumeric characters, and packed decimal data is useful for manipulating numeric values that require precise representation. Within integer and floating-point data types there are further subdivisions. For example, integers can be classed as BYTE, WORD, and LONG. Choosing one of these integer subdivisions lets you control two things: • • The amount of storage required for the integer The range of values that the integer can accept See Table 9-1 for more information on the range and storage requirements of these integer subtypes. Similarly, floating-point data can be classed as SINGLE, DOUBLE, GFLOAT, and HFLOAT. See Table 9-1 for more information on the range and storage requirements of these floating-point subtypes. In addition to numeric and string data types, VAX BASIC also provides a unique data type called RFA. Variables of the RFA data type require six bytes of storage and can contain only a Record File Address. RFA variables are used with RMS file I/O; the operations that can be performed on them are strictly limited. See the VAX BASIC Reference Manual for more information on the RFA data type. Finally, VAX BASIC allows you to construct your own forms of data representation using records. Traditionally, VAX BASIC programs have had just three data types: integer, string, and floating-point. A data type was assigned to a variable with a suffix on the variable names; a dollar sign ( $ ) denoted a string variable, a percent sign ( % ) denoted an integer variable, and variable names without suffixes denoted floating-point variables. By referencing a variable in your program, you would implicitly declare the variable with the data type indicated by the suffix character. 9-2 Data Definition VAX BASIC now lets you explicitly assign data types to variables, parameters, and functions. This feature gives you more control over the storage and precision used by your program. You can, however, still use implicit data typing in your programs. You can ensure that all program variables are explicitly declared by specifying OPTION TYPE= EXPLICIT or by using the /TYPE=EXPLICIT qualifier when you compile your programs. See Section 9 .3 for more information on the OPTION statement. Table 9-1 lists the keywords you use to assign data types along with their size, range, and precision. Table 9-1: VAX BASIC Data Types Size Range Precision (decimal) (digits) 8 bits -128 to +127 NA WORD 16 bits -32768 to +32767 NA LONG 32 bits -2147483648 to +2147483647 NA SINGLE 32 bits 6 DOUBLE 64 bits .29 * 10- 38 to 1.7 * 1038 .29 * 10- 38 to 64 bits 1.7 * 1038 .56 * 10- 308 to Data Type Keyword INTEGER BYTE REAL GFLOAT 16 15 .90 * 10308 HFLOAT 128 bits .84 * 10- 4932 to .59 * 104932 33 0 to 16 bytes 1 * 10- 31 to 1 * NA DECIMAL DECIMAL(d,s) 1031 Data Definition 9-3 Table 9-1 (Cont.): Data Type Keyword VAX BASIC Data Types Size Range Precision (decimal) (digits) One character per byte Max= 65535 NA 6 bytes NA NA STRING STRING RFA RFA As shown in the table, there are four data type keywords that specify integer data. The data type INTEGER is a general data type because it specifies only that a variable contains integer data. The subtypes BYTE, WORD, and LONG specify exactly how much storage is allocated to an integer variable. If you specify the INTEGER data type, the subtype of integer variables depends on the default integer data type in effect when the program is compiled. This default is determined by one of two things: • • The program's OPTION statement, if present. See Section 9.3 for more information on the OPTION statement. The /INTEGER-SIZE qualifier you use to compile the program. Similarly, there are five data type keywords that specify floating-point data. The data type REAL is a general data type because it specifies only that a variable contains floating-point data. The subtypes SINGLE, DOUBLE, GFLOAT, and HFLOAT specify exactly how much storage is allocated to a floating-point variable. If you specify the data type REAL, the subtype of floating-point variables depends on the default floatingpoint subtype in effect when the program is compiled. This default is determined by one of two things: • • The OPTION statement, if present The /REAL _SIZE qualifier you use to compile the program Choosing a numeric subtype always involves a tradeoff between storage requirements and range or precision. You can reduce the size of an executable image by choosing the smallest numeric subtype that is large enough to meet your needs. 9-4 Data Definition 9.3 Setting the Default Data Type and Size There are two ways to set the default data type and size for your program: • • With the OPTION statement With qualifiers: /TYPE_DEFAULT /INTEGER-SIZE /REAL_SIZE /DECIMAL _SIZE The OPTION statement can override the defaults set with qualifiers. For example, the following statement sets the default integer type to be LONG. OPTION SIZE = INTEGER LONG You can have more than one OPTION statement in a program module; however OPTION statements can be preceded only by a SUB, FUNCTION, REM, or another OPTION statement. Note that the OPTION statement can also specify the following: • • • • Integer and packed decimal overflow checking Program optimization Rounding or truncation of packed decimal numbers Subscript checking See the VAX BASIC Reference Manual for more information about the OPTION statement. The OPTION statement in the following example specifies that all program variables must be explicitly typed and that all implicitly typed constants are INTEGER. In addition, any variable typed as INTEGER is a LONG integer and any variable typed as REAL is a DOUBLE floating-point number. OPTION TYPE= EXPLICIT, CONSTANT TYPE = INTEGER, SIZE = INTEGER LONG, SIZE = REAL DOUBLE ! Variables must be declared & ! All implicit constants be integers & ! 32-bit integers by default & ! 64-bit floating-point ! numbers by default Data Definition 9-5 You can create variables of other data types by explicitly declaring them with the DECLARE, COMMON, or MAP statement. 9.4 Declaring Variables Explicitly The DECLARE statement explicitly assigns a data type or subtype to a variable, function, or constant. The subtype you specify overrides any defaults specified in the OPTION statement, in the BASIC environment or with the /INTEGER_SIZE, /REAL _SIZE, and /DECIMAL _SIZE qualifiers. For example, if you compile your program with the /INTEGER_SIZE=WORD qualifier and declare an integer variable to be LONG, the variable is LONG rather than WORD. In this format of the DECLARE statement, the data type STRING specifies a dynamic string variable. You can define a variable only once in a program. For example, if a variable name appears in a DECLARE statement, it cannot also appear in a COMMON or MAP statement. You should use unique variable names to avoid confusion and make program documentation easier. For example, if you declare variable B to be LONG, there cannot also be a floating-point variable B in your program. It is possible to have both an INTEGER variable B% and an INTEGER variable B in the same program; however, this is poor programming practice. When you explicitly declare an array, VAX BASIC allows you to specify both upper and lower bound values. The value you supply as the upper bound determines the maximum subscript value for a given dimension, and the value you supply for the lower bound determines the minimum subscript value for a given dimension. For more information on specifying bounds with the DECLARE statement, see the VAX BASIC Reference Manual and Chapter 8 in this manual. You can also use the DECLARE statement to assign a data type and value to DEF functions and constants. See Section 9.5 for an explanation of declaring named constants. The following statement declares the DEF function circumference and declares a SINGLE parameter for the function: DECLARE LONG FUNCTION circumference(SINGLE) 9-6 Data Definition DECLARE FUNCTION lets you assign a data type to parameters and to the value a function returns. DECLARE FUNCTION also lets you name the function without using the usual convention (beginning the function name with FN and ending the function name with a percent or dollar sign suffix). For example: Example DECLARE STRING FUNCTION concat (STRING, STRING) !Declare the function new_string$ = concat(A$, B$) DEF concat (STRINGY, STRING Z) concat = Y + Z END DEF !Invoke the function !Define the function END This format allows only one data type in a single statement. Declaring more than one type of function requires a DECLARE statement for each type. These data typing features give you control over storage allocation. Compiling a program with OPTION TYPE= EXPLICIT is particularly useful because it causes VAX BASIC to signal an error when an implicit variable is encountered. This prevents a typing mistake from being interpreted as a new variable. DIGITAL supports implicit variables for compatibility with other BASICs and also because they are useful for beginning programmers. However, DIGITAL recommends that you use explicit declarations for new program development. 9.5 Declaring Named Constants Explicitly Constants are values that do not change during program execution. You can declare named constants within a program unit with the DECLARE statement. You can also refer to constants outside the program unit with the EXTERNAL statement. In addition, VAX BASIC provides notation for binary, octal, decimal, and hexadecimal constants. Data Definition 9-7 Named constants are useful for the following reasons: • • 9.5.1 If a commonly-used constant must be changed, you can make the change in a single place. They make the program easier to understand. Declaring Constants Within a Program Unit The value assigned to a named constant need not be in the allowable range of the default data type; however, it must be in the valid range of the data type being declared. The following statement declares a LONG constant named XYZ and assigns it a value of 1000. In DECLARE CONSTANT statements, VAX BASIC signals an overflow error only if the value is outside the range of the data type being declared. DECLARE LONG CONSTANT XYZ = 1000 The following example declares a double-precision constant: Example DECLARE DOUBLE CONSTANT plancks = 6.6237E-27 INPUT "FREQUENCY"; freq PRINT "ENERGY EQUALS"; plancks I freq END A DECLARE CONSTANT statement allows only one data type. To declare constants of different data types, you must use additional DECLARE CONSTANT statements. 9.5.2 Declaring Constants External to the Program Unit To declare constants external to the program unit, use the EXTERNAL statement. For example: EXTERNAL LONG CONSTANT SS$_NORMAL The VAX/VMS Linker automatically supplies the values for constants specified in EXTERNAL statements. For more information on using the EXTERNAL statement, see the VAX BASIC Reference Manual. 9-8 Data Definition 9.5.3 Declaring a Default Constant Type To declare a default constant type, specify a CONSTANT TYPE clause with the OPTION statement. This CONSTANT TYPE clause specifies the data type for all constants that do not end in a data type suffix or are not in explicit literal notation with a data type supplied. For instance, the following OPTION statement specifies that all implicitly typed constants will be INTEGER. OPTION CONSTANT TYPE = INTEGER 9.6 Operations with Multiple Data Types When an expression contains operands of different data types, it is called a mixed-mode expression. Before a mixed-mode expression can be evaluated, the operands must be converted, or promoted, to a common data type. The result of the evaluation may also be converted depending on the data type of the variable to which it is assigned. When evaluating mixed-mode expressions, VAX BASIC performs promotions such that no operand loses any range or precision. When assigning values to variables, VAX BASIC converts the result of the expression to the data type of the variable. If the value of the expression is outside the allowable range of the variable's data type, VAX BASIC signals "Integer error or overflow", "Floating-point error or overflow", or "DECIMAL error or overflow". In general, VAX BASIC promotes operands with different data types to the lowest data type that can hold the largest and most precise possible value of either operand's data type. VAX BASIC then performs the operation in that data type, and yields a result of that data type. If the result of the expression is assigned to a variable, VAX BASIC converts the result to the data type of the variable. Table 9-2 lists the resulting data type for all combinations except those involving DECIMAL data types. Data Definition 9-9 Table 9-2: Result Data Types in VAX BASIC Expressions BYTE WORD LONG SINGLE DOUBLE GFLOAT HFLOAT BYTE BYTE WORD LONG SINGLE DOUBLE GFLOAT HFLOAT WORD WORD WORD LONG SINGLE DOUBLE GFLOAT HFLOAT LONG LONG LONG LONG SINGLE DOUBLE GFLOAT HFLOAT SINGLE SINGLE SINGLE SINGLE SINGLE DOUBLE GFLOAT HFLOAT DOUBLE DOUBLE DOUBLE DOUBLE DOUBLE DOUBLE HFLOAT HFLOAT GFLOAT GFLOAT GFLOAT GFLOAT GFLOAT HFLOAT GFLOAT HFLOAT HFLOAT HFLOAT HFLOAT HFLOAT HFLOAT HFLOAT HFLOAT HFLOAT For example, if one operand is SINGLE and one operand is DOUBLE, VAX BASIC promotes the SINGLE value to DOUBLE, performs the specified operation, and returns the result as a DOUBLE value. This promotion is necessary because the SINGLE data type has less precision than the DOUBLE value, whereas the DOUBLE data type can hold the largest and most precise possible SINGLE value. If VAX BASIC did not promote the SINGLE value and the operation yielded a more precise result than was represented in SINGLE, the value would lose precision. With one exception, the resulting data type is the same as that of the operand with the higher data type. The exception is when the operands are DOUBLE and GFLOAT. When an expression contains a DOUBLE and a GFLOAT operand, VAX BASIC promotes both values to HFLOAT, and returns an HFLOAT value. This is necessary because a DOUBLE value is more precise than a GFLOAT value, but cannot contain the largest possible GFLOAT value. Consequently, VAX BASIC promotes these data types to a data type that can hold the largest and most precise value of either operand. VAX BASIC also allows the DECIMAL(d,s) data type. DECIMAL values are converted to REAL before exponentiation. For all other operations involving a DECIMAL value, the number of digits ( d) and the scale or position of the decimal point ( s) in the result depend on the data type of the other operand. If one operand is DECIMAL and the other is DECIMAL or INTEGER, the d and s values of the result are determined as follows: • 9-10 Data Definition If both operands are typed DECIMAL, and if both operands have the same digit ( d) and scale ( s) values, no conversions occur and the result of the operation has exactly the same d and s values as the operands. Note, however, that overflow can occur if the result exceeds the range specified by the d value. • If both operands are DECIMAL, but have different digit and scale values, VAX BASIC always uses the larger number of specified digits for the result. In the following statements, variable A allows three digits to the left of the decimal point and two digits to the right. Variable B allows one digit to the left of the decimal point and three digits to the right. DECLARE DECIMAL(5,2) A DECLARE DECIMAL(4,3) B Therefore, the result allows three digits to the left of the decimal point and three digits to the right. If one operand is typed DECIMAL and one is typed INTEGER, the INTEGER value is converted to a DECIMAL(d,s) data type as follows: • • • BYTE is converted to DECIMAL(3,0). WORD is converted to DECIMAL(S ,O). LONG is converted to DECIMAL(lO,O). VAX BASIC then determines the d and s values of the result by evaluating the d ands values of the operands as described above. Note that only INTEGER data types are converted to the DECIMAL data type. If one operand is DECIMAL and one is floating-point, the DECIMAL value is converted to a floating-point value. The total number of digits ( d) in the DECIMAL value determines its new data type: Range of d Converted to: <=1 through <= 6 SINGLE <= 7 through <= 15 DOUBLE GFLOAT HFLOAT = 16 DOUBLE <= 17 through <= 31 HFLOAT If the value of dis between 7 and 15, the operand is converted to DOUBLE if the floating-point operand is DOUBLE, to GFLOAT if the floating-point operand is GFLOAT, and to HFLOAT if the floating-point operand is HFLOAT. Thus, a DECIMAL(8,5) operand is converted to DOUBLE if the other operand is SINGLE or DOUBLE, to GFLOAT if the other operand is GFLOAT, and to HFLOAT if the other operand is HFLOAT. Data Definition 9-11 Figure 9-1 shows a mixed-mode expression, and the data types of the intermediate and final results. Figure 9-1 : Mixed-Mode Expression Results v WORD • LONG I DECIMAL(6,2) LONG + ( DOUBLE • GFLOAT v HFLOAT ~ HFLOAT ZK-5182-86 Note that the LONG integer is first converted to DECIMAL(lO,O). When VAX BASIC performs the division, both operands are converted to DECIMAL(l2,2). You can convert any numeric variable or expression to a specified data type with the REAL, INTEGER, and DECIMAL functions. See the VAX BASIC Reference Manual for more information on these functions. 9. 7 Allocating Static Storage VAX BASIC programs allocate both static and dynamic storage. The size of static storage does not change during program execution. Variables and arrays appearing in MAP or COMMON statements use static storage. Because this storage is static, all string variables appearing in MAP or COMMON statements are fixed-length strings. 9-12 Data Definition Dynamic storage is allocated when the program executes. Variables and arrays declared in the following statements use dynamic storage: • • • DECLARE statements DIMENSION statements Implicitly declared variables Normally, string variables and arrays declared in this way are dynamic strings, and their length can change during program execution. However, if you declare or dimension an array of a user-defined data type (a RECORD name), then all string variables and arrays are fixed-length strings. See Chapter 10 in this manual for more information about the RECORD statement. MAP and COMMON statements create a named storage area called a program section, or PSECT. MAP statements require a map name, but in COMMON statements the name is optional. The PSECT name is the same as the map or common name. If you do not specify a common name, VAX BASIC supplies a default PSECT name of $BLANK. The following sections explain how to use static storage. 9. 7.1 The COMMON Statement The COMMON statement defines a named area of storage (called a PSECT). Any VAX BASIC subprogram can access the values in a common by specifying a common with the same name. An item in a COMMON statement can be any one of the following: • • • • • • A numeric variable A numeric array A fixed-length string variable An array of fixed-length strings A RECORD instance A FILL item The amount of storage reserved for a variable depends on its data type. You can specify a length for string variables and string array elements that appear in a COMMON statement. If you do not specify a length, the default is 16. The following statement specifies 2 bytes for emp.code, 3 bytes for wage.code, and 22 bytes for dep.code. COMMON (code) STRING emp.code=2, wage.code=3, dep.code=22 Data Definition 9-13 In a single program module, multiple common areas with the same name allocate storage end-to-end in a single PSECT. That is, VAX BASIC concatenates all common areas with the same name in the same program module, in the order they appear. For example, the following statements allocate storage for five LONG integers in a single PSECT named into. COMMON (into) LONG call_count, sub1_count, sub2_count COMMON (into) LONG sub3_count, sub4_count When you explicitly declare an array, VAX BASIC allows you to specify both upper and lower bound values. The value you supply as the upper bound determines the maximum subscript value for a given dimension, whereas the value you supply for the lower bound determines the minimum subscript value for a given dimension. For more information on specifying bounds with the COMMON statement, see the VAX BASIC Reference Manual and Chapter 8 in this manual. 9. 7.2 The MAP Statement The MAP statement, like the COMMON statement, creates a named area of static storage. However, if a program module contains multiple maps with the same name, the maps are overlaid on the same area of storage, rather than being concatenated. When used with the MAP clause of the OPEN statement, the storage allocated by the MAP statement becomes the record buffer for that file. Variables in the MAP statement correspond to fields in the file's records. A map item can be one of the following: • • • • • • A numeric variable A numeric array A fixed-length string variable An array of fixed-length strings A RECORD instance A FILL item When you explicitly declare an array, VAX BASIC allows you to specify both upper and lower bound values. The value you supply as the upper bound determines the maximum subscript value for a given dimension, whereas the value you supply for the lower bound determines the minimum subscript value for a given dimension. 9-14 Data Definition For more information on specifying bounds with the MAP statement, see the VAX BASIC Reference Manual, and Chapter 8 in this manual. 9. 7 .2. 1 Single Maps You associate a map with a record buffer by referencing the map in the OPEN statement. The MAP statement must appear before any reference to map variables. For example, the following program uses map variables to access fields in payroll records. Changes to map variables do not change the actual records in the file. To transfer the changed variables to the file, you must use the PUT or UPDATE statement. For more information, see Chapter 15. Example WHEN ERROR USE eof_handler DECLARE INTEGER CONSTANT EOF = 11 MAP (PAYROL) STRING emp_name, LONG wage_class, & STRING sal_rev_date, SINGLE tax_ytd OPEN "payroll.dat" FOR INPUT AS FILE #4Y. ,ORGANIZATION SEQUENTIAL ,ACCESS READ ,MAP PAYROL OPEN "payrol. new" FOR OUTPUT AS FILE #6Y. ,ORGANIZATION SEQUENTIAL ,ACCESS WRITE ,MAP payrol & & & & & & PRINT "PAYROLL VERIFICATION" get_loop: WHILE 1Y. = 1Y. GET #4 PRINT emp_name, wage_class, sal_rev_date, tax_ytd PRINT "YOU CAN CHANGE:" PRINT "1. EMPLOYEE NAME" PRINT 11 2. WAGE CLASS" PRINT "3. REVIEW DATE" PRINT "4. TAX YEAR-TO-DATE" PRINT "5. DONE" read_loop: WHILE 1Y. = 1Y. Data Definition 9-1 5 INPUT "CHANGES? ANSWER WITH YES OR NO" IF chng$ = "NO" THEN ITERATE get_loop ELSE INPUT "NUMBER" ;numberY. chng$ END IF SELECT numberY, CASE 1 INPUT "EMPLOYEE NAME"; emp_name CASE 2 INPUT "WAGE CLASS"; wage_class CASE 3 INPUT "REVIEW DATE";sal_rev_date CASE 4 INPUT "TAX YEAR-TO-DATE"; tax_ytd CASE 5 EXIT read_loop CASE ELSE PRINT "Invalid response -- please try again" END SELECT NEXT PUT #5 NEXT END WHEN HANDLER eof_handler IF ERR = EOF THEN PRINT "End of file" ELSE EXIT HANDLER END IF END HANDLER END 9.7.2.2 Multiple Maps When a program contains more than one map with the same name, the storage allocated by these MAP statements is overlaid, as shown in Figure 9-2. This technique is useful for manipulating strings. When you use more than one map to access a record buffer, VAX BASIC uses the size of the largest map to determine the size of the record. (The RECORDSIZE clause of the OPEN statement can override this map-defined record size. For more information, see Chapter 15.) 9-16 Data Definition Figure 9-2: Multiple Maps NA.ME$= 40 BYTES ~~ .....,., ( ADDRESS$= 44 BYTES FIRST.NAMES$ LAST.NAMES$ 15 BYTES 25 BYTES STREET. NUMBER$ ~ STREET$ CITY$ 16 BYTES 23 BYTES 5 BYTES ZK-5183-86 You can also use multiple maps to interpret numeric data in more than one way. The following example creates a map area named barray. The first MAP statement allocates 26 bytes of storage in the form of an integer BYTE array. The second MAP statement defines this same storage as a 26-byte string named ABC. When the FOR ... NEXT loop executes, it assigns values corresponding to the ASCII values for the uppercase letters A through Z. Example MAP (barray) BYTE alphabet(26) MAP (barray) STRING ABC = 26 FOR IY. = OY. TO 26% alphabet(IY.) = IY. + 66Y. NEXT !Y. PRINT ABC END Output ABCDEFGHIJKLMNOPQRSTUVWXYZ 9. 7.3 FILL Items FILL items reserve space in map and common blocks and in record buffers accessed by MOVE or REMAP statements. Thus, FILL items mask parts of the record buffer and let you skip over fields and reserve space in or between data elements. Data Definition 9-17 FILL formats are available for all data types. Table 9-3 summarizes the FILL formats and their default allocations if no data type is specified. Table 9-3: FILL Item Formats, Representations, and Default Allocations FILL Format Representation Bytes Used FILL Floating-point 4, 8, or 16 FILL(n) n floating-point elements 4n, 8n, or 16n FILL% Integer (BYTE, WORD, or LONG) 1, 2, or 4 FILL%(n) n integer elements ln, 2n, or 4n FILL$ String 16 FILL$(n) n string elements 16n FILL$= m String m FILL$(n) = m n string elements, m bytes each NOTE In the applicable formats of FILL, n represents a repeat count, not an array subscript. FILL(n), for example, represents n real elements, not n+l. You can also use data type keywords with FILL and optionally data type suffixes. The data type and storage requirements are those of the last data type specified. For example: MAP (QED) STRING A, FILL$=24, LONG SSN, FILLY., REAL SAL, FILL(5) This MAP statement uses data type keywords to reserve space for • • • • • • 9-18 Data Definition A 16-character string variable A. Twenty-four bytes of padding. One LONG variable, SSN. Four bytes of padding. One REAL variable, SAL. Space for five floating-point numbers. This requires 10, 20, or 80 bytes of padding, depending on the default size for floating-point numbers. You can specify user-defined data types (RECORD names) for FILL items. For instance, in the following example, the first line defines a RECORD of data type X. The MAP statement contains a fill item of this data type, thus reserving space in the buffer for one RECORD of type X. RECORD X REAL Y1, Y2(10) END RECORD X MAP (QED) X FILL See Chapter 10 for more information on the RECORD statement. 9. 7.4 Using COMMON and MAP in Subprograms The COMMON and MAP statements create a block of storage called a PSECT. This common or map storage block is accessible to any subprogram. A VAX BASIC main program and a subprogram can share such an area by referencing the same common or map name. For instance, the following example contains common blocks that define • • • A 16-character string field called A by the main program and X by the subprogram A 10-character string field called B by the main program and Z by the subprogram A 4-byte integer field called C by the main program and Y by the subprogram !In a main program COMMON (A1) STRING A, B = 10, LONG C !In a subprogram COMMON (A1) STRING X, Z = 10, LONG Y If a subprogram defines a common or map area with the same name as a common or map area in the main program, it overlays the common or map defined in the main program. Multiple COMMON statements with the same name behave differently depending on whether these statements are in the same program module. If they are in the same program module, then the storage for each common area is concatenated. However, if they are in different program units, then the common areas overlay the same storage. The following COMMON statements are in the same program module; therefore, they Data Definition 9-19 are concatenated in a single PSECT. The PSECT contains two 32-byte strings. COMMON (XYZ) STRING A = 32 COMMON (XYZ) STRING B = 32 In contrast, the following COMMON statements are in different program modules, and thus overlay the same storage. Therefore, the PSECT contains one 32-byte string, called A in the main program and Bin the subprogram. !In the main program COMMON (XYZ) STRING A = 32 !In the subprogram COMMON (XYZ) STRING B = 32 Although you can redefine the storage in a common section when you access it from a subprogram, you should generally not do so. Common areas should contain exactly the same variables in all program modules. To make sure of this, you should use the %INCLUDE directive, as shown in the following example: Example COMMON (SHARE) WORD emp_num, DECIMAL (8,0) salary, STRING wage_class = 2 It It !In the main program %INCLUDE "COMMON.BAS" !In the subprogram %INCLUDE "COMMON.BAS" If you use the %INCLUDE directive, you can lessen the chance of a typographical error appearing in your program. For more information on using the %INCLUDE directive, see Chapter 18. If you must redefine the variables in a PSECT, you should use the MAP statement or a record with variants for each overlay. When you use the MAP statement, use the %INCLUDE directive to create identical maps before redefining them, as shown in the following example. The map defined in MAP.BAS is included in both program modules as a 40-byte 9-20 Data Definition string. This map is redefined in the subprogram, allowing the subprogram to access parts of this string. Example MAP (REDEF) STRING f ull_name = 40 !In the main program %INCLUDE "MAP.BAS" !In the subprogram %INCLUDE "MAP.BAS" MAP (REDEF) STRING first_name=15, MI=1, last_name=24 9.8 Dynamic Mapping Dynamic mapping lets you redefine the position of variables in a static storage area. This storage area can be either a map name or a previously declared static string variable. Dynamic mapping requires three VAX BASIC statements: • • • A declarative statement, such as a MAP statement, allocating a fixedlength storage area A MAP DYNAMIC statement, naming the variables whose positions can change at run time A REMAP statement, specifying the new positions of the variables named in the MAP DYNAMIC statement The MAP DYNAMIC statement does not affect the amount of storage allocated. The MAP DYNAMIC statement causes VAX BASIC to create internal pointers to the variables and array elements. Until your program executes the REMAP statement, the storage for each variable and each array element named in the MAP DYNAMIC statement starts at the beginning of the map storage area. The MAP DYNAMIC statement is nonexecutable. With this statement, you cannot specify a string length. All string items have a length of zero until the program executes a REMAP statement. Data Definition 9-21 The REMAP statement specifies the new positions of variables named in the MAP DYNAMIC statement. That is, it causes VAX BASIC to change the internal pointers to the data. Because the REMAP statement is executable, it can redefine the pointer for a variable or array element each time the REMAP statement is executed. With the MAP DYNAMIC statement, you can specify either a map name or a previously declared static string variable. When you specify a map name, a MAP statement with the same map name must lexically precede the MAP DYNAMIC statement. In the following example, the MAP statement creates a storage area and names it emp_buffer. The MAP DYNAMIC statement specifies that the positions of variables emp_name and emp_address within the map area, can be dynamically defined with the REMAP statement. Example DECLARE LONG CONSTANT emp_fixed_info = 4 + 9 + 2 MAP (emp_buffer) LONG badge, & STRING social_sec_num = 9, & BYTE name_length, & address_length, & FILL (60) MAP DYNAMIC (emp_buffer) STRING emp_name, emp_address & WHILE 1% GET #1 REMAP (emp_buffer) STRING FILL = emp_fixed_info, & emp_name = name_length, & emp_address = address_length NEXT At the start of program execution, the storage for badge is the first 4 bytes of emp_buffer, the storage for social _sec_num is equal to 9 bytes and together name_f ength and address_length are equal to 2 bytes. The FILL keyword reserves 60 additional bytes of storage. The MAP DYNAMIC statement defines the variables emp_name and emp_address whose positions and lengths will change at run time. When executed, the REMAP statement defines the FILL area to be equal to emp-fixed_info and defines the positions and lengths of emp_name and emp_address. When you specify a static string variable, it must be either a variable declared in a MAP or COMMON statement or a parameter declared in a SUB, FUNCTION, PICTURE or DEF. The actual parameter passed to the procedure must be a static string variable defined in a COMMON, MAP, or RECORD statement. 9-22 Data Definition The following example shows the use of a static string variable as a parameter declared in a SUB. The MAP DYNAMIC statement specifies the input parameter, input_rec, as the string to be dynamically defined with the REMAP statement. In addition, the MAP DYNAMIC statement specifies a string array A whose elements will point to positions in input_ rec after the REMAP statement is executed. The REMAP statement defines the length and position of each element contained in array A. The FOR. .. NEXT loop then assigns each element contained in array A into array item, the target array. Example SUB deblock (STRING input_rec, STRING item()) MAP DYNAMIC (input_rec) STRING A(1 TO 3) REMAP (input_rec) & A(1) = 5, & A(2) = 3, & A(3) = 4 FOR I = LBOUND{A) TO UBOUND(A) item(!) = A(I) NEXT I END SUB Note that dynamic map variables are local to the program module in which they reside. Therefore, REMAP only affects how that module views the buffer. For more information on using the MAP DYNAMIC and REMAP statements, see the VAX BASIC Reference Manual. Data Definition 9-23 Chapter 10 Creating and Using Data Structures A data structure is a collection of data items that can contain elements or components of different data types. The RECORD statement lets you create your own data structures. You use the RECORD statement to create a pattern of a data structure, called the RECORD template. Once you have created a template, you use it to declare an instance of the RECORD, that is, a RECORD variable. You declare a record variable just as you declare a variable of any other type: with the DECLARE statement or another declarative statement. A RECORD instance is a variable whose structure matches that of the RECORD template. Remember that the RECORD statement does not create any variables. It merely creates a template, or user-defined data type, that you can then use to create variables. This chapter describes how to create and use data structures. 10. 1 The RECORD Statement The RECORD statement names and defines a data structure. Once a data structure (or RECORD) has been named and defined, you can use that RECORD name anywhere that you can use a VAX BASIC data type keyword. You build the data structure using: • • • Variables of any valid VAX BASIC data type RECORD variables of previously defined RECORD data types Any combination of the two Creating and Using Data Structures 10-1 The following example creates a RECORD template called Employee. Employee is a data structure that contains one LONG integer, one 10-character string, one 20-character string, and one 11-character string. Example RECORD Employee LONG Emp_number STRING First_name = 10 STRING Last_name = 20 STRING Soc_sec_number = 11 END RECORD Employee To create instances of this data structure, you use declarative statements. For instance, in the following example, the first DECLARE statement creates a variable named Emp_rec of data type Employee. The second DECLARE statement creates a one-dimensional array, named Emp_array, that contains 1001 instances of the Employee data type. Example DECLARE Employee Emp_rec DECLARE Employee Emp_array (1000) Any reference to a RECORD component must contain the name of the RECORD instance (that is, the name of the declared variable) and the name of the elementary RECORD component you are accessing, separated by two colons ( :: ). For example, the following program assigns values to an instance of the Employee RECORD template: Example ! Record Template RECORD Employee LONG Emp_number STRING First_name = 10 STRING Last_name = 10 STRING Soc_sec_number = 11 END RECORD Employee ! Declarations DECLARE Employee Emp_rec DECLARE STRING Social_security ! Program logic starts here. 10-2 Creating and Using Data Structures INPUT 'Employee number'; Emp_rec::Emp_number INPUT 'First name'; Emp_rec::First_name INPUT 'Last name'; Emp_rec::Last_name INPUT 'Social security'; Social_security IF Social_security <> "" THEN Emp_rec::Soc_sec_number = Social_security END IF PRINT PRINT "Employee number is: "; Emp_rec::Emp_number Emp_rec::First_name PRINT "First name is: "; Emp_rec::Last_name PRINT "Last name is: "; PRINT "Social security is: "; Emp_rec::Soc_sec_number END When you access an array of RECORD instances, the array subscript should immediately follow the name of the RECORD variable. The following example shows an array of RECORD instances. Example ! Record Template RECORD Employee LONG Emp_number STRING First_name = 10 STRING Last_name = 10 STRING Soc_sec_number = 11 END RECORD ! Declarations DECLARE Employee Emp_array ( 10 ) DECLARE INTEGER Index DECLARE STRING Social_security ! Program logic starts here. FOR Index = 0 TO 10 PRINT INPUT 'Employee number'; Emp_array(Index)::Emp_number INPUT 'First name'; Emp_array(lndex)::First_name INPUT 'Last name'; Emp_array(Index)::Last_name INPUT 'Social security'; Social_security IF Social_security <> "" THEN Emp_array(Index)::Soc_sec_number = Social_security END IF NEXT Index FOR Index = 0 TO 10 Creating and Using Data Structures 10-3 PRINT PRINT "Employee number is: "; Emp_array(Index)::Emp_number Emp_array(Index)::First_name PRINT "First name is: "; PRINT "Last name is: "; Emp_array(Index)::Last_name PRINT "Social security is: "; Emp_array(Index)::Soc_sec_number NEXT Index END You can have a RECORD that contains an array. When you declare arrays, VAX BASIC allows you to specify both lower and upper bounds. Example RECORD Grade_record STRING INTEGER Student_name = 30 Quiz_scores (1 TO 10) Array to hold ten quiz grades. END RECORD ! Declarations DECLARE Grade_record Student_grades ( 5 ) !The Student_grades array holds information on six students !(O through 5), each of whom has ten quiz grades (1through10). DECLARE INTEGER I,J !Program logic starts here. FOR I = 0 TO 5 !This loop executes once for each student. PRINT INPUT 'Student name'; Student_grades(I)::Student_name FOR J = 1 TO 10 !This loop executes ten times for each student. PRINT 'Score for quiz number'; J INPUT Student_grades(I)::Quiz_scores(J) NEXT J NEXT I FOR I = 0 TO 5 PRINT PRINT 'Student name: '; Student_grades(I)::Student_name FOR J = 1 TO 10 PRINT 'Score for quiz number'; J; ": "; PRINT Student_grades(I)::Quiz_scores(J) 10-4 Creating and Using Data Structures NEXT J NEXT I END Because any reference to a component of a RECORD instance must begin with the name of the RECORD instance, RECORD component names need not be unique in your program. For example, you can have a RECORD component called First_name in any number of different RECORD statements. References to this component are unambiguous because every RECORD component reference must specify the record instance in which it resides. 10.1.1 Grouping RECORD Components A RECORD component can consist of a named group of instances, identified with the keyword GROUP. You use GROUP to refer to a collection of RECORD components, or to create an array of components that have different data types. The GROUP name can be followed by a list of upper and lower bounds, which define an array of the GROUP components. GROUP is valid only within a RECORD block. The declarations between the GROUP statement and the END GROUP statement are called a GROUP block. For instance, the following example declares a RECORD template of data type Yacht. Yacht is made up of two groups: Type_of_yacht and Specifications. Each of these groups is composed of elementary RECORD components. VAX BASIC also allows groups within other groups. Example RECORD Yacht GROUP Type_of _yacht STRING Manufacturer = 10 STRING Model = 10 END GROUP Type_of _yacht GROUP Specifications STRING Rig = 6 STRING Length_over_all = 3 DECIMAL(6,0) Displacement DECIMAL(2,0) Beam DECIMAL(7,2) Price END GROUP Specifications END RECORD Yacht Creating and Using Data Structures 10-5 10.1.2 RECORD Variants In some cases, it is useful to have different record components overlay the same record field, in much the same way that multiple maps can overlay the same storage. Such an overlay is called a RECORD variant. You use the keywords VARIANT and CASE to set up RECORD variants. The following example creates a RECORD template for any of three kinds of boats. Example RECORD Boat STRING Make = 10 STRING Model = 10 STRING Type_of_boat = 1 This field contains the value S, P, or C. Value S causes the record instance to be interpreted as describing a sailboat, value P as describing a powerboat, and value C as describing a canoe. VARIANT CASE ! Sailboats STRING Rig CASE WORD CASE WORD WORD = 20 ! Powerboats Horsepower ! Canoes Length Weight END VARIANT END RECORD The SELECT ... CASE statement makes it easy to access one of several possible RECORD variants in a particular RECORD instance. A RECORD component outside the overlaid fields usually determines which RECORD variant is being used in a particular reference; in this case the determining RECORD component is Type_of_boat. You can use this component in the SELECT expression. 10-6 Creating and Using Data Structures Example ! Declarations DECLARE Boat My_boat Main program logic starts here Input_boat_information: INPUT 'Make of boat'; My_boat::Make INPUT 'Model'; My_boat::Model PRINT 'Type of boat (S =Sailboat, P =Powerboat, C =Canoe)'; INPUT My_boat::Type_of_boat SELECT My_boat::Type_of_boat CASE "S" INPUT ' Sail rig' ; My _boat : : Rig CASE "P" INPUT 'Horsepower'; My_boat::Horsepower CASE "C" INPUT 'Length'; My_boat::Length INPUT 'Weight'; My_boat::Weight CASE ELSE PRINT "Invalid type of boat, please try again." END SELECT The value of the Type_of_boat component determines the format of the variant part of the record. The following example is a slightly more complex version of the same type of procedure. This program prompts for the RECORD instance components in each variant. When the user responds to the "Wage Class" prompt, the program branches to one of three case blocks depending on the value of Wage_class. Creating and Using Data Structures 10-7 Example !Record templates RECORD Emp_wage_class STRING Emp_name = 30 Employee name string. STRING Street = 16 STRING City = 20 STRING State = 2 DECIMAL(6,0) Zip These components make up the employee address field. STRING Wage_class 1 VARIANT CASE GROUP Hourly DECIMAL(4,2) Hourly_wage SINGLE Regular_pay_ytd SINGLE Overtime_pay_ytd Hourly workers. Hourly wage rate. Regular pay year-to-date. Overtime pay year-to-date. END GROUP Hourly CASE GROUP Salaried DECIMAL(7,2) Yearly_salary SINGLE Pay_ytd Salaried workers. Yearly salary. Pay year-to-date. END GROUP Salaried CASE GROUP Executive DECIMAL(8,2) Yearly_salary SINGLE Pay_ytd SINGLE Expenses_ytd Executives. Yearly salary. Pay year-to-date. Expenses year-to-date. END GROUP Executive END VARIANT END RECORD Declarations: DECLARE Emp_wage_class Emp Main Program logic starts here. LINPUT "Name"; Emp: :Emp_name LINPUT "Street"; Emp::Street LINPUT "State"; Emp::State INPUT "Zip Code"; Emp::Zip LINPUT "Wage Class"; Emp::Wage_class 10-8 Creating and Using Data Structures Use LINPUT statements for string fields so the entire string is assigned to the variable. SELECT Emp::Wage_class CASE "A" INPUT 'Rate';Emp::Hourly_wage INPUT 'Regular pay';Emp::Regular_pay_ytd INPUT 'Overtime pay';Emp::Overtime_pay_ytd CASE "B" INPUT 'Salary';Emp::Salaried::yearly_salary INPUT 'Pay YTD';Emp::Salaried::pay_ytd CASE "C" INPUT 'Salary';Emp: :Executive::yearly_salary INPUT 'Pay YTD';Emp::Executive::pay_ytd INPUT 'Expenses';Emp::Expenses_ytd END SELECT Variant fields can appear anywhere within the RECORD. When you use RECORD variants, you imply that any RECORD instance can contain any one of the listed variants. Therefore, if each variant requires a different amount of space, VAX BASIC uses the case that requires the most storage to determine the space allocated for each RECORD instance. 10.1.3 Accessing RECORD Components To access a particular elementary component within a RECORD that contains other groups, you use the name of the declared RECORD instance, the group name (or group names, if groups are nested), and the elementary component name, each separated by double colons ( :: ). In the following example, the PRINT statement displays the Rig component in the Specifications group in the variable named My_yacht. The RECORD instance name qualifies the group name and the group name qualifies the elementary RECORD component. The elementary component name, qualified by all intermediate group names, and by the RECORD instance name, is called a fully qualified component. The full qualification of a component is called a component path name. Example DECLARE Yacht My_yacht PRINT My_yacht::Specifications::Rig Creating and Using Data Structures 10-9 Because it is cumbersome to specify the entire component path name, VAX BASIC allows elliptical references to RECORD components. GROUP names are optional in the component path name unless: • • A RECORD contains more than one component with the same name The GROUP is an array The rules for using elliptical references are as follows: • • • • You must always specify the RECORD instance, that is, the name of the declared variable. You must always specify any dimensioned group. You may omit any other intermediate component names. You must specify the final component name. The following example shows that using the complete component path name is valid but not required. The assignment statement uses the fully-qualified component name; the PRINT statement uses an elliptical reference to the same component, omitting Extended-family and Nuclear_ family GROUP names. Note that the Children GROUP name is required because the GROUP is an array; the elliptical reference to this compon~rtt must include the desired array element, in this case the second element of the Children array. Example ! RECORD templates: RECORD Family GROUP Extended_family STRING Grandfather(1) = 30 STRING Grandmother(1) = 30 Two-element fixed-length string arrays for the names of maternal and paternal grandparents. GROUP Nuclear_family STRING Father = 30 STRING Mother = 30 GROUP Children (10) STRING Kid = 10 STRING Gender = 1 END GROUP Children END GROUP Nuclear_family END GROUP Extended_f amily 10-10 Creating and Using Data Structures Fixed-length strings for the names of parents. An 11-element array for the names and gender of children. END RECORD ! Declarations DECLARE Family My_family ! Program logic starts here. My_family: :Extended_family: :Nuclear_family: :Children(!): :Kid = "Johnny" PRINT My_family: :Children(1)::Kid END Output Johnny Example ! RECORD Templates. RECORD Test INTEGER Test_integers(2) 3-element array of integers. GROUP Group_! Single GROUP containing: REAL My_number STRING Group_1_string a real number and a 16-character (default) string END GROUP GROUP Group_2(6) INTEGER My_number DECIMAL Group_2_decimal A 6-element GROUP, each element containing: an integer and a DECIMAL number. END GROUP END RECORD ! Declarations DECLARE Test Array_of_test(10) DECLARE Test Single_test Create an 11-element array of type Test ... ... and a separate single instance of type Test. The minimal reference to the string Group_L...string in RECORD instance Array_of_test is as follows: Array_of_test(i)::Group_1_string In this case, i is the subscript for array Array_of_test. Because the RECORD instance is itself an array, the reference must include a specific array element. Creating and Using Data Structures 10-11 Because Single_test is not an array, the minimal reference to string Group_1_string in RECORD instance Single_test is as follows: Single_test::Group_1_string The minimal reference for the REAL variable My_number in GROUP Group_1 in RECORD instance Array_of_test is as follows: Array_of_test(i}::Group_1::My_nwnber Here, i is the subscript for array Array_of_test. The minimal reference to the REAL variable My_number in RECORD instance Single_test is as follows: Single_test::Group_1::My_nwnber Because there is a variable named My_number in groups Group_1 and Group_2, you must specify either Group_1::My_number or Group_2(i)::My_ number. In this case, extra component names are required to resolve an otherwise ambiguous reference. The minimal reference to the DECIMAL variable Group_2_decimal in RECORD instances Array_of_test and Single_test are the fully qualified references. In the following examples, i is the subscript for array Array_of_test and j is an index into the group array Group_2. Even though Group_2_decimal is a unique component name within RECORD instance Single_test, the element of array Group_2 must be specified. In this case the extra components must be specified because each element of group Group_2 contains a component named Group_2_decimal. Array_of_test(i): :Group_2(j)::Group_2_decimal Single_test::Group_2(j)::Group_2_decimal You can assign all the values from one RECORD instance to another RECORD instance, as long as the RECORD instances are identical except for names. In the following example, RECORD instances First_test1, Second_test1, and the individual elements of array Array_of-test1 have the same form: an array of four groups, each of which contains a 10-byte string variable, followed by a REAL variable, followed by an INTEGER variable. Any of these RECORD instances can be assigned to one another. 10-12 Creating and Using Data Structures Example !RECORD Templates RECORD Test1 GROUP Group_1(4) STRING My_string_1 REAL My_real_1 INTEGER My_integer_1 10 END GROUP END RECORD RECORD Test2 GROUP Group_2 STRING My_string_2 REAL My_real_2 INTEGER My_integer_2 10 END GROUP END RECORD RECORD Test3 STRING My_string_3 = 10 REAL My_real_3 INTEGER My_integer_3 END RECORD !Declarations DECLARE Test1 First_test1, Second_test1, Array_of_test1(3) t t DECLARE Test2 First_test2 DECLARE Test3 First_test3, Array_of_test3(10) t !Program logic starts here ! A single RECORD instance is assigned to another single instance First_test1 = Second_test1 ! An array element is assigned to a single instance Second_test1 = Array_of_test1(2) ! And vice versa Creating and Using Data Structures 10-13 Array_of_test1(2) = Second_test1 Further, you can assign values from single RECORD instances to groups contained in other instances. In the following example, Array_of_test1 and First_test1 do not have the same form because Array_of_test1 is an array of RECORD Test1 and First_test1 is a single instance of RECORD Test1. Therefore, First_test1 and Array_of_test1 cannot be assigned to one another. Example ! A single instance is assigned to one group Array_of_test1(3)::Group_1(2) = First_test3 ! An array element is assigned a value from ! a group contained in another array instance Array_of_test3(5) = Array_of_test1(3)::Group_1(3) The examples shown in this chapter explain the mechanics of using data structures. See Chapter 14 for more information about using data structures as parameters. See Chapter 15 for more information about using data structures for file input and output. 10-14 Creating and Using Data Structures Chapter 11 Program Control VAX BASIC normally executes statements sequentially. Control statements let you change this sequence of execution. VAX BASIC control statements can alter the sequence of program execution at several levels: • • • • • Statement modifiers control the execution of a single statement. Loops or decision blocks control the execution of a block of statements. Branching statements such as GOTO and ON GOTO pass control to statements or local subroutines. The EXIT and ITERATE statements explicitly control loops or decision blocks. The SLEEP, WAIT, STOP and END control statements suspend or halt the execution of your entire program. This chapter describes all of the VAX BASIC control statements. 11. 1 Statement Modifiers Statement modifiers are control structures that operate on a single statement. Statement modifiers let you execute a statement conditionally or create an implied loop. VAX BASIC has five statement modifiers: IF, UNLESS, FOR, UNTIL, and WHILE. A statement modifier affects only the statement immediately preceding it. You can modify only executable statements; declarative statements are not modifiable. Program Control 11-1 11. 1. 1 The IF Modifier The IF modifier tests a conditional expression. If the conditional expression is true, VAX BASIC executes the statement. If it is false, VAX BASIC does not execute the modified statement but continues execution at the next program statement. The following is an example of a statement using the IF modifier: PRINT A IF (A < 6) 11.1.2 The UNLESS Modifier The UNLESS modifier tests a conditional expression. VAX BASIC executes the modified statement only if the conditional expression is false. Like the IF modifier, the UNLESS modifier operates on a single statement: PRINT A UNLESS (A < 6) This is equivalent to PRINT A IF A >= 6 11.1.3 The FOR Modifier The FOR modifier creates a loop on a single line. The following is an example of an implied loop created by a FOR modifier: A = A + 1 FOR IY. = 11. TO 101. 11.1.4 The UNTIL Modifier The UNTIL modifier, like the FOR modifier, creates a single-line loop. However, instead of using a formal loop variable, you specify the terminating condition with a conditional expression. The modified statement executes repeatedly as long as the condition is false. For example: B = B + 1 UNTIL (A - B) < 0.0001 Because of precision limitations, you should not use real number calculations in UNTIL loops. For example: Z = Z + 1 UNTIL Z/6 = 100 11-2 Program Control Because Z/5 may never exactly equal 100, the loop could execute indefinitely. 11.1.5 The WHILE Modifier The WHILE modifier repeats a statement as long as a conditional expression is true. Like the UNTIL and FOR modifiers, it lets you create single-line loops. In the following example, VAX BASIC replaces the value of A with A/2 as long as the absolute value of A is greater than 1/10. Note that you can inadvertently create an infinite loop if the terminating condition is never reached. A= A I 2 WHILE ABS(A) > 0.1 11.1.6 Nesting Modifiers You can append more than one modifier to a statement. This is called nesting modifiers. VAX BASIC evaluates nested modifiers from right to left. If the test of the rightmost modifier fails, control passes to the next statement, not to the preceding modifier on the same line. In the following example, VAX BASIC first tests the rightmost modifier of the first PRINT statement. Because this condition is false, VAX BASIC executes the following PRINT statement and tests the rightmost modifier. Because this condition is met, VAX BASIC tests the leftmost modifier of the same PRINT statement. This condition, however, is not met. Therefore, VAX BASIC executes the following PRINT statement. Because both conditions are met in the third PRINT statement, VAX BASIC prints the value of C. Example A =5 B = 10 c = 15 PRINT "A =" A IF A = 5 UNLESS C = 15 PRINT "B =" B UNLESS C = 16 IF B = 10 PRINT "C =" C IF B = 10 UNLESS C = 5 END Output c = 16 Program Control 11-3 11.2 Loops Loops allow you to repeat the execution of a set of statements. This set of statements is called a loop block. There are three types of VAX BASIC program loops: • • • FOR. .. NEXT WHILE ... NEXT UNTIL.NEXT If you know how many times you want a loop to execute, that is, the number of iterations, you can use a FOR ... NEXT loop. If you do not know the exact number of iterations when the loop begins execution, you can use either a WHILE ... NEXT or an UNTIL.NEXT loop. Note that all of these types of loops can be nested, that is, lexically located one inside another. 11.2.1 FOR...NEXT Loops In a FOR. .. NEXT loop, you specify a loop control variable (the loop index) that determines the number of loop iterations. This number must be a scalar (unsubscripted) variable. When VAX BASIC begins execution of a FOR. .. NEXT loop, the starting and ending values of the loop control variable are known. The FOR statement assigns the control variable a starting value and a terminating value. You can use the optional STEP clause to specify the amount to be added to the loop control variable after each loop iteration. When a FOR loop block executes, the VAX BASIC compiler does the following: 1. Evaluates the starting value and assigns it to the control variable. 2. Evaluates the ending value and the step value and assigns these results to temporary storage locations. 3. Tests whether the ending value has been exceeded. If the ending value has already been exceeded, VAX BASIC executes the statement following the NEXT statement. If the ending value has not been exceeded, VAX BASIC executes the statements in the loop. 11-4 Program Control 4. Adds the step value to the control variable and transfers control to the FOR statement, which tests whether the ending value has been exceeded. Steps 3 and 4 are repeated until the ending value is exceeded. Note that VAX BASIC performs the test before the loop executes. When the control variable exceeds the ending value, VAX BASIC exits the loop, and then subtracts the step value from the control variable. This means that after loop execution, the value of the control variable is the value last used in the loop, not the value that caused loop termination. If the starting value is greater than the ending value, and the step value is positive, the loop will not execute. Example 1 assigns the values 1 through 10 to consecutive array elements 1 through 10 of New_array, whereas Example 2 assigns consecutive multiples of 2 to the odd-numbered elements of New_array. Example 1 FOR IY. = 11. TO 101. New_array(IY.) = IY. NEXT IY. Example 2 FOR IY. = 11. TO 101. STEP 2 New_array(IY.) = IY. + 1Y. NEXT lY. Note that the starting, ending, and step values can be run-time expressions. You can have VAX BASIC calculate these values when the program runs, as opposed to using a constant value. For instance, the following example assigns sales information to array Sales_data. The number of iterations depends on the value of the variable Days_in_month, which represents the number of days in that particular month. Example FOR IY. = 11. TO Days_in_month Sales_data(IY.) = Quantity_sold NEXT lY. Because the starting, ending, and step values can be numeric expressions, they are not evaluated until the program runs. This means that you can have a FOR ... NEXT loop that does not execute. The following example prompts the user for the starting, ending, and step values for a loop, and then tries to execute that loop. The loop executes zero times because it is impossible to go from 0 to 5 using a step value of -1. Program Control 11-5 Example counted = OX INPUT "Start"; startX INPUT "Finish"; finishX INPUT "Step value"; step_valX FOR IY. = startY. TO finishX STEP step_valY. counterX = counterY. + 1Y. NEXT IX PRINT "This loop executed"; counter%; "times." Output Start? O Finish? 6 Step value? -1 This loop executed 0 times. Whenever possible, you should use integer variables to control the execution of FOR. .. NEXT loops because some decimal fractions cannot be represented exactly in a binary computer, and the calculation of floating-point control variables is subject to this inherent imprecision. In the following example, the first loop uses an integer control variable while the second uses a floating-point control variable. The first loop executes 100 times and the second 99 times. After the ninety-ninth iteration of the second loop, the internal representation of the value of Floating_point_variable exceeds 10 and VAX BASIC exits the loop. Because the first loop uses integer values to control execution, VAX BASIC does not exit the loop until Integer_variable equals 100. Example Loop_count_1 = OY. Loop_count_2 = OY. FOR Integer_variable = 1Y. to 1001. STEP 1Y. Loop_count_1 = Loop_count_1 + 1Y. NEXT Integer_variable FOR Floating_point_variable = 0.1 to 10 STEP 0.1 Loop_count_2 = Loop_count_2 + 1Y. NEXT Floating_point_variable 11-6 Program Control PRINT "Integer loop count:"; Loop_count_1 PRINT "Integer loop end :"; Integer_variable PRINT "Real loop count: "; Loop_count_2 PRINT "Real loop end: "· Floating_point_variable Output Integer loop count: Integer loop end: Real loop count: Real loop end: 100 100 99 9.9 If you need to use floating-point values in a loop, you should initialize a floating-point variable and increment it within the loop. Example Real_counter = 0.1 Count_loop: FOR Integer_variable = 11. TO 1000001. Real_counter = Real_counter + .1 NEXT Integer_variable Although it is not recommended programming practice, you can assign a value to a FOR ... NEXT loop's control variable while in the loop. This affects the number of times a loop executes. For example, assigning a value that exceeds the ending value of a loop will cause the loop's execution to end as soon as VAX BASIC performs the termination test in the FOR statement. Assigning values to ending or step variables, however, has no effect at all on the loop's execution. 11.2.2 WHILE ... NEXT Loops A WHILE ... NEXT statement uses a conditional expression to control loop execution; the loop is executed as long as a given condition is true. A WHILE ... NEXT loop is useful when you do not know how many loop iterations are required. In the following example, the first statement tells the user to input data and then type DONE when he is finished. After the user enters the first piece of input, VAX BASIC executes the WHILE ... NEXT loop. If the first input value is not "DONE", the loop executes and prompts the user for another input value. Once the user enters this input value, the WHILE ... NEXT loop once again checks to see if this value corresponds to "DONE". The loop will continue executing until the user types "DONE" in response to the prompt. Program Control 11-7 Example INPUT 'Type "DONE" when finished'; Answer WHILE (Answer <> "DONE") INPUT "More data"; Answer NEXT Note that the NEXT statement in the WHILE ... NEXT and UNTIL.NEXT loops does not increment a control variable; your program must change a variable in the conditional expression or the loop will execute indefinitely. The evaluation of the conditional expression determines whether the loop executes. The test is performed (that is, the conditional expression is evaluated) before the first iteration; if the value is false (0), the loop does not execute. It can be useful to intentionally create an infinite loop by coding a WHILE ... NEXT loop whose conditional expression is always true. Of course, when doing this, you must still take care to provide a way out of the loop. You can do this with an EXIT statement or by trapping a runtime error. See Chapter 17 for more information about trapping run-time errors. 11.2.3 UNTIL...NEXT Loops The UNTIL.NEXT loop behaves exactly like a WHILE ... NEXT loop, except that the logical sense of the conditional expression is reversed; that is, the UNTIL.NEXT loop executes until a given condition is true. An UNTIL.NEXT loop executes repeatedly for as long as the conditional expression is false. Note that in UNTIL.NEXT and WHILE ... NEXT loops, the NEXT statement does not increment a control variable. You must explicitly change a variable in the conditional expression or the loop will execute indefinitely. It is possible to code the example in Section 11.2.2 as an UNTIL.. .NEXT loop as shown in the following example. These loops are equivalent except for the logical sense of the termination test (WHILE Answer < > "DONE" as opposed to UNTIL Answer = "DONE"). 11-8 Program Control Example INPUT 'Type "DONE" when finished.'; Answer UNTIL (Answer = "DONE") INPUT "More data"; Answer NEXT UNTIL and FOR loops differ because VAX BASIC exits UNTIL loops as soon as the test for the terminating condition is met. This test occurs after VAX BASIC executes the NEXT statement and before it executes the UNTIL statement. For example, the following loop executes 10 times. When VAX BASIC exits the FOR loop,]% equals 10. Example FOR JX = 1X to 101. A=A+ 1 PRINT A NEXT JX The following UNTIL loop executes only nine times. After the ninth iteration, the conditional expression is true; control then passes out of the loop. Example JX = 11. UNTIL JX = 10X PRINT JX JX = J1. + 1X NEXT 11.2.4 Nesting Loops When a loop block is entirely contained in another loop block, it is called a nested loop. The following example declares a two-dimensional array and uses nested FOR. .. NEXT loops to fill the array elements with sales information. The inner loop executes 16 times for each iteration of the outer loop. This example assigns a value to each of the 256 elements of the array. Program Control 11-9 Example DECLARE INTEGER Column_number, Row_number REAL Sales_info, Two_dim_array (161., 161.) FOR Row_number = OY. TO 161. FOR Column_number = OY. to 161. INPUT "Please enter the sales information";saies_info Two_dim_array (Row_number, Column_number) = Sales_info NEXT Column_number NEXT Row_number Note that in nested loops the inner loop is entirely contained in the outer loop: nested loops cannot overlap. 11.3 Unconditional Branching (the GOTO Statement) The GOTO statement specifies which program line the VAX BASIC compiler is to execute next, regardless of that line's position in the program. If the statement at the target line number or label is nonexecutable (such as a REM statement), VAX BASIC transfers control to the next executable statement following the target line number. You can use a GOTO statement to exit from a loop; however, it is better programming practice to use the EXIT statement. 11.4 Conditional Branching Conditional branching is the transfer of program control only when specified conditions are met. There are three VAX BASIC statements that let you conditionally transfer control to a target statement in your program: • • • 11-10 Program Control The ON ... GOTO ... OTHERWISE statement The IF ... THEN ... ELSE statement The SELECT ... CASE statement 11.4.1 The ON... GOTO...OTHERWISE Statement In the ON ... GOTO ... OTHERWISE statement, VAX BASIC tests the value specified after the ON keyword. If the value is l, VAX BASIC transfers control to the first target in the list; if the value is 2, control passes to the second target, and so on. If the value is less than l, or greater than the number of targets in the list, VAX BASIC transfers control to the target specified in the OTHERWISE clause. Example Menu: PRINT "Would you like to change:" PRINT "1. First name" PRINT "2. Last name" INPUT CHOICEY. ON CHOICEY. GOTO First_name, Last_name OTHERWISE Other_choice First_name: INPUT "First name"; firstname$ GOTO Done Last_name: INPUT "Last name"; lastname$ GOTO Done Other_choice: PRINT "Invalid choice" PRINT "Let's try again" GOTO Menu Done: END Note that if you do not supply an OTHERWISE clause and the control variable is less than 1 or greater than the number of targets, VAX BASIC signals "ON statement out of range (ERR= 58)". Program Control 11-11 11.4.2 The IF...THEN ...ELSE Statement The IF... THEN ... ELSE statement evaluates a conditional expression and uses the result to determine which block of statements to execute next. If the conditional expression is true, VAX BASIC executes the statements in the THEN clause. If the conditional expression is false, VAX BASIC executes the statements in the ELSE clause, if one is present. If the conditional expression is false and there is no ELSE clause, VAX BASIC executes the statement immediately following the END IF statement. In the following example, VAX BASIC evaluates the conditional expression number < 0. If the input value of number is less than zero, the conditional expression is true. VAX BASIC then executes the four statements in the THEN clause and skips the statement in the ELSE clause. VAX BASIC transfers control to the statement following the END IF. If the value of number is greater than or equal to zero, the conditional expression is false. VAX BASIC then skips the statements in the THEN clause and executes the statement in the ELSE clause. Example INPUT "Input number"; number IF (number < O) THEN number = number * (-1) PRINT "That square root is imaginary" PRINT "The square root of its absolute value is"; PRINT SQR(number) ELSE PRINT "The square root is"; SQR(number) END IF END Output Input number? -9 That square root is imaginary The square root of its absolute value is 3 One of the most common programming errors is neglecting to terminate an IF... THEN ... ELSE statement. After an IF block is executed, control is transferred to the statement immediately following the END IF. If there is no END IF, VAX BASIC transfers control to the next line number. When this happens, any code between the keyword ELSE and the next line number becomes part of the ELSE clause. If there are no line numbers, 11-12 Program Control the VAX BASIC compiler ignores the remaining program code from the keyword ELSE to the end of the program. Therefore it is very important that you always use END IF to terminate IF statements. In the following example, the first IF ... THEN ... ELSE statement is terminated by END IF, and therefore works as expected. Because the second IF ... THEN ... ELSE statement is not terminated by END IF, the VAX BASIC compiler assumes that the last PRINT statement in the program is part of the second ELSE clause. When you run this program, the first IF ... THEN ... ELSE statement will always execute correctly. However, the final PRINT statement will execute only when the value of On_off_val is l, because the compiler considers this PRINT statement to be part of the second ELSE clause. Example 10 DECLARE INTEGER light_bulb DECLARE INTEGER circuit_switch DECLARE INTEGER CONSTANT Opened = 0 DECLARE INTEGER CONSTANT Closed = 1 PRINT "Please enter zero or one, corresponding to the circuit" PRINT "switch being open or closed" INPUT On_ott_val IF On_ott_val = Opened THEN PRINT "The light bulb is ott. 11 ELSE PRINT "The light bulb is on." END IF IF On_ott_val = Closed THEN PRINT "The light bulb is on." ELSE PRINT "The light bulb is ott." PRINT "That's all for now." 20 END Program Control 11-13 Output 1 Please enter zero or one, corresponding to the circuit switch being open or closed ? 0 The light bulb is off. The light bulb is off. That's all for now. Output 2 Please enter zero or one, corresponding to the circuit switch being open or closed ? 1 The light bulb is on. The light bulb is on. Note that a statement in a THEN or ELSE clause can be followed by a modifier. In this case, the modifying IF applies only to the statement that immediately precedes it: Example IF A = B THEN PRINT A IF A = 3 ELSE END PRINT B IF B > 0 IF 11.4.3 The SELECT... CASE Statement The SELECT... CASE statement lets you specify an expression (the SELECT expression), any number of possible values (cases) for the SELECT expression, and a list of statements (a CASE block) for each case. The SELECT expression can be a numeric or string value. CASE values can be single or multiple values, one or more ranges of values, or relationships. When a match is found between the SELECT expression and a CASE value, the statements in the following CASE block are executed. Control is then transferred to the statement following the END SELECT statement. In the following example, the CASE values appear to overlap; that is, the CASE value that tests for values greater than or equal to 0.5 also includes the values greater than or equal to 1.0. However, VAX BASIC executes the statements associated with the first matching CASE statement and then transfers control to the statement following END SELECT. In this program, each range of values is tested before it overlaps in the next range. 11-14 Program Control Because the compiler executes the first matching CASE statement, the overlapping values do not matter. Example DECLARE REAL Stock_change INPUT "Please enter stock price change";Stock_change SELECT Stock_change CASE <= 0.6 PRINT "Don't sell yet." CASE <= 1.0 PRINT "Sell today." CASE ELSE PRINT "Sell NOW!" END SELECT END Output Please enter stock price change? 2.1 Sell NOW! If no match is found for any of the specified cases and there is no CASE ELSE block, VAX BASIC transfers control to the statement following END SELECT without executing any of the statements in the SELECT block. SELECT ... CASE is powerful because it lets you use run-time expressions for both SELECT expressions and CASE values. The following example uses VAX BASIC built-in string functions to examine command input. Example This program is a skeleton command processor. It recognizes three VAX BASIC environment commands: SAVE SCRATCH OLD DECLARE INTEGER CONSTANT True = -1 DECLARE INTEGER CONSTANT False = 0 DECLARE STRING CONSTANT Null_input = "" !This is the null string. DECLARE STRING Command Program Control 11-15 ! Main program logic starts here. Command_loop: WHILE True This loop executes until the user types only a carriage return in response to the prompt. PRINT PRINT "Please enter a command (uppercase only)." PRINT "Type a carriage return when finished." INPUT Command PRINT SELECT Command CASE Null_input GOTO Done If user types RETURN, exit from the loop and end the program. The next three cases use the SEG$ and LEN string functions. LEN returns the length of the typed string, and SEG$ searches the string literals ("SAVE", "SCRATCH", and "OLD") for a match up to that length. Note that if the user types an "S", it is interpreted as a SAVE command only because SAVE is the first case tested. CASE SEG$ ( "SAVE". 1x. LEN (Command) ) PRINT "That was a SAVE command." CASE SEG$ ( "SCRATCH", 11., LEN (Command) PRINT "That was a SCRATCH command." CASE SEG$( "OLD", 1Y.. LEN (Command) PRINT "That was an OLD command." CASE ELSE PRINT "Invalid command, please try again." END SELECT NEXT Done: END 11.5 The EXIT and ITERATE Statements This section describes the EXIT and ITERATE statements and shows their use with nested control structures. The ITERATE and EXIT statements let you explicitly control loop execution. These statements can be used to transfer control to the top or bottom of a control structure. 11-16 Program Control You can use EXIT to transfer control out of any of these structures: • • • • • • • FOR. .. NEXT loops WHILE ... NEXT loops UNTIL.NEXT loops IF... THEN ... ELSE blocks SELECT ... CASE blocks SUB, FUNCTION and PICTURE subprograms DEF functions, and programs In the case of control structures, EXIT passes control to the first statement following the end of the control structure. You can use ITERATE to explicitly reexecute a FOR. .. NEXT, WHILE ... NEXT, or UNTIL.NEXT loop. EXIT and ITERATE statements can appear only within the code blocks you wish to leave or reexecute. Executing the ITERATE statement is equivalent to transferring control to the loop's NEXT statement. The termination test is still performed when the NEXT statement transfers control to the top of the loop. In addition, transferring control to the NEXT statement means that a FOR loop's control variable is incremented. Supplying a label for every loop lets you state explicitly which loop to leave or reexecute. If you do not supply a label for the ITERATE statement, VAX BASIC reexecutes the innermost active loop. For example, if an ITERATE statement (that does not specify a label) is executed in the innermost of three nested loops, only the innermost loop is reexecuted. In contrast, labeling each loop and supplying a label argument to the ITERATE statement lets you reexecute any of the loops. A label name also helps document your code. Because you must use a label with EXIT and it is sometimes necessary to use a label with ITERATE, you should always label the structures you want to control with these statements. The following example shows the use of both the EXIT and ITERATE statements. This program explicitly exits the loop if you type a carriage return in response to the prompt. If you type a string, the program prints the length of the string and explicitly reexecutes the loop. Program Control 11-17 Example DECLARE STRING User_string Read_loop: WHILE 1Y. = 1Y. LINPUT "Please type a string"; User_string IF User_string == "" THEN EXIT Read_loop ELSE PRINT "Length is ";LEN(User_string) ITERATE Read_loop END IF NEXT END 11.6 Executing Local Subroutines In VAX BASIC, a subroutine is a block of code accessed by a GOSUB or ON GOSUB statement. It must be in the same program unit as the statement that calls it. The RETURN statement in the subroutine returns control to the statement immediately following the GOSUB. The first line of a subroutine can be any valid VAX BASIC statement, including a REM statement. You do not have to transfer control to the first line of the subroutine. Instead, you can include several entry points into the same subroutine. You can also reference subroutines by using a GOSUB or ON GOSUB statement to another subroutine. Variables and data in a subroutine are global to the program unit in which the subroutine resides. 11.6.1 The GOSUB and RETURN Statements The GOSUB statement unconditionally transfers control to a line in a subroutine. The last statement in a subroutine is a RETURN statement, which returns control to the first statement after the calling GOSUB. A subroutine can contain more than one RETURN statement so you can return control conditionally, depending on a specified condition. 11-18 Program Control The following example first assigns a value of 5 to the variable A, then transfers control to the subroutine labeled Times_two. This subroutine replaces the value of A with A multiplied by 2. The subroutine's RETURN statement transfers control to the first PRINT statement, which displays the changed value. The program calls the subroutine two more times, with different values for A. Each time, the RETURN transfers control to the statement immediately following the corresponding GOSUB. Example A =6 GOSUB Times_two PRINT A A = 16 GOSUB Times_two PRINT A A = 26 GOSUB Times_two PRINT A GOTO Done Times_two: !This is the subroutine entry point = A A * 2 RETURN Done: END Output 10 30 60 Note that VAX BASIC signals "RETURN without GOSUB" if it encounters a RETURN statement without first having encountered a GOSUB or ON GOSUB statement. Program Control 11-19 11.8.2 The ON...GOSUB...OTHERWISE Statement The ON ... GOSUB ... OTHERWISE statement transfers control to one of several target subroutines depending on the value of a numeric expression. A RETURN statement returns control to the first statement after the calling ON GOSUB. A subroutine can contain more than one RETURN statement so that you can return control conditionally, depending on a specified condition. VAX BASIC tests the value of the integer expression. If the value is l, control transfers to the first line number or label in the list; if the value is 2, control passes to the second line number or label, and so on. If the control variable's value is less than 1 or greater than the number of targets in the list, VAX BASIC transfers control to the line number of label specified in the OTHERWISE clause. If you do not supply an OTHERWISE clause and the control variable's value is less than 1 or greater than the number of targets, VAX BASIC signals "ON statement out of range (ERR= 58)". Example INPUT "Please enter first integer value"; First_valueY. INPUT "Please enter second integer value"; Second_valueY. Choice: PRINT "Do you want to perform:" PRINT "1. Multiplication" PRINT "2. Division" PRINT "3. Exponentiation" INPUT SelectionY. ON SelectionY. GOSUB Mult. Div, Expon OTHERWISE Wrong GOTO Done Mult: ResultY. = First_valueY. * Second_valueY. PRINT Result% RETURN Div: ResultY. = First_value I Second_valueY. PRINT ResultX RETURN Expon: ResultY. = First_valueY. ** Second_valueY. PRINT ResultY. RETURN 11-20 Program Control Wrong: PRINT "Invalid selection" RETURN Done: END 11. 7 Suspending and Halting Program Execution There are two VAX BASIC statements that you can use to suspend program execution: • • SLEEP WAIT These statements cause VAX BASIC either to suspend program execution for a specified time or to wait a certain period of time for user input. After execution of the last statement, a VAX BASIC program automatically halts and closes all files. However, you can explicitly halt program execution by using one of the following statements: • • STOP END The STOP statement does not close files. It can appear anywhere in a program. The END statement closes files and must be the last statement in a main program. For more information on the STOP and END statements, see Section 11.7.3 and Section 11.7.4. 11.7.1 The SLEEP Statement The SLEEP statement suspends program execution for a specified number of seconds. The following program waits two minutes (120 seconds) after receiving the input string, and then prints it. Program Control 11-21 Example INPUT "Type a string of characters"; C$ SLEEP 1201. PRINT C$ END The SLEEP statement is useful if you have a program that depends on another program for data. Instead of constantly checking for a condition, the SLEEP statement lets you check the condition at specified intervals. 11.7.2 The WAIT Statement You use the WAIT statement only with terminal input statements such as INPUT, INPUT LINE, and LINPUT. For example, the following program prompts for input, then waits 30 seconds for your response. If the program does not receive input in the specified time, VAX BASIC signals "Keyboard wait exhausted (ERR= 15)" and exits the program. Example WAIT 30Y. INPUT "You have 30 seconds to type your password"; PSW$ END The WAIT statement affects all subsequent INPUT, INPUT LINE, LINPUT, MAT INPUT, and MAT LINPUT statements. To disable a previously specified WAIT statement, use WAIT 0%. In the following example, the first WAIT statement causes the first INPUT statement to wait 30 seconds for a response. The WAIT 0% statement disables this 30-second requirement for all subsequent INPUT statements. Example WAIT 30% INPUT "You have 30 seconds to type your password"; PSW$ WAIT 0% INPUT "What directory do you want to go to"; DIR$ 11.7.3 The STOP Statement The STOP statement is a debugging tool that lets you check the flow of program logic. STOP suspends program execution but does not close files. 11-22 Program Control When VAX BASIC executes a STOP statement, it signals "STOP at line <line-num> ". If the program executes in the BASIC environment, VAX BASIC then prompts with the DCL command level prompt. In response, you can type: • • Immediate mode statements (to examine or change program values) The CONTINUE statement (to continue program execution) You use the STOP statement when debugging in immediate mode in the BASIC environment. For more information on immediate mode statements, see Chapter 3 in this manual. If you compile, link, and execute a program containing a STOP statement at DCL command level, VAX BASIC displays a number sign ( #) prompt when the STOP statement is encountered. At this point, you can type: • • CONTINUE (to continue program execution) EXIT (to return to DCL command level) 11.7.4 The END Statement The END statement marks the end of a main program. When VAX BASIC executes an END statement it closes all files and halts program execution. The END statement is optional in VAX BASIC programs. However, you should include it for good programming practice. The END statement must be the last statement in the main program. If you run your program in the BASIC environment, the END statement returns you to VAX BASIC command level. If you execute the program outside the BASIC environment, the END statement returns you to DCL command level. Program Control 11-23 Chapter 12 Functions A function is a single statement or group of statements that perform operations on operands and return the result to your program. VAX BASIC has built-in functions that perform numeric and string operations, conversions, and date and time operations. This chapter describes only a selected group of built-in functions. For a complete description of all VAX BASIC built-in functions, see the VAX BASIC Reference Manual. This chapter also describes user-defined functions. VAX BASIC lets you define your own functions in two ways: • • With the DEF statement As separately compiled subprograms (external functions) DEF function definitions are local to a program module, while external functions can be accessed by any program module. You create local functions with the DEF statement and optionally declare them with the DECLARE statement. You create external functions with the FUNCTION statement and declare them with the EXTERNAL statement. For more information on creating external functions with the FUNCTION statement, see Chapter 14. Once you have created and declared a function, you can invoke it just as you would a built-in function. 12. 1 Built-In Functions The functions described in this section let you perform sophisticated manipulations of string and numeric data. VAX BASIC also provides algebraic, exponential, trigonometric, and randomizing mathematical functions. Functions 12-1 12.1.1 Numeric Functions Numeric functions generally return a result of the same data type as the function's parameter. For example, if you pass a DOUBLE argument to any of the trigonometric functions, they return a DOUBLE result. If the format of a VAX BASIC function specifies an argument of a particular data type, VAX BASIC converts the actual argument supplied to the specified data type. For instance, if you supply an integer argument to a function that expects a floating-point number, VAX BASIC converts the argument to floating-point. Floating-point arguments that are passed to integer functions are truncated, not rounded. The following are some examples of VAX BASIC built-in numeric functions. 12. 1. 1. 1 The ABS Function The ABS function returns a floating-point number that equals the absolute value of a specified numeric expression. The following is an example of the ABS function: Example READ A,B DATA 10,-35.3 NEW_A = ABS(A) PRINT NEW_A; ABS(B) END Output 10 35.3 ABS always returns a number of the default floating-point data type. 12-2 Functions 12. 1.1.2 The INT and FIX Functions The INT function returns the floating-point value of the largest integer less than or equal to a specified expression. INT always returns a number of the default floating-point type. The FIX function truncates the value of a floating-point number at the decimal point. FIX always returns a number of the default floating-point type. The following example points out the differences between the INT and FIX functions. Note that the value returned by FIX(-45.3) differs from the value returned by INT(-45.3). Example PRINT INT(23.663); FIX(23.563) PRINT INT(3.1); FIX(3.1) PRINT INT(-46.3); FIX(-46.3) PRINT INT(-11); FIX(-11) END Output 23 23 3 3 -46 -45 -11 -11 12.1.1.3 The SIN, COS, and TAN Functions The SIN, COS, and TAN functions return the sine, cosine, and tangents of an angle in radians or degrees, depending on which angle clause you choose with the OPTION statement. If you supply a floating-point argument to the SIN, COS, and TAN functions, they return a number of the same floating-point type. If you supply an integer argument, they convert the argument to the default floating-point data type and return a floating-point number of that type. The following program accepts an angle in degrees, converts the angle to radians, and prints the angle's sine, cosine, and tangent. Functions 12-3 Example !CONVERT ANGLE (X) TO RADIANS, AND !FIND SIN, COS AND TAN PRINT "DEGREES", "RADIANS", "SINE", "COSINE","TANGENT" FOR IY. = 01. TO 61. READ X LET Y = X * 2 * PI I 360 PRINT PRINT X ,Y ,SIN(Y) ,COS(Y) ,TAN(Y) NEXT !Y. DATA 0,10,20,30,360,46 END Output SINE COSINE TANGENT 0 0 1 0 10 .174633 .173648 .984808 .176327 20 .349066 .34202 .939693 .36397 30 .623699 .6 .866026 .67736 360 6.28319 .174846E-06 1 .174846E-06 46 .786398 .707107 .707107 1 DEGREES 0 RADIANS NOTE As an angle approaches 90 degrees (PI/2 radians}, 270 degrees (3•Pl/2 radians), 450 degrees (S•PI/2 radians) and so on, the tangent of that angle approaches infinity. If your program tries to find the tangent of such an angle, VAX BASIC signals "Division by O" (ERR=61 ). 2. 1. 1.4 The LOG 10 Function A logarithm is the exponent of some number (called a base). Common logarithms use the base 10. The common logarithm of a number n, for example, is the power to which 10 must be raised to equal n. For example, the common logarithm of 100 is 2, because 10 raised to the power 2 equals 100. The LOGlO function returns a number's common logarithm. The following example calculates the common logarithms of all multiples of 10 from 10 to 100 inclusive: 12-4 Functions Example FOR Il = 10l TO 100l STEP 10l PRINT LOG10(IU NEXT !% END Output 1 1.30103 1.47712 1.60206 1.69897 1.77816 1.8461 1.90309 1.96424 2 If you supply a floating-point argument to LOGlO, the function returns a floating-point number of the same data type. If you supply an integer argument, LOG 10 converts it to the default floating-point data type and returns a value of that type. 12. 1. 1.5 The EXP Function The EXP function returns the value of e raised to a specified power. The following example prints the value of e and e raised to the second power: Example READ A,B DATA 1,2 PRINT 1 e RAISED TO THE POWER 1 ; A; " EQUALS" ; EXP (A) PRINT 'e RAISED TO THE POWER'; B; "EQUALS"; EXP(B) END Output e RAISED TO THE POWER 1 EQUALS 2.71828 e RAISED TO THE POWER 2 EQUALS 7.38906 If you supply a floating-point argument to EXP, the function returns a floating-point number of the same data type. If you supply an integer argument, EXP converts it to the default floating-point data type and returns a value of that type. Functions 12-5 12. 1. 1.6 The RND Function The RND function returns a number greater than or equal to zero and less than 1. The RND function always returns a floating-point number of the default floating-point data type. The RND function generates seemingly unrelated numbers. However, given the same starting conditions, a computer always gives the same results. Each time you execute a program with the RND function, you receive the same results. Example PRINT RND,RND,RND,RND END Output 1 .76308 .179978 .902878 .88984 .179978 .902878 .88984 Output 2 .76308 With the RANDOMIZE statement, you can change the RND function's starting condition and generate truly random numbers. To do this, place a RANDOMIZE statement before the line invoking the RND function. Note that the RANDOMIZE statement should be used only once in a program. With the RANDOMIZE statement, each invocation of RND returns a new and unpredictable number. Example RANDOMIZE PRINT RND,RND,RND,RND END Output 1 .403732 .34971 .15302 .92462 .272398 .261667 .10209 Output 2 .404165 The RND function can generate a series of random numbers over any open range. To produce random numbers in the open range A to B, use the following formula: (B-A)•RND + A 12-6 Functions The following program produces 10 numbers in the open range 4 to 6: Example FOR IY. = 11. TO 101. PRINT (61.-41.) * RND + 4 NEXT IY. END Output 6.62616 4.36996 6.80676 6.77068 4.77402 4.96189 6.76439 4.37166 6.2776 4.63843 12. 1.2 Data Conversion Functions VAX BASIC provides built-in functions that can: • • Convert a 1-character string to the character's ASCII value and vice versa Translate strings from one data format to another, for example, EBCDIC to ASCII The following sections describe some of these functions. 12.1.2. 1 The ASCII Function The ASCII function returns the numeric ASCII value of a string's first character. The ASCII function returns an integer value between 0 and 255, inclusive. For instance, in the following example, the PRINT statement prints the integer value 66 because this is the ASCII value equivalent of an uppercase B, the first character in the string. Functions 12-7 Example test_string$ = "BAT" PRINT ASCII(test_string$) END Output 66 Note that the ASCII value of a null string is zero. 12.1.2.2 The CHR$ Function The CHR$ function returns the character whose ASCII value you supply. If the ASCII integer expression that you supply is less than zero or greater than 255, VAX BASIC treats it as a modulo 256 value. In other words, VAX BASIC treats the integer expression as the remainder of the actual supplied integer divided by 256. Therefore, CHR$(325) is equivalent to CHR$(69) and CHR$(-1) is equivalent to CHR$(255). The following program outputs the character whose ASCII value corresponds to the input value modulo 256: Example PRINT "THIS PROGRAM FINDS THE CHARACTER WHOSE" PRINT "VALUE (MODULO 266) YOU TYPE" INPUT valueY. PRINT CHR$(valueY.) END Output 1 THIS PROGRAM FINDS THE CHARACTER WHOSE VALUE (MODULO 266) YOU TYPE ? 69 E Output 2 THIS PROGRAM FINDS THE CHARACTER WHOSE VALUE (MODULO 266) YOU TYPE ? 1093 E 12-8 Functions 12.1.3 String Numeric Functions Numeric strings are numbers represented by ASCII characters. A numeric string consists of an optional sign, a string of digits, and an optional decimal point. You can use E notation in a numeric string for floatingpoint constants. The following sections describe some of the VAX BASIC numeric string functions. 12. 1.3. 1 The FORMAT$ Function The FORMAT$ function converts a numeric value to a string. The output string is formatted according to a string you provide. The expression you give this function can be any string or numeric expression. The format string must contain at least one PRINT USING format field. The formatting rules are the same as those for printing numbers with PRINT USING. See Chapter 16 in this manual for more information on the PRINT USING statement and formatting rules. Example A =6 B$ = "##.##" Z$ = FORMAT$(A, B$) PRINT Z$ END Output 6.00 12.1.3.2 The NUM$ and NUM1$ Functions The NUM$ function evaluates a numeric expression and returns a string of characters formatted as the PRINT statement would format it. The returned numeric string is preceded by one space for positive numbers and by a minus sign for negative numbers. The numeric string is always followed by a space, as shown in the following example. Functions 12-9 Example PRINT NUM$(7465097802134) PRINT NUM$(-60) END Output .74661E+13 -60 The NUM1$ function translates a number into a string of numeric characters. NUM1$ does not return leading or trailing spaces or E format. The following example illustrates the use of the NUM1$ function: Example PRINT NUM1$ (PI) PRINT NUM1$(97.6 * 30466.23 + 30386.1) PRINT NUM1$(1E-38) END Output 3.14169 2ggga10 .00000000000000000000000000000001 NUM1$ returns up to 6 digits of accuracy for single-precision real numbers, up to 16 digits of accuracy for double-precision numbers, and up to 10 digits of accuracy for LONG integers. NUM1$ returns up to 15 digits of accuracy for GFLOAT numbers and up to 33 digits of accuracy for HFLOAT numbers. The following example shows the difference between NUM$ and NUM1$: Example A$ = NUM$(1000000) B$ = NUM1$(1000000) PRINT LEN(A$); "/";A$; "/" PRINT LEN(B$); "/"; B$; "/" END Output 8 I .1E+07 I 7 /1000000/ Note that A$ has a leading and trailing space. 12-1 0 Functions 12.1.3.3 The VAL% and VAL Functions The VAL% function returns the integer value of a numeric string. This numeric string expression must be the string representation of an integer. It can contain the ASCII characters 0 through 9, a plus sign ( + ), and a minus sign ( - ). The VAL function returns the floating-point value of a numeric string. The numeric string expression must be the string representation of some number. It can contain the ASCII characters 0 through 9, a plus sign ( + ), a minus sign ( - ), and an uppercase E. VAL returns a number of the default floating-point data type. VAX BASIC signals "Illegal number" (ERR= 52) if the argument is outside the range of the default floating-point data type. The following is an example of VAL and VAL%: Example A = VAL("922") B$ = "100" CY. = VALY.(B$) PRINT A PRINT CY. END Output 922 100 12.1.4 String Arithmetic Functions String arithmetic functions process numeric strings as arithmetic operands. This lets you add (SUM$), subtract (DIF$), multiply (PROD$) and divide (QUO$) numeric strings, and express them at a specified level of precision (PLACE$). String arithmetic offers greater precision than floating-point arithmetic or longword integers, and it eliminates the need for scaling. However, string arithmetic executes much more slowly than the corresponding integer or floating-point operations. Functions 12-11 The operands for the functions can be numeric strings representing any integer or floating-point value (E notation is not valid). Table 12-1 shows the string arithmetic functions and their formats, and gives brief descriptions of what they do. Table 12-1: String Arithmetic. Functions Function Format Description SUM$ SUM$(A$,B$) DIF$ DIF$(A$,B$) B$ is subtracted from A$. PROD$ PROD$(A$,B$,P%) A$ is multiplied by B$. The product is expressed with precision P%. QUO$ QUO$(A$,B$,P%) A$ is divided by B$. The quotient is expressed with precision P%. PLACE$ PLACE$(A$ ,P%) A$ is expressed with precision P%. B$ is added to A$. String arithmetic computations permit 56 significant digits. The functions QUO$, PLACE$, and PROD$, however, permit up to 60 significant digits. Table 12-2 shows how VAX BASIC determines the precision permitted by each function and if that precision is implicit or explicit. Table 12-2: Precision of String Arithmetic Functions Function How Determined How Stated 12. 1.4. 1 SUM$ Precision of argument Implicitly DIF$ Precision of argument Implicitly PROD$ Value of argument Explicitly QUO$ Value of argument Explicitly PLACE$ Value of argument Explicitly The SUM$ and DIF$ Functions SUM$ and DIF$ take the precision of the more precise argument in the function unless padded zeros generate that precision. SUM$ and DIF$ omit trailing zeros to the right of the decimal point. 12-12 Functions The size and precision of results returned by the SUM$ and DIF$ functions depend on the size and precision of the arguments involved: • • • • 12. 1.4.2 The sum or difference of two integers takes the precision of the larger integer. The sum or difference of two decimal fractions takes the precision of the more precise fraction. The sum or difference of two real numbers takes precision as follows: The sum or difference of the integer parts takes the precision of the larger part. The sum or difference of the decimal fraction parts takes the precision of the more precise part. VAX BASIC truncates trailing zeros. The QUO$, PLACE$, and PROD$ Functions In the PLACE$, PROD$, and QUO$ functions, the value of the integer expression argument explicitly determines numeric precision. That is, the integer expression parameter determines the point at which the number is rounded or truncated. If the integer expression is between -5000 and 5000, rounding occurs according to the following rules: • • • For positive integer expressions, rounding occurs to the right of the decimal place. For example, if the integer expression is 1, rounding occurs one digit to the right of the decimal place (the number is rounded to the nearest tenth). If 2, rounding occurs two digits to the right of the decimal place (the number is rounded to the nearest hundredth), and so on. For zero, VAX BASIC rounds to the nearest unit. For negative integer expressions, rounding occurs to the left of the decimal place. For example, if the integer expression is -1, rounding occurs one place to the left of the decimal point. In this case, VAX BASIC moves the decimal point one place to the left, then rounds to units. If the integer expression is -2, rounding occurs two places to the left of the decimal point; VAX BASIC moves the decimal point two places to the left, then rounds to units. Note that when rounding numeric strings, VAX BASIC returns only part of the number. Functions 12-13 If the integer expression is between 5001 and 15000, the following rules apply: • • • If the integer expression is 10000, VAX BASIC truncates the number at the decimal point. If the integer expression is greater than 10000 (10000 plus n) VAX BASIC truncates the numeric string n places to the right of the decimal point. For example, if the integer expression is 10001 (10000 plus 1), VAX BASIC truncates the number starting one place to the right of the decimal point. If 10002 (10000 plus 2), VAX BASIC truncates the number starting two places to the right of the decimal point, and so on. If the integer expression is less than 10000 (10000 minus n) VAX BASIC truncates the numeric string n places to the left of the decimal point. For example, if the integer expression is 9999 (10000 minus 1), VAX BASIC truncates the number starting one place to the left of the decimal point. If 9998 (10000 minus 2), VAX BASIC truncates starting two places to the left of the decimal point, and so on. The PLACE$ function returns a numeric string, truncated or rounded according to an integer argument you supply. The following example displays the use of the PLACE$ function with several different integer expression arguments: Example number$ = "123466.654321" FOR IY. = -6Y. TO 6% PRINT PLACE$(number$, IY.) NEXT lY. PRINT FOR I% = 9996 TO 10006 PRINT PLACE$(number$, I%) NEXT !% Output 1 12 123 1235 12346 123467 123466.7 123466.65 123466.654 123466.6543 123466.66432 12-14 Functions 1 12 123 1234 12346 123466 123466.6 123466.66 123466.664 123466.6643 123466.66432 The PROD$ function returns the product of two numeric strings. The returned string's precision depends on the value you specify for the integer precision expression. (See Section 12.1.4 for allowable values of the integer precision expression). Example A$ = "-4.333" 8$ = "7.23326" s_product$ = PROD$(A$, 8$, 100061.) PRINT s_product$ END Output -31.34171 12.1.5 Date and Time Functions VAX 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 VAX/VMS System Services Reference Manual and the VAX/VMS Run-Time Library Routines Reference Manual for more information. Functions 12-15 12. 1.5. 1 The 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. Example PRINT DATE$(0) PRINT DATE$(126) PRINT DATE$(6168) END Output 15-Jun-85 06-May-70 16-Jun-76 If you supply an invalid date (for example, day 370 of 1973), the results are undefined. 12.1.5.2 The 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. Example PRINT TIME$(0) PRINT TIME$(1) PRINT TIME$(1440) PRINT TIME$(721) END Output 03:53 PM 11:69 PM 12:00 AM 11:59 AM 12-16 Functions 12.1.5.3 The TIME Function 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 listed below: 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 seconds 3 Returns zero 4 Returns zero All other arguments to TIME are undefined and cause VAX BASIC to signal "Not implemented" (ERR=250). 12. 1.8 Terminal Control Functions VAX BASIC provides several terminal control functions. These functions let you: • • • 12. 1.6. 1 Enable and disable CTRL/C trapping Enable and disable terminal echoing Read a single keystroke from a terminal The CTRLC and RCTRLC Functions 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 a 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 old contents. For example, if you type a 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. Functions 12-17 Example WHEN ERROR USE error_handler YY. = CTRLC END WHEN HANDLER error_handler IF ERR = 28 THEN PRINT 111., "Abort" END HANDLER NOTE When you trap a CTRL/C with an error handler, your program may be in an inconsistent state; therefore, you should handle the CTRL/C error and exit the program as quickly as possible. 12. 1.6.2 The ECHO and NOECHO Functions 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. This program shows a password routine in which the password does not echo: Example YY. = NOECHO(OY.) INPUT "PASSWORD"; pword$ IF pword$=="PLUGH" THEN PRINT "THAT IS CORRECT" END IF YY. = ECHO (OU END Note that the Y% = ECHO(O%) statement is necessary to tum the echo back on. If this statement were not included, then all subsequent user inputs would not echo to the terminal screen. 12-18 Functions 12.1.6.3 The 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, VAX 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, VAX BASIC signals the error "Illegal operation" (ERR=141). Once you have specified a channel, VAX BASIC allows you to specify an optional WAIT clause. A WAIT clause followed by no value tells VAX BASIC to wait indefinitely for input to become available. A WAIT clause followed by a value from 1 through 255 tells VAX BASIC to wait the specified number of seconds for input. Example DECLARE STRING KEYSTROKE Inkey_Loop: WHILE 1Y. KEYSTROKE = INKEY$(1Y.,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 "KPO" 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 Functions 12-19 12.2 User-Defined Functions The DEF statement lets you create your own single-line or multi-line functions. In the traditional VAX BASIC usage, a function name consists of the following: • • • The letters FN From 1 to 28 letters, digits, underscores, or periods An optional percent sign or dollar sign 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, DIGITAL recommends that you use explicit data typing when defining functions for new program development. Refer to Chapter 14 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 multi-line. Whether you use the single-line or multi-line format for function definitions depends on the complexity of the function you create. In general, multi-line DEF functions perform more complex functions than single-line DEF functions. However, the important distinction between single- and multi-line DEF functions is that multi-line DEF functions can be invoked recursively, whereas single-line DEF functions cannot. 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 eight 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. 12-20 Functions 12.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 eight 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, VAX BASIC does the following: Copies the values 5.6 and 7.8 into the formal parameters numer and • denomin • • Evaluates the expression to the right of the equal sign Returns the value to the statement that invoked the function (the PRINT statement) The PRINT statement then prints the returned value. Example DEF REAL fnratio (numer, denomin) = numer I denomin PRINT fnratio(5.6, 7.8) END Output .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, VAX BASIC built-in function, or any user-defined Functions 12-21 function except the function being defined. The following are valid function definitions: Example DEF FN_A(X) = XA2 + 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 A 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. For instance, the following function definition uses three VAX BASIC built-in functions to return an integer corresponding to the day of the month. DATE$(0) returns a date string in the form dd-Mmm-yy. The SEG$ function strips out of this value the characters starting at character position 1 up to and including the character at position 2 (the day number). The VAL% function converts this resulting numeric string to an integer. In this way, fnday_number returns the day of the month as an integer. DEF INTEGER fnday_number = VALY. (SEG$(DATE$(0Y.), 1Y., 21.)) 12.2.2 Multi-Line DEF Functions The DEF statement can also define multi-line functions. Multi-line 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. NOTE If a multi-line DEF function contains DATA statements, they are global to the program. Multi-line function definitions can contain any constant, variable, VAX BASIC built-in function, or user-defined function. In VAX BASIC, the function definition can contain a reference to the function you are defining. Therefore, a multi-line DEF function can be recursive, or invoke itself. 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. 12-22 Functions The following example shows a multi-line 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; VAX 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. Example DEF fn_discount(A) IF A > 10 THEN PRINT "OUT OF RANGE" EXIT DEF ELSE fn_discount = AAA END IF END DEF INPUT Z PRINT fn_discount(Z) END Output 1 ? 4 266 Output 2 ? 12 OUT OF RANGE 0 If you do not explicitly declare the function with the DECLARE statement, the restrictions for naming a multi-line 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. Functions 12-23 Example 1 DECLARE STRING FUNCTION concat (STRING, STRING) !Declare the function DEF STRING concat (STRINGY, STRING Z) concat = Y + Z !Define the function FNEND new_string$ concat(A$, B$) !Invoke the function END Example 2 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 = 01. 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% = -11. END IF 12-24 Functions 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 may be wrong. !If the negative argument flag was set, make the result negative. IF negativeY. 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 Output 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 VAX 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. Functions 12-25 Example DECLARE INTEGER FUNCTION factor ( INTEGER ) DEF INTEGER factor ( INTEGER F ) IF F <= OY. THEN factor = 1Y. ELSE factor = factor(F - 1Y.) * F END IF END DEF INPUT "INPUT N TO FIND N FACTORIAL"; NY. PRINT "N! IS"; factor(NY.) END Output INPUT N TO FIND N FACTORIAL? 6 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 VAX 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 multi-line 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: • • • • 12-26 Functions If the DEF function contains an ON ERROR GOTO, GOTO, ON GOTO, GOSUB, ON GOSUB, or RESUME statement, that statement's target line number must also be in that DEF function. An ON ERROR GO BACK statement can transfer control out of a DEF function; however, a RESUME statement in an error handler outside the DEF function cannot transfer control back into the DEF function. If the DEF function contains a handler, and was invoked from a protected region, an EXIT HANDLER statement causes control to be transferred to the specified handler for that protected region. However, if the DEF function contains a handler but was not invoked from a protected region, an EXIT HANDLER statement causes control to be transferred to the default error handler. A subroutine cannot be shared by more than one DEF function. However, if you rewrite the subroutine as a DEF function with no parameters, other function definitions can share it. 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 VAX 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, VAX BASIC signals the error "explicit declaration of first required". If you do not specify the OPTION TYPE= EXPLICIT statement, VAX BASIC assumes that first is a new variable and initializes it to zero. Example OPTION TYPE = EXPLICIT DECLARE INTEGER A, B DEF fn_sum(INTEGER first, INTEGER second) = first + second A B = 60 = 26 PRINT fn_sum(A, B) PRINT first END Functions 12-27 Chapter 13 String Handling This chapter defines dynamic and fixed-length strings and string virtual arrays, explains which you should choose for your application, and shows you how to use them. 13.1 Introduction A string is a sequence of ASCII characters. VAX BASIC allows you to use three types of strings: • • • Dynamic strings Fixed-length strings String virtual arrays Dynamic strings are strings whose length can change during program execution. The length of a dynamic string variable may or may not change, depending on the statement used to modify it. Fixed-length strings are strings whose length never changes. In other words, their length remains static. String constants are always fixedlength. String variables can be either fixed-length or dynamic. A string variable is fixed-length if it is named in a COMMON, MAP, or RECORD statement. If a string variable is not part of a map or common block, RECORD, or virtual array, it is a dynamic string. When a string variable is fixed-length, its length does not change, regardless of the statement you use to modify it. See Table 13-1 for more information on string modification. String Handling 13-1 Strings in virtual arrays have both fixed-length and dynamic attributes. String virtual arrays have a specified maximum length between 0 and 512 characters. During program execution, the length of an element in a string virtual array can change; however, the length is always between 0 and the maximum string size specified when the array was created. See Section 13.4 and Chapter 15 for more information about virtual arrays. Table 13-1: String Modification Statement Changes made to Fixed-Length Strings Changes made to Dynamic Strings LET Value Value and length LSET Value Value RSET Value Value Terminal I/ 0 Statements 1 Value Value and length 1 Terminal I/O statements include INPUT, INPUT LINE, LINPUT, MAT INPUT, and so on. 13.2 Using Dynamic Strings Although dynamic strings are less efficient than fixed-length strings, they are often more flexible. For example, to concatenate strings, you can just use the LET statement to assign the concatenated value to a dynamic string variable, without having to be concerned about VAX BASIC truncating the string or adding trailing spaces to it. However, if the destination variable is fixed-length, you must make sure that it is long enough to receive the concatenated string, or VAX BASIC truncates the new value to fit the destination string. Similarly, if you use LSET or RSET to concatenate strings, you must ensure that the destination variable is long enough to receive the data. The LET, LSET and RSET statements all operate on dynamic strings as well as fixed-length strings. The LET statement can change the length of a dynamic string; LSET and RSET do not. LSET and RSET are more efficient than LET when changing the value of a dynamic string. For more information on LSET and RSET, see Sections 13.5.2 and 13.5.3. 13-2 String Handling 11 In the following example, the first line assigns the value ABC" to A$, the second line assigns XYZ" to B$, and the third line assigns six spaces to C$. These variables are dynamic strings. In the fourth line, LSET assigns A$ the value of A$ concatenated with B$. Because the LSET statement does not change the length of the destination string variable, only the first three characters of the expression A$ + B$ are assigned to A$. The fifth line uses LSET to assign C$ the value of A$ concatenated with B$. Because C$ already has a length of 6, this statement assigns the value ABCXYZ" to it. 11 11 Example LET At = "ABC" LET Bt = "XYZ" LET Ct = " LSET At = At + Bt LSET C$ = A$ + Bt PRINT A$ PRINT C$ END Output ABC ABCXYZ Like the LET statement, the INPUT, INPUT LINE, and LINPUT statements can change the length of a dynamic string, but they cannot change the length of a fixed-length string. In this example, the first line assigns the null string to variable A$. The second line uses the LEN function to show that the null string has a length of zero. The third line uses the INPUT statement to assign a new value to A$, and the fourth and fifth lines print the new value and its length. String Handling 13-3 Example !Declare a dynamic string LET A$ = "" PRINT LEN(A$) INPUT A$ PRINT A$ PRINT LEN(A$) END Output 0 THIS IS A TEST THIS IS A TEST ? 14 You should not confuse the null string with a null character. A null character is one whose ASCII numeric code is zero. The null string is a string whose length is zero. 13.3 Using Fixed-Length Strings It is generally more efficient to manipulate a fixed-length string than a dynamic string. Creating or modifying a dynamic string often causes VAX BASIC to create new storage, and this increases processor overhead. Modifying fixed-length strings involves less overhead because VAX BASIC manipulates existing storage using VAX character instructions. If a string variable is part of a map or common block, or virtual array, a LET, INPUT, LINPUT, or INPUT LINE statement changes its value, but not its length. In the following example, the MAP statement in the first line explicitly assigns a length to each string variable. Because the LINPUT statements cannot change this length, VAX BASIC truncates values to fit the address and city_state variables. Because the zip variable is longer than the assigned value, VAX BASIC left-justifies the assigned value and pads it with spaces. The sixth line uses the compile-time constant HT (horizontal tab) to separate fields in the employee record. 13-4 String Handling Example MAP (FIELDS) STRING full_name = 10, address = 10, city_state = 10, zip = 10 LINPUT "NAME"; full_name LINPUT "ADDRESS"; address LINPUT "CITY AND STATE"; city_state LINPUT "ZIP CODE"; zip EMPLOYEE_RECORD$ = full_name + HT + address + HT t + city_state + HT + zip PRINT EMPLOYEE_RECORD$ END Output NAME'? JOE SMITH ADDRESS'? 66 GRANT AVENUE CITY AND STATE'? NEW YORK NY ZIP'? 01001 JOE SMITH 66 GRANT A NEW YORK N 01001 13.4 Using String Virtual Arrays Virtual arrays are stored on disk. You create a virtual array by opening a disk file and then using the DIM # statement to dimension the array on the open channel. This section describes only string virtual arrays. See Chapter 15 for more information on virtual arrays. Elements of string virtual arrays behave much like dynamic strings, with two exceptions: • • When you create the virtual string array, you specify a maximum length for the array's elements. The length of an array element can never exceed this maximum. If you do not supply a length, the default is 16 characters. A string virtual array element cannot contain trailing nulls. When you assign a value to a string virtual array element, VAX BASIC pads the value with nulls, if necessary, to fit the length of the virtual array element. However, when you retrieve the virtual array element, VAX BASIC strips all trailing nulls from the string. Therefore, when you access an element in a string virtual array, the string never has trailing nulls. String Handling 13-5 In the following example, The first two lines dimension a string virtual array and open a file on channel #1. The third line assigns a IO-character string to the first element of this string array, and to the variable A$. This IO-character string consists of "ABCDE" plus five null characters. The PRINT statements show that the length of A$ is 10, while the length of test(l) is only 5 because VAX BASIC strips trailing nulls from string array elements. Example DIM #1%, STRING test(5) OPEN "TEST" AS FILE #1%, ORGANIZATION VIRTUAL A$, test(1Y.) = "ABCDE" + STRING$(51., OY.) PRINT "LENGTH OF A$ IS: "; LEN(A$) PRINT "LENGTH OF TEST(1) IS: "; LEN(test(1%)) END Output LENGTH OF A$ IS: 10 LENGTH OF TEST(1) IS: 5 Although the storage for string virtual array elements is fixed, the length of a string array element can change because VAX BASIC strips the trailing nulls whenever it retrieves a value from the array. 13.5 Assigning String Data To assign string data, you use the LET, LSET, RSET, and MID$ statements. The following sections describe how to use these statements. 13.5. 1 The LET Statement The LET statement assigns string data to a string variable. The keyword LET is optional. Again, LSET is more efficient than LET when changing a dynamic string variable. In the following example, B is a string variable and "ret_status" is a quoted string expression. LET B = "ret_status" 13-6 String Handling The LET statement changes the length of dynamic strings but does not change the length of fixed-length strings. For instance, the following example, first creates a fixed-length string named ABC by declaring the string in a MAP statement. The program then creates a dynamic string named XYZ by declaring it in a DECLARE statement. The third line assigns a 3-character value to both variable ABC and XYZ, then prints the value and the length of the string variables. Variable ABC continues to have a length of 10: the three characters assigned, plus seven spaces for padding. The length of the dynamic variable changes with the values assigned to it. Example MAP (TEST) STRING ABC = 10 DECLARE STRING XYZ ABC = "ABC" XYZ = "XYZ" PRINT ABC, LEN(ABC) PRINT XYZ, LEN(XYZ) ABC = "A" XYZ = "X" PRINT ABC, LEN(ABC) PRINT XYZ, LEN(XYZ) Output ABC XYZ A x 10 3 10 1 13.5.2 The LSET Statement The LSET statement left-justifies data and assigns it to a string variable, without changing the variable's length. In the following example, ABC is a string variable and "ABC" is a string constant. LSET ABC = "ABC" If the string expression's value is shorter than the string variable's current length, LSET left-justifies the expression and pads the string variable with spaces. In the following example, the LET statement creates the 5-character string variable test$. The LSET statement in the second line assigns the string XYZ to the variable test$ but does not change the length of test$. Because test$ has a length of 5, the LSET statement pads the string XYZ with two spaces when assigning the value. The PRINT statement shows that test$ includes these two spaces. String Handling 13-7 Example LET test$ = "ABCDE" LSET test$ = "XYZ" PRINT "'"; test$; "'" END Output 'XYZ I LSET left-justifies a string expression longer than the string variable and truncates it on the right as shown in the following example: Example LET test$ = "ABCDE" LSET test$ = "12346678" PRINT test$ END Output 12346 The LET statement creates the 5-character string variable test$. The LSET statement in the second line assigns the characters "12345" to test$. Because LSET does not change the string variable's length, it truncates the last three characters (678). 13.5.3 The RSET Statement The RSET statement right-justifies data and assigns it to a string variable without changing the variable's length. In the following example, C_R is a string variable and "cust_rec" is a string constant. RSET C_R = "cust_rec" RSET right-justifies a string expression shorter than the string variable and pads it with spaces on the left. In the following example, the LET statement creates the 5-character string variable test$. The RSET statement in the second line assigns the string XYZ to test$ but does not change the length of test$. Because test$ is five characters long, the RSET statement pads XYZ with two spaces when assigning the value. The PRINT statement shows that test$ includes these two spaces. 13-8 String Handling Example LET test$ = "ABCDE" RSET test$ = "XYZ" PRINT "'" ; test$; "'" END Output I XYZ' If the string expression's value is longer than the string variable, RSET right-justifies the string expression and truncates characters on the left to fit the string variable as shown in the following example: Example LET test$ = "ABCDE" RSET test$ = "987664321" PRINT test$ END Output 64321 The LET statement creates a 5-character string variable, test$. The RSET statement assigns "54321" to test$. RSET, which does not change the variable's length, truncates "9876" from the left side of the string expression. Note that, when using LSET and RSET, padding can become part of the data: Example LET A$ = '12346' LSET A$ = 'ABC' LET 8$ = '12346678' RSET 8$ = A$ PRINT " 1 " ; 8$; " 1 " Output ABC I String Handling 13-9 13.5.4 The MIDS Assignment Statement You can replace a portion of a string with another string using the MID$ assignment statement. You specify a starting character position that indicates where to begin the substitution. If you specify a starting character position that is less than 1, VAX BASIC assumes a starting character position of 1. In addition, you can optionally specify the number of characters to substitute from the source string expression. If you do not specify the number of characters to substitute, VAX BASIC attempts to insert the entire source expression. However, the MID$ statement never changes the length of the target string variable; therefore, the entire source expression may not fit into the available space. The following example illustrates the use of MID$ as an assignment statement. In this example, "ABCD" is the input string, the starting character position is 1, and the length of the segment to be replaced is 3 characters. Note that when you use MID$ as an assignment statement, the length of the input string does not change. Therefore, the length of the result ("123D"), is equal to the length of the input string. Example DECLARE STRING old_string, replace_string old_string = "ABCD" replace_string = "123" PRINT old_string MID$(old_string,1,3) = replace_string PRINT old_string Output ABCD 123D Keep these considerations in mind when you use the MID$ assignment statement: • • • 13-10 String Handling The length argument is optional. If not specified, the number of characters replaced will be the minimum of the length of the replacement string and the length of the input string minus the starting position value. If the length of the segment is less than or equal to zero, VAX BASIC assumes a length of zero. The length of the input string does not change regardless of the value of the length of the segment. 13.6 Manipulating String Data with String Functions When used with the LET statement, VAX BASIC string functions let you manipulate and modify strings. These functions let you: • • • • Determine the length of a string (LEN) Search for the position of a set of characters in a string (POS) Extract segments from a string (SEG$, MID$) Create a string of any length, made up of any single character (STRING$) Create a string of spaces (SP ACE$) Remove trailing spaces and tabs from a string (TRM$) Edit a string (EDIT$) • • • These functions are discussed in the following sections. See the VAX BASIC Reference Manual for more information about each string function. 13.6.1 The LEN Function The LEN function returns the number of characters in a string as an integer value. For example: LEN(spec) Spec is a string expression. The length of the string expression includes leading and trailing blanks. In the following example, the variable Z$ is set equal to "ABC XYZ", which has a length of eight. Example alpha$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" PRINT LEN(alpha$) Z$ = "ABC" + " " + ""XYZ" PRINT LEN(Z$) END Output 26 8 String Handling 13-11 13.8.2 The POS Function POS searches a string for a group of characters (a substring). In the following example, spec is the string to be searched, test is the substring for which you are searching and 15 is the character position where VAX BASIC starts the search. POS(spec,test,15) The position returned by POS is relative to the beginning of the string, not the starting position of the search. For example, if you search the string "ABCDE" for the substring "E", it does not matter whether you specify a starting position of 1, 2, 3, 4, or 5, VAX BASIC still returns the value 5 as the position where the substring was found. If the function finds the substring, it returns the position of the substring's first character. Otherwise, it returns zero as in the following example: Example alpha$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" Z$ = "DEFG" XX = POS(ALPHA$,Z$,1%) PRINT XX Q$ = "TEST" YX = POS(ALPHA$, Q$, 1%) PRINT YY. END Output 4 0 If you specify a starting position other than 1, VAX BASIC still returns the position of the substring relative to the beginning of the string as shown in the following example: Example alpha$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" Z$ = "HIJ" PRINT POS(ALPHA$, Z$, 71.) END Output 8 13-12 String Handling If you know that the substring is not near the string's beginning, specifying a starting position greater than one speeds program execution by reducing the number of characters VAX BASIC must search. You can use the POS function to associate a character string with an integer that you can then use in calculations. This technique is called a table lookup. For instance, the following example prompts for a 3-character string, changes the string to uppercase letters and searches the table string to find a match. The WHILE loop executes indefinitely until a carriage return is typed in response to the prompt. Example DECLARE STRING CONSTANT table = t "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC" DECLARE STRING month, UPPER_CASE_MONTH, message DECLARE INTEGER month_length DECLARE REAL month_pos PRINT "Please type the first three letters of a month" PRINT "To end the program, type only RETURN);" Loop_1: WHILE 1Y. = 1Y. INPUT month UPPER_CASE_MONTH = EDIT$(month, 32%) month_length = LEN(UPPER_CASE_MONTH) EXIT Loop_1 IF month_length = OX IF month_length = 31. THEN month_pos = (POS(table, UPPER_CASE_MONTH, 1) + 2) / 3 IF (month_pos = 01.) OR (month_pos <> FIX(month_pos)) THEN MESSAGE = " Invalid abbreviation, try again" ELSE MESSAGE = " is month number" + NUM$(MONTH_POS) END IF ELSE MESSAGE = 11 Abbreviation not three characters, try again" END IF PRINT month; message NEXT END Output Please type the first three letters of a month To end the program, type only RETURN? Nov Nov is month number 11 Keep these considerations in mind when you use POS: • • If you specify a starting position less than l, POS assumes a starting position of one. If you specify a starting position greater than the searched string's length, POS returns a zero (unless the substring is null). String Handling 13-13 • When searching for a null string: If you specify a starting position greater than the string's length, POS returns the string's length plus one. If the string to be searched is also null, POS returns a value of one. If the specified starting position is less than or equal to l, POS returns a value of one. If the specified starting position is greater than one and less than or equal to the string's length plus l, POS returns the specified starting position. Note that searching for a null string is not the same as searching for the null character. A null string has a length of zero, while the null character has a length of one. The null character is an ASCII character whose value is zero. 13.6.3 The SEGS Function The SEG$ function extracts a segment (substring) from a string. The original string remains unchanged. In the following example, time is the input string, 13 is the position of the first character extracted and 16 is the position of the last character extracted. SEG$(time,13,16) SEG$ extracts from the input string the substring that starts at the first character position, up to and including the last character position. It returns the extracted segment. Example PRINT SEG$("ABCDEFG 11 , 31., 61.) END Output CDE If you specify character positions that exist in the string, the length of the returned substring always equals (int-exp2 - int-expl + 1). 13-14 String Handling Keep these considerations in mind when you use SEG$: • • • • If the starting character position is less than l, VAX BASIC assumes a value of 1. If the starting character position is greater than the ending character position, or the length of the string, SEG$ returns a null string. If the ending character position is greater than the length of the string, SEG$ returns all characters from the starting character position to the end of the string. If the starting character position is equal to the ending character position, SEG$ returns the character at the starting position. You can replace part of a string by using the SEG$ function with the string concatenation operator ( + ). In the following example, when VAX BASIC creates C$, it concatenates the first two characters of A$, the 3-letter string XYZ, and the last two characters of A$. The original contents of A$ do not change. Example = A$ "ABCDEFG 11 C$ = SEG$(A$, 1Y., 2Y.) + 11 XYZ" + SEG$(A$, 6Y., 7Y.) PRINT C$ PRINT A$ END Output ABXYZFG AB CDEFG You can use similar string expressions to replace characters in any string. If you do not change the length of the target string, use the MID$ assignment statement to perform string replacement. A general formula to replace characters in positions n through m of string A$ with characters in B$ is: C$ = SEG$(A$,l %,n-1) + B$ + SEG$(A$,m+l,LEN(A$)) The following example replaces the sixth through ninth characters of the string "ABCDEFGHIJK" with "123456". String Handling 13-15 Example A$ = "ABCDEFGHIJK" 8$ = "123456" C$ = SEG$(A$,1Y.,5Y.) + 8$ + SEG$(A$,10Y.,LEN(A$)) PRINT C$ PRINT A$ PRINT 8$ END Output ABCDE123456JK ABCDEFGHIJK 123456 The following formulas are more specific applications of the general formula. • To replace the first n characters of A$ with B$ use • C$ = B$ + SEG$(A$,n+l,LEN(A$)) To replace all but the first n characters of A$ with B$ use • C$ = SEG$(A$,l,n) + B$ To replace all but the last n characters of A$ with B$ use • C$ = B$ + SEG$(A$,(LEN(A$)-n) + l,LEN(A$)) To replace the last n characters of A$ with B$ use • C$ = SEG$(A$,l,LEN(A$)-n) + B$ To insert B$ in A$ after the nth character in A$ use C$ = SEG$(A$,1,n) + B$ + SEG$(A$,n+l,LEN(A$)) 13.6.4 The MIDS Function The MID$ function extracts a specified substring, beginning at a specified character position and ending at a specified length. If you specify a starting character position that is less than l, VAX BASIC automatically assumes a starting character position of 1. In the following example, the MID$ function uses the input string "ABCD", and extracts a segment consisting of 3 characters. Because VAX BASIC automatically assumes a starting character position of 1 when the specified starting character position is less than 1, the string that is extracted begins with the first character of the input string. 13-16 String Handling Example DECLARE STRING old_string, new_string old_string = "ABCD" new_string = MID$(old_string, 0, 3) PRINT new_string Output ABC Keep these considerations in mind when you use the MID$ function: • • • • If the position of the segment's first character is greater than the input string, MID$ returns a null string. If the length of the segment is greater than the length of the input string, VAX BASIC returns the string that begins at the specified starting character position and includes all characters remaining in the string. If the length of the segment is less than or equal to zero, MID$ returns a null string. If you specify a floating-point expression for the position of the segment's first character or for the length of the segment, VAX BASIC truncates it to a long integer. 13.8.5 The STRINGS Function The STRING$ function creates a character string containing multiple occurrences of a single character. In the following example, 23 is the length of the returned string and 30 is the ASCII value of the character that makes up the string. This value is treated modulo 256. STRING$(23,30) The following example creates a 10-character string containing uppercase As, which have ASCII value 65. String Handling 13-17 Example out$ = STRING$(10Y., 66Y.) PRINT out$ END Output AAAAAAAAAA Keep these considerations in mind when you use the STRING$ function: • • If the length of the returned string is less than or equal to zero, STRING$ returns a null string. If the length of the returned string is greater than 65535, VAX BASIC signals an error. 13.8.8 The SPACES Function The SP ACE$ function creates a character string containing spaces. In this example, 5 is the number of spaces in the string. SPACE$(6) The following example creates a 9-character string which contains 3 spaces. Example A$ = "ABC" B$ = "XYZ" PRINT A$ + SPACE$(3Y.) + B$ END Output ABC XYZ 13.8.7 The TRMS Function The TRM$ function removes trailing blanks and tabs from a string. The input string remains unchanged. In the following example, all trailing blanks that appear in the string expression, "ABCDE " are removed once the TRM$ function is invoked. 13-18 String Handling Example AS = "ABCDE BS = "XYZ" first$ = AS + BS second$ = TRM${A$) + BS PRINT first$ PRINT second$ END Output ABCDE XU ABCDEXYZ The TRM$ function is especially useful for extracting the nonblank characters from a fixed-length string (for example, a COMMON or MAP, or a parameter passed from a program written in another language). 13.6.8 The EDITS Function The EDIT$ function performs one or more string editing functions, depending on the value of an argument you supply. The input string remains unchanged. In the following example, stu_rec is a string expression and 32 determines the editing function performed. EDIT${stu_rec,32) Table 13-2 shows the action VAX BASIC takes for a given value of the integer expression. Table 13-2: EDIT$ Options Value of Expression Effect Discards each character's parity bit (bit 7). Note that you should not use this value for characters in the DEC Multinational Character Set. 2 Discards all spaces and tabs. 4 Discards all carriage returns, line feeds, form feeds, deletes, escapes, and nulls. 8 Discards leading spaces and tabs. 16 Converts multiple spaces and tabs to a single space. String Handling 13-19 Table 13-2 (Cont.): Value of Expression 32 64 EDIT$ Options Effect Converts lowercase letters to uppercase. Converts left brackets ( [) to left parentheses [(], and right brackets (]) to right parentheses [)]. 128 Discards trailing spaces and tabs. (Same as TRM$ function.) 256 Suppresses all editing for characters within quotation marks. If the string has only one quotation mark, VAX BASIC suppresses all editing for the characters following the quotation mark. All values are additive; for example, by specifying 168, you can: • • • Discard leading spaces and tabs (value 8) Convert lowercase letters to uppercase (value 32) Discard trailing spaces and tabs (value 128) The following program requests an input string, discards all spaces and tabs, converts lowercase letters to uppercase, and converts brackets to parentheses: Example LINPUT "PLEASE TYPE A STRING";input_string$ new_string$ = EDIT$(input_string$, 2Y. + 32Y. + 64Y.) PRINT new_string$ END Output PLEASE TYPE A STRING? 88 88ABC(5,5) abc[TAB][5,5] 13. 7 Manipulating String Data with Multiple Maps Mapping a string storage area in more than one way lets you extract a substring from a string or concatenate strings. In the following example, the three MAP statements reference the same 108 bytes of data. 13-20 String Handling Example MAP (emprec) first_name$ = 10, last_name$ = 20, street_number$ = 6, street$ = 16, city$ = 20, state$ = 2, zip$ = 6, wage_claSB$ = 2, date_of_review$ = 8, salary_ytd$ = 10, tax_ytd$ = 10 MAP (emprec) full_namet = 30, addreBB$ = 48, salary_info$ = 30 MAP (emprec) employee_record$ = 108 You can move data into a map in different ways. For instance, you can use terminal input, arrays, and files. In the following example, the READ and DATA statements are used to move data into a map. Example READ EMPLOYEE_RECORD$ DATA "WILLIAM DAVIDSON 2241 MADISON BLVD " & "SCRANTON PA14226A912/10/78$13,326.77$926.31" Because all the MAP statements in the example shown above reference the same storage area (emprec), you can access parts of this area through the mapped variables as shown in Example 1 and Example 2. Example 1 PRINT full_name$ PRINT wage_class$ PRINT salary_ytd$ Output 1 WILLIAM DAVIDSON A9 $13,326.77 String Handling 13-21 Example 2 PRINT last_name$ PRINT tax_ytd$ Output 2 DAVIDSON $926.31 You can assign a new value to any of the mapped variables. For instance, the following example prompts the user for changed information by displaying a menu of topics. The user can then choose which topics need to be changed and then separately assign new values to each variable. Example Loop_1: WHILE 1Y. = 1Y. INPUT "Changes? (please type YES or NO)"; CH$ EXIT Loop_1 IF CH$ = "NO" PRINT "1. FIRST NAME" PRINT "2. LAST NAME" PRINT "3. STREET NUMBER" PRINT "4. STREET" PRINT "6. CITY" PRINT 11 6. STATE" PRINT "7. ZIP" PRINT "8. WAGE CLASS" PRINT "9. DATE OF REVIEW" PRINT "10. SALARY YTD" PRINT "11. TAX YTD" INPUT "CHANGE NUMBER"; NUMBERY. 13-22 String Handling SELECT NUMBER% CASE 1% INPUT "FIRST NAME"; first_name$ CASE 2% INPUT "LAST NAME"; last_name$ CASE 3% INPUT "STREET NUMBER"; street_number$ CASE 4% INPUT "STREET"; street$ CASE 5Y. INPUT "CITY"; city$ CASE 6Y. INPUT "STATE"; state$ CASE 7% INPUT "ZIP CODE"; zip$ CASE SY. INPUT "WAGE CLASS"; wage_class$ CASE 9Y. INPUT "DATE OF REVIEW"; date_of_review$ CASE 10% INPUT "SALARY YTD"; salary_ytd$ CASE 11% INPUT "TAX YTD"; tax_ytd$ CASE ELSE PRINT "Invalid choice" END SELECT NEXT END Output Changes? (please type YES or NO)? YES 1 . FIRST NAME 2. LAST NAME 3. STREET NUMBER 4. STREET 5. CITY 6. STATE 7. ZIP 8 . WAGE CLASS 9. DATE OF REVIEW 10. SALARY YTD 11. TAX YTD CHANGE NUMBER? 10 SALARY YTD7 14,277.08 Changes? (please type YES or NO)? YES CHANGE NUMBER? 11 TAX YTD7 998.32 Changes? (please type YES or NO)? NO See Chapter 9 and the VAX BASIC Reference Manual for more information on the MAP statement. String Handling 13-23 Chapter 14 Program Segmentation Program segmentation is the process of dividing a program into small, manageable routines and modules. In a segmented or modular program, each routine or module usually performs only one logical function. You can therefore design and implement a modular program faster than a nonsegmented program. Program modularity also simplifies debugging and testing, as well as program maintenance and transportability. This chapter describes how to • • • Declare VAX BASIC subprograms Write VAX BASIC subprograms Share data among program units Subprograms processed by the VAX BASIC compiler conform to the VAX Procedure Calling Standard. This standard prescribes how arguments are passed, how values are returned, and how procedures receive and return control. Because VAX BASIC conforms to the VAX Procedure Calling Standard, a VAX BASIC subprogram or main program can call or be called by any procedure written in a language that also conforms to this standard. For information about calling non-BASIC procedures, see Chapter 21. Program Segmentation 14-1 14.1 VAX BASIC Subprograms VAX BASIC has SUB, FUNCTION, and PICTURE subprograms. Each of these subprograms receives parameters and can modify parameters passed by reference or by descriptor. The differences between SUB, FUNCTION, and PICTURE subprograms are as follows: • • • FUNCTION subprograms must be declared with an EXTERNAL statement in the calling program. Declaring SUB and PICTURE subprograms is optional. FUNCTION subprograms return a value; SUB and PICTURE subprograms do not. PICTURE subprograms must be invoked with the DRAW statement and are reserved for use with VAX BASIC graphics. For more information on PICTURE subprograms, see Programming with VAX BASIC Graphics. All subprograms invoked by a VAX BASIC program must have unique names. A VAX BASIC program cannot have different subprograms with the same identifiers. Subprograms can return a value to the calling program by way of parameters. You can use subprograms to separate routines that you commonly use. For example, you can use subprograms to perform file I/O operations, to sort data, or for table lookups. You can also use subprograms to separate very large programs into smaller, more manageable routines, or you can separate modules that are modified often. If all references to system-specific features are isolated, it is easier to transport the program to a different system. VAX/VMS System Services and VAX Run-Time Library routines are specific to VAX/VMS systems; therefore, you should consider isolating references to them in subprograms. Chapter 21 describes how to access Run-Time Library routines and system services from VAX BASIC. You should also consider isolating complex processing algorithms that are used commonly. If complex processing routines are isolated, they can be shared by many programs while the complexity remains hidden from the main program logic. However, they can share data only if the data is • • Passed as a parameter from the CALL statement or function invocation to the subprogram-see Section 14.2 Part of a MAP or COMMON block-see Chapter 8 for information about using MAP and COMMON statements 14-2 Program Segmentation • In a file-see Chapter 15 for more information about accessing data from a file All DATA statements are local to a subprogram. Each time you call a subprogram, VAX BASIC positions the data pointer at the beginning of the subprogram's data. The data pointer in the main program is not affected by READ or RESTORE statements in the subprogram (in contrast with the RESTORE # statement, which resets record pointers to the first record in the file no matter where it is executed). Chapter 7 contains more information on the READ and RESTORE statements. For more information on the RESTORE #statement, see Chapter 15. 14.1.1 SUB Subprograms A SUB subprogram is a program module that can be separately compiled and that cannot return a value. A SUB subprogram is delimited by the SUB and END SUB statements. You may use the EXTERNAL statement to explicitly declare the SUB subprogram. The END SUB statement does the following: • • • • Marks the end of the SUB subprogram Does not affect 1/0 operations or files Releases the storage allocated to local variables Returns control to the calling program The EXIT SUB statement transfers control to the statement lexically following the statement that invoked the subprogram. It is equivalent to an unconditional branch to an END SUB statement. The following SUB subprogram sorts two integers. If this SUB is invoked with actual parameter values that are already in sorted order, the EXIT SUB statement is executed and control returns to the calling program. Program Segmentation 14-3 SUB sort_0t1t (INTEGER X, INTEGER Y) DECLARE INTEGER temp IF X > Y THEN temp = X x =y Y = temp ELSE EXIT SUB END IF END SUB 14.1.2 FUNCTION Subprograms A FUNCTION subprogram is a program module that returns a value and can be separately compiled. It must be delimited by the FUNCTION and END FUNCTION statements. You use the EXTERNAL statement to name and explicitly declare the data type of an external function. The END FUNCTION statement does the following: • • • • • Marks the end of a function subprogram Does not affect I/O operations or files Releases the storage allocated to local variables Optionally specifies a return value for the function Returns control to the calling program The EXIT FUNCTION statement immediately returns program control to the statement that invoked the function and optionally returns the function's return value. It is equivalent to an unconditional transfer to the END FUNCTION statement. You can specify an expression with both the END FUNCTION and EXIT FUNCTION statements, which is another way of returning a function value. This expression must match the function data type, and it supersedes any function assignment. For more information, see the VAX BASIC Reference Manual. The following function returns the volume of a sphere of radius R. If this function is invoked with an actual parameter value less than or equal to zero, the function returns zero. 14-4 Program Segmentation Example FUNCTION REAL Sphere_volume (REAL R) IF R <= 0 THEN Sphere_volume = 0.0 ELSE Sphere_volume = 4/3 * PI * R ** 3 END IF END FUNCTION The following example declares the FUNCTION subprogram and invokes it: Example PROGRAM call_sphere EXTERNAL REAL FUNCTION SPHERE_VOLUME(REAL) PRINT SPHERE_VOLUME(6.926) END PROGRAM Note that this module is compiled separately from the FUNCTION subprogram. You can link these modules together to run the program from DCL level. To run the program in the BASIC environment, you follow these steps: 1. 2. 3. 4. Compile the function subprogram Load the resulting object module with the LOAD command Read in the main program with the OLD command Type RUN See Chapter 3 for more information about the LOAD command and linking and running multiple-unit programs. 14.2 Declaring Subprograms and Parameters You declare a subprogram by naming it in an EXTERNAL statement in the calling program. You may also declare the data type of each parameter. If the subprogram is a function, the EXTERNAL statement also lets you specify the data type of the returned value. Program Segmentation 14-5 The following statements are sample subprogram declarations using the EXTERNAL statement: EXTERNAL SUB my_sub (LONG, STRING) EXTERNAL GFLOAT FUNCTION my_func (GFLOAT, LONG, GFLOAT) EXTERNAL REAL FUNCTION determinant (LONG DIM(,)) Note that the parameter lists contain only data type and dimension information; they cannot contain any format or actual parameters. When the external procedure is invoked, VAX BASIC ensures that the actual parameter data type matches the data type specified in the EXTERNAL declaration. However, VAX BASIC does not check to make sure that the parameters declared in the EXTERNAL statement match those in the external routine. You must ensure that these parameters match. You can pass data of any VAX BASIC data type to a VAX BASIC subprogram, including RFAs and RECORDs. VAX BASIC allows you to pass up to 255 parameters, separated by commas. The data can be any one of the following: • • • • • • Constants Variables Expressions Functions Array elements Entire arrays (but not virtual arrays) For passing constants, variables, functions and array elements, you simply name them in the argument list. For example: CALL SUB01(var1, var2) CALL SUB02(Po_numY., Vouch, 66.67, Cust_list(6), FNA(BY.)) However, when passing an entire array, you must use a special format. You specify the array name followed by commas enclosed in parentheses. The number of commas must be the number of array dimensions minus one. For example, array_name() is a one-dimensional array, array_name(,) is a two-dimensional array, array_name(,,) signifies a three-dimensional array, and so on. The following example creates a three-dimensional array, loads the array with values, and passes the array to a subprogram as a parameter. The subprogram can access and change values in array elements, and these changes remain in effect when control returns to the main program. 14-6 Program Segmentation Example PROGRAM fill_array OPTION TYPE = EXPLICIT DECLARE LONG I,J,K, three_d(10,10,10) EXTERNAL SUB example_sub (LONG DIM(,,)) FOR I = 0 TO 10 FOR J = 0 TO 10 FOR K = 0 TO 10 three_d(I,J,K) =I + J + K NEXT K NEXT J NEXT I CALL example_sub( three_d(,,)) END PROGRAM SUB example_sub( LONG X( , , )) END SUB If you do not specify data types for parameters, the default data type is determined by • • • • The last specified parameter data type An OPTION statement A VAX BASIC compilation qualifier (for example, /REAL _SIZE=DOUBLE) The system default The last specified parameter data type overrides all the other default data types, the defaults specified in the OPTION statement override any compilation qualifiers and system defaults, and so on. See Chapter 3 for more information on the OPTION statement and establishing data type defaults. When you know the length of a string or the dimensions of an array at compile time, you can achieve optimum performance, by passing them BY REF. When you call programs written in other languages, the practice of declaring subprograms and specifying the data types of parameters becomes more important because other languages may not use the VAX BASIC default parameter-passing mechanisms. For more information on calling subprograms written in other languages, see Chapter 21. Program Segmentation 14-7 14.3 Compiling Subprograms A VAX BASIC source file can contain multiple program units. When you compile such a file, VAX BASIC produces a single object file containing the code from all the program units. You can then link this object file to create an executable image. If the main program and subprograms are in separate source files, you can compile them separately from DCL level. For example, the following command causes VAX BASIC to create MAIN.OBJ, SUBl.OBJ, and SUB2.0BJ by separating the file names with commas: $ BASIC main,sub1,sub2 To link these programs, you must specify all object files as input to the VAX/VMS Linker. Alternatively, you can compile multiple modules into a single object file at DCL command level by separating the file names with plus signs: $ BASIC main+sub1+sub2 The plus signs used to separate the file names cause VAX BASIC to create a single object file named MAIN.OBJ from the three source modules. To link this program, you specify only one input file to the linker. Note that you cannot concatenate source files that do not contain line numbers. In the BASIC environment, you can compile multiple program units with a resulting single object file by using the APPEND command followed by the COMPILE command. For more information on the APPEND and COMPILE commands, see Chapter 3. When creating a multiple-unit program, follow these rules: • • • • If the source file contains line numbers, then the line numbers for each subprogram must be numerically greater than the highest line number of all preceding subprograms. Line numbers must be unique and no greater than 32767. Each subprogram must end with an END SUB or END FUNCTION statement before the next subprogram begins. If the source file contains line numbers, then text following an END SUB or END FUNCTION statement must begin on a numbered line. 14-8 Program Segmentation • If the source file does not contain line numbers, then text following an END SUB or END FUNCTION statement must begin on a new physical line. Note that in a multiple-unit program that contains line numbers, any comments or statements following an END, END SUB, or END FUNCTION statement become part of the preceding subprogram unless they begin on a numbered line. In a multiple-unit program that does not contain line numbers, however, any comments following an END, END SUB, or END FUNCTION statement become part of the following subprogram if one exists. In the following example, the function Strip changes all brackets to parentheses in the string A$ or alpha, and strips all trailing spaces and tabs: Example PROGRAM scan EXTERNAL STRING FUNCTION Strip (STRING) A$= "USER$DISK:[BASIC.TRYOUTS] B$ = Strip( A$ ) PRINT 8$ END PROGRAM FUNCTION STRING Strip( STRING alpha ) IF (POS( alpha, "[", 11.)) > OY. THEN Strip = EDIT$(alpha, 1281. +641.) ELSE Strip = EDIT$(alpha, 1281.) END IF END FUNCTION 14.4 Invoking Subprograms The following sections describe how to • • • Invoke subprograms Pass parameters to subprograms Share data among program modules Program Segmentation 14-9 14.4.1 Invoking SUB Subprograms The CALL statement transfers control to a subprogram, and optionally passes arguments to it. The parameters in the CALL statement specify variables, constants, expressions, array elements, or entire arrays to be passed to the subprogram. You can also specify a function in the argument list; when you do this, VAX BASIC passes the value returned by the function to the subprogram. If possible, VAX BASIC converts the actual arguments to the data type specified in the EXTERNAL statement. VAX BASIC signals an error when the conversion is not possible. The following example shows a VAX BASIC main program calling a VAX BASIC subprogram. The main program prompts for three integers: A, B, and C. It then passes these variables as parameters to the SUB subprogram. The subprogram prints the sum of these variables and returns control to the calling program. Example PROGRAM get_input OPTION TYPE = EXPLICIT EXTERNAL SUB SUB01(LONG, LONG, LONG) DECLARE LONG A, 8, C INPUT "Please type three integers"; A, 8, C CALL SUB01 (A, 8, C) END PROGRAM SUB SUB01 (LONG X, LONG Y, LONG Z) PRINT "The sum is"; X + Y + Z END SUB 14.4.2 Invoking FUNCTION Subprograms The following example performs the same task as the example shown in Section 14.4.1; however, this example uses a FUNCTION subprogram that returns the value to the main program and the main program prints the result. 14-10 Program Segmentation Example PROGRAM invoke_funct EXTERNAL LONG FUNCTION FUN01(LONG, LONG, LONG) DECLARE LONG A, B, C INPUT "Please type three integers"; A, B, C PRINT "The sum is"; FUN01(A, B, C) END PROGRAM FUNCTION LONG FUN01 (LONG X, LONG Y, LONG Z) FUN01 = X + Y + Z END FUNCTION If you do not assign a value to the function name and you do not specify a return value on an EXIT FUNCTION or END FUNCTION statement, the function returns zero or the null string. Note that when writing FUNCTION subprograms, you must specify a data type for the function in both the main program EXTERNAL statement and the subprogram FUNCTION statement. This data type keyword specifies the data type of the value returned by the function subprogram. You should ensure that the data type specified in an EXTERNAL FUNCTION statement matches the data type specified in the FUNCTION statement. If you declare a FUNCTION subprogram with an EXTERNAL statement and use the CALL statement to invoke the function, it executes correctly but the function value is not available. Note that VAX BASIC still performs parameter validation when you invoke a function with the CALL statement. Note that you cannot use the CALL statement to invoke a string or packed decimal function. 14.5 Returning Program Status A PROGRAM unit lets you return a status from a VAX BASIC image. To do this, you can optionally include an integer expression with the END PROGRAM and EXIT PROGRAM statements. After executing a program, you can examine this status by checking the DCL symbol $STATUS. By default, VAX BASIC returns a status of 1, indicating success. Success is signaled with an odd numbered status value, while an error is signaled with an even numbered value. $STATUS contains the same value as the integer expression for the exit status in the EXIT and END PROGRAM statements. Note that if a program is terminated with an EXIT PROGRAM statement, the expression on the EXIT PROGRAM statement overrides any expression on the END PROGRAM statement. Program Segmentation 14-11 In the following example, exit_status contains the status value returned by the program. After program execution, $STATUS has the value of exit_status. You can examine the value of $STATUS and display the corresponding message text with the lexical function F$MESSAGE at DCL level, as shown following this example: Example PROGRAM Venture DECLARE INTEGER exit_status, t REAL capital EXTERNAL LONG CONSTANT SS$_BADPARAM EXTERNAL SUB play_safe(INTEGER), t minor_risk(INTEGER),major_risk(INTEGER) Exit_status = 1% SET NO PROMPT How_much: INPUT "Enter the amount of your free capital $";capital SELECT capital CASE = 0 exit_status = SS$_BADPARAM EXIT PROGRAM exit_status CASE < 6000 CALL play_safe(capital) CASE < 16000 CALL minor_risk(capital) CASE < 60000 CALL major_risk(capital) CASE ELSE PRINT "I can't cope with that amount, try again." END SELECT GOTO How_much END PROGRAM exit_status After program execution, you can examine the status of the program at DCL level: $ SHOW SYMBOL $STATUS $STATUS = "Y.X10" $ error_text = F$MESSAGE(%X10) $ SHOW SYMBOL error_text ERROR_TEXT = "SYSTEM-W-BADPARAM, bad parameter value" The PROGRAM statement is always optional; EXIT PROGRAM and END PROGRAM are legal without a matching PROGRAM statement. Without a PROGRAM statement, these statements still exit the main compilation unit. The EXIT PROGRAM and END PROGRAM statements are not valid within SUB, FUNCTION, or PICTURE subprograms. 14-12 Program Segmentation Chapter 15 File Input and Output This chapter explains the VAX BASIC file organizations and record operations that are implemented through VAX Record Management Services (VAX RMS). For a more thorough understanding of file organization and file and record operations, see the VAX Record Management Services Reference Manual. RMS stores data in physical blocks. A block is the smallest number of bytes VAX BASIC transfers in a read or write operation. On disk, a block is 512 bytes. On magnetic tape, it is between 18 and 8192 bytes. RMS stores one or more data records in each block. A data record can also be divided into smaller units, called fields. A data record can be smaller than, equal to, or larger than a disk block. 15.1 Record Formats The format of a record determines how RMS stores the record in a block. You specify the record format in an OPEN statement. The following are valid VAX BASIC record formats: • • • Fixed-length records Variable-length records Stream records File Input and Output 15-1 15.1. 1 Fixed-Length Records Fixed-length records are all the same length. RMS stores fixed-length records as they appear in the record buffer, including any spaces or null characters following the data; this process is called padding. Processing these records involves less overhead than other record formats; however, this format can use disk storage space less efficiently than variable-length or stream records. 15.1.2 Variable-Length Records Variable-length records can have different lengths, but no record can exceed a maximum size set for the file. When the record is written to a file, RMS adds a record length header that contains the length of the record (excluding the header) in bytes. When your program retrieves a record, this header is not included in the record buffer. While variablelength records usually make more efficient use of storage space than fixed-length records, manipulation of the record length headers generates processor overhead. 15. 1.3 Stream Records VAX BASIC interprets stream records as a continuous sequence, or stream, of bytes. Unlike the fixed- and variable-length formats, stream records do not contain control information such as record counts, segment flags, or other system-supplied boundaries. Stream records are delimited by special characters or character sequences called terminators. Note that stream record formats are valid only in sequential files. RMS defines three types of stream record format: • • • STREAM records can be delimited by any special character (usually a carriage return/line-feed pair). STREAM_LF records must be delimited by a line-feed character. STREAM_CR records must be delimited by a carriage return. While you can access existing files of any one of these stream record formats, VAX BASIC creates new stream files only in the STREAM format; you can create files of the other two stream record formats by modifying the RMS FAB control structure in a USEROPEN routine. For more information on USEROPEN routines, see Section 15.8.11. 15-2 File Input and Output 15.2 File Organizations VAX BASIC provides several types of file organization: sequential, relative, indexed, and virtual. If you do not specify a file organization when creating a file, the default is a terminal-format file (a sequential file with variable-length records). The following sections describe each type of file organization. 15.2. 1 Terminal-Format Files A terminal-format file is a sequential file of variable-length records. Terminal-format files are the default; that is, you create a terminal-format file when you do not specify a file organization when you open a file. You can then use the PRINT, INPUT, INPUT LINE, and LINPUT statements to access a terminal-format file. See Chapters 7 and 8 for more information about terminal-format files. 15.2.2 Sequential Files A sequential file contains records that are stored in the order they are written. Sequential files can contain records of any valid VAX BASIC record format: fixed-length, variable-length, or stream. You usually read a sequential file from the beginning; therefore, a sequential file is most useful when you access the data sequentially each time you use it. You can also access sequential fixed-length records randomly by specifying a record number if the file resides on disk. In either case, sequential files can reside on both disk and magnetic tape devices, and those stored on disk support shared access. File Input and Output 15-3 15.2.3 Relative Files A relative file contains a series of "cells" that are numbered consecutively from 1 ton, where n represents the relative record number. Each cell can contain only a single record. For fixed-length records, the length of each cell equals the record length plus 1 byte. For variable-length records, the length of the cell equals the maximum record size plus 3 bytes. You can access records in a relative file either sequentially or randomly. The relative record number is the key value in random access mode; that is, to access a record in a relative file in random access mode, you must know the relative record number of that record. You can add records to a relative file either at the end of the file or into any empty cell. Relative files are most useful when randomly accessed and when the record can be identified by its cell number (for example, when inventory numbers correspond to cell numbers). Relative files support shared access. You can delete records from relative files, but not sequential files. 15.2.4 Indexed Files An indexed file contains data records that are sorted in ascending or descending order according to a primary index key value. The index key is a record field (or set of fields) that determines the order in which the records are logically accessed. Keys must be variables declared in a MAP statement. Keys can be any one of the following: • • • • • Strings WORD integers LONG integers Quadword integers Packed decimal numbers String keys can also be segmented; the key can be composed of up to eight string variables in a map. Quadword keys must be referenced using a record or group exactly 8 bytes long. Along with the primary index key value, you can also specify up to 254 alternate keys; RMS creates one index for each key you specify. For each of these keys you can also specify either an ascending or descending collating sequence. Each index is stored as part of the file, and each 15-4 File Input and Output entry in the index contains a pointer to a record. Therefore, each key you specify corresponds to a sorted list of record pointers. An indexed file of library books, for example, might be ordered by book title; that is, the title of the book is the primary key for the file. The keys for alternate indexes might include the author's name and the book's Library of Congress number. Neither of these alternate indexes contains the actual records; instead, they contain sorted pointers to the appropriate records. Indexed files are most useful when randomly accessed or when you want to access the records in more than one way. 15.2.5 Virtual Files A virtual file is a random access file that stores one or more data records or virtual array elements in each physical 512-byte disk block. You create a virtual file by specifying ORGANIZATION VIRTUAL as part of the OPEN statement. Apart from virtual arrays and compatibility with BASIC-PLUS and BASIC-PLUS-2, you should use sequential fixed-length instead of virtual files, as they provide the same capabilities. See Section 15.5 for more information on accessing the individual records in a disk block. 15.3 Record Access and Record Context Record access modes determine the order in which your program retrieves or stores records in a file. They determine the record context: the current record and the next record to be processed. When your program successfully executes any record operation, the current record and next record pointers can change. If a record operation is unsuccessful, these pointers do not change. The four record access modes valid for RMS are as follows: • • • • Sequential access-valid on any file organization Random-by-record number access-valid on sequential fixed and all relative files Random-by-key access-valid on indexed files Random-by-RFA (Record File Address) access-valid on any RMS file located on disk File Input and Output 15-5 With sequential access, the next record is the next logical record in the file. In the case of relative files, the next logical record is the next existing record (deleted or never-written records are skipped). In the case of indexed files, the next logical record is the record with the next ascending or descending value in the current key of reference depending on that key's collating sequence. You can therefore access relative or indexed files sequentially by not specifying a relative record number or key value. You can also access sequential fixed-length and relative files randomly by record number; that is, you can specify the record number of the record to be retrieved. For relative files, this record number corresponds to the cell number of the desired record. You can access indexed files randomly by key. The key specification includes a primary or alternate key and its value. VAX BASIC retrieves the record corresponding to that value in the particular key chosen. You can access disk files of any organization by Record File Address (RFA); this means that you specify an RFA variable whose value uniquely identifies a particular record. The RFA requires six bytes of information. For more information about RFAs, see Section 15.6.10. 15.4 1/0 and Record Buffers An 1/0 buffer is a storage area in your program that RMS uses to store data for 1/0 operations. You do not have direct access to 1/0 buffers; they are controlled entirely by RMS. The 1/0 buffer holds blocks of data transferred from the device, and its size is always greater than or equal to that of the record buffer. For more information about the amount of storage allocated for 1/0 buffers, see the VAX Record Management Services Reference Manual. A record buffer is another storage area in your program. You have direct access to and control of the record buffer. When your program reads a record from a file, the information is transferred from the file to the 1/0 buffer in one large chunk of data, and then the requested record is transferred to the record buffer. When your program writes a record, data is transferred from the record buffer to the 1/0 buffer, and then to the file either when the 1/0 buffer is full or when other blocks need to be read in. You can use MAP statements to create static record buffers and associate program variables with areas (fields) of the buffer. Static record buffers are buffers whose size does not change during program execution and whose program variables are always associated with the same fields in the buffer. 15-6 File Input and Output You can create dynamic record buffers with either a MAP DYNAMIC or a REMAP statement. These statements, when used after a MAP statement, associate or reassociate a particular program variable with a different area (field) of the record buffer. However, the total size of a record buffer does not change during program execution. NOTE If you do not specify a map, you must use MOVE TO and MOVE FROM statements to transfer data back and forth from the record buffer to program variables. However, MOVE statements do not transfer data to or from a file. 15.5 Accessing the Contents of a Record VAX BASIC provides several different methods for accessing the contents of a record: • • • • MAP statement MAP DYNAMIC, and REMAP statements (dynamic mapping) MOVE statements FIELD statements The FIELD statement is a declining feature and is not recommended for new program development. DIGITAL recommends that you use either MAP statements, dynamic mapping or MOVE statements to access record contents. 15.5. 1 The MAP Statement Normally, a record is divided into predetermined fields, the sizes of which are known at compile time. The MAP statement creates the storage area for this record and determines its total size. File Input and Output 15-7 Example 1 RECORD name_addr STRING last_name = 15, k street_name = 30, k INTEGER house_num END RECORD MAP (student_buffer) name_addr student_info Example 2 MAP (Emp_rec) STRING Emp_name = 26, LONG Badge, STRING Address • 25, STRING Department = 4 15.5.2 The MAP DYNAMIC and REMAP Statements There are situations where predetermined fields are not applicable or possible. In these situations, you must perform record defielding in your program at run time. Using the MAP DYNAMIC statement, you can specify the variables in the map whose positions can change at run time. The REMAP statement then specifies the new positions of the variables named in the MAP DYNAMIC statement. The following example shows how you can use MAP, MAP DYNAMIC, and REMAP to deblock your record fields. The MAP statement allocates a storage area of 2048 bytes and names it Emp_rec. The MAP DYNAMIC statement specifies that the variables Emp_name, Badge, Address, and Department are all located in Emp_rec, and that their positions can be changed at run time with the REMAP statement. The REMAP statement then redefines these variables to their appropriate sizes. Example MAP (Emp_rec) FILL$ = 2048 MAP DYNAMIC (Emp_rec) STRING Emp_name, LONG Badge, STRING Address, STRING Department 15-8 File Input and Output REMAP (Emp_rec) FILL$ = Record_offset, Emp_name = 25, Badge, Address = 25, Department = 4 Note that when accessing virtual or sequential files, you can specify a RECORD clause for the GET statement. The following program opens a virtual file with each block containing 512 bytes. However, each block contains 4 logical records that are 128 bytes long. Each of these logical records consists of a 20-character first name field, a 44-character last name field, and a 64-character company name field. Example DECLARE WORD Record_number MAP (Virt) STRING FILL = 512 MAP DYNAMIC (Virt) STRING First_name, Last_name, Company OPEN "VIRT.DAT" FOR INPUT AS FILE #5, VIRTUAL, MAP Virt Record_number = 1Y. & & & WHEN ERROR IN WHILE -1Y. GET #5, RECORD Record_number FOR IY. = OY. TO 3Y. REMAP (Virt) STRING FILL= (IY. * 1281.), First_name = 20, Last_name = 44, Company = 64 PRINT First_name, Last_name, Company NEXT IY. Record_number = Record_number + 1Y. NEXT & & & USE IF ERR = 11Y. THEN PRINT "Finished" CONTINUE 32767 ELSE EXIT HANDLER END IF END WHEN END After the first 512-byte block is brought into memory, the FOR. .. NEXT loop deblocks the data into 128-byte logical records. At each iteration of the FOR. .. NEXT loop, the REMAP statement uses the loop variable to mask off 128-byte sections of the block. File Input and Output 15-9 For more information on the MAP DYNAMIC and REMAP statements, see Chapter 9 and the VAX BASIC Reference Manual. 15.5.3 The MOVE Statement The MOVE statement defines data fields and moves them to and from the record buffer created by VAX BASIC. For example: MOVE FROM #9Y., A$, Cost, Name$ = 30Y., ID_numY. This statement moves a record with four data fields from the record buffer to the variables in the list: • • • • A string field A$ with a default length of 16 characters A number field Cost of the default data type A second 30-character string field Name$ An integer field JD_num% Valid variables in the MOVE list are as follows: • • • • Scalar variables Arrays Array elements FILL items Because VAX BASIC dynamically assigns space for string variables, the default string length during a MOVE TO operation is the length of the string. The default for MOVE FROM is 16 characters. An entire array specified in a MOVE statement must include the array name, followed by n-l commas, where n is the number of dimensions in the array. Note that these commas must be enclosed in parentheses. You specify a single array element by naming the array and the subscripts of that element. The following statement moves three arrays from the program to the record buffer. A$ specifies a one-dimensional string array, C specifies a two-dimensional array of the default data type, and D% specifies a threedimensional integer array. B(3,2) specifies the element of array B that appears in row 3, column 2. MOVE TO #6Y., A$(), C(,), DY.(,,), 8(3,2) 15-10 File Input and Output Successive MOVE statements to or from the buffer start at the beginning of the record buffer. If a MOVE TO operation only partially fills the buffer, the rest of the buffer is unchanged. You use the GET statement to read a record from a file, and then you move the data from the buffer to variables and reference the variables in your program. A MOVE TO operation moves data from the variables into the buffer created by VAX BASIC. A PUT or UPDATE statement then moves the data from the buffer to the file. The following program opens file MOV.DAT, reads the first record into the buffer, and moves the data from the buffer into the variables specified in the MOVE FROM statement. Example DECLARE STRING Emp_name, Address, Department DECLARE LONG Badge OPEN "MDV.DAT" AS FILE #1Y,, RELATIVE VARIABLE, ACCESS MODIFY, ALLOW NONE, RECORDSIZE 612% ll ll ll GET #1% MOVE FROM #iY., Emp_name = 26, Badge, Address = 26, Department = 4 · MOVE TO #1Y., Emp_name = 26, Badge, Address = 26, Department = 4 UPDATE #iY. CLOSE #iY. END The MOVE TO statement moves the data from the named variables into the buffer. The UPDATE statement writes the record back into file MOV.DAT. The CLOSE statement closes the file. File Input and Output 15-11 15.6 File and Record Operations You can perform a variety of operations on files and on the records within a file. The following is a list of all the file and record operations supported by VAX BASIC: • • • • • • • • • • • • • • Open a file for processing with the OPEN statement Locate a record in a file with the FIND statement Read a record from a file with the GET statement Write a record to a file with the PUT statement Delete a record from a file with the DELETE statement Change the contents of a record field with the UPDATE statement Unlock the last record accessed with the UNLOCK statement Unlock all previously locked records with the FREE statement Write data to a terminal-format file with the PRINT # statement Reset the current record pointer to the beginning of a file with the RESTORE/RESET # statements Delete all the records after a certain point; that is, truncate the records, with the SCRATCH statement Rename a file with the NAME AS statement Close an open file with the CLOSE statement Delete an entire file with the KILL statement Note that before you can perform any operations on the records in a file, you must first open the file for processing. 15.6. 1 Opening Files The OPEN statement opens a file for processing, specifies the characteristics of the file to RMS, and verifies the result. Opening a file with the specification FOR INPUT specifies that you want to use an existing file. Opening a file with the specification FOR OUTPUT indicates that you want to create a new file. If you do not specify FOR INPUT or FOR OUTPUT, VAX BASIC tries to open an existing file. If no such file exists, VAX BASIC then creates a new file. 15-12 File Input and Output Clauses to the OPEN statement allow you to specify the characteristics of a file. All OPEN statement clauses concerning file or record format are optional when you open an existing file; those attributes that are not specified default to the attributes of the existing file. When you open an existing file, you must specify the file name, channel number, and unless the file is a terminal-format file, an organization clause. If you do not know the organization of the file you want to open, you can specify ORGANIZATION UNDEFINED. If you specify ORGANIZATION UNDEFINED, also specify RECORDTYPE ANY. If you do not specify a map in the OPEN statement, the size of your pro- gram's record buffer is determined by the OPEN statement RECORDSIZE clause, or by the record size associated with the file. If you specify both a MAP clause and a RECORDSIZE clause in the OPEN statement, the specified record size overrides the size specified by the MAP clause. The following statement opens a new sequential file of stream format records: OPEN "TEST.DAT" FOR OUTPUT AS FILE #1Y., SEQUENTIAL STREAM t The following example creates a relative file and associates it with a static record buffer. The MAP statement defines the record buffer's total size and the data types of its variables. When the program is compiled, VAX BASIC allocates space in the record buffer for one integer, one 16-byte string, and one double-precision floating-point number. The record size is the total of these fields, or 28 bytes. All subsequent record operations use this static buffer for I/O to the file. Example MAP (Inv_item) LONG Part_number, STRING Inv_name = 16, DOUBLE Unit_price OPEN "INVENTORY.DAT" FOR OUTPUT AS FILE 11Y. ,ORGANIZATION RELATIVE FIXED, ACCESS MODIFY ,ALLOW READ, MAP Inv_item t t t t The following OPEN statement opens a sequential file for reading only (ACCESS READ). Because the OPEN statement does not contain a MAP clause, VAX BASIC creates a record buffer. This record buffer is 100 bytes long. OPEN "CASE.DAT" AS FILE #1Y. ,ORGANIZATION SEQUENTIAL VARIABLE , ACCESS READ ,RECORDSIZE 100Y. t t t F~e Input and Output 15-13 When you do not specify a MAP statement, your program must use MOVE TO and MOVE FROM statements to move data between the record buffer and a list of variables. The OPEN statement for indexed files must have a MAP clause. Moreover, if you are creating an indexed file, a PRIMARY KEY clause is required. You can create a segmented index key containing more than one string variable by separating the variables with commas and enclosing them in parentheses. All the string variables must be part of the associated map. In the following example, the primary key is made up of three string variables. This key causes the records to be sorted in alphabetical order according to the person's last name, first name, and middle initial. MAP (Segkey) STRING First_name = 15, MI = 1, Last_name = 15 OPEN "NAMES.IND" FOR OUTPUT AS FILE #11,, & ORGANIZATION INDEXED, & PRIMARY KEY (Last_name, First_name, MI), & MAP Segkey Note that there are restrictions on the maximum record size allowed for various file and record formats. See the VAX Record Management Services Reference Manual for more information. You can use logical names to assign a mnemonic name to all or part of a complete file specification, including node, device and directory. The advantage in using logical names is that programs do not depend on literal file specifications. You can define logical names: • • • From DCL command level with the ASSIGN or DEFINE command From within a program with the SYS$CRELMN system service From within the BASIC environment with the VAX BASIC command ASSIGN VAX BASIC supports any valid logical name as part of a file specification. A logical name specifies a 1- through 255-character name to be associated with the specified device or file specification. If the logical name specifies a device, you must end the logical name with a colon. The following example defines a logical name for a file specification: $ ASSIGN DUA1: [SENDER]PAYROL.DAT PAYROLL_DATA This example defines a logical name for a physical device: $ ASSIGN DUA2: DISK2: Once you define the logical name! you can reference that name in your program. 15-14 File Input and Output Example OPEN "PAYROLL_DATA" FOR INPUT AS FILE #11., & ORGANIZATION SEQUENTIAL OPEN "DISK2:[SORT_DATA] SORT.LIS" FOR OUTPUT AS FILE #21,, & SEQUENTIAL VARIABLE These OPEN statements do not depend on the availability of DUAl: or DUA2: in order to work. If these devices are not available, you can simply redefine the logical names so that they specify other disk drives before running the program. In addition, you can redirect the entire file specification for PAYROLL_DATA to point to the test or production version of the data. For more information on logical names, see the Introduction to VAX/VMS. 15.6.2 Creating Virtual Array Files VAX BASIC virtual arrays let you define arrays that reside on disk. You use them just as you would an ordinary array. You create a virtual array by dimensioning an array with the DIM# statement, then opening a VIRTUAL file on that channel. You access virtual arrays just as you do normal arrays. The following DIM# statement dimensions a virtual array on channel #1. The OPEN statement opens a virtual file that contains the array. The last program line assigns a value to one array element. Example DIM #11., LONG Int_array(10,10,10) OPEN "VIRT.DAT" FOR OUTPUT AS FILE #11., VIRTUAL Int_array(6,6,6) = 1001. Note that you cannot redimension virtual arrays with an executable DIM statement. See Chapter 8 for more information on virtual arrays. File Input and Output 15-15 15.6.3 Locating Records The FIND statement locates a specified record and makes it the current record. Using the FIND statement to locate records can be faster than using a GET statement because the FIND statement does not transfer any data to the record buffer; therefore, it executes faster than a GET statement. However, if you are interested in the contents of a record, you must retrieve it with a GET operation. The FIND statement sets the current record pointer to the record just found, making it the target for a GET, UPDATE, or DELETE statement. (Note that you must have write access to a record before issuing a PUT, UPDATE, or DELETE operation.) A sequential FIND operation searches records in the following order: • • • Sequential files from beginning to end Relative files in ascending relative record or cell number order Indexed files in ascending or descending order, based on the current key of reference and the key's collating sequence For sequential fixed-length and relative files, you can find a particular record by specifying a RECORD clause. This is called a random access FIND. You can also perform a random access FIND for indexed files by specifying a key of reference, a relational test, and a key value. In the following example, the first FIND statement finds the first record whose key value either equals or follows SMITH in the key's collating sequence. The second FIND statement finds the first record whose key value follows JONES in the key's collating sequence. Each record found by the FIND statement becomes the current record. (Note that you can only have one current record at a time.) Example MAP (Emp) STRING Emp_name, LONG Emp_number, SSN OPEN "EMP.DAT" AS FILE #1%, INDEXED, ACCESS READ, MAP Emp, PRIMARY KEY Emp_name FIND #1%, KEY #0% NXEQ "SMITH" FIND #1%, KEY #0% NX "JONES" & & & The string expression can contain fewer characters than the key of the record you want to find. However, if you want to locate a record whose string key field exactly matches the string expression you provide, you 15-16 File Input and Output must pad the string expression with spaces to the exact length of the key of reference. For example: FIND #6Y., KEY #01. EQ "TOM FIND #6Y., KEY #OY. EQ "TOM" The first FIND statement locates a record whose primary key field equals "TOM ". The second FIND statement locates the first record whose primary key field begins with "TOM". Table 15-1 displays the status of the current record and next record pointers after both a sequential and a random access FIND. Table 15-1: Record Context After a FIND Operation Record Access Mode File Type Current Record Next Record Sequential FIND Sequential Record found Current record + 1 Relative Record found Next existing record Indexed Record found Next record in current key order All Record found Unchanged Random access FIND Note that a random access FIND operation locates the specified record and makes it the current record, but the next record pointer does not change. You can specify an ALLOW clause to the FIND statement if you have opened the file with ACCESS MODIFY or ACCESS WRITE and have specified UNLOCK EXPLICIT. The ALLOW clause lets you control the type of lock that RMS puts on the records you access. ALLOW NONE specifies that no other users can access this record (this is the default). ALLOW READ lets other users read the record; however, they cannot perform UPDATE or DELETE operations to this record. ALLOW MODIFY specifies that other users can both read and write to this record. This means that other access streams can perform GET, DELETE, or UPDATE operations to the specified record. You can also specify a WAIT clause to the FIND statement; this clause allows you to wait for a record to become available in the event that it is currently locked by another process. In addition, you can specify a REGARDLESS clause; this clause allows you to read a locked record. For more information on the WAIT and REGARDLESS clauses, see Section 15.6.9. File Input and Output 15-17 15.6.4 Reading Records The GET statement moves 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. You should not use GET statements on terminal-format files, or virtual array files. For sequential files, a sequential GET retrieves the next record in the file. For relative files, a sequential GET retrieves the next existing record. For indexed files, a sequential GET retrieves the record with the next ascending or descending value in the current key of reference, depending on that key's collating sequence. Table 15-2 shows the current record and next record pointers after a GET operation. Note that the values of these pointers vary depending on whether or not the previous operation was a FIND. Table 15-2: Record Context After a GET Operation Record Access Mode File Type Current Record Next Record Sequential GET with FIND Sequential Record found Current record + 1 Relative Record found Next existing record Sequential GET without FIND Random GET Indexed Record found Next record in current key Sequential Next record Next record + 1 Relative Next existing record Next existing record + 1 Indexed Next record in current key Record following next record in current key All Record specified Next record in succession If you precede a sequential GET operation with a FIND operation, the current record is the one located by FIND. If you do not perform a FIND operation before a sequential GET operation, the current record is the next sequential record. The following example illustrates the use of the GET operation to sequentially access records in an indexed file. The example opens an indexed file and displays the first 25 records with serial numbers greater than AB2721 in ascending primary key value order. 15-18 File Input and Output Example MAP (Bee) STRING Owner = 30Y., LONG Vehicle_number, k STRING Serial_number = 22Y. OPEN "VEH.IDN" FOR INPUT AS FILE #2Y., k ORGANIZATION INDEXED, PRIMARY KEY Serial_number, k MAP Bee, ACCESS READ GET #2Y., KEY #OY. EQ "AB2721" FOR IY. = 11. TO 261. GET #2Y. PRINT "Vehicle Number= ";Vehicle_number PRINT "Owner is: ";Owner PRINT NEXT !Y. The following example performs random GET operations by specifying a record number: Example MAP (Bee) STRING Owner = 30Y., LONG Vehicle_number, STRING Serial_number = 221. OPEN "VEH.IDN" FOR INPUT AS FILE #21., ORGANIZATION SEQUENTIAL FIXED, MAP Bee, ACCESS READ INPUT "Which record do you want";AY. t t t WHILE (AY. <> OY.) GET #21., RECORD AY. PRINT "The vehicle number is", Vehicle_number PRINT "The serial number is", Serial_number PRINT "The owner of vehicle";Vehicle_number; "is", Owner INPUT "Next Record";AY. NEXT CLOSE #21. END You can specify an ALLOW clause in a GET statement if you have opened the file with ACCESS MODIFY or ACCESS WRITE and UNLOCK EXPLICIT. The ALLOW clause lets you control the type of lock RMS places on the retrieved record. ALLOW NONE specifies that no other users can access this record (this is the default). ALLOW READ lets other access streams have read access to the record. That is, other users can retrieve the record, but cannot perform DELETE, PUT, or UPDATE operations on it. ALLOW MODIFY lets other access streams perform GET, DELETE, or UPDATE operations on the record. File Input and Output 15-19 If you are trying to access a locked record, VAX BASIC signals "Record/bucket locked" (ERR= 154). However, if you only need to read this record, you can override the lock with the REGARDLESS clause. The REGARDLESS clause allows you to read a locked record. Use caution when using the REGARDLESS clause because a record accessed in this way may be in the process of being changed by another program. Alternatively, you can also specify the WAIT clause on a GET statement; the WAIT clause allows you to handle record locked conditions by waiting for the record to become available. Note that if a WAIT clause is specified on a GET operation to a unit-record device such as a terminal, the integer expression indicates how long to wait for the I/Oto complete, rather than how long to wait on a record locked condition. For more information, see Section 15.6.9. 15.8.5 Writing Records For a file opened with ACCESS WRITE or ACCESS MODIFY, the PUT statement moves data from the record buffer to a file using the IjO buffer. PUT statements are valid on RMS sequential, relative, and indexed files. You cannot use PUT statements on terminal-format files, or virtual array files. Sequential access is valid on RMS sequential, relative, and indexed files. For sequential, variable and stream files, a sequential PUT operation adds a record at the end of the file. For sequential fixed and relative files, PUT writes records sequentially or randomly depending on the presence of a RECORD clause. For indexed files, RMS stores records in order of the primary key's collating sequence. Therefore, you do not need to specify a random or sequential PUT. The following table shows the record context after both random and sequential PUT operations. Table 15-3: 15-20 Record Context After a PUT Operation Record Access Mode File Type Current Record Next Record Sequential PUT Sequential None End of file Sequential PUT Relative None Next record Sequential PUT Indexed None Undefined Random PUT Relative None Unchanged File Input and Output After a PUT operation, the current record pointer has no value. However, the value of the next record pointer changes depending on the file type and the record access mode used with the PUT operation. In a sequential, stream, or variable file, records can only be added at the end of the file; therefore, the next record after PUT is the end of the file. In a relative, sequential, or fixed file, the next record after a PUT operation is the next logical record. The following example opens a sequential file with ACCESS APPEND specified. For sequential files, this is almost identical to ACCESS WRITE. The only difference is that, with ACCESS APPEND, VAX BASIC positions the file pointer after the last record in the file when it opens the file for processing. All subsequent PUT operations append the new record to the end of the existing file. Example MAP (Buff) STRING Code = 4%, Exp_date = 9%, Type_desig = 32% OPEN "INV.DAT"FOR INPUT AS FILE #2%, k ORGANIZATION SEQUENTIAL FIXED, ACCESS APPEND, k MAP Buff WHILE -1% INPUT "What is the specification code";Code INPUT "What is the expiration date";Exp_date INPUT "What is the designator";Type_desig PUT #2% NEXT If the current record pointer is not at the end of the file when you attempt a sequential PUT operation to a sequential file, VAX BASIC signals "Not at end of file" (ERR= 149). In the following example, the PUT statement writes records to an existing indexed file. In this case, the error message "Duplicate key detected" (ERR = 134) indicates that a record with a matching key field already exists, and you did not allow duplicates on that key. File Input and Output 15-21 Example 10 20 30 MAP (Purchase_rec) STRING R_num = 6, Dept_name = 10, Pur_dat = 9 OPEN "INFO.DAT"FOR OUTPUT AS FILE #2, ORGANIZATION INDEXED FIXED, ACCESS WRITE, PRIMARY KEY R_num, MAP Purchase_rec WHILE -1% INPUT "Requisition number";R_num INPUT "Department name";Dept_name INPUT "Date of purchase";Pur_dat PRINT PUT #2Y. NEXT "" "" Output Requisition number? 2622A Department name? COSMETICS Date of purchase? 16-JUNE-1986 Requisition number? 2678D Department name? AUTOMOTIVE Date of purchase? 16-JUNE-1986 Requisition number? 4167C Department name? AUTOMOTIVE Date of purchase? 6-JANUARY-1986 Requisition number? 2622A Department name? SPORTING GOODS Date of purchase? 26-FEBRUARY-1986 Y.BAS-F-DUPKEYDET, Duplicate key detected -BAS-I-ON_CHAFIL, on channel 2 for file USER$$DISK:[MAGNUS]INFO.DAT;8 at user PC 0017E693 -BAS-0-FROLINMOD, from line 30 in module DUPLICATES -RMS-F-DUP, duplicate key detected (DUP not set) 15.8.8 Deleting Records The DELETE statement removes a record from a file that was opened with ACCESS MODIFY. After you have deleted a record you cannot retrieve it. DELETE works with relative and indexed files only. 15-22 File Input and Output A successful FIND or GET operation must precede the DELETE operation. These operations make the target record available for deletion. In the following example, the FIND statement locates record 67 in a relative file and the DELETE statement removes this record from the file. Because the cell itself is not deleted, you can use the PUT statement to write a record into that cell after deleting its contents. FIND 11%, RECORD 67% DELETE #1% NOTE There is no current record after a deletion. The next record pointer is unchanged. 15.6.7 Updating Records UPDATE writes a new record at the location indicated by the current record pointer. UPDATE is valid on RMS sequential, relative, and indexed files. The UPDATE statement operates on the current record, provided that you have write access to that record. In order to successfully update a variablelength record, you must know the exact size of the record you want to update. VAX BASIC has access to this information after a successful GET operation. If you have not performed a successful GET operation on the variable-length record, then you must specify a COUNT clause in the UPDATE statement that contains the record size information. An UPDATE will fail with the exception "No current record" (ERR= 131) if you have not previously established a current record with a successful GET or FIND. Therefore, when updating records you should include error trapping in your program to make sure all GET operations execute successfully. An UPDATE operation on a sequential file is valid only when: • • • The file containing the record is on disk The new record is the same size as the one it is replacing You have established a current record via a GET or FIND operation . Note that COUNT defaults to the size of the current record if a GET was performed. If a FIND operation was used to locate the current record, then you must supply a COUNT value. File Input and Output 15-23 The following program searches to find a record in which the L _name field matches the specified Search_name$. Once this record is found and retrieved, the Rm_num field of that record is updated; the program then prompts for another Search_name$. If a match is not found, VAX BASIC prints the message "No such record" and prompts the user for another Search_name$. The program ends when the user enters a null string for the Search_name$ value. Example 20 30 MAP (AAA) STRING L_name = 60Y., F_name = 20Y., Rm_num = SY. OPEN "STU .DAT"FOR INPUT AS FILE #9Y., & ORGANIZATION SEQUENTIAL FIXED, MAP AAA INPUT "Last name";Search_name$ Search_name$ = EDIT$(Search_name$, -1Y.) IF Search_name$ = "" THEN GOTO 32010 END IF 50 55 60 65 70 75 RESTORE #9Y. WHEN ERROR IN GET #9Y. WHILE Search_name$ <> L_name USE IF ERR=11 THEN PRINT "No such record" CONTINUE 50 ELSE EXIT HANDLER END IF END WHEN INPUT "Room number";Rm_num UPDATE #9Y. GOTO 50 CLOSE #9Y. PRINT "Update complete" END 80 90 100 32010 32030 32767 NOTE An UPDATE operation invalidates the value of the current record pointer. The next record pointer is unchanged. When you update a record in a relative variable file, the new record can be larger or smaller than the record it replaces, provided that it is smaller than the maximum record size set for the file. When you update a record in an indexed variable file, the new record can also be larger or smaller than the record it replaces. The updated record: • • 15-24 Can be no longer than the maximum record size, if specified Must include at least the primary key field File Input and Output The following program updates a specified record on an indexed file: Example MAP (UPD) STRING Enrdat = SY., LONG Part_num, Sh_num, REAL Cost OPEN "REC.ING"FOR INPUT AS FILE #SY., IE INDEXED, MAP UPD, PRIMARY KEY Part_num INPUT "Part number to update";AY. Loop1: WHILE -11. GET #SY., KEY #01., EQ AY. INPUT "Revised Cost is";Cost UPDATE #SY. INPUT "Next Record";AY. IF AY. = 01. THEN EXIT Loop1 END IF NEXT CLOSE #SY. END If the new record either omits one of the old record's alternate key fields or changes one of them, the OPEN statement must specify a CHANGES clause for that key field when the file is created. Otherwise, VAX BASIC signals the error "Key not changeable" (ERR= 130). 15.6.8 Controlling Record Access When you open a file, VAX BASIC allows you to specify how you will access the file and what types of access you will allow other running programs while you have the file open. If you open a file for read access only (ACCESS READ), VAX BASIC by default allows other programs to have unrestricted access to the file. You can restrict access with an ALLOW clause only if the file's security constraints allow you write access to the file. VAX BASIC by default prevents access by other programs to any file you open with ACCESS WRITE, ACCESS MODIFY, or ACCESS SCRATCH (sequential files only). This default action is equivalent to specifying the OPEN statement ALLOW NONE clause. To allow less restrictive access to the open file, specify ALLOW READ or ALLOW MODIFY. File Input and Output 15-25 When a file is open for read access only and you have not restricted access to other programs with ALLOW NONE, VAX BASIC allows other programs to read any record in the file including records that your program is concurrently accessing. However, when you retrieve a record with the GET statement from a file you have opened with the intent to modify, VAX BASIC normally restricts other programs from accessing that record. This restriction is called locking. To allow other programs to access a record you have locked, you must release the lock on the record in one of the following ways: • • • • Retrieve another record on the same channel. Unless you have opened the file with the UNLOCK EXPLICIT clause discussed below, this action will unlock the previous record. Explicitly unlock the record with the UNLOCK or FREE statement. The UNLOCK statement releases the current record. The FREE statement releases all records locked on a given channel. Perform an UPDATE operation on the record. An UPDATE statement causes the current record to be unlocked. Close the file. In addition to the capability of restricting access via the OPEN statement ALLOW clause, VAX BASIC allows programs to explicitly control record locking on each record that is retrieved. To use explicit record locking on a file, the OPEN statement must include an UNLOCK EXPLICIT clause. You may then optionally specify an ALLOW clause on the GET and FIND statements. The ALLOW clause on a GET or FIND statement specifies the type of access allowed by other programs to the record while you are accessing it. For instance, the following statement specifies that other programs may read but not modify the records you have locked. GET #1, ALLOW READ If you specify UNLOCK EXPLICIT when opening a file, all records that you retrieve remain locked until you explicitly unlock them with a FREE, UNLOCK, or CLOSE statement. 15-26 File Input and Output 15.6.9 Gaining Access to Locked Records If you are trying to access a record that is currently locked, one possible solution is to use the REGARDLESS clause on the GET or FIND statement. The REGARDLESS clause is useful when you are interested in having only read access to the specified record. Be aware, however, that using the REGARDLESS clause to read a locked record can lead to unexpected results because the record you read can be in the process of being changed by another program. Another solution is to include a WAIT clause on the GET or FIND statement. Note that you cannot specify a WAIT clause and a REGARDLESS clause on the same statement line. By specifying the WAIT clause, you can tell RMS to wait for a locked record to become available. You can optionally specify an integer expression from 0 through 255 with the WAIT clause. This integer expression indicates the number of seconds RMS should wait for a locked record to become available. If the record does not become available within the specified number of seconds, RMS signals the error "Keyboard wait exhausted" (ERR=15). If you do not specify an integer expression with the WAIT clause, RMS waits indefinitely for the record to become available. Once the record becomes available, RMS delivers the record to the program. Note that a deadlock condition can occur when you cause RMS to wait indefinitely for a locked record. A deadlock condition occurs when two users simultaneously try to access locked records in each other's possession. When a deadlock occurs, RMS signals the error, "RMS$_ DEADLOCK". In turn, VAX BASIC signals the error, "Detected deadlock error while waiting for GET or FIND" (ERR=193). To handle this error, you can either stop trying to access the particular record, or, if you must access the record, free all locked records (regardless of the channel) and then attempt the GET or FIND again. You need to unlock all records because you cannot know which record the other process wants. NOTE If the timeout value specified in the WAIT clause is less than the SYSGEN parameter DEADLOCK_WAIT, then a "keyboard wait exhausted" (ERR=15) message can indicate that either the record did not become available during the specified time, or there is an actual deadlock situation. However, if the timeout value is greater than the SYSGEN parameter DEADLOCK_ WAIT, the system correctly specifies that a deadlock situation has occurred. File Input and Output 15-27 The following example uses the WAIT clause to overcome a record locked condition and traps the resulting error condition: Example MAP (worker) STRING first_name = 10, last_name = 20, badge_number = 6, LONG dept_number & & & MAP (departments) STRING dept_name = 10, LONG dept_code & OPEN "Employee_data.dat" FOR INPUT AS FILE #1Y., INDEXED FIXED, MAP worker, ACCESS MODIFY, PRIMARY badge_number & & OPEN "departments.dat" FOR INPUT AS FILE #2, INDEXED FIXED, MAP departments, ACCESS MODIFY, PRIMARY dept_code WHEN ERROR IN WHILE -1Y. GET #1, WAIT WHEN ERROR USE time_expired_handler GET #2Y., KEY #0 EQ dept_number, & WAIT 10Y. END WHEN PRINT badge_number, dept_name NEXT USE SELECT ERR CASE = 11Y. PRINT "End of file reached" CLOSE 11,, 2Y. CASE = 1931, PRINT "Deadlock detected" UNLOCK #21, RETRY CASE ELSE EXIT HANDLER END SELECT END WHEN 15-28 File Input and Output & & HANDLER time_expired_handler IF ERR = 16% OR ERR = 193% THEN PRINT "Department info not available for:" PRINT "Employee ";badge_number PRINT "Going on to next record." CONTINUE ELSE EXIT HANDLER END IF END HANDLER END PROGRAM The first WHEN ERROR block traps any deadlock conditions. The WHEN ERROR handler unlocks the current record on channel #2 in case another program is trying to access it and then retries the operation. The detached handler for the second WHEN ERROR block traps timeout errors and deadlock errors. If the desired information does not become available in the specified amount of time, or a deadlock condition occurs, the employee's badge number is printed out with an appropriate message, and the GET statement tries to retrieve the next record in the sequence. 15.8.10 Accessing Records by Record File Address A Record File Address (RFA) uniquely specifies a record in a file. Accessing records by RF A is therefore more efficient and faster than other forms of random record access. Because an RFA requires six bytes of storage, VAX BASIC has a special data type, RFA that denotes variables that contain RFA information. Variables of data type RFA can be used only with the 1/0 statements and functions that use RFA information, and in comparison and assignment statements. You cannot print these variables or use them in any arithmetic operation. However, you can compare RFA variables using the equal to ( =) and not equal to < > relational operators. You cannot create named constants of the RFA data type. However, you can assign values from one RFA variable to another, and you can use RFA variables as parameters. Accessing a record by RF A requires three steps: 1. Explicitly declare the variable or array of data type RFA to hold the address. File Input and Output 15-29 2. Assign the address to the variable or array element. You can do this either with the GETRFA function, or by reading a file of RFAs generated by previous GETRFA functions or by the VAX/VMS Sort Utility. 3. Specify the variable in the RFA clause of a GET or FIND statement. The GETRFA function returns the RFA of the last record accessed on a channel. Therefore, you must access a record in the file with a GET, FIND, or PUT statement before using the GETRFA function. Otherwise, GETRFA returns a zero, which is an invalid RFA. The following example declares an array of type RFA containing 100 elements. After each PUT operation, the RFA of the record is assigned to an element of the array. Once the RFA information is assigned to a program variable or array element, you can use the RFA clause on a GET or FIND statement to retrieve the record. Example DECLARE RFA R_array(1 TO 100) DECLARE LONG I MAP (XYZ) STRING A = 80 OPEN "TEST.DAT" FOR OUTPUT AS FILE #1, SEQUENTIAL, MAP XYZ FOR I = 11. TO 1001. k PUT #1 R_array(I) = GETRFA(1%) NEXT I You can use the RFA clause on GET statements for any file organization; the only restriction is that the file must reside on a disk that is accessible to the node that is executing the program. The following example continues the previous one. It randomly retrieves the records in a sequential file by using RFAs stored in the array. 15-30 File Input and Output Example DECLARE RFA R_array(1Y. TO 100%) DECLARE LONG I MAP (XYZ) STRING A = 80 OPEN "TEST.DAT" FOR OUTPUT AS FILE #1, SEQUENTIAL, MAP XYZ FOR I = 1% TO 100% & PUT #1 R_array(I) = GETRFA(1Y.) NEXT I WHILE -1Y. PRINT "Which record would you like to see"; INPUT "(type a carriage return to exit)";Rec_numY. EXIT PROGRAM IF Rec_numY. = OY. GET #1, RFA R_array(Rec_numY.) PRINT A NEXT 15.8.11 Transferring Data to Terminal-Format Files The PRINT# statement transfers program data to a terminal-format file. In the following example, the INPUT statements prompt the user for three values: S_name$, Area$, and Quantity%. Once these values are entered, the PRINT# statement writes these values to a terminal-format file that is open on channel #·4. Example FOR IY. = 1% TO 10% INPUT "Name of salesperson":S_name$ INPUT "Sales district";Area$ INPUT "Quantity sold";QuantityY. PRINT #4%, S_name$, Area$, Quantity% NEXT !Y. If you do not specify an output list in the PRINT# statement, a blank line is written to the terminal-format file. A PRINT statement without a channel number transfers program data to a terminal. See Chapter 7 for more. information. File Input and Output 15-31 15.8. 12 Resetting the File Position The RESTORE# statement resets the current record pointer to the beginning of the file; it does not change the file. RESET # is a synonym for RESTORE. For example: RESTORE #3Y., KEY #2Y. RESET #3Y. The RESTORE# statement restores the file in terms of the second alternate key. The RESET # statement restores the file in terms of the primary key. The RESTORE # statement can be used by all RMS file organizations. RESTORE without a channel number resets the data pointer for READ and DATA statements but does not affect any files. 15.8.13 Truncating Files The SCRATCH statement is valid only on sequential files. Although you cannot delete individual records from a sequential file, you can delete all records starting with the current record through to the end of the file. In order to do this, you must first specify ACCESS SCRATCH when you open the file. To truncate the file, locate the first record to be deleted. Once the current record pointer points to this record, execute the SCRATCH statement. The following program locates the thirty-third record and truncates the file beginning with that record. Example OPEN "MMM.DAT" AS FILE #2Y., IE SEQUENTIAL FIXED, ACCESS SCRATCH first_bad_record = 33Y. FIND #2Y., RECORD first_bad_record SCRATCH #2Y. CLOSE #2Y. END SCRATCH does not change the physical size of the file; it reduces the amount of information contained in the file. (You can use the DCL command SET FILE/TRUNCATE to truncate the excess file space.) Therefore, you can write records with the PUT statement immediately after a SCRATCH operation. 15-32 File Input and Output 15.6.14 Renaming Files If the security constraints permit, you can change the name or directory of a file with the NAME ... AS statement. For example: NAME "MONEY.DAT" AS "ACCOUNTS.DAT" This statement changes the name of the file MONEY.DAT to ACCOUNTS.DAT. NOTE The NAME ... AS statement can change only the name and directory of a file; it cannot be used to change the device name. You must always include an output file type because there is no default. If you use the NAME ... AS statement on an open file, the new name does not take effect until you close the file. 15.6.15 Closing Files and Ending 1/0 All programs should close files before the program terminates. However, VAX BASIC automatically closes files in the following situations: • • • At an END, END PROGRAM, or EXIT PROGRAM statement When it completes the last statement in the program if no END statement exists While executing a CHAIN statement VAX BASIC does not close files after executing a STOP, END SUB, END FUNCTION, or END PICTURE statement. The CLOSE statement closes files and disassociates these files and their buffers from the channel numbers. If the file is a magnetic tape device and the data is written to a tape, CLOSE writes trailer labels at the end of the file. The following is an example of the CLOSE statement: Example CLOSE #1% B% = 4% CLOSE #2%, B%, 7% CLOSE I% FOR I% = 1% TO 20% File Input and Output 15-33 15.6.16 Deleting Files If the security constraints permit, you can delete a file with the KILL statement. KILL "TEST.DAT" This statement deletes the file named TEST.DAT. Note that this statement deletes only the most current version of the file. Do not omit the file type, because there is no default. You can delete only one file at a time; to delete all versions of a file matching a file specification, use the Run-Time Library routine LIB$DELETEJILE. You can delete a file that is currently being accessed by other users; however, the file is not deleted until all users have closed it. You cannot open or access a file once you have deleted it. 15. 7 File-Related Functions VAX BASIC provides built-in functions for finding • • • The characteristics of the last file opened (FSP$) The number of bytes moved in the last 1/0 operation (RECOUNT) The file status (STATUS, VMSSTATUS, and RMSSTATUS) These functions are discussed in the following sections. 15.7.1 The FSPS Function If you do not know the organization of a file, you can find out by opening the file for input with the ORGANIZATION UNDEFINED and RECORDTYPE ANY clauses. Your program can then use the FSP$ function to determine the characteristics of that file. Your program must execute FSP$ immediately after the OPEN FOR INPUT statement. 15-34 File Input and Output Example RECORD FSP_data VARIANT CASE BYTE Rat BYTE Org WORD Max_record_size LONG File_size WORD Bucketsize_blocksize WORD Num_keys LONG Max_record_number CASE Ret_string = 16 END RECORD DECLARE FSP_data File_chars OPEN "FIL.DAT" FOR INPUT AS FILE #11., ORGANIZATION UNDEFINED, RECORDTYPE ANY, ACCESS READ File_chars::Ret_string = FSP$(11.) • • • • • • • Rat returns the low byte that is the RMS record attributes (RAT) field. Org returns the high byte that is the RMS organization (ORG) field. Max_record_size returns the RMS maximum record size (MRS) field. File_size returns the RMS allocation quantity (ALQ) field. Bucketsize_blocksize returns the RMS bucket size (BKS) field for disk files or the RMS block size (BLS) field for magnetic tape files. Num_keys returns the number of keys. Max_record_number returns the RMS maximum record number (MRN) field if the file is a relative file. Note that FSP$ returns zeros in bytes 9 through 12. For more information, see the VAX Record Management Services Reference Manual. File Input and Output 15-35 15.7.2 The RECOUNT Function Read operations can transfer varying amounts of data. The system variable RECOUNT contains the number of characters (bytes) read after each read operation. After a read operation from your terminal, RECOUNT contains the number of characters transferred, including the line terminator. After accessing a record, RECOUNT contains the number of characters in the record. RECOUNT is reset by every read operation on any channel, including the controlling terminal. Therefore, if you need to use the value of RECOUNT, copy it to another variable before executing another read operation. RECOUNT is undefined if an error occurs during a read operation. RECOUNT is often used as the argument to the COUNT clause in the UPDATE or PUT statement for variable-length files. The following sequence of statements ensures that the output record on channel #5 is the same length as the input record on channel #4. Example GET #4% bytes_readY. = RECOUNT PUT #5%, COUNT bytes_readY. 15.7.3 The STATUS, VMSSTATUS, and RMSSTATUS Functions The STATUS function accesses the status longword that contains characteristics of the last opened file. If an error occurs during an input operation, the value of STATUS is undefined. If an error does not occur, the six low-order bits of the returned value contain information about the type of device accessed by the last input operation. These bits correspond to the following devices: • • • • 15-36 If bit 0 is set, the device type is a record-oriented device. If bit 1 is set, the device type is a carriage control device. If bit 2 is set, the device type is a terminal. If bit 3 is set, the device type is a directory oriented device. File Input and Output • If bit 4 is set, the device type is a single directory device. • If bit 5 is set, the device type is a sequential block-oriented device (magnetic tape or TKSO). Both the VMSSTATUS and RMSSTATUS functions are used to determine which non-BASIC error caused a resulting VAX BASIC error. In particular, VMSSTATUS can be used for any non-BASIC errors, while RMSSTATUS is used specifically for RMS errors. For more information on these functions, see Chapter 17 and the VAX BASIC Reference Manual. 15.8 OPEN Statement Options This section explains the OPEN statement keywords that enable you to control how a file is created or opened. These keywords are as follows: BUCKETSIZE BUFFER CONNECT CONTIGUOUS DEFAULTNAME EXTENDSIZE FILE SIZE NOSPAN RECORDTYPE TEMPORARY USEROPEN WINDOW SIZE 15.8.1 The BUCKETSIZE Clause The BUCKETSIZE clause applies only to relative and indexed files. A bucket is a logical storage structure that RMS uses to build and maintain relative and indexed files on disk devices. A bucket consists of 1 or more disk blocks. The default bucket size is the recordsize rounded up to a block boundary. Although RMS defines the bucket size in terms of disk blocks, the BUCKETSIZE clause specifies the number of records a bucket contains. For example: OPEN 11 STOCK_DATA.DAT 11 FOR OUTPUT AS FILE #1%, ORGANIZATION RELATIVE FIXED, BUCKETSIZE 12% & File Input and Output 15-37 This example specifies a bucket containing approximately 12 records. RMS reads in entire buckets into the 1/0 buffer at once, and a GET statement transfers one record from the I/O buffer to your program's record buffer. When you open an existing relative or indexed file and specify a bucket size other than that originally assigned to the file, VAX BASIC signals "File attributes not matched" (ERR= 160). Records cannot span bucket boundaries. Therefore, when you specify a bucket size in your program, you must consider the size of the largest record in the file. Note that a bucket must contain at least one record. Buckets in both relative and indexed files contain information in addition to the records stored in the bucket. You should take this into consideration. There are two ways to establish the number of blocks in a bucket. The first is to use the VAX BASIC default. The second is to specify the approximate number of records you want in each bucket. VAX BASIC then calculates a bucket size based on that number. The default bucket size assigned to relative and indexed files is as small as possible. A small bucket size, however, is rarely desirable. VAX BASIC selects a default bucket size depending on • • • The record length The file organization (relative or indexed) The record format If you do not define the BUCKETSIZE clause in the OPEN statement, VAX BASIC does the following: • • • Assumes that there is a minimum of one record in the bucket Calculates a size Assigns the appropriate number of blocks Note that when you specify a bucket size for files in your program, you must keep in mind the space versus speed trade-offs. A large bucket size increases file processing speed because a greater amount of data is available in memory at one time. However, it also increases the memory space needed for buffer allocation and the processing time required to search the bucket. Conversely, a small bucket size minimizes buffer requirements, but increases the number of accesses to the storage device, thereby decreasing the speed of operations. 15-38 File Input and Output DIGITAL recommends that you use the DCL command EDIT /FOL to design files used in production applications where performance is a concern. 15.8.2 The BUFFER Clause The BUFFER keyword applies to disk files of any organization. In the case of sequential files, the BUFFER clause sets the number of blocks read in on each disk access. For relative and indexed files, the BUFFER clause determines the number of I/O buffers that are allocated. In general, the VAX/VMS operating system supplies adequate defaults for all file types; therefore the BUFFER clause is rarely necessary. You can specify up to 127 buffers as either a positive or a negative number: • • • < BUFFER < 127), RMS allocates enough space for the specified number of buckets. If (-128 < BUFFER < 0), VAX BASIC allocates the absolute value of the specified number of buffers. If (BUFFER = 0), VAX BASIC allocates the process default for the particular file organization and device-this value is usually adequate. If (0 15.8.3 The CONNECT Clause The CONNECT clause can be used only on indexed files. CONNECT lets you process different groups of records on different indexed keys or on the same key without incurring all of the RMS overhead of opening the same file more than once. For example, a program can read records in an indexed file sequentially by one key and randomly by another. Each stream is an independent, active series of record operations. Example MAP (Indmap) WORD Emp_num, STRING Emp_last_name = 20, SINGLE Salary, STRING Wage_code = 2 OPEN "IND.DAT" FOR INPUT AS FILE #1Y,, ORGANIZATION INDEXED, MAP Indmap, PRIMARY KEY Emp_num, ALTERNATE KEY Emp_last_name k k k k k k k File Input and Output 15-39 OPEN "IND.DAT" FOR INPUT AS FILE #2% ORGANIZATION INDEXED, MAP Ind.map, CONNECT 1 OPEN "IND.DAT" FOR INPUT AS FILE #3% ORGANIZATION INDEXED, MAP Ind.map, PRIMARY KEY Emp_num, ALTERNATE KEY Wage_code, CONNECT 1 The channel on which you open the file for the first time is called the parent. The CONNECT clause specifies another channel on which you access the same file; connected channels are called children. More than one OPEN statement can connect to the parent channel; however, you cannot connect to a channel that has already been connected to another channel. 15.8.4 The CONTIGUOUS Clause A contiguous file with physically adjoining blocks minimizes disk searching and decreases file access time. Once the system knows where a contiguous file starts on the disk, it does not need to use as many retrieval pointers to locate the pieces of that file. Rather, it can access data by calculating the distance from the beginning of the file to the desired data. If there is not enough contiguous disk space, VAX BASIC allocates as much contiguous space as possible. (For truly contiguous records, you must use the USEROPEN clause and set the CTG bit in the FAB FOP field-see the VAX Record Management Services Reference Manual. Opening a file with both the FILESIZE and CONTIGUOUS clauses preextends the file contiguously or in as few disk extents as possible. 15-40 File Input and Output 15.8.5 The DEFAULTNAME Clause The DEFAULTNAME clause in the OPEN statement lets you specify a default file specification for the file to be opened. It is valid with all file organizations. VAX BASIC uses the DEFAULTNAME clause for any part of the file specification that is not explicitly supplied. Example LINPUT "Next data file";Fil$ OPEN Fil$ FOR INPUT AS FILE #6%, ORGANIZATION SEQUENTIAL, DEFAULTNAME "USER$DEVICE:.DAT" & & The DEFAULTNAME clause supplies default values for the device, directory, and file type portions of the file specification. Typing ABC in response to the "Next data file?" prompt causes VAX BASIC to try to open USER$DEVICE:ABC.DAT. VAX BASIC uses the DEFAULTNAME values only if you do not supply those parts of the file specification appearing in the DEFAULTNAME clause. For example, if you type SYS$DEVICE:ABC in response to the prompt, VAX BASIC tries to open SYS$DEVICE:ABC.DAT. In this case, SYS$DEVICE: overrides the device default in the DEFAULTNAME clause. Any part of the file specification still missing is filled in from the current default device and directory of the process. 15.8.6 The EXTENDSIZE Clause The EXTENDSIZE attribute determines how many disk blocks RMS adds to the file when the current allocation is exhausted. The EXTENDSIZE clause only has an effect when creating a file. You specify EXTENDSIZE as a number of blocks. For example: OPEN "TSK.ORN" FOR OUTPUT AS FILE #2%, & ORGANIZATION RELATIVE, EXTENDSIZE 128% The EXTENDSIZE clause causes RMS to add 128 disk blocks whenever the current space allocation is exhausted and the file must be extended. The value you specify must conform to the following requirements: • It must be specified when you create the file • It cannot exceed 65 ,535 disk blocks File Input and Output 15-41 If you specify zero, the extension size equals the RMS default value. The EXTENDSIZE value can be overridden for single OPEN operations. 15.8. 7 The FILESIZE Clause With the FILESIZE attribute, you can allocate disk space for a file when you create it. The following statement allocates 50 blocks of disk space for the file "VALUES.DAT": OPEN "VALUES.DAT" FOR OUTPUT AS FILE #3Y., FILESIZE 50Y. Preextending a file has several advantages: • • • The system can create a complete directory structure for the file, instead of allocating and mapping additional disk blocks when needed. You reserve the needed disk space for your application. This ensures that you do not run out of space when the program is running. Preextension can make some of the file's disk blocks contiguous, especially when used with the CONTIGUOUS keyword. Note that preextension can be a disadvantage if it allocates disk space needed by other users. The FILESIZE clause is ignored when VAX BASIC opens an existing file. 15.8.8 The NOSPAN Clause By default, sequential files allow records to cross or span block boundaries. If records cross block boundaries, RMS packs records into the file endto-end throughout the file, leaving space for control information and padding. The NOSPAN clause overrides this default, forcing records to fit into individual blocks (with space provided for control information and padding). When block boundaries restrict records, fixed-length records must be less than 512 bytes, and variable-length records less than 510 bytes. This can waste extra bytes at the end of each block. However, when records span block boundaries, RMS writes records end-to-end without regard for block boundaries. For example, if you specify NOSPAN, only four 120-byte records fit into a disk block. If you do not specify NOSPAN, VAX BASIC begins writing the fifth record in the block, and continues writing that record in the next block. This minimizes wasted disk space and improves the file's capacity, at the minimal expense of increased processing overhead. 15-42 File Input and Output 15.8.9 The RECORDTYPE Clause The RECORDTYPE clause lets you specify record formats that are compatible with files created by other language processors. You can choose one of four qualifiers: LIST, FORTRAN, ANY, and NONE. The default for VAX BASIC is LIST, which specifies carriage return format. This is standard for ASCII text files and means that carriage control is performed by RMS when writing the file to a unit-record device. If your program accesses a file created with a FORTRAN language proces- sor, use the FORTRAN qualifier. In the following example, the FORTRAN qualifier sets the FORTRAN carriage control attribute in the RAT field in the FAB. For more information on the FAB control structure, see Section 15.8.11. The first byte of the record is assumed to be the carriage control information. OPEN "FIL.DAT" FOR INPUT AS FILE #1%, IE ORGANIZATION SEQUENTIAL, RECORDTYPE FORTRAN If your program accesses a file created by an unknown language processor or by DCL, use the ANY qualifier; this qualifier causes VAX BASIC to handle any record attribute type. If you create a file with the ANY qualifier, VAX BASIC uses the default of LIST. OPEN "FIL.DAT" FOR INPUT AS FILE #1%, ORGANIZATION INDEXED, RECORDTYPE ANY IE 15.8.10 The TEMPORARY Clause If you specify the TEMPORARY clause in the OPEN statement, VAX BASIC deletes that file in any one of the following cases: • • • When you close the file When the program aborts or exits When your process terminates No entry for this file is made in any directory. File Input and Output 15-43 15.8.11 The USEROPEN Clause The USEROPEN clause specifies an external long function that VAX BASIC executes when you open or create a file. (You do not need to declare the USEROPEN routine with an EXTERNAL FUNCTION statement.) This procedure can then specify additional OPEN parameters for the file. For example: OPEN "FILE.DAT" FOR INPUT AS FILE #2%, & ORGANIZATION INDEXED, USEROPEN Myopen, MAP ABC The code in Myopen determines how the file FILE.DAT is opened. The Run-Time Library sets up six RMS control structures before calling the USEROPEN procedure. Table 15-4 defines these structures and their meanings. Table 15-4: VAX RMS Control Structures Set for the USEROPEN Clause FAB File Access Block RAB Record Access Block NAM Name Block XAB FHC Extended Attributes Block ESA Expanded Name String RSA Resultant Name String A USEROPEN procedure should not alter the allocation of these structures, although it can modify the contents of many of the fields. You should not modify fields set by other OPEN statement keywords. For example, you should use the RECORDSIZE clause, not a USEROPEN routine, to set the record length. The allocation of the RMS control structures (except for the RAB) lasts only for the duration of the OPEN statement. Therefore, your USEROPEN can retain only the RAB address for use after the OPEN operation is complete. Note that any additional structures that you allocate and link into the RMS structures must be unlinked before exiting the USER OPEN. NOTE Future releases of the Run-Time Library may alter the use of some VAX RMS fields. Therefore, you may have to alter your USEROPEN procedures accordingly. 15-44 File Input and Output The following steps describe the execution of the USEROPEN routine: 1. VAX BASIC performs normal OPEN statement processing up to the point where it would call the RMS OPEN/CREATE and CONNECT routines. VAX BASIC then passes control to the USEROPEN routine. 2. VAX BASIC passes the address of the FAB as the first parameter, the address of the RAB as the second parameter, and the address of the user-specified channel number as the third parameter to the routine. 3. The USEROPEN routine can modify the contents of the RMS control structures, and it must call the RMS OPEN or RMS CREATE routine and the RMS CONNECT routine and return the status in RO. The following program creates a USEROPEN routine to obtain a RAB address. Example %TITLE Y.SBTTL Y.IDENT "Example USEROPEN" "Useropen Routine to obtain RAB address" "Version 1.0" FUNCTION LONG Get_rab_address ( Fabdef User_fab, Rabdef User_rab, LONG Channel ) !++ ! FUNCTIONAL DESCRIPTION: Save the address of the RMS Record Access Block allocated by the caller in a global symbol. Open the file and return the status from RMS. FORMAL PARAMETERS (Standard for all BASIC USEROPEN procedures) User_fab User_rab Channel RETURN VALUE: Address of RMS File Access Block Address of RMS Record Access Block Logical Unit assigned to file by caller. RMS Status value GLOBAL COMMON USAGE RAB_ptr Single longword PSECT used to pass RAB address to caller. OPTION INACTIVE = SETUP, CONSTANT TYPE = INTEGER, TYPE = EXPLICIT & & Y.NOLIST %INCLUDE 11 $FABDEF 11 %FROM %LIBRARY 11 SYS$LIBRARY:BASIC$STARLET 11 %INCLUDE 11 $RABDEF 11 %FROM %LIBRARY 11 SYS$LIBRARY:BASIC$STARLET 11 %INCLUDE 11 $RMSDEF 11 %FROM %LIBRARY 11 SYS$LIBRARY:BASIC$STARLET 11 %INCLUDE "STARLET" %FROM %LIBRARY 11 SYS$LIBRARY:BASIC$STARLET 11 %LIST File Input and Output 15-45 !+ ! Common area used to pass RAB address to caller. !- COMMON (RAB_ptr) DECLARE LONG !+ ! rab_address LONG Rms_status Save RAB address in global symbol known to caller. Perform standard RMS open sequence !- Rab_address = LOC(User_rab::rab$b_bid) Rms_status = Sys$open( User_fab ) IF Rms_status AND Rms$_normal THEN Rms_status = Sys$connect( User_rab ) END IF END FUNCTION Rms_status NOTE You cannot use a USEROPEN routine to fill the RBF, UBF, BKS, or CTX fields in the RAB. These fields are filled in after the USEROPEN routine returns; any values placed there by the USEROPEN routine are overwritten. Also, you must not set RMS Locate mode when using a USEROPEN routine on sequential files. 15.8.12 The WINDOWSIZE Clause The WINDOWSIZE clause specifies the number of block retrieval pointers in memory for the file. WINDOWSIZE is not a file attribute, and therefore can be changed any time you open a file. Retrieval pointers are associated with the file header and point to contiguous blocks on disk. By keeping retrieval pointers in memory, you can reduce the 1/0 associated with locating a record because the operating system does not have to access the file header for pointers as frequently. The number of retrieval pointers in memory at any one time is determined by the system default or by the value you supply in the WINDOWSIZE clause. The usual default number of retrieval pointers is 7. A value of zero specifies the default number of retrieval pointers. A value of 255 specifies mapping the entire file, if possible. Values between 128 and 254 inclusive are reserved. 15-46 File Input and Output Chapter 16 Formatting Output with the PRINT USING Statement The PRINT USING statement controls the appearance and location of data on a line of output. With it, you can create formatted lists, tables, reports, and forms. This chapter describes how to format data with the PRINT USING statement. 16.1 Introduction The ability to format data with the PRINT USING statement is useful because the way in which VAX BASIC displays data with the PRINT statement is often limited. For example, a program may use floating-point numbers to represent dollars and cents. The PRINT statement displays floating-point numbers with up to six digits of accuracy, and places the decimal point anywhere in that 6-digit field. In contrast, PRINT USING lets you display floating-point numbers in the following ways: • • • • Rounded to two decimal places Vertically aligned on the decimal point Preceded by a dollar sign With commas every third digit to the left of the decimal point Formatting monetary values in this way provides a much more readable report. Another use for formatted numeric values might be to print checks on a line printer. PRINT USING lets you print numbers with a dollar sign and an asterisk-filled field preceding the first digit. Formatting Output with the PRINT USING Statement 16-1 PRINT USING also formats string data. With it you can left- and rightjustify string expressions, or center a string expression over a specified column position. Further, the PRINT USING statement can contain string literals. These are strings that do not control the format of a print item, but instead are printed exactly as they appear in the format string. DIGITAL recommends that you declare all format expressions as string constants. When you do this the VAX BASIC compiler causes the RunTime Library to compile the string at compile time rather than at run time, thus improving the performance of your code. 16.2 Using Format Strings Format strings determine the way in which items are to be printed in the output file. Format strings can be any of the following: • • • • String variables String literals Named string constants A combination of the above The PRINT USING statement must contain one or more format strings. Each format string is made up of one format field. Each format field controls the output of one print item and can contain only certain characters, as described throughout the chapter. The PRINT USING statement must also contain a list of items you want printed. To format print items, you must separate them with commas or semicolons. Separators between print items do not affect output format as they do with the PRINT statement. However, if a comma or semicolon follows the last print item, VAX BASIC does not return the cursor or print head to the beginning of the next line after it prints the last item in the list. When VAX BASIC encounters an invalid character within the current format field, it automatically ends the format field. Therefore, you do not need to delimit format fields. The character that terminates the previous field can be either a new format field or a string literal. In the following example, the first three characters in the format string (###)make up a valid numeric format field. The fourth character (A) is invalid in a numeric format field; therefore, VAX BASIC ends the first format field after the third character. VAX BASIC continues to scan the format string, searching for a character that begins a format field. The 16-2 Formatting Output with the PRINT USING Statement first such character is the number sign at character position 7. Therefore, the characters at positions 4, 5, and 6 are treated as a string literal. The characters at positions 7, 8, and 9 make up a second valid numeric format field. Example PRINT USING "###ABC###", 123, 346 Output 123ABC346 When the statement executes, VAX BASIC prints the first number in the list using the first format field, then prints the string literal ABC, and finally prints the second number in the list using the second format field. If you were to supply a third number in the list, VAX BASIC would reuse the first format string. This is called reversion. Example PRINT USING "###ABC###", 123, 346, 664 Output 123ABC346 664ABC Because any character not part of a format field is printed just as it appears in the format field, you can use a space or multiple spaces to separate format fields in the format string as shown in the following example. Example DECLARE STRING CONSTANT format_string = "###.## DECLARE SINGLE A,B A = 2.666 B = 100.360 PRINT USING format_string, A, B, A, B ###.##" Output 2.67 2.67 100.35 100.36 Formatting Output with the PRINT USING Statement 16-3 When the VAX BASIC compiler encounters the PRINT USING statement, VAX BASIC prints the value of A (rounded according to PRINT USING rules), three spaces, then the value of B. VAX BASIC prints the three spaces because they are treated as a string literal in the format string. Notice that when VAX BASIC reuses a format string, it begins on a new line. 16.3 Printing Numbers With the PRINT USING statement, you can specify: • • • • • • • The number of digits to print, thus rounding the number to a given place The decimal point location, thus vertically aligning numbers at the decimal point Special symbols, including trailing minus signs, asterisk-filled number fields, floating currency symbols, embedded commas, and E notation Debits and credits Leading zeros or leading spaces Blank-if-zero fields A special character that is to be printed as a literal Unlike the PRINT statement, PRINT USING does not automatically print a space before and after a number. Unless you reserve enough digit positions to contain the integer portion of the number (and a minus sign, if necessary), VAX BASIC prints a percent sign (%)to signal this condition and displays the number in PRINT format. 18.3.1 Specifying the Number of Digits You reserve places for digits by including a number sign ( #) for each digit position. If you print negative numbers, you must also reserve a place for the minus sign. 16-4 Formatting Output with the PRINT USING Statement Example PRINT USING "###",123 PRINT USING "#####",12345 PRINT USING "####",-678 END Three places reserved Five places reserved Four places reserved Output 123 12345 -678 If there are not enough digits to fill the field, VAX BASIC prints spaces before the first digit. Example format_string$ = 11 ##### 11 PRINT USING format_string$, PRINT USING format_string$, PRINT USING format_string$, PRINT USING format_string$, END 1 10 -1709 12345 Output 1 10 -1709 12345 If you have not reserved enough digits to print the fractional part of a number, VAX BASIC rounds the number to fit the field. Example PRINT USING "### 11 ,126.7 PRINT USING "#",5.9 PRINT USING "#",5.4 END Output 127 6 5 If you have not reserved enough places to print a number's integer portion, VAX BASIC prints a percent sign as a warning followed by the number in PRINT statement format. After VAX BASIC prints the number, it completes the rest of the list in PRINT USING format. Formatting Output with the PRINT USING Statement 16-5 In the following example, PRINT USING displays the first number. Because there are not enough places to the left of the decimal point to display a 3-digit number, VAX BASIC prints the second number in PRINT statement format, with a space before and after, but includes a percent sign warning. Example PRINT USING 11 ### 11 , 266 PRINT USING 11 ## 11 , 266 END Output 266 1. 256 16.3.2 Specifying Decimal Point Location The decimal point's position in the format string determines the number of reserved places on either side of it. If the print item's fractional part does not use all of the reserved places to the right of the decimal point, VAX BASIC fills the remaining spaces with zeros. Example DECLARE STRING CONSTANT FM = "##.###" PRINT USING FM, 16.72 PRINT USING FM, 39.3758 PRINT USING FM, 26 Output 16.720 39.376 26.000 If there are more fractional digits than reserved places to the right of the decimal point, VAX BASIC rounds the number to fit the reserved places. Note that there must be enough places reserved to the left of the decimal point for the integer portion of the number. Otherwise, VAX BASIC prints the number in PRINT format preceded by a percent sign. The following example shows how PRINT USING rounds numbers when you specify decimal point location. 16-6 Formatting Output with the PRINT USING Statement Example PRINT USING"##.##", 25.789 PRINT USING "##.###", 100.2 PRINT USING "#.##",.999 END Output 26.79 Y. 100.2 1.00 VAX BASIC fills all reserved spaces to the left of the decimal point with specified digits, spaces, or the minus sign. Example PRINT USING"##.##", 6.26 PRINT USING 11 ##.## 11 , -6.26 PRINT USING "###.##,-6.26 END Output 6.26 -6.26 -6.26 16.3.3 Printing Numbers with Special Symbols Special symbols let you print numbers with trailing minus signs, asteriskfill fields, floating currency symbols, commas, or E notation. You can also specify debits, credits, leading zeros, leading blanks, and blank-if-zero fields. Table 16-1 summarizes these special characters. Formatting Output with the PRINT USING Statement 16-7 Table 16-1: Character 16-8 Format Characters for Numeric Fields Effect on Format Number sign ( #) Reserves a place for one digit. Decimal point (period) ( . ) Determines decimal point location and reserves a place for the radix point. Comma(,) Prints a comma before every third digit to the left of the decimal point and reserves a place for one digit or digit separator. Two asterisks ( ** ) Print leading asterisks before the first digit and reserve places for two digits. Two dollar signs ( $$) Print a currency symbol before the first digit. They also reserve places for the currency symbol and one digit. By default, the currency symbol is a dollar sign. To change the currency symbol, see Section 16.3.3.3. Four carets ( Print a number in E (exponential) format and reserve four places for E notation. AAAA ) Minus sign ( - ) Prints a trailing minus sign for negative numbers. Printing a negative number in an asterisk-fill or a currency field requires that the field also have a trailing minus sign or credit/debit character. Zero in angle brackets ( < 0 > ) Prints leading zeros instead of leading spaces. Formatting Output with the PRINT USING Statement Table 16-1 (Cont.): 16.3.3. 1 Format Characters for Numeric Fields Character Effect on Format Percent sign in angle brackets ( < % > ) Prints all spaces in the field if the value of the print item, when rounded to fit the numeric field, is zero. CD in angle brackets ( <CD> ) Prints credit and debit characters immediately following the number. VAX BASIC prints CR for negative numbers and zero, and DR for positive numbers. Underscore (-) Specifies that the next character is a literal, not a formatting character. Commas You can place a comma anywhere in a number field to the left of the decimal point or to the right of the field's first character. A comma cannot start a format field. VAX BASIC prints a comma to the left of every third digit from the decimal point. If there are fewer than four digits to the left of the decimal point, VAX BASIC omits the comma. Example PRINT USING "##,###",10000 PRINT USING "##,###",759 PRINT USING "$$#,###.##",25694.3 PRINT USING "**#,###",7259 PRINT USING "####,#.##",25239 END Output 10,000 759 $25,694.30 ••7,259 25,239.00 Formatting Output with the PRINT USING Statement 16-9 16.3.3.2 Asterisk-Fill Fields To print asterisks (•)before the first digit of a number, you must start the field with two asterisks. Example DECLARE STRING CONSTANT FM = "**##.##" PRINT USING FM, 1.2 PRINT USING FM, 27.96 PRINT USING FM, 107 PRINT USING FM, 1007.6 END Output ***1.20 ••27.96 •107.00 1007.60 Note that the asterisks reserve two places as well as cause asterisk fill. To specify a negative number in an asterisk-fill field, you must place a trailing minus sign in the field. The trailing minus sign must be the last character in the format string. Example DECLARE STRING CONSTANT FM = "**##.##-" PRINT USING FM, 27.96 PRINT USING FM, -107 PRINT USING FM, -1007.6 END Output ••27.96 *107.001007.60- If you try to print a negative number in an asterisk-fill field that does not include a trailing minus sign, VAX BASIC signals "PRINT USING format error" (ERR= 116). You cannot specify both asterisk-fill and zero-fill for the same numeric field. 16-10 Formatting Output with the PRINT USING Statement 16.3.3.3 Currency Symbols To print a currency symbol before the first digit of a number, you must start the field with two dollar signs. If the data contains both positive and negative numbers, you must include a trailing minus sign. Example DECLARE STRING CONSTANT FM = "$$##.##-" PRINT USING FM, 77.44 PRINT USING FM, 304.66 PRINT USING FM, 2211.42 PRINT USING FM, -126.6 PRINT USING FM, 127.82 END Output $77.44 $304.66 Y. 2211.42 $126.60$127 .82 Note that the dollar signs reserve places for the currency symbol and only one digit; the dollar sign is always printed. (Hence the warning indicator ( % ) when the third PRINT USING statement executes.) Contrast this with the asterisk-fill field, where VAX BASIC prints asterisks only when there are leading spaces. By default, the currency symbol is a dollar sign. On VAX/VMS systems, you can change the currency symbol, radix point, and digit separator by assigning the characters you want to the logical names SYS$CURRENCY, SYS$RADIX_pQINT, and SYS$ DIGIT_SEP, respectively. If you try to print a negative number in a dollar sign field that does not include either a trailing minus sign or the CR/DR formatting character, VAX BASIC signals "PRINT USING Format error" (ERR= 116). Formatting Output with the PRINT USING Statement 16-11 16.3.3.4 Negative Fields To allow for a field containing negative values, you must place a trailing minus sign in the format field. A negative format field causes the value to be printed with a trailing minus sign. You can also denote negative fields with CR and DR. See Section 16.3.3.8 for more information. You must use a trailing minus or the CR/DR formatting character to indicate a negative number in an asterisk-fill or floating dollar sign field. For fields with trailing minus signs, VAX BASIC prints a minus sign after negative numbers as shown in Example 1, and a space after positive numbers as shown in Example 2: Example 1 !Standard field PRINT USING "###.##",-10.64 PRINT USING 11 ###.## 11 ,10.64 END Output 1 -10.64 10.64 Example 2 !Fields with Trailing Minus Signs PRINT USING "##.##-",-10.64 PRINT USING "##.##-",10.64 END Output 2 10.6410.64 16.3.3.5 E (Exponential) Format To print a number in E format, you must place four carets ( """'") at the end of the field. The carets reserve space for: • • • 16-12 The capital letter E A plus or minus sign (which indicates a positive or negative exponent) An exponent (the exponent is 2 digits for single and double, 3 digits for G _floating and 4 digits for H_floating) Formatting Output with the PRINT USING Statement In exponential format, VAX BASIC does not pad the digits to the left of the decimal point. Instead, the most significant digit shifts to the leftmost place of the format field, and the exponent compensates for this adjustment. Example PRINT USING "###.#t····n,5 PRINT USING "###.tt•···n,1000 PRINT USING ".tt····n,5 END Output 600.00E-02 100.00E+01 .60E+01 If you use fewer than four carets, the number does not print in E format; the carets print as literal characters. If you use more than four carets, VAX BASIC prints the number in E format and includes the extra carets as a string literal. Example PRINT USING "###.#1···n,5 PRINT USING "###.##····· 11 ,6 END Output 5.oo··· 600.00E-02· You must reserve a place for a minus sign to the left of the decimal point to display negative numbers in exponential format. If you do not, VAX BASIC prints a percent sign (%)as a warning. You cannot use exponential format with asterisk-fill, floating dollar sign, or trailing minus formats. Formatting Output with the PRINT USING Statement 16-1 J 16.3.3.6 Leading Zeros To print leading zeros in a numeric field, you must start the format field with a zero enclosed in angle brackets ( <O> ). These characters also reserve one place for a digit. Example DECLARE STRING CONSTANT FM = "<0>####.## 11 PRINT USING FM, 1.23, 12.34, 123.46, 1234.66, 12346.67 Output 00001.23 00012.34 00123.46 01234.66 12346.67 When you specify zero-fill, you cannot specify asterisk-fill or floatingdollar sign format for the same field. 16.3.3. 7 Blank-If-Zero Fields To make VAX BASIC print a blank field for values which round to zero, you must start the numeric field with a percent sign (%)enclosed in angle brackets ( <%> ). In the following example, PRINT USING displays spaces in each reserved position for the second and third items in the list. The value of the second item is zero, while the value of the third item becomes zero when rounded to fit the numeric field. Example DECLARE STRING CONSTANT FM = 11 <Y.>####.## 11 PRINT USING FM, 1000, 0, .001, -6000 Output 1000.00 -6000 16-14 Formatting Output with the PRINT USING Statement 16.3.3.8 Debits and Credits You can have VAX BASIC use credit and debit notation to differentiate positive and negative numbers. To do this, you place the characters <CD> (Credit/Debit) at the end of the numeric format string. This causes VAX BASIC to print CR (Credit Record) after negative numbers, and DR (Debit Record) after positive numbers and zero. Example DECLARE STRING CONSTANT FM = "$$####.##<cd>" PRINT USING FM, -552.35, 200, -5 Output $552.35CR $200.00DR $5.00CR You cannot use a trailing minus sign and Credit/Debit formatting in the same numeric field. Using the Credit/Debit formatting character causes the value to be printed with a leading space. 16.4 Printing Strings With the PRINT USING statement, you can specify the following aspects of string format: • • • • • The number of characters Left-justified format Right-justified format Centered format Extended field format Table 16-2 summarizes the format characters and their effects. July 1988 Formatting Output with the PRINT USING Statement 16-15 Table 16-2: Format Characters for String Fields Character Effect on Format Single quotation mark ( ') Starts the string field and reserves a place for one character. L (upper- or lowercase) Left-justifies the string and reserves a place for one character. R (upper- or lowercase) Right-justifies the string and reserves a place for one character. C (upper- or lowercase) Centers the string in the field and reserves a place for one character. E (upper- or lowercase) Left-justifies the string; expands the field, as necessary, to print the entire string; and reserves a place for one character. Two backslashes ( \ \) Reserves n+2 character positions, where n is the number of spaces between the two backslashes. PRINT USING left-justifies the string in this field. This formatting character is included for compatibility with BASIC-PLUS. DIGITAL recommends that you do not use this type of field for new program development. Exclamation point ( ! ) Creates a one-character field. The exclamation point both starts and ends the field. This formatting character is included for compatibility with BASIC-PLUS. DIGITAL recommends that you do not use this type of field for new program development. Instead, use a single quotation mark to create a one-character field. You must start string format fields with a single quotation mark (') that reserves a space in the print field, followed by: • • • • 16-16 A contiguous series of upper- or lowercase Ls for left-justified output A contiguous series of upper- or lowercase Rs for right-justified output A contiguous series of upper- or lowercase Cs for centered output A contiguous series of upper- or lowercase Es for extended field output Formatting Output with the PRINT USING Statement VAX BASIC ignores the overflow of strings larger than the string format field except for extended fields. For extended fields, VAX BASIC extends the field to print the entire string. If a string to be printed is shorter than the format field, VAX BASIC pads the string field with spaces. For more information on extended fields, see Section 16.4.4. A string field containing only a single quotation mark is a one-character string field. VAX BASIC prints the first character of the string expression corresponding to a one-character string field and ignores all following characters. Example PRINT USING "'","ABCDE" END Output A See Section 16.4.4 for an example of many different types of fields used together. 18.4. 1 Left-Justified Format VAX BASIC prints strings in a left-justified field starting with the left-most character. VAX BASIC pads shorter strings with spaces and truncates longer strings on the right to fit the field. A left-justified field contains a single quotation mark followed by a series of Ls. Example PRINT USING "' LLLLLL", "ABCDE" PRINT USING "'LLLL","ABC" PRINT USING "'LLLLL","12346678" END Output ABCDE ABC 123466 Formatting Output with the PRINT USING Statement 16-17 18.4.2 Right-Justified Format VAX BASIC prints strings in a right-justified field starting with the rightmost character. VAX BASIC pads the left side of shorter strings with spaces. If a string is longer than the field, VAX BASIC left-justifies and truncates the right side of the string. A right-justified field contains a single quotation mark (') followed by a series of Rs. Example DECLARE STRING CONSTANT right_justify = "'RRRRR" PRINT USING right_justify,"ABCD" PRINT USING right_justify,"A" PRINT USING right_justify,"STUVWXYZ" END Output ABCD A STUVWX 18.4.3 Centered Fields VAX BASIC prints strings in a centered field by aligning the center of the string with the center of the field. If VAX BASIC cannot exactly center the string-as is the case for a 2-character string in a 5-character field, for example-VAX BASIC prints the string one character off center to the left. A centered field contains a single quotation mark followed by a series of Cs. 16-18 Formatting Output with the PRINT USING Statement Example DECLARE STRING CONSTANT center= "'CCCC" PRINT USING center, "A" PRINT USING center, "AB" PRINT USING center, "ABC" PRINT USING center, "ABCD" PRINT USING center, "ABCDE" END Output A AB ABC ABCD ABCDE If there are more characters than places in the field, VAX BASIC leftjustifies and truncates the string on the right. 16.4.4 Extended Fields An extended field contains a single quotation mark followed by one or more Es. The extended field is the only field that automatically prints the entire string. In addition: • • If the string is smaller than the format field, VAX BASIC left-justifies the string as in a left-justified field. If the string is longer than the format field, VAX BASIC extends the field and prints the entire string. Example PRINT USING "'E", "THE QUICK BROWN" PRINT USING "'EEEEEEE', "FOX" END Output THE QUICK BROWN FOX The following example uses left-justified, right-justified, centered, and extended fields. Formatting Output with the PRINT USING Statement 16-19 Example PRINT USING "'LLLLLLLLL", 11 THIS TEXT" PRINT USING "'LLLLLLLLLLLLLL","SHOULD PRINT" PRINT USING " 1 LLLLLLLLLLLLLL 11 , 1 AT LEFT MARGIN' PRINT USING "'RRRR","1,2,3,4" PRINT USING "'RRRR", 1 1,2,3 1 PRINT USING "'RRRR',"1,2" PRINT USING "'RRRR"."1" PRINT USING " 1 CCCCCCCCC 11 ,"A" PRINT USING " 1 CCCCCCCCC","ABC 11 PRINT USING "'CCCCCCCCC","ABCDE" PRINT USING " 1 CCCCCCCCC", 11 ABCDEFG 11 PRINT USING " 1 CCCCCCCCC", 11 ABCDEFGHI" PRINT USING " 1 LLLLLLLLLLLLLLLLL 1 , 11 YOU ONLY SEE PART OF THIS 11 PRINT USING "'E","YOU CAN SEE ALL OF THE LINE WHEN IT IS EXTENDED" END Output THIS TEXT SHOULD PRINT AT LEFT MARGIN 1,2,3 1,2,3 1,2 1 A ABC ABCDE AB CDEFG ABCDEFGHI YOU ONLY SEE PART YOU CAN SEE ALL OF THE LINE WHEN IT IS EXTENDED 16.5 PRINT USING Statement Error Conditions There are two types of PRINT USING error conditions: fatal and warning. VAX BASIC signals a fatal error if • • • • • 16-20 The format string is not a valid string expression There are no valid fields in the format string You specify a string for a numeric field You specify a number for a string field You separate the items to be printed with characters other than commas or semicolons Formatting Output with the PRINT USING Statement • • A format field contains an invalid combination of characters You print a negative number in a floating dollar sign or asterisk-fill field without a trailing minus sign VAX BASIC issues a warning if a number does not fit in the field. If a number is larger than the field allows, VAX BASIC prints a percent sign (%)followed by the number in the standard PRINT format and continues execution. If a string is larger than any field other than an extended field, VAX BASIC truncates the string and does not print the excess characters. If a field contains an invalid combination of characters, VAX BASIC does not recognize the first invalid character or any character to its right as part of the field. These characters may form another valid field or be considered text. If the invalid characters form a new valid field, a fatal error condition may arise if the item to be printed does not match the field. The following examples demonstrate invalid character combinations in numeric fields. Example 1 PRINT USING "$$••##.##",6.41,16.30 The dollar signs form a complete field and the rest forms a second valid field. The first number (5.41) is formatted by the first valid field ($$). It prints as "$5". The second number (16.30) is formatted by the second field (**##.##} and prints as "**16.30". Output 1 $6**16.30 Example 2 PRINT USING "##.r-- 11 ,6.43E09 Because the field has only three carets instead of four, VAX BASIC prints a percent sign and the number, followed by three carets. Output 2 Y. .643E+10--- Formatting Output with the PRINT USING Statement 16-21 Example 3 PRINT USING " 1 LLEEE 11 ,"VWXYZ 11 You cannot combine two letters in one field. VAX BASIC interprets EEE as a string literal. Output 3 VWXEEE. 16-22 Formatting Output with the PRINT USING Statement Chapter 17 Handling Run-Time Errors The process of detecting and correcting errors that occur when your program is running is called error handling. This chapter describes default error handling and how to handle VAX BASIC run-time errors with your own error handlers. Throughout this chapter, the term error is used to imply any VAX/VMS exception, not only an exception of ERROR severity. 17.1 Default Error Handling VAX BASIC provides default run-time error handling for all programs. If you do not provide your own error handlers, the default error handling procedures remain in effect throughout program execution time. When an error occurs in your program, VAX BASIC diagnoses the error and displays a message telling you the nature and severity of the error. There are four severity levels of VAX BASIC errors: SEVERE, ERROR, WARNING, and INFORMATIONAL. The severity of an error determines whether or not the program aborts if the error occurs when default error handling is in effect. When default error handling is in effect, ERROR and SEVERE errors always terminate program execution, but program execution continues when WARNING and INFORMATIONAL errors occur. To override the default error handling procedures, you can provide your own error handlers, as described in the following sections. (Note that you should not call LIB$ESTABLISH from a VAX BASIC program as this RTL routine overrides the default error handling procedures and may adversely affect program behavior.) Handling Run-Time Errors 17-1 Only one error can be handled at a time. If an error has occurred but has not yet been handled completely, that error is said to be pending. When an error is pending and a second error occurs, program execution always terminates immediately. Therefore, one of the most important functions of an error handler is to clear the error so that subsequent errors can also be handled. If you do not supply your own error handler, program control passes to the VAX BASIC error handler when an error occurs. For instance, when VAX BASIC default error handling is in effect, a program will abort when division by zero is attempted because division by zero is an error of SEVERE severity. With an error handler, you can include an alternative set of instructions for the program to follow; if the zero was input at a terminal, a user-written error handler could display a "Try again" message and reexecute the program lines requesting input. 17.2 User-Supplied Error Handlers It is good programming practice to anticipate certain errors and provide your own error handlers for them. User-written error handlers allow you to handle errors for a specified block of program statements as well as complete program units. Any program module can contain one or more error handlers. These error handlers test the error condition and include statements to be executed if an error occurs. To provide your own error handlers, you use WHEN ERROR constructs. A WHEN ERROR construct consists of two blocks of code: a protected region and a handler. A protected region is a block of code that is monitored by the compiler for the occurrence of an error. A handler is the block of code that receives program control when an error occurs during the execution of the statements in the protected region. There are two forms of WHEN ERROR constructs; in both cases the protected region begins immediately after a WHEN ERROR statement. The following partial programs illustrate each form. In Example l, the handler is attached to the protected region, while in Example 2, the handler catch-1tandler is detached and must be provided elsewhere in the program unit. 17-2 Handling Run-Time Errors Example 1 WHEN ERROR IN protected_statement_1 protected_statement_2 USE handler_statement_1 handler_statement_2 END WHEN Example 2 WHEN ERROR USE catch_handler protected_statement_1 protected_statement_2 END WHEN HANDLER catch_handler handler_statement_1 handler_statement_2 END HANDLER The following sections further explain the concepts of protected regions and handlers. 17.2.1 Protected Regions A protected region is a block of code that is monitored by the compiler for the occurrence of an error. The bounds of this region are determined by the actual ordering of the source code. Statements that are lexically between a WHEN ERROR statement and a USE or END WHEN statement are in the protected region. If an error occurs inside the protected region, control passes to the error handler associated with the WHEN ERROR statement. When an error occurs beyond the limits of a protected region, default error handling is in effect unless other error handlers are provided. For more details about handler priorities, see Sections 17.2.3 and 17.3. Handling Run-Time Errors 17-3 The WHEN ERROR statement signals the start of a block of protected statements. The WHEN ERROR statement also specifies the handler to be used for any errors that occur inside the protected region. The keyword USE either explicitly names the associated handler for the protected region, or marks the start of the actual handler statements. The statements in the actual error handler receive control only if an error occurs in the protected region. The following example prompts the user for two integer values and displays their sum. The WHEN ERROR block traps any invalid input values, displays a message telling the user that the input was invalid, and reprompts the user for input. Example DECLARE INTEGER value_1, value_2 WHEN ERROR IN INPUT "PLEASE INPUT 2 INTEGERS"; value_1, value_2 !protected statement USE PRINT "INVALID INPUT - PLEASE TRY AGAIN" !handler statement RETRY !handler statement END WHEN PRINT "THEIR SUM IS"; value_1 + value_2 Protected regions can be nested; a protected region can be within the bounds of another protected region. However, WHEN ERROR statements cannot appear inside an error handler, and protected regions cannot cross over into other block structures. If you are using a WHEN ERROR block with a detached handler, that handler cannot exist within a protected region. 17.2.2 Handlers A handler is the block of code containing instructions to be executed only when an error occurs during the execution of statements in the protected region. When an error occurs during the execution of a protected region, VAX BASIC branches to the handler you have supplied. In tum, the handler processes the error. An error handler typically performs the following functions: • • • Determines which error occurred Takes appropriate action based on the nature of the error Clears the error condition with a RETRY, CONTINUE, END WHEN, or END HANDLER statement 17-4 Handling Run-Time Errors • • • Continues program execution when possible Possibly identifies which program unit or statement caused the error Resignals errors with EXIT HANDLER (when an error cannot be handled for some reason) Handlers can be attached to, or detached from, the statements in the WHEN ERROR protected region. An attached handler is delimited by a USE and an END WHEN statement. The attached handler immediately follows the protected region of a WHEN ERROR IN block. The following example illustrates an attached handler that traps errors on I/O statements, division by zero and illegal numbers. Example PROGRAM accident_prone DECLARE REAL age, accidents, rating WHEN ERROR IN Get_age: INPUT "Enter your age";age INPUT "How many serious accidents have you had";accidents rating = accidents/age PRINT "That's ";rating;" serious accidents per year!" USE SELECT ERR !Trap division by zero CASE = 61 PRINT "Please enter an age greater than 0" CONTINUE Get_age !Trap illegal number CASE = 52 PRINT "Please enter a positive number" RETRY CASE ELSE !Revert to default error handling EXIT HANDLER END SELECT END WHEN END PROGRAM A detached handler is defined separately in your program unit. It requires an identifier and must be delimited by a HANDLER and an END HANDLER statement. Handler names must be valid VAX BASIC identifiers and cannot be the same as the identifier for any label, PROGRAM name, DEF or DEF• function, SUB, FUNCTION, or PICTURE subprogram. Handling Run-Time Errors 17-5 The main advantage of using a detached handler is that it can be referenced by more than one WHEN ERROR USE statement. The following example illustrates a simple detached handler: Example WHEN ERROR USE catcher KILL "INPUT.DAT" END WHEN HANDLER catcher !Catch if file does not exist IF ERR = 5 THEN CONTINUE END IF END HANDLER The statements within a handler are never executed if an error does not occur or if no protected region exists for the statement that caused the exception. When your program generates an error, control transfers to the specified handler. If the code in an error handler generates a second error, control returns to the VAX BASIC error handler and program execution ends, usually with the first error only partly processed. To avoid the possibility of your error handler causing a second error, you should keep handlers as simple as possible and keep operations that might cause errors outside the handler. Your handler can include conditional expressions to test the error and branch accordingly, as shown in the following example: Example PROGRAM Check_records WHEN ERROR USE Global_handler END WHEN HANDLER Global_handler SELECT ERR !Trap buffer overflow CASE = 161 PRINT "Record too long" CONTINUE 17-6 Handling Run-Time Errors !Trap end of file on device CASE = 11 PRINT "End of file" CONTINUE Over CASE ELSE EXIT HANDLER END SELECT END HANDLER Over: CLOSE #11, END PROGRAM Note that ON ERROR statements are not allowed within protected regions or handlers. For compatibility issues related to ON ERROR statements, see Section 17.3. 17.2.3 Exiting from Handlers After processing an error, a handler typically clears the error so that program execution can continue. VAX BASIC provides statements that clear the error condition and exit from the handler: • • • • RETRY CONTINUE END HANDLER END WHEN These statements differ from each other in that they revert control of program execution to different points in the program. Examples of these statements are included in the following sections. An additional statement, EXIT HANDLER, is provided to allow you to exit from a handler with the error still pending. The END HANDLER statement identifies the end of the block of statements in the handler. The END WHEN statement marks the end of the protected region when a detached handler is used; it marks the end of the handler when an attached handler is used. If the handler does not process an error with an EXIT HANDLER, RETRY, or CONTINUE statement, the error is cleared by the END HANDLER or END WHEN statement; however, processing continues with the statement immediately after the protected region (and the attached handler, if one exists) where the error occurred. These statements do not return control to the protected region. This is known as "falling out the bottom of a handler". Be careful not to fall out of the bottom of a handler unintentionally. Handling Run-Time Errors 17-7 Note that you cannot exit from a handler with the following statements: • • • • • • EXIT PROGRAM EXIT FUNCTION EXIT SUB EXIT DEF GOSUB (with a target outside the handler) GOTO (with a target outside the handler) Also, you cannot exit from a handler with a RESUME statement. The RESUME statement is valid only in blocks of code referred to by ON ERROR statements. Section 17.3 describes the ON ERROR statements. 17 .2.3. 1 The RETRY Statement You use the RETRY statement to clear the error and reexecute the statement that caused the error. Be sure to take corrective action before trying the protected statement again. Example DECLARE REAL radius WHEN ERROR USE fix_it INPUT "Please supply the radius of the circle"; radius END WHEN HANDLER fix_it !trap overflow error IF ERR = 48 PRINT "Please supply a smaller radius" RETRY END HANDLER PRINT "The circumference of the circle is "; 2•PI•radius In FOR. .. NEXT loops, if the error occurs while VAX BASIC is evaluating the limit or increment values, RETRY reexecutes the FOR statement; if the error occurs while VAX BASIC is evaluating the index variable, RETRY reexecutes the NEXT statement. In UNTIL.NEXT and WHILE ... NEXT loops, if the error occurs while VAX BASIC is evaluating the relational expression, RETRY reexecutes the NEXT statement. 17-8 Handling Run-Time Errors 17.2.3.2 The CONTINUE Statement You can use the CONTINUE statement to clear the error and cause execution to continue at the statement immediately following the propagated error. When the CONTINUE statement is within an attached handler, you can specify a target. The target can be a line number or label within the bounds of the associated protected region, in a surrounding protected region, or within an unprotected region. However, you must specify a target within the current program module. You cannot specify a target for the CONTINUE statement when it is in a detached handler. Example DIM LONG her_attributes(10),his_attributes(10) DECLARE INTEGER counter WHEN ERROR USE fix_it DATA 12,2,36,21,26.6,32,32,30,16,4 FOR counter = 0 TO 12 READ her_attributes(counter) NEXT counter MAT his_attributes = her_attributes END WHEN HANDLER fix_it !Trap out of data IF ERR = 67 THEN RESTORE CONTINUE ELSE EXIT HANDLER END IF END HANDLER When a DEF function is invoked from a protected region and an error occurs that has not been handled, a CONTINUE statement with no target causes execution to resume at the statement following the one that invoked the function. Note that if an error occurs in a loop control statement or SELECT or CASE statement, the CONTINUE statement causes VAX BASIC to resume execution at the statement following the end of the loop structure (the NEXT, END CASE, or END SELECT statements). NOTE When you use the RETRY or the CONTINUE statement without a target, the compiler builds read only tables in the generated Handling Run-Time Errors 17-9 object file with information about statements in the associated protected regions. Therefore, when space is extremely critical, do not protect large regions with handlers containing RETRY or CONTINUE without a specified target. 17 .2.3.3 The EXIT HANDLER Statement Unlike RETRY and CONTINUE, the EXIT HANDLER statement does not clear the error; rather, it allows you to exit from the handler with the error pending. This allows you to pass an error to the handler associated with the next outer protected region, or back to VAX BASIC default error handling, or to the calling procedure. When an error occurs within a nested protected region, control passes to the handler associated with the innermost protected region in which the error occurred. If the innermost handler does not handle the error, the error is passed to the next outer handler with the EXIT HANDLER statement. All handlers for any outer WHEN ERROR blocks are processed before reverting to default error handling or resignaling the calling procedure. The following example shows two nested protected regions. Neither handler traps division by zero. If division by zero occurs, the handler associated with the innermost protected region, inner_handler, does not clear the error; therefore, the error is passed to the handler associated with the next outer protected region. Outer_handler does not clear this error either, and so the error is passed to the default error handler. As this error is fatal, the program aborts. Example PROGRAM nesting OPTION TYPE = EXPLICIT DECLARE LONG divisor DECLARE REAL dividend, quotient WHEN ERROR USE outer_handler INPUT "Enter divisor";Divisor INPUT "Enter dividend";Dividend WHEN ERROR USE inner_handler Quotient = Dividend/Divisor PRINT "The quotient is ";Quotient END WHEN END WHEN 17-10 Handling Run-Time Errors HANDLER outer_handler !Trap data format error IF ERR = 50 THEN PRINT "Illegal input ... try again" RETRY ELSE PRINT "In outer_handler" PRINT "Reverting to default handling now" EXIT HANDLER END IF END HANDLER HANDLER inner_handler !Trap overflow/decimal error IF ERR = 181 THEN CONTINUE ELSE PRINT "Inside inner_handler" PRINT "Reverting to outer handler now" EXIT HANDLER END IF END HANDLER END PROGRAM Output Enter divisor? 0 Enter dividend? 53 Inside inner_handler Reverting to outer handler now Inside outer_handler Reverting to default handling now Y.BAS-F-DIVBY_ZER, Division by 0 -BAS-USEPC_PSL, at user PC=001C18B3, PSL=03COOOA4 -SYSTEM-F-FLTDIV_F, arithmetic fault, floating divide by zero at PC=001C18B3, PSL=03COOOA4 -BAS-I-FROLINMOD, in module ERROR_7 For more information about exiting program units while an error is pending, see Section 17.2.6. Handling Run-Time Errors 17-11 17.2.4 Selecting the Severity of Errors to Handle The OPTION HANDLE statement lets you specify the severity level of errors that are to be handled by an error handler in addition to the BASIC errors that can normally be handled or trapped. You can specify any one of the following error severity levels: BASIC, SEVERE, ERROR, WARNING, or INFORMATIONAL. OPTION HANDLE = BASIC is the default, which is in effect if you do not specify an alternative in the OPTION HANDLE statement. Only trappable VAX BASIC errors transfer control to the current error handler when this option is in effect. Refer to Appendix B to determine which BASIC errors are not trappable. When you specify an error severity level other than BASIC in the OPTION HANDLE statement, the following errors will transfer control to the error handler: • • • All trappable BASIC errors of this or lesser severity All non-BASIC errors of this or lesser severity BASIC errors of this or lesser severity that are not normally trappable For example, if you specify OPTION HANDLE = ERROR, you can handle all BASIC and non-BASIC errors of ERROR severity (both trappable and non-trappable), and all WARNING and INFORMATIONAL errors, but no SEVERE errors. 17.2.5 Identifying Errors VAX BASIC provides several built-in functions that return information about an error. You can use these functions inside your error handlers to determine details about the error and conditionally handle these errors. These functions include • • • • • • 17-12 ERR ERL ERN$ ERT$ VMSSTATUS RMSSTATUS Handling Run-Time Errors Note that if an error occurs in your program that is not a VAX BASIC error or does not map onto a VAX BASIC error, it is signaled as NOTBASIC ("Not a BASIC error") (ERR = 194). In this case, you can use the built-in function VMSSTATUS to determine what caused the error. VMSSTATUS is discussed in Section 17.2.5.5. 17 .2.5. 1 Determining the Error Number (ERR) You use the ERR function to return the number of the last error that occurred. Appendix B in this manual lists the number of each VAX BASIC run-time error. For instance, ERR 153 is "RECALREXI, Record already exists". The following example shows a handler that traps this error: Example OPTION HANDLE = ERROR WHEN ERROR USE find_error END WHEN HANDLER find_error SELECT ERR !Record already exists CASE = 163 PRINT "Choose new record" CONTINUE CASE ELSE EXIT HANDLER END SELECT END HANDLER The results of ERR remain undefined until an error occurs. Although ERR remains defined as the number of the last error after control leaves the error handler, it is poor programming practice to refer to this variable outside the scope of an error handler. Handling Run-Time Errors 17-13 17 .2.5.2 Determining the Error Line Number (ERL) After your program generates an error, the ERL function returns the BASIC line number of the signaled error. This function is valid only in line-numbered programs. The ERL function, like ERR, lets you set up branching to one of several paths in the code. The following handler continues execution at different points in the program, depending on the value of ERL. Example 10 DECLARE INTEGER CONSTANT TRUE = -1 20 WHEN ERROR USE err_handler 900 END WHEN 1000 HANDLER err_handler SELECT TRUE CASE (ERR = 11) AND (ERL = 790) !Is error end of file at line 790? PRINT "Completed" CONTINUE CASE (ERR = 149) AND (ERL = 80) !Is error not at end of file on line 80? PRINT "CHECK ACCESS MODE" CONTINUE CASE ELSE !Let VAX BASIC handle any other errors EXIT HANDLER 1500 END SELECT 2000 END HANDLER 32000 CLOSE #5 32767 END The results of ERL are undefined until an error occurs, or if the error occurs in a subprogram not written in VAX BASIC. Although ERL remains defined as the line number of the last error even after control leaves the error handler, it is poor programming practice to refer to this variable outside the scope of an error handler. If you reference ERL in a compilation unit with line numbers, code and data are included in your program to allow VAX BASIC to determine ERL when an exception occurs. If you do not need to reference ERL, you can save program size and reduce execution time by compiling your program with the /NOLINE qualifier. Note that if your program references ERL and you compile the program with the /NOLINE switch, VAX BASIC signals the message "ERL overrides /NOLINE" and the 17-14 Handling Run-Time Errors program is compiled with the /LINE qualifier. Even if you do not use any line numbers, you can reduce execution time by compiling with the /NOLINE qualifier. If an error occurs in a subprogram containing line numbers, VAX BASIC sets the ERL variable to the subprogram line number where the error was detected. If the subprogram also executes an EXIT HANDLER statement, control passes back to the outer procedure's handler. The error is assumed to occur on the statement where the call or invocation occurs. 17 .2.5.3 Determining Where the Error Occurred (ERN$) You use the ERN$ function to return the name of the program unit in which the error was detected. ERN$ returns the name of a main program, SUB, FUNCTION, or PICTURE subprogram, or DEF function. If the PROGRAM statement is used with a user-supplied identifier, the ERN$ value is the specified identifier for the main program. The results of ERN$ are undefined until the program generates an error. In the following example, control passes to the main program for error handling if the error occurs in the module SUBARC. Example HANDLER locat_ern IF ERN$ = "SUBARC" THEN PRINT "ERROR IS ";ERR PRINT "RETURNING TO MAIN PROGRAM FOR ERROR HANDLING" EXIT HANDLER ELSE PRINT "PROGRAM MODULE GENERATING ERROR IS ";ERN$ END IF END HANDLER Note that ERN$ is invalid when an error occurs in a subprogram compiled with the /NOSETUP qualifier. 17 .2.5.4 Determining the Error Message Text (ERT$) You use the ERT$ function to access the message text associated with a specified error number. Use of the ERT$ function is not limited to the scope of the error handler; you can access ERT$ at any time. The following detached handler tests whether the error occurred in a DEF module named TSLFE, and if so, prints the text of the signaled error and resumes execution. Handling Run-Time Errors 17-15 Example HANDLER catch_it IF ERN$ = "TSLFE" THEN PRINT ERT$(ERR) CONTINUE ELSE EXIT HANDLER END IF END HANDLER 17 .2.5.5 Determining VAX/VMS Error Information VAX BASIC provides a built-in function, VMSSTATUS, that returns the originally signaled error before it is translated to a BASIC error. For instance, for the BASIC error "End of file on device" (ERR= 11), the VMSSTATUS function returns "RMS$--EOF" (RMS end of file). This function is useful when the error is NOTBASIC (ERR= 194). When there is no error pending, VMSSTATUS is undefined. The value returned by this function is the actual signaled error value. If non-BASIC errors are being handled, the VMSSTATUS function may be the only way to find out which error caused the exception. The following example shows a program that performs file I/O. The first WHEN ERROR block traps any errors that occur while the program is opening the file or requesting user input. The detached handler for this block checks the value of VMSSTATUS to determine the exception that occurred. The inner error handler handles two special errors, BAS$K_ RECNOTFOU and BAS$K-RECBUCLOC, separately. If the error signaled does not correspond to one of these, the inner error handler passes control to the outer handler with the EXIT HANDLER statement. The outer handler sets the program status to VMSSTATUS. When the program exits; the operating system displays any status that is of warning severity or greater. Example PROGRAM Tester OPTION HANDLE = ERROR EXTERNAL LONG CONSTANT BAS$K_RECNOTFOU, BAS$K_RECBUCLOC DECLARE LONG Final_status MAP (Rec_buffer) & STRING Rec_key = 6, & STRING Rest_of_record = 20 Final_status = 1 17-16 Handling Run-Time Errors WHEN ERROR USE Global_handler OPEN "My_database" FOR INPUT AS FILE #1 , INDEXED FIXED ,ACCESS READ ,MAP Rec_buffer ,PRIMARY Rec_key t t t t Get_key: INPUT "Record to retrieve"; Rec_key WHEN ERROR IN GET #1%, KEY #0 EQ Rec_key PRINT Rest_of_record USE SELECT ERR CASE = BAS$K_RECNOTFOU PRINT "Record not found" CONTINUE Get_key CASE = BAS$K_RECBUCLOC SLEEP 2% RETRY CASE ELSE EXIT HANDLER END SELECT END WHEN END WHEN HANDLER Global_handler Final_status = VMSSTATUS END HANDLER END PROGRAM Final_status 17.2.5.6 Determining RMS Error Information The RMSSTATUS function lets you determine which RMS error caused a resulting VAX BASIC error. You must specify an open channel as the first parameter to RMSSTATUS. If this channel is not open, the error "1/0 channel not open" (ERR= 9) is signaled. The second parameter to the function lets you specify either STATUS or VALUE; this parameter is optional. If you do not specify the second parameter, RMSSTATUS returns the STATUS value by default. STATUS represents the RMS "STS" field and VALUE corresponds to the RMS "STV" field. The following example shows an error handler that prints both the status and the value of any RMS error. Handling Run-Time Errors 17-17 Example WHEN ERROR IN OPEN "file.txt" FOR OUTPUT AS FILE 1Y. PRINT #11., TIME$(0Y.) USE !Error 12 is fatal system I/0 failure IF ERR = 12 THEN PRINT "An unexpected RMS error has occurred:" PRINT "Status= "; RMSSTATUS(11.) PRINT "Value = "; RMSSTATUS(1Y., VALUE) EXIT HANDLER END IF END WHEN CLOSE #1Y. GOTO done done: END If you want to find an RMS status without knowing which particular channel to check, you can use VMSSTATUS to get the STATUS value (STS) if an error has occurred. 17.2.6 CTRL/C Trapping Error handling procedures are commonly used to trap user CTRL/C responses. With CTRL/C trapping enabled, control is transferred to an error handler if a user presses CTRL/C during program execution. You enable CTRL/C trapping in your program by invoking the built-in CTRLC function. For example: YY. = CTRLC After you invoke the CTRLC function, a CTRL/C entered at the terminal transfers control to the error handler. Once the CTRL/C is trapped, you can include routines to interact with the program, as shown in the following example. 17-18 Handling Run-Time Errors Example WHEN ERROR IN YY. = CTRLC OPEN 1 FIL_DAT 1 FOR INPUT AS FILE 111. INPUT "HOW MANY RECORDS"; Rec_read1. FOR IY. = 11. TO Rec_readY. GET 111. PRINT Name$, Address$, Emp_codeY. PRINT NEXT I1. USE !Trap ·c IF (ERR = 281.) THEN PRINT "CURRENT RECORD IS 11 ; I1. ELSE EXIT HANDLER END IF CONTINUE Clean_up END WHEN Clean_up: CLOSE #11. PRINT "END OF PROCESSING" END Output SMITH, DEXTER 231 COLUMBUS ST 09341 TRAVIS, JOHN PO BOX 80 64119 ·c THE CURRENT RECORD IS 3 END PROCESSING Note that the error condition is still pending until the error handler executes the CONTINUE statement. Therefore, if you press CTRL/C a second time while the error handler is executing, control returns to the VAX BASIC error handler, which terminates the program. To disable CTRL/C trapping, use the RCTRLC function. The RCTRLC function disables only CTRL/C trapping, not the CTRL/C interrupts themselves. Alternatively, to prevent both CTRL/C and CTRL/Y from interrupting a program, use the DCL command SET NO CONTROL, or the RTL routine LIB$DISESTABLISH. See the VAX BASIC Reference Manual for more details about the CTRLC and RCTRLC functions. Handling Run-Time Errms 17-19 17.2. 7 Handling Errors in Multiple-Unit Programs You can use WHEN ERROR constructs anywhere in your main program or program modules. Procedure and function invocations, such as invocations of DEF and DEF• functions and SUB, FUNCTION, and PICTURE subroutines, as well as non-BASIC programs, are valid within protected regions. GOTO and GOSUB statements are valid within handlers provided that the target is within the handler, an outer handler, or an unprotected region. Note, however, that a detached handler cannot appear within DEF or DEF• functions without the associated protected region. When an error occurs within nested handlers, VAX BASIC maintains the same priorities for handler use; control always passes to the handler associated with the innermost protected region in which the error occurred. When an exception occurs, all handlers for any outer WHEN ERROR blocks are processed before the program reverts to default error handling. Outer handlers are invoked when an inner handler executes an EXIT HANDLER statement. When there are no more outer handlers, and the outermost handler executes an EXIT HANDLER statement, program control reverts to the handler associated with the calling routine. Example SUB LIST(A$) WHEN ERROR USE sub_handler OPEN A$ FOR INPUT AS FILE #12% Get_data: LINPUT #12%, B$ PRINT B$ GOTO Get_data END WHEN HANDLER sub_handler !Trap end of file IF ERR <> 11% THEN EXIT HANDLER END IF END HANDLER CLose_up: CLOSE #12% END SUB You can call a subprogram while an error is pending; however, if you do, the subprogram cannot re-signal an error back to the calling program. If the subprogram tries to re-signal an error, VAX BASIC signals "Improper error handling" and program execution terminates. 17-20 Handling Run-Time Errors The following rules apply to error handling in function definitions: • • DEF and DEF• function definitions cannot appear within a protected region. However, protected regions can be contained within the function definitions. To trap errors while a DEF function is active, include protected regions inside the DEF function. If you do this, the associated handler remains in effect until your program leaves the protected region, or the DEF function. Example WHEN ERROR IN Invoke_def: AY. = FNIN_PUTY.( 11 PROMPT 11 ) USE PRINT "ERROR"; ERT$(ERRY.); IF ERN$ = "FNIN_PUT" THEN PRINT "IN FUNCTION" CONTINUE ELSE PRINT "IN MAIN" CONTINUE Invoke_def END IF END WHEN Main_code: DEF FNIN_PUTY.(P$) WHEN ERROR IN PRINT P$ INPUT LINE_IN$ FNIN_PUTY. = INTEGER(LINE_IN$) USE IF ERR = 50 THEN RETRY ELSE EXIT HANDLER END IF END WHEN END DEF Handling Run-Time Errors 17-21 NOTE A pending error is passed to VAX BASIC default error handling procedures under the following conditions: • If you use a GOSUB statement and the invoked procedure • is not lexically contained within any protected region If you invoke a DEF• function and the DEF• function is not lexically contained within any protected region Under these circumstances, a pending error is passed to the VAX BASIC default error handling even when the invoking statement is contained within a protected region. A handler associated with the invoking statement will not be used. 17.2.8 Forcing Errors The CAUSE ERROR statement allows a program to artificially generate an error when the program would not otherwise do so. You can force any VAX BASIC run-time error. You must specify the number of the error the compiler should force; the error numbers are listed in Appendix B of this manual. The following statement forces an end-of-file error (ERR= 11) to occur. CAUSE ERROR 111. You can use this feature to debug an error handler during program development, as shown in the following example: Example WHEN ERROR IN CAUSE ERROR 111. 17-22 Handling Run-Time Errors USE SELECT ERR CASE = 11% PRINT "Trapped an end of file on device" CONTINUE CASE ELSE EXIT HANDLER END WHEN 17.3 Using the ON ERROR Statements VAX BASIC supports ON ERROR statements as an alternative to WHEN blocks primarily for compatibility with existing programs. WHEN ERROR blocks are similar to declarative statements in that they do not depend on run-time flow of control. The ON ERROR statements, however, affect error handling only if the statements execute at run time. For example, if a GOTO statement precedes an ON ERROR statement, the ON ERROR statement will not have any effect because it does not execute. WHEN ERROR blocks let you handle errors that occur in a specific range of statements. ON ERROR statements let you specify a general error handler that is in effect until you specify another ON ERROR statement or until you pass control to the VAX BASIC error handler. NOTE For all current program development, DIGITAL recommends that you use WHEN ERROR constructs for user-written error handlers. Mixing WHEN ERROR constructs and ON ERROR statements within the same program is not recommended. The ON ERROR statements are supported for compatibility with other versions of DIGITAL BASICs. It is important to note that all of these statements are illegal within a protected region, or an attached or detached handler. The ON ERROR statements are fully documented in the VAX BASIC Reference Manual. This section merely illustrates the main features of the ON ERROR statements. The ON ERROR statements can be used to transfer control to a labeled block of error handling code. If you have executed an ON ERROR statement and an error occurs, the ON ERROR statement immediately transfers control to the label or line number that starts the error handling code. Otherwise, the ON ERROR statement specifies the branch to be taken in the event of an error. Handling Run-Time Errors 17-23 There are three forms of the ON ERROR statement: • ON ERROR GOTO 0 • The ON ERROR GOTO 0 statement reverts control to VAX BASIC default error handling in one of two ways: If an error is pending, execution of the ON ERROR GOTO 0 statement returns control to the VAX BASIC error handler immediately. If no error is pending, an ON ERROR GOTO 0 statement disables your current error handler. The VAX BASIC error handler handles all subsequent errors until another ON ERROR statement is executed, unless an error occurs in a WHEN ERROR protected region. ON ERROR GO TO target • The ON ERROR GOTO target statement reverts control to the target when subsequent errors occur that are not handled by WHEN block handlers. ON ERROR GO BACK The ON ERROR GO BACK statement transfers control to the calling program's error handler if an error occurs in the subprogram or DEF function. If you use ON ERROR GO BACK in a PROGRAM unit (outside of a DEF function) and no other outer protected region exists, it is equivalent to ON ERROR GOTO 0 and VAX BASIC default error handling is in effect. With ON ERROR GO BACK, if an error occurs in the execution of a function or subprogram, the error is passed to either the error handler of the surrounding program module (in the case of a DEF function definition) or the error handler of the calling program (in the case of a separately compiled subprogram). An error handler in the DEF function does not permanently override an error handler in the main program. VAX BASIC saves the error handler in the main program when you transfer into a DEF, and restores it when you return. Traditionally, the ON ERROR GOTO statement is placed before any other executable statements. The following example clears end-of-file errors and passes all other errors back to the VAX BASIC default error handling procedures. 17-24 Handling Run-Time Errors Example 5 ON ERROR GOTO Error_handler Error_handler: !Trap end of file on device IF ERR = 11 THEN RESUME 1000 ELSE ON ERROR GO BACK END IF The ON ERROR GOTO statement remains in effect after your program successfully handles an error. When the system signals another error, control once again transfers to the specified error handler. Every ON ERROR error handler must end with one of the following statements: • • • RESUME [target] ON ERROR GOTO 0 ON ERROR GO BACK If none of these statements is present, the VAX BASIC error handler aborts your program with the fatal error "Error trap needs RESUME" as soon as an END, END SUB, END DEF, END FUNCTION, END PROGRAM, or END PICTURE statement is encountered. The RESUME statement, like the RETRY and CONTINUE statements, clears the error condition. You can resume execution at any line number or label that is in the same module as the RESUME statement, unless that line or target is inside a DEF function, a WHEN ERROR protected region, or a handler. In general, RESUME without a target transfers control to the beginning of the program block where the error occurred. • • If you resume execution at a multi-statement line, execution begins at the first statement after the line number or label-not necessarily at the statement that generated the error. If an entire loop block is associated with a single line number or label and an error occurs within the loop, RESUME with no target transfers control to the statement immediately after the FOR, WHILE, or UNTIL statement, not to the line number or label. For more details on the RESUME statement, see the VAX BASIC Reference Manual. Handling Run-Time Errors 17-25 DIGITAL does not recommend using both ON ERROR statements and WHEN ERROR constructs in the same program. However, when this is the case, the order of handler priorities is as follows: 1. Control passes to the handler associated with the innermost WHEN ERROR block. 2. If protected regions are nested, the pending error is handled by the handler associated with the next outer WHEN ERROR block. 3. When no outer protected regions can handle the error, and if an ON ERROR statement is in effect, control transfers to the target of the next outer ON ERROR statement (if one is present). 4. If no outer handler is available or can handle the error, the error is passed to VAX BASIC default error handling. Default error handling is equivalent to ON ERROR GOTO 0. For information on specific run-time errors, refer to Appendix Bin this manual. 17-26 HandJing Run-Time Errors Chapter 18 Compiler Directives Compiler directives are instructions that tell VAX BASIC to perform certain operations as it translates a source program. This chapter describes how to control program compilation using compiler directives. 18.1 Introduction With compiler directives, you can do the following: • • • • • • • • • • Place program titles and subtitles in the header that appears on each page of the listing file Place a program version identification string in both the listing file and the object module Start or stop the inclusion of listing information for selected parts of a program Start or stop the inclusion of cross-reference information for selected parts of a program Include VAX BASIC code from another source file or a text library Include CDD record definitions in a VAX BASIC program Record dependency relationships in the CDD Display a message at compile time Conditionally compile parts of a program Terminate compilation When using compiler directives follow these rules: • Directives must begin with a percent sign. July 1988 Compiler Directives 18-1 • • • • Directives can be preceded by an optional line number. Directives must be the only text on the line (except for %IF-%THEN%ELSE-%END %IF). Directives cannot appear within a quoted string. Directives cannot follow an END, END SUB, or END FUNCTION statement. 18.2 Controlling the Compilation Listing Listing directives let you control the content and appearance of the compilation listing. There are eight compiler listing directives: • • • • • • • • %TITLE places a title string on the first line of the listing header. %SBTTL places a subtitle string on the second line of the listing header. %IDENT places an identification string on the second line of the listing header and within the object module. %PAGE causes VAX BASIC to skip to top-of-form in the output listing. %NOLIST causes VAX BASIC to stop accumulating information for the output listing. %LIST causes VAX BASIC to resume accumulating information for the output listing. %NOCROSS causes VAX BASIC to stop accumulating cross-reference information for the output listing. %CROSS causes VAX BASIC to resume accumulating cross-reference information for the output listing. These directives are described in the following sections. The listing control directives have no effect if no source program listing is being produced. Similarly, the %CROSS and %NOCROSS directives have no effect if no cross-reference listing is being produced. However, the %IDENT directive places the specified text in the object module whether or not a listing is produced. For more information on how these directives affect your source code, see Chapter 4. 18-2 Compiler Directives 18.2.1 The %TITLE and %SBTTL Directives The %TITLE directive lets you specify a line of text that appears on the first line of every page in the compilation listing. This text line is a quoted string of up to 45 characters and normally contains the source program title and other information. If the %TITLE directive is the first source text in a module, then the quoted string appears in the first line of every page of the compilation listing. ·Otherwise, the quoted string appears in the first line of every subsequent page in the compilation listing. That is, if VAX BASIC encounters a %TITLE directive after it has begun creating a page in the output listing, the title information will not appear on that page. Rather, it appears on all of the following pages until it encounters another %TITLE directive. The quoted string appears in character positions 33 to 81 in the first line of the listing header. %TITLE must appear on its own line. For example: Y.TITLE "File OPEN Subprogram -- Author Hugh Ristics" SUB FILSUB (STRING F_NAME) The %SBTTL directive lets you specify a line of text that appears on the second line of every page in the compilation listing (beneath the title). If VAX BASIC encounters a %SBTTL directive after it has begun creating a page in the output listing, the subtitle information will not appear on that page. Rather, it appears on all following pages until it encounters another %SBTTL or %TITLE directive. If you want the subtitle to appear on the first page, the %SBTTL directive must appear directly after the %TITLE directive. Any number of %SBTTL directives can appear in a source file; thus, you can use subtitle text to identify parts of the source program. As in %TITLE, the text you use in %SBTTL must be a quoted string not exceeding 45 characters. The quoted string appears in the second line of the listing header, in character positions 33 to 81. Note, however, that subtitle information only appears on listing pages that contain the actual source code. The following example shows the use of both %TITLE and %SBTTL directives. The first line of the listing's first page contains "Payroll Program" and the second line contains "Constant Declarations." When VAX BASIC encounters the %SBTTL directive, the second line on each subsequent page becomes "Subroutines". When VAX BASIC encounters the %SBTTL directive, the second line on each subsequent page becomes "Error Handler". Compiler Directives 18-3 Example Y.TITLE "Payroll Program" Y.SBTTL "Constant Declarations" Y.SBTTL "Subroutines" Y.SBTTL "Error Handler" You can use multiple %TITLE directives in a single source file; however, whenever VAX BASIC encounters a %TITLE directive, the %SBTTL information is set to the null string. Therefore, if you want to display subtitle information, each new %TITLE directive should be accompanied by a new %SBTTL directive. 18.2.2 The %1DENT Directive The %IDENT directive identifies the version of a program module. The identification text must be a quoted string of up to 31 characters. The information contained within the identification text appears in the listing file and the object module. Thus, the map file created by the VAX/VMS Linker also contains this information. The identification text appears in the first 31 character positions of the second line on each subsequent listing page. For instance, in the following example, the %IDENT information appears as the first entry on the second line of the listing. The information is also included in the object module if the compilation produces one. If the linker generates a map listing, this information also appears there. Example Y.IDENT "V6.3" SUB PAY If your source module contains multiple %IDENT directives, VAX BASIC signals a warning and uses the version specified in the first %IDENT directive. 18-4 Compiler Directives 18.2.3 The %PAGE Directive The %PAGE directive causes VAX BASIC to begin a new page in the listing file. In the following example, the %PAGE directives cause VAX BASIC to skip to a new page in the listing file just before each new subtitle. Note that, in order to have title and subtitle information appear in the heading of each page, you cannot place a line number between the %PAGE, %TITLE, and %SBTTL directives. Example %TITLE "Payroll Program" Y.SBTTL "Constant Declarations" %PAGE Y.SBTTL "Subroutines" %PAGE Y.SBTTL "Error Handler" 18.2.4 The %LIST and %NOLIST Directives %LIST and %NOLIST are complementary directives. The %LIST directive causes VAX BASIC to resume adding information to the listing file, while the %NOLIST directive causes VAX BASIC to stop adding information to the listing file. Therefore, you can control which parts of the source program are to be listed. In the following example, as soon as VAX BASIC encounters the %LIST directive, it resumes adding new information to the listing file. Compiler Directives 18-5 Example Y.TITLE "Payroll Program" Y.SBTTL "Constant Declarations" Y.NOLIST Y.LIST Y.PAGE Y.SBTTL "Subroutines" Y.PAGE Y.SBTTL "Error Handler" If you have not requested the creation of a compilation listing, the %LIST and %NOLIST directives have no effect. If a program line contains a syntax error, VAX BASIC overrides the %NOLIST directive for that line and produces the normal error diagnostics in the listing file. 18.2.5 The %CROSS and %NOCROSS Directives The %CROSS and %NOCROSS directives are complementary. The %CROSS directive causes VAX BASIC to resume adding cross-reference information, while the %NOCROSS directive causes VAX BASIC to stop adding cross-reference information to the listing file. Therefore, you can specify that only certain parts of the source program are to be cross-referenced. In the following example, as soon as VAX BASIC encounters the %CROSS directive, it resumes adding new cross-reference information to the listing file. 18-6 Compiler Directives Example %TITLE "Payroll Program" Y.SBTTL "Constant Declarations" Y.NOCROSS %CROSS %PAGE Y.SBTTL "Subroutines" %PAGE Y.SBTTL "Error Handler" If you have not requested the creation of a cross-reference listing, the %CROSS and %NOCROSS directives have no effect. 18.3 Accessing External Source Files The %INCLUDE directive lets you access VAX BASIC source text from a file into the source program. The %INCLUDE directive also lets you access record definitions in the VAX Common Data Dictionary (COD) as well as access source text from a text library. The line on which a %INCLUDE directive resides can be continued, but cannot contain any other directives or statements. If you are including a source text file, you must supply a file specification. If you do not provide a file type, VAX BASIC uses the default type BAS. For example: %INCLUDE "KEN.BAS" If you are including a COD definition, you must supply a valid VAX COD path specification to extract a RECORD definition from the COD. For example: %INCLUDE %FROM Y.CDD 11 CDD$TOP.EMPLOYEE 11 Compiler Directives 18-7 See Chapter 23, the VAX BASIC Reference Manual and the VAX Common Data Dictionary Utilities Reference Manual for more information. If you are including source text from a text library, you must supply the name of the text module you wish to include as well as the name of the library where the module resides. If you do not specify a library name, VAX BASIC uses the default library, BASIC$LIBRARY. Moreover, if you do not specify a directory name or file type, VAX BASIC uses the default device and the file type TLB. In the following example, when VAX BASIC encounters the %INCLUDE directive, the compiler searches through the library SYS$LIBRARY:BASIC_ LIB.TLB for the specified module DMB_TEST and compiles the text as if it were placed in the position of the %INCLUDE directive. Y.!NCLUDE "DMB_TEST" %FROM %LIBRARY 11 SYS$LIBRARY:BASIC_LIB.TLB" VAX BASIC supplies the text library BASIC$STARLET located in SYS$LIBRARY. This text library contains condition codes and other symbols defined in the system object and shareable image libraries. Using the definitions from BASIC$STARLET allows you to reference condition codes and other system-defined symbols as local, rather than global symbols. To create your own text libraries using the VAX/VMS Librarian Utility, see the VAX/VMS Librarian Reference Manual. All file specifications, CDD path specifications, text modules and library specifications must be string literals enclosed in quotes. The source files accessed with %INCLUDE cannot contain line numbers. This requirement means that all statements in the accessed file are associated with the VAX BASIC line containing the %INCLUDE directive if line numbers are being used. Therefore, if you are using line numbers, a %INCLUDE directive cannot appear before the first line number in a source program. A file accessed by %INCLUDE can itself contain a %INCLUDE directive. When a program is compiled, VAX BASIC inserts the included text at the point at which it encounters the %INCLUDE directive. The compilation listing identifies any text obtained from an included file by placing a mnemonic in the first character position of the line in which the text appears. "In" specifies text that was either accessed from a source file or from a text library, and "Cn" specifies a record definition that was accessed from the CDD. Both the I and the C tell you that the text was accessed with the %INCLUDE directive, and n tells you the nesting level of the included text. 18-8 Compiler Directives The %INCLUDE directive is useful when you want to share code among multiple program modules. To do this, you must first create a file that contains the shareable code, then include that file in all the modules that require it. Thus, you reduce the chance of a typographical error. You can prevent the %INCLUDE file code from appearing in the compilation listing by using the BASIC command qualifier /SHOW=NOINCLUDE or /SHOW=NOCDD_DEFINITIONS. For text files and text library modules, use the qualifier /SHOW=NOINCLUDE. For COD definitions, use the qualifier /SHOW=NOCDD_DEFINITIONS. 18.4 Controlling Compilation VAX BASIC lets you control the compilation of a program by creating and testing lexical constants. You create and assign values to lexical constants with the %LET directive. These constants are always LONG integers. You control the compilation by using the %IF-%THEN-%ELSE-%END %IF directive to test these lexical constants. Thus, you can conditionally: • • • • • Supply different values for program variables and constants Skip over part of a program Abort a compilation Include VAX BASIC source code from another file Display informational messages during the compilation VAX BASIC also supplies the lexical built-in function % VARIANT that can be used to conditionally control compilation. %IF-% THEN-%ELSE-%END %IF uses lexical expressions to determine whether to execute directives in the %THEN clause or the %ELSE clause. The following sections describe the use of: • • • • • Lexical constants and expressions (%LET Directive) %VARIANT %ABORT %PRINT %IF-% THEN-%ELSE-%END %IF Compiler Directives 18-9 18.4.1 The %LET Directive The %LET directive creates and assigns values to lexical constants. Lexical constants are always LONG integers. These constants control the execution of the %IF-% THEN-%ELSE-%END %IF directive. All lexical constants must be created with %LET before they can be used in a %IF-% THEN-%ELSE-%END %IF, and each lexical constant must be created with a separate %LET directive. All lexical constant names must also be preceded by a percent sign and cannot end with a dollar sign or percent sign. A lexical expression can be: • • • • A lexical constant An integer literal A lexical built-in function (%VARIANT) Any combination of these, separated by logical, relational, or arithmetic operators The %LET directive lets you create constants that control conditional compilation. For example: %LET %debug_on = 0% See Section 18.4.5 for an example of using %LET with %IF-%THEN%ELSE. 18.4.2 The %VARIANT Directive The %VARIANT directive is a built-in lexical function that returns an integer. The value of this returned integer is determined by: • • The SET VARIANT command when a program is compiled in the BASIC environment. The /VARIANT qualifier when a program is compiled from the system command level or from within the BASIC environment. The %VARIANT function returns the variant value set with either of these methods. The default value for the %VARIANT function is zero. See Section 18.4.5 for an example of controlling compilation with %VARIANT. 18-10 Compiler Directives 18.4.3 The %ABORT Directive The %ABORT directive terminates the compilation and displays a message you provide. The text must be a quoted string literal. This information is displayed to SYS$ERROR and in the compilation listing if one is being created. VAX BASIC stops the compilation and terminates the listing file as soon as it encounters a %ABORT directive, and so VAX BASIC does not perform syntax checking on the remainder of the program. See Section 18.4.5 for an example of using %ABORT. 18.4.4 The %PRINT Directive The %PRINT directive allows you to insert a message into your source code that the VAX BASIC compiler displays at compile time. The text must be a quoted string literal. This information is displayed to SYS$ERROR and in the compilation listing if one is being created. VAX BASIC prints the message specified as soon as it encounters a %PRINT directive. See Section 18.4.5 for an example of using %PRINT. 18.4.5 The %IF-%THEN-%ELSE-%END %IF Directive The %IF-% THEN-%ELSE-%END %IF directive lets you do the following things conditionally: • • Compile source text Execute another compiler directive This directive differs from all others in that it can appear anywhere in a program where a space is allowed, except within a quoted string. You must include %END %IF. Otherwise, the rest of the source program becomes part of the %THEN or %ELSE clause. You must also include a lexical expression and some VAX BASIC source code. The truth or falsity of the lexical expression determines whether VAX BASIC compiles the source code in the %THEN clause or the %ELSE clause. If the lexical expression is true, VAX BASIC neither compiles nor checks the syntax of source code in the %ELSE clause. If the lexical expression is false, VAX BASIC neither compiles nor checks the syntax of source code in the %THEN clause. Compiler Directives 18-11 The following example also uses the %VARIANT directive, which returns the value set by the SET VARIANT command or /VARIANT qualifier: Example Y.IF CY.VARIANT = 21.) Y.THEN DECLARE LONG int_array(100) Y.ELSE DECLARE WORD int_array(100) Y.END Y.IF This directive allows for two possibilities. If you compile this program with a /VARIANT=2 qualifier, then VAX BASIC creates an array of longword integers. If you compile this program with any other variant value, VAX BASIC creates an array of word integers. Because %IF can appear within a program line, you can express the same directive this way: DECLARE 1.IF (Y.VARIANT=2%) Y.THEN LONG %ELSE WORD 1.END Y.IF int_array(100) A %THEN or %ELSE clause can also contain other compiler directives. For example, the following program creates the lexical constant %my_ constant and assigns it a value of 8. The %IF directive evaluates the conditional expression ((%my_constant + %VARIANT) > = 10%). If this expression is true, VAX BASIC executes the %THEN clause, aborting the compilation and issuing an error message. If the expression is false, VAX BASIC prints the specified message and continues to compile your program without aborting the compilation. Example Y.LET Y.my_constant = 81. Y.IF ( CY.my_constant + Y.VARIANT) >= 10% )%THEN Y.ABORT "Cannot compile with VARIANT >= 211 ELSE Y.PRINT "Successful Compilation" Y.END Y.!F The compilation listing shows you which clause was actually compiled. 18-12 Compiler Directives Example %LET %my_constant = 8% %IF ( (%my_constant + %VARIANT) >= 10% )%THEN %ABORT "Cannot compile with VARIANT >= 2" ELSE %PRINT "Successful Compilation" %END %IF The compilation listing shows you which clause was actually compiled. 18.5 Record Dependency Relationships in the COD By using the %INCLUDE %FROM %CDD or the %REPORT %DEPENDENCY directives in conjunction with the /DEPENDENCY_DATA qualifier in the BASIC command, you can record dependency relationships in a CDO dictionary between a compiled module entity and included records or other referenced dictionary entities. This functionality is available only if you have CDD /Plus Version 4.0 or later installed on your system. See Chapter 24 for detailed information. July 1988 Compiler Directives 18-13 USING VAX BASIC FEATURES ON VAX/VMS Chapter 19 Data Representation This chapter describes how to represent data using VAX BASIC on the VAX/VMS operating system. 19. 1 Integer Format There are three ways in which integer data can be represented: byte, word, and longword. Note that negative integer values are stored in two's complement format. The following sections describe each of these formats. 19. 1.1 Byte-Length Integer Format Byte-length integers are in the range -127 to 128 and are stored as a single byte (8 bits), starting on an arbitrary byte boundary. Bits are labeled from the right, 0 through 7. See Figure 19-1. Data Representation 19-1 Figure 19-1: Byte-Length Integer Format 0 7 s word: I G N BINARY NUMBER ZK-5173-86 19.1.2 Word-Length Integer Format Word-length integers are in the range -32768 to 32767 and are stored as two contiguous bytes, starting on an arbitrary byte boundary. Bits are labeled from the right, 0 through 15. See Figure 19-2. Figure 19-2: Word-Length Integer Format 15 0 s I G N BINARY NUMBER ZK-5174-86 19.1.3 Longword Integer Format Longword integers are stored as four contiguous bytes, starting on an arbitrary byte boundary. Values are in the range -2147483647 to 2147483647. See Figure 19~3. 19-2 Data Representation Figure 19-3: Longword Integer Format 0 31 s I G BINARY NUMBER N ZK-5175-86 19.2 Real Number Format Real numbers, like integers, can be represented in varying formats. These formats include SINGLE floating-point, DOUBLE floating-point, GFLOAT floating-point, HFLOAT floating-point, and packed DECIMAL format. The following sections describe each of these formats. 19.2. 1 SINGLE Floating-Point Nu111ber For111at (f_floating) F_floating (single-precision) floating-point numbers are stored as four contiguous bytes, starting on an arbitrary byte boundary. Bits are labeled from the right, 0 through 31. The format for single-precision is sign magnitude, with bit 15 the sign bit, bits 14 to 7 an excess-128 binary exponent, and bits 6 through 0 and 31 through 16 a normalized 24-bit fraction with the redundant most significant fraction bit not represented. See Figure 19-4. The 8-bit exponent field encodes the values between 0 and 255, inclusive. An exponent value of 0 together with a sign bit of 0 indicates that the F_floating number has a value of 0. Exponent values between 1 and 255 indicate true binary exponents of -127 through 127. An exponent value of 0, together with a sign bit of l, is taken as reserved. (Floating-point instructions processing a reserved operand take a reserved operand fault.) The magf!itude of an F_floating number is in the approximate range .29 * 10- 38 through* 10 38 • The precision of an F_floating number is approximately one part in 223 (approximately 7 decimal digits). Data Representation 19-3 Figure 19-4: Single-Precision Real Number Format 76 15 14 0 s I G EXPONENT FRACTION N FRACTION 31 16 ZK-5176-86 19.2.2 DOUBLE Floating-Point Number format (D-floating) Double-precision real number format consists of eight contiguous bytes, starting on an arbitrary byte boundary. Bits are labeled from the right, 0 through 63. See Figure 19-5. The form of a D_floating number is identical to the F_floating form, except for an additional 32 low-significance fraction bits. Within the fraction, bits increase in significance from 48 to 63, 32 through 47, 16 through 31, and 0 through 6. The exponent conventions and approximate range of values is the same for both D_ floating and F_floating numbers. The precision of a D_floating number is approximately one part in 255 (approximately 16 decimal digits). 19-4 Data Representation Figure 19-5: Double-Precision Real Number Format 76 15 14 0 s I G EXPONENT FRACTION N FRACTION FRACTION FRACTION 63 48 ZK-5177-86 19.2.3 GFLOAT Floating-Point Number Format (G-floating) The G_floating floating-point number format is eight contiguous bytes, starting on an arbitrary byte boundary. Bits are labeled from the right, 0 through 63. The form of a G_floating number is sign magnitude with bit 15 the sign bit, bits 14 through 4 an excess-1024 binary exponent, and bits 3 through 0 and 63 through 16 a normalized 53-bit fraction with the redundant most significant fraction bit not represented. Within the fraction, bits of increasing significance go 48 through 63, 32 through 47, 16 through 31, and 0 through 3. The 11-bit exponent field encodes the values 0 through 204 7. An exponent value of 0 together with a sign bit of 0 indicates that the G_floating number's value is 0. Exponent values between 1 and 2047 indicate true binary exponents between -1023 and 1023. The value of a G _floating number is in the approximate range .56 • 10 - 308 to .9 • 10308 ; the precision is approximately one part in 252 (approximately 15 decimal digits). Note that both double and G_floating formats require 8 bytes. G_floating format provides a greater range, but less precision than double. Data Representation 19-5 19.2.4 HFLOAT Floating-Point Number Format (H-floating) An H_floating floating-point number is 16 contiguous bytes, starting on an arbitrary byte boundary. H_floating format combines a large range with extensive precision, but requires twice the amount of storage of double and G_floating. The bits are labeled from the right 0 through 127. The form of an H_floating number is sign magnitude with bit 15 the sign bit, bits 14 to 0 an excess -16384 binary exponent, and bits 127 to 16 a normalized 113-bit fraction with the redundant most significant fraction bit not represented. Within the fraction, bits of increasing significance go 112 through 127, 96 through 111, 80 through 95, 64 through 79, 48 through 63, 32 through 47, and 16 through 31. The 15-bit exponent field encodes the values 0 through 32767. An exponent value of 0 together with a sign bit of 0 indicates the H_floating number has a value of 0. Exponent values between 1 and 32767 indicate true binary exponents between -16383 and 16383. The value of an H_floating number is in the approximate range .84 • 104932 through .59 * 104932 • The precision of an H_floating number is approxi~ mately one part in 2 112 (approximately 33 decimal digits). 19.3 Packed Decimal Number Format The DECIMAL data type is useful for storing numbers with a fixed decimal point. DECIMAL numbers are stored as a precise representation of the value stored within the constraints of the specified number of fractional digits. A packed decimal string is a contiguous sequence of bytes in memory. The address A and length L are sufficient to specify a packed decimal string, but note that Lis the number of digits, not bytes, in the string. Every byte of a packed decimal string is divided into two 4-bit fields (nibbles), each of which must contain decimal digits, except the low nibble of the last byte, which must contain a sign. The representation for the digits and sign is as follows: 19-6 Data Representation Digit or Sign Decimal Hexadecimal 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9 + 10,12,14 or 15 A,C,E or F 11 or 13 B or D Despite the options, the preferred sign representation is 12 for positive and 13 for negative. The length L is the number of digits in the packed decimal string (not counting the sign) and must be in the range 1 through 31. If the number of digits is odd, the digits and the sign fit into ((L/2) + 1) bytes; when the number of digits is even, an extra "O" digit must appear in the high nibble (bits 7 to 4) of the first byte. The address A of the string specifies the byte of the string containing the most significant digit in its high nibble. Digits of decreasing significance are assigned to increasing byte addresses and from high nibble to low nibble within a byte. Note that the decimal point is specified by the descriptor for the packed decimal string. See Section 19.6. 19.4 String and Array Descriptor Format A descriptor is a VAX/VMS data structure that describes the parameter being passed. The following sections describe the formats for both string and array descriptors. Data Representation 19-7 19.4.1 Fixed-Length String Descriptor Format A fixed-length string descriptor consists of two longwords. The first word of the first longword contains a value equal to the string's length. The third byte contains a 14 (OE hexadecimal; the VAX/VMS code describing an ASCII character string). The fourth byte contains a 1. The second longword is a pointer containing the address of the string's first byte. See Figure 19-6. For more information, see the Introduction to VAX/VMS System Routines for the VAX Procedure Calling and Condition Handling Standard. Figure 19-6: Fixed-Length String Descriptor Format l OE LENGTH POINTER ZK-5178·86 19.4.2 Dynamic String Descriptor Format A dynamic string descriptor consists of two longwords. The first word of the first longword contains a value equal to the string's length. The third byte contains a 14 (OE hexadecimal; the VAX/VMS code describing an ASCII character string). The fourth byte contains a 2. The second longword is a pointer containing the address of the string's first character. See Figure 19-7. 19-8 Data Representation Figure 19-7: Dynamic String Descriptor Format OE l LENGTH POINTER ZK-5179-86 19.5 Array Descriptors VAX BASIC creates class A array descriptors (DSC$K_CLASS_A) for all arrays except virtual arrays. Virtual array descriptors differ in format and can be manipulated only with VAX BASIC Run-Time Library support routines. Most array descriptors created by VAX BASIC describe the actual data in an array. Some arrays, however, have elements that differ in length from one another. VAX BASIC arrays of this type include both dynamic string arrays and arrays of any datatype which have appeared in MAP DYNAMIC and REMAP statements. An array descriptor for an array of this type describes an array of element descriptors. One element descriptor exists for each array element and points to the actual data. As shown in Figure 19-8, VAX BASIC array descriptors consist of three blocks of information. The first block, the prototype block, is always four longwords in length. The second and third blocks, the multiplier and bounds blocks, vary in length depending on the number of dimensions for the array being described. The sections following the figure describe each block. Data Representation 19-9 Figure 19-8: 4 Array Descriptor Format l DTYPE l l LENGTH POINTER DIMCT1 DO DIGITS l PROTOTYPE BLOCK SCALE ARSIZE AO M1 M2 MULTIPLIER BLOCK Mn L1 U1 BOUNDS BLOCK Ln Un ZK-5535-86 19.5. 1 The Prototype Block In the prototype block, if the data type is not aligned bit string or packed decimal string, the first word of the first longword contains a value denoting the number of bytes in each array element. The length of an aligned bit string array element is specified in bits. The length of a packed decimal string array element is the number of 4-bit digits, not including the sign. 19-1 0 Data Representation July 1981 For arrays requiring a descriptor for each element, the value in this field is the length of the descriptor for the element. Dynamic string arrays and most remapped arrays require 8 bytes for the element descriptor. Remapped packed decimal arrays require 12 bytes for the element descriptor. Data Representation 19-10.1 The third byte of the first longword contains a code indicating the VAX/VMS data type of the array described by the descriptor. For arrays requiring element descriptors, the value is 24 (the VAX/VMS literal DSC$K_DTYPE_DSC and the value 18 hexadecimal). For other arrays, the value reflects the actual data type of the array. The fourth byte denotes the class of the array descriptor and will always have the value 4 (DSC$K_CLASS-A). The second longword is a pointer containing the address of the first element of the array or the first element descriptor. The first byte of the third longword contains a scale factor for packed decimal arrays and for DOUBLE arrays in programs compiled with a scale factor. The second byte specifies the number of digits in each packed decimal array element; for array types other than packed decimal, this byte is zero. The third byte contains array flags indicating that the multiplier and bounds blocks are present (Hexadecimal DO). The fourth byte contains a value equal to the number of dimensions in the array. The fourth longword contains the total size of the array in bytes. 19.5.2 The Multiplier Block For arrays where all dimensions have a lower bound of zero, the first longword (AO) of the multiplier block has the same value as the second longword of the prototype block (the pointer). For arrays with dimensions that possess nonzero lower bounds, the value of AO is the address of the first array element adjusted to account for the non-zero lower bounds in all dimensions. You can use this field in the descriptor to access arrays without consideration of the lower bounds of the array dimensions when computing the element address. The multiplier block contains an additional longword for each dimension of the array. Each longword contains the number of elements in the corresponding dimension (the upper bound minus the lower bound plus 1). 19.5.3 The Bounds Block The third block, the bounds block, consists of one longword pair for each dimension of the array. The first longword of each pair specifies the lower bound of the corresponding dimension and the second longword specifies the upper bound of that dimension. Data Representation 19-11 19.6 Decimal Scalar String Descriptor (Packed Decimal String Descriptor) A single descriptor form gives decimal size and scaling information for both scalar data and simple strings. See Figure 19-9. Figure 19-9: Decimal Scalar String Descriptor 9 21 LENGTH POINTER RESERVED DIGITS SCALE ZK-5181-86 For packed decimal strings, the length field contains the number of 4-bit digits (not including the sign). The pointer field contains the address of the first byte in the packed decimal string. The scale field contains a signed power-of-ten multiplier to convert the internal form to the external form. For example, if the internal number is 123 and the scale field is +l, then the external number is 1230. The digits field is 0; the number of digits is computed from the length field. The reserved field must be zero. 19-12 Oata Representation Chapter 20 Advanced File Input and Output This chapter describes some of the more advanced I/O features available in VAX BASIC. For more information on I/O to RMS disk files, see Chapter 15 in this manual. 20. 1 Introduction This chapter discusses the following topics: • • • • RMS I/Oto ANSI magnetic tapes Device-specific I/O to magnetic tapes (including TKSO devices), disks, and unit record devices I/Oto mailboxes Network I/O When you do not specify a file name in the OPEN statement, the I/O you perform is said to be device-specific. This means that read and write operations (GET and PUT statements) are performed directly to or from the device. For example: OPEN "MTA2:" FOR OUTPUT AS FILE #1 OPEN "MTA1:PARTS.DAT" FOR INPUT AS FILE #2, SEQUENTIAL Because the file specification in the first line does not contain a file name, the OPEN statement opens the tape drive for device-specific I/O. The second line opens an ANSI-format tape file using RMS because a file name is part of the file specification. The following sections describe both I/Oto ANSI-format magnetic tapes and device-specific I/O to magnetic tape, unit record, and disks devices. Advanced File Input and Output 20-1 20.2 RMS 1/0 to Magnetic Tape VAX BASIC supports I/Oto ANSI-formatted magnetic tapes. When performing I/Oto ANSI-formatted magnetic tapes, you can read or write to only one file to a magnetic tape at a time, and the files are not available to other users. ANSI tape files are RMS sequential files. 20.2.1 Allocating and Mounting a Tape You should allocate the tape unit to your process before starting file operations. For example: $ ALLOCATE MT1: This command assigns tape drive MTl: to your process. You must also set the tape density and label with the MOUNT command. Optionally, you can specify a logical name to assign to the device, in this case, TAPE. $ MOUNT/DENSITY=1600 MT1: VOL001 TAPE When mounting a TKSO, you cannot specify a density. If the records do not specify the size of the block (no value in HDR 2), specify the BLOCKSIZE as part of the MOUNT command. For example: $ MOUNT/DENSITY=1600/BLOCKSIZE=128 MT1: VOL020 TAPE Alternatively, you can use the $MOUNT system service to mount tapes. 20.2.2 Opening a Tape File for Output To create and open a magnetic tape file for output, you use the OPEN statement. For instance, the following statement opens the file PARTS.DAT and writes 256 byte records that are blocked four to a physical tape block of 1024 bytes. OPEN "MT1:PARTS.DAT" FOR OUTPUT AS FILE #21., SEQUENTIAL FIXED, RECORDSIZE 2661., BLOCKSIZE 4% & Specifying FIXED record format creates ANSI F format records. Specifying VARIABLE creates ANSI D format records. If you do not specify a record format, the default is VARIABLE. 20-2 Advanced File Input and Output NOTE Every record in an ANSI D formatted file is prefixed by a 4-byte header giving the record length in decimal ASCII digits. The length includes the 4-byte header. VAX BASIC adds the 4-byte header to the record size when calculating block size. The header is transparent to your program. If you do not specify a block size, VAX BASIC defaults to one record per block. For small records, this can be inefficient; the tape will contain many inter-record gaps. 20.2.3 Opening a Tape File for Input To open an existing magnetic tape file, you also use the OPEN statement. For example, the following statement opens the file PAYROLL.DAT. If you do not specify a record size or a block size, VAX BASIC defaults to the values in the header block. If you do not specify a record format, VAX BASIC defaults to the format present in the header block (ANSI F or ANSI D). You must specify ACCESS READ if the tape is not write-enabled. For example: 100 OPEN "TAPE:PAYROLL.DAT" FOR INPUT AS FILE #4% ,ACCESS READ 20.2.4 Positioning a Tape NOREWIND positions the tape for reading and writing as follows: • • Specifying NOREWIND when you create a file positions the tape at the logical end-of-tape and leaves the unit open for writing. If you omit NO REWIND, you start writing at the beginning of the tape (BOT), logically deleting all subsequent files. Specifying NOREWIND when you open an existing file starts a search for the file at the current position. The search continues to the logical end-of-tape. If the record is not found, VAX BASIC rewinds and continues the search until reaching the logical end-of-tape again. Omitting NOREWIND tells VAX BASIC to rewind the tape and search for the file name until reaching the end-of-tape. In either case, you receive an error message if the file does not exist. Advanced File Input and Output 20-3 For example, the following statement opens PAYROL.DAT after advancing the tape to the logical end-of-tape. If you omit NOREWIND, the file opens at the beginning of the tape, logically deleting all subsequent files. OPEN "MT1:PAYROL.DAT" FOR OUTPUT AS FILE #11. & ,ORGANIZATION SEQUENTIAL, NOREWIND Note that you cannot specify REWIND; to avoid rewinding the tape, omit the NOREWIND keyword. 20.2.5 Writing Records to a File The PUT statement writes sequential records to the file. The following program writes a record to the file. Successive PUT operations write successive records. Example OPEN "MTO:TEST.DAT" FOR OUTPUT AS FILE #2, & SEQUENTIAL FIXED, RECORDSIZE 201. 8$ = "" WHILE 8$ <> "NO" LINPUT "Name"; A$ MOVE TO #2, A$ = 20 PUT #2 LINPUT "Write another record"; 8$ NEXT CLOSE #2 END Each PUT writes one record to the file. If your OPEN statement specifies a RECORDSIZE clause, the record buffer length equals RECORDSIZE or the map size. For example: RECORDSIZE 601. This clause specifies a record length and a record buffer size of 60 bytes. You can specify a record length between 18 and 8192 bytes. The default is 132 bytes. If you specify a MAP clause and no RECORDSIZE clause, then the record size is the size of the map. If you also specify BLOCKSIZE, the size of the buffer equals the value in BLOCKSIZE multiplied by the record size. For example: RECORDSIZE 601., 8LOCKSIZE 4Y. 20-4 Advanced File Input and Output These clauses specify a logical record length of 60 bytes and a physical tape record size of 240 bytes (60 * 4). You specify BLOCKSIZE as an integer number of records. RMS rounds the resulting value to the next multiple of four. The total 1/0 buffer length cannot exceed 8192 bytes. The default is a buffer (tape block) containing one record. To write true variable-length records, use the COUNT clause with the PUT statement to specify the number of bytes of data written to the file. Without COUNT, all records equal the length specified by the RECORDSIZE clause when you opened the file. 20w2.6 Reading Records from a File The GET statement reads one logical record into the buffer. For example, in the following program, the first GET reads a group of four records (a total of 80 bytes) from the file on channel #5 and transfers the first 20 bytes to the record buffers. Successive GET operations read 20 byte records to the record buffer performing an 1/0 to the tape every 4 records. Example OPEN 11 MTO:TEST.DAT 11 FOR INPUT AS FILE #5%, & ORGANIZATION SEQUENTIAL FIXED, RECORDSIZE 20%, & BLDCKSIZE 4%, ACCESS READ B$ = "" WHILE B$ <> "ND" GET #5 MOVE FROM #5, A$ = 20 PRINT A$ LINPUT "Do you want another record"; B$ NEXT CLOSE #5 END 20.2. 7 Controlling Tape Output Format Magnetic tape physical records range from 18 to 8192 bytes. With RMS tapes, you can optionally specify this size in the BLOCKSIZE clause as a positive integer indicating the number of records in each block. VAX BASIC then calculates the actual size in bytes. Thus, a fixed-length file on tape with 126 byte records can have a block size between 1 and 64, inclusive. The default is 126 bytes (one record per block). Advanced File Input and Output 20-5 For instance, in the following example of an OPEN statement, the RECORDSIZE clause defines the size of the records in the file as 90 bytes, and BLOCKSIZE defines the size of a block as 12 records (1080 bytes). Thus, your program contains an 1/0 buffer of 1080 bytes. Each physical read or write operation moves 1080 bytes of data between the tape and this buffer. Every twelfth GET or PUT operation causes a physical read or write. The next eleven GET or PUT operations only move data into or out of the 1/0 buffer. Specifying a block size larger than the default can reduce overhead by eliminating some physical reading and writing to the tape. In addition, specifying a large block size conserves space on the tape by reducing the number of inter-record gaps (IRGs). In the example, a block size of 12 saves time by accessing the tape only after every twelfth record operation. OPEN "MTO: [SMITH] TEST.SEQ" FOR OUTPUT AS FILE #12% & ,ORGANIZATION SEQUENTIAL FIXED, RECORDSIZE 90% & ,BLOCKSIZE 12% Through RMS, VAX BASIC controls the blocking and deblocking of records. RMS checks each PUT operation to see if the specified record fits in the tape block. If it does not, RMS fills the rest of the block with circumflexes (blanks) and starts the record in a new block. Records cannot span blocks in magnetic tape files. When you read blocks of records, your program can issue successive GET statements until it locates the fields of the record you want. For example, the following program finds and displays a record on the terminal. You can invoke the RECOUNT function to determine how many bytes were read in the GET operation. Example MAP (XXX) NA.ME$ = 5%, address$ = 20% OPEN "MTO:FILE.DAT" FOR INPUT AS FILE #4%, & SEQUENTIAL FIXED, MAP XXX, ACCESS READ NA.ME$ = "" GET #4 UNTIL NA.ME$ = "JONES" PRINT NA.ME$; "LIVES AT"; address$ CLOSE #4 END 20-6 Advanced File Input and Output July 1988 20.2.8 Rewinding a Tape With the RESTORE# statement, you can rewind the tape to the start of the currently open file. Example OPEN "MTO:FTF.DAT" FOR INPUT AS FILE #2Y., ACCESS READ GET #2Y. RESTORE #2Y. GET #2Y. You cannot rewind past the beginning of the currently open file. 20.2.9 Closing a File The CLOSE statement ends I/O to the file. For example, the following statement ends input and output to the file open on channel #6. CLOSE #6Y. If you opened the file with ACCESS READ, CLOSE has no further effect. If you opened the file without specifying ACCESS READ and the tape is not write-locked (that is, if the plastic write ring is in place), VAX BASIC does the following: • • Writes file trailer labels and two end-of-file marks following the last record Backspaces over the last end-of-file mark VAX BASIC does not rewind the tape. 20.3 Device-Specific 1/0 Device-specific I/O lets you perform I/O directly to a device. The following sections describe device-specific I/O to unit record devices, tapes, and disks. Advanced File Input and Output 20-7 20.3.1 Device-Specific 1/0 to Unit Record Devices You perform device-specific I/Oto unit record devices by using only the device name in the OPEN statement file specification. You should allocate the device at DCL command level before reading or writing to the device. For example, this command allocates a card reader: $ ALLOCATE CR1: Once the device is allocated, you can read records from it: Example MAP (DNG) AY. = SOY. OPEN "CR1:" FOR INPUT AS FILE #11., ACCESS READ, MAP DNG GET #11. VAX BASIC treats the device as a file, and data is read from the card reader as a series of fixed-length records. 20.3.2 Device-Specific 1/0 to Magnetic Tape Devices When performing device-specific I/O to a tape drive, you open the physical device and transfer data between the tape and your program. GET and PUT statements perform read and write operations. UPDATE and DELETE statements are invalid when you perform device-specific I/O. 20.3.2. 1 Allocating and Mounting a Tape You must allocate the tape unit to your process before starting file operations. For example, the following command line assigns tape drive MTl: to your process. $ ALLOCATE MT1: Use the DCL command MOUNT and the /FOREIGN qualifier to mount the tape. For example: $MOUNT/FOREIGN MT1: If your program needs a blocksize other than 512 bytes, or a particular tape density, specify these characteristics with the MOUNT command as well. For example: $ MOUNT/FOREIGN/BLOCKSIZE=1024/DENSITY=1600 MT1: 20-8 Advanced File Input and Output When reading a foreign tape, you must make sure the /BLOCKSIZE qualifier has a value at least as large as the largest record on the tape. 20.3.2.2 Opening a Tape File for Output To create and open the magnetic tape file for output, you use the OPEN statement. For example, the following statement opens tape drive MTl: for writing. It is important to use the SEQUENTIAL VARIABLE clause unless the records are fixed. In contrast to ANSI tape processing, RMS does not write record length headers or variable-length records to foreign tapes. If you specify SEQUENTIAL VARIABLE, you should have some way to determine where records begin and end. OPEN "MT1:" FOR OUTPUT AS FILE #11., ORGANIZATION SEQUENTIAL VARIABLE 20.3.2.3 t Opening a Tape File for Input To access a tape with existing data, you also use the OPEN statement. For example, the following statement opens the tape unit MT2:. OPEN "MT2:" AS FILE #21. Depending on how you access records, there are two ways to open a foreign magnetic tape. If your program uses dynamic buffering and MOVE statements, open the file with no RECORDSIZE clause. RMS will provide the correct buffer size for VAX BASIC. Do not specify a BLOCKSIZE value or ORGANIZATION clause with the OPEN statement. If your program uses MAP and REMAP statements, but you do not know how long the records are, specify a MAP that is as large as the value you specified for the /BLOCKSIZE qualifier when mounting the tape. Do not specify a BLOCKSIZE value or ORGANIZATION clause with the OPEN statement. When processing records, each GET operation will read one physical record whose size is returned in RECOUNT. If you are using a map only, the first n bytes (where n is the value returned in RECOUNT) are valid. Advanced File Input and Output 20-9 20.3.2.4 Writing Records to a File The PUT statement writes records to the file in sequential order. Example OPEN "MTO:" FOR OUTPUT AS FILE #9%, lz SEQUENTIAL VARIABLE INPUT "NAME";NA.ME$ MOVE TO #9%, NA.ME$ PUT #9% The last line writes the contents of the record buffer to the device. Successive PUT operations write successive records. The default record length (and therefore, the size of the buffer) is 132 bytes. The RECORDSIZE attribute causes VAX BASIC to read or write records of a specified length. For instance, the following statement opens tape unit MTO: and specifies records of 900 characters. You must specify an even integer larger than or equal to 18. If you specify a buffer length less than 18, VAX BASIC signals an error. If you try to write a record longer than the buffer, VAX BASIC signals the error "Size of record invalid" (ERR = 156). OPEN "MTO:" FOR INPUT AS FILE #1%, RECORDSIZE 900% To write records shorter than the buffer, include the COUNT clause with the PUT statement. For example, the following statement writes a 56-character record to the file open on channel #6. If you do not specify COUNT, VAX BASIC writes a full buffer. You can specify a minimum count of 18, and a maximum count equal to the buffer size. When writing records to a foreign magnetic tape, neither VAX BASIC nor RMS prefixes the records with any count bytes. PUT #6%, COUNT 56% 20.3.2.5 Reading Records from a File The GET statement reads records into the buffer. For instance, the following program reads a record into the buffer, prints a string field, and rewinds the file before closing. Successive GET operations read successive records. VAX BASIC signals the error "End of file on device" (ERR= 11) if you encounter a tape mark during a GET operation. If you trap this error and continue, you can skip over any tape mark(s). The system variable RECOUNT is set to the number of bytes transferred after each GET operation. 20-10 Advanced File Input and Output Example OPEN "MT1:" FOR INPUT AS FILE 111., ACCESS READ GET 111. MOVE FROM 111., A$ = RECOUNT PRINT A$ RESTORE 111. CLOSE 111. 20.3.2.6 Rewinding a Tape When you mount a magnetic tape, the system will position the tape at the load point (BOT). Your program can rewind the tape during program execution with the RESTORE statement. Example OPEN "MT1:" FOR OUTPUT AS FILE 121., ACCESS READ PUT 121. RESTORE 121. INPUT "NEXT RECORD"; NXTRECBBY. If you rewind a tape opened without ACCESS READ before closing it, you erase all data written before the RESTORE operation. 20.3.2. 7 Closing a Tape The CLOSE statement ends 1/0 to the tape. For example, the following statement ends input and output to the tape open on channel #12. CLOSE 1121. If you opened the file with ACCESS READ, CLOSE has no further effect. If you opened the file without specifying ACCESS READ and the tape is not write-locked (that is, if the plastic write ring is in place), VAX BASIC does the following: • • Writes file trailer labels and two end-of-file marks following the last record Backspaces over the last end-of-file mark The tape is not rewound unless you specified RESTORE in your program. Advanced File Input and Output 20-11 20.3.3 Device-Specific 1/0 to Disks When performing device-specific 1/0 to disks, you write and read data with PUT and GET statements. The data must fit in 512-byte blocks, and you must do your own blocking and deblocking with MAP /REMAP or MOVE statements. Note that, when accessing disks with device-specific 1/0 operations, you are performing logical 1/0. Because of this, you should be careful not to overwrite block number zero, which is often the disk's boot block. You must have LOG_IO privileges to perform these operations. The following sections describe device-specific 1/0 to disks. 20.3.3. 1 Assigning and Mounting a Disk You must allocate a disk unit to your process before starting operations. For example, the following command line assigns disk DUA3: to your process. $ ALLOCATE DUA3: When you perform 1/0 directly to a disk, you must mount the disk with the MOUNT command before accessing it. For example: $ MOUNT/FOREIGN DUA3: You can then open the disk for input or output. 20.3.3.2 Opening a Disk File for Output To create and open the disk file, you use the OPEN statement. For example: OPEN "DUA3:" FOR OUTPUT AS FILE #21., SEQUENTIAL FIXED, t RECORDSIZE=512 You can then write data to the disk. The record size determined by the MAP or RECORDSIZE clause must be an integer multiple of 512 bytes. 20-12 Advanced File Input and Output 20.3.3.3 Opening a Disk File for Input To open an existing disk file, you also use the OPEN statement. For example: OPEN "DUA1:" FOR INPUT AS FILE #4Y., SEQUENTIAL FIXED, k RECORDSIZE=612 You can then read data from the disk. The recordsize determined by the MAP or RECORDSIZE clause must be an integer multiple of 512 bytes. The default is 512. Specify ACCESS READ in the OPEN statement if you only plan to read from the disk. 20.3.3.4 Writing Records to a Disk File You write data by defining a record buffer and writing the data to the file with PUT statements. For example, the following program writes eight 64 byte records into each 512-byte block on the disk. When your program fills one block, writing continues in the next. The FILL field in the MOVE statement positions the data in the block. Example INPUT "HOW MANY RECORDS TO WRITE"; JY. OPEN "DBB2: FOR OUTPUT AS FILE #2Y., SEQUENTIAL FIXED, k RECORDSIZE=512 FOR KY. = 1Y. TO JY. FOR IY. = OY. TO 7Y. INPUT "NAME OF BOOK"; BOOK_NAME$ INPUT "RETRIEVAL NUMBER"; RET_NUMY. INPUT "SUBJECT AREA"; SUBJ$ MOVE TO #2Y., FILL$ = IY. * 64Y., BOOK_NAME$, RET_NUMY., SUBJ$ NEXT IY. PUT #2Y. NEXT KY. CLOSE #2 When you write records, VAX BASIC does not prefix the records with any count bytes. Advanced File Input and Output 20-13 20.3.3.5 Reading Records from a Disk File You read data by defining a record buffer and reading the data from the device with GET statements. After the data has been retrieved with a GET statement you can deblock the data with MOVE or REMAP statements. In the following example, each disk block contains twelve 40-byte records. Each record contains a 32-byte string, a 4-byte SINGLE number, and a 4-byte LONG integer. After each GET operation, the FOR ... NEXT loop uses the REMAP statement to redefine the position of the variables in the record. At the end of the file, the program closes the file. See Chapter 9 and the VAX BASIC Reference Manual for more information on the MAP, MAP DYNAMIC and REMAP statements. Example MAP (SAM) FILL$ = 512 MAP DYNAMIC (SAM) STRING PRT_ID, SINGLE MAFLD, LONG ADIR_OLDN OPEN "DUA1:" FOR INPUT AS FILE #21,, SEQUENTIAL FIXED, & ACCESS READ, MAP SAM WHEN ERROR USE err_hand WHILE 1Y. = 1Y. GET #2Y. FOR IY. = OY. TO 11Y. REMAP (SAM) STRING FILL(IY. * 40Y.), PRT_ID = 32, MAFLD, ADIR_OLDN PRINT PRT_ID, MAFLD, ADIR_OLDN NEXT IY. NEXT END WHEN HANDLER err_hand IF ERR <> 11Y. THEN EXIT HANDLER END IF END HANDLER CLOSE #2Y. END 20.4 1/0 to Mailboxes A mailbox is a record ljO device that passes data from one process to another. You can use a valid mailbox name as a file name, and treat that mailbox as a normal record file. You must have TMPMBX or PRMMBX privilege to create mailboxes. Mailboxes are created and deleted by system services. For more information on using system services in VAX BASIC programs, see Chapter 21 in this manual. 20-14 Advanced File Input and Output Use the EXTERNAL statement to define the SYS$CREMBX system service that creates the mailbox. In VAX BASIC programs, you create mailboxes by invoking SYS$CREMBX as a function passing either a channel argument and a string literal or a logical name for the mailbox. For example: EXTERNAL INTEGER FUNCTION SYS$CREMBX SYS$STATUSY. = SYS$CREMBX(.CHANY.,,,,, "CONFIRMATION_MBX") If you supply a logical name for the mailbox, be sure that it is in uppercase letters. Once you create the mailbox, you can use it as a logical file name. The following two examples, when executed on two separate processes, allow you to send and receive data from one process to another. Example 1 DECLARE STRING passenger_name, Confirm_msg OPEN "CONFIRMATION_MBX" AS FILE #1Y. INPUT "WHAT IS THE PASSENGER NAME"; passenger_name PRINT t1Y., passenger_name LINPUT #1Y., confirm_msg PRINT confirm_msg END Example 2 MAP (res) STRING passenger_name = 32Y. DECLARE WORD mbx_chan, LONG sys_status EXTERNAL LONG FUNCTION sys$crembx (LONG, WORD, LONG, LONG, LONG, LONG, STRING) WHEN ERROR USE err_trap sys_status = sys$crembx ( ,mbx_chan,,,,, "CONFIRMATION_MBX") OPEN "CONFIRMATION_MBX" FOR INPUT AS FILE #1Y. LINPUT #1Y., passenger_name OPEN "RESER.LST" FOR INPUT AS FILE #2Y., t ORGANIZATION INDEXED, MAP RES, ACCESS READ PRIMARY passenger_name FIND #2Y., KEY #OY. EQ passenger_name RECEIVING.MSG$ = "Passenger reservation confirmed" PRINT #1Y., RECEIVING.MSG$ END WHEN HANDLER err_trap IF (ERR = 166) t t THEN RECEIVING.MSG$ = "Reservation does not exist" ELSE EXIT HANDLER END IF END HANDLER CLOSE t2Y., #1Y. END PROGRAM Advanced File Input and Output 20-15 Example 1 requests a passenger name and sends it to the mailbox. Example 2 looks up the name in an indexed file. If the passenger name exists, Example 2 writes the confirmation message to the mailbox. If the passenger name does not exist, the error handler writes an alternate message. Example 1 then reads the mailbox and returns the result. VAX BASIC treats the mailbox as a sequential file. You write to the file with the PRINT # or PUT statement, and read it with the INPUT #, LINPUT #, or GET statement. When either program closes the mailbox, the other program receives an end-of-file error message when it attempts to read the mailbox. NOTE All mailbox operations are synchronous. Control does not pass back from a mailbox operation, such as a PUT, to your program until the other program completes the corresponding operation, such as a GET. 20.5 Network 1/0 If your system supports DECnet-VAX facilities, and your computer is one of the nodes in a DECnet-VAX network, you can communicate with other nodes in the network with VAX BASIC program statements. VAX BASIC lets you do the following: • • 20-16 Read and write files on a remote node as you do files on your own system (remote file access) Exchange data with a process executing at a remote location (task-totask communication) Advanced File Input and Output 20.5.1 Remote File Access To write or read files at a remote site, include the node name as part of the file specification. For example: OPEN "WESTON::DUA1: [HOLT]TEST.DAT;2" FOR INPUT AS FILE #21. You can also assign a logical name to the file specification, and use that logical name in all file lfO. NOTE You need NETMBX privileges to access files at a remote node. If the account at the remote site requires a usemame and password, include this access string in the file specification. You do this by enclosing the access string in quotation marks and placing it between the node name and the double colon. For example, the following file specification accesses the account [HOLT.IMP] on node WESTON by giving the usemame HOLT and the password PASWRD. After accessing the file, your VAX BASIC program can read and write records as if the file were in your account. OPEN 'WESTON"HOLT PASWRD": :DUAO:[HOLT.TMP]INDEXU.DAT;4' & FOR INPUT AS FILE #11., INDEXED, PRIMARY TEXT$ 20.5.2 Task-to-Task Communication VAX BASIC supports task-to-task communication if your account has NETMBX privileges. Follow these steps for task-to-task communication: 1. Establish a command file at the remote site to execute the program you want. The program must be in executable image format. For example, you can create the file MARG.COM at the remote site. MARG.COM contains a line to run an image (in this case, COPYT.EXE): $ RUN COPYT The OPEN statements in the programs at both nodes must specify the same file attributes. Advanced File Input and Output 20-17 2. Start task-to-task communication by accessing the command file at the remote site. For example, a program at the local node could contain the following line: OPEN 'WESTON::"TASK =MARG"' AS FILE #1%, SEQUENTIAL 3. The system then assigns the logical name SYS$NET to the program at the local node. At the remote node, the program (COPYT.EXE) must use this logical for all operations. For example: OPEN 'SYS$NET' FOR INPUT AS FILE #1Y,, SEQUENTIAL 4. The two programs can then exchange messages. The programs must have a complementary series of send/receive statements. Example !Local Program MAP (SJK) MSG$ = 32% OPEN 1 WESTON 11 DAVIS PSWRD": :"TASK =MARG"' & FOR OUTPUT AS FILE #1%, SEQUENTIAL, MAP SJK LINPUT "WHAT IS THE CUSTOMER NAME"; MSG$ PUT #1% GET #1% PRINT MSG$ CLOSE #1% END !Remote Node Program MAP (SJK) MSG$ = 321. MAP (FIL) NAME$ = 32%, RESERVATION$ = 64% OPEN 'SYS$NET' FOR INPUT AS FILE #1%, SEQUENTIAL, & MAP SJK OPEN 1 RESER.DAT 1 FOR INPUT AS FILE #2%, & INDEXED FIXED, PRIMARY NAME$, MAP FIL GET #1Y, MSG$ = "NAME CONFIRMED" WHEN ERROR IN 100 FIND #2%. KEY OY. EQ MSG$ USE IF ERR = 163 THEN MSG$ = "ERROR IN NAME" ELSE EXIT HANDLER END IF END WHEN 10 20-18 Advanced File Input and Output PUT 11% CLOSE 12%, 1% END The task-to-task communication ends when the files are closed. See the VAX/VMS Networking Manual and the VAX/VMS System Manager's Reference Manual for more information. Advanced File Input and Output 20-19 Chapter 21 Using VAX BASIC in the Common Language Environment The VAX BASIC compiler lets you call external routines from a VAX BASIC program. This chapter shows you how to call the following from VAX BASIC: • • • External routines written in other VAX languages VAX/VMS Run-Time Library routines VAX/VMS system services The terms routine, procedure, and function are used throughout this chapter. A routine is a closed, ordered set of instructions that performs one or more specific tasks. Every routine has an entry point (the routine name), and may or may not have an argument list. Procedures and functions are specific types of routines: a procedure is a routine that does not return a value, while a function is a routine that returns a value by assigning that value to the function's identifier. System routines are prewritten VAX/VMS routines that perform common tasks such as finding the square root of a number or allocating virtual memory. You can call any system routine from VAX BASIC provided that the data structures necessary for that routine are supported. The system routines used most often are VAX/VMS Run-Time Library routines and system services. System routines, which are discussed later in this chapter, are documented in detail in the VAX/VMS Run-Time Library Routines Reference Manual and the VAX/VMS System Services Reference Manual. Using VAX BASIC in the Common Language Environment 21-1 21.1 Specifying Parameter-Passing Mechanisms When you pass data between routines that are not written in the same VAX language, you have to specify how you want that data to be represented and interpreted. You do this by specifying a parameter-passing mechanism. The three general parameter-passing mechanisms and their keywords in VAX BASIC are as follows: • • • By reference-BY REF By descriptor-BY DESC By value-BY VALUE The following sections outline each of these parameter-passing mechanisms in more detail. 21.1.1 Passing Parameters by Reference When you pass a parameter by reference, VAX BASIC passes the address at which the actual parameter value is stored. In other words, your routine has access to the parameter's storage address; therefore, you can manipulate and change the value of this parameter. Any changes that you make to the value of the parameter in your routine are reflected in the calling routine as well. 21.1.2 Passing Parameters by Descriptor A descriptor is a data structure that contains the address of a parameter, along with other information such as the parameter's data type and size. When you pass a parameter by descriptor, the VAX BASIC compiler passes the address of a descriptor to the called routine. You usually use descriptors to pass parameters that have unknown lengths, such as the following: • • • Character strings Arrays Compound data structures Like parameters passed by reference, any change made to the value of a parameter passed by descriptor is reflected in the calling routine. 21-2 Using VAX BASIC in the Common Language Environment 21.1.3 Passing Parameters by Value When you pass a parameter by value, you pass a copy of the parameter value to the routine instead of passing its address. Because the actual value of the parameter is passed, the routine does not have access to the storage location of the parameter; therefore, any changes that you make to the parameter value in the routine do not affect the value of that parameter in the calling routine. 21. 1.4 VAX BASIC Default Parameter-Passing Mechanisms There are default parameter-passing mechanisms established for every data type you can use with VAX BASIC. Table 21-1 shows which VAX BASIC data types you can use with each parameter-passing mechanism. Table 21-1: Allowable Parameter-Passing Mechanisms Parameter BY VALUE BY REF BY DESC Variables Yes Yes Yes Constants Yes Local copy 1 Local copy Expressions Yes Local copy 1 Local copy Elements of a nonvirtual array Yes Yes 1 Yes Virtual array elements Yes Local copy 1 Local copy Non virtual entire array No Yes Yes 1 Virtual entire array No No No Integer and Real Data 1 Specifies the default parameter-passing mechanism. Using VAX BASIC in the Common Language Environment 21-3 Table 21-1 (Cont.): Allowable Parameter-Passing Mechanisms BY VALUE BY REF BY DESC Variables No Yes 1 Yes Constants No Local copy 1 Local copy Expressions No Local copy 1 Local copy Non virtual array elements No Yes 1 Yes Virtual array elements No Local copyl Local copy Non virtual entire arrays No Yes Yes 1 Virtual entire arrays No No No Variables No Yes Yes Constants No Local copy Local copy 1 Expressions No Local copy Local copy 1 Non virtual array elements No Yes Yes 1 Virtual array elements No Local copy Local copy 1 Non virtual entire arrays No Yes Yes 1 Virtual entire arrays No No No No Yes 1 No No 1 No Parameter Packed Decimal Data String Data Other Parameters RECORD variables RF A variables 1 Specifies the default parameter-passing mechanism. 21-4 Using VAX BASIC in the Common Language Environment Yes 21.1.5 Creating Local Copies If a parameter is an expression, function, or virtual array element, then it is not possible to pass the parameter's address. In these cases, VAX BASIC makes a local copy of the parameter's value and passes this local copy by reference. You can force VAX BASIC to make a local copy of any parameter by enclosing the parameter in parentheses. Forcing VAX BASIC to make a local copy is a useful technique because you make it impossible for the subprogram to modify the actual parameter. In the following example, when variable A is printed in the main program, the value is zero because the variable A is not modifiable by the subprogram. Example DECLARE LONG A CALL SUB1 ((A)) PRINT A END SUB SUB1 (LONG 8) 8 =3 END SUB Output 0 By removing the extra parentheses from A, you allow the subprogram to modify the parameter. Using VAX BASIC in the Common Language Environment 21-5 Example DECLARE LONG A CALL SUB1 (A) PRINT A END SUB SUB1 (LONG B) B =3 END SUB Output 3 21.2 Calling External Routines Most of the steps of calling external routines are the same whether you are calling an external routine written in VAX BASIC, an external routine written in some other VAX language, a system service, or a VAX/VMS Run-Time Library routine. The following sections outline the procedure for calling non-BASIC external routines. For information on calling BASIC routines, see Chapter 14. 21.2.1 Determining the Type of Call Before you call an external routine, you must determine whether the call to the routine should be a function call or a procedure call. You should call a routine as a function if it returns any type of value. If the routine does not return a value, you should call it as a procedure. 21.2.2 Declaring an External Routine and Its Arguments To call an external routine or system routine you need to declare it as an external procedure or function and to declare the names, data types, and passing mechanisms for the arguments. Arguments can be either required or optional. You should include the following information in a routine declaration: • • 21-6 The name of the external routine The data types of all the routine parameters Using VAX BASIC in the Common Language Environment • The passing mechanisms for all the routine parameters, provided that the routine is not written in VAX BASIC When you declare an external routine, use the EXTERNAL statement. This allows you to specify the data types and parameter-passing mechanisms only once. In the following example, the EXTERNAL statement declares cobsub as an external subprogram with two parameters: a LONG integer and a string both passed by reference. EXTERNAL SUB cobsub (LONG BY REF, STRING BY REF) With the EXTERNAL statement, VAX BASIC allows you to specify that particular parameters do not have to conform to specific data types and that all parameters past a certain point are optional. A parameter declared as ANY indicates that any data type can appear in the parameter position. In the following example, the EXTERNAL statement declares a SUB subprogram named allocate. This subprogram has three parameters: one LONG integer, and two that can be of any VAX BASIC data type. EXTERNAL SUB allocate(LONG, ANY,) A parameter declared as OPTIONAL indicates that all following parameters are optional. You can have both required and optional parameters. The required parameters, however, must appear before the OPTIONAL keyword because all parameters following it are considered optional. In the following example, the EXTERNAL statement declares the RunTime Library routine LIB$LOOKUP_KEY. The keyword OPTIONAL is specified to indicate that the last three parameters can be optional. EXTERNAL LONG FUNCTION LIB$LOOKUP_KEY(STRING, LONG, OPTIONAL LONG, t STRING, INTEGER) For more information on using the EXTERNAL statement, see the VAX BASIC Reference Manual. Using VAX BASIC in the Common Language Environment 21-7 21.2.3 Calling the Routine Once you have declared an external routine, you can invoke it. To invoke a procedure, you use the CALL statement. To invoke a function, you use the function name in an expression. You must specify the name of the routine being invoked and all parameters required for that routine. Make sure the data types and passing mechanisms for the actual parameters you are passing match those you declared earlier, and those declared in the routine. If you do not want to specify a value for a required parameter, you can pass a null argument by inserting a comma as a placeholder in the argument list. If you are passing a parameter using a mechanism other than the default passing mechanism for that data type, you must specify the passing mechanism in the CALL statement or the function invocation. The following example shows you how to call the external subprogram allocate declared in Section 21.2.2. When allocate is called, it is called as a procedure. The first parameter must always be a valid LONG INTEGER value; the second and third parameters can be of any valid VAX BASIC data type. EXTERNAL SUB allocate(LONG, ANY,) CALL allocate (entityY., a$, 11.) This next example shows you how to call the Run-Time Library routine LIB$LOOKUP_KEY declared in Section 21.2.2. When the routine LIB$LOOKUP_KEY is called, it is invoked as a function. The first two parameters are required; all remaining parameters are optional. EXTERNAL LONG FUNCTION LIB$LOOKUP_KEY(STRING, LONG, OPTIONAL LONG, t STRING, INTEGER) ret_statusY. = LIB$LOOKUP_KEY(value$, pointY.) Note that if the actual parameter's data type in the CALL statement does not match that specified in the EXTERNAL statement, VAX BASIC reports the compile-time informational message "Mode for parameter of routine changed to match declaration". This tells you that VAX BASIC has made a local copy of the value of the parameter, and that this local copy has the data type specified in the EXTERNAL declaration. VAX BASIC warns you of this because the change means that the parameter can no longer 21-8 Using VAX BASIC in the Common Language Environment be modified by the subprogram. If VAX BASIC cannot convert the data type, VAX BASIC signals the error "Mode for parameter of routine not as declared". The routine being called receives control, executes, and then returns control to the calling routine at the next statement after the CALL statement or function invocation. VAX BASIC provides the built-in function LOC to allow you to access the address of a named external function. This is especially useful when passing the address of a callback or AST routine to an external subprogram. In the following example, the address of the function compare is passed to the subprogram come_back_now using the LOC function. EXTERNAL LONG FUNCTION compare (LONG, LONG) EXTERNAL SUB come_back_now (LONG BY VALUE) CALL come_back_now (LOC(compare) BY VALUE) 21.3 Calling VAX BASIC Subprograms from Other Languages When you call a VAX BASIC subprogram from another language, there are some additional considerations that you should be aware of. For instance, although VAX BASIC conforms to the VAX Procedure Calling Standard, you should specify explicit passing mechanisms when calling a routine written in another language. VAX BASIC's default passing mechanisms may not match what the procedure expects. VAX FORTRAN passes and receives numeric data by reference; only the default parameter-passing mechanisms are required for passing numeric data back and forth between VAX FORTRAN and VAX BASIC programs. Both VAX BASIC and VAX FORTRAN pass strings by descriptor. However, VAX FORTRAN subprograms cannot change the length of strings passed to them. Therefore, if you pass a string to a VAX FORTRAN subprogram, you must make sure that the string is long enough to receive the result. You do this in one of two ways: • • Pre-extend the string. Set the string variable equal to SP ACE$(n), where n is large enough to receive the result. Define the string as fixed-length. Name the string in a COMMON or MAP statement. Because the length of the returned string does not change, it is either padded with spaces or truncated. Using VAX BASIC in the Common Language Environment 21-9 To pass an array to a VAX FORTRAN subprogram, you must specify BY REF. Note that VAX FORTRAN arrays are one-based, while VAX BASIC arrays are zero-based by default. For example, in VAX FORTRAN the array Two_D(S,3) represents a 5 by 3 matrix, while in VAX BASIC the array Two_d(S,3) represents a 6 by 4 matrix. You can adjust your array bounds in VAX BASIC by using the keyword TO when defining the array bounds. For more information on array bounds, see Chapter 8. When passing two-dimensional arrays as parameters, keep in mind that VAX FORTRAN addresses array elements in column major order, while VAX BASIC refers to array elements in row major order. That is, VAX FORTRAN arrays are of the form Fortran_array(column,row}, while VAX BASIC array elements are addressed as Basic_array(row,column). The VAX FORTRAN array Grid(x,y) is therefore referred to as GRID(y,x) in VAX BASIC. You should reverse references to array elements when passing arrays between VAX BASIC and VAX FORTRAN program modules. You can do this in one of two ways: • • Reverse array bounds in parameter lists Switch row and column variables within loops in your program module The following example shows a VAX BASIC program that passes a two-dimensional array to a VAX FORTRAN subprogram. Example VAX BASIC Main Program: PROGRAM call_f ortran ! The VAX BASIC main program prints the array before calling the subroutine EXTERNAL SUB forsub (WORD DIM(,) BY REF) DIM WORD array_x(1 TO 10, 1 TO 6) FOR column = 1 TO 6 FOR row = 1 TO 10 array_x(row,column)=(10•row + column) PRINT array_x(row,column); NEXT row PRINT NEXT column PRINT CALL forsub(array_x(,) BY REF) END PROGRAM 21-10 Using VAX BASIC in the Common Language Environment FORTRAN Subprogram: C C 20 The FORTRAN subprogram receives and then prints the same array SUBROUTINE forsub(f_array) INTEGER*2 f_array(5,10) DO 20 row= 1,5 TYPE*· (f_array(row,column), column= 1,10) CONTINUE RETURN END You can pass only the data types that VAX BASIC and VAX FORTRAN have in common. You cannot pass a complex number from a VAX FORTRAN program to a VAX BASIC program, because VAX BASIC does not support complex numbers. However, you can pass a complex number as two floating-point numbers and treat them independently in the VAX BASIC program. 21.4 Calling System Routines The steps for calling system routines are the same as those for calling any external routine. However, when calling system routines, you need to provide additional information, which is discussed in the following sections. 21.4.1 VAX/VMS Run-Time Library Routines The VAX/VMS Run-Time Library routines are grouped according to the types of tasks they perform. The routines in each group have a prefix that identifies them as members of a particular VAX/VMS Run-Time Library facility. Table 21-2 lists all the language-independent Run-Time Library facility prefixes and the types of tasks each facility performs. Using VAX BASIC in the Common Language Environment 21-11 Table 21-2: 21.4.2 Run-Time Library Facilities Facility Prefix Types of Tasks Performed DTK$ DECtalk routines that are used to control DIGITAL's DECtalk device LIB$ General purpose routines that obtain records from devices, manipulate strings, convert data types for 1/0, allocate resources, obtain system information, signal exceptions, establish condition handlers, enable detection of hardware exceptions, and process cross-reference data MTH$ Mathematics routines that perform arithmetic, algebraic, and trigonometric calculations OTS$ Language-independent support routines that perform tasks such as data type conversions as part of a compiler's generated code PPL$ Parallel processing routines that help you implement concurrent programs on single-CPU and multiprocessor systems SMG$ Screen management routines that are used in designing, composing, and keeping track of complex images on a video screen STR$ String manipulation routines that perform such tasks as searching for substrings, concatenating strings, and prefixing and appending strings System Service Routines System services are system routines that perform a variety of tasks such as controlling processes, communicating among processes, and coordinating I/O. Unlike the VAX/VMS Run-Time Library routines, which are divided into groups by facility, all system services share the same facility prefix (SYS$). However, these services are logically divided into groups that perform similar tasks. Table 21-3 describes these groups. 21-12 Using VAX BASIC in the Common Language Environment July 1988 Table 21-3: 21.4.3 System Services Group Types of Tasks Performed AST Allows processes to control the handling of ASTs Change Mode Changes the access mode of particular routines Condition Handling Designates condition handlers for special purposes Event Flag Clears, sets, reads, and waits for event flags, and associates with event flag clusters Information Returns information about the system, queues, jobs, processes, locks, and devices Input/Output Performs IjO directly, without going through VAX RMS Lock Management Enables processes to coordinate access to shareable system resources Logical Na mes Provides methods of accessing and maintaining pairs of character string logical names and equivalence names Memory Management Increases or decreases available virtual memory, controls paging and swapping, and creates and accesses shareable files of code or data Process Control Creates, deletes, and controls execution of processes Security Enhances the security of VAX/VMS systems Time and Timing Schedules events, and obtains and formats binary time values System Routine Arguments All of the system routine arguments are described in terms of the following information: • • • • VMS usage Data type Type of access allowed Passing mechanism Using VAX BASIC in the Common Language Environment 21-13 VMS usages are data structures that are layered on the standard VMS /VMS data types. For example, the VMS usage mask_longword signifies an unsigned longword integer that is used as a bit mask, and the VMS usage floating_point represents any VAX/VMS floating-point data type. Table 21-4 lists all the VMS usages and the VAX BASIC statements you need to implement them. Table 21-4: VMS Usages VMS Usage VAX BASIC Implementation access_bit_names Not applicable (NA) access_mode BYTE (signed) address LONG address_range LONG address_range (1) or RECORD Address_range LONG beginning_address LONG ending_address END RECORD arg-1ist NA ast_procedure EXTERNAL LONG FUNCTION asLproc 1 boolean LONG byte_signed BYTE byte_unsigned BYTE 2 channel WORD char_string STRING complex_number RECORD complex REAL reaLpart REAL imaginary-part END RECORD cond_value LONG context LONG 1 Use the LOC function to pass the address of an AST routine to a system service. Specify BY VALUE for the passing mechanism. 2 Although unsigned data structures are not directly supported in VAX BASIC, you can substitute the signed equivalent provided you do not exceed the range of the signed data structure. 21-14 Using VAX BASIC in the Common Language Environment Table 21-4 (Cont.): VMS Usages VMS Usage VAX BASIC Implementation date_time BASIC$QUADWORD 3 device_name STRING eLcluster_name STRING eLnumber LONG exiLhandler_block RECORD EHCB LONG flink LONG handler_addr BYTE arg_count BYTE FILL(3) LONG status_value_addr END RECORD fab NA file_protection LONG floating_point SINGLE DOUBLE GFLOAT HFLOAT function_code RECORD function-code WORD major-function WORD subfunction END RECORD identifier LONG io_status_block RECORD iosb WORD iosb_field(l to 4) END RECORD 3 The definition of the RECORD structures are included in the VAX BASIC system definitions text library. See Section 21.4.4 for more information. Using VAX BASIC in the Common Language Environment 21-15 Table 21-4 (Cont.): VMS Usages VMS Usage VAX BASIC Implementation item-1isL2 RECORD item-1.isLtwo GROUP item(lS) VARIANT CASE WORD comp-1.ength WORD code LONG comp_address CASE LONG terminator END VARIANT END GROUP END RECORD item-1isL3 RECORD item-1.isL3 GROUP item (15) VARIANT CASE WORD buf-1.en WORD code LONG buffer-address LONG length_address CASE LONG terminator END VARIANT END GROUP END RECORD item-1.ist_pair RECORD item-1.isLpair GROUP item(lS) VARIANT CASE LONG code LONG item_value CASE LONG terminator END VARIANT END GROUP END RECORD item-1.isLpair 21- 16 Using VAX BASIC in the Common Language Environment Table 21-4 (Cont.): VMS Usages VMS Usage VAX BASIC Implementation item_quota-1ist RECORD item_quota-1ist GROUP quota(n) VARIANT CASE BYTE quota_name LONG item_value CASE BYTE lisLend END VARIANT END GROUP END RECORD locLJ.d LONG lock_status_block NA lock_value_block NA logical _name STRING longworcLsigned LONG longword_unsigned LONG 2 mask_byte BYTE mask-1ongword LONG mask_quadword BASIC$QUADWORD 3 mask_word WORD nulLarg A null argument is indicated by a comma used as a placekeeper in the argument list. octaword_signed BASIC$0CTAWORD octaword_unsigned BASIC$0CTAWORD page_protection LONG procedure EXTERNAL LONG FUNCTION proc process_id LONG process_name STRING 2 Although unsigned data structures are not directly supported in VAX BASIC, you can substitute the signed equivalent provided you do not exceed the range of the signed data structure. 3 The definition of the RECORD structures are included in the VAX BASIC system definitions text library. See Section 21.4.4 for more information. Using VAX BASIC in the Common Language Environment 21-17 Table 21-4 (Cont.): VMS Usages VMS Usage VAX BASIC Implementation quad worcLsigned BASIC$QUADWORD 3 quadword_unsigned BASIC$QUADWORD 3 rights_holder BASIC$QUADWORD 3 rights_id LONG rah NA section_id BASIC$QUADWORD 3 section_name STRING system_access_id BASIC$QUADWORD 3 time_name STRING uic LONG user_arg LONG varying_arg Dependent upon application. vector_byte_signed BYTE array(n) vector_byte_unsigned BYTE array(n) 2 vector-1ongword_signed LONG array(n) vector-1ongword_unsigned LONG array(n) 2 vector_quadworcLsigned NA vector_quad word_unsigned NA vector_worcLsigned WORD array(n) vector_ word_unsigned WORD array(n) 2 worcLsigned WORD word_unsigned WORD 2 2 Although unsigned data structures are not directly supported in VAX BASIC, you can substitute the signed equivalent provided you do not exceed the range of the signed data structure. 3 The definition of the RECORD structures are included in the VAX BASIC system definitions text library. See Section 21.4.4 for more information. 21-18 Using VAX BASIC in the Common Language Environment If a system routine argument is optional, it will be indicated in the format section of the routine description in one of two ways: [,optional-argument] ,[optional-argument] If the comma appears outside the brackets, you must either pass a zero by value or use a comma in the argument list as a placeholder to indicate the place of the omitted argument. If this is the last argument in the list, you must still include the comma as a placeholder. If the comma appears inside the brackets, you can omit the argument altogether as long as it is the last argument in the list. 21.4.4 Including Symbolic Definitions To enhance program development, VAX BASIC allows you to use symbolic definitions. Symbolic definitions are names or symbols associated with values. These symbols are used in many ways; the value associated with a symbol can be a status code, a mask, or an offset into a data structure. Many system routines depend on values that are defined in separate symbol definition files. For example, the status code for successful completion has a value of one. However, this code for successful completion is defined in the system library (STARLET) as the symbol SS$_NORMAL. A program might compare the status code returned by a system service to either the symbolic constant SS$_NORMAL or the integer value 1. The program would execute the same way in either case. In the first case, the value for SS$_NORMAL is supplied at link time by the VAX/VMS Linker. In the second case, the value one is included in the program as a literal constant. The advantages of using symbolic definitions are as follows: • • • Because symbolic definition names are mnemonic, the program is easier to read and understand. It is easier to write the symbolic definition and let the VAX/VMS Linker fill in the value, than to look up the value associated with the symbol and include that value in the program. Should the value associated with a symbol ever change, you must relink the program. To change a hard-coded definition, you must edit the source file, then recompile and relink. Symbolic definitions used by system services are located in the default system library, STARLET.OLB. Using VAX BASIC in the Common Language Environment 21-19 For Run-Time Library routines, the only time that you need to include symbolic definitions is when you are calling an SMG$ routine, or when you are calling a routine that is a jacket to a system service. (A jacket routine in the Run-Time Library is a routine that provides a simpler, more easily used interface to a system service.) If you call a routine in the SMG$ facility, you must include the definition file SMGDEF. All system services, however, require that you include SSDEF to check status. Many other system services require other symbol definitions as well. To determine whether or not you need to include other symbolic definitions for the system service you want to reference, refer to the documentation for that service. If the documentation states that values are defined in the specified macro, you must include those symbolic definitions in your program. VAX BASIC provides a text library that contains symbolic definitions that can be accessed using the %INCLUDE directive. In the following example, the definition file, SMGDEF is included from the text library SYS$LIBRARY:BASIC$STARLET.TLB: Y.INCLUDE "SMGDEF" Y.FROM Y.LIBRARY "SYS$LIBRARY:BASIC$STARLET.TLB" For more information on including text libraries, see Chapter 18. 21.4.5 Condition Values Many system routines return a condition value that indicates success or failure. If a condition value is returned, you should check this value after you call a system routine and control returns to your program. Condition values indicating success always appear first in the list of condition values for a particular routine, and success codes always have odd values. A success code that is common to many system routines is the condition value SS$_NORMAL, which indicates that the routine completed normally and successfully. You can test for this condition value as follows: ret_status = SMG$CREATE_PASTEBOARD(pb_id) IF (ret_status <> SS$_NORMAL) THEN CALL LIB$STOP(ret_status BY VALUE) END IF Because all success codes have odd values, you can check a return status for any success code. For example, you can cause execution to continue only if a success code is returned by including the following statements in your program. 21-20 Using VAX BASIC in the Common language Environment ret_status = SMG$CREATE_PASTEBOARD(pb_id) IF (ret_status AND 1%) = 01. THEN CALL LIB$STOP(ret_status BY VALUE) END IF In general, you can check for a particular success or failure code or you can test the condition value returned against all success codes or all failure codes. 21.5 Examples of Calling System Routines This section provides complete examples of calling system routines from VAX BASIC. In addition to the examples provided here, the VAX/VMS Run-Time Library Routines Reference Manual and the VAX/VMS System Services Reference Manual also provide examples for selected routines. Refer to these manuals for help on the use of a specific system routine. The following example uses a function that invokes the SYS$TRNLNM system service. SYS$TRNLNM translates a logical name to an equivalence name. It places the equivalence name string into a string variable you supply in the parameter list. System services never change a string variable's length. Therefore, if you use a system service that returns a string, be sure that the receiving string variable is long enough for the returned data. You can make sure of this in one of two ways: • • Define the string variable's length in a MAP, COMMON or RECORD definition. Assign a long string to the variable (for example, A$ = SP ACE$(80)). This pre-extends the variable so that it is long enough to receive all of the returned data. Example 10 !This function attempts to translate a logical name while searching !through all of the tables defined in LNM$DCL_LOGICAL. If the translation !is successful, $TRNLNM returns the equivalence name string. FUNCTION STRING Translate(STRING Logical_name) EXTERNAL LONG FUNCTION SYS$TRNLNM (LONG, STRING, STRING, LONG, ITEM_LIST) EXTERNAL LONG CONSTANT LNM$M_CASE_BLIND, LNM$_STRING, SS$_NORMAL !Declare the parameters DECLARE LONG attributes, trans_status DECLARE WORD equiv_len & Using VAX BASIC in the Common Language Environment 21-21 !Declare the value returned by the function. DECLARE LONG CONSTANT Buffer_length = 266 RECORD item_list GROUP item (1) VARIANT CASE WORD Buf_len WORD Code LONG Buffer_address LONG Length_address CASE LONG Terminator END VARIANT END GROUP item END RECORD item_list !Declare an instance of the record DECLARE ITEM_LIST TRNLNM_ITEMS !Define a common area for Translation_buffer COMMON (Trans_buffer) & STRING Translation_buffer = Buffer_length !Setting TRN$LNM to not distinguish between uppercase and lowercase !letters in the logical name to be translated Attributes = LNM$M_CASE_BLIND !Assign values to each record item TRNLNM_ITEMS::item(O)::Buf_len = Buffer_length TRNLNM_ITEMS::item(O)::Code = LNM$_STRING TRNLNM_ITEMS::item(O)::Buffer_address = LOC(Translation_buffer) TRNLNM_ITEMS::item(O)::Length_address = LOC(Equiv_len) TRNLNM_ITEMS::item(1)::Terminator = OY. !Invoke the function TRANS_STATUS = SYS$TRNLNM(attributes, 11 LNM$DCL_LOGICAL 11 , logical_name, & ,trnlnm_items) !Check the condition value IF trans_status AND SS$_NORMAL THEN Translate = LEFT(Translation_buffer, Equiv_len) ELSE Translate = 1111 END IF END FUNCTION This next example is a complete program that demonstrates the use of the system service $QIOW. Unlike SYS$QIO, SYS$QIOW performs synchronously; SYS$QIOW returns a condition value to the caller after IJO operation is complete. 21-22 Using VAX BASIC in the Common Language Environment Example 10 !Declare SYS$QIOW as an EXTERNAL FUNCTION EXTERNAL LONG FUNCTION SYS$QIOW(,WORD BY VALUE.LONG BY VALUE.WORD DIM() & BY REF,,,STRING BY REF.LONG BY VALUE,, & LONG BY VALUE, , ) !Declare SYS$ASSIGN as an EXTERNAL FUNCTION EXTERNAL LONG FUNCTION SYS$ASSIGN(STRING,WORD,,) EXTERNAL LONG CONSTANT IO$_WRITEVBLK !Declare the parameters DECLARE STRING my_term, out_str, & WORD term_chan, counter, stat_block(3),& LONG ret_status, msg_len, car_cntrl out_str = "Successful $QIOW output!" my_term = "SYS$COMMAND" msg_len = LEN(out_str) car_cntrl = 32% !Assign a channel to the terminal ret_status = SYS$ASSIGN(my_term, term_chan, ,) CALL LIB$STOP(ret_status BY VALUE) IF (ret_status AND 1%) = 0% !Output the message four times FOR counter = 1% to 4% ret_status = SYS$QIOW(,term_chan BY VALUE, IO$_WRITEVBLK BY VALUE, & stat_block() BY REF,, ,out_str BY REF, & msg_len BY VALUE,,car_cntrl BY VALUE,,) CALL LIB$STOP(ret_status BY VALUE) IF (ret_status AND 1%) = 0% CALL LIB$STOP(stat_block(O%) BY VALUE) & IF (stat_block(O%) and 1%) = oi NEXT counter END Output Successful $QIOW output! Successful $QIOW output! Successful $QIOW output! Successful $QIOW output! In addition to invoking the function SYS$QIOW, the previous example also invokes the function SYS$ASSIGN. This function provides a process with an 1/0 channel so that input and output operations can be performed on a logical device name (my_term). As soon as SYS$ASSIGN is invoked and a path is established to the device, a counter is set up to invoke the $QIOW function four times. Once all I\ 0 operations are complete, $QIOW returns to the caller. Using VAX BASIC in the Common Language Environment 21-23 21.6 The VAX Procedure Calling and Condition Handling Standard The primary purpose of the VAX Procedure Calling and Condition Handling Standard is to define the concepts for invoking routines and passing data between them. Some of the interface attributes that the VAX Procedure Calling and Condition Handling Standard specifies are as follows: • • • • The argument list The return of the function value Register usage Stack usage These attributes are examined in more detail in the following sections. The VAX Procedure Calling and Condition Handling Standard also defines such interfaces as the calling sequence, the argument data types and descriptor formats, condition handling, and stack unwinding. These attributes are discussed in detail in the Introduction to VAX/VMS System Routines. 21.8.1 The Argument List One of the module interfaces defined by the VAX Procedure Calling and Condition Handling Standard is the argument list. You use an argument list to pass information to a routine and receive results. An argument list is a collection of longwords in memory that represents a routine parameter list and possibly includes a function value. Figure 21-1 shows a typical argument list. 21-24 Using VAX BASIC in the Common Language Environment Figure 21-1 : Structure of a VAX Argument List l 0 n arg1 arg2 . argn ZK-5503-86 The VAX/VMS operating system requires that the first longword be present. This longword stores the number of arguments (the argument count: n) as an unsigned integer value in the low byte of the longword. The remaining 24 bits of the first longword are reserved for DIGITAL use and should be zero. The longwords labeled arg1 through argn are the actual parameters, which can be any of the following: • • • An uninterpreted 32-bit value (passed by value) An address (passed by reference) An address of a descriptor (passed by descriptor) The forms of the arguments in the argument list depend on the passing mechanisms specified. The argument list contains the parameters that are passed to the routine. If, for example, you pass three arguments, the first one by value, the second by reference, and the third by descriptor, the argument list would contain the value of the first argument, the address of the second, and the address of the descriptor of the third. Figure 21-2 illustrates this argument list. Using VAX BASIC in the Common language Environment 21-25 Figure 21-2: Example of a VAX Argument List 0 l 3 copy of the first parameter address of the second parameter address of descriptor of the third parameter ZK-5504-86 21.6.2 The Return of the Function Value A function is a routine that returns a single value to the calling routine. The function value represents the return value that is assigned to the function's identifier during execution. According to the VAX Procedure Calling and Condition Handling Standard, a function value can be returned as either an actual value or a condition value that indicates success or failure. 21.6.3 Register and Stack Usage The VAX Procedure Calling and Condition Handling Standard defines several registers. These registers and their defined uses are listed in Table 21-5. 21-26 Using VAX BASIC in the Common Language Environment Table 21-5: Register VAX Register Usage Use PC Program counter SP Stack pointer FP Current stack frame pointer AP Argument pointer Rl Environment value (when necessary) RO, Rl Function value return registers The called routine can use registers R2 through Rll for computation and the AP register as a temporary register. The stack is a Last-In/First-Out (LIFO) temporary storage area allocated by the system for each user process. On the call stack, the system maintains information about each routine call in the current image. Each time a routine is called by a program, the hardware creates a structure on the call stack known as the call frame. The call frame for each active routine contains the following: • • • • A pointer to the call frame of the previous routine call. This pointer corresponds to the frame pointer (FP). The argument pointer (AP) of the previous routine call. The storage address of the point at which the routine was called; that is, the address of the instruction following the call to the current routine. This address is called the program counter (PC). The contents of other general registers. Based on a mask specified in the control information, the system restores the saved contents of these registers to the calling routine when control returns to it. When execution of a routine ceases, the system uses the frame pointer in the call frame of the current routine to locate the frame of the previous routine. The system then removes the call frame of the current routine from the stack. Using VAX BASIC in the Common Language Environment 21-27 21. 7 Additional Information The information provided on system routines in this chapter is general to all system services and VAX/VMS Run-Time Library routines. For specific information on these routines, refer to the VAX/VMS Run-Time Library Routines Reference Manual and the VAX/VMS System Services Reference Manual. For more information on the VAX Procedure Calling and Condition Handling Standard, see the Introduction to VAX/VMS System Routines. For information on programming considerations with external routines, refer to the Introduction to VAX/VMS System Routines and the Guide to Creating Modular Procedures on VAX/VMS. 21-28 Using VAX BASIC in the Common Language Environment Chapter 22 Libraries and Shareable Images Libraries and shareable images allow you to access program symbols and incorporate commonly used routines into your source code. This chapter describes how to create and access libraries and shareable images in VAX BASIC. 22.1 Introduction Libraries are files that can contain object modules, text modules and shareable images. There are two types of libraries: system-supplied and user-supplied. System-supplied libraries are provided by the VAX/VMS system, whereas user-supplied libraries are libraries that you create. Shareable images are similar to libraries; they contain code that can be shared by other programs. However, shareable images contain executable code rather than object code. If you have routines that are used in many programs, placing the routines in object module libraries or shareable images lets you access them at link time. You do not need to include the routines in the source code, thus shortening compilation time and conserving disk space. If you have routines that are used simultaneously by many different programs, placing the routines in installed shareable images can improve performance at run time, conserve main physical memory, and reduce paging I/O because one copy of the executable code is shared by all users. Libraries and Shareable Images 22-1 Object module libraries, shareable image libraries and shareable images can be accessed in the BASIC environment as well as at DCL command level. When you link programs at DCL command level, these libraries can contain object code created by any VAX native mode compiler or asse/mbler. When you run a program in the BASIC environment, you can access: • • Object libraries containing only VAX BASIC object code (object code from SUB, FUNCTION and PICTURE subprograms) Sharable image libraries that contain BASIC or non-BASIC object code (such as a transfer vector written in VAX MACRO) Only BASIC subprograms can be loaded into the environment with the LOAD command. For a more thorough understanding of libraries and shareable images, refer to the VMS Linker Utility Manual and the Guide to Creating Modular Library Procedures. See the VMS Install Utility Manual for more information on installing shareable images. For information on text libraries, see Chapter 18 in this manual. 22.2 System-Supplied Libraries If symbols are unresolved after the VAX/VMS Linker searches all usersupplied libraries, the linker goes on to search the files in the default system library. VAX/VMS supplies the following system libraries: 22-2 Libraries and Shareable Images July 1981 System Library Purpose IMAGELIB.OLB This library contains the symbol tables for the parts of the VAX Common Run-Time Library (RTL) that are in shareable images. If either the VAX/VMS Linker or the VAX BASIC compiler needs to search the default system library, it searches the shareable image symbol table library (IMAGELIB.OLB) first. STARLET.OLB This library is an object module library containing the object files used to create the shareable image version of the RTL, as well as other less frequently used procedures. This object library also contains modules for interfacing to VAX/VMS System Services. If program symbols remain unresolved after the VAX/VMS Linker searches IMAGELIB.OLB, the linker then searches this library. The linker searches modules in the following order: 1. 2. Modules and libraries specified in the LINK command line, in the order given User-supplied libraries (logicals of the form LNK$LIBRARY and LNK$LIBRARY_l through LNK$LIBRARY_999) Libraries and Shareable Images 22-2.1 3. Images contained in IMAGELIB.OLB 4. Modules contained in STARLET.OLB If the linker finds no needed routines in the RTL shareable images, it does not include any shareable images in the image being created. You can use the /NOSYSSHR qualifier to the LINK command to suppress the linker's search of RTL shareable images. Similarly, you can use the /NOSYSLIB qualifier to suppress the linker's search of both RTL shareable images and STARLET.OLB. Note that the VAX/VMS Linker searches user-supplied libraries before searching the default system library. This means that, if one of your modules has the same name (program symbol) as a VAX/VMS System Service or an RTL routine, the VAX/VMS Linker will include your module in the resulting image rather than the system service or RTL routine. 22.3 Creating User-Supplied Object Module Libraries You create a user-supplied object module library with the DCL command LIBRARY. To do this, you must specify a library file specification as well as a list of the program modules you want to insert into the library. For example: $ BASIC MODULE1,MODULE2 $LIBRARY/CREATE TESTLIB1.0LB MODULE1.0BJ,MODULE2.0BJ The BASIC command creates object files from MODULEl.BAS and MODULE2.BAS. The LIBRARY command creates an object module library named TESTLIBl.OLB and inserts MODULEl.OBJ and MODULE2.0BJ into it. See the VAX/VMS DCL Dictionary for more information on the LIBRARY command. 22.3.1 Accessing User-Supplied Object Module Libraries in the BASIC Environment Within the BASIC environment, VAX BASIC allows you to automatically access user-supplied object module libraries containing object files created by VAX BASIC. To do this, you must assign the logical name BASIC$LIBn to each library you wish to access, where n represents a number from 0 to 9. For example: $ASSIGN USER$$DEV:[SMITH]TESTLIB.OLB BASIC$LIBO Libraries and Shareable Images 22-3 After you enter this command, a program executing in the BASIC environment automatically accesses USER$$DEV:[SMITH]TESTLIB.OLB to resolve program symbols. Note that this command assigns BASIC$LIBO as a process-wide logical name. A privileged user can also assign a VAX BASIC library as a group- or system-wide logical name. 22.3.2 Accessing User-Supplied Object Module Libraries at DCL Level To access user-supplied object module libraries at DCL level, you must specify the /LIBRARY qualifier to the DCL command LINK. For example: $ LINK MAIN,TESTLIB/LIBRARY This command causes the linker to search TESTLIB.OLB if there are unresolved symbols in the VAX BASIC object module MAIN.OBJ. You can also explicitly include a module from a library with the /INCLUDE qualifier: $ LINK MAIN,TESTLIB/LIBRARY/INCLUDE = (module1,module2) This command causes the VAX/VMS Linker to include module1 and module2 from TESTLIB.OLB, whether or not it needs these modules to resolve symbols. As in the BASIC environment, BASIC at DCL level allows you to access user-supplied object module libraries automatically. However, a program executing at DCL level does not automatically search libraries that are assigned to the logical name BASIC$LIBO. Instead, the linker searches libraries that are assigned to the logical name LNK$LIBRARY. If you have more than one library for the linker to search, you must number these libraries consecutively otherwise the linker does not search past the first missing logical name. The linker allows you to number libraries from 1 through 999. For example: $ASSIGN USER$$DEV:[KELLY]TESTLIB.OLB LNK$LIBRARY $ASSIGN USER$$DEV:[KELLY]TESTLIB1.0LB LNK$LIBRARY_1 $ASSIGN USER$$DEV:[KELLY]TESTLIB2.0LB LNK$LIBRARY_2 After you issue these commands, a program executing at DCL level automatically accesses USER$$DEV:[KELLY]TESTLIB.OLB, USER$$DEV:[KELLY]TESTLIB1.0LB and USER$$DEV:[KELLY] TESTLIB2.0LB to resolve program symbols. 22-4 Libraries and Shareable Images On MicroVAX/VMS systems, LNK$LIBRARY_l is already used by the system; therefore, you should begin your assignments with LNK$LIBRARY_2 and number any additional libraries consecutively. On other VAX/VMS systems, number the first library as LNK$LIBRARY, the second as LNK$LIBRARY_l, the third as LNK$LIBRARY_2, and so on. 22.4 Shareable Images Shareable images are not directly executable. They contain executable code that can be shared by other images and are intended to be included by the VAX/VMS Linker in other images. You can access shareable images both in the BASIC environment and at DCL level, as described in the next two sections. The benefits of using shareable images include • • • • • Conserving disk storage space Conserving main physical memory Reducing paging IfO Allowing shared memory-resident data bases Eliminating the need to relink programs that access a new version of a shared routine Note that some of these benefits can only be realized if the shareable image is installed with the VAX/VMS Install Utility (INSTALL). To create a shareable image, use the /SHAREABLE qualifier to the DCL command LINK. In addition, you must specify at least one object module. For example: $ LINK/SHAREABLE prog1 This command creates an image that can be linked to other programs. You cannot execute a shareable image with the DCL command RUN. When a program is linked with a shareable image, the required shareable image code is not included in the created executable image on disk. This code is included by the image activator at run time. Therefore, many programs can reside on disk and be bound with a particular shareable image, and only one physical copy of that shareable image file needs to exist on disk. Libraries and Shareable Images 22-5 If a shareable image has been installed, you conserve physical memory and potentially reduce paging I/O. In this case, many processes can include the physical memory pages of an installed shareable image in their address space. This reduces the requirements for physical memory. Paging occurs when a process attempts to access a virtual address that is not in the process working set. When this page fault occurs, the page is either in a disk file, in which case paging I/O is required, or is already in physical memory. If a page fault occurs for a shared page, the shared page may already be resident in memory and in this case, no paging I/O is required. 22.4.1 Accessing Shareable Images in the BASIC Environment Within the BASIC environment, you can access only shareable images contained in shareable image libraries when you issue the DCL command RUN. VAX BASIC always searches the system shareable image library, SYS$LIBRARY:IMAGELIB.OLB. To cause VAX BASIC to search an additional shareable image library, you must first create the shareable image library and then assign it to the logical name BASIC$LIB. To create a shareable image library, you must use the /CREATE and /SHARE qualifiers to the DCL command LIBRARY. You must also specify the name of the library as well as the names of the shareable images that you wish to insert. For example: $ LIBRARY/CREATE/SHARE library_name prog1 Once you have created the library, you must assign it to the logical name BASIC$LIBn where n represents a number from 0 to 9. For example: $ ASSIGN DEV$$DISK: [BOB.LIBRARIES]library_name BASIC$LIBO After you issue this command, a program executing in the BASIC environment automatically accesses library_name as a shareable image. 22-6 Libraries and Shareable Images 22.4.2 Accessing Shareable Images at DCL Level To access a shareable image at DCL level, you must follow these steps: 1. Write and compile a program unit that is to be inserted into a shareable image. 2. Create an options file required for the link operation. 3. Link the program with the qualifier /SHAREABLE and specify the options file with the /OPTION qualifier. 4. Write a main program that accesses the routine in the shareable image. 5. Compile the main program and link it with the shareable image. The following example is an illustration of how to access a shareable image at DCL level using these five steps. Step 1: Write and compile a program unit that is to be inserted into a shareable image. !Program name - ADD.BAS FUNCTION REAL ADD (LONG A, LONG B) ADD = A + B FUNCTIONEND Step 2: Create an options file required for the link operation. !Program name - ADDSUB.OPT UNIVERSAL = ADD Step 3: Link the program with the qualifiers /SHAREABLE and /OPTION. $ LINK/SHAREABLE ADD, ADDSUB/OPTION Copy the shareable image to SYS$SHARE:, or assign a logical name to the full image file specification. Step 4: Write a main program that accesses the routine in the shareable image. !Program name - CALLADD.BAS EXTERNAL REAL FUNCTION ADD (LONG, LONG) DECLARE LONG X,Y x =1 y =2 PRINT ADD(X,Y) END Libraries and Shareable Images 22-7 Step 5: Compile the main program and link it with the shareable image. $ LINK CALLADD,ADDMAIN/OPTION In order to link CALLADO with the shareable image ADD, you must have a VAX/VMS Linker options file specifying that ADD is a shareable image: !Options file - ADDMAIN.OPT ADD/SHAREABLE Now you are ready to execute the program. When you do this, the image activator attempts to locate the shareable image in the directory SYS$SHARE:. If you want the image activator to access a shareable image outside SYS$SHARE:, you must assign a logical name to the shareable image before you execute the program. That is, you must assign the full file specification of the shareable image to the name of the shareable image, as follows: $ DEFINE MYSHR DISK$WORKDISK: [MYDIR]MYSHR This is a very simple example of using shareable images. For a thorough understanding of shareable images, see the VAX/VMS Linker Reference Manual. 22-8 Libraries and Shareable Images Chapter 23 Extracting Record Definitions from the VAX Common Data Dictionary This chapter describes how to extract record definitions from the VAX Common Data Dictionary (CDD). !3. 1 Introduction to the COD The VAX Common Data Dictionary (CDD) is a tool that supports sharing of data definitions by VAX/VMS programming languages and VAX Information Architecture products. Each language or product translates the generic definitions stored in the CDD into language- or productspecific definitions that it can use. Because CDD data definitions can be used by several different products, programmers do not have to write special programs to allow different products to work together or store redundant copies of data files. Also, because CDD data definitions are centrally located, you can change several programs by modifying a single data definition. There are two types of dictionaries: DMU-format and CDO-format. DMUformat dictionaries are the only type used prior to CDD /Plus Version 4.0. CDO-format dictionaries are introduced in CDD /Plus Version 4.0; they have the capability of recording dependency information, as described in Chapter 24. The two types of dictionaries can coexist on a system. Refer to Chapter 24 and the CDD /Plus documention for more information on CDD/Plus. July 1988 Extracting Record Definitions from the VAX Common Data Dictionary 23-1 23.2 Extracting COD Data Definitions in VAX BASIC A data definition is one type of CDD object. In VAX BASIC, you can extract only data definition objects into your program. To extract a CDD data definition in VAX BASIC, specify the %INCLUDE %FROM %CDD compiler directive and a CDD path name. You can use this to extract a data definition from either a DMU-format or CDO-format dictionary. For example: %INCLUDE %FROM %CDD "CDD$TOP.BASIC.BASICDEF" The %INCLUDE %FROM %CDD directive extracts the CDD data definition you specify, and translates it into VAX BASIC syntax. In VAX BASIC, the syntax for data definitions or data structures is defined by the RECORD statement. Once a CDD data definition is translated into RECORD statement syntax, you can reference the name of the RECORD statement in your VAX BASIC programs. After compilation, the translated RECORD statement is included as a part of your program's listing. The following is an example of a CDD -data definition and the translated VAX BASIC RECORD statement. In general, the examples in this chapter are of DMU-format CDD data definitions that were written in the VAX Common Data Definition Language (CDDL). Chapter 24 contains additional information about using the CDO utility to create CDO-format definitions for use with CDD/Plus. In all examples, the CDDL data definition is displayed in lowercase letters and the translated RECORD statement is displayed in uppercase letters. COOL Definition define record cdd$top.basic.basicdef description is /* This is an example record containing only data types supported by VAX BASIC */. employee structure. datatype is text street size is 30 characters. city datatype is text size is 30 characters. state datatype is text size is 2 characters. 23-2 Extracting Record Definitions from the VAX Common Data Dictionary July 1981 zip_code structure. new datatype is packed decimal size is 4 digits. datatype is packed decimal old size is 5 digits. end zip_code structure. emp_number datatype is signed word. wage_class datatype is text size is 2 characters. datatype is d_floating. salary_ytd end employee structure. end basicdef. Translated RECORD Statement Cl Cl Cl Cl Cl Cl Cl Cl Cl Cl Cl Cl Cl Cl %INCLUDE %FROM %CDD "CDD$TDP.BASIC.BASICDEF" This is an example record containing only data types supported by VAX BASIC RECORD EMPLOYEE UNSPECIFIED STRING STREET = 30 TEXT STRING CITY = 30 TEXT STRING STATE = 2 TEXT GROUP ZIP_CODE UNSPECIFIED DECIMAL(4 ,0 ) NEW PACKED DECIMAL DECIMAL(5 ,0 ) OLD PACKED DECIMAL END GROUP WORD EMP_NUMBER SIGNED WORD STRING WAGE_CLASS = 2 TEXT D_FLOATING DOUBLE SALARY_YTD END RECORD When VAX BASIC translates a CDD data definition, it does the following: • • For DMU-format definitions, it takes the field name specified in the first CDDL STRUCTURE statement and assigns that name to the VAX BASIC RECORD. For CDO-format definitions, it takes the record name from the CDO DEFINE RECORD statement and assigns that name to the VAX BASIC record. In the preceding example, for instance, the first CDDL structure statement is employee structure. When VAX BASIC translates this line of the CDD data definition, it names the RECORD EMPLOYEE. If this first structure is unnamed, VAX BASIC signals the error "Record from CDD does not have a record name". Translates the field name in any subsequent CDDL STRUCTURE statement to be the name of a group. For instance, in the preceding example, the second STRUCTURE statement, zip_code structure, is translated to GROUP ZJP_CODE. July 1988 Extracting Record Definitions from the VAX Common Data Dictionary 23-3 • Translates subordinate field names in CDDL STRUCTURE statements to elementary components in the RECORD statement. In the preceding example, for instance, the subordinate field name street is translated to STRING STREET. If you specify the /LIST qualifier, when VAX BASIC translates a CDD data definition, it does the following: • • • Begins each line of the RECORD statement with the letter "C" followed by a number. The "C" tells you that the RECORD statement was translated from a CDD data definition. The number tells you the nesting level of the %INCLUDE %FROM %CDD directive within the source program. For example, if your source program directly extracts a CDD record definition, then each line is preceded by a "Cl". If the CDD extraction came from a file included in the source program, then each line of the record definition is preceded by a "C2", and so on. Includes the explanatory text in the CDDL DESCRIPTION clause as comment fields. Translates the data type text in the subordinate field to a comment field that tells you the data type of each elementary RECORD component. For example, the comment! TEXT tells you that STRING STREET is a text data type. VAX BASIC requires that a CDD data definition include a minimum of one structure to be translated into a RECORD statement. If a CDD data definition contains only a single subordinate field (without a structure), VAX BASIC signals an error message because it cannot give a name to the RECORD statement. For this reason, you cannot include a CDO FIELD definition in a VAX BASIC program. You can, however, include CDO RECORD definitions that contain that field. See Chapter 24 for more information. For more information on how VAX BASIC translates CDD data types, see Section 23. 8. 23-4 Extracting Record Definitions from the VAX Common Data Dictionary July 1988 23.3 CDD Path Names When you extract a COD record definition with the VAX BASIC %INCLUDE %FROM %COD directive, you specify a path name. The path name tells COD where to locate a particular data definition in its directory. A COD path name consists of a string of names separated by periods and enclosed in quotation marks. The origin is the top, or root, of a dictionary directory. This directory contains other dictionary directories and objects. For example: %INCLUDE %FROM %CDD 11 CDD$TOP.BASIC.EMPLOYEE_DATA 11 In this example, the path name CDD$TOP.BASIC.EMPLOYEE_DATA points to the root dictionary directory, CDD$TOP, which contains the dictionary directory BASIC, which in turn contains the object EMPLOYEE_ DATA. EMPLOYEE_DATA is a data definition. VAX BASIC allows three types of valid path name parameters when referring to CDD dictionary definitions. They differ in the method of specifying the dictionary origin. • Dictionary anchor path name An anchor path name begins with an anchor, which is a VMS directory specification, as the dictionary origin. The anchor specifies the VMS directory that contains the COO dictionary. This is known as the CDO naming convention. In the following example, MYNODE::DISK$2:[MYDIRECTORY] is the anchor: MYNODE: :DISK$2: [MYDIRECTORY]PERSONNEL.EMPLOYEES_REC • CDD$TOP path name You use this to refer to either DMU-format dictionary definitions or COO-format dictionary definitions in a compatibility dictionary. The path origin is always CDD$TOP. This is known as the DMU naming convention. For example: CDD$TOP.PERSONNEL.EMPLOYEES_REC • Relative path name You can omit the origin of a path name and specify a relative path name. To do this, you must first assign the name of a dictionary directory to the logical name CDD$DEFAULT. For example: $DEFINE CDD$DEFAULT CDD$TOP.BASIC July 1988 Extracting Record Definitions from the VAX Common Data Dictionary 23-5 Using this command defines the dictionary directory CDD$TOP.BASIC as the default start of your directory. You can override the defined default by specifying either CDD$TOP or an anchor in a path name (thereby specifying a full path name as described previously). Any path name that does not begin with either CDD$TOP or an anchor is automatically appended to the current CDD$DEFAULT. For example, you can specify: PERSONNEL.EMPLOYEES_REC If CDD$DEFAULT is MYNODE::MY$DISK:[MYDIR], the relative path name is the same as: MYNODE: :MY$DISK: [MYDIR]PERSONNEL.EMPLOYEES_REC. Similarly, if CDD$DEFAULT is CDD$TOP.MYDIR, the relative path name is the same as: CDD$TOP.MYDIR.PERSONNEL.EMPLOYEES_REC. 23.4 Specifying a COD History List Entry When you extract a record from the CDD, you have the option of entering a history list entry in the CDD data base. The history list entry provides a history of users that access the CDD. You enter a history list entry by specifying either the DCL command BASIC/ AUDIT or the BASIC environment command SET/ AUDIT or COM/ AUDIT. For example: $ BASIC/LIST/SHOW=CDD/AUDIT="Copied for Yearly Employee Analysis" Note that instead of typing the text directly on the command line, you can also specify a file specification that contains the history entry. When you specify a history list entry with AUDIT, the following information is included in the history log: • • • 23-6 Your user name, UIC, and process name The entry text you specify That the access was by way of a VAX BASIC program Extracting Record Definitions from the VAX Common Data Dictionary July 1988 • • That the access was an extraction (marked in the history log as COMPILE) The name of the program module that requested the extraction and the time and date of the request A history list entry is included even if errors are signaled during compilation. Therefore, you should debug your program before you specify a history list entry. The default is /NOAUDIT. 23.5 The NAME FOR BASIC Clause VAX BASIC supports the CDDL field attribute clause NAME FOR BASIC. The CDDL field attribute clause NAME FOR BASIC declares a facilityspecific name for a field. For example: name for basic is 11 subject_name$ 11 When you assign a name using the NAME FOR BASIC clause in a CDDL data definition, VAX BASIC recognizes only this name when you refer to the field. Note that when you use the NAME FOR BASIC clause, you can place dollar sign ( $ ) and percent sign ( % ) suffixes in your RECORD statement field names. The following example is a CDDL data definition containing the NAME FOR BASIC clause, and the corresponding VAX BASIC RECORD statement. CDDL Definition define record city_study description is /* This example formats data resulting from a study on the relationship between place of birth and earning potential*/. info structure. subject_name datatype text size 10 name for basic is 11 subject_name$ 11 • birth_city datatype text size 10 name for basic is "city_of_birth$". datatype signed byte salary name for basic is "salary%". end info structure. end city_study. Extracting Record Definitions from the VAX Common Data Dictionary 23-7 Translated RECORD Statement %INCLUDE %FROM %CDD CDD$TOP.BASIC.CITY_STUDY This example formats data resulting from a study on the relationship between place of bir1 and earning potential RECORD INFO UNSPECIFIED STRING SUBJECT_NAME$ = 10 TEXT STRING CITY_OF_BIRTH$ = 10 TEXT BYTE SALARY% SIGNED BYTE END RECORD 11 C1 C1 C1 C1 C1 C1 C1 C1 11 Be careful when you use the NAME FOR BASIC clause because it enables you to assign completely different names to the same field. For more information about the CDDL NAME FOR BASIC field attribute clause, see the CDD documentation. 23.6 COD Arrays The CDD supports three types of arrays: • • • Multidimensional arrays (the ARRAY clause) One-dimensional, fixed length arrays (the OCCURS clause or ARRAY clause) One-dimensional, variable length arrays (the OCCURS DEPENDING ON clause-note that VAX BASIC does not support this clause) Arrays are valid for any CDD field. VAX BASIC does not support dimensions on a RECORD statement. You cannot, therefore, declare an entire RECORD statement as an array. However, you can dimension an instance of the record. The following is an example of a CDD data definition containing arrays and the corresponding VAX BASIC RECORD statement. COOL Definition define record cdd$top.basic.array1 description is /*test arrays*/. 23-8 Extracting Record Definitions from the VAX Common Data Dictionary July 1988 array_l structure. my_byte array 0:2 my_string array 0:10 my_s_real array 0:2 0:4 my_d_real array 1:3 my_g_real occurs 4 times my_h_real occurs 4 times end array_l structure. end arrayl. data type data type data type data type data type datatype signed byte. text size 10. f_floating. d_floating. g_floating. h_floating. Translated RECORD Statement Cl Cl Cl Cl Cl Cl Cl Cl Cl %INCLUDE %FROM %CDD 11 CDD$TOP.BASIC.ARRAY1 11 test arrays RECORD ARRAY_l MY_BYTE(O TO 2) BYTE STRING MY_STRING(O TD 10) = 10 SINGLE MY_S_REAL(O TO 2,0 TO 4) DOUBLE MY_D_REAL(l TO 3) GFLOAT MY_G_REAL(l TO 4) HFLDAT MY_H_REAL(l TO 4) END RECORD UNSPECIFIED SIGNED BYTE TEXT F_FLOATING D_FLOATING G_FLOATING H_FLOATING By default, arrays in the CDD are row-major. This means that when storage is allocated for the array, the rightmost subscript varies fastest. All VAX BASIC arrays are row-major. VAX BASIC does not support columnmajor arrays. If a CDD definition containing a column-major array is extracted, VAX BASIC signals the error" <array-name> from CDD is a column major array". By default, VAX BASIC extracts an array field from the CDD with the bounds specified in the data definition. However, if you use the qualifier /OLD_VERSION=CDD_ARRAYS when you extract a data definition, VAX BASIC translates the data definition with lower bounds as zero and adjusts the upper bounds. This means that an array with dimensions of (2,5) in the CDD is translated by VAX BASIC to be an array with a lower bound of 0 and an upper bound of 3. VAX BASIC issues an informational message to confirm the array bounds when you use this qualifier. The following CDD data definition and corresponding RECORD statement were extracted with the /OLD_ VERSION=CDD_ARRAYS qualifier. Extracting Record Definitions from the VAX Common Data Dictionary 23-8.1 CDDL Definition define record cdd$top.basic.array2 description is I• test arrays with /old_version=cdd_arrays qualifier•/. array_2 structure. my_byte my_string my_s_real my_d_real my_g_real dep_item my_h_real array 0:2 array O:iO array 0:2 0:4 array i :3 occurs 4 times data type datatype datatype datatype datatype datatype signed byte. text size iO. f_floating. d_floating. g_floating. signed longword. datatype h_floating. occurs 4 times end array_2 structure. end array2. Translated RECORD Statement i Ci Ci Ci Ci Ci Ci Ci Ci Ci Ci %INCLUDE Y.FROM Y.CDD "CDD$TOP.BASIC.ARRAY2" test arrays with /old_version=cdd_arrays qualifier RECORD ARRAY_2 UNSPECIFIED BYTE MY_BYTE(O TO 2) SIGNED BYTE STRING MY_STRING(O TO iO) = iO TEXT SINGLE MY_S_REAL(O TO 2,0 TO 4) F_FLOATING DOUBLE MY_D_REAL(O TO 2) D_FLOATING GFLOAT MY_G_REAL(O TO 3) G_FLOATING LONG DEP_ITEM SIGNED LONGWORD HFLOAT MY_H_REAL(O TO 3) H_FLOATING END RECORD 23. 7 COO Variants A variant comprises two or more fields of a record that provide alternative descriptions for the same portion of a record. The following is an example of a CDD data definition containing variant fields and the corresponding VAX BASIC RECORD statement. Extracting Record Definitions from the VAX Common Data Dictionary 23-9 CDDL Definition define record cdd$top.basic.variant_example description is /• test simple variant •/. variant_example structure. my_string datatype text size 9. variants. variant. my_s_real my_d_real end variant. datatype datatype variant. my_g_real datatype my_h_real datatype end variant. end variants. my_byte datatype end variant_example structure. end variant_example. f_floating. d_floating. g_floating. h_floating. signed byte. Translated RECORD Statement 1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 Y.!NCLUDE Y.FROM Y.CDD 11 CDD$TOP.BASIC.VARIANT_EXAMPLE 11 test simple variant UNSPECIFIED RECORD VARIANT_EXAMPLE TEXT STRING MY_STRING = g VARIANT CASE F_FLOATING SINGLE MY_S_REAL D_FLOATING DOUBLE MY_D_REAL CASE G_FLOATING GFLOAT MY_G_REAL H_FLOATING HFLOAT MY_H_REAL END VARIANT MY_BYTE BYTE SIGNED BYTE END RECORD CDD data definitions sometimes contain VARIANTS OF field description statements as well as simple variants. A CDD VARIANTS OF statement names a tag variable whose value at run time determines which of the variant fields is the current variant. VAX BASIC does not support the VARIANTS OF statement. If a CDD data definition containing a VARIANTS OF statement is extracted, VAX BASIC signals the informational message, "%BASIC-I-CDDTAGIGN, <number> tag value from CDD ignored" and treats the VARIANTS OF as an ordinary variant and ignores the tag value. 23-10 Extracting Record Definitions from the VAX Common Data Dictionary 23.8 COD Data Types VAX BASIC supports only a subset of COD data types. They are described in Table 23-1. Table 23-1: Supported CDD Data Types COD Data Type VAX BASIC Translation TEXT STRING SIGNED BYTE BYTE SIGNED WORD WORD SIGNED LONGWORD LONG LFLOATING SINGLE D_FLOATING DOUBLE G_FLOATING GFLOAT H_FLOATING HFLOAT PACKED DECIMAL DECIMAL If a COD data definition containing an unsupported data type is extracted, VAX BASIC signals the informational message "CDDSUBGRO, datatype in COD not supported, substituted group for: <field-name> " and translates the data type by creating a group to contain the data type field. The group name is the name of the unsupported data type followed by the text "_VALUE". This allows you to access the field name within the group. An example of how VAX BASIC translates unsupported COD data types is shown in the following COD data definition and corresponding VAX BASIC RECORD statement. CDDL Definition define record cdd$top.basic.stock description is /* this is an example data definition that contains data types not supported by VAX BASIC •/. stock structure. product_no date_ordered status_code datatype is text size is 8 characters. datatype is date. datatype is unsigned byte. Extracting Record Definitions from the VAX Common Data Dictionary 23-11 quantity location unit_price end stock structure. end stock. datatype is unsigned longword aligned on longword. array 1:4 datatype is text size is 30 characters. datatype is longword. Translated RECORD Statement 1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 %INCLUDE Y.FROM Y.CDD 11 CDD$TOP.BASIC.STOCK 11 This is an example data definition that contains data types not supported by VAX BASIC ! UNSPECIFIED RECORD STOCK TEXT STRING PRODUCT_NO = 8 GROUP DATE_ORDERED DATE STRING STRING_VALUE = 8 END GROUP UNSIGNED BYTE GROUP STATUS_CODE BYTE BYTE_VALUE END GROUP STRING FILL = 3 UNSIGNED LONGWORD GROUP QUANTITY LONG LONG_ VALUE END GROUP TEXT STRING LOCATION(1 TO 4) = 30 GROUP UNIT_PRICE UNSIGNED LONGWORD LONG LONG_ VALUE END GROUP END RECORD Y.BASIC-I-CDDSUBGRO, data type in CDD not supported, substituted group for: STOCK::DATE_ORDERED. Y.BASIC-I-CDDSUBGRO, data type in CDD not supported, substituted group for: STOCK: :STATUS_CODE. Y.BASIC-I-CDDSUBGRO, data type in CDD not supported, substituted group for: STOCK::QUANTITY. Y.BASIC-I-CDDSUBGRO, data type in CDD not supported, substituted group for: STOCK: :UNIT_PRICE. Table 23-2 describes the CDD data types not supported by VAX BASIC and their translation. 23-12 Extracting Record Definitions from the VAX Common Data Dictionary Table 23-2: Unsupported CDD Data Types CDD Data Type VAX BASIC Translation UNSIGNED BYTE GROUP cdd-field-name BYTE BYTE_VALUE END GROUP UNSIGNED WORD GROUP cdd-field-name WORD WORD_VALUE END GROUP UNSIGNED LONGWORD GROUP cdd-field-name LONG LONG_VALUE END GROUP SIGNED QUADWORD GROUP cdd-field-name STRING STRING_VALUE = 8 END GROUP UNSIGNED QUADWORD GROUP cdd-field-name STRING STRING_VALUE = 8 END GROUP SIGNED OCTAWORD GROUP cdd-field-name STRING STRING_VALUE= 16 END GROUP UNSIGNED OCTAWORD GROUP cdd-field-name STRING STRING_VALUE = 16 END GROUP LFLOATING COMPLEX GROUP cdd-field-name SINGLE SINGLE_R_VALUE SINGLE SINGLE_LVALUE END GROUP D_FLOATING COMPLEX GROUP cdd-field-name DOUBLE DOUBLE_R_VALUE DOUBLE DOUBLE_LVALUE END GROUP G_FLOATING COMPLEX GROUP cdd-field-name GFLOAT GFLOALR_VALUE GFLOAT GFLOALLVALUE END GROUP Extracting Record Definitions from the VAX Common Data Dictionary 23-13 Table 23-2 (Cont.): Unsupported CDD Data Types COD Data Type VAX BASIC Translation H_FLOATINC COMPLEX GROUP cdd-field-name HFLOAT HFLOAT_R_VALUE HFLOAT HFLOAT-1_VALUE END GROUP ZONED NUMERIC GROUP cdd-field-name STRING STRING_VALUE= length END GROUP UNSIGNED NUMERIC GROUP cdd-field-name STRING STRING_VALUE= length END GROUP LEFT SEPARATE NUMERIC GROUP cdd-field-name STRING STRING_VALUE= length+ 1 END GROUP LEFT OVERPUNCHED NUMERIC GROUP cdd-field-name STRING STRING_VALUE = length END GROUP RIGHT SEPARATE NUMERIC GROUP cdd-field-name STRING STRING_VALUE= length+ 1 END GROUP RIGHT OVERPUNCHED NUMERIC GROUP cdd-field-name STRING STRING_VALUE= length END GROUP VARYING STRING GROUP cdd-field-name WORD WORD_VALUE STRING STRING_VALUE= length END GROUP BIT 1 GROUP cdd-field-name STRING STRING_VALUE= length /8 END GROUP DATE GROUP cdd-field-name STRING STRING_VALUE= 8 END GROUP 1 CDD specifies bit field length in bits; VAX BASIC specifies string length in bytes. If the length in bits does not divide 11 evenly Jnto bytes, VAX BASIC signals the error %BASIC-E-CDDBITFLD, field <fieldname> from CDD has bit offset or length. 23-14 Extracting Record Definitions from the VAX Common Data Dictionary Table 23-2 (Cont.): Unsupported COD Data Types COD Data Type VAX BASIC Translation POINTER GROUP cdd-field-name LONG LONG_VALUE END GROUP UNSPECIFIED GROUP cdd-field-name STRING STRING_VALUE= length END GROUP VIRTUAL FIELD Ignored The following sections describe how VAX BASIC translates CDD data types in greater detail. 23.8.1 Character String Data Types There are two CDD character string data types, TEXT and VARYING STRING. The TEXT data type translates directly into the VAX BASIC STRING data type. VARYING STRING is not a supported VAX BASIC data type; therefore, VAX BASIC creates a group to contain the field. The following example is a CDDL definition that contains both the TEXT and VARYING STRING data types and the translated VAX BASIC RECORD statement. CDDL Definition define record cdd$top.basic.strings description is I• test •/. basicstrings structure. abc datatype is text size is 10. xyz datatype is varying string size is 16. end basicstrings structure. end strings. Extracting Record Definitions from the VAX Common Data Dictionary 23-15 Translated RECORD Statement 1 %INCLUDE Y.FROM Y.CDD 11 CDD$TOP.BASIC.STRINGS 11 Ci Ci Ci Ci Ci Ci Ci Ci test RECORD BASICSTRINGS STRING ABC = iO GROUP XYZ WORD WORD_ VALUE STRING STRING_VALUE = i6 END GROUP END RECORD UNSPECIFIED TEXT VARYING STRING ................ i Y.BASIC-I-CDDSUBGRO, i: data type in CDD not supported, substituted group for: BASICSTRINGS: :XYZ. In the VARYING STRING data type, the actual character string is preceded by a 16-bit count field. Therefore, VAX BASIC creates a WORD variable to hold the specified string length. NOTE The count field preceding the VARYING STRING is actually an UNSIGNED WORD. Therefore, the count field of a VARYING STRING whose length is greater than 32767 is interpreted by VAX BASIC as a negative number. In the preceding example, the group name (XYZ) is the same name as the CDD field. Therefore, VAX BASIC supplies an additional name for the RECORD components. The supplied names are WORD_VALUE and STRING_VALUE. For example, the following program statement creates an instance of the record BASICSTRINGS, called MY_REC: iOO MAP (TEST) BASICSTRINGS MY_REC The names you use to reference these components in VAX BASIC are MY_REC::XYZ::WORD_VALUE and MY_REC::XYZ::STRING_VALUE. 23-16 Extracting Record Definitions from the VAX Common Data Dictionary 23.8.2 Integer Data Types The CDD refers to integer data types as fixed-point data types. The CDD supports BYTE, WORD, LONGWORD, QUADWORD, and OCTAWORD integer data types. Each of these data types can have the following additional attributes: • • • • • • • SIGNED UNSIGNED SIZE DIGITS FRACTION BASE SCALE In CDDL, if integer data types are not specified as being signed or unsigned, the default is unsigned. VAX BASIC supports only signed BYTE, signed WORD, and signed LONGWORD integers. If a CDDL data definition containing an unsigned BYTE, WORD, or LONGWORD integer is extracted, VAX BASIC signals the informational message "CDDSUBGRO, datatype in CDD not supported, substituted group for: <field-name> ", and creates a group to contain the field. Because the group name is the same as the CDD field name, VAX BASIC assigns a new name to the field. This is shown in the following CDD data definition and corresponding VAX BASIC RECORD statement. CDDL Definition define record cdd$top.basic.integers description is /•Test of selected integer data types•/. basicint structure. my_byte datatype is signed byte. my_ubyte datatype is byte. my_word datatype is signed word. my_uword datatype is unsigned word. my_long datatype is signed longword. my_ulong datatype is unsigned longword. end basicint structure. end integers. Extracting Record Definitions from the VAX Common Data Dictionary 23-17 Translated RECORD Statement 1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 Y.!NCLUDE Y.FROM Y.CDD 11 CDD$TOP.BASIC.INTEGERS" ! Test of selected integer data types UNSPECIFIED RECORD BASICINT BYTE MY_BYTE SIGNED BYTE GROUP MY_UBYTE UNSIGNED BYTE BYTE BYTE_ VALUE END GROUP WORD MY_WORD SIGNED WORD GROUP MY_UWORD UNSIGNED WORD WORD WORD_VALUE END GROUP LONG MY_LONG SIGNED LONGWORJ;> GROUP MY_ULONG UNSIGNED LONGWORD LONG LONG_ VALUE END GROUP END RECORD ................ 1 Y.BASIC-I-CDDSUBGRO, 1: data type in CDD not supported, substituted group for: BASICINT::MY_UBYTE. Y.BASIC-I-CDDSUBGRO, 1: data type in CDD not supported, substituted group for: BASICINT::MY_UWORD. Y.BASIC-I-CDDSUBGRO, 1: data type in CDD not supported, substituted group for: BASICINT::MY_ULONG. When the preceding data definition is extracted from the COD, VAX BASIC signals an informational message for each of the unsigned data types, and names the COD unsigned byte field BYTE_VALUE, the CDD unsigned word field WORD_VALUE, and the COD unsigned longword field LONG_VALUE. VAX BASIC does not support QUADWORD or OCTAWORD integers. If a CDD definition contains a QUADWORD or OCTAWORD integer, VAX BASIC signals the informational message "CDDSUBGRO, datatype in CDD not supported, substituted group for: <field-name> "and creates a group to contain the field and a string component within the group. The string component is 8 bytes for QUADWORD integers and 16 bytes for OCTAWORD integers. For example: 23-18 Extracting Record Definitions from the VAX Common Data Dictionary CDDL Definition define record cdd$top.basic.bigintegers description is /•Test of quadword and octaword integer data types•/. basicint structure. my_quad datatype is signed quadword. my_octa datatype is signed octaword. end basicint structure. end bigintegers. Translated RECORD Statement 1 C1 C1 C1 C1 C1 C1 C1 C1 C1 %INCLUDE Y.FROM Y.CDD 11 CDD$TOP.BASIC.BIGINTEGERS 11 ! Test of quadword and octaword integer data types RECORD BASICINT UNSPECIFIED GROUP MY_QUAD SIGNED QUADWORD STRING STRING_VALUE = 8 END GROUP GROUP MY_OCTA SIGNED OCTAWORD STRING STRING_VALUE = 16 END GROUP END RECORD Y.BASIC-I-CDDSUBGRO, data type in CDD not supported, substituted group for: BASICINT::MY_QUAD. Y.BASIC-I-CDDSUBGRO, data type in CDD not supported, substituted group for: BASICINT::MY_OCTA. The COD supports the SCALE keyword to specify an implied exponent in integer data types, and the BASE keyword to specify that the scale for a fixed-point field is to be interpreted in a numeric base other than 10. VAX BASIC does not support these integer attributes. Therefore, VAX BASIC signals the informational message "CDDATTSCA, COD specifies SCALE for <name> . Not supported", for fixed-point fields containing a SCALE specification and the error message, "CDDATTBAS, COD attributes for <name> are other than base 10", for fixed-point fields specifying a base other than 10. For example: CDDL Definition define record cdd$top.basic.funnyintegers description is /•Test of quadword and octaword integer data types •/. basicint structure. my_byte datatype is signed byte scale 2. my_long datatype is signed longword base 8. end basicint structure. end funnyintegers. Extracting Record Definitions from the VAX Common Data Dictionary 23-1 9 Translated RECORD Statement 1 C1 C1 C1 C1 C1 C1 C1 Y.!NCLUDE Y.FROM 1.CDD "CDD$TOP.BASIC.FUNNYINTEGERS" Test of quadword and octaword integer data types RECORD BASICINT UNSPECIFIED GROUP MY_BYTE SIGNED BYTE BYTE BYTE_VALUE END GROUP LONG MY_LONG SIGNED LONGWORD END RECORD Y.BASIC-I-CDDATTSCA, 1.BASIC-E-CDDATTBAS, CDD specifies SCALE for BASICINT::MY_BYTE. Not supported CDD attributes for BASICINT::MY_LONG are other than base 10 At compilation time, VAX BASIC also signals these warning errors for each reference to fields that are not base 10 or that have a SCALE. 23.8.3 Floating-Point Data Types The CDD supports F_floating, D_floating, G_floating, and H_floating data types. These correspond to the BASIC SINGLE, DOUBLE, GFLOAT, and HFLOAT data types, respectively. As with fixed-point data types, the CDD also allows the specification of scale and base for floating-point data types. If a CDD data definition contains a floating-point field that specifies a SCALE or BASE, VAX BASIC signals the informational message "CDDATTSCA, CDD specifies SCALE for <name>. Not supported" or the error message "CDDATTBAS, CDD attributes for <name> are other than base 1O". For example: CDDL Definition define record floats description is /*Test of floating-point data types*/. basicfloat structure. my_single datatype is f_floating scale 3. my_double datatype is d_floating base 16. my_gfloat datatype is g_floating. my_hfloat datatype is h_floating. end basicfloat structure. end floats. 23-20 Extracting Record Definitions from the VAX Common Data Dictionary Translated RECORD Statement C1 C1 C1 C1 C1 C1 C1 C1 C1 %INCLUDE Y.FROM Y.CDD 11 CDD$TOP.BASIC.FLOATS 11 ! Test of floating-point data types RECORD BASICFLOAT ! UNSPECIFIED GROUP MY_SINGLE F_FLOATING SINGLE SINGLE_VALUE END GROUP D_FLOATING DOUBLE MY_DOUBLE GFLOAT MY_GFLOAT G_FLOATING H_FLOATING HFLOAT MY_HFLOAT END RECORD ................ 1 Y.BASIC-I-CDDATTSCA, 1: Y.BASIC-E-CDDATTBAS, 1: CDD specifies SCALE for BASICFLOAT::MY_SINGLE. Not supported CDD attributes for BASICFLOAT::MY_DOUBLE are other than base 10 In addition, the COD supports complex floating-point numbers, whereas VAX BASIC does not support them. Complex floating-point numbers consist of a real and an imaginary part. Each part requires the same amount of storage as a simple floating-point number. Therefore, each complex floating-point number requires twice as much storage as a simple floating-point number. If a COD data definition containing complex numbers is extracted, VAX BASIC signals the informational message, "CDDSUBGRO, datatype in COD not supported, substituted group for <field-name> ", and creates a group to contain the field. As before, VAX BASIC uses the data type and _ vALUE to create the group name, but because each complex number contains both a real and an imaginary part, VAX BASIC adds an "_R" to the name of the real part and an "-1" to the name of the imaginary part. This is illustrated in the following COD data definition and corresponding VAX BASIC RECORD statement. Extracting Record Definitions from the VAX Common Data Dictionary 23-21 CDDL Definition define record cdd$top.basic.complex description is /*test complex data types */. complex structure. my_s_complex_i datatype my_d_complex_i datatype my_g_complex_i datatype my_h_complex_i datatype end complex structure. end complex. f_floating_complex. d_floating_complex. g_floating_complex. h_floating_complex. Translated RECORD Statement i Ci Ci Ci Ci Ci Ci Ci Ci Ci Ci Ci Ci Ci Ci Ci Cl Ci Ci Ci Y.!NCLUDE Y.FROM 1.CDD 11 CDD$TOP.BASIC.COMPLEX 11 test complex data types UNSPECIFIED RECORD COMPLEX GROUP MY_S_COMPLEX_i F_FLOATING_COMPLEX SINGLE SINGLE_R_VALUE SINGLE SINGLE_I_VALUE END GROUP GROUP MY_D_COMPLEX_i D_FLOATING_COMPLEX DOUBLE DOUBLE_R_VALUE DOUBLE DOUBLE_I_VALUE END GROUP GROUP MY_G_COMPLEX_i G_FLOATING_COMPLEX GFLOAT GFLOAT_R_VALUE GFLOAT GFLOAT_I_VALUE END GROUP GROUP MY_H_COMPLEX_i H_FLOATING_COMPLEX HFLOAT HFLOAT_R_VALUE HFLOAT HFLOAT_I_VALUE END GROUP END RECORD ................ 1 1.BASIC-I-CDDSUBGRO, i: data type in CDD not supported, substituted group for: COMPLEX::MY_S_COMPLEX_l. 1.BASIC-I-CDDSUBGRO, i: data type in CDD not supported, substituted group for: COMPLEX::MY_D_COMPLEX_l. 1.BASIC-I-CDDSUBGRO, i: data type in CDD not supported, substituted group for: COMPLEX::MY_G_COMPLEX_i. 1.BASIC-I-CDDSUBGRO, i: data type in CDD not supported, substituted group for: COMPLEX::MY_H_COMPLEX_l. 23-22 Extracting Record Definitions from the VAX Common Data Dictionary 23.8.4 Decimal String Data Types The CDD supports the following forms of decimal string data types: • • • • • • • LEFT OVERPUNCHED NUMERIC LEFT SEPARATE NUMERIC RIGHT OVERPUNCHED NUMERIC RIGHT SEPARATE NUMERIC PACKED DECIMAL UNSIGNED NUMERIC ZONED NUMERIC VAX BASIC supports only the PACKED DECIMAL decimal string data type, which corresponds to the VAX BASIC DECIMAL data type. For all other decimal string data types, VAX BASIC creates a group with the same name as the CDD subordinate field, and creates a string record component to contain the field. For example: CDDL Definition define record cdd$top.basic.decimalstring description is /*test decimal string data types•/. decimalstring structure. my_packed_decimal my_zoned_numeric my_unsigned_numeric my_lef_sep_numeric my_left_ovpnch_numeric my_right_sep_numeric my_right_ovpnch_numeric datatype is packed decimal size is 6 digits 2 fractions. datatype is zoned numeric size is 6 digits 2 fractions. datatype is unsigned numeric size is 8 digits 4 fractions. datatype is left separate numeric size is 10 digits 3 fractions. datatype is left overpunched numeric size is 6 digits 2 fractions. datatype is right separate numeric size is 3 digits 1 fractions. datatype is right overpunched numeric size is 4 digits 2 fractions. end decimalstring structure. end decimalstring. Extracting Record Definitions from the VAX Common Data Dictionary 23-23 Translated RECORD Statement 1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 %INCLUDE Y.FROM Y.CDD "CDD$TOP.BASIC.DECIMALSTRING" ! test decimal string data types RECORD DECIMALSTRING UNSPECIFIED DECIMAL(5 ,2 ) MY_PACKED_DECIMAL PACKED DECIMAL GROUP MY_ZONED_NUMERIC ZONED NUMERIC ! STRING STRING_ VALUE = 6 END GROUP GROUP MY_UNSIGNED_NUMERIC UNSIGNED NUMERIC STRING STRING_VALUE = 8 END GROUP GROUP MY_LEF_SEP_NUMERIC NUMERIC LEFT SEPARATE STRING STRING_VALUE = 11 END GROUP GROUP MY_LEFT_OVPNCH_NUMERIC NUMERIC LEFT OVERPUNCHED STRING STRING_ VALUE = 5 END GROUP GROUP MY_RIGHT_SEP_NUMERIC NUMERIC RIGHT SEPARATE STRING STRING_VALUE = 4 END GROUP GROUP MY_RIGHT_OVPNCH_NUMERIC NUMERIC RIGHT OVERPUNCHED STRING STRING_VALUE = 4 END GROUP END RECORD Y.BASIC-I-CDDSUBGRO, data type in CDD not supported, substituted group for: DECIMALSTRING::MY_ZONED_NUMERIC. Y.BASIC-I-CDDSUBGRO, data type in CDD not supported, substituted group for: DECIMALSTRING::MY_UNSIGNED_NUMERIC. Y.BASIC-I-CDDSUBGRO, data type in CDD not supported, substituted group for: DECIMALSTRING::MY_LEF_SEP_NUMERIC. Y.BASIC-I-CDDSUBGRO, data type in CDD not supported, substituted group for: DECIMALSTRING::MY_LEFT_OVPNCH_NUMERIC. Y.BASIC-I-CDDSUBGRO, data type in CDD not supported, substituted group for: DECIMALSTRING::MY_RIGHT_SEP_NUMERIC. Y.BASIC-I-CDDSUBGRO, data type in CDD not supported, substituted group for: DECIMALSTRING::MY_RIGHT_OVPNCH_NUMERIC. 23.8.5 Other Data Types The CDD supports the following additional data types: • • • 23-24 BIT DATE POINTER Extracting Record Definitions from the VAX Common Data Dictionary • • UNSPECIFIED VIRTUAL VAX BASIC does not support these data types. VAX BASIC translates these data types by signaling the informational message "CDDSUBGRO, data type in CDD not supported, substituted group for: <field name> ", and creates a group to contain the field. See Table 23-2 for a description of how VAX BASIC translates these data types. If you extract a CDD definition that contains a BIT field, the field must be a multiple of 8 bits (1 byte). This means that the following field must be aligned on a byte boundary. If the following field is not aligned on a byte boundary, VAX BASIC signals the error "CDDBITFLD, field <name> from CDD has bit offset or length". Extracting Record Definitions from the VAX Common Data Dictionary 23-25 Chapter 24 COD/Plus Support in VAX BASIC This chapter explains the capabilities of CDD /Plus and how a VAX BASIC user can take advantage of them. This chapter only applies to you if you have CDD /Plus Version 4.0 or later installed on your system. 24. 1 Introduction to COD /Plus VAX BASIC Version 3.3 and higher supports CDD/Plus Version 4.0 features. In addition to supporting features available in VAX CDD (see Chapter 23), VAX BASIC supports dependency recording. Dependency recording allows you to record (or track) what programs use a CDD /Plus data definition. It helps you evaluate the effort needed to change a record definition by identifying the modules that need to be modified and/or recompiled. To support dependency recording, CDD /Plus uses a dictionary structure known as CDO-format. (The type of dictionary used in CDD versions prior to Version 4.0 is known as DMU-format.) You can have many CDOformat dictionaries in use on a VMS system (but only one DMU-format dictionary). The two types of dictionaries can coexist on a system and a program can refer to data definitions in both types. When dependency recording is in effect, the VAX BASIC compiler updates the CDO-format dictionary to show what dictionary entities the program uses. A dictionary entity is any object stored in a CDD dictionary, such as as a data definition or form definition. July 1988 CDD /Plus Support in VAX BASIC 24-1 In addition to supporting the functionality of the DMU-format dictionary, a COO-format dictionary allows many additional capabilities that are useful to VAX BASIC applications. Using COD/Plus gives BASIC users the following capabilities: • • • • • • • Defining and managing data definitions using the COO utility Reading existing DMU-format dictionaries from COO Referring to COO-format dictionaries distributed over multiple nodes in the network Creating, accessing, and controlling data definitions at the field definition level Forming relationships between COO dictionary definitions, possibly connecting definitions from multiple nodes in the network Tracking the use of dictionary-defined information Querying CDD /Plus to learn what relationships exist When you compile a program that contains references to data definitions in a DMU-format dictionary, the data definitions are included in your program, but the DMU-format dictionary cannot be updated to show that the program uses those data definitions and depends on their continued integrity. COO-format dictionaries offer the additional capability of recording dependency relationships between programs and the dictionary entities that they use. 24.2 COD/Plus Concepts This section introduces background concepts that distinguish COD /Plus Version 4.0 from previous versions of the COD. 24-2 COO/Plus Support in VAX BASIC July 1988 24.2.1 Dictionary Formats COD /Plus allows two types of dictionaries: • The DMU-format dictionary • You create and manipulate a DMU-format dictionary using the DMU, CDDL, and CDDV utilities. This type of dictionary was the only format available prior to Version 4.0 of the Common Data Dictionary. The COO-format dictionary You create and manipulate a COO-format dictionary using the COO utility and the COD /Plus Call Interface. Some of the advantages of COO-format dictionaries have been mentioned previously and will be clarified in later sections. These two types of dictionaries can co-exist on a system to form one logical directory structure. COD /Plus uses a special dictionary, known as the compatibility dictionary, that allows an application to refer to dictionary definitions without concern about which type of dictionary format the definitions are stored in. The compatibility dictionary is a COO-format dictionary whose directory hierarchy matches that of the DMU-format dictionary (if any) on the system. NOTE The compatibility dictionary is an installation option for COD /Plus. Even if you do not have a compatibility dictionary, an application program can refer to both types of dictionary. In this case, the user must be careful to refer to COO-format dictionaries with an anchor origin path name, and to the DMUformat dictionary with a CDD$TOP path name. Anchor origin path names are described in the next section. Refer to COD /Plus documentation for detailed information on the COO utility and the compatibility dictionary. July 1988 COD/Plus Support in VAX BASIC 24-3 24.2.2 Dictionary Path Names To access dictionary definitions, you must specify a path name in the %INCLUDE %FROM %CDD or %REPORT %DEPENDENCY directive. The path name tells CDD where to locate a particular data definition in its directory. A CDD path name consists of a string of names separated by periods and enclosed in quotation marks. The origin is the top, or root, of a dictionary directory. This directory contains other dictionary directories, subdictionary directories and objects. For example: %INCLUDE %FROM %CDD 11 CDD$TOP.BASIC.EMPLDYEE_DATA 11 In this example, the path name CDD$TOP.BASIC.EMPLOYEE_DATA points to the root dictionary directory, CDD$TOP. The root directory CDD$TOP contains the dictionary directory BASIC, which in turn contains the object EMPLOYEE_DATA, a data definition. VAX BASIC allows three types of valid path name parameters w11en referring to CDO dictionary definitions. They differ in the method of specifying the dictionary origin. • Dictionary anchor path name An anchor path name begins with an anchor, which is a VMS directory specification, as the dictionary origin. The anchor specifies the VMS directory that contains the CDO dictionary. This is known as the CDO naming convention; In the following example, MYNODE::DISK$2:[MYDIRECTORY] is the anchor: MYNODE: :DISK$2: [MYDIRECTORY]PERSONNEL.EMPLOYEES_REC • CDD$TOP path name You use this to refer to either DMU-format dictionary definitions or CDO-format dictionary definitions in a compatibility dictionary. The path origin is always CDD$TOP. This is known as the DMU naming convention. For example: CDD$TOP.PERSONNEL.EMPLOYEES_REC • Relative path name CDD always begins its search at CDD$TOP (or at the anchor you specify) unless you define another directory or object to be the start of your directory. You can do this by assigning the name of a dictionary directory to the logical name CDD$DEFAULT. For example: 24-4 COD/Plus Support in VAX BASIC July 198E $DEFINE CDD$DEFAULT CDD$TOP.BASIC Using this command defines the dictionary directory CDD$TOP.BASIC as the default start of your directory. You can override the defined default by specifying CDD$TOP in a path name. You can omit the origin of a path name and specify a relative path name. Any path name that does not begin with either CDD$TOP or an anchor is automatically appended to the current CDD$DEFAULT. For example, you can specify: PERSONNEL.EMPLOYEES_REC If CDD$DEFAULT is MYNODE::MY$DISK:[MYDIR], the relative path name is the same as: MYNODE: :MY$DISK: [MYDIR]PERSONNEL.EMPLOYEES_REC. Similarly, if CDD$DEFAULT is CDD$TOP.MYDIR, the relative path name is the same as: CDD$TOP.MYDIR.PERSONNEL.EMPLOYEES_REC. 24.2.3 Dictionary Entities Several types of entities can exist in a dictionary. DMU-format and CDOformat dictionaries each contain record entities, database entities, and form entities, for example. When you compile a program with CDD /Plus support enabled, the compiler creates a construct known as a compiled module entity in the CDO-format dictionary. Only CDO-format dictionaries can contain compiled module entities. A compiled module entity is created for the main program and each SUB, PICTURE subprogram, and FUNCTION. Each compiled module entity points to a file entity that contains the fully qualifieq VMS file specification of the .OBJ file. Several compiled module entities can point to the same file entity. Compiled module entities are put in the current CDD$DEFAULT directory. The VAX BASIC compiler creates a compiled module entity (and relationships in CDD /Plus dictionaries that depend on compiled module entities) only if the compilation generates an object file. Therefore, compiled module entities are not generated if you specify the /NOOBJECT qualifier on the command line or if the program has compilation errors. July 1988 COD/Plus Support in VAX BASIC 24-5 24.2.4 Dictionary Relationships Relationships occur in a CDO-format dictionary when two or more CDO entity definitions are connected in any of several possible ways. For example, you can relate a set of field definitions to a record definition by including the field names in the record definition. Consider the following sequence of CDO commands: COO> DEFINE FIELD REG_DOG_NAME DATATYPE IS TEXT SIZE IS 25 CHARACTERS. CDO> DEFINE FIELD BREED DATATYPE IS TEXT SIZE IS 20 CHARACTERS. CDO> DEFINE FIELD CALL_NAME DATATYPE IS TEXT SIZE IS 20 CHARACTERS. CDO> DEFINE FIELD OWNER_NUMBER DATATYPE IS TEXT SIZE IS 5. CDO> DEFINE RECORD DOG_REC. cont>REG_DOG_NAME. cont>BREED. cont>CALL_NAME. cont>OWNER_NUMBER. cont>END RECORD. This sequence defines four field entities initially, and then defines a record entity containing those four fields. Thus, CDD /Plus creates a relationship between the record DOG_REC and each field that DOG_REC uses. You can create other types of relationships from a VAX BASIC program by using %INCLUDE and %REPORT directives in conjunction with the compilation qualifier /DEPENDENCY_DATA. Later sections will show you how to do that. See CDD /Plus documentation for detailed information about relationships in a CDO-format dictionary. 24.3 Using COD/Plus with VAX BASIC When dependency recording is in effect, the compiler updates the CDOformat dictionary to show what dictionary data entities are used by the program (in other words, the data dependencies created by the compilation). To take advantage of dependency recording, the VAX BASIC user must do the following: • Use either or both of two VAX BASIC lexical directives in the source program, %INCLUDE %FROM %CDD and %REPORT %DEPENDENCY, to define the dependency relationships you want to 24-6 COD/Plus Support in VAX BASIC July 1988 • • 24.3.1 create between your program and definitions in the the CDO-format dictionary. These directives will be described further in later sections. Establish a CDO-format dictionary as CDD$DEFAULT. Include the /DEPENDENCY_DATA qualifier in the BASIC command that compiles the module. The /DEPENDENCV_DATA Qualifier When you compile a program that references CDO-format data definitions, you can include the /DEPENDENCY_DATA qualifier in the BASIC command line. That qualifier tells the compiler to create dependency relationships (as defined in the program by %INCLUDE and %REPORT directives) and update the dictionary to show those relationships. To prevent update of the dictionary, specify /NODEPENDENCY_DATA (the default). In this case, the compiler can extract record definitions from the dictionary (as specified by %INCLUDE %FROM %CDD directives in the program), but will not update the dictionary. In other words, the compilation will not add compiled module entities and file entities to the dictionary, nor create dependency relationships in the dictionary, unless you specify the /DEPENDENCY_DATA qualifier. 24.3.2 Creating Relationships with Included Record Definitions In Section 24.2.4, an example defined a record description as a set of fields (thus establishing a simple relationship in the CDD between the record and its fields). With that record description defined, you can include it in a VAX BASIC program. With either a DMU-format or CDO-format dictionary, the compiler can extract a record description into a program. To accomplish this, you must use the %INCLUDE lexical directive in the source program. The format is as follows: %INCLUDE %FROM %CDD "pathname" July 1988 COD/Plus Support in VAX BASIC 24-7 For example, the following BASIC source code extracts a record description named ADDRESS_REC from the CDD: PROGRAM EXAMPLE! %INCLUDE %FROM %CDD "CDD$TOP.SMITH.ADDRESS_REC" DECLARE ADDRESS_REC TEST_RECORD INPUT "First name";TEST_RECORD: :FIRST_NAME INPUT "Last name";TEST_RECORD: :LAST_NAME INP~T "Address";TEST_RECORD: :ADDRESS INPUT "City" ; TEST _RECORD: : CITY INPUT "State"; TEST_RECORD:: STATE INPUT "Zip code";TEST_RECORD: :ZIP_CODE PRINT TEST_RECORD: :FIRST_NAME; TEST_RECORD: :LAST_NAME PRINT TEST_RECORD: :ADDRESS PRINT TEST_RECORD: :CITY; TEST_RECORD: :STATE; TEST_RECORD: :ZIP_CODE The listing shows the physical content of the record, as in the following listing excerpt: 1 2 8 9 PROGRAM EXAMPLE! %INCLUDE %FROM %CDD "CDD$TOP.SMITH.ADDRESS_REC" RECORD ADDRESS_REC UNSPECIFIED STRING FIRST_NAME = 20 TEXT STRING LAST_NAME = 30 TEXT STRING ADDRESS = 40 TEXT STRING CITY = 20 TEXT STRING STATE = 2 TEXT DECIMAL(5 ,0 ) ZIP_CODE PACKED DECIMAL END RECORD DECLARE ADDRESS_REC TEST_RECORD INPUT "First name"; TEST_RECORD: : FIRST_NAME INPUT "Last name";TEST_RECORD: :LAST_NAME INPUT "Address";TEST_RECDRD: :ADDRESS INPUT "City";TEST_RECORD: :CITY INPUT "State"; TEST_RECORD:: STATE INPUT "Zip code";TEST_RECORD: :ZIP_CODE 10 11 12 13 PRINT TEST_RECORD: :FIRST_NAME; TEST_RECORD: :LAST_NAME PRINT TEST_RECORD: :ADDRESS PRINT TEST_RECORD: :CITY; TEST_RECORD: :STATE; TEST_RECORD: :ZIP. Cl Cl Cl Cl Cl Cl Cl Cl 3 4 5 6 7 In the case of a CDO-format dictionary, you can also cause the dictionary to create and maintain a formal relationship between the record description and the compiled module entity that represents your program in the dictionary. This is known as a CDD$COMPILED_DEPENDS_ON relationship. To accomplish this relationship, you must specify the /DEPENDENCY_ DATA qualifier when you compile the program. $ BASIC/DEPENDENCY_DATA EX1.BAS 24-8 COD/Plus Support in VAX BASIC July 1988 If you specify the /DEPENDENCY_DATA qualifier to the VAX BASIC compiler, the compiled module entity is created and updated to reflect the fact that your program uses that record. If someone wants to change the data definition at a later date, CDO allows that person to find out what programs depend on it before doing so. For example: CDO> DIRECTORY Directory SYS$COMMON: [CDDPLUS]SMITH ADDRESS;! ADDRESS_REC;1 CITY; 1 EXAMPLE1;1 FIRST_NAME;1 LAST_NAME;1 STATE;1 ZIP_CODE;1 FIELD RECORD FIELD CDD$COMPILED_MODULE FIELD FIELD FIELD FIELD You can use the CDO SHOW USES command to find out what programs use a dictionary definition. For example: CDO> SHOW USES ADDRESS_REC Owners of SYS$COMMON: [CDDPLUS]SMITH.ADDRESS_REC;1 I SYS$COMMON: [CDDPLUS]SMITH.EXAMPLE1;1 (Type : CDD$COMPILED_MODULE) I I via CDD$COMPILED_DEPENDS_ON You can also use CDO to find out what dictionary definitions a program uses. For example: CDO> SHOW USED_BY EXAMPLE! Members of SYS$COMMON: [CDDPLUS]SMITH.EXAMPLE1;1 I EX1 (Type : CDD$FILE) I I via CDD$IN_FILE I SYS$COMMON: [CDDPLUS]SMITH.ADDRESS_REC;1 (Type : RECORD) I I via CDD$COMPILED_DEPENDS_ON July 1988 COD/Plus Support in VAX BASIC 24-9 24.4 Creating Relationships for Referenced Dictionary Entities The compiler can create a relationship between a compiled module entity and any dictionary entity that a program references (such as an Rdb/VMS database or a form definition). The referenced dictionary entity is not copied to the program. Instead, the compiled program simply references the dictionary entity at run time, or with the help of a preprocessor. To create such relationships in a BASIC program, you must use a %REPORT %DEPENDENCY lexical directive in the source program and specify the /DEPENDENCY_DATA qualifier when you compile the program. The format is as follows: %REPORT %DEPENDENCY "pathname" ["relationship-type"] The "pathname" parameter identifies the dictionary item that the compiled object module references. The path name can specify a CDO-format dictionary item (with an anchor as the first element), or it can specify a CDO-format item in the compatibility dictionary (which can be specified either as a CDD$TOP path name or as an anchor path name). See Section 24.2.2 for a full description of the path name options. The optional "relationship-type" parameter determines the type of relationship by specifying a CDD /Plus protocol. There are many valid values; refer to CDD /Plus documentation for full information. The most commonly-used type of relationship for VAX BASIC users is: CDD$COMPILED_DEPENDS_ON This specifies a relationship that links a compiled object module to the element that goes into the compilation. This is the default. The %REPORT %DEPENDENCY directive is meaningful only when the following three conditions are true: • • • 24-10 /DEPENDENCY_DATA qualifier is specified in the BASIC command line. (If it is not specified, the compiler checks syntax but does not update the dictionary to reflect this usage of the item.) Your current CDD$DEFAULT points to a directory in a CDO dictionary. The dictionary item specified by pathname is in a CDO-format dictionary. (No relationship can be created in a DMU-format dictionary.) COD/Plus Support in VAX BASIC July 1988 Suppose the VAX BASIC program DOG_REPORT.BAS contains the following directive: 'l,REPORT %DEPENDENCY "DISK1$: [CDDPLUS. BASIC] SMITH. DOG_DATABASE" Use the /DEPENDENCY_DATA qualifier when you compile the program: $ BASIC/DEPENDECY_DATA DOG_REPORT After the compilation, the dictionary contains the following: CDO> DIR Directory DISK1$: [CDDPLUS.BASIC]SMITH BREED;1 CALL_NAME;1 DOG_REPORT$MAIN;1 DOG_DATABASE;1 DOG_INFORMATION;1 DOG_REC;1 OWNER_NUMBER;1 REG_DOG_NAME;1 FIELD FIELD CDD$COMPILED_MODULE CDD$DATABASE CDD$RMS_DATABASE RECORD FIELD FIELD CDO> SHOW USES DOG_DATABASE Owners of DISK1$: [CDDPLUS.BASIC]SMITH.DOG_DATABASE;1 I DISK1$: [CDDPLUS.BASIC]SMITH.DOG_REPORT$MAIN;1 (Type I I via CDD$COMPILED_DEPENDS_ON CDD$COMPILED_MODULE) CDO> SHOW USED_BY DOG_REPORT$MAIN Members of DISK1$: [CDDPLUS.BASIC]SMITH.DOG_REPORT$MAIN;1 I DOG_REPORT (Type : CDD$FILE) I I via CDD$IN_FILE I DISK1$: [CDDPLUS.BASIC]SMITH.DOG_DATABASE;1 (Type : CDD$DATABASE) I I via CDD$COMPILED_DEPENDS_ON l4.5 Specifying a COD History List Entry When your VAX BASIC program accesses the CDD, you have the option of entering a history list entry in the CDD data base. The history list entry provides a history of users that access the CDD. You enter a history list entry by specifying the DCL command qualifier /AUDIT. For example: $ BASIC/DEPENDENCY_DATA/AUDIT="History text goes here" EX1.BAS Note that instead of typing the text directly on the command line, you can also specify a file specification that contains the history entry. July 1988 COD/Plus Support in VAX BASIC 24-11 When you specify/ AUDIT, a history list entry is created for each compiled module entity that the compilation creates. In addition, the compilation will add a history list entry to each data definition that your program extracts with the %INCLUDE %FROM %CDD directive. You can display history list information using the CDO utility. For example: CDO> SHOW GENERIC CDD$COMPILED_MDDULE EXAMPLE! /AUDIT Definition of EXAMPLE! (Type : CDD$COMPILED_MODULE) History entered by SMITH ([SMITH]) using VAX BASIC V3.3 to CREATE definition on 25-APR-1988 13:04:01.48 Explanation: "History text goes here" 24-12 COD/Plus Support in VAX BASIC July 198 Appendix A Compile-Time Error Messages This appendix describes compile-time and compiler command errors, their causes, and the user action required to correct them. A. 1 Compile-Time Errors VAX BASIC diagnoses compile-time errors and: • • • • Indicates the program line that generated the error or errors Displays this program line Shows you the location of the error or errors and assigns a number to each location for future reference Displays the mnemonic, statement number within the line, the location number as previously displayed, and the message text. This is repeated for each error in the line. VAX BASIC repeats this procedure for each error diagnosed during compilation. The error message format for compile-time errors is: Y.BASIC-<l>-<mnemonic>, <n>: <message> <I> Is a letter indicating the severity of the error. The severity indicator can be one of the following: • • I, indicating information W, indicating a warning Compile-Time Error Messages A-1 • • E, indicating an error F, indicating a severe error <mnemonic> Is a 3- to 9-character string that identifies the error. Error messages in this appendix are alphabetized by this mnemonic. <n>: Is the nth error within the line's "picture". <message> Is the text of the error message. For example: Diagnostic on source line 1, listing line 1, BASIC line 10 10 DECLARE REAL BYTE A, A ........................ 1 ....... 2 Y.BASIC-E-CONDATSPC, 1: Y.BASIC-E-ILLMULDEF, 2: conflicting data type specifications illegal multiple definition of name A This display tells you that two errors were detected on line 10; VAX BASIC displays the line containing the error, then prints a "picture" showing you where the errors were detected. In the example, the picture shows a "1" under the keyword BYTE and a "2" under the second occurrence of variable A. The following line shows you: • • • The error mnemonic CONDATSPC Which error in the line's "picture" is referred to by the mnemonic The message associated with that error In this case, the error message tells you that there are two contradictory data-type keywords in the statement. The next line shows you the same type of information for the second error; in this case, the compiler detected multiple declarations of variable A. If a compilation causes an error of severity I or W, the compilation continues and produces an object module. If a compilation causes an error of severity E, the compilation continues but produces no object module. If a compilation causes an error of severity F, the compilation aborts immediately. A-2 Compile-Time Error Messages The following is an alphabetized list of compilation error messages: ACTARGMUS, actual argument must be specified Explanation: ERROR - A DEF function reference contains a null argument, for example, FNA(l,,2). User Action: Specify all arguments when referencing a DEF function. ALLOCSML, allocated area may be too small for section Explanation: WARNING - A MAP or COMMON with the same name exists in more than one program module, and the first one encountered by the compiler is smaller than the subsequent ones. User Action: VAX BASIC first allocates MAP and COMMON areas in the main program, then MAP and COMMON areas in subprograms, in the order in which they were loaded. Thus, you can avoid this error by loading modules with the largest MAP or COMMON first. However, it is better practice to make MAP and COMMON areas equal in size. AMBRECCOM, ambiguous RECORD component Explanation: ERROR - The program contains an ambiguous RECORD component reference, for example, A::D when both A::B::D and A::C::D exist. User Action: Remove the ambiguity by fully specifying the record component. AMPCONILL, & continuation is illegal after %INCLUDE directive Explanation: ERROR - A program contains an %INCLUDE directive followed by an ampersand continuation to another statement. For example, the following is illegal: 2300 %INCLUDE %FROM %CDD 11 CDD$TOP.PERSONNEL.EMPLOYEE 11 GOTO 3000 & Ampersand continuation of the %INCLUDE directive is legal, however. User Action: Recode to eliminate the line continuation or use backslash continuation. July 1988 Compile-Time Error Messages A-3 AMPCONREP, & continuation is illegal after %REPORT directive Explanation: ERROR - A program contains a %REPORT directive followed by an ampersand continuation to another statement. For example, the following is illegal: 2300 %REPORT %DEPENDENCY 11 CDD$TOP.PERSONNEL.EMPLOYEE.COURSE_FORM 11 GOTO 3000 & Ampersand continuation of the %REPORT directive itself is legal, however. User Action: Recode to eliminate the line continuation or use backslash continuation. ANSDEFMUS, ANSI DEF must be defined before reference Explanation: ERROR - A program compiled with the / ANSL STANDARD qualifier contains a reference to a DEF function before the function definition. User Action: Renumber the line containing the function definition so that the definition precedes all references to the function. ANSILNREQ, a line number is required on first line for ANSI Explanation: ERROR - When you specify the /ANSI qualifier, a program must have a line number on the first line for the ANSI qualifier. User Action: Supply a line number on the first line. ANSKEYSPC, keywords must be delimited by spaces in /ANSI Explanation: ERROR - A program compiled with the /ANSI_ STANDARD qualifier contains a line where two elements (two keywords, a keyword and a line number, or a keyword and a string constant) are not separated by at least one space. For example, PRINT"Hello". User Action: Delimit all keywords, line numbers, and string constants with at least one space. A-4 Compile-Time Error Messages July 1988 ANSLINDIG, ANSI line number may not exceed 4 digits Explanation: ERROR - A program compiled with the /ANSI_ STANDARD qualifier contains a line number with more than 4 digits, that is, a number greater than 9999. User Action: Renumber the program lines so that no line number exceeds 9999. ANSLINNUM, ANSI line numbers must begin in column 1 Explanation: ERROR - A program compiled with the /ANSI_ STANDARD qualifier contains a line number preceded by one or more spaces or tabs. User Action: Remove any spaces and tabs that precede the line number. ANSREQREA, ANSI requires REAL default type Explanation: ERROR - The / ANSLSTANDARD qualifier conflicts with the /TYPE_DEFAULT qualifier. User Action: Do not specify a default data type other than REAL. REAL is the default. Compile-Time Error Messages A-4.1 ANSREQSCA, ANSI requires SCALE 0 Explanation. ERROR - The / ANSI_STANDARD qualifier conflicts with the /SCALE qualifier. User Action. Do not specify a scale factor. ANSREQSET, ANSI requires SETUP Explanation. ERROR - The /ANSI-STANDARD qualifier conflicts with the /NOSETUP qualifier. User Action. Do not specify /NOSETUP. ANYDIMNOT, dimension checking not allowed on ANY Explanation. ERROR - Both a datatype of ANY and a DIM clause were specified in an EXTERNAL statement. User Action. Remove the DIM clause from the EXTERNAL statement. ANY implies either scalar or array. ANYNOTALL, ANY not allowed on EXTERNAL PICTURE Explanation. ERROR - An attempt was made to specify the ANY keyword on an EXTERNAL PICTURE declaration. This is not allowed because the ANY data type should be used for calling non-BASIC procedures only. User Action. Remove the ANY keyword from the EXTERNAL PICTURE declaration. APPMISNUM, append file missing line number on first line Explanation. ERROR - An attempt was made to append a source file that does not contain a line number on the first line. User Action. Put a line number on the first line of the appended file. APPNOTALL, append not allowed on programs without line numbers Explanation. ERROR - The APPEND command cannot be used on a program without line numbers. User Action. Use an include file. Compile-Time Error Messages A-5 ARESTYMUS, area style must be "HOLLOW", "SOLID", "PATTERN" or "HATCH" Explanation. ERROR - You specified an invalid value in the SET AREA STYLE statement. User Action. Specify one of the values listed in the message. AREREQTHR, AREA output requires at least 3 X, Y points Explanation. ERROR - An AREA graphic output statement specifies less than 3 points. User Action. Specify at least 3 points in the AREA graphic output statement. ARGERR, illegal argument for command Explanation. ERROR - An argument was entered for a command that does not take an argument, or an invalid argument was entered for a command, for example, SCALE A or LIST A. User Action. Reenter the command with the proper arguments. ARRMUSHAV, array must have 1 dimension Explanation. ERROR - An array with multiple dimensions is specified where a 1 dimensional array is required. User Action. Specify an array that has 1 dimension. ARRMUSELE, array must have at least 4 elements Explanation. ERROR - You specified an array with less than four elements. This statement requires an array with at least four elements in it. User Action. Supply an array declared as having at least 4 elements. ARRNAMREQ, array names only allowed Explanation. ERROR - The type of variable name required must be an array name. User Action. Change the variable name to an array name. A-6 Compile-Time Error Messages ARRNOTALL, array <name> not allowed in DEF declaration Explanation. ERROR - The parameter list for a DEF function definition contained an entire array. User Action. Remove the array specification. Passing an entire array as a parameter to a DEF function is not allowed. ARRTOOBIG, named array <array-name> is too large Explanation. ERROR - An array requires less than (2"29 - 1) bytes of storage. User Action. Reduce the size of the array. ATROVRVAR, attributes of overlaid variable <name> don't match Explanation. ERROR - A variable name appears in more than one overlaid MAP; however, the attributes specified for the variable are inconsistent. User Action. If the same variable name appears in multiple overlaid MAPs, the attributes (for example, data type) must be identical. ATRPRIREF, attributes of prior reference to <name> don't match Explanation. WARNING - A variable or array is referenced before the MAP that declares it. The attributes of the referenced variable do not match those of the declaration. User Action. Make sure that the variable or array has the same attributes in both the reference and the declaration. ATTGTRZER, graphics attribute value must be greater than zero Explanation. ERROR - You specified a negative value when a positive value is required. User Action. Supply a value greater than zero. BADFMTSTR, invalid PRINT USING format string Explanation. ERROR - The PRINT USING format string specified is not valid. User Action. Supply a valid PRINT USING format string. Compile-Time Error Messages A-7 BADLOGIC, internal logic error detected Explanation. ERROR - An internal logic error was detected. User Action. This error should never occur. Please submit a Software Performance Report with a machine-readable copy of the source program. BADNO, qualifier <name> does not accept 'NO' Explanation. ERROR - A qualifier that does not allow a 'NO' prefix was entered. For example, NODOUBLE. User Action. Select the proper qualifier. In the example, the complementary form of DOUBLE is SINGLE. BADPROGNM, error in program name Explanation. ERROR - The program name is longer than 39 characters or contains invalid characters. User Action. Change the program name to be less than or equal to 39 characters and make sure that it contains only letters, digits, dollar signs, and underscores. BADVALUE, <text> is an invalid keyword value Explanation. FATAL - The command supplied an invalid value for a keyword. User Action. Supply a valid value. BASICHLB, BASIC's HELP library is not installed on this system Explanation. INFORMATION - A HELP command was entered and the VAX BASIC BASIC HELP library was not available. User Action. See your system manager. BIFREQNUM, built in function requires numeric expression Explanation. ERROR - A reference to a VAX BASIC built-in function contains a string instead of a numeric expression. User Action. Supply a numeric expression. A-8 Compile-Time Error Messages BIFREQSTR, built in function requires string expression Explanation. ERROR - The program specifies a numeric expression for a built-in function that requires a string argument. User Action. Supply a string expression for the built-in function. BLTFUNNOT, built in function not supported Explanation. ERROR - The program contains a reference to a built-in function not supported by this version of VAX BASIC. User Action. Remove the function reference. BOTBOUSPE, bottom boundary must be less than the top boundary Explanation. ERROR - In a statement that specifies a viewport or windowsize, you specified a bottom boundary that is greater than or equal to the corresponding top boundary. User Action. Correct the bottom boundary so that it is less than the top boundary. BOUCANNOT, bound cannot be specified for array Explanation. ERROR - An EXTERNAL statement declaring a SUB or FUNCTION subprogram specifies bounds in an array parameter, for example: EXTERNAL SUB XYZ (LONG DIM(1,2,3)) User Action. Remove the array parameter's bound specifications. When declaring an external subprogram, you can specify only the number of dimensions for an array parameter. For example: EXTERNAL SUB XYZ (LONG DIM(,,)) BOUMUSTBE, bounds must be specified for array Explanation. ERROR - The program contains an array declaration that does not specify the bounds (maximum subscript value), for example: DECLARE LONG A(,) User Action. Supply bounds for the declared array, for example: DECLARE LONG A(50,50) Compile-Time Error Messages A-9 CANCON, can't continue Explanation. FATAL - A CONTINUE command was typed after changes had been made to the source code. User Action. After changes have been made to the source code, you can run the program, but you cannot continue it. CAUNOTALL, CAUSE statement not allowed in error handler Explanation. ERROR - A CAUSE statement is specified within an error handler. User Action. Remove the CAUSE statement from the error handler. CDDACCERR, CDD access error Explanation. ERROR - The CDD detected an error on an attempted CDD record extraction. VAX BASIC displays the CDD error. User Action. Take action based on the associated CDD error. CDDACCITE, CDD error while accessing item <field-name> of record Explanation. ERROR - The CDD reported an error when accessing the field. The CDD record definition is corrupt, or there is an internal error in either VAX BASIC or the CDD. User Action. If the problem is not in the CDD definition, please submit an SPR with the source code of a small program that produces this error. CDDACCREC, CDD error while accessing record Explanation. ERROR - The CDD reported an error when accessing the record. The CDD record definition is corrupt or there is an internal error in either VAX BASIC or the CDD. User Action. If the problem is not in the CDD definition, please submit an SPR with the source code of a small program that produces this error. A-10 Compile-Time Error Messages CDDADJBOU, adjusted bounds for dimension <number> of <array> to be zero based Explanation. INFORMATION - The CDD contains an array field with a lower bound that is not zero. VAX BASIC adjusts the bound so that the array is zero based. User Action. None. CDDALCOFF, please submit an SPR-CDD inconsistent with allocated offset for <field-name> Explanation. FATAL - The offset of a field within a VAX BASIC RECORD differs from the offset specified by the CDD for that record. User Action. Please submit an SPR with the source code of a small program that produces this error. CDDALCSIZ, please submit an SPR-CDD inconsistent with allocated size for <field-name> Explanation. FATAL - The amount of storage allocated for a field in a VAX BASIC RECORD differs from the amount specified by the CDD for that record. User Action. Please submit an SPR with the source code of a small program that produces this error. CDDALCSPN, please submit an SPR-CDD inconsistent with allocated span for <field-name> Explanation. FATAL - The amount of storage allocated by a VAX BASIC RECORD for an array differs from the amount specified by the CDD for that record. User Action. Please submit an SPR with the source code of a small program this error. CDDAMBFLD, ambiguous field name <name> for <RECORD-name> Explanation. ERROR - More than one CDDL structure share the same level and the same name. User Action. Change the CDD definition so that the structures have different names. Compile-Time Error Messages A-11 CDDATTBAS, CDD attributes for <name> are other than base 10 Explanation. ERROR - A field in a CDD definition uses the BASE keyword. This warns you that the numeric field is not interpreted as a base 10 number. User Action. Remove the BASE attribute in the CDD or avoid using the field. CDDATTDAT, CDD data type attribute not permitted for GROUP Explanation. ERROR - A CDD definition specified a data type after the CDD STRUCTURE keyword. VAX BASIC translates STRUCTURE to a VAX BASIC RECORD or GROUP statement. These VAX BASIC statements do not allow data type attributes. User Action. Change the CDD definition. CDDATTDIG, DIGITS attribute of <field-name> not supported for data type Explanation. INFORMATION - The field contains a CDD fixedpoint data-type that specifies the number of allowed digits. This warning tells you that VAX BASIC interprets the field as BYTE, WORD, or LONG and does not support the DIGITS attribute for this data type. User Action. None. CDDATTSCA, CDD specifies SCALE for <RECORD-component>. Not supported. Explanation. INFORMATION - A field in a CDD definition uses the SCALE keyword. This warns you that the field has an implied exponent. User Action. Remove the SCALE attribute in the CDD, or avoid using the field. CDDATTTXT, CDD TEXT attribute for group <group-name> ignored Explanation. INFORMATION - A CDD record definition specifies a data type of TEXT for the entire record. User Action. None. VAX BASIC ignores the TEXT attribute and substitutes the UNSPECIFIED attribute. A-12 Compile-Time Error Messages CDDBASNAM, COD specified BASIC name <name> has illegal form Explanation. ERROR - The VAX BASIC name specified in the COD record definition is a reserved keyword or contains an illegal character. User Action. Change the invalid field name. CDDBITFLD, field <field-name> from COD has bit offset or length Explanation. ERROR - A COD field does not start on a byte boundary. User Action. Change the bit field in the COD to have a length that is a multiple of 8 bits. CDDCOLMAJ, <array-name> from COD is a column major array Explanation. ERROR - An array specified in a COD definition is column-major rather than row-major. Thus it is incompatible with VAX BASIC arrays. User Action. Change the COD definition to be a row-major array. CDDDIGERR, decimal digits of <value> in COD out of range for <field-name> Explanation. ERROR - A packed numeric COD specifies more than 31 digits. User Action. Reduce the number of digits specified in the COD definition. CDDDIMNOT, RECORD cannot be dimensioned Explanation. ERROR - A COD definition is itself an array. This is incompatible with VAX BASIC RECORDs, which can contain arrays but cannot be arrays. User Action. None. You cannot access COD definitions that are arrays. Compile-Time Error Messages A-13 CDDDUPREC, RECORD <name> from COD has duplicate name Explanation. ERROR - The COD record name conflicts with a previous RECORD name. The previous RECORD name may be a standard VAX BASIC RECORD or another COD record. User Action. Remove one of the duplicate definitions. CDDFLDNAM, field name missing Explanation. ERROR - The COD definition contains a field that is not named. User Action. Supply a field name for the COD definition. CDDINTONLY, % not allowed on <name> with non-integer datatype Explanation. ERROR - The % suffix is allowed only on numeric data types. User Action. Remove the % suffix from the variable name or change the datatype keyword. CDDLOWBOU, lower bound omitted for dimension <number> of <array-name> Explanation. ERROR - An array in a COD definition does not specify a lower bound. User Action. Check to make sure the omission is not a mistake. VAX BASIC supplies a lower bound of zero and continues after issuing this warning. CDDMAXDIM, <array-name> exceeds maximum dimensions Explanation. ERROR - An array in a COD definition specifies more than 32 dimensions. User Action. Reduce the number of dimensions in the CDD definition. CDDNAMKEY, <name> is a BASIC keyword Explanation. ERROR - A CDD definition contains a field name that is a reserved word in VAX BASIC. User Action. Change the name in the COD definition or supply a VAX BASIC name clause. A-14 Compile-Time Error Messages CDDOCCIGN, OCCURS DEPENDING ON clause for <array-name> from CDD ignored Explanation: INFORMATION - The CDD contains an array field with a variable number of elements. VAX BASIC creates an array large enough for the maximum value. User Action: If you modify the array field, be sure also to change the field that contains the number of array elements. CDDOFFERR, CDD offset error, field <field-name> offsets out of order Explanation: ERROR - The CDD definition has been corrupted or there is an internal error in either VAX BASIC or the CDD. User Action: If the problem is not in the CDD definition, please submit an SPR with the source code of a small program that produces this error. CDDPLUSERR, CDD /Plus access error Explanation: ERROR - CDD /Plus detected an error while attempting to record dependency data. VAX BASIC displays the CDD/Plus error. User Action: Take action based on the associated CDD /Plus error. CDDPREERR, decimal precision of <VALUE> in CDD out of range for <field-name> Explanation: ERROR - The number of fractional digits for a packed decimal field is greater than the total number of digits specified for that field. User Action: Change the number of fractional digits in the CDD to be less than or equal to the total number of digits. CDDRECFOR, CDD record format is not fixed Explanation: ERROR - The CDD supports both variable and fixed-length records. VAX BASIC supports only fixed-length records. User Action: Change the CDD record definition to specify fixed-length. July 1988 Compile-Time Error Messages A-15 CDDRECNAM, record from CDD does not have a record name Explanation: ERROR - VAX BASIC uses the field name of the outermost structure to name the record, and therefore cannot include a CDD record that does not provide a record name. User Action: Change the CDD record definition to provide a field name for the outermost structure of the record. CDDSCAERR, decimal scale of <scale-factor> is out of range for <field> from CDD Explanation: ERROR - The scale factor for a packed decimal CDD field is greater than the number of digits in the field or less than zero. User Action: Change the scale factor in the CDD definition. CDDSCAZER, scale 0 specified for CDD field <field-name> Explanation: INFORMATION - A CDD field specifies no scale factor for a D_floating field, but the VAX BASIC program specifies a non-zero scale factor. User Action: Use a scale factor of zero in the VAX BASIC program. CDDSTRONLY, $ not allowed on <name> with non-string datatype Explanation: ERROR - The $ suffix is only allowed on string data types. User Action: Remove the$ suffix from the variable name or change the datatype keyword. CDDSUBGRO, substituted GROUP for <field-name> . Data type in CDD not supported. Explanation: INFORMATION - The CDD definition specifies a data type that is not native to VAX BASIC. VAX BASIC creates a GROUP with the same name as the CDD field and creates variable names for the GROUP components. User Action: None. A-16 Compile-Time Error Messages CDDTAGIGN, tag value ignored for <field-name> from CDD Explanation: INFORMATION - The CDD record definition contains a VARIANTS OF. User Action: None. VAX BASIC translates the VARIANTS OF as if it were a regular variant; however, the tag value is ignored. Compile-Time Error Messages A-16.1 CDDUNSDAT, data type specified in CDD for <field-name> not supported Explanation. ERROR - The data type specified for a field is not supported by VAX BASIC. User Action. Change the data type in the CDD record definition. CDDUPPBOU, upper bound omitted for dimension <number> of <array-name> Explanation. ERROR - An array in a COD definition does not specify an upper bound. User Action. Specify an upper bound in the CDD definition. CDDVARFLD, field <name> from CDD has variable offset or length Explanation. ERROR - A CDD field can be either variable or fixed-length. VAX BASIC supports only fixed-length fields. User Action. Change the COD definition. CHAEXPMUS, channel expression must be numeric Explanation. ERROR - The program contains a nonnumeric channel expression, for example, PUT #A$ User Action. Change the channel expression to be numeric. CHALINCLA, CHAIN does not support line number clause Explanation. ERROR - A CHAIN statement contains a LINE keyword and a line number argument. User Action. Remove the LINE keyword and the line number argument. CHANGES, unsaved change has been made, CTRL/Z or EXIT to exit Explanation. WARNING - A VAX BASIC source program in memory has been modified, and an EXIT command or CTRL/Z has been typed. VAX BASIC signals the error notifying you that if you exit from the compiler, the program modifications will be lost. User Action. If you want to SAVE the program, type SAVE. If you do not want to save the program, type EXIT or CTRL/Z. Compile-Time Error Messages A-17 CHANOTALL, CHANGES not allowed on primary key Explanation. ERROR - The PRIMARY KEY clause in an OPEN statement specifies CHANGES. User Action. Remove the CHANGES keyword; you cannot change the value of a primary key. CHASTAAMB, CHANGE statement is ambiguous Explanation. ERROR - A string variable and a numeric array have the same name in a CHANGE statement. User Action. Change the name of the string variable or the numeric array. CLIPMUSBE, clipping must be set to "ON" or "OFF" Explanation. ERROR - You specified an invalid value in the SET CLIP statement. User Action. Specify one of the values listed in the message. CLOSEIN, error closing <file-name> as input Explanation. ERROR - An error was detected while closing an input file. User Action. Take corrective action based on the associated message. CLOSEOUT, error closing <file-name> as output Explanation. ERROR - An error was detected while closing an output file. User Action. Take corrective action based on the associated message. CMDNOTALL, command not allowed on programs without line numbers Explanation. ERROR - A command that cannot be used on a program without line numbers has been used on a program without line numbers. User Action. Do not use this command on programs without line numbers. A-18 Compile-Time Error Messages CODLENEST, internal code length estimate error. Submit an SPR Explanation. FATAL - VAX BASIC has incorrectly estimated the size of the generated code for your program. User Action. Submit an SPR with the program that caused the error. (You can often work around this error by making a simple change to your code.) COLOUTRAN, color intensities must be in the range 0.0 to 1.0 Explanation. ERROR - The value specified for color intensity is either less than 0.0 or greater than 1.0. User Action. Supply a value between 0.0 and 1.0. COMMAPALI, variable <name> not aligned in COMMON/MAP <name> Explanation. INFORMATION - In a COMMON or MAP, the total storage preceding a REAL, WORD, or LONG numeric variable is an odd number of bytes. User Action. None. In VAX BASIC, numeric data can start on any byte boundary. COMMAPNEQ, COMMON/MAP area sizes are not equal for section Explanation. WARNING - A MAP or COMMON with the same name exists in more than one program module, but the size of the areas differs. User Action. Make the size of the COMMON or MAP areas equal in size in all modules. COMMAPOVF, COM/MAP <name> is too large Explanation. ERROR - The program contains a MAP or COMMON longer than (2"31 - 1) longwords. User Action. Reduce the length of the COMMON or MAP. Compile-Time Error Messages A-19 CONCOMSYN, conditional compilation cannot be used with /SYNTAX Explanation. FATAL - The /SYNTAX_CHECKING qualifier is in effect when a program line containing the %IF, %THEN, %ELSE, or %END %IF lexical directive was entered. User Action. Turn off syntax checking before entering a program line containing the %IF, %THEN, %ELSE, or %END %IF lexical directive. CONDATSPC, conflicting data type specifications Explanation. ERROR - The program contains a declarative statement containing two or more consecutive and contradictory data type keywords, for example, DECLARE REAL BYTE. User Action. Remove one of the data type keywords or make sure that the keywords refer to the same generic data type. For example, DECLARE REAL SINGLE is valid. CONEXPREQ, constant expression required Explanation. ERROR - A statement specifies a variable, built-in function reference or exponentiation where a constant is required. User Action. Supply an expression containing only literals or declared constants or remove the exponentiation operation. CONTARNOT, CONTINUE target not legal in detached error handlers Explanation. ERROR - A CONTINUE statement within a detached WHEN block error handler contains a target. User Action. Remove the target line number or label from the CONTINUE statement or use an attached error handler. CONIS-1NC, constant is inconsistent with the type of <name> Explanation. ERROR - A DECLARE CONSTANT statement specifies a value that is inconsistent with the data type of the constant, for example, a BYTE value specified for a REAL constant. User Action. Change the declaration so that the data type of the value matches that of the constant. A-20 Compile-Time Error Messages CONIS_NEE, <item> requires conditional expression Explanation. ERROR - A CASE or IF keyword is immediately followed by a floating-point or string expression. User Action. Supply a conditional expression (relational, logical, or integer). CONLFTSID, constant <name> not allowed on left side of assignment Explanation. ERROR - The program tries to assign a value to a user-defined constant. User Action. Remove the assignment statement; once you have assigned a value to a declared constant, you cannot change it. CONNOTALL, constant <name> not allowed in assignment context Explanation. ERROR - The program tries to assign a value to a user-defined constant. User Action. Remove the assignment statement; once you have assigned a value to a declared constant, you cannot change it. COOMUSBE, coordinates must be within NOC space (0.0 to 1.0) Explanation. ERROR - The value of a coordinate is either less than 0.0 or greater than 1.0. User Action. Supply a value between 0.0 and 1.0. CORSTAFRA, corrupted stack frame Explanation. ERROR - An immediate mode statement was entered after a STOP statement was executed in the BASIC environment and something corrupted the stack. User Action. Check program logic to make sure that all array references are within array bounds. This error can also be caused by loading non-BASIC object modules in the BASIC environment. Compile-Time Error Messages A-21 COUONLALO, COUNT clause only allowed with array LIST clause Explanation. ERROR - A COUNT clause was found on a SET INITIAL CHOICE statement that contains a LIST clause that does not contain a string array. User Action. Remove the COUNT clause or use the array form of the LIST clause. COUVALCAN, COUNT value cannot be greater than array size Explanation. ERROR - In the COUNT clause, you specified a count that is larger than the size of the array that you supplied. User Action. Change either the COUNT value or the size of the array so that COUNT is less than or equal to the number of elements in the array. DATTYPEXP, data type required for variable <name> with /EXPLICIT Explanation. ERROR - A program compiled with the /TYPE=EXPLICIT qualifier declares a variable without specifying a data type. User Action. Supply a data type keyword for the variable or compile the program without the /TYPE=EXPLICIT qualifier. DATTYPNOT, data type keyword not allowed in SUB statement Explanation. ERROR - A SUB statement contains a data type keyword between the subprogram name and the parameter list. User Action. Remove the data type keyword. In a SUB statement, data type keywords can appear only within the parameter list. DATTYPREQ, data type required in EXTERNAL CONSTANT declaration Explanation. ERROR - An EXTERNAL CONSTANT statement has no data type keyword. User Action. Supply a data type keyword to specify the data type of the external constant. A-22 Compile-Time Error Messages DECIMERR, DECIMAL overflow Explanation. WARNING - The program contains a DECIMAL expression whose value is outside the valid range. User Action. Reduce the value of the DECIMAL expression. DECLEXSYN, DECLARED lexical function syntax error Explanation. ERROR - The syntax of the %DECLARED lexical function is specified incorrectly. User Action. Supply the correct syntax. DECPREOUT, DECIMAL precision specification out of range Explanation. ERROR - In the declaration for a packed decimal variable or constant, the number of digits to the right of the decimal point is greater than the total number of digits specified, or greater than 31. User Action. Change the declaration so that the total number of digits specified is less than 31, and the number of digits to the right of the decimal point is less than or equal to the total number of digits. DECSIZOUT, DECIMAL size specification out of range Explanation. ERROR - The declaration for a packed decimal variable or variable specifies more than 31 digits. User Action. Change the declaration to specify 31 or fewer digits. DEFINVNOT, DEF invocation not allowed in assignment context Explanation. ERROR - A DEF function invocation (including a parameter list) appears on the left side of an assignment statement. User Action. Remove the assignment statement. You cannot assign values to a function invocation. Compile-Time Error Messages A-23 DEFMODNOT, DEF <name> mode not as declared Explanation. ERROR - The specified data type in a function declaration disagrees with the data type specified in the function definition. User Action. Make the data type specifications match in both the function declaration and the function definition. DEFNOTDEF, DEF <name> not defined Explanation. ERROR - The program contains a reference to a nonexistent user-defined function. User Action. Define the function in a DEF statement. DEFNOTWHE, DEF not allowed in WHEN block or handler Explanation. ERROR - A DEF function definition is not allowed in a WHEN block or its associated handler. User Action. Remove the DEF function definition from within the WHEN block or handler. DEFRESREF, DEF <name> result reference illegal in this context Explanation. ERROR - The program attempts to assign a value to a DEF name outside the DEF block. User Action. Remove the assignment statement. You cannot assign a value to a DEF outside of the DEF block. DEFSIZNOT, DEF <name> decimal size not as declared Explanation. ERROR - The DECIMAL(d,s) size specified in the DEF statement does not match the DECIMAL(d,s) used in the associated DECLARE DEF statement. User Action. Make the DECIMAL size specification agree in both the DECLARE DEF and DEF statements. A-24 Compile-Time Error Messages DEFSTAPAR, DEF* formal <formal-name> inconsistent with usage outside DEF* Explanation: ERROR - A DEF* formal parameter has the same name as a program variable, but different attributes. User Action: You should not use the same names for DEF* parameters or program variables. If you do, you must ensure that they have the same data type and size. DEFSTRPAR, DEF string parameter is illegal in MAP DYNAMIC or REMAP Explanation: ERROR - You cannot use a static string that is a parameter declared in a DEF or DEF* function as the storage area in a MAP DYNAMIC or REMAP statement. User Action: Change the storage area specification in the MAP DYNAMIC or REMAP statement to use either a MAP name or a static string variable that is not a parameter to the DEF or DEF* function. DELETE, ignoring <item> Explanation: ERROR - The program contains a syntax error. The compiler tries to recover from the error by ignoring an operator or separator in the source line. For example, DIM A(3, ) is a syntax error, but VAX BASIC continues the compilation by ignoring the comma. The compilation continues only in order to discover other errors; no object module is produced. User Action: Correct the syntax error in the displayed line. DEPNOTANS, /DEPENDENCY_DATA qualifier not allowed with /ANSI Explanation: ERROR - The /DEPENDENCY_DATA qualifier conflicts with the/ ANSLSTANDARD qualifier. User Action: Specify either the /DEPENDENCY_DATA qualifier or the / ANSI_STANDARD qualifier, but not both. July 1988 Compile-Time Error Messages A-25 DESOUTRAN, destination out of range Explanation: FATAL - The branch destination in an ON GOSUB statement is greater than 32767 bytes away from the statement. User Action: Reduce the distance between the destination and the statement. DIMOUTRAN, dimension is out of range Explanation: ERROR - The program contains the declaration of an array that specifies a negative number as a dimension. User Action: Change the dimension to a positive number. DIMLSSZERO, dimension must be greater than zero Explanation: ERROR - The number specified for a dimension must be greater than zero. User Action: Change the number to be greater than zero. DIMTOOBIG, dimension for array <name> must be between 1 and <number> Explanation: ERROR - The number of the dimension specified is greater than the number of dimensions in the array. User Action: Change the dimension number to be less than or equal to the number of dimensions in the array. DIRMUSTBE, directive must be only item on line Explanation: ERROR - The program contains a compiler directive that is not the only item on the line. User Action: Place the directive on its own line. DIRNOTIMM, directive not valid in immediate mode Explanation: ERROR - A compiler directive was typed in the BASIC environment. User Action: None. Compiler directives are invalid in immediate mode. A-26 Compile-Time Error Messages July 1988 DIVBY_ZER, division by zero Explanation: WARNING - The value of a number divided by zero is indeterminate. User Action: Change the expression so that no expression is divided by the constant zero. DRAWITREQ, DRAW WITH clause requires 4X4 matrix Explanation: ERROR - A user matrix is specified in a DRAW statement WITH clause where a 2 dimensional matrix with lower bounds 0 and upper bounds 4 in both dimensions is required. User Action: Declare the matrix to be a 2 dimensional matrix with lower bounds 0 and upper bounds 4 in both dimensions. DUPCLASPE, duplicate clause specified Explanation: ERROR - A duplicate clause was found on a SET INITIAL statement or a graphics input statement. User Action: Remove the duplicate clause. Compile-Time Error Messages A-26.1 DUPLINNOT, duplicate line numbers not ANSI Explanation. ERROR - A program compiled with the /ANSI_ STANDARD qualifier from the DCL command level, or called into the BASIC environment with the OLD command while the / ANSl_STANDARD qualifier is in effect, contains two identical line numbers. User Action. Remove one instance of the duplicate line number. Even if you compile the program without the/ ANSI_ STANDARD, VAX BASIC will ignore all statements connected with the first instance of the duplicate line number before compiling the program. DUPLNFND, duplicate line number <number> found Explanation. INFORMATION or WARNING Explanation. INFORMATION - A line number in an include file is the same as a line number in the main source file. Explanation. WARNING - There are two lines in the main source file with the same line number. VAX BASIC keeps the second occurrence of the line number. User Action. Correct the source by changing one of the line numbers to an unused number. DYNATTONL, DYNAMIC attribute only valid for MAP areas Explanation. ERROR - A COMMON keyword is followed by the DYNAMIC keyword. User Action. Remove the DYNAMIC keyword. The DYNAMIC attribute is valid only for MAP areas. DYNSTRINH, dynamic string variable <name> inhibits optimization Explanation. INFORMATION - This error is reported only when the /NOSETUP qualifier is in effect. The program contains a dynamic string variable. This prevents optimization of the compiler-generated code. User Action. Place the string variable in a COMMON or MAP. Compile-Time Error Messages A-27 ELSIMPCON, ELSE appears in improper context, ignored Explanation. ERROR - The program contains an ELSE clause that either is not preceded by an IF statement or that appears after an IF has been terminated with a line number or END IF. User Action. Remove either the ELSE clause or the terminating line number or END IF. ENDIMPCON, END IF appears in improper context, ignored Explanation. ERROR - The program contains an END IF statement that either is not preceded by an IF statement or occurs after an IF has been terminated by a line number. User Action. Supply an IF statement or remove the terminating line number. ENDSTAREQ, END statement required in ANSI Explanation. INFORMATION - A program compiled with the / ANSLSTANDARD qualifier does not contain an END statement. User Action. Include an END statement as the last statement in the program. ANSI Minimal BASIC requires an END statement. ENTARRFIE, entire array field of virtual record cannot be passed Explanation. ERROR - The program attempts to pass an entire array as a parameter to a subprogram when: 1 the array is an item in a record and 2) the record is itself dimensioned as a virtual array. User Action. Assign the values of the array to another array that is of the same data type and dimension but that is not a field of a virtual array record, and pass the second array as the parameter. ENTARRNOT, entire array not allowed in this context Explanation. ERROR - The program specifies an entire array in a context that permits only array elements, for example, in a PRINT statement. User Action. Remove the reference to the entire array. A-28 Compile-Time Error Messages ENTGRONOT, entire GROUP or RECORD not allowed in this context Explanation. ERROR - The program specifies an entire GROUP or RECORD in a context that permits only GROUP or RECORD components, for example, PRINT ABC::XYZ where XYZ is a GROUP. User Action. Remove the reference to the entire GROUP or RECORD. ENTVIRARR, entire virtual array cannot be a parameter Explanation. ERROR - The program attempts to pass an entire virtual array as a parameter. User Action. None. You cannot pass an entire virtual array as a parameter. EOLNOTTER, End of line does not terminate IFs due to active blocks Explanation. ERROR - A THEN or ELSE clause contains a loop block, and a line number terminates the IF-THEN-ELSE before the end of the loop block. User Action. Make sure that any loop is entirely contained in the THEN or ELSE clause. ERLNOTALL, ERL statement not allowed in programs without line numbers Explanation. ERROR - An ERL statement has been found in a program without line numbers. User Action. Remove the ERL statement. ERRACCLIB, error accessing module <mod-name> in text library <text-lib-name> Explanation. ERROR - VAX BASIC found an unexpected LIBRARIAN error while trying to %INCLUDE a text library module. This error message is followed by a specific LIBRARIAN (LBR) message. User Action. Take appropriate action based on the associated LBR message. Compile-Time Error Messages A-29 ERRCLOLIB, error closing text library <text-lib-name> Explanation. ERROR - The text library specified in an %INCLUDE directive could not be closed. This error message is followed by the specific LIBRARIAN (LBR) error. User Action. Take appropriate action based on the associated LBR message. ERROPEFIL, error opening file Explanation. ERROR - The file specified in a %INCLUDE directive could not be opened. This error message is followed by the specific RMS error. User Action. Take appropriate action based on the associated RMS error. ERROPELIB, error opening text library <text-lib-name> Explanation. ERROR - The text library specified in an %INCLUDE directive could not be opened. This error message is followed by the specific LIBRARIAN (LBR) error. User Action. Take appropriate action based on the associated LBR message. ERRRECCOM, erroneous RECORD component Explanation. ERROR - The program contains an erroneous record component, for example, specifying A::B when RECORD A has no component named B. User Action. Remove the erroneous reference. EXEDIMILL, executable DIMENSION illegal for static array Explanation. ERROR - A DIMENSION statement names an array already declared with a DECLARE, COMMON, MAP, or RECORD statement, or one that was declared statically in a previous DIMENSION statement. User Action. Remove the executable DIMENSION statement or originally declare the array as executable in a DIMENSION statement. A-30 Compile-Time Error Messages EXPDECREQ, explicit declaration of <name> required Explanation: ERROR - The program is compiled with the /TYPE:EXPLICIT qualifier in effect, and the program refer~nces a variable, constant, function, or subprogram name that is not explicitly declared. User Action: Explicitly declare the variable, constant, function, or subprogram. EXPIFDIR, expecting IF directive Explanation: ERROR - The program contains a %END that is not immediately followed by a %IF. User Action: Supply a %IF immediately following the %END. EXPNOTALL, expression not allowed in this context Explanation: ERROR - The program contains an expression in a context that allows only simple variables, array elements or entire arrays, for example, in FIELD and MOVE statements. User Action: Remove the expression. EXPTOOCOM, expression too complicated Explanation: ERROR - The program contains an expression or statement too complicated to compile. This message can occur whenever VAX BASIC is unable to allocate sufficient registers. User Action: Recode as required; for example, rewrite the statement as two or more less complicated statements. EXPUNAOPE, expecting unary operator or legal lexical operand Explanation: ERROR - A compiler directive contains an invalid lexical expression, for example, %IF *3% %THEN. User Action: Correct the lexical expression. EXTELSFOU, extra ELSE directive found Explanation:· ERROR - The program contains a %ELSE directive that is not matched with a %IF directive. User Action: Make sure that each %ELSE is preceded by a %IF, and that each %IF contains no more than one %ELSE clause. July 1988 Compile-Time Error Messages A-31 EXTENDIF, extra END IF directive found Explanation: ERROR - A program unit contains a %END %IF without a preceding %IF directive. User Action: Supply a %IF for the %END %IF. EXTLEFPAR, extra left parenthesis in expression Explanation: ERROR - A compiler directive contains a lexical expression with an extra left parenthesis. User Action: Remove the extra parenthesis. EXTNAMTOO, EXTERNAL name too long, truncating to <new-name> Explanation: WARNING - An EXTERNAL statement names a symbol longer than 31 characters. User Action: Shorten the symbol name to 31 characters or less. EXTRIGPAR, extra right parenthesis in expression. Explanation: ERROR - A compiler directive contains a lexical expression with an extra right parenthesis. User Action: Remove the extra parenthesis. EXTSTRVAR, EXTERNAL STRING variables not supported Explanation: ERROR - The program contains an EXTERNAL statement that specifies an external string variable. User Action: Remove or change the EXTERNAL statement. VAX BASIC does not support external string variables. FEANOTANS, language feature not ANSI Explanation: INFORMATION - A program compiled with the / ANSI_STANDARD qualifier contains a VAX BASIC feature (such as a long variable name or a string array) that does not conform to the ANSI Minimal BASIC Standard. (See Chapter 7 for more information on the ANSI Minimal Standard.) User Action: Although VAX BASIC allows you to run programs with non-ANSI language features, you must remove these features if you want your program to be transportable to other ANSI Minimal BASIC compilers. A-32 Compile-Time Error Messages FIEVALONL, FIELD valid only for dynamic string variables Explanation. ERROR - A FIELD statement contains a numeric or fixed-length string variable. User Action. Remove the numeric or fixed-length string variable. Only dynamic string variables are valid in FIELD statements. FILACCERR, file access error for INCLUDE directive <file-name> Explanation. ERROR - The file named in the %INCLUDE directive was correctly opened but could not be read for some reason, for example, the disk drive was switched off line. User Action. Take action based on the associated RMS error messages. FILEWRITE, <prog-name> written to file: <file-name> Explanation. INFORMATION - The specified program name has been saved in file-name. User Action. None. FILNOTALL, FILL not allowed in MAP DYNAMIC Explanation. ERROR - A MAP DYNAMIC statement contains a FILL item. User Action. Remove the FILL item. FILNOTDEL, error deleting <file-name> Explanation. ERROR - An error was detected in attempting to delete a file. User Action. Supply a valid file specification, or take corrective action based on the associated message. FILTOOBIG, FILL number <n> in overlay <m> of MAP <name> too big Explanation. ERROR - A FILL string length or repeat count caused the compiler to try to allocate more than 2"31 longwords of storage. User Action. Check the specified MAP statement and change the FILL string length or repeat count. Compile-Time Error Messages A-33 FLOCVTILL, floating CVT valid only for SINGLE and DOUBLE Explanation. ERROR - A CVTF$ or CVT$F function names a GFLOAT or HFLOAT value as an argument. User Action. Use a SINGLE or DOUBLE argument rather than GFLOAT or HFLOAT. FLOPOIERR, floating point error or overflow Explanation. WARNING - The program contains a numeric expression whose value is outside the valid range for the default floating-point data type. User Action. Modify the expression so that its value is within the allowable range or select as the default REAL size a floatingpoint data type that has a greater range. FNEWHINOT, exit from DEF while not in DEF Explanation. ERROR - An FNEXIT or EXIT DEF statement has no preceding DEF statement. User Action. Define the function before inserting an FNEXIT or EXIT DEF statement. FNEWITDEF, end of DEF seen while not in DEF Explanation. ERROR - An FNEND or END DEF statement has no preceding DEF statement. User Action. Define the function before inserting an FNEND statement or delete the FNEND statement. FORFEEMUS, FORM FEED must appear at end of line Explanation. INFORMATION - A form feed character is followed by other characters in the same line. User Action. Remove the characters following the form feed. A form feed must be the last or only character on a line. FORPARMUS, formal parameter must be supplied for <name> Explanation. ERROR - The declaration of a DEF, SUB, or FUNCTION routine contains the parentheses for a parameter list but no parameters. User Action. Supply a parameter list or remove the parentheses. A-34 Compile-Time Error Messages FORSTRP AR, formal string parameters may not be FIELDed Explanation. ERROR - A variable name appears both in a subprogram formal parameter list and a FIELD statement in the subprogram. User Action. Remove the variable from FIELD statement or the parameter list. FOUENDWIT, found end of <block> without matching <item> Explanation. ERROR - The program contains an END SELECT, END DEF, END FUNCTION, FUNCTIONEND, SUBEND, END SUB, or END IF without a matching SELECT, DEF, SUB, FUNCTION or IF. User Action. Supply a SELECT, DEF, FUNCTION, SUB, or IF to match the END <block> statement, or remove the erroneous END statement. FOUND, found <item> when expecting <item> Explanation. ERROR - The program contains a syntax error. VAX BASIC displays the item where the error was detected, then displays one or more items that make more sense in that context. The compilation continues so that other errors may be detected. The actual program line remains unchanged and no object file is produced. User Action. Examine the line carefully to discover the error. Change the program line to correct the syntax error. FOUNXTWIT, found NEXT without matching WHILE or UNTIL Explanation. ERROR - The program contains a NEXT statement without a corresponding WHILE or UNTIL statement. User Action. Supply a WHILE or UNTIL statement or remove the erroneous NEXT statement. FOUWITMAT, found NEXT without matching FOR Explanation. ERROR - The program contains a NEXT <controlvariable> statement without a matching FOR <controlvariable > statement. User Action. Supply a FOR statement or remove the erroneous NEXT statement. Compile-Time Error Messages A-35 FUNINVNOT, function invocation not allowed in assignment context Explanation. ERROR - An external function invocation (including a parameter list) appears on the left side of an assignment statement. User Action. Remove the assignment statement. You cannot assign values to a function invocation. FUNNESTOO, function nested too deep Explanation. ERROR - The program contains too many levels of function definitions within function definitions. User Action. Reduce the number of nested functions. FUNWHINOT, exit from FUNCTION while not in FUNCTION Explanation. ERROR - An EXIT FUNCTION or FUNCTIONEXIT statement was found in a module that is not a FUNCTION subprogram. User Action. Remove the EXIT FUNCTION or FUNCTIONEXIT statement. GRAARRMUS, graphics array must be integer or real Explanation. ERROR - The specified array has a data type other than an integer or real data type. User Action. Declare the array with an integer or real data type. HANNOTDEF, HANDLER not allowed in DEF Explanation. ERROR - A HANDLER definition has been found within a DEF function definition. User Action. Remove the HANDLER definition from inside the DEF function definition. HANNOTFOU, error handler <name> not found Explanation. ERROR - You did not define the HANDLER you referenced in a WHEN statement. User Action. Define the HANDLER you reference in the WHEN statement. A-36 Compile-Time Error Messages HANNOTWHE, HANDLER not allowed in a WHEN block or handler Explanation: ERROR - A detached HANDLER definition was found in a WHEN block protected region or associated handler. User Action: Remove the HANDLER definition from within all WHEN block protected regions and associated handlers. HANWHINOT, exit from HANDLER while not in HANDLER Explanation: ERROR - An EXIT HANDLER statement was found while not in a HANDLER block. User Action: Remove the EXIT HANDLER statement. HORJUSMUS, horizontal justification must be "LEFT", "CENTER", "RIGHT" or "NORMAL" Explanation: ERROR - You specified an invalid value for the horizontal component of the SET TEXT JUSTIFY statement. User Action: Specify one of the values listed in the message. IDEMAYAPP, IDENT directive may appear only once per module Explanation: WARNING - The program contains more than one %IDENT compiler directive. User Action: Remove all but one %IDENT directive. IDENAMTOO, IDENT directive name is too long Explanation: WARNING - The quoted string in a %IDENT directive is too long. User Action: Reduce the length of the string. The maximum length is 31 characters. IF_EXPMUS, IF directive expression must be terminated by THEN directive Explanation: ERROR - A %IF directive contains a %ELSE clause with no intervening % THEN clause. User Action: Insert a %THEN clause. Compile-Time Error Messages A-37 IF_IN _INC, IF directive in INCLUDE directive needs END IF directive in same file Explanation: ERROR - A %INCLUDE file contains a %IF but no %END %IF. User Action: Supply a %END %IF for the %INCLUDE file. IF_NOTTER, IF statement not terminated Explanation: ERROR - The program contains an IF-THEN-ELSE statement within a block (for example, a FOR-NEXT, SELECTCASE, or WHILE block) and the end of the block was reached before the IF-THEN-ELSE statement was terminated. User Action: Check program logic to be sure IF-THEN-ELSE statements are terminated with a line number or an END IF statement before the end of the block is reached. ILLALLCLA, illegal ALLOW clause <clause> Explanation: ERROR - The program contains an ALLOW clause on a GET statement, and the file was not opened with the UNLOCK EXPLICIT clause. User Action: Either remove the ALLOW clause from the GET statement or use the UNLOCK EXPLICIT clause in the OPEN statement. ILLARGBP2, illegal argument count for BP2 Explanation: INFORMATION - The program contains a SUB, DEF or EXTERNAL FUNCTION reference with more than 32 parameters. This error is reported only when the /FLAG:BP2COMP ATIBILITY qualifier is in effect. User Action: If the program must run under both VAX BASIC and PDP-11 BASIC-PLUS-2, the function must have 32 or fewer parameters. ILLAR GP AS, illegal argument passing mechanism Explanation: ERROR - The program specifies an invalid argument-passing mechanism. For example, passing strings or arrays BY VALUE, or passing an entire virtual array. User Action: Check all elements for proper parameter-passing mechanism. A-38 Compile-Time Error Messages July 1988 ILLCALFUN, illegal CALL of a DECIMAL, HFLOAT or STRING function Explanation. ERROR - You attempted to use the CALL statement to invoke either a DECIMAL, HFLOAT, or STRING function. User Action. Invoke the function not using the CALL statement. ILLCHA, illegal character <ASCII code> Explanation. WARNING - The program contains illegal or incorrect characters. User Action. Examine the program for correct usage of the VAX BASIC character set and possibly delete the character. ILLCHAEXT, illegal character <ASCII code> in external name Explanation. ERROR - The external symbol in an EXTERNAL FUNCTION or CONSTANT declaration contains an invalid character. User Action. Remove the invalid character. External names can use only printable ASCII characters: ASCII values in the range 32 to 126, inclusive. ILLCHAIDE, illegal character <ASCII value> in ID ENT directive Explanation. WARNING - A %IDENT directive contains an illegal character with the reported ASCII value. User Action. Remove the illegal character. ILLCONTYP, illegal constant type Explanation. ERROR - The program contains an invalid declaration, for example, DECLARE RFA CONSTANT. User Action. Remove the invalid data type. You cannot declare constants of the RFA data type. Compile-Time Error Messages A-39 ILLEXTPDP, <name> is illegal as a PDP-11 external name Explanation. INFORMATION - This error is reported only when the /FLAG:BP2COMPATIBILITY qualifier is in effect. The external name is longer than six characters or contains a non-RADSO character. User Action. Reduce the length of the name or remove the non-RADSO character. ILLFRMNAM, illegally formed name Explanation. ERROR - The program contains an invalid user identifier (such as a variable, constant or function name). User Action. Change the name to comply with the rules for naming user identifiers. See the VAX BASIC Reference Manual for more information. ILLFRMNUM, illegally formed numeric constant Explanation. ERROR - The program contains either: 1) an invalid E-format expression or 2) a numeric constant with a digit that is invalid in the specified radix, for example, a decimal constant containing a hexadecimal digit. User Action. Supply a valid E-format expression or a constant that is valid in the specified radix. ILLGOTO, can't GOTO outside current procedure Explanation. WARNING - The target line number of an immediate mode GOTO statement is outside of the currently compiled procedure. User Action. None. If you RUN a source file containing more than one program unit, the currently compiled program is the last program unit in the source file. If you use the OLD command to read a program into memory and load one or more object modules, then type RUN, the currently compiled procedure is the program you read into memory with OLD. A-40 Compile-Time Error Messages ILLIDEPDP, illegal %IDENT string for PDP-11 Explanation. INFORMATION - A %IDENT compiler directive contains a string that is invalid for PDP-11 systems. This error is issued only when the BP2 compatibility flagger is enabled. User Action. Change the %IDENT string. The string must be between 1 and 6 characters, and must contain only RAD-50 characters. ILLIO_CHA, illegal 1/0 channel Explanation. ERROR - A constant channel expression is greater than 99, or a variable channel expression is greater than 119. User Action. If the channel expression is a constant, change to be less than or equal to 99. A variable channel expression can be less than or equal to 119; however, channels in the range 100 through 119 are reserved for programs using LIB$GET_LUN. ILLLINNUM, illegal line number in CHAIN Explanation. ERROR - A CHAIN with LINE statement specifies an invalid line number. Either the number is outside the valid range, or a string expression follows the LINE keyword. User Action. Supply an integer line number between 1 and 32767, inclusive. ILLLOCARG, illegal LOC argument Explanation. ERROR - An argument to the LOC function is a constant, virtual array element, or expression. User Action. Change the argument to the LOC function. ILLLOONES, illegal loop nesting, expecting NEXT <variable> Explanation. ERROR - The program contains overlapping loops. User Action. Examine the program logic to make sure that the FOR and NEXT statements for the inside loop lie entirely within the outside loop. Compile-Time Error Messages A-41 ILLMATOPE, illegal matrix operation Explanation. ERROR - The program attempts matrix division. The operation is treated as a MAT multiply, and the compilation continues. User Action. Remove the attempted matrix division. VAX BASIC does not support this operation. ILLMCHPDP, illegal passing mechanism on PDP-lls Explanation. INFORMATION - This error is reported only when the /FLAG:BP2COMPATIBILITY qualifier is in effect. A parameter list contains a BY clause that is invalid in PDP-11 BASIC-PLUS-2, for example, specifying BY DESC for parameters that are not entire arrays or strings. User Action. See the VAX BASIC Reference Manual for allowable BASIC-PLUS-2 parameter-passing mechanisms. ILLMIDLEN, illegal MID assignment length Explanation. ERROR - The value of the length in the MID statement is either greater than the length of the string or less than or equal to zero. User Action. Correct the length to be between 1 and the length of the string. ILLMIDSTRT, illegal MID starting value Explanation. ERROR - The starting value in the MID statement is less than or equal to zero. User Action. Correct the starting value to be greater than or equal to one. ILLMODMIX, illegal mode mixing Explanation. ERROR - The program contains string and numeric operands in the same operation. User Action. Change the expression so that it contains either string or numeric operands, but not both. A-42 Compile-Time Error Messages ILLMULDEF, illegal multiple definition of name <name> Explanation. ERROR - The program uses the same name for: • • • • More than one variable A variable and a MAP A variable and a COMMON A MAP and COMMON User Action. Use unique names for variables, COMMONs and MAPs. ILLMULOPT, OPTIONAL cannot be specified more than once Explanation. ERROR - The OPTIONAL clause was specified more than once in the EXTERNAL statement for a single SUB or FUNCTION. This is not allowed because OPTIONAL implies that all parameters following it are optional. User Action. Fix the EXTERNAL statement so that it has at most 1 OPTIONAL clause per SUB or FUNCTION. ILLNESDEF, illegally nested DEFs Explanation. ERROR - The program contains a DEF function block within another DEF function block. User Action. Remove the inner DEF block. A DEF cannot contain another DEF. ILLOPEARG, illegal operation for argument Explanation. ERROR - The program performs an operation that is inconsistent with the data type of the arguments, for example, an arithmetic operation on variables of the RFA data type. User Action. Remove the operation or change the data type of the arguments. ILLOPTBAS, illegal OPTION BASE value Explanation. INFORMATION - A program compiled with the / ANSl_STANDARD qualifier contains an OPTION BASE statement that specifies a value other than 0 or 1. User Action. Change the OPTION BASE statement to specify either 0 or 1. Compile-Time Error Messages A-43 ILLQUACOM, illegal qualifier combination Explanation. ERROR - In the BASIC environment, you specified an illegal combination of qualifiers, such as COMPILE/NOSHOW=CDD. User Action. Issue the command again, using a valid combination of qualifiers. ILLSTROPE, illegal string operator Explanation. ERROR - The program specifies an invalid string operation; for example, A$ = B$ - C$. User Action. Replace the invalid operator. ILLUSAFIE, illegal usage of FIELDed variable Explanation. A MAT statement operates on an element of a string array that appears in a FIELD statement. User Action. Remove the array from the MAT statement. ILLUSEUNA, illegal use of unary operator Explanation. ERROR - A compiler directive contains an invalid lexical expression, for example, %IF 1 NOT 2. User Action. Correct the invalid lexical expression. ILLWAIVAL, WAIT value must be in the range 0 to 255 inclusive Explanation. ERROR - An integer expression was specified on a WAIT clause that is less than 0 or greater than 255. User Action. Specify an integer expression from 0 through 255. IMMMODOPE, immediate mode operation requires storage allocation Explanation. ERROR - An immediate mode statement attempted to allocate storage, for example, to create a new variable. User Action. None. You cannot create new storage in immediate mode. A-44 Compile-Time Error Messages IMMNOTANS, immediate mode not valid when ANSI Explanation. ERROR - An immediate mode statement was typed when in ANSI mode. User Action. None. IMPCNTNOT, implied continuation not allowed Explanation. ERROR - The program contains an implied continuation line after a statement that does not allow implicit continuation, for example, a DATA statement. User Action. Use an ampersand ( & ) to continue the statement. IMPDECILL, implicit declaration of <name> illegal in immediate mode Explanation. ERROR - A new variable was named in an immediate mode statement after a STOP, for example, PRINT B after a STOP in a program that has no variable named B. User Action. None. You cannot create new variables in immediate mode after a STOP statement. IMPDECNOT implied declaration not allowed for <name> with /EXPLICIT Explanation. ERROR - A program compiled with the /TYPE=EXPLICIT qualifier contains an implicitly declared variable. User Action. Declare the variable explicitly or compile the program without the /TYPE=EXPLICIT qualifier. INACODFOL, inaccessible code follows line <n> statement <m> Explanation. WARNING - The program contains one or more statements that cannot be accessed, for example, a multistatement line whose first statement is a GOTO, EXIT, ITERATE, RESUME, or RETURN. User Action. Make sure that these statements are the only statements on the line, or the last statement on a multi-statement line. Compile-Time Error Messages A-45 INCDIRSYN, INCLUDE directive syntax error Explanation. ERROR - A %INCLUDE directive either is not followed by a quoted string or incorrectly uses the %FROM %COD or %FROM %LIBRARY clause. User Action. Supply either a quoted string or the correct syntax for the %FROM %COD or %FROM %LIBRARY clause. INCFUNUSA, inconsistent function usage for function <name> Explanation. ERROR - The parameter list in a DEF function invocation contains a string where the function expected a number, or vice versa. This message is issued only when the invocation occurs before the DEF statement in the program. User Action. Supply a correct parameter in the function invocation or correct the parameter list in the DEF. INCRMSERR, INCLUDE directive RMS error number <number> Explanation. ERROR - A %INCLUDE directive caused an RMS error when accessing the specified file. User Action. Take action based on the reported RMS error number. INCSUBUSE, inconsistent subscript use for <array-name> Explanation. ERROR - The number of subscripts in an array reference does not match the number of subscripts specified when the array was created. User Action. Specify the same number of subscripts. INIOUTRAN, initial value must be within the specified range Explanation. ERROR - The specified initial value is not within the range specified in the RANGE clause. User Action. Change either the initial value or the range values so that the initial value falls within the range. A-46 Compile-Time Error Messages INPPROMUS, input prompt must be a string constant Explanation. ERROR - An INPUT, LINPUT, or INPUT LINE statement list contains a numeric constant immediately following the statement. User Action. Remove the numeric constant. You can specify only a string constant immediately after an INPUT, LINPUT, or INPUT LINE statement. INSERTS, assuming <keyword> before <keyword> Explanation. ERROR - The program contains a syntax error. VAX BASIC assumes a keyword is missing and continues compilation under that assumption so that other errors may be detected. The actual program line remains unchanged and no object file is produced. User Action. Examine the line carefully to discover the error. Change the program line to correct the syntax error. INSERTM, assuming <keyword> to match <keyword> Explanation. ERROR - The program contains a syntax error. VAX BASIC assumes a keyword is misspelled and continues compilation under that assumption so that other errors may be detected. The actual program line remains unchanged and no object file is produced. User Action. Examine the line carefully to discover the error. Change the program line to correct the syntax error. INSSP ADYN, insufficient space for MAP DYNAMIC variable in MAP <name> Explanation. ERROR - A variable named in a MAP DYNAMIC statement is larger than the MAP. For example, an HFLOAT variable in a MAP that is only four bytes long. User Action. Increase the size of the MAP so that it is large enough to hold the largest member. Compile-Time Error Messages A-4 7 INTCODERR, an internal coding error has been detected. Submit an SPR. Explanation. ERROR - An error has been detected in the VAX BASIC compiler. User Action. Please submit an SPR with the source code of a small program that produces this error. INTCONEXC, integer constant exceeds machine integer size Explanation. ERROR - The value specified in a DECLARE CONSTANT statement exceeds the largest allowable value for an integer. The maximum is 2147483647. User Action. Supply a value in the valid range. INTCONREQ, integer constant required Explanation. ERROR - The program contains a noninteger named constant in a context that requires an integer. For example: DIM A ('123'D) User Action. Supply an integer constant. INTDATTYP, integer data type not supported in ANSI Explanation. ERROR - A program compiled with the /ANSI_ STANDARD qualifier contains an integer variable or array. User Action. Remove the integer variable or array. INTERR, integer error or overflow Explanation. WARNING - The program contains an integer expression whose value is outside the valid range. User Action. Modify the expression so that its value is within the allowable range or use an integer data type that can contain all possible values for the expression. INVCHNNUM, invalid channel number, must be greater than zero Explanation. ERROR - A channel number less than or equal to zero was specified. User Action. Change the channel number to be greater than zero. A-48 Compile-Time Error Messages INVCONREQ, invalid conversion requested Explanation. ERROR - The program contains a reference to the REAL or INTEGER functions and the argument is an entire array, GROUP, RECORD, or RFA expression. User Action. Remove the invalid argument. The argument to these functions must be a numeric expression. INVINTTYP, invalid integer type Explanation. ERROR - A reference to the INTEGER function contains an invalid data type keyword, for example, A = INTEGER(A, SINGLE). User Action. Change the invalid data type keyword. The INTEGER function returns only BYTE, WORD, or LONG values. INVLOGNAM, invalid logical name Explanation. ERROR - The argument to the ASSIGN compiler command specified a logical name length of less than 1 or greater than 63. User Action. Supply a valid logical name. INVPRISPE, invalid priority specification, expecting < or > Explanation. ERROR - On the SET INPUT PRIORITY statement, you specified a character other than < or > to indicate the relative priorities of the two transformation numbers. User Action. Specify the priority relationship with less than (lower priority) or greater than > (higher priority). < INVREATYP, invalid real type Explanation. ERROR - A reference to the REAL function contains an invalid data type keyword, for example, A = REAL(A, LONG). User Action. Change the invalid data type keyword. The REAL function returns only SINGLE, DOUBLE, GFLOAT, or HFLOAT values. Compile-Time· Error Messages A-49 INVSUBTYP, <data-type> is not a subtype of <data-type> Explanation. ERROR - The program contains an invalid declaration containing contradictory type declarations, for example, DECLARE REAL BYTE. User Action. Supply a valid declaration. Use only valid integer subtypes for INTEGER and only valid floating-point subtypes for REAL. IS_NOTDYN, <name> is not a DYNAMIC MAP variable of MAP <name> Explanation. ERROR - A REMAP statement names a variable that was not named in the MAP DYNAMIC statement for that MAP. User Action. Remove the variable from the REMAP statement or name the variable in the MAP DYNAMIC statement for that map. ITEMUSAPP, ITERATE must appear within a loop Explanation. ERROR - The program contains an ITERATE statement that is not within a FOR-NEXT, WHILE, or UNTIL loop. User Action. Remove the ITERATE statement, or surround it with a loop. JMPBADBLO, jump to line number <line number> is into a controlled block Explanation. ERROR - The program attempts to transfer control to a WHEN block or associated handler. User Action. Change the program logic so that it does not transfer control to a WHEN block or associated handler. JMPBADLAB, jump to label: <label> is into a block Explanation. ERROR - The program attempted to transfer control into a FOR-NEXT, WHILE, UNTIL, IF or SELECT-CASE block. User Action. Change the program logic so that it does not transfer control into a block. A-50 Compile-Time Error Messages JMPBADLIN, jump to line number <number> is into a block Explanation. INFORMATION - The program transfers control to a line number within a FOR-NEXT, WHILE, UNTIL, IF or SELECT-CASE block. User Action. This is an informational message. However, it is bad programming practice to transfer control into a block. JMPINTDEF, jump into DEF Explanation. ERROR - The program attempts to transfer control into a DEF block. User Action. Change the control statement; you cannot transfer control into a DEF block except by invoking the function. JMPOUTDEF, jump out of DEF Explanation. ERROR - The program attempts to transfer control out of a DEF block. User Action. Change the control statement. Use an EXIT DEF, FNEXIT, FNEND, or END DEF statement to transfer control out of a DEF block. JMPOUTHAN, jump out of HANDLER Explanation. ERROR - The program attempts to transfer control out of an error handler. User Action. Change the control statement. Use an EXIT HANDLER, RETRY, or CONTINUE statement to transfer control out of an error handler. JMPOUTPRO, jump out of program unit Explanation. ERROR - In a source file containing more than one program module, a statement attempts to transfer control from one module into another. User Action. Change the statement that attempts to transfer control; you cannot transfer control into a different program module. Compile-Time Error Messages A-51 JMPUNRLIN, jump to unreferenceable line number <number> Explanation. ERROR - A RESUME, GOSUB, or GOTO statement attempts to transfer control to a CASE statement. User Action. Label or number the SELECT statement and transfer control to the beginning of the SELECT-CASE block. KEYCANNOT, key <name> in MAP <map-name> cannot be a dynamic variable Explanation. ERROR - A KEY clause in an OPEN statement specifies a variable declared as dynamic in a MAP DYNAMIC statement. User Action. Specify a static variable in the KEY clause; that is, declare the variable in a MAP statement, not a MAP DYNAMIC statement. KEYIS_NEE, key is needed for indexed files Explanation. ERROR - The program attempts to open an indexed file for output, and the PRIMARY KEY clause is missing. User Action. Supply a PRIMARY KEY clause. KEYMUSBE, key must be either word, longword, string, decimal, record or group Explanation. ERROR - A FIND or GET statement on an indexed file contains a key specification that is not a WORD, LONG, STRING, DECIMAL, or an 8-byte RECORD or GROUP expression. User Action. Change the key specification to be a WORD, LONG, STRING, DECIMAL, or an 8-byte RECORD or GROUP expression. KEYMUSTBE, key, <vbl-name> in map <map-name> must be either word, longword, string, decimal, record or group Explanation. ERROR - An OPEN statement contains a key specification that is not an unsubscripted WORD, LONG, STRING, DECIMAL, or an 8-byte RECORD or GROUP variable. User Action. Change the key specification to be an unsubscripted WORD, LONG, STRING, DECIMAL, or an 8-byte RECORD or GROUP variable. A-52 Compile-Time Error Messages KEYNOTMAP, KEY <vbl-name> is not an unsubscripted variable in MAP <name> Explanation. ERROR - An indexed file OPEN statement specifies a KEY variable that does not appear in a MAP statement. User Action. Place the KEY variable in the MAP referenced by the OPEN statement's MAP clause. KEYREQMAP, KEY clauses require a MAP clause Explanation. ERROR - An OPEN statement specifies KEY clauses without specifying a MAP clause. User Action. Supply a MAP clause to define the position of the keys in the record buffer. KEYSEGMUS, key segment <name> in map <map-name> must be a string key Explanation. ERROR - An OPEN statement specifies a segmented key containing a numeric variable. For example: OPEN "INDEX.DAT" AS FILE #1, ORGANIZATION INDEXED, PRIMARY KEY (A$, B$, CY.), MAP ABC I& User Action. Specify only string variables in segmented keys. KEYSINC, <keyword> keyword inconsistent with <keyword> Explanation. ERROR - An OPEN statement contains contradictory record format specifications, for example, both FIXED and VARIABLE. User Action. Specify only one record format. KEYTOOLON, KEY <name> in MAP <name> is too long (max is 255) Explanation. ERROR - A KEY variable is longer than 255 characters. User Action. Reduce the length of the KEY variable. The maximum key length is 255 characters. Compile-Time Error Messages A-53 KEYWORINC, keyword inconsistent with <OPEN clause> clause Explanation. ERROR - An OPEN statement contains an ALLOW, ACCESS, or RECORDTYPE clause whose keyword argument is invalid, for example, ACCESS FORTRAN. User Action. Change the clause argument to a valid keyword for that clause. LABNOTDEF, label <label> not defined Explanation. ERROR - The program tries to transfer control to a nonexistent label. User Action. Define the label before transferring control to it. LABNOTLAB, label <name> does not label an active block statement Explanation. ERROR - An EXIT statement in a loop, IF-THENELSE or SELECT-CASE block specifies a label that does not refer to that block. User Action. Change the program so that the label actually refers to the block in which the EXIT statement occurs. LABNOTLOO, label <name> does not label an active loop statement Explanation. ERROR - In a loop, an EXIT or ITERATE statement specifies a label that does not refer to that loop. User Action. Change the program so that the label actually refers to the loop in which the EXIT or ITERATE statement occurs. LANFEADEC, language feature is declining Explanation. INFORMATION - The program contains a language feature that is not recommended for new program development, for example, the FIELD statement. This error is reported only when the /FLAG:DECLINING qualifier is in effect. User Action. Use: 1) MAP, MAP DYNAMIC and REMAP statements instead of FIELD, 2) EDIT$ rather than CVT$$, 3) and overlaid MAPs rather than CVTxx functions. A-54 Compile-Time Error Messages LANFEAINC, language feature incompatible with BASIC-PLUS-2 Explanation: INFORMATION - The program contains syntax that results in different behavior under VAX BASIC and PDP-11 BASIC-PLUS-2, for example, opening a terminal-format file. This error is reported only when the /FLAG:BP2COMPATIBILITY qualifier is in effect. User Action: None. LANFEAINH, language feature inhibits optimization Explanation: INFORMATION - A program compiled with the /NOSETUP qualifier contains a language feature that requires /SETUP, for example, the RESUME statement. The compilation continues with /SETUP in effect. User Action: None. The program must be compiled with /SETUP in effect for the language feature to work. LANFEANOT, language feature not available in BASIC-PLUS-2 Explanation: INFORMATION - The program contains a language element that is not supported in BASIC-PLUS-2, for example, RECORD statements. This error is reported only when the /FLAG:BP2COMPATIBILITY qualifier is in effect. User Action: If the program must run under both VAX BASIC and PDP-11 BASIC-PLUS-2, you must remove the incompatible language feature. LANFEAOPE, language feature not available in VAX BASIC Explanation: ERROR - The program contains a PRINT statement with a RECORD clause. VAX BASIC does not support the RECORD clause. User Action: Remove the RECORD clause. LEFBOUSPE, left boundary must be less than the right boundary Explanation: ERROR - In a statement that specifies a viewport or windowsize, you specified a left boundary that is greater than or equal to the corresponding right boundary. User Action: Correct the left boundary so that it is less than the right boundary. Compile-Time Error Messages A-55 LENDYNSTR, string length not allowed on dynamic string <name> Explanation: ERROR - The program contains a dynamic string variable declaration that specifies a string length. User Action: Length specifications are allowed only for fixedlength strings; remove the length specification from the dynamic string, or allocate the string in a MAP or COMMON. LENNUMFIL, string length not allowed on numeric FILL Explanation: ERROR - The program contains a numeric FILL item that specifies a length. User Action: Remove the length specification from the numeric FILL item. LETDIRSYN, LET directive syntax error Explanation: ERROR - A %LET directive contains a syntax error, for example, an invalid lexical identifier. User Action: Use the correct syntax for the %LET directive. LETKEYREQ, LET keyword required in ANSI Explanation: INFORMATION - A program compiled with the / ANSI_STANDARD qualifier contains an assignment statement that omits the LET keyword. User Action: Supply a LET keyword. LEXDIRSYN, lexical directive syntax error Explanation: ERROR - A syntax error was detected in a lexical directive. User Action: Correct the syntax of the lexical directive. LEXIDEMUS, lexical identifier must be declared before reference Explanation: ERROR - You reference a lexical identifier before you declare it. User Action: Declare the lexicial identifier before you reference it. A-56 Compile-Time Error Messages July 1988 LINNOTALL, line numbers not allowed, use the EDIT command Explanation: ERROR - An EDIT command with a line number has been found in a program without line numbers. User Action: Use the EDIT command without specifying a line number to invoke a text editor. Compile-Time Error Messages A-56.1 LINNUMERR, illegal line number Explanation. ERROR - The program contains a line number that is outside the valid range or is not a valid integer (note that the per cent sign ( % ) suffix is not valid for line numbers). User Action. Specify only integer line numbers in the range 1 to 32767, inclusive. LINNUMINC, line number may not appear in INCLUDE directive file Explanation. ERROR - The file specified in a %INCLUDE compiler directive contains a line number. User Action. Remove the line number from the file. LINNUMUND, line number <n> undefined due to conditional compilation Explanation. ERROR - The program references a line number that does not appear in the object code as a result of the branch taken in a %IF-%THEN-%ELSE-%END-%IF directive. User Action. Change the %IF-%THEN-%ELSE-%END-%IF directive or remove the line number reference. LINREQTWO, LINES output requires at least 2 X,Y points Explanation. ERROR - A LINE graphic output statement specifies less than 2 points. User Action. Specify a minimum of 2 points in the LINE graphic output statement. LNPNOTBP2, programs without line numbers are not allowed in BASICPLUS-2 Explanation. INFORMATIONAL - BASIC-PLUS-2 does not support programs without line numbers. User Action. Add a line number to the first line of the program. LOGOPENON, logical operation on non-integer quantity Explanation. ERROR - The program contains a logical operation performed on strings or real numbers. User Action. Change the logical operands to integers. Compile-Time Error Messages A-57 LOOINDMUS, loop control variable must be a numeric variable Explanation. ERROR - A FOR statement specifies a string variable as the loop control variable. User Action. Specify a numeric variable. You can use only numeric variables as loop control variables. LOOINIMUS, loop initial value must be a numeric expression Explanation. ERROR - A FOR statement attempts to assign a string expression as the loop control variable's initial value. User Action. Remove the string expression. You can assign only numeric values as the loop's initial value. LOOLIMMUS, loop limit must be numeric Explanation. ERROR - A FOR statement attempts to assign a string expression as the loop control variable's limiting value. User Action. Remove the string expression. You can assign only numeric values as the loop control variable's limiting value. LOOWILNEV, loop will never execute Explanation. WARNING - The program contains a FOR/NEXT loop that is not executable; for example, FOR 1% = 1% TO 0%. Compilation continues, but the loop is ignored. User Action. Change the loop parameters or insert an appropriate STEP clause. LOWLSSUP, lower bound must be less than upper bound Explanation. ERROR - The lower bound specified in the array is greater than the upper bound. User Action. Correct the bounds. LOWNOTVIR, lower bound not permitted with virtual arrays Explanation. ERROR - Lower bounds of virtual arrays must be zero. User Action. Correct the lower bounds to be zero. A-58 Compile-Time Error Messages LOWNOTZERO, lower bound must be zero Explanation. ERROR - The lower bound of the array must be zero. User Action. Correct the lower bound to be zero. LOWRANVAL, range lower value must be less than upper value Explanation. ERROR - In the RANGE clause, the first value is greater than the second value. User Action. Change the range clause so that the first value is less than the second value. LRSETNOT, <keyword> is not allowed with MID Explanation. ERROR - The LSET and RSET keywords are not allowed with MID. User Action. Change the LSET or RSET keyword to LET. MAPDYNNOT, MAP DYNAMIC <map-name> may not be larger than 32767 bytes Explanation. ERROR - A MAP DYNAMIC statement references a map that is greater than 32767 bytes in size. User Action. Reduce the size of the map, as defined in the MAP statement(s), to 32767 bytes or less. MAPDYNREQ, MAP DYNAMIC <name> requires corresponding static MAP Explanation. ERROR - The program contains a MAP DYNAMIC statement whose MAP name does not appear in a MAP statement. User Action. Provide a MAP with the same name as the MAP DYNAMIC name. MAPNOTDEF, MAP <name> used in OPEN not defined Explanation. ERROR - An OPEN statement's MAP clause references a nonexistent MAP. User Action. Define the MAP referenced by the MAP clause, or remove the MAP clause. Compile-Time Error Messages A-59 MAPTOOLAR, MAP too large in OPEN Explanation. FATAL - The size of the MAP referenced in an OPEN statement is greater than 32767 bytes. User Action. Reduce the size of the MAP. MAPVARALI, variable <name> not aligned in multiple references in MAP <name> Explanation. ERROR - More than one overlaid MAP contains the same variable, but the variable's position differs in the MAPs. User Action. The same variable can appear in multiple overlaid MAPs, but the variable must occupy the same position in the PSECT; make sure that the variable appears in the same position in the MAPs. MAPVARREF, MAP variable <name> referenced before declaration Explanation. INFORMATION - A reference to a MAP variable occurs before the MAP statement. User Action. Make sure that the MAP statement precedes any references to variables in the MAP. MATDIMERR, matrix dimension error Explanation. ERROR - The program either: • • Contains a MAT ION, MAT TRN, or MAT INV performed on a one-dimensional array Performs a matrix operation that requires identical subscripts in the operand arrays and those arrays have different subscripts User Action. Dimension the arrays to the proper number of subscripts. MATLOWBOU, matrix must have lower bound 0 and upper bound 4 Explanation. ERROR - The specified transformation matrix either has a lower bound other than 0 or an upper bound other than 4. User Action. Declare the matrix such that both dimensions have a lower bound of 0 and an upper bound of 4. A-60 Compile-Time Error Messages MATMUL20P, MAT multiply of 2 4X4 matrices required Explanation. ERROR - You specified the wrong dimensions in a matrix in the MAT multiply statement or a WITH clause on the DRAW statement. A 2-dimensional matrix with lower bounds 0 and upper bounds 4 in both dimensions is required. User Action. Declare the matrix to be a 2-dimensional matrix with lower bounds 0 and upper bounds 4 in both dimensions. MATONEOR2, MAT statements require one or two dimensions Explanation. ERROR - A MAT statement references an array of more than two dimensions. User Action. Remove the array reference. MAT statements are valid only on arrays of one or two dimensions. MAXCONCOM, maximum conditional compilation depth exceeded Explanation. FATAL - Too many nested %IF-%THEN-%ELSE%END-%IF directives are contained in the program. User Action. Reduce the number of nested %IF-%THEN%ELSE-%END-%IF directives. You can nest up to eight such constructs. MAXDIMEXC, maximum number of dimensions exceeded. Maximum is 32 Explanation. ERROR - An array declaration specifies more than the allowed number of dimensions. User Action. Reduce the number of dimensions to 32 or less. MAXKEYSEG, maximum of 8 key segments exceeded Explanation. ERROR - An OPEN statement specifies a segmented key with more than eight segments. User Action. Reduce the number of segments in the key clause to eight or less. Compile-Time Error Messages A-61 MAXP AREXC, maximum parameters exceeded for <name> . Maximum is <number> Explanation. ERROR - The program attempts to declare a DEF with more than eight parameters or a subprogram with more than 255 parameters. User Action. Reduce the number of parameters; DEFs allow up to eight parameters and subprograms allow up to 255 parameters. MAXPAREXP, no more than <number> parameter(s) expected for < sub-func-name > Explanation. ERROR - An external SUB or FUNCTION was called with more parameters than were specified in the EXTERNAL statement, including both OPTIONAL and nonOPTIONAL parameters. User Action. Reduce the number of parameters in the call. MERGE, merged <item> and <item> Explanation. ERROR - The program contains a syntax error. VAX BASIC assumes that there is an incorrect space, for example, PR INT. Compilation continues so that other errors may be detected. The actual program line remains unchanged and no object file is produced. User Action. Examine the line carefully to discover the error. Change the program line to correct the syntax error. MINPAREXP, at least <number> parameter(s) expected for < sub-func-name > Explanation. ERROR - An external SUB or FUNCTION was called with fewer parameters than were specified as nonOPTIONAL parameters in the EXTERNAL statement. User Action. Increase the number of parameters in the call so that the number of parameters is equal to or greater than the number of non-OPTIONAL parameters. A-62 Compile-Time Error Messages MISENDIF, missing END IF directive before end of program unit Explanation. ERROR - A %IF directive crosses a program module boundary. User Action. Terminate the %IF with a %END %IF before beginning a new source module. MISENDFOR, missing END <block> for <block> at line <n> statement <m> Explanation. ERROR - The program contains a SELECT, IF, or DEF without a matching END statement. User Action. Supply a matching END statement. MISMATEND, mismatched END, expected <block> Explanation. ERROR - The program contains an incorrect END statement, for example, an END RECORD statement instead of an END GROUP statement. User Action. Supply the correct type of END statement. MISMATFOR missing NEXT for <item> at line <n> statement <m> Explanation. ERROR - The program contains a FOR, WHILE, or UNTIL without a matching NEXT. User Action. Supply the matching NEXT statement. MODNOTFND, module <mod-name> not found in text library <text-lib-name> Explanation. ERROR - The module name you specified in an %INCLUDE directive was not found in the text library you specified. User Action. Place the module name in the specified text library. MULCHRARR multiple character array name not ANSI Explanation. INFORMATION - A program compiled with the / ANSl_STANDARD qualifier contains an array whose name contains more than one character. User Action. Reduce the length of the name to a single character. Compile-Time Error Messages A-63 MULCHRDEF, multiple character DEF name not ANSI Explanation. INFORMATION - A program compiled with the / ANSl_STANDARD qualifier contains a DEF whose name contains more than one character. User Action. Reduce the length of the name to a single character. MULDEFLEX, multiple definition of lexical identifier is illegal Explanation. ERROR - A lexical constant is named in more than one %LET directive. User Action. Declare the lexical constant only once with %LET. MULHANSPE, multiple handlers specified for WHEN block Explanation. ERROR - A WHEN block specifies both an attached and detached error handler. User Action. Change the WHEN block to specify either an attached or detached error handler. MULNOTBP2, multiple program units per module not BASIC-PLUS-2 compatible Explanation. INFORMATION - A program compiled with the /FLAG:BP2COMPATIBILITY qualifier contains more than one program unit. BASIC-PLUS-2 does not allow more than one program unit in a single file. User Action. Separate the program into individual program units and compile the units separately. MULOPTBAS, multiple OPTION BASE statements not ANSI Explanation. ERROR - A program compiled with the /ANSI_ STANDARD qualifier contains more than one OPTION BASE statement. User Action. Specify the OPTION BASE statement only once per program. A-64 Compile-Time Error Messages MULPRONOT, multiple program units per module not ANSI Explanation. INFORMATION - A program compiled with the / ANSl_STANDARD qualifier contains more than one program unit. User Action. Rewrite the program converting the subprograms to subroutines. MULSTAPER, multiple statements per line not ANSI Explanation. INFORMATION - A program compiled with the / ANSl_STANDARD qualifier contains more than one statement on a line. User Action. Change the program so that each statement has its own line number. MULTDEF, multiple definition of <name> Explanation. WARNING - A variable is declared in more than one declarative statement. User Action. Make sure that the variable is declared only once. NAMNOTREC, name <name> is not of a RECORD component Explanation. ERROR - A RECORD component reference uses an invalid record name, for example, A::B when A is not a RECORD name. User Action. Change the erroneous reference. NAMTOOLON, name is too long, changed to <name> Explanation. WARNING - A variable or array name is longer than 31 characters. VAX BASIC truncates the name to 31 characters and continues compilation so that other errors may be detected. The actual program line remains unchanged and no object file is produced. User Action. Reduce the length of the variable name to 31 or fewer characters. Compile-Time Error Messages A-65 NEGFILSTR, negative FILL or string length Explanation. ERROR - The program contains a negative FILL specification or string length. User Action. Change the FILL specification or string length to a positive number. NESFORLOO, nested FOR loops with same control variable <name> Explanation. ERROR - The program contains nested FOR/NEXT loops that use the same index variable. User Action. Change the index variable for all but one of the loops. NOBASFRAM, no BASIC frame on stack Explanation. ERROR - VAX BASIC could not find a valid stack frame. This could be caused by running a program with /CHECK=NOBOUNDS or by a non-BASIC subprogram. User Action. Debug the program before running with /CHECK=NOBOUNDS or check the logic of the non-BASIC subprogram. NODESCALL, no descriptor allocated for array <name> Explanation. ERROR - An immediate mode statement required an array descriptor, but it was not available. VAX BASIC allocates array descriptors only if the program code requires it. User Action. None. NODIAGFILE, unsaved changes, no diagnostics file produced Explanation. WARNING - The program in memory contains changes that have not been saved. Therefore, no diagnostics file will be produced from this compilation. User Action. SAVE or REPLACE the file. NOEDIT, no change made Explanation. WARNING - The search string in an EDIT command was not located in the text. User Action. Enter valid search string. A-66 Compile-Time Error Messages NOFILEALL, a file specification is not allowed with the REPLACE command Explanation. ERROR - The REPLACE command does not allow the use of a file specification. User Action. Use either the SAVE command with a file specification or the REPLACE command without one. NOFRAME, compiled procedure is currently not active Explanation. WARNING - A STOP statement or CTRL/C was encountered, and neither the executing procedure nor any of its callers was the source compiled as a result of the RUN command. User Action. None; you cannot examine or modify a variable in immediate mode unless the currently compiled program unit is active. If you run a source file containing more than one program unit, the currently compiled program is the last program unit in the source file. If you use the OLD command to read a program into memory and load one or more object modules, then type RUN, the currently compiled procedure is the program you read into memory with OLD. NOHANSPE, no handler specified for WHEN block Explanation. ERROR - A WHEN block has been found that does not specify an error handler. User Action. Specify an error handler for the WHEN block. NOLINENUM, missing line number on first line Explanation. WARNING - There is no line number on the first line of the program. User Action. Add a line number to the first line of the program or remove all line numbers from the program. NOLNROOM, out of memory for line numbers Explanation. ERROR - The program contains more linenumbered statements than VAX BASIC allows. User Action. Change the program so that it uses multi-statement lines instead of having each statement on its own line or split the program into one or more program units in separate files. Compile-Time Error Messages A-67 NOMAPNAME, MAP statement requires map name Explanation. ERROR - A MAP statement does not specify a map name. User Action. Specify a name for the MAP. NOSRCLINE, unsaved changes, no source line debugging available Explanation. WARNING - The program in memory contains changes that have not been saved. Therefore, no source line debugging will be available from this compilation. User Action. SAVE or REPLACE the file. NOSUCHMAP, no such MAP area <name> Explanation. ERROR - A REMAP statement names a nonexistent MAP area. User Action. Supply a MAP before executing the REMAP statement. NOTIMP, not implemented in this version Explanation. ERROR - The program attempted to use a feature that does not exist in this version of VAX BASIC. User Action. Examine your program and remove the nonimplemented feature. NOTPASSBY, <item> may not be passed BY <mechanism> Explanation. ERROR - The program specifies an incorrect passing mechanism for a parameter's data type, or an invalid parameter. For example, you cannot pass an entire array BY VALUE, nor can you pass a label as a parameter. User Action. Specify a valid parameter or passing mechanism. NOTRANS, no main program Explanation. WARNING - When a RUN command was typed, only subroutines or functions were available. VAX BASIC requires a main program to receive the transfer of control. User Action. Supply a main program. A-68 Compile-Time Error Messages NOTRECVBY, <item> may not be received by <mechanism> Explanation. ERROR - A subprogram specifies an invalid parameter or an incorrect passing mechanism for a parameter's data type. For example, you cannot receive an entire array BY VALUE. User Action. Specify a valid parameter or passing mechanism. NOTXTROOM, out of memory for statement text Explanation. ERROR - The program contains more text than VAX BASIC allows. User Action. Split the program into one or more program units. NOVALUE, <text> keyword requires a value Explanation. ERROR - A keyword command was typed without a value. User Action. Supply a valid keyword value. NUMARREXP, numeric array expected Explanation. ERROR - A CHANGE statement does not specify a numeric array. User Action. Supply a numeric array in the CHANGE statement. NUMCONREQ, numeric constant required Explanation. ERROR - The program contains a string in a context that requires a numeric constant. For example: DECLARE INTEGER CONTANT A = 11 ABC 11 User Action. Supply a numeric constant. NUMIS_NEE, numeric expression is required Explanation. ERROR - The program contains a string expression in a context that requires a numeric expression, for example, WHILE A$. User Action. Supply a numeric expression. Compile-Time Error Messages A-69 NUMVARREQ, numeric variable required Explanation. ERROR - A nonnumeric variable was found with a numeric datatype. User Action. Specify a numeric variable. OBJFAIL, failure in loading object file Explanation. FATAL - Either an attempt was made to load a non-BASIC object module, or the compiler could not find the object file referenced by a CALL statement or EXTERNAL FUNCTION reference. User Action. If the object file resides in the VAX Common Run-Time Library, you must link the program at DCL level. If the object file is in a user-supplied library, use the LIBRARY command to install the missing object module. You can load only VAX ~ASIC object modules. ONENOTWHE, ON ERROR not allowed in WHEN block or handler Explanation. ERROR - An ON ERROR statement has been found in a WHEN block or an associated error handler. User Action. Remove the ON ERROR statement from the WHEN block or associated error handler. OPEEXPNOT, operator expected, not found Explanation. ERROR - A compiler directive contains an invalid lexical expression that has a right parenthesis immediately followed by a lexical identifier. User Action. Correct the lexical expression. OPEMUSFOL, operator must follow right parenthesis Explanation. ERROR - The program contains an incorrect lexical expression. User Action. Correct the lexical expression. OPENIN, error opening <file-name> as input Explanation. ERROR - An error was detected in attempting to open a file for input. User Action. Make sure the file specification is correct. A-70 Compile-Time Error Messages OPENOUT, error opening <file-name> as output Explanation. ERROR - An error was detected in attempting to open a file for output. User Action. Supply a valid file specification, or take corrective action based on the associated message. OPNCLAVAL, OPEN clause <clause> value greater than <number> Explanation. ERROR - An OPEN statement contains a RECORDSIZE, FILESIZE, EXTENDSIZE, WINDOWSIZE, BLOCKSIZE, BUCKETSIZE, or BUFFER clause whose argument is too large. User Action. Supply a smaller value for the argument. OPNDUPCLA, duplicate OPEN clause Explanation. WARNING - An OPEN statement contains more than one clause of the same type. User Action. Remove one of the clauses. OPNILLCLA, <clause> is an unsupported OPEN clause Explanation. ERROR - An OPEN statement specifies invalid attributes for the file, for example, CLUSTERSIZE on VAX/VMS systems, or uses the keyword COMMON in an 1/0 clause. User Action. Substitute valid attributes for the file or remove the COMMON keyword. OPNINCCLA, <keyword> keyword is inconsistent with file organization Explanation. ERROR - An OPEN statement contains a clause that is not appropriate for the specified file organization, for example, opening a relative file with the ACCESS APPEND clause. User Action. Remove the inconsistent clause. Compile-Time Error Messages A-71 OPTBASMUS, OPTION BASE must be before array declarations Explanation. ERROR - A program compiled with the /ANSI_ STANDARD qualifier contains an OPTION BASE statement that lexically follows an array declaration. User Action. Move the OPTION BASE statement so that it lexically precedes the array declaration. OPTCLACON, OPTION clause contradicts prior clause Explanation. ERROR - The OPTION statement contains contradictory clauses, for example, specifying the default integer size as both BYTE and LONG. User Action. Remove one of the clauses. OPTNOTALL, OPTIONAL not allowed on EXTERNAL PICTURE Explanation. ERROR - An attempt was made to specify the OPTIONAL keyword on an EXTERNAL PICTURE declaration. This is not allowed because OPTIONAL parameters should be used for calling non-BASIC procedures only. User Action. Remove the OPTIONAL keyword from the EXTERNAL PICTURE declaration. OPTOUTSEQ, OPTION statement out of sequence Explanation. ERROR - The OPTION statement is either: 1) not the first statement in a main program or 2) not the first statement following the SUB or FUNCTION statement. User Action. Move the OPTION statement so that it is either the first statement in the main program or the first statement following the SUB or FUNCTION statement in the subprogram. ORGUNDREQ, ORGANIZATION UNDEFINED requires FOR INPUT clause Explanation. ERROR - The program opens a file with ORGANIZATION UNDEFINED, but does not specify FOR INPUT. User Action. Specify FOR INPUT in the OPEN statement. You cannot create a file with an undefined file organization. A-72 Compile-Time Error Messages OVFCHKSUP, OVERFLOW checking supported only for INTEGER and DECIMAL Explanation. ERROR - Overflow checking was specified for a floating-point data type in: 1) a compiler command, 2) a qualifier to the DCL BASIC command, or 3) an OPTION statement. User Action. Specify overflow checking only for INTEGER and/ or DECIMAL data types. OVRNOLINE, <keyword> overrides NOLINE Explanation. WARNING - The program: 1) was compiled /NOLINES and 2) uses a keyword that requires line number information. For example, ERL and RESUME with line number both require that the program be compiled /LINES. User Action. None. If you use a keyword that requires line number information, VAX BASIC automatically overrides the /NOLINE qualifier. PAREXPFOR, <n> parameters expected for <routine> Explanation. ERROR - The CALL or invocation of a routine specifies a different number of parameters than the number specified when the routine was declared. User Action. Change the number of parameters to match the number declared. PARINCPRE, parameter <name> inconsistent with previous declaration or reference Explanation. ERROR - An external subprogram or DEF function declaration specifies a data type for one of the parameters that is different than the data type the SUB, FUNCTION, or DEF statement specifies. User Action. Change the specified data type in either the declaration or the SUB, FUNCTION, or DEF statement so that the data types agree. Compile-Time Error Messages A-73 PARMODCHA, mode for parameter <n> of routine <name> changed to match declaration Explanation. INFORMATION - The data type specified in a routine invocation does not match that of the routine declaration. VAX BASIC issues this message only if the data type conversion results in a parameter that cannot be modified by the routine that was invoked. User Action. Make the data type specifications in the declaration and the invocation match. PARMODNOT, mode for parameter <n> of routine <name> not as declared Explanation. ERROR - The CALL or invocation of a routine specifies a string argument for a parameter that was specified as a numeric when the routine was declared, or vice versa. User Action. Change the string parameter to numeric, or vice versa. PARNOTENT, parenthesis illegal, entire array required context Explanation. ERROR - Parenthesis are used to specify an entire array in a context where an entire array is always required. User Action. Remove the empty parenthesis from the entire array reference. PARSTRNOT, parameter <n> of <type> structure not as declared Explanation. ERROR - The actual parameter list in subprogram CALL or an invocation specifies an entire array where the subprogram declaration specified a simple variable or vice versa. User Action. Change the actual parameter list to match the declared parameter list or vice versa. P ARTYPREQ, parameter type specification required with /EXPLICIT Explanation. ERROR - In a program compiled with /TYPE=EXPLICIT, no data type keyword is specified for a parameter. User Action. Supply a data type keyword for the parameter. There are no default data types when you compile a program with /TYPE=EXPLICIT. A- 74 Compile-Time Error Messages PASMECDEF, passing mechanism not allowed for DEF Explanation. ERROR - A DEF function declaration specifies a passing mechanism for a parameter. User Action. Remove the passing mechanism clause. P ASMECDIS, passing mechanism disagrees with declaration Explanation. ERROR - The CALL or invocation of a routine specifies a different passing mechanism for a parameter than that specified when the routine was declared. User Action. Remove the BY clause specified in the CALL or invocation; VAX BASIC automatically passes parameters with the passing mechanism specified when the routine was declared. PASMECNOT, passing mechanism not allowed for <item> Explanation. ERROR - A program specifies a passing mechanism in a context other than the invocation or declaration of an external subprogram. User Action. Remove the passing mechanism clause. PASWITNO, <name> has a passing mechanism specified with no parameter list Explanation. WARNING - A CALL statement, external function reference, or EXTERNAL statement specifies a BY clause but does not specify a formal parameter list. User Action. Remove the BY clause or supply a parameter list. PATNOTREC, path name does not specify a CDD record Explanation. ERROR - The %INCLUDE directive contains an invalid path name for a record definition. User Action. Supply a valid path name for a record definition. PICWHINOT, exit from PICTURE while not in PICTURE Explanation. ERROR - An EXIT PICTURE statement was found in a module that is not a PICTURE subprogram. User Action. Remove the EXIT PICTURE statement. Compile-Time Error Messages A-75 POIREQONE, POINTS output requires at least 1 X, Y point Explanation. ERROR - You do not specify a point in the POINT graphic output statement. User Action. Specify a minimum of 1 point in the POINT graphic output statement. POSGTRTAR, starting position greater than target length Explanation. ERROR - The starting value in the MID statement is greater than the length of the string. User Action. Correct the value to be less than or equal to the length of the string. PRELOGNAM, previous logical name assignment replaced Explanation. INFORMATION - The specified logical name already existed. The new equivalence name replaces the old one. User Action. None. PRICDDERR, prior severe COD error Explanation. ERROR - There have been one or more severe COD errors, and this may be the reason for the following errors. User Action. Recompile the program after correcting the first COD-related errors. PRIUSICLA, PRINT USING clause must be a string expression Explanation. ERROR - A PRINT USING statement specifies a numeric format string. User Action. Supply a valid format string. PRIUSICON, PRINT USING conflicts with RECORD clause Explanation. ERROR - A PRINT USING statement contains a RECORD clause. User Action. Remove the RECORD clause or use the PRINT statement instead of PRINT USING. A-76 Compile-Time Error Messages PROSTRNES, program structures nested too deeply Explanation. FATAL - The program contains too many nested block constructs, for example, DEF function definitions. User Action. Reduce the number of nested block constructs. PROTOOBIG, program too big to compile Explanation. FATAL - The program is too big. User Action. Recode the program as two or more modules. PROWHINOT, exit from PROGRAM while not in a main program Explanation. ERROR - An EXIT PROGRAM statement was found in a program unit that is not a main program. User Action. Use the type of EXIT appropriate to the program unit. QUALERR, unknown qualifier <name> Explanation. ERROR - An attempt was made to enter an invalid qualifier to a SET, LOCK, or COMPILE command. User Action. Enter the SET, LOCK, or COMPILE command with the correct qualifier. RADNOTSUP, radix not supported Explanation. ERROR - A literal constant specifies a radix. For example, in the following DECLARE statement, H is an invalid radix specifier: 10 DECLARE LONG CONST.ANT A = H"111" User Action. Specify a valid radix. See the VAX BASIC Reference Manual for a list of the radices VAX BASIC allows. Compile-Time Error Messages A-77 REAACCINC, READ access inconsistent with FOR OUTPUT Explanation. ERROR - An OPEN statement specifies FOR OUTPUT and ACCESS READ. User Action. FOR OUTPUT specifies that a new file is created; ACCESS READ specifies that the program can only read the file. If you want to create a new file, remove the ACCESS READ clause; if you want read-only access to a file, specify FOR INPUT. READERR, error reading <file-name> Explanation. ERROR - An error was detected in attempting to read a file. User Action. Supply a valid file specification or take corrective action based on the associated message. REAWITDAT, READ without DATA statement Explanation. ERROR - The program contains a READ statement and there are no DATA statements. User Action. Supply a DATA statement or remove the READ statement. RECENTARR, RECORD entire array must not have subfields specified Explanation. ERROR - A RECORD component reference specifies an array before the end of the component path, for example, A::B(,)::C. User Action. Remove the erroneous reference. RECFILTOO, <field-name> from CDD has FILL too large Explanation. ERROR - The total size of a CDD record is greater than 65535 bytes. User Action. Reduce the size of the record. A-78 Compile-Time Error Messages RECKEYQAD, entire RECORD or GROUP must be 8 bytes in length Explanation. ERROR - The user attempts to specify an entire RECORD or GROUP name in a key value field on a GET or FIND statement and the size of the structure does not match the size of the QUADWORD. User Action. When specifying a quadword key, use an 8 byte RECORD or GROUP. Otherwise, specify the name of an elementary item in the RECORD or GROUP. RECNOTBY, record may not be passed BY <mechanism> Explanation. ERROR - The program attempts to pass a record to a subprogram using either the BY VALUE or BY DESC parameter-passing mechanism. User Action. Remove the passing mechanism, or specify BY REF. VAX BASIC programs can pass records only by reference. RECNOTDEF, record type <name> not defined Explanation. ERROR - The program declares an instance of a user data type, but this type was not defined in the program module. User Action. Define the data type with a RECORD statement. RECOVEMAP, RECORDSIZE overflows MAP Explanation. ERROR - An OPEN statement contains both a RECORDSIZE clause and a MAP clause, and the RECORDSIZE clause is larger than the MAP. User Action. Make the RECORDSIZE the same as the MAP size. RECRECDEF, recursive RECORD definition of type <name> Explanation. ERROR - The program contains two or more RECORD statements that reference each other. User Action. Change the program so that the RECORD statements do not point at each other. Compile-Time Error Messages A-79 RECTOBIGL, record too big from module <mod-name> in text library <text-lib-name> Explanation. ERROR - the text library module specified in an %INCLUDE directive contains a record longer than 255 bytes. User Action. Extract the module from the text library, edit it to remove any records longer than 255 bytes, and replace the module in the text library. RECTOOBIG, record too big from INCLUDE directive file Explanation. ERROR - The file specified in an %INCLUDE directive contains a record longer than 255 bytes. User Action. Edit the file to remove any records longer than 255 bytes. RECTOOLAR, RECORD <name> too large. Limit is 65535 bytes. Explanation. ERROR - The components of a RECORD definition add up to more than 65535 bytes. User Action. Reduce the size of the RECORD. REMARRREF, entire REMAPPED array <name> cannot be passed BY REF Explanation. ERROR - The program attempts to pass an array declared in a MAP DYNAMIC statement to an external subprogram by reference. User Action. Entire remapped arrays must be passed by descriptor. Specify the BY DESC passing mechanism either in the EXTERNAL declaration or the subprogram invocation. REMNOTALL, REM statement not allowed in programs without line numbers Explanation. ERROR - A REM statement has been found in a program without line numbers. User Action. Remove the REM statement. A-80 Compile-Time Error Messages REPLACE, assuming <operator(s)> replaced by <operator> Explanation. ERROR - The program contains a syntax error. VAX BASIC found incorrect or multiple operators where another single operator makes more sense, for example, 10 A== B. Compilation continues so that other errors may be detected. The actual program line remains unchanged and no object file is produced. User Action. Examine the line carefully to discover the error. Change the program line to correct the syntax error. REQNUMEXP, <item> requires a numeric expression Explanation. ERROR - The program contains a string expression in a context requiring a numeric expression. User Action. Supply a numeric expression. REQSTREXP, <item> requires string expression Explanation. ERROR - The program contains a numeric expression in a context requiring a string expression, for example, the file specification in an OPEN statement or the default file specification in a DEFAULTNAME clause. User Action. Supply a string expression. RESABOCON, RESEQUENCE aborted due to conditional compilation Explanation. ERROR - A resequenced program contains a %IF-% THEN-%ELSE-%END-%IF directive. User Action. Remove the %IF-% THEN-%ELSE-%END-%IF directive. RESABOSYN, RESEQUENCE aborted due to syntax error Explanation. ERROR - A RESEQUENCE operation was terminated because the program was not syntactically correct. User Action. Correct the syntax error and retry the RESEQUENCE operation. Compile-Time Error Messages A-81 RESATTINC, result attributes inconsistent with prior declaration Explanation. ERROR - An external or DEF function declaration specifies a data type for the function's result, which is different than the data type the DEF or FUNCTION statement specifies. User Action. Change the specified data type in either the declaration or the DEF or FUNCTION statement so that the data types agree. RESINCLIN, RESEQUENCE cannot be used if INCLUDE files reference line numbers Explanation. ERROR - The current program references an include file that contains line number references, for example, GOTO. User Action. Remove the %INCLUDE directive. VAX BASIC cannot resequence lines in an INCLUDE file. RESLINGTR, RESEQUENCE cannot generate line numbers greater than 32767 Explanation. ERROR - The RESEQUENCE command specified an interval or starting point that would have created a line number greater than 32767. User Action. Reduce the interval or the starting point. RESNOTWHE, RESUME not allowed in WHEN block or handler Explanation. ERROR - A RESUME statement has been found in a WHEN block or an associated error handler. User Action. Remove the RESUME statement from the WHEN block or associated error handler. RESORDLIN, RESEQUENCE cannot change the order of or delete lines Explanation. ERROR - The RESEQUENCE command specifies invalid source program changes. User Action. Supply a valid RESEQUENCE command. A-82 Compile-Time Error Messages RETCONMUS, RETRY and CONTINUE must appear in error handlers Explanation. ERROR - A RETRY or CONTINUE statement is not in an error handler associated with a WHEN block protected region. User Action. Remove the RETRY or CONTINUE statement. RFAEXPREQ, RFA expression required Explanation. ERROR - A GET BY RFA statement contains an expression that is not of the RFA data type. User Action. Supply a valid RFA expression. RFANOTALL, RFA not allowed in this context Explanation. ERROR - The program attempts to use an RFA expression in an arithmetic expression or other invalid context. User Action. Remove the RFA expression. You can use the RFA data type only in file IjO, in an assignment statement, or in a comparison. ROUSUPDEC, ROUNDing supported only for DECIMAL Explanation. ERROR - Rounding was specified for a nonDECIMAL data type in: 1) a compiler command, 2) a qualifier to the BASIC DCL command, or 3) an OPTION statement. User Action. Specify rounding only for the DECIMAL data type. RPTCOUMUS, repeat count must be positive numeric Explanation. ERROR - A FILL item specifies a nonnumeric or negative repeat count, for example, FILL(A$) or FILL(-3). User Action. Supply a valid repeat count. SCAFACINH, SCALE factor inhibits optimization Explanation. INFORMATION - This error is reported only when the /SETUP qualifier is in effect. Specifying a scale factor prevents optimization of the compiler-generated code. User Action. Compile the program without specifying a scale factor. Compile-Time Error Messages A-83 SCA LEO, scale factor used is 0 for single precision Explanation. WARNING - An attempt was made to set the SCALE factor while in single precision. User Action. Set the precision to /DOUBLE. You cannot use scaling when in single precision. SCAOUTRAN, SCALE is out of range. Valid is 0 to 6. Explanation. ERROR - The OPTION statement specifies a scale factor that is not between zero and six, inclusive. User Action. Supply a valid scale factor. SEQERR, attempt to sequence over existing statement Explanation. ERROR - A SEQUENCE command specifies a starting line number that already exists in the VAX BASIC source program in memory. User Action. Specify a starting line number higher than any existing line or delete the old statement before using the SEQUENCE command. SEVINTERR, severe internal error has been detected. Submit an SPR. Explanation. FATAL - An error has been detected in the VAX BASIC compiler. User Action. Please submit an SPR with the source code of a small program that produces this error. SPANOSPA, SPAN is inconsistent with NOSPAN Explanation. WARNING - An OPEN statement specifies both SPAN and NOSPAN. User Action. Remove one of the clauses. A-84 Compile-Time Error Messages SEVERRSCA, please submit an SPR-internal error in SCA support Explanation: FATAL - A severe error has been detected in the SCA support in the VAX BASIC compiler. If you recompile your program without the / ANALYSIS_DATA qualifier, this error should no longer occur. User Action: Please submit an SPR with the source code of a small program that produces the error. SEVINTERR, severe internal error has been detected. Submit an SPR. Explanation: FATAL - An error has been detected in the VAX BASIC compiler. User Action: Please submit an SPR with the source code of a small program that produces this error. SHRNOTAVL, Unable to access the shareable image <name> Explanation: ERROR - The shareable image is not available on your system. User Action: Install the correct version of the required shareable image. SP ANOSP A, SP AN is inconsistent with NOSP AN Explanation: WARNING - An OPEN statement specifies both SPAN and NOSPAN. User Action: Remove one of the clauses. July 1988 Compile-Time Error Messages A-84.1 SPELL, assuming <item> intended to be the keyword: <keyword> Explanation. ERROR - The program contains a syntax error. VAX BASIC assumes that a keyword has been misspelled, and compilation continues so that other errors may be detected. The actual program line remains unchanged and no object file is produced. User Action. Examine the line carefully to discover the error. Change the program line to correct the syntax error. SPENUMEXC, specified numeric exceeds valid character code Explanation. ERROR - A quoted literal of type character (C) contains a value outside the valid range, for example, '300'C. User Action. Use a valid ASCII value. STACKOVF, stack frame overflow for variables Explanation. ERROR - The program requires too much space for dynamic variables. User Action. Reduce the number of dynamic variables or place some of the variables in a MAP or COMMON. STANOTALL, statement not allowed within a PICTURE definition Explanation. ERROR - The statement you specified is not allowed in a PICTURE definition. User Action. Remove the statement from the PICTURE definition. STARISNEE, star(*) is needed in DEF, not"/" Explanation. ERROR - The program contains a statement that starts with DEF/. User Action. Change the DEF/ to DEF•. STRARRNOT, string array not ANSI Explanation. INFORMATION - A program compiled with the / ANSl_STANDARD qualifier contains a string array. User Action. Remove the string array. Compile-Time Error Messages A-85 STRCONEXP, string constant expression is too long Explanation. ERROR - The program contains a DECLARE STRING CONSTANT statement where the value assigned to the constant exceeds the maximum number of characters allowed for string constant expressions. The maximum length of a string constant expression at compile-time is 498 characters. User Action. Change the string constant to a string variable and assign the string expression to the variable at run-time. STRCONREQ, string constant required Explanation. ERROR - The program contains a numeric expression in a context that requires a string expression, for example: DECLARE STRING CONSTANT ABC = 123 User Action. Supply a string literal or a named string constant. STRDEFNOT, string DEF not ANSI Explanation. INFORMATION - A program compiled with the / ANSI_STANDARD qualifier contains a string DEF. User Action. Remove the string DEF. STRLENANY, string length not allowed on ANY Explanation. ERROR - An ANY parameter specifies a string length in an EXTERNAL statement. This is not allowed because ANY implies that you can use any data type, not specifically a string data type. User Action. Remove the string length specification from the ANY clause. STRIS_NEE, string expression is required Explanation. ERROR - The program contains a numeric expression where a string expression is needed, for example, NAME 1% AS "ABC.DAT". User Action. Supply a string expression. A-86 Compile-Time Error Messages STRLENDYN, string length not allowed on MAP DYNAMIC variable Explanation. ERROR - A string variable in a MAP DYNAMIC statement specifies a string length. User Action. Remove the string length. All string variables named in a MAP DYNAMIC statement have a length of zero until a REMAP statement executes. STRLENINC, virtual array string <name> length increased from <n> to <m> Explanation. WARNING - In a string virtual array DIM statement, the specified string length is not a power of two. User Action. None. VAX BASIC increases the string length to the next higher power of two. STRLENMUS, string length specification for <name> must be numeric Explanation. ERROR - The length specification for a fixed-length string is nonnumeric, for example, COMMON A$ = "ABC". User Action. Supply a numeric length specification. STRLENNOT, string length not allowed on numeric variable <name> Explanation. ERROR - The declaration for a numeric variable contains a string length specification. User Action. Remove the string length specification. STRLENTRU, virtual array string <name> length truncated from <n> to <m> Explanation. WARNING - A string virtual array specifies a string length greater than 512. VAX BASIC truncates the length specification to 512. User Action. None. The maximum string length for virtual arrays is 512. STRLITREQ, string literal required for compiler directive Explanation. ERROR - A quoted string is missing in a compiler directive that requires one, for example, %IDENT. User Action. Supply a string literal for the compiler directive. Compile-Time Error Messages A-87 STROUTRAN, string is too large Explanation. ERROR - A string exceeds the maximum allowable length. The maximum length is 65535 characters. User Action. Reduce the length of the string. STRRECFIE, string record element may not be FIELDed Explanation. ERROR - A FIELD statement contains a string record element as the fielded variable. User Action. Replace the string record element with a dynamic string. Fielded variables must be dynamic. STRRECFOR, stream format must have sequential organization Explanation. ERROR - A file was opened using STREAM as a record format, but the specified organization was not SEQUENTIAL. User Action. Change the OPEN statement so that it specifies ORGANIZATION SEQUENTIAL. STRVAREXP, string variable expected Explanation. ERROR - A CHANGE statement specifies a numeric variable. User Action. Supply a string variable; the CHANGE statement changes a string variable to a numeric array and vice versa. STRVARREQ, string variable required Explanation. ERROR - A statement references a numeric variable instead of a string variable, for example, LINPUT A%. User Action. Supply a string variable instead of a numeric variable. SUBMAYNOT, subscript may not be specified for entire array Explanation. ERROR - A CALL statement or external function reference passes an entire array as a parameter and contains a subscript expression, for example, A(,,3). User Action. Remove the subscript expression. You cannot specify any subscripts when passing an entire array as a parameter. A-88 Compile-Time Error Messages SUBOUTRAN, subscript out of range for <array-name> Explanation. ERROR - The program references an array element with constant subscript(s) outside the bounds of the array. User Action. Check program logic to make sure all subscripts are within the bounds of the array. SUBRECCOM, subscripting error in RECORD component Explanation. ERROR - The program contains a RECORD component reference with invalid subscripts, for example, A::B(l,2)::C where B has only one subscript, or A::B where A requires a subscript. User Action. Change the erroneous reference. You must specify as many subscripts as were defined in the RECORD. SUBWHINOT, exit from SUB seen while not in SUB Explanation. ERROR - A program contains an EXIT SUB or SUBEXIT statement with no preceding SUB statement. User Action. If the program is a subprogram, supply a SUB statement; otherwise, remove the EXIT SUB or SUBEXIT statement. SUFFILNOT, suffix not allowed on FILL after datatype keyword Explanation. ERROR - A FILL item defined with an explicit data type ends in a percent or dollar sign. User Action. Remove the FILL item's percent or dollar sign. SUFINTONLY, % only allowed with BYTE, WORD, LONG, or INTEGER keywords Explanation. ERROR - The % suffix is only allowed on integer data types. User Action. Remove the % suffix from the variable name or change the data type keyword. Compile-Time Error Messages A-89 SUFNOTALL, suffix not allowed on variable <name> Explanation. ERROR - A name, which cannot end in a percent sign or dollar sign, such as a label name, ends with either a percent sign or dollar sign. User Action. Remove the variable's percent or dollar sign. SUFNOTHAN, suffix not allowed on HANDLER <name> Explanation. ERROR - A HANDLER name ends in a percent or dollar sign. User Action. Remove the percent or dollar sign from the HANDLER name. SUFNOTREC, suffix not allowed for record type Explanation. ERROR - A record definition specifies a userdefined record type that ends in a percent or dollar sign. User Action. Remove the record type's percent or dollar sign. SUFSTRONLY, $ is only allowed with STRING keyword Explanation. ERROR - The $ suffix is only allowed on string data types. User Action. Remove the $ suffix from the variable name or change the data type keyword. SYNNOTANS, syntax check mode not allowed when ANSI Explanation. ERROR - A SET /SYNTAX-CHECK command was entered when the / ANSLSTANDARD qualifier was in effect. User Action. None; syntax checking is not supported in ANSI mode. SYSERROR, system service error Explanation. ERROR - An error was detected while executing a system service. User Action. Take corrective action based on the associated message. A-90 Compile-Time Error Messages TEXFOLEND, text following end of program unit must be on new <type of line> line Explanation: ERROR - The compiler detected text following an END, END SUB, or END FUNCTION statement. User Action: Remove the text. In a multi-module source file with line numbers, any text following an END, END SUB, or END FUNCTION statement must begin on a numbered line. In a multi-module source file without line numbers, any text following an END, END SUB, or END FUNCTION statement must begin on a new physical line. TEXLINMSG, text line exceeded 255 characters Explanation: INFORMATION - An input line contains more than 255 characters. VAX BASIC saves the first 255 input characters into the line buffer and ignores the rest of the input. User Action: Supply no more than 255 characters per input line to avoid truncation of input. TEXPATMUS, text path must be "RIGHT", "LEFT", "UP" or "DOWN" Explanation: ERROR - You specified an invalid value for the path specification of the SET TEXT PATH statement. User Action: Specify one of the values listed in the message. TEXPREMUS, text precision must be "STROKE","CHAR" or "STRING" Explanation: ERROR - You specified an invalid value for the text precision of the SET TEXT FONT statement. User Action: Specify one of the values listed in the message. THEMUSFOL, THEN directive must follow a lexical expression Explanation: ERROR - A %IF directive contains a lexical expression that is not immediately followed by a %THEN. User Action: Supply a % THEN clause. % THEN, %ELSE, and %END %IF are required in a %IF directive. July 1988 Compile-Time Error Messages A-91 TOMCHINFO, extra information on command line has been ignored Explanation: INFORMATION - You supplied an argument to a CONTINUE, EXIT, IDENTIFY, or SCRATCH command. These commands do not accept arguments. VAX BASIC ignores the extra data and executes the command. User Action: Remove the argument from the command. TOOFEWARG, too few arguments Explanation: ERROR - The invocation of a VAX BASIC built-in function contains too few arguments. User Action: Supply the correct number of arguments to the function. TOOMANARG, too many arguments Explanation: ERROR - The invocation of a VAX BASIC built-in function contains too many arguments. User Action: Supply the correct number of arguments to the function. TOOMANIND, too many array indices active Explanation: ERROR - A subscript expression contains more than 100 array indices between the open parenthesis and the close parenthesis. User Action: Reduce the number of active array indices. TOOMANKEY, too many keys - limit is 255 Explanation: ERROR - An OPEN statement specifies more than 255 index keys. User Action: Reduce the number of index keys. The maximum is 255. TOOMANP AR, too many function parameters active Explanation: ERROR - An external function invocation contains too many expressions in the actual parameter list. User Action: Reduce the number of expressions in the actual parameter by assigning the expressions to temporary variables. A-92 Compile-Time Error Messages TRAFUNONL, Transformation functions only permitted with multiplication Explanation: ERROR - A graphics transformation function is used in a MAT statement other than matrix multiplication. User Action: Remove the transformation function from the MAT statement. TRAOUTRAN, transformation number must be in the range 1 - 255 Explanation: ERROR - You specified a transformation number that is less than 1 or greater than 255. User Action: Change the transformation number to be within the range 1 to 255. Compile-Time Error Messages A-92.1 TYPDEFSTR, TYPE default of STRING is not allowed. Explanation: ERROR - STRING was specified as the default data type in: 1) a compiler command, 2) a qualifier to the DCL BASIC command, or 3) an OPTION statement. User Action: Specify a numeric data type as the default. UNDEFINED, unresolved/undefined symbols Explanation: ERROR - A program executed in the BASIC environment calls or invokes a subprogram or routine that has not been loaded. User Action: Load the subprogram or routine before running the program in the BASIC environment. UNDLINNUM, undefined line number Explanation: ERROR - A statement tries to transfer control to a nonexistent line. Or, in a numberless program, a line number is referenced. User Action: Replace the nonexistent line number with the correct destination line number or label. UNELEXDIR, unexpected lexical directive encountered Explanation: ERROR - The specified lexical directive is not legal in this statement. User Action: Use a supported lexical directive. UNEXPEOF, unexpected end of file Explanation: ERROR - An end-of-file was specified immediately after an ampersand continuation character. User Action: Remove the ampersand continuation character or continue the line. UNKCOMINP, unknown command input Explanation: ERROR - An attempt was made to enter an invalid or unknown command. User Action: Enter the VAX BASIC command correctly. July 1988 Compile-Time Error Messages A-93 UNLINCREA, UNLOCK EXPLICIT clause inconsistent with ACCESS READ Explanation: ERROR - An OPEN statement contains both an ACCESS READ and an UNLOCK EXPLICIT clause. This is inconsistent because ACCESS READ specifies no record locking while UNLOCK EXPLICIT specifies that all accessed records remain locked until explicitly unlocked. User Action: Either remove the UNLOCK EXPLICIT clause or change the ACCESS clause. UNSCDDLEV, unsupported CDD level <number> . Supported level is <number> Explanation: ERROR - The current CDD version is incompatible with VAX BASIC. User Action: Use a supported version of the CDD. UNTSTRLIT, unterminated string literal Explanation: ERROR - The program contains an improperly terminated string literal; for example, "ABC , "ABC', and 'ABC" are all improperly terminated. User Action: Use the same type of quotation mark (either single or double) for both beginning and ending string delimiters. USEONLALO, USE only allowed inside WHEN blocks Explanation: ERROR - A USE statement is not within a WHEN block. User Action: Remove the USE statement. USERABORT, user ABORT directive <text> Explanation: FATAL - The compilation was terminated as the result of a %ABORT directive. The compiler prints the text following the %ABORT. User Action: None. A-94 Compile-Time Error Messages USERPRINT, <text> Explanation. SUCCESS - The compilation found a %PRINT directive and printed the specified message to the terminal and listing file. User Action. None. USEVARNOT, user variable <name> not allowed in declaration Explanation. ERROR - The parameter list in an external subprogram declaration contains a user variable name. User Action. Remove the variable from the parameter list. When declaring a routine, the parameter list can contain only data type and parameter-passing mechanism specifications. VAL TOOLAR, value too large for constant Explanation. WARNING - The value of an EXTERNAL CONSTANT is larger than the specified data type allows. User Action. Make sure the data type specified in the EXTERNAL CONSTANT statement matches that of the actual constant. VALUEREQ, PRINT USING requires a value Explanation. ERROR - A PRINT USING statement must have at least one expression or value. User Action. Supply an expression or value at the end of the PRINT USING statement. VARCONREQ, variable or constant required Explanation. ERROR - The program contains an executable DIM statement that contains an expression in the bounds list. User Action. Remove the expression from the bounds list. Executable DIM statements can have only constants or variables (simple or subscripted) as bounds. Compile-Time Error Messages A-95 VERJUSMUS, vertical justification must be "TOP", "CAP","HALF","BASE", "BOTTOM" or "NORMAL" Explanation. ERROR - You specified an invalid value for the vertical component of the SET TEXT JUSTIFY statement. User Action. Specify one of the values listed in the message. VIRARROVF, virtual array space exceeded at array <name> Explanation. ERROR - The storage for virtual arrays on a single channel exceeds 2147483647 bytes. User Action. If there is only one virtual array on the channel, you must reduce the amount of storage used by the array. However, if there is more than one virtual array on the channel, you can put each array on a separate channel. VIRNOTALL, virtual array not allowed in graphics statements Explanation. ERROR - You specified an entire virtual array on a statement that does not allow them. User Action. Specify a non-virtual array in place of the virtual array. VIRRECTOO, virtual RECORD <name> is too large. Limit is 512 bytes Explanation. ERROR - The elements of a virtual array are of type <name> and the total storage requirement for each element is greater than 512 bytes. User Action. Reduce the size of the RECORD. WRITEERR, error writing <file-name> Explanation. ERROR - An error was detected in attempting to write to a file. User Action. Supply a valid file specification or take corrective action based on the associated message. WROTYPLIB, library <lib-name> is not an OBJECT or IMAGE library Explanation. WARNING - The logical BASIC$LIBn translates to a library that is not an object library or a shareable image library. User Action. Change the logical BASIC$L1Bn to translate to an object library or a shareable image library. A-96 Compile-Time Error Messages XYPOIREQ, X, Y point required between semicolons Explanation. ERROR - In a list of points in a statement such as PLOT LINES, you specified two semicolons in a row without an X,Y point specification between them. User Action. Either supply another point or remove the extra semicolon. Compile-Time Error Messages A-97 Appendix B Run-Time Error Messages VAX BASIC returns run-time error messages if an error occurs while a program is executing. The error is diagnosed and for programs without line numbers, VAX BASIC indicates the program line that generated the error. Warning error messages indicate that an error has occurred, but program execution continues. In some cases, VAX BASIC reprompts for more information or correct data; in other cases, VAX BASIC performs the specified operation, but the results are not as expected. Fatal error messages indicate that the program has aborted. You can recover from most fatal errors by including error-handling routines in your program and by specifying OPTION HANDLE= FATAL. Certain errors, however, are not recoverable even when error-handlers are used. In the description of these errors they are designated as not trappable. You do not need error-handling routines to trap errors that generate warning messages. Section B. l of this appendix lists VAX BASIC run-time errors, alphabetized by mnemonic code. Section B.2 is a cross reference numerical listing of run-time errors generated by VAX BASIC; Section B.3 lists error messages which VAX BASIC does not generate, but which can be displayed with the ERT$ function. See the VAX BASIC Reference Manual for information about RMSSTATUS and VMSSTATUS. B. 1 VAX BASIC Run-Time Errors by Mnemonic The VAX BASIC error message format is: XBAS-<l>-<mnemonic>, <message> -BAS-I-FROLINMOD, from Line x in module y Run-Time Error Messages B-1 <I> Is a letter indicating the severity of the error. The severity indicator can be one of the following: • • • • I, indicating information W, indicating a warning E, indicating an error F, indicating a severe error <mnemonic> Is a 3- to 9-character string that identifies the error. <x> Is the line number where the error occurred. <y> Is the name of the module where the error occurred. Warning error messages indicate that an error has occurred, but program execution continues. In some cases, VAX BASIC reprompts for more information or correct data; in other cases, VAX BASIC performs the specified operation, but the results are not as expected. Fatal error messages indicate that the program has aborted. ARGDONMAT, Arguments don't match (ERR=88) Explanation. The proper array descriptor was not specified for a matrix operation. User Action. Use VAX BASIC to create the array. ARGTOOLAR, Argument too large in EXP (ERR=49) Explanation. The program contains: • • An argument to the EXP function larger than 88 An exponentiation operation that results in a number greater than 1E38 User Action. Change the EXP argument to be in the valid range, or reduce the size of the exponent. 8-2 Run-Time Error Messages ARRMUSSAM, Arrays must be same dimension (ERR=238) Explanation. The program attempts to perform matrix addition or subtraction on input arrays with a different dimensions. User Action. Use arrays that have identical dimensions. ARRMUSSQU, Arrays must be square (ERR=239) Explanation. The program attempts matrix inversion (MAT INV) on an array that is not inversible. User Action. Use only square arrays when performing a matrix inversion. ARRTOOSMA, Array too small (ERR=l 97) Explanation. The array you referenced with a graphics statement is too small. Check the description of the graphics statement to get the minimum size requirement for the array. User Action. Increase the size of the array. BADDIRDEV, Bad directory for device (ERR=l) Explanation. The device directory does not exist or is unreadable. User Action. Supply a valid directory. BADRECIDE, Bad record identifier (ERR=143) Explanation. The program attempted a record access that specified: • • A zero or negative record number on a RELATIVE file A null key value on an INDEXED file User Action. Change the record number or key specification to a valid value. BADRECVAL, Bad RECORDSIZE value on OPEN (ERR=148) Explanation. The value in the RECORDSIZE clause in the OPEN statement either (1) is zero or greater than 65535 or (2) does not match the recordsize of an existing file. User Action. Change the value in the RECORDSIZE clause. Run-Time Error Messages B-3 CANCHAARR, Cannot change array dimensions (ERR=240) Explanation. The program attempts to redimension an array to a different number of dimensions. User Action. Change the arrays dimensions in the DIM or MAT statement. CANFINFIL, Can't find file or account (ERR=S) Explanation. The specified file or directory is not present on the device. User Action. Supply a valid file specification. CANINVMAT, Can't invert matrix (ERR=56) Explanation. The program attempts to invert a single-dimension matrix. User Action. Supply a matrix of the proper form for inversion. CANOPEFIL, Cannot open file (ERR=162) Explanation. The program attempts to open a file that cannot be opened. User Action. Use VMSSTATUS to determine the RMS failure that caused the error. CLIPONOFF, Clipping must be set to ON or OFF (ERR=259) Explanation. Valid strings for the SET CLIP statement are "ON" and "OFF". User Action. Change the string to either "ON" or "OFF". COLNOTCON, Color indices are not contiguous (ERR=261) Explanation. The color indices on the device you are using are not contiguous. User Action. Unlike most devices, all color indices between zero and the number returned by the ASK MAX COLOR statement, are not available on this device. B-4 Run-Time Error Messages COONOTNDC, Coordinates are not within NDC space (ERR=273) Explanation. The boundaries of NDC space are O,l,0,1; coordinates must be within this range. User Action. Supply coordinates with values between 0 and 1. Make sure that the minimum value of x is less than the maximum value of x and that the minimum value of y is less than the maximum value of y. CORFILSTR, Corrupted file structure (ERR=29) Explanation. RMS has detected an invalid file structure on disk. User Action. See your system manager. DATFORERR, Data format error (ERR=SO) Explanation. The program specifies a data type in a statement that does not agree with the value supplied or invalid data was used in string arithmetic. User Action. Change the statement or supply data of the correct type. DATOVERF, data overflow (ERR= 289) Explanation. The keystroke retrieved by the INKEY$ function caused the type-ahead buffer to overflow or the terminal attempted to send a valid ANSI escape sequence that did not correspond to a keystroke. User Action. Specify the DCL command SET TERMINAL/HOSTSYNC, before using the INKEY$ function. This command will prevent the type-ahead buffer from overflowing. DATTYPERR, Data type error (ERR=lOl) Explanation. The program attempts to access a parameter passed BY DESC (by descriptor), and the descriptor contains an incorrect data type. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE= FATAL. User Action. Check the program code that created the passed parameter and make sure it creates a parameter of correct data type. Run-Time Error Messages B-5 DEADLOCK, Detected deadlock while waiting for GET or FIND (ERR=193) Explanation. The record your program is trying to access is currently locked on another channel or by another process. Simultaneously, your program has locked a record that the other user cannot access. The deadlock cannot be resolved. User Action. Possible solutions include: • • Use the FREE statement to unlock all locked records Use GEL.REGARDLESS if read access is sufficient DECERR, DECIMAL error or overflow (ERR=l 81) Explanation. The result of a DECIMAL expression is greater than or requires more precision than can be contained in the variable. User Action. Reduce the magnitude of the expression or increase the allowed digits in the DECIMAL variable. User Action. Check program logic or trap the error in an error handler. DEVHUNWRI, Device hung or write locked (ERR=14) Explanation. The program attempted an operation to a hardware device that is not functioning properly or is protected against writing. User Action. Check the device on which the operation is performed. DEVINMET, Device is an input metafile (ERR=270) Explanation. The operation cannot be performed on an input metafile (device type 3). User Action. Specify the device id for a device other than an input metafile. DEVNOTOPE, Device is not open (ERR=268) Explanation. The device has not been identified in an OPEN ... FOR GRAPHICS statement. User Action. Specify the device id number in an OPEN ... FOR GRAPHICS statement. B-6 Run-Time Error Messages DEVOPEINC, Device and operation are incompatible (ERR=272) Explanation. The operation you requested cannot be performed on the specified device. For example, output cannot be displayed on a device that is for input only. User Action. Specify the device id for a device with the appropriate compatibility. Device types are listed in Programming with VAX BASIC Graphics. DEVOUTMET, Device is an output metafile (ERR=269) Explanation. The specified device is an output metafile (device type 2). User Action. Specify the device id for a device other than an output metafile. DEVTYPNOT, Device type is not supported (ERR=267) Explanation. The specified device type is not supported by VAX GKS. User Action. Specify an alternative device type. Standard supported device types are listed in Programming with VAX BASIC Graphics and in the VAX GKS documentation. Verify with your system manager that support for the specified device has been installed. Also, verify that the VAX GKS startup command procedure has properly executed. DIFUSELON, Differing use of LONG/WORD or SINGLE/DOUBLE qualifiers (ERR=229) Explanation. The main and subprograms were compiled with different LONG/WORD modes. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE= FATAL. User Action. Recompile one of the programs with the same qualifier as the other. Run-Time Error Messages 8-7 DIMOUTRAN, Dimension number out of range (ERR=195) Explanation. The upper or lower bound of the specified dimension cannot be returned because the array has fewer dimensions than the one requested. User Action. Change the dimensions specified with the LBOUND or UBOUND function. DIRERR, Directive error (ERR=253) Explanation. A system service call resulted in an error. User Action. See the VAX/VMS 1/0 Reference Volume or the VAX Record Management Services Reference Manual. DIVBY-2ER, Division by 0 (ERR=61) Explanation. The program attempts to divide a value by zero. User Action. Check program logic and change the attempted division or trap the error in an error handler. DUPKEYDET, Duplicate key detected (ERR=134) Explanation. In a PUT operation to an indexed file, a duplicate key was specified, and DUPLICATES was not specified when the file was created. User Action. Change the duplicate key, or re-create the file specifying DUPLICATES for that key. ECHTYPNOT, Prompt/echo type not supported (ERR=256) Explanation. The specified prompt or echo type is invalid. VAX BASIC supports only the default prompt and echo types. User Action. Do not change the prompt or echo type. If you do so, you should continue to use direct calls to VAX GKS routines rather than use VAX BASIC input statements. ENDFILDEV, End of file on device (ERR=ll) Explanation. The program attempted to read data beyond the end of the file. User Action. None. The program can trap this error in an error handler. B-8 Run-Time Error Messages ENTPOINOT, Entered points not within a transformation (ERR=285) Explanation. Input points are not within the viewport of a defined transformation. User Action. Issue a warning to the user to input points within the defined area. Alternatively, you can change at least one transformation to include the viewport area not defined. At the start of program execution, transformation 1 includes all of NDC space. Optionally, you can define one transformation to cover the default viewport. ERRFILCOR, Error on OPEN - file corrupted (ERR=l 78) Explanation. The program attempted to open an invalid structure on disk. User Action. See your system manager. ERRTRANEE, ERROR trap needs RESUME (ERR=246) Explanation. An error handler attempts to execute an END, END SUB, END FUNCTION, SUBEND, FUNCTIONEND, or FNEND statement without first executing a RESUME statement. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE= FATAL. User Action. Change the program logic so that the error handler executes a RESUME statement before executing an END, END SUB, END DEF, SUBEND, FUNCTIONEND, or FNEND statement. FATSYSIO_, Fatal system I/O failure (ERR=12) Explanation. An I/O error has occurred in: (1) the system or (2) Record Management Services. The last operation will not be completed. User Action. See the VAX/VMS System Messages and Recovery Procedures Reference Manual for RMS errors or retry the operation. Use VMSSTATUS to return the VAX/VMS condition code that caused the error. Run-Time Error Messages 8-9 FIEOVEBUF, FIELD overflows buffer (ERR=63) Explanation. A FIELD statement attempts to access more data than exists in the specified buffer. User Action. Change the FIELD statement to match the buffer's size, or increase the buffer's size. FILACPFAI, FILE ACP failure (ERR=252) Explanation. The operating system's file handler reported an error to RMS. User Action. See the VAX/VMS I/O Reference Volume or the VAX Record Management Services Reference Manual. FILATTNOT, File attributes not matched (ERR=160) Explanation. The following attributes in the OPEN statement do not match the corresponding attributes of the target file: • • • • • ORGANIZATION BUCKETSIZE BLOCKSIZE Key number, size, position, or attributes (CHANGES and DUPLICATES) Record format User Action. Change the OPEN statement attributes to match those of the file or remove the clause. FILEXPDAT, File expiration date not yet reached (ERR=174) Explanation. The program attempted to delete a file before the file's expiration date was reached. User Action. Change the file's expiration date. FILIS_LOC, File is locked (ERR=138) Explanation. The program does not allow shared access, and attempts to access a file that has been locked by another user or by the system. User Action. Change the OPEN statement to allow shared access or wait until the file is released by other users. 8-1 0 Run-Time Error Messages FLOPOIERR, Floating point error or overflow (ERR=48) Explanation. A program operation resulted in a floating-point number with absolute value outside the allowable range for that data type. User Action. Check program logic or trap the error in an error handler. FNEWITFUN, FNEND without function call (ERR=73) Explanation. The program executes an END DEF or FNEND statement before executing a function call. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE= FATAL. User Action. Check program logic to make sure that END DEF or FNEND statements are executed only in multi-line DEFs or remove the END DEF or FNEND statement. GKSNOTINS, VAX GKS is not installed (ERR=226) Explanation. Graphics statements are not operational when VAX GKS is not installed. User Action. See your system manager. ILLALLCLA, Illegal ALLOW clause (ERR=168) Explanation. The value specified for the ALLOW clause (sharing) on the OPEN statement is illegal for the type of file organization. User Action. Change the ALLOW clause argument. ILLARGLOG, Illegal argument in LOG (ERR=53) Explanation. The program contains a negative or zero argument to the LOG or LOGlO function. User Action. Supply an argument in the valid range. Run-Time Error Messages B-11 ILLARESTY, Illegal area style (ERR=262) Explanation. Area style must be one of the following: • • • • SOLID (the default) HOLLOW HATCH PATTERN User Action. Specify a valid area style for the device. ILLBYTCOU, Illegal byte count for 1/0 (ERR=31) Explanation. A PRINT or INPUT list invoked a function that closed an 1/0 channel. User Action. Change the function so that it does not close the I/ 0 channel. ILLCNTCLA, Illegal count clause (ERR=290) Explanation. In a graphics statement, you specified a COUNT clause with a numeric value which exceeds the size of the array. User Action. Specify a numeric value which is less than or equal to the size of the array. ILLCOLIND, Illegal color index (ERR=280) Explanation. The index you specified is not supported by the device. User Action. Specify a valid color index. The valid range of indices for the device is from 0 to the value retrieved by the ASK MAX COLOR statement. ILLCOLMIX, Illegal color mix (ERR-291) Explanation. The color mix value specified on the SET COLOR MIX statement is outside the range of 0 to 1. User Action. Specify a value between 0 and 1. B-12 Run-Time Error Messages ILLDEVID, Illegal device identification number (ERR=266) Explanation: The device identification number is beyond the valid range of 0 through 255. User Action: Specify a device identification number between 0 and 255. ILLDEVNAM, Illegal device name in OPEN (ERR=292) Explanation: An explicit or implicit OPEN ... FOR GRAPHICS statement contains an illegal device name for the device type being used. Possible causes include: • • • • Specifying a device that does not exist on the system Specifying a logical name that is not defined Specifying a file name that does not exist when the device type is for an input metafile Specifying a file name for a device type that requires a VMS physical device name User Action: Specify an appropriate device name. ILLECHARE, Illegal echo area (ERR=283) Explanation: The specified echo area boundaries are invalid. User Action: Specify echo area boundaries within the device viewport. ILLEXIDEF, Illegal exit from DEF* (ERR=245) Explanation: A multi-line DEF* contains a branch to an END, END SUB, END DEF, SUBEND, or FUNCTIONEND statement. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE= FATAL. User Action: Change the program logic so that the program executes the multi-line function's END DEF or FNEND statement before executing the END, END SUB, END DEF, SUBEND, or FUNCTIONEND statement. Run-Time Error Messages 8-13 ILLFIEVAR, Illegal FIELD variable (ERR=l 22) Explanation: A FIELDed variable· is referenced after a nonBASIC subprogram closed the file associated with that variable. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE = SEVERE. User Action: Check program logic; do not reference the variable after the file has been closed. ILLFILNAM, Illegal file name (ERR=2) Explanation: A file name is: (1) too long, (2) incorrectly formatted, or (3) contains embedded blanks or invalid characters. User Action: Supply a valid file specification. ILLILLACC, Illegal or illogical access (ERR=136) Explanation: The requested access is impossible because: • • • The attempted record operation and the ACCESS clause in the OPEN statement are incompatible. The ACCESS clause is inconsistent with the file organization. ACCESS READ or APPEND was specified when the file was created. User Action: Change the ACCESS clause. ILLINIVAL, Illegal initial value (ERR=284) Explanation: The current initial value specified on the SET INITIAL VALUE or LOCATE VALUE statement is beyond the range of possible values. User Action: Specify an initial value within the default range (0 through 1) or within the alternative range you optionally specified, or change the range limits. ILLIO_CHA, Illegal I/O channel (ERR=46) Explanation: The program specified an I/O channel outside the legal range. User Action: Specify I/O channels in the range 1 to 99, inclusive or one returned from LIB$GET_LUN. B-14 Run-Time Error Messages July 1988 ILLKEYATT, Illegal key attributes (ERR=137) Explanation. The program specified CHANGES for the primary key. User Action. Remove the CHANGES specification from the primary key. You can specify CHANGES only for alternate keys. ILLLINSIZ, Illegal line size (ERR=275) Explanation. The specified line size is less than or equal to zero. User Action. Specify a line size value greater than zero. ILLLINSTY, Illegal line style number (ERR=274) Explanation. The specified line style number is less than or equal to zero. User Action. Specify a valid line style value greater than zero. ILLNETOPE, Illegal network operation (ERR=l 90) Explanation. The program tries to mix GET and PUT operations, or PRINT and INPUT operations, on a remote terminal-format file. User Action. Change the file organization when opening the file to be sequential variable. ILLNUM, Illegal number (ERR=52) Explanation. A value supplied to a numeric variable is incorrect, for example "ABC" and "1..2" are illegal numbers. User Action. Supply numeric values of the correct form. Run-Time Error Messages B-15 ILLOPE, Illegal operation (ERR=l 41) Explanation. The program attempts to: • • • • • • • • DELETE a record in a sequential file UPDATE a record on a magtape file Rewind a process-permanent file DELETE a record in a read-only file Assign a value to a virtual array element in a read-only file Perform a MARGIN operation on VIRTUAL file Transpose a matrix, or perform a matrix multiplication, with the same array as source and destination Perform an invalid operation on a VIRTUAL file, for example, using GET and PUT on a VIRTUAL file, then attempting to reference a virtual array dimensioned on that file User Action. Change the illegal operation. ILLPICOPE, Illegal picture operation (ERR=258) Explanation. The program attempts to change a transformation within a picture definition. The following statements are invalid within pictures and within routines that are called by pictures: • • • • • • • SET WINDOW SET VIEWPORT SET DEVICE WINDOW SET DEVICE VIEWPORT SET TRANSFORMATION SET INPUT PRIORITY SET CLIP User Action. Remove any invalid statements from the picture definition. Set the boundaries for windows and viewports before a picture is invoked. B-16 Run-Time Error Messages ILLPOISTY, Illegal point style number (ERR=276) Explanation. The specified point style is less than or equal to zero. User Action. Specify a valid point style greater than or equal to zero. ILLRECACC, Illogical record accessing (ERR=152) Explanation. The program attempts to perform an operation that is invalid for the specified file type, for example, a random access on a sequential file. User Action. Supply a valid operation for that file type or change the file type. ILLRECFIL, Illegal record on file (ERR=142) Explanation. A record contains an invalid byte count field. User Action. Use the DCL command DUMP to check the file for possible bad data. ILLRECLOC, Illegal record locking (ERR=187) Explanation. The program contains an ALLOW clause on a GET statement and the file was not opened with the UNLOCK EXPLICIT clause. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE = FATAL. User Action. Either remove the ALLOW clause from the GET statement or use the EXPLICIT UNLOCK clause in the OPEN statement. ILLRESSUB, Illegal RESUME to subroutine (ERR=247) Explanation. While in an error handler activated by an ON ERROR GO BACK, the error handler attempts to RESUME without a line number. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE = FATAL. User Action. None; you cannot specify the RESUME statement without a line number in any program module except in the program module containing the error handler. Run-Time Error Messages B-17 ILLSTYIND, Illegal area style index (ERR=279) Explanation. The specified area style index is less than or equal to zero. User Action. Specify a valid area style index greater than zero. ILLSWIUSA, Illegal switch usage (ERR=67) Explanation. The program attempts an illegal SYS call. User Action. See the appropriate RSTS/E SYS call documentation. ILLSYSUSA, Illegal SYS usage() (ERR=18) Explanation. The program attempted an illegal SYS call. User Action. See the appropriate RSTS/E SYS call documentation. ILLTEXHEI, Illegal text height (ERR=2 78) Explanation. The text height is less than or equal to zero. User Action. Specify a text height greater than zero. ILL TEXJUS, Illegal text justification (ERR=263) Explanation. The specified text justification factor is invalid. User Action. See Programming with VAX BASIC Graphics for valid justification values. Specify valid values. ILL TEXP AT, Illegal text path (ERR=265) Explanation. The specified text path is invalid. User Action. Specify a valid text path. Valid text path values are: • • • • B-18 Run-Time Error Messages RIGHT (the default) LEFT UP DOWN ILLTEXPRE, Illegal text precision (ERR=264) Explanation. The specified precision string is invalid. User Action. Valid precision values are: "STROI<En for software fonts, "STRINGn and "CHARn for hardware fonts. Specify a valid string for the precision value. ILLTEXRAT, Illegal text width-to-height ratio (ERR=276) Explanation. The specified width-to-height ratio is less than or equal to zero. User Action. Specify a width-to-height ratio greater than zero. ILLTFFOPE, Illegal terminal-format file operation (ERR=191) Explanation. The program specifies a GETRFA function on a terminal-format file. User Action. Change the file organization when opening the file to be sequential variable. ILLTRANUM, Illegal transformation number (ERR=257) Explanation. The specified tranformation number is less than 1 or greater than 255. User Action. Specify a transformation number between 1 and 255. ILLUSADEV, Illegal usage for device (ERR=133) Explanation. The requested operation cannot be performed because: • • • The device specification contains illegal syntax The specified device does not exist on your system The specified device is inappropriate for the requested operation (for example, an indexed file access on magnetic tape) User Action. Supply the correct device type. Run-Time Error Messages B-19 ILLWAIVAL, Illegal wait value (ERR=192) Explanation. The specified integer expression on the WAIT clause is less than zero or greater than 255. User Action. Specify an integer expression whose value is 0 through 255. IMASQUROO, Imaginary square roots (ERR=54) Explanation. An argument to the SQR function is negative. User Action. Supply arguments to the SQR function that are greater than or equal to zero. IMPERRHAN, improper error handling (ERR=186) Explanation. After an error has occurred, a program's error handler calls another program unit, and the called program unit executes an ON ERROR GO BACK statement before clearing the error with a RESUME statement. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE = FATAL. User Action. Change the program logic so that the called program clears the error condition before executing the ON ERROR GO BACK statement. INDNOTFUL, Index not fully optimized (ERR=l 70) Explanation. A record was successfully written to an INDEXED file; however, the alternate key path was not optimized. This slows record access. User Action. Delete the record and rewrite it. INTERR, Integer error (ERR=51) Explanation. The program contains an integer whose absolute value is greater than 255 in BYTE mode, 32767 in WORD mode, or 2147483647 in LONG mode. User Action. Use an integer in the valid range for specified data type. B-20 Run-Time Error Messages INVCHASTR, Invalid character in string (ERR= 287) Explanation. The program attempts to output a string that contains an invalid character. User Action. Remove the invalid character from the string. INVFILOPT, Invalid file options (ERR=139) Explanation. The program has specified invalid file options in the OPEN statement. User Action. Change the invalid file options. INVKEYREF, Invalid key of reference (ERR=144) Explanation. The program attempts to perform a GET, FIND, or RESTORE on an INDEXED file using an invalid KEY, for example, an alternate KEY that does not exist for the file that was opened. User Action. Use a valid KEY in the GET, FIND, or RESTORE statement. INVRFAFIE, Invalid RFA field (ERR=173) Explanation. During a FIND or GET by RFA, an invalid record's file address was specified. User Action. Supply a correct RFA field. IO_CHAALR, 1/0 channel already open (ERR=7) Explanation. The program attempted to open a channel that had already been opened and the implicit close failed. User Action. Submit an SPR. IO_CHANOT, 1/0 channel not open (ERR=9) Explanation. The program attempted to perform an 1/0 operation before opening the channel. User Action. Open the channel before attempting an 1/0 operation to it. Run-Time Error Messages B-21 KEYFIEBEY, Key field beyond end ofrecord (ERR=151) Explanation. The position given for the key field exceeds the maximum size of the record. User Action. Specify a key field within the record. KEYLARTHA, Key larger than record (ERR=159) Explanation. The key specification exceeds the maximum record size. User Action. Reduce the size of the key specification. KEYNOTCHA, Key not changeable (ERR=130) Explanation. An UPDATE statement attempted to change a key field that did not have CHANGES specified in the OPEN statement. User Action. Remove the changed key field in the UPDATE statement or specify CHANGES for that key field in the OPEN statement. Note that the primary key cannot be changed and that you cannot specify CHANGES when you open an existing file if the OPEN statement that created the file did not specify CHANGES. KEYSIZTOO, Key size too large (ERR=145) Explanation. The key length on a GET or FIND is either zero or larger than the key length defined for the target record. User Action. Change the key specification in the GET or FIND statement. KEYWAIEXH, Keyboard wait exhausted (ERR=lS) Explanation. No input was received during the execution of an INPUT, LINPUT, or INPUT LINE statement that was preceded by a WAIT statement or INKEY$ timeout value. User Action. None; you must supply input within the specified time. 8-22 Run-Time Error Messages MATDIMERR, Matrix dimension error (ERR=124) Explanation. The program: • • • Attempts to assign more than two dimensions to an array Attempts to reference an array with fewer or more subscripts than there are dimensions in the array Attempts to redimension an array that cannot be redimensioned This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE= FATAL. User Action. Change the number of array subscripts. Reference the array using the correct number of dimensions, or change the array so that it can be redimensioned. MAXMEMEXC, Maximum memory exceeded (ERR=126) Explanation. The program has insufficient string and I/O buffer space because: (1) its allowable memory size has been exceeded, or (2) the system's maximum memory capacity has been reached. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE= FATAL. User Action. Reduce the amount of string or I/O buffer space, or split the program into two or more programs. MEMMANVIO, Memory management violation (ERR=35) Explanation. The program attempted to read or write to a memory location to which it was not allowed access. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE =FATAL. User Action. If the program was compiled with /NOCHECK, it may be exceeding an array bound; recompile with /CHECK. Otherwise, check program logic. MISSPEFEA, Missing special feature (ERR=66) Explanation. The program attempts to use an unavailable SYS call. User Action. See the appropriate RSTS/E SYS call documentation. Run-Time Error Messages B-23 MOVOVEBUF, Move overflows buffer (ERR=161) Explanation. In a MOVE statement, the combined length of elements in the I/O list exceeds the size of the record just read or the size of the buffer. User Action. Reduce the size of the I/O list or increase the file's RECORDSIZE. NEGFILSTR, Negative fill or string length (ERR=166) Explanation. A MOVE statement I/O list contains a FILL item or string length with a negative value. User Action. Change the FILL item or string length value to be greater than or equal to zero. NEGZERTAB, negative or zero TAB (ERR=l 76) Explanation. The program attempted a zero or negative TAB. This error is signaled only for programs compiled with the / ANSI_STANDARD qualifier. User Action. Change the argument to the TAB statement. NETOPERR, network operation error (ERR=l 82) Explanation. The program attempts to perform an invalid network operation, or the network software failed during a network operation. User Action. Take action based on the associated error messages. NODNAMERR, Node name error (ERR=l 75) Explanation. A file specification's node name contains a syntax error. User Action. Supply a valid node name. NOTBASIC, Not a BASIC error (ERR=l 94) Explanation. The error is not a VAX BASIC error and is not mapped to an alternative VAX BASIC error message. User Action. Use RMSSTATUS or VMSSTATUS to access the text of the error message. B-24 Run-Time Error Messages NOTENDFIL, Not at end of file (ERR=149) Explanation. The program attempted a PUT operation: (1) on a sequential or relative file before the last record, or (2) without opening the file for WRITE access. User Action. OPEN a sequential or relative file with ACCESS APPEND or OPEN the file with ACCESS WRITE. NOTENODAT, Not enough data in record (ERR=59) Explanation. An INPUT statement did not find enough data in one line to satisfy all the specified variables. User Action. Supply enough data in the record or reduce the number of specified variables. NOTIMP, Not implemented (ERR=250) Explanation. The program attempted to use a feature that does not exist in this version of VAX BASIC for example, TIME(4%). User Action. Do not use the feature. NOTRANACC, Not a random access device (ERR=64) Explanation. The program attempts a random access on a device that does not allow such access; for example, a PUT with a record number to a magtape file. User Action. Make the access sequential instead of random or use a suitable 1/0 device. NO_CURREC, No current record (ERR=131) Explanation. The program attempts a DELETE or UPDATE when the previous GET or FIND failed, or no previous GET or FIND was done. User Action. Correct the cause of failure for the previous GET or FIND, or make sure a GET or FIND was done, then retry the operation. NQ_pRIKEY, No primary key specified (ERR=150) Explanation. The program attempts to create an INDEXED file without specifying a PRIMARY KEY value. User Action. Specify a PRIMARY KEY. Run-Time Error Messages B-25 NO_ROOUSE, No room for user on device (ERR=4) Explanation. No user storage space exists on the specified device. User Action. Delete files that are no longer needed. NUMCOOINS, Number of coordinates insufficient (ERR=281) Explanation. Insufficient coordinates are provided. A GRAPH POINTS statement requires the coordinates for at least one point. A GRAPH LINES statement requires a minimum of two points. A GRAPH AREA statement requires a minimum of three points. User Action. Supply an adequate number of points. ONEOR_TWO, One or two dimensions only (ERR=102) Explanation. The program contains a MAT statement that attempts to assign more than two dimensions to an array. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE =FATAL. User Action. Change the number of dimensions in the MAT statement to one or two. ON _STAOUT, ON statement out of range (ERR=58) Explanation. The index value in an ON GOTO or ON GOSUB statement is less than one or greater than the number of line numbers in the list. User Action. Check program logic to make sure that the index value is greater than or equal to one, and less than or equal to the number of line numbers in the ON GOTO or ON GOSUB statement. OUTOF_DAT, Out of data (ERR=57) Explanation. A READ statement requested additional data from an exhausted DATA list. User Action. Remove the READ statement, reduce the number of variables in the READ statement, or supply more DATA items. B-26 Run-Time Error Messages PRIKEYOUT, Primary key out of sequence (ERR=158) Explanation: RMS has detected an error in a sequential PUT to an INDEXED file. User Action: Change the PUT statement. If this does not work, the file is corrupted and you cannot do anything. PRIUSIFOR, PRINT-USING format error (ERR=116) Explanation: The program contains a PRINT USING statement with an invalid format string. User Action: Change the PRINT USING format string. PRQC_TRA, Programmable ~c trap (ERR=28) Explanation: A CTRL/C was typed at the controlling terminal. User Action: None; however, you can trap this error with an error handler. PROLOSSOR, Internal error in VAX BASIC Run-Time Library. Please submit an SPR. (ERR=103) Explanation: A consistency check in the VAX BASIC run-time support failed. Program execution is aborted. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE = FATAL. User Action: This error should never occur. Submit a Software Performance Report. PROVIO, Protection violation (ERR=lO) Explanation: The program attempted to read or write to a file whose protection code did not allow the operation. User Action: Use a different file or change the file's protection code or the attempted operation. RECALREXI, Record already exists (ERR=153) Explanation: An attempted random access PUT on a relative file has encountered a pre-existing record. User Action: Specify a different record number for the PUT or delete the record. July 1988 Run-Time Error Messages B-27 RECATTNOT, Record attributes not matched (ERR=228) Explanation: A RECORDTYPE clause specifies record attributes that do not match those of the file. User Action: Change the RECORDTYPE attribute to match that of the file. RECBUCLOC, Record/bucket locked (ERR=154) Explanation: The program attempts to access a record or bucket that has been locked by another program. User Action: Retry the operation. RECFILTOO, Record on file too big (ERR=157) Explanation: The specified record is longer than the input buffer. User Action: Increase the input buffer's size. RECHASBEE, Record has been deleted (ERR=132) Explanation: A record previously located by its Record File Address (RFA) has been deleted. User Action: None. RECNOTFOU, Record not found (ERR=lSS) Explanation: A random access GET or FIND was attempted on a deleted or nonexistent record. User Action: None. RECNUMEXC, RECORD number exceeds maximum (ERR=147) Explanation: The specified record number exceeds the maximum specified for this file. User Action: Reduce the specified record number. The maximum record number cannot be specified in VAX BASIC; it is either a default, or it was specified by a non-BASIC program when the file was created. B-28 Run-Time Error Messages RECOVEMAP, RECORDSIZE overflows MAP buffer (ERR=185) Explanation: The OPEN statement specifies a RECORDSIZE value larger than the size of the MAP specified in the MAP clause. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE= FATAL. User Action: Increase the size of the MAP to match the RECORDSIZE value. REDARR, Redimensioned array (ERR=lOS) Explanation: A MAT statement attempts to redimension an array to have more elements than were originally dimensioned. User Action: Change the statement that attempts the redimension or increase the original number elements. REMOVEBUF, REMAP overflows buffer (ERR=183) Explanation: A REMAP statement causes the variables in the dynamic MAP to be associated with nonexistent storage. User Action: Change the REMAP statement so that all variables are associated with the storage in the MAP. REMSTRNOT, REMAP string is not static (ERR=l 96) Explanation: The program referenced a string with a REMAP statement that was not declared in COMMON or MAP. User Action: Declare the string in the COMMON or MAP statement. RESNO_ERR, RESUME and no error (ERR=104) Explanation: The program executes a RESUME statement without a line number outside of the error handling routine. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE = FATAL. User Action: Check program logic to make sure that the RESUME statement is executed only in the error handler. Run-Time Error Messages B-29 RETWITGOS, RETURN without GOSUB (ERR=72) Explanation: The program executes a RETURN statement before a GOSUB. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE= FATAL. User Action: Check program logic to make sure that RETURN statements are executed only in subroutines or remove the RETURN statement. RRVNOTFUL, RRV not fully updated, (ERR=l 71) Explanation: RMS wrote a record successfully, but did not update one or more Record Retrieval Vectors. Therefore, you cannot retrieve any records associated with those vectors. User Action: Delete the record and rewrite it. SCAFACINT, SCALE factor interlock (ERR=127) Explanation: A subprogram was compiled with a different SCALE factor than that of the calling program. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE= FATAL. User Action: Recompile one of the programs with a scale factor that matches the other. SIZRECINV, Size of record invalid (ERR=156) Explanation: The program contains a COUNT or RECORDSIZE specification that is invalid because: • • • • • B-30 Run-Time Error Messages COUNT equals zero COUNT exceeds the maximum size of the record COUNT conflicts with the actual size of the current record during a sequential file UPDATE on disk COUNT does not equal the recordsize for fixed format records You specified a record size in the OPEN statement that was unequal to the actual record size established when the file was created. July 1988 User Action: Supply a valid COUNT value in the PUT or UPDATE statement, or a valid RECORDSIZE in the OPEN statement, whichever is applicable. July 1988 Run-Time Error Messages B-30.1 STO, Stop (ERR=123) Explanation. The program executed a STOP statement. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE= INFO or a greater severity. User Action. Continue execution by typing CONTINUE or terminate execution by typing EXIT. STRLENZER, string length is zero (ERR = 288) Explanation. A graphics statement references a null string where a null string is illegal. User Action. Adjust the string length so that it is greater than zero. STRTOOLON, String too long (ERR=227) Explanation. The program attempts to create a string longer than 65535 bytes. User Action. Reduce the length of the string. SUBOUTRAN, Subscript out of range (ERR=55) Explanation. The program attempts to reference an array element outside of the array's dimensioned bounds. User Action. Check program logic to make sure that all array references are to elements within the array boundaries. TAPBOTDET, Tape BOT detected (ERR=129) Explanation. The program attempts a rewind or backspace operation on a magnetic tape that is already at the beginning of the file. User Action. Trap the error or check program logic; do not rewind or backspace if the magnetic tape is at the beginning of the file. Run-Time Error Messages 8-31 TAPNOTANS, Tape not ANSI labeled (ERR=146) Explanation. The program attempts to access a file-structured magnetic tape that does not have an ANSI label. User Action. Determine the magnetic tape's format by mounting it with the /FOREIGN qualifier and using the DCL DUMP com- mand. You can then access it as a non-file-structured magnetic tape. TAPRECNOT, Tape records not ANSI (ERR=128) Explanation. The records in the magtape you accessed are neither ANSI D nor ANSI F format. User Action. Determine the magtape's format by mounting it with the /FOREIGN qualifier and using the DCL DUMP command. TERFORFIL, Terminal format file required (ERR=164) Explanation. The program attempted to use PRINT#, INPUT#, LINPUT #,MAT INPUT#, MAT PRINT#, or PRINT USING# to access a RELATIVE, INDEXED, or VIRTUAL file. User Action. Supply a terminal-format file. TOOFEWARG, Too few arguments (ERR=97) Explanation. A function invocation, CALL, or DRAW statement passed fewer arguments than were defined in the function, picture, DEF, DEF•, or subprogram. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE= FATAL. User Action. Change the number of arguments to match the number defined in the function or subprogram. TOOLITDAT, too little data in record (ERR= 189) Explanation. An INPUT statement did not find enough data in one line to satisfy all the specified variables. This error is signaled only for programs compiled with the / ANSI_STANDARD qualifier. User Action. Supply enough data in the record, or reduce the number of specified variables. B-32 Run-Time Error Messages TOOMANARG, Too many arguments (ERR=89) Explanation: A function invocation, CALL, or DRAW statement passed more arguments than were expected. This error cannot be trapped with a VAX BASIC error handler unless the program contains OPTION HANDLE= FATAL. User Action: Reduce the number of arguments. A SUB or FUNCTION subprogram can pass a maximum of 255 arguments; a DEF function call can pass a maximum of eight arguments. TOOMUCDAT, too much data in record (ERR=177) Explanation: The user has given too many items in response to the INPUT statement. This error is only signalled for ANSI INPUT. User Action: Supply the correct number of items to the INPUT statement or change the INPUT statement. TRANOTDIF, Transformation numbers are not different (ERR=260) Explanation: The same transformation number is used twice in the SET INPUT PRIORITY statement. User Action: Specify two different transformations in the SET INPUT PRIORITY statement. UNEFILDAT, unexpired file date (ERR=179) Explanation: The program attempts to delete a file whose expiration date has not yet passed. User Action: None. UNINUMNOT, Unit number is not defined for the device (ERR=282) Explanation: The specified unit is a method that is not supported by the device. (The default unit is 1.) User Action: Verify the supported units for the device and specify a valid unit. Run-Time Error Messages 8-33 UNKGKSERR, Unknown GKS error (ERR=286) Explanation: A graphics error has ocurred that is not mapped to a VAX BASIC error message. User Action: Use VMSSTATUS to access the text of the VAX GKS error message. USEABOINP, User aborted input, locate point cancelled (ERR=293) Explanation: ERROR - The middle mouse button was pressed during the execution of a graphics input statement that uses a mouse to enter points (e.g. LOCATE POINT). The pressing of the middle mouse button aborts the graphics input statement in progress and the data in the variables used for the graphics input statement is unchanged. The pressing of the middle mouse button during a graphics input statement is analogous to typing CTRL/Z at a regular INPUT statement. User Action: None. The program can trap this error in an error handler and attempt the input statement agam if so desired. VIRARRDIS, Virtual array not on disk (ERR=43) Explanation: The program attempted to reference a virtual array on a nondisk device, or the virtual array is not opened as ORGANIZATION VIRTUAL. User Action: Virtual arrays must be on disk; change the file specification in the OPEN statement for this array. Open the file with ORGANIZATION VIRTUAL. VIRARROPE, Virtual array not yet open (ERR=45) Explanation: The program attempted to reference a virtual array before opening the associated disk file. User Action: Open the disk file containing the virtual array before referencing the array. VIRBUFTOO, Virtual buffer too large (ERR=42) Explanation: The program attempted to access a VIRTUAL file and the buffer size was not 512 bytes. User Action: Change the I/O buffer to be a multiple of 512 bytes. B-34 Run-Time Error Messages July 1988 B.2 VAX BASIC Run-time Errors By Number 1 BADDIRDEV, Bad directory for device 2 ILLFILNAM, Illegal file name 4 NQ_ROOUSE, No room for user on device 5 CANFINFIL, Can't find file or account 7 IO_CHAALR, 1/0 channel already open 9 IO_CHANOT, 1/0 channel not open 10 PROVIO, Protection violation 11 ENDFILDEV, End of file on device 12 FATSYSIO_, Fatal system 1/0 failure 14 DEVHUNWRI, Device hung or write locked 15 KEYWAIEXH, Keyboard wait exhausted 18 ILLSYSUSA, Illegal SYS( ) usage 28 PROC __ TRA, Programmable AC trap 29 CORFILSTR, Corrupted file structure 31 ILLBYTCOU, Illegal byte count for 1/0 35 MEMMANVIO, Memory management violation 42 VIRBUFTOO, Virtual buffer too large 43 VIRARRDIS, Virtual array not on disk 45 VIRARROPE, Virtual array not yet open 46 ILLIO_CHA, Illegal 1/0 channel 48 FLOPOIERR, Floating point error or overflow 49 ARGTOOLAR, Argument too large in EXP 50 DATFORERR, Data format error 51 INTERR, Integer error 52 ILLNUM, Illegal number 53 ILLARGLOG, Illegal argument in LOG 54 IMASQUROO, Imaginary square roots 55 SUBOUTRAN, Subscript out of range Run-Time Error Messages 8-35 8-36 56 CANINVMAT, Can't invert matrix 57 OUTOLDAT, Out of data 58 ON _STAOUT, ON statement out of range 59 NOTENODAT, Not enough data in record 61 DIVBY_ZER, Division by 0 63 FIEOVEBUF, FIELD overflows buffer 64 NOTRANACC, Not a random access device 66 MISSPEFEA, Missing special feature 67 ILLSWIUSA, Illegal switch usage 72 RETWITGOS, RETURN without GOSUB 73 FNEWITFUN, FNEND without function call 88 ARGDONMAT, Arguments don't match 89 TOOMANARG, Too many arguments 97 TOOFEWARG, Too few arguments 101 DATTYPERR, Data type error 102 ONEOR_TWO, One or two dimensions only 103 PROLOSSOR, Internal error in VAX Run-Time Library. Please submit an SPR. 104 RESNO_ERR, RESUME and no error 105 REDARR, Redimensioned array 116 PRIUSIFOR, PRINT-USING format error 122 ILLFIEVAR, Illegal FIELD variable 123 STO, Stop 124 MATDIMERR, Matrix dimension error 126 MAXMEMEXC, Maximum memory exceeded 127 SCAFACINT, SCALE factor interlock 128 TAPRECNOT, Tape records not ANSI 129 TAPBOTDET, Tape BOT detected 130 KEYNOTCHA, Key not changeable 131 NO_CURREC, No current record 132 RECHASBEE, Record has been deleted 133 ILLUSADEV, Illegal usage for device Run-Time Error Messages July 1988 134 DUPKEYDET, Duplicate key detected 136 ILLILLACC, Illegal or illogical access 137 ILLKEYATT, Illegal key attributes 138 FILIS_LOC, File is locked 139 INVFILOPT, Invalid file options 141 ILLOPE, Illegal operation 142 ILLRECFIL, Illegal record on file 143 BADRECIDE, Bad record identifier 144 INVKEYREF, Invalid key of reference 145 KEYSIZTOO, Key size too large 146 TAPNOTANS, Tape not ANSI labeled 147 RECNUMEXC, RECORD number exceeds maximum 148 BADRECVAL, Bad RECORDSIZE value on OPEN 149 NOTENDFIL, Not at end of file 150 NO_PRIKEY, No primary key specified 151 KEYFIEBEY, Key field beyond end of record 152 ILLRECACC, Illogical record accessing 153 RECALREXI, Record already exists 154 RECBUCLOC, Record/bucket locked 155 RECNOTFOU, Record not found 156 SIZRECINV, Size of record invalid 157 RECFILTOO, Record on file too big 158 PRIKEYOUT, Primary key out of sequence 159 KEYLARTHA, Key larger than record 160 FILATTNOT, File attributes not matched 161 MOVOVEBUF, Move overflows buffer 162 CANNOT OPEN FILE 164 TERFORFIL, Terminal format file required 166 NEGFILSTR, Negative fill or string length 168 ILLALLCLA, Illegal ALLOW clause 170 INDNOTFUL, Index not fully optimized Run-Time Error Messages B-37 171 B-38 RRVNOTFUL, RRV not fully updated, 173 INVRFAFIE, Invalid RFA field 174 FILEXPDAT, File expiration date not yet reached 175 NODNAMERR, Node name error 176 NEGTABNOT, Negative TAB not allowed 177 TOOMUCDAT, Too much data in record 178 ERRFILCOR, Error on OPEN - file corrupted 179 UNEFILDAT, Unexpired file date 181 DECERR, Decimal error or overflow 182 NETOPERR, Network operation error 183 REMOVEBUF, REMAP overflows buffer 185 RECOVEMAP, RECORDSIZE overflows MAP buffer 186 IMPERRHAN, Improper error handling 187 ILLRECLOC, Illegal record locking 189 TOOLITDAT, Too little data in record 190 ILLNETOPE, Illegal network operation 191 ILLTFFOPE, Illegal terminal-format file operation 192 ILLWAIVAL, Illegal wait value 193 DEADLOCK, Detected deadlock while waiting for GET or FIND 194 NOTBASIC, Not a BASIC error 195 DIMOUTRAN, Dimension number out of range 196 REMSTRNOT, REMAP string is not static 197 ARRTOOSMA, Array too small 226 GKSNOTINS, VAX GKS is not installed 227 STRTOOLON, String too long 228 RECATTNOT, Record attributes not matched 229 DIFUSELON, Differing use of LONG/WORD qualifiers 238 ARRMUSSAM, Arrays must be same dimension 239 ARRMUSSQU, Arrays must be square 240 CANCHAARR, Cannot change array dimensions 245 ILLEXIDEF, Illegal exit from DEF• Run-Time Error Messages 246 ERRTRANEE, ERROR trap needs RESUME 247 ILLRESSUB, Illegal RESUME to subroutine 250 NOTIMP, Not implemented 252 FILACPFAI, FILE ACP failure 253 DIRERR, Directive error 256 ECHTYPNOT, Prompt/echo type not supported 257 ILLTRANUM, Illegal transformation number 258 ILLPICOPE, Illegal picture operation 259 CLIPONOFF, Clipping must be ON or OFF 260 TRANOTDIF, Transformation numbers are not different 261 COLNOTCON, Color indices are not contiguous 262 ILLARESTY, Illegal area style 263 ILL TEXJUS, Illegal text justification 264 ILL TEXPRE, Illegal text precision 265 ILLTEXPAT, Illegal text path 266 ILLDEVID, Illegal device identification number 267 DEVTYPNOT, Device type is not supported 268 DEVNOTOPE, Device is not open 269 DEVOUTMET, Device is an output metafile 270 DEVINMET, Device is an input metafile 272 DEVOPEING, Device and operation are incompatible 273 COONOTNDC, Coordinates are not within NDC space 274 ILLLINSTY, Illegal line style number 275 ILLLINSIZ, Illegal line size 276 ILLPOISTY, Illegal point style number 277 ILLTEXRAT, Illegal text width-to-height ratio 278 ILLTEXHEI, Illegal text height Run-Time Error Messages B-39 279 ILLSTYIND, Illegal area style index 280 ILLCOLIND, Illegal color index 281 NUMCOOINS, Number of coordinates is insufficient 282 UNINUMNOT, Unit number is not defined for the device 283 ILLECHARE, Illegal echo area 284 ILLINIVAL, Illegal initial value 285 ENTPOINOT, Entered points not within a transformation 286 UNKGKSERR, Unknown GKS error 287 INVCHASTR, Invalid character in string 288 STRLENZER, String length is zero 289 DATOVERF, Data overflow 290 ILLCNTCLA, Illegal count clause 291 ILLCOLMIX, Illegal color mix 292 ILLDEVNAM, Illegal device name in OPEN 293 USEABOINP, User aborted input, locate point cancelled B.3 Errors Not Generated By VAX BASIC The following errors cannot be generated in VAX BASIC. However, they can be displayed with the ERT$ function and are included for completeness. Number Text 3 ?Account or device in use 6 ?Not a valid device 8 ?Device not available 13 ?User data error on device 16 ?Name or account now exists 17 ?Too many open files on unit 19 ?Disk block is interlocked 20 ?Pack ids don't match 21 ?Disk pack is not mounted 22 ?Disk pack is locked out B-40 Run-Time Error Messages July 1988 Number Text 23 24 25 26 27 ?Illegal cluster size 30 32 33 34 ?Disk pack is private ?Disk pack needs 'cleaning' ?Fatal disk pack mount error ?1/0 to detached keyboard ?Device not file-structured ?No buffer space available ?Odd address trap ?Reserved instruction trap 36 37 38 39 40 41 44 47 ?SP stack overflow 60 62 ?Integer overflow, FOR loop 65 68-70 71 74 75 76 77 78 79 80 81 ?Disk error during swap ?Memory parity (or ECC) failure ?Magtape select error ?Magtape record length error ?Non-res run-time system ?Matrix or array too big ?Line too long ?No run-time system ?Illegal MAGTAPE( ) usage unused ?Statement not found ?Undefined function called ?Illegal symbol ?Illegal verb ?Illegal expression ?Illegal mode mixing ?Illegal IF statement ?Illegal conditional clause ?Illegal function name Run-Time Error Messages B-41 8-42 Number Text 82 ?Illegal dummy variable 83 ?Illegal FN redefinition 84 ?Illegal line number(s) 85 ?Modifier error 86 ?Can't compile statement 87 ?Expression too complicated 90 %Inconsistent function usage 91 ?Illegal DEF nesting 92 ?FOR without NEXT 93 ?NEXT without FOR 94 ?DEF without FNEND 95 ?FNEND without DEF 96 ?Literal string needed 98 ?Syntax error 99 ?String is needed 100 ?Number is needed 106 %Inconsistent subscript use 107 ?ON statement needs GOTO 108 ?End of statement not seen 109 ?What? 110 ?Bad line number pair 111 ?Not enough available memory 112 ?Execute only file 113 ?Please use the run command 114 ?Can't CONTinue 115 117 ?File exists-REN AME /REPLACE 118 ?Bad number in PRINT USING 119 ?Illegal in immediate mode 120 ?PRINT-USING buffer overflow Run-Time Error Messages ?Matrix or array without DIM Number Text 121 ?Illegal statement 125 ?Wrong math package 135 ?Illegal usage 140 ?Index not initialized 163 ?No file name 165 ?Cannot position to EOF 167 ?Illegal record format 169 unused 172 ?Record lock failed 180 ?No support for operation in task 182 ?Network operation rejected 184 ?Unaligned REMAP variable 188 ?UNLOCK EXPLICIT requires RECORDSIZE 512 198-225 unused 230 ?No fields in image 231 ?Illegal string image 232 ?Null image 233 ?Illegal numeric image 234 ?Numeric image for string 235 ?String image for numeric 236 ?TIME limit exceeded 237 ?First arg to SEG$ greater than second 241 ?Floating overflow 242 ?Floating underflow 243 ?CHAIN to nonexistent line number 244 ?Exponentiation error 248 ?Illegal return from subroutine 249 ?Argument out of bounds 251 ?Recursive subroutine call 254-255 unused 294-300 unused July 1988 Run-Time Error Messages B-43 INDEX A %ABORT directive• 18-11 ABS function• 12-2 Addition of matrices• 8-22 Address expression with DEPOSIT debugger command • 5-19 with EXAMINE debugger command• 5-18 with SET BREAK debugger command• 5-14 with SET TRACE debugger command• 5-15 Allocation map• 4-27 Ampersand (&) in comment field• 6-8 Ampersand (&) continuation character• 3-2 ANSl-D formatted file• 20-3 ANSI tape files accessing• 20-4 APPEND command• 3-13 Arrays• 6-13, 6-15, 8-1 to 8-26 as part of a record buffer• 8-7 bounds• 8-8 bounds of CDD•4-12 coo• 23-7 creating explicitly • 8-3 to 8- 7 creating implicitly• 8-8 to 8-9 creating virtual array files • 15-15 descriptors of• 19-9 FORTRAN • 2 1-10 input• 8-10 to 8-22 matrix• 8-1 of fixed-length strings• 8-7 of RECORD instances• 10-3 output• 8-10 to 8-22 July 1988 Arrays (cont'd.) redimensioning with DIM statement• 8-6 referencing • 8-3, 8-9 sharing among program modules• 8-7 subscripts• 8-1 to 8-2 vector• 8-1 within a RECORD• 10-4 zero-based • 8-1 ASCII character set• 6-7 ASCII function• 12-7 ASSIGN command• 3-14 Assignment of matrices• 8-22 Asterisk (*) with PRINT USING statement• 16-10 B BASIC /ANAL YSIS_DA TA• 4-7 /ANSI _ST ANDA RD• 4-7 ANSI Minimal BASIC• 4-7 /AUDIT• 4-7, 23-5 COD• 23-1 to 23-25 /CHECK •4-8 /CROSS_REFERENCE • 4-8 cross-reference listing• 4-8 /DEBUG •4-8 /DECIMAL_SIZE • 4-9 /DEPENDENcv_oA TA. 4-9 /DIAGNOSTICS• 4-10 /FLAG• 4-10 /INTEGER_SIZE • 4-10 line numbers• 5-9 /LINES• 4-10 /LISTING• 4-10 /MACHINE_CODE • 4-11 lndex-1 BASIC (cont'd.) /OBJECT• 4-11 /OLD_ VERSION=CDD_ARRA VS• 23-8 producing source listing file• 4-11 REAL _SIZE• 4-12 /ROUND_DECIMAL • 4-13 /SCALE • 4-13 /SHOW•4-13 /SHOW=CDD • 23-5 /SYNTAX _CHECK• 4-14 /TYPE_DEFAULT • 4-14 /VARI ANT• 4-14 /WARNINGS • 4-15 BASIC/CROSS_REFERENCE • 4-16, 4-25, 4-27 BASIC/LISTING• 4-15 BASIC character set• 6-7 BASIC command• 2-21, 4-4 BASIC command qualifiers list of• 4-6 BASIC compiler functions of• 4-4 Block loop• 11-4 BLOCKSIZE with the MOUNT command• 20-2 Block size specifying • 20-3 Bounds array• 6-15 COD arrays• 4-12 Bounds block • 19-11 Breakpoint• 5-13 Bucketsize • 15-37 default value• 15-38 Buffers l/0• 15-6 record • 15-6 Built-in lexical functions %VARIANT directive• 18-10 BY DESC•21-2 BY REF• 21-2 BYTE data type• 6-9 subtypes• 6-9 BY VALUE• 21-3 2-lndex c Call stack • 5-12 CALL statement• 14-10, 21-8 implicit declarations in • 14-10 parameters in• 14-10 using for FUNCTION subprograms • 14-10 CANCEL MODULE debugger command • 5-23 CANCEL SCOPE debugger command • 5-24 CASE in RECORD variants • 10-6 CASE block• 11-14 CAUSE ERROR statement• 17-22 COD array bounds• 4-12 COD (Common Data Dictionary) • 23-1 to 24-12 arrays • 23-7 CDD$TOP • 23-4 CDDL•23-2 NAME clause• 23-6 STRUCTURE statement• 23-3 subordinate field • 23-3 VARIANTS OF statement• 23-9 data definition • 23-3 extracting• 23-2 translating • 23-3 data types• 23-3, 23-11 to 23-25 character string • 23-15 complex• 23-21 decimal string• 23-23 fixed-point • 23-1 7 floating-point• 23-20 integer• 23-17 other• 23-24 definition • 23-1 dictionary directory• 23-4 history list entry • 23-5 %INCLUDE %FROM %COD directive• 23-2 object• 23-4 /OLD_ VERSION=CDD_ARRA VS• 23-8 path name • 23-4 to 23-5, 24-4 to 24-5 full• 23-5 relative • 23-5 variant• 23-9 with the RECORD statement• 23-2 CDD$TOP • 23-4, 24-4 July 198E CDD definitions COMMON statement (cont'd.) including • 18-7, 24-4 CDDL NAME clause • 23-6 Centered fields with PRINT USING statement • 16-18 CHANGE command• 4-2 Channels specifying with RMSST A TUS function • 17-17 Characters nonprinting • 6-7 Character set ASCll•6-7 BASIC•6-7 CHA$ function• 12-8 CLOSE statement ending file 1/0 • 20-7 ending 1/0 to a tape• 20-11 Comma using with PRINT statement• 7-11 ::ommand See also Debugger command Command procedures• 2-14 creating and executing• 2-16 example of• 2-17 executing in batch• 2-16 executing interactively• 2-16 login•2-19 Command qualifiers with the BASIC command• 2-21 , 4-4 with the DELETE command• 2-11 with the LINK command• 2-21 with the PRINT command• 2-10 with the PURGE command• 2-11 :om mas with PRINT USING statement• 16-9 :omment fields• 6-8 :omments entering into the BASIC environment• 3-12 in environment • 3-5 :ommon area defining • 9-19 :ommon block • 8-7 :ommon Data Dictionary See CDD :OM MON statement• 8-7, 9-13 sharing arrays with • 8-7 with subprograms • 9-19 Communication task-to-task• 20-17 Compilation controlling with %LET directive• 18-9 terminating with %ABORT directive• 18-11 Compilation listing with /SHOW • 4-13 with %INCLUDE • 18-8 COMPILE command • 3-9, 3-14 in environment• 3-9 Compiler commands• 3-9 to 3-30 listing • 4-15 specifying options for• 3-14 to 3-30 Compiler directives • 18-1 benefits of • 18-1 conventions of• 18-1 listing • 18-2 Compiling /DEBUG• 5-4 Component of a RECORD• 10-1 Concatenation • 9-1 9 Conditional expressions in IF ... THEN ... ELSE statement• 11-12 in WHILE ... NEXT loops• 11-8 Condition values • 21-20 Constants declaring • 9-7, 9-8 declaring externally• 9-8 definition of• 9-7 string • 13-1 Continuation lines DCL commands • 2-4 CONTINUE command• 3-8, 3-18 after CTRL/C • 3-18 after STOP statement • 3-18 CONTINUE statement• 17-9 Control structures • 11-1 to 11-18 Control variable loop• 11-4 COS function • 12-3 CREA TE command• 2-16 /CROSS_REFERENCE • 4-16, 4-27 CROSS_REFERENCE • 4-25 %CROSS directive• 18-6 July 1988 lndex-3 Cross-reference listing• 4-25 CTRL/C trapping• 12-17 CTRL/C trapping• 17-18 to 17-19 CTRL/Y interrupting debugger• 5-6 CTRL/Z exiting debugger• 5-6 CTRLC function• 12-17, 17-18 Currency symbol with PRINT USING statement• 16-11 Current record pointer resetting with RESTORE statement• 15-32 setting with FIND statement• 15-16 D Data formatting with PRINT USING statement• 16-1 passing between VAX BASIC and VAX FORTRAN• 21-9 rereading with RESTORE statement• 7-9 sharing between modules• 7-8 Data blocks• 15-1 Data records • 15-1 accessing by RFA • 15-6, 15-29 to 15-31 access modes for• 15-5 to 15-6 deleting with DELETE statement• 15-22 determining the number transferred • 15-36 fields in• 15-1 fixed-length • 15-2 handling locked conditions• 15-20, 15-27 locating • 15-16 moving with MOVE statement• 15-1 O next record pointer • 15-6 random access by key • 15-6 random access by record number• 15-6 reading with GET statement• 15-18 record context of• 15-5 to 15-6 sequential access • 15-6 stream format• 15-2 variable-length• 15-2 writing with PUT statement• 15-20 DATA statement• 7-7 to 7-9 comment fields in• 7-8 continuing with ampersand• 7-8 Data structures• 10-1 to 10-14 4-lndex Data type and size setting the default • 9-5 setting the default with qualifiers• 9-5 setting the default with the OPTION statement• 9-5 Data type keywords with FILL• 9-18 Data type promotions with expressions • 9-9 to 9-12 Data types • 6-9 BYTE• 6-9 DECIMAL• 6-9 definition of• 9-2 Floating-point• 9-2 INTEGER• 6-9, 9-2 list of• 9-2 LONG• 6-9 packed decimal • 6-9 REAL• 6-9 RFA • 6-9, 9-2 STRING• 6-9 subtypes• 6-9 table of• 9-3 user-defined• 10-1 WORD•6-9 DATE$ function• 12-16 DCL $STATUS• 14-11 DCL commands continuation indicator• 2-4 file-handling• 2-8 for program development• 2-20 rules and options• 2-4 to 2-14 DCL symbols defining• 2-14 Deadlock• 15-27 Debit and credit notation with PRINT USING statement• 16-15 DEBUG command• 5-5 Debugger• 5-1 Debugger command summary• 5-26 Debugging • 5-1 /DEBUG qualifier• 5-4 DECIMAL variables• 6-14 DECIMAL data type• 6-9 Decimal point location with PRINT USING statement• 16-6 Decision blocks controlling • 11 -1 to 11-18 Decision structures• 11-11 to 11-16 comparison of• 11-11 Declarative statements • 6-10, 9-1 purpose of• 9-1 DECLARE statement• 8-4, 9-6 DEF• 12-20 to 12-27 formal parameter list• 12-20 multi-line• 12-22 recursion in• 12-22, 12-25 transferring control into• 12-26 transferring control out of• 12-26 parameters• 12-27 single-line• 12-21 DEF• handling errors in• 17-21 Default values changing with LOCK command• 3-23 examining with SHOW command• 3-28 in the environment• 3-9 specifying with /TYPE _DEFAULT• 4-14 specifying with SET command• 3-28 DEF functions declaring • 9-6 DELETE command • 2-10, 3-18 with comma (,) • 3-18 with hyphen (-) • 3-18 DELETE statement• 15-22 to 15-23 current and next record pointers after• 15-23 DEPOSIT debugger command• 5-19 Descriptors array• 19-9 decimal scalar string• 19-12 dynamic string• 19-8 fixed-length string • 19-8 packed decimal string • 19-12 DET function• 8-26 Device-specific 1/0 performing to a tape drive• 20-8 performing to unit record devices• 20-8 to disks • 20-1 2 DIF$ function precision of• 12-13 DIMENSION statement• 8-4 to 8-6 declarative • 8-5 executable• 8-6 Directories referencing• 2-8 setting the default• 2-6 DIRECTORY command• 2-8 Directory hierarchies illustration of• 2-6 Directory structure• 2-5 Disks accessing • 20-12 creating • 20-12 opening • 20-12 opening an existing disk file• 20-13 Disk unit allocating • 20-12 Display source code• 5-8 Division by zero• 17-2 Dynamic mapping • 9-21, 15-8 to 15-10 Dynamic module setting• 5-23 Dynamic storage• 6-11 allocating• 9-13 Dynamic string descriptors • 19-8 Dynamic strings concatenating• 13-2 modifying• 13-4 using• 13-2 E ECHO function• 12-18 EDIT$ function string function • 13-19 EDIT command• 3-2, 3-18 in line mode• 3-18 with text editor• 3-19 EDT editor invoking• 4-2 using• 4-1 EDT Keypad Emulator Interface • 4-3 EDT text editor• 3-2 Elliptical references • 10-9 ELSE clause • 11-12 END FUNCTION statement • 14-4 specifying expression with • 14-4 END HANDLER statement • 17-7 END IF statement• 11-12 END SUB statement • 14-3 lndex-5 END WHEN statement • 17-7 Environment• 3-1 to 3-30 compiling in• 3-9 continuing program lines in• 3-2 creating programs in• 3-2 to 3-5 editing programs in• 3-2 to 3-5 entering comments into• 3-12 entering DCL commands in• 3-13 entering program statements in • 3-1 invoking• 3-1 running multiple program units in• 3-3 running programs in• 3-2 to 3-5 ERL function• 17-14, 17-15 ERN$ function • 17-15 ERR function • 17-13 Error conditions with PRINT USING statement• 16-20 Error handlers debugging• 17-22 user-written• 17-2 to 17-23 Error handling• 17-1 to 17-26 default• 17-1 to 17-2 Error messages compile-time• A-1 run-time• B-1 Errors forcing• 17-22 handling in DEF•s • 17-21 handling in functions• 17-21 handling in subprograms• 17-20 to 17-22 handling RMS • 17-17 handling VMS • 17-16 in a function• 17-24 NOTBASIC• 17-12 OPTION HANDLE statement• 17-12 pending• 17-2, 17-19 run-time• 17-1 severity levels • 17-12 severity of • 17-1 trapping• 17-1 to 17-26 types of• 17-1 Error trapping• 17-1 to 17-26 ERT$ function • 1 7-15 EVALUATE debugger command• 5-19 EVE interface • 4-3 EXAMINE debugger command• 5-18 Exception handling• 17-1 to 17-26 6-lndex Exclamation point (!) • 6-8 Execution start/resume in debugging• 5-11 EXIT command• 3-20 EXIT debugger command • 5-6 EXIT FUNCTION statement• 14-4 specifying expression with• 14-4 EXIT HANDLER statement• 17-10 EXIT PROGRAM statement• 14-12 EXIT statement• 11-16 to 11-18 EXIT SUB statement • 14-3 EXP function• 12-5 Explicit data typing • 9-3 Exponential format with asterisk-fill• 16-13 with PRINT USING statement • 16-12 Expression See also Address expression See also Language expression Expressions • 6-1 7 mixed-mode • 9-9 Extended fields with PRINT USING statement• 16-19 Extensible VAX Editor(EVE) • 4-3 External routines calling • 2 1-6, 2 1-8 declaring• 21-6 EXTERNAL statement • 9-8, 14-4, 14-5, 21-7 specifying data type of parameters • 14-5 specifying data type of return value• 14-4, 14-5 specifying parameter-passing mechanism in • 14-5 type checking with • 14-6 F File name specifying in the OPEN statement• 20-1 File operations • 15-12 File organization • 15-3 indexed • 15-4 relative • 15-4 sequential • 15-3 terminal-format• 15-3 virtual • 15-5 :ile organization (cont'd.) Formatting characters virtual• 15-5 iles appending• 4-5 closing• 15-33 deleting• 2-10 deleting with KILL statement• 15-34 displaying• 2-8 file-related functions• 15-34 to 15-37 including• 18-7 opening with OPEN statement• 15-12 printing• 2-10 purging• 2-11 renaming and moving• 2-11 renaming with NAME ... AS statement• 15-33 restoring• 15-32 searching• 2-12 setting protection• 2-12 transferring data to • 15-3 1 truncating with SCRATCH statement• 15-32 typing• 2-10 ile specification example of• 2-5 ILL formats• 9-18 ILL items• 9-17 IND statement• 15-16 to 15-17 random access• 15-16 sequential• 15-16 ixed-length strings• 13-1 changing• 13-4 using• 13-4 IXED record formats specifying• 20-2 IX function• 12-3 loating-point variables• 6-13 loating-point data• 9-4 loating-point numbers displaying with PRINT USING statement• 16-1 OR. .. NEXT loops• 11-4 to 11-7 ORMA T$ function• 12-9 ormat characters with PRINT USING statement• 16-7 ormat fields with PRINT USING statement• 16-2 ormat strings with PRINT USING statement• 16-2 with PRINT statement• 7-11 FOR modifier• 11-1 FOR statement in immediate mode statements• 3-7 FORTRAN arrays • 2 1-10 FREE statement• 15-26 FSP$ function • 15-34 FUNCTION• 14-4 to 14-5 Function call• 21-6 Functions• 12-1 to 12-27 built-in• 12-1 date and time• 12-15 to 12-17 string arithmetic• 12-11 to 12-15 terminal control• 12-17 creating with DEF• 12-20 to 12-27 data conversion• 12-7 declaring• 12-23 external• 14-4 file-related• 15-34 to 15-37 naming. 12-20, 12-22, 12-23 numeric string• 12-9 parameter data types• 12-2 recursion in• 12-25 resultant data type• 12-2 string arithmetic• 12-12 precision of• 12-12 FUNCTION subprograms• 14-2 running in the environment• 14-5 specifying a data type for• 14-11 G GETRFA function• 15-30 GET statement• 15-18 to 15-20, 20-5 current and next record pointers after• 15-18 reading data• 20-14 reading records with• 20-10 sequential • 15-18 with REGARDLESS clause• 15-27 with WAIT clause• 15-20 Global symbols assignment operations• 2-14 to 2-16 GO debugger command• 5-11 GROUP clause• 10-5 to 10-9 lndex-7 H Handler attached • 17-5 detached • 17-5 exiting from • 17-7 Handler priorities• 17-10, 17-20, 17-26 Header information IDENTIFY command • 3-21 omitting with RUNNH command• 3-25 Help online• 5-3 HELP command• 2-3, 3-20 HELP debugger command• 5-3, 5-4 HELP facility accessing• 2-3 I 1/0 device-specific • 20- 7 performing to ANSI-formatted magnetic tapes • 20-2 to mailboxes• 20-14 1/0 buffer• 15-6 %1DENT directive• 18-4 IDENTIFY command• 3-21 IF ... THEN ... ELSE statement• 11-12 to 11-13 %IF-% THEN-%ELSE-%END %IF directive• 18-9, 18-11 IF modifier• 11-1 IF statement in immediate mode statements• 3-7 Immediate mode• 3-5 to 3-9 debugging in• 3-8 to 3-9 debugging multiple program units• 3-8 debugging restrictions• 3-8 examining variables in• 3-5 FOR statement in • 3-7 IF statement in• 3-7 invalid statements • 3-7 UNLESS statement in• 3-7 UNTIL statement in• 3-7 WHILE statement in• 3-7 Implicit data typing• 9-3 %INCLUDE %FROM %COD directive• 23-2, 24-7 8-lndex %INCLUDE directive• 9-20, 18-7 accessing record definitions • 18- 7 accessing text libraries• 18- 7 benefits of• 18-9 from a file• 18-7 Indexed files• 15-4 alternate index keys • 15-4 index key values • 15-4 Informational errors • 17-1 Initialization debugger• 5-5 Initialization of variables• 6-15 INKEY$ function• 12-19 Input• 7-1 to 7-10 from source program • 7-7 to 7-10 from terminal• 7-5 from terminal-format files• 7-5, 7-16 to 7-18 interactive • 7-1 methods for receiving • 7-1 strings• 7-4 to 7-5 INPUT LINE statement• 7-4 to 7-5, 7-16 disabling the prompt • 7-5 to 7-6 with strings • 13-3 INPUT statement• 7-2 to 7-4, 7-16 disabling the prompt• 7-5 to 7-6 with strings • 13-3 Instance RECORD • 10-1 Integer variables • 6-14 INTEGER data type• 6-9, 9-4 Integer format byte-length • 19-1 longword• 19-2 word-length• 19-2 Interrupt debugging session • 5-6 INT function• 12-3 INV function• 8-25 Invoking debugger• 5-5 ITERATE statement• 11-16 to 11-18 K Keypad mode • 4-1 July 198 L Labels• 6-4 Language expression EVALUATE debugger command• 5-19 with DEPOSIT debugger command • 5-19 LBOUND function• 8-8 Leading zeros with PRINT USING statement• 16-14 Left-justified format with PRINT USING statement• 16-17 LEN function string function• 13-11 %LET directive• 18-9, 18-10 LET statement • 8-9, 8-10 with dynamic strings• 13-2 with string data• 13-6 Lexical constants creating• 18-10 Lexical expressions variations of• 18-10 Libraries object module• 22-1 shareable image• 22-1 system-supplied• 22-1, 22-2 user-supplied• 22-1, 22-3 Line mode• 3-2, 3-5, 4-1 line numbers in• 3-5 Line number debugger source display• 5-10 SET BREAK debugger command • 5-14 SET TRACE debugger command• 5-16 Line numbers• 6-1 generating• 3-27 programs without• 6-1 with %INCLUDE directive• 18-8 with SEQUENCE command• 3-27 /LINE qualifier• 5-16 Lines displaying with LIST command Ill 3-22 displaying with LISTNH command• 3-22 Line terminator accepting as input• 7-4 LINK command• 4-32 qualifiers of• 4-33 Linker error messages• 4-37 Linker (cont'd.) input files• 4-35 output files• 4-35 Linking /DEBUG• 5-4 LINPUT statement • 7-4 to 7-5, 7-16 disabling the prompt• 7-5 to 7-6 with strings• 13-3 List• 8-1 LIST command• 3-22 %LIST directive• 18-5 /LISTING • 4-15 Listing compilation • 4-15 cross-reference• 4-25 source program• 4-23 storage map• 4-27 LISTNH command• 3-22 LOAD command• 3-8, 3-22 Local symbols assignment operations• 2-14 LOC function• 21-9 LOCK command• 3-23 LOG 10 function • 12-4 Logarithms common• 12-4 Logging in• 2-1, 2-2 Logical names assigning with ASSIGN command• 3-14 defining• 2-15, 15-14 example of• 15-14 using• 15-14 LOGIN.COM file example of• 2-19 LOGOUT command• 2-2 LONG data type • 6-9 subtypes • 6-9 Loop blocks • 11-4 Loop control variable • 11-4 Loop index • 11-4 Loops • 11-4 to 11-10 FOR ... NEXT• 11-4 to 11-7 UNTIL. .. NEXT• 11-8 WHILE ... NEXT• 11-7 to 11-8 Lower bounds with COMMON statement • 9-14 with DECLARE statement• 9-6 with MAP statement• 9-14 lndex-9 Lower bounds (cont'd.) with the RECORD statement• 10-4 LSET statement concatenating strings• 13-2 with dynamic strings• 13-2 with string data • 13-7 M Magnetic tape blocksizes • 20-5 Magnetic tape file creating for output• 20-9 Magnetic tape files creating• 20-2 existing• 20-3 opening• 20-2, 20-9 Mailboxes creating• 20-15 passing data between processes• 20-14 Map area defining• 9-19 MAP DYNAMIC statement• 9-21 Maps multiple• 9-16 single• 9-15 MAP statement• 8-7, 9-14 overlaying array storage with• 8-7 with subprograms • 9-19 MAT INPUT statement• 8-16 continuing input line with ampersand• 8-18 filling array elements with• 8-17 from a terminal• 8-16 from a terminal-format file• 8-16 prompt character• 8-17 subscripts in • 8-16 MAT LINPUT statement• 8-18 filling array elements with • 8-18 redimensioning arrays with• 8-19 MAT PRINT statement• 8-19 with comma (,) • 8-20 with semicolon (;) • 8-20 MAT READ statement• 8-15 subscripts in • 8-15 with DAT A statement• 8-16 Matrix• 8-1 arithmetic• 8-22 functions• 8-24 to 8-26 10-lndex MAT statement• 8-5, 8-13 adding elements of arrays• 8-22 assigning array values from other arrays• 8-22 assigning values with• 8-11 creating arrays with • 8-14 displaying values with • 8-11 for array computations• 8-21 to 8-26 keywords • 8-13 multiplying elements of arrays• 8-23 redimensioning with • 8-14 subscripts in • 8-14 subtracting elements of arrays• 8-22 use of row and column zero• 8-12 with implicitly created arrays• 8-12 MAT statements• 8-11 to 8-20 Memory clearing with NEW command• 3-23 clearing with SCRATCH command• 3-27 Merge APPEND command• 3-10 MID$ assignment statement • 13-10 MID$ function string function • 13-16 Mixed-mode expressions • 9-9 Mode immediate• 3-5 line• 3-2, 3-5 Modifiers statement • 11-1 to 11-3 Module setting• 5-22 Module names• 6-6, 14-11 MOVE statement • 15-7, 15-10 to 15- 11 default string lengths • 15-10 valid variables in • 15-10 Multiplication of matrices• 8-23 Multiplier block • 19-11 N NAME clause (COOL) • 23-6 Names variables • 6-13 Negative format fields with PRINT USING statement• 16-1 2 Network 1/0 • 20-16 ~gative format fields with PRINT USING statement• 16-12 ~twork 1/0 • 20-16 :_w command• 3-3, 3-23 ~xt record pointer • 15-6 NOCROSS directive• 18-6 )ECHO function• 12-18 >keypad mode • 4-1 IOLINE with ERL function• 17-14 NOLIST directive• 18-5 mprinting characters• 6- 7 )REWIND positioning tape• 20-3 HBASIC errors• 17-16 to 17-18 111 character• 13-4 string• 13-4 JM1$ function• 12-10 JM$ function• 12-9 1mbers printing with PRINT USING statement• 16-4 1meric data interpreting with multiple maps • 9-17 JM function• 8-21 1ject module libraries at DCL level• 22-4 creating• 22-3 module names in• 6-6 within the BASIC environment• 22-3 1ject module library using• 4-36 1ject modules • 3-9 loading with LOAD command• 3-22 producing with /OBJECT• 4-11 LD_ VERSION=CDD_ARRA YS • 4-12 D command• 3-2, 3-8, 3-24 I ERROR GO BACK statement• 17-24 I ERROR GOTO statement• 17-24 passing to default error handler• 17-24 I ERROR statement• 17-23, 17-23 to 17-26 EN statement• 7-17, 15-12 BUCKETSIZE • 15-37 clauses for optimizing 1/0 • 15-37 to 15-46 OPEN statement (cont'd.) control structures set by USEROPEN keyword • 15-44 EXTENDSIZE clause• 15-41 FOR INPUT• 15-12 FOR OUTPUT • 15-12 opening indexed files • 15-14 ORGANIZATION UNDEFINED• 15-34 RECORDSIZE • 15-13 RECORDTYPE ANY• 15-34 specifying file characteristics with • 15-13 UNLOCK EXPLICIT• 15-26 with BUFFER clause• 15-39 with CONNECT clause• 15-39 with CONTIGUOUS clause• 15-40 with DEF AUL TNAME clause• 15-41 with FILESIZE clause• 15-42 with MAP clause• 15-13 with NOSP AN clause • 15-42 with RECORDTYPE clause• 15-43 with TEMPORARY clause• 15-43 with USEROPEN keyword • 15-44 with WINDOWSIZE attribute• 15-46 Operand • 6-1 7 Operator• 6-1 7 Optimization with handlers• 17-9 OPTION HANDLE statement• 17-12 OPTION statement • 3-14 Output • 7-11 to 7-16 displaying with PRINT statement• 7-1 O format for numbers • 7-14 format for strings • 7-14 to 7-16 to terminal-format files• 7-16 to 7-18 p Packed decimal data type • 6-9 variables• 6-14 Packed decimal format• 19-6 Packed Decimal string descriptors• 19-12 %PAGE directive• 18-5 Parameter-passing mechanisms• 21-2 to 21-5 declaring in EXTERNAL statement• 14-5 default • 21-3 lndex-11 Parameters creating local copies of• 21-5 to 21-6 default data types for• 14-7 null• 21-8 passing BY DESC • 21-2 passing BY REF• 21-2 passing BY VALUE• 21-3 Password changing• 2-2 Path Name• 24-4 in debugging• 5-8, 5-12, 5-14, 5-23 PC and SHOW CALLS debugger display• 5-12 and source display• 5-9 and STEP debugger command• 5-12 breakpoint• 5-14 PICTURE subprograms• 14-2 PLACE$ function• 12-14 precision of• 12-13 significant digits• 12-12 Placeholders reserving with PRINT USING statement• 16-4 POS function string function• 13-12 Positional qualifiers rules for precedence• 4-5 Predefined constants BEL• 6-12 BS• 6-12 CR• 6-12 DEL• 6-12 ESC • 6-12 FF• 6-12 HT• 6-12 LF • 6-12 Pl• 6-12 SI• 6-12 SO• 6-12 SP• 6-12 VT• 6-12 PRINT command• 2-10 %PRINT directive• 18-11 PRINT statement•7-10, 7-16 expression values • 7-10 for array elements• 8-11 string literals• 7-10 with comma• 7-11 with semicolon • 7-12 12-lndex PRINT USING statement• 16-1 Print zones • 7-11 to 7-14 Priorities of handlers• 17-20 Procedure call• 21-6 PROD$ function• 12-15 precision of• 12-13 significant digits• 12-12 Program control• 11-1 to 11-18 Program execution resuming with CONTINUE command• 3-18 Programs comments• 6-8 controlling• 11-1 to 11-18 documenting• 6-7 naming• 6-6 renaming with RENAME command• 3-24 renumbering with RESEQUENCE command• 3-25 PROGRAM statement• 6-5, 14-11 to 14-12 identifiers• 6-6, 14-11 Prompt debugger (DBG> ) • 5-5 enabling and disabling • 7-5 Protected regions• 17-2, 17-3 nested • 17-10 to 17-11 Prototype block • 19-10 PURGE command• 2-11 PUT statement• 15-20 to 15-22, 20-4 current and next record pointers after• 15-20 sequential• 15-20 writing data• 20-13 writing records with • 20-10 n qualifier /VARIANT• 18-10 QUO$ function precision of• 12-13 significant digits• 12-12 R RANDOMIZE statement• 12-6 Random number generator• 12-6 selecting range• 12-6 July 19 NEW command• 3-3, 3-23 Next record pointer• 15-6 %NOCROSS directive• 18-6 NOECHO function• 12-18 Nokeypad mode • 4-1 /NOLINE with ERL function• 17-14 %NOLIST directive• 18-5 Non printing characters• 6-7 NORE WIND positioning tape• 20-3 NOTBASIC errors• 17-16 to 17-18 Null character• 13-4 string• 13-4 NUM 1$ function• 12-10 NUM$ function• 12-9 Numbers printing with PRINT USING statement• 16-4 Numeric data interpreting with multiple maps• 9-17 NUM function• 8-21 0 Object module libraries at DCL level• 22-4 creating• 22-3 module names in• 6-6 within the BASIC environment• 22-3 Object module library using• 4-36 Object modules• 3-9 loading with LOAD command• 3-22 producing with /OBJECT• 4-11 /OLD_ VERSION=CDD_ARRA YS • 4-1 2 OLD command• 3-2, 3-8, 3-24 ON ERROR GO BACK statement• 17-24 ON ERROR GOTO statement• 17-24 passing to default error handler• 17-24 ON ERROR statement• 17-23, 17-23 to 17-26 OPEN statement• 7-17, 15-12 BUCKETSIZE • 15-37 clauses for optimizing 1/0 • 15-37 to 15-46 control structures set by USEROPEN keyword• 15-44 EXTENDSIZE clause • 15-41 OPEN statement (cont'd.) FOR INPUT• 15-12 FOR OUTPUT • 15-12 opening indexed files• 15-14 ORGANIZATION UNDEFINED• 15-34 RECORDSIZE • 15-13 RECORDTYPE ANY• 15-34 specifying file characteristics with• 15-13 UNLOCK EXPLICIT• 15-26 with BUFFER clause• 15-39 with CONNECT clause• 15-39 with CONTIGUOUS clause • 15-40 with DEFAULTNAME clause• 15-41 with FILESIZE clause• 15-42 with MAP clause• 15-13 with NOSP AN clause • 15-42 with RECORDTYPE clause• 15-43 with TEMPORARY clause• 15-43 with USEROPEN keyword • 15-44 with WINDOWSIZE attribute• 15-46 Operand • 6-17 Operator • 6-1 7 Optimization with handlers• 17-9 OPTION HANDLE statement• 17-12 OPTION statement • 3-14 Output • 7-10 to 7-16 displaying with PRINT statement• 7-1 O format for numbers • 7-14 format for strings • 7-14 to 7-16 to terminal-format files• 7-16 to 7-18 p Packed decimal data type • 6-9 variables• 6-14 Packed decimal format• 19-6 Packed Decimal string descriptors• 19-12 %PAGE directive• 18-5 Parameter-passing mechanisms• 21-2 to 21-5 declaring in EXTERNAL statement• 14-5 default• 21-3 Parameters creating local copies of• 21-5 to 21-6 default data types for• 14- 7 null• 21-8 lndex-11 Parameters (cont'd.) passing BY DESC • 21-2 passing BY REF• 21-2 passing BY VALUE• 21-3 Password changing• 2-2 Path name in debugging• 5-8, 5-12, 5-14, 5-23 PC and SHOW CALLS debugger display• 5-12 and source display• 5-9 and STEP debugger command• 5-12 breakpoint• 5-14 PICTURE subprograms• 14-2 PLACE$ function• 12-14 precision of• 12-13 significant digits• 12-12 Placeholders reserving with PRINT USING statement• 16-4 POS function string function • 13-12 Positional qualifiers rules for precedence• 4-5 Predefined constants BEL• 6-12 BS• 6-12 CR• 6-12 DEL• 6-12 ESC • 6-12 FF• 6-12 HT• 6-12 LF • 6-12 Pl• 6-12 SI• 6-12 6-12 SP• 6-12 VT• 6-12 PRINT command• 2-10 %PRINT directive• 18-11 PRINT statement• 7-10, 7-16 expression values• 7-10 for array elements • 8-11 string literals• 7-10 with comma• 7-11 with semicolon• 7-12 PRINT USING statement• 16-1 Print zones• 7-11 to 7-14 Priorities of handlers• 17-20 so. 12-lndex Procedure call • 21-6 PROD$ function• 12-15 precision of• 12-13 significant digits• 12-12 Program control• 11-1 to 11-18 Program execution resuming with CONTINUE command• 3-18 Programs comments • 6-8 controlling • 11-1 to 11-18 documenting• 6-7 naming• 6-6 renaming with RENAME command• 3-24 renumbering with RESEQUENCE command • 3-25 PROGRAM statement • 6-5, 14-11 to 14-12 identifiers • 6-6, 14-11 Prompt debugger (DBG > ) • 5-5 enabling and disabling• 7-5 Protected regions• 17-2, 17-3 nested • 17-10 to 17-11 Prototype block • 19-10 PURGE command• 2-11 PUT statement• 15-20 to 15-22, 20-4 current and next record pointers after• 15-20 sequential• 15-20 writing data • 20-13 writing records with • 20-10 Q qualifier /VARIANT• 18-10 QUO$ function precision of• 12-13 significant digits• 12-12 R RANDOMIZE statement• 12-6 Random number generator• 12-6 selecting range• 12-6 Random number generators changing seed• 12-6 RCTRLC function• 12-17, 17-19 READ statement• 7-7. to 7-9 REAL data type• 6-9 Real number format DOUBLE floating-point• 19-4 GFLOA T floating-point• 19-5 HFLOA T floating-point• 19-6 SINGLE floating-point• 19-3 Record buffer• 15-6 Record buffers accessing with multiple maps • 9-16 dynamic• 15-7 static • 15-6 RECORD components• 10-1 accessing • 10-9 to 10-14 fully qualified• 10-9 grouping• 10-5 referencing• 10-2, 10-9 Record File Address• 15-29 Record formats• 15-1 to 15-2 RECORD instances• 10-1 arrays of• 10-3 Record operations • 15-12 Records blocking and deblocking of• 20-6 writing to a terminal-format file• 7-17 writing with PUT and GET statements• 20-4 RECORD statement • 10-1 to 10-14 RECORD templates• 10-1 RECORD variants• 10-6 to 10-9 RECOUNT function• 15-36 Relative files• 15-4 REMAP statement• 9-22 Remote files accessing • 20-1 7 RENAME command• 2-11, 3-24 REPLACE command• 3-25 RESEQUENCE command• 3-25 RESTORE statement • 7-9 rewinding tape with• 20-7 with magnetic tapes• 20-11 RESUME statement• 17-8, 17-25 to 17-26 to a label• 17-25 to a line number• 17-25 Retrieval pointers• 15-46 RETRY statement • 17-8 RF A data type • 6-9 Right justification RSET statement • 13-8 Right-justified format with PRINT USING statement• 16-18 RMSST A TUS function• 15-36 to 15-37, 17-17 AND function• 12-6 Round-off errors overcoming with SCALE command• 3-27 RSET statement concatenating strings• 13-2 with dynamic strings• 13-2 with string data • 13-8 AST (run-time symbol table)• 5-22 RUN command• 3-2, 3-3, 3-9, 3-25, 4-38, 5-5 RUNNH command• 3-2, 3-3, 3-25 Run-time errors• 17-1 to 17-26 Run-Time Library routines• 21-11 s SAVE command• 3-3, 3-26 %SBTTL directive• 18-3 SCALE command• 3-27 Scope debugging• 5-23 SCRATCH command• 3-27 Screen mode • 5-8 SEARCH command• 2-12 SEG$ function string function • 13-14 SELECT ... CASE statement • 11-14 to 11-16 with RECORD variants• 10-6 Semicolons using with PRINT statement• 7-12 SEQUENCE command• 3-27 Sequential files • 15-3 SET [NO] PROMPT statement• 7-5 to 7-6, 8-17 SET BREAK debugger command• 5-13 SET command• 3-28 SET DEFAULT command• 2-6 SET MODE [NO]DYNAMIC debugger command• 5-23 SET MODE SCREEN debugger command • 5-8 SET MODULE debugger command• 5-22 SET NO PROMPT statement disabling the prompt• 7-6 SET PASSWORD command• 2-2 SET PROTECTION command • 2-12 SET SCOPE debugger command• 5-24 lndex-13 SET TRACE debugger command• 5-15 SET VARI ANT command• 18-10 Severe errors • 17-1 Shareable images• 22-5 accessing• 22-5 accessing at DCL level• 22-7 benefits of• 22-5 contents of• 22-1 creating• 22-5 installed• 22-1 within the BASIC environment• 22-6 /SHARE qualifier• 5-16 SHOW CALLS debugger command• 5-12 SHOW command• 3-28 SHOW MODULE debugger command • 5-22 SHOW SCOPE debugger command• 5-24 SHOW SYMBOL debugger command• 5-23 /SILENT qualifier• 5-16 SIN function• 12-3 Single tape file example of creating• 15-45 Source display• 5-8, 5-9 not available• 5-10 TYPE debugger command• 5-8 Source program listing• 4-23 Source programs compiling• 2-21 creating• 2-21 linking• 2-21 SPACE$ function string function• 13-18 Statement modifiers• 11-1 to 11-3 FOR• 11-1 IF• 11-1 UNLESS • 11-1 UNTIL• 11-1 WHILE• 11-1 Static storage • 6-11 allocating • 9-12 dynamic mapping• 9-21 $STATUS• 14-11 Status on exit • 14-11 ST A TUS function• 15-36 to 15-37 STEP clause • 11-4 STEP debugger command • 5-11 STOP statement• 3-5, 3-8 14-lndex STOP statement (cont'd.) resuming program execution after• 3-8 Storage dynamic • 6-11 redefining• 9-20 static • 6-11 Stream record format• 15-2 String dynamic • 13-1 fixed-length• 13-1 manipulating with multiple maps • 9-16 numeric• 12-9 variable • 6-14 virtual array• 13-1 STRING$ function string function • 13-17 String data assigning and justifying • 13-6 formatting with PRINT USING statement• 16-2 manipulating with MAP statements• 13-20 manipulating with string functions• 13-11 STRING data type• 6-9 String format fields • 16-16 String function EDIT$ function • 13-19 LEN function • 13-11 MID$ function • 13-16 POS function • 13-12 purposes • 13-11 SEG$ function• 13-14 SPACE$ function• 13-18 STRING$ function • 13-17 TRM$ function • 13-18 with the LET statement • 13-11 Strings printing with PRINT USING statement• 16-15 String variables fixed-length• 13-1 String virtual arrays assigning values• 13-5 creating • 13-5 Subdirectories creating• 2-6 deleting• 2-8 Subprograms• 14-2 calling from other languages• 21-9 compiling • 14-8 to 14-9 compiling from a single source file• 14-8 Subprograms (cont'd.) compiling from multiple source files• 14-8 creating a single object file • 14-8 DAT A statements in• 14-3 handling errors in• 17-20 to 17-22 invoking• 14-10 to 14-11 passing data to • 14-6 READ statements in • 14-3 RESTORE statements in• 14-3 Subscripted variables • 6-13, 6-15 SUB subprograms• 14-2 to 14-4 Subtraction of matrices• 8-22 Subtypes numeric • 9-4 SUM$ function precision of• 12-13 Symbol record• 5-4 Symbolic debugger see Debugger Symbolic definitions • 2 1-19 accessing with %INCLUDE directive• 21-20 location of• 21-19 Symbols assignment operations• 2-14 /SYSTEM qualifier• 5-16 System routines arguments of• 21-13 calling• 21-11 calling as a procedure• 21-7 examples of calling• 21-21 System Service routines • 21-12 System services example of calling• 21-21 T TAN function• 12-3 Tapes allocating• 20-2 setting the density• 20-2 Tape unit allocating for device-specific 1/0 • 20-8 Template RECORD• 10-1 Terminal-format files• 15-3 channel specification for• 7-17 Terminal-format files (cont'd.) closing• 7-17 input and output• 7-16 to 7-18 opening• 7-17 transferring data to • 15-31 writing records to • 7-17 Text libraries accessing • 18-8 creating • 18-8 system-supplied • 18-8 THEN clause • 11-12 TIME$ function• 12-16 TIME function• 12-17 % TITLE directive• 18-3 Traceback SHOW CALLS debugger command • 5-12 Tracepoint• 5-15 TRM$ function string function• 13-18 TRN function• 8-24 TYPE command• 2-10 TYPE debugger command • 5-8 u UBOUND function • 8-8 UNLESS modifier• 11-1 UNLESS statement in immediate mode statements• 3-7 UNLOCK EXPLICIT clause• 15-26 UNLOCK statement• 15-26 UNSA VE command • 3-30 UNTIL. .. NEXT loops• 11-8 UNTIL modifier• 11-1 UNTIL statement in immediate mode statements• 3-7 UPDATE statement• 15-23 to 15-25 current and next record pointers after• 15-24 in an indexed file• 15-24 in a relative file• 15-24 in a sequential file• 15-23 Upper bounds with COMMON statement• 9-14 with DECLARE statement• 9-6 with MAP statement• 9-14 with the RECORD statement • 10-4 lndex-15 v VAL% function• 12-11 VAL function• 12-11 Variable name DEPOSIT debugger command• 5-19 EVALUATE debugger command• 5-19 EXAMINE debugger command• 5-18 VARI ABLE record formats specifying• 20-2 Variables• 6-13 arrays of• 6-13, 6-15 declaring• 6-9 floating-point• 6-13 initialization of• 3- 7, 6-15 integer• 6-14 names• 6-13 packed decimal • 6-14 redefining• 9-20 string• 6-14, 13-1 subscripted• 6-13, 6-15 VARI ANT• 10-6 to 10-9 Variant COD• 23-9 % VARI ANT directive• 18-9, 18-10 VAX/VMS Debugger see Debugger VAX/VMS Symbolic Debugger see Debugger VAX Procedure Calling Standard• 21-9 VAXTPU using• 4-2 Vector• 8-1 Virtual array files• 15-15 Virtual files• 15-5 VMS data structures table of • 2 1- 14 VMSSTATUS function• 15-36 to 15-37, 17-16 w WAIT clause• 15-27 Warning errors• 17-1 WHEN ERROR constructs• 17-2 to 17-23 attached handler• 17-2 CONTINUE to target • 17-9 16-lndex WHEN ERROR constructs (cont'd.) exiting handler• 17-7 nested • 17-10 to 17-11 protected region• 17-2 with CONTINUE statement• 17-9 with EXIT HANDLER statement• 17-10 with RETRY statement • 17-8 WHILE ... NEXT loops• 11-7 to 11-8 WHILE modifier• 11-1 WHILE statement in immediate mode statements • 3-7 Wildcard characters• 2-9, 2-10 WORD data type • 6-9 subtypes • 6-9 z Zero-fill with asterisk-fill• 16-14 How to Order Additional Documentation Technical Support If you need help deciding which documentation best meets your needs, call 800-343-4040 before placing your electronic, telephone, or direct mail order. Orders To place an order at the Electronic Store, dial 800-DEC-DEMO (800-332-3366) using a 1200- or 2400-baud modern. If you need assistance using the Electronic Store, call 800-DIGITAL (800-344-4825). Telephone and Direct Mail Orders Your Location Call Contact Continental USA, Alaska, or Hawaii 800-DIGITAL Digital Equipment Corporation P.O. Box CS2008 Nashua, New Hampshire 03061 Puerto Rico 809-754-7575 Local DIGITAL subsidiary Canada 800-267-6215 Digital Equipment of Canada Attn: DECdirect Operations KA02/2 P.O. Box 13000 100 Herzberg Road Kanata, Ontario, Canada K2K 2A6 International Internal 1 Local DIGITAL subsidiary or approved distributor SOC Order Processing - WMO/ElS or Software Distribution Center Digital Equipment Corporation Westminster, Massachusetts 01473 1 For internal orders, you must submit an Internal Software Order Form (EN-01740-07). Reader's Comments VAX BASIC User Manual Al-HY 15A-TE AD-HY 15A-T2 Please use this postage-paid form to comment on this manual. If you require a written reply to a software problem and are eligible to receive one under Software Performance Report (SPR) service, submit your comments on an SPR form. Thank you for your assistance. I rate this manual's: Accuracy (software works as manual says) Completeness (enough information) Clarity (easy to understand) Organization (structure of subject matter) Figures (useful) Examples (useful) Index (ability to find topic) Page layout (easy to find information) Excellent Good Fair Poor D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D I would like to see more/less What I like best about this manual is What I like least about this manual is I found the following errors in this manual: Page Description Additional comments or suggestions to improve this manual: I am using Version ___ of the software this manual describes. Name/Title Dept. Company Date Mailing Address Phone -- Do Not Tear - Fold Here and Tape --------------ir---~-----------;~:;~· 1f Mailed in the United States BUSINESS REPLY MAIL FIRST CLASS PERMIT NO. 33 MAYNARD MASS. POSTAGE WILL BE PAID BY ADDRESSEE DIGIT AL EQUIPMENT CORPORATION Corporate User Publications-Spit Brook ZK01-3/J35 110 SPIT BROOK ROAD NASHUA, NH 03062-9987 111 ..... 11.11 .... 11 .... 1.11.1 .. 1.1 .. 1•• 1.1 ... 1.11 .. 1 - - Do Not Tear - Fold Here - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Reader's Comments VAX BASIC User Manual Al-HY 15A-TE AD-HY 15A-T2 Please use this postage-paid form to comment on this manual. If you require a written reply to a software problem and are eligible to receive one under Software Performance Report (SPR) service, submit your comments on an SPR form. Thank you for your assistance. I rate this manual's: Accuracy (software works as manual says) Completeness (enough information) Clarity (easy to understand) Organization (structure of subject matter) Figures (useful) Examples (useful) Index (ability to find topic) Page layout (easy to find information) Excellent Good Fair Poor D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D I would like to see more/less What I like best about this manual is What I like least about this manual is I found the following errors in this manual: Page Description Additional comments or suggestions to improve this manual: I am using Version _ _ _ of the software this manual describes. Name/Title Dept. Date Company Mailing Address Phone - Do Not Tear - Fold Here and Tape --------------1r---~-----------~;~1f Mailed in the United States BUSINESS REPLY MAIL FIRST CLASS PERMIT NO. 33 MAYNARD MASS. POSTAGE WILL BE PAID BY ADDRESSEE DIGIT AL EQUIPMENT CORPORATION Corporate User Publications-Spit Brook ZK01-3/J35 110 SPIT BROOK ROAD NASHUA, NH 03062-9987 111 ••••• 11.11 •••• 11 •••• 1.11.1 •• 1.1 ••1••1.1 ••• 1.11 •• 1 - - Do Not Tear - Fold Here - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Home
Privacy and Data
Site structure and layout ©2025 Majenko Technologies