Languages Library TAL Programmer’s Guide Abstract This manual provides usage information for TAL (Transaction Application Language) and the TAL compiler for system and application programmers. Part Number 096254 Edition Second Published Product Version Release ID Supported Releases September 1993 TAL C30, TAL D10, TAL D20 D20.00 This manual supports C30/D10.00 and all subsequent releases until otherwise indicated in a new edition.
Document History Edition Part Number Product Version Earliest Supported Release Published First Second 065721 096254 TAL D10 TAL C30 TAL D10 TAL D20 N/A C30/D10.00 January 1993 September 1993 New editions incorporate any updates issued since the previous edition. A plus sign (+) after a release ID indicates that this manual describes function added to the base release, either by an interim product modification (IPM) or by a new product version on a .99 site update tape (SUT).
New and Changed Information The TAL Programmer’s Guide gives guidelines for using TAL. This edition incorporates new features introduced in the D20 release and corrects text in response to reader comment forms. This edition includes the following new features: For INT, REAL, and UNSIGNED data types and parameter types, a width argument can consist of any constant expression, including LITERALs and DEFINEs. FIXED(*) is now a data type and a parameter type.
New and Changed Information iv 096254 Tandem Computers Incorporated
Contents About This Manual xxv Notation Conventions Section 1 Introducing TAL Using TAL 1-1 Major Features 1-1 System Services 1-3 System Procedures 1-3 TAL Run-Time Library CRE Services Section 2 xxxiii 1-3 1-3 Getting Started Sample Source File 2-1 Creating Source Files 2-2 Compiler Directives 2-2 System Procedures 2-3 Procedures 2-3 Data Declarations 2-3 Statements 2-4 Comments 2-4 Compiling Source Files Running Programs Section 3 2-4 2-5 Structuring Programs Source Files 3-1 Compi
Contents Declaring Procedures 3-6 Procedure Heading 3-6 Procedure Body 3-6 FORWARD Procedures 3-6 EXTERNAL Procedures 3-7 Procedure Entry Points 3-7 Local Data 3-8 Local Labels 3-8 Local Statements 3-8 Declaring Subprocedures 3-10 Subprocedure Heading 3-10 Subprocedure Body 3-10 FORWARD Subprocedures 3-10 Subprocedure Entry Points 3-11 Sublocal Data 3-12 Sublocal Labels 3-12 Sublocal Statements 3-12 Formatting Programs 3-13 Formatting With Comments 3-14 Formatting With BEGIN-END Constructs Using Semicolons
Contents Section 5 Using Expressions About Expressions 5-1 Complexity 5-1 Functionality 5-1 Operands 5-2 Identifiers 5-2 Data Types 5-4 Data Type Aliases 5-6 Storage Units 5-6 Data Types of Expressions Variables 5-7 Constants 5-7 LITERALs 5-11 Standard Functions 5-12 Precedence of Operators 5-6 5-13 Arithmetic Expressions 5-15 Operands in Arithmetic Expressions 5-15 Signed Arithmetic Operators 5-16 Unsigned Arithmetic Operators 5-18 Bitwise Logical Operators 5-20 Conditional Expressions 5-21 Conditions
Contents Section 6 Using Simple Variables Declaring Simple Variables 6-1 Specifying Data Types 6-1 Initializing Simple Variables 6-2 Allocating Simple Variables 6-3 Assigning Data to Simple Variables 6-4 Assigning Variables 6-4 Matching Data Types 6-4 Converting Data Types 6-4 Assigning Character Strings 6-4 Multiple Variables 6-5 Simple Variables by Data Type 6-5 STRING Simple Variables 6-5 INT Simple Variables 6-6 INT(32) Simple Variables 6-8 REAL Simple Variables 6-9 REAL(64) Simple Variables 6-10 FIXE
Contents Scanning Arrays 7-19 Delimiting the Scan Area 7-19 Determining What Stopped the Scan 7-20 Scanning Bytes in Word-Aligned Arrays 7-20 Multipart Scan Example 7-20 Comparing Arrays 7-23 Using Standard Functions With Arrays Using Read-Only Arrays 7-23 7-24 Declaring Read-Only Arrays 7-24 Accessing Read-Only Arrays 7-24 Section 8 Using Structures Kinds of Structures Structure Layout 8-1 8-2 Declaring Definition Structures 8-3 Specifying Structure Occurrences 8-3 Using Indirection 8-3 Allocati
Contents Declaring Simple Pointers in Structures 8-17 Addresses Simple Pointers Can Contain 8-18 Allocating Simple Pointers in Structures 8-18 Declaring Structure Pointers in Structures 8-19 Addresses Structure Pointers Can Contain 8-20 Allocating Structure Pointers in Structures 8-20 Declaring Redefinitions 8-21 Simple Variables or Arrays as Redefinitions 8-21 Definition Substructures as Redefinitions 8-23 Referral Substructures as Redefinitions 8-25 Simple Pointers as Redefinitions 8-26 Structure Pointer
Contents Using Structure Pointers 9-12 Declaring Structure Pointers 9-12 Initializing Structure Pointers 9-13 Initializing Global Structure Pointers 9-13 Initializing Local or Sublocal Structure Pointers 9-15 Allocating Structure Pointers 9-16 Assigning Addresses to Structure Pointers 9-16 Accessing Data With Structure Pointers 9-18 Indexing Structure Pointers 9-20 Section 10 Using Equivalenced Variables Example Diagrams 10-1 Variables You Can Equivalence 10-1 Equivalencing Simple Variables 10-2 Decla
Contents Declaring Data in Procedures 11-4 Allocating Local Variables 11-5 Allocating Parameters and Variables Returning From a Procedure 11-5 11-7 Using Procedure Options 11-7 Declaring the MAIN Procedure 11-7 Declaring Functions 11-8 Declaring FORWARD Procedures 11-8 Declaring EXTERNAL Procedures 11-9 Declaring VARIABLE Procedures 11-9 Declaring EXTENSIBLE Procedures 11-10 Passing Parameters to VARIABLE or EXTENSIBLE Procedures Converting VARIABLE Procedures to EXTENSIBLE 11-13 Comparing Procedures an
Contents Section 12 Controlling Program Flow IF Statement 12-2 IF Statement Execution IF-ELSE Pairing 12-4 12-3 CASE Statement, Labeled 12-5 Statement Forms Generated by the Compiler Directives and CASE Statements 12-7 Labeled CASE Statement Execution 12-7 WHILE Statement DO Statement 12-6 12-8 12-10 FOR Statement 12-12 Nesting FOR Loops 12-13 Standard FOR Loops 12-13 Optimized FOR Loops 12-15 ASSERT Statement 12-17 Using ASSERT with ASSERTION 12-17 Nullifying ASSERT Statements 12-18 CALL Statement 1
Contents Section 13 Using Special Expressions Assignment Expression CASE Expression IF Expression 13-2 13-3 13-4 Group Comparison Expression 13-5 Comparing a Variable to a Constant List 13-5 Comparing a Variable to a Single Byte 13-5 Comparing a Variable to a Variable 13-6 Using the Next Address 13-7 Testing the Condition Code Setting 13-9 Section 14 Compiling Programs The Compiler 14-1 BINSERV 14-1 SYMSERV 14-1 Compiling Source Files 14-2 Running the Compiler 14-2 Completion Codes Returned by the Com
Contents Compiling With Search Lists 14-12 Creating the Master Search List 14-12 Clearing the Master Search List 14-12 Searching the Master Search List 14-13 Binding the Master Search List 14-13 Compiling With Relocatable Data Blocks 14-14 Declaring Relocatable Global Data 14-14 Allocating Global Data Blocks 14-16 Sharing Global Data Blocks 14-20 Directives for Relocatable Data 14-21 Compiling With Saved Global Data 14-23 Saving Global Data 14-23 Retrieving Global Data 14-23 Saved Global Data Compilation S
Contents Cross-Reference Listings 15-11 Source-File Cross-References 15-11 Identifier Cross-References 15-11 LMAP Listings 15-13 Entry-Point Load Map 15-14 Data-Block Load Maps 15-14 Compilation Statistics Object-File Statistics 15-16 15-16 Section 16 Running and Debugging Programs Running Programs 16-1 Specifying Run Options 16-1 Passing Run-Time Parameters 16-3 Stopping Programs 16-3 Run-Time Errors 16-3 Debugging Programs 16-4 Using the Inspect Product 16-4 Requesting the Inspect Product 16-4 Compilin
Contents TAL and C Guidelines 17-9 Using Identifiers 17-9 Matching Data Types 17-10 Memory Models 17-11 Calling C Routines From TAL Modules 17-12 Calling TAL Routines From C Modules 17-13 Sharing Data 17-15 Parameters and Variables 17-18 Extended Data Segments 17-33 CRE Guidelines for TAL 17-37 General Coding Guidelines 17-37 Specifying a Run-Time Environment 17-39 The User Heap 17-41 Including Library Files 17-43 Initializing the CRE 17-44 Terminating Programs 17-45 Sharing the Standard Files 17-46 Access
Contents Appendix B Managing Addressing Extended Pointer Format B-1 Accessing the Upper 32K-Word Area B-2 Storing Addresses in Simple Pointers B-2 Storing Addresses in Structure Pointers B-4 Managing Data Allocation in Upper 32K-Word Area Managing Large Blocks of Memory B-7 Indexing the Upper 32K-Word Boundary B-8 Accessing the User Code Segment B-9 Initializing Simple Pointers B-9 Assigning Addresses to Simple Pointers B-9 Using Extended Data Segments B-10 Using the Automatic Extended Segment B-10 Us
Contents TACL DEFINE Commands E-4 Substituting File Names E-4 TACL DEFINE Names E-5 Setting DEFINE CLASS Attributes E-5 TACL PARAM Commands E-6 PARAM BINSERV Command E-6 PARAM SAMECPU Command E-6 PARAM SWAPVOL Command E-7 PARAM SYMSERV Command E-7 Using PARAM Commands E-7 TACL ASSIGN Commands E-8 Ordinary ASSIGN Command E-8 ASSIGN SSV Command E-9 Appendix F Type Correspondence Glossary Glossary–1 Index Index–1 096254 Tandem Computers Incorporated xix
Contents Figures xx Figure 2-1. Sample Source File Figure 3-1. Structure of a Sample Compilation Unit Figure 4-1. User Data Segment Figure 4-2. Automatic Extended Data Segment Figure 4-3. Byte and Word Addressing in User Data Segment Figure 4-4. Primary and Secondary Storage in the User Data Segment Figure 6-1. Simple Variable Storage Allocation Figure 7-1. Allocating Direct Arrays Figure 7-2. Allocating Indirect Arrays 7-10 Figure 9-1. Allocating Simple Pointers 9-7 Figure 9-2.
Contents Figure 15-6. CODE Listing 15-9 Figure 15-7. ICODE Listing Figure 15-8. Global Map Figure 15-9. File Name Map 15-9 15-10 15-10 Figure 15-10. Source-File Cross-Reference Listing Figure 15-11. Identifier Cross-Reference Listing Figure 15-12. Entry-Point Load Map by Name Figure 15-13. Data-Block Load Map by Location 15-11 15-13 15-14 15-15 Figure 15-14. Read-Only Data-Block Load Map by Location Figure 15-15. Compiler Statistics Figure 15-16.
Contents Tables Table 3-1. xxii Data Declarations 3-4 Table 3-2. TAL Statements Table 4-1. Registers in Current Process Environment Table 5-1. Reserved Keywords Table 5-2. Nonreserved Keywords Table 5-3. Data Types Table 5-4. Storage Units Table 5-5. Variables Table 5-6. Number Base Formats Table 5-7. Summary of Standard Functions Table 5-8. Precedence of Operators Table 5-9. Operands in Arithmetic Expressions Table 5-10. Signed Arithmetic Operators Table 5-11.
Contents Table 10-1. Equivalenced Variables Table 10-2. Indexes and Offsets Table 11-1. Value and Reference Parameters 11-3 Table 11-2. Procedures and Subprocedures 11-14 Table 11-3. Formal Parameter Specification 11-20 Table 11-4. Value Parameter Storage Allocation Table 11-5. Reference Parameter Storage Allocation Table 11-6. Reference Parameter Address Conversions Table 11-7. Entry Values Loaded Onto Register Stack Table 12-1. Program Control Statements Table 13-1.
Contents Examples xxiv Example 17-1. D-Series TAL and C Extended Segment Management 17-35 Example 17-2. D-Series CRE Sample Program Example A-1. C- or D-Series String-Display Program Example A-2. C-Series String-Display Program Example A-3. D-Series String-Entry Program A-3 Example A-4. C-Series String-Entry Program A-4 Example A-5. C- or D-Series Binary-to-ASCII Conversion Program Example A-6a. D-Series Mainline Module Example A-6b. D-Series Initialization Module Example A-6c.
About This Manual The Transaction Application Language (TAL) is a high-level, block-structured language used to write systems software and transaction-oriented applications. The TAL compiler compiles TAL source programs into executable object programs. The compiler and the object programs it generates execute under control of the Tandem NonStop Kernel. This manual gives guidelines for using TAL and the TAL compiler.
About This Manual How to Use This Manual Set The TAL manual set consists of the manuals listed in Table 1: Table 1. TAL Manual Set Manual Description TAL Programmer’s Guide Helps you get started in creating, structuring, compiling, running and debugging programs. Describes how to declare and access procedures and variables and how the TAL compiler allocates storage for variables.
About This Manual Organization of Manual The TAL Programmer’s Guide is organized as follows: Section 1, “Introducing TAL,” summarizes the features of TAL. Section 2, “Getting Started,” explains how to create, compile, and run a program. Section 3, “Structuring Programs,” describes how to structure source programs. Section 4, “Introducing the Environment,” describes the process environment, addressing modes, and storage allocation.
About This Manual Appendix E, “File Names and TACL Commands,” describes D-series file-naming conventions and TACL ASSIGN, DEFINE, and PARAM commands. Appendix F, “Data Type Correspondence,” lists the data types of Tandem languages. System Dependencies The features mentioned in this manual are supported on all currently supported systems except where noted. Table 2 lists the systems that TAL supports: Table 2.
About This Manual Compiler Dependencies The TAL compiler is a disk-resident program on each Tandem system. In general, a particular version of the compiler runs on the corresponding or later version of the operating system. For example, the D20 version of the compiler requires at least the D20 version of the operating system.
About This Manual Table 4 describes manuals that provide information about programming in the Tandem environment. Table 4. Programming Manuals Manual Description Guardian Procedure Calls Reference Manual Guardian Programmer’s Guide Describes the syntax and programming considerations for using system procedures. Explains how to use the programmatic interface of the operating system. Describes error codes, error lists, system messages, and trap numbers for system procedures.
About This Manual Your Comments Invited After you have had a chance to use this manual, please take a moment to fill out the Reader Comment Card and send it to us. The Reader Comment Card is located at the back of the printed manual and as a separate file in the CD Read Document List. You can fax the card to us at (408) 285-6660 or mail the card by using the business reply address on the back of the card in the printed manual.
About This Manual xxxii 096254 Tandem Computers Incorporated
Notation Conventions This manual presents terms that represent keywords, information you supply, and identifiers as follows: Keywords are shown in uppercase in text and in examples. For instance, the keyword SOURCE appears in an example as follows: ?SOURCE . . . Identifiers are shown in lowercase in examples and in uppercase in example comments and in text.
1 Introducing TAL The Transaction Application Language (TAL) is a high-level, block-structured language that works efficiently with the system hardware to provide optimal object program performance. The TAL compiler compiles TAL source programs into executable object programs. The compiler and the object programs it generates execute under control of the Tandem NonStop Kernel.
Introducing TAL Major Features Recursion—Because each activation of a procedure or subprocedure has its own data area, a procedure or subprocedure can call itself or can call other procedures that in turn calls the original procedure. Parameters—A procedure or subprocedure can have optional or required parameters. The same procedure or subprocedure can process different sets of variables sent by different calls to it.
Introducing TAL CRE Services System Services Your program can ignore many things such as the presence of other running programs and whether your program fits into memory. For example, programs are loaded into memory for you and absent pages are brought from disk into memory as needed. System Procedures The file system treats all devices as files, including disk files, disk packs, terminals, printers, and programs running on the system.
Introducing TAL CRE Services When you use the CRE, each routine in your program, regardless of language, can: Use the routine’s run-time library without overwriting the data of another runtime library Share data in the CRE user heap Share access to the standard files—standard input, standard output, and standard log Call math and string functions provided in the CRELIB file Call Saved Messages Utility (SMU) functions provided in the Common Language Utility Library (CLULIB file) Without the CRE, only routin
2 Getting Started To get you started quickly, this section presents a sample program and describes the basic commands for developing and running a program. Sample Source File The sample program adds two numbers together. The source code for the sample program is in a source file named MYSRC. Figure 2-1 shows the content of the sample source file. Figure 2-1. Sample Source File !This is a source file named MYSRC. ?SOURCE $SYSTEM.SYSTEM.
Getting Started Creating Source Files Creating Source Files A source file contains source code for your program. The source code can include declarations, statements, compiler directives, and comments. You can use a text editor to create a file and to type source code into the file. The PS Text Edit Reference Manual and the Edit User’s Guide and Reference Manual describe how to use an editor. When you enter the source code into the source file, you can use lowercase or uppercase letters.
Getting Started Creating Source Files System Procedures System procedures are procedures provided by the operating system. Declarations for system procedures are located in the EXTDECS files.
Getting Started Compiling Source Files Statements Statements let you specify the actions you want a program to perform. All statements are executable. For example, you use statements to: Call procedures Return from called procedures Assign values to variables Copy data from one location to another Scan data for a character Select statements to execute based on a condition The sample source file includes statements that call a procedure and assign values to variables.
Getting Started Running Programs Running Programs After the compiler generates an object file for your program, you can run the program by issuing a TACL RUN command. To run the sample program MYPROG, issue the following command at the TACL prompt: RUN myprog You can include run options in the TACL RUN command. Section 16, “Running and Debugging Programs,” gives an overview of some commonly used run options. For more information on run options, see the TACL Reference Manual.
3 Structuring Programs This section describes how you can structure and format a TAL source program. The structure is the order and level at which major components appear in a program. The format is the spacing and alignment you use to make the program readable. Source Files A program consists of one or more source files. A source file can be a complete program or a part of a modular program.
Structuring Programs Compilation Units Figure 3-1.
Structuring Programs Compilation Units Figure 3-1 shows three procedures and a subprocedure. You can declare any number of procedures in a compilation unit. You can declare any number of subprocedures within any procedure. You cannot, however, declare a subprocedure within another subprocedure. The shading in Figure 3-1 represents the scope of identifiers—that is, the set of levels at which you can access identifiers: Identifiers in the unshaded areas have global scope.
Structuring Programs Naming Compilation Units Naming You can assign an identifier to the compilation unit by using the NAME declaration. If Compilation Units present, the NAME declaration must be the first declaration in the compilation unit. For example, you can assign the identifier INPUT_MODULE to a compilation unit as follows: NAME input_module; Normally, you include the NAME declaration in compilation units that you compile separately and then bind together by using Binder.
Structuring Programs Declaring Global Data Declaring Global Data Global data is data that can be accessed by all compilation units in the program. Global data can be any data item listed in Table 3-1 earlier in this section. All global data declarations except LITERALs and DEFINEs must appear before any procedure declarations. Global LITERAL and DEFINE declarations can appear between procedures as well. You can declare unblocked or blocked data.
Structuring Programs Declaring Procedures Declaring Procedures Procedure Heading You declare procedures to define routines that are callable from routines in any compilation unit in the program. You can declare procedures that perform discrete operations such as I/O or error handling. Normally, a procedure declaration includes a procedure heading and a procedure body.
Structuring Programs Declaring Procedures EXTERNAL Procedures If you want to call a procedure that is compiled in another compilation unit, first declare a procedure heading that includes the EXTERNAL keyword. Once you declare an EXTERNAL procedure, you can call the procedure from anywhere in the current compilation unit.
Structuring Programs Declaring Procedures Local Data Local data is data you declare inside a procedure and can access only from within that procedure. Local data can be any data item described in Table 3-1 earlier in this section. Within a procedure, all local data declarations must appear before any subprocedure declarations or local statements.
Structuring Programs Declaring Procedures Table 3-2 lists the statements you can include in a TAL program. (Statement names in uppercase reflect a keyword. The assignment and move statements have no keywords in them; their names are in lowercase.) Table 3-2.
Structuring Programs Declaring Subprocedures Declaring You declare subprocedures to specify discrete portions of source code within a Subprocedures procedure. You can call subprocedures only from within the encompassing procedure. You can declare any number of subprocedures within a procedure, but you cannot declare subprocedures within subprocedures. Place any subprocedure declarations following the procedure’s local declarations. In a subprocedure declaration, you normally specify a heading and a body.
Structuring Programs Declaring Subprocedures Subprocedure Entry Points A subprocedure entry point is an identifier by which callers can call a subprocedure. The primary entry point is the subprocedure identifier. Secondary entry points are entry-point identifiers declared within the subprocedure and then placed at statements where the subprocedure can begin executing.
Structuring Programs Declaring Subprocedures Sublocal Data Sublocal data is data you declare inside a subprocedure and can access only from within the same subprocedure. Sublocal data can be any data item described in Table 3-1 earlier in this section. Within a subprocedure, all sublocal data declarations must appear before any sublocal statements. Also, sublocal arrays and structures must be directly addressed. (Addressing is explained in Section 4, “Introducing the Environment.
Structuring Programs Formatting Programs Formatting Programs You can format a program to make it easier to understand and maintain. The TAL compiler allows almost a free format for source code. You can use any format that serves your purposes. The only limitation is that the maximum line length for source code is 132 characters.
Structuring Programs Formatting Programs Formatting With Comments You can insert comments anywhere in the source code to make the code easier to understand and maintain. For instance, you can explain the purpose of certain constructs or variables. During compilation, the compiler ignores comments.
Structuring Programs Formatting Programs Skipping Parts of Code When you want the compiler to ignore a portion of the code, you can either: Comment it out Use conditional compilation For example, when your code contains ! comments, you can use -- to comment out the portion you want the compiler to ignore: PROC my_proc; BEGIN !Lots of code END; --Comment out the following portion of code: --PROC no_proc; -- BEGIN -- !Lots of code -- END; --End of commented-out portion of code PROC your_proc; BEGIN !Lots of
Structuring Programs Formatting Programs Formatting With BEGIN-END Constructs You use BEGIN-END constructs to group various items into a single entity. If you align the BEGIN and END keywords vertically, the program is easier to understand. Following are some uses for BEGIN-END constructs.
Structuring Programs Formatting Programs Using Semicolons Use semicolons to end each data declaration and to separate successive statements. Ending Data Declarations Here is an example of using semicolons to end data declarations: INT INT INT STRING STRING num1; num2; num3; char1; char2; The following example is equivalent to the preceding example: INT num1, num2, num3; STRING char1, char2; Separating Successive Statements You must use a semicolon between successive statements.
Structuring Programs Using Compiler Directives Null Statements You can use a semicolon without a statement to create a null statement, which means do nothing. The compiler generates no code for null statements. You can use a null statement anywhere you can use a statement, except immediately before an ELSE or UNTIL keyword.
Structuring Programs Using Compiler Directives When the argument list of a directive continues on a subsequent line, you must specify at least the leading parenthesis of the argument list on the same line as the directive name: ?PUSHLIST, NOLIST, SOURCE $SYSTEM.SYSTEM.
4 Introducing the Environment This section introduces you to: The process environment in which your program runs Addressing modes you can use in this environment Allocation of data storage by the compiler System dependencies Process Environment Your object programs execute as individual processes on a Tandem system. A program is a static group of machine instructions and initialized data that reside in a file.
Introducing the Environment Process Environment Data Space The current data space of your process consists of: A user data segment An automatic extended data segment if needed Any user-defined (explicit) extended data segments (The term segment refers a nonextended segment except where the word extended is specifically used.) User Data Segment The user data segment provides a private storage area for the variables of your process. Your process can modify the content of the user data segment.
Introducing the Environment Process Environment Figure 4-1 shows the organization of the user data segment. Figure 4-1.
Introducing the Environment Process Environment Extended Data Segments Extended data segments provide indirect data storage in addition to storage in the user data segment. References to extended data segments are not as fast as those to the user data segment. An extended data segment can be as large as 127.5 megabytes. When you declare arrays and structures by specifying the extended indirection symbol (.EXT), the compiler automatically allocates and deallocates an appropriately sized extended segment.
Introducing the Environment Addressing Modes System Code Space System Library Space Registers The current system code space available to your process contains one segment of system code. The current system library space contains up to 31 segments of system library code, available to your process one at a time. Table 4-1 lists the registers that describe your process in the current process environment: Table 4-1.
Introducing the Environment Addressing Modes Figure 4-3. Byte and Word Addressing in User Data Segment Word addresses Byte addresses [0] [0] [1] [1] [2] [3] [2] [4] [5] [3] [6] [7] . . . . . . [32767] [65534] [65535] . . . . . . Upper limit for 16-bit byte addresses Lower 32K-word area [65535] Upper 32K-word area 348 Direct Addressing Direct addressing uses 16-bit addresses and requires only one memory reference.
Introducing the Environment Addressing Modes Standard Indirect Addressing Standard indirect addressing is 16-bit indirect addressing in the user data segment, including: Byte or word addresses in the lower 32K-word area Word addresses in the upper 32K-word area If you use the CRE, however, the upper 32K-word area is not available for your data. Extended Indirect Addressing Extended indirect addressing is relocatable 32-bit indirect addressing anywhere in virtual memory, usually in an extended data segment.
Introducing the Environment Storage Allocation Storage Allocation The compiler generates code during compilation to allocate storage for variables. The compiler allocates storage as follows: For global variables—when compilation begins For local or sublocal variables—when the encompassing procedure or subprocedure is invoked The compiler allocates each variable either in the user data segment or in the automatic extended segment, depending on how you declared the variable.
Introducing the Environment Storage Allocation Global Primary Area The global primary area can store up to 256 words of the following kinds of global variables: Direct variables—simple variables (which are always direct), direct arrays, and direct structures Pointers—simple pointers and structure pointers—that you declare Implicit pointers—pointers that the compiler provides when you declare indirect arrays or indirect structures Two implicit extended-stack pointers (described in “Extended Stack” later in
Introducing the Environment Storage Allocation Secondary Storage Areas The secondary storage areas are: A global secondary area, which begins following the location of the last global variable allocated in the global primary area A local secondary area, which begins following the location of the last local variable allocated in the local primary area The secondary areas have no explicit size, but the total of all primary and secondary areas cannot exceed the lower 32K-word area of the user data segment.
Introducing the Environment Storage Allocation Extended Stack The compiler allocates the extended stack in the automatic extended data segment in a data block named $EXTENDED#STACK. The default size of the extended stack is 64K bytes or the maximum space required by a procedure, whichever is greater. When you use recursion or compile compilation units separately, the compiler cannot calculate the size requirements of the extended stack precisely.
5 Using Expressions This section describes how you use arithmetic and conditional expressions. It gives information about operands (identifiers, data types, variables, constants) and about arithmetic and conditional operators and their effect on operands. For information about assignment, CASE, IF, and group comparison expressions, see Section 13, “Using Special Expressions.” About Expressions An expression is a sequence of operands and operators that, when evaluated, produces a single value.
Using Expressions Operands Operands Operands in expressions can be items such as variables, constants, LITERALs, and function invocations. The following subsections describe identifiers, data types, variables, constants, LITERALs, and functions, followed by arithmetic expressions and conditional expressions. Identifiers Identifiers are names you declare for objects such as variables, LITERALs, and procedures (including functions).
Using Expressions Operands Keywords Keywords have predefined meanings to the compiler when used as described in this manual. Table 5-1 lists reserved keywords, which you cannot use as identifiers. Table 5-1.
Using Expressions Operands Data Types When you declare most kinds of variables, you specify a data type, which dictates: The kind of values the variable can store The amount of storage the compiler allocates for the variable The operations you can perform on the variable The byte or word addressing mode of the variable Table 5-3 gives information about each data type. Table 5-3.
Using Expressions Operands Specifying Widths For INT, REAL, and UNSIGNED data types, the value in parentheses is a constant expression that specifies the width, in bits, of the variable. As of the D20 release, the constant expression can include LITERALs and DEFINEs (previously declared constants and text).
Using Expressions Operands Data Type Aliases The compiler accepts the following aliases for the listed data types: Data Type Alias INT REAL FIXED(0) INT(16) REAL(32) INT(64) For consistency, the remainder of this manual avoids using data type aliases. For example, although the following declarations are equivalent, the manual uses FIXED(0): FIXED(0) var; INT(64) var; Storage Units Storage units are the containers in which you can access data stored in memory.
Using Expressions Operands An INT(32) expression can include INT(32) and UNSIGNED(17–31) operands. The system treats UNSIGNED(17–31) operands as if they were 32-bit values. It places an UNSIGNED(17–31) operand in the right bits of a doubleword and sets the unused left bits to 0, with no sign extension. For example, for an UNSIGNED(29) operand, the system fills the three leftmost bits of the doubleword with zeros.
Using Expressions Operands Table 5-6. Number Base Formats Number Base Prefix Digits Allowed Example Decimal Octal Binary Hexadecimal None % %B %H 0 through 9 0 through 7 0 or 1 0 through 9, A through F 46 %57 %B101111 %H2F STRING. A STRING numeric constant is an unsigned 8-bit integer in the range 0 through 255. Examples are: 59 %12 %B101 %h2A !Decimal base !Octal base !Binary base !Hexadecimal base INT.
Using Expressions Operands FIXED(0). FIXED(0) numeric constants are discussed under “Fixed-Point Constants,” described next. Fixed-Point Constants A fixed-point constant is type FIXED and is a signed 64-bit fixed-point number. The range of a FIXED constant is determined by its fpoint. For example, the ranges for FIXED(0) and FIXED(2) are: fpoint Range FIXED(0) –9,223,372,036,854,775,808 through 9,223,372,036,854,775,807 FIXED(2) –92,233,720,368,547,758.08 through 92,233,720,368,547,758.
Using Expressions Operands Here are examples: Decimal Value REAL REAL(64) 0 2 2 2 -17.2 -17.2 0.0E0 2.0e0 0.2E1 20.0E-1 -17.2E0 -1720.0E-2 0.0L0 2.0L0 0.2L1 20.0L-1 -17.2L0 -1720.0L-2 Character String Constants A character string constant consists of one or more contiguous ASCII characters enclosed in quotation mark delimiters, as in: "Now is the time for good parties.
Using Expressions Operands LITERALs A LITERAL declaration specifies one or more identifiers and associates each with a constant expression. Each identifier in a LITERAL declaration is known as a LITERAL. You can define a LITERAL once and then reference it by identifier many times in the program. When a you need to change a LITERAL, you only change the declaration, not every reference to it. LITERALs also make the source code more meaningful.
Using Expressions Operands Using LITERALS You can use LITERALs in declarations and statements: LITERAL array_length = 50; INT .
Using Expressions Precedence of Operators Precedence of Operators in expressions can be arithmetic (signed, unsigned, or logical) or conditional Operators (Boolean or relational, signed or unsigned). Within an expression, the compiler evaluates operators in order of precedence. Within each level of precedence, the compiler evaluates operators from left to right. Table 5-8 shows the level of precedence for each operator, from highest (0) to lowest (9). Table 5-8.
Using Expressions Precedence of Operators Table 5-8. Precedence of Operators (Page 2 of 2) Operator Operation Precedence '<' '=' '>' '<=' '>=' '<>' NOT AND OR := .<...> := Unsigned less than Unsigned equal to Unsigned greater than Unsigned less than or equal to Unsigned greater than or equal to Unsigned not equal to Boolean negation Boolean conjunction Boolean disjunction Assignment Bit deposit ** 5 5 5 5 5 5 6 7 8 9 9 ** Described in the TAL Reference Manual.
Using Expressions Arithmetic Expressions Arithmetic Expressions An arithmetic expression is a sequence of operands and arithmetic operators that computes a single numeric value of a specific data type.
Using Expressions Arithmetic Expressions Signed Arithmetic Operators Signed arithmetic operators and the operand types on which they can operate are shown in Table 5-10. Table 5-10.
Using Expressions Arithmetic Expressions Scaling of FIXED Operands When you declare a FIXED variable, you can specify an implied fixed-point setting (fpoint)—an integer in the range –19 through 19, enclosed in parentheses following the keyword FIXED. If you do not specify an fpoint, the default fpoint is 0 (no decimal places). A positive fpoint specifies the number of decimal places to the right of the decimal point: FIXED(3) x := 0.
Using Expressions Arithmetic Expressions The following example shows how the system makes automatic adjustments when operands in an expression have different fpoints: FIXED a; FIXED(2) b; FIXED (-1) c; Data declarations a := 2.
Using Expressions Arithmetic Expressions Table 5-13 shows the combinations of operand types you can use with binary unsigned arithmetic operators and the result types yielded by such operators. The order of the operand types in each combination is interchangeable except in the last case. Table 5-13.
Using Expressions Arithmetic Expressions Bitwise Logical Operators You use logical operators—LOR, LAND, and XOR—to perform bit-by-bit operations on STRING, INT, and UNSIGNED(1–16) operands only. Logical operators always return 16-bit results. Table 5-14 gives information about these operators. Table 5-14.
Using Expressions Conditional Expressions Conditional A conditional expression is a sequence of conditions and Boolean or relational Expressions operators that establishes the relationship between values. You can use conditional expressions to direct program flow. Following are examples of conditional expressions: a NOT a a OR b a AND b a AND NOT b OR c Conditions !condition !NOT condition !condition OR condition !condition AND condition !condition AND NOT condition ...
Using Expressions Conditional Expressions Boolean Operators You use Boolean operators—NOT, OR, and AND—to set the state of a single value or the relationship between two values. Table 5-16 describes the Boolean operators, the operand types you can use with them, and the results that such operators yield. Table 5-16.
Using Expressions Conditional Expressions Relational Operators Relational operators can be signed or unsigned. Signed Relational Operators Signed relational operators perform signed comparison of two operands and return a true or false state. Table 5-17 describes signed relational operators, operand data types, and the results yielded by such operators. Table 5-17.
Using Expressions Conditional Expressions Controlling Program Execution You use relational expressions in control statements to determine the flow of execution.
Using Expressions Testing Hardware Indicators Testing Hardware Hardware indicators include condition code, carry, and overflow settings. Arithmetic Indicators and conditional operations, assignments, and some file-system calls affect the setting of the hardware indicators. To check the setting of a hardware indicator, use an IF statement immediately after the operation that affects the hardware indicator.
Using Expressions Testing Hardware Indicators Carry Indicator The carry indicator is bit 9 in the environment register (ENV.K).
Using Expressions Accessing Operands A program can deal with arithmetic overflows in one of four ways: Desired Effect Method Abort on all overflows Recover globally from overflows Recover locally from statement overflows Ignore all overflows Use the system’s default trap handler. Use a user-supplied trap handler. Turn off overflow trapping and use $OVERFLOW. Turn off overflow trapping throughout the program.
Using Expressions Accessing Operands Using a variable in two different ways can make your program more difficult to understand and maintain.
Using Expressions Accessing Operands You can use bit extraction in conditional expressions: INT word; STRING var; IF word.<0:7> = "A" THEN ... ; IF var.<15> THEN ... ; !Check for “A” in 8-bit field !Check for nonzero value ! in bit <15> To access bits in the result of an expression, enclose the expression in parentheses: INT result; INT num1 := 51; INT num2 := 28; result := (num1 + num2).
Using Expressions Accessing Operands Number of Positions to Shift Specify the number of bit positions to shift as an INT expression. A value greater than 31 gives undefined results (different on TNS and TNS/R systems). Effect on Hardware Indicators The bit-shift operation sets the condition code indicator, described under “Testing Hardware Indicators” earlier in this section.
Using Expressions Accessing Operands You can shift the right byte of a word into the left byte and set the right byte to zero: INT b; !Declare variable b := b '<<' 8; !Shift right byte into left ! byte, leaving zero in ! right byte The following unsigned left shift shows how zeros fill the vacated bits from the right: Initial value '<<' 2 = = 0 010 111 010 101 000 1 011 101 010 100 000 The following unsigned right shift shows how zeros fill the vacated bits from the left: Initial value '>>' 2 = =
6 Using Simple Variables A simple variable is a single-element data item of a specified data type. You use simple variables to store data that can change during program execution. This section describes: Declaring simple variables Initializing simple variables Allocating storage for simple variables Assigning data to simple variables Using simple variables, discussed by data type Declaring Simple Variables Before you access a simple variable, you must declare it.
Using Simple Variables Declaring Simple Variables Initializing Simple Variables You can initialize a simple variable of any data type (except UNSIGNED) when you declare it. Following the identifier in the declaration, specify an assignment operator (:=) and an initialization value: INT var := 45; !Declare VAR and initialize ! it with the value 45 You can initialize a simple variable with character strings or numbers.
Using Simple Variables Declaring Simple Variables Global, Local, and Sublocal Initializations At the global level, initialize variables with expressions that contain only constants or LITERALs as operands.
Using Simple Variables Assigning Data to Simple Variables Assigning Data to Simple Variables Assigning Variables Matching Data Types Converting Data Types After you declare a variable, you can assign a value to it.
Using Simple Variables Simple Variables by Data Type Multiple Variables You can assign a value to more than one simple variable at a time.
Using Simple Variables Simple Variables by Data Type INT Simple Variables An INT simple variable can contain a signed or unsigned 16-bit integer in the range 0 through 65,535 (unsigned) or –32,768 through 32,767 (signed).
Using Simple Variables Simple Variables by Data Type Storage Allocation The compiler allocates a word for each INT simple variable. Here are examples of numeric and character string initializations: INT int_num := %110; INT two_chars := "AB"; %110 "A" "B" 353 For INT simple variables, a one-byte initialization behaves differently from a one-byte assignment as follows: If you initialize an INT variable with a one-byte character string, the compiler allocates the character in the left byte of the word.
Using Simple Variables Simple Variables by Data Type INT(32) Simple Variables An INT(32) simple variable can contain a signed or unsigned 32-bit integer in the range –2,147,483,648 through 2,147,483,647, suffixed by D for decimal, octal, or binary integers or %D for hexadecimal integers. It also can contain a character string of up to four characters.
Using Simple Variables Simple Variables by Data Type REAL Simple Variables A REAL simple variable can contain a signed 32-bit floating-point number in the range ±8.6361685550944446 * 10-78 through ±1.15792089237316189 * 10+77, precise to approximately seven significant digits. The format of a REAL constant includes an integer part, a fractional part suffixed by E, and an exponent. Here is an example of a REAL constant value: -30.
Using Simple Variables Simple Variables by Data Type REAL(64) Simple Variables A REAL(64) simple variable can contain a signed 64-bit floating-point number in the same range as REAL numbers, but precise to approximately 17 significant digits. The format of a REAL(64) constant is the same as for REAL constants, except that the suffix is L instead of E. Here are examples of REAL(64) values: Decimal Value REAL(64) 0 2 2 2 -17.2 -17.2 0.0L0 2.0L0 0.2L1 20.0L-1 -17.2L0 -1720.
Using Simple Variables Simple Variables by Data Type FIXED Simple Variables A FIXED simple variable can contain a signed 64-bit fixed-point number in the range –9,223,372,036,854,775,808 through 9,223,372,036,854,775,807, suffixed by F for decimal, octal, or binary numbers or %F for hexadecimal numbers. For decimal numbers, you can also specify a fractional part, preceded by a decimal point: 300.
Using Simple Variables Simple Variables by Data Type Stored Forms The following examples compare the stored form of values having various fpoints: FIXED(-3) FIXED(-3) FIXED FIXED FIXED(3) FIXED(3) a b c d e f := := := := := := 643000F; .643F; 643000F; .643F; 643000F; .
Using Simple Variables Simple Variables by Data Type UNSIGNED Simple Variables When you declare an UNSIGNED simple variable, you must specify the width, in bits, of the simple variable. Specify the width as a constant expression in the range 1 through 31, enclosed in parentheses, following the UNSIGNED keyword. The constant expression can include LITERALs and DEFINEs: UNSIGNED(5) bit_var; !Width of BIT_VAR is 5 bits You cannot initialize UNSIGNED variables when you declare them.
7 Using Arrays An array is a collectively stored set of elements of the same data type. You use arrays to store constants, especially character strings. You can use the array identifier to access the elements individually or as a group.
Using Arrays Declaring Arrays Using Indirection The global primary storage area is limited to 256 words and the local primary area is limited to 127 words. The global and local secondary areas have no explicit size, and the total of all primary and secondary areas can be as large as the lower 32K-word area of the user data segment. You can minimize the impact on the primary areas by declaring indirect global and local arrays.
Using Arrays Declaring Arrays Initializing Arrays With Constant Lists A constant list can include the following elements: Numbers INT .numbers[0:5] := [1,2,3,4,5,6]; Character strings of up to 127 characters on one line INT(32) .words[0:3] := ["cats", "dogs", "bats", "cows"]; STRING .buffer[0:102] := [ "A constant list can consist ", "of several character string constants ", "one to a line, separated by commas.
Using Arrays Declaring Arrays Global, Local, and Sublocal Initializations You can initialize an array declared at any level except for extended indirect arrays declared at the local level: INT(32) .a[0:1] := [5D, 7D]; PROC my_procedure; BEGIN STRING .b[0:1] := ["A","B"]; FIXED .
Using Arrays Declaring Arrays INT Arrays For INT arrays, the compiler allocates a word for each element: A[0] INT a[0:2]; B[0] A[1] A[2] INT b[2:3]; B[2] INT c[-2:-1]; B[3] C[-2] C[-1] 362 INT(32) Arrays For INT(32) arrays, the compiler allocates a doubleword for each element: D[0] INT(32) d[0:1]; D[1] 363 REAL Arrays For REAL arrays, the compiler allocates a doubleword for each element: REAL r[4:5]; R[4] R[5] 364 096254 Tandem Computers Incorporated 7–5
Using Arrays Declaring Arrays REAL(64) Arrays For REAL(64) arrays, the compiler allocates a quadrupleword for each element: REAL(64) r[0:1]; R[0] R[1] 365 FIXED Arrays For FIXED arrays, the compiler allocates a quadrupleword for each element: FIXED f[0:1]; F[0] F[1] 366 When you declare a FIXED array, you can specify the implied fpoint of values you store in the array elements. The fpoint is an integer in the range –19 through 19, enclosed in parentheses, following the FIXED keyword.
Using Arrays Declaring Arrays UNSIGNED Arrays When you declare an UNSIGNED array, you must specify as part of the data type a value of 1, 2, 4, or 8 that specifies the width, in bits, of the elements in the array. Here is an example of an UNSIGNED array that has eight 4-bit elements: UNSIGNED(4) array[0:7]; The compiler packs allocation of UNSIGNED array elements in sequential words.
Using Arrays Declaring Arrays Allocating Arrays The compiler allocates storage for an array in a particular storage area based on declaration characteristics such as: The global, local, or sublocal level The direct, standard indirect, or extended indirect addressing mode Allocating Direct Arrays The compiler allocates storage for directly addressed arrays in the global, local, or sublocal primary areas of the user data segment as shown in Figure 7-1. Figure 7-1.
Using Arrays Declaring Arrays Allocating Indirect Arrays You can declare global or local indirect arrays. Sublocal arrays cannot be indirectly addressed. For each standard indirect array, the compiler allocates space as follows: 1. It allocates a word of storage in the global (or local) primary area of the user data segment for an implicit standard pointer. 2. It then allocates storage for each array in the global (or local) secondary area. 3.
Using Arrays Declaring Arrays Figure 7-2 shows storage allocation for global indirect arrays. Figure 7-2. Allocating Indirect Arrays User data segment G[0] ptr to A G[1] INT(32) .EXT a[0:9]; INT .EXT b[1:9]; Global G[2] primary G[3] area G[4] G[5] STRING .c[0:1]; INT .d[-1:49]; G[6] ptr to B ptr to C ptr to D C[0] C[1] Global G[7] secondary G[8] area D[-1] G[57] D[49] D[0] ... Automatic extended data segment A[0] A[1] ... A[9] B[0] B[1] B[2] ...
Using Arrays Declaring Arrays Addressability of Arrays The zeroth element of an array must always be addressable. If it is not addressable, the compiler issues an address range violation error. Addressability in the User Data Segment The zeroth element of a direct array must fit within the lower 32K-word area of the user data segment, even if the zeroth element is not allocated. The global area has G-plus addressing. If a global array is located at G[0], its lower bound must be a zero or negative value.
Using Arrays Accessing Arrays Accessing Arrays After you declare an array, you can access its elements by using the array identifier in statements, regardless of addressing mode. For example, you can declare a direct array, a standard indirect array, and an extended indirect array, and then access each by its identifier: INT dir_array[0:2]; !Declare direct array INT .std_array[0:2]; !Declare standard indirect array INT .
Using Arrays Assigning the Address of Arrays You can use constants and LITERALs as index values: LITERAL index = 5; INT table[0:9]; !Declare LITERAL !Declare array table[index] := "AB"; !Access sixth element of array You can use variables as index values: INT .EXT b[0:10]; INT .
Using Arrays Copying Data Into Arrays Copying Data To copy data to multiple array elements, use the move statement. You can, for Into Arrays example, copy: A constant list into an array Data between arrays Data within an array Copying a Constant List Into an Array To copy a constant list into an array, specify the destination array and the constant list in a move statement. You can copy the source data from left to right or from right to left.
Using Arrays Copying Data Into Arrays Copying a Byte Constant Into a STRING Array To copy a single byte constant into an element of the destination array, enclose the constant in brackets in the move statement.
Using Arrays Copying Data Into Arrays Copying Words To copy words regardless of source data type, specify the WORDS keyword in the FOR clause. WORDS generates a word copy for the number of words specified by the count value. For example, to copy words instead of doublewords from an INT(32) source array, multiply LENGTH by 2 and include the WORDS keyword: LITERAL length = 12; !Count value (number of ! words to copy) INT(32) .new_array[0:length - 1];!Destination INT(32) .
Using Arrays Copying Data Into Arrays Copying Data Within an Array To copy data within an array, specify the same array for the destination and source arrays and include the FOR clause in the move statement. For example, you can free element [0] of a 12-element array by specifying the following move statement. This move statement first copies element [10] into element [11], then element [9] into element [10], and so forth.
Using Arrays Copying Data Into Arrays The compiler does a standard move and returns a 16-bit next address if: Both arrays have standard byte addresses Both arrays have standard word addresses The compiler does an extended move and returns a 32-bit next address if: One of the two arrays has a standard byte address and the other has a standard word address Either array has an extended address STRING arrays and arrays pointed to by STRING pointers are byte addressed. All other arrays are word addressed.
Using Arrays Scanning Arrays When the preceding example executes, LINE_ARRAY contains the following: DATE: Feb 1, 1992 ID NUMBER: 854-70-1950 DEPARTMENT: 107 Initializing a Large Array Quickly To initialize a large array quickly, you can concatenate two copy operations in a move statement. The first copy operation copies two spaces into element [0], and the second copies the spaces from element [0] into the remaining elements: LITERAL length = 100; INT .
Using Arrays Scanning Arrays Determining What Stopped the Scan To determine what stopped the scan, test $CARRY in an IF statement immediately after the SCAN or RSCAN statement. If $CARRY is true after a SCAN UNTIL, the test character did not occur. If $CARRY is true after SCAN WHILE, a character other than the test character did not occur. Here are examples for using $CARRY: IF $CARRY THEN ... ; IF NOT $CARRY THEN ...
Using Arrays Scanning Arrays In the diagrams shown with the following examples, an arrow points to the character that stopped the scan. Scanning WHILE SCAN WHILE searches until it finds a byte character other than the test character or a zero. The following example scans left to right while spaces occur, starting from the zeroth element of INT_ARRAY. The scan stops at the beginning of the last name and stores that address in the next-address pointer START_LAST_NAME.
Using Arrays Scanning Arrays Computing the Offset of a Character The following SCAN WHILE example finds the offset of the first name from the beginning of the array. It scans left to right from the address following the comma, looking for a character other than a space or a zero. It stops at the beginning of the first name and stores that address in the next-address pointer START_FIRST_NAME.
Using Arrays Using Standard Functions With Arrays Comparing Arrays You can compare two arrays, or compare an array to a constant list, by using a group comparison expression in a statement. Group comparison expressions are described in Section 13, “Using Special Expressions.” Here are some examples. You can compare an array to a constant list: STRING an_array[0:3]; !Some code here IF an_array[0] = ["ABCD"] THEN ...
Using Arrays Using Read-Only Arrays Using Read-Only A read-only array is an array you cannot modify. When you declare a read-only array, Arrays the compiler allocates storage for the array in a user code segment. Declaring Read-Only Arrays Read-only array declarations differ from other array declarations in a number of ways: You must specify the read-only array symbol (= 'P') following the array identifier.
Using Arrays Using Read-Only Arrays A procedure located in the upper 32K-word area of the code segment can access global STRING read-only arrays located in the lower 32K-word area only by using extended pointers. Here is an example: PROC q (sp, len); STRING .EXT sp; INT len; BEGIN !Code to print sp[0:len - 1] END; PROC p; BEGIN STRING s = 'P' := "Hello"; STRING .
8 Using Structures A structure is a collectively stored set of data items that you can access individually or as a group. Structures contain structure items (fields) such as simple variables, arrays, simple pointers, structure pointers, and nested structures (called substructures). The structure items can be of different data types. Structures usually contain related data items such as the fields of a file record.
Using Structures Structure Layout Structure Layout The structure layout is a BEGIN-END construct that contains declarations of structure items. Table 8-2 lists structure items. Table 8-2.
Using Structures Declaring Definition Structures Declaring Definition A definition structure describes a structure layout and allocates storage for it. To Structures declare a single occurrence of a definition structure, specify: The keyword STRUCT The structure identifier, usually preceded by an indirection symbol (. or .EXT) A semicolon The structure layout (enclosed in a BEGIN-END construct) You can, for example, declare a definition structure named INVENTORY like this: STRUCT .
Using Structures Declaring Definition Structures To declare a standard indirect structure, precede the structure identifier with the standard indirection symbol (.): STRUCT .std_structure; BEGIN INT a; INT b; END; !Declare standard indirect ! definition structure ! (global or local scope) For very large structures, you should use extended indirection. When you declare one or more extended indirect structures (or arrays), the compiler allocates the automatic extended data segment.
Using Structures Declaring Definition Structures Extended Indirect Structures For each extended indirect structure, the compiler allocates space as follows: 1. It allocates two words of storage in the global (or local) primary area of the user data segment for the implicit extended structure pointer. 2. Next, it allocates storage for the structure in the automatic extended data segment. 3.
Using Structures Declaring Definition Structures Addressability of Structures The zeroth occurrence of a structure must be addressable. If it is not addressable, the compiler issues an address range violation error. (In the following diagrams, parentheses enclose the zeroth occurrence to indicate that it is not addressable.
Using Structures Declaring Template Structures Declaring Template (A template structure declares a structure layout but allocates no storage for it. You Structures use the template in subsequent structure, substructure, or structure pointer declarations.
Using Structures Declaring Referral Structures Declaring Referral A referral structure allocates storage for a structure whose layout is the same as that of Structures a specified structure or structure pointer. To declare a single occurrence (copy) of a referral structure, specify: The keyword STRUCT The structure identifier, usually preceded by an indirection symbol (. or .
Using Structures Declaring Simple Variables and Arrays in Structures To declare a standard indirect structure, precede the structure identifier with the standard indirection symbol (.), as shown in the preceding example. For very large structures, you should use extended indirection. When you declare one or more extended indirect structures (or arrays), the compiler allocates the automatic extended data segment.
Using Structures Declaring Simple Variables and Arrays in Structures Declaring Arrays That Use No Memory If you declare within a structure an array that has bounds of [n:n-1], the compiler places the identifier of the array in the symbol table but allocates no storage for the array. You can then apply the array’s data type to subsequent items in the same structure. For example, suppose you declare within a structure an INT(32) array that has bounds of [0:-1], followed by a FIXED variable.
Using Structures Declaring Simple Variables and Arrays in Structures This example shows how the compiler allocates STRING simple variables (VAR1 and VAR2) and STRING arrays (A, B, and C) on byte boundaries. The compiler allocates a pad byte following array C because VAR4 must be word aligned. STRUCT .
Using Structures Declaring Substructures Declaring Substructures A substructure is a structure embedded within another structure or substructure. In general, substructures have the following characteristics: They must be directly addressed. They have byte addresses, not word addresses. They can be nested to a maximum of 64 levels. They can have bounds of [n: n-1]. Such substructures are addressable but use no memory. You can declare definition or referral substructures.
Using Structures Declaring Substructures Declaring Multidimensional Arrays You can nest substructures in a structure to simulate a multidimensional array. The following structure simulates a two-dimensional array. The structure represents two warehouses. The two substructures represent 50 items and ten employees in each warehouse. The substructures are both nested at the second level but contain different kinds of records: LITERAL last = 49; !Declare number of last item STRUCT .
Using Structures Declaring Substructures Allocating Definition Substructures The compiler allocates storage for each substructure when it allocates storage for the encompassing structure. The compiler aligns a definition substructure on a byte or word boundary. Byte Alignment. A definition substructure is byte aligned if the first item it contains begins on a byte boundary. In the following example, definition substructure SUB follows a STRING item (X); the first item in SUB is also a STRING item (AA).
Using Structures Declaring Substructures Declaring Referral Substructures A referral substructure uses the layout of a previously declared structure.
Using Structures Declaring Fillers Declaring Fillers You can declare filler bytes or bits to allocate place holder space within a structure. You cannot access filler locations. You can use filler items to allocate space within a structure when the structure layout must match a structure layout defined by another program. The new structure declaration need only include data items used by your program. You can use filler items for the unused data.
Using Structures Declaring Simple Pointers in Structures Declaring Simple Pointers in Structures You can declare simple pointers within a structure. A simple pointer is a variable in which you store the memory address, usually of a simple variable or array, which you can access with this pointer. The compiler allocates space for the pointer but not for the data to which the pointer points.
Using Structures Declaring Simple Pointers in Structures Addresses Simple Pointers Can Contain The addressing mode and data type of a simple pointer determines the kind of address the pointer can contain, as described in Table 8-4. Table 8-4. Addresses in Simple Pointers Addressing Mode Data Type Kind of Addresses Standard STRING Standard Any except STRING STRING 16-bit byte address in the lower 32K-word area of the user data segment. 16-bit word address anywhere in the user data segment.
Using Structures Declaring Structure Pointers in Structures Declaring Structure You can declare structure pointers within a structure or substructure. A structure Pointers in Structures pointer is a variable in which you store the memory address of a structure, which you can access with this structure pointer. The compiler allocates space for the pointer but not for the data to which the pointer points.
Using Structures Declaring Structure Pointers in Structures Addresses Structure Pointers Can Contain The addressing mode and STRING or INT attribute of a structure pointer determine the kind of addresses the pointer can contain, as described in Table 8-5. Table 8-5.
Using Structures Declaring Redefinitions Declaring A redefinition declares a new identifier and sometimes a new description for a Redefinitions previously declared item in the same structure. The new item or the previous item can be a simple variable, array, pointer, or substructure. The new item must be at the same BEGIN-END level in a structure as the previous item. The new item must also be of the same length or shorter than the previous item.
Using Structures Declaring Redefinitions You can declare DW_ADDR to redefine DW_MEM as follows: STRUCT dw_template (*); BEGIN INT(32) .dw_mem; INT dw_addr = dw_mem; END; !Redefinition Even if the lower bound of the new array is not zero, the new specified lower bound is always associated with the zeroth element of the previous array. In the following example, new INT(32) array B[1:2] redefines previous INT array A[0:3]: A[-2] A[-1] . . A[0] . STRUCT .
Using Structures Declaring Redefinitions Definition Substructures as Redefinitions To declare a definition substructure that redefines a previously declared item within the same structure, specify: The keyword STRUCT The identifier of the new substructure Optional bounds—if you omit the bounds, the default bounds are [0:0] (one occurrence) An equal sign (=) The identifier of a previous item at the same BEGIN-END level of the encompassing structure—the previous item can be a simple variable, array, pointer
Using Structures Declaring Redefinitions You can declare new substructure SS to redefine array A and then declare simple variable V to redefine substructure SS as follows: STRUCT .
Using Structures Declaring Redefinitions Alignment of Substructure Redefinitions The new substructure must have the same byte or word alignment as the previous substructure. That is, if the previous substructure starts on an odd byte, the first item in the new substructure must be a STRING item.
Using Structures Declaring Redefinitions For example, you can declare a referral substructure redefinition that uses a template structure layout: STRUCT temp(*); BEGIN STRING a[0:2]; INT b; STRING c; END; !Declare template structure STRUCT .
Using Structures Accessing Structure Items For example, you can declare new standard and extended structure pointers to redefine simple variables as follows: STRUCT record; BEGIN FIXED(0) data; INT std_link_addr; INT .std_link(record) = std_link_addr; !Redefinition INT ext_link_addr; INT .EXT ext_link(record) = ext_link_addr; !Redefinition END; Accessing You access an item in a definition or referral structure by using the item’s fully Structure Items qualified identifier in a statement.
Using Structures Accessing Structure Items Indexing Structures You can access a particular structure item by appending indexes (enclosed in brackets) to the various levels in the qualified identifier of the structure item. For example, you can access an array element in a particular structure and substructure occurrence by appending indexes as follows: my_struct[1].my_substruct[0].
Using Structures Accessing Structure Items The following example shows how you can index a standard indirect structure: STRUCT .std_struct[0:99]; BEGIN INT var; STRING array[0:25]; STRUCT substr[0:9]; BEGIN STRING array[0:25]; END; END; !Standard indirect structure INT index := 5; !Simple variable !Simple variable !Array !Substructure !Array PROC x MAIN; !Declare procedure X BEGIN std_struct[index].var := 35; !Access STD_STRUCT[5].VAR std_struct[index+2].array[0] := "A"; !Access STD_STRUCT[7].
Using Structures Accessing Structure Items Indexing Extended Indirect Structures The index for extended indirect structures must be a signed INT or INT(32) arithmetic expression, depending on the size of the offset of the structure item you want to access. The offset of a structure item is from the zeroth structure occurrence (not the current structure occurrence). C-Series System.
Using Structures Accessing Structure Items To access a structure item whose offset is outside the signed INT range (–32678 through 32,767), you must use an INT(32) index. To convert an INT index to an INT(32) index, you can use the $DBL standard function: STRUCT .EXT xstruct[0:9999]; BEGIN STRING array[0:9]; END; !Upper byte offset > 32,767; ! INT(32) index required INT index; PROC my_proc MAIN; BEGIN !Some code here to initialize INDEX xstruct[$DBL(index)].
Using Structures Accessing Structure Items D-Series System. If you are writing a program to run on a D-series system and need to index into extended indirect structures, you can either: Determine when to use a signed INT or INT(32) index as described for C-series programs in the preceding subsection. Use the INT32INDEX directive, which is easier and safer, albeit slightly less efficient. INT32INDEX generates INT(32) indexes from INT indexes and computes the correct offset for the indexed structure item.
Using Structures Accessing Structure Items Standard Addressing Contrasted With Extended Indexing The allowed offset of a standard indirect structure item is greater than that of an extended indirect structure item. The following example declares a standard indirect structure item accessed by an index that is greater than that allowed for an extended indirect structure item: LITERAL ub = 32759; STRUCT .
Using Structures Accessing Structure Items Assigning Values to Structure Items You assign a value to a structure item by using its fully qualified identifier in an assignment statement. For example, the assignment statement for assigning an expression to simple variable VAR declared in SUBSTRUCT_A in STRUCT_B is: struct_b.substruct_a.var := any_expression; Here are examples. You can assign a value to VAR3 in DEF_STRUCT: STRUCT .
Using Structures Accessing Structure Items Assigning Addresses to Pointers in Structures You can assign to pointers the kinds of addresses listed in Tables 8-4 and 8-5 earlier in this section. To assign an address to a pointer within a structure, specify the fully qualified pointer identifier in an assignment statement. Prefix the structure identifier with @. For example, the assignment statement to assign an address to PTR_X declared in SUBSTRUCT_A in STRUCT_B is: @struct_b.substruct_a.
Using Structures Accessing Structure Items The following example assigns the address of a structure to structure pointers declared in another structure: STRUCT .s1; BEGIN INT var1; INT var2; END; !Declare S1 STRUCT .s2; BEGIN INT .std_ptr (s1); INT .EXT ext_ptr (s1); END; !Declare S2 PROC g MAIN; BEGIN @s2.std_ptr := @s1[0]; @s2.ext_ptr := $XADR(s1); END; Accessing Data Through Pointers in Structures !Declare STD_PTR !Declare EXT_PTR !Assign standard address ! of S1 to S2.
Using Structures Accessing Structure Items The last two statements in the following example access S3 to which the structure pointers declared in S2 point: INT .a[0:99]; STRUCT .s3; BEGIN INT b[0:99]; END; STRUCT .s2; BEGIN INT .std_ptr (s3); INT .EXT ext_ptr (s3); END; PROC i MAIN; BEGIN @s2.std_ptr := @s3; !Declare array A !Declare S3 !Declare array B !Declare S2 !Declare STD_PTR !Declare EXT_PTR !Assign standard address ! of S3 to S2.STD_PTR @s2.
Using Structures Accessing Structure Items The following example shows how you can access structure items by using structure pointers declared in structures: STRUCT template (*); BEGIN STRING b[0:2]; INT e; END; !Declare template structure STRUCT .link_list; !Declare definition structure BEGIN INT .fwd_ptr (link_list); !Declare structure pointer and ! redefine simple variable STRING .EXT ptr_to_ext_item(template); !Declare structure pointer INT(32) .
Using Structures Accessing Structure Items Copying Data in Structures You can copy data to structures by using a move statement. For example, you can copy: Structure occurrences between structures Structure occurrences within a structure Substructure occurrences between structures Structure items To start copying from the lower occurrence, use the left-to-right move operator (':='). To start copying from the upper occurrence, use the right-to-left move operator ('=:').
Using Structures Accessing Structure Items Copying Structure Occurrences Within a Structure To copy occurrences within a structure, specify in a move statement: The same structure for destination and source The FOR clause including the ELEMENTS qualifier For example, you can copy the data in each occurrence of a structure one occurrence to the right, beginning with occurrence [8], thus freeing occurrence [0] for new data.
Using Structures Accessing Structure Items Copying Structure Items You can use a move statement to copy structure items within and between structures and substructures. Structure items you can copy are simple variables, arrays, and pointers declared within structures or substructures.
Using Structures Accessing Structure Items Copying Structure Occurrences Using Structure Pointers You can copy structure occurrences using structure pointers: LITERAL copies := 3; STRUCT a_struct; BEGIN INT a; STRING b; END; !Definition structure STRUCT b_struct (a_struct) [0:copies - 1]; !Referral structure INT .EXT ptr0(a_struct) := $XADR (a_struct); !Assign address of A_STRUCT to ! extended INT pointer PTR0 STRING .
Using Structures Using Standard Functions With Structures Using Standard You can use the following standard functions with structures.
9 Using Pointers This section describes: How to declare and initialize pointers How to assign addresses to pointers How to access data with pointers How the compiler allocates storage for pointers You can declare the following kinds of pointers: Simple pointer—a variable into which you can store a memory address, usually of a simple variable or array, which you can access with this simple pointer.
Using Pointers Using Simple Pointers Using Simple Pointers A simple pointer is a variable into which you must store a memory address, usually of a simple variable or an array element. When you refer to a simple pointer identifier in expressions, you access the item whose address is stored in the simple pointer. Before accessing data through a simple pointer, you must declare the pointer and store a memory address in it.
Using Pointers Using Simple Pointers Initializing Simple Pointers To initialize a pointer in the declaration, specify the assignment operator after the pointer identifier, followed by an initialization expression that represents an address. The addressing mode and data type determines the kind of address the simple pointer can contain, as described in Table 9-2. Table 9-2.
Using Pointers Using Simple Pointers The following table shows the kinds of global variables to which you can apply the @ operator: Variable @identifier? Direct array Standard indirect array Extended indirect array Direct structure Standard indirect structure Extended indirect structure Simple pointer Structure pointer Yes Yes No Yes Yes No No No For example, you can initialize a global standard simple pointer with the address of an array element: STRING .array[0:3]; !Declare ARRAY STRING .
Using Pointers Using Simple Pointers Extended Pointers You can initialize global extended pointers with extended addresses converted from standard addresses by the $DBL, $UDBL, and $DBLL standard functions. These functions compute the initialized value if their arguments are constant expressions or expressions that follow the rules applied to standard global pointers. Here is an example of the $UDBL function: INT a[0:2]; INT .
Using Pointers Using Simple Pointers You can initialize a local or sublocal extended simple pointer with the address of an extended indirect array: INT .EXT ext_array[0:99]; !Declare EXT_ARRAY INT .
Using Pointers Using Simple Pointers Figure 9-1. Allocating Simple Pointers Address Contains byte offset INT(32) .a[0:1]; INT b; STRING .c[0:3]; INT .p1; INT .p2 := @a; INT .p3 := @b; G[0] .A G[1] B G[2] .C G[3] .P1 Undefined G[4] .P2 200 G[5] .P3 1 200 408 ...
Using Pointers Using Simple Pointers Assigning Addresses of Simple Variables or Arrays To assign the address of a simple variable or array to a standard simple pointer, place the variable or array identifier (prefixed by @) on the right side of the assignment operator: STRING .bytes[0:3]; STRING .
Using Pointers Using Simple Pointers Assigning the Content of Simple Pointers To assign an address contained in a simple pointer (for instance, PTR1) to another simple pointer (for instance, PTR2), specify @PTR1 on the right side of the assignment operator: Accessing Data With Simple Pointers INT array[0:99]; INT .ptr1 := @array; INT .
Using Pointers Using Simple Pointers The following example shows pointers used in assignment, move, IF, and SCAN statements: INT var_a; INT var_b; INT .ptr; !Declare variables VAR_A and ! VAR_B !Declare standard simple ! pointer PTR INT .EXT ptr_a; !Declare extended simple INT .
Using Pointers Using Simple Pointers The index represents an element offset from the address stored in the simple pointer; that is, from the address of a simple variable, array, or structure item. The element offset yielded by an index depends on the data type of the simple pointer: Data Type Element Offset STRING INT INT(32) or REAL REAL(64) or FIXED Byte Word Doubleword Quadrupleword For example, you can initialize an INT simple pointer with the address of an INT(32) array.
Using Pointers Using Structure Pointers Using Structure A structure pointer is a variable that you associate with a particular structure layout. Pointers You must store the memory address of a structure in the structure pointer before you access the data to which it points. You can store an address by initializing the pointer when you declare it or by assigning an address to it later in an assignment statement.
Using Pointers Using Structure Pointers Initializing Structure Pointers To initialize a pointer when you declare it, specify the assignment operator after the identifier, followed by an initialization expression. The addressing mode and STRING or INT attribute of the structure pointer determine the kind of addresses the pointer can contain, as described in Table 9-3. Table 9-3.
Using Pointers Using Structure Pointers You can initialize standard structure pointers with the addresses of structure items by using: The $OFFSET standard function, which returns an item’s byte offset from the zeroth occurrence of the encompassing structure An unsigned operator such as '+' to append an offset in the range 0 through 65,535 to a standard pointer Bit-shift operations ('>>' 1 or '<<' 1) to convert a byte address to a word address or vice versa For example, the following initializations store
Using Pointers Using Structure Pointers Here is another way to access a STRING item in a structure. You can convert the word address of the structure to a byte address when you initialize the STRING structure pointer and then access the STRING item in a statement: STRUCT .astruct[0:1]; BEGIN STRING s1; STRING s2; STRING s3; END; STRING .ptr (astruct) := @astruct[1] '<<' 1; !Declare STRING PTR; initialize ! it with converted byte ! address of ASTRUCT[1] ptr.
Using Pointers Using Structure Pointers You can initialize a local or sublocal extended structure pointer with the address of an extended indirect structure: STRUCT .EXT ext_struct[0:2]; !Declare EXT_STRUCT BEGIN INT array1[0:7]; END; INT .
Using Pointers Using Structure Pointers Address of Structure Occurrence To assign the address of a standard structure occurrence to a structure pointer, place the structure identifier, prefixed with @, on the right of the assignment operator: STRUCT struct_a[0:2]; BEGIN INT array1[0:7]; END; !Declare STRUCT_A PROC any MAIN; BEGIN INT .
Using Pointers Using Structure Pointers Accessing Data With Structure Pointers You access the data item to which a pointer points by using the pointer identifier, without @, in statements. In a move, SCAN, or RSCAN statement, you normally use the unqualified identifier of a structure pointer. (An extended pointer cannot be the object of a SCAN or RSCAN statement.
Using Pointers Using Structure Pointers Copying Structure Occurrences To copy structure occurrences from one location to another, use unqualified identifiers of structure pointers such as STRUCT_PTR1 and STRUCT_PTR2 in move statements: STRUCT .old_record[0:2]; BEGIN STRING name[0:31]; INT salary; END; !Declare OLD_RECORD STRUCT .new_record (old_record) [0:2]; !Declare NEW_RECORD INT .struct_ptr1 (old_record) := @old_record; !Declare STRUCT_PTR1; ! initialize it with ! address of OLD_RECORD INT .
Using Pointers Using Structure Pointers In the following example, a STRING structure pointer accesses a substructure in a structure: STRUCT name_def(*); BEGIN STRING first[0:3]; STRING last[0:3]; END; STRUCT .record; BEGIN STRUCT name (name_def); INT age; END; !Declare substructure STRING .my_name(name_def) := @record.
Using Pointers Using Structure Pointers The indexed item determines the size of the index offset, as listed in Table 9-4: Table 9-4.
Using Pointers Using Structure Pointers The following example shows how you can index a standard structure pointer: STRUCT .std_struct[0:99]; BEGIN INT var; STRING array[0:25]; STRUCT substr[0:9]; BEGIN STRING array[0:25]; END; END; !Standard indirect structure INT index := 5; !Simple variable !Simple variable !Array !Substructure !Array PROC x MAIN; !Declare procedure X BEGIN INT struct_ptr (std_struct) := @std_struct; !Declare standard structure pointer struct_ptr[index].
Using Pointers Using Structure Pointers Whenever you increase the structure size or number of occurrences, you must repeat the preceding sequence of steps. To access a structure item whose offset is within the signed INT range, you can use an INT index as follows: !Default NOINHIBITXX in effect STRUCT .EXT xstruct[0:9]; BEGIN STRING array[0:9]; END; !Declare extended indirect ! structure; upper byte offset ! is within INT range INT index; STRING var; !Declare INT index PROC my_proc MAIN; BEGIN INT .
Using Pointers Using Structure Pointers In the preceding example, the upper-byte offset of ARRAY is larger than 32,767, computed as follows: 9999 * 10 + 9 = 99999 Size of offset to ARRAY[9] Upper bound of array Size of structure in bytes Upper bound of structure 334 D-Series System.
Using Pointers Using Structure Pointers Specify INT32INDEX or NOINT32INDEX immediately before the declarations to which it applies. The specified directive then applies to those declarations throughout the compilation. The following D-series example shows how INT32INDEX generates correct offsets and NOINT32INDEX generates incorrect offsets: !The default NOINT32INDEX is in effect. STRUCT .
10 Using Equivalenced Variables Equivalencing lets you declare more than one identifier and description for a location in a primary storage area. This section describes how to equivalence a new variable to a previously declared variable. You can declare: Equivalenced simple variables Equivalenced simple pointers Equivalenced structures Equivalenced structure pointers The new and previous variables can have different data types and byte-addressing and word-addressing attributes.
Using Equivalenced Variables Equivalencing Simple Variables Equivalencing Simple Variables Declaring Equivalenced Simple Variables You can equivalence a new simple variable to a previously declared variable as listed in Table 10-1 earlier in this section.
Using Equivalenced Variables Equivalencing Simple Variables Equivalencing Simple Variables to Simple Pointers If you equivalence a simple variable to a simple pointer, the simple variable is equivalenced to the location occupied by the simple pointer, not to the location whose address is stored in the pointer: PTR = 200 INT .ptr := 200; INT addr = ptr; ADDR . . .
Using Equivalenced Variables Equivalencing Simple Variables Also avoid equivalencing a simple variable to an extended indirect array: INT .EXT array[0:999]; INT(32) addr = array; ptr to ARRAY ADDR ARRAY . . . Automatic extended data segment 309 Avoid Odd-Byte Equivalencing If you equivalence a STRING variable to an odd-byte array element, the compiler converts the odd-byte index to the previous word boundary as shown in the diagram and issues a warning.
Using Equivalenced Variables Equivalencing Simple Variables Accessing Equivalenced Simple Variables Once you have declared an equivalenced variable, you access it in the same way as you access any other variable, by specifying its identifier in a statement. Accessing Words in Doublewords You can declare two INT variables, each equivalent to one of the two words of an INT(32) variable.
Using Equivalenced Variables Equivalencing Simple Pointers Equivalencing Simple Pointers Declaring Equivalenced Simple Pointers You can equivalence a new simple pointer to a previously declared variable as listed in Table 10-1 earlier in this section.
Using Equivalenced Variables Equivalencing Simple Pointers When you equivalence extended pointers, you need not worry about byte and word addressing mismatches, because extended pointers always point to byte addresses. Thus, you can equivalence an extended INT pointer to an extended STRING pointer: Primary area of user data segment XSTRPTR = %2000000D XINTPTR %2000000D . . . STRING .EXT xstrptr := %2000000D; INT .
Using Equivalenced Variables Equivalencing Simple Pointers You can equivalence an extended pointer to an INT(32) simple variable: Primary area of user data segment XADDR = %2000000D XPTR %2000000D . . . INT(32) xaddr := %2000000D; INT .EXT xptr = xaddr; Automatic extended data segment 417 Accessing Equivalenced Simple Pointers After you declare an equivalenced pointer, you can access it by specifying in a statement the identifier of the pointer or of the variable to which the pointer is equivalenced.
Using Equivalenced Variables Equivalencing Structures If you prefix @ to the pointer identifier in the preceding example and assign a value to the pointer, you change the content of both the direct variable and the simple pointer: DIR = 66 @ptr := 66; PTR = 66 . . . G[66] 311 If you assign a value to the simple pointer without the @ operator, you change the content of only the variable to which the simple pointer points. Location G[66] now contains 15: DIR = 66 ptr := 15; PTR = 66 . . .
Using Equivalenced Variables Equivalencing Structures Equivalencing Definition Structures To declare an equivalenced definition structure, specify: The keyword STRUCT The identifier of the new structure, often preceded by an indirection symbol An equal sign (=) The identifier of the previous variable The layout of the new structure (enclosed in a BEGIN-END construct) For portability to future software platforms, declare equivalenced variables that fit within the previous variable.
Using Equivalenced Variables Equivalencing Structures Equivalencing Extended Indirect Structures You can equivalence an extended indirect definition structure to another extended indirect structure: Primary area of user data segment STRUCT .EXT xstr1; BEGIN STRING old_name[0:20]; STRING old_addr[0:50]; END; ptr to XSTR1 ptr to XSTR2 XSTR1 XSTR2 . . . . . . . . . STRUCT .
Using Equivalenced Variables Equivalencing Structures Equivalencing Structures to Arrays You can equivalence a structure to an array. The following example equivalences a standard indirect structure to a standard indirect array: Primary area STRING .array[0:127]; STRUCT .str = array; BEGIN STRING name[0:63]; STRING addr[0:63]; END; ptr to ARRAY ptr to STR . . . ARRAY STR . . . . . .
Using Equivalenced Variables Equivalencing Structures Equivalencing Structures to Structure Pointers If you equivalence an indirect structure to a structure pointer, the indirect structure behaves exactly like the structure pointer: STRUCT .str1; BEGIN INT a[0:3]; INT b[0:9]; END; INT .ptr (str1) := @str1; STRUCT .str2 = ptr; BEGIN STRING a2[0:7]; STRING b2[0:19]; END; ptr to STR1 PTR ptr to STR2 . . . STR1 . . . STR2 . . .
Using Equivalenced Variables Equivalencing Structures Avoid equivalencing a direct structure to an indirect variable, because the direct structure is not equivalenced to the indirect structure. Avoid the following practice: STRUCT .ind_str; BEGIN STRING a[0:19]; STRING b[0:49]; END; STRUCT dir_str = ind_str; BEGIN INT a[0:9]; INT b[0:24]; END; Primary area ptr to IND_STR IND_STR DIR_STR . . . . . .
Using Equivalenced Variables Equivalencing Structure Pointers Equivalencing Referral Structures to Definition Structures You can equivalence a referral structure to a previous definition structure. In the following example, both are standard indirect structures: STRUCT .d_str; BEGIN STRING name[0:19]; STRING address [0:49]; END; ptr to D_STR . . . STRUCT tmp (*); BEGIN INT name[0:9]; INT address[0:24]; END; STRUCT .r_str (tmp) = d_str; ptr to R_STR D_STR R_STR . . . . . .
Using Equivalenced Variables Equivalencing Structure Pointers Declaring Equivalenced Structure Pointers To declare an equivalenced structure pointer, specify: STRING or INT attribute (as described in Table 9-3 in Section 9) The identifier of the new structure pointer, preceded by an indirection symbol A referral that provides a structure layout—enclose the identifier of a previously declared structure or structure pointer in parentheses An equal sign (=) The identifier of the previous variable For portabi
Using Equivalenced Variables Equivalencing Structure Pointers Equivalencing Structure Pointers to Structures Equivalencing an extended structure pointer to an extended indirect structure is the same as equivalencing an indirect structure to another indirect structure. Primary area of user data segment STRUCT .EXT str; BEGIN STRING name[0:20]; STRING addr[0:50]; END; INT .EXT ptr (str) = str; ptr to STR PTR STR . . .
Using Equivalenced Variables Equivalencing Structure Pointers Avoid Mixing Addressing Modes All guidelines for avoiding mixed address modes given earlier in this section apply to equivalenced structure pointers. Accessing Data Through Equivalenced Structure Pointers To access a structure through a structure pointer, qualify the name of the pointer with the appropriate structure item names, as was described in Section 9, “Using Pointers.
Using Equivalenced Variables Using Indexes or Offsets However, if you assign an address to the structure pointer in the preceding example, both the structure pointer and the implicit pointer point to the new address, rather than to the structure data. You can no longer access the structure data. Avoid the last statement in the following example: Primary area INT var1; INT var2; G[0] VAR1 VAR2 STRUCT .str; BEGIN INT a[0:3]; INT b[0:9]; END; ptr to STR PTR = 0 . . . STR INT .ptr (str) = str; . . .
Using Equivalenced Variables Using Indexes or Offsets For direct INT previous variables, indexes and offsets both have word offsets: INT x[0:1]; INT indx = x[1]; INT offst = x + 1; x[0] x[1] INDX OFFST 324 For direct previous variables other than INT, indexes have element offsets and offsets have word offsets: Offset XX+0 INT(32) xx; INT indx = xx[1]; INT offst = xx + 1; Index XX[0] OFFST XX+1 XX+2 XX[1] INDX XX+3 325 You can equivalence a variable to an offset simple pointer but not to an index
Using Equivalenced Variables Emulating Pascal Variant Parts Emulating Pascal Variant Parts You can simulate variant parts of a Pascal record type by using equivalenced structures as follows. (For information on record type variant parts, see the Pascal Reference Manual.
11 Using Procedures Procedures are program units that can contain the executable portions of a TAL program and that are callable from anywhere in the program. Procedures let you segment a program into discrete parts that each perform a particular operation such as I/O or error-handling. A procedure can call other procedures, one at a time, or it can call another procedure that in turn calls another, and so on. It can pass parameters (arguments).
Using Procedures Declaring Procedures Declaring Procedures To declare a procedure in its simplest form, specify: The keyword PROC The procedure identifier, followed by a semicolon The procedure body—a BEGIN-END construct that can include data declarations, subprocedure declarations, and statements Here is an example of a procedure declaration: PROC my_proc; !Declare procedure MY_PROC BEGIN INT var; !Declare local data !Declare subprocedures, if any var := 99; !Specify local statements CALL some_proc; END;
Using Procedures Declaring Parameters in Procedures Declaring Parameters You can include formal parameters in the procedure declaration. Callers can then pass in Procedures corresponding actual parameters for use in the called procedure. Specifying a Formal Parameter List To include formal parameters in a procedure declaration, specify a comma-separated list (enclosed in parentheses) of up to 32 formal parameters.
Using Procedures Declaring Data in Procedures Passing Actual Parameters The formal parameter declarations in the called procedure dictates how the calling procedure declares the actual parameters. For example, if the called procedure declares a simple variable as a formal reference parameter, the calling procedure must declare a simple pointer as the actual parameter. The calling procedure passes actual parameters by specifying an actual parameter list in a CALL statement.
Using Procedures Declaring Data in Procedures Allocating Local Variables When a procedure is activated, the compiler allocates storage for the procedure's variables in the procedure's private local storage area, which consists of a primary and a secondary storage area.
Using Procedures Declaring Data in Procedures Figure 11-1.
Using Procedures Using Procedure Options Returning From a Procedure A called procedure returns control to the caller when a RETURN statement is executed or the last END keyword is reached. (In a nonfunction procedure, a RETURN statement is optional.
Using Procedures Using Procedure Options Declaring Functions A function is a procedure or subprocedure that returns a result to the caller.
Using Procedures Using Procedure Options Declaring EXTERNAL Procedures An EXTERNAL procedure declaration lets the current compilation unit call a procedure that is declared in another compilation unit. The other compilation unit can be a system library, a user library, or a user file.
Using Procedures Using Procedure Options For example, the following VARIABLE procedure returns control to the caller if either required parameter is absent. Also the procedure provides a default 0 to use if the optional parameter is absent. PROC errmsg (msg, count, errnum) VARIABLE; INT .
Using Procedures Using Procedure Options In the following example, the EXTENSIBLE procedure returns control to the caller if either required parameter is absent. Also the procedure provides a default 0 to use if the optional parameter is absent. PROC errmsg (msg, count, errnum) EXTENSIBLE; INT .
Using Procedures Using Procedure Options Passing Parameters Conditionally As of the D20 release, you can pass a parameter or parameter pair to a VARIABLE or EXTENSIBLE procedure based on a condition at execution time by using the $OPTIONAL function. $OPTIONAL is evaluated each time the encompassing CALL statement is executed: If the conditional expression is true, the actual parameter is passed. If the conditional expression is false, the actual parameter is not passed.
Using Procedures Using Procedure Options A called procedure cannot distinguish between a parameter that is passed conditionally and one that is passed unconditionally. The execution time is shorter, however, when you pass or omit a parameter unconditionally. To make your code portable to future software platforms, use $OPTIONAL for each optional parameter when calling a VARIABLE or EXTENSIBLE procedure.
Using Procedures Comparing Procedures and Subprocedures Comparing Procedures and subprocedures are program units that can contain executable parts of Procedures and your program. A subprocedure is declared inside a procedure. A procedure can Subprocedures contain any number of subprocedures, but a subprocedure cannot contain another subprocedure. Neither procedures or subprocedures can contain another procedure.
Using Procedures Declaring and Calling Subprocedures Declaring and Calling To declare a subprocedure in its simplest form, specify: Subprocedures The keyword SUBPROC The identifier of the subprocedure, followed by a semicolon A subprocedure body—a BEGIN-END construct that can contain sublocal data declarations and statements The following example declares MY_SUBPROC within MY_PROC.
Using Procedures Declaring and Calling Subprocedures Sublocal Variables Because each subprocedure has only a 32-word storage area for variables, declare large arrays or structures at the global or local level and make them indirect.
Using Procedures Declaring and Calling Subprocedures Sublocal Storage Limitations Because sublocal storage area is so limited, the way you use sublocal variables is as important as how many you declare. When a subprocedure is activated, the compiler allocates the subprocedure's parameters, variables, and temporary results of expressions in the subprocedure’s private storage area.
Using Procedures Declaring and Calling Subprocedures Sublocal Parameter Storage Limitations The order in which a subprocedure passes parameters could result in a range violation error. The error occurs when an actual parameter of the subprocedure refers to a sublocal variable located beyond S[–31] in the caller’s sublocal storage area. The following example shows two subprocedure calls.
Using Procedures Declaring and Calling Subprocedures Figure 11-2. Sublocal Data Storage Limitations 1. At activation of SUB2: 2. First call to SUB1: 3.
Using Procedures Using Parameters Using Parameters This subsection gives additional information about declaring, passing, and allocating parameters of procedures and subprocedures. For portability to future software platforms, treat formal parameters as spatially unrelated in memory storage. Declaring Formal Parameters Table 11-3 summarizes the formal parameter characteristics you can declare depending on the kind of actual parameter your procedure expects. Table 11-3.
Using Procedures Using Parameters Value parameters are described next, followed by reference parameters. Using Value Parameters If a procedure or subprocedure declares a formal parameter as a value parameter, callers in effect pass a copy of the actual parameter. The called procedure or subprocedure can modify the parameter as if it were a local or sublocal variable but cannot modify the original variable in the caller’s scope.
Using Procedures Using Parameters STRING Value Parameters. Declare byte value parameters as INT simple variables where possible because: Passing STRING parameters by value is not portable to future software platforms. The system places an actual STRING value in the right byte of a word as if the value were an INT expression.
Using Procedures Using Parameters PROC Value Parameters. Specify a procedure as a formal PROC parameter if the actual parameter is the address of: A C small-memory-model routine A FORTRAN routine compiled with the NOEXTENDEDREF directive A TAL procedure or function procedure For each actual PROC parameter, the compiler allocates a word of storage in the parameter area of the called procedure. The actual PROC parameter is a 16-bit address that contains the PEP and map information of the passed procedure.
Using Procedures Using Parameters PROC(32) Value Parameters. Specify a procedure as a formal PROC(32) parameter if the actual parameter is the address of: A C large-memory-model routine A FORTRAN routine compiled with the EXTENDEDREF directive A Pascal routine For each actual PROC(32) parameter, the compiler allocates a doubleword of storage in the parameter area of the called procedure.
Using Procedures Using Parameters VARIABLE or EXTENSIBLE Procedures as Parameters. When you call a VARIABLE or EXTENSIBLE procedure declared as a formal parameter, include an actual parameter list as usual. For each omitted actual parameter, however, you must specify an empty comma for each word of the parameter. For example, to omit a FIXED parameter, specify four empty commas, one for each word of the omitted quadrupleword.
Using Procedures Using Parameters Addresses and Pointer Contents as Value Parameters You can pass the address of a variable or the content of a pointer as an actual value parameter. The called procedure can then assign the address to a pointer. In the actual parameter list, prefix the identifier of the variable or pointer with the @ operator: INT .EXT array1[0:9]; INT .EXT array2[0:9]; INT .EXT ptr := @array2[9]; PROC move1 (x, y); INT(32) x; INT(32) y; BEGIN INT .EXT xptr := x; INT .
Using Procedures Using Parameters Index Register Contents as Value Parameters When you call a procedure or subprocedure, you can pass the content of an index register as a value parameter. If the called procedure or subprocedure expects a reference parameter, the compiler issues a warning. When the compiler encounters the invocation, it saves the content of the index registers, evaluates actual parameters, and branches to the called procedure or subprocedure.
Using Procedures Using Parameters In the CALL statement, do not modify the content of an index register. If you do so, the index register contains the original (unmodified) content when control returns to the caller, and the compiler emits an error message.
Using Procedures Using Parameters Using Reference Parameters A reference parameter is a formal parameter for which the caller passes the address of a value. The called procedure can access and modify the original value in the caller’s scope. Except in the case of definition structures, you declare formal reference parameters as if they were simple pointers or structure pointers (by using an indirection symbol).
Using Procedures Using Parameters Arrays as Reference Parameters If a procedure expects an array as an actual parameter, declare the formal parameter as a simple pointer, preceding its identifier with an indirection symbol. The following example declares two formal reference parameters (for array elements) as simple pointers, one standard and the other extended: PROC new_proc (array1, array2, elements_to_move); INT .array1; !Declare simple pointers as formal INT .
Using Procedures Using Parameters The following example passes array bounds information: LITERAL array_lb = 0; LITERAL array_ub = 9; INT .array[array_lb:array_ub]; PROC zero (a, lb, ub); INT .a; INT lb; INT ub; BEGIN INT i; FOR i := lb TO ub DO a[i] := 0; END; PROC m MAIN; BEGIN CALL zero (array, array_lb, array_ub); END; !Pass lower and upper array bounds Structures as Reference Parameters Either definition structures or referral structures can be formal reference parameters.
Using Procedures Using Parameters Referral Structures as Parameters. When you declare a referral structure as a formal parameter, include an indirection symbol and a referral (enclosed in parentheses) that provides the structure layout. The referral can be the identifier of an existing structure or structure pointer. In the following example, STRUCT_A is the referral in the formal parameter declaration for REF_STRUCT: STRUCT .
Using Procedures Using Parameters Pointer Content as Reference Parameters To pass the content of a pointer, prefix the pointer identifier with @ in the actual parameter list. The called procedure can then change the pointer content in the caller. An example is: INT .array1[0:99]; INT .array2[0:99]; PROC proc1 (wptr); INT .wptr; BEGIN wptr := @array2[0]; END; !Declare ARRAY1 !Declare ARRAY2 !Declare WPTR (formal parameter) !Assign address of ARRAY2[0] to WPTR PROC proc2 MAIN; BEGIN INT .
Using Procedures Using Parameters Here is another example that shows the need to store addresses in pointers before passing them as reference parameters: STRUCT t (*); BEGIN INT i; !More structure items END; STRUCT .x (t); STRING .a (t); !or INT .a (t); !or STRING .EXT a (t); !or INT .EXT a (t); PROC p (f); STRUCT .f (t); !or STRUCT .EXT f(t); !or STRING .f (t); !or STRING .EXT f (t); !or INT .f (t); !or INT .EXT f (t); BEGIN f.
Using Procedures Using Parameters Reference Parameter Address Conversions When you pass a reference parameter, its addressing mode should match that of the formal parameter. If not, the compiler converts the addressing mode of the actual parameter to match that of the formal parameter. When converting an address, the compiler assumes that a STRING pointer contains a byte address and that a pointer of any other type contains a word address. In some conversions, part of the address is lost.
Using Procedures Using Parameters Procedure Parameter Area The system creates a private parameter area for each activation of a procedure. Before control passes to the called procedure, the system stores any actual parameter values in the private parameter area. For each activation of a procedure, the parameter area provides storage for: Up to 32 named parameters with no limit on the number of words of parameters. (The compiler generates code for accessing parameter words beyond L-31.
Using Procedures Using Parameters If the same identifier appears at the global, local, and sublocal levels, however, local statements cannot access the global identifier, and sublocal statements cannot access the local or global identifier: INT a := 4; INT b := 1; PROC p (a, b); INT a; INT b; BEGIN INT c; SUBPROC sub2 (b); INT b; BEGIN c := b + 5; END; a := a + b; CALL sub2 (a); END; 096254 Tandem Computers Incorporated !Declare global variables A and B !Declare local formal parameters ! A and B !Declar
Using Procedures Parameter Masks Parameter Masks When a procedure calls a VARIABLE or EXTENSIBLE procedure, the compiler provides a parameter mask and keeps track of which actual parameters are passed to the procedure. When a procedure calls a VARIABLE or EXTENSIBLE procedure that is declared as a formal parameter, however, the compiler does not provide a parameter mask. The caller must provide the parameter mask as part of the CALL statement.
Using Procedures Parameter Masks VARIABLE Word Parameter Mask If a VARIABLE procedure has 16 or fewer formal parameters, the compiler generates a one-word mask. It associates each formal parameter with a bit in the mask, right justifying the layout so the last parameter corresponds to bit <15>. In the following example, PROC_A has six formal parameters. Procedure A_CALLER calls PROC_A and passes three actual parameters to it.
Using Procedures Parameter Masks VARIABLE Parameter Area Figure 11-4 shows the parameter area of PROC_A when called by A_CALLER in the preceding example. The figure shows: Storage allocation for the formal parameters P1 through P6 of PROC_A Storage of actual parameters X, Y, and Z passed by A_CALLER Storage of the parameter mask of PROC_A. The value of the parameter mask (%000032) represents the bit settings for the actual parameters (shown in Figure 11-3 earlier in this section). Figure 11-4.
Using Procedures Parameter Masks VARIABLE Doubleword Parameter Mask If a VARIABLE procedure has more than 16 parameters, the compiler generates a doubleword mask. It allocates the high-order word of the mask in location L[–4] and the low-order word of the mask in location L[–3]. The compiler associates each formal parameter with a bit in the mask, right-justifying the layout so the last formal parameter corresponds to bit <15> of the low-order word.
Using Procedures Parameter Masks EXTENSIBLE Parameter Masks When a procedure calls an EXTENSIBLE procedure, the compiler provides a parameter mask and keeps track of which actual parameters are passed to the procedure. The format of the EXTENSIBLE parameter mask differs from the format of the VARIABLE parameter mask. When an EXTENSIBLE procedure is called, the compiler: 1. Allocates storage for each formal parameter in the called procedure’s parameter area 2.
Using Procedures Parameter Masks EXTENSIBLE Word Parameter Mask If an EXTENSIBLE procedure has 16 or fewer parameter words, the compiler generates a one-word mask. The compiler associates each word in each formal parameter with a bit in the parameter mask, left justifying the layout so the first parameter word corresponds to bit <0>. In the following example, PROC_C has seven formal parameters of varying lengths.
Using Procedures Parameter Masks EXTENSIBLE Doubleword Parameter Mask If an EXTENSIBLE procedure has more than 16 (but less than 33) parameter words, the compiler generates a doubleword mask. It associates each word of each formal parameter with a bit in the mask, left justifying the layout so the first parameter word corresponds to bit <0> of the low-order word. In the following example, PROC_D has 12 formal parameters of varying lengths.
Using Procedures Parameter Masks EXTENSIBLE Parameter Area Figure 11-8 shows the parameter area of PROC_D when PROC_D is called by D_CALLER in the preceding example.
Using Procedures Parameter Masks Figure 11-8.
Using Procedures Parameter Masks Procedure Entry Sequence When an EXTENSIBLE procedure is activated, the procedure’s entry code loads certain values onto the register stack. Table 11-7 shows: The values that the entry code loads onto the register stack The RP setting that results Table 11-7.
Using Procedures Using Labels Using Labels Within a procedure, you can declare labels for use within the same procedure. Labels have local or sublocal scope only. Labels are the only declarable objects that you need not declare before using them. For best program management, however, declare all labels. Using Local Labels To declare and use local labels: 1.
Using Procedures Using Labels In the following example, sublocal GOTO statements reference local labels in the encompassing procedure.
Using Procedures Using Labels Using Sublocal Labels To declare and use sublocal labels: 1. Declare the label identifier inside a subprocedure in the sublocal declarations; for example: LABEL sub_label; 2. Place the label identifier and a colon (:) preceding a statement in the same subprocedure: sub_label: a := 5; 3. !Declare SUB_LABEL !Use the label for ! this statement Reference the label in a GOTO statement located in the same subprocedure.
Using Procedures Using Labels Using Undeclared Labels You need not declare labels before using them; however, if a variable and an undeclared label in the same scope have the same identifier and if you use the label before you access the variable, the compiler issues an error message.
Using Procedures Getting Addresses of Procedures and Subprocedures Getting Addresses of To get the address of a procedure or subprocedure, prefix its identifier with @.
12 Controlling Program Flow Conditional statements let you provide a choice of paths in your program. These statements contain a condition, which lets the program select which path to take during execution. Some statements can also be executed repeatedly, applying a set of operations to different data during each iteration. A group of statements that can be executed repeatedly is called a loop.
Controlling Program Flow IF Statement IF Statement The IF statement conditionally selects one of two statements. The IF statement tests the condition before selecting a statement. If the condition is true, the THEN clause executes. If the condition is false, the ELSE clause executes, if present. To specify an IF statement, include: IF condition Specifies a condition that, if true, causes the THEN clause to execute. If false, the condition causes the ELSE clause to execute.
Controlling Program Flow IF Statement IF Statement Execution The IF-THEN form executes as shown in Figure 12-1. Figure 12-1. IF-THEN Execution IF condition THEN statement TRUE FALSE ; next-statement 404 The IF-THEN-ELSE form executes as shown in Figure 12-2. Figure 12-2.
Controlling Program Flow IF Statement IF-ELSE Pairing You can nest IF statements to any level. In a nested IF statement, the innermost IF clause pairs with the closest ELSE clause. Formatting can make the IF-ELSE pairing obvious or ambiguous. The following side-by-side examples are equivalent.
Controlling Program Flow CASE Statement, Labeled CASE Statement, A labeled CASE statement consists of a selector and a series of case alternatives. Each Labeled alternative associates one or more case labels with a set of statements. When the selector matches a case label, the associated set of statements executes. The unlabeled CASE statement is described in the TAL Reference Manual.
Controlling Program Flow CASE Statement, Labeled For example, this labeled CASE statement has four case-alternatives and the OTHERWISE clause: INT location; LITERAL bay_area, los_angeles, hawaii, elsewhere; PROC area_proc (area_code); INT area_code; BEGIN CASE area_code OF BEGIN 408, 415 -> location := bay_area; 213, 818 -> location := los_angeles; 808 -> location := hawaii; OTHERWISE -> location := elsewhere; END; END; Statement Forms Generated by the Compiler !Declare procedure !Declare selector as ! fo
Controlling Program Flow CASE Statement, Labeled Directives and CASE Statements If a CASE statement contains many GOTO statements, you can use the OPTIMIZE directive to reduce the size of the object code. Use OPTIMIZE level 1 or 2 as follows: In a program under development, use level 1. In a stable program, use level 2, which optimizes code across statement boundaries, so debugging is more difficult. The CHECK directive does not affect the labeled CASE statement (as it does the unlabeled CASE statement).
Controlling Program Flow WHILE Statement WHILE Statement The WHILE statement is a repeating loop that executes a statement while a specified condition is true. To specify a WHILE statement, include: WHILE condition Specifies a condition that, if true, causes the loop to execute. If the condition is false, the loop does not execute. The condition can be either: A conditional expression An INT arithmetic expression. If the result of the arithmetic expression is not 0, the condition is true.
Controlling Program Flow WHILE Statement This WHILE loop increments INDEX until a nonalphabetic character occurs: LITERAL len = 255; STRING .array[0:len - 1]; INT index := -1; WHILE (index < len - 1) AND ($ALPHA(array[index := index + 1])) DO ... ; Figure 12-4 shows the action of the WHILE statement. Figure 12-4.
Controlling Program Flow DO Statement DO Statement The DO statement is a repeating loop that executes a statement until a specified condition becomes true. If the condition is always false, the loop repeats until a statement in the DO loop causes an exit. To specify a DO statement, include: DO statement Specifies a statement to execute until the condition becomes true. The statement can be any TAL statement. UNTIL condition Specifies a condition that, if false, causes the DO loop to continue.
Controlling Program Flow DO Statement Figure 12-5.
Controlling Program Flow FOR Statement FOR Statement The FOR statement is a repeating loop that executes a statement while incrementing or decrementing an index automatically. The loop terminates when the index reaches a limit value. If the index is greater than the limit on the first test, the loop never executes. To specify a FOR statement, include: FOR index := Specifies a value that increments or decrements automatically until it reaches a specified value and terminates the loop.
Controlling Program Flow FOR Statement This standard FOR loop uses the DOWNTO clause to reverse a string from "BAT" to "TAB": LITERAL len = 3; LITERAL limit = len - 1; STRING .normal_str[0:limit] := "BAT"; STRING .reversed_str[0:limit]; INT index; FOR index := limit DOWNTO 0 DO reversed_str[limit - index] := normal_str[index]; Nesting FOR Loops You can nest FOR loops to any level. The following nested FOR loop treats MULTIPLES as a two-dimensional array.
Controlling Program Flow FOR Statement Standard FOR Loop Execution Figure 12-6 shows the action of the standard FOR loop. Figure 12-6.
Controlling Program Flow FOR Statement Optimized FOR Loops For index, optimized FOR loops specify a register reserved by a USE statement. Optimized FOR loops execute faster than standard FOR loops; they execute as follows: When the looping terminates, index is equal to limit. limit is calculated only once, at the start of the first iteration of the loop. You optimize a FOR loop as follows: 1. Before the FOR statement, specify a USE statement to reserve an index register. 2.
Controlling Program Flow FOR Statement Optimized FOR Loop Execution The execution of optimized FOR loops differs from standard FOR loops as follows: When the looping terminates, index is equal to limit. limit is calculated only once—at the start of the first time through the loop.
Controlling Program Flow ASSERT Statement ASSERT Statement The ASSERT statement conditionally invokes the procedure named in an ASSERTION directive. It is a debugging or error-handling tool. To specify the ASSERT statement, include: ASSERT assert-level Specifies an integer in the range 0 through 32,767, followed by a colon.
Controlling Program Flow ASSERT Statement The following example activates PROCESS_DEBUG_ when an out-of-range condition occurs: ?SOURCE $SYSTEM.SYSTEM.
Controlling Program Flow CALL Statement CALL Statement You use the CALL statement to call a procedure, subprocedure, or entry-point identifier, and optionally pass parameters to it. To specify a CALL statement, you can include: CALL identifier Specifies the identifier of a procedure, subprocedure, or entry-point identifier. As of the D20 release, the CALL keyword is optional.
Controlling Program Flow CALL Statement Omitting Parameters Conditionally To omit a parameter or parameter pair conditionally, use the $OPTIONAL standard function (D20 release or later) as described in Section 11, “Using Procedures.” Calling Functions Calling Procedures Declared as Formal Parameters Passing Parameter Pairs 12–20 Callers usually invoke functions by using the function identifier in expressions, as described in Section 11, “Using Procedures.
Controlling Program Flow RETURN Statement RETURN Statement The RETURN statement returns control to the caller. If the invoked procedure or subprocedure is a function, RETURN must return a result. As of the D20 release, RETURN can also return a program-specified condition code (CC). The form of the RETURN statement depends on whether the return is from a function or from a procedure or subprocedure that is not a function.
Controlling Program Flow RETURN Statement Returning a Condition Code As of the D20 release, if result-expression is any type except FIXED or REAL(64), a function can return a cc-expression and a result-expression. cc-expression is an INT expression whose numeric value specifies the condition code value to return to the caller.
Controlling Program Flow RETURN Statement The following procedure returns a condition code that indicates whether an add operation overflows: PROC p (s, x, y); INT .s, x, y; BEGIN INT cc_result; INT i; i := x + y; IF $OVERFLOW THEN cc_result := 1 ELSE cc_result := 0; s := i; RETURN , cc_result; END; Returning From Nonfunction Procedures !If overflow, condition code ! is >; otherwise, it is = In procedures and subprocedures that are not functions, a RETURN statement is optional.
Controlling Program Flow GOTO Statement GOTO Statement The GOTO statement unconditionally transfers program control to the statement that is preceded by the specified label. To specify a GOTO statement, include a label identifier after the GOTO keyword; for example: GOTO label_one; Local Scope A local GOTO statement can refer only to a local label in the same procedure. A local GOTO statement cannot refer to a label in a subprocedure or in any other procedure.
Controlling Program Flow GOTO Statement Usage Guidelines GOTO statements can make a program harder to understand and maintain, but they are useful when you need to: Branch to a common exit or common error-handling code after some condition is met Exit from the middle of a multidimensional search or loop after some condition is met Maximize program performance For most other circumstances, use conditional control statements such as labeled CASE, DO, IF, and WHILE.
13 Using Special Expressions Special expressions let you perform specialized arithmetic or conditional operations. This section describes the special expressions listed in Table 13-1. Table 13-1.
Using Special Expressions Assignment Expression Assignment The assignment expression assigns the value of an expression to a variable. Expression To use an assignment expression, specify: The identifier of a variable An assignment operator (:=) An expression that represents a value of the same data type as the variable. The result of the expression becomes the result of the assignment expression.
Using Special Expressions CASE Expression CASE Expression The CASE expression selects one of several expressions. You can nest CASE expressions. To use a CASE expression, specify: CASE selector OF Specifies an INT arithmetic expression that selects the expression to evaluate. BEGIN expressions; Specifies a choice of one or more expressions. Separate successive expressions with semicolons.
Using Special Expressions IF Expression IF Expression The IF expression conditionally selects one of two expressions, usually for assignment to a variable. To use an IF expression, specify: IF condition Specifies a condition that, if true, causes the result of the THEN expression to become the result of the overall IF expression. If the condition is false, the result of the ELSE expression becomes the result of the overall IF expression.
Using Special Expressions Group Comparison Expression Group Comparison The group comparison expression compares a variable with another variable or with a Expression constant. In general, to use a group comparison expression, specify these items: A variable (var1) with or without an index var1 can be a simple variable, array, simple pointer, structure, structure data item, or structure pointer, but not a read-only array. A relational operator.
Using Special Expressions Group Comparison Expression Comparing a Variable to a Variable To compare a variable to another variable, include the FOR clause in the group comparison expression. In the FOR clause, specify a count value—a positive INT arithmetic expression that specifies the number of bytes, words, or elements you want to compare.
Using Special Expressions Group Comparison Expression Comparing Elements When you compare elements between arrays, you can specify the ELEMENTS keyword following the count value in the FOR clause of the group comparison expression. For example, you can compare doubleword elements between INT(32) arrays: INT(32) in_array[0:19]; INT(32) out_array[0:19]; !Code to assign values to arrays IF in_array <> out_array FOR 20 ELEMENTS THEN ...
Using Special Expressions Group Comparison Expression The compiler does a standard comparison and returns a 16-bit next address if: Both var1 and var2 have standard byte addresses Both var1 and var2 have standard word addresses The compiler does an extended comparison (which is slightly less efficient) and returns a 32-bit next address if: Either var1 or var2 has a standard byte address and the other has a standard word address Either var1 or var2 has an extended address Variables (including structure data
Using Special Expressions Group Comparison Expression Testing the Condition Code Setting The system treats the items being compared as unsigned values.
14 Compiling Programs When you run the TAL compiler, the input is a source file—a file that contains TAL source text such as data declarations, statements, compiler directives, and comments. The output from a compilation is an executable or bindable object file that consists of relocatable code and data blocks. You can bind object files with other object files into a new executable or bindable object file.
Compiling Programs Compiling Source files Compiling Figure 14-1 shows the source file as input to the compiler and the object file as output Source Files from the compiler. Figure 14-1. Compiling a Source File Into an Object File Source file TAL compiler Object file 410 The source file can include SOURCE directives that read in code from other source files. In effect, you can compile more than one source file into an object file, but the input to the compiler is always a single source file.
Compiling Programs Compiling Source files In an unstructured disk file, each record has 132 characters; partial lines are filled with blanks through column 132. You can specify a file name or a TACL DEFINE name. The file must exist before you specify its name for the OUT file. You can create the file by using the File Utility Program (FUP). The following example specifies a file named MYLIST as the OUT file: TAL /IN mysource, OUT mylist/ myobject The OUT file is often a spooler location, in this case, $S.
Compiling Programs Compiling Source files Target File Option The target file is the disk file that is to receive the object code. You can specify a file name or a TACL DEFINE name as described in Appendix E. Previous examples sent the object code to a disk file named MYOBJECT: TAL /IN mysource/ myobject If you omit the target file, BINSERV creates a file named OBJECT on your current default subvolume.
Compiling Programs Binding Object Files Completion Codes Returned by the Compiler When the compiler compiles a source file, it either completes the compilation normally or stops abnormally. It then returns a process-completion code to the TACL product indicating the status of the compilation. Table 14-1 explains the process-completion code values. Table 14-1.
Compiling Programs Binding Object Files Binding can take place: During a compilation session After a compilation session At run time (library binding) Binding During Compilation During compilation, BINSERV constructs a master search list of object files from SEARCH directives in the source file. After a successful compilation, BINSERV binds into the new object file any procedures from object files listed in the master search list that resolve external references.
Compiling Programs Using Directives in the Source File Using Directives Compiler directives let you: in the Source File Specify input source code Control listings, generate the object code, and build the object file Perform conditional compilation A directive line in your source file can contain any number of compiler directives. You must start each new directive line and any continuation lines with a question mark (?) in column 1.
Compiling Programs Using Directive Stacks Using Directive Stacks Several directives have a compile-time directive stack on which you can push and pop directive settings. Directives that have directive stacks are: CHECK CODE DEFEXPAND ICODE INNERLIST INT32INDEX LIST MAP Each directive stack is 32 levels deep. The compiler initially sets all levels of each directive stack to the off state.
Compiling Programs File Names as Directive Arguments File Names as The following directives accept names of disk files as arguments: Directive Arguments ERRORFILE LIBRARY SAVEGLOBALS SEARCH SOURCE USEGLOBALS A disk file name consists of four parts, with each part separated by periods: A D-series node name or a C-series system name A volume name A subvolume name A file ID Here is an example of a file name: \mynode.$myvol.mysubvol.
Compiling Programs Compiling With Source Directives Compiling With You can specify a SOURCE directive in a source file to read in source code from other SOURCE Directives source files. In the SOURCE directive, specify the source file name, followed by an optional list of one or more section names enclosed in parentheses. If you omit the list of section names, the compiler reads in the entire file.
Compiling Programs Compiling With Source Directives Including System Procedure Declarations You can use SOURCE directives to read in external declarations of system procedures from the EXTDECS files. In these files, the procedure name and the corresponding section name are the same. EXTDECS0 contains the current release version of system procedures, for example, the D20 version. In the following D-series example, a SOURCE directive specifies the current version of system procedures.
Compiling Programs Compiling With Search Lists Compiling With You can share data and procedures between object files by specifying search lists of Search Lists object file names for resolving unsatisfied external references and validating parameter lists at the end of the compilation session.
Compiling Programs Compiling With Search Lists Searching the Master Search List BINSERV searches the object files in the order in which they appear in the master search list. If a procedure or entry-point name that resolves an external reference appears in more than one file, BINSERV uses only the first occurrence. Thus, the order in which you specify the files could be important.
Compiling Programs Compiling With Relocatable Data Blocks Compiling With When you compile modules of a program separately or bind TAL code with code Relocatable Data written in other languages, the binding process might relocate some of your global Blocks data. All global data to be shared with compilation units written in other languages must be relocatable. Declaring Relocatable Global Data You can declare blocked and unblocked relocatable global data (variables, LITERALs, and DEFINEs).
Compiling Programs Compiling With Relocatable Data Blocks As of the D20 release, a variable declared in a named data block can have the same name as the data block. Modules written in TAL can share global variables with modules written in C by placing each shared variable in its own block and giving the variable and the block the same name.
Compiling Programs Compiling With Relocatable Data Blocks Declaring Unblocked Data Place all unblocked global declarations (those not contained in BLOCK declarations) before the first BLOCK declaration. Unblocked declarations are relocatable and shareable among all compilation units in a program. Here is an example of unblocked data declarations: INT a; INT .b[0:9]; INT .EXT c[0:14]; LITERAL limit = 32; The compiler places unblocked data declarations in implicit primary data blocks.
Compiling Programs Compiling With Relocatable Data Blocks Primary Relocatable Data Blocks The compiler creates and names primary data blocks as follows: Primary Block Compiler-Assigned Name Implicit Implicit Named Private #GLOBAL &template-name (for each unblocked template structure) The identifier specified in the BLOCK declaration The identifier specified in the NAME declaration The compiler allocates the following variables in primary data blocks: Directly addressed variables Standard or extended po
Compiling Programs Compiling With Relocatable Data Blocks Example of Data Blocks Created by the Compiler Table 14-2 shows the primary, secondary, and extended data blocks the compiler creates from the example global data declarations, including the names (shown in boldface) that the compiler gives them. Table 14-2.
Compiling Programs Compiling With Relocatable Data Blocks Allocation Example Figure 14-3 shows the global storage allocation resulting from binding object files that contain BLOCK declarations. You can rearrange the primary block by using Binder commands. Secondary blocks must always follow the primary blocks. Figure 14-3. Allocating Global Data Blocks Global primary area User data segment Extended data segment #GLOBAL $#GLOBAL Named blocks Named blocks Private block Private block .
Compiling Programs Compiling With Relocatable Data Blocks Sharing Global Data Blocks Because the length of any shared data block must match in all compilation units, it is recommended that you declare all shareable global data in one source file. You can then share that global data block with other source files as follows: 1. In the source file that declares the data block, specify the SECTION directive at the beginning of the data block to assign a section name to the data block.
Compiling Programs Compiling With Relocatable Data Blocks Directives for Relocatable Data The RELOCATE and INHIBITXX directives help you make sure that your global data is relocatable. These directives do not affect local and sublocal variables. RELOCATE Directive RELOCATE instructs the compiler and BINSERV to issue warnings if references to nonrelocatable data occur. RELOCATE can appear anywhere on the compilation command or in the source file. It is effective for the source code that follows it.
Compiling Programs Compiling With Relocatable Data Blocks Specify INHIBITXX or NOINHIBITXX immediately before the global declarations to which it applies. The specified directive then applies to those declarations throughout the compilation. The following example shows how NOINHIBITXX generates efficient addressing, while INHIBITXX suppresses efficient addressing: !Default NOINHIBITXX in effect; assign NOINHIBITXX ! attribute to subsequent declaration. STRUCT .
Compiling Programs Compiling With Saved Global Data Compiling With During program development or maintenance, you often need to change procedural Saved Global Data code or data without changing the global declarations. You can save the global data in a file during a compilation session and then use the saved global data during a subsequent compilation. You can shorten the compile time by not compiling global declarations each time.
Compiling Programs Compiling With Saved Global Data Saved Global Data Compilation Session The following session shows how you can save and retrieve global data. It also shows how you can check the syntax of global data declarations and how to save and retrieve such declarations. Creating the Source File Using an editor, you can create a source file, such as MYPROG, that includes BEGINCOMPILATION and USEGLOBALS.
Compiling Programs Compiling With Saved Global Data Checking the Syntax of Global Data The following compilation command compiles source file MYPROG but produces no object file. The SAVEGLOBALS directive saves global declarations in file TALSYM.
Compiling Programs Compiling With Cross-References Compiling With The CROSSREF directive either: Cross-References Collects source-level cross-reference information produced during compilation Selects the identifier classes for which you want to collect cross-references The default is NOCROSSREF. You can specify CROSSREF or NOCROSSREF in the compilation command or any number of times anywhere in the source file.
Compiling Programs Compiling With Cross-References You add or delete classes from the current class list as follows. When you list more than one class, enclose the list in parentheses. To add classes to the current list, specify CROSSREF and list the classes you want to add. The following example adds the one missing class to the default list: ?CROSSREF UNREF To delete classes from the current list, specify NOCROSSREF and list the classes you want to delete.
Compiling Programs Compiling With Cross-References You can add and delete classes when you start the collection: ?CROSSREF, CROSSREF UNREF, NOCROSSREF VARIABLES !Start collecting cross-references and ! change the class list NAME test; INT i; ?NOCROSSREF BLOCK PRIVATE; INT j; END BLOCK; !Stop cross-references for BLOCK ?CROSSREF, CROSSREF VARIABLES !Start cross-references for procedure and ! add a class to the class list PROC p MAIN; BEGIN !Lots of code END; For other cross-reference options, use the stan
Compiling Programs Compiling With Cross-References The following example makes changes to the current class list and turns the collection or listing of cross-references on and off: !Default LIST and NOSUPPRESS are in effect ?CROSSREF, CROSSREF UNREF, NOCROSSREF VARIABLES !Collect (and list) cross-references NAME test; INT i; ?NOCROSSREF BLOCK PRIVATE; INT j; END BLOCK; !Stop collecting cross-references ?CROSSREF, CROSSREF VARIABLES !Resume collecting (and listing) ! cross-references PROC p MAIN; BEGIN !L
15 Compiler Listing This section describes the TAL listing and gives brief samples of the information.
Compiler Listing Banner Banner The first page of the listing contains a banner, which consists of two lines that list the compiler version and the copyright notice. Figure 15-2 shows a sample banner. Figure 15-2. Sample Banner TAL - T9250D20 - (01JUN93) Copyright Tandem Computers Incorporated 1976, 1978, 1981-1983, 1985, 1987-1993 Directives in The line following the banner shows the directives you specified in the compilation Compilation command to run the compiler.
Compiler Listing Source Listing Source Listing If the LIST directive is in effect (the default), the source text is listed line by line. Each line consists of: The edit-file line number The code-address field The lexical (nesting) level of the source text The BEGIN-END pair counter A text line from the source file For example, here are two lines from a source listing: 31. 32.
Compiler Listing Source Listing If the ABSLIST directive is in effect, the compiler attempts to list the address for each line relative to location C[0]. The limitations on the use of ABSLIST are given in the directive description in the TAL Reference Manual. Lexical-Level Counter BEGIN-END Pair Counter The lexical-level counter is a single-digit value that represents the compiler’s interpretation of the current source line.
Compiler Listing Source Listing Figure 15-3. Source Listing 2. 3. 4. Source 1. 2. 3. 4. 5. 6. 7. 5. Source 24. 25. 26. 27. 28. 31. 32. 33. 34. 37. 38. 39. Conditional Compilation Listing ?ICODE, SYMBOLS, SAVEABEND, INSPECT 000000 0 0 NAME mymodule; 000000 0 0 000000 0 0 ?SOURCE outd file: [2] $VOL.PROG1.
Compiler Listing Local or Sublocal Map Local or Sublocal Map If the MAP and LIST directives are in effect (the defaults), a map of local or sublocal identifiers follows the corresponding source listing and gives information on the identifier class of an object, its variable type, and addressing. Table 15-1 lists the column headings and possible values. Only one of the columns named Addressing Mode, Offset, or Value appears in the map. Table 15-1.
Compiler Listing INNERLIST Listing Figure 15-4 shows a local map that corresponds to the following hash procedure: INT PROC compute_hash (name, table_len); INT .name; INT(32) table_len; BEGIN INT int_table_len := $INT (table_len); INT hash_val := 0; USE name_index; USE name_limit; name_limit := name.<8:14>; FOR name_index := 0 TO name_limit DO hash_val := ((hash_val '<<' 3) LOR hash_val.
Compiler Listing INNERLIST Listing Figure 15-5. INNERLIST Listing ?INNERLIST 1 000000 0 0 INT PROC compute_hash (name, table_len); 2 000000 1 0 INT .name; 3 000000 1 0 INT(32) table_len; 4 000000 1 0 BEGIN 5 000000 1 1 INT int_table_len := $INT (table_len); 6 000000 1 1 INT hash_val := 0; 7 000000 1 1 USE name_index; 000000 1 LDD L-004 000001 0 STAR 0 000002 1 LDI +000 000003 7 PUSH 711 8 000004 1 1 USE name_limit; 9 000004 1 1 10 000004 1 1 name_limit := name.
Compiler Listing Global Map CODE Listing If the CODE and LIST directives (the defaults) are in effect, the compiler produces an octal code listing following the local map if one exists. Figure 15-6 shows a sample CODE listing that corresponds to the previous hash procedure. The octal address in the leftmost column is the offset from the procedure base. (If ABSLIST is in effect, the compiler attempts to list addresses relative to the code segment.
Compiler Listing File Name Map Figure 15-8.
Compiler Listing Cross-Reference Listings Cross-Reference Listings To collect cross-reference information, specify the CROSSREF directive without parameters. If LIST and NOSUPPRESS (the defaults) are in effect at the end of the source file, the cross-reference listings follow the global map.
Compiler Listing Cross-Reference Listings The qualifier field varies according to the following rules: If an identifier has no qualifier, it is a global item. GLOBAL_X If an identifier has one qualifier, it is declared in a global structure or in a procedure. ITEM_A OF GLOB_STRUCT_OR_PROC If an identifier has two qualifiers, it is declared in either a structure or subprocedure within a procedure.
Compiler Listing LMAP Listings Host Source File The abbreviated edit-file name of the host source file appears on the same line as the identifier name. The sequence number assigned to the source file appears in brackets. The line number where the declaration starts accompanies the file name. An example is: SOURCE1S[23] 137 Reference Lines Reference lines include an entry for each reference in the compilation.
Compiler Listing LMAP Listings Entry-Point Load Map The entry-point load map gives information about each procedure entry point. Table 15-3 describes the information in each column of the map. Table 15-3.
Compiler Listing LMAP Listings Table 15-4 describes the information that the data-block load map and the read-only data-block load map give for each data block. Table 15-4.
Compiler Listing Compilation Statistics Compilation Statistics The compiler prints compilation statistics at the end of each compilation. If the SYNTAX directive is in effect or if source errors occur, the compiler does not print any other statistics. Figure 15-15 shows the statistics emitted when source errors stop the compilation. Figure 15-15.
Compiler Listing Compilation Statistics Figure 15-16 shows sample BINSERV statistics. Figure 15-16. Object-File Statistics PAGE 91 \SYS.$VOL.SUBV.SRC [1] BINDER AND COMPILER STATISTICS BINDER - OBJECT FILE BINDER - T9621D20 - (01JUN93) Copyright Tandem Computers Incorporated 1982-1993 SYSTEM \X Object file name is $XVOL.XSUBVOL.
16 Running and Debugging Programs Running Programs After the compiler produces an executable object file for your program, you can run the program by using the TACL RUN command. This command is summarized here and described fully in the TACL Reference Manual. In the RUN command, specify the name of an executable object file and run options if any.
Running and Debugging Programs Running Programs MEM Pages Option You can use the MEM (memory) option in the RUN command to increase the number of memory pages for your program’s data. For the MEM value, specify an integer in the range 1 through 64. For example, you can specify 40 memory pages in the RUN command: RUN myprog /MEM 40/ If you omit the MEM option or if the MEM value is less than the compile-time or bindtime memory-pages value (described next), the system uses the larger value.
Running and Debugging Programs Running Programs Passing Run-Time Parameters You can pass parameters to a program at run time in the RUN command. The syntax and meaning of the parameters are dictated by the program. For example, you can run the program AVERAGE and pass five parameters to the program as follows: RUN average 8 99 571 28 5 You can group several words into a single parameter by enclosing them in quotation marks; for example: RUN mystery "The butler did it.
Running and Debugging Programs Debugging Programs Debugging Programs You can use the Inspect or Debug product to debug your program. Debug is the default debugger on the system; however, it displays values only by machine address and only in octal or ASCII base. For symbolic debugging, you can use the Inspect product. Using the Inspect Product In high-level Inspect mode, you can display values by variable name or statement number. In low-level Inspect mode, you can display values by machine address.
Running and Debugging Programs Debugging Programs Setting Breakpoints A breakpoint is a location within your program at which to suspend execution so you can use Inspect commands to check results at that point. Usually, you request at least one breakpoint at the Inspect prompt before the first instruction in your program executes. For example, you can set an unconditional breakpoint at a statement or at an edit line number.
Running and Debugging Programs Debugging Programs Sample Inspect Session This discussion presents a source file and shows the steps for running the object file in an Inspect session. Sample Source File The sample source file is named MYSRC. Figure 16-1 shows the source code in the sample source file. Figure 16-1. Sample Source File !This is a source file named MYSRC. ?INSPECT ?SYMBOLS !Request symbolic debugger !Save symbols in object file ! for symbolic debugger ?NOLIST, SOURCE $system.system.
Running and Debugging Programs Debugging Programs Compiling the Sample Source File To compile the sample source file into an object file, specify the source file name (MYSRC) and an object file name (MYPROG): TAL /IN mysrc/ myprog Figure 16-2 shows the beginning of the compiler listing for the sample object file. Figure 16-2. Sample Compiler Listing PAGE 1 [1] $MYVOL.MYSUBV.MYSRC TAL - T9250D20 - (01JUN93) Copyright Tandem Computers Incorporated 1976, 1978, 1981–1983, 1985, 1987–1993 1. 2. 3. 4. 5. 6. 7.
Running and Debugging Programs Debugging Programs Running a Sample Inspect Session The step numbers in the following Inspect session correspond to the interactive operations shown in Figure 16-3. In the figure, commands you enter are shown in boldface. 1. To run your program in an Inspect session, enter the TACL RUND command at the TACL prompt. Specify the name of your object file and any appropriate run options.
Running and Debugging Programs Debugging Programs Figure 16-3. Running a Sample Inspect Session 1. 25> RUND myprog INSPECT - Symbolic Debugger - T9673D20 - (01JUN93) . . . Copyright Tandem Computers Incorporated 1983, 1985-1993 INSPECT *175,08,111 MYPROG #MYPROC.#6(MYSRC) 2. -MYPROG-BREAK #21 Num Type 1 Code Subtype Location #MYPROC.#21(MYSRC) 3. -MYPROG-RESUME INSPECT BREAKPOINT 1: #21 175,08,111 MYPROG #MYPROC.#21(MYSRC) 4. -MYPROG-DISPLAY total TOTAL = 15 5.
17 Mixed-Language Programming This section gives an overview of: Mixed-language features provided by TAL TAL and C guidelines CRE guidelines for TAL programs Mixed-Language Features of TAL NAME and BLOCK Declarations You can use the following TAL features in mixed-language programs: NAME and BLOCK declarations Procedure declaration LANGUAGE attribute Procedure declaration public name PROC and PROC(32) parameter types Parameter pairs ENV directive HEAP directive All global data to be shared with routines
Mixed-Language Programming Mixed-Language Features of TAL You can specify the location of a named or private data block. For more information, see Section 14, “Compiling Programs.” LANGUAGE Attribute Before calling an external routine, a TAL module must include an EXTERNAL procedure declaration for the external routine. If you are using a D-series TAL compiler, you can use the LANGUAGE attribute in the declaration to specify that the external routine is a C, COBOL85, FORTRAN, or Pascal routine.
Mixed-Language Programming Mixed-Language Features of TAL Public Name Before calling an external routine, a D-series TAL module can include an EXTERNAL procedure declaration that specifies a public name for use in Binder. In particular, specify an external routine identifier as a public name when the identifier does not conform to TAL rules.
Mixed-Language Programming Mixed-Language Features of TAL PROC Parameter Type Specify a procedure as a formal PROC parameter in a TAL routine that expects one of the following actual parameters: A C small-memory-model routine A FORTRAN routine compiled with the NOEXTENDEDREF directive A TAL routine TAL Receiving PROC Parameters The following TAL routine declares a formal PROC parameter: PROC tal_proc (param_proc); PROC param_proc; BEGIN !Lots of code END; !Formal PROC parameter The following callers can
Mixed-Language Programming Mixed-Language Features of TAL PROC(32) Parameter Type Specify a procedure as a formal PROC(32) formal parameter in a TAL routine that expects one of the following actual parameters: A C large-memory-model routine A FORTRAN routine compiled with the EXTENDEDREF directive A Pascal routine TAL Receiving PROC(32) Parameters The following TAL routine declares a formal PROC(32) parameter:: PROC tal_proc (param_proc32); PROC(32) param_proc32; BEGIN !Lots of code END; !Formal PROC(32)
Mixed-Language Programming Mixed-Language Features of TAL Parameter Pairs A TAL parameter pair consists of two formal parameters (connected by a colon) that together describe a single data type to FORTRAN or Pascal routines. Some D-series system routines require that callers pass actual parameter pairs (as described in the Guardian Application Conversion Guide). Table 17-1 lists the parameter types in other languages that correspond to the TAL parameter pair. Table 17-1.
Mixed-Language Programming Mixed-Language Features of TAL Passing Parameter Pairs The calling routine can pass parameter pairs to the called routine in a CALL statement. For example, the calling routine can declare and pass a parameter pair to IN_PROCEDURE (declared in the preceding example) as follows: PROC caller; BEGIN LITERAL length = 5; STRING .
Mixed-Language Programming Mixed-Language Features of TAL In the following example, the caller passes a parameter pair and the current-length parameter to the procedure declared in the preceding example: PROC out_proc_caller; BEGIN INT cur_len; !Declare simple variable CUR_LEN LITERAL max_len = 20; STRING .
Mixed-Language Programming TAL and C Guidelines TAL and C Guidelines This subsection provides guidelines for writing programs composed of TAL and Tandem C modules.
Mixed-Language Programming TAL and C Guidelines Matching Data Types Use data types that are compatible between languages for: Shared global variables Formal or actual parameters Function return values Table 17-2 lists compatible TAL and C data types for each TAL addressing mode. Table 17-2.
Mixed-Language Programming TAL and C Guidelines Memory Models A C program can use the small-memory model or the large-memory model, depending on the amount of data storage required. The large-memory model is recommended and is the default setting. All examples in this subsection illustrate the large-memory model unless otherwise noted.
Mixed-Language Programming TAL and C Guidelines Calling C Routines From TAL Modules A TAL module must include an EXTERNAL procedure declaration for each C routine to be called. The following TAL code shows the EXTERNAL procedure declaration for C_FUNC and a routine that calls C_FUNC. ARRAY is declared with .EXT, because C_FUNC uses the large-memory model: TAL Code C Code INT status := 0; STRING .
Mixed-Language Programming TAL and C Guidelines Calling TAL Routines From C Modules A D-series C module has full access to the C run-time library even if the C module does not contain the MAIN routine. A C-series C module that does not contain the MAIN routine cannot fully access the C run-time library. When you code C modules that call TAL routines: Include an interface declaration for each TAL routine to be called. If a called TAL routine sets the condition code, include the talh header file.
Mixed-Language Programming TAL and C Guidelines This example shows a large-memory-model C module that calls a TAL routine: C Code #include nolist short arr[5]; /*stored in extended segment */ _tal void C_Name = "tal^name" (extptr short *); void func1 (short *xarr) { C_Name (xarr); printf ("xarr[2] after TAL = %d", xarr[2]); } main () { arr[4] = 8; func1 (arr); } TAL Code PROC tal^name (a); INT .
Mixed-Language Programming TAL and C Guidelines Sharing Data You can share global data in the user data segment between the following kinds of TAL and C modules: TAL modules that declare global variables having standard indirection (.) C small-memory-model modules You can share global data in the automatic extended data segment between the following kinds of TAL and C modules: TAL modules that declare global variables having extended indirection (.
Mixed-Language Programming TAL and C Guidelines C Code short *c_int_ptr; char *c_char_ptr; /* pointer to TAL data */ /* pointer to TAL data */ short INIT_C_PTRS (short *tal_intptr, char *tal_strptr) { /* called from TAL */ c_int_ptr = tal_intptr; c_char_ptr = tal_strptr; return 1; } /* Access the TAL arrays by using the pointers */ TAL Code STRUCT rec (*); BEGIN INT x; STRING tal_str_array[0:9]; END; INT .EXT tal_int_array[0:4]; STRUCT .
Mixed-Language Programming TAL and C Guidelines This example shows how to share C data with a TAL module. The C module passes the addresses of two C arrays to a TAL routine. The TAL routine assigns the array addresses to TAL pointers.
Mixed-Language Programming TAL and C Guidelines Sharing TAL Data With C Using BLOCK Declarations As of the D20 release, TAL modules can share global data with C modules by declaring each shared variable in its own BLOCK declaration and giving both the variable and the BLOCK the same name. The C modules must also declare each shared variable; the layout of the variable must match in both the TAL and C modules.
Mixed-Language Programming TAL and C Guidelines STRING and char Variables TAL STRING and C char simple variables each occupies one byte of a word. Following are STRING and char compatibility guidelines: Share variables of type TAL STRING and C char by using pointers.
Mixed-Language Programming TAL and C Guidelines The following are compatible arrays in TAL and C (large-memory model): TAL Code C Code INT .EXT robin[0:9]; INT(32) .EXT gull[0:14]; STRING .EXT grebe[0:9]; short robin [10]; long gull [15]; char grebe [10]; Structures All TAL and C structures begin on a word boundary. Following are guidelines for sharing TAL and C structures and passing them as parameters: Specify the same layout for corresponding TAL and C structures.
Mixed-Language Programming TAL and C Guidelines Substructures The TAL compiler allocates alignment of substructures on a byte or word boundary as follows: Each definition substructure occurrence is byte aligned if the first item it contains begins on a byte boundary. Each definition substructure occurrence is word aligned if the first item it contains begins on a word boundary. Each referral substructure occurrence is always word aligned. C substructures always begin and end on word boundaries.
Mixed-Language Programming TAL and C Guidelines You can ensure compatible layouts between TAL and C substructures as follows: Declare TAL referral substructures rather than definition substructures. Referral substructures are always word-aligned. If you must declare TAL definition substructures, either: Use FILLER declarations as needed to begin and end TAL definition substructures on word boundaries, as shown in TAL structure REC4 in the example that follows.
Mixed-Language Programming TAL and C Guidelines Multidimensional Arrays In C, you can declare multidimensional arrays. In TAL, you can emulate multidimensional arrays by declaring structures that contain arrays. Here is an example of multidimensional arrays in TAL and C (large-memory model): TAL Code STRUCT rec1 (*); BEGIN INT y[0:4]; END; C Code short cma[10][5]; STRUCT .EXT tma(rec1)[0:9]; !Sample access! tma[8].
Mixed-Language Programming TAL and C Guidelines Redefinitions and Unions Variant records are approximated by TAL structure redefinitions and C unions. A TAL redefinition declares a structure item that uses the same memory location as an existing structure item.
Mixed-Language Programming TAL and C Guidelines Pointers Pointers contain memory addresses of data. You must store an address into a pointer before you use it. In TAL and C pointer declarations, you specify the data type of the data to which the pointer points. You must use pointers when sharing global variables. You can pass pointer contents by value between TAL and C routines. Differences between TAL and C pointers include the following: TAL structure pointers can point to a byte or word address.
Mixed-Language Programming TAL and C Guidelines Here are examples of TAL and C structure pointers (large-memory-model) that implement a linked list: 17–26 TAL Code STRUCT rec (*); BEGIN INT x; INT .EXT strptr (rec); END; C Code struct rec { short x; struct rec *p; }; STRUCT .EXT joe (rec); struct rec joe; PROC callme (param1); INT .
Mixed-Language Programming TAL and C Guidelines Enumeration Variables Using C enumeration constants, you can associate a group of named constant values with an int variable. A C enumeration variable occupies 16 bits of memory. You define all integer operations on them. The C compiler provides no range checking, so an enumeration variable can hold a value not represented in the enumeration. A C routine can share an enumeration variable with TAL routines.
Mixed-Language Programming TAL and C Guidelines Bit-Field Manipulation You can manipulate bit fields in both TAL and C. In TAL, you can use either: Built-in bit-extraction and bit-deposit operations Bit-wise operators LAND and LOR In C, you can use either: Bit-wise operators & (and) and | (or) Defines The following TAL bit-deposit operation and C bit-wise operation are equivalent: TAL Code C Code INT x := -1; INT y := 0; short a = -1; short b = 0; short temp = 0; PROC example; BEGIN y.<0:2> := x.
Mixed-Language Programming TAL and C Guidelines UNSIGNED Variables and Packed Bit Fields In general, TAL UNSIGNED simple variables in structures are compatible with C unsigned packed bit fields (which only appear in structures). You cannot, however, pass C bit fields as reference parameters to TAL routines.
Mixed-Language Programming TAL and C Guidelines TAL Routines as Parameters to C You can call C routines and pass TAL routines as parameters. You can pass any TAL routine except EXTENSIBLE or VARIABLE routines as parameters. A passed TAL routine can access the routine’s local variables and global TAL variables. The passed routine can contain subprocedures, but they cannot be passed as parameters.
Mixed-Language Programming TAL and C Guidelines C Module /* C function that accepts TAL routine as a parameter */ void C_FUNC (short (*F) (short n)) { short j; j = (*F)(2); /* lots of code */ } TAL Module PROC c_func (x) LANGUAGE C; INT PROC(32) x; EXTERNAL; !EXTERNAL procedure declaration ! for C routine to be called !Parameter declaration INT PROC tal_param_proc (f); !Procedure to be passed as a INT f; ! parameter to C_FUNC BEGIN RETURN f; END; PROC tal_caller; !Procedure that calls C_FUNC BEGIN ! and
Mixed-Language Programming TAL and C Guidelines C Routines as Parameters to TAL You can call TAL routines and pass C routines as parameters. You can call a TAL entry-point identifier as if it were the routine identifier. C routines cannot be nested. When a called TAL routine in turn calls a C routine received as a parameter, the TAL routine assumes that all required parameters of the C routine are value parameters.
Mixed-Language Programming TAL and C Guidelines When you pass a large-memory-model C routine as a parameter, the compiler passes a 32-bit address that contains PEP and map information in the high-order word and a zero in the low-order word. When you pass a small-memory-model C routine as a parameter, the compiler passes a 16-bit address that contains PEP and map information.
Mixed-Language Programming TAL and C Guidelines 6. You must keep track of addresses stored in extended pointers. When storing addresses into subsequent pointers, you must allow space for preceding data items. (See “Managing Data Allocation in Extended Segments” in Appendix B.) 7. To refer to data in the current segment, call READX or WRITEX . 8. To move data between extended segments, call MOVEX. 9. To manage large blocks of memory, call DEFINEPOOL, GETPOOL, and PUTPOOL. 10.
Mixed-Language Programming TAL and C Guidelines In Example 17-1, a large-memory-model C routine calls a TAL routine that manipulates data in an explicit extended segment and then restores the automatic extended segment. When control returns to the C routine, it manipulates data in the restored automatic extended segment: Example 17-1. D-Series TAL and C Extended Segment Management (Page 1 of 2) TAL Code INT .EXT array[0:10]; !Allocated in the automatic ! extended data segment ID 1024D INT .
Mixed-Language Programming TAL and C Guidelines Example 17-1.
Mixed-Language Programming CRE Guidelines for TAL CRE Guidelines for TAL The CRE provides routines that support mixed-language programs compiled on D-series compilers. A mixed-language program can consist of C, COBOL85, FORTRAN, Pascal, and TAL routines.
Mixed-Language Programming CRE Guidelines for TAL To terminate execution, call CRE_TERMINATOR_, which calls PROCESS_STOP_. Do not call the PROCESS_STOP_, STOP, or ABEND system procedures. For services provided by the CRE, call CRE routines. For example, call CRE routines to: Open, manipulate, and close the standard files Perform math or string operations For services not provided by the CRE, call system procedures.
Mixed-Language Programming CRE Guidelines for TAL Specifying a Run-Time Environment To specify the intended run-time environment of a D-series TAL compilation unit, use the ENV directive. To execute in the intended environment, the routines must also meet the requirements of the intended run-time environment. The attributes of the ENV directive are: ENV Attribute Intended Run-Time Environment COMMON OLD NEUTRAL The CRE. A COBOL or FORTRAN run-time environment outside the CRE.
Mixed-Language Programming CRE Guidelines for TAL ENV OLD Directive An object file compiled with ENV OLD can run in a COBOL85 or FORTRAN run-time environment outside the CRE (if the object file meets the requirements of the run-time environment). When ENV OLD is in effect, all routines in the compilation unit (except routines in object files listed in SEARCH directives) have the ENV OLD attribute. SEARCH directives can list object files compiled with any ENV attribute except COMMON.
Mixed-Language Programming CRE Guidelines for TAL The User Heap The user heap is a shared resource the CRE makes available to your routines, regardless of language. The user heap is in the block named #HEAP, which differs from the CRE-reserved block named #CRE_HEAP. Binder allocates memory space for the user heap as follows: If a TAL program contains a small-memory model C or Pascal module, the user heap is the last global data block in the lower 32K-word area of the user data segment.
Mixed-Language Programming CRE Guidelines for TAL Only C, Pascal, or TAL routines can access data in the user heap. To access heap data, a C, Pascal, or TAL routine assigns the address returned from malloc or NEW to a pointer and uses the pointer in an expression. All routines that need access to such data must either: Use the same data layout Call a routine that accesses the data for you COBOL85 and FORTRAN routines access heap data by calling C, Pascal, or TAL routines.
Mixed-Language Programming CRE Guidelines for TAL Including Library Files To run in the CRE, your program needs the TALLIB library file. Your program can also use the CRELIB and CLULIB library files. TALLIB provides the TAL_CRE_INITIALIZER_ routine. This routine is described in the next subsection. CRELIB provides routines that enable your routine to perform tasks such as the following.
Mixed-Language Programming CRE Guidelines for TAL The following example shows SEARCH directives for TALLIB and CLULIB, followed by SOURCE directives for TALDECS, CREDECS, and CLUDECS: ?ENV COMMON NAME cre_example; ?SEARCH $SYSTEM.SYSTEM.TALLIB ?SEARCH $SYSTEM.SYSTEM.CLULIB ?SOURCE $SYSTEM.SYSTEM.TALDECS (TAL_CRE_INITIALIZER_) ?SOURCE $SYSTEM.SYSTEM.CREDECS (CRE_TERMINATOR_) ?SOURCE $SYSTEM.SYSTEM.
Mixed-Language Programming CRE Guidelines for TAL The following example initializes the CRE without saving messages: ?ENV COMMON NAME initialize_CRE; ?SEARCH $SYSTEM.SYSTEM.TALLIB ?SOURCE $SYSTEM.SYSTEM.TALDECS (TAL_CRE_INITIALIZER_) PROC mymain MAIN; BEGIN CALL TAL_CRE_INITIALIZER_; !Lots of code END; !Initialize the CRE The following example initializes the CRE and saves ASSIGN and PARAM messages but not the startup message: ?ENV COMMON NAME initialize_CRE; ?SEARCH $SYSTEM.SYSTEM.
Mixed-Language Programming CRE Guidelines for TAL Sharing the Standard Files To open and access standard input, output, and log files, a TAL routine must call CRE routines directly.
Mixed-Language Programming CRE Guidelines for TAL Writing a Message to Standard Files To write a record to standard log , a TAL routine calls CRE_LOG_MESSAGE_. For example, to write the content of a 15-character array named MSG to standard log, you can specify: CALL CRE_LOG_MESSAGE_ (msg:15); To write a record to standard output , a TAL routine calls CRE_FILE_OUTPUT_.
Mixed-Language Programming CRE Guidelines for TAL Accessing $RECEIVE $RECEIVE is a special file through which a routine can receive messages from the operating system, from your backup process, or from another process. Routines written in any language supported by the CRE can read $RECEIVE. The routines in a program can access $RECEIVE by calling either CRE routines only or system procedures only.
Mixed-Language Programming CRE Guidelines for TAL Handling Errors in CRE Math Routines The CRE provides libraries of math routines, such as sine and cosine routines, that your program can call. When a CRE math routine receives an invalid parameter or produces an invalid result, an arithmetic fault occurs when control returns to the caller. The caller’s run-time library (except TAL) determines the program’s behavior.
Mixed-Language Programming CRE Guidelines for TAL CRE Sample Program Example 17-2 shows the source code of a D-series program written for the CRE. This program contains a TAL routine that calls a C routine, each of which displays a greeting. Example 17-2. D-Series CRE Sample Program (Page 1 of 2) TAL Code ?SYMBOLS, INSPECT ?ENV COMMON NAME talsrc; !Source in ?PUSHLIST, ?POPLIST ?PUSHLIST, ? ?POPLIST ?PUSHLIST, ? ? ? ? ?POPLIST CRE run-time library routines: NOLIST, SOURCE $SYSTEM.
Mixed-Language Programming CRE Guidelines for TAL Example 17-2.
Appendix A Sample Programs This appendix includes the following examples: String-display sample program String-entry sample program Binary-to-ASCII conversion sample program Modular programming example String-Display Programs Example A-1 shows the source code for a string-display program that displays "Hello, World" on the terminal. Example A-1. C- or D-Series String-Display Program !Global data declarations: INT .out_file_name[0:11]; ?PUSHLIST, NOLIST, SOURCE $SYSTEM.SYSTEM.
Sample Programs String-Display Programs Example A-2 shows a C-series version of the previous string-display program. Example A-2. C-Series String-Display Program) ?NOLIST, SOURCE $SYSTEM.SYSTEM.
Sample Programs String-Entry Program String-Entry Program This string-entry program opens the home terminal and then loops forever. In each loop iteration, the program: 1. Displays "ENTER STRING" and accepts a character string of up to 68 characters. 2. Scans the input string for an asterisk. If an asterisk occurs, the program displays a circumflex at the position of the first asterisk. Example A-3 shows the D-series source code for the string-entry program. Example A-3.
Sample Programs String-Entry Program Example A-4 shows the C-series source code for the string-entry program. Example A-4. C-Series String-Entry Program LITERAL maxlength = 68; INT termnum, left_side, !Maximum length of BUFFER !File number of home terminal !BUFFER address of first ! character after prompt !Number of bytes transferred !General-purpose variable !Location of asterisk num_xferred, count, asterisk; INT .ibuffer[0:maxlength/2]; STRING .buffer := @ibuffer '<<' 1, !Input-output buffer .
Sample Programs Binary-to-ASCII Conversion Program Binary-to-ASCII This binary-to-ASCII conversion program performs a conversion function typical of Conversion Program many algorithms in TAL. The program converts a binary INT value to an ASCII (base 10) value with a maximum length of six characters including the sign, then returns the converted character string and its length to the calling procedure.
Sample Programs Binary-to-ASCII Conversion Program Example A-5. C- or D-Series Binary-to-ASCII Conversion Program !1! !2! !3! !4! !5! !6! A–6 !INT PROC ASCII converts a binary INT value to an ASCII ! (base 10) value of up to six characters (including the ! sign) and returns the ASCII value and its length. INT PROC ascii (v, rjust, stg); INT v; !INT value to convert INT rjust; !Right justify result flag STRING .stg; !Target string BEGIN STRING .
Sample Programs Modular Programming Example Modular Programming This modular programming example illustrates how you can divide the code for a Example program into separately compilable modules. The program converts records in the input file to a different format and length by reordering fields and adding fields to records.
Sample Programs Modular Programming Example File-Naming Conventions This modular program follows these file-naming conventions: Source file names end with the character S. Object file names correspond to source file names and end with O. For instance, the object file built from the source file INS is named INO. Section names ending with D belong to a specific module. For instance, IND is the section that contains LITERAL declarations for INS.
Sample Programs Modular Programming Example Compiling and Binding the Modular Program To compile each source file into an object file, you can issue the following compilation commands You need do all these steps only once: TAL TAL TAL TAL TAL /IN /IN /IN /IN /IN inits/ inito ins/ ino outs/ outo msgs/ msgo converts/ converto To bind the modular object files into a single object file, you can issue the following Binder commands.
Sample Programs Modular Programming Example Mainline Module Example A-6a shows the mainline module, which contains the MAIN procedure. The record-definition structures are not listed because they are translations of the Data Definition Language (DDL) source code into TAL. Example A-6a.
Sample Programs Modular Programming Example Example A-6a. D-Series Mainline Module (Page 2 of 2) WHILE (i < $OCCURS(in_rec.name)) AND (ch_ptr <> ",") DO BEGIN @ch_ptr := @ch_ptr[1]; i := i + 1; END; out_rec.name.last_name ':=' in_rec.name FOR i BYTES; IF ch_ptr = ',' THEN !Copy first name BEGIN @ch_ptr := @ch_ptr[1]; !Advance past comma out_rec.name.first_name ':=' ch_ptr FOR $OCCURS(in_rec.name) '-' i '-' 1 BYTES; END; out_rec.address ':=' in_rec.address !Copy address FOR $OCCURS(in_rec.
Sample Programs Modular Programming Example Initialization Module Example A-6b shows the source code for the initialization module. This module defines a primary global data block, DEFAULT_VOL, which is accessible to all procedures in the modules that declare the block for reference. Example A-6b.
Sample Programs Modular Programming Example Example A-6b. D-Series Initialization Module (Page 2 of 2) ?SECTION startup PROC startup (rucb, passthru, message, meslen, match) VARIABLE; INT .rucb, .passthru, .message, meslen, match; BEGIN INT .
Sample Programs Modular Programming Example Input File Module Example A-6c shows the source code for the input file module, which contains all procedures that manipulate the input file. If you make I/O changes, only this module needs to be recompiled. The initialization module, for example, calls a procedure in this module. This module declares a private global data block, which is accessible only to the procedures in this module. Example A-6c.
Sample Programs Modular Programming Example Example A-6c. D-Series Input File Module (Page 2 of 3) ?SECTION in_file_init PROC in_file_init; BEGIN INT in_file_name_len := 6; STRING .
Sample Programs Modular Programming Example Example A-6c. D-Series Input File Module (Page 3 of 3) ?SECTION read_in INT PROC read_in (rec:rec_len); STRING .EXT rec; INT rec_len; BEGIN INT error; CALL READX (in_file, rec, rec_len); IF < THEN BEGIN error := FILE_GETINFO_ (in_file); CALL msg (msg_read, error); CALL PROCESS_STOP_ (!phandle!, !specifier!, !options!, 3 !Completion code ABEND!, !...
Sample Programs Modular Programming Example Output File Module Example A-6d shows the source code for the output file module. This module declares a private global data block, which is accessible only to procedures in this module. Some code that is parallel to code in the input file handler is not listed. Example A-6d.
Sample Programs Modular Programming Example Example A-6d. D-Series Output File Module (Page 2 of 3) IF status = 0 !FEOK! THEN BEGIN status := FILE_OPEN_ (out_file_name:out_file_name_len, out_file); IF out_file = -1 !unable to open file! THEN BEGIN CALL msg (msg_out_open, status); CALL PROCESS_STOP_ (!phandle!, !specifier!, !options!, 3 !Completion code ABEND!, !...
Sample Programs Modular Programming Example Example A-6d. D-Series Output File Module (Page 3 of 3) ?SECTION out_close PROC out_close; BEGIN CALL FILE_CLOSE_ (out_file); END; ?SECTION end_of_code_sections ?NOMAP Message Module Example A-6e shows the message module listing. The terminal number in the private global data block is is accessible only to procedures in this module. Example A-6e.
Sample Programs Modular Programming Example Example A-6e. D-Series Message Module (Page 2 of 3) ?SECTION msg_init PROC msg_init; BEGIN INT term_name_len; STRING .term_name[0:term_name_max_len - 1]; CALL PROCESS_GETINFO_(!process_handle!, !file_name:max_len!, !file_name_len!, !priority!, !moms_phandle!, term_name:term_name_max_len, term_name_len, !...! ); CALL FILE_OPEN_(term_name:term_name_len, term_file_number); END; ?SECTION msg PROC msg (number, altnum); INT number, altnum; BEGIN STRING .
Sample Programs Modular Programming Example Example A-6e.
Sample Programs Modular Programming Example Data-Block Load Map Figure A-2 shows the data-block load map for the modular programming example: Figure A-2. Data-Block Load Map for Modular Program DATA BLOCK MAP BY NAME Base Limit Type Mode Name Date Time Lang Source File 000005 000003 000000 000002 000000 000001 000000 000204 000012 000000 000002 COMMON COMMON COMMON COMMON COMMON COMMON COMMON WORD WORD WORD WORD WORD WORD WORD .
Appendix B Managing Addressing This appendix discusses: Extended pointer format Accessing the upper 32K-word area of the user data segment Creating and accessing an extended data segment Accessing a code segment The coding practices covered in this appendix predate automatic extended segment management and are described here in support of existing programs.
Managing Addressing Accessing the Upper 32K-Word Area The segment specifier in an extended pointer indicates which segment is being accessed by the pointer: Segment Specifier Segment 0 1 Current user data segment System data segment if in privileged mode User data segment if in nonprivileged mode Current code segment Current user code segment (read access only) Base address for the current extended data segment 2 3 4–n An extended pointer, having 32 bits, can access byte addresses anywhere in a segmen
Managing Addressing Accessing the Upper 32K-Word Area You can use the $XADR standard function to convert the 16-bit address contained in a standard simple pointer to a 32-bit address with which to initialize an extended simple pointer: INT .std_ptr := %100000; !Declare INT standard simple ! pointer INT .
Managing Addressing Accessing the Upper 32K-Word Area Storing Addresses in Structure Pointers You can store an address in a structure pointer either by initializing the pointer at declaration or by assigning an address to it after declaration.
Managing Addressing Accessing the Upper 32K-Word Area You can associate an extended structure pointer with the structure pointer declared in the preceding example and then assign the first byte address in the upper 32K-word area of the current user data segment to the new structure pointer: STRING .
Managing Addressing Accessing the Upper 32K-Word Area You can use a move statement to copy a constant list to the address contained in a simple pointer. You can then assign one of the values in the constant list to an array element by appending an index to the pointer to access that particular value: INT var[0:4]; INT .
Managing Addressing Accessing the Upper 32K-Word Area You can use an INT extended structure pointer to copy data to byte-addressed structure items in the upper 32K-word area of the current data user segment: STRUCT name_rec (*); BEGIN STRING name[0:25]; END; !Declare template structure INT .EXT ext_ptr(name_rec) := %200000D; !Point to beginning ! of upper 32K-word area ext_ptr.name[0] ':=' "Anasta L.
Managing Addressing Accessing the Upper 32K-Word Area Indexing the Upper 32K-Word Boundary Although an index for standard indirect structures must fall within the signed INT range, a word offset (from the zeroth structure occurrence) can be in the range –65,535 through 65,535. The following example shows how you can access such offsets: STRUCT x (*); BEGIN INT i, j; END; PROC m MAIN; BEGIN INT .y (x) := %70000; !Y[0:18430] spans the ! 32K-word boundary USE i; FOR i := 0 TO 18430 DO y[i].i := y[i].
Managing Addressing Accessing the User Code Segment Accessing the User You can access the user code segment by storing a 32-bit byte address in an extended Code Segment pointer. To build the address, use: The $DBLL standard function, which returns an INT(32) value from two INT values. The first INT value becomes the upper half of the INT(32) value, and the second value becomes the lower half. An unsigned bit-shift operation ('<<' 1), which converts a word address to a byte address.
Managing Addressing Using Extended Data Segments Using Extended Data In addition to the user data segment, you can store data in: Segments The automatic extended data segment One or more explicit extended data segments You should use only the automatic extended data segment if possible. You should not mix the two approaches. If you must use explicit segments and the automatic segment, however, follow guidelines 4 and 10 in “Using Explicit Extended Segments” that follows.
Managing Addressing Using Extended Data Segments 8. To manage large blocks of memory, call DEFINEPOOL, GETPOOL, and PUTPOOL. 9. To determine the size of a segment, call SEGMENT_GETINFO_. 10. To access data in the automatic extended segment, call SEGMENT_USE_ and restore the segment number that you saved at step 4. 11. To delete an explicit segment that you no longer need, call SEGMENT_DEALLOCATE_.
Managing Addressing Using Extended Data Segments Example B-1. D-Series Extended Segment Allocation ?INSPECT, SYMBOLS ?SOURCE $SYSTEM.SYSTEM.EXTDECS0 ( ? SEGMENT_ALLOCATE_, SEGMENT_USE_) PROC alloc_xsegment MAIN; BEGIN DEFINE error = ! ...! #; INT .
Managing Addressing Using Extended Data Segments Managing Data Allocation in Extended Segments When you declare a pointer, the compiler allocates storage for the pointer itself but does not allocate storage for data at the address that is contained in the pointer. You must manage such allocation yourself. You must remember which addresses you have used and the length of the data item pointed to by each pointer. When you initialize subsequent pointers, you must allow space for the preceding data items.
Managing Addressing Using Extended Data Segments Accessing Data in an Extended Segment After you declare a pointer and store an address in the pointer, you can use an assignment or move statement to place an item at the location pointed to by the pointer. For example, you can declare a structure, declare and initialize an INT extended structure pointer, and then access byte-addressed structure items in the current extended data segment.
Managing Addressing Using Extended Data Segments Copying Data Between Segments You cannot use a move statement to copy data between extended segments. You can use a move statement to copy data from an extended segment to the user data segment and then from there to another extended segment, or you can use the MOVEX system procedure.
Managing Addressing Using Extended Data Segments D-Series Extended Segment Management Program Example B-2 shows D-series extended segment management program. Example B-2. D-Series Extended Segment Management Program(Page 1 of 3) ?INSPECT, SYMBOLS ?NOCODE ?PAGE "dummy page directive" ?PUSHLIST, NOLIST SOURCE $SYSTEM.SYSTEM.
Managing Addressing Using Extended Data Segments Example B-2.
Managing Addressing Using Extended Data Segments Example B-2. D-Series Extended Addressing Program (Page 3 of 3) !USE new extended data segment for more manipulations.
Managing Addressing Using Extended Data Segments C-Series Extended Segment Examples On a C-series system, you call ALLOCATESEGMENT and USESEGMENT to create and use an explicit extended data segment. ALLOCATESEGMENT does not return the base address of the extended segment. The first segment address you can use in the explicit extended segment is 4D '<<' 17 or %2000000D. The following declarations are equivalent: STRING .EXT ptr := 4D '<<' 17; STRING .
Managing Addressing Using Extended Data Segments C-Series Extended Segment Allocation Program Example B-3 shows a C-series version of the previous D-series extended segment allocation program. This example is not portable to future software platforms: Example B-3. C-Series Extended Segment Allocation Program ?INSPECT, SYMBOLS ?SOURCE $SYSTEM.SYSTEM.EXTDECS0 ( ? ALLOCATESEGMENT, USESEGMENT) PROC alloc_xsegment MAIN; BEGIN DEFINE error = ! ...! #; INT .
Managing Addressing Using Extended Data Segments Managing Data Allocation in Extended Segments When you declare a pointer, the compiler allocates storage for the pointer itself but does not allocate storage for data at the address that is contained in the pointer. You must manage such allocation yourself. You must remember which addresses you have used and the length of the data item pointed to by each pointer. When you initialize subsequent pointers, you must allow space for the preceding data items.
Managing Addressing Using Extended Data Segments C-Series Extended Segment Management Program Example B-4 shows a C-series version of the previous D-series extended segment management program. This example is not portable to future software platforms. Example B-4.
Managing Addressing Using Extended Data Segments Example B-4.
Managing Addressing Using Extended Data Segments Example B-4. C-Series Extended Addressing Program (Page 3 of 3) !USE new extended data segment for more manipulations.
Appendix C Improving Performance Although the TAL compiler is a one-pass compiler and is subject to certain limitations inherent in this characteristic, it generates efficient object code for the target computer. If optimum run-time speed is important, however, you can maximize efficiency by following the guidelines given in this appendix. General Guidelines The following guidelines describe general practices for achieving efficient code: Code programs as cleanly and clearly as possible.
Improving Performance Indexing Guidelines STACK and STORE Statements STACK and STORE statements do not improve the efficiency of access to data items. These statements are provided primarily for moving operands to and from the register stack when working with the CODE statement. Indexing Guidelines The compiler saves index values in index registers so you can refer to them in later statements.
Improving Performance Arithmetic Guidelines Arithmetic Guidelines A single complex arithmetic expression might cause more memory references than several smaller expressions that are equivalent to the single complex expression. The excessive memory references are triggered by register stack overflow, which is especially likely if indexes are involved. Use of an index might cause part of the computation to be pushed on the stack and later popped off.
Appendix D ASCII Character Set Char Left Right Hex Dec Meaning NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US SP ! " # $ % & ' ( ) ∗ 000000 000400 001000 001400 002000 002400 003000 003400 004000 004400 005000 005400 006000 006400 007000 007400 010000 010400 011000 011400 012000 012400 013000 013400 014000 014400 015000 015400 016000 016400 017000 017400 020000 020400 021000 021400 022000 022400 023000 023400 024000 024400 025000 0
ASCII Character Set D–2 Char Left Right Hex Dec Meaning + , .
ASCII Character Set Char Left Right Hex Dec Meaning R S T U V W X Y Z 051000 051400 052000 052400 053000 053400 054000 054400 055000 000122 000123 000124 000125 000126 000127 000130 000131 000132 52 53 54 55 56 57 58 59 5A 82 83 84 85 86 87 88 89 90 Uppercase R Uppercase S Uppercase T Uppercase U Uppercase V Uppercase W Uppercase X Uppercase Y Uppercase Z [ \ ] ^ _ ` 055400 056000 056400 057000 057400 060000 000133 000134 000135 000136 000137 000140 5B 5C 5D 5E 5F 60 91 92 93 94 95 96 Open
ASCII Character Set D–4 Char Left Right Hex Dec Meaning { | } ~ DEL 075400 076000 076400 077000 077400 000173 000174 000175 000176 000177 7B 7C 7D 7E 7F 123 124 125 126 127 Opening brace Vertical line Closing brace Tilde Delete 096254 Tandem Computers Incorporated
Appendix E File Names and TACL Commands This appendix describes how you specify disk file names and TACL commands. Topics include: Disk file names TACL DEFINE commands TACL PARAM commands TACL ASSIGN commands TACL ASSIGN SSV commands For information on process or device file names, see the Guardian Programmer’s Guide. Disk File Names A disk file name identifies a file that contains data or a program. A disk file name reflects the specified file’s location on a Tandem system.
File Names and TACL Commands Disk File Names Parts of a Disk File Name A disk file has a unique file name that consists of four parts, with each part separated by a period: A D-series node name or a C-series system name A volume name A subvolume name A file ID Here is an example of a disk file name: \mynode.$myvol.mysubvol.myfile You can name your own subvolumes and file IDs, but nodes (systems) and volumes are named by the system manager.
File Names and TACL Commands Disk File Names File ID The file ID, such as MYFILE, is the identifier of the file in the subvolume. The file ID can contain from one to eight alphanumeric characters, the first of which must be alphabetic. The file ID is required. Partial File Names A partial file name contains at least the file ID, but does not contain all the file-name parts.
File Names and TACL Commands TACL Commands Internal File Names The C-series operating system uses the internal form of a file name when passing it between your program and the operating system. The D-series operating system uses the internal form only if your program has not been converted to use D-series features. For information on converting external file names to internal file names in a program, see the Guardian Programmer’s Guide and the Guardian Procedure Calls Reference Manual.
File Names and TACL Commands TACL Commands TACL DEFINE Names TACL DEFINE names: Are not case-sensitive Consist of 2 to 24 characters Begin with an equals sign (=) followed by an alphabetic character Continue with any combination of letters, digits, hyphens (-), underscores (_), and circumflexes (^) Some examples of valid DEFINE names are: =A =The_chosen_file =Long-but-not-too-long =The-File-of-The-Week DEFINE names that begin with an equals sign followed by an underscore (=_) are reserved by Tandem.
File Names and TACL Commands TACL PARAM Commands DEFAULTS DEFINE In the DEFAULTS class, a permanently built-in DEFINE named =_DEFAULTS has the following attributes, which are active regardless of any DEFMODE setting: Attribute Required Purpose VOLUME Yes SWAP No CATALOG No Contains the default node, volume, and subvolume names for the current process as set by the TACL VOLUME, SYSTEM, and LOGON commands Contains the node and volume name in which the operating system is to store swap files Contains
File Names and TACL Commands TACL PARAM Commands PARAM SWAPVOL Command The PARAM SWAPVOL command lets you specify the volume that the compiler, BINSERV, and SYMSERV use for temporary files. For example: PARAM SWAPVOL $myvol The compiler ignores any node specification and allocates temporary files on its own node. If you omit the volume, the compiler uses the default volume for temporary files; BINSERV and SYMSERV use the volume that is to receive the object file.
File Names and TACL Commands TACL ASSIGN Commands TACL ASSIGN Commands You can issue the TACL ASSIGN command before starting the compiler to substitute actual file names for logical file names used in the source file. The TACL product stores the file-name mapping until the compiler requests it.
File Names and TACL Commands TACL ASSIGN Commands ASSIGN SSV Command The ASSIGN SSV (Search SubVolume) command lets you specify which node, volume, and subvolume to take files from. The compiler uses ASSIGN SSV information to resolve incomplete file names in the SEARCH, SOURCE, and USEGLOBALS directives. For each ASSIGN SSV command, append to the SSV keyword a value in the range 0 through 49. Values in the range 0 through 9 can appear with or without a leading 0.
File Names and TACL Commands TACL ASSIGN Commands Processing ASSIGN SSV Commands For each file name the compiler processes, the compiler scans the SSVs in ascending order from SSV0 until it finds a subvolume that holds the file. For example, if you issue the following ASSIGN commands before running the compiler: ASSIGN ASSIGN ASSIGN ASSIGN ASSIGN SSV7, SSV10, SSV8, SSV20, trig, $aa.b3 $aa.grplip mylib $cc.divlib $sp.math.
Appendix F Data Type Correspondence The tables in this appendix provide information on: Data type correspondence among Tandem languages The return value size generated by each data type These tables are useful if your programs: Use data from files created in another language Pass parameters to programs written in callable languages The return value sizes given in these tables do not correspond to the storage size of SQL data types.
Data Type Correspondence Table F-1.
Data Type Correspondence Table F-2.
Data Type Correspondence Table F-4. Character Types Character Character String Varying Length Character String BASIC STRING STRING — C signed char unsigned char pointer to char COBOL Alphabetic Numeric DISPLAY Alphanumeric-Edited Alphanumeric Numeric-Edited CHARACTER Alphabetic Numeric DISPLAY Alphanumeric-Edited Alphanumeric Numeric-Edited CHARACTER array CHARACTER*n struct { int len; char val [n] }; 01 name. 03 len USAGE IS NATIVE-2 [1] 03 val PIC X(n).
Data Type Correspondence Table F-6.
Glossary actual parameter. An argument that a calling procedure or subprocedure passes to a called procedure or subprocedure. addressing mode. The mode in which a variable is to be accessed—direct addressing, standard indirect addressing, or extended indirect addressing—as specified in the data declaration. AND. A Boolean operator that produces a true state if both adjacent conditions are true. arithmetic expression. An expression that computes a single numeric value. array.
Glossary bit shift. The shifting of bits within an INT or INT(32) expression a specified number of positions to the left or right. An INT expression can consist of STRING, INT, or UNSIGNED(1–16) values. An INT(32) expression can consist of INT(32) or UNSIGNED(17–31) values. bit-shift operators. Unsigned ('<<', '>>') or signed (<<, >>) operators that left shift or right shift a bit field within an INT or INT(32) expression. bitwise logical operator.
Glossary code space. A part of virtual memory that is reserved for user code, user library code, system code, and system library code. The current code space of your process consists of an optional library code space and a user code space. CODE statement. A statement that specifies machine codes or constants for inclusion in the object code. comment. A note that you insert into the source code to describe a construct or operation in your source code. The compiler ignores comments during compilation.
Glossary CPU. Central processing unit. Historically, the main data processing unit of a computer. A Tandem system has multiple cooperating processors rather than a single CPU; processors are sometimes called CPUs. CRE. Common Run-Time Environment. Services that facilitate D-series mixedlanguage programs. CREDECS. A file, provided by the CRE, that contains external declarations for CRELIB functions whose names begin with CRE_. See also “CRELIB.” CRELIB.
Glossary definition structure. A declaration that describes a structure layout and allocates storage for the structure layout. Contrast with “referral structure” and “template structure.” dereferencing operator. A period (.) prefixed to an INT simple variable, which causes the content of the variable to become the standard word address of another data item. direct addressing.
Glossary extended stack. A data block named $EXTENDED#STACK that is created in the automatic extended data segment by the compiler when you declare extended indirect arrays and structures. EXTENSIBLE procedure. A procedure that you declare using the EXTENSIBLE keyword; a procedure to which you can add formal parameters without recompiling its callers; a procedure for which the compiler considers all parameters to be optional, even if some are required by your program. Contrast with “VARIABLE procedure.
Glossary function. A procedure or subprocedure that returns a value to the calling procedure or subprocedure. global data. Data declarations that appear before the first procedure declaration; identifiers that are accessible to all compilation units in a program, unless the the data declarations appear in a BLOCK declaration that includes the PRIVATE keyword. GOTO statement. A statement that unconditionally branches to a label within a procedure or subprocedure. group comparison expression.
Glossary INTERRUPT attribute. A procedure attribute (used only for operating system procedures) that causes the compiler to generate an IXIT (interrupt exit) instruction instead of an EXIT instruction at the end of execution. keyword. A term that has a predefined meaning to the compiler. label. An identifier you place before a statement for access by other statements within the encompassing procedure, usually a GOTO statement. labeled tape.
Glossary named data block. A BLOCK declaration that specifies a data-block identifier. The global data declared within the BLOCK declaration is accessible to all compilation units in the program. Contrast with “private data block.” network. Two or more nodes linked together for intersystem communication. node. A computer system connected to one or more computer systems in a network. NonStop SQL. A relational database management system that provides efficient online access to large distributed databases.
Glossary precedence of operators. The order in which the compiler evaluates operators in expressions. primary storage area. The area of the user data segment that can store pointers and directly addressed variables. Contrast with “secondary storage area.” PRIV procedure. A procedure you declare using the PRIV keyword; a procedure that can execute privileged instructions. Normally only operating system procedures are PRIV procedures. private data area.
Glossary REAL(64). A data type that requires a quadrupleword of storage and that can represent a 64-bit floating-point number. recursion. The ability of a procedure or subprocedure to call itself. redefinition. A declaration, within a structure, that associates a new identifier and sometimes a new description with a previously declared item in the same structure. reduced instruction set computing. See “RISC.” reference parameter.
Glossary Saved Messages Utility. See "SMU functions." SCAN statement. A statement that scans sequential bytes, left to right, for a test character. scope. The set of levels—global, local, or sublocal—at which you can access each identifier. secondary storage area. The part of the user data segment that stores the data of indirect arrays and structures. For standard indirection, the secondary storage area is in the user data segment.
Glossary STRING. A data type that requires a byte or word of storage and that can represent an ASCII character or an 8-bit integer. structure. A variable that can contain different kinds of variables of different data types. A definition structure, a template structure, or a referral structure. structure data item. An accessible structure field declared within a structure, including a simple variable, array, substructure, simple pointer, structure pointer, or redefinition. Contrast with “structure item.
Glossary TNS/R system. Tandem NonStop Series/RISC system. Tandem computers that are based on RISC technology. TNS/R processors implement the RISC instruction set and are upwardly compatible with the TNS system-level architecture. Transaction Application Language. See “TAL.” type transfer. The conversion of a variable from one data type to another data type. unblocked global data. Global data you declare before any BLOCK declarations.
Index 16-bit (standard) addressing 4-7 16-bit (standard) pointers 9-1 32-bit (extended) addressing 4-7 32-bit (extended) pointers 9-1 A Accelerated object files xxviii Actual parameters See Parameters Addition operator signed 5-16 unsigned 5-18 Address conversions bit-shift operations 5-30 byte-to-word simple pointer initialization 9-4 structure pointer initialization 9-14 reference parameters 11-35 standard-to-extended simple pointer assignment 9-8 simple pointer initialization 9-5 structure pointer assign
Index Addressing definition structures 8-3 performance guidelines C-1 referral structures 8-8 template structures 8-7 Addressing modes byte 4-5 direct 4-6 extended (32-bit) indirect 4-7 indexing 4-7 indirect 4-6 standard (16-bit) indirect 4-7 word 4-5 Aliases, data types 5-6 Ampersand (&) concatenated move (copy) operations 7-18 prefix, template block name allocation 14-17 description 14-16 listing 15-14 AND operator 5-22 Arithmetic expressions description 5-15 in conditional expressions 5-21 performance g
Index Arrays (continued) multidimensional simulated by structures 8-13 TAL and C guidelines 17-23 of arrays 8-9 of structures definition structures 8-3 referral structures 8-8 TAL and C guidelines 17-23 redefinitions 8-21 scanning 7-19 storage allocation 7-8 TAL and C guidelines 17-19 ASCII character set D-1 ASSERT statement 12-17 ASSIGN command, TACL product E-8 ASSIGN message, saving 17-44 ASSIGN SSV command, TACL product E-9 Assignment expression 13-2 Assignment statement arrays 7-13 simple pointers 9-7
Index Binary-to-ASCII conversion program A-5 Binder 14-5 Binding object files during compilation 14-6 modular sample program A-9 overview 14-5 run-time 14-6 stand-alone Binder 14-6 TAL and C for CRE 17-51 BINSERV action of 14-1 and SEARCH directive 14-12 binding object files 14-6 resolving external references 14-13 specifying which one E-6 Bit extractions 5-28 Bit fields bit-extraction operations 5-28 manipulating in TAL and C 17-28 UNSIGNED and C packed 17-29 UNSIGNED data type 5-6 Bit operations extracti
Index BLOCK declarations (continued) modular sample program named block A-12 private block A-19 storage allocation 14-19 Boolean operators 5-22 Bounds, upper and lower arrays 7-1 definition structures 8-3 referral structures 8-8 Branch table form, labeled CASE statement 12-6 BREAK command, Inspect product 16-5 BREAK key, stopping programs 16-3 Breakpoints, setting 16-5 Built-in functions See Standard functions BY keyword, FOR statement 12-12 Byte 5-6 Byte addressing 4-5 BYTES keyword group comparison expre
Index CASE statement, labeled branch table form 12-6 conditional test form 12-6 description 12-5 modular sample program A-20 with CHECK directive 12-7 with OPTIMIZE directive 12-7 CCE (condition code equal to) 5-25 CCG (condition code greater than) 5-25 CCL (condition code less than) 5-25 char variables, TAL and C mixed programming 17-19 Character set D-1 Character strings format 5-10 initializing with 6-2 interlanguage correspondence F-3 maximum length 5-10 CHECK directive, with labeled CASE statement 12-
Index Compilation statistics, compiler listing 15-16 Compilation units description 14-2 naming 14-14 order of components 3-3 scope of identifiers 3-3 structuring 3-1 Compiler processes integrated with 14-1 starting 14-2 Compiler directives See Directives Compiler listing banner 15-2 compilation statistics 15-16 compiler messages 15-2 cross-references 15-11 directives in 15-2 innerlisting 15-7 maps file name map 15-10 global map 15-9 load map 15-13 local map 15-6 sublocal map 15-6 octal code 15-9 page heade
Index Compound statements 3-16 Concatenated move (copy) operations 7-18 Condition code indicator, testing 5-25 Conditional compilation asterisk in listing 15-5 directives (DEFINETOG, IF, ENDIF, IFNOT) 3-15 Conditional expressions assigning 5-24 description 5-21 Conditional statements 12-1 Conditional test form, labeled CASE statement 12-6 Constant expressions 5-1 Constant lists copying into arrays 7-14 group comparison expressions 13-5 initializing arrays 7-3 move statement 7-14 Constants arithmetic expres
Index CRE guidelines (continued) object files, stopping 17-45 run-time environment, specifying 17-39 sample program 17-50 spooling 17-47 standard files, accessing 17-46 user heap, accessing 17-41 $RECEIVE, accessing 17-48 CREDECS (CRE external declarations file) including in program 17-43 sample program 17-50 CRELIB (CRE library file) 17-43 #CRE_GLOBALS (CRE control block) 17-39 #CRE_HEAP (CRE run-time heap) 17-39 CRE_TERMINATOR_ 17-45 Cross-references collecting with CROSSREF directive 14-26 compiler list
Index Data declarations (continued) local 3-8 sublocal 3-12 unblocked 3-5 Data Definition Language (DDL) and byte-aligned structures 17-21 and type correspondence F-1 Data sets arrays 7-1 structures 8-1 Data space 4-2 Data types compatibility with C data types 17-10 description 5-4 format 5-4 interlanguage correspondence F-2 of Boolean operands 5-22 of expressions 5-6 of logical arithmetic operands 5-20 of signed arithmetic operands 5-16 of signed relational results 5-23 of special expressions 13-1 of unsi
Index Declarations arrays 7-1 BLOCKs 14-14 equivalenced variables 10-1 functions 11-8 labels 11-48 LITERALs 5-11 NAME 14-14 procedures 11-2 simple pointers 9-2 simple variables 6-1 structure pointers 9-12 structures 8-3 subprocedures 11-15 DEFAULT DEFINE E-6 DEFINE command, TACL product E-4 DEFINEPOOL system procedure extended data segment B-16 upper 32K-word area B-7 DEFINETOG directive 3-15 Definition structures addressability 8-6 as reference parameters 11-31 declaring 8-3 equivalenced 10-10 storage all
Index Directives (continued) file names 14-9 HEAP 17-41 IF 3-15 IFNOT 3-15 overview of 3-18 SAVEGLOBALS 14-23 SEARCH 14-12, 14-23 SOURCE 14-10 specifying in compilation command 14-4 specifying in source files 14-7 USEGLOBALS 14-23 Disk file names E-1 DISPLAY command, Inspect product 16-5 Displaying program values 16-5 Division by powers of two 5-30 Division operator signed 5-16 unsigned 5-18 unsigned modulo 5-18 DO keyword DO statement 12-10 FOR statement 12-12 WHILE statement 12-8 DO statement 12-10 Docum
Index ELSE keyword IF expression 13-4 IF statement 12-2 ENDIF directive 3-15 Entry points entry-point identifiers procedures 3-7 subprocedures 3-11 procedure identifiers 3-7 recorded in PEP and XEP tables 11-1 subprocedure identifiers 3-11 Enumeration variables in C 17-27 ENV directive 17-39 Environment register 4-5 Equivalenced variables definition structures 10-10 indexing 10-19 kinds of 10-1 referral structures 10-14 simple pointers 10-6 simple variables 10-2 structure pointers 10-16 Error handling ASSE
Index Expressions arithmetic expression 5-15 assignment expression 13-2 Boolean operations 5-22 CASE expression 13-3 conditional expression 5-21 constant expression 5-1 data types 5-6 description 5-1 fixed-point, scaling of 5-17 group comparison expression 13-5 IF expression 13-4 logical operations 5-20 precedence of operators 5-13 relational operations 5-23 .
Index Extended pointers (continued) declaring simple pointers 9-2 structure pointers 9-12 description 9-1 format B-1 performance guidelines C-1 Extended relocatable data blocks 14-17 Extended stack organization of 4-4 pointers (#SX, #MX) 4-11 storage allocation 4-11 $EXTENDED#STACK 4-11 EXTENDED#STACK#POINTERS 4-11 EXTENSIBLE procedures checking for parameters ($PARAM) 11-10 converting from VARIABLE 11-13 declaring 11-10 parameter area 11-45 parameter masks 11-42 passing as parameters 11-25 procedure entry
Index File names (continued) logical directives that accept 14-9 TACL ASSIGN command E-8 TACL DEFINE command E-4 File records See Structures File type, interlanguage correspondence F-4 File-system errors, testing for 5-25 FILLER declaration 8-16 FIXED data type arrays 7-6 fpoint 6-11 numeric constants 5-9 range of values allowed 5-4 scaling of operands 5-17 simple variables 6-11 FIXED parameter type description 11-20 reference parameters 11-32 value parameters 11-22 FIXED(*) data type arrays 7-6 range of v
Index FOR keyword FOR statement 12-12 group comparison expression 13-6 move statement 7-15 FOR loops See FOR statement FOR statement description 12-12 optimized 12-15 standard 12-13 Formal parameters See Parameters Format of programs 3-13 FORTRAN environment, ENV directive 17-39 FORTRAN LANGUAGE attribute, TAL procedures 17-2 FORWARD procedures 11-8 fpoint of reference parameters 11-32 of value parameters 11-22 positive or negative 5-5 scaling in expressions 5-17 specifying 6-11 Fractions FIXED numbers 5-9
Index #GLOBAL allocation 14-17 description 14-16 listing 15-14 $#GLOBAL description 14-17 listing 15-14 .
Index GOTO statement description 12-24 local (with local labels) 11-48 sublocal (with local labels) 11-49 sublocal (with sublocal labels) 11-50 Group comparison expressions description 13-5 in conditional expressions 5-21 H %H prefix, hexadecimal constants 5-7 Hardware indicators, testing 5-25 HEAP directive 17-41 #HEAP (CRE user heap) 17-41 Hexadecimal number base 5-7 I I register 4-5 I/O See Input/output Identifiers rules for specifying 5-2 scope of 3-3 structure pointers, qualifying 9-18 structures, qua
Index Improving performance addressing C-1 arithmetic expressions C-3 general guidelines C-1 indexing C-2 STACK and STORE statements C-2 IN file compilation command 14-2 RUN command 16-1 Index registers, as value parameters 11-27 Indexing arrays 7-12 description 4-7 equivalenced variables 10-19 performance guidelines C-2 simple pointers 9-10 structure pointers 9-20, 9-22 structures 8-28, 8-30 upper 32K-word area B-8 Indirection arrays 7-2 definition structures 8-3 description 4-6 TAL and C guidelines 17-18
Index Input/output sample programs input file module A-14 output file module A-17 string display A-1 string entry A-3 Inspect product and SYMBOLS directive 16-4 commands BREAK 16-5 CLEAR 16-8 DISPLAY 16-5 RESUME 16-8 STEP 16-5 STOP 16-5 overview 16-4 sample session 16-6 specifying 16-4 starting 16-4 stopping 16-5 Instruction register 4-5 INT attribute, structure pointers 9-13 INT data type arrays 7-5 numeric constants 5-8 range of values allowed 5-4 simple variables 6-6 INT parameter type 11-20 INT(16), al
Index Integers by data type 5-8 interlanguage correspondence F-2 Interface declaration in C 17-13 Interlanguage type correspondence character strings F-3 complex F-3 files F-4 fixed F-3 floating F-3 integers F-2 logical F-4 pointers F-5 sets F-4 structures F-4 Internal file names E-4 K Keywords 5-3 L L register 4-5 L suffix, REAL(64) numbers 5-9 Labeled CASE statement See CASE statement, labeled Labels declaring and using 11-48 local (with local GOTOs) 11-48 local (with sublocal GOTOs) 11-49 local (with su
Index Left shifts, bit 5-29 Lexical-level counter, compiler listing 15-4 LIB option, RUN command 16-1 Library code space 4-1 LIBRARY directive 14-6 Library file, binding 14-6 Limitations See Size Line length, maximum 3-13 Listings See Compiler listing LITERALs declaring 5-11 in arithmetic expressions 5-15 modular sample program A-19 with C enumeration variables 17-27 Load map, compiler listing 15-13 Local data accessing 11-4 declaring 3-8 scope of 3-3 Local map, compiler listing 15-6 Local register 4-5 Loc
Index M MAIN procedures 11-7 Mainline module, sample program A-10 Manuals program development xxx programming xxx system xxix MAP DEFINE command E-5 #MCB (CRE master control block) 17-39 MEM option, RUN command 16-2 Memory models, TAL and C guidelines 17-11 Message module, sample program A-19 Minus operator binary signed 5-16 binary unsigned 5-18 unary 5-16 Mixed-language programming BLOCK declarations 17-1 CRE guidelines 17-37 LANGUAGE attribute, procedures 17-2 NAME declarations 17-1 parameter pairs 17-6
Index Multidimensional arrays 8-13 Multiplication by powers of two 5-30 Multiplication operator signed 5-16 unsigned 5-18 #MX (extended stack pointer) 4-11 N NAME declarations description 14-14 in program structure 3-5 mixed-language programming 17-1 sample program CRE 17-50 mainline module A-10 Named data blocks See NAME declarations NEUTRAL keyword, ENV directive 17-39 Next address group comparison expression 13-7 move statement 7-17 NOCROSSREF directive 14-26 Node name in file names E-2 NOLIST directive
Index Object files, accelerated xxviii OBJECT, default target file 14-4 Octal code, compiler listing 15-9 Octal number base 5-7 OF keyword CASE expression 13-3 CASE statement, labeled 12-5 Offsets, equivalenced variables 10-19 OLD keyword, ENV directive 17-39 Operands accessing 5-27 in arithmetic expressions 5-15 in expressions 5-2 Operators arithmetic signed 5-16 unsigned 5-18 bit-shift 5-29 Boolean 5-22 in expressions 5-13 logical 5-20 precedence of 5-13 relational 5-23 OPTIMIZE directive, labeled CASE s
Index $PARAM, checking for parameters EXTENSIBLE procedures 11-10 VARIABLE procedures 11-9 PARAM BINSERV command E-6 PARAM message, saving 17-44 PARAM SAMECPU command E-6 PARAM SWAPVOL command E-7 PARAM SYMSERV command E-7 Parameter area procedures 11-36 EXTENSIBLE 11-45 VARIABLE 11-40 subprocedures 11-36 Parameter list procedures 11-3 subprocedures 11-15 Parameter masks EXTENSIBLE procedures 11-42 procedures as parameters 11-25 VARIABLE procedures 11-38 Parameter pairs declaring 17-6 passing conditionally
Index Parameters (continued) scope of 11-36 specifications 11-20 PASCAL LANGUAGE attribute, TAL procedures 17-2 Pascal variant parts, emulating 10-21 Passing parameters CALL statement 12-19 conditionally 11-12 unconditionally 11-11 PEP table 11-1 Performance guidelines addressing C-1 arithmetic expressions C-3 general C-1 indexing C-2 STACK and STORE statements C-2 Platforms, software xxviii Plus operator binary signed 5-16 binary unsigned 5-18 unary 5-16 Pointers accessing explicit extended data segments
Index PRINTSYM directive (with USEGLOBALS) 14-25 Private data area, as a TAL feature 1-1 Private data blocks declaring 14-15 in program structure 3-5 PRIVATE keyword, BLOCK declaration 14-15 PROC keyword function declaration 11-8 procedure declaration 11-2 PROC parameter type description 11-23 mixed-language programming 17-4 passing C routines to TAL 17-32 passing TAL routines to C 17-30 PROC(32) parameter type description 11-24 mixed-language programming 17-5 passing C routines to TAL 17-32 passing TAL ro
Index Procedures (continued) typed See Functions VARIABLE 11-9 Process environment 4-1 Processes 4-1 Processor, specifying for compiler E-6 Program control ASSERT statement 12-17 CALL statement 12-19 CASE statement, labeled 12-5 conditional expressions 5-21 DO statement 12-10 FOR statement 12-12 GOTO statement 12-24 IF statement 12-2 labeled CASE statement 12-5 relational expressions 5-24 RETURN statement 12-21 WHILE statement 12-8 Program flow, controlling 12-1 Program register 4-5 Programs See also Objec
Index R Ranges, data types 5-4 Read-only arrays 7-24 REAL data type arrays 7-5 numeric constants 5-9 range of values allowed 5-4 simple variables 6-9 REAL parameter type 11-20 REAL(32), alias of REAL 5-4, 5-6 REAL(64) data type arrays 7-6 numeric constants 5-9 range of values allowed 5-4 simple variables 6-10 REAL(64) parameter type 11-20 $RECEIVE, accessing in the CRE 17-48 Records See Structures Recursion, as a TAL feature 1-2 Redefinitions arrays 8-21 definition substructures 8-23 referral substructures
Index Referral structures addressability 8-9 addressing 8-8 as reference parameters 11-32 declaring 8-8 equivalenced 10-14 storage allocation 8-9 Referral substructures declaring 8-15 redefinitions 8-25 storage allocation 8-15 Register pointer 4-5 Register stack description 4-5 performance guidelines C-2 Registers in process environment 4-5 Relational expressions description 5-21 program flow, controlling 5-24 Relational operators conditional expressions 5-21 group comparison expression 13-9 signed 5-23 te
Index RSCAN statement arrays 7-19 example 7-21 RTLDECS (CRE external declarations file) 17-43 RUN command, TACL product running object files 16-1 running the compiler 14-2 Run-time environment, specifying with ENV directive 17-39 Run-time errors 16-3 Run-time libraries CLULIB 17-43 CRELIB 17-43 TALLIB 17-43 Run-time library, TALLIB 17-44 RUND command, TACL product 16-4 Running object files getting started 2-5 with run-time options 16-1 Running programs See Running object files S S register 4-5 Saved Messag
Index Search subvolume command E-9 Secondary relocatable data blocks 14-17 Secondary storage (global, local) allocation in 4-8 description 4-10 SECTION directive and global data blocks 14-20 and SOURCE directive 14-10 Section names, in SOURCE directive 14-10 Segment specifier, extended pointer B-2 SEGMENT_ALLOCATE_ TAL and C guidelines 17-33 TAL guidelines B-10 SEGMENT_DEALLOCATE_ TAL and C guidelines 17-33 TAL guidelines B-10 SEGMENT_USE_ TAL and C guidelines 17-33 TAL guidelines B-10 Selector CASE expres
Index Simple pointers accessing data assignment statement 9-7, 9-9 indexing 9-10 move and SCAN statements 9-9 upper 32K-word area B-2 addresses in 9-3 as structure items 8-17 declaring 9-2 equivalenced 10-6 redefinitions 8-26 storage allocation 9-6 @ operator 9-3, 9-7 Simple variables accessing 6-4 as reference parameters 11-29 as structure items 8-9 as value parameters 11-21 assignments 6-4 by data type 6-5 declaring 6-1 dereferencing 5-27 equivalenced 10-2 initializing 6-2 redefinitions 8-21 storage allo
Index Size (continued) procedures 11-1 referral structure occurrences 8-8 referral structures 8-8 secondary storage areas 4-10 storage units 5-6 sublocal storage area 11-15 user data segment 4-2 SMU (Saved Messages Utility) routines 17-43 Software platforms, future xxviii Source code, compiler listing 15-3 SOURCE directive and global data blocks 14-20 compiling with 14-10 effect on other directives 14-10 Source files 14-1 compiling 2-4, 14-2 creating 2-2 modular 3-1 modular sample program A-9 Special expre
Index Standard indirection description 4-7 TAL and C guidelines 17-18 Standard input file, CRE 17-46 Standard log file, CRE 17-46 Standard output file, CRE 17-46 Standard pointers accessing data simple pointers 9-9 structure pointers 9-18 declaring simple pointers 9-2 structure pointers 9-12 description 9-1 Startup message, saving 17-44 Statement mnemonics, compiler listing 15-7 Statements ASSERT 12-17 assignment arrays 7-13 simple pointers 9-7 simple variables 6-4 structure items 8-34 structure pointers 9
Index Statements (continued) sublocal scope 3-12 WHILE 12-8 STEP command, Inspect product 16-5 Stepping through programs 16-5 STOP command Inspect product 16-5 TACL product 16-3 Stopping Inspect product 16-5 Stopping object files CRE_TERMINATOR_ 17-45 TACL STOP command 16-3 Storage allocation arrays 7-8 arrays in structures 8-10 definition structures 8-4 definition substructures 8-14 extended data segment automatic 4-10 explicit B-13, B-21 global data blocks 14-16 object files bound with BLOCKs 14-19 param
Index Storage allocation (continued) user data segment lower 32K-word area 4-8 upper 32K-word area B-5 variables 4-8 Storage units, by data type 5-6 STORE statement, performance guidelines C-2 STRING and C char variables 17-19 STRING attribute, structure pointers 9-13 STRING data type arrays 7-4 numeric constants 5-8 range of values allowed 5-4 simple variables 6-5 STRING parameter type 11-20, 11-22 String-display sample program A-1 String-entry sample program A-3 Strings, character 5-10 STRUCT keyword, st
Index Structure pointers (continued) redefinitions 8-26 storage allocation 9-16 upper 32K-word area copying data to B-6 storing addresses B-4 $OFFSET function 9-14 Structures accessing 8-27 as parameters 11-31 assignments 8-34 declaring 8-1 definition structure 8-3 equivalenced definition structures 10-10 referral structures 10-14 identifiers, qualifying 8-27 indexing 8-28 indirection definition structures 8-3 referral structures 8-8 interlanguage correspondence F-4 kinds of 8-1 layout 8-2 referral structu
Index Sublocal storage description 4-9 formal parameters 11-15 limitations parameters 11-18 variables 11-17 parameter area 11-36 Sublocal variables 11-16 Subprocedures address of (PEP number) 11-52 compared to procedures 11-14 declaring 11-15 in program structure 3-10 parameter area 11-36 parameters 11-15 RETURN statement 12-21 sublocal storage area limitations, parameters 11-18 limitations, variables 11-17 size 11-15 TAL and C guidelines 17-21 Substructures declaring 8-12 definition substructures 8-12 ref
Index SYNTAX directive (with USEGLOBALS) 14-25 System code space 4-5 System library space 4-5 System messages, saving 17-44 System name, in file names E-2 System procedures overview of 2-3 sample program mainline module A-12 string display A-1 string entry A-3 with SOURCE directive 14-11 System services 1-3 Systems supported by TAL xxviii T TACL commands ASSIGN E-8 ASSIGN SSV E-9 DEFINE E-4 directives that accept 14-9 PARAM E-6 RUN (running object files) 16-1 RUND (debugging object files) 16-4 starting the
Index TAL and C guidelines (continued) redefinitions and C unions 17-24 structures 17-20 TAL calling C 17-12 UNSIGNED and C bit fields 17-29 TAL calling C 17-12 TALLIB (TAL library file) 17-43 TAL_CRE_INITIALIZER_ 17-44 Tandem NonStop Series system xxviii Tandem NonStop Series/RISC system xxviii TAPE DEFINE command E-5 Target file binding 14-6 compilation command option 14-4 Template blocks allocation 14-17 description 14-16 Template structures 8-7 Temporary files, specifying volume E-7 Temporary pointer S
Index UNSPECIFIED language attribute, procedures 17-2 UNTIL keyword, DO statement 12-10 Upper 32K-word area accessing B-2 indexing B-8 managing storage allocation B-5 organization 4-2 USE statement with FOR statement 12-15 USEGLOBALS directive and CROSSREF directive 14-26 compiling with saved globals 14-23 User code segment accessing B-9 description 4-1 User code space 4-1 User data segment description 4-2 organization 4-3 specifying size with DATAPAGES directive B-2 storage allocation 4-8 User heap, CRE 1
Index VARIABLE procedures checking for parameters ($PARAM) 11-9 converting to EXTENSIBLE 11-13 declaring 11-9 parameter areas 11-40 parameter masks 11-38 passing as parameters 11-25 sample program initialization module A-13 string display A-1 Variables getting the address of 5-27 in arithmetic expressions 5-15 kinds of 5-7 arrays 7-1 pointers 9-1 simple variables 6-1 structures 8-1 Variant parts, emulating 10-21 Volume name defaults DEFAULT DEFINE E-6 specifying E-4 in file names E-2 W WHILE keyword, WHILE
Index X $XADR procedures as parameters 11-24 upper 32K-word area B-8 XEP table 11-1 XOR operator 5-20 Z ZZBInnnn target file 14-4 Special characters " (character string delimiter) 5-10 #CRE_GLOBALS (CRE control block) 17-39 #CRE_HEAP (CRE run-time heap) 17-39 #GLOBAL allocation 14-17 description 14-16 listing 15-14 #HEAP (CRE user heap) 17-41 #MCB (CRE master control block) 17-39 #MX (extended stack pointer) 4-11 #SX (extended stack pointer) 4-11 $#GLOBAL description 14-17 listing 15-14 $CARRY function 5-2
Index %B prefix, binary constants 5-7 %D suffix, hexadecimal INT(32) numbers 5-8 %F suffix, FIXED numbers 5-9 %H prefix, hexadecimal constants 5-7 & concatenated move (copy) operations 7-18 prefix, template block name allocation 14-17 description 14-16, listing 15-14 '*' (unsigned multiplication) 5-18 '+' (unsigned addition) 5-18 '-' (unsigned subtraction) 5-18 '/' (unsigned division) 5-18 '<' (unsigned less than) 5-23 '<<' (unsigned left shift) 5-29 '<=' (unsigned less than or equal to) 5-23 '<>' (unsigne
Index -> (next-address symbol) group comparison expression 13-7 move statement 7-17 . (period) bit extractions 5-28 dereferencing operator 5-27 in file names E-2 . (standard indirection symbol) arrays 7-1 definition structures 8-3 referral structures 8-8 simple pointers 9-2 structure pointers 9-12 .. (ellipsis in labeled CASE statement 12-5 .#GLOBAL description 14-17 listing 15-14 .
Index [n:n] bounds arrays 7-1 structures 8-3, 8-8 : (colon) bit extractions 5-28 entry-point identifiers procedures 3-7 subprocedures 3-11 label identifiers 11-48 := (assignment operator) assignment expression 13-2 assignment statement 6-4 ^ (circumflex) in identifiers 5-2 _ (underscore) in identifiers 5-2 096254 Tandem Computers Incorporated Index–49